static route expiry feature support (#12865)

*[Bgpcfgd] static route expiry feature
This commit is contained in:
jcaiMR 2022-11-30 08:23:08 +08:00 committed by GitHub
parent bbcad1362f
commit fe9667950c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 3 deletions

View File

@ -2,6 +2,7 @@ import os
import signal
import sys
import syslog
import threading
import traceback
from swsscommon import swsscommon
@ -17,6 +18,7 @@ from .managers_db import BGPDataBaseMgr
from .managers_intf import InterfaceMgr
from .managers_setsrc import ZebraSetSrc
from .managers_static_rt import StaticRouteMgr
from .static_rt_timer import StaticRouteTimer
from .managers_rm import RouteMapMgr
from .runner import Runner, signal_handler
from .template import TemplateFabric
@ -27,6 +29,9 @@ 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)
#
@ -59,6 +64,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),
@ -67,6 +73,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 """
@ -93,11 +94,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):
diff_set = ip_nh_set.symmetric_difference(cur_nh_set)

View File

@ -0,0 +1,58 @@
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:
if timer.isdigit():
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()