Add support for static route expiry (#12712)

* add support for static route expiry

* fix debug info

* fix a format issue
This commit is contained in:
jcaiMR 2022-11-16 11:38:43 +08:00 committed by GitHub
parent 668485aac5
commit 71ec4d7fc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 85 additions and 4 deletions

View File

@ -2,6 +2,7 @@ import os
import signal
import sys
import syslog
import threading
import traceback
from swsscommon import swsscommon
@ -19,15 +20,18 @@ from .managers_setsrc import ZebraSetSrc
from .managers_static_rt import StaticRouteMgr
from .managers_rm import RouteMapMgr
from .managers_device_global import DeviceGlobalCfgMgr
from .static_rt_timer import StaticRouteTimer
from .runner import Runner, signal_handler
from .template import TemplateFabric
from .utils import read_constants
from .frr import FRR
from .vars import g_debug
def do_work():
""" Main function """
st_rt_timer = StaticRouteTimer()
thr = threading.Thread(target = st_rt_timer.run)
thr.start()
frr = FRR(["bgpd", "zebra", "staticd"])
frr.wait_for_daemons(seconds=20)
#
@ -62,6 +66,7 @@ def do_work():
BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR"),
# Static Route Managers
StaticRouteMgr(common_objs, "CONFIG_DB", "STATIC_ROUTE"),
StaticRouteMgr(common_objs, "APPL_DB", "STATIC_ROUTE"),
# Route Advertisement Managers
AdvertiseRouteMgr(common_objs, "STATE_DB", swsscommon.STATE_ADVERTISE_NETWORK_TABLE_NAME),
RouteMapMgr(common_objs, "APPL_DB", swsscommon.APP_BGP_PROFILE_TABLE_NAME),
@ -72,6 +77,7 @@ def do_work():
for mgr in managers:
runner.add_manager(mgr)
runner.run()
thr.join()
def main():

View File

@ -4,6 +4,7 @@ from .manager import Manager
from .template import TemplateFabric
import socket
from swsscommon import swsscommon
from ipaddress import ip_network, IPv4Network
class StaticRouteMgr(Manager):
""" This class updates static routes when STATIC_ROUTE table is updated """
@ -96,11 +97,28 @@ class StaticRouteMgr(Manager):
Split key into vrf name and prefix.
:param key: key to split
:return: vrf name extracted from the key, ip prefix extracted from the key
key example: APPL_DB vrf:5.5.5.0/24, 5.5.5.0/24, vrf:2001::0/64, 2001::0/64
CONFIG_DB vrf|5.5.5.0/24, 5.5.5.0/24, vrf|2001::0/64, 2001::0/64
"""
if '|' not in key:
return 'default', key
else:
vrf = ""
prefix = ""
if '|' in key:
return tuple(key.split('|', 1))
else:
try:
_ = ip_network(key)
vrf, prefix = 'default', key
except ValueError:
# key in APPL_DB
log_debug("static route key {} is not prefix only formart, split with ':'".format(key))
output = key.split(':', 1)
if len(output) < 2:
log_debug("invalid input in APPL_DB {}".format(key))
raise ValueError
vrf = output[0]
prefix = key[len(vrf)+1:]
return vrf, prefix
def static_route_commands(self, ip_nh_set, cur_nh_set, ip_prefix, vrf, route_tag, cur_route_tag):
op_cmd_list = {}

View File

@ -0,0 +1,57 @@
from .log import log_err, log_info, log_debug
from swsscommon import swsscommon
import time
class StaticRouteTimer(object):
""" This class checks the static routes and deletes those entries that have not been refreshed """
def __init__(self):
self.db = swsscommon.SonicV2Connector()
self.db.connect(self.db.APPL_DB)
self.timer = None
self.start = None
DEFAULT_TIMER = 180
DEFAULT_SLEEP = 60
MAX_TIMER = 1800
def set_timer(self):
""" Check for custom route expiry time in STATIC_ROUTE:EXPIRY_TIME """
timer = self.db.get(self.db.APPL_DB, "STATIC_ROUTE_EXPIRY_TIME", "time")
if timer is not None:
timer = int(timer)
if timer > 0 and timer <= self.MAX_TIMER:
self.timer = timer
return
log_err("Custom static route expiry time of {}s is invalid!".format(timer))
return
def alarm(self):
""" Clear unrefreshed static routes """
static_routes = self.db.keys(self.db.APPL_DB, "STATIC_ROUTE:*")
if static_routes is not None:
for sr in static_routes:
expiry = self.db.get(self.db.APPL_DB, sr, "expiry")
if expiry == "false":
continue
refresh = self.db.get(self.db.APPL_DB, sr, "refresh")
if refresh == "true":
self.db.set(self.db.APPL_DB, sr, "refresh", "false")
log_debug("Refresh status of static route {} is set to false".format(sr))
else:
self.db.delete(self.db.APPL_DB, sr)
log_debug("Static route {} deleted".format(sr))
self.start = time.time()
return
def run(self):
self.start = time.time()
while True:
self.set_timer()
if self.timer:
log_info("Static route expiry set to {}s".format(self.timer))
time.sleep(self.timer)
self.alarm()
else:
time.sleep(self.DEFAULT_SLEEP)
if time.time() - self.start >= self.DEFAULT_TIMER:
self.alarm()