forked from Mirror/frr
Merge pull request #17491 from pguibert6WIND/bgp_evpn_rt5_routemap
Bgp evpn rt5 routemap
This commit is contained in:
commit
8c9cd28aaa
131
tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json
Normal file
131
tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
{
|
||||||
|
"bgpLocalRouterId":"192.168.100.21",
|
||||||
|
"defaultLocPrf":100,
|
||||||
|
"localAS":65000,
|
||||||
|
"192.168.101.41:2":{
|
||||||
|
"rd":"192.168.101.41:2",
|
||||||
|
"[5]:[0]:[32]:[192.168.101.41]":{
|
||||||
|
"prefix":"[5]:[0]:[32]:[192.168.101.41]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"internal",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":32,
|
||||||
|
"ip":"192.168.101.41",
|
||||||
|
"metric":0,
|
||||||
|
"locPrf":100,
|
||||||
|
"weight":0,
|
||||||
|
"peerId":"192.168.100.41",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.41",
|
||||||
|
"hostname":"r2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"[5]:[0]:[128]:[fd00::2]":{
|
||||||
|
"prefix":"[5]:[0]:[128]:[fd00::2]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"internal",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":128,
|
||||||
|
"ip":"fd00::2",
|
||||||
|
"metric":0,
|
||||||
|
"locPrf":100,
|
||||||
|
"weight":0,
|
||||||
|
"peerId":"192.168.100.41",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.41",
|
||||||
|
"hostname":"r2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"192.168.102.21:2":{
|
||||||
|
"rd":"192.168.102.21:2",
|
||||||
|
"[5]:[0]:[32]:[192.168.102.21]":{
|
||||||
|
"prefix":"[5]:[0]:[32]:[192.168.102.21]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"external",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":32,
|
||||||
|
"ip":"192.168.102.21",
|
||||||
|
"metric":0,
|
||||||
|
"weight":32768,
|
||||||
|
"peerId":"(unspec)",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.21",
|
||||||
|
"hostname":"r1",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"[5]:[0]:[128]:[fd00::1]":{
|
||||||
|
"prefix":"[5]:[0]:[128]:[fd00::1]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"external",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":128,
|
||||||
|
"ip":"fd00::1",
|
||||||
|
"metric":0,
|
||||||
|
"weight":32768,
|
||||||
|
"peerId":"(unspec)",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.21",
|
||||||
|
"hostname":"r1",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"numPrefix":4,
|
||||||
|
"totalPrefix":4
|
||||||
|
}
|
191
tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json
Normal file
191
tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
{
|
||||||
|
"bgpLocalRouterId":"192.168.100.21",
|
||||||
|
"defaultLocPrf":100,
|
||||||
|
"localAS":65000,
|
||||||
|
"192.168.101.41:2":{
|
||||||
|
"rd":"192.168.101.41:2",
|
||||||
|
"[5]:[0]:[32]:[192.168.101.41]":{
|
||||||
|
"prefix":"[5]:[0]:[32]:[192.168.101.41]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"internal",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":32,
|
||||||
|
"ip":"192.168.101.41",
|
||||||
|
"metric":0,
|
||||||
|
"locPrf":100,
|
||||||
|
"weight":0,
|
||||||
|
"peerId":"192.168.100.41",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.41",
|
||||||
|
"hostname":"r2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"[5]:[0]:[32]:[192.168.102.41]":{
|
||||||
|
"prefix":"[5]:[0]:[32]:[192.168.102.41]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"internal",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":32,
|
||||||
|
"ip":"192.168.102.41",
|
||||||
|
"metric":0,
|
||||||
|
"locPrf":100,
|
||||||
|
"weight":0,
|
||||||
|
"peerId":"192.168.100.41",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.41",
|
||||||
|
"hostname":"r2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"[5]:[0]:[128]:[fd00::2]":{
|
||||||
|
"prefix":"[5]:[0]:[128]:[fd00::2]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"internal",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":128,
|
||||||
|
"ip":"fd00::2",
|
||||||
|
"metric":0,
|
||||||
|
"locPrf":100,
|
||||||
|
"weight":0,
|
||||||
|
"peerId":"192.168.100.41",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.41",
|
||||||
|
"hostname":"r2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"[5]:[0]:[128]:[fd00::3]":{
|
||||||
|
"prefix":"[5]:[0]:[128]:[fd00::3]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"internal",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":128,
|
||||||
|
"ip":"fd00::3",
|
||||||
|
"metric":0,
|
||||||
|
"locPrf":100,
|
||||||
|
"weight":0,
|
||||||
|
"peerId":"192.168.100.41",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.41",
|
||||||
|
"hostname":"r2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"192.168.102.21:2":{
|
||||||
|
"rd":"192.168.102.21:2",
|
||||||
|
"[5]:[0]:[32]:[192.168.102.21]":{
|
||||||
|
"prefix":"[5]:[0]:[32]:[192.168.102.21]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"external",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":32,
|
||||||
|
"ip":"192.168.102.21",
|
||||||
|
"metric":0,
|
||||||
|
"weight":32768,
|
||||||
|
"peerId":"(unspec)",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.21",
|
||||||
|
"hostname":"r1",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"[5]:[0]:[128]:[fd00::1]":{
|
||||||
|
"prefix":"[5]:[0]:[128]:[fd00::1]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"external",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":128,
|
||||||
|
"ip":"fd00::1",
|
||||||
|
"metric":0,
|
||||||
|
"weight":32768,
|
||||||
|
"peerId":"(unspec)",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.21",
|
||||||
|
"hostname":"r1",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"numPrefix":6,
|
||||||
|
"totalPrefix":6
|
||||||
|
}
|
131
tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json
Normal file
131
tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
{
|
||||||
|
"bgpLocalRouterId":"192.168.100.41",
|
||||||
|
"defaultLocPrf":100,
|
||||||
|
"localAS":65000,
|
||||||
|
"192.168.101.41:2":{
|
||||||
|
"rd":"192.168.101.41:2",
|
||||||
|
"[5]:[0]:[32]:[192.168.101.41]":{
|
||||||
|
"prefix":"[5]:[0]:[32]:[192.168.101.41]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"external",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":32,
|
||||||
|
"ip":"192.168.101.41",
|
||||||
|
"metric":0,
|
||||||
|
"weight":32768,
|
||||||
|
"peerId":"(unspec)",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.41",
|
||||||
|
"hostname":"r2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"[5]:[0]:[128]:[fd00::2]":{
|
||||||
|
"prefix":"[5]:[0]:[128]:[fd00::2]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"external",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":128,
|
||||||
|
"ip":"fd00::2",
|
||||||
|
"metric":0,
|
||||||
|
"weight":32768,
|
||||||
|
"peerId":"(unspec)",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.41",
|
||||||
|
"hostname":"r2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"192.168.102.21:2":{
|
||||||
|
"rd":"192.168.102.21:2",
|
||||||
|
"[5]:[0]:[32]:[192.168.102.21]":{
|
||||||
|
"prefix":"[5]:[0]:[32]:[192.168.102.21]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"internal",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":32,
|
||||||
|
"ip":"192.168.102.21",
|
||||||
|
"metric":0,
|
||||||
|
"locPrf":100,
|
||||||
|
"weight":0,
|
||||||
|
"peerId":"192.168.100.21",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.21",
|
||||||
|
"hostname":"r1",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"[5]:[0]:[128]:[fd00::1]":{
|
||||||
|
"prefix":"[5]:[0]:[128]:[fd00::1]",
|
||||||
|
"prefixLen":352,
|
||||||
|
"paths":[
|
||||||
|
{
|
||||||
|
"valid":true,
|
||||||
|
"bestpath":true,
|
||||||
|
"selectionReason":"First path received",
|
||||||
|
"pathFrom":"internal",
|
||||||
|
"routeType":5,
|
||||||
|
"ethTag":0,
|
||||||
|
"ipLen":128,
|
||||||
|
"ip":"fd00::1",
|
||||||
|
"metric":0,
|
||||||
|
"locPrf":100,
|
||||||
|
"weight":0,
|
||||||
|
"peerId":"192.168.100.21",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.168.100.21",
|
||||||
|
"hostname":"r1",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"numPrefix":4,
|
||||||
|
"totalPrefix":4
|
||||||
|
}
|
|
@ -20,12 +20,30 @@ router bgp 65000 vrf r2-vrf-101
|
||||||
no bgp network import-check
|
no bgp network import-check
|
||||||
address-family ipv4 unicast
|
address-family ipv4 unicast
|
||||||
network 192.168.101.41/32
|
network 192.168.101.41/32
|
||||||
|
network 192.168.102.41/32
|
||||||
exit-address-family
|
exit-address-family
|
||||||
address-family ipv6 unicast
|
address-family ipv6 unicast
|
||||||
network fd00::2/128
|
network fd00::2/128
|
||||||
|
network fd00::3/128
|
||||||
exit-address-family
|
exit-address-family
|
||||||
address-family l2vpn evpn
|
address-family l2vpn evpn
|
||||||
advertise ipv4 unicast
|
advertise ipv4 unicast route-map rmap4
|
||||||
advertise ipv6 unicast
|
advertise ipv6 unicast route-map rmap6
|
||||||
exit-address-family
|
exit-address-family
|
||||||
!
|
!
|
||||||
|
access-list acl4_1 seq 10 permit 192.168.101.41/32
|
||||||
|
access-list acl4_2 seq 10 permit 192.168.102.41/32
|
||||||
|
ipv6 access-list acl6_1 seq 10 permit fd00::2/128
|
||||||
|
ipv6 access-list acl6_2 seq 10 permit fd00::3/128
|
||||||
|
route-map rmap4 permit 1
|
||||||
|
match ip address acl4_1
|
||||||
|
exit
|
||||||
|
route-map rmap4 deny 2
|
||||||
|
match ip address acl4_2
|
||||||
|
exit
|
||||||
|
route-map rmap6 permit 1
|
||||||
|
match ipv6 address acl6_1
|
||||||
|
exit
|
||||||
|
route-map rmap6 deny 2
|
||||||
|
match ipv6 address acl6_2
|
||||||
|
exit
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
with route advertisements on a separate netns.
|
with route advertisements on a separate netns.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
from functools import partial
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -160,6 +162,36 @@ def teardown_module(_mod):
|
||||||
tgen.stop_topology()
|
tgen.stop_topology()
|
||||||
|
|
||||||
|
|
||||||
|
def _test_evpn_ping_router(pingrouter, ipv4_only=False):
|
||||||
|
"""
|
||||||
|
internal function to check ping between r1 and r2
|
||||||
|
"""
|
||||||
|
# Check IPv4 and IPv6 connectivity between r1 and r2 ( routing vxlan evpn)
|
||||||
|
logger.info(
|
||||||
|
"Check Ping IPv4 from R1(r1-vrf-101) to R2(r2-vrf-101 = 192.168.101.41)"
|
||||||
|
)
|
||||||
|
output = pingrouter.run("ip netns exec r1-vrf-101 ping 192.168.101.41 -f -c 1000")
|
||||||
|
logger.info(output)
|
||||||
|
if "1000 packets transmitted, 1000 received" not in output:
|
||||||
|
assertmsg = (
|
||||||
|
"expected ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) should be ok"
|
||||||
|
)
|
||||||
|
assert 0, assertmsg
|
||||||
|
else:
|
||||||
|
logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK")
|
||||||
|
|
||||||
|
if ipv4_only:
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(r2-vrf-101 = fd00::2)")
|
||||||
|
output = pingrouter.run("ip netns exec r1-vrf-101 ping fd00::2 -f -c 1000")
|
||||||
|
logger.info(output)
|
||||||
|
if "1000 packets transmitted, 1000 received" not in output:
|
||||||
|
assert 0, "expected ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) should be ok"
|
||||||
|
else:
|
||||||
|
logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) OK")
|
||||||
|
|
||||||
|
|
||||||
def test_protocols_convergence():
|
def test_protocols_convergence():
|
||||||
"""
|
"""
|
||||||
Assert that all protocols have converged
|
Assert that all protocols have converged
|
||||||
|
@ -168,7 +200,34 @@ def test_protocols_convergence():
|
||||||
tgen = get_topogen()
|
tgen = get_topogen()
|
||||||
if tgen.routers_have_failure():
|
if tgen.routers_have_failure():
|
||||||
pytest.skip(tgen.errors)
|
pytest.skip(tgen.errors)
|
||||||
topotest.sleep(4, "waiting 4 seconds for bgp convergence")
|
# Check BGP IPv4 routing tables on r1
|
||||||
|
logger.info("Checking BGP L2VPN EVPN routes for convergence on r1")
|
||||||
|
|
||||||
|
for rname in ("r1", "r2"):
|
||||||
|
router = tgen.gears[rname]
|
||||||
|
json_file = "{}/{}/bgp_l2vpn_evpn_routes.json".format(CWD, router.name)
|
||||||
|
if not os.path.isfile(json_file):
|
||||||
|
assert 0, "bgp_l2vpn_evpn_routes.json file not found"
|
||||||
|
|
||||||
|
expected = json.loads(open(json_file).read())
|
||||||
|
test_func = partial(
|
||||||
|
topotest.router_json_cmp,
|
||||||
|
router,
|
||||||
|
"show bgp l2vpn evpn json",
|
||||||
|
expected,
|
||||||
|
)
|
||||||
|
_, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
|
||||||
|
assertmsg = '"{}" JSON output mismatches'.format(router.name)
|
||||||
|
assert result is None, assertmsg
|
||||||
|
|
||||||
|
|
||||||
|
def test_protocols_dump_info():
|
||||||
|
"""
|
||||||
|
Dump EVPN information
|
||||||
|
"""
|
||||||
|
tgen = get_topogen()
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
# Check IPv4/IPv6 routing tables.
|
# Check IPv4/IPv6 routing tables.
|
||||||
output = tgen.gears["r1"].vtysh_cmd("show bgp l2vpn evpn", isjson=False)
|
output = tgen.gears["r1"].vtysh_cmd("show bgp l2vpn evpn", isjson=False)
|
||||||
logger.info("==== result from show bgp l2vpn evpn")
|
logger.info("==== result from show bgp l2vpn evpn")
|
||||||
|
@ -203,6 +262,15 @@ def test_protocols_convergence():
|
||||||
logger.info("==== result from show evpn rmac vni all")
|
logger.info("==== result from show evpn rmac vni all")
|
||||||
logger.info(output)
|
logger.info(output)
|
||||||
|
|
||||||
|
|
||||||
|
def test_router_check_ip():
|
||||||
|
"""
|
||||||
|
Check routes are correctly installed
|
||||||
|
"""
|
||||||
|
tgen = get_topogen()
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
expected = {
|
expected = {
|
||||||
"fd00::2/128": [
|
"fd00::2/128": [
|
||||||
{
|
{
|
||||||
|
@ -221,56 +289,112 @@ def test_protocols_convergence():
|
||||||
)
|
)
|
||||||
assert result is None, "ipv6 route check failed"
|
assert result is None, "ipv6 route check failed"
|
||||||
|
|
||||||
expected = {
|
|
||||||
"101": {
|
def _test_router_check_evpn_contexts(router, ipv4_only=False):
|
||||||
"numNextHops": 2,
|
"""
|
||||||
"192.168.100.41": {
|
Check EVPN nexthops and RMAC number are correctly configured
|
||||||
"nexthopIp": "192.168.100.41",
|
"""
|
||||||
},
|
if ipv4_only:
|
||||||
"::ffff:192.168.100.41": {
|
expected = {
|
||||||
"nexthopIp": "::ffff:192.168.100.41",
|
"101": {
|
||||||
},
|
"numNextHops": 1,
|
||||||
|
"192.168.100.41": {
|
||||||
|
"nexthopIp": "192.168.100.41",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
expected = {
|
||||||
|
"101": {
|
||||||
|
"numNextHops": 2,
|
||||||
|
"192.168.100.41": {
|
||||||
|
"nexthopIp": "192.168.100.41",
|
||||||
|
},
|
||||||
|
"::ffff:192.168.100.41": {
|
||||||
|
"nexthopIp": "::ffff:192.168.100.41",
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
result = topotest.router_json_cmp(
|
result = topotest.router_json_cmp(
|
||||||
tgen.gears["r1"], "show evpn next-hops vni all json", expected
|
router, "show evpn next-hops vni all json", expected
|
||||||
)
|
)
|
||||||
assert result is None, "evpn next-hops check failed"
|
assert result is None, "evpn next-hops check failed"
|
||||||
|
|
||||||
expected = {"101": {"numRmacs": 1}}
|
expected = {"101": {"numRmacs": 1}}
|
||||||
result = topotest.router_json_cmp(
|
result = topotest.router_json_cmp(router, "show evpn rmac vni all json", expected)
|
||||||
tgen.gears["r1"], "show evpn rmac vni all json", expected
|
|
||||||
)
|
|
||||||
assert result is None, "evpn rmac number check failed"
|
assert result is None, "evpn rmac number check failed"
|
||||||
|
|
||||||
# Check IPv4 and IPv6 connectivity between r1 and r2 ( routing vxlan evpn)
|
|
||||||
pingrouter = tgen.gears["r1"]
|
|
||||||
logger.info(
|
|
||||||
"Check Ping IPv4 from R1(r1-vrf-101) to R2(r2-vrf-101 = 192.168.101.41)"
|
|
||||||
)
|
|
||||||
output = pingrouter.run("ip netns exec r1-vrf-101 ping 192.168.101.41 -f -c 1000")
|
|
||||||
logger.info(output)
|
|
||||||
if "1000 packets transmitted, 1000 received" not in output:
|
|
||||||
assertmsg = (
|
|
||||||
"expected ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) should be ok"
|
|
||||||
)
|
|
||||||
assert 0, assertmsg
|
|
||||||
else:
|
|
||||||
logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK")
|
|
||||||
|
|
||||||
logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(r2-vrf-101 = fd00::2)")
|
def test_router_check_evpn_contexts():
|
||||||
output = pingrouter.run("ip netns exec r1-vrf-101 ping fd00::2 -f -c 1000")
|
"""
|
||||||
logger.info(output)
|
Check EVPN nexthops and RMAC number are correctly configured
|
||||||
if "1000 packets transmitted, 1000 received" not in output:
|
"""
|
||||||
assert 0, "expected ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) should be ok"
|
tgen = get_topogen()
|
||||||
else:
|
if tgen.routers_have_failure():
|
||||||
logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) OK")
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
_test_router_check_evpn_contexts(tgen.gears["r1"])
|
||||||
|
|
||||||
|
|
||||||
|
def test_evpn_ping():
|
||||||
|
"""
|
||||||
|
Check ping between R1 and R2 is ok
|
||||||
|
"""
|
||||||
|
tgen = get_topogen()
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
_test_evpn_ping_router(tgen.gears["r1"])
|
||||||
|
|
||||||
|
|
||||||
|
def test_evpn_disable_routemap():
|
||||||
|
"""
|
||||||
|
Check the removal of a route-map on R2. More EVPN Prefixes are expected
|
||||||
|
"""
|
||||||
|
tgen = get_topogen()
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
tgen.gears["r2"].vtysh_cmd(
|
||||||
|
"""
|
||||||
|
configure terminal\n
|
||||||
|
router bgp 65000 vrf r2-vrf-101\n
|
||||||
|
address-family l2vpn evpn\n
|
||||||
|
advertise ipv4 unicast\n
|
||||||
|
advertise ipv6 unicast\n
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
router = tgen.gears["r1"]
|
||||||
|
json_file = "{}/{}/bgp_l2vpn_evpn_routes_all.json".format(CWD, router.name)
|
||||||
|
if not os.path.isfile(json_file):
|
||||||
|
assert 0, "bgp_l2vpn_evpn_routes.json file not found"
|
||||||
|
|
||||||
|
expected = json.loads(open(json_file).read())
|
||||||
|
test_func = partial(
|
||||||
|
topotest.router_json_cmp,
|
||||||
|
router,
|
||||||
|
"show bgp l2vpn evpn json",
|
||||||
|
expected,
|
||||||
|
)
|
||||||
|
_, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
|
||||||
|
assertmsg = '"{}" JSON output mismatches'.format(router.name)
|
||||||
|
assert result is None, assertmsg
|
||||||
|
|
||||||
|
|
||||||
|
def test_evpn_remove_ip():
|
||||||
|
"""
|
||||||
|
Check the removal of an EVPN route is correctly handled
|
||||||
|
"""
|
||||||
|
tgen = get_topogen()
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
config_no_ipv6 = {
|
config_no_ipv6 = {
|
||||||
"r2": {
|
"r2": {
|
||||||
"raw_config": [
|
"raw_config": [
|
||||||
"router bgp 65000 vrf r2-vrf-101",
|
"router bgp 65000 vrf r2-vrf-101",
|
||||||
"address-family ipv6 unicast",
|
"address-family ipv6 unicast",
|
||||||
|
"no network fd00::3/128",
|
||||||
"no network fd00::2/128",
|
"no network fd00::2/128",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -293,6 +417,7 @@ def test_protocols_convergence():
|
||||||
}
|
}
|
||||||
result = verify_bgp_rib(tgen, "ipv6", "r1", ipv6_routes, expected=False)
|
result = verify_bgp_rib(tgen, "ipv6", "r1", ipv6_routes, expected=False)
|
||||||
assert result is not True, "expect IPv6 route fd00::2/128 withdrawn"
|
assert result is not True, "expect IPv6 route fd00::2/128 withdrawn"
|
||||||
|
|
||||||
output = tgen.gears["r1"].vtysh_cmd("show evpn next-hops vni all", isjson=False)
|
output = tgen.gears["r1"].vtysh_cmd("show evpn next-hops vni all", isjson=False)
|
||||||
logger.info("==== result from show evpn next-hops vni all")
|
logger.info("==== result from show evpn next-hops vni all")
|
||||||
logger.info(output)
|
logger.info(output)
|
||||||
|
@ -300,37 +425,27 @@ def test_protocols_convergence():
|
||||||
logger.info("==== result from show evpn next-hops vni all")
|
logger.info("==== result from show evpn next-hops vni all")
|
||||||
logger.info(output)
|
logger.info(output)
|
||||||
|
|
||||||
expected = {
|
|
||||||
"101": {
|
|
||||||
"numNextHops": 1,
|
|
||||||
"192.168.100.41": {
|
|
||||||
"nexthopIp": "192.168.100.41",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result = topotest.router_json_cmp(
|
|
||||||
tgen.gears["r1"], "show evpn next-hops vni all json", expected
|
|
||||||
)
|
|
||||||
assert result is None, "evpn next-hops check failed"
|
|
||||||
|
|
||||||
expected = {"101": {"numRmacs": 1}}
|
def test_router_check_evpn_contexts_again():
|
||||||
result = topotest.router_json_cmp(
|
"""
|
||||||
tgen.gears["r1"], "show evpn rmac vni all json", expected
|
Check EVPN nexthops and RMAC number are correctly configured
|
||||||
)
|
"""
|
||||||
assert result is None, "evpn rmac number check failed"
|
tgen = get_topogen()
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
logger.info(
|
_test_router_check_evpn_contexts(tgen.gears["r1"], ipv4_only=True)
|
||||||
"Check Ping IPv4 from R1(r1-vrf-101) to R2(r2-vrf-101 = 192.168.101.41)"
|
|
||||||
)
|
|
||||||
output = pingrouter.run("ip netns exec r1-vrf-101 ping 192.168.101.41 -f -c 1000")
|
def test_evpn_ping_again():
|
||||||
logger.info(output)
|
"""
|
||||||
if "1000 packets transmitted, 1000 received" not in output:
|
Check ping between R1 and R2 is ok
|
||||||
assertmsg = (
|
"""
|
||||||
"expected ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) should be ok"
|
tgen = get_topogen()
|
||||||
)
|
if tgen.routers_have_failure():
|
||||||
assert 0, assertmsg
|
pytest.skip(tgen.errors)
|
||||||
else:
|
|
||||||
logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK")
|
_test_evpn_ping_router(tgen.gears["r1"], ipv4_only=True)
|
||||||
|
|
||||||
|
|
||||||
def test_memory_leak():
|
def test_memory_leak():
|
||||||
|
|
Loading…
Reference in a new issue