summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/bgpd/test_aspath.c1
-rw-r--r--tests/bgpd/test_capability.c1
-rw-r--r--tests/bgpd/test_peer_attr.c1
-rw-r--r--tests/isisd/test_fuzz_isis_tlv_tests.h.gzbin221946 -> 206007 bytes
-rw-r--r--tests/lib/test_typelist.h2
-rw-r--r--tests/topotests/Dockerfile1
-rw-r--r--tests/topotests/all-protocol-startup/r1/ipv4_routes.ref1
-rw-r--r--tests/topotests/all-protocol-startup/r1/ipv6_routes.ref3
-rw-r--r--tests/topotests/all-protocol-startup/r1/zebra.conf7
-rwxr-xr-xtests/topotests/bgp-ecmp-topo2/ebgp_ecmp_topo2.json234
-rwxr-xr-xtests/topotests/bgp-ecmp-topo2/ibgp_ecmp_topo2.json234
-rw-r--r--tests/topotests/bgp-route-map/bgp_route_map_topo1.json187
-rwxr-xr-xtests/topotests/bgp-route-map/bgp_route_map_topo2.json316
-rwxr-xr-xtests/topotests/bgp-route-map/test_route_map_topo1.py1361
-rwxr-xr-xtests/topotests/bgp-route-map/test_route_map_topo2.py3916
-rw-r--r--tests/topotests/bgp_aggregate-address_route-map/__init__.py0
-rw-r--r--tests/topotests/bgp_aggregate-address_route-map/r1/bgpd.conf10
-rw-r--r--tests/topotests/bgp_aggregate-address_route-map/r1/zebra.conf9
-rw-r--r--tests/topotests/bgp_aggregate-address_route-map/r2/bgpd.conf4
-rw-r--r--tests/topotests/bgp_aggregate-address_route-map/r2/zebra.conf6
-rw-r--r--tests/topotests/bgp_aggregate-address_route-map/test_bgp_aggregate-address_route-map.py131
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py11
-rw-r--r--tests/topotests/bgp_rr_ibgp/spine1/bgpd.conf8
-rw-r--r--tests/topotests/bgp_rr_ibgp/spine1/show_ip_route.json_ref162
-rw-r--r--tests/topotests/bgp_rr_ibgp/spine1/staticd.conf1
-rw-r--r--tests/topotests/bgp_rr_ibgp/spine1/zebra.conf9
-rw-r--r--tests/topotests/bgp_rr_ibgp/spine2/bgpd.conf8
-rw-r--r--tests/topotests/bgp_rr_ibgp/spine2/show_ip_route.json_ref162
-rw-r--r--tests/topotests/bgp_rr_ibgp/spine2/staticd.conf1
-rw-r--r--tests/topotests/bgp_rr_ibgp/spine2/zebra.conf9
-rwxr-xr-xtests/topotests/bgp_rr_ibgp/test_bgp_rr_ibgp_topo1.py245
-rw-r--r--tests/topotests/bgp_rr_ibgp/tor1/bgpd.conf5
-rw-r--r--tests/topotests/bgp_rr_ibgp/tor1/show_ip_route.json_ref169
-rw-r--r--tests/topotests/bgp_rr_ibgp/tor1/staticd.conf1
-rw-r--r--tests/topotests/bgp_rr_ibgp/tor1/zebra.conf12
-rw-r--r--tests/topotests/bgp_rr_ibgp/tor2/bgpd.conf5
-rw-r--r--tests/topotests/bgp_rr_ibgp/tor2/show_ip_route.json_ref169
-rw-r--r--tests/topotests/bgp_rr_ibgp/tor2/staticd.conf1
-rw-r--r--tests/topotests/bgp_rr_ibgp/tor2/zebra.conf13
-rwxr-xr-xtests/topotests/conftest.py6
-rw-r--r--tests/topotests/ldp-topo1/r1/ip_mpls_route.ref-15
-rw-r--r--tests/topotests/ldp-topo1/r1/show_ipv4_route.ref-17
-rw-r--r--tests/topotests/ldp-topo1/r1/show_mpls_ldp_binding.ref-142
-rw-r--r--tests/topotests/ldp-topo1/r1/show_mpls_ldp_discovery.ref-17
-rw-r--r--tests/topotests/ldp-topo1/r1/show_mpls_ldp_interface.ref-12
-rw-r--r--tests/topotests/ldp-topo1/r1/show_mpls_ldp_neighbor.ref-18
-rw-r--r--tests/topotests/ldp-topo1/r1/show_mpls_table.ref16
-rw-r--r--tests/topotests/ldp-topo1/r1/show_mpls_table.ref-18
-rw-r--r--tests/topotests/ldp-topo1/r1/show_mpls_table.ref-no-impl-null8
-rw-r--r--tests/topotests/ldp-topo1/r2/show_ipv4_route.ref-17
-rw-r--r--tests/topotests/ldp-topo1/r2/show_mpls_ldp_binding.ref-156
-rw-r--r--tests/topotests/ldp-topo1/r2/show_mpls_ldp_discovery.ref-112
-rw-r--r--tests/topotests/ldp-topo1/r2/show_mpls_ldp_interface.ref-13
-rw-r--r--tests/topotests/ldp-topo1/r2/show_mpls_ldp_neighbor.ref-126
-rw-r--r--tests/topotests/ldp-topo1/r2/show_mpls_table.ref14
-rw-r--r--tests/topotests/ldp-topo1/r2/show_mpls_table.ref-17
-rw-r--r--tests/topotests/ldp-topo1/r2/show_mpls_table.ref-no-impl-null7
-rw-r--r--tests/topotests/ldp-topo1/r3/show_ipv4_route.ref-17
-rw-r--r--tests/topotests/ldp-topo1/r3/show_mpls_ldp_binding.ref-149
-rw-r--r--tests/topotests/ldp-topo1/r3/show_mpls_ldp_discovery.ref-19
-rw-r--r--tests/topotests/ldp-topo1/r3/show_mpls_ldp_interface.ref-12
-rw-r--r--tests/topotests/ldp-topo1/r3/show_mpls_ldp_neighbor.ref-117
-rw-r--r--tests/topotests/ldp-topo1/r3/show_mpls_table.ref20
-rw-r--r--tests/topotests/ldp-topo1/r3/show_mpls_table.ref-110
-rw-r--r--tests/topotests/ldp-topo1/r3/show_mpls_table.ref-no-impl-null10
-rw-r--r--tests/topotests/ldp-topo1/r4/show_ipv4_route.ref-17
-rw-r--r--tests/topotests/ldp-topo1/r4/show_mpls_ldp_binding.ref-149
-rw-r--r--tests/topotests/ldp-topo1/r4/show_mpls_ldp_discovery.ref-19
-rw-r--r--tests/topotests/ldp-topo1/r4/show_mpls_ldp_interface.ref-12
-rw-r--r--tests/topotests/ldp-topo1/r4/show_mpls_ldp_neighbor.ref-117
-rw-r--r--tests/topotests/ldp-topo1/r4/show_mpls_table.ref18
-rw-r--r--tests/topotests/ldp-topo1/r4/show_mpls_table.ref-19
-rw-r--r--tests/topotests/ldp-topo1/r4/show_mpls_table.ref-no-impl-null9
-rwxr-xr-xtests/topotests/ldp-topo1/test_ldp_topo1.py119
-rw-r--r--tests/topotests/ldp-vpls-topo1/r1/show_ip_ospf_neighbor.ref31
-rw-r--r--tests/topotests/ldp-vpls-topo1/r1/show_ip_ospf_neighbor.ref-no-neigh18
-rw-r--r--tests/topotests/ldp-vpls-topo1/r1/show_ip_ospf_neighbor.ref-old-nolist14
-rw-r--r--tests/topotests/ldp-vpls-topo1/r2/show_ip_ospf_neighbor.ref30
-rw-r--r--tests/topotests/ldp-vpls-topo1/r2/show_ip_ospf_neighbor.ref-no-neigh18
-rw-r--r--tests/topotests/ldp-vpls-topo1/r2/show_ip_ospf_neighbor.ref-old-nolist14
-rw-r--r--tests/topotests/ldp-vpls-topo1/r3/show_ip_ospf_neighbor.ref30
-rw-r--r--tests/topotests/ldp-vpls-topo1/r3/show_ip_ospf_neighbor.ref-no-neigh18
-rw-r--r--tests/topotests/ldp-vpls-topo1/r3/show_ip_ospf_neighbor.ref-old-nolist14
-rwxr-xr-xtests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py27
-rw-r--r--tests/topotests/lib/bgp.py152
-rw-r--r--tests/topotests/lib/common_config.py512
-rw-r--r--tests/topotests/lib/topojson.py2
-rw-r--r--tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json12
-rw-r--r--tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json18
-rw-r--r--tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json10
-rw-r--r--tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json12
-rw-r--r--tests/topotests/pytest.ini2
92 files changed, 8007 insertions, 947 deletions
diff --git a/tests/bgpd/test_aspath.c b/tests/bgpd/test_aspath.c
index b2612892f9..b5db36703a 100644
--- a/tests/bgpd/test_aspath.c
+++ b/tests/bgpd/test_aspath.c
@@ -1379,6 +1379,7 @@ int main(void)
i = 0;
+ frr_pthread_init();
bgp_pthreads_init();
bgp_pth_ka->running = true;
diff --git a/tests/bgpd/test_capability.c b/tests/bgpd/test_capability.c
index 968f9ac445..db1cf0611d 100644
--- a/tests/bgpd/test_capability.c
+++ b/tests/bgpd/test_capability.c
@@ -916,6 +916,7 @@ int main(void)
vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);
+ frr_pthread_init();
bgp_pthreads_init();
bgp_pth_ka->running = true;
diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c
index 8e1b62ac15..e5d3030ed1 100644
--- a/tests/bgpd/test_peer_attr.c
+++ b/tests/bgpd/test_peer_attr.c
@@ -1391,6 +1391,7 @@ static void bgp_startup(void)
bgp_master_init(master);
bgp_option_set(BGP_OPT_NO_LISTEN);
vrf_init(NULL, NULL, NULL, NULL, NULL);
+ frr_pthread_init();
bgp_init(0);
bgp_pthreads_run();
}
diff --git a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
index 6f8bc2218e..46e45e5ee0 100644
--- a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
+++ b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
Binary files differ
diff --git a/tests/lib/test_typelist.h b/tests/lib/test_typelist.h
index 7ff210cae3..f20bbc52d9 100644
--- a/tests/lib/test_typelist.h
+++ b/tests/lib/test_typelist.h
@@ -280,7 +280,7 @@ static void concat(test_, TYPE)(void)
assert(!tmp || tmp->val >= j);
} else
assert(gteq == list_first(&head));
-
+
if (gteq)
assert(gteq->val >= j);
}
diff --git a/tests/topotests/Dockerfile b/tests/topotests/Dockerfile
index 4602688782..fc6d6df530 100644
--- a/tests/topotests/Dockerfile
+++ b/tests/topotests/Dockerfile
@@ -19,6 +19,7 @@ RUN export DEBIAN_FRONTEND=noninteractive \
libpython-dev \
libreadline-dev \
libc-ares-dev \
+ libcap-dev \
man \
mininet \
pkg-config \
diff --git a/tests/topotests/all-protocol-startup/r1/ipv4_routes.ref b/tests/topotests/all-protocol-startup/r1/ipv4_routes.ref
index 0a20231371..a7d6fe11a6 100644
--- a/tests/topotests/all-protocol-startup/r1/ipv4_routes.ref
+++ b/tests/topotests/all-protocol-startup/r1/ipv4_routes.ref
@@ -15,6 +15,7 @@ S>* 4.5.6.11/32 [1/0] via 192.168.0.2, r1-eth0, XX:XX:XX
S>* 4.5.6.12/32 [1/0] is directly connected, r1-eth0, XX:XX:XX
S>* 4.5.6.13/32 [1/0] unreachable (blackhole), XX:XX:XX
S>* 4.5.6.14/32 [1/0] unreachable (blackhole), XX:XX:XX
+S 4.5.6.15/32 [255/0] via 192.168.0.2, r1-eth0, XX:XX:XX
S>* 4.5.6.7/32 [1/0] unreachable (blackhole), XX:XX:XX
S>* 4.5.6.8/32 [1/0] unreachable (blackhole), XX:XX:XX
S>* 4.5.6.9/32 [1/0] unreachable (ICMP unreachable), XX:XX:XX
diff --git a/tests/topotests/all-protocol-startup/r1/ipv6_routes.ref b/tests/topotests/all-protocol-startup/r1/ipv6_routes.ref
index 6e3e9c87c1..d5bc16a2bf 100644
--- a/tests/topotests/all-protocol-startup/r1/ipv6_routes.ref
+++ b/tests/topotests/all-protocol-startup/r1/ipv6_routes.ref
@@ -20,9 +20,10 @@ C * fe80::/64 is directly connected, r1-eth7, XX:XX:XX
C * fe80::/64 is directly connected, r1-eth8, XX:XX:XX
C * fe80::/64 is directly connected, r1-eth9, XX:XX:XX
O fc00:0:0:4::/64 [110/10] is directly connected, r1-eth4, XX:XX:XX
-S>* 4:5::/32 [1/0] is directly connected, r1-eth0, XX:XX:XX
S>* 4:5::6:10/128 [1/0] via fc00::2, r1-eth0, XX:XX:XX
S>* 4:5::6:11/128 [1/0] via fc00::2, r1-eth0, XX:XX:XX
+S>* 4:5::6:12/128 [1/0] is directly connected, r1-eth0, XX:XX:XX
+S 4:5::6:15/128 [255/0] via fc00::2, r1-eth0, XX:XX:XX
S>* 4:5::6:7/128 [1/0] unreachable (blackhole), XX:XX:XX
S>* 4:5::6:8/128 [1/0] unreachable (blackhole), XX:XX:XX
S>* 4:5::6:9/128 [1/0] unreachable (ICMP unreachable), XX:XX:XX
diff --git a/tests/topotests/all-protocol-startup/r1/zebra.conf b/tests/topotests/all-protocol-startup/r1/zebra.conf
index c621593ef7..85c8676964 100644
--- a/tests/topotests/all-protocol-startup/r1/zebra.conf
+++ b/tests/topotests/all-protocol-startup/r1/zebra.conf
@@ -20,7 +20,12 @@ ip route 4.5.6.11/32 192.168.0.2 r1-eth0
ipv6 route 4:5::6:11/128 fc00:0:0:0::2 r1-eth0
# Create ifname routes
ip route 4.5.6.12/32 r1-eth0
-ipv6 route 4:5::6:12/32 r1-eth0
+ipv6 route 4:5::6:12/128 r1-eth0
+# Create a route that has a large admin distance
+# an admin distance of 255 should be accepted
+# by zebra but not installed.
+ip route 4.5.6.15/32 192.168.0.2 255
+ipv6 route 4:5::6:15/128 fc00:0:0:0::2 255
!
interface r1-eth0
description to sw0 - no routing protocol
diff --git a/tests/topotests/bgp-ecmp-topo2/ebgp_ecmp_topo2.json b/tests/topotests/bgp-ecmp-topo2/ebgp_ecmp_topo2.json
index 50797f130a..34f11c0a29 100755
--- a/tests/topotests/bgp-ecmp-topo2/ebgp_ecmp_topo2.json
+++ b/tests/topotests/bgp-ecmp-topo2/ebgp_ecmp_topo2.json
@@ -564,6 +564,16 @@
"ipv6": "auto"
}
},
+ "route_maps": {
+ "rmap_global": [{
+ "action": "permit",
+ "set": {
+ "ipv6": {
+ "nexthop": "prefer-global"
+ }
+ }
+ }]
+ },
"bgp": {
"local_as": "300",
"address_family": {
@@ -620,38 +630,198 @@
"neighbor": {
"r2": {
"dest_link": {
- "r3-link1": {},
- "r3-link2": {},
- "r3-link3": {},
- "r3-link4": {},
- "r3-link5": {},
- "r3-link6": {},
- "r3-link7": {},
- "r3-link8": {},
- "r3-link9": {},
- "r3-link10": {},
- "r3-link11": {},
- "r3-link12": {},
- "r3-link13": {},
- "r3-link14": {},
- "r3-link15": {},
- "r3-link16": {},
- "r3-link17": {},
- "r3-link18": {},
- "r3-link19": {},
- "r3-link20": {},
- "r3-link21": {},
- "r3-link22": {},
- "r3-link23": {},
- "r3-link24": {},
- "r3-link25": {},
- "r3-link26": {},
- "r3-link27": {},
- "r3-link28": {},
- "r3-link29": {},
- "r3-link30": {},
- "r3-link31": {},
- "r3-link32": {}
+ "r3-link1": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link2": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link3": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link4": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link5": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link6": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link7": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link8": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link9": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link10": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link11": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link12": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link13": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link14": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link15": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link16": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link17": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link18": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link19": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link20": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link21": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link22": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link23": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link24": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link25": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link26": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link27": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link28": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link29": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link30": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link31": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link32": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
}
}
}
diff --git a/tests/topotests/bgp-ecmp-topo2/ibgp_ecmp_topo2.json b/tests/topotests/bgp-ecmp-topo2/ibgp_ecmp_topo2.json
index 9010b8c273..9eea9073c7 100755
--- a/tests/topotests/bgp-ecmp-topo2/ibgp_ecmp_topo2.json
+++ b/tests/topotests/bgp-ecmp-topo2/ibgp_ecmp_topo2.json
@@ -574,6 +574,16 @@
"ipv6": "auto"
}
},
+ "route_maps": {
+ "rmap_global": [{
+ "action": "permit",
+ "set": {
+ "ipv6": {
+ "nexthop": "prefer-global"
+ }
+ }
+ }]
+ },
"bgp": {
"local_as": "100",
"address_family": {
@@ -630,38 +640,198 @@
"neighbor": {
"r2": {
"dest_link": {
- "r3-link1": {},
- "r3-link2": {},
- "r3-link3": {},
- "r3-link4": {},
- "r3-link5": {},
- "r3-link6": {},
- "r3-link7": {},
- "r3-link8": {},
- "r3-link9": {},
- "r3-link10": {},
- "r3-link11": {},
- "r3-link12": {},
- "r3-link13": {},
- "r3-link14": {},
- "r3-link15": {},
- "r3-link16": {},
- "r3-link17": {},
- "r3-link18": {},
- "r3-link19": {},
- "r3-link20": {},
- "r3-link21": {},
- "r3-link22": {},
- "r3-link23": {},
- "r3-link24": {},
- "r3-link25": {},
- "r3-link26": {},
- "r3-link27": {},
- "r3-link28": {},
- "r3-link29": {},
- "r3-link30": {},
- "r3-link31": {},
- "r3-link32": {}
+ "r3-link1": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link2": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link3": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link4": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link5": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link6": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link7": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link8": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link9": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link10": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link11": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link12": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link13": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link14": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link15": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link16": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link17": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link18": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link19": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link20": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link21": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link22": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link23": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link24": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link25": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link26": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link27": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link28": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link29": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link30": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link31": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ },
+ "r3-link32": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
}
}
}
diff --git a/tests/topotests/bgp-route-map/bgp_route_map_topo1.json b/tests/topotests/bgp-route-map/bgp_route_map_topo1.json
new file mode 100644
index 0000000000..e89263961d
--- /dev/null
+++ b/tests/topotests/bgp-route-map/bgp_route_map_topo1.json
@@ -0,0 +1,187 @@
+{
+ "address_types": ["ipv4","ipv6"],
+ "ipv4base":"10.0.0.0",
+ "ipv4mask":30,
+ "ipv6base":"fd00::",
+ "ipv6mask":64,
+ "link_ip_start":{"ipv4":"10.0.0.0", "v4mask":30, "ipv6":"fd00::", "v6mask":64},
+ "lo_prefix":{"ipv4":"1.0.", "v4mask":32, "ipv6":"2001:DB8:F::", "v6mask":128},
+ "routers":{
+ "r1":{
+ "links":{
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r2":{"ipv4":"auto", "ipv6":"auto"},
+ "r3":{"ipv4":"auto", "ipv6":"auto"}
+ },
+ "bgp":{
+ "local_as":"100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r2":{
+ "links":{
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r1":{"ipv4":"auto", "ipv6":"auto"},
+ "r3":{"ipv4":"auto", "ipv6":"auto"}
+ },
+ "bgp":{
+ "local_as":"100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r2": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r2": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r3":{
+ "links":{
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r1":{"ipv4":"auto", "ipv6":"auto"},
+ "r2":{"ipv4":"auto", "ipv6":"auto"},
+ "r4":{"ipv4":"auto", "ipv6":"auto"}
+ },
+ "bgp":{
+ "local_as":"100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r2": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r2": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r4":{
+ "links":{
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r3":{"ipv4":"auto", "ipv6":"auto"}
+ },
+ "bgp":{
+ "local_as":"200",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp-route-map/bgp_route_map_topo2.json b/tests/topotests/bgp-route-map/bgp_route_map_topo2.json
new file mode 100755
index 0000000000..c22a4c3ea7
--- /dev/null
+++ b/tests/topotests/bgp-route-map/bgp_route_map_topo2.json
@@ -0,0 +1,316 @@
+{
+ "address_types": ["ipv4", "ipv6"],
+ "ipv4base": "10.0.0.0",
+ "ipv4mask": 30,
+ "ipv6base": "fd00::",
+ "ipv6mask": 64,
+ "link_ip_start": {
+ "ipv4": "10.0.0.0",
+ "v4mask": 30,
+ "ipv6": "fd00::",
+ "v6mask": 64
+ },
+ "lo_prefix": {
+ "ipv4": "1.0.",
+ "v4mask": 32,
+ "ipv6": "2001:DB8:F::",
+ "v6mask": 128
+ },
+ "routers": {
+ "r1": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r2": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r3": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1": {}
+ }
+ }
+ },
+ "redistribute": [{
+ "redist_type": "static"
+ },
+ {
+ "redist_type": "connected"
+ }
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1": {}
+ }
+ }
+ },
+ "redistribute": [{
+ "redist_type": "static"
+ },
+ {
+ "redist_type": "connected"
+ }
+ ]
+ }
+ }
+ }
+ },
+
+ "static_routes": [{
+ "network": "10.0.20.1/32",
+ "no_of_ip": 2,
+ "next_hop": "10.0.0.2"
+ },
+ {
+ "network": "1::1/128",
+ "no_of_ip": 2,
+ "next_hop": "fd00::2"
+ }]
+ },
+ "r2": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r3": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r2": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r2": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r3": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r2": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r4": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r5": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r2": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r3": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r2": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r3": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r4": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r3": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "200",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r5": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r3": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "300",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r5": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r5": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp-route-map/test_route_map_topo1.py b/tests/topotests/bgp-route-map/test_route_map_topo1.py
new file mode 100755
index 0000000000..86ec6c82d2
--- /dev/null
+++ b/tests/topotests/bgp-route-map/test_route_map_topo1.py
@@ -0,0 +1,1361 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2019 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.
+#
+
+#################################
+# TOPOLOGY
+#################################
+"""
+
+ +-------+
+ +------- | R2 |
+ | +-------+
+ | |
+ +-------+ |
+ | R1 | |
+ +-------+ |
+ | |
+ | +-------+ +-------+
+ +---------- | R3 |----------| R4 |
+ +-------+ +-------+
+
+"""
+
+#################################
+# TEST SUMMARY
+#################################
+"""
+Following tests are covered to test route-map functionality:
+TC_34:
+ Verify if route-maps is applied in both inbound and
+ outbound direction to same neighbor/interface.
+TC_36:
+ Test permit/deny statements operation in route-maps with a
+ permutation and combination of permit/deny in prefix-lists
+TC_35:
+ Test multiple sequence numbers in a single route-map for different
+ match/set clauses.
+TC_37:
+ Test add/remove route-maps with multiple set
+ clauses and without any match statement.(Set only)
+TC_38:
+ Test add/remove route-maps with multiple match
+ clauses and without any set statement.(Match only)
+"""
+
+import sys
+import json
+import time
+import pytest
+import inspect
+import os
+from time import sleep
+
+# 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, get_topogen
+from mininet.topo import Topo
+
+# Required to instantiate the topology builder class.
+from lib.topojson import *
+from lib.common_config import (
+ start_topology, write_test_header,
+ write_test_footer, verify_bgp_community,
+ verify_rib, delete_route_maps, create_bgp_community_lists,
+ interface_status, create_route_maps, create_prefix_lists,
+ verify_route_maps, check_address_types,
+ shutdown_bringup_interface, verify_prefix_lists, reset_config_on_routers)
+from lib.topolog import logger
+from lib.bgp import (
+ verify_bgp_convergence, create_router_bgp,
+ clear_bgp_and_verify, verify_bgp_attributes)
+from lib.topojson import build_topo_from_json, build_config_from_json
+
+
+# Global variables
+bgp_convergence = False
+BGP_CONVERGENCE = False
+ADDR_TYPES = check_address_types()
+# Reading the data from JSON File for topology and configuration creation
+jsonFile = "{}/bgp_route_map_topo1.json".format(CWD)
+try:
+ with open(jsonFile, 'r') as topoJson:
+ topo = json.load(topoJson)
+except IOError:
+ assert False, "Could not read file {}".format(jsonFile)
+
+# Global variables
+bgp_convergence = False
+NETWORK = {
+ "ipv4": ["11.0.20.1/32", "20.0.20.1/32"],
+ "ipv6": ["1::1/128", "2::1/128"]
+}
+MASK = {"ipv4": "32", "ipv6": "128"}
+NEXT_HOP = {
+ "ipv4": "10.0.0.2",
+ "ipv6": "fd00::2"
+}
+ADDR_TYPES = check_address_types()
+
+
+class CreateTopo(Topo):
+ """
+ Test topology builder
+
+
+ * `Topo`: Topology object
+ """
+
+ def build(self, *_args, **_opts):
+ """Build function"""
+ tgen = get_topogen(self)
+
+ # Building topology from json file
+ build_topo_from_json(tgen, topo)
+
+
+def setup_module(mod):
+ """
+ Sets up the pytest environment
+
+ * `mod`: module name
+ """
+ global ADDR_TYPES
+ 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(CreateTopo, mod.__name__)
+ # ... and here it calls Mininet initialization functions.
+
+ # Starting topology, create tmp files which are loaded to routers
+ # to start deamons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # Checking BGP convergence
+ global bgp_convergence
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Api call verify whether BGP is converged
+ bgp_convergence = verify_bgp_convergence(tgen, topo)
+ assert bgp_convergence is True, ("setup_module :Failed \n Error:"
+ " {}".format(bgp_convergence))
+
+ logger.info("Running setup_module() done")
+
+
+def teardown_module():
+ """
+ Teardown the pytest environment
+
+ * `mod`: module name
+ """
+
+ 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 test_route_map_inbound_outbound_same_neighbor_p0(request):
+ """
+ TC_34:
+ Verify if route-maps is applied in both inbound and
+ outbound direction to same neighbor/interface.
+ """
+
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ for adt in ADDR_TYPES:
+
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": NETWORK[adt][0],
+ "no_of_ip": 9,
+ "next_hop": NEXT_HOP[adt],
+ }
+ ]
+ }
+ }
+
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "local_as": 100,
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ input_dict_2 = {
+ "r4": {
+ "static_routes": [
+ {
+ "network": NETWORK[adt][1],
+ "no_of_ip": 9,
+ "next_hop": NEXT_HOP[adt],
+ }
+ ]
+ }
+ }
+
+ result = create_static_routes(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_5 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ input_dict_2 = {
+ "r3": {
+ "prefix_lists": {
+ "ipv4": {
+ "pf_list_1_ipv4": [{
+ "seqid": 10,
+ "action": "permit",
+ "network": NETWORK["ipv4"][0]
+ }],
+ "pf_list_2_ipv4": [{
+ "seqid": 10,
+ "action": "permit",
+ "network": NETWORK["ipv4"][1]
+ }]
+ },
+ "ipv6": {
+ "pf_list_1_ipv6": [{
+ "seqid": 100,
+ "action": "permit",
+ "network": NETWORK["ipv6"][0]
+ }],
+ "pf_list_2_ipv6": [{
+ "seqid": 100,
+ "action": "permit",
+ "network": NETWORK["ipv6"][1]
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_6 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_tag_1_{}".format(addr_type): [{
+ "action": "deny",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_1_{}".format(addr_type)
+ }
+ }
+ }],
+ "rmap_match_tag_2_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_2_{}".format(addr_type)
+ }
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_6)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_7 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [
+ {"name":
+ "rmap_match_tag_1_ipv4",
+ "direction": "in"},
+ {"name":
+ "rmap_match_tag_1_ipv4",
+ "direction": "out"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [
+ {"name":
+ "rmap_match_tag_1_ipv6",
+ "direction": "in"},
+ {"name":
+ "rmap_match_tag_1_ipv6",
+ "direction": "out"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_7)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ for adt in ADDR_TYPES:
+ # Verifying RIB routes
+ dut = "r3"
+ protocol = "bgp"
+ input_dict_2 = {
+ "r4": {
+ "static_routes": [
+ {
+ "network": [NETWORK[adt][1]],
+ "no_of_ip": 9,
+ "next_hop": NEXT_HOP[adt]
+ }
+ ]
+ }
+ }
+
+ result = verify_rib(tgen, adt, dut, input_dict_2, protocol=protocol)
+ assert result is not True, "Testcase {} : Failed \n"
+ "Expected behavior: routes are not present in rib \n"
+ "Error: {}".format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = "r4"
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": [NETWORK[adt][0]],
+ "no_of_ip": 9,
+ "next_hop": NEXT_HOP[adt]
+ }
+ ]
+ }
+ }
+ result = verify_rib(tgen, adt, dut, input_dict, protocol=protocol)
+ assert result is not True, "Testcase {} : Failed \n "
+ "Expected behavior: routes are not present in rib \n "
+ "Error: {}".format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+
+@pytest.mark.parametrize("prefix_action, rmap_action", [("permit", "permit"),
+ ("permit", "deny"), ("deny", "permit"),
+ ("deny", "deny")])
+def test_route_map_with_action_values_combination_of_prefix_action_p0(
+ request, prefix_action, rmap_action):
+ """
+ TC_36:
+ Test permit/deny statements operation in route-maps with a permutation and
+ combination of permit/deny in prefix-lists
+ """
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ for adt in ADDR_TYPES:
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": NETWORK[adt][0],
+ "no_of_ip": 9,
+ "next_hop": NEXT_HOP[adt]
+ }
+ ]
+ }
+ }
+
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "local_as": 100,
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Permit in perfix list and route-map
+ input_dict_2 = {
+ "r3": {
+ "prefix_lists": {
+ "ipv4": {
+ "pf_list_1_ipv4": [{
+ "seqid": 10,
+ "network": "any",
+ "action": prefix_action
+ }]
+ },
+ "ipv6": {
+ "pf_list_1_ipv6": [{
+ "seqid": 100,
+ "network": "any",
+ "action": prefix_action
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": rmap_action,
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_1_{}".format(addr_type)
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_7 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [
+ {"name":
+ "rmap_match_pf_1_ipv4",
+ "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [
+ {"name":
+ "rmap_match_pf_1_ipv6",
+ "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_7)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ dut = "r3"
+ protocol = "bgp"
+ input_dict_2 = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": [NETWORK[adt][0]],
+ "no_of_ip": 9,
+ "next_hop": NEXT_HOP[adt],
+ }
+ ]
+ }
+ }
+
+ result = verify_rib(tgen, adt, dut, input_dict_2, protocol=protocol)
+ if "deny" in [prefix_action, rmap_action]:
+ assert result is not True, "Testcase {} : Failed \n Error: {}".\
+ format(tc_name, result)
+ else:
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+
+def test_route_map_multiple_seq_different_match_set_clause_p0(request):
+ """
+ TC_35:
+ Test multiple sequence numbers in a single route-map for different
+ match/set clauses.
+ """
+
+ tgen = get_topogen()
+ # test case name
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ for adt in ADDR_TYPES:
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [{
+ "network": NETWORK[adt][0],
+ "no_of_ip": 1,
+ "next_hop": NEXT_HOP[adt]
+ }]
+ }
+ }
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ "r3": {
+ "prefix_lists": {
+ "ipv4": {
+ "pf_list_1_ipv4": [{
+ "seqid": 10,
+ "network": "any",
+ "action": "permit"
+ }]
+ },
+ "ipv6": {
+ "pf_list_1_ipv6": [{
+ "seqid": 100,
+ "network": "any",
+ "action": "permit"
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [
+ {
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_2_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "aspath": {
+ "as_num": 500
+ }
+ }
+ },
+ {
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_2_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ },
+ {
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": "in"
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": "in"
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ for adt in ADDR_TYPES:
+ # Verifying RIB routes
+ dut = "r3"
+ protocol = "bgp"
+ input_dict = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_list1": [{
+ "set": {
+ "med": 50,
+ }
+ }],
+ }
+ }
+ }
+
+ static_routes = [NETWORK[adt][0]]
+
+ time.sleep(2)
+ result = verify_bgp_attributes(tgen, adt, dut, static_routes,
+ "rmap_match_pf_list1", input_dict)
+ assert result is True, "Test case {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ dut = "r4"
+ result = verify_bgp_attributes(tgen, adt, dut, static_routes,
+ "rmap_match_pf_list1", input_dict)
+ assert result is True, "Test case {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ logger.info("Testcase " + tc_name + " :Passed \n")
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_route_map_set_only_no_match_p0(request):
+ """
+ TC_37:
+ Test add/remove route-maps with multiple set
+ clauses and without any match statement.(Set only)
+ """
+
+ tgen = get_topogen()
+ # test case name
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ for adt in ADDR_TYPES:
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [{
+ "network": NETWORK[adt][0],
+ "no_of_ip": 1,
+ "next_hop": NEXT_HOP[adt]
+ }]
+ }
+ }
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1": [
+ {
+ "action": "permit",
+ "set": {
+ "med": 50,
+ "localpref": 150,
+ "weight": 4000
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name": "rmap_match_pf_1",
+ "direction": "in"
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name": "rmap_match_pf_1",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name": "rmap_match_pf_1",
+ "direction": "in"
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name": "rmap_match_pf_1",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ time.sleep(2)
+ for adt in ADDR_TYPES:
+ input_dict_4 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1": [
+ {
+ "action": "permit",
+ "set": {
+ "med": 50,
+ }
+ }
+ ]
+ }
+ }
+ }
+ # Verifying RIB routes
+ static_routes = [NETWORK[adt][0]]
+ result = verify_bgp_attributes(tgen, adt, "r3", static_routes,
+ "rmap_match_pf_1", input_dict_3)
+ assert result is True, "Test case {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ result = verify_bgp_attributes(tgen, adt, "r4", static_routes,
+ "rmap_match_pf_1", input_dict_4)
+ assert result is True, "Test case {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ logger.info("Testcase " + tc_name + " :Passed \n")
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_route_map_match_only_no_set_p0(request):
+ """
+ TC_38:
+ Test add/remove route-maps with multiple match
+ clauses and without any set statement.(Match only)
+ """
+
+ tgen = get_topogen()
+ # test case name
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ for adt in ADDR_TYPES:
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [{
+ "network": NETWORK[adt][0],
+ "no_of_ip": 1,
+ "next_hop": NEXT_HOP[adt]
+ }]
+ }
+ }
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ "r1": {
+ "prefix_lists": {
+ "ipv4": {
+ "pf_list_1_ipv4": [{
+ "seqid": 10,
+ "network": "any",
+ "action": "permit"
+ }]
+ },
+ "ipv6": {
+ "pf_list_1_ipv6": [{
+ "seqid": 100,
+ "network": "any",
+ "action": "permit"
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r1": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ "set": {
+ "med": 50,
+ "localpref": 150,
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create ip prefix list
+ input_dict_5 = {
+ "r3": {
+ "prefix_lists": {
+ "ipv4": {
+ "pf_list_1_ipv4": [{
+ "seqid": 10,
+ "network": "any",
+ "action": "permit"
+ }]
+ },
+ "ipv6": {
+ "pf_list_1_ipv6": [{
+ "seqid": 100,
+ "network": "any",
+ "action": "permit"
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_6 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_1_{}".format(addr_type)
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_6)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_7 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": "in"
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": "in"
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_7)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ for adt in ADDR_TYPES:
+ # Verifying RIB routes
+ static_routes = [NETWORK[adt][0]]
+ result = verify_bgp_attributes(tgen, adt, "r3", static_routes,
+ "rmap_match_pf_1", input_dict_3)
+ assert result is True, "Test case {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
+
+
diff --git a/tests/topotests/bgp-route-map/test_route_map_topo2.py b/tests/topotests/bgp-route-map/test_route_map_topo2.py
new file mode 100755
index 0000000000..7009fc97ce
--- /dev/null
+++ b/tests/topotests/bgp-route-map/test_route_map_topo2.py
@@ -0,0 +1,3916 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2019 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.
+#
+
+"""Following tests are covered to test route-map functionality.
+TC_57:
+ Create route map to match prefix-list and permit inbound
+ and outbound prefixes and set criteria on match
+TC_52:
+ Test modify set/match clauses in a route-map to see
+ if it takes immediate effect.
+TC_61:
+ Delete the route maps.
+TC_50_1:
+ Test modify/remove prefix-lists referenced by a
+ route-map for match statement.
+TC_50_1:
+ Remove prefix-list referencec by route-map match cluase
+ and verifying it reflecting as intended
+TC_51:
+ Add and remove community-list referencec by route-map match cluase
+ and verifying it reflecting as intended
+TC_45:
+ Test multiple match statements as part of a route-map's single
+ sequence number. (Logical OR-ed of multiple match statements)
+TC_44:
+ Test multiple match statements as part of a route-map's single
+ sequence number. (Logical AND of multiple match statements)
+TC_41:
+ Test add/remove route-maps to specific neighbor and see if
+ it takes effect as intended
+TC_56:
+ Test clear BGP sessions and interface flaps to see if
+ route-map properties are intact.
+TC_46:
+ Verify if a blank sequence number can be create(without any
+ match/set clause) and check if it allows all the traffic/prefixes
+TC_48:
+ Create route map setting local preference and weight to eBGP peeer
+ and metric to ibgp peer and verifying it should not get advertised
+TC_43:
+ Test multiple set statements as part of a route-map's
+ single sequence number.
+TC_54:
+ Verify route-maps continue clause functionality.
+TC_55:
+ Verify route-maps goto clause functionality.
+TC_53:
+ Verify route-maps call clause functionality.
+TC_58:
+ Create route map deny inbound and outbound prefixes on
+ match prefix list and set criteria on match
+TC_59:
+ Create route map to permit inbound prefixes with filter
+ match tag and set criteria
+TC_60
+ Create route map to deny outbound prefixes with filter match tag,
+ and set criteria
+"""
+
+#################################
+# TOPOLOGY
+#################################
+"""
+
+ +-------+
+ +--------- | R2 |
+ | +-------+
+ |iBGP |
+ +-------+ |
+ | R1 | |iBGP
+ +-------+ |
+ | |
+ | iBGP +-------+ eBGP +-------+
+ +---------- | R3 |----------| R4 |
+ +-------+ +-------+
+ |
+ |eBGP
+ |
+ +-------+
+ | R5 |
+ +-------+
+
+
+"""
+
+import sys
+import json
+import time
+import pytest
+import inspect
+import os
+from time import sleep
+
+# 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, get_topogen
+from mininet.topo import Topo
+
+# Required to instantiate the topology builder class.
+from lib.common_config import (
+ start_topology, write_test_header,
+ write_test_footer, create_static_routes,
+ verify_rib, delete_route_maps, create_bgp_community_lists,
+ interface_status, create_route_maps, create_prefix_lists,
+ verify_route_maps, check_address_types, verify_bgp_community,
+ shutdown_bringup_interface, verify_prefix_lists, reset_config_on_routers)
+from lib.topolog import logger
+from lib.bgp import (
+ verify_bgp_convergence, create_router_bgp,
+ clear_bgp_and_verify, verify_bgp_attributes)
+from lib.topojson import build_topo_from_json, build_config_from_json
+
+# Reading the data from JSON File for topology and configuration creation
+jsonFile = "{}/bgp_route_map_topo2.json".format(CWD)
+
+try:
+ with open(jsonFile, 'r') as topoJson:
+ topo = json.load(topoJson)
+except IOError:
+ assert False, "Could not read file {}".format(jsonFile)
+
+# Global variables
+# Global variables
+bgp_convergence = False
+NETWORK = {
+ "ipv4": ["11.0.20.1/32", "11.0.20.2/32"],
+ "ipv6": ["2::1/128", "2::2/128"]
+}
+
+bgp_convergence = False
+BGP_CONVERGENCE = False
+ADDR_TYPES = check_address_types()
+
+
+class BGPRmapTopo(Topo):
+ """BGPRmapTopo.
+
+ BGPRmap topology 1
+ * `Topo`: Topology object
+ """
+
+ def build(self, *_args, **_opts):
+ """Build function."""
+ tgen = get_topogen(self)
+
+ # Building topology and configuration from json file
+ build_topo_from_json(tgen, topo)
+
+
+def setup_module(mod):
+ """setup_module.
+
+ Set up the pytest environment
+ * `mod`: module name
+ """
+ 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(BGPRmapTopo, mod.__name__)
+ # ... and here it calls Mininet initialization functions.
+
+ # Starting topology, create tmp files which are loaded to routers
+ # to start deamons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # Checking BGP convergence
+ global bgp_convergence
+ global ADDR_TYPES
+
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Api call verify whether BGP is converged
+ bgp_convergence = verify_bgp_convergence(tgen, topo)
+ assert bgp_convergence is True, ('setup_module :Failed \n Error:'
+ ' {}'.format(bgp_convergence))
+ logger.info("Running setup_module() done")
+
+
+def teardown_module(mod):
+ """teardown_module.
+
+ Teardown the pytest environment.
+ * `mod`: module name
+ """
+ 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)
+
+
+#####################################################
+# Tests starting
+#####################################################
+
+
+def test_rmap_match_prefix_list_permit_in_and_outbound_prefixes_p0():
+ """
+ TC: 57
+ Create route map to match prefix-list and permit inbound
+ and outbound prefixes and set criteria on match
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit',
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit',
+ }]
+ }
+ }
+ }
+ }
+
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ for addr_type in ADDR_TYPES:
+ # Create route map
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_" + addr_type
+ }
+ },
+ "set": {
+ "localpref": 150,
+ "weight": 100
+ }
+ },
+ ],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_" + addr_type
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ },
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+
+ # dual stack changes
+ for addr_type in ADDR_TYPES:
+ result4 = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result4 is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result4)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ # dual stack changes
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result4 = verify_bgp_attributes(tgen, addr_type, dut, routes[
+ addr_type],rmap_name, input_dict_3)
+ assert result4 is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result4)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ # dual stack changes
+ for addr_type in ADDR_TYPES:
+ result4 = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result4 is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result4)
+
+ # Verifying BGP set attributes
+ dut = 'r4'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ # dual stack changes
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_modify_set_match_clauses_in_rmap_p0():
+ """
+ TC_52:
+ Test modify set/match clauses in a route-map to see
+ if it takes immediate effect.
+ """
+
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit',
+ }],
+ 'pf_list_2_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit',
+ }],
+ 'pf_list_2_ipv6': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ # dual stack changes
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result4 = verify_bgp_attributes(tgen, addr_type, dut, routes[
+ addr_type],rmap_name, input_dict_3)
+ assert result4 is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result4)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ # dual stack changes
+ for addr_type in ADDR_TYPES:
+ result4 = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result4 is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result4)
+
+ # Verifying BGP set attributes
+ dut = 'r4'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[
+ addr_type],rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Modify set/match clause of in-used route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 1000,
+ }
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 2000
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r4'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_delete_route_maps_p1():
+ """
+ TC_61:
+ Delete the route maps.
+ """
+
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_tag_1_{}".format(addr_type): [{
+ "action": "deny",
+ "match": {
+ addr_type: {
+ "tag": "4001"
+ }
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Delete route maps
+ for addr_type in ADDR_TYPES:
+ input_dict = {
+ 'r3': {
+ 'route_maps': ['rmap_match_tag_1_{}'.format(addr_type)]
+ }
+ }
+ result = delete_route_maps(tgen, input_dict)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ result = verify_route_maps(tgen, input_dict)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_modify_prefix_list_referenced_by_rmap_p0():
+ """
+ TC_50_1:
+ Test modify/remove prefix-lists referenced by a
+ route-map for match statement.
+ """
+
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit',
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit',
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ "weight": 100
+ }
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r4'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Modify ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'deny'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'deny'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ sleep(5)
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_remove_prefix_list_referenced_by_rmap_p0():
+ """
+ TC_50_1:
+ Remove prefix-list referencec by route-map match cluase
+ and verifying it reflecting as intended
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ for addr_type in ADDR_TYPES:
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r4'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Remove/Delete prefix list
+ input_dict_3 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit',
+ 'delete': True
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit',
+ 'delete': True
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ result = verify_prefix_lists(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Api call to clear bgp, so config changes would be reflected
+ dut = 'r3'
+ result = clear_bgp_and_verify(tgen, topo, dut)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_add_and_remove_community_list_referenced_by_rmap_p0():
+ """
+ TC_51:
+ Add and remove community-list referencec by route-map match cluase
+ and verifying it reflecting as intended
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Creating configuration from JSON
+ # build_config_from_json(tgen, topo)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_5 = {
+ "r1": {
+ "route_maps": {
+ "rm_r1_out_{}".format(addr_type): [{
+ "action": "permit",
+ "set": {
+ "large_community": {"num": "1:1:1 1:2:3 2:1:1 2:2:2"}
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_5)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_6 = {
+ 'r1': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name": "rm_r1_out_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name": "rm_r1_out_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_6)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ # Create standard large commumity-list
+ input_dict_1 = {
+ "r3": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "rmap_lcomm_{}".format(addr_type),
+ "value": "1:1:1 1:2:3 2:1:1 2:2:2",
+ "large": True
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_1)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ # Create route map
+ input_dict_2 = {
+ "r3": {
+ "route_maps": {
+ "rm_r3_in_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type : {
+ "large-community-list": {"id": "rmap_lcomm_"+
+ addr_type}
+ }
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_3 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name": "rm_r3_in_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name": "rm_r3_in_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_3)
+
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ sleep(5)
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verify large-community-list
+ dut = 'r3'
+ networks = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ input_dict_4 = {
+ 'largeCommunity': '1:1:1 1:2:3 2:1:1 2:2:2'
+ }
+ for addr_type in ADDR_TYPES:
+ result = verify_bgp_community(tgen, addr_type, dut, networks[
+ addr_type],input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_multiple_match_statement_in_route_map_logical_ORed_p0():
+ """
+ TC_45:
+ Test multiple match statements as part of a route-map's single
+ sequence number. (Logical OR-ed of multiple match statements)
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Api call to advertise networks
+ input_dict_nw1 = {
+ 'r1': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [
+ {"network": '10.0.30.1/32'}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "advertise_networks": [
+ {"network": '1::1/128'}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_nw1)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Api call to advertise networks
+ input_dict_nw2 = {
+ 'r1': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [
+ {"network": '20.0.30.1/32'}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "advertise_networks": [
+ {"network": '2::1/128'}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_nw2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_2_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_2_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ input_dict_3_addr_type ={}
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150
+ }
+ }]
+ }
+ }
+ }
+ input_dict_3_addr_type[addr_type] = input_dict_3
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 200
+ }
+ }]
+ }
+ }
+ }
+ input_dict_3_addr_type[addr_type] = input_dict_3
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_6 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_6)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.30.1/32"],
+ "ipv6": ["1::1/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3_addr_type[addr_type])
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ routes = {
+ "ipv4": ["20.0.30.1/32"],
+ "ipv6": ["2::1/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_multiple_match_statement_in_route_map_logical_ANDed():
+ """
+ TC_44:
+ Test multiple match statements as part of a route-map's single
+ sequence number. (Logical AND of multiple match statements)
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_5 = {
+ "r1": {
+ "route_maps": {
+ "rm_r1_out_{}".format(addr_type): [{
+ "action": "permit",
+ "set": {
+ "large_community": {
+ "num": "1:1:1 1:2:3 2:1:1 2:2:2"}
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_5)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ for addr_type in ADDR_TYPES:
+ input_dict_6 = {
+ 'r1': {
+ "bgp": {
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rm_r1_out_{}".format(addr_type),
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_6)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ # Create standard large commumity-list
+ input_dict_1 = {
+ "r3": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "rmap_lcomm_{}".format(addr_type),
+ "value": "1:1:1 1:2:3 2:1:1 2:2:2",
+ "large": True
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_1)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ # Create route map
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type : {
+ "large_community_list": {"id": "rmap_lcomm_"+
+ addr_type}
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ # Configure neighbor for route map
+ for addr_type in ADDR_TYPES:
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_{}".format(addr_type),
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ # sleep(10)
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_add_remove_rmap_to_specific_neighbor_p0():
+ """
+ TC_41:
+ Test add/remove route-maps to specific neighbor and see if
+ it takes effect as intended
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'deny'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'deny'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : \n'
+ 'Expected Behavior: Routes are not present in RIB \n'
+ ' Error: {}'.format(
+ tc_name, result)
+
+ # Remove applied rmap from neighbor
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in',
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in',
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_clear_bgp_and_flap_interface_to_verify_rmap_properties_p0():
+ """
+ TC_56:
+ Test clear BGP sessions and interface flaps to see if
+ route-map properties are intact.
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ "weight": 100
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # clear bgp, so config changes would be reflected
+ dut = 'r3'
+ result = clear_bgp_and_verify(tgen, topo, dut)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Flap interface to see if route-map properties are intact
+ # Shutdown interface
+ dut = "r3"
+ intf = "r3-r1-eth0"
+ shutdown_bringup_interface(tgen, dut, intf, False)
+
+ sleep(5)
+
+ # Bringup interface
+ dut = "r3"
+ intf = "r3-r1-eth0"
+ shutdown_bringup_interface(tgen, dut, intf, True)
+
+ # Verify BGP convergence once interface is up
+ result = verify_bgp_convergence(tgen, topo)
+ assert result is True, (
+ 'setup_module :Failed \n Error:' ' {}'.format(result))
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_rmap_without_match_and_set_clause_p0():
+ """
+ TC_46:
+ Verify if a blank sequence number can be create(without any
+ match/set clause) and check if it allows all the traffic/prefixes
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_no_match_set_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5'
+ }],
+ "rmap_no_match_set_2_{}".format(addr_type): [{
+ "action": "deny",
+ 'seq_id': '5'
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_no_match_set_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_no_match_set_2_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_no_match_set_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_no_match_set_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_set_localpref_weight_to_ebgp_and_med_to_ibgp_peers_p0():
+ """
+ TC_48:
+ Create route map setting local preference and weight to eBGP peeer
+ and metric to ibgp peer and verifying it should not get advertised
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ input_dict_3_addr_type ={}
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(
+ addr_type)
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(
+ addr_type)
+ }},
+ "set": {
+ "localpref": 150
+ }
+ }],
+ "rmap_match_pf_3_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(
+ addr_type)
+ }},
+ "set": {
+ "weight": 1000
+ }
+ }]
+ }
+ }
+ }
+ input_dict_3_addr_type[addr_type] = input_dict_3
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_3_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_3_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ rmap_name = "rmap_match_pf_1"
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[
+ addr_type],rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r4'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ rmap_name = "rmap_match_pf_2"
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3_addr_type[addr_type])
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: Attributes are not set \n'
+ 'Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r5'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ # Verifying BGP set attributes
+ dut = 'r5'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+
+ rmap_name = "rmap_match_pf_3"
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_3_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3_addr_type[addr_type])
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: Attributes are not set \n'
+ 'Error: {}'.format(
+ tc_name, result)
+
+ logger.info("Expected behaviour: {}".format(result))
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_multiple_set_on_single_sequence_in_rmap_p0():
+ """
+ TC_43:
+ Test multiple set statements as part of a route-map's
+ single sequence number.
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ "weight": 100,
+ "med": 50
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+
+ rmap_name = "rmap_match_pf_1"
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_route_maps_with_continue_clause_p0():
+ """
+ TC_54:
+ Verify route-maps continue clause functionality.
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '10',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150
+ },
+ "continue": "30"
+ },
+ {
+ "action": "permit",
+ 'seq_id': '20',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 200
+ }
+ },
+ {
+ "action": "permit",
+ 'seq_id': '30',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 100
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ rmap_name = "rmap_match_pf_1"
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ seq_id = {
+ "ipv4": ["10", "30"],
+ "ipv6": ["10", "30"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[
+ addr_type],rmap_name, input_dict_3, seq_id[addr_type])
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_route_maps_with_goto_clause_p0():
+ """
+ TC_55:
+ Verify route-maps goto clause functionality.
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '10',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "goto": "30"
+ },
+ {
+ "action": "permit",
+ 'seq_id': '20',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 100
+ }
+ },
+ {
+ "action": "permit",
+ 'seq_id': '30',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 200
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ rmap_name = "rmap_match_pf_1"
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ seq_id = {
+ "ipv4": ["10", "30"],
+ "ipv6": ["10", "30"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[
+ addr_type],rmap_name, input_dict_3, seq_id[addr_type])
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_route_maps_with_call_clause_p0():
+ """
+ TC_53:
+ Verify route-maps call clause functionality.
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150
+ },
+ "call": "rmap_match_pf_2_{}".format(addr_type)
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 200
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ rmap_name = "rmap_match_pf_1"
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ rmap_name = "rmap_match_pf_2"
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_create_rmap_match_prefix_list_to_deny_in_and_outbound_prefixes_p0():
+ """
+ TC_58:
+ Create route map deny inbound and outbound prefixes on
+ match prefix list and set criteria on match
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "deny",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "deny",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_create_rmap_to_match_tag_permit_inbound_prefixes_p0():
+ """
+ TC_59:
+ Create route map to permit inbound prefixes with filter
+ match tag and set criteria
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ for addr_type in ADDR_TYPES:
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": NETWORK[addr_type],
+ "next_hop": "Null0",
+ "tag": 4001
+ }
+ ]
+ }
+ }
+
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "local_as": 100,
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ input_dict_3 = {
+ "r1": {
+ "route_maps": {
+ "rmap_match_tag_1_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "tag": "4001"
+ }
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r1': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rmap_match_tag_1_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rmap_match_tag_1_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+
+ for addr_type in ADDR_TYPES:
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": NETWORK[addr_type],
+ "next_hop": "Null0",
+ "tag": 4001
+ }
+ ]
+ }
+ }
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_create_rmap_to_match_tag_deny_outbound_prefixes_p0():
+ """
+ TC_60
+ Create route map to deny outbound prefixes with filter match tag,
+ and set criteria
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ for addr_type in ADDR_TYPES:
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": NETWORK[addr_type],
+ "next_hop": "Null0",
+ "tag": 4001
+ }
+ ]
+ }
+ }
+
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "local_as": 100,
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ input_dict_3 = {
+ "r1": {
+ "route_maps": {
+ "rmap_match_tag_1_{}".format(addr_type): [{
+ "action": "deny",
+ "match": {
+ addr_type: {
+ "tag": "4001"
+ }
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r1': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rmap_match_tag_1_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rmap_match_tag_1_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+
+ for addr_type in ADDR_TYPES:
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": NETWORK[addr_type],
+ "next_hop": "Null0",
+ "tag": 4001
+ }
+ ]
+ }
+ }
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behavior: routes are denied \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+if __name__ == '__main__':
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_aggregate-address_route-map/__init__.py b/tests/topotests/bgp_aggregate-address_route-map/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_aggregate-address_route-map/__init__.py
diff --git a/tests/topotests/bgp_aggregate-address_route-map/r1/bgpd.conf b/tests/topotests/bgp_aggregate-address_route-map/r1/bgpd.conf
new file mode 100644
index 0000000000..ef34817bb1
--- /dev/null
+++ b/tests/topotests/bgp_aggregate-address_route-map/r1/bgpd.conf
@@ -0,0 +1,10 @@
+router bgp 65000
+ neighbor 192.168.255.2 remote-as 65001
+ address-family ipv4 unicast
+ redistribute connected
+ aggregate-address 172.16.255.0/24 route-map aggr-rmap
+ exit-address-family
+!
+route-map aggr-rmap permit 10
+ set metric 123
+!
diff --git a/tests/topotests/bgp_aggregate-address_route-map/r1/zebra.conf b/tests/topotests/bgp_aggregate-address_route-map/r1/zebra.conf
new file mode 100644
index 0000000000..0a283c06d5
--- /dev/null
+++ b/tests/topotests/bgp_aggregate-address_route-map/r1/zebra.conf
@@ -0,0 +1,9 @@
+!
+interface lo
+ ip address 172.16.255.254/32
+!
+interface r1-eth0
+ ip address 192.168.255.1/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_aggregate-address_route-map/r2/bgpd.conf b/tests/topotests/bgp_aggregate-address_route-map/r2/bgpd.conf
new file mode 100644
index 0000000000..73d4d0aeea
--- /dev/null
+++ b/tests/topotests/bgp_aggregate-address_route-map/r2/bgpd.conf
@@ -0,0 +1,4 @@
+router bgp 65001
+ neighbor 192.168.255.1 remote-as 65000
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_aggregate-address_route-map/r2/zebra.conf b/tests/topotests/bgp_aggregate-address_route-map/r2/zebra.conf
new file mode 100644
index 0000000000..606c17bec9
--- /dev/null
+++ b/tests/topotests/bgp_aggregate-address_route-map/r2/zebra.conf
@@ -0,0 +1,6 @@
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_aggregate-address_route-map/test_bgp_aggregate-address_route-map.py b/tests/topotests/bgp_aggregate-address_route-map/test_bgp_aggregate-address_route-map.py
new file mode 100644
index 0000000000..d6753e9b23
--- /dev/null
+++ b/tests/topotests/bgp_aggregate-address_route-map/test_bgp_aggregate-address_route-map.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+
+#
+# bgp_aggregate-address_route-map.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2019 by
+# Network Device Education Foundation, Inc. ("NetDEF")
+#
+# 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.
+#
+
+"""
+bgp_aggregate-address_route-map.py:
+
+Test if works the following commands:
+router bgp 65031
+ address-family ipv4 unicast
+ aggregate-address 192.168.255.0/24 route-map aggr-rmap
+
+route-map aggr-rmap permit 10
+ set metric 123
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+import functools
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, '../'))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from mininet.topo import Topo
+
+class TemplateTopo(Topo):
+ def build(self, *_args, **_opts):
+ tgen = get_topogen(self)
+
+ for routern in range(1, 3):
+ tgen.add_router('r{}'.format(routern))
+
+ switch = tgen.add_switch('s1')
+ switch.add_link(tgen.gears['r1'])
+ switch.add_link(tgen.gears['r2'])
+
+def setup_module(mod):
+ tgen = Topogen(TemplateTopo, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+
+ for i, (rname, router) in enumerate(router_list.iteritems(), 1):
+ router.load_config(
+ TopoRouter.RD_ZEBRA,
+ os.path.join(CWD, '{}/zebra.conf'.format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP,
+ os.path.join(CWD, '{}/bgpd.conf'.format(rname))
+ )
+
+ tgen.start_router()
+
+def teardown_module(mod):
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+def test_bgp_maximum_prefix_invalid():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ router = tgen.gears['r2']
+
+ def _bgp_converge(router):
+ output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json"))
+ expected = {
+ '192.168.255.1': {
+ 'bgpState': 'Established',
+ 'addressFamilyInfo': {
+ 'ipv4Unicast': {
+ 'acceptedPrefixCounter': 3
+ }
+ }
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ def _bgp_aggregate_address_has_metric(router):
+ output = json.loads(router.vtysh_cmd("show ip bgp 172.16.255.0/24 json"))
+ expected = {
+ 'paths': [
+ {
+ 'med': 123
+ }
+ ]
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_converge, router)
+ success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5)
+
+ assert result is None, 'Failed to see bgp convergence in "{}"'.format(router)
+
+ test_func = functools.partial(_bgp_aggregate_address_has_metric, router)
+ success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5)
+
+ assert result is None, 'Failed to see applied metric for aggregated prefix in "{}"'.format(router)
+
+if __name__ == '__main__':
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py
index 149a420a32..547a5949a3 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py
@@ -11,16 +11,17 @@ for rtr in l3mdev_rtrs:
rtrs = ['r1', 'r3', 'r4']
for rtr in rtrs:
- luCommand(rtr, 'ip link show type vrf {}-cust1'.format(rtr),'cust1: .*UP,LOWER_UP','pass','VRF cust1 up')
- luCommand(rtr, 'ip add show vrf {}-cust1'.format(rtr),'r..eth4: .*UP,LOWER_UP.* 192.168','pass','VRF cust1 IP config')
+ luCommand(rtr, 'ip link show type vrf {}-cust1'.format(rtr),'cust1: .*UP','pass','VRF cust1 intf up')
+ luCommand(rtr, 'ip add show vrf {}-cust1'.format(rtr),'r..eth4.*UP','pass','VRF cust1 IP intf up')
+ luCommand(rtr, 'ip add show vrf {}-cust1'.format(rtr),'192.168','pass','VRF cust1 IP config')
luCommand(rtr, 'ip route show vrf {}-cust1'.format(rtr),'192.168...0/24 dev r.-eth','pass','VRF cust1 interface route')
-luCommand('r4', 'ip link show type vrf r4-cust2','cust2: .*UP,LOWER_UP','pass','VRF cust2 up')
-luCommand('r4', 'ip add show vrf r4-cust2','r..eth5.*UP,LOWER_UP.* 192.168','pass','VRF cust1 IP config')
+luCommand('r4', 'ip link show type vrf r4-cust2','cust2: .*UP','pass','VRF cust2 up')
+luCommand('r4', 'ip add show vrf r4-cust2','r..eth5.*UP.* 192.168','pass','VRF cust1 IP config')
luCommand(rtr, 'ip route show vrf r4-cust2'.format(rtr),'192.168...0/24 dev r.-eth','pass','VRF cust2 interface route')
rtrs = ['ce1', 'ce2', 'ce3']
for rtr in rtrs:
luCommand(rtr, 'ip route show','192.168...0/24 dev ce.-eth0','pass','CE interface route')
luCommand(rtr,'ping 192.168.1.1 -c 1',' 0. packet loss','wait','CE->PE ping')
-luCommand('ce4', 'ip link show type vrf ce4-cust2','cust2: .*UP,LOWER_UP','pass','VRF cust2 up')
+luCommand('ce4', 'ip link show type vrf ce4-cust2','cust2: .*UP','pass','VRF cust2 up')
luCommand('ce4', 'ip route show vrf ce4-cust2','192.168...0/24 dev ce.-eth0','pass','CE interface route')
luCommand('ce4','ping 192.168.2.1 -c 1 -I ce4-cust2',' 0. packet loss','wait','CE4->PE4 ping')
diff --git a/tests/topotests/bgp_rr_ibgp/spine1/bgpd.conf b/tests/topotests/bgp_rr_ibgp/spine1/bgpd.conf
new file mode 100644
index 0000000000..29a119c291
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/spine1/bgpd.conf
@@ -0,0 +1,8 @@
+hostname spine1
+router bgp 99
+ neighbor 192.168.2.1 remote-as internal
+ neighbor 192.168.4.2 remote-as internal
+ address-family ipv4 uni
+ redistribute connected
+ neighbor 192.168.2.1 route-reflector-client
+ neighbor 192.168.4.2 route-reflector-client
diff --git a/tests/topotests/bgp_rr_ibgp/spine1/show_ip_route.json_ref b/tests/topotests/bgp_rr_ibgp/spine1/show_ip_route.json_ref
new file mode 100644
index 0000000000..552e96ddb9
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/spine1/show_ip_route.json_ref
@@ -0,0 +1,162 @@
+{
+ "192.168.1.0\/24":[
+ {
+ "prefix":"192.168.1.0\/24",
+ "protocol":"bgp",
+ "selected":true,
+ "destSelected":true,
+ "distance":200,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":13,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"192.168.2.1",
+ "afi":"ipv4",
+ "interfaceIndex":2,
+ "interfaceName":"spine1-eth0",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.2.0\/24":[
+ {
+ "prefix":"192.168.2.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":2,
+ "interfaceName":"spine1-eth0",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.3.0\/24":[
+ {
+ "prefix":"192.168.3.0\/24",
+ "protocol":"bgp",
+ "selected":true,
+ "destSelected":true,
+ "distance":200,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":13,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"192.168.4.2",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"spine1-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.4.0\/24":[
+ {
+ "prefix":"192.168.4.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":3,
+ "interfaceName":"spine1-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.5.0\/24":[
+ {
+ "prefix":"192.168.5.0\/24",
+ "protocol":"bgp",
+ "selected":true,
+ "destSelected":true,
+ "distance":200,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":13,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"192.168.2.1",
+ "afi":"ipv4",
+ "interfaceIndex":2,
+ "interfaceName":"spine1-eth0",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.6.0\/24":[
+ {
+ "prefix":"192.168.6.0\/24",
+ "protocol":"bgp",
+ "selected":true,
+ "destSelected":true,
+ "distance":200,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":13,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"192.168.4.2",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"spine1-eth1",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_rr_ibgp/spine1/staticd.conf b/tests/topotests/bgp_rr_ibgp/spine1/staticd.conf
new file mode 100644
index 0000000000..6d8f0952d3
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/spine1/staticd.conf
@@ -0,0 +1 @@
+hostname spine1
diff --git a/tests/topotests/bgp_rr_ibgp/spine1/zebra.conf b/tests/topotests/bgp_rr_ibgp/spine1/zebra.conf
new file mode 100644
index 0000000000..ea25462d53
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/spine1/zebra.conf
@@ -0,0 +1,9 @@
+hostname spine1
+ip forwarding
+ipv6 forwarding
+
+int spine1-eth0
+ ip addr 192.168.2.3/24
+
+int spine1-eth1
+ ip addr 192.168.4.3/24
diff --git a/tests/topotests/bgp_rr_ibgp/spine2/bgpd.conf b/tests/topotests/bgp_rr_ibgp/spine2/bgpd.conf
new file mode 100644
index 0000000000..a865b388ac
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/spine2/bgpd.conf
@@ -0,0 +1,8 @@
+hostname spine2
+router bgp 99
+ neighbor 192.168.5.1 remote-as internal
+ neighbor 192.168.6.2 remote-as internal
+ address-family ipv4 uni
+ redistribute connected
+ neighbor 192.168.5.1 route-reflector-client
+ neighbor 192.168.6.2 route-reflector-client
diff --git a/tests/topotests/bgp_rr_ibgp/spine2/show_ip_route.json_ref b/tests/topotests/bgp_rr_ibgp/spine2/show_ip_route.json_ref
new file mode 100644
index 0000000000..c428a8832f
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/spine2/show_ip_route.json_ref
@@ -0,0 +1,162 @@
+{
+ "192.168.1.0\/24":[
+ {
+ "prefix":"192.168.1.0\/24",
+ "protocol":"bgp",
+ "selected":true,
+ "destSelected":true,
+ "distance":200,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":13,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"192.168.5.1",
+ "afi":"ipv4",
+ "interfaceIndex":2,
+ "interfaceName":"spine2-eth0",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.2.0\/24":[
+ {
+ "prefix":"192.168.2.0\/24",
+ "protocol":"bgp",
+ "selected":true,
+ "destSelected":true,
+ "distance":200,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":13,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"192.168.5.1",
+ "afi":"ipv4",
+ "interfaceIndex":2,
+ "interfaceName":"spine2-eth0",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.3.0\/24":[
+ {
+ "prefix":"192.168.3.0\/24",
+ "protocol":"bgp",
+ "selected":true,
+ "destSelected":true,
+ "distance":200,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":13,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"192.168.6.2",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"spine2-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.4.0\/24":[
+ {
+ "prefix":"192.168.4.0\/24",
+ "protocol":"bgp",
+ "selected":true,
+ "destSelected":true,
+ "distance":200,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":13,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"192.168.6.2",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"spine2-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.5.0\/24":[
+ {
+ "prefix":"192.168.5.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":2,
+ "interfaceName":"spine2-eth0",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.6.0\/24":[
+ {
+ "prefix":"192.168.6.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":3,
+ "interfaceName":"spine2-eth1",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_rr_ibgp/spine2/staticd.conf b/tests/topotests/bgp_rr_ibgp/spine2/staticd.conf
new file mode 100644
index 0000000000..3ee14d262c
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/spine2/staticd.conf
@@ -0,0 +1 @@
+hostname spine2
diff --git a/tests/topotests/bgp_rr_ibgp/spine2/zebra.conf b/tests/topotests/bgp_rr_ibgp/spine2/zebra.conf
new file mode 100644
index 0000000000..a06681fbc4
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/spine2/zebra.conf
@@ -0,0 +1,9 @@
+hostname spine2
+ip forwarding
+ipv6 forwarding
+
+int spine2-eth0
+ ip addr 192.168.5.4/24
+
+int spine2-eth1
+ ip addr 192.168.6.4/24
diff --git a/tests/topotests/bgp_rr_ibgp/test_bgp_rr_ibgp_topo1.py b/tests/topotests/bgp_rr_ibgp/test_bgp_rr_ibgp_topo1.py
new file mode 100755
index 0000000000..c28394a7a7
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/test_bgp_rr_ibgp_topo1.py
@@ -0,0 +1,245 @@
+#!/usr/bin/env python
+
+#
+# test_bgp_rr_ibgp_topo1.py
+#
+# Copyright (c) 2019 by
+# Cumulus Networks, Inc.
+# Donald Sharp
+#
+# 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_bgp_rr_ibgp_topo1.py: Testing IBGP with RR and no IGP
+
+
+ In a leaf/spine topology with only IBGP connections, where
+ the same network is being redistributed at multiple points
+ in the network ( say a redistribute connected at both leaf and spines )
+ we end up in a state where zebra gets very confused.
+
+ eva# show ip route
+ Codes: K - kernel route, C - connected, S - static, R - RIP,
+ O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+ F - PBR, f - OpenFabric,
+ > - selected route, * - FIB route, q - queued route, r - rejected route
+
+ C>* 192.168.1.0/24 is directly connected, tor1-eth0, 00:00:30
+ C>* 192.168.2.0/24 is directly connected, tor1-eth1, 00:00:30
+ B 192.168.3.0/24 [200/0] via 192.168.4.2 inactive, 00:00:25
+ via 192.168.6.2 inactive, 00:00:25
+ B>* 192.168.4.0/24 [200/0] via 192.168.2.3, tor1-eth1, 00:00:25
+ * via 192.168.6.2 inactive, 00:00:25
+ C>* 192.168.5.0/24 is directly connected, tor1-eth2, 00:00:30
+ B>* 192.168.6.0/24 [200/0] via 192.168.4.2 inactive, 00:00:25
+ * via 192.168.5.4, tor1-eth2, 00:00:25
+
+ Effectively we have ibgp routes recursing through ibgp routes
+ and there is no metric to discern whom to listen to.
+
+ This draft:
+ https://tools.ietf.org/html/draft-ietf-idr-bgp-optimal-route-reflection-19
+
+ appears to address this issue. From looking at both cisco and arista
+ deployments they are handling this issue by having the route reflector
+ prefer the localy learned routes over from their clients.
+
+ Add this topology, in a broken state, so that when we do fix this issue
+ it is a simple matter of touching this topology up and re-adding it
+ to the normal daily builds. I also wanted to add this topology
+ since it is in a state of `doneness` and I wanted to move onto
+ my normal day job without having to remember about this test.
+
+ This topology is not configured to be run as part of the normal
+ topotests.
+
+"""
+
+import os
+import re
+import sys
+import pytest
+import json
+
+# 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
+
+#####################################################
+##
+## Network Topology Definition
+##
+#####################################################
+
+class NetworkTopo(Topo):
+ "BGP_RR_IBGP Topology 1"
+
+ def build(self, **_opts):
+ "Build function"
+
+ tgen = get_topogen(self)
+
+ tgen.add_router('tor1')
+ tgen.add_router('tor2')
+ tgen.add_router('spine1')
+ tgen.add_router('spine2')
+
+ # First switch is for a dummy interface (for local network)
+ # on tor1
+ # 192.168.1.0/24
+ switch = tgen.add_switch('sw1')
+ switch.add_link(tgen.gears['tor1'])
+
+ # 192.168.2.0/24 - tor1 <-> spine1 connection
+ switch = tgen.add_switch('sw2')
+ switch.add_link(tgen.gears['tor1'])
+ switch.add_link(tgen.gears['spine1'])
+
+ # 3rd switch is for a dummy interface (for local netwokr)
+ # 192.168.3.0/24 - tor2
+ switch = tgen.add_switch('sw3')
+ switch.add_link(tgen.gears['tor2'])
+
+ # 192.168.4.0/24 - tor2 <-> spine1 connection
+ switch = tgen.add_switch('sw4')
+ switch.add_link(tgen.gears['tor2'])
+ switch.add_link(tgen.gears['spine1'])
+
+ # 192.168.5.0/24 - tor1 <-> spine2 connection
+ switch = tgen.add_switch('sw5')
+ switch.add_link(tgen.gears['tor1'])
+ switch.add_link(tgen.gears['spine2'])
+
+ # 192.168.6.0/24 - tor2 <-> spine2 connection
+ switch = tgen.add_switch('sw6')
+ switch.add_link(tgen.gears['tor2'])
+ switch.add_link(tgen.gears['spine2'])
+
+#####################################################
+##
+## Tests starting
+##
+#####################################################
+
+def setup_module(module):
+ "Setup topology"
+ tgen = Topogen(NetworkTopo, module.__name__)
+ tgen.start_topology()
+
+ # This is a sample of configuration loading.
+ router_list = tgen.routers()
+ for rname, router in router_list.iteritems():
+ router.load_config(
+ TopoRouter.RD_ZEBRA,
+ os.path.join(CWD, '{}/zebra.conf'.format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP,
+ os.path.join(CWD, '{}/bgpd.conf'.format(rname))
+ )
+
+ tgen.start_router()
+ # tgen.mininet_cli()
+
+
+def teardown_module(_mod):
+ "Teardown the pytest environment"
+ tgen = get_topogen()
+
+ # This function tears down the whole topology.
+ tgen.stop_topology()
+
+
+def test_converge_protocols():
+ "Wait for protocol convergence"
+
+ tgen = get_topogen()
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ topotest.sleep(5, 'Waiting for BGP_RR_IBGP convergence')
+
+
+def test_bgp_rr_ibgp_routes():
+ "Test Route Reflection"
+
+ tgen = get_topogen()
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Verify BGP_RR_IBGP Status
+ logger.info("Verifying BGP_RR_IBGP routes")
+
+def test_zebra_ipv4_routingTable():
+ "Test 'show ip route'"
+
+ tgen = get_topogen()
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ failures = 0
+ router_list = tgen.routers().values()
+ for router in router_list:
+ output = router.vtysh_cmd('show ip route json', isjson=True)
+ refTableFile = '{}/{}/show_ip_route.json_ref'.format(CWD, router.name)
+ expected = json.loads(open(refTableFile).read())
+
+ assertmsg = 'Zebra IPv4 Routing Table verification failed for router {}'.format(router.name)
+ assert topotest.json_cmp(output, expected) is None, assertmsg
+
+def test_shutdown_check_stderr():
+ if os.environ.get('TOPOTESTS_CHECK_STDERR') is None:
+ pytest.skip('Skipping test for Stderr output and memory leaks')
+
+ tgen = get_topogen()
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Verifying unexpected STDERR output from daemons")
+
+ router_list = tgen.routers().values()
+ for router in router_list:
+ router.stop()
+
+ log = tgen.net[router.name].getStdErr('bgpd')
+ if log:
+ logger.error('BGPd StdErr Log:' + log)
+ log = tgen.net[router.name].getStdErr('zebra')
+ if log:
+ logger.error('Zebra StdErr Log:' + log)
+
+
+if __name__ == '__main__':
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
+
+#
+# Auxiliary Functions
+#
diff --git a/tests/topotests/bgp_rr_ibgp/tor1/bgpd.conf b/tests/topotests/bgp_rr_ibgp/tor1/bgpd.conf
new file mode 100644
index 0000000000..44a78dffd7
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/tor1/bgpd.conf
@@ -0,0 +1,5 @@
+hostname tor1
+router bgp 99
+ neighbor 192.168.2.3 remote-as internal
+ neighbor 192.168.5.4 remote-as internal
+ redistribute connected
diff --git a/tests/topotests/bgp_rr_ibgp/tor1/show_ip_route.json_ref b/tests/topotests/bgp_rr_ibgp/tor1/show_ip_route.json_ref
new file mode 100644
index 0000000000..223dcebbca
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/tor1/show_ip_route.json_ref
@@ -0,0 +1,169 @@
+{
+ "192.168.1.0\/24":[
+ {
+ "prefix":"192.168.1.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":2,
+ "interfaceName":"tor1-eth0",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.2.0\/24":[
+ {
+ "prefix":"192.168.2.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":3,
+ "interfaceName":"tor1-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.3.0\/24":[
+ {
+ "prefix":"192.168.3.0\/24",
+ "protocol":"bgp",
+ "distance":200,
+ "metric":0,
+ "table":254,
+ "internalStatus":0,
+ "internalFlags":5,
+ "internalNextHopNum":2,
+ "internalNextHopActiveNum":0,
+ "nexthops":[
+ {
+ "flags":0,
+ "ip":"192.168.4.2",
+ "afi":"ipv4"
+ },
+ {
+ "flags":0,
+ "ip":"192.168.6.2",
+ "afi":"ipv4"
+ }
+ ]
+ }
+ ],
+ "192.168.4.0\/24":[
+ {
+ "prefix":"192.168.4.0\/24",
+ "protocol":"bgp",
+ "selected":true,
+ "destSelected":true,
+ "distance":200,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":13,
+ "internalNextHopNum":2,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"192.168.2.3",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"tor1-eth1",
+ "active":true
+ },
+ {
+ "flags":0,
+ "ip":"192.168.6.2",
+ "afi":"ipv4"
+ }
+ ]
+ }
+ ],
+ "192.168.5.0\/24":[
+ {
+ "prefix":"192.168.5.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":4,
+ "interfaceName":"tor1-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.6.0\/24":[
+ {
+ "prefix":"192.168.6.0\/24",
+ "protocol":"bgp",
+ "selected":true,
+ "destSelected":true,
+ "distance":200,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":13,
+ "internalNextHopNum":2,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":0,
+ "ip":"192.168.4.2",
+ "afi":"ipv4"
+ },
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"192.168.5.4",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"tor1-eth2",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_rr_ibgp/tor1/staticd.conf b/tests/topotests/bgp_rr_ibgp/tor1/staticd.conf
new file mode 100644
index 0000000000..bb8d510b01
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/tor1/staticd.conf
@@ -0,0 +1 @@
+hostname tor1
diff --git a/tests/topotests/bgp_rr_ibgp/tor1/zebra.conf b/tests/topotests/bgp_rr_ibgp/tor1/zebra.conf
new file mode 100644
index 0000000000..f2fa713507
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/tor1/zebra.conf
@@ -0,0 +1,12 @@
+hostname tor1
+ip forwarding
+ipv6 forwarding
+
+int tor1-eth0
+ ip addr 192.168.1.1/24
+
+int tor1-eth1
+ ip addr 192.168.2.1/24
+
+int tor1-eth2
+ ip addr 192.168.5.1/24
diff --git a/tests/topotests/bgp_rr_ibgp/tor2/bgpd.conf b/tests/topotests/bgp_rr_ibgp/tor2/bgpd.conf
new file mode 100644
index 0000000000..5ef1de260e
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/tor2/bgpd.conf
@@ -0,0 +1,5 @@
+hostname tor2
+router bgp 99
+ neighbor 192.168.4.3 remote-as internal
+ neighbor 192.168.6.4 remote-as internal
+ redistribute connected
diff --git a/tests/topotests/bgp_rr_ibgp/tor2/show_ip_route.json_ref b/tests/topotests/bgp_rr_ibgp/tor2/show_ip_route.json_ref
new file mode 100644
index 0000000000..5f041b8c62
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/tor2/show_ip_route.json_ref
@@ -0,0 +1,169 @@
+{
+ "192.168.1.0\/24":[
+ {
+ "prefix":"192.168.1.0\/24",
+ "protocol":"bgp",
+ "distance":200,
+ "metric":0,
+ "table":254,
+ "internalStatus":0,
+ "internalFlags":5,
+ "internalNextHopNum":2,
+ "internalNextHopActiveNum":0,
+ "nexthops":[
+ {
+ "flags":0,
+ "ip":"192.168.2.1",
+ "afi":"ipv4"
+ },
+ {
+ "flags":0,
+ "ip":"192.168.5.1",
+ "afi":"ipv4"
+ }
+ ]
+ }
+ ],
+ "192.168.2.0\/24":[
+ {
+ "prefix":"192.168.2.0\/24",
+ "protocol":"bgp",
+ "selected":true,
+ "destSelected":true,
+ "distance":200,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":13,
+ "internalNextHopNum":2,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"192.168.4.3",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"tor2-eth1",
+ "active":true
+ },
+ {
+ "flags":0,
+ "ip":"192.168.5.1",
+ "afi":"ipv4"
+ }
+ ]
+ }
+ ],
+ "192.168.3.0\/24":[
+ {
+ "prefix":"192.168.3.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":2,
+ "interfaceName":"tor2-eth0",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.4.0\/24":[
+ {
+ "prefix":"192.168.4.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":3,
+ "interfaceName":"tor2-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.5.0\/24":[
+ {
+ "prefix":"192.168.5.0\/24",
+ "protocol":"bgp",
+ "selected":true,
+ "destSelected":true,
+ "distance":200,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":13,
+ "internalNextHopNum":2,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":0,
+ "ip":"192.168.2.1",
+ "afi":"ipv4"
+ },
+ {
+ "flags":3,
+ "fib":true,
+ "ip":"192.168.6.4",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"tor2-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.6.0\/24":[
+ {
+ "prefix":"192.168.6.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "internalStatus":16,
+ "internalFlags":8,
+ "internalNextHopNum":1,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "flags":3,
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":4,
+ "interfaceName":"tor2-eth2",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_rr_ibgp/tor2/staticd.conf b/tests/topotests/bgp_rr_ibgp/tor2/staticd.conf
new file mode 100644
index 0000000000..03098e75d9
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/tor2/staticd.conf
@@ -0,0 +1 @@
+hostname tor2
diff --git a/tests/topotests/bgp_rr_ibgp/tor2/zebra.conf b/tests/topotests/bgp_rr_ibgp/tor2/zebra.conf
new file mode 100644
index 0000000000..3318cbb196
--- /dev/null
+++ b/tests/topotests/bgp_rr_ibgp/tor2/zebra.conf
@@ -0,0 +1,13 @@
+hostname tor2
+ip forwarding
+ipv6 forwarding
+
+int tor2-eth0
+ ip addr 192.168.3.2/24
+
+int tor2-eth1
+ ip addr 192.168.4.2/24
+
+
+int tor2-eth2
+ ip addr 192.168.6.2/24
diff --git a/tests/topotests/conftest.py b/tests/topotests/conftest.py
index 49e48ba927..76b0ab017e 100755
--- a/tests/topotests/conftest.py
+++ b/tests/topotests/conftest.py
@@ -74,3 +74,9 @@ def pytest_runtest_makereport(item, call):
parent._previousfailed = item
logger.error('assert failed at "{}/{}": {}'.format(
modname, item.name, call.excinfo.value))
+
+ # (topogen) Set topology error to avoid advancing in the test.
+ tgen = get_topogen()
+ if tgen is not None:
+ # This will cause topogen to report error on `routers_have_failure`.
+ tgen.set_error('{}/{}'.format(modname, item.name))
diff --git a/tests/topotests/ldp-topo1/r1/ip_mpls_route.ref-1 b/tests/topotests/ldp-topo1/r1/ip_mpls_route.ref-1
deleted file mode 100644
index f244122f1a..0000000000
--- a/tests/topotests/ldp-topo1/r1/ip_mpls_route.ref-1
+++ /dev/null
@@ -1,5 +0,0 @@
-xx as to xx via inet 10.0.1.2 dev r1-eth0 proto xx
-xx as to xx via inet 10.0.1.2 dev r1-eth0 proto xx
-xx via inet 10.0.1.2 dev r1-eth0 proto xx
-xx via inet 10.0.1.2 dev r1-eth0 proto xx
-xx via inet 10.0.1.2 dev r1-eth0 proto xx
diff --git a/tests/topotests/ldp-topo1/r1/show_ipv4_route.ref-1 b/tests/topotests/ldp-topo1/r1/show_ipv4_route.ref-1
deleted file mode 100644
index ff99ff9866..0000000000
--- a/tests/topotests/ldp-topo1/r1/show_ipv4_route.ref-1
+++ /dev/null
@@ -1,7 +0,0 @@
-O 1.1.1.1/32 [110/0] is directly connected, lo
-O>* 2.2.2.2/32 [110/10] via 10.0.1.2, r1-eth0
-O>* 3.3.3.3/32 [110/20] via 10.0.1.2, r1-eth0, label xxx
-O>* 4.4.4.4/32 [110/20] via 10.0.1.2, r1-eth0, label xxx
-O 10.0.1.0/24 [110/10] is directly connected, r1-eth0
-O>* 10.0.2.0/24 [110/20] via 10.0.1.2, r1-eth0
-O>* 10.0.3.0/24 [110/20] via 10.0.1.2, r1-eth0
diff --git a/tests/topotests/ldp-topo1/r1/show_mpls_ldp_binding.ref-1 b/tests/topotests/ldp-topo1/r1/show_mpls_ldp_binding.ref-1
deleted file mode 100644
index ff72a1c0b7..0000000000
--- a/tests/topotests/ldp-topo1/r1/show_mpls_ldp_binding.ref-1
+++ /dev/null
@@ -1,42 +0,0 @@
-1.1.1.1/32
- Local binding: label: imp-null
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 xxx
-2.2.2.2/32
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 imp-null
-3.3.3.3/32
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 xxx
-4.4.4.4/32
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 xxx
-10.0.1.0/24
- Local binding: label: imp-null
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 imp-null
-10.0.2.0/24
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 imp-null
-10.0.3.0/24
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 imp-null
diff --git a/tests/topotests/ldp-topo1/r1/show_mpls_ldp_discovery.ref-1 b/tests/topotests/ldp-topo1/r1/show_mpls_ldp_discovery.ref-1
deleted file mode 100644
index 38522e162e..0000000000
--- a/tests/topotests/ldp-topo1/r1/show_mpls_ldp_discovery.ref-1
+++ /dev/null
@@ -1,7 +0,0 @@
-Local LDP Identifier: 1.1.1.1:0
-Discovery Sources:
- Interfaces:
- r1-eth0: xmit/recv
- LDP Id: 2.2.2.2:0, Transport address: 2.2.2.2
- Hold time: 15 sec
- Targeted Hellos:
diff --git a/tests/topotests/ldp-topo1/r1/show_mpls_ldp_interface.ref-1 b/tests/topotests/ldp-topo1/r1/show_mpls_ldp_interface.ref-1
deleted file mode 100644
index 0fb15d2da7..0000000000
--- a/tests/topotests/ldp-topo1/r1/show_mpls_ldp_interface.ref-1
+++ /dev/null
@@ -1,2 +0,0 @@
-AF Interface State Uptime Hello Timers ac
-ipv4 r1-eth0 ACTIVE xx:xx:xx 5/15 1
diff --git a/tests/topotests/ldp-topo1/r1/show_mpls_ldp_neighbor.ref-1 b/tests/topotests/ldp-topo1/r1/show_mpls_ldp_neighbor.ref-1
deleted file mode 100644
index 3df98bfae5..0000000000
--- a/tests/topotests/ldp-topo1/r1/show_mpls_ldp_neighbor.ref-1
+++ /dev/null
@@ -1,8 +0,0 @@
-Peer LDP Identifier: 2.2.2.2:0
- TCP connection: 1.1.1.1:xxx - 2.2.2.2:xxx
- Session Holdtime: 180 sec
- State: OPERATIONAL; Downstream-Unsolicited
- Up time: xx:xx:xx
- LDP Discovery Sources:
- IPv4:
- Interface: r1-eth0
diff --git a/tests/topotests/ldp-topo1/r1/show_mpls_table.ref b/tests/topotests/ldp-topo1/r1/show_mpls_table.ref
index 61cb9eec82..7e24359af3 100644
--- a/tests/topotests/ldp-topo1/r1/show_mpls_table.ref
+++ b/tests/topotests/ldp-topo1/r1/show_mpls_table.ref
@@ -1,8 +1,8 @@
- Inbound Outbound
- Label Type Nexthop Label
--------- ------- --------------- --------
- XX LDP 10.0.1.2 XX
- XX LDP 10.0.1.2 XX
- XX LDP 10.0.1.2 implicit-null
- XX LDP 10.0.1.2 implicit-null
- XX LDP 10.0.1.2 implicit-null
+ Inbound Label Type Nexthop Outbound Label
+ -----------------------------------------------
+ XX LDP 10.0.1.2 XX
+ XX LDP 10.0.1.2 XX
+ XX LDP 10.0.1.2 implicit-null
+ XX LDP 10.0.1.2 implicit-null
+ XX LDP 10.0.1.2 implicit-null
+
diff --git a/tests/topotests/ldp-topo1/r1/show_mpls_table.ref-1 b/tests/topotests/ldp-topo1/r1/show_mpls_table.ref-1
deleted file mode 100644
index 912a082019..0000000000
--- a/tests/topotests/ldp-topo1/r1/show_mpls_table.ref-1
+++ /dev/null
@@ -1,8 +0,0 @@
- Inbound Outbound
- Label Type Nexthop Label
--------- ------- --------------- --------
- XX LDP 10.0.1.2 3
- XX LDP 10.0.1.2 3
- XX LDP 10.0.1.2 3
- XX LDP 10.0.1.2 XX
- XX LDP 10.0.1.2 XX
diff --git a/tests/topotests/ldp-topo1/r1/show_mpls_table.ref-no-impl-null b/tests/topotests/ldp-topo1/r1/show_mpls_table.ref-no-impl-null
deleted file mode 100644
index 912a082019..0000000000
--- a/tests/topotests/ldp-topo1/r1/show_mpls_table.ref-no-impl-null
+++ /dev/null
@@ -1,8 +0,0 @@
- Inbound Outbound
- Label Type Nexthop Label
--------- ------- --------------- --------
- XX LDP 10.0.1.2 3
- XX LDP 10.0.1.2 3
- XX LDP 10.0.1.2 3
- XX LDP 10.0.1.2 XX
- XX LDP 10.0.1.2 XX
diff --git a/tests/topotests/ldp-topo1/r2/show_ipv4_route.ref-1 b/tests/topotests/ldp-topo1/r2/show_ipv4_route.ref-1
deleted file mode 100644
index eaec2f16b9..0000000000
--- a/tests/topotests/ldp-topo1/r2/show_ipv4_route.ref-1
+++ /dev/null
@@ -1,7 +0,0 @@
-O>* 1.1.1.1/32 [110/10] via 10.0.1.1, r2-eth0
-O 2.2.2.2/32 [110/0] is directly connected, lo
-O>* 3.3.3.3/32 [110/10] via 10.0.2.3, r2-eth1
-O>* 4.4.4.4/32 [110/10] via 10.0.2.4, r2-eth1
-O 10.0.1.0/24 [110/10] is directly connected, r2-eth0
-O 10.0.2.0/24 [110/10] is directly connected, r2-eth1
-O 10.0.3.0/24 [110/10] is directly connected, r2-eth2
diff --git a/tests/topotests/ldp-topo1/r2/show_mpls_ldp_binding.ref-1 b/tests/topotests/ldp-topo1/r2/show_mpls_ldp_binding.ref-1
deleted file mode 100644
index 54ee39080a..0000000000
--- a/tests/topotests/ldp-topo1/r2/show_mpls_ldp_binding.ref-1
+++ /dev/null
@@ -1,56 +0,0 @@
-1.1.1.1/32
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 1.1.1.1 imp-null
- 3.3.3.3 xxx
- 4.4.4.4 xxx
-2.2.2.2/32
- Local binding: label: imp-null
- Remote bindings:
- Peer Label
- ----------------- ---------
- 1.1.1.1 xxx
- 3.3.3.3 xxx
- 4.4.4.4 xxx
-3.3.3.3/32
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 1.1.1.1 xxx
- 3.3.3.3 imp-null
- 4.4.4.4 xxx
-4.4.4.4/32
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 1.1.1.1 xxx
- 3.3.3.3 xxx
- 4.4.4.4 imp-null
-10.0.1.0/24
- Local binding: label: imp-null
- Remote bindings:
- Peer Label
- ----------------- ---------
- 1.1.1.1 imp-null
- 3.3.3.3 xxx
- 4.4.4.4 xxx
-10.0.2.0/24
- Local binding: label: imp-null
- Remote bindings:
- Peer Label
- ----------------- ---------
- 1.1.1.1 xxx
- 3.3.3.3 imp-null
- 4.4.4.4 imp-null
-10.0.3.0/24
- Local binding: label: imp-null
- Remote bindings:
- Peer Label
- ----------------- ---------
- 1.1.1.1 xxx
- 3.3.3.3 imp-null
- 4.4.4.4 xxx
diff --git a/tests/topotests/ldp-topo1/r2/show_mpls_ldp_discovery.ref-1 b/tests/topotests/ldp-topo1/r2/show_mpls_ldp_discovery.ref-1
deleted file mode 100644
index b1bebd7c46..0000000000
--- a/tests/topotests/ldp-topo1/r2/show_mpls_ldp_discovery.ref-1
+++ /dev/null
@@ -1,12 +0,0 @@
-Local LDP Identifier: 2.2.2.2:0
-Discovery Sources:
- Interfaces:
- r2-eth0: xmit/recv
- LDP Id: 1.1.1.1:0, Transport address: 1.1.1.1
- Hold time: 15 sec
- r2-eth1: xmit/recv
- LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3
- Hold time: 15 sec
- LDP Id: 4.4.4.4:0, Transport address: 4.4.4.4
- Hold time: 15 sec
- Targeted Hellos:
diff --git a/tests/topotests/ldp-topo1/r2/show_mpls_ldp_interface.ref-1 b/tests/topotests/ldp-topo1/r2/show_mpls_ldp_interface.ref-1
deleted file mode 100644
index f9fc98408c..0000000000
--- a/tests/topotests/ldp-topo1/r2/show_mpls_ldp_interface.ref-1
+++ /dev/null
@@ -1,3 +0,0 @@
-AF Interface State Uptime Hello Timers ac
-ipv4 r2-eth0 ACTIVE xx:xx:xx 5/15 1
-ipv4 r2-eth1 ACTIVE xx:xx:xx 5/15 2
diff --git a/tests/topotests/ldp-topo1/r2/show_mpls_ldp_neighbor.ref-1 b/tests/topotests/ldp-topo1/r2/show_mpls_ldp_neighbor.ref-1
deleted file mode 100644
index a70e2f48c6..0000000000
--- a/tests/topotests/ldp-topo1/r2/show_mpls_ldp_neighbor.ref-1
+++ /dev/null
@@ -1,26 +0,0 @@
-Peer LDP Identifier: 1.1.1.1:0
- TCP connection: 2.2.2.2:xxx - 1.1.1.1:xxx
- Session Holdtime: 180 sec
- State: OPERATIONAL; Downstream-Unsolicited
- Up time: xx:xx:xx
- LDP Discovery Sources:
- IPv4:
- Interface: r2-eth0
-
-Peer LDP Identifier: 3.3.3.3:0
- TCP connection: 2.2.2.2:xxx - 3.3.3.3:xxx
- Session Holdtime: 180 sec
- State: OPERATIONAL; Downstream-Unsolicited
- Up time: xx:xx:xx
- LDP Discovery Sources:
- IPv4:
- Interface: r2-eth1
-
-Peer LDP Identifier: 4.4.4.4:0
- TCP connection: 2.2.2.2:xxx - 4.4.4.4:xxx
- Session Holdtime: 180 sec
- State: OPERATIONAL; Downstream-Unsolicited
- Up time: xx:xx:xx
- LDP Discovery Sources:
- IPv4:
- Interface: r2-eth1
diff --git a/tests/topotests/ldp-topo1/r2/show_mpls_table.ref b/tests/topotests/ldp-topo1/r2/show_mpls_table.ref
index 46420ccd11..df05a6b31a 100644
--- a/tests/topotests/ldp-topo1/r2/show_mpls_table.ref
+++ b/tests/topotests/ldp-topo1/r2/show_mpls_table.ref
@@ -1,7 +1,7 @@
- Inbound Outbound
- Label Type Nexthop Label
--------- ------- --------------- --------
- XX LDP 10.0.1.1 implicit-null
- XX LDP 10.0.2.3 implicit-null
- XX LDP 10.0.2.4 implicit-null
- XX LDP 10.0.3.3 implicit-null
+ Inbound Label Type Nexthop Outbound Label
+ -----------------------------------------------
+ XX LDP 10.0.1.1 implicit-null
+ XX LDP 10.0.2.3 implicit-null
+ XX LDP 10.0.2.4 implicit-null
+ XX LDP 10.0.3.3 implicit-null
+
diff --git a/tests/topotests/ldp-topo1/r2/show_mpls_table.ref-1 b/tests/topotests/ldp-topo1/r2/show_mpls_table.ref-1
deleted file mode 100644
index ba244e76ec..0000000000
--- a/tests/topotests/ldp-topo1/r2/show_mpls_table.ref-1
+++ /dev/null
@@ -1,7 +0,0 @@
- Inbound Outbound
- Label Type Nexthop Label
--------- ------- --------------- --------
- XX LDP 10.0.1.1 3
- XX LDP 10.0.2.3 3
- XX LDP 10.0.2.4 3
- XX LDP 10.0.3.3 3
diff --git a/tests/topotests/ldp-topo1/r2/show_mpls_table.ref-no-impl-null b/tests/topotests/ldp-topo1/r2/show_mpls_table.ref-no-impl-null
deleted file mode 100644
index ba244e76ec..0000000000
--- a/tests/topotests/ldp-topo1/r2/show_mpls_table.ref-no-impl-null
+++ /dev/null
@@ -1,7 +0,0 @@
- Inbound Outbound
- Label Type Nexthop Label
--------- ------- --------------- --------
- XX LDP 10.0.1.1 3
- XX LDP 10.0.2.3 3
- XX LDP 10.0.2.4 3
- XX LDP 10.0.3.3 3
diff --git a/tests/topotests/ldp-topo1/r3/show_ipv4_route.ref-1 b/tests/topotests/ldp-topo1/r3/show_ipv4_route.ref-1
deleted file mode 100644
index c8a29400b2..0000000000
--- a/tests/topotests/ldp-topo1/r3/show_ipv4_route.ref-1
+++ /dev/null
@@ -1,7 +0,0 @@
-O>* 1.1.1.1/32 [110/20] via 10.0.2.2, r3-eth0, label xxx
-O>* 2.2.2.2/32 [110/10] via 10.0.2.2, r3-eth0
-O 3.3.3.3/32 [110/0] is directly connected, lo
-O>* 4.4.4.4/32 [110/10] via 10.0.2.4, r3-eth0
-O>* 10.0.1.0/24 [110/20] via 10.0.2.2, r3-eth0
-O 10.0.2.0/24 [110/10] is directly connected, r3-eth0
-O 10.0.3.0/24 [110/10] is directly connected, r3-eth1
diff --git a/tests/topotests/ldp-topo1/r3/show_mpls_ldp_binding.ref-1 b/tests/topotests/ldp-topo1/r3/show_mpls_ldp_binding.ref-1
deleted file mode 100644
index e04d2b7e4a..0000000000
--- a/tests/topotests/ldp-topo1/r3/show_mpls_ldp_binding.ref-1
+++ /dev/null
@@ -1,49 +0,0 @@
-1.1.1.1/32
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 xxx
- 4.4.4.4 xxx
-2.2.2.2/32
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 imp-null
- 4.4.4.4 xxx
-3.3.3.3/32
- Local binding: label: imp-null
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 xxx
- 4.4.4.4 xxx
-4.4.4.4/32
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 xxx
- 4.4.4.4 imp-null
-10.0.1.0/24
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 imp-null
- 4.4.4.4 xxx
-10.0.2.0/24
- Local binding: label: imp-null
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 imp-null
- 4.4.4.4 imp-null
-10.0.3.0/24
- Local binding: label: imp-null
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 imp-null
- 4.4.4.4 xxx
diff --git a/tests/topotests/ldp-topo1/r3/show_mpls_ldp_discovery.ref-1 b/tests/topotests/ldp-topo1/r3/show_mpls_ldp_discovery.ref-1
deleted file mode 100644
index 5e299fff9c..0000000000
--- a/tests/topotests/ldp-topo1/r3/show_mpls_ldp_discovery.ref-1
+++ /dev/null
@@ -1,9 +0,0 @@
-Local LDP Identifier: 3.3.3.3:0
-Discovery Sources:
- Interfaces:
- r3-eth0: xmit/recv
- LDP Id: 2.2.2.2:0, Transport address: 2.2.2.2
- Hold time: 15 sec
- LDP Id: 4.4.4.4:0, Transport address: 4.4.4.4
- Hold time: 15 sec
- Targeted Hellos:
diff --git a/tests/topotests/ldp-topo1/r3/show_mpls_ldp_interface.ref-1 b/tests/topotests/ldp-topo1/r3/show_mpls_ldp_interface.ref-1
deleted file mode 100644
index 243811e3a9..0000000000
--- a/tests/topotests/ldp-topo1/r3/show_mpls_ldp_interface.ref-1
+++ /dev/null
@@ -1,2 +0,0 @@
-AF Interface State Uptime Hello Timers ac
-ipv4 r3-eth0 ACTIVE xx:xx:xx 5/15 2
diff --git a/tests/topotests/ldp-topo1/r3/show_mpls_ldp_neighbor.ref-1 b/tests/topotests/ldp-topo1/r3/show_mpls_ldp_neighbor.ref-1
deleted file mode 100644
index ee1983ac29..0000000000
--- a/tests/topotests/ldp-topo1/r3/show_mpls_ldp_neighbor.ref-1
+++ /dev/null
@@ -1,17 +0,0 @@
-Peer LDP Identifier: 2.2.2.2:0
- TCP connection: 3.3.3.3:xxx - 2.2.2.2:xxx
- Session Holdtime: 180 sec
- State: OPERATIONAL; Downstream-Unsolicited
- Up time: xx:xx:xx
- LDP Discovery Sources:
- IPv4:
- Interface: r3-eth0
-
-Peer LDP Identifier: 4.4.4.4:0
- TCP connection: 3.3.3.3:xxx - 4.4.4.4:xxx
- Session Holdtime: 180 sec
- State: OPERATIONAL; Downstream-Unsolicited
- Up time: xx:xx:xx
- LDP Discovery Sources:
- IPv4:
- Interface: r3-eth0
diff --git a/tests/topotests/ldp-topo1/r3/show_mpls_table.ref b/tests/topotests/ldp-topo1/r3/show_mpls_table.ref
index c367f240f4..3978895613 100644
--- a/tests/topotests/ldp-topo1/r3/show_mpls_table.ref
+++ b/tests/topotests/ldp-topo1/r3/show_mpls_table.ref
@@ -1,10 +1,10 @@
- Inbound Outbound
- Label Type Nexthop Label
--------- ------- --------------- --------
- XX LDP 10.0.2.2 XX
- XX LDP 10.0.2.2 implicit-null
- XX LDP 10.0.2.2 implicit-null
- XX LDP 10.0.2.4 implicit-null
- XX LDP 10.0.3.2 XX
- XX LDP 10.0.3.2 implicit-null
- XX LDP 10.0.3.2 implicit-null
+ Inbound Label Type Nexthop Outbound Label
+ -----------------------------------------------
+ XX LDP 10.0.2.2 XX
+ XX LDP 10.0.2.2 implicit-null
+ XX LDP 10.0.2.2 implicit-null
+ XX LDP 10.0.2.4 implicit-null
+ XX LDP 10.0.3.2 XX
+ XX LDP 10.0.3.2 implicit-null
+ XX LDP 10.0.3.2 implicit-null
+
diff --git a/tests/topotests/ldp-topo1/r3/show_mpls_table.ref-1 b/tests/topotests/ldp-topo1/r3/show_mpls_table.ref-1
deleted file mode 100644
index 9198969bd5..0000000000
--- a/tests/topotests/ldp-topo1/r3/show_mpls_table.ref-1
+++ /dev/null
@@ -1,10 +0,0 @@
- Inbound Outbound
- Label Type Nexthop Label
--------- ------- --------------- --------
- XX LDP 10.0.2.2 3
- XX LDP 10.0.2.2 3
- XX LDP 10.0.2.2 XX
- XX LDP 10.0.2.4 3
- XX LDP 10.0.3.2 3
- XX LDP 10.0.3.2 3
- XX LDP 10.0.3.2 XX
diff --git a/tests/topotests/ldp-topo1/r3/show_mpls_table.ref-no-impl-null b/tests/topotests/ldp-topo1/r3/show_mpls_table.ref-no-impl-null
deleted file mode 100644
index 9198969bd5..0000000000
--- a/tests/topotests/ldp-topo1/r3/show_mpls_table.ref-no-impl-null
+++ /dev/null
@@ -1,10 +0,0 @@
- Inbound Outbound
- Label Type Nexthop Label
--------- ------- --------------- --------
- XX LDP 10.0.2.2 3
- XX LDP 10.0.2.2 3
- XX LDP 10.0.2.2 XX
- XX LDP 10.0.2.4 3
- XX LDP 10.0.3.2 3
- XX LDP 10.0.3.2 3
- XX LDP 10.0.3.2 XX
diff --git a/tests/topotests/ldp-topo1/r4/show_ipv4_route.ref-1 b/tests/topotests/ldp-topo1/r4/show_ipv4_route.ref-1
deleted file mode 100644
index df2a2b585f..0000000000
--- a/tests/topotests/ldp-topo1/r4/show_ipv4_route.ref-1
+++ /dev/null
@@ -1,7 +0,0 @@
-O>* 1.1.1.1/32 [110/20] via 10.0.2.2, r4-eth0, label xxx
-O>* 2.2.2.2/32 [110/10] via 10.0.2.2, r4-eth0
-O>* 3.3.3.3/32 [110/10] via 10.0.2.3, r4-eth0
-O 4.4.4.4/32 [110/0] is directly connected, lo
-O>* 10.0.1.0/24 [110/20] via 10.0.2.2, r4-eth0
-O 10.0.2.0/24 [110/10] is directly connected, r4-eth0
-O>* 10.0.3.0/24 [110/20] via 10.0.2.2, r4-eth0
diff --git a/tests/topotests/ldp-topo1/r4/show_mpls_ldp_binding.ref-1 b/tests/topotests/ldp-topo1/r4/show_mpls_ldp_binding.ref-1
deleted file mode 100644
index 3d55805d7c..0000000000
--- a/tests/topotests/ldp-topo1/r4/show_mpls_ldp_binding.ref-1
+++ /dev/null
@@ -1,49 +0,0 @@
-1.1.1.1/32
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 xxx
- 3.3.3.3 xxx
-2.2.2.2/32
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 imp-null
- 3.3.3.3 xxx
-3.3.3.3/32
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 xxx
- 3.3.3.3 imp-null
-4.4.4.4/32
- Local binding: label: imp-null
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 xxx
- 3.3.3.3 xxx
-10.0.1.0/24
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 imp-null
- 3.3.3.3 xxx
-10.0.2.0/24
- Local binding: label: imp-null
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 imp-null
- 3.3.3.3 imp-null
-10.0.3.0/24
- Local binding: label: xxx
- Remote bindings:
- Peer Label
- ----------------- ---------
- 2.2.2.2 imp-null
- 3.3.3.3 imp-null
diff --git a/tests/topotests/ldp-topo1/r4/show_mpls_ldp_discovery.ref-1 b/tests/topotests/ldp-topo1/r4/show_mpls_ldp_discovery.ref-1
deleted file mode 100644
index 3ebddd606a..0000000000
--- a/tests/topotests/ldp-topo1/r4/show_mpls_ldp_discovery.ref-1
+++ /dev/null
@@ -1,9 +0,0 @@
-Local LDP Identifier: 4.4.4.4:0
-Discovery Sources:
- Interfaces:
- r4-eth0: xmit/recv
- LDP Id: 2.2.2.2:0, Transport address: 2.2.2.2
- Hold time: 15 sec
- LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3
- Hold time: 15 sec
- Targeted Hellos:
diff --git a/tests/topotests/ldp-topo1/r4/show_mpls_ldp_interface.ref-1 b/tests/topotests/ldp-topo1/r4/show_mpls_ldp_interface.ref-1
deleted file mode 100644
index dd57656f15..0000000000
--- a/tests/topotests/ldp-topo1/r4/show_mpls_ldp_interface.ref-1
+++ /dev/null
@@ -1,2 +0,0 @@
-AF Interface State Uptime Hello Timers ac
-ipv4 r4-eth0 ACTIVE xx:xx:xx 5/15 2
diff --git a/tests/topotests/ldp-topo1/r4/show_mpls_ldp_neighbor.ref-1 b/tests/topotests/ldp-topo1/r4/show_mpls_ldp_neighbor.ref-1
deleted file mode 100644
index fb0e7d7dfa..0000000000
--- a/tests/topotests/ldp-topo1/r4/show_mpls_ldp_neighbor.ref-1
+++ /dev/null
@@ -1,17 +0,0 @@
-Peer LDP Identifier: 2.2.2.2:0
- TCP connection: 4.4.4.4:xxx - 2.2.2.2:xxx
- Session Holdtime: 180 sec
- State: OPERATIONAL; Downstream-Unsolicited
- Up time: xx:xx:xx
- LDP Discovery Sources:
- IPv4:
- Interface: r4-eth0
-
-Peer LDP Identifier: 3.3.3.3:0
- TCP connection: 4.4.4.4:xxx - 3.3.3.3:xxx
- Session Holdtime: 180 sec
- State: OPERATIONAL; Downstream-Unsolicited
- Up time: xx:xx:xx
- LDP Discovery Sources:
- IPv4:
- Interface: r4-eth0
diff --git a/tests/topotests/ldp-topo1/r4/show_mpls_table.ref b/tests/topotests/ldp-topo1/r4/show_mpls_table.ref
index 9f86cd67cc..174dcebd4d 100644
--- a/tests/topotests/ldp-topo1/r4/show_mpls_table.ref
+++ b/tests/topotests/ldp-topo1/r4/show_mpls_table.ref
@@ -1,9 +1,9 @@
- Inbound Outbound
- Label Type Nexthop Label
--------- ------- --------------- --------
- XX LDP 10.0.2.2 XX
- XX LDP 10.0.2.2 implicit-null
- XX LDP 10.0.2.2 implicit-null
- XX LDP 10.0.2.2 implicit-null
- XX LDP 10.0.2.3 implicit-null
- XX LDP 10.0.2.3 implicit-null
+ Inbound Label Type Nexthop Outbound Label
+ -----------------------------------------------
+ XX LDP 10.0.2.2 XX
+ XX LDP 10.0.2.2 implicit-null
+ XX LDP 10.0.2.2 implicit-null
+ XX LDP 10.0.2.2 implicit-null
+ XX LDP 10.0.2.3 implicit-null
+ XX LDP 10.0.2.3 implicit-null
+
diff --git a/tests/topotests/ldp-topo1/r4/show_mpls_table.ref-1 b/tests/topotests/ldp-topo1/r4/show_mpls_table.ref-1
deleted file mode 100644
index b8cf5a2702..0000000000
--- a/tests/topotests/ldp-topo1/r4/show_mpls_table.ref-1
+++ /dev/null
@@ -1,9 +0,0 @@
- Inbound Outbound
- Label Type Nexthop Label
--------- ------- --------------- --------
- XX LDP 10.0.2.2 3
- XX LDP 10.0.2.2 3
- XX LDP 10.0.2.2 3
- XX LDP 10.0.2.2 XX
- XX LDP 10.0.2.3 3
- XX LDP 10.0.2.3 3
diff --git a/tests/topotests/ldp-topo1/r4/show_mpls_table.ref-no-impl-null b/tests/topotests/ldp-topo1/r4/show_mpls_table.ref-no-impl-null
deleted file mode 100644
index b8cf5a2702..0000000000
--- a/tests/topotests/ldp-topo1/r4/show_mpls_table.ref-no-impl-null
+++ /dev/null
@@ -1,9 +0,0 @@
- Inbound Outbound
- Label Type Nexthop Label
--------- ------- --------------- --------
- XX LDP 10.0.2.2 3
- XX LDP 10.0.2.2 3
- XX LDP 10.0.2.2 3
- XX LDP 10.0.2.2 XX
- XX LDP 10.0.2.3 3
- XX LDP 10.0.2.3 3
diff --git a/tests/topotests/ldp-topo1/test_ldp_topo1.py b/tests/topotests/ldp-topo1/test_ldp_topo1.py
index 409a5f54c8..f02f4c4e21 100755
--- a/tests/topotests/ldp-topo1/test_ldp_topo1.py
+++ b/tests/topotests/ldp-topo1/test_ldp_topo1.py
@@ -77,12 +77,6 @@ from lib import topotest
fatal_error = ""
-# Expected version of CLI Output - Appendix to filename
-# empty string = current, latest output (default)
-# "-1" ... "-NNN" previous versions (incrementing with each version)
-cli_version = ""
-
-
#####################################################
##
## Network Topology Definition
@@ -164,7 +158,6 @@ def teardown_module(module):
def test_router_running():
global fatal_error
global net
- global cli_version
# Skip if previous fatal error condition is raised
if (fatal_error != ""):
@@ -179,35 +172,12 @@ def test_router_running():
fatal_error = net['r%s' % i].checkRouterRunning()
assert fatal_error == "", fatal_error
- # Detect CLI Version
- # At this time, there are only 2 possible outputs, so simple check
- output = net['r1'].cmd('vtysh -c "show mpls ldp discovery" 2> /dev/null').rstrip()
-
- # Check if old or new format of CLI Output. Default is to current format
- #
- # Old (v1) output looks like this:
- # Local LDP Identifier: 1.1.1.1:0
- # Discovery Sources:
- # Interfaces:
- # r1-eth0: xmit/recv
- # LDP Id: 2.2.2.2:0, Transport address: 2.2.2.2
- # Hold time: 15 sec
- # Targeted Hellos:
- #
- # Current (v0) output looks like this:
- # AF ID Type Source Holdtime
- # ipv4 2.2.2.2 Link r1-eth0 15
- pattern = re.compile("^Local LDP Identifier.*")
- if pattern.match(output):
- cli_version = "-1"
-
# For debugging after starting FRR/Quagga daemons, uncomment the next line
# CLI(net)
def test_mpls_interfaces():
global fatal_error
global net
- global cli_version
# Skip if previous fatal error condition is raised
if (fatal_error != ""):
@@ -220,7 +190,7 @@ def test_mpls_interfaces():
print("******************************************\n")
failures = 0
for i in range(1, 5):
- refTableFile = '%s/r%s/show_mpls_ldp_interface.ref%s' % (thisDir, i, cli_version)
+ refTableFile = '%s/r%s/show_mpls_ldp_interface.ref'
if os.path.isfile(refTableFile):
# Read expected result from file
expected = open(refTableFile).read().rstrip()
@@ -263,7 +233,6 @@ def test_mpls_interfaces():
def test_mpls_ldp_neighbor_establish():
global fatal_error
global net
- global cli_version
# Skip if previous fatal error condition is raised
if (fatal_error != ""):
@@ -279,22 +248,22 @@ def test_mpls_ldp_neighbor_establish():
# Look for any node not yet converged
for i in range(1, 5):
established = net['r%s' % i].cmd('vtysh -c "show mpls ldp neighbor" 2> /dev/null').rstrip()
- if cli_version != "-1":
- # On current version, we need to make sure they all turn to OPERATIONAL on all lines
- #
- lines = ('\n'.join(established.splitlines()) + '\n').splitlines(1)
- # Check all lines to be either table header (starting with ^AF or show OPERATIONAL)
- header = r'^AF.*'
- operational = r'^ip.*OPERATIONAL.*'
- found_operational = 0
- for j in range(1, len(lines)):
- if (not re.search(header, lines[j])) and (not re.search(operational, lines[j])):
- established = "" # Empty string shows NOT established
- if re.search(operational, lines[j]):
- found_operational += 1
- if found_operational < 1:
- # Need at least one operational neighbor
+
+ # On current version, we need to make sure they all turn to OPERATIONAL on all lines
+ #
+ lines = ('\n'.join(established.splitlines()) + '\n').splitlines(1)
+ # Check all lines to be either table header (starting with ^AF or show OPERATIONAL)
+ header = r'^AF.*'
+ operational = r'^ip.*OPERATIONAL.*'
+ found_operational = 0
+ for j in range(1, len(lines)):
+ if (not re.search(header, lines[j])) and (not re.search(operational, lines[j])):
established = "" # Empty string shows NOT established
+ if re.search(operational, lines[j]):
+ found_operational += 1
+ if found_operational < 1:
+ # Need at least one operational neighbor
+ established = "" # Empty string shows NOT established
if not established:
print('Waiting for r%s' %i)
sys.stdout.flush()
@@ -326,7 +295,6 @@ def test_mpls_ldp_neighbor_establish():
def test_mpls_ldp_discovery():
global fatal_error
global net
- global cli_version
# Skip if previous fatal error condition is raised
if (fatal_error != ""):
@@ -339,7 +307,7 @@ def test_mpls_ldp_discovery():
print("******************************************\n")
failures = 0
for i in range(1, 5):
- refTableFile = '%s/r%s/show_mpls_ldp_discovery.ref%s' % (thisDir, i, cli_version)
+ refTableFile = '%s/r%s/show_mpls_ldp_discovery.ref'
if os.path.isfile(refTableFile):
# Actual output from router
actual = net['r%s' % i].cmd('vtysh -c "show mpls ldp discovery" 2> /dev/null').rstrip()
@@ -381,7 +349,6 @@ def test_mpls_ldp_discovery():
def test_mpls_ldp_neighbor():
global fatal_error
global net
- global cli_version
# Skip if previous fatal error condition is raised
if (fatal_error != ""):
@@ -394,7 +361,7 @@ def test_mpls_ldp_neighbor():
print("******************************************\n")
failures = 0
for i in range(1, 5):
- refTableFile = '%s/r%s/show_mpls_ldp_neighbor.ref%s' % (thisDir, i, cli_version)
+ refTableFile = '%s/r%s/show_mpls_ldp_neighbor.ref'
if os.path.isfile(refTableFile):
# Read expected result from file
expected = open(refTableFile).read().rstrip()
@@ -405,17 +372,8 @@ def test_mpls_ldp_neighbor():
actual = net['r%s' % i].cmd('vtysh -c "show mpls ldp neighbor" 2> /dev/null').rstrip()
# Mask out changing parts in output
- if cli_version == "-1":
- # Mask out Timer in Uptime
- actual = re.sub(r"Up time: [0-9][0-9]:[0-9][0-9]:[0-9][0-9]", "Up time: xx:xx:xx", actual)
- # Mask out Port numbers in TCP connection
- actual = re.sub(r"TCP connection: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]):[0-9]+ - ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]):[0-9]+",
- r"TCP connection: \1:xxx - \2:xxx", actual)
- else:
- # Current Version
- #
- # Mask out Timer in Uptime
- actual = re.sub(r"(ipv4 [0-9\.]+ +OPERATIONAL [0-9\.]+ +)[0-9][0-9]:[0-9][0-9]:[0-9][0-9]", r"\1xx:xx:xx", actual)
+ # Mask out Timer in Uptime
+ actual = re.sub(r"(ipv4 [0-9\.]+ +OPERATIONAL [0-9\.]+ +)[0-9][0-9]:[0-9][0-9]:[0-9][0-9]", r"\1xx:xx:xx", actual)
# Fix newlines (make them all the same)
actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
@@ -446,7 +404,6 @@ def test_mpls_ldp_neighbor():
def test_mpls_ldp_binding():
global fatal_error
global net
- global cli_version
# Skip this test for now until proper sorting of the output
# is implemented
@@ -463,7 +420,7 @@ def test_mpls_ldp_binding():
print("******************************************\n")
failures = 0
for i in range(1, 5):
- refTableFile = '%s/r%s/show_mpls_ldp_binding.ref%s' % (thisDir, i, cli_version)
+ refTableFile = '%s/r%s/show_mpls_ldp_binding.ref'
if os.path.isfile(refTableFile):
# Read expected result from file
expected = open(refTableFile).read().rstrip()
@@ -474,16 +431,9 @@ def test_mpls_ldp_binding():
actual = net['r%s' % i].cmd('vtysh -c "show mpls ldp binding" 2> /dev/null').rstrip()
# Mask out changing parts in output
- if cli_version == "-1":
- # Mask out label
- actual = re.sub(r"label: [0-9]+", "label: xxx", actual)
- actual = re.sub(r"(\s+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+[ ]+)[0-9]+", r"\1xxx", actual)
- else:
- # Current Version
- #
- # Mask out label
- actual = re.sub(r"(ipv4 [0-9\./]+ +[0-9\.]+ +)[0-9][0-9] (.*)", r"\1xxx\2", actual)
- actual = re.sub(r"(ipv4 [0-9\./]+ +[0-9\.]+ +[a-z\-]+ +)[0-9][0-9] (.*)", r"\1xxx\2", actual)
+ # Mask out label
+ actual = re.sub(r"(ipv4 [0-9\./]+ +[0-9\.]+ +)[0-9][0-9] (.*)", r"\1xxx\2", actual)
+ actual = re.sub(r"(ipv4 [0-9\./]+ +[0-9\.]+ +[a-z\-]+ +)[0-9][0-9] (.*)", r"\1xxx\2", actual)
# Fix newlines (make them all the same)
actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
@@ -527,7 +477,6 @@ def test_mpls_ldp_binding():
def test_zebra_ipv4_routingTable():
global fatal_error
global net
- global cli_version
# Skip if previous fatal error condition is raised
if (fatal_error != ""):
@@ -540,7 +489,7 @@ def test_zebra_ipv4_routingTable():
print("******************************************\n")
failures = 0
for i in range(1, 5):
- refTableFile = '%s/r%s/show_ipv4_route.ref%s' % (thisDir, i, cli_version)
+ refTableFile = '%s/r%s/show_ipv4_route.ref'
if os.path.isfile(refTableFile):
# Read expected result from file
expected = open(refTableFile).read().rstrip()
@@ -562,9 +511,6 @@ def test_zebra_ipv4_routingTable():
# now fix newlines of expected (make them all the same)
expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
- # Add missing comma before label (for old version)
- actual = re.sub(r"([0-9]) label ", r"\1, label ", actual)
-
# Fix newlines (make them all the same)
actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
@@ -594,7 +540,6 @@ def test_zebra_ipv4_routingTable():
def test_mpls_table():
global fatal_error
global net
- global cli_version
# Skip if previous fatal error condition is raised
if (fatal_error != ""):
@@ -607,23 +552,16 @@ def test_mpls_table():
print("******************************************\n")
failures = 0
- version = cli_version
- if (version == ""):
- # check for new output without implicit-null
- output = net['r1'].cmd('vtysh -c "show mpls table" 2> /dev/null').rstrip()
- if 'LDP 10.0.1.2 3' in output:
- version = "-no-impl-null"
-
for i in range(1, 5):
- refTableFile = '%s/r%s/show_mpls_table.ref%s' % (thisDir, i, version)
+ refTableFile = '%s/r%s/show_mpls_table.ref'
if os.path.isfile(refTableFile):
# Read expected result from file
- expected = open(refTableFile).read().rstrip()
+ expected = open(refTableFile).read()
# Fix newlines (make them all the same)
expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
# Actual output from router
- actual = net['r%s' % i].cmd('vtysh -c "show mpls table" 2> /dev/null').rstrip()
+ actual = net['r%s' % i].cmd('vtysh -c "show mpls table" 2> /dev/null')
# Fix inconsistent Label numbers at beginning of line
actual = re.sub(r"(\s+)[0-9]+(\s+LDP)", r"\1XX\2", actual)
@@ -672,7 +610,6 @@ def test_mpls_table():
def test_linux_mpls_routes():
global fatal_error
global net
- global cli_version
# Skip if previous fatal error condition is raised
if (fatal_error != ""):
diff --git a/tests/topotests/ldp-vpls-topo1/r1/show_ip_ospf_neighbor.ref b/tests/topotests/ldp-vpls-topo1/r1/show_ip_ospf_neighbor.ref
deleted file mode 100644
index fb193265be..0000000000
--- a/tests/topotests/ldp-vpls-topo1/r1/show_ip_ospf_neighbor.ref
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "neighbors":[
- {
- "2.2.2.2":[
- {
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.1.2",
- "ifaceName":"r1-eth1:10.0.1.1",
- "retransmitCounter":0,
- "requestCounter":0,
- "dbSummaryCounter":0
- }
- ]
- },
- {
- "3.3.3.3":[
- {
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.2.3",
- "ifaceName":"r1-eth2:10.0.2.1",
- "retransmitCounter":0,
- "requestCounter":0,
- "dbSummaryCounter":0
- }
- ]
- }
- ]
-}
-
diff --git a/tests/topotests/ldp-vpls-topo1/r1/show_ip_ospf_neighbor.ref-no-neigh b/tests/topotests/ldp-vpls-topo1/r1/show_ip_ospf_neighbor.ref-no-neigh
deleted file mode 100644
index 7c4d0ab58c..0000000000
--- a/tests/topotests/ldp-vpls-topo1/r1/show_ip_ospf_neighbor.ref-no-neigh
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "2.2.2.2":[
- {
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.1.2",
- "ifaceName":"r1-eth1:10.0.1.1"
- }
- ],
- "3.3.3.3":[
- {
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.2.3",
- "ifaceName":"r1-eth2:10.0.2.1"
- }
- ]
-}
diff --git a/tests/topotests/ldp-vpls-topo1/r1/show_ip_ospf_neighbor.ref-old-nolist b/tests/topotests/ldp-vpls-topo1/r1/show_ip_ospf_neighbor.ref-old-nolist
deleted file mode 100644
index 2270c3fdde..0000000000
--- a/tests/topotests/ldp-vpls-topo1/r1/show_ip_ospf_neighbor.ref-old-nolist
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "2.2.2.2":{
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.1.2",
- "ifaceName":"r1-eth1:10.0.1.1"
- },
- "3.3.3.3":{
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.2.3",
- "ifaceName":"r1-eth2:10.0.2.1"
- }
-}
diff --git a/tests/topotests/ldp-vpls-topo1/r2/show_ip_ospf_neighbor.ref b/tests/topotests/ldp-vpls-topo1/r2/show_ip_ospf_neighbor.ref
deleted file mode 100644
index 1376579757..0000000000
--- a/tests/topotests/ldp-vpls-topo1/r2/show_ip_ospf_neighbor.ref
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "neighbors":[
- {
- "1.1.1.1":[
- {
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.1.1",
- "ifaceName":"r2-eth1:10.0.1.2",
- "retransmitCounter":0,
- "requestCounter":0,
- "dbSummaryCounter":0
- }
- ]
- },
- {
- "3.3.3.3":[
- {
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.3.3",
- "ifaceName":"r2-eth2:10.0.3.2",
- "retransmitCounter":0,
- "requestCounter":0,
- "dbSummaryCounter":0
- }
- ]
- }
- ]
-}
diff --git a/tests/topotests/ldp-vpls-topo1/r2/show_ip_ospf_neighbor.ref-no-neigh b/tests/topotests/ldp-vpls-topo1/r2/show_ip_ospf_neighbor.ref-no-neigh
deleted file mode 100644
index a982c1cbd3..0000000000
--- a/tests/topotests/ldp-vpls-topo1/r2/show_ip_ospf_neighbor.ref-no-neigh
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "1.1.1.1":[
- {
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.1.1",
- "ifaceName":"r2-eth1:10.0.1.2"
- }
- ],
- "3.3.3.3":[
- {
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.3.3",
- "ifaceName":"r2-eth2:10.0.3.2"
- }
- ]
-}
diff --git a/tests/topotests/ldp-vpls-topo1/r2/show_ip_ospf_neighbor.ref-old-nolist b/tests/topotests/ldp-vpls-topo1/r2/show_ip_ospf_neighbor.ref-old-nolist
deleted file mode 100644
index 18ffbc2f8a..0000000000
--- a/tests/topotests/ldp-vpls-topo1/r2/show_ip_ospf_neighbor.ref-old-nolist
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "1.1.1.1":{
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.1.1",
- "ifaceName":"r2-eth1:10.0.1.2"
- },
- "3.3.3.3":{
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.3.3",
- "ifaceName":"r2-eth2:10.0.3.2"
- }
-}
diff --git a/tests/topotests/ldp-vpls-topo1/r3/show_ip_ospf_neighbor.ref b/tests/topotests/ldp-vpls-topo1/r3/show_ip_ospf_neighbor.ref
deleted file mode 100644
index 41de304b2b..0000000000
--- a/tests/topotests/ldp-vpls-topo1/r3/show_ip_ospf_neighbor.ref
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "neighbors":[
- {
- "1.1.1.1":[
- {
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.2.1",
- "ifaceName":"r3-eth1:10.0.2.3",
- "retransmitCounter":0,
- "requestCounter":0,
- "dbSummaryCounter":0
- }
- ]
- },
- {
- "2.2.2.2":[
- {
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.3.2",
- "ifaceName":"r3-eth2:10.0.3.3",
- "retransmitCounter":0,
- "requestCounter":0,
- "dbSummaryCounter":0
- }
- ]
- }
- ]
-}
diff --git a/tests/topotests/ldp-vpls-topo1/r3/show_ip_ospf_neighbor.ref-no-neigh b/tests/topotests/ldp-vpls-topo1/r3/show_ip_ospf_neighbor.ref-no-neigh
deleted file mode 100644
index d7e0e42405..0000000000
--- a/tests/topotests/ldp-vpls-topo1/r3/show_ip_ospf_neighbor.ref-no-neigh
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "1.1.1.1":[
- {
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.2.1",
- "ifaceName":"r3-eth1:10.0.2.3"
- }
- ],
- "2.2.2.2":[
- {
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.3.2",
- "ifaceName":"r3-eth2:10.0.3.3"
- }
- ]
-}
diff --git a/tests/topotests/ldp-vpls-topo1/r3/show_ip_ospf_neighbor.ref-old-nolist b/tests/topotests/ldp-vpls-topo1/r3/show_ip_ospf_neighbor.ref-old-nolist
deleted file mode 100644
index b0669742ab..0000000000
--- a/tests/topotests/ldp-vpls-topo1/r3/show_ip_ospf_neighbor.ref-old-nolist
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "1.1.1.1":{
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.2.1",
- "ifaceName":"r3-eth1:10.0.2.3"
- },
- "2.2.2.2":{
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.3.2",
- "ifaceName":"r3-eth2:10.0.3.3"
- }
-}
diff --git a/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py b/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py
index 0948c2e41b..ce651c50cd 100755
--- a/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py
+++ b/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py
@@ -144,9 +144,6 @@ def setup_module(mod):
)
tgen.start_router()
- for router in router_list.values():
- if router.has_version('<', '3'):
- tgen.set_error('unsupported version')
def teardown_module(mod):
"Teardown the pytest environment"
@@ -180,30 +177,8 @@ def test_ospf_convergence():
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
- # Old output (before FRR PR1383) didn't show a list of neighbors.
- # Check for dict object and compare to old output if this is the case
- tgen = get_topogen()
- router = tgen.gears['r1']
- output = router.vtysh_cmd("show ip ospf neighbor json", isjson=True)
-
- # We could have either old format (without "neighbors" and direct list
- # of IP's or new format from PR1659 with "neighbors".
- # Trying old formats first and fall back to new format
- #
- # New format: neighbors have dict instead of list of dicts (PR1723).
- if output.has_key('neighbors'):
- if isinstance(output['neighbors'], dict):
- reffile = "show_ip_ospf_neighbor.json"
- else:
- reffile = "show_ip_ospf_neighbor.ref"
- else:
- if isinstance(output["2.2.2.2"], dict):
- reffile = "show_ip_ospf_neighbor.ref-old-nolist"
- else:
- reffile = "show_ip_ospf_neighbor.ref-no-neigh"
-
for rname in ['r1', 'r2', 'r3']:
- router_compare_json_output(rname, "show ip ospf neighbor json", reffile)
+ router_compare_json_output(rname, "show ip ospf neighbor json", "show_ip_ospf_neighbor.json")
def test_rib():
logger.info("Test: verify RIB")
diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py
index c47dddb8d4..41d6a326cf 100644
--- a/tests/topotests/lib/bgp.py
+++ b/tests/topotests/lib/bgp.py
@@ -445,10 +445,10 @@ def __create_bgp_unicast_address_family(topo, input_dict, router, addr_type,
bgp_data = input_dict[router]["bgp"]["address_family"]
neigh_data = bgp_data[addr_type]["unicast"]["neighbor"]
- for name, peer_dict in deepcopy(neigh_data).iteritems():
+ for peer_name, peer_dict in deepcopy(neigh_data).iteritems():
for dest_link, peer in peer_dict["dest_link"].iteritems():
deactivate = None
- nh_details = topo[name]
+ nh_details = topo[peer_name]
# Loopback interface
if "source_link" in peer and peer["source_link"] == "lo":
for destRouterLink, data in sorted(nh_details["links"].
@@ -864,7 +864,7 @@ def clear_bgp_and_verify(tgen, topo, router):
peer_uptime_before_clear_bgp = {}
# Verifying BGP convergence before bgp clear command
- for retry in range(1, 11):
+ for retry in range(31):
sleeptime = 3
# Waiting for BGP to converge
logger.info("Waiting for %s sec for BGP to converge on router"
@@ -944,7 +944,7 @@ def clear_bgp_and_verify(tgen, topo, router):
peer_uptime_after_clear_bgp = {}
# Verifying BGP convergence after bgp clear command
- for retry in range(11):
+ for retry in range(31):
sleeptime = 3
# Waiting for BGP to converge
logger.info("Waiting for %s sec for BGP to converge on router"
@@ -1229,6 +1229,150 @@ def verify_bgp_timers_and_functionality(tgen, topo, input_dict):
return True
+@retry(attempts=3, wait=4, return_is_str=True)
+def verify_bgp_attributes(tgen, addr_type, dut, static_routes, rmap_name,
+ input_dict, seq_id=None):
+ """
+ API will verify BGP attributes set by Route-map for given prefix and
+ DUT. it will run "show bgp ipv4/ipv6 {prefix_address} json" command
+ in DUT to verify BGP attributes set by route-map, Set attributes
+ values will be read from input_dict and verified with command output.
+
+ * `tgen`: topogen object
+ * `addr_type` : ip type, ipv4/ipv6
+ * `dut`: Device Under Test
+ * `static_routes`: Static Routes for which BGP set attributes needs to be
+ verified
+ * `rmap_name`: route map name for which set criteria needs to be verified
+ * `input_dict`: defines for which router, AS numbers needs
+ * `seq_id`: sequence number of rmap, default is None
+
+ Usage
+ -----
+ input_dict = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_ipv4": [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_" + addr_type
+ }
+ },
+ "set": {
+ "localpref": 150,
+ "weight": 100
+ }
+ }],
+ "rmap_match_pf_2_ipv6": [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_" + addr_type
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }]
+ }
+ }
+ }
+ result = verify_bgp_attributes(tgen, 'ipv4', "r1", "10.0.20.1/32",
+ rmap_match_pf_1_ipv4, input_dict)
+
+ Returns
+ -------
+ errormsg(str) or True
+ """
+
+ logger.debug("Entering lib API: verify_bgp_attributes()")
+ for router, rnode in tgen.routers().iteritems():
+ if router != dut:
+ continue
+
+ logger.info('Verifying BGP set attributes for dut {}:'.format(router))
+
+ for static_route in static_routes:
+ cmd = "show bgp {} {} json".format(addr_type, static_route)
+ show_bgp_json = run_frr_cmd(rnode, cmd, isjson=True)
+ print("show_bgp_json $$$$$", show_bgp_json)
+
+ dict_to_test = []
+ tmp_list = []
+ for rmap_router in input_dict.keys():
+ for rmap, values in input_dict[rmap_router][
+ "route_maps"].items():
+ print("rmap == rmap_name $$$$1", rmap, rmap_name)
+ if rmap == rmap_name:
+ print("rmap == rmap_name $$$$", rmap, rmap_name)
+ dict_to_test = values
+ for rmap_dict in values:
+ if seq_id is not None:
+ if type(seq_id) is not list:
+ seq_id = [seq_id]
+
+ if "seq_id" in rmap_dict:
+ rmap_seq_id = \
+ rmap_dict["seq_id"]
+ for _seq_id in seq_id:
+ if _seq_id == rmap_seq_id:
+ tmp_list.append(rmap_dict)
+ if tmp_list:
+ dict_to_test = tmp_list
+
+ print("dict_to_test $$$$", dict_to_test)
+ for rmap_dict in dict_to_test:
+ if "set" in rmap_dict:
+ for criteria in rmap_dict["set"].keys():
+ if criteria not in show_bgp_json[
+ "paths"][0]:
+ errormsg = ("BGP attribute: {}"
+ " is not found in"
+ " cli: {} output "
+ "in router {}".
+ format(criteria,
+ cmd,
+ router))
+ return errormsg
+
+ if rmap_dict["set"][criteria] == \
+ show_bgp_json["paths"][0][
+ criteria]:
+ logger.info("Verifying BGP "
+ "attribute {} for"
+ " route: {} in "
+ "router: {}, found"
+ " expected value:"
+ " {}".
+ format(criteria,
+ static_route,
+ dut,
+ rmap_dict[
+ "set"][
+ criteria]))
+ else:
+ errormsg = \
+ ("Failed: Verifying BGP "
+ "attribute {} for route:"
+ " {} in router: {}, "
+ " expected value: {} but"
+ " found: {}".
+ format(criteria,
+ static_route,
+ dut,
+ rmap_dict["set"]
+ [criteria],
+ show_bgp_json[
+ 'paths'][
+ 0][criteria]))
+ return errormsg
+
+ logger.debug("Exiting lib API: verify_bgp_attributes()")
+ return True
+
@retry(attempts=3, wait=2, return_is_str=True)
def verify_best_path_as_per_bgp_attribute(tgen, addr_type, router, input_dict,
attribute):
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py
index f2d33f94ae..c413bf45c7 100644
--- a/tests/topotests/lib/common_config.py
+++ b/tests/topotests/lib/common_config.py
@@ -21,6 +21,7 @@
from collections import OrderedDict
from datetime import datetime
from time import sleep
+from copy import deepcopy
from subprocess import call
from subprocess import STDOUT as SUB_STDOUT
from subprocess import PIPE as SUB_PIPE
@@ -34,11 +35,7 @@ import ConfigParser
import traceback
import socket
import ipaddr
-import re
-from lib import topotest
-
-from functools import partial
from lib.topolog import logger, logger_config
from lib.topogen import TopoRouter
from lib.topotest import interface_set_status
@@ -208,6 +205,7 @@ def create_common_configuration(tgen, router, data, config_type=None,
"interface_config": "! Interfaces Config\n",
"static_route": "! Static Route Config\n",
"prefix_list": "! Prefix List Config\n",
+ "bgp_community_list": "! Community List Config\n",
"route_maps": "! Route Maps Config\n",
"bgp": "! BGP Config\n"
})
@@ -547,13 +545,11 @@ def generate_ips(network, no_of_ips):
Returns list of IPs.
based on start_ip and no_of_ips
- * `network` : from here the ip will start generating, start_ip will be
- first ip
+ * `network` : from here the ip will start generating,
+ start_ip will be
* `no_of_ips` : these many IPs will be generated
-
- Limitation: It will generate IPs only for ip_mask 32
-
"""
+
ipaddress_list = []
if type(network) is not list:
network = [network]
@@ -736,62 +732,6 @@ def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0):
return _retry
-def disable_v6_link_local(tgen, router, intf_name=None):
- """
- Disables ipv6 link local addresses for a particular interface or
- all interfaces
-
- * `tgen`: tgen onject
- * `router` : router for which hightest interface should be
- calculated
- * `intf_name` : Interface name for which v6 link local needs to
- be disabled
- """
-
- router_list = tgen.routers()
- for rname, rnode in router_list.iteritems():
- if rname != router:
- continue
-
- linklocal = []
-
- ifaces = router_list[router].run('ip -6 address')
-
- # Fix newlines (make them all the same)
- ifaces = ('\n'.join(ifaces.splitlines()) + '\n').splitlines()
-
- interface = None
- ll_per_if_count = 0
- for line in ifaces:
- # Interface name
- m = re.search('[0-9]+: ([^:]+)[@if0-9:]+ <', line)
- if m:
- interface = m.group(1).split("@")[0]
- ll_per_if_count = 0
-
- # Interface ip
- m = re.search('inet6 (fe80::[0-9a-f]+:[0-9a-f]+:[0-9a-f]+'
- ':[0-9a-f]+[/0-9]*) scope link', line)
- if m:
- local = m.group(1)
- ll_per_if_count += 1
- if ll_per_if_count > 1:
- linklocal += [["%s-%s" % (interface, ll_per_if_count), local]]
- else:
- linklocal += [[interface, local]]
-
- if len(linklocal[0]) > 1:
- link_local_dict = {item[0]: item[1] for item in linklocal}
-
- for lname, laddr in link_local_dict.items():
-
- if intf_name is not None and lname != intf_name:
- continue
-
- cmd = "ip addr del {} dev {}".format(laddr, lname)
- router_list[router].run(cmd)
-
-
#############################################
# These APIs, will used by testcase
#############################################
@@ -821,8 +761,6 @@ def create_interfaces_cfg(tgen, topo, build=False):
interface_name = destRouterLink
else:
interface_name = data["interface"]
- if "ipv6" in data:
- disable_v6_link_local(tgen, c_router, interface_name)
interface_data.append("interface {}".format(
str(interface_name)
))
@@ -893,6 +831,7 @@ def create_static_routes(tgen, input_dict, build=False):
"""
result = False
logger.debug("Entering lib API: create_static_routes()")
+ input_dict = deepcopy(input_dict)
try:
for router in input_dict.keys():
if "static_routes" not in input_dict[router]:
@@ -918,16 +857,21 @@ def create_static_routes(tgen, input_dict, build=False):
next_hop = static_route["next_hop"]
network = static_route["network"]
- ip_list = generate_ips([network], no_of_ip)
+ if type(network) is not list:
+ network = [network]
+
+ ip_list = generate_ips(network, no_of_ip)
for ip in ip_list:
addr_type = validate_ip_address(ip)
+
if addr_type == "ipv4":
cmd = "ip route {} {}".format(ip, next_hop)
else:
cmd = "ipv6 route {} {}".format(ip, next_hop)
if tag:
- cmd = "{} {}".format(cmd, str(tag))
+ cmd = "{} tag {}".format(cmd, str(tag))
+
if admin_distance:
cmd = "{} {}".format(cmd, admin_distance)
@@ -1112,11 +1056,11 @@ def create_route_maps(tgen, input_dict, build=False):
"prefix_list": "pf_list_1"
}
- "large-community-list": "{
+ "large-community-list": {
"id": "community_1",
"exact_match": True
}
- "community": {
+ "community_list": {
"id": "community_2",
"exact_match": True
}
@@ -1152,12 +1096,11 @@ def create_route_maps(tgen, input_dict, build=False):
result = False
logger.debug("Entering lib API: create_route_maps()")
-
+ input_dict = deepcopy(input_dict)
try:
for router in input_dict.keys():
if "route_maps" not in input_dict[router]:
- errormsg = "route_maps not present in input_dict"
- logger.debug(errormsg)
+ logger.debug("route_maps not present in input_dict")
continue
rmap_data = []
for rmap_name, rmap_value in \
@@ -1187,10 +1130,41 @@ def create_route_maps(tgen, input_dict, build=False):
rmap_name, rmap_action, seq_id
))
+ if "continue" in rmap_dict:
+ continue_to = rmap_dict["continue"]
+ if continue_to:
+ rmap_data.append("on-match goto {}".
+ format(continue_to))
+ else:
+ logger.error("In continue, 'route-map entry "
+ "sequence number' is not provided")
+ return False
+
+ if "goto" in rmap_dict:
+ go_to = rmap_dict["goto"]
+ if go_to:
+ rmap_data.append("on-match goto {}".
+ format(go_to))
+ else:
+ logger.error("In goto, 'Goto Clause number' is not"
+ " provided")
+ return False
+
+ if "call" in rmap_dict:
+ call_rmap = rmap_dict["call"]
+ if call_rmap:
+ rmap_data.append("call {}".
+ format(call_rmap))
+ else:
+ logger.error("In call, 'destination Route-Map' is"
+ " not provided")
+ return False
+
# Verifying if SET criteria is defined
if "set" in rmap_dict:
set_data = rmap_dict["set"]
-
+ ipv4_data = set_data.setdefault("ipv4", {})
+ ipv6_data = set_data.setdefault("ipv6", {})
local_preference = set_data.setdefault("localpref",
None)
metric = set_data.setdefault("med", None)
@@ -1199,7 +1173,10 @@ def create_route_maps(tgen, input_dict, build=False):
community = set_data.setdefault("community", {})
large_community = set_data.setdefault(
"large_community", {})
+ large_comm_list = set_data.setdefault(
+ "large_comm_list", {})
set_action = set_data.setdefault("set_action", None)
+ nexthop = set_data.setdefault("nexthop", None)
# Local Preference
if local_preference:
@@ -1243,42 +1220,86 @@ def create_route_maps(tgen, input_dict, build=False):
rmap_data.append(cmd)
else:
- logger.errror("In large_community, AS Num not"
- " provided")
+ logger.error("In large_community, AS Num not"
+ " provided")
+ return False
+ if large_comm_list:
+ id = large_comm_list.setdefault("id", None)
+ del_comm = large_comm_list.setdefault("delete",
+ None)
+ if id:
+ cmd = "set large-comm-list {}".format(id)
+ if del_comm:
+ cmd = "{} delete".format(cmd)
+
+ rmap_data.append(cmd)
+ else:
+ logger.error("In large_comm_list 'id' not"
+ " provided")
return False
# Weight
if weight:
rmap_data.append("set weight {}".format(
weight))
+ if ipv6_data:
+ nexthop = ipv6_data.setdefault("nexthop", None)
+ if nexthop:
+ rmap_data.append("set ipv6 next-hop {}".format(
+ nexthop
+ ))
# Adding MATCH and SET sequence to RMAP if defined
if "match" in rmap_dict:
match_data = rmap_dict["match"]
ipv4_data = match_data.setdefault("ipv4", {})
ipv6_data = match_data.setdefault("ipv6", {})
- community = match_data.setdefault("community-list",
- {})
+ community = match_data.setdefault(
+ "community_list",{})
large_community = match_data.setdefault(
- "large-community-list", {}
+ "large_community", {}
+ )
+ large_community_list = match_data.setdefault(
+ "large_community_list", {}
)
- tag = match_data.setdefault("tag", None)
if ipv4_data:
- prefix_name = ipv4_data.setdefault("prefix_lists",
- None)
+ # fetch prefix list data from rmap
+ prefix_name = \
+ ipv4_data.setdefault("prefix_lists",
+ None)
if prefix_name:
- rmap_data.append("match ip address prefix-list"
- " {}".format(prefix_name))
+ rmap_data.append("match ip address"
+ " prefix-list {}".format(prefix_name))
+
+ # fetch tag data from rmap
+ tag = ipv4_data.setdefault("tag", None)
+ if tag:
+ rmap_data.append("match tag {}".format(tag))
+
+ # fetch large community data from rmap
+ large_community_list = ipv4_data.setdefault(
+ "large_community_list",{})
+ large_community = match_data.setdefault(
+ "large_community", {})
+
if ipv6_data:
prefix_name = ipv6_data.setdefault("prefix_lists",
None)
if prefix_name:
- rmap_data.append("match ipv6 address "
- "prefix-list {}".
- format(prefix_name))
- if tag:
- rmap_data.append("match tag {}".format(tag))
+ rmap_data.append("match ipv6 address"
+ " prefix-list {}".format(prefix_name))
+
+ # fetch tag data from rmap
+ tag = ipv6_data.setdefault("tag", None)
+ if tag:
+ rmap_data.append("match tag {}".format(tag))
+
+ # fetch large community data from rmap
+ large_community_list = ipv6_data.setdefault(
+ "large_community_list",{})
+ large_community = match_data.setdefault(
+ "large_community", {})
if community:
if "id" not in community:
@@ -1293,10 +1314,9 @@ def create_route_maps(tgen, input_dict, build=False):
cmd = "{} exact-match".format(cmd)
rmap_data.append(cmd)
-
if large_community:
if "id" not in large_community:
- logger.error("'num' is mandatory for "
+ logger.error("'id' is mandatory for "
"large-community-list in match "
"criteria")
return False
@@ -1306,7 +1326,19 @@ def create_route_maps(tgen, input_dict, build=False):
"exact_match", False)
if exact_match:
cmd = "{} exact-match".format(cmd)
-
+ rmap_data.append(cmd)
+ if large_community_list:
+ if "id" not in large_community_list:
+ logger.error("'id' is mandatory for "
+ "large-community-list in match "
+ "criteria")
+ return False
+ cmd = "match large-community {}".format(
+ large_community_list["id"])
+ exact_match = large_community_list.setdefault(
+ "exact_match", False)
+ if exact_match:
+ cmd = "{} exact-match".format(cmd)
rmap_data.append(cmd)
result = create_common_configuration(tgen, router,
@@ -1320,10 +1352,172 @@ def create_route_maps(tgen, input_dict, build=False):
logger.error(errormsg)
return errormsg
- logger.debug("Exiting lib API: create_prefix_lists()")
+ logger.debug("Exiting lib API: create_route_maps()")
return result
+def delete_route_maps(tgen, input_dict):
+ """
+ Delete ip route maps from device
+
+ * `tgen` : Topogen object
+ * `input_dict` : for which router,
+ route map has to be deleted
+
+ Usage
+ -----
+ # Delete route-map rmap_1 and rmap_2 from router r1
+ input_dict = {
+ "r1": {
+ "route_maps": ["rmap_1", "rmap__2"]
+ }
+ }
+ result = delete_route_maps("ipv4", input_dict)
+
+ Returns
+ -------
+ errormsg(str) or True
+ """
+ logger.info("Entering lib API: delete_route_maps()")
+
+ for router in input_dict.keys():
+ route_maps = input_dict[router]["route_maps"][:]
+ rmap_data = input_dict[router]
+ rmap_data["route_maps"] = {}
+ for route_map_name in route_maps:
+ rmap_data["route_maps"].update({
+ route_map_name:
+ [{
+ "delete": True
+ }]
+ })
+
+ return create_route_maps(tgen, input_dict)
+
+
+def create_bgp_community_lists(tgen, input_dict, build=False):
+ """
+ Create bgp community-list or large-community-list on the devices as per
+ the arguments passed. Takes list of communities in input.
+
+ Parameters
+ ----------
+ * `tgen` : Topogen object
+ * `input_dict` : Input dict data, required when configuring from testcase
+ * `build` : Only for initial setup phase this is set as True.
+ Usage
+ -----
+ input_dict_1 = {
+ "r3": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "rmap_lcomm_{}".format(addr_type),
+ "value": "1:1:1 1:2:3 2:1:1 2:2:2",
+ "large": True
+ }
+ ]
+ }
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_1)
+ """
+
+ result = False
+ logger.debug("Entering lib API: create_bgp_community_lists()")
+ input_dict = deepcopy(input_dict)
+ try:
+ for router in input_dict.keys():
+ if "bgp_community_lists" not in input_dict[router]:
+ errormsg = "bgp_community_lists not present in input_dict"
+ logger.debug(errormsg)
+ continue
+
+ config_data = []
+
+ community_list = input_dict[router]["bgp_community_lists"]
+ for community_dict in community_list:
+ del_action = community_dict.setdefault("delete", False)
+ community_type = community_dict.setdefault("community_type",
+ None)
+ action = community_dict.setdefault("action", None)
+ value = community_dict.setdefault("value", '')
+ large = community_dict.setdefault("large", None)
+ name = community_dict.setdefault("name", None)
+ if large:
+ cmd = "bgp large-community-list"
+ else:
+ cmd = "bgp community-list"
+
+ if not large and not (community_type and action and value):
+ errormsg = "community_type, action and value are " \
+ "required in bgp_community_list"
+ logger.error(errormsg)
+ return False
+
+ try:
+ community_type = int(community_type)
+ cmd = "{} {} {} {}".format(cmd, community_type, action,
+ value)
+ except ValueError:
+
+ cmd = "{} {} {} {} {}".format(
+ cmd, community_type, name, action, value)
+
+ if del_action:
+ cmd = "no {}".format(cmd)
+
+ config_data.append(cmd)
+
+ result = create_common_configuration(tgen, router, config_data,
+ "bgp_community_list",
+ build=build)
+
+ except InvalidCLIError:
+ # Traceback
+ errormsg = traceback.format_exc()
+ logger.error(errormsg)
+ return errormsg
+
+ logger.debug("Exiting lib API: create_bgp_community_lists()")
+ return result
+
+
+def shutdown_bringup_interface(tgen, dut, intf_name, ifaceaction=False):
+ """
+ Shutdown or bringup router's interface "
+
+ * `tgen` : Topogen object
+ * `dut` : Device under test
+ * `intf_name` : Interface name to be shut/no shut
+ * `ifaceaction` : Action, to shut/no shut interface,
+ by default is False
+
+ Usage
+ -----
+ dut = "r3"
+ intf = "r3-r1-eth0"
+ # Shut down ineterface
+ shutdown_bringup_interface(tgen, dut, intf, False)
+
+ # Bring up ineterface
+ shutdown_bringup_interface(tgen, dut, intf, True)
+
+ Returns
+ -------
+ errormsg(str) or True
+ """
+
+ router_list = tgen.routers()
+ if ifaceaction:
+ logger.info("Bringing up interface : {}".format(intf_name))
+ else:
+ logger.info("Shutting down interface : {}".format(intf_name))
+
+ interface_set_status(router_list[dut], intf_name, ifaceaction)
+
+
#############################################
# Verification APIs
#############################################
@@ -1625,5 +1819,133 @@ def verify_prefix_lists(tgen, input_dict):
logger.info("Prefix list %s is/are not present in the router"
" from router %s", prefix_list, router)
- logger.debug("Exiting lib API: verify_prefix_lissts()")
+ logger.debug("Exiting lib API: verify_prefix_lists()")
+ return True
+
+
+@retry(attempts=2, wait=4, return_is_str=True, initial_wait=2)
+def verify_route_maps(tgen, input_dict):
+ """
+ Running "show route-map" command and verifying given route-map
+ is present in router.
+ Parameters
+ ----------
+ * `tgen` : topogen object
+ * `input_dict`: data to verify prefix lists
+ Usage
+ -----
+ # To verify rmap_1 and rmap_2 are present in router r1
+ input_dict = {
+ "r1": {
+ "route_maps": ["rmap_1", "rmap_2"]
+ }
+ }
+ result = verify_route_maps(tgen, input_dict)
+ Returns
+ -------
+ errormsg(str) or True
+ """
+
+ logger.debug("Entering lib API: verify_route_maps()")
+
+ for router in input_dict.keys():
+ if router not in tgen.routers():
+ continue
+
+ rnode = tgen.routers()[router]
+ # Show ip route-map
+ show_route_maps = rnode.vtysh_cmd("show route-map")
+
+ # Verify route-map is deleted
+ route_maps = input_dict[router]["route_maps"]
+ for route_map in route_maps:
+ if route_map in show_route_maps:
+ errormsg = ("Route map {} is not deleted from router"
+ " {}".format(route_map, router))
+ return errormsg
+
+ logger.info("Route map %s is/are deleted successfully from"
+ " router %s", route_maps, router)
+
+ logger.debug("Exiting lib API: verify_route_maps()")
+ return True
+
+
+@retry(attempts=3, wait=4, return_is_str=True)
+def verify_bgp_community(tgen, addr_type, router, network, input_dict=None):
+ """
+ API to veiryf BGP large community is attached in route for any given
+ DUT by running "show bgp ipv4/6 {route address} json" command.
+
+ Parameters
+ ----------
+ * `tgen`: topogen object
+ * `addr_type` : ip type, ipv4/ipv6
+ * `dut`: Device Under Test
+ * `network`: network for which set criteria needs to be verified
+ * `input_dict`: having details like - for which router, community and
+ values needs to be verified
+ Usage
+ -----
+ networks = ["200.50.2.0/32"]
+ input_dict = {
+ "largeCommunity": "2:1:1 2:2:2 2:3:3 2:4:4 2:5:5"
+ }
+ result = verify_bgp_community(tgen, "ipv4", dut, network, input_dict=None)
+
+ Returns
+ -------
+ errormsg(str) or True
+ """
+
+ logger.info("Entering lib API: verify_bgp_community()")
+ if router not in tgen.routers():
+ return False
+
+ rnode = tgen.routers()[router]
+
+ logger.debug("Verifying BGP community attributes on dut %s: for %s "
+ "network %s", router, addr_type, network)
+
+ for net in network:
+ cmd = "show bgp {} {} json".format(addr_type, net)
+ show_bgp_json = rnode.vtysh_cmd(cmd, isjson=True)
+ logger.info(show_bgp_json)
+ if "paths" not in show_bgp_json:
+ return "Prefix {} not found in BGP table of router: {}". \
+ format(net, router)
+
+ as_paths = show_bgp_json["paths"]
+ found = False
+ for i in range(len(as_paths)):
+ if "largeCommunity" in show_bgp_json["paths"][i] or \
+ "community" in show_bgp_json["paths"][i]:
+ found = True
+ logger.info("Large Community attribute is found for route:"
+ " %s in router: %s", net, router)
+ if input_dict is not None:
+ for criteria, comm_val in input_dict.items():
+ show_val = show_bgp_json["paths"][i][criteria][
+ "string"]
+ if comm_val == show_val:
+ logger.info("Verifying BGP %s for prefix: %s"
+ " in router: %s, found expected"
+ " value: %s", criteria, net, router,
+ comm_val)
+ else:
+ errormsg = "Failed: Verifying BGP attribute" \
+ " {} for route: {} in router: {}" \
+ ", expected value: {} but found" \
+ ": {}".format(
+ criteria, net, router, comm_val,
+ show_val)
+ return errormsg
+
+ if not found:
+ errormsg = (
+ "Large Community attribute is not found for route: "
+ "{} in router: {} ".format(net, router))
+ return errormsg
+
+ logger.debug("Exiting lib API: verify_bgp_community()")
return True
diff --git a/tests/topotests/lib/topojson.py b/tests/topotests/lib/topojson.py
index 7a00fe4c50..fff5a1e82f 100644
--- a/tests/topotests/lib/topojson.py
+++ b/tests/topotests/lib/topojson.py
@@ -35,6 +35,7 @@ from lib.common_config import (
create_static_routes,
create_prefix_lists,
create_route_maps,
+ create_bgp_community_lists
)
from lib.bgp import create_router_bgp
@@ -179,6 +180,7 @@ def build_config_from_json(tgen, topo, save_bkup=True):
("links", create_interfaces_cfg),
("static_routes", create_static_routes),
("prefix_lists", create_prefix_lists),
+ ("bgp_community_list", create_bgp_community_lists),
("route_maps", create_route_maps),
("bgp", create_router_bgp)
])
diff --git a/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json
index 254c137acd..6b1fe76b6e 100644
--- a/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json
+++ b/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json
@@ -4,7 +4,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -17,7 +17,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -30,7 +30,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":8300,
"distance":150,
"installed":true,
@@ -43,7 +43,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":8400,
"distance":150,
"installed":true,
@@ -56,7 +56,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -69,7 +69,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
diff --git a/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json
index 0d73a409ed..79965d280a 100644
--- a/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json
+++ b/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json
@@ -4,7 +4,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":20100,
"distance":150,
"installed":true,
@@ -17,7 +17,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -30,7 +30,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":10400,
"distance":150,
"installed":true,
@@ -43,7 +43,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -56,7 +56,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -69,7 +69,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -82,7 +82,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -95,7 +95,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -108,7 +108,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
diff --git a/tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json
index b15f90afd1..ceb2f7a0e5 100644
--- a/tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json
+++ b/tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json
@@ -4,7 +4,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":8100,
"distance":150,
"installed":true,
@@ -17,7 +17,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -30,7 +30,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":8400,
"distance":150,
"installed":true,
@@ -43,7 +43,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -56,7 +56,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
diff --git a/tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json
index d1238517f5..d7f54b224d 100644
--- a/tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json
+++ b/tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json
@@ -4,7 +4,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":8100,
"distance":150,
"installed":true,
@@ -17,7 +17,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -30,7 +30,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":8300,
"distance":150,
"installed":true,
@@ -43,7 +43,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -56,7 +56,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
@@ -69,7 +69,7 @@
"installed":true,
"nexthops":[
{
- "type":"SR",
+ "type":"SR (OSPF)",
"outLabel":3,
"distance":150,
"installed":true,
diff --git a/tests/topotests/pytest.ini b/tests/topotests/pytest.ini
index ade5bfd501..62c825341f 100644
--- a/tests/topotests/pytest.ini
+++ b/tests/topotests/pytest.ini
@@ -1,6 +1,6 @@
# Skip pytests example directory
[pytest]
-norecursedirs = .git example-test example-topojson-test lib docker
+norecursedirs = .git example-test example-topojson-test lib docker bgp_rr_ibgp
[topogen]
# Default configuration values