From 0d5bd461af9f77631be6d77438090166ca4bf1aa Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Mon, 16 Dec 2024 15:29:39 +0100 Subject: topotests: bgp_evpn_rt5, add test with match evpn vni command Add a test that ensures that the 'match evpn vni' command works with bgp evpn rt5 updates. Signed-off-by: Philippe Guibert --- tests/topotests/bgp_evpn_rt5/r1/bgpd.conf | 12 +++++++ tests/topotests/bgp_evpn_rt5/r3/bgpd.conf | 31 ++++++++++++++++++ tests/topotests/bgp_evpn_rt5/r3/zebra.conf | 13 ++++++++ tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py | 45 +++++++++++++++++++++------ 4 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 tests/topotests/bgp_evpn_rt5/r3/bgpd.conf create mode 100644 tests/topotests/bgp_evpn_rt5/r3/zebra.conf diff --git a/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf index c8c4faf22..c49f3ce12 100644 --- a/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf +++ b/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf @@ -5,11 +5,17 @@ router bgp 65000 bgp router-id 192.168.100.21 bgp log-neighbor-changes no bgp default ipv4-unicast + no bgp ebgp-requires-policy neighbor 192.168.100.41 remote-as 65000 neighbor 192.168.100.41 capability extended-nexthop + neighbor 192.168.100.61 remote-as 65500 + neighbor 192.168.100.61 capability extended-nexthop ! address-family l2vpn evpn neighbor 192.168.100.41 activate + neighbor 192.168.100.41 route-map rmap_r1 in + neighbor 192.168.100.61 activate + neighbor 192.168.100.61 route-map rmap_r3 in advertise-all-vni exit-address-family ! @@ -28,3 +34,9 @@ router bgp 65000 vrf r1-vrf-101 advertise ipv6 unicast exit-address-family ! +route-map rmap_r3 deny 1 + match evpn vni 102 +exit +route-map rmap_r1 permit 1 + match evpn vni 101 +exit diff --git a/tests/topotests/bgp_evpn_rt5/r3/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r3/bgpd.conf new file mode 100644 index 000000000..43f04c8bd --- /dev/null +++ b/tests/topotests/bgp_evpn_rt5/r3/bgpd.conf @@ -0,0 +1,31 @@ +! debug bgp neighbor-events +! debug bgp updates +! debug bgp zebra +router bgp 65500 + bgp router-id 192.168.100.61 + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy + neighbor 192.168.100.21 remote-as 65000 + neighbor 192.168.100.21 capability extended-nexthop + ! + address-family l2vpn evpn + neighbor 192.168.100.21 activate + advertise-all-vni + exit-address-family +! +router bgp 65000 vrf r3-vrf-102 + bgp router-id 192.168.100.61 + bgp log-neighbor-changes + no bgp network import-check + address-family ipv4 unicast + network 192.168.102.102/32 + exit-address-family + address-family ipv6 unicast + network fd00:102::1/128 + exit-address-family + address-family l2vpn evpn + advertise ipv4 unicast + advertise ipv6 unicast + exit-address-family + ! diff --git a/tests/topotests/bgp_evpn_rt5/r3/zebra.conf b/tests/topotests/bgp_evpn_rt5/r3/zebra.conf new file mode 100644 index 000000000..3ab51423d --- /dev/null +++ b/tests/topotests/bgp_evpn_rt5/r3/zebra.conf @@ -0,0 +1,13 @@ +vrf r3-vrf-102 + vni 102 + exit-vrf +! +interface r3-eth0 + ip address 192.168.100.61/24 +! +interface loop102 vrf r3-vrf-102 + ip address 192.168.102.61/32 + ipv6 address fd00:6::1/128 +! + + diff --git a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py index c874cbed6..8570f4f8a 100644 --- a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py +++ b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py @@ -42,10 +42,12 @@ def build_topo(tgen): tgen.add_router("r1") tgen.add_router("r2") + tgen.add_router("r3") switch = tgen.add_switch("s1") switch.add_link(tgen.gears["r1"]) switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) switch = tgen.add_switch("s2") switch.add_link(tgen.gears["r1"]) @@ -53,6 +55,9 @@ def build_topo(tgen): switch = tgen.add_switch("s3") switch.add_link(tgen.gears["r2"]) + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["r3"]) + def setup_module(mod): "Sets up the pytest environment" @@ -71,16 +76,16 @@ def setup_module(mod): ) return pytest.skip("Skipping BGP EVPN RT5 NETNS Test. Kernel not supported") - # create VRF vrf-101 on R1 and R2 + # create VRF vrf-101 on R1, R2, R3 # create loop101 cmds_vrflite = [ - "ip link add {}-vrf-101 type vrf table 101", - "ip ru add oif {}-vrf-101 table 101", - "ip ru add iif {}-vrf-101 table 101", - "ip link set dev {}-vrf-101 up", - "ip link add loop101 type dummy", - "ip link set dev loop101 master {}-vrf-101", - "ip link set dev loop101 up", + "ip link add {0}-vrf-{1} type vrf table {1}", + "ip ru add oif {0}-vrf-{1} table {1}", + "ip ru add iif {0}-vrf-{1} table {1}", + "ip link set dev {0}-vrf-{1} up", + "ip link add loop{1} type dummy", + "ip link set dev loop{1} master {0}-vrf-{1}", + "ip link set dev loop{1} up", ] cmds_r2 = [ # config routing 101 @@ -92,6 +97,15 @@ def setup_module(mod): "ip link set vxlan-101 up type bridge_slave learning off flood off mcast_flood off", ] + cmds_r3 = [ # config routing 102 + "ip link add name bridge-102 up type bridge stp_state 0", + "ip link set bridge-102 master {}-vrf-102", + "ip link set dev bridge-102 up", + "ip link add name vxlan-102 type vxlan id 102 dstport 4789 dev r3-eth0 local 192.168.100.61", + "ip link set dev vxlan-102 master bridge-102", + "ip link set vxlan-102 up type bridge_slave learning off flood off mcast_flood off", + ] + # cmds_r1_netns_method3 = [ # "ip link add name vxlan-{1} type vxlan id {1} dstport 4789 dev {0}-eth0 local 192.168.100.21", # "ip link set dev vxlan-{1} netns {0}-vrf-{1}", @@ -111,8 +125,8 @@ def setup_module(mod): router = tgen.gears["r2"] for cmd in cmds_vrflite: - logger.info("cmd to r2: " + cmd.format("r2")) - output = router.cmd_raises(cmd.format("r2")) + logger.info("cmd to r2: " + cmd.format("r2", 101)) + output = router.cmd_raises(cmd.format("r2", 101)) logger.info("result: " + output) for cmd in cmds_r2: @@ -120,6 +134,17 @@ def setup_module(mod): output = router.cmd_raises(cmd.format("r2")) logger.info("result: " + output) + router = tgen.gears["r3"] + for cmd in cmds_vrflite: + logger.info("cmd to r3: " + cmd.format("r3", 102)) + output = router.cmd_raises(cmd.format("r3", 102)) + logger.info("result: " + output) + + for cmd in cmds_r3: + logger.info("cmd to r3: " + cmd.format("r3")) + output = router.cmd_raises(cmd.format("r3")) + logger.info("result: " + output) + tgen.net["r1"].cmd_raises( "ip link add name vxlan-101 type vxlan id 101 dstport 4789 dev r1-eth0 local 192.168.100.21" ) -- cgit v1.2.3 From 82339c94edc6c864593e6199f7b279927d964083 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Mon, 30 Dec 2024 16:04:14 +0100 Subject: topotests: bgp_evpn_rt5, configure route_distinguisher When not configuring a route distinguisher, neither route-target, the derived rd settings differ if config load applies with frr.conf or not. For instance, the forged rd with frr.conf: > # show bgp l2vpn evpn json > "192.168.101.41:3":{ > "rd":"192.168.101.41:3", and without: > "192.168.101.41:2":{ > "rd":"192.168.101.41:2", The defined rts also are impacted. Temporay fix this by using an hardset configuration for all route distinguisher and route target of the setups. Signed-off-by: Philippe Guibert --- tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json | 8 ++++---- tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json | 8 ++++---- tests/topotests/bgp_evpn_rt5/r1/bgpd.conf | 2 ++ tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json | 8 ++++---- tests/topotests/bgp_evpn_rt5/r2/bgpd.conf | 2 ++ tests/topotests/bgp_evpn_rt5/r3/bgpd.conf | 2 ++ 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json b/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json index 7532ce933..cfab5726e 100644 --- a/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json +++ b/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json @@ -2,8 +2,8 @@ "bgpLocalRouterId":"192.168.100.21", "defaultLocPrf":100, "localAS":65000, - "192.168.101.41:2":{ - "rd":"192.168.101.41:2", + "65000:201":{ + "rd":"65000:201", "[5]:[0]:[32]:[192.168.101.41]":{ "prefix":"[5]:[0]:[32]:[192.168.101.41]", "prefixLen":352, @@ -65,8 +65,8 @@ ] } }, - "192.168.102.21:2":{ - "rd":"192.168.102.21:2", + "65000:101":{ + "rd":"65000:101", "[5]:[0]:[32]:[192.168.102.21]":{ "prefix":"[5]:[0]:[32]:[192.168.102.21]", "prefixLen":352, diff --git a/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json b/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json index a14ba1291..444c67e44 100644 --- a/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json +++ b/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json @@ -2,8 +2,8 @@ "bgpLocalRouterId":"192.168.100.21", "defaultLocPrf":100, "localAS":65000, - "192.168.101.41:2":{ - "rd":"192.168.101.41:2", + "65000:201":{ + "rd":"65000:201", "[5]:[0]:[32]:[192.168.101.41]":{ "prefix":"[5]:[0]:[32]:[192.168.101.41]", "prefixLen":352, @@ -125,8 +125,8 @@ ] } }, - "192.168.102.21:2":{ - "rd":"192.168.102.21:2", + "65000:101":{ + "rd":"65000:101", "[5]:[0]:[32]:[192.168.102.21]":{ "prefix":"[5]:[0]:[32]:[192.168.102.21]", "prefixLen":352, diff --git a/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf index c49f3ce12..b9c230206 100644 --- a/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf +++ b/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf @@ -30,6 +30,8 @@ router bgp 65000 vrf r1-vrf-101 network fd00::1/128 exit-address-family address-family l2vpn evpn + rd 65000:101 + route-target both 65:101 advertise ipv4 unicast advertise ipv6 unicast exit-address-family diff --git a/tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json b/tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json index 597bca5fd..3a55a7a38 100644 --- a/tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json +++ b/tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json @@ -2,8 +2,8 @@ "bgpLocalRouterId":"192.168.100.41", "defaultLocPrf":100, "localAS":65000, - "192.168.101.41:2":{ - "rd":"192.168.101.41:2", + "65000:201":{ + "rd":"65000:201", "[5]:[0]:[32]:[192.168.101.41]":{ "prefix":"[5]:[0]:[32]:[192.168.101.41]", "prefixLen":352, @@ -63,8 +63,8 @@ ] } }, - "192.168.102.21:2":{ - "rd":"192.168.102.21:2", + "65000:101":{ + "rd":"65000:101", "[5]:[0]:[32]:[192.168.102.21]":{ "prefix":"[5]:[0]:[32]:[192.168.102.21]", "prefixLen":352, diff --git a/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf index 4f1d8e4a3..8d60c3e17 100644 --- a/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf +++ b/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf @@ -27,6 +27,8 @@ router bgp 65000 vrf r2-vrf-101 network fd00::3/128 exit-address-family address-family l2vpn evpn + rd 65000:201 + route-target both 65:101 advertise ipv4 unicast route-map rmap4 advertise ipv6 unicast route-map rmap6 exit-address-family diff --git a/tests/topotests/bgp_evpn_rt5/r3/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r3/bgpd.conf index 43f04c8bd..860612ec7 100644 --- a/tests/topotests/bgp_evpn_rt5/r3/bgpd.conf +++ b/tests/topotests/bgp_evpn_rt5/r3/bgpd.conf @@ -25,6 +25,8 @@ router bgp 65000 vrf r3-vrf-102 network fd00:102::1/128 exit-address-family address-family l2vpn evpn + rd 65000:302 + route-target both 65:101 advertise ipv4 unicast advertise ipv6 unicast exit-address-family -- cgit v1.2.3 From d84b93f2872daeb1605ed09bbd9fb6fbbfa9b760 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 19 Dec 2024 17:28:21 +0100 Subject: topotests: add unified configuration Replace the various per-daemon config files with a unique frr.conf configuration file. Signed-off-by: Philippe Guibert --- tests/topotests/bgp_bmp/test_bgp_bmp_1.py | 2 +- tests/topotests/bgp_evpn_rt5/r1/bgpd.conf | 44 ------------------ tests/topotests/bgp_evpn_rt5/r1/frr.conf | 61 +++++++++++++++++++++++++ tests/topotests/bgp_evpn_rt5/r1/zebra.conf | 23 ---------- tests/topotests/bgp_evpn_rt5/r2/bgpd.conf | 51 --------------------- tests/topotests/bgp_evpn_rt5/r2/frr.conf | 65 +++++++++++++++++++++++++++ tests/topotests/bgp_evpn_rt5/r2/zebra.conf | 19 -------- tests/topotests/bgp_evpn_rt5/r3/bgpd.conf | 33 -------------- tests/topotests/bgp_evpn_rt5/r3/frr.conf | 46 +++++++++++++++++++ tests/topotests/bgp_evpn_rt5/r3/zebra.conf | 13 ------ tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py | 14 ++---- 11 files changed, 177 insertions(+), 194 deletions(-) delete mode 100644 tests/topotests/bgp_evpn_rt5/r1/bgpd.conf create mode 100644 tests/topotests/bgp_evpn_rt5/r1/frr.conf delete mode 100644 tests/topotests/bgp_evpn_rt5/r1/zebra.conf delete mode 100644 tests/topotests/bgp_evpn_rt5/r2/bgpd.conf create mode 100644 tests/topotests/bgp_evpn_rt5/r2/frr.conf delete mode 100644 tests/topotests/bgp_evpn_rt5/r2/zebra.conf delete mode 100644 tests/topotests/bgp_evpn_rt5/r3/bgpd.conf create mode 100644 tests/topotests/bgp_evpn_rt5/r3/frr.conf delete mode 100644 tests/topotests/bgp_evpn_rt5/r3/zebra.conf diff --git a/tests/topotests/bgp_bmp/test_bgp_bmp_1.py b/tests/topotests/bgp_bmp/test_bgp_bmp_1.py index be3e07929..1d7aa9747 100644 --- a/tests/topotests/bgp_bmp/test_bgp_bmp_1.py +++ b/tests/topotests/bgp_bmp/test_bgp_bmp_1.py @@ -78,7 +78,7 @@ def setup_module(mod): "tcpdump -nni r1-eth0 -s 0 -w {} &".format(pcap_file), stdout=None ) - for rname, router in tgen.routers().items(): + for _, (rname, router) in enumerate(tgen.routers().items(), 1): logger.info("Loading router %s" % rname) router.load_frr_config( os.path.join(CWD, "{}/frr.conf".format(rname)), diff --git a/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf deleted file mode 100644 index b9c230206..000000000 --- a/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf +++ /dev/null @@ -1,44 +0,0 @@ -! debug bgp neighbor-events -! debug bgp updates -! debug bgp zebra -router bgp 65000 - bgp router-id 192.168.100.21 - bgp log-neighbor-changes - no bgp default ipv4-unicast - no bgp ebgp-requires-policy - neighbor 192.168.100.41 remote-as 65000 - neighbor 192.168.100.41 capability extended-nexthop - neighbor 192.168.100.61 remote-as 65500 - neighbor 192.168.100.61 capability extended-nexthop - ! - address-family l2vpn evpn - neighbor 192.168.100.41 activate - neighbor 192.168.100.41 route-map rmap_r1 in - neighbor 192.168.100.61 activate - neighbor 192.168.100.61 route-map rmap_r3 in - advertise-all-vni - exit-address-family -! -router bgp 65000 vrf r1-vrf-101 - bgp router-id 192.168.102.21 - bgp log-neighbor-changes - no bgp network import-check - address-family ipv4 unicast - network 192.168.102.21/32 - exit-address-family - address-family ipv6 unicast - network fd00::1/128 - exit-address-family - address-family l2vpn evpn - rd 65000:101 - route-target both 65:101 - advertise ipv4 unicast - advertise ipv6 unicast - exit-address-family - ! -route-map rmap_r3 deny 1 - match evpn vni 102 -exit -route-map rmap_r1 permit 1 - match evpn vni 101 -exit diff --git a/tests/topotests/bgp_evpn_rt5/r1/frr.conf b/tests/topotests/bgp_evpn_rt5/r1/frr.conf new file mode 100644 index 000000000..e4a805998 --- /dev/null +++ b/tests/topotests/bgp_evpn_rt5/r1/frr.conf @@ -0,0 +1,61 @@ +! debug zebra vxlan +! debug zebra kernel +! debug zebra dplane +! debug zebra rib +! debug bgp neighbor-events +! debug bgp updates +! debug bgp zebra +vrf r1-vrf-101 + vni 101 + exit-vrf +! +interface r1-eth0 + ip address 192.168.100.21/24 +! +interface loop101 vrf r1-vrf-101 + ip address 192.168.102.21/32 + ipv6 address fd00::1/128 +! +router bgp 65000 + bgp router-id 192.168.100.21 + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy + neighbor 192.168.100.41 remote-as 65000 + neighbor 192.168.100.41 capability extended-nexthop + neighbor 192.168.100.61 remote-as 65500 + neighbor 192.168.100.61 capability extended-nexthop + ! + address-family l2vpn evpn + neighbor 192.168.100.41 activate + neighbor 192.168.100.41 route-map rmap_r1 in + neighbor 192.168.100.61 activate + neighbor 192.168.100.61 route-map rmap_r3 in + advertise-all-vni + exit-address-family +! +router bgp 65000 vrf r1-vrf-101 + bgp router-id 192.168.102.21 + bgp log-neighbor-changes + no bgp network import-check + address-family ipv4 unicast + network 192.168.102.21/32 + exit-address-family + address-family ipv6 unicast + network fd00::1/128 + exit-address-family + address-family l2vpn evpn + rd 65000:101 + route-target both 65:101 + advertise ipv4 unicast + advertise ipv6 unicast + exit-address-family + ! +route-map rmap_r3 deny 1 + match evpn vni 102 +exit +route-map rmap_r1 permit 1 + match evpn vni 101 +exit + + diff --git a/tests/topotests/bgp_evpn_rt5/r1/zebra.conf b/tests/topotests/bgp_evpn_rt5/r1/zebra.conf deleted file mode 100644 index c3d508c2b..000000000 --- a/tests/topotests/bgp_evpn_rt5/r1/zebra.conf +++ /dev/null @@ -1,23 +0,0 @@ -log stdout - -hostname r1 -password zebra - -! debug zebra vxlan -! debug zebra kernel -! debug zebra dplane -! debug zebra rib -log stdout -vrf r1-vrf-101 - vni 101 - exit-vrf -! -interface r1-eth0 - ip address 192.168.100.21/24 -! -interface loop101 vrf r1-vrf-101 - ip address 192.168.102.21/32 - ipv6 address fd00::1/128 -! - - diff --git a/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf deleted file mode 100644 index 8d60c3e17..000000000 --- a/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf +++ /dev/null @@ -1,51 +0,0 @@ -! debug bgp neighbor-events -! debug bgp updates -! debug bgp zebra -router bgp 65000 - bgp router-id 192.168.100.41 - bgp log-neighbor-changes - no bgp default ipv4-unicast - neighbor 192.168.100.21 peer-group - neighbor 192.168.100.21 remote-as 65000 - neighbor 192.168.100.21 capability extended-nexthop - ! - address-family l2vpn evpn - neighbor 192.168.100.21 activate - advertise-all-vni - exit-address-family -! -router bgp 65000 vrf r2-vrf-101 - bgp router-id 192.168.101.41 - bgp log-neighbor-changes - no bgp network import-check - address-family ipv4 unicast - network 192.168.101.41/32 - network 192.168.102.41/32 - exit-address-family - address-family ipv6 unicast - network fd00::2/128 - network fd00::3/128 - exit-address-family - address-family l2vpn evpn - rd 65000:201 - route-target both 65:101 - advertise ipv4 unicast route-map rmap4 - advertise ipv6 unicast route-map rmap6 - exit-address-family - ! -access-list acl4_1 seq 10 permit 192.168.101.41/32 -access-list acl4_2 seq 10 permit 192.168.102.41/32 -ipv6 access-list acl6_1 seq 10 permit fd00::2/128 -ipv6 access-list acl6_2 seq 10 permit fd00::3/128 -route-map rmap4 permit 1 - match ip address acl4_1 -exit -route-map rmap4 deny 2 - match ip address acl4_2 -exit -route-map rmap6 permit 1 - match ipv6 address acl6_1 -exit -route-map rmap6 deny 2 - match ipv6 address acl6_2 -exit diff --git a/tests/topotests/bgp_evpn_rt5/r2/frr.conf b/tests/topotests/bgp_evpn_rt5/r2/frr.conf new file mode 100644 index 000000000..0bb4b7cab --- /dev/null +++ b/tests/topotests/bgp_evpn_rt5/r2/frr.conf @@ -0,0 +1,65 @@ +! debug zebra vxlan +! debug bgp neighbor-events +! debug bgp updates +! debug bgp zebra + +vrf r2-vrf-101 + vni 101 + exit-vrf +! +interface loop101 vrf r2-vrf-101 + ip address 192.168.101.41/32 + ipv6 address fd00::2/128 +! +interface r2-eth0 + ip address 192.168.100.41/24 +! +router bgp 65000 + bgp router-id 192.168.100.41 + bgp log-neighbor-changes + no bgp default ipv4-unicast + neighbor 192.168.100.21 peer-group + neighbor 192.168.100.21 remote-as 65000 + neighbor 192.168.100.21 capability extended-nexthop + ! + address-family l2vpn evpn + neighbor 192.168.100.21 activate + advertise-all-vni + exit-address-family +! +router bgp 65000 vrf r2-vrf-101 + bgp router-id 192.168.101.41 + bgp log-neighbor-changes + no bgp network import-check + address-family ipv4 unicast + network 192.168.101.41/32 + network 192.168.102.41/32 + exit-address-family + address-family ipv6 unicast + network fd00::2/128 + network fd00::3/128 + exit-address-family + address-family l2vpn evpn + rd 65000:201 + route-target both 65:101 + advertise ipv4 unicast route-map rmap4 + advertise ipv6 unicast route-map rmap6 + exit-address-family + ! +access-list acl4_1 seq 10 permit 192.168.101.41/32 +access-list acl4_2 seq 10 permit 192.168.102.41/32 +ipv6 access-list acl6_1 seq 10 permit fd00::2/128 +ipv6 access-list acl6_2 seq 10 permit fd00::3/128 +route-map rmap4 permit 1 + match ip address acl4_1 +exit +route-map rmap4 deny 2 + match ip address acl4_2 +exit +route-map rmap6 permit 1 + match ipv6 address acl6_1 +exit +route-map rmap6 deny 2 + match ipv6 address acl6_2 +exit + diff --git a/tests/topotests/bgp_evpn_rt5/r2/zebra.conf b/tests/topotests/bgp_evpn_rt5/r2/zebra.conf deleted file mode 100644 index 7db40cb59..000000000 --- a/tests/topotests/bgp_evpn_rt5/r2/zebra.conf +++ /dev/null @@ -1,19 +0,0 @@ -log stdout - -hostname r2 -password zebra - -! debug zebra vxlan - -vrf r2-vrf-101 - vni 101 - exit-vrf -! -interface loop101 vrf r2-vrf-101 - ip address 192.168.101.41/32 - ipv6 address fd00::2/128 -! -interface r2-eth0 - ip address 192.168.100.41/24 -! - diff --git a/tests/topotests/bgp_evpn_rt5/r3/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r3/bgpd.conf deleted file mode 100644 index 860612ec7..000000000 --- a/tests/topotests/bgp_evpn_rt5/r3/bgpd.conf +++ /dev/null @@ -1,33 +0,0 @@ -! debug bgp neighbor-events -! debug bgp updates -! debug bgp zebra -router bgp 65500 - bgp router-id 192.168.100.61 - bgp log-neighbor-changes - no bgp default ipv4-unicast - no bgp ebgp-requires-policy - neighbor 192.168.100.21 remote-as 65000 - neighbor 192.168.100.21 capability extended-nexthop - ! - address-family l2vpn evpn - neighbor 192.168.100.21 activate - advertise-all-vni - exit-address-family -! -router bgp 65000 vrf r3-vrf-102 - bgp router-id 192.168.100.61 - bgp log-neighbor-changes - no bgp network import-check - address-family ipv4 unicast - network 192.168.102.102/32 - exit-address-family - address-family ipv6 unicast - network fd00:102::1/128 - exit-address-family - address-family l2vpn evpn - rd 65000:302 - route-target both 65:101 - advertise ipv4 unicast - advertise ipv6 unicast - exit-address-family - ! diff --git a/tests/topotests/bgp_evpn_rt5/r3/frr.conf b/tests/topotests/bgp_evpn_rt5/r3/frr.conf new file mode 100644 index 000000000..3f3851bd8 --- /dev/null +++ b/tests/topotests/bgp_evpn_rt5/r3/frr.conf @@ -0,0 +1,46 @@ +! debug bgp neighbor-events +! debug bgp updates +! debug bgp zebra +vrf r3-vrf-102 + vni 102 + exit-vrf +! +interface r3-eth0 + ip address 192.168.100.61/24 +! +interface loop102 vrf r3-vrf-102 + ip address 192.168.102.61/32 + ipv6 address fd00:6::1/128 +! +router bgp 65500 + bgp router-id 192.168.100.61 + bgp log-neighbor-changes + no bgp default ipv4-unicast + no bgp ebgp-requires-policy + neighbor 192.168.100.21 remote-as 65000 + neighbor 192.168.100.21 capability extended-nexthop + ! + address-family l2vpn evpn + neighbor 192.168.100.21 activate + advertise-all-vni + exit-address-family +! +router bgp 65000 vrf r3-vrf-102 + bgp router-id 192.168.100.61 + bgp log-neighbor-changes + no bgp network import-check + address-family ipv4 unicast + network 192.168.102.102/32 + exit-address-family + address-family ipv6 unicast + network fd00:102::1/128 + exit-address-family + address-family l2vpn evpn + rd 65000:302 + route-target both 65:101 + advertise ipv4 unicast + advertise ipv6 unicast + exit-address-family + ! + + diff --git a/tests/topotests/bgp_evpn_rt5/r3/zebra.conf b/tests/topotests/bgp_evpn_rt5/r3/zebra.conf deleted file mode 100644 index 3ab51423d..000000000 --- a/tests/topotests/bgp_evpn_rt5/r3/zebra.conf +++ /dev/null @@ -1,13 +0,0 @@ -vrf r3-vrf-102 - vni 102 - exit-vrf -! -interface r3-eth0 - ip address 192.168.100.61/24 -! -interface loop102 vrf r3-vrf-102 - ip address 192.168.102.61/32 - ipv6 address fd00:6::1/128 -! - - diff --git a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py index 8570f4f8a..2b8355af0 100644 --- a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py +++ b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py @@ -159,19 +159,13 @@ def setup_module(mod): tgen.net["r1"].cmd_raises("ip -n r1-vrf-101 link set bridge-101 up") tgen.net["r1"].cmd_raises("ip -n r1-vrf-101 link set vxlan-101 up") - for rname, router in router_list.items(): + for rname, router in tgen.routers().items(): + logger.info("Loading router %s" % rname) if rname == "r1": router.use_netns_vrf() - router.load_config( - TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) - ) + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) else: - router.load_config( - TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) - ) - router.load_config( - TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) - ) + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) # Initialize all routers. tgen.start_router() -- cgit v1.2.3 From 6855bf2232b661f97752b24b4eb31205199d136c Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 31 Dec 2024 14:42:17 +0100 Subject: bgpd: fix bgp evpn memory leaks when adj-rib-in is disabled Some bgp evpn memory contexts are not freed at the end of the bgp process. > ================================================================= > ==1208677==ERROR: LeakSanitizer: detected memory leaks > > Direct leak of 96 byte(s) in 2 object(s) allocated from: > #0 0x7f93ad4b4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154 > #1 0x7f93ace77233 in qcalloc lib/memory.c:106 > #2 0x563bb68f4df1 in process_type5_route bgpd/bgp_evpn.c:5084 > #3 0x563bb68fb663 in bgp_nlri_parse_evpn bgpd/bgp_evpn.c:6302 > #4 0x563bb69ea2a9 in bgp_nlri_parse bgpd/bgp_packet.c:347 > #5 0x563bb69f7716 in bgp_update_receive bgpd/bgp_packet.c:2482 > #6 0x563bb6a04d3b in bgp_process_packet bgpd/bgp_packet.c:4091 > #7 0x7f93acf8082d in event_call lib/event.c:1996 > #8 0x7f93ace48931 in frr_run lib/libfrr.c:1232 > #9 0x563bb6880ae1 in main bgpd/bgp_main.c:557 > #10 0x7f93ac829d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 Actually, the bgp evpn context may noy be used if adj rib in is unused. This may lead to memory leaks. Fix this by freeing the context in those corner cases. Signed-off-by: Philippe Guibert --- bgpd/bgp_route.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index a1b12e5a8..2a28018d4 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4910,6 +4910,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bool force_evpn_import = false; safi_t orig_safi = safi; struct bgp_labels bgp_labels = {}; + struct bgp_route_evpn *p_evpn = evpn; uint8_t i; if (frrtrace_enabled(frr_bgp, process_update)) { @@ -4951,11 +4952,9 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, * will not be interned. In which case, it is ok to update the * attr->evpn_overlay, so that, this can be stored in adj_in. */ - if (evpn) { - if (afi == AFI_L2VPN) - bgp_attr_set_evpn_overlay(attr, evpn); - else - evpn_overlay_free(evpn); + if (evpn && afi == AFI_L2VPN) { + bgp_attr_set_evpn_overlay(attr, evpn); + p_evpn = NULL; } bgp_adj_in_set(dest, peer, attr, addpath_id, &bgp_labels); } @@ -5128,11 +5127,9 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, * attr->evpn_overlay with evpn directly. Instead memcpy * evpn to new_atr.evpn_overlay before it is interned. */ - if (soft_reconfig && evpn) { - if (afi == AFI_L2VPN) - bgp_attr_set_evpn_overlay(&new_attr, evpn); - else - evpn_overlay_free(evpn); + if (soft_reconfig && evpn && afi == AFI_L2VPN) { + bgp_attr_set_evpn_overlay(&new_attr, evpn); + p_evpn = NULL; } /* Apply incoming route-map. @@ -5301,7 +5298,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_dest_unlock_node(dest); bgp_attr_unintern(&attr_new); - + if (p_evpn) + evpn_overlay_free(p_evpn); return; } @@ -5466,6 +5464,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, ret = bgp_damp_update(pi, dest, afi, safi); if (ret == BGP_DAMP_SUPPRESSED) { bgp_dest_unlock_node(dest); + if (p_evpn) + evpn_overlay_free(p_evpn); return; } } @@ -5552,6 +5552,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, type, sub_type, NULL); } #endif + if (p_evpn) + evpn_overlay_free(p_evpn); return; } // End of implicit withdraw @@ -5646,6 +5648,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } #endif + if (p_evpn) + evpn_overlay_free(p_evpn); return; /* This BGP update is filtered. Log the reason then update BGP @@ -5709,6 +5713,8 @@ filtered: } #endif + if (p_evpn) + evpn_overlay_free(p_evpn); return; } -- cgit v1.2.3 From 9f7177af13c4ccf8166bf861994702635703dd9a Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 31 Dec 2024 14:38:11 +0100 Subject: bgpd: fix duplicate BGP instance created with unified config When running the bgp_evpn_rt5 setup with unified config, memory leak about a non deleted BGP instance happens. > root@ubuntu2204hwe:~/frr/tests/topotests/bgp_evpn_rt5# cat /tmp/topotests/bgp_evpn_rt5.test_bgp_evpn/r1.asan.bgpd.1164105 > > ================================================================= > ==1164105==ERROR: LeakSanitizer: detected memory leaks > > Indirect leak of 12496 byte(s) in 1 object(s) allocated from: > #0 0x7f358eeb4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154 > #1 0x7f358e877233 in qcalloc lib/memory.c:106 > #2 0x55d06c95680a in bgp_create bgpd/bgpd.c:3405 > #3 0x55d06c95a7b3 in bgp_get bgpd/bgpd.c:3805 > #4 0x55d06c87a9b5 in bgp_get_vty bgpd/bgp_vty.c:603 > #5 0x55d06c68dc71 in bgp_evpn_local_l3vni_add bgpd/bgp_evpn.c:7032 > #6 0x55d06c92989b in bgp_zebra_process_local_l3vni bgpd/bgp_zebra.c:3204 > #7 0x7f358e9e3feb in zclient_read lib/zclient.c:4626 > #8 0x7f358e98082d in event_call lib/event.c:1996 > #9 0x7f358e848931 in frr_run lib/libfrr.c:1232 > #10 0x55d06c60eae1 in main bgpd/bgp_main.c:557 > #11 0x7f358e229d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 Actually, a BGP VRF Instance is created in auto mode when creating the global BGP instance for the L3 VNI. And again, an other BGP VRF instance is created. Fix this by ensuring that a non existing BGP instance is not present. If it is present, and with auto mode or in hidden mode, then override the AS value. Fixes: f153b9a9b636 ("bgpd: Ignore auto created VRF BGP instances") Signed-off-by: Philippe Guibert --- bgpd/bgp_vty.c | 18 ++++++++++-------- bgpd/bgpd.c | 24 ++++++++++++++---------- bgpd/bgpd.h | 8 +++----- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 33b220d3e..8fefbeb49 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1499,13 +1499,12 @@ DEFUN_NOSH (router_bgp, int idx_asn = 2; int idx_view_vrf = 3; int idx_vrf = 4; - int is_new_bgp = 0; int idx_asnotation = 3; int idx_asnotation_kind = 4; enum asnotation_mode asnotation = ASNOTATION_UNDEFINED; int ret; as_t as; - struct bgp *bgp; + struct bgp *bgp = NULL; const char *name = NULL; enum bgp_instance_type inst_type; @@ -1567,11 +1566,14 @@ DEFUN_NOSH (router_bgp, asnotation = ASNOTATION_PLAIN; } - if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) - is_new_bgp = (bgp_lookup(as, name) == NULL); - - ret = bgp_get_vty(&bgp, &as, name, inst_type, - argv[idx_asn]->arg, asnotation); + ret = bgp_lookup_by_as_name_type(&bgp, &as, argv[idx_asn]->arg, asnotation, name, + inst_type, true); + if (bgp && ret == BGP_INSTANCE_EXISTS) + ret = CMD_SUCCESS; + else if (bgp == NULL && ret == CMD_SUCCESS) + /* SUCCESS and bgp is NULL */ + ret = bgp_get_vty(&bgp, &as, name, inst_type, argv[idx_asn]->arg, + asnotation); switch (ret) { case BGP_ERR_AS_MISMATCH: vty_out(vty, "BGP is already running; AS is %s\n", @@ -1591,7 +1593,7 @@ DEFUN_NOSH (router_bgp, * any pending VRF-VPN leaking that was configured via * earlier "router bgp X vrf FOO" blocks. */ - if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT) + if (bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT) vpn_leak_postchange_all(); if (inst_type == BGP_INSTANCE_TYPE_VRF || diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index c2254ae79..c45690a79 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3634,13 +3634,13 @@ struct bgp *bgp_lookup(as_t as, const char *name) } /* Lookup BGP structure by view name. */ -struct bgp *bgp_lookup_by_name(const char *name) +static struct bgp *bgp_lookup_by_name_filter(const char *name, bool filter_auto) { struct bgp *bgp; struct listnode *node, *nnode; for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { - if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) + if (filter_auto && CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) continue; if ((bgp->name == NULL && name == NULL) || (bgp->name && name && strcmp(bgp->name, name) == 0)) @@ -3649,6 +3649,11 @@ struct bgp *bgp_lookup_by_name(const char *name) return NULL; } +struct bgp *bgp_lookup_by_name(const char *name) +{ + return bgp_lookup_by_name_filter(name, true); +} + /* Lookup BGP instance based on VRF id. */ /* Note: Only to be used for incoming messages from Zebra. */ struct bgp *bgp_lookup_by_vrf_id(vrf_id_t vrf_id) @@ -3734,10 +3739,9 @@ int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id, return bgp_check_main_socket(create, bgp); } -int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, - const char *as_pretty, +int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *as_pretty, enum asnotation_mode asnotation, const char *name, - enum bgp_instance_type inst_type) + enum bgp_instance_type inst_type, bool force_config) { struct bgp *bgp; struct peer *peer = NULL; @@ -3746,7 +3750,7 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, /* Multiple instance check. */ if (name) - bgp = bgp_lookup_by_name(name); + bgp = bgp_lookup_by_name_filter(name, !force_config); else bgp = bgp_get_default(); @@ -3756,7 +3760,7 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, /* Handle AS number change */ if (bgp->as != *as) { if (hidden || CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) { - if (hidden) { + if (force_config == false && hidden) { bgp_create(as, name, inst_type, as_pretty, asnotation, bgp, hidden); @@ -3764,7 +3768,8 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, BGP_FLAG_INSTANCE_HIDDEN); } else { bgp->as = *as; - UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO); + if (force_config == false) + UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO); } /* Set all peer's local AS with this ASN */ @@ -3801,8 +3806,7 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, struct vrf *vrf = NULL; int ret = 0; - ret = bgp_lookup_by_as_name_type(bgp_val, as, as_pretty, asnotation, - name, inst_type); + ret = bgp_lookup_by_as_name_type(bgp_val, as, as_pretty, asnotation, name, inst_type, false); if (ret || *bgp_val) return ret; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index c72072852..9a1ac6cc7 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -2859,11 +2859,9 @@ extern struct peer *peer_new(struct bgp *bgp); extern struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, const char *ip_str, bool use_json); -extern int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, - const char *as_pretty, - enum asnotation_mode asnotation, - const char *name, - enum bgp_instance_type inst_type); +extern int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *as_pretty, + enum asnotation_mode asnotation, const char *name, + enum bgp_instance_type inst_type, bool force_config); /* Hooks */ DECLARE_HOOK(bgp_vrf_status_changed, (struct bgp *bgp, struct interface *ifp), -- cgit v1.2.3 From 3a921c6a1d32cdc082714b4337bcb3ac3486d5ec Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 9 Jan 2025 10:26:02 +0100 Subject: bgpd: fix import vrf creates multiple bgp instances The more the vrf green is referenced in the import bgp command, the more there are instances created. The below configuration shows that the vrf green is referenced twice, and two BGP instances of vrf green are created. The below configuration: > router bgp 99 > [..] > import vrf green > exit > router bgp 99 vrf blue > [..] > import vrf green > exit > router bgp 99 vrf green > [..] > exit > > r4# show bgp vrfs > Type Id routerId #PeersCfg #PeersEstb Name > L3-VNI RouterMAC Interface > DFLT 0 10.0.3.4 0 0 default > 0 00:00:00:00:00:00 unknown > VRF 5 10.0.40.4 0 0 blue > 0 00:00:00:00:00:00 unknown > VRF 6 0.0.0.0 0 0 green > 0 00:00:00:00:00:00 unknown > VRF 6 10.0.94.4 0 0 green > 0 00:00:00:00:00:00 unknown Fix this at import command, by looking at an already present bgp instance. Signed-off-by: Philippe Guibert --- bgpd/bgp_vty.c | 2 +- bgpd/bgpd.c | 2 +- bgpd/bgpd.h | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 8fefbeb49..3e71a8948 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -10561,7 +10561,7 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd, SET_FLAG(bgp_default->flags, BGP_FLAG_INSTANCE_HIDDEN); } - vrf_bgp = bgp_lookup_by_name(import_name); + vrf_bgp = bgp_lookup_by_name_filter(import_name, false); if (!vrf_bgp) { if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) { vrf_bgp = bgp_default; diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index c45690a79..d5463f3d0 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3634,7 +3634,7 @@ struct bgp *bgp_lookup(as_t as, const char *name) } /* Lookup BGP structure by view name. */ -static struct bgp *bgp_lookup_by_name_filter(const char *name, bool filter_auto) +struct bgp *bgp_lookup_by_name_filter(const char *name, bool filter_auto) { struct bgp *bgp; struct listnode *node, *nnode; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 9a1ac6cc7..96a78e666 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -2285,6 +2285,7 @@ extern void bgp_zclient_reset(void); extern struct bgp *bgp_get_default(void); extern struct bgp *bgp_lookup(as_t, const char *); extern struct bgp *bgp_lookup_by_name(const char *); +extern struct bgp *bgp_lookup_by_name_filter(const char *name, bool filter_auto); extern struct bgp *bgp_lookup_by_vrf_id(vrf_id_t); extern struct bgp *bgp_get_evpn(void); extern void bgp_set_evpn(struct bgp *bgp); -- cgit v1.2.3 From 25b6751d14900f3a3b6304f5c1292da6516dc119 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 9 Jan 2025 21:31:01 +0100 Subject: bgpd: fix static analyzer issues around bgp pointer Some static analyzer issues can be observed in BGP code: > In file included from ./lib/zebra.h:13, > from lib/event.c:8: > ./lib/compiler.h:222:26: note: '#pragma message: Remove `clear thread cpu` command' > 222 | #define CPP_NOTICE(text) _Pragma(CPP_STR(message text)) > | ^~~~~~~ > lib/event.c:433:1: note: in expansion of macro 'CPP_NOTICE' > 433 | CPP_NOTICE("Remove `clear thread cpu` command") > | ^~~~~~~~~~ > bgpd/bgp_vty.c:1592:5: warning: Access to field 'as_pretty' results in a dereference of a null pointer (loaded from variable 'bgp') [core.NullDereference] > 1592 | bgp->as_pretty); > | ^~~~~~~~~~~~~~ > bgpd/bgp_vty.c:1599:5: warning: Access to field 'as_pretty' results in a dereference of a null pointer (loaded from variable 'bgp') [core.NullDereference] > 1599 | bgp->as_pretty); > | ^~~~~~~~~~~~~~ > bgpd/bgp_vty.c:1612:7: warning: Access to field 'flags' results in a dereference of a null pointer (loaded from variable 'bgp') [core.NullDereference] > 1612 | IS_BGP_INSTANCE_HIDDEN(bgp)) { > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ > ./bgpd/bgpd.h:2906:3: note: expanded from macro 'IS_BGP_INSTANCE_HIDDEN' > 2906 | (CHECK_FLAG(_bgp->flags, BGP_FLAG_INSTANCE_HIDDEN) && \ > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ./lib/zebra.h:274:31: note: expanded from macro 'CHECK_FLAG' > 274 | #define CHECK_FLAG(V,F) ((V) & (F)) > | ^~~ > bgpd/bgp_vty.c:1614:4: warning: Access to field 'flags' results in a dereference of a null pointer (loaded from variable 'bgp') [core.NullDereference] > 1614 | UNSET_FLAG(bgp->flags, BGP_FLAG_INSTANCE_HIDDEN); > | ^ ~~~ > ./lib/zebra.h:276:34: note: expanded from macro 'UNSET_FLAG' > 276 | #define UNSET_FLAG(V,F) (V) &= ~(F) > | ~ ^ > 4 warnings generated. > Static Analysis warning summary compared to base: Fix those issues by protecting the bgp pointer. Signed-off-by: Philippe Guibert --- bgpd/bgp_vty.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 3e71a8948..2b3e11929 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1577,27 +1577,29 @@ DEFUN_NOSH (router_bgp, switch (ret) { case BGP_ERR_AS_MISMATCH: vty_out(vty, "BGP is already running; AS is %s\n", - bgp->as_pretty); + bgp ? bgp->as_pretty : "unknown"); return CMD_WARNING_CONFIG_FAILED; case BGP_ERR_INSTANCE_MISMATCH: vty_out(vty, "BGP instance name and AS number mismatch\n"); - vty_out(vty, - "BGP instance is already running; AS is %s\n", - bgp->as_pretty); + vty_out(vty, "BGP instance is already running; AS is %s\n", + bgp ? bgp->as_pretty : "unknown"); return CMD_WARNING_CONFIG_FAILED; } + if (!bgp) { + vty_out(vty, "BGP instance not found\n"); + return CMD_WARNING_CONFIG_FAILED; + } /* * If we just instantiated the default instance, complete * any pending VRF-VPN leaking that was configured via * earlier "router bgp X vrf FOO" blocks. */ - if (bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT) + if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) vpn_leak_postchange_all(); - if (inst_type == BGP_INSTANCE_TYPE_VRF || - IS_BGP_INSTANCE_HIDDEN(bgp)) { + if (inst_type == BGP_INSTANCE_TYPE_VRF || IS_BGP_INSTANCE_HIDDEN(bgp)) { bgp_vpn_leak_export(bgp); UNSET_FLAG(bgp->flags, BGP_FLAG_INSTANCE_HIDDEN); UNSET_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS); -- cgit v1.2.3