+++ /dev/null
-{
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:61",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:101:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:61",
- "ipLen":32,
- "ip":"50.0.1.11",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:101:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:61",
- "ipLen":128,
- "ip":"50:0:1::11",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:101:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:62",
- "weight":0,
- "peerId":"10.0.1.2",
- "path":"102",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"RT:102:100 ET:8"
- },
- "nexthops":[
- {
- "ip":"10.100.0.2",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[3]:[0]:[32]:[10.100.0.1]":{
- "prefix":"[3]:[0]:[32]:[10.100.0.1]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":3,
- "ethTag":0,
- "ipLen":32,
- "ip":"10.100.0.1",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:101:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[3]:[0]:[32]:[10.100.0.2]":{
- "prefix":"[3]:[0]:[32]:[10.100.0.2]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":3,
- "ethTag":0,
- "ipLen":32,
- "ip":"10.100.0.2",
- "weight":0,
- "peerId":"10.0.1.2",
- "path":"102",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"RT:102:100 ET:8"
- },
- "nexthops":[
- {
- "ip":"10.100.0.2",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]": null,
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]": null,
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]": null,
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]": null,
- "[3]:[0]:[32]:[10.100.0.1]": null,
- "[3]:[0]:[32]:[10.100.0.2]": null
-}
\ No newline at end of file
+++ /dev/null
-{
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:61",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:101:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:61",
- "ipLen":32,
- "ip":"50.0.1.11",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:101:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:61",
- "ipLen":128,
- "ip":"50:0:1::11",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:101:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:62",
- "weight":0,
- "peerId":"10.0.1.2",
- "path":"102",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"RT:102:100 ET:8"
- },
- "nexthops":[
- {
- "ip":"10.100.0.2",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[3]:[0]:[32]:[10.100.0.1]":{
- "prefix":"[3]:[0]:[32]:[10.100.0.1]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":3,
- "ethTag":0,
- "ipLen":32,
- "ip":"10.100.0.1",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:101:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[3]:[0]:[32]:[10.100.0.2]":{
- "prefix":"[3]:[0]:[32]:[10.100.0.2]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":3,
- "ethTag":0,
- "ipLen":32,
- "ip":"10.100.0.2",
- "weight":0,
- "peerId":"10.0.1.2",
- "path":"102",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"RT:102:100 ET:8"
- },
- "nexthops":[
- {
- "ip":"10.100.0.2",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "vrfName": "vrf-blue",
- "routerId": "10.100.0.1",
- "defaultLocPrf": 100,
- "localAS": 101,
- "routes": { "100.0.0.21/32": [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "prefix":"100.0.0.21",
- "prefixLen":32,
- "network":"100.0.0.21\/32",
- "metric":0,
- "weight":0,
- "peerId":"50.0.1.11",
- "path":"111",
- "origin":"IGP",
- "nexthops":[
- {
- "ip":"50.0.1.11",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
-] } }
\ No newline at end of file
+++ /dev/null
-{
- "vrfName": "vrf-blue",
- "routerId": "10.100.0.1",
- "defaultLocPrf": 100,
- "localAS": 101,
- "routes": { "100.0.0.21/32": [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "prefix":"100.0.0.21",
- "prefixLen":32,
- "network":"100.0.0.21\/32",
- "metric":0,
- "weight":0,
- "peerId":"50.0.1.11",
- "path":"111",
- "origin":"IGP",
- "nexthops":[
- {
- "ip":"50.0.1.11",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
-] } }
\ No newline at end of file
+++ /dev/null
-{
- "vrfName": "vrf-blue",
- "routerId": "10.100.0.1",
- "defaultLocPrf": 100,
- "localAS": 101,
- "routes": { "100.0.0.21/32": null } }
+++ /dev/null
-{
- "vrfName": "vrf-blue",
- "routerId": "10.100.0.1",
- "defaultLocPrf": 100,
- "localAS": 101,
- "routes": { "100::21/128": [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "prefix":"100::21",
- "prefixLen":128,
- "network":"100::21\/128",
- "metric":0,
- "weight":0,
- "peerId":"50:0:1::11",
- "path":"111",
- "origin":"IGP",
- "nexthops":[
- {
- "ip":"50:0:1::11",
- "afi":"ipv6",
- "scope":"global"
- }
- ]
- }
-] } }
+++ /dev/null
-{
- "vrfName": "vrf-blue",
- "routerId": "10.100.0.1",
- "defaultLocPrf": 100,
- "localAS": 101,
- "routes": { "100::21/128": [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "prefix":"100::21",
- "prefixLen":128,
- "network":"100::21\/128",
- "metric":0,
- "weight":0,
- "peerId":"50:0:1::11",
- "path":"111",
- "origin":"IGP",
- "nexthops":[
- {
- "ip":"50:0:1::11",
- "afi":"ipv6",
- "scope":"global"
- }
- ]
- }
-] } }
+++ /dev/null
-{
- "vrfName": "vrf-blue",
- "routerId": "10.100.0.1",
- "defaultLocPrf": 100,
- "localAS": 101,
- "routes": { "100::21/128": null } }
\ No newline at end of file
+++ /dev/null
-router bgp 101
- bgp router-id 10.100.0.1
- no bgp ebgp-requires-policy
- no bgp network import-check
- neighbor 10.0.1.2 remote-as 102
- !
- address-family l2vpn evpn
- neighbor 10.0.1.2 activate
- advertise-all-vni
- exit-address-family
-!
-router bgp 101 vrf vrf-blue
- bgp router-id 10.100.0.1
- no bgp ebgp-requires-policy
- no bgp network import-check
- neighbor 50.0.1.11 remote-as 111
- neighbor 50:0:1::11 remote-as 111
- !
- address-family ipv4 unicast
- no neighbor 50:0:1::11 activate
- exit-address-family
- !
- address-family ipv6 unicast
- neighbor 50:0:1::11 activate
- exit-address-family
- !
- address-family l2vpn evpn
- advertise ipv4 unicast gateway-ip
- advertise ipv6 unicast gateway-ip
- exit-address-family
\ No newline at end of file
+++ /dev/null
-!
-log file zebra.log
-!
-ip route 10.100.0.2/32 10.0.1.2
-!
-vrf vrf-blue
- vni 1000 prefix-routes-only
- exit-vrf
-!
-interface lo
- ip address 10.100.0.1/32
-interface PE1-eth0
- ip address 10.0.1.1/24
-!
+++ /dev/null
-{
- "50.0.1.0\/24":[
- {
- "prefix":"50.0.1.0\/24",
- "protocol":"connected",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":0,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "directlyConnected":true,
- "interfaceName":"br100",
- "active":true
- }
- ]
- }
- ],
- "100.0.0.21\/32":[
- {
- "prefix":"100.0.0.21\/32",
- "protocol":"bgp",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":20,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"50.0.1.11",
- "afi":"ipv4",
- "interfaceName":"br100",
- "active":true,
- "weight":1
- }
- ]
- }
- ]
-}
+++ /dev/null
-{
- "50.0.1.0\/24":[
- {
- "prefix":"50.0.1.0\/24",
- "protocol":"connected",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":0,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "directlyConnected":true,
- "interfaceName":"br100",
- "active":true
- }
- ]
- }
- ],
- "100.0.0.21\/32":[
- {
- "prefix":"100.0.0.21\/32",
- "protocol":"bgp",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":20,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"50.0.1.11",
- "afi":"ipv4",
- "interfaceName":"br100",
- "active":true,
- "weight":1
- }
- ]
- }
- ]
-}
+++ /dev/null
-{
- "50.0.1.0\/24":[
- {
- "prefix":"50.0.1.0\/24",
- "protocol":"connected",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":0,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "directlyConnected":true,
- "interfaceName":"br100",
- "active":true
- }
- ]
- }
- ],
- "100.0.0.21\/32": null
-}
+++ /dev/null
-{
- "50:0:1::\/48":[
- {
- "prefix":"50:0:1::\/48",
- "protocol":"connected",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":0,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "directlyConnected":true,
- "interfaceName":"br100",
- "active":true
- }
- ]
- }
- ],
- "100::21\/128":[
- {
- "prefix":"100::21\/128",
- "protocol":"bgp",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":20,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"br100",
- "active":true,
- "weight":1
- }
- ]
- }
- ]
-}
\ No newline at end of file
+++ /dev/null
-{
- "50:0:1::\/48":[
- {
- "prefix":"50:0:1::\/48",
- "protocol":"connected",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":0,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "directlyConnected":true,
- "interfaceName":"br100",
- "active":true
- }
- ]
- }
- ],
- "100::21\/128":[
- {
- "prefix":"100::21\/128",
- "protocol":"bgp",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":20,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"br100",
- "active":true,
- "weight":1
- }
- ]
- }
- ]
-}
\ No newline at end of file
+++ /dev/null
-{
- "50:0:1::\/48":[
- {
- "prefix":"50:0:1::\/48",
- "protocol":"connected",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":0,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "directlyConnected":true,
- "interfaceName":"br100",
- "active":true
- }
- ]
- }
- ],
- "100::21\/128": null
-}
\ No newline at end of file
+++ /dev/null
-{
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:61",
- "weight":0,
- "peerId":"10.0.1.1",
- "path":"101",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"RT:101:100 ET:8"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:61",
- "ipLen":32,
- "ip":"50.0.1.11",
- "weight":0,
- "peerId":"10.0.1.1",
- "path":"101",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"RT:101:100 ET:8"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:61",
- "ipLen":128,
- "ip":"50:0:1::11",
- "weight":0,
- "peerId":"10.0.1.1",
- "path":"101",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"RT:101:100 ET:8"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:62",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:102:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.2",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[3]:[0]:[32]:[10.100.0.1]":{
- "prefix":"[3]:[0]:[32]:[10.100.0.1]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":3,
- "ethTag":0,
- "ipLen":32,
- "ip":"10.100.0.1",
- "weight":0,
- "peerId":"10.0.1.1",
- "path":"101",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"RT:101:100 ET:8"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[3]:[0]:[32]:[10.100.0.2]":{
- "prefix":"[3]:[0]:[32]:[10.100.0.2]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":3,
- "ethTag":0,
- "ipLen":32,
- "ip":"10.100.0.2",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:102:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.2",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]": null,
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]": null,
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]": null,
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:62",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:102:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.2",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[3]:[0]:[32]:[10.100.0.1]": null,
- "[3]:[0]:[32]:[10.100.0.2]":{
- "prefix":"[3]:[0]:[32]:[10.100.0.2]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":3,
- "ethTag":0,
- "ipLen":32,
- "ip":"10.100.0.2",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:102:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.2",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:61",
- "weight":0,
- "peerId":"10.0.1.1",
- "path":"101",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"RT:101:100 ET:8"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:61",
- "ipLen":32,
- "ip":"50.0.1.11",
- "weight":0,
- "peerId":"10.0.1.1",
- "path":"101",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"RT:101:100 ET:8"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:61",
- "ipLen":128,
- "ip":"50:0:1::11",
- "weight":0,
- "peerId":"10.0.1.1",
- "path":"101",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"RT:101:100 ET:8"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]":{
- "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":2,
- "ethTag":0,
- "macLen":48,
- "mac":"1a:2b:3c:4d:5e:62",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:102:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.2",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[3]:[0]:[32]:[10.100.0.1]":{
- "prefix":"[3]:[0]:[32]:[10.100.0.1]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":3,
- "ethTag":0,
- "ipLen":32,
- "ip":"10.100.0.1",
- "weight":0,
- "peerId":"10.0.1.1",
- "path":"101",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"RT:101:100 ET:8"
- },
- "nexthops":[
- {
- "ip":"10.100.0.1",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- },
- "[3]:[0]:[32]:[10.100.0.2]":{
- "prefix":"[3]:[0]:[32]:[10.100.0.2]",
- "prefixLen":320,
- "paths":[
- [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "routeType":3,
- "ethTag":0,
- "ipLen":32,
- "ip":"10.100.0.2",
- "weight":32768,
- "peerId":"(unspec)",
- "path":"",
- "origin":"IGP",
- "extendedCommunity":{
- "string":"ET:8 RT:102:100"
- },
- "nexthops":[
- {
- "ip":"10.100.0.2",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
- ]
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "vrfName": "vrf-blue",
- "routerId": "10.100.0.2",
- "defaultLocPrf": 100,
- "localAS": 101,
- "routes": { "100.0.0.21/32": [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "prefix":"100.0.0.21",
- "prefixLen":32,
- "network":"100.0.0.21\/32",
- "metric":0,
- "weight":0,
- "peerId":"10.0.1.1",
- "path":"101 111",
- "origin":"IGP",
- "nexthops":[
- {
- "ip":"50.0.1.11",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
-] } }
\ No newline at end of file
+++ /dev/null
-{
- "vrfName": "vrf-blue",
- "routerId": "10.100.0.2",
- "defaultLocPrf": 100,
- "localAS": 101,
- "routes": { "100.0.0.21/32": [
- {
- "valid":null,
- "bestpath":null,
- "pathFrom":"external",
- "prefix":"100.0.0.21",
- "prefixLen":32,
- "network":"100.0.0.21\/32",
- "metric":0,
- "weight":0,
- "peerId":"10.0.1.1",
- "path":"101 111",
- "origin":"IGP",
- "nexthops":[
- {
- "ip":"50.0.1.11",
- "afi":"ipv4",
- "used":true
- }
- ]
- }
-] } }
+++ /dev/null
-{
- "vrfName": "vrf-blue",
- "routerId": "10.100.0.2",
- "defaultLocPrf": 100,
- "localAS": 101,
- "routes": { "100.0.0.21/32": null } }
\ No newline at end of file
+++ /dev/null
-{
- "vrfName": "vrf-blue",
- "routerId": "10.100.0.2",
- "defaultLocPrf": 100,
- "localAS": 101,
- "routes": { "100::21/128": [
- {
- "valid":true,
- "bestpath":true,
- "pathFrom":"external",
- "prefix":"100::21",
- "prefixLen":128,
- "network":"100::21\/128",
- "metric":0,
- "weight":0,
- "peerId":"10.0.1.1",
- "path":"101 111",
- "origin":"IGP",
- "nexthops":[
- {
- "ip":"50:0:1::11",
- "afi":"ipv6",
- "scope":"global",
- "used":true
- }
- ]
- }
-] } }
\ No newline at end of file
+++ /dev/null
-{
- "vrfName": "vrf-blue",
- "routerId": "10.100.0.2",
- "defaultLocPrf": 100,
- "localAS": 101,
- "routes": { "100::21/128": [
- {
- "valid":null,
- "bestpath":null,
- "pathFrom":"external",
- "prefix":"100::21",
- "prefixLen":128,
- "network":"100::21\/128",
- "metric":0,
- "weight":0,
- "peerId":"10.0.1.1",
- "path":"101 111",
- "origin":"IGP",
- "nexthops":[
- {
- "ip":"50:0:1::11",
- "afi":"ipv6",
- "scope":"global",
- "used":true
- }
- ]
- }
-] } }
+++ /dev/null
-{
- "vrfName": "vrf-blue",
- "routerId": "10.100.0.2",
- "defaultLocPrf": 100,
- "localAS": 101,
- "routes": { "100::21/128": null } }
\ No newline at end of file
+++ /dev/null
-router bgp 102
- bgp router-id 10.100.0.2
- no bgp ebgp-requires-policy
- no bgp network import-check
- neighbor 10.0.1.1 remote-as 101
- !
- address-family l2vpn evpn
- neighbor 10.0.1.1 activate
- advertise-all-vni
- enable-resolve-overlay-index
- exit-address-family
-!
-router bgp 101 vrf vrf-blue
- bgp router-id 10.100.0.2
+++ /dev/null
-!
-log file zebra.log
-!
-ip route 10.100.0.1/32 10.0.1.1
-!
-vrf vrf-blue
- vni 1000 prefix-routes-only
- exit-vrf
-!
-interface lo
- ip address 10.100.0.2/32
-interface PE2-eth0
- ip address 10.0.1.2/24
-!
+++ /dev/null
-{
- "50.0.1.0\/24":[
- {
- "prefix":"50.0.1.0\/24",
- "protocol":"connected",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":0,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "directlyConnected":true,
- "interfaceName":"br100",
- "active":true
- }
- ]
- }
- ],
- "100.0.0.21\/32":[
- {
- "prefix":"100.0.0.21\/32",
- "protocol":"bgp",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":20,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":40,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"50.0.1.11",
- "afi":"ipv4",
- "interfaceName":"br100",
- "active":true,
- "weight":1
- }
- ]
- }
- ]
-}
\ No newline at end of file
+++ /dev/null
-{
- "50.0.1.0\/24":[
- {
- "prefix":"50.0.1.0\/24",
- "protocol":"connected",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":0,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "directlyConnected":true,
- "interfaceName":"br100",
- "active":true
- }
- ]
- }
- ],
- "100.0.0.21\/32": null
-}
\ No newline at end of file
+++ /dev/null
-{
- "50.0.1.0\/24":[
- {
- "prefix":"50.0.1.0\/24",
- "protocol":"connected",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":0,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "directlyConnected":true,
- "interfaceName":"br100",
- "active":true
- }
- ]
- }
- ],
- "100.0.0.21\/32": null
-}
\ No newline at end of file
+++ /dev/null
-{
- "50:0:1::\/48":[
- {
- "prefix":"50:0:1::\/48",
- "protocol":"connected",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":0,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "directlyConnected":true,
- "interfaceName":"br100",
- "active":true
- }
- ]
- }
- ],
- "100::21\/128":[
- {
- "prefix":"100::21\/128",
- "protocol":"bgp",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":20,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":40,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"50:0:1::11",
- "afi":"ipv6",
- "interfaceName":"br100",
- "active":true,
- "weight":1
- }
- ]
- }
- ]
-}
\ No newline at end of file
+++ /dev/null
-{
- "50:0:1::\/48":[
- {
- "prefix":"50:0:1::\/48",
- "protocol":"connected",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":0,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "directlyConnected":true,
- "interfaceName":"br100",
- "active":true
- }
- ]
- }
- ],
- "100::21\/128": null
-}
\ No newline at end of file
+++ /dev/null
-{
- "50:0:1::\/48":[
- {
- "prefix":"50:0:1::\/48",
- "protocol":"connected",
- "vrfName":"vrf-blue",
- "selected":true,
- "destSelected":true,
- "distance":0,
- "metric":0,
- "installed":true,
- "table":10,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "directlyConnected":true,
- "interfaceName":"br100",
- "active":true
- }
- ]
- }
- ],
- "100::21\/128": null
-}
\ No newline at end of file
+++ /dev/null
-router bgp 111
- bgp router-id 10.100.0.11
- no bgp ebgp-requires-policy
- no bgp network import-check
- neighbor 50.0.1.1 remote-as 101
- neighbor 50:0:1::1 remote-as 101
- !
- address-family ipv4 unicast
- network 100.0.0.21/32
- no neighbor 50:0:1::1 activate
- exit-address-family
- !
- address-family ipv6 unicast
- network 100::21/128
- neighbor 50:0:1::1 activate
- exit-address-family
-
-
+++ /dev/null
-!
-int host1-eth0
- ip address 50.0.1.11/24
- ipv6 address 50:0:1::11/48
+++ /dev/null
-!
-int host1-eth0
- ip address 50.0.1.21/24
- ipv6 address 50:0:1::21/48
+++ /dev/null
-#!/usr/bin/env python
-#
-# Copyright (c) 2020 by VMware, Inc. ("VMware")
-# Used Copyright (c) 2018 by Network Device Education Foundation, Inc. ("NetDEF")
-# in this file.
-#
-# Permission to use, copy, modify, and/or distribute this software
-# for any purpose with or without fee is hereby granted, provided
-# that the above copyright notice and this permission notice appear
-# in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
-# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-# OF THIS SOFTWARE.
-#
-
-"""
-test_bgp_evpn_overlay_index_gateway.py: Test EVPN gateway IP overlay index functionality
-Following functionality is covered:
-
- +--------+ BGP +--------+ BGP +--------+ +--------+
- SN1 | | IPv4/v6 | | EVPN | | | |
- ======+ Host1 +---------+ PE1 +------+ PE2 +------+ Host2 +
- | | | | | | | |
- +--------+ +--------+ +--------+ +--------+
-
- Host1 is connected to PE1 and host2 is connected to PE2
- Host1 and PE1 have IPv4/v6 BGP sessions.
- PE1 and PE2 gave EVPN session.
- Host1 advertises IPv4/v6 prefixes to PE1.
- PE1 advertises these prefixes to PE2 as EVPN type-5 routes.
- Gateway IP for these EVPN type-5 routes is host1 IP.
- Host1 MAC/IP is advertised by PE1 as EVPN type-2 route
-
-Following testcases are covered:
-TC_1:
-Check BGP and zebra states for above topology at PE1 and PE2.
-
-TC_2:
-Stop advertising prefixes from host1. It should withdraw type-5 routes. Check states at PE1 and PE2
-Advertise the prefixes again. Check states.
-
-TC_3:
-Shut down VxLAN interface at PE1. This should withdraw type-2 routes. Check states at PE1 and PE2.
-Enable VxLAN interface again. Check states.
-"""
-
-import os
-import sys
-import json
-from functools import partial
-import pytest
-import time
-import platform
-
-#Current Working Directory
-CWD = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(CWD, "../"))
-
-# pylint: disable=C0413
-# Import topogen and topotest helpers
-from lib import topotest
-from lib.topogen import Topogen, TopoRouter, get_topogen
-from lib.topolog import logger
-from lib.common_config import (
- step,
- write_test_header,
- write_test_footer,
- generate_support_bundle,
-)
-
-# Required to instantiate the topology builder class.
-from mininet.topo import Topo
-
-pytestmark = [pytest.mark.bgpd]
-
-
-#Global variables
-PES = ['PE1', 'PE2']
-HOSTS = ['host1', 'host2']
-PE_SUFFIX = {'PE1': '1', 'PE2': '2'}
-HOST_SUFFIX = {'host1': '1', 'host2': '2'}
-TRIGGERS = ["base", "no_rt5", "no_rt2"]
-
-
-class TemplateTopo(Topo):
- """Test topology builder"""
-
- def build(self, *_args, **_opts):
- """Build function"""
- tgen = get_topogen(self)
-
- # This function only purpose is to define allocation and relationship
- # between routers and add links.
-
- # Create routers
- for pe in PES:
- tgen.add_router(pe)
- for host in HOSTS:
- tgen.add_router(host)
-
- krel = platform.release()
- logger.info('Kernel version ' + krel)
-
- #Add links
- tgen.add_link(tgen.gears['PE1'], tgen.gears['PE2'], 'PE1-eth0', 'PE2-eth0')
- tgen.add_link(tgen.gears['PE1'], tgen.gears['host1'], 'PE1-eth1', 'host1-eth0')
- tgen.add_link(tgen.gears['PE2'], tgen.gears['host2'], 'PE2-eth1', 'host2-eth0')
-
-
-def setup_module(mod):
- "Sets up the pytest environment"
-
- testsuite_run_time = time.asctime(time.localtime(time.time()))
- logger.info("Testsuite start time: {}".format(testsuite_run_time))
- logger.info("=" * 40)
-
- logger.info("Running setup_module to create topology")
-
- # This function initiates the topology build with Topogen...
- tgen = Topogen(TemplateTopo, mod.__name__)
- # ... and here it calls Mininet initialization functions.
-
- kernelv = platform.release()
- if topotest.version_cmp(kernelv, "4.15") < 0:
- logger.info("For EVPN, kernel version should be minimum 4.15. Kernel present {}".format(kernelv))
- return
-
- if topotest.version_cmp(kernelv, '4.15') == 0:
- l3mdev_accept = 1
- logger.info('setting net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept))
- else:
- l3mdev_accept = 0
-
- # Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
- tgen.start_topology()
-
- # Configure MAC address for hosts as these MACs are advertised with EVPN type-2 routes
- for (name, host) in tgen.gears.items():
- if name not in HOSTS:
- continue
-
- host_mac = "1a:2b:3c:4d:5e:6{}".format(HOST_SUFFIX[name])
- host.run("ip link set dev {}-eth0 down").format(name)
- host.run("ip link set dev {0}-eth0 address {1}".format(name, host_mac))
- host.run("ip link set dev {}-eth0 up").format(name)
-
- # Configure PE VxLAN and Bridge interfaces
- for (name, pe) in tgen.gears.items():
- if name not in PES:
- continue
- vtep_ip = "10.100.0.{}".format(PE_SUFFIX[name])
- bridge_ip = "50.0.1.{}/24".format(PE_SUFFIX[name])
- bridge_ipv6 = "50:0:1::{}/48".format(PE_SUFFIX[name])
-
- pe.run("ip link add vrf-blue type vrf table 10")
- pe.run("ip link set dev vrf-blue up")
- pe.run("ip link add vxlan100 type vxlan id 100 dstport 4789 local {}".format(vtep_ip))
- pe.run("ip link add name br100 type bridge stp_state 0")
- pe.run("ip link set dev vxlan100 master br100")
- pe.run("ip link set dev {}-eth1 master br100".format(name))
- pe.run("ip addr add {} dev br100".format(bridge_ip))
- pe.run("ip link set up dev br100")
- pe.run("ip link set up dev vxlan100")
- pe.run("ip link set up dev {}-eth1".format(name))
- pe.run("ip link set dev br100 master vrf-blue")
- pe.run("ip -6 addr add {} dev br100".format(bridge_ipv6))
-
- pe.run("ip link add vxlan1000 type vxlan id 1000 dstport 4789 local {}".format(vtep_ip))
- pe.run("ip link add name br1000 type bridge stp_state 0")
- pe.run("ip link set dev vxlan1000 master br100")
- pe.run("ip link set up dev br1000")
- pe.run("ip link set up dev vxlan1000")
- pe.run("ip link set dev br1000 master vrf-blue")
-
- pe.run("sysctl -w net.ipv4.ip_forward=1")
- pe.run("sysctl -w net.ipv6.conf.all.forwarding=1")
- pe.run("sysctl -w net.ipv4.udp_l3mdev_accept={}".format(l3mdev_accept))
- pe.run("sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept))
-
- # For all registred routers, load the zebra configuration file
- for (name, router) in tgen.routers().items():
- router.load_config(
- TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(name))
- )
- router.load_config(
- TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(name))
- )
-
- # After loading the configurations, this function loads configured daemons.
- tgen.start_router()
-
- logger.info("Running setup_module() done")
-
-
-def teardown_module(mod):
- """Teardown the pytest environment"""
-
- logger.info("Running teardown_module to delete topology")
-
- tgen = get_topogen()
-
- # Stop toplogy and Remove tmp files
- tgen.stop_topology()
-
- logger.info(
- "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
- )
- logger.info("=" * 40)
-
-
-def evpn_gateway_ip_show_op_check(trigger=" "):
- """
- This function checks CLI O/P for commands mentioned in show_commands for a given trigger
- :param trigger: Should be a trigger present in TRIGGERS
- :return: Returns a tuple (result: None for success, retmsg: Log message to be printed on failure)
- """
- tgen = get_topogen()
-
- if trigger not in TRIGGERS:
- return "Unexpected trigger", "Unexpected trigger {}".format(trigger)
-
- show_commands = {'bgp_vni_routes': 'show bgp l2vpn evpn route vni 100 json',
- 'bgp_vrf_ipv4' : 'show bgp vrf vrf-blue ipv4 json',
- 'bgp_vrf_ipv6' : 'show bgp vrf vrf-blue ipv6 json',
- 'zebra_vrf_ipv4': 'show ip route vrf vrf-blue json',
- 'zebra_vrf_ipv6': 'show ipv6 route vrf vrf-blue json'}
-
- for (name, pe) in tgen.gears.items():
- if name not in PES:
- continue
-
- for (cmd_key, command) in show_commands.items():
- expected_op_file = "{0}/{1}/{2}_{3}.json".format(CWD, name, cmd_key, trigger)
- expected_op = json.loads(open(expected_op_file).read())
-
- test_func = partial(topotest.router_json_cmp, pe, command, expected_op)
- ret, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
- assertmsg = '"{0}" JSON output mismatch for {1}'.format(name, command)
- if result is not None:
- return result, assertmsg
-
- return None, "Pass"
-
-
-def test_evpn_gateway_ip_basic_topo(request):
- """
- Tets EVPN overlay index gateway IP functionality. VErify show O/Ps on PE1 and PE2
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- kernelv = platform.release()
- if topotest.version_cmp(kernelv, "4.15") < 0:
- logger.info("For EVPN, kernel version should be minimum 4.15")
- write_test_footer(tc_name)
- return
-
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- step("Check O/Ps for EVPN gateway IP overlay Index functionality at PE1 and PE2")
-
- result, assertmsg = evpn_gateway_ip_show_op_check("base")
-
- if result is not None:
- generate_support_bundle()
- assert result is None, assertmsg
-
- write_test_footer(tc_name)
-
-
-def test_evpn_gateway_ip_flap_rt5(request):
- """
- Withdraw EVPN type-5 routes and check O/Ps at PE1 and PE2
- """
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- kernelv = platform.release()
- if topotest.version_cmp(kernelv, "4.15") < 0:
- logger.info("For EVPN, kernel version should be minimum 4.15")
- write_test_footer(tc_name)
- return
-
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- h1 = tgen.gears['host1']
-
- step("Withdraw type-5 routes")
-
- h1.run('vtysh -c "config t" \
- -c "router bgp 111" \
- -c "address-family ipv4" \
- -c "no network 100.0.0.21/32"')
- h1.run('vtysh -c "config t" \
- -c "router bgp 111" \
- -c "address-family ipv6" \
- -c "no network 100::21/128"')
-
- result, assertmsg = evpn_gateway_ip_show_op_check("no_rt5")
- if result is not None:
- generate_support_bundle()
- assert result is None, assertmsg
-
- step("Advertise type-5 routes again")
-
- h1.run('vtysh -c "config t" \
- -c "router bgp 111" \
- -c "address-family ipv4" \
- -c "network 100.0.0.21/32"')
- h1.run('vtysh -c "config t" \
- -c "router bgp 111" \
- -c "address-family ipv6" \
- -c "network 100::21/128"')
-
- result, assertmsg = evpn_gateway_ip_show_op_check("base")
- if result is not None:
- generate_support_bundle()
-
- assert result is None, assertmsg
-
- write_test_footer(tc_name)
-
-
-def test_evpn_gateway_ip_flap_rt2(request):
- """
- Withdraw EVPN type-2 routes and check O/Ps at PE1 and PE2
- """
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- kernelv = platform.release()
- if topotest.version_cmp(kernelv, "4.15") < 0:
- logger.info("For EVPN, kernel version should be minimum 4.15")
- write_test_footer(tc_name)
- return
-
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
-
- step("Shut down VxLAN interface at PE1 which results in withdraw of type-2 routes")
-
- pe1 = tgen.gears['PE1']
-
- pe1.run('ip link set dev vxlan100 down')
-
- result, assertmsg = evpn_gateway_ip_show_op_check("no_rt2")
- if result is not None:
- generate_support_bundle()
- assert result is None, assertmsg
-
- step("Bring up VxLAN interface at PE1 and advertise type-2 routes again")
-
- pe1.run('ip link set dev vxlan100 up')
-
- result, assertmsg = evpn_gateway_ip_show_op_check("base")
- if result is not None:
- generate_support_bundle()
- assert result is None, assertmsg
-
- write_test_footer(tc_name)
-
-
-def test_memory_leak():
- """Run the memory leak test and report results"""
- tgen = get_topogen()
- if not tgen.is_memleak_enabled():
- pytest.skip("Memory leak test/report is disabled")
-
- tgen.report_memory_leaks()
-
-if __name__ == "__main__":
- args = ["-s"] + sys.argv[1:]
- sys.exit(pytest.main(args))
--- /dev/null
+{
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:61",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:101:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:61",
+ "ipLen":32,
+ "ip":"50.0.1.11",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:101:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:61",
+ "ipLen":128,
+ "ip":"50:0:1::11",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:101:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:62",
+ "weight":0,
+ "peerId":"10.0.1.2",
+ "path":"102",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"RT:102:100 ET:8"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[3]:[0]:[32]:[10.100.0.1]":{
+ "prefix":"[3]:[0]:[32]:[10.100.0.1]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":3,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"10.100.0.1",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:101:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[3]:[0]:[32]:[10.100.0.2]":{
+ "prefix":"[3]:[0]:[32]:[10.100.0.2]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":3,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"10.100.0.2",
+ "weight":0,
+ "peerId":"10.0.1.2",
+ "path":"102",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"RT:102:100 ET:8"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]": null,
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]": null,
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]": null,
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]": null,
+ "[3]:[0]:[32]:[10.100.0.1]": null,
+ "[3]:[0]:[32]:[10.100.0.2]": null
+}
\ No newline at end of file
--- /dev/null
+{
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:61",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:101:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:61",
+ "ipLen":32,
+ "ip":"50.0.1.11",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:101:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:61",
+ "ipLen":128,
+ "ip":"50:0:1::11",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:101:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:62",
+ "weight":0,
+ "peerId":"10.0.1.2",
+ "path":"102",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"RT:102:100 ET:8"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[3]:[0]:[32]:[10.100.0.1]":{
+ "prefix":"[3]:[0]:[32]:[10.100.0.1]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":3,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"10.100.0.1",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:101:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[3]:[0]:[32]:[10.100.0.2]":{
+ "prefix":"[3]:[0]:[32]:[10.100.0.2]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":3,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"10.100.0.2",
+ "weight":0,
+ "peerId":"10.0.1.2",
+ "path":"102",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"RT:102:100 ET:8"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "vrfName": "vrf-blue",
+ "routerId": "10.100.0.1",
+ "defaultLocPrf": 100,
+ "localAS": 101,
+ "routes": { "100.0.0.21/32": [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "prefix":"100.0.0.21",
+ "prefixLen":32,
+ "network":"100.0.0.21\/32",
+ "metric":0,
+ "weight":0,
+ "peerId":"50.0.1.11",
+ "path":"111",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"50.0.1.11",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+] } }
\ No newline at end of file
--- /dev/null
+{
+ "vrfName": "vrf-blue",
+ "routerId": "10.100.0.1",
+ "defaultLocPrf": 100,
+ "localAS": 101,
+ "routes": { "100.0.0.21/32": [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "prefix":"100.0.0.21",
+ "prefixLen":32,
+ "network":"100.0.0.21\/32",
+ "metric":0,
+ "weight":0,
+ "peerId":"50.0.1.11",
+ "path":"111",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"50.0.1.11",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+] } }
\ No newline at end of file
--- /dev/null
+{
+ "vrfName": "vrf-blue",
+ "routerId": "10.100.0.1",
+ "defaultLocPrf": 100,
+ "localAS": 101,
+ "routes": { "100.0.0.21/32": null } }
--- /dev/null
+{
+ "vrfName": "vrf-blue",
+ "routerId": "10.100.0.1",
+ "defaultLocPrf": 100,
+ "localAS": 101,
+ "routes": { "100::21/128": [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "prefix":"100::21",
+ "prefixLen":128,
+ "network":"100::21\/128",
+ "metric":0,
+ "weight":0,
+ "peerId":"50:0:1::11",
+ "path":"111",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"50:0:1::11",
+ "afi":"ipv6",
+ "scope":"global"
+ }
+ ]
+ }
+] } }
--- /dev/null
+{
+ "vrfName": "vrf-blue",
+ "routerId": "10.100.0.1",
+ "defaultLocPrf": 100,
+ "localAS": 101,
+ "routes": { "100::21/128": [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "prefix":"100::21",
+ "prefixLen":128,
+ "network":"100::21\/128",
+ "metric":0,
+ "weight":0,
+ "peerId":"50:0:1::11",
+ "path":"111",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"50:0:1::11",
+ "afi":"ipv6",
+ "scope":"global"
+ }
+ ]
+ }
+] } }
--- /dev/null
+{
+ "vrfName": "vrf-blue",
+ "routerId": "10.100.0.1",
+ "defaultLocPrf": 100,
+ "localAS": 101,
+ "routes": { "100::21/128": null } }
\ No newline at end of file
--- /dev/null
+router bgp 101
+ bgp router-id 10.100.0.1
+ no bgp ebgp-requires-policy
+ no bgp network import-check
+ neighbor 10.0.1.2 remote-as 102
+ !
+ address-family l2vpn evpn
+ neighbor 10.0.1.2 activate
+ advertise-all-vni
+ exit-address-family
+!
+router bgp 101 vrf vrf-blue
+ bgp router-id 10.100.0.1
+ no bgp ebgp-requires-policy
+ no bgp network import-check
+ neighbor 50.0.1.11 remote-as 111
+ neighbor 50:0:1::11 remote-as 111
+ !
+ address-family ipv4 unicast
+ no neighbor 50:0:1::11 activate
+ exit-address-family
+ !
+ address-family ipv6 unicast
+ neighbor 50:0:1::11 activate
+ exit-address-family
+ !
+ address-family l2vpn evpn
+ advertise ipv4 unicast gateway-ip
+ advertise ipv6 unicast gateway-ip
+ exit-address-family
\ No newline at end of file
--- /dev/null
+!
+log file zebra.log
+!
+ip route 10.100.0.2/32 10.0.1.2
+!
+vrf vrf-blue
+ vni 1000 prefix-routes-only
+ exit-vrf
+!
+interface lo
+ ip address 10.100.0.1/32
+interface PE1-eth0
+ ip address 10.0.1.1/24
+!
--- /dev/null
+{
+ "50.0.1.0\/24":[
+ {
+ "prefix":"50.0.1.0\/24",
+ "protocol":"connected",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"br100",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "100.0.0.21\/32":[
+ {
+ "prefix":"100.0.0.21\/32",
+ "protocol":"bgp",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":20,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"50.0.1.11",
+ "afi":"ipv4",
+ "interfaceName":"br100",
+ "active":true,
+ "weight":1
+ }
+ ]
+ }
+ ]
+}
--- /dev/null
+{
+ "50.0.1.0\/24":[
+ {
+ "prefix":"50.0.1.0\/24",
+ "protocol":"connected",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"br100",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "100.0.0.21\/32":[
+ {
+ "prefix":"100.0.0.21\/32",
+ "protocol":"bgp",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":20,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"50.0.1.11",
+ "afi":"ipv4",
+ "interfaceName":"br100",
+ "active":true,
+ "weight":1
+ }
+ ]
+ }
+ ]
+}
--- /dev/null
+{
+ "50.0.1.0\/24":[
+ {
+ "prefix":"50.0.1.0\/24",
+ "protocol":"connected",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"br100",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "100.0.0.21\/32": null
+}
--- /dev/null
+{
+ "50:0:1::\/48":[
+ {
+ "prefix":"50:0:1::\/48",
+ "protocol":"connected",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"br100",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "100::21\/128":[
+ {
+ "prefix":"100::21\/128",
+ "protocol":"bgp",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":20,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "afi":"ipv6",
+ "interfaceName":"br100",
+ "active":true,
+ "weight":1
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
--- /dev/null
+{
+ "50:0:1::\/48":[
+ {
+ "prefix":"50:0:1::\/48",
+ "protocol":"connected",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"br100",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "100::21\/128":[
+ {
+ "prefix":"100::21\/128",
+ "protocol":"bgp",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":20,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "afi":"ipv6",
+ "interfaceName":"br100",
+ "active":true,
+ "weight":1
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
--- /dev/null
+{
+ "50:0:1::\/48":[
+ {
+ "prefix":"50:0:1::\/48",
+ "protocol":"connected",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"br100",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "100::21\/128": null
+}
\ No newline at end of file
--- /dev/null
+{
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:61",
+ "weight":0,
+ "peerId":"10.0.1.1",
+ "path":"101",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"RT:101:100 ET:8"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:61",
+ "ipLen":32,
+ "ip":"50.0.1.11",
+ "weight":0,
+ "peerId":"10.0.1.1",
+ "path":"101",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"RT:101:100 ET:8"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:61",
+ "ipLen":128,
+ "ip":"50:0:1::11",
+ "weight":0,
+ "peerId":"10.0.1.1",
+ "path":"101",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"RT:101:100 ET:8"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:62",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:102:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[3]:[0]:[32]:[10.100.0.1]":{
+ "prefix":"[3]:[0]:[32]:[10.100.0.1]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":3,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"10.100.0.1",
+ "weight":0,
+ "peerId":"10.0.1.1",
+ "path":"101",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"RT:101:100 ET:8"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[3]:[0]:[32]:[10.100.0.2]":{
+ "prefix":"[3]:[0]:[32]:[10.100.0.2]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":3,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"10.100.0.2",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:102:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]": null,
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]": null,
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]": null,
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:62",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:102:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[3]:[0]:[32]:[10.100.0.1]": null,
+ "[3]:[0]:[32]:[10.100.0.2]":{
+ "prefix":"[3]:[0]:[32]:[10.100.0.2]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":3,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"10.100.0.2",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:102:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:61",
+ "weight":0,
+ "peerId":"10.0.1.1",
+ "path":"101",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"RT:101:100 ET:8"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[32]:[50.0.1.11]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:61",
+ "ipLen":32,
+ "ip":"50.0.1.11",
+ "weight":0,
+ "peerId":"10.0.1.1",
+ "path":"101",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"RT:101:100 ET:8"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:61]:[128]:[50:0:1::11]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:61",
+ "ipLen":128,
+ "ip":"50:0:1::11",
+ "weight":0,
+ "peerId":"10.0.1.1",
+ "path":"101",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"RT:101:100 ET:8"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]":{
+ "prefix":"[2]:[0]:[48]:[1a:2b:3c:4d:5e:62]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":2,
+ "ethTag":0,
+ "macLen":48,
+ "mac":"1a:2b:3c:4d:5e:62",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:102:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[3]:[0]:[32]:[10.100.0.1]":{
+ "prefix":"[3]:[0]:[32]:[10.100.0.1]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":3,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"10.100.0.1",
+ "weight":0,
+ "peerId":"10.0.1.1",
+ "path":"101",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"RT:101:100 ET:8"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ "[3]:[0]:[32]:[10.100.0.2]":{
+ "prefix":"[3]:[0]:[32]:[10.100.0.2]",
+ "prefixLen":320,
+ "paths":[
+ [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "routeType":3,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"10.100.0.2",
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "extendedCommunity":{
+ "string":"ET:8 RT:102:100"
+ },
+ "nexthops":[
+ {
+ "ip":"10.100.0.2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ ]
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "vrfName": "vrf-blue",
+ "routerId": "10.100.0.2",
+ "defaultLocPrf": 100,
+ "localAS": 101,
+ "routes": { "100.0.0.21/32": [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "prefix":"100.0.0.21",
+ "prefixLen":32,
+ "network":"100.0.0.21\/32",
+ "metric":0,
+ "weight":0,
+ "peerId":"10.0.1.1",
+ "path":"101 111",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"50.0.1.11",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+] } }
\ No newline at end of file
--- /dev/null
+{
+ "vrfName": "vrf-blue",
+ "routerId": "10.100.0.2",
+ "defaultLocPrf": 100,
+ "localAS": 101,
+ "routes": { "100.0.0.21/32": [
+ {
+ "valid":null,
+ "bestpath":null,
+ "pathFrom":"external",
+ "prefix":"100.0.0.21",
+ "prefixLen":32,
+ "network":"100.0.0.21\/32",
+ "metric":0,
+ "weight":0,
+ "peerId":"10.0.1.1",
+ "path":"101 111",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"50.0.1.11",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+] } }
--- /dev/null
+{
+ "vrfName": "vrf-blue",
+ "routerId": "10.100.0.2",
+ "defaultLocPrf": 100,
+ "localAS": 101,
+ "routes": { "100.0.0.21/32": null } }
\ No newline at end of file
--- /dev/null
+{
+ "vrfName": "vrf-blue",
+ "routerId": "10.100.0.2",
+ "defaultLocPrf": 100,
+ "localAS": 101,
+ "routes": { "100::21/128": [
+ {
+ "valid":true,
+ "bestpath":true,
+ "pathFrom":"external",
+ "prefix":"100::21",
+ "prefixLen":128,
+ "network":"100::21\/128",
+ "metric":0,
+ "weight":0,
+ "peerId":"10.0.1.1",
+ "path":"101 111",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"50:0:1::11",
+ "afi":"ipv6",
+ "scope":"global",
+ "used":true
+ }
+ ]
+ }
+] } }
\ No newline at end of file
--- /dev/null
+{
+ "vrfName": "vrf-blue",
+ "routerId": "10.100.0.2",
+ "defaultLocPrf": 100,
+ "localAS": 101,
+ "routes": { "100::21/128": [
+ {
+ "valid":null,
+ "bestpath":null,
+ "pathFrom":"external",
+ "prefix":"100::21",
+ "prefixLen":128,
+ "network":"100::21\/128",
+ "metric":0,
+ "weight":0,
+ "peerId":"10.0.1.1",
+ "path":"101 111",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"50:0:1::11",
+ "afi":"ipv6",
+ "scope":"global",
+ "used":true
+ }
+ ]
+ }
+] } }
--- /dev/null
+{
+ "vrfName": "vrf-blue",
+ "routerId": "10.100.0.2",
+ "defaultLocPrf": 100,
+ "localAS": 101,
+ "routes": { "100::21/128": null } }
\ No newline at end of file
--- /dev/null
+router bgp 102
+ bgp router-id 10.100.0.2
+ no bgp ebgp-requires-policy
+ no bgp network import-check
+ neighbor 10.0.1.1 remote-as 101
+ !
+ address-family l2vpn evpn
+ neighbor 10.0.1.1 activate
+ advertise-all-vni
+ enable-resolve-overlay-index
+ exit-address-family
+!
+router bgp 101 vrf vrf-blue
+ bgp router-id 10.100.0.2
--- /dev/null
+!
+log file zebra.log
+!
+ip route 10.100.0.1/32 10.0.1.1
+!
+vrf vrf-blue
+ vni 1000 prefix-routes-only
+ exit-vrf
+!
+interface lo
+ ip address 10.100.0.2/32
+interface PE2-eth0
+ ip address 10.0.1.2/24
+!
--- /dev/null
+{
+ "50.0.1.0\/24":[
+ {
+ "prefix":"50.0.1.0\/24",
+ "protocol":"connected",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"br100",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "100.0.0.21\/32":[
+ {
+ "prefix":"100.0.0.21\/32",
+ "protocol":"bgp",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":20,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":40,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"50.0.1.11",
+ "afi":"ipv4",
+ "interfaceName":"br100",
+ "active":true,
+ "weight":1
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
--- /dev/null
+{
+ "50.0.1.0\/24":[
+ {
+ "prefix":"50.0.1.0\/24",
+ "protocol":"connected",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"br100",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "100.0.0.21\/32": null
+}
\ No newline at end of file
--- /dev/null
+{
+ "50.0.1.0\/24":[
+ {
+ "prefix":"50.0.1.0\/24",
+ "protocol":"connected",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"br100",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "100.0.0.21\/32": null
+}
\ No newline at end of file
--- /dev/null
+{
+ "50:0:1::\/48":[
+ {
+ "prefix":"50:0:1::\/48",
+ "protocol":"connected",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"br100",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "100::21\/128":[
+ {
+ "prefix":"100::21\/128",
+ "protocol":"bgp",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":20,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":40,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"50:0:1::11",
+ "afi":"ipv6",
+ "interfaceName":"br100",
+ "active":true,
+ "weight":1
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
--- /dev/null
+{
+ "50:0:1::\/48":[
+ {
+ "prefix":"50:0:1::\/48",
+ "protocol":"connected",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"br100",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "100::21\/128": null
+}
\ No newline at end of file
--- /dev/null
+{
+ "50:0:1::\/48":[
+ {
+ "prefix":"50:0:1::\/48",
+ "protocol":"connected",
+ "vrfName":"vrf-blue",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":10,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"br100",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "100::21\/128": null
+}
\ No newline at end of file
--- /dev/null
+router bgp 111
+ bgp router-id 10.100.0.11
+ no bgp ebgp-requires-policy
+ no bgp network import-check
+ neighbor 50.0.1.1 remote-as 101
+ neighbor 50:0:1::1 remote-as 101
+ !
+ address-family ipv4 unicast
+ network 100.0.0.21/32
+ no neighbor 50:0:1::1 activate
+ exit-address-family
+ !
+ address-family ipv6 unicast
+ network 100::21/128
+ neighbor 50:0:1::1 activate
+ exit-address-family
+
+
--- /dev/null
+!
+int host1-eth0
+ ip address 50.0.1.11/24
+ ipv6 address 50:0:1::11/48
--- /dev/null
+!
+int host1-eth0
+ ip address 50.0.1.21/24
+ ipv6 address 50:0:1::21/48
--- /dev/null
+#!/usr/bin/env python
+#
+# Copyright (c) 2020 by VMware, Inc. ("VMware")
+# Used Copyright (c) 2018 by Network Device Education Foundation, Inc. ("NetDEF")
+# in this file.
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+test_bgp_evpn_overlay_index_gateway.py: Test EVPN gateway IP overlay index functionality
+Following functionality is covered:
+
+ +--------+ BGP +--------+ BGP +--------+ +--------+
+ SN1 | | IPv4/v6 | | EVPN | | | |
+ ======+ Host1 +---------+ PE1 +------+ PE2 +------+ Host2 +
+ | | | | | | | |
+ +--------+ +--------+ +--------+ +--------+
+
+ Host1 is connected to PE1 and host2 is connected to PE2
+ Host1 and PE1 have IPv4/v6 BGP sessions.
+ PE1 and PE2 gave EVPN session.
+ Host1 advertises IPv4/v6 prefixes to PE1.
+ PE1 advertises these prefixes to PE2 as EVPN type-5 routes.
+ Gateway IP for these EVPN type-5 routes is host1 IP.
+ Host1 MAC/IP is advertised by PE1 as EVPN type-2 route
+
+Following testcases are covered:
+TC_1:
+Check BGP and zebra states for above topology at PE1 and PE2.
+
+TC_2:
+Stop advertising prefixes from host1. It should withdraw type-5 routes. Check states at PE1 and PE2
+Advertise the prefixes again. Check states.
+
+TC_3:
+Shut down VxLAN interface at PE1. This should withdraw type-2 routes. Check states at PE1 and PE2.
+Enable VxLAN interface again. Check states.
+"""
+
+import os
+import sys
+import json
+from functools import partial
+import pytest
+import time
+import platform
+
+#Current Working Directory
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from lib.common_config import (
+ step,
+ write_test_header,
+ write_test_footer,
+ generate_support_bundle,
+)
+
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+pytestmark = [pytest.mark.bgpd]
+
+
+#Global variables
+PES = ['PE1', 'PE2']
+HOSTS = ['host1', 'host2']
+PE_SUFFIX = {'PE1': '1', 'PE2': '2'}
+HOST_SUFFIX = {'host1': '1', 'host2': '2'}
+TRIGGERS = ["base", "no_rt5", "no_rt2"]
+
+
+class TemplateTopo(Topo):
+ """Test topology builder"""
+
+ def build(self, *_args, **_opts):
+ """Build function"""
+ tgen = get_topogen(self)
+
+ # This function only purpose is to define allocation and relationship
+ # between routers and add links.
+
+ # Create routers
+ for pe in PES:
+ tgen.add_router(pe)
+ for host in HOSTS:
+ tgen.add_router(host)
+
+ krel = platform.release()
+ logger.info('Kernel version ' + krel)
+
+ #Add links
+ tgen.add_link(tgen.gears['PE1'], tgen.gears['PE2'], 'PE1-eth0', 'PE2-eth0')
+ tgen.add_link(tgen.gears['PE1'], tgen.gears['host1'], 'PE1-eth1', 'host1-eth0')
+ tgen.add_link(tgen.gears['PE2'], tgen.gears['host2'], 'PE2-eth1', 'host2-eth0')
+
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+
+ testsuite_run_time = time.asctime(time.localtime(time.time()))
+ logger.info("Testsuite start time: {}".format(testsuite_run_time))
+ logger.info("=" * 40)
+
+ logger.info("Running setup_module to create topology")
+
+ # This function initiates the topology build with Topogen...
+ tgen = Topogen(TemplateTopo, mod.__name__)
+ # ... and here it calls Mininet initialization functions.
+
+ kernelv = platform.release()
+ if topotest.version_cmp(kernelv, "4.15") < 0:
+ logger.info("For EVPN, kernel version should be minimum 4.15. Kernel present {}".format(kernelv))
+ return
+
+ if topotest.version_cmp(kernelv, '4.15') == 0:
+ l3mdev_accept = 1
+ logger.info('setting net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept))
+ else:
+ l3mdev_accept = 0
+
+ # Starting topology, create tmp files which are loaded to routers
+ # to start deamons and then start routers
+ tgen.start_topology()
+
+ # Configure MAC address for hosts as these MACs are advertised with EVPN type-2 routes
+ for (name, host) in tgen.gears.items():
+ if name not in HOSTS:
+ continue
+
+ host_mac = "1a:2b:3c:4d:5e:6{}".format(HOST_SUFFIX[name])
+ host.run("ip link set dev {}-eth0 down").format(name)
+ host.run("ip link set dev {0}-eth0 address {1}".format(name, host_mac))
+ host.run("ip link set dev {}-eth0 up").format(name)
+
+ # Configure PE VxLAN and Bridge interfaces
+ for (name, pe) in tgen.gears.items():
+ if name not in PES:
+ continue
+ vtep_ip = "10.100.0.{}".format(PE_SUFFIX[name])
+ bridge_ip = "50.0.1.{}/24".format(PE_SUFFIX[name])
+ bridge_ipv6 = "50:0:1::{}/48".format(PE_SUFFIX[name])
+
+ pe.run("ip link add vrf-blue type vrf table 10")
+ pe.run("ip link set dev vrf-blue up")
+ pe.run("ip link add vxlan100 type vxlan id 100 dstport 4789 local {}".format(vtep_ip))
+ pe.run("ip link add name br100 type bridge stp_state 0")
+ pe.run("ip link set dev vxlan100 master br100")
+ pe.run("ip link set dev {}-eth1 master br100".format(name))
+ pe.run("ip addr add {} dev br100".format(bridge_ip))
+ pe.run("ip link set up dev br100")
+ pe.run("ip link set up dev vxlan100")
+ pe.run("ip link set up dev {}-eth1".format(name))
+ pe.run("ip link set dev br100 master vrf-blue")
+ pe.run("ip -6 addr add {} dev br100".format(bridge_ipv6))
+
+ pe.run("ip link add vxlan1000 type vxlan id 1000 dstport 4789 local {}".format(vtep_ip))
+ pe.run("ip link add name br1000 type bridge stp_state 0")
+ pe.run("ip link set dev vxlan1000 master br100")
+ pe.run("ip link set up dev br1000")
+ pe.run("ip link set up dev vxlan1000")
+ pe.run("ip link set dev br1000 master vrf-blue")
+
+ pe.run("sysctl -w net.ipv4.ip_forward=1")
+ pe.run("sysctl -w net.ipv6.conf.all.forwarding=1")
+ pe.run("sysctl -w net.ipv4.udp_l3mdev_accept={}".format(l3mdev_accept))
+ pe.run("sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept))
+
+ # For all registred routers, load the zebra configuration file
+ for (name, router) in tgen.routers().items():
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(name))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(name))
+ )
+
+ # After loading the configurations, this function loads configured daemons.
+ tgen.start_router()
+
+ logger.info("Running setup_module() done")
+
+
+def teardown_module(mod):
+ """Teardown the pytest environment"""
+
+ logger.info("Running teardown_module to delete topology")
+
+ tgen = get_topogen()
+
+ # Stop toplogy and Remove tmp files
+ tgen.stop_topology()
+
+ logger.info(
+ "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
+ )
+ logger.info("=" * 40)
+
+
+def evpn_gateway_ip_show_op_check(trigger=" "):
+ """
+ This function checks CLI O/P for commands mentioned in show_commands for a given trigger
+ :param trigger: Should be a trigger present in TRIGGERS
+ :return: Returns a tuple (result: None for success, retmsg: Log message to be printed on failure)
+ """
+ tgen = get_topogen()
+
+ if trigger not in TRIGGERS:
+ return "Unexpected trigger", "Unexpected trigger {}".format(trigger)
+
+ show_commands = {'bgp_vni_routes': 'show bgp l2vpn evpn route vni 100 json',
+ 'bgp_vrf_ipv4' : 'show bgp vrf vrf-blue ipv4 json',
+ 'bgp_vrf_ipv6' : 'show bgp vrf vrf-blue ipv6 json',
+ 'zebra_vrf_ipv4': 'show ip route vrf vrf-blue json',
+ 'zebra_vrf_ipv6': 'show ipv6 route vrf vrf-blue json'}
+
+ for (name, pe) in tgen.gears.items():
+ if name not in PES:
+ continue
+
+ for (cmd_key, command) in show_commands.items():
+ expected_op_file = "{0}/{1}/{2}_{3}.json".format(CWD, name, cmd_key, trigger)
+ expected_op = json.loads(open(expected_op_file).read())
+
+ test_func = partial(topotest.router_json_cmp, pe, command, expected_op)
+ ret, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assertmsg = '"{0}" JSON output mismatch for {1}'.format(name, command)
+ if result is not None:
+ return result, assertmsg
+
+ return None, "Pass"
+
+
+def test_evpn_gateway_ip_basic_topo(request):
+ """
+ Tets EVPN overlay index gateway IP functionality. VErify show O/Ps on PE1 and PE2
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ kernelv = platform.release()
+ if topotest.version_cmp(kernelv, "4.15") < 0:
+ logger.info("For EVPN, kernel version should be minimum 4.15")
+ write_test_footer(tc_name)
+ return
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ step("Check O/Ps for EVPN gateway IP overlay Index functionality at PE1 and PE2")
+
+ result, assertmsg = evpn_gateway_ip_show_op_check("base")
+
+ if result is not None:
+ generate_support_bundle()
+ assert result is None, assertmsg
+
+ write_test_footer(tc_name)
+
+
+def test_evpn_gateway_ip_flap_rt5(request):
+ """
+ Withdraw EVPN type-5 routes and check O/Ps at PE1 and PE2
+ """
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ kernelv = platform.release()
+ if topotest.version_cmp(kernelv, "4.15") < 0:
+ logger.info("For EVPN, kernel version should be minimum 4.15")
+ write_test_footer(tc_name)
+ return
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ h1 = tgen.gears['host1']
+
+ step("Withdraw type-5 routes")
+
+ h1.run('vtysh -c "config t" \
+ -c "router bgp 111" \
+ -c "address-family ipv4" \
+ -c "no network 100.0.0.21/32"')
+ h1.run('vtysh -c "config t" \
+ -c "router bgp 111" \
+ -c "address-family ipv6" \
+ -c "no network 100::21/128"')
+
+ result, assertmsg = evpn_gateway_ip_show_op_check("no_rt5")
+ if result is not None:
+ generate_support_bundle()
+ assert result is None, assertmsg
+
+ step("Advertise type-5 routes again")
+
+ h1.run('vtysh -c "config t" \
+ -c "router bgp 111" \
+ -c "address-family ipv4" \
+ -c "network 100.0.0.21/32"')
+ h1.run('vtysh -c "config t" \
+ -c "router bgp 111" \
+ -c "address-family ipv6" \
+ -c "network 100::21/128"')
+
+ result, assertmsg = evpn_gateway_ip_show_op_check("base")
+ if result is not None:
+ generate_support_bundle()
+
+ assert result is None, assertmsg
+
+ write_test_footer(tc_name)
+
+
+def test_evpn_gateway_ip_flap_rt2(request):
+ """
+ Withdraw EVPN type-2 routes and check O/Ps at PE1 and PE2
+ """
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ kernelv = platform.release()
+ if topotest.version_cmp(kernelv, "4.15") < 0:
+ logger.info("For EVPN, kernel version should be minimum 4.15")
+ write_test_footer(tc_name)
+ return
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+
+ step("Shut down VxLAN interface at PE1 which results in withdraw of type-2 routes")
+
+ pe1 = tgen.gears['PE1']
+
+ pe1.run('ip link set dev vxlan100 down')
+
+ result, assertmsg = evpn_gateway_ip_show_op_check("no_rt2")
+ if result is not None:
+ generate_support_bundle()
+ assert result is None, assertmsg
+
+ step("Bring up VxLAN interface at PE1 and advertise type-2 routes again")
+
+ pe1.run('ip link set dev vxlan100 up')
+
+ result, assertmsg = evpn_gateway_ip_show_op_check("base")
+ if result is not None:
+ generate_support_bundle()
+ assert result is None, assertmsg
+
+ write_test_footer(tc_name)
+
+
+def test_memory_leak():
+ """Run the memory leak test and report results"""
+ tgen = get_topogen()
+ if not tgen.is_memleak_enabled():
+ pytest.skip("Memory leak test/report is disabled")
+
+ tgen.report_memory_leaks()
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
+++ /dev/null
-log file zebra.log
-!
-hostname dst
-!
-debug zebra kernel
-debug zebra packet
-debug zebra mpls
-!
-interface lo
- ip address 9.9.9.2/32
- ipv6 address 2001:db8:1066::2/128
-!
-interface eth-rt6
- ip address 10.0.11.2/24
- link-params
- enable
- exit-link-params
-!
-!
-ip forwarding
-!
-line vty
-!
+++ /dev/null
-log file bgpd.log
-!
-router bgp 1
- bgp router-id 1.1.1.1
- neighbor 6.6.6.6 remote-as 1
- neighbor 6.6.6.6 update-source lo
- !
- address-family ipv4 unicast
- redistribute static
- neighbor 6.6.6.6 next-hop-self
- neighbor 6.6.6.6 route-map SET_SR_POLICY in
- exit-address-family
-!
-route-map SET_SR_POLICY permit 10
- set sr-te color 1
-!
+++ /dev/null
-password 1
-hostname rt1
-log file ospfd.log
-!
-debug ospf sr
-debug ospf te
-debug ospf event
-debug ospf lsa
-debug ospf zebra
-!
-interface lo
- ip ospf area 0.0.0.0
-!
-interface eth-sw1
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-router ospf
- ospf router-id 1.1.1.1
- network 1.1.1.1/32 area 0.0.0.0
- network 10.0.0.0/16 area 0.0.0.0
- capability opaque
- !ospf opaque-lsa
- mpls-te on
- mpls-te export
- mpls-te router-address 1.1.1.1
- router-info area 0.0.0.0
- passive-interface lo
- segment-routing on
- segment-routing global-block 16000 23999
- !segment-routing local-block 15000 15999
- segment-routing node-msd 8
- segment-routing prefix 1.1.1.1/32 index 10
-!
+++ /dev/null
-log file pathd.log
-!
-hostname rt1
-!
-segment-routing
- traffic-eng
- mpls-te on
- mpls-te import ospfv2
- segment-list default
- index 10 nai adjacency 10.0.1.1 10.0.1.2
- index 20 nai adjacency 10.0.2.2 10.0.2.4
- index 30 nai adjacency 10.0.7.4 10.0.7.6
-
-
- !
- segment-list test
- index 10 nai adjacency 10.0.1.1 10.0.1.2
- index 20 nai adjacency 10.0.2.2 10.0.2.4
- index 30 nai adjacency 10.0.6.4 10.0.6.5
- index 40 nai adjacency 10.0.8.5 10.0.8.6
- !
- policy color 1 endpoint 6.6.6.6
- name default
- binding-sid 1111
- !
- !
-!
+++ /dev/null
-{
- "frr-pathd:pathd": {
- "srte": {
- "policy": [
- {
- "color": 1,
- "endpoint": "6.6.6.6",
- "is-operational": false
- }
- ]
- }
- }
-}
+++ /dev/null
-{
- "frr-pathd:pathd": {
- "srte": {
- "policy": [
- {
- "color": 1,
- "endpoint": "6.6.6.6",
- "is-operational": true,
- "candidate-path": [
- {
- "preference": 100,
- "discriminator": "*",
- "is-best-candidate-path": true
- }
- ]
- }
- ]
- }
- }
-}
+++ /dev/null
-{
- "frr-pathd:pathd": {
- "srte": {
- "policy": [
- {
- "color": 1,
- "endpoint": "6.6.6.6",
- "is-operational": true,
- "candidate-path": [
- {
- "preference": 100,
- "discriminator": "*",
- "is-best-candidate-path": true
- }
- ]
- }
- ]
- }
- }
-}
+++ /dev/null
-{
- "frr-pathd:pathd": {
- "srte": {
- "policy": [
- {
- "color": 1,
- "endpoint": "6.6.6.6",
- "is-operational": true,
- "candidate-path": [
- {
- "preference": 100,
- "discriminator": "*",
- "is-best-candidate-path": false
- },
- {
- "preference": 200,
- "discriminator": "*",
- "is-best-candidate-path": true
- }
- ]
- }
- ]
- }
- }
-}
+++ /dev/null
-log file zebra.log
-!
-hostname rt1
-!
-debug zebra kernel
-debug zebra packet
-debug zebra mpls
-!
-interface lo
- ip address 1.1.1.1/32
-!
-interface eth-sw1
- ip address 10.0.1.1/24
- link-params
- enable
- exit-link-params
-!
-ip forwarding
-!
-line vty
-!
+++ /dev/null
-hostname rt2
-log file ospfd.log
-!
-debug ospf sr
-debug ospf te
-debug ospf event
-debug ospf lsa
-debug ospf zebra
-!
-interface lo
- ip ospf area 0.0.0.0
-!
-interface eth-sw1
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-interface eth-rt4-1
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-interface eth-rt4-2
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-router ospf
- ospf router-id 2.2.2.2
- network 2.2.2.2/32 area 0.0.0.0
- network 10.0.0.0/16 area 0.0.0.0
- capability opaque
- !ospf opaque-lsa
- mpls-te on
- !mpls-te export
- mpls-te router-address 2.2.2.2
- router-info area 0.0.0.0
- passive-interface lo
- segment-routing on
- segment-routing global-block 16000 23999
- !segment-routing local-block 15000 15999
- segment-routing node-msd 8
- segment-routing prefix 2.2.2.2/32 index 20
-!
+++ /dev/null
-log file zebra.log
-!
-hostname rt2
-!
-debug zebra kernel
-debug zebra packet
-debug zebra mpls
-!
-interface lo
- ip address 2.2.2.2/32
-!
-interface eth-sw1
- ip address 10.0.1.2/24
- link-params
- enable
- exit-link-params
-!
-interface eth-rt4-1
- ip address 10.0.2.2/24
- link-params
- enable
- exit-link-params
-!
-!
-interface eth-rt4-2
- ip address 10.0.3.2/24
- link-params
- enable
- exit-link-params
-!
-!
-ip forwarding
-!
-line vty
-!
+++ /dev/null
-hostname rt3
-log file ospfd.log
-!
-debug ospf sr
-debug ospf te
-debug ospf event
-debug ospf lsa
-debug ospf zebra
-!
-interface lo
- ip ospf area 0.0.0.0
-!
-interface eth-sw1
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-interface eth-rt5-1
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-interface eth-rt5-2
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-router ospf
- ospf router-id 3.3.3.3
- network 3.3.3.3/32 area 0.0.0.0
- network 10.0.0.0/16 area 0.0.0.0
- capability opaque
- !ospf opaque-lsa
- mpls-te on
- !mpls-te export
- mpls-te router-address 3.3.3.3
- router-info area 0.0.0.0
- segment-routing on
- segment-routing global-block 16000 23999
- !segment-routing local-block 15000 15999
- segment-routing node-msd 8
- segment-routing prefix 3.3.3.3/32 index 30
-!
+++ /dev/null
-log file zebra.log
-!
-hostname rt3
-!
-debug zebra kernel
-debug zebra packet
-debug zebra mpls
-!
-interface lo
- ip address 3.3.3.3/32
-!
-interface eth-sw1
- ip address 10.0.1.3/24
- link-params
- enable
- exit-link-params
-!!
-interface eth-rt5-1
- ip address 10.0.4.3/24
- link-params
- enable
- exit-link-params
-!!
-interface eth-rt5-2
- ip address 10.0.5.3/24
- link-params
- enable
- exit-link-params
-!!
-ip forwarding
-!
-line vty
-!
+++ /dev/null
-hostname rt4
-log file ospfd.log
-!
-debug ospf sr
-debug ospf te
-debug ospf event
-debug ospf lsa
-debug ospf zebra
-!
-interface lo
- ip ospf area 0.0.0.0
-!
-interface eth-rt2-1
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-interface eth-rt2-2
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-interface eth-rt5
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-interface eth-rt6
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-router ospf
- ospf router-id 4.4.4.4
- network 4.4.4.4/32 area 0.0.0.0
- network 10.0.0.0/16 area 0.0.0.0
- capability opaque
- !ospf opaque-lsa
- mpls-te on
- !mpls-te export
- mpls-te router-address 4.4.4.4
- router-info area 0.0.0.0
- passive-interface lo
- segment-routing on
- segment-routing global-block 16000 23999
- !segment-routing local-block 15000 15999
- segment-routing node-msd 8
- segment-routing prefix 4.4.4.4/32 index 40
-!
+++ /dev/null
-log file zebra.log
-!
-hostname rt4
-!
-debug zebra kernel
-debug zebra packet
-debug zebra mpls
-!
-interface lo
- ip address 4.4.4.4/32
-!
-interface eth-rt2-1
- ip address 10.0.2.4/24
- link-params
- enable
- exit-link-params
-!!
-!
-interface eth-rt2-2
- ip address 10.0.3.4/24
- link-params
- enable
- exit-link-params
-!!
-!
-interface eth-rt5
- ip address 10.0.6.4/24
- link-params
- enable
- exit-link-params
-!!
-!
-interface eth-rt6
- ip address 10.0.7.4/24
- link-params
- enable
- exit-link-params
-!!
-!
-ip forwarding
-!
-line vty
-!
+++ /dev/null
-hostname rt5
-log file ospfd.log
-!
-debug ospf sr
-debug ospf te
-debug ospf event
-debug ospf lsa
-debug ospf zebra
-!
-interface lo
- ip ospf area 0.0.0.0
-!
-interface eth-rt3-1
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-interface eth-rt3-2
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-interface eth-rt4
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-interface eth-rt6
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-router ospf
- ospf router-id 5.5.5.5
- network 5.5.5.5/32 area 0.0.0.0
- network 10.0.0.0/16 area 0.0.0.0
- capability opaque
-! ospf opaque-lsa
- mpls-te on
-! mpls-te export
- mpls-te router-address 5.5.5.5
- router-info area 0.0.0.0
- passive-interface lo
- segment-routing on
- segment-routing global-block 16000 23999
-! segment-routing local-block 15000 15999
- segment-routing node-msd 8
- segment-routing prefix 5.5.5.5/32 index 50
-!
+++ /dev/null
-log file zebra.log
-!
-hostname rt5
-!
-debug zebra kernel
-debug zebra packet
-debug zebra mpls
-!
-interface lo
- ip address 5.5.5.5/32
-!
-interface eth-rt3-1
- ip address 10.0.4.5/24
- link-params
- enable
- exit-link-params
-!!
-!
-interface eth-rt3-2
- ip address 10.0.5.5/24
- link-params
- enable
- exit-link-params
-!!
-!
-interface eth-rt4
- ip address 10.0.6.5/24
- link-params
- enable
- exit-link-params
-!!
-!
-interface eth-rt6
- ip address 10.0.8.5/24
- link-params
- enable
- exit-link-params
-!!
-!
-ip forwarding
-!
-line vty
-!
+++ /dev/null
-log file bgpd.log
-!
-router bgp 1
- bgp router-id 6.6.6.6
- neighbor 1.1.1.1 remote-as 1
- neighbor 1.1.1.1 update-source lo
- !
- address-family ipv4 unicast
- redistribute static
- neighbor 1.1.1.1 next-hop-self
- exit-address-family
-!
+++ /dev/null
-hostname rt6
-log file ospfd.log
-!
-debug ospf sr
-debug ospf te
-debug ospf event
-debug ospf lsa
-debug ospf zebra
-!
-interface lo
- ip ospf area 0.0.0.0
-!
-interface eth-rt4
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-interface eth-rt5
- ip ospf network point-to-point
- ip ospf hello-interval 2
- ip ospf dead-interval 10
- ip ospf area 0.0.0.0
-!
-router ospf
- ospf router-id 6.6.6.6
- network 6.6.6.6/32 area 0.0.0.0
- network 10.0.0.0/16 area 0.0.0.0
- capability opaque
-! ospf opaque-lsa
- mpls-te on
- mpls-te export
- mpls-te router-address 6.6.6.6
- router-info area 0.0.0.0
- passive-interface lo
- segment-routing on
- segment-routing global-block 16000 23999
-! segment-routing local-block 15000 15999
- segment-routing node-msd 8
- segment-routing prefix 6.6.6.6/32 index 60
-!
+++ /dev/null
-log file pathd.log
-!
-hostname rt6
-!
-segment-routing
- traffic-eng
- mpls-te on
- mpls-te import ospfv2
- segment-list default
- index 10 nai adjacency 10.0.7.6 10.0.7.4
- index 20 nai adjacency 10.0.2.4 10.0.2.2
- index 30 nai adjacency 10.0.1.2 10.0.1.1
- !
- segment-list test
- index 10 nai adjacency 10.0.8.6 10.0.8.5
- index 20 nai adjacency 10.0.6.5 10.0.6.4
- index 30 nai adjacency 10.0.2.4 10.0.2.2
- index 40 nai adjacency 10.0.1.2 10.0.1.1
- !
- policy color 1 endpoint 1.1.1.1
- name default
- binding-sid 6666
- !
- !
-!
+++ /dev/null
-{
- "frr-pathd:pathd": {
- "srte": {
- "policy": [
- {
- "color": 1,
- "endpoint": "1.1.1.1",
- "is-operational": false
- }
- ]
- }
- }
-}
+++ /dev/null
-{
- "frr-pathd:pathd": {
- "srte": {
- "policy": [
- {
- "color": 1,
- "endpoint": "1.1.1.1",
- "is-operational": true,
- "candidate-path": [
- {
- "preference": 100,
- "is-best-candidate-path": true
- }
- ]
- }
- ]
- }
- }
-}
+++ /dev/null
-{
- "frr-pathd:pathd": {
- "srte": {
- "policy": [
- {
- "color": 1,
- "endpoint": "1.1.1.1",
- "is-operational": true,
- "candidate-path": [
- {
- "preference": 100,
- "is-best-candidate-path": true
- }
- ]
- }
- ]
- }
- }
-}
+++ /dev/null
-{
- "frr-pathd:pathd": {
- "srte": {
- "policy": [
- {
- "color": 1,
- "endpoint": "1.1.1.1",
- "is-operational": true,
- "candidate-path": [
- {
- "preference": 100,
- "is-best-candidate-path": false
- },
- {
- "preference": 200,
- "is-best-candidate-path": true
- }
- ]
- }
- ]
- }
- }
-}
+++ /dev/null
-log file zebra.log
-!
-hostname rt6
-!
-debug zebra kernel
-debug zebra packet
-debug zebra mpls
-!
-interface lo
- ip address 6.6.6.6/32
-!
-interface eth-rt4
- ip address 10.0.7.6/24
- link-params
- enable
- exit-link-params
-!!
-!
-interface eth-rt5
- ip address 10.0.8.6/24
- link-params
- enable
- exit-link-params
-!!
-!
-interface eth-dst
- ip address 10.0.11.1/24
- link-params
- enable
- exit-link-params
-!!
-!
-ip forwarding
-!
-ip route 9.9.9.2/32 10.0.11.2
-!
-line vty
-!
+++ /dev/null
-#!/usr/bin/env python
-
-#
-# test_ospf_sr_te_topo1.py
-#
-# Copyright (c) 2021 by
-# Volta Networks
-#
-# Permission to use, copy, modify, and/or distribute this software
-# for any purpose with or without fee is hereby granted, provided
-# that the above copyright notice and this permission notice appear
-# in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
-# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-# OF THIS SOFTWARE.
-#
-
-"""
-test_ospf_sr_te_topo1.py:
-
- +---------+
- | |
- | RT1 |
- | 1.1.1.1 |
- | |
- +---------+
- |eth-sw1
- |
- |
- |
- +---------+ | +---------+
- | | | | |
- | RT2 |eth-sw1 | eth-sw1| RT3 |
- | 2.2.2.2 +----------+ + 3.3.3.3 |
- | | 10.0.1.0/24 | |
- +---------+ +---------+
- eth-rt4-1| eth-rt5-1| |eth-rt5-2
- | | |
- 10.0.2.0/24| 10.0.4.0/24| |10.0.5.0/24
- | | |
- eth-rt2-1| eth-rt3-1| |eth-rt3-2
- +---------+ +---------+
- | | | |
- | RT4 | 10.0.6.0/24 | RT5 |
- | 4.4.4.4 +---------------------+ 5.5.5.5 |
- | |eth-rt5 eth-rt4| |
- +---------+ +---------+
- eth-rt6| |eth-rt6
- | |
- 10.0.7.0/24| |10.0.8.0/24
- | +---------+ |
- | | | |
- | | RT6 | |
- +----------+ 6.6.6.6 +-----------+
- eth-rt4| |eth-rt5
- +---------+
- |eth-dst (.1)
- |
- |10.0.11.0/24
- |
- |eth-rt6 (.2)
- +---------+
- | |
- | DST |
- | 9.9.9.2 |
- | |
- +---------+
-
-"""
-
-import os
-import sys
-import pytest
-import json
-import re
-from time import sleep
-from functools import partial
-
-# Save the Current Working Directory to find configuration files.
-CWD = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(CWD, "../"))
-
-# pylint: disable=C0413
-# Import topogen and topotest helpers
-from lib import topotest
-from lib.topogen import Topogen, TopoRouter, get_topogen
-from lib.topolog import logger
-
-# Required to instantiate the topology builder class.
-from mininet.topo import Topo
-
-pytestmark = [pytest.mark.bgpd, pytest.mark.ospfd, pytest.mark.pathd]
-
-
-class TemplateTopo(Topo):
- "Test topology builder"
-
- def build(self, *_args, **_opts):
- "Build function"
- tgen = get_topogen(self)
-
- #
- # Define FRR Routers
- #
- for router in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6", "dst"]:
- tgen.add_router(router)
-
- #
- # Define connections
- #
- switch = tgen.add_switch("s1")
- switch.add_link(tgen.gears["rt1"], nodeif="eth-sw1")
- switch.add_link(tgen.gears["rt2"], nodeif="eth-sw1")
- #switch.add_link(tgen.gears["rt3"], nodeif="eth-sw1")
-
- switch = tgen.add_switch("s2")
- switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4-1")
- switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2-1")
-
- #switch = tgen.add_switch("s3")
- #switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4-2")
- #switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2-2")
-
- switch = tgen.add_switch("s4")
- switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5-1")
- switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3-1")
-
- switch = tgen.add_switch("s5")
- switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5-2")
- switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3-2")
-
- switch = tgen.add_switch("s6")
- switch.add_link(tgen.gears["rt4"], nodeif="eth-rt5")
- switch.add_link(tgen.gears["rt5"], nodeif="eth-rt4")
-
- switch = tgen.add_switch("s7")
- switch.add_link(tgen.gears["rt4"], nodeif="eth-rt6")
- switch.add_link(tgen.gears["rt6"], nodeif="eth-rt4")
-
- switch = tgen.add_switch("s8")
- switch.add_link(tgen.gears["rt5"], nodeif="eth-rt6")
- switch.add_link(tgen.gears["rt6"], nodeif="eth-rt5")
-
- switch = tgen.add_switch("s9")
- switch.add_link(tgen.gears["rt6"], nodeif="eth-dst")
- switch.add_link(tgen.gears["dst"], nodeif="eth-rt6")
-
-
-def setup_module(mod):
- "Sets up the pytest environment"
-
- tgen = Topogen(TemplateTopo, mod.__name__)
-
- frrdir = tgen.config.get(tgen.CONFIG_SECTION, "frrdir")
- if not os.path.isfile(os.path.join(frrdir, "pathd")):
- pytest.skip("pathd daemon wasn't built in:"+frrdir)
-
- tgen.start_topology()
-
- router_list = tgen.routers()
-
- # For all registered routers, load the zebra configuration file
- for rname, router in router_list.items():
- router.load_config(
- TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
- )
- router.load_config(
- TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname))
- )
- router.load_config(
- TopoRouter.RD_PATH, os.path.join(CWD, "{}/pathd.conf".format(rname))
- )
- router.load_config(
- TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
- )
-
- tgen.start_router()
-
-
-def teardown_module(mod):
- "Teardown the pytest environment"
- tgen = get_topogen()
-
- # This function tears down the whole topology.
- tgen.stop_topology()
-
-
-def setup_testcase(msg):
- logger.info(msg)
- tgen = get_topogen()
-
- # Skip if previous fatal error condition is raised
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- return tgen
-
-
-def print_cmd_result(rname, command):
- print(get_topogen().gears[rname].vtysh_cmd(command, isjson=False))
-
-
-def compare_json_test(router, command, reference, exact):
- output = router.vtysh_cmd(command, isjson=True)
- result = topotest.json_cmp(output, reference)
-
- # Note: topotest.json_cmp() just checks on inclusion of keys.
- # For exact matching also compare the other way around.
- if not result and exact:
- return topotest.json_cmp(reference, output)
- else:
- return result
-
-
-def cmp_json_output(rname, command, reference, exact=False):
- "Compare router JSON output"
-
- logger.info('Comparing router "%s" "%s" output', rname, command)
-
- tgen = get_topogen()
- filename = "{}/{}/{}".format(CWD, rname, reference)
- expected = json.loads(open(filename).read())
-
- # Run test function until we get an result. Wait at most 60 seconds.
- test_func = partial(compare_json_test, tgen.gears[rname], command, expected, exact)
- _, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
- assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
- assert diff is None, assertmsg
-
-
-def cmp_json_output_exact(rname, command, reference):
- return cmp_json_output(rname, command, reference, True)
-
-
-def add_candidate_path(rname, endpoint, pref, name, segment_list="default"):
- get_topogen().net[rname].cmd(
- """ \
- vtysh -c "conf t" \
- -c "segment-routing" \
- -c "traffic-eng" \
- -c "policy color 1 endpoint """
- + endpoint
- + """" \
- -c "candidate-path preference """
- + str(pref)
- + """ name """
- + name
- + """ explicit segment-list """
- + segment_list
- + '''"'''
- )
-
-
-def delete_candidate_path(rname, endpoint, pref):
- get_topogen().net[rname].cmd(
- """ \
- vtysh -c "conf t" \
- -c "segment-routing" \
- -c "traffic-eng" \
- -c "policy color 1 endpoint """
- + endpoint
- + """" \
- -c "no candidate-path preference """
- + str(pref)
- + '''"'''
- )
-
-
-def add_segment(rname, name, index, label):
- get_topogen().net[rname].cmd(
- """ \
- vtysh -c "conf t" \
- -c "segment-routing" \
- -c "traffic-eng" \
- -c "segment-list """
- + name
- + """" \
- -c "index """
- + str(index)
- + """ mpls label """
- + str(label)
- + '''"'''
- )
-
-
-def delete_segment(rname, name, index):
- get_topogen().net[rname].cmd(
- """ \
- vtysh -c "conf t" \
- -c "segment-routing" \
- -c "traffic-eng" \
- -c "segment-list """
- + name
- + """" \
- -c "no index """
- + str(index)
- + '''"'''
- )
-
-
-def add_segment_adj(rname, name, index, src, dst):
- get_topogen().net[rname].cmd(
- """ \
- vtysh -c "conf t" \
- -c "segment-routing" \
- -c "traffic-eng" \
- -c "segment-list """
- + name
- + """" \
- -c "index """
- + str(index)
- + """ nai adjacency """
- + str(src)
- + """ """
- + str(dst)
- + '''"'''
- )
-
-
-def create_sr_policy(rname, endpoint, bsid):
- get_topogen().net[rname].cmd(
- """ \
- vtysh -c "conf t" \
- -c "segment-routing" \
- -c "traffic-eng" \
- -c "policy color 1 endpoint """
- + endpoint
- + """" \
- -c "name default" \
- -c "binding-sid """
- + str(bsid)
- + '''"'''
- )
-
-
-def delete_sr_policy(rname, endpoint):
- get_topogen().net[rname].cmd(
- """ \
- vtysh -c "conf t" \
- -c "segment-routing" \
- -c "traffic-eng" \
- -c "no policy color 1 endpoint """
- + endpoint
- + '''"'''
- )
-
-
-def create_prefix_sid(rname, prefix, sid):
- get_topogen().net[rname].cmd(
- """ \
- vtysh -c "conf t" \
- -c "router ospf " \
- -c "segment-routing prefix """
- + prefix
- + " index "
- + str(sid)
- + '''"'''
- )
-
-
-def delete_prefix_sid(rname, prefix):
- get_topogen().net[rname].cmd(
- ''' \
- vtysh -c "conf t" \
- -c "router ospf " \
- -c "no segment-routing prefix "'''
- + prefix
- )
-
-
-def check_bsid(rt, bsid, fn_name, positive):
- """
- Search for a bsid in rt1 and rt6
- Positive means that check is true is bsid is found
- Positive="False" means that check is true is bsid is NOT found
- """
-
- logger.info('Checking "%s" bsid "%s" for router "%s" ', positive, bsid, rt)
-
- count = 0
- candidate_key = bsid
- candidate_output = ""
- # First wait for convergence
- tgen = get_topogen()
- while count < 30:
- matched = False
- matched_key = False
- sleep(1)
- count += 1
- router = tgen.gears[rt]
- candidate_output = router.vtysh_cmd("show mpls table json")
- candidate_output_json = json.loads(candidate_output)
- for item in candidate_output_json.items():
- # logger.info('item "%s"', item)
- if item[0] == candidate_key:
- matched_key = True
- if positive:
- break
- if positive:
- if matched_key:
- matched = True
- assertmsg = "{} don't has entry {} but is was expected".format(
- router.name, candidate_key)
- else:
- if not matched_key:
- matched = True
- assertmsg = "{} has entry {} but is wans't expected".format(
- router.name, candidate_key)
- if matched:
- logger.info('Success "%s" in "%s"', router.name, fn_name)
- return
- assert matched, assertmsg
-
-
-#
-# Step 1
-#
-# Checking the MPLS table using a single SR Policy and a single Candidate Path
-# Segment list are base in adjacency that query TED
-#
-def test_srte_init_step1():
- setup_testcase("Test (step 1): wait OSPF convergence / label distribution")
-
- check_bsid("rt1", "1111", test_srte_init_step1.__name__, False)
- check_bsid("rt6", "6666", test_srte_init_step1.__name__, False)
-
-
-def test_srte_add_candidate_check_mpls_table_step1():
- setup_testcase("Test (step 1): check MPLS table regarding the added Candidate Path")
-
- for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
- add_candidate_path(rname, endpoint, 100, "default")
- check_bsid(rname, "1111" if rname == "rt1" else "6666", test_srte_init_step1.__name__, True)
- delete_candidate_path(rname, endpoint, 100)
-
-
-def test_srte_reinstall_sr_policy_check_mpls_table_step1():
- setup_testcase(
- "Test (step 1): check MPLS table after the SR Policy was removed and reinstalled"
- )
-
- for rname, endpoint, bsid in [("rt1", "6.6.6.6", 1111), ("rt6", "1.1.1.1", 6666)]:
- add_candidate_path(rname, endpoint, 100, "default")
- delete_sr_policy(rname, endpoint)
- check_bsid(rname, bsid, test_srte_init_step1.__name__, False)
- create_sr_policy(rname, endpoint, bsid)
- add_candidate_path(rname, endpoint, 100, "default")
- check_bsid(rname, "1111" if rname == "rt1" else "6666", test_srte_init_step1.__name__, True)
- delete_candidate_path(rname, endpoint, 100)
-
-
-#
-# Step 2
-#
-# Checking pathd operational data using a single SR Policy and a single Candidate Path
-# Segment list are base in adjacency that query TED
-#
-def test_srte_bare_policy_step2():
- setup_testcase("Test (step 2): bare SR Policy should not be operational")
-
- for rname in ["rt1", "rt6"]:
- cmp_json_output_exact(
- rname,
- "show yang operational-data /frr-pathd:pathd pathd",
- "step2/show_operational_data.ref",
- )
-
-
-def test_srte_add_candidate_check_operational_data_step2():
- setup_testcase(
- "Test (step 2): add single Candidate Path, SR Policy should be operational"
- )
-
- for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
- add_candidate_path(rname, endpoint, 100, "default")
- cmp_json_output(
- rname,
- "show yang operational-data /frr-pathd:pathd pathd",
- "step2/show_operational_data_with_candidate.ref",
- )
-
-
-def test_srte_config_remove_candidate_check_operational_data_step2():
- setup_testcase(
- "Test (step 2): remove single Candidate Path, SR Policy should not be operational anymore"
- )
-
- for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
- delete_candidate_path(rname, endpoint, 100)
- cmp_json_output_exact(
- rname,
- "show yang operational-data /frr-pathd:pathd pathd",
- "step2/show_operational_data.ref",
- )
-
-
-#
-# Step 3
-#
-# Testing the Candidate Path selection
-# Segment list are based in adjacencies resolved by query TED
-#
-def test_srte_add_two_candidates_step3():
- setup_testcase("Test (step 3): second Candidate Path has higher Priority")
-
- for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
- for pref, cand_name in [("100", "first"), ("200", "second")]:
- add_candidate_path(rname, endpoint, pref, cand_name)
- cmp_json_output(
- rname,
- "show yang operational-data /frr-pathd:pathd pathd",
- "step3/show_operational_data_with_two_candidates.ref",
- )
-
- # cleanup
- for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
- for pref in ["100", "200"]:
- delete_candidate_path(rname, endpoint, pref)
-
-
-def test_srte_add_two_candidates_with_reverse_priority_step3():
- setup_testcase("Test (step 3): second Candidate Path has lower Priority")
-
- # Use reversed priorities here
- for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
- for pref, cand_name in [("200", "first"), ("100", "second")]:
- add_candidate_path(rname, endpoint, pref, cand_name)
- cmp_json_output(
- rname,
- "show yang operational-data /frr-pathd:pathd pathd",
- "step3/show_operational_data_with_two_candidates.ref",
- )
-
- # cleanup
- for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
- for pref in ["100", "200"]:
- delete_candidate_path(rname, endpoint, pref)
-
-
-def test_srte_remove_best_candidate_step3():
- setup_testcase("Test (step 3): delete the Candidate Path with higher priority")
-
- for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
- for pref, cand_name in [("100", "first"), ("200", "second")]:
- add_candidate_path(rname, endpoint, pref, cand_name)
-
- # Delete candidate with higher priority
- for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
- delete_candidate_path(rname, endpoint, 200)
-
- # Candidate with lower priority should get active now
- for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
- cmp_json_output(
- rname,
- "show yang operational-data /frr-pathd:pathd pathd",
- "step3/show_operational_data_with_single_candidate.ref",
- )
- # cleanup
- delete_candidate_path(rname, endpoint, 100)
-
-
-#
-# Step 4
-#
-# Checking MPLS table with a single SR Policy and a Candidate Path with different Segment Lists and other modifications
-# Segment list are base in adjacency that query TED
-#
-def test_srte_change_segment_list_check_mpls_table_step4():
- setup_testcase("Test (step 4): check MPLS table for changed Segment List")
-
- for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
- add_candidate_path(rname, endpoint, 100, "default")
- # now change the segment list name
- add_candidate_path(rname, endpoint, 100, "default", "test")
- check_bsid(rname, "1111" if rname == "rt1" else "6666", test_srte_init_step1.__name__, True)
- delete_segment(rname, "test", 10)
- delete_segment(rname, "test", 20)
- delete_segment(rname, "test", 30)
- delete_segment(rname, "test", 40)
- if rname == "rt1":
- add_segment_adj(rname, "test", 10, "10.0.1.1", "10.0.1.2")
- add_segment_adj(rname, "test", 20, "10.0.2.2", "10.0.2.4")
- add_segment_adj(rname, "test", 30, "10.0.6.4", "10.0.6.5")
- add_segment_adj(rname, "test", 40, "10.0.8.5", "10.0.8.6")
- else:
- add_segment_adj(rname, "test", 10, "10.0.8.6", "10.0.8.5")
- add_segment_adj(rname, "test", 20, "10.0.6.5", "10.0.6.4")
- add_segment_adj(rname, "test", 30, "10.0.2.4", "10.0.2.2")
- add_segment_adj(rname, "test", 40, "10.0.1.2", "10.0.1.1")
- check_bsid(rname, "1111" if rname == "rt1" else "6666", test_srte_init_step1.__name__, True)
- delete_candidate_path(rname, endpoint, 100)
-
-
-def test_srte_change_sl_priority_error_ted_check_mpls_table_step4():
- setup_testcase("Test (step 4): check MPLS table keeps low prio sl")
-
- for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
- add_candidate_path(rname, endpoint, 100, "default")
- # now change the segment list name
- add_candidate_path(rname, endpoint, 200, "test", "test")
- check_bsid(rname, "1111" if rname == "rt1" else "6666", test_srte_init_step1.__name__, True)
- delete_segment(rname, "test", 10)
- delete_segment(rname, "test", 20)
- delete_segment(rname, "test", 30)
- delete_segment(rname, "test", 40)
- # These won't resolv
- if rname == "rt1":
- add_segment_adj(rname, "test", 10, "10.0.1.99", "10.0.1.99")
- add_segment_adj(rname, "test", 20, "10.0.2.99", "10.0.2.99")
- add_segment_adj(rname, "test", 30, "10.0.6.99", "10.0.6.99")
- add_segment_adj(rname, "test", 40, "10.0.8.99", "10.0.8.99")
- else:
- add_segment_adj(rname, "test", 10, "10.0.8.99", "10.0.8.99")
- add_segment_adj(rname, "test", 20, "10.0.6.99", "10.0.6.99")
- add_segment_adj(rname, "test", 30, "10.0.2.99", "10.0.2.99")
- add_segment_adj(rname, "test", 40, "10.0.1.99", "10.0.1.99")
- # So policy sticks with default sl even higher prio
- check_bsid(rname, "1111" if rname == "rt1" else "6666", test_srte_init_step1.__name__, True)
- delete_candidate_path(rname, endpoint, 100)
-
-
-# Memory leak test template
-def test_memory_leak():
- "Run the memory leak test and report results."
- tgen = get_topogen()
- if not tgen.is_memleak_enabled():
- pytest.skip("Memory leak test/report is disabled")
-
- tgen.report_memory_leaks()
-
-
-if __name__ == "__main__":
- args = ["-s"] + sys.argv[1:]
- sys.exit(pytest.main(args))
--- /dev/null
+log file zebra.log
+!
+hostname dst
+!
+debug zebra kernel
+debug zebra packet
+debug zebra mpls
+!
+interface lo
+ ip address 9.9.9.2/32
+ ipv6 address 2001:db8:1066::2/128
+!
+interface eth-rt6
+ ip address 10.0.11.2/24
+ link-params
+ enable
+ exit-link-params
+!
+!
+ip forwarding
+!
+line vty
+!
--- /dev/null
+log file bgpd.log
+!
+router bgp 1
+ bgp router-id 1.1.1.1
+ neighbor 6.6.6.6 remote-as 1
+ neighbor 6.6.6.6 update-source lo
+ !
+ address-family ipv4 unicast
+ redistribute static
+ neighbor 6.6.6.6 next-hop-self
+ neighbor 6.6.6.6 route-map SET_SR_POLICY in
+ exit-address-family
+!
+route-map SET_SR_POLICY permit 10
+ set sr-te color 1
+!
--- /dev/null
+password 1
+hostname rt1
+log file ospfd.log
+!
+debug ospf sr
+debug ospf te
+debug ospf event
+debug ospf lsa
+debug ospf zebra
+!
+interface lo
+ ip ospf area 0.0.0.0
+!
+interface eth-sw1
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+router ospf
+ ospf router-id 1.1.1.1
+ network 1.1.1.1/32 area 0.0.0.0
+ network 10.0.0.0/16 area 0.0.0.0
+ capability opaque
+ !ospf opaque-lsa
+ mpls-te on
+ mpls-te export
+ mpls-te router-address 1.1.1.1
+ router-info area 0.0.0.0
+ passive-interface lo
+ segment-routing on
+ segment-routing global-block 16000 23999
+ !segment-routing local-block 15000 15999
+ segment-routing node-msd 8
+ segment-routing prefix 1.1.1.1/32 index 10
+!
--- /dev/null
+log file pathd.log
+!
+hostname rt1
+!
+segment-routing
+ traffic-eng
+ mpls-te on
+ mpls-te import ospfv2
+ segment-list default
+ index 10 nai adjacency 10.0.1.1 10.0.1.2
+ index 20 nai adjacency 10.0.2.2 10.0.2.4
+ index 30 nai adjacency 10.0.7.4 10.0.7.6
+
+
+ !
+ segment-list test
+ index 10 nai adjacency 10.0.1.1 10.0.1.2
+ index 20 nai adjacency 10.0.2.2 10.0.2.4
+ index 30 nai adjacency 10.0.6.4 10.0.6.5
+ index 40 nai adjacency 10.0.8.5 10.0.8.6
+ !
+ policy color 1 endpoint 6.6.6.6
+ name default
+ binding-sid 1111
+ !
+ !
+!
--- /dev/null
+{
+ "frr-pathd:pathd": {
+ "srte": {
+ "policy": [
+ {
+ "color": 1,
+ "endpoint": "6.6.6.6",
+ "is-operational": false
+ }
+ ]
+ }
+ }
+}
--- /dev/null
+{
+ "frr-pathd:pathd": {
+ "srte": {
+ "policy": [
+ {
+ "color": 1,
+ "endpoint": "6.6.6.6",
+ "is-operational": true,
+ "candidate-path": [
+ {
+ "preference": 100,
+ "discriminator": "*",
+ "is-best-candidate-path": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
--- /dev/null
+{
+ "frr-pathd:pathd": {
+ "srte": {
+ "policy": [
+ {
+ "color": 1,
+ "endpoint": "6.6.6.6",
+ "is-operational": true,
+ "candidate-path": [
+ {
+ "preference": 100,
+ "discriminator": "*",
+ "is-best-candidate-path": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
--- /dev/null
+{
+ "frr-pathd:pathd": {
+ "srte": {
+ "policy": [
+ {
+ "color": 1,
+ "endpoint": "6.6.6.6",
+ "is-operational": true,
+ "candidate-path": [
+ {
+ "preference": 100,
+ "discriminator": "*",
+ "is-best-candidate-path": false
+ },
+ {
+ "preference": 200,
+ "discriminator": "*",
+ "is-best-candidate-path": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
--- /dev/null
+log file zebra.log
+!
+hostname rt1
+!
+debug zebra kernel
+debug zebra packet
+debug zebra mpls
+!
+interface lo
+ ip address 1.1.1.1/32
+!
+interface eth-sw1
+ ip address 10.0.1.1/24
+ link-params
+ enable
+ exit-link-params
+!
+ip forwarding
+!
+line vty
+!
--- /dev/null
+hostname rt2
+log file ospfd.log
+!
+debug ospf sr
+debug ospf te
+debug ospf event
+debug ospf lsa
+debug ospf zebra
+!
+interface lo
+ ip ospf area 0.0.0.0
+!
+interface eth-sw1
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface eth-rt4-1
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface eth-rt4-2
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+router ospf
+ ospf router-id 2.2.2.2
+ network 2.2.2.2/32 area 0.0.0.0
+ network 10.0.0.0/16 area 0.0.0.0
+ capability opaque
+ !ospf opaque-lsa
+ mpls-te on
+ !mpls-te export
+ mpls-te router-address 2.2.2.2
+ router-info area 0.0.0.0
+ passive-interface lo
+ segment-routing on
+ segment-routing global-block 16000 23999
+ !segment-routing local-block 15000 15999
+ segment-routing node-msd 8
+ segment-routing prefix 2.2.2.2/32 index 20
+!
--- /dev/null
+log file zebra.log
+!
+hostname rt2
+!
+debug zebra kernel
+debug zebra packet
+debug zebra mpls
+!
+interface lo
+ ip address 2.2.2.2/32
+!
+interface eth-sw1
+ ip address 10.0.1.2/24
+ link-params
+ enable
+ exit-link-params
+!
+interface eth-rt4-1
+ ip address 10.0.2.2/24
+ link-params
+ enable
+ exit-link-params
+!
+!
+interface eth-rt4-2
+ ip address 10.0.3.2/24
+ link-params
+ enable
+ exit-link-params
+!
+!
+ip forwarding
+!
+line vty
+!
--- /dev/null
+hostname rt3
+log file ospfd.log
+!
+debug ospf sr
+debug ospf te
+debug ospf event
+debug ospf lsa
+debug ospf zebra
+!
+interface lo
+ ip ospf area 0.0.0.0
+!
+interface eth-sw1
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface eth-rt5-1
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface eth-rt5-2
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+router ospf
+ ospf router-id 3.3.3.3
+ network 3.3.3.3/32 area 0.0.0.0
+ network 10.0.0.0/16 area 0.0.0.0
+ capability opaque
+ !ospf opaque-lsa
+ mpls-te on
+ !mpls-te export
+ mpls-te router-address 3.3.3.3
+ router-info area 0.0.0.0
+ segment-routing on
+ segment-routing global-block 16000 23999
+ !segment-routing local-block 15000 15999
+ segment-routing node-msd 8
+ segment-routing prefix 3.3.3.3/32 index 30
+!
--- /dev/null
+log file zebra.log
+!
+hostname rt3
+!
+debug zebra kernel
+debug zebra packet
+debug zebra mpls
+!
+interface lo
+ ip address 3.3.3.3/32
+!
+interface eth-sw1
+ ip address 10.0.1.3/24
+ link-params
+ enable
+ exit-link-params
+!!
+interface eth-rt5-1
+ ip address 10.0.4.3/24
+ link-params
+ enable
+ exit-link-params
+!!
+interface eth-rt5-2
+ ip address 10.0.5.3/24
+ link-params
+ enable
+ exit-link-params
+!!
+ip forwarding
+!
+line vty
+!
--- /dev/null
+hostname rt4
+log file ospfd.log
+!
+debug ospf sr
+debug ospf te
+debug ospf event
+debug ospf lsa
+debug ospf zebra
+!
+interface lo
+ ip ospf area 0.0.0.0
+!
+interface eth-rt2-1
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface eth-rt2-2
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface eth-rt5
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface eth-rt6
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+router ospf
+ ospf router-id 4.4.4.4
+ network 4.4.4.4/32 area 0.0.0.0
+ network 10.0.0.0/16 area 0.0.0.0
+ capability opaque
+ !ospf opaque-lsa
+ mpls-te on
+ !mpls-te export
+ mpls-te router-address 4.4.4.4
+ router-info area 0.0.0.0
+ passive-interface lo
+ segment-routing on
+ segment-routing global-block 16000 23999
+ !segment-routing local-block 15000 15999
+ segment-routing node-msd 8
+ segment-routing prefix 4.4.4.4/32 index 40
+!
--- /dev/null
+log file zebra.log
+!
+hostname rt4
+!
+debug zebra kernel
+debug zebra packet
+debug zebra mpls
+!
+interface lo
+ ip address 4.4.4.4/32
+!
+interface eth-rt2-1
+ ip address 10.0.2.4/24
+ link-params
+ enable
+ exit-link-params
+!!
+!
+interface eth-rt2-2
+ ip address 10.0.3.4/24
+ link-params
+ enable
+ exit-link-params
+!!
+!
+interface eth-rt5
+ ip address 10.0.6.4/24
+ link-params
+ enable
+ exit-link-params
+!!
+!
+interface eth-rt6
+ ip address 10.0.7.4/24
+ link-params
+ enable
+ exit-link-params
+!!
+!
+ip forwarding
+!
+line vty
+!
--- /dev/null
+hostname rt5
+log file ospfd.log
+!
+debug ospf sr
+debug ospf te
+debug ospf event
+debug ospf lsa
+debug ospf zebra
+!
+interface lo
+ ip ospf area 0.0.0.0
+!
+interface eth-rt3-1
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface eth-rt3-2
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface eth-rt4
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface eth-rt6
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+router ospf
+ ospf router-id 5.5.5.5
+ network 5.5.5.5/32 area 0.0.0.0
+ network 10.0.0.0/16 area 0.0.0.0
+ capability opaque
+! ospf opaque-lsa
+ mpls-te on
+! mpls-te export
+ mpls-te router-address 5.5.5.5
+ router-info area 0.0.0.0
+ passive-interface lo
+ segment-routing on
+ segment-routing global-block 16000 23999
+! segment-routing local-block 15000 15999
+ segment-routing node-msd 8
+ segment-routing prefix 5.5.5.5/32 index 50
+!
--- /dev/null
+log file zebra.log
+!
+hostname rt5
+!
+debug zebra kernel
+debug zebra packet
+debug zebra mpls
+!
+interface lo
+ ip address 5.5.5.5/32
+!
+interface eth-rt3-1
+ ip address 10.0.4.5/24
+ link-params
+ enable
+ exit-link-params
+!!
+!
+interface eth-rt3-2
+ ip address 10.0.5.5/24
+ link-params
+ enable
+ exit-link-params
+!!
+!
+interface eth-rt4
+ ip address 10.0.6.5/24
+ link-params
+ enable
+ exit-link-params
+!!
+!
+interface eth-rt6
+ ip address 10.0.8.5/24
+ link-params
+ enable
+ exit-link-params
+!!
+!
+ip forwarding
+!
+line vty
+!
--- /dev/null
+log file bgpd.log
+!
+router bgp 1
+ bgp router-id 6.6.6.6
+ neighbor 1.1.1.1 remote-as 1
+ neighbor 1.1.1.1 update-source lo
+ !
+ address-family ipv4 unicast
+ redistribute static
+ neighbor 1.1.1.1 next-hop-self
+ exit-address-family
+!
--- /dev/null
+hostname rt6
+log file ospfd.log
+!
+debug ospf sr
+debug ospf te
+debug ospf event
+debug ospf lsa
+debug ospf zebra
+!
+interface lo
+ ip ospf area 0.0.0.0
+!
+interface eth-rt4
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface eth-rt5
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+router ospf
+ ospf router-id 6.6.6.6
+ network 6.6.6.6/32 area 0.0.0.0
+ network 10.0.0.0/16 area 0.0.0.0
+ capability opaque
+! ospf opaque-lsa
+ mpls-te on
+ mpls-te export
+ mpls-te router-address 6.6.6.6
+ router-info area 0.0.0.0
+ passive-interface lo
+ segment-routing on
+ segment-routing global-block 16000 23999
+! segment-routing local-block 15000 15999
+ segment-routing node-msd 8
+ segment-routing prefix 6.6.6.6/32 index 60
+!
--- /dev/null
+log file pathd.log
+!
+hostname rt6
+!
+segment-routing
+ traffic-eng
+ mpls-te on
+ mpls-te import ospfv2
+ segment-list default
+ index 10 nai adjacency 10.0.7.6 10.0.7.4
+ index 20 nai adjacency 10.0.2.4 10.0.2.2
+ index 30 nai adjacency 10.0.1.2 10.0.1.1
+ !
+ segment-list test
+ index 10 nai adjacency 10.0.8.6 10.0.8.5
+ index 20 nai adjacency 10.0.6.5 10.0.6.4
+ index 30 nai adjacency 10.0.2.4 10.0.2.2
+ index 40 nai adjacency 10.0.1.2 10.0.1.1
+ !
+ policy color 1 endpoint 1.1.1.1
+ name default
+ binding-sid 6666
+ !
+ !
+!
--- /dev/null
+{
+ "frr-pathd:pathd": {
+ "srte": {
+ "policy": [
+ {
+ "color": 1,
+ "endpoint": "1.1.1.1",
+ "is-operational": false
+ }
+ ]
+ }
+ }
+}
--- /dev/null
+{
+ "frr-pathd:pathd": {
+ "srte": {
+ "policy": [
+ {
+ "color": 1,
+ "endpoint": "1.1.1.1",
+ "is-operational": true,
+ "candidate-path": [
+ {
+ "preference": 100,
+ "is-best-candidate-path": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
--- /dev/null
+{
+ "frr-pathd:pathd": {
+ "srte": {
+ "policy": [
+ {
+ "color": 1,
+ "endpoint": "1.1.1.1",
+ "is-operational": true,
+ "candidate-path": [
+ {
+ "preference": 100,
+ "is-best-candidate-path": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
--- /dev/null
+{
+ "frr-pathd:pathd": {
+ "srte": {
+ "policy": [
+ {
+ "color": 1,
+ "endpoint": "1.1.1.1",
+ "is-operational": true,
+ "candidate-path": [
+ {
+ "preference": 100,
+ "is-best-candidate-path": false
+ },
+ {
+ "preference": 200,
+ "is-best-candidate-path": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
--- /dev/null
+log file zebra.log
+!
+hostname rt6
+!
+debug zebra kernel
+debug zebra packet
+debug zebra mpls
+!
+interface lo
+ ip address 6.6.6.6/32
+!
+interface eth-rt4
+ ip address 10.0.7.6/24
+ link-params
+ enable
+ exit-link-params
+!!
+!
+interface eth-rt5
+ ip address 10.0.8.6/24
+ link-params
+ enable
+ exit-link-params
+!!
+!
+interface eth-dst
+ ip address 10.0.11.1/24
+ link-params
+ enable
+ exit-link-params
+!!
+!
+ip forwarding
+!
+ip route 9.9.9.2/32 10.0.11.2
+!
+line vty
+!
--- /dev/null
+#!/usr/bin/env python
+
+#
+# test_ospf_sr_te_topo1.py
+#
+# Copyright (c) 2021 by
+# Volta Networks
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+test_ospf_sr_te_topo1.py:
+
+ +---------+
+ | |
+ | RT1 |
+ | 1.1.1.1 |
+ | |
+ +---------+
+ |eth-sw1
+ |
+ |
+ |
+ +---------+ | +---------+
+ | | | | |
+ | RT2 |eth-sw1 | eth-sw1| RT3 |
+ | 2.2.2.2 +----------+ + 3.3.3.3 |
+ | | 10.0.1.0/24 | |
+ +---------+ +---------+
+ eth-rt4-1| eth-rt5-1| |eth-rt5-2
+ | | |
+ 10.0.2.0/24| 10.0.4.0/24| |10.0.5.0/24
+ | | |
+ eth-rt2-1| eth-rt3-1| |eth-rt3-2
+ +---------+ +---------+
+ | | | |
+ | RT4 | 10.0.6.0/24 | RT5 |
+ | 4.4.4.4 +---------------------+ 5.5.5.5 |
+ | |eth-rt5 eth-rt4| |
+ +---------+ +---------+
+ eth-rt6| |eth-rt6
+ | |
+ 10.0.7.0/24| |10.0.8.0/24
+ | +---------+ |
+ | | | |
+ | | RT6 | |
+ +----------+ 6.6.6.6 +-----------+
+ eth-rt4| |eth-rt5
+ +---------+
+ |eth-dst (.1)
+ |
+ |10.0.11.0/24
+ |
+ |eth-rt6 (.2)
+ +---------+
+ | |
+ | DST |
+ | 9.9.9.2 |
+ | |
+ +---------+
+
+"""
+
+import os
+import sys
+import pytest
+import json
+import re
+from time import sleep
+from functools import partial
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+pytestmark = [pytest.mark.bgpd, pytest.mark.ospfd, pytest.mark.pathd]
+
+
+class TemplateTopo(Topo):
+ "Test topology builder"
+
+ def build(self, *_args, **_opts):
+ "Build function"
+ tgen = get_topogen(self)
+
+ #
+ # Define FRR Routers
+ #
+ for router in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6", "dst"]:
+ tgen.add_router(router)
+
+ #
+ # Define connections
+ #
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["rt1"], nodeif="eth-sw1")
+ switch.add_link(tgen.gears["rt2"], nodeif="eth-sw1")
+ #switch.add_link(tgen.gears["rt3"], nodeif="eth-sw1")
+
+ switch = tgen.add_switch("s2")
+ switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4-1")
+ switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2-1")
+
+ #switch = tgen.add_switch("s3")
+ #switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4-2")
+ #switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2-2")
+
+ switch = tgen.add_switch("s4")
+ switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5-1")
+ switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3-1")
+
+ switch = tgen.add_switch("s5")
+ switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5-2")
+ switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3-2")
+
+ switch = tgen.add_switch("s6")
+ switch.add_link(tgen.gears["rt4"], nodeif="eth-rt5")
+ switch.add_link(tgen.gears["rt5"], nodeif="eth-rt4")
+
+ switch = tgen.add_switch("s7")
+ switch.add_link(tgen.gears["rt4"], nodeif="eth-rt6")
+ switch.add_link(tgen.gears["rt6"], nodeif="eth-rt4")
+
+ switch = tgen.add_switch("s8")
+ switch.add_link(tgen.gears["rt5"], nodeif="eth-rt6")
+ switch.add_link(tgen.gears["rt6"], nodeif="eth-rt5")
+
+ switch = tgen.add_switch("s9")
+ switch.add_link(tgen.gears["rt6"], nodeif="eth-dst")
+ switch.add_link(tgen.gears["dst"], nodeif="eth-rt6")
+
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+
+ tgen = Topogen(TemplateTopo, mod.__name__)
+
+ frrdir = tgen.config.get(tgen.CONFIG_SECTION, "frrdir")
+ if not os.path.isfile(os.path.join(frrdir, "pathd")):
+ pytest.skip("pathd daemon wasn't built in:"+frrdir)
+
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+
+ # For all registered routers, load the zebra configuration file
+ for rname, router in router_list.items():
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_PATH, os.path.join(CWD, "{}/pathd.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+ )
+
+ tgen.start_router()
+
+
+def teardown_module(mod):
+ "Teardown the pytest environment"
+ tgen = get_topogen()
+
+ # This function tears down the whole topology.
+ tgen.stop_topology()
+
+
+def setup_testcase(msg):
+ logger.info(msg)
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ return tgen
+
+
+def print_cmd_result(rname, command):
+ print(get_topogen().gears[rname].vtysh_cmd(command, isjson=False))
+
+
+def compare_json_test(router, command, reference, exact):
+ output = router.vtysh_cmd(command, isjson=True)
+ result = topotest.json_cmp(output, reference)
+
+ # Note: topotest.json_cmp() just checks on inclusion of keys.
+ # For exact matching also compare the other way around.
+ if not result and exact:
+ return topotest.json_cmp(reference, output)
+ else:
+ return result
+
+
+def cmp_json_output(rname, command, reference, exact=False):
+ "Compare router JSON output"
+
+ logger.info('Comparing router "%s" "%s" output', rname, command)
+
+ tgen = get_topogen()
+ filename = "{}/{}/{}".format(CWD, rname, reference)
+ expected = json.loads(open(filename).read())
+
+ # Run test function until we get an result. Wait at most 60 seconds.
+ test_func = partial(compare_json_test, tgen.gears[rname], command, expected, exact)
+ _, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
+ assert diff is None, assertmsg
+
+
+def cmp_json_output_exact(rname, command, reference):
+ return cmp_json_output(rname, command, reference, True)
+
+
+def add_candidate_path(rname, endpoint, pref, name, segment_list="default"):
+ get_topogen().net[rname].cmd(
+ """ \
+ vtysh -c "conf t" \
+ -c "segment-routing" \
+ -c "traffic-eng" \
+ -c "policy color 1 endpoint """
+ + endpoint
+ + """" \
+ -c "candidate-path preference """
+ + str(pref)
+ + """ name """
+ + name
+ + """ explicit segment-list """
+ + segment_list
+ + '''"'''
+ )
+
+
+def delete_candidate_path(rname, endpoint, pref):
+ get_topogen().net[rname].cmd(
+ """ \
+ vtysh -c "conf t" \
+ -c "segment-routing" \
+ -c "traffic-eng" \
+ -c "policy color 1 endpoint """
+ + endpoint
+ + """" \
+ -c "no candidate-path preference """
+ + str(pref)
+ + '''"'''
+ )
+
+
+def add_segment(rname, name, index, label):
+ get_topogen().net[rname].cmd(
+ """ \
+ vtysh -c "conf t" \
+ -c "segment-routing" \
+ -c "traffic-eng" \
+ -c "segment-list """
+ + name
+ + """" \
+ -c "index """
+ + str(index)
+ + """ mpls label """
+ + str(label)
+ + '''"'''
+ )
+
+
+def delete_segment(rname, name, index):
+ get_topogen().net[rname].cmd(
+ """ \
+ vtysh -c "conf t" \
+ -c "segment-routing" \
+ -c "traffic-eng" \
+ -c "segment-list """
+ + name
+ + """" \
+ -c "no index """
+ + str(index)
+ + '''"'''
+ )
+
+
+def add_segment_adj(rname, name, index, src, dst):
+ get_topogen().net[rname].cmd(
+ """ \
+ vtysh -c "conf t" \
+ -c "segment-routing" \
+ -c "traffic-eng" \
+ -c "segment-list """
+ + name
+ + """" \
+ -c "index """
+ + str(index)
+ + """ nai adjacency """
+ + str(src)
+ + """ """
+ + str(dst)
+ + '''"'''
+ )
+
+
+def create_sr_policy(rname, endpoint, bsid):
+ get_topogen().net[rname].cmd(
+ """ \
+ vtysh -c "conf t" \
+ -c "segment-routing" \
+ -c "traffic-eng" \
+ -c "policy color 1 endpoint """
+ + endpoint
+ + """" \
+ -c "name default" \
+ -c "binding-sid """
+ + str(bsid)
+ + '''"'''
+ )
+
+
+def delete_sr_policy(rname, endpoint):
+ get_topogen().net[rname].cmd(
+ """ \
+ vtysh -c "conf t" \
+ -c "segment-routing" \
+ -c "traffic-eng" \
+ -c "no policy color 1 endpoint """
+ + endpoint
+ + '''"'''
+ )
+
+
+def create_prefix_sid(rname, prefix, sid):
+ get_topogen().net[rname].cmd(
+ """ \
+ vtysh -c "conf t" \
+ -c "router ospf " \
+ -c "segment-routing prefix """
+ + prefix
+ + " index "
+ + str(sid)
+ + '''"'''
+ )
+
+
+def delete_prefix_sid(rname, prefix):
+ get_topogen().net[rname].cmd(
+ ''' \
+ vtysh -c "conf t" \
+ -c "router ospf " \
+ -c "no segment-routing prefix "'''
+ + prefix
+ )
+
+
+def check_bsid(rt, bsid, fn_name, positive):
+ """
+ Search for a bsid in rt1 and rt6
+ Positive means that check is true is bsid is found
+ Positive="False" means that check is true is bsid is NOT found
+ """
+
+ logger.info('Checking "%s" bsid "%s" for router "%s" ', positive, bsid, rt)
+
+ count = 0
+ candidate_key = bsid
+ candidate_output = ""
+ # First wait for convergence
+ tgen = get_topogen()
+ while count < 30:
+ matched = False
+ matched_key = False
+ sleep(1)
+ count += 1
+ router = tgen.gears[rt]
+ candidate_output = router.vtysh_cmd("show mpls table json")
+ candidate_output_json = json.loads(candidate_output)
+ for item in candidate_output_json.items():
+ # logger.info('item "%s"', item)
+ if item[0] == candidate_key:
+ matched_key = True
+ if positive:
+ break
+ if positive:
+ if matched_key:
+ matched = True
+ assertmsg = "{} don't has entry {} but is was expected".format(
+ router.name, candidate_key)
+ else:
+ if not matched_key:
+ matched = True
+ assertmsg = "{} has entry {} but is wans't expected".format(
+ router.name, candidate_key)
+ if matched:
+ logger.info('Success "%s" in "%s"', router.name, fn_name)
+ return
+ assert matched, assertmsg
+
+
+#
+# Step 1
+#
+# Checking the MPLS table using a single SR Policy and a single Candidate Path
+# Segment list are base in adjacency that query TED
+#
+def test_srte_init_step1():
+ setup_testcase("Test (step 1): wait OSPF convergence / label distribution")
+
+ check_bsid("rt1", "1111", test_srte_init_step1.__name__, False)
+ check_bsid("rt6", "6666", test_srte_init_step1.__name__, False)
+
+
+def test_srte_add_candidate_check_mpls_table_step1():
+ setup_testcase("Test (step 1): check MPLS table regarding the added Candidate Path")
+
+ for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
+ add_candidate_path(rname, endpoint, 100, "default")
+ check_bsid(rname, "1111" if rname == "rt1" else "6666", test_srte_init_step1.__name__, True)
+ delete_candidate_path(rname, endpoint, 100)
+
+
+def test_srte_reinstall_sr_policy_check_mpls_table_step1():
+ setup_testcase(
+ "Test (step 1): check MPLS table after the SR Policy was removed and reinstalled"
+ )
+
+ for rname, endpoint, bsid in [("rt1", "6.6.6.6", 1111), ("rt6", "1.1.1.1", 6666)]:
+ add_candidate_path(rname, endpoint, 100, "default")
+ delete_sr_policy(rname, endpoint)
+ check_bsid(rname, bsid, test_srte_init_step1.__name__, False)
+ create_sr_policy(rname, endpoint, bsid)
+ add_candidate_path(rname, endpoint, 100, "default")
+ check_bsid(rname, "1111" if rname == "rt1" else "6666", test_srte_init_step1.__name__, True)
+ delete_candidate_path(rname, endpoint, 100)
+
+
+#
+# Step 2
+#
+# Checking pathd operational data using a single SR Policy and a single Candidate Path
+# Segment list are base in adjacency that query TED
+#
+def test_srte_bare_policy_step2():
+ setup_testcase("Test (step 2): bare SR Policy should not be operational")
+
+ for rname in ["rt1", "rt6"]:
+ cmp_json_output_exact(
+ rname,
+ "show yang operational-data /frr-pathd:pathd pathd",
+ "step2/show_operational_data.ref",
+ )
+
+
+def test_srte_add_candidate_check_operational_data_step2():
+ setup_testcase(
+ "Test (step 2): add single Candidate Path, SR Policy should be operational"
+ )
+
+ for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
+ add_candidate_path(rname, endpoint, 100, "default")
+ cmp_json_output(
+ rname,
+ "show yang operational-data /frr-pathd:pathd pathd",
+ "step2/show_operational_data_with_candidate.ref",
+ )
+
+
+def test_srte_config_remove_candidate_check_operational_data_step2():
+ setup_testcase(
+ "Test (step 2): remove single Candidate Path, SR Policy should not be operational anymore"
+ )
+
+ for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
+ delete_candidate_path(rname, endpoint, 100)
+ cmp_json_output_exact(
+ rname,
+ "show yang operational-data /frr-pathd:pathd pathd",
+ "step2/show_operational_data.ref",
+ )
+
+
+#
+# Step 3
+#
+# Testing the Candidate Path selection
+# Segment list are based in adjacencies resolved by query TED
+#
+def test_srte_add_two_candidates_step3():
+ setup_testcase("Test (step 3): second Candidate Path has higher Priority")
+
+ for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
+ for pref, cand_name in [("100", "first"), ("200", "second")]:
+ add_candidate_path(rname, endpoint, pref, cand_name)
+ cmp_json_output(
+ rname,
+ "show yang operational-data /frr-pathd:pathd pathd",
+ "step3/show_operational_data_with_two_candidates.ref",
+ )
+
+ # cleanup
+ for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
+ for pref in ["100", "200"]:
+ delete_candidate_path(rname, endpoint, pref)
+
+
+def test_srte_add_two_candidates_with_reverse_priority_step3():
+ setup_testcase("Test (step 3): second Candidate Path has lower Priority")
+
+ # Use reversed priorities here
+ for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
+ for pref, cand_name in [("200", "first"), ("100", "second")]:
+ add_candidate_path(rname, endpoint, pref, cand_name)
+ cmp_json_output(
+ rname,
+ "show yang operational-data /frr-pathd:pathd pathd",
+ "step3/show_operational_data_with_two_candidates.ref",
+ )
+
+ # cleanup
+ for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
+ for pref in ["100", "200"]:
+ delete_candidate_path(rname, endpoint, pref)
+
+
+def test_srte_remove_best_candidate_step3():
+ setup_testcase("Test (step 3): delete the Candidate Path with higher priority")
+
+ for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
+ for pref, cand_name in [("100", "first"), ("200", "second")]:
+ add_candidate_path(rname, endpoint, pref, cand_name)
+
+ # Delete candidate with higher priority
+ for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
+ delete_candidate_path(rname, endpoint, 200)
+
+ # Candidate with lower priority should get active now
+ for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
+ cmp_json_output(
+ rname,
+ "show yang operational-data /frr-pathd:pathd pathd",
+ "step3/show_operational_data_with_single_candidate.ref",
+ )
+ # cleanup
+ delete_candidate_path(rname, endpoint, 100)
+
+
+#
+# Step 4
+#
+# Checking MPLS table with a single SR Policy and a Candidate Path with different Segment Lists and other modifications
+# Segment list are base in adjacency that query TED
+#
+def test_srte_change_segment_list_check_mpls_table_step4():
+ setup_testcase("Test (step 4): check MPLS table for changed Segment List")
+
+ for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
+ add_candidate_path(rname, endpoint, 100, "default")
+ # now change the segment list name
+ add_candidate_path(rname, endpoint, 100, "default", "test")
+ check_bsid(rname, "1111" if rname == "rt1" else "6666", test_srte_init_step1.__name__, True)
+ delete_segment(rname, "test", 10)
+ delete_segment(rname, "test", 20)
+ delete_segment(rname, "test", 30)
+ delete_segment(rname, "test", 40)
+ if rname == "rt1":
+ add_segment_adj(rname, "test", 10, "10.0.1.1", "10.0.1.2")
+ add_segment_adj(rname, "test", 20, "10.0.2.2", "10.0.2.4")
+ add_segment_adj(rname, "test", 30, "10.0.6.4", "10.0.6.5")
+ add_segment_adj(rname, "test", 40, "10.0.8.5", "10.0.8.6")
+ else:
+ add_segment_adj(rname, "test", 10, "10.0.8.6", "10.0.8.5")
+ add_segment_adj(rname, "test", 20, "10.0.6.5", "10.0.6.4")
+ add_segment_adj(rname, "test", 30, "10.0.2.4", "10.0.2.2")
+ add_segment_adj(rname, "test", 40, "10.0.1.2", "10.0.1.1")
+ check_bsid(rname, "1111" if rname == "rt1" else "6666", test_srte_init_step1.__name__, True)
+ delete_candidate_path(rname, endpoint, 100)
+
+
+def test_srte_change_sl_priority_error_ted_check_mpls_table_step4():
+ setup_testcase("Test (step 4): check MPLS table keeps low prio sl")
+
+ for rname, endpoint in [("rt1", "6.6.6.6"), ("rt6", "1.1.1.1")]:
+ add_candidate_path(rname, endpoint, 100, "default")
+ # now change the segment list name
+ add_candidate_path(rname, endpoint, 200, "test", "test")
+ check_bsid(rname, "1111" if rname == "rt1" else "6666", test_srte_init_step1.__name__, True)
+ delete_segment(rname, "test", 10)
+ delete_segment(rname, "test", 20)
+ delete_segment(rname, "test", 30)
+ delete_segment(rname, "test", 40)
+ # These won't resolv
+ if rname == "rt1":
+ add_segment_adj(rname, "test", 10, "10.0.1.99", "10.0.1.99")
+ add_segment_adj(rname, "test", 20, "10.0.2.99", "10.0.2.99")
+ add_segment_adj(rname, "test", 30, "10.0.6.99", "10.0.6.99")
+ add_segment_adj(rname, "test", 40, "10.0.8.99", "10.0.8.99")
+ else:
+ add_segment_adj(rname, "test", 10, "10.0.8.99", "10.0.8.99")
+ add_segment_adj(rname, "test", 20, "10.0.6.99", "10.0.6.99")
+ add_segment_adj(rname, "test", 30, "10.0.2.99", "10.0.2.99")
+ add_segment_adj(rname, "test", 40, "10.0.1.99", "10.0.1.99")
+ # So policy sticks with default sl even higher prio
+ check_bsid(rname, "1111" if rname == "rt1" else "6666", test_srte_init_step1.__name__, True)
+ delete_candidate_path(rname, endpoint, 100)
+
+
+# Memory leak test template
+def test_memory_leak():
+ "Run the memory leak test and report results."
+ tgen = get_topogen()
+ if not tgen.is_memleak_enabled():
+ pytest.skip("Memory leak test/report is disabled")
+
+ tgen.report_memory_leaks()
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))