Commit bd5fe6ea17 for frr
commit bd5fe6ea17c9b15ecedf563c4c827e8e42fe28c1
Author: Philippe Guibert <philippe.guibert@6wind.com>
Date: Fri Aug 28 10:36:44 2026 +0200
topotests: bgp_srv6l3vpn_sid, add 'no srv6-only' tests at reception
There are no tests that control how the nexthops of imported L3VPN
prefixes are handled when dealing with MPLS/SRv6 coexistence. Add tests
for that.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
diff --git a/tests/topotests/bgp_srv6l3vpn_sid/r2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_sid/r2/bgpd.conf
index ce25e473fa..cf1d69fea6 100644
--- a/tests/topotests/bgp_srv6l3vpn_sid/r2/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_sid/r2/bgpd.conf
@@ -41,7 +41,6 @@ router bgp 2
!
segment-routing srv6
locator loc1
- no srv6-only
!
!
router bgp 2 vrf vrf10
diff --git a/tests/topotests/bgp_srv6l3vpn_sid/r2/vpnv6_rib_2001_8_mpls_srv6_localpref.json b/tests/topotests/bgp_srv6l3vpn_sid/r2/vpnv6_rib_2001_8_mpls_srv6_localpref.json
new file mode 100644
index 0000000000..45d42cace0
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_sid/r2/vpnv6_rib_2001_8_mpls_srv6_localpref.json
@@ -0,0 +1,85 @@
+{
+ "1:30":{
+ "prefix":"2001:8::/64",
+ "advertisedTo": {
+ "2001::1":{
+ }
+ },
+ "pathCount":2,
+ "paths":[
+ {
+ "aspath":{
+ "string":"1",
+ "length":1
+ },
+ "origin":"incomplete",
+ "metric":0,
+ "valid":true,
+ "extendedCommunity":{
+ "string":"RT:55:55"
+ },
+ "remoteLabel":48,
+ "remoteSid":"2002:db8:1:1::",
+ "remoteSidStructure":{
+ "locatorBlockLen":40,
+ "locatorNodeLen":24,
+ "functionLen":16,
+ "argumentLen":0,
+ "transpositionLen":16,
+ "transpositionOffset":64
+ },
+ "nexthops":[
+ {
+ "ip":"2001::1",
+ "hostname":"r1",
+ "afi":"ipv6",
+ "scope":"global",
+ "linkLocalOnly":false,
+ "length":48,
+ "metric":0,
+ "accessible":true,
+ "used":true
+ }
+ ],
+ "peer":{
+ "peerId":"2001::1",
+ "routerId":"192.0.2.1"
+ }
+ },
+ {
+ "aspath":{
+ "string":"1",
+ "length":1
+ },
+ "origin":"incomplete",
+ "metric":0,
+ "locPrf":250,
+ "valid":true,
+ "bestpath": {
+ "selectionReason":"Local Pref"
+ },
+ "extendedCommunity":{
+ "string":"RT:55:55"
+ },
+ "remoteLabel":16,
+ "nexthops":[
+ {
+ "ip":"2001::1",
+ "hostname":"r1",
+ "afi":"ipv6",
+ "scope":"global",
+ "linkLocalOnly":false,
+ "length":48,
+ "metric":0,
+ "accessible":true,
+ "used":true
+ }
+ ],
+ "peer":{
+ "peerId":"2001::1",
+ "routerId":"192.0.2.1"
+ }
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_sid/r2/vrf20_ipv6_2001_8_both_mpls_selected.json b/tests/topotests/bgp_srv6l3vpn_sid/r2/vrf20_ipv6_2001_8_both_mpls_selected.json
new file mode 100644
index 0000000000..ab620237e4
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_sid/r2/vrf20_ipv6_2001_8_both_mpls_selected.json
@@ -0,0 +1,71 @@
+{
+ "prefix":"2001:8::/64",
+ "pathCount":2,
+ "paths":[
+ {
+ "importedFrom":"1:30",
+ "aspath":{
+ "string":"1",
+ "length":1
+ },
+ "origin":"incomplete",
+ "metric":0,
+ "valid":true,
+ "extendedCommunity":{
+ "string":"RT:55:55"
+ },
+ "remoteLabel":48,
+ "remoteSid":"2002:db8:1:1::",
+ "remoteSidStructure":{
+ "locatorBlockLen":40,
+ "locatorNodeLen":24,
+ "functionLen":16,
+ "argumentLen":0,
+ "transpositionLen":16,
+ "transpositionOffset":64
+ },
+ "nexthops":[
+ {
+ "ip":"2001::1",
+ "afi":"ipv6",
+ "scope":"global",
+ "linkLocalOnly":false,
+ "length":48,
+ "metric":0,
+ "accessible":true,
+ "used":true
+ }
+ ]
+ },
+ {
+ "importedFrom":"1:30",
+ "aspath":{
+ "string":"1",
+ "length":1
+ },
+ "origin":"incomplete",
+ "metric":0,
+ "locPrf":250,
+ "valid":true,
+ "bestpath": {
+ "overall": true
+ },
+ "extendedCommunity":{
+ "string":"RT:55:55"
+ },
+ "remoteLabel":16,
+ "nexthops":[
+ {
+ "ip":"2001::1",
+ "afi":"ipv6",
+ "scope":"global",
+ "linkLocalOnly":false,
+ "length":48,
+ "metric":0,
+ "accessible":true,
+ "used":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_sid/r2/vrf20_ipv6_2001_8_both_srv6_selected.json b/tests/topotests/bgp_srv6l3vpn_sid/r2/vrf20_ipv6_2001_8_both_srv6_selected.json
new file mode 100644
index 0000000000..6628710f81
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_sid/r2/vrf20_ipv6_2001_8_both_srv6_selected.json
@@ -0,0 +1,71 @@
+{
+ "prefix":"2001:8::/64",
+ "pathCount":2,
+ "paths":[
+ {
+ "importedFrom":"1:30",
+ "aspath":{
+ "string":"1",
+ "length":1
+ },
+ "origin":"incomplete",
+ "metric":0,
+ "valid":true,
+ "bestpath": {
+ "overall": true
+ },
+ "extendedCommunity":{
+ "string":"RT:55:55"
+ },
+ "remoteLabel":48,
+ "remoteSid":"2002:db8:1:1::",
+ "remoteSidStructure":{
+ "locatorBlockLen":40,
+ "locatorNodeLen":24,
+ "functionLen":16,
+ "argumentLen":0,
+ "transpositionLen":16,
+ "transpositionOffset":64
+ },
+ "nexthops":[
+ {
+ "ip":"2001::1",
+ "afi":"ipv6",
+ "scope":"global",
+ "linkLocalOnly":false,
+ "length":48,
+ "metric":0,
+ "accessible":true,
+ "used":true
+ }
+ ]
+ },
+ {
+ "importedFrom":"1:30",
+ "aspath":{
+ "string":"1",
+ "length":1
+ },
+ "origin":"incomplete",
+ "metric":0,
+ "locPrf":250,
+ "valid":false,
+ "extendedCommunity":{
+ "string":"RT:55:55"
+ },
+ "remoteLabel":16,
+ "nexthops":[
+ {
+ "ip":"2001::1",
+ "afi":"ipv6",
+ "scope":"global",
+ "linkLocalOnly":false,
+ "length":48,
+ "metric":0,
+ "accessible":true,
+ "used":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_sid/test_bgp_srv6l3vpn_sid.py b/tests/topotests/bgp_srv6l3vpn_sid/test_bgp_srv6l3vpn_sid.py
index c1cde8fadf..83be4d7dfe 100755
--- a/tests/topotests/bgp_srv6l3vpn_sid/test_bgp_srv6l3vpn_sid.py
+++ b/tests/topotests/bgp_srv6l3vpn_sid/test_bgp_srv6l3vpn_sid.py
@@ -677,6 +677,125 @@ def test_sid_add_vrf_30_readd_srv6_keep_mpls():
)
+def test_sid_add_peer_srv6_check_both_entries_received():
+ """
+ Configure peer 2001::2 with addpath
+ Test that both SRv6 and MPLS prefixes are sent to r2
+ """
+ get_topogen().gears["r1"].vtysh_cmd(
+ """
+ configure terminal
+ router bgp 1
+ address-family ipv6 vpn
+ neighbor 2001::2 addpath-tx-all-paths
+ exit-address-family
+ """
+ )
+ check_rib(
+ "r2", "show bgp ipv6 vpn 2001:8::/64 json", "r2/vpnv6_rib_2001_8_mpls_srv6.json"
+ )
+
+
+def test_sid_r2_add_route_map_to_priorize_mpls_entry():
+ """
+ Configure a route-map on r2 so that bestpath in VPN is the MPLS VPN update
+ Test that MPLS prefix is bestpath
+ """
+ get_topogen().gears["r2"].vtysh_cmd(
+ """
+ configure terminal
+ bgp route-map delay-timer 5
+ route-map rmap permit 10
+ match vpn dataplane mpls
+ set local-preference 250
+ exit
+ route-map rmap permit 20
+ exit
+ router bgp 2
+ address-family ipv6 vpn
+ neighbor 2001::1 route-map rmap in
+ exit-address-family
+ """
+ )
+ check_rib(
+ "r2",
+ "show bgp ipv6 vpn 2001:8::/64 json",
+ "r2/vpnv6_rib_2001_8_mpls_srv6_localpref.json",
+ )
+
+
+def test_sid_add_peer_srv6_check_srv6_entry_selected_on_vrf():
+ """
+ Configure vrf20 so that 2001:8::/64 is imported.
+ Test that on vrf20, only srv6 received prefix is selected.
+ """
+
+ get_topogen().gears["r2"].vtysh_cmd(
+ """
+ configure terminal
+ router bgp 2 vrf vrf20
+ address-family ipv6 unicast
+ rt vpn both 88:88 55:55
+ exit
+ """
+ )
+ logger.info("On r2, check that the SRv6 prefix 2001:8::/64 is selected in vrf20")
+ check_rib(
+ "r2",
+ "show bgp vrf vrf20 ipv6 2001:8::/64 json",
+ "r2/vrf20_ipv6_2001_8_both_srv6_selected.json",
+ )
+
+
+def test_sid_add_peer_no_srv6_only():
+ """
+ Configure no srv6-only on r2 default VRF
+ Test that on vrf20, that MPLS prefix 2001:8::/64 is imported
+ """
+
+ get_topogen().gears["r2"].vtysh_cmd(
+ """
+ configure terminal
+ router bgp 2
+ segment-routing srv6
+ no srv6-only
+ exit
+ exit
+ """
+ )
+
+ logger.info("On r2, flush BGP sessions to force re-run best path over 2001:8::/64")
+ get_topogen().gears["r2"].vtysh_cmd("clear bgp ipv6 vpn *")
+
+ logger.info("On r2, check that the MPLS prefix 2001:8::/64 is selected in vrf20")
+ check_rib(
+ "r2",
+ "show bgp vrf vrf20 ipv6 2001:8::/64 json",
+ "r2/vrf20_ipv6_2001_8_both_mpls_selected.json",
+ )
+
+
+def test_sid_r2_del_route_map_to_depriorize_mpls_entry():
+ """
+ Unconfigure the r2 route-map initially used to priorize mpls entry
+ Test that both SRv6 and MPLS VPN prefixes are received.
+ """
+ get_topogen().gears["r2"].vtysh_cmd(
+ """
+ configure terminal
+ router bgp 2
+ address-family ipv6 vpn
+ no neighbor 2001::1 route-map rmap in
+ exit-address-family
+ exit
+ no route-map rmap
+ """
+ )
+ check_rib(
+ "r2", "show bgp ipv6 vpn 2001:8::/64 json", "r2/vpnv6_rib_2001_8_mpls_srv6.json"
+ )
+
+
def test_sid_add_peer_srv6_filtered():
"""
Configure peer 2001::2 with encapsulation-srv6
@@ -687,7 +806,6 @@ def test_sid_add_peer_srv6_filtered():
configure terminal
router bgp 1
address-family ipv6 vpn
- neighbor 2001::2 addpath-tx-all-paths
neighbor 2001::2 encapsulation-srv6
exit-address-family
"""
@@ -1007,7 +1125,6 @@ def test_sid_configure_r2_listener_as_srv6_and_mpls_again():
router bgp 2 vrf vrf20
address-family ipv6 unicast
label vpn export auto
- rt vpn both 55:55 88:88
exit-address-family
exit
router bgp 2