-
Notifications
You must be signed in to change notification settings - Fork 1.8k
[master]staticroutebfd process implementation #13789
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3ffcab7
5e96ff3
fa52a10
8fe89b5
054f104
3b03463
dbb585c
7170bdb
d1a5428
9245cc0
72b6e59
59d14cb
7273f8a
f473872
25e4754
765aebc
6e68a89
862ec93
e4b921b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,4 +9,5 @@ program:pimd | |
| program:frrcfgd | ||
| {%- else %} | ||
| program:bgpcfgd | ||
| program:staticroutebfd | ||
| {%- endif %} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,7 @@ def __init__(self, common_objs, db, table): | |
| self.directory.subscribe([("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/bgp_asn"),], self.on_bgp_asn_change) | ||
| self.static_routes = {} | ||
| self.vrf_pending_redistribution = set() | ||
| self.config_db = None | ||
|
|
||
| OP_DELETE = 'DELETE' | ||
| OP_ADD = 'ADD' | ||
|
|
@@ -41,7 +42,17 @@ def set_handler(self, key, data): | |
| intf_list = arg_list(data['ifname']) if 'ifname' in data else None | ||
| dist_list = arg_list(data['distance']) if 'distance' in data else None | ||
| nh_vrf_list = arg_list(data['nexthop-vrf']) if 'nexthop-vrf' in data else None | ||
| route_tag = self.ROUTE_ADVERTISE_DISABLE_TAG if 'advertise' in data and data['advertise'] == "false" else self.ROUTE_ADVERTISE_ENABLE_TAG | ||
| bfd_enable = arg_list(data['bfd']) if 'bfd' in data else None | ||
| route_tag = self.ROUTE_ADVERTISE_DISABLE_TAG if 'advertise' in data and data['advertise'] == "false" else self.ROUTE_ADVERTISE_ENABLE_TAG | ||
|
|
||
| # bfd enabled route would be handled in staticroutebfd, skip here | ||
| if bfd_enable and bfd_enable[0].lower() == "true": | ||
| log_debug("{} static route {} bfd flag is true".format(self.db_name, key)) | ||
| tmp_nh_set, tmp_route_tag = self.static_routes.get(vrf, {}).get(ip_prefix, (IpNextHopSet(is_ipv6), route_tag)) | ||
| if tmp_nh_set: #clear nexthop set if it is not empty | ||
| log_debug("{} static route {} bfd flag is true, cur_nh is not empty, clear it".format(self.db_name, key)) | ||
| self.static_routes.setdefault(vrf, {}).pop(ip_prefix, None) | ||
| return True | ||
|
|
||
| try: | ||
| ip_nh_set = IpNextHopSet(is_ipv6, bkh_list, nh_list, intf_list, dist_list, nh_vrf_list) | ||
|
|
@@ -60,19 +71,59 @@ def set_handler(self, key, data): | |
|
|
||
| if cmd_list: | ||
| self.cfg_mgr.push_list(cmd_list) | ||
| log_debug("Static route {} is scheduled for updates".format(key)) | ||
| log_debug("{} Static route {} is scheduled for updates. {}".format(self.db_name, key, str(cmd_list))) | ||
| else: | ||
| log_debug("Nothing to update for static route {}".format(key)) | ||
| log_debug("{} Nothing to update for static route {}".format(self.db_name, key)) | ||
|
|
||
| self.static_routes.setdefault(vrf, {})[ip_prefix] = (ip_nh_set, route_tag) | ||
|
|
||
| return True | ||
|
|
||
|
|
||
| def skip_appl_del(self, vrf, ip_prefix): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. May be it is good to provide some comments as to what this function does and why it is skipped for some cases.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @baorliu , would you please address this for completion?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will update it soon... |
||
| """ | ||
| If a static route is bfd enabled, the processed static route is written into application DB by staticroutebfd. | ||
| When we disable bfd for that route at runtime, that static route entry will be removed from APPL_DB STATIC_ROUTE_TABLE. | ||
| In the case, the StaticRouteMgr(appl_db) cannot uninstall the static route from FRR if the static route is still in CONFIG_DB, | ||
| so need this checking (skip appl_db deletion) to avoid race condition between StaticRouteMgr(appl_db) and StaticRouteMgr(config_db) | ||
| For more detailed information: | ||
| https://github.com/sonic-net/SONiC/blob/master/doc/static-route/SONiC_static_route_bfd_hld.md#bfd-field-changes-from-true-to-false | ||
|
|
||
| :param vrf: vrf from the split_key(key) return | ||
| :param ip_prefix: ip_prefix from the split_key(key) return | ||
| :return: True if the deletion comes from APPL_DB and the vrf|ip_prefix exists in CONFIG_DB, otherwise return False | ||
| """ | ||
| if self.db_name == "CONFIG_DB": | ||
| return False | ||
|
|
||
| if self.config_db is None: | ||
| self.config_db = swsscommon.SonicV2Connector() | ||
| self.config_db.connect(self.config_db.CONFIG_DB) | ||
|
|
||
| #just pop local cache if the route exist in config_db | ||
| cfg_key = "STATIC_ROUTE|" + vrf + "|" + ip_prefix | ||
| nexthop = self.config_db.get(self.config_db.CONFIG_DB, cfg_key, "nexthop") | ||
| if nexthop and len(nexthop)>0: | ||
| self.static_routes.setdefault(vrf, {}).pop(ip_prefix, None) | ||
| return True | ||
|
|
||
| if vrf == "default": | ||
| cfg_key = "STATIC_ROUTE|" + ip_prefix | ||
| nexthop = self.config_db.get(self.config_db.CONFIG_DB, cfg_key, "nexthop") | ||
| if nexthop and len(nexthop)>0: | ||
| self.static_routes.setdefault(vrf, {}).pop(ip_prefix, None) | ||
| return True | ||
|
|
||
| return False | ||
|
|
||
| def del_handler(self, key): | ||
| vrf, ip_prefix = self.split_key(key) | ||
| is_ipv6 = TemplateFabric.is_ipv6(ip_prefix) | ||
|
|
||
| if self.skip_appl_del(vrf, ip_prefix): | ||
| log_debug("{} ignore appl_db static route deletion because of key {} exist in config_db".format(self.db_name, key)) | ||
| return | ||
|
|
||
| ip_nh_set = IpNextHopSet(is_ipv6) | ||
| cur_nh_set, route_tag = self.static_routes.get(vrf, {}).get(ip_prefix, (IpNextHopSet(is_ipv6), self.ROUTE_ADVERTISE_DISABLE_TAG)) | ||
| cmd_list = self.static_route_commands(ip_nh_set, cur_nh_set, ip_prefix, vrf, route_tag, route_tag) | ||
|
|
@@ -85,9 +136,9 @@ def del_handler(self, key): | |
|
|
||
| if cmd_list: | ||
| self.cfg_mgr.push_list(cmd_list) | ||
| log_debug("Static route {} is scheduled for updates".format(key)) | ||
| log_debug("{} Static route {} is scheduled for updates. {}".format(self.db_name, key, str(cmd_list))) | ||
| else: | ||
| log_debug("Nothing to update for static route {}".format(key)) | ||
| log_debug("{} Nothing to update for static route {}".format(self.db_name, key)) | ||
|
|
||
| self.static_routes.setdefault(vrf, {}).pop(ip_prefix, None) | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.