-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
[staticroutebfd]fix an issue on deleting a non-bfd static route #15269
Changes from all commits
1bf4dd8
a3bc84c
64739f4
b0e7c70
8a76f1f
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,5 +9,4 @@ program:pimd | |
program:frrcfgd | ||
{%- else %} | ||
program:bgpcfgd | ||
program:staticroutebfd | ||
{%- endif %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -400,20 +400,27 @@ def static_route_set_handler(self, key, data): | |
self.handle_bfd_change(key, data_copy, True) | ||
data['bfd_nh_hold'] = "true" | ||
|
||
# preprocess empty nexthop-vrf list before save to LOCAL_CONFIG_TABLE, bfd session need this information | ||
nh_list = arg_list(data['nexthop']) if 'nexthop' in data else None | ||
nh_vrf_list = arg_list(data['nexthop-vrf']) if 'nexthop-vrf' in data else None | ||
if nh_vrf_list is None: | ||
nh_vrf_list = [vrf] * len(nh_list) if len(nh_list) > 0 else None | ||
data['nexthop-vrf'] = ','.join(nh_vrf_list) if nh_vrf_list else '' | ||
else: # preprocess empty nexthop-vrf member | ||
for index in range(len(nh_vrf_list)): | ||
if len(nh_vrf_list[index]) == 0: | ||
nh_vrf_list[index] = vrf | ||
data['nexthop-vrf'] = ','.join(nh_vrf_list) | ||
|
||
if not bfd_enabled: | ||
#skip if bfd is not enabled, but store it to local_db to detect bfd field dynamic change | ||
data['bfd'] = "false" | ||
self.set_local_db(LOCAL_CONFIG_TABLE, route_cfg_key, data) | ||
return True | ||
|
||
bkh_list = arg_list(data['blackhole']) if 'blackhole' in data else None | ||
nh_list = arg_list(data['nexthop']) if 'nexthop' in data else None | ||
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 | ||
if nh_vrf_list is None: | ||
nh_vrf_list = [vrf] * len(nh_list) if len(nh_list) > 0 else None | ||
data['nexthop-vrf'] = ','.join(nh_vrf_list) if nh_vrf_list else '' | ||
if intf_list is None or nh_list is None or nh_vrf_list is None or \ | ||
len(intf_list) != len(nh_list) or len(intf_list) != len(nh_vrf_list): | ||
log_err("Static route bfd set Failed, nexthop, interface and vrf lists do not match.") | ||
|
@@ -502,18 +509,26 @@ def static_route_del_handler(self, key, redis_del): | |
arg_list = lambda v: [x.strip() for x in v.split(',')] if len(v.strip()) != 0 else None | ||
nh_list = arg_list(data['nexthop']) if 'nexthop' in data else None | ||
nh_vrf_list = arg_list(data['nexthop-vrf']) if 'nexthop-vrf' in data else None | ||
for index in range(len(nh_list)): | ||
nh_ip = nh_list[index] | ||
nh_vrf = nh_vrf_list[index] | ||
nh_key = nh_vrf + "|" + nh_ip | ||
self.remove_from_nh_table_entry(nh_key, route_cfg_key) | ||
bfd_field = arg_list(data['bfd']) if 'bfd' in data else ["false"] | ||
bfd_enabled = self.isFieldTrue(bfd_field) | ||
|
||
# for a bfd_enabled static route, the nh_vrf_list was processed, has same length with nh_list | ||
if bfd_enabled and nh_list and nh_vrf_list and len(nh_list) == len(nh_vrf_list): | ||
for index in range(len(nh_list)): | ||
nh_ip = nh_list[index] | ||
nh_vrf = nh_vrf_list[index] | ||
nh_key = nh_vrf + "|" + nh_ip | ||
self.remove_from_nh_table_entry(nh_key, route_cfg_key) | ||
|
||
if len(self.get_local_db(LOCAL_NEXTHOP_TABLE, nh_key)) == 0: | ||
bfd_key = nh_vrf + ":default:" + nh_ip | ||
self.remove_from_local_db(LOCAL_BFD_TABLE, bfd_key) | ||
self.del_bfd_session_from_appl_db(bfd_key) | ||
|
||
if len(self.get_local_db(LOCAL_NEXTHOP_TABLE, nh_key)) == 0: | ||
bfd_key = nh_vrf + ":default:" + nh_ip | ||
self.remove_from_local_db(LOCAL_BFD_TABLE, bfd_key) | ||
self.del_bfd_session_from_appl_db(bfd_key) | ||
# do not delete it from appl_db if the route is not bfd enabled | ||
if bfd_enabled: | ||
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. Why aren't we removing the static route if bfd not enabled? What was the previous behavior? Does this mean if the user removes static route via CLI, won't it get removed from APP_DB? 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. If BFD is not enabled, staticroutebfd does not write static route entry to appl_db. so it should not delete it from appl_db. In general, prefix in config_db should not in appl_db. but to be safe, it is better that staticroutebfd does not touch that route in appl_db if it is not created by staticroutebfd. |
||
self.del_static_route_from_appl_db(route_cfg_key.replace("|", ":")) | ||
|
||
self.del_static_route_from_appl_db(route_cfg_key.replace("|", ":")) | ||
self.remove_from_local_db(LOCAL_SRT_TABLE, route_cfg_key) | ||
|
||
if redis_del: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -169,6 +169,94 @@ def test_set_del(): | |
{'del_default:2.2.2.0/24': {}} | ||
) | ||
|
||
# test add a non-bfd static route | ||
set_del_test(dut, "srt", | ||
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. I also suggest adding a testcase which has nexthop-vrf parameter 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. new testcases are added for nexthop-vrf list. thanks |
||
"SET", | ||
("3.3.3.0/24", { | ||
"nexthop": "192.168.1.2 , 192.168.2.2", | ||
"ifname": "if1, if2", | ||
}), | ||
{}, | ||
{} | ||
) | ||
|
||
# test delete a non-bfd static route | ||
set_del_test(dut, "srt", | ||
"DEL", | ||
("3.3.3.0/24", {}), | ||
{}, | ||
{} | ||
) | ||
|
||
def test_set_del_vrf(): | ||
dut = constructor() | ||
intf_setup(dut) | ||
|
||
set_del_test(dut, "srt", | ||
"SET", | ||
("vrfred|2.2.2.0/24", { | ||
"bfd": "true", | ||
"nexthop": "192.168.1.2 , 192.168.2.2, 192.168.3.2", | ||
"ifname": "if1, if2, if3", | ||
"nexthop-vrf": "testvrf1, , default", | ||
}), | ||
{ | ||
"set_testvrf1:default:192.168.1.2" : {'multihop': 'true', 'rx_interval': '50', 'tx_interval': '50', 'multiplier': '3', 'local_addr': '192.168.1.1'}, | ||
"set_vrfred:default:192.168.2.2" : {'multihop': 'true', 'rx_interval': '50', 'tx_interval': '50', 'multiplier': '3', 'local_addr': '192.168.2.1'}, | ||
"set_default:default:192.168.3.2" : {'multihop': 'true', 'rx_interval': '50', 'tx_interval': '50', 'multiplier': '3', 'local_addr': '192.168.3.1'} | ||
}, | ||
{} | ||
) | ||
|
||
set_del_test(dut, "bfd", | ||
"SET", | ||
("testvrf1|default|192.168.1.2", { | ||
"state": "Up" | ||
}), | ||
{}, | ||
{'set_vrfred:2.2.2.0/24': {'nexthop': '192.168.1.2', 'ifname': 'if1', 'nexthop-vrf': 'testvrf1', 'expiry': 'false'}} | ||
) | ||
set_del_test(dut, "bfd", | ||
"SET", | ||
("vrfred|default|192.168.2.2", { | ||
"state": "Up" | ||
}), | ||
{}, | ||
{'set_vrfred:2.2.2.0/24': {'nexthop': '192.168.2.2,192.168.1.2 ', 'ifname': 'if2,if1', 'nexthop-vrf': 'testvrf1,vrfred', 'expiry': 'false'}} | ||
) | ||
set_del_test(dut, "bfd", | ||
"SET", | ||
("default|default|192.168.3.2", { | ||
"state": "Up" | ||
}), | ||
{}, | ||
{'set_vrfred:2.2.2.0/24': {'nexthop': '192.168.2.2,192.168.1.2,192.168.3.2 ', 'ifname': 'if2,if1,if3', 'nexthop-vrf': 'testvrf1,vrfred,default', 'expiry': 'false'}} | ||
) | ||
|
||
set_del_test(dut, "srt", | ||
"SET", | ||
("vrfred|2.2.2.0/24", { | ||
"bfd": "true", | ||
"nexthop": "192.168.1.2 , 192.168.2.2", | ||
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. fv-pairs for del notification will be empty 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. I will remove that to prevent DUT using these values in case |
||
"ifname": "if1, if2", | ||
"nexthop-vrf": "testvrf1,", | ||
}), | ||
{ | ||
"del_default:default:192.168.3.2" : {} | ||
}, | ||
{'set_vrfred:2.2.2.0/24': {'nexthop': '192.168.2.2,192.168.1.2 ', 'ifname': 'if2,if1', 'nexthop-vrf': 'vrfred, testvrf1', 'expiry': 'false'}} | ||
) | ||
|
||
set_del_test(dut, "srt", | ||
"DEL", | ||
("vrfred|2.2.2.0/24", { }), | ||
{ | ||
"del_testvrf1:default:192.168.1.2" : {}, | ||
"del_vrfred:default:192.168.2.2" : {} | ||
}, | ||
{'del_vrfred:2.2.2.0/24': {}} | ||
) | ||
|
||
def test_bfd_del(): | ||
dut = constructor() | ||
intf_setup(dut) | ||
|
@@ -514,3 +602,4 @@ def test_set_bfd_change_no_hold(): | |
) | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But Isn't this a critical process? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
staticroutebfd itself supports recovery from restart/crash. So it is not necessary to set it to critical process. When a critical process crashes, the bgp container itself will restart, which has more impact. to reduce impact to the bgp container, removed it from critical process, and let supervisord restart staticroutebfd only (see change in supervisord.conf.j2 below).