mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-09 01:57:26 +00:00
tests: Add new tests to bgp-basic-functionality-topo1
1. Added new tests to bgp-basic-functionality-topo1 3. Execution time increased by 55 sec Signed-off-by: Kuldeep Kashyap <kashyapk@vmware.com>
This commit is contained in:
parent
5c2bb61763
commit
19f4da0bec
@ -1,36 +1,17 @@
|
|||||||
{
|
{
|
||||||
|
"address_types": ["ipv4", "ipv6"],
|
||||||
"ipv4base": "10.0.0.0",
|
"ipv4base": "10.0.0.0",
|
||||||
"ipv4mask": 30,
|
"ipv4mask": 30,
|
||||||
"ipv6base": "fd00::",
|
"ipv6base": "fd00::",
|
||||||
"ipv6mask": 64,
|
"ipv6mask": 64,
|
||||||
"link_ip_start": {
|
"link_ip_start": {"ipv4": "10.0.0.0", "v4mask": 30, "ipv6": "fd00::", "v6mask": 64},
|
||||||
"ipv4": "10.0.0.0",
|
"lo_prefix": {"ipv4": "1.0.", "v4mask": 32, "ipv6": "2001:db8:f::", "v6mask": 128},
|
||||||
"v4mask": 30,
|
|
||||||
"ipv6": "fd00::",
|
|
||||||
"v6mask": 64
|
|
||||||
},
|
|
||||||
"lo_prefix": {
|
|
||||||
"ipv4": "1.0.",
|
|
||||||
"v4mask": 32,
|
|
||||||
"ipv6": "2001:DB8:F::",
|
|
||||||
"v6mask": 128
|
|
||||||
},
|
|
||||||
"routers": {
|
"routers": {
|
||||||
"r1": {
|
"r1": {
|
||||||
"links": {
|
"links": {
|
||||||
"lo": {
|
"lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
|
||||||
"ipv4": "auto",
|
"r2": {"ipv4": "auto", "ipv6": "auto"},
|
||||||
"ipv6": "auto",
|
"r3": {"ipv4": "auto", "ipv6": "auto"}
|
||||||
"type": "loopback"
|
|
||||||
},
|
|
||||||
"r2": {
|
|
||||||
"ipv4": "auto",
|
|
||||||
"ipv6": "auto"
|
|
||||||
},
|
|
||||||
"r3": {
|
|
||||||
"ipv4": "auto",
|
|
||||||
"ipv6": "auto"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"bgp": {
|
"bgp": {
|
||||||
"local_as": "100",
|
"local_as": "100",
|
||||||
@ -38,16 +19,16 @@
|
|||||||
"ipv4": {
|
"ipv4": {
|
||||||
"unicast": {
|
"unicast": {
|
||||||
"neighbor": {
|
"neighbor": {
|
||||||
"r2": {
|
"r2": {"dest_link": {"r1": {}}},
|
||||||
"dest_link": {
|
"r3": {"dest_link": {"r1": {}}}
|
||||||
"r1": {}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"r3": {
|
"ipv6": {
|
||||||
"dest_link": {
|
"unicast": {
|
||||||
"r1": {}
|
"neighbor": {
|
||||||
}
|
"r2": {"dest_link": {"r1": {}}},
|
||||||
}
|
"r3": {"dest_link": {"r1": {}}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,19 +37,9 @@
|
|||||||
},
|
},
|
||||||
"r2": {
|
"r2": {
|
||||||
"links": {
|
"links": {
|
||||||
"lo": {
|
"lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
|
||||||
"ipv4": "auto",
|
"r1": {"ipv4": "auto", "ipv6": "auto"},
|
||||||
"ipv6": "auto",
|
"r3": {"ipv4": "auto", "ipv6": "auto"}
|
||||||
"type": "loopback"
|
|
||||||
},
|
|
||||||
"r1": {
|
|
||||||
"ipv4": "auto",
|
|
||||||
"ipv6": "auto"
|
|
||||||
},
|
|
||||||
"r3": {
|
|
||||||
"ipv4": "auto",
|
|
||||||
"ipv6": "auto"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"bgp": {
|
"bgp": {
|
||||||
"local_as": "100",
|
"local_as": "100",
|
||||||
@ -76,16 +47,16 @@
|
|||||||
"ipv4": {
|
"ipv4": {
|
||||||
"unicast": {
|
"unicast": {
|
||||||
"neighbor": {
|
"neighbor": {
|
||||||
"r1": {
|
"r1": {"dest_link": {"r2": {}}},
|
||||||
"dest_link": {
|
"r3": {"dest_link": {"r2": {}}}
|
||||||
"r2": {}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"r3": {
|
"ipv6": {
|
||||||
"dest_link": {
|
"unicast": {
|
||||||
"r2": {}
|
"neighbor": {
|
||||||
}
|
"r1": {"dest_link": {"r2": {}}},
|
||||||
}
|
"r3": {"dest_link": {"r2": {}}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,23 +65,10 @@
|
|||||||
},
|
},
|
||||||
"r3": {
|
"r3": {
|
||||||
"links": {
|
"links": {
|
||||||
"lo": {
|
"lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
|
||||||
"ipv4": "auto",
|
"r1": {"ipv4": "auto", "ipv6": "auto"},
|
||||||
"ipv6": "auto",
|
"r2": {"ipv4": "auto", "ipv6": "auto"},
|
||||||
"type": "loopback"
|
"r4": {"ipv4": "auto", "ipv6": "auto"}
|
||||||
},
|
|
||||||
"r1": {
|
|
||||||
"ipv4": "auto",
|
|
||||||
"ipv6": "auto"
|
|
||||||
},
|
|
||||||
"r2": {
|
|
||||||
"ipv4": "auto",
|
|
||||||
"ipv6": "auto"
|
|
||||||
},
|
|
||||||
"r4": {
|
|
||||||
"ipv4": "auto",
|
|
||||||
"ipv6": "auto"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"bgp": {
|
"bgp": {
|
||||||
"local_as": "100",
|
"local_as": "100",
|
||||||
@ -118,21 +76,18 @@
|
|||||||
"ipv4": {
|
"ipv4": {
|
||||||
"unicast": {
|
"unicast": {
|
||||||
"neighbor": {
|
"neighbor": {
|
||||||
"r1": {
|
"r1": {"dest_link": {"r3": {}}},
|
||||||
"dest_link": {
|
"r2": {"dest_link": {"r3": {}}},
|
||||||
"r3": {}
|
"r4": {"dest_link": {"r3": {}}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"r2": {
|
"ipv6": {
|
||||||
"dest_link": {
|
"unicast": {
|
||||||
"r3": {}
|
"neighbor": {
|
||||||
}
|
"r1": {"dest_link": {"r3": {}}},
|
||||||
},
|
"r2": {"dest_link": {"r3": {}}},
|
||||||
"r4": {
|
"r4": {"dest_link": {"r3": {}}}
|
||||||
"dest_link": {
|
|
||||||
"r3": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,29 +96,17 @@
|
|||||||
},
|
},
|
||||||
"r4": {
|
"r4": {
|
||||||
"links": {
|
"links": {
|
||||||
"lo": {
|
"lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
|
||||||
"ipv4": "auto",
|
"r3": {"ipv4": "auto", "ipv6": "auto"}
|
||||||
"ipv6": "auto",
|
|
||||||
"type": "loopback"
|
|
||||||
},
|
|
||||||
"r3": {
|
|
||||||
"ipv4": "auto",
|
|
||||||
"ipv6": "auto"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"bgp": {
|
"bgp": {
|
||||||
"local_as": "200",
|
"local_as": "200",
|
||||||
"address_family": {
|
"address_family": {
|
||||||
"ipv4": {
|
"ipv4": {
|
||||||
"unicast": {
|
"unicast": {"neighbor": {"r3": {"dest_link": {"r4": {}}}}}
|
||||||
"neighbor": {
|
},
|
||||||
"r3": {
|
"ipv6": {
|
||||||
"dest_link": {
|
"unicast": {"neighbor": {"r3": {"dest_link": {"r4": {}}}}}
|
||||||
"r4": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,8 @@ Test steps
|
|||||||
- Verify clear bgp
|
- Verify clear bgp
|
||||||
- Test bgp convergence with loopback interface
|
- Test bgp convergence with loopback interface
|
||||||
- Test advertise network using network command
|
- Test advertise network using network command
|
||||||
|
- Verify routes not installed in zebra when /32 routes received
|
||||||
|
with loopback BGP session subnet
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@ -59,6 +61,7 @@ from lib.topogen import Topogen, get_topogen
|
|||||||
from mininet.topo import Topo
|
from mininet.topo import Topo
|
||||||
|
|
||||||
from lib.common_config import (
|
from lib.common_config import (
|
||||||
|
step,
|
||||||
start_topology,
|
start_topology,
|
||||||
write_test_header,
|
write_test_header,
|
||||||
write_test_footer,
|
write_test_footer,
|
||||||
@ -66,6 +69,13 @@ from lib.common_config import (
|
|||||||
create_static_routes,
|
create_static_routes,
|
||||||
verify_rib,
|
verify_rib,
|
||||||
verify_admin_distance_for_static_routes,
|
verify_admin_distance_for_static_routes,
|
||||||
|
check_address_types,
|
||||||
|
apply_raw_config,
|
||||||
|
addKernelRoute,
|
||||||
|
verify_fib_routes,
|
||||||
|
create_prefix_lists,
|
||||||
|
create_route_maps,
|
||||||
|
verify_bgp_community,
|
||||||
)
|
)
|
||||||
from lib.topolog import logger
|
from lib.topolog import logger
|
||||||
from lib.bgp import (
|
from lib.bgp import (
|
||||||
@ -76,6 +86,7 @@ from lib.bgp import (
|
|||||||
verify_as_numbers,
|
verify_as_numbers,
|
||||||
clear_bgp_and_verify,
|
clear_bgp_and_verify,
|
||||||
verify_bgp_timers_and_functionality,
|
verify_bgp_timers_and_functionality,
|
||||||
|
verify_bgp_rib,
|
||||||
)
|
)
|
||||||
from lib.topojson import build_topo_from_json, build_config_from_json
|
from lib.topojson import build_topo_from_json, build_config_from_json
|
||||||
|
|
||||||
@ -90,6 +101,18 @@ except IOError:
|
|||||||
# Global Variable
|
# Global Variable
|
||||||
KEEPALIVETIMER = 2
|
KEEPALIVETIMER = 2
|
||||||
HOLDDOWNTIMER = 6
|
HOLDDOWNTIMER = 6
|
||||||
|
r1_ipv4_loopback = "1.0.1.0/24"
|
||||||
|
r2_ipv4_loopback = "1.0.2.0/24"
|
||||||
|
r3_ipv4_loopback = "1.0.3.0/24"
|
||||||
|
r4_ipv4_loopback = "1.0.4.0/24"
|
||||||
|
r1_ipv6_loopback = "2001:db8:f::1:0/120"
|
||||||
|
r2_ipv6_loopback = "2001:db8:f::2:0/120"
|
||||||
|
r3_ipv6_loopback = "2001:db8:f::3:0/120"
|
||||||
|
r4_ipv6_loopback = "2001:db8:f::4:0/120"
|
||||||
|
NETWORK = {
|
||||||
|
"ipv4": ["100.1.1.1/32", "100.1.1.2/32"],
|
||||||
|
"ipv6": ["100::1/128", "100::2/128"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class CreateTopo(Topo):
|
class CreateTopo(Topo):
|
||||||
@ -131,7 +154,9 @@ def setup_module(mod):
|
|||||||
# Creating configuration from JSON
|
# Creating configuration from JSON
|
||||||
build_config_from_json(tgen, topo)
|
build_config_from_json(tgen, topo)
|
||||||
|
|
||||||
|
global ADDR_TYPES
|
||||||
global BGP_CONVERGENCE
|
global BGP_CONVERGENCE
|
||||||
|
ADDR_TYPES = check_address_types()
|
||||||
BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
|
BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
|
||||||
assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error: {}".format(
|
assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error: {}".format(
|
||||||
BGP_CONVERGENCE
|
BGP_CONVERGENCE
|
||||||
@ -522,6 +547,243 @@ def test_clear_bgp_and_verify(request):
|
|||||||
write_test_footer(tc_name)
|
write_test_footer(tc_name)
|
||||||
|
|
||||||
|
|
||||||
|
def test_BGP_attributes_with_vrf_default_keyword_p0(request):
|
||||||
|
"""
|
||||||
|
TC_9:
|
||||||
|
Verify BGP functionality for default vrf with
|
||||||
|
"vrf default" keyword.
|
||||||
|
"""
|
||||||
|
|
||||||
|
tc_name = request.node.name
|
||||||
|
write_test_header(tc_name)
|
||||||
|
tgen = get_topogen()
|
||||||
|
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
#reset_config_on_routers(tgen)
|
||||||
|
|
||||||
|
step("Configure static routes and redistribute in BGP on R3")
|
||||||
|
for addr_type in ADDR_TYPES:
|
||||||
|
input_dict = {
|
||||||
|
"r3": {
|
||||||
|
"static_routes": [
|
||||||
|
{
|
||||||
|
"network": NETWORK[addr_type][0],
|
||||||
|
"no_of_ip": 4,
|
||||||
|
"next_hop": "Null0",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = create_static_routes(tgen, input_dict)
|
||||||
|
assert result is True, "Testcase {} : Failed \n Error: {}".format(
|
||||||
|
tc_name, result
|
||||||
|
)
|
||||||
|
|
||||||
|
input_dict_2 = {
|
||||||
|
"r3": {
|
||||||
|
"bgp": {
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
|
||||||
|
"ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = create_router_bgp(tgen, topo, input_dict_2)
|
||||||
|
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
step(
|
||||||
|
"Create a route-map to match a specific prefix and modify"
|
||||||
|
"BGP attributes for matched prefix"
|
||||||
|
)
|
||||||
|
input_dict_2 = {
|
||||||
|
"r3": {
|
||||||
|
"prefix_lists": {
|
||||||
|
"ipv4": {
|
||||||
|
"ABC": [
|
||||||
|
{
|
||||||
|
"seqid": 10,
|
||||||
|
"action": "permit",
|
||||||
|
"network": NETWORK["ipv4"][0],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"XYZ": [
|
||||||
|
{
|
||||||
|
"seqid": 100,
|
||||||
|
"action": "permit",
|
||||||
|
"network": NETWORK["ipv6"][0],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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:
|
||||||
|
if addr_type == "ipv4":
|
||||||
|
pf_list = "ABC"
|
||||||
|
else:
|
||||||
|
pf_list = "XYZ"
|
||||||
|
|
||||||
|
input_dict_6 = {
|
||||||
|
"r3": {
|
||||||
|
"route_maps": {
|
||||||
|
"BGP_ATTR_{}".format(addr_type): [
|
||||||
|
{
|
||||||
|
"action": "permit",
|
||||||
|
"seq_id": 10,
|
||||||
|
"match": {addr_type: {"prefix_lists": pf_list}},
|
||||||
|
"set": {
|
||||||
|
"aspath": {"as_num": 500, "as_action": "prepend"},
|
||||||
|
"localpref": 500,
|
||||||
|
"origin": "egp",
|
||||||
|
"community": {"num": "500:500", "action": "additive"},
|
||||||
|
"large_community": {
|
||||||
|
"num": "500:500:500",
|
||||||
|
"action": "additive",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{"action": "permit", "seq_id": 20},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"BGP_ATTR_{}".format(addr_type): [
|
||||||
|
{
|
||||||
|
"action": "permit",
|
||||||
|
"seq_id": 100,
|
||||||
|
"match": {addr_type: {"prefix_lists": pf_list}},
|
||||||
|
"set": {
|
||||||
|
"aspath": {"as_num": 500, "as_action": "prepend"},
|
||||||
|
"localpref": 500,
|
||||||
|
"origin": "egp",
|
||||||
|
"community": {"num": "500:500", "action": "additive"},
|
||||||
|
"large_community": {
|
||||||
|
"num": "500:500:500",
|
||||||
|
"action": "additive",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{"action": "permit", "seq_id": 200},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = create_route_maps(tgen, input_dict_6)
|
||||||
|
assert result is True, "Testcase {} : Failed \n Error: {}".format(
|
||||||
|
tc_name, result
|
||||||
|
)
|
||||||
|
|
||||||
|
step("Apply the route-map on R3 in outbound direction for peer R4")
|
||||||
|
|
||||||
|
input_dict_7 = {
|
||||||
|
"r3": {
|
||||||
|
"bgp": {
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r4": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3": {
|
||||||
|
"route_maps": [
|
||||||
|
{
|
||||||
|
"name": "BGP_ATTR_ipv4",
|
||||||
|
"direction": "out",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r4": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3": {
|
||||||
|
"route_maps": [
|
||||||
|
{
|
||||||
|
"name": "BGP_ATTR_ipv6",
|
||||||
|
"direction": "out",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = create_router_bgp(tgen, topo, input_dict_7)
|
||||||
|
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
step(
|
||||||
|
"verify modified attributes for specific prefix with 'vrf default'"
|
||||||
|
"keyword on R4"
|
||||||
|
)
|
||||||
|
for addr_type in ADDR_TYPES:
|
||||||
|
dut = "r4"
|
||||||
|
input_dict = {
|
||||||
|
"r3": {
|
||||||
|
"static_routes": [
|
||||||
|
{
|
||||||
|
"network": NETWORK[addr_type][0],
|
||||||
|
"vrf": "default",
|
||||||
|
"largeCommunity": "500:500:500",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
|
||||||
|
assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
|
||||||
|
result = verify_rib(tgen, addr_type, dut, input_dict)
|
||||||
|
assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
for addr_type in ADDR_TYPES:
|
||||||
|
dut = "r4"
|
||||||
|
input_dict = {
|
||||||
|
"r3": {
|
||||||
|
"static_routes": [
|
||||||
|
{
|
||||||
|
"network": NETWORK[addr_type][0],
|
||||||
|
"vrf": "default",
|
||||||
|
"community": "500:500",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
|
||||||
|
assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
|
||||||
|
result = verify_rib(tgen, addr_type, dut, input_dict)
|
||||||
|
assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
input_dict_4 = {"largeCommunity": "500:500:500", "community": "500:500"}
|
||||||
|
|
||||||
|
result = verify_bgp_community(
|
||||||
|
tgen, addr_type, dut, [NETWORK[addr_type][0]], input_dict_4
|
||||||
|
)
|
||||||
|
assert result is True, "Test case {} : Should fail \n Error: {}".format(
|
||||||
|
tc_name, result
|
||||||
|
)
|
||||||
|
|
||||||
|
write_test_footer(tc_name)
|
||||||
|
|
||||||
|
|
||||||
def test_bgp_with_loopback_interface(request):
|
def test_bgp_with_loopback_interface(request):
|
||||||
"""
|
"""
|
||||||
Test BGP with loopback interface
|
Test BGP with loopback interface
|
||||||
@ -588,6 +850,298 @@ def test_bgp_with_loopback_interface(request):
|
|||||||
write_test_footer(tc_name)
|
write_test_footer(tc_name)
|
||||||
|
|
||||||
|
|
||||||
|
def test_bgp_with_loopback_with_same_subnet_p1(request):
|
||||||
|
"""
|
||||||
|
Verify routes not installed in zebra when /32 routes received
|
||||||
|
with loopback BGP session subnet
|
||||||
|
"""
|
||||||
|
|
||||||
|
tgen = get_topogen()
|
||||||
|
if BGP_CONVERGENCE is not True:
|
||||||
|
pytest.skip("skipped because of BGP Convergence failure")
|
||||||
|
|
||||||
|
# test case name
|
||||||
|
tc_name = request.node.name
|
||||||
|
write_test_header(tc_name)
|
||||||
|
|
||||||
|
# Creating configuration from JSON
|
||||||
|
reset_config_on_routers(tgen)
|
||||||
|
step("Delete BGP seesion created initially")
|
||||||
|
input_dict_r1 = {
|
||||||
|
"r1": {"bgp": {"delete": True}},
|
||||||
|
"r2": {"bgp": {"delete": True}},
|
||||||
|
"r3": {"bgp": {"delete": True}},
|
||||||
|
"r4": {"bgp": {"delete": True}},
|
||||||
|
}
|
||||||
|
result = create_router_bgp(tgen, topo, input_dict_r1)
|
||||||
|
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
step("Create BGP session over loop address")
|
||||||
|
topo_modify = deepcopy(topo)
|
||||||
|
|
||||||
|
for routerN in sorted(topo["routers"].keys()):
|
||||||
|
for addr_type in ADDR_TYPES:
|
||||||
|
for bgp_neighbor in topo_modify["routers"][routerN]["bgp"][
|
||||||
|
"address_family"
|
||||||
|
][addr_type]["unicast"]["neighbor"].keys():
|
||||||
|
|
||||||
|
# Adding ['source_link'] = 'lo' key:value pair
|
||||||
|
topo_modify["routers"][routerN]["bgp"]["address_family"][addr_type][
|
||||||
|
"unicast"
|
||||||
|
]["neighbor"][bgp_neighbor]["dest_link"] = {
|
||||||
|
"lo": {"source_link": "lo", "ebgp_multihop": 2}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = create_router_bgp(tgen, topo_modify["routers"])
|
||||||
|
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
step("Disable IPv6 BGP nbr from ipv4 address family")
|
||||||
|
raw_config = {
|
||||||
|
"r1": {
|
||||||
|
"raw_config": [
|
||||||
|
"router bgp {}".format(topo["routers"]["r1"]["bgp"]["local_as"]),
|
||||||
|
"address-family ipv4 unicast",
|
||||||
|
"no neighbor {} activate".format(
|
||||||
|
topo["routers"]["r2"]["links"]["lo"]["ipv6"].split("/")[0]
|
||||||
|
),
|
||||||
|
"no neighbor {} activate".format(
|
||||||
|
topo["routers"]["r3"]["links"]["lo"]["ipv6"].split("/")[0]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"r2": {
|
||||||
|
"raw_config": [
|
||||||
|
"router bgp {}".format(topo["routers"]["r2"]["bgp"]["local_as"]),
|
||||||
|
"address-family ipv4 unicast",
|
||||||
|
"no neighbor {} activate".format(
|
||||||
|
topo["routers"]["r1"]["links"]["lo"]["ipv6"].split("/")[0]
|
||||||
|
),
|
||||||
|
"no neighbor {} activate".format(
|
||||||
|
topo["routers"]["r3"]["links"]["lo"]["ipv6"].split("/")[0]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"r3": {
|
||||||
|
"raw_config": [
|
||||||
|
"router bgp {}".format(topo["routers"]["r3"]["bgp"]["local_as"]),
|
||||||
|
"address-family ipv4 unicast",
|
||||||
|
"no neighbor {} activate".format(
|
||||||
|
topo["routers"]["r1"]["links"]["lo"]["ipv6"].split("/")[0]
|
||||||
|
),
|
||||||
|
"no neighbor {} activate".format(
|
||||||
|
topo["routers"]["r2"]["links"]["lo"]["ipv6"].split("/")[0]
|
||||||
|
),
|
||||||
|
"no neighbor {} activate".format(
|
||||||
|
topo["routers"]["r4"]["links"]["lo"]["ipv6"].split("/")[0]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"r4": {
|
||||||
|
"raw_config": [
|
||||||
|
"router bgp {}".format(topo["routers"]["r4"]["bgp"]["local_as"]),
|
||||||
|
"address-family ipv4 unicast",
|
||||||
|
"no neighbor {} activate".format(
|
||||||
|
topo["routers"]["r3"]["links"]["lo"]["ipv6"].split("/")[0]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
step("Configure kernel routes")
|
||||||
|
result = apply_raw_config(tgen, raw_config)
|
||||||
|
assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
r1_ipv4_lo = topo["routers"]["r1"]["links"]["lo"]["ipv4"]
|
||||||
|
r1_ipv6_lo = topo["routers"]["r1"]["links"]["lo"]["ipv6"]
|
||||||
|
r2_ipv4_lo = topo["routers"]["r2"]["links"]["lo"]["ipv4"]
|
||||||
|
r2_ipv6_lo = topo["routers"]["r2"]["links"]["lo"]["ipv6"]
|
||||||
|
r3_ipv4_lo = topo["routers"]["r3"]["links"]["lo"]["ipv4"]
|
||||||
|
r3_ipv6_lo = topo["routers"]["r3"]["links"]["lo"]["ipv6"]
|
||||||
|
r4_ipv4_lo = topo["routers"]["r4"]["links"]["lo"]["ipv4"]
|
||||||
|
r4_ipv6_lo = topo["routers"]["r4"]["links"]["lo"]["ipv6"]
|
||||||
|
|
||||||
|
r1_r2 = topo["routers"]["r1"]["links"]["r2"]["ipv6"].split("/")[0]
|
||||||
|
r2_r1 = topo["routers"]["r2"]["links"]["r1"]["ipv6"].split("/")[0]
|
||||||
|
r1_r3 = topo["routers"]["r1"]["links"]["r3"]["ipv6"].split("/")[0]
|
||||||
|
r3_r1 = topo["routers"]["r3"]["links"]["r1"]["ipv6"].split("/")[0]
|
||||||
|
r2_r3 = topo["routers"]["r2"]["links"]["r3"]["ipv6"].split("/")[0]
|
||||||
|
r3_r2 = topo["routers"]["r3"]["links"]["r2"]["ipv6"].split("/")[0]
|
||||||
|
r3_r4 = topo["routers"]["r3"]["links"]["r4"]["ipv6"].split("/")[0]
|
||||||
|
r4_r3 = topo["routers"]["r4"]["links"]["r3"]["ipv6"].split("/")[0]
|
||||||
|
|
||||||
|
r1_r2_ipv4 = topo["routers"]["r1"]["links"]["r2"]["ipv4"].split("/")[0]
|
||||||
|
r2_r1_ipv4 = topo["routers"]["r2"]["links"]["r1"]["ipv4"].split("/")[0]
|
||||||
|
r1_r3_ipv4 = topo["routers"]["r1"]["links"]["r3"]["ipv4"].split("/")[0]
|
||||||
|
r3_r1_ipv4 = topo["routers"]["r3"]["links"]["r1"]["ipv4"].split("/")[0]
|
||||||
|
r2_r3_ipv4 = topo["routers"]["r2"]["links"]["r3"]["ipv4"].split("/")[0]
|
||||||
|
r3_r2_ipv4 = topo["routers"]["r3"]["links"]["r2"]["ipv4"].split("/")[0]
|
||||||
|
r3_r4_ipv4 = topo["routers"]["r3"]["links"]["r4"]["ipv4"].split("/")[0]
|
||||||
|
r4_r3_ipv4 = topo["routers"]["r4"]["links"]["r3"]["ipv4"].split("/")[0]
|
||||||
|
|
||||||
|
r1_r2_intf = topo["routers"]["r1"]["links"]["r2"]["interface"]
|
||||||
|
r2_r1_intf = topo["routers"]["r2"]["links"]["r1"]["interface"]
|
||||||
|
r1_r3_intf = topo["routers"]["r1"]["links"]["r3"]["interface"]
|
||||||
|
r3_r1_intf = topo["routers"]["r3"]["links"]["r1"]["interface"]
|
||||||
|
r2_r3_intf = topo["routers"]["r2"]["links"]["r3"]["interface"]
|
||||||
|
r3_r2_intf = topo["routers"]["r3"]["links"]["r2"]["interface"]
|
||||||
|
r3_r4_intf = topo["routers"]["r3"]["links"]["r4"]["interface"]
|
||||||
|
r4_r3_intf = topo["routers"]["r4"]["links"]["r3"]["interface"]
|
||||||
|
|
||||||
|
ipv4_list = [
|
||||||
|
("r1", r1_r2_intf, r2_ipv4_loopback),
|
||||||
|
("r1", r1_r3_intf, r3_ipv4_loopback),
|
||||||
|
("r2", r2_r1_intf, r1_ipv4_loopback),
|
||||||
|
("r2", r2_r3_intf, r3_ipv4_loopback),
|
||||||
|
("r3", r3_r1_intf, r1_ipv4_loopback),
|
||||||
|
("r3", r3_r2_intf, r2_ipv4_loopback),
|
||||||
|
("r3", r3_r4_intf, r4_ipv4_loopback),
|
||||||
|
("r4", r4_r3_intf, r3_ipv4_loopback),
|
||||||
|
]
|
||||||
|
|
||||||
|
ipv6_list = [
|
||||||
|
("r1", r1_r2_intf, r2_ipv6_loopback, r2_r1),
|
||||||
|
("r1", r1_r3_intf, r3_ipv6_loopback, r3_r1),
|
||||||
|
("r2", r2_r1_intf, r1_ipv6_loopback, r1_r2),
|
||||||
|
("r2", r2_r3_intf, r3_ipv6_loopback, r3_r2),
|
||||||
|
("r3", r3_r1_intf, r1_ipv6_loopback, r1_r3),
|
||||||
|
("r3", r3_r2_intf, r2_ipv6_loopback, r2_r3),
|
||||||
|
("r3", r3_r4_intf, r4_ipv6_loopback, r4_r3),
|
||||||
|
("r4", r4_r3_intf, r3_ipv6_loopback, r3_r4),
|
||||||
|
]
|
||||||
|
|
||||||
|
for dut, intf, loop_addr in ipv4_list:
|
||||||
|
result = addKernelRoute(tgen, dut, intf, loop_addr)
|
||||||
|
assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
for dut, intf, loop_addr, next_hop in ipv6_list:
|
||||||
|
result = addKernelRoute(tgen, dut, intf, loop_addr, next_hop)
|
||||||
|
assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
step("Configure static routes")
|
||||||
|
|
||||||
|
input_dict = {
|
||||||
|
"r1": {
|
||||||
|
"static_routes": [
|
||||||
|
{"network": r2_ipv4_loopback, "next_hop": r2_r1_ipv4},
|
||||||
|
{"network": r3_ipv4_loopback, "next_hop": r3_r1_ipv4},
|
||||||
|
{"network": r2_ipv6_loopback, "next_hop": r2_r1},
|
||||||
|
{"network": r3_ipv6_loopback, "next_hop": r3_r1},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"r2": {
|
||||||
|
"static_routes": [
|
||||||
|
{"network": r1_ipv4_loopback, "next_hop": r1_r2_ipv4},
|
||||||
|
{"network": r3_ipv4_loopback, "next_hop": r3_r2_ipv4},
|
||||||
|
{"network": r1_ipv6_loopback, "next_hop": r1_r2},
|
||||||
|
{"network": r3_ipv6_loopback, "next_hop": r3_r2},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"r3": {
|
||||||
|
"static_routes": [
|
||||||
|
{"network": r1_ipv4_loopback, "next_hop": r1_r3_ipv4},
|
||||||
|
{"network": r2_ipv4_loopback, "next_hop": r2_r3_ipv4},
|
||||||
|
{"network": r4_ipv4_loopback, "next_hop": r4_r3_ipv4},
|
||||||
|
{"network": r1_ipv6_loopback, "next_hop": r1_r3},
|
||||||
|
{"network": r2_ipv6_loopback, "next_hop": r2_r3},
|
||||||
|
{"network": r4_ipv6_loopback, "next_hop": r4_r3},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"r4": {
|
||||||
|
"static_routes": [
|
||||||
|
{"network": r3_ipv4_loopback, "next_hop": r3_r4_ipv4},
|
||||||
|
{"network": r3_ipv6_loopback, "next_hop": r3_r4},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
result = create_static_routes(tgen, input_dict)
|
||||||
|
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
step("Verify BGP session convergence")
|
||||||
|
|
||||||
|
result = verify_bgp_convergence(tgen, topo_modify)
|
||||||
|
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
step("Configure redistribute connected on R2 and R4")
|
||||||
|
input_dict_1 = {
|
||||||
|
"r2": {
|
||||||
|
"bgp": {
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {"redistribute": [{"redist_type": "connected"}]}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {"redistribute": [{"redist_type": "connected"}]}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r4": {
|
||||||
|
"bgp": {
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {"redistribute": [{"redist_type": "connected"}]}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {"redistribute": [{"redist_type": "connected"}]}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
result = create_router_bgp(tgen, topo, input_dict_1)
|
||||||
|
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
step("Verify Ipv4 and Ipv6 network installed in R1 RIB but not in FIB")
|
||||||
|
input_dict_r1 = {
|
||||||
|
"r1": {
|
||||||
|
"static_routes": [
|
||||||
|
{"network": "1.0.2.17/32"},
|
||||||
|
{"network": "2001:db8:f::2:17/128"},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dut = "r1"
|
||||||
|
protocol = "bgp"
|
||||||
|
for addr_type in ADDR_TYPES:
|
||||||
|
result = verify_rib(tgen, addr_type, dut, input_dict_r1, protocol=protocol)
|
||||||
|
assert result is True, "Testcase {} :Failed \n Error: {}".format(
|
||||||
|
tc_name, result
|
||||||
|
)
|
||||||
|
|
||||||
|
result = verify_fib_routes(tgen, addr_type, dut, input_dict_r1, expected=False)
|
||||||
|
assert result is not True, "Testcase {} : Failed \n"
|
||||||
|
"Expected behavior: routes should not present in fib \n"
|
||||||
|
"Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
step("Verify Ipv4 and Ipv6 network installed in r3 RIB but not in FIB")
|
||||||
|
input_dict_r3 = {
|
||||||
|
"r3": {
|
||||||
|
"static_routes": [
|
||||||
|
{"network": "1.0.4.17/32"},
|
||||||
|
{"network": "2001:db8:f::4:17/128"},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dut = "r3"
|
||||||
|
protocol = "bgp"
|
||||||
|
for addr_type in ADDR_TYPES:
|
||||||
|
result = verify_rib(
|
||||||
|
tgen, addr_type, dut, input_dict_r3, protocol=protocol, fib=None
|
||||||
|
)
|
||||||
|
assert result is True, "Testcase {} :Failed \n Error: {}".format(
|
||||||
|
tc_name, result
|
||||||
|
)
|
||||||
|
|
||||||
|
result = verify_fib_routes(tgen, addr_type, dut, input_dict_r1, expected=False)
|
||||||
|
assert result is not True, "Testcase {} : Failed \n"
|
||||||
|
"Expected behavior: routes should not present in fib \n"
|
||||||
|
"Error: {}".format(tc_name, result)
|
||||||
|
|
||||||
|
write_test_footer(tc_name)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
args = ["-s"] + sys.argv[1:]
|
args = ["-s"] + sys.argv[1:]
|
||||||
sys.exit(pytest.main(args))
|
sys.exit(pytest.main(args))
|
||||||
|
@ -46,6 +46,7 @@ from lib.common_config import (
|
|||||||
LOGDIR = "/tmp/topotests/"
|
LOGDIR = "/tmp/topotests/"
|
||||||
TMPDIR = None
|
TMPDIR = None
|
||||||
|
|
||||||
|
|
||||||
def create_router_bgp(tgen, topo, input_dict=None, build=False, load_config=True):
|
def create_router_bgp(tgen, topo, input_dict=None, build=False, load_config=True):
|
||||||
"""
|
"""
|
||||||
API to configure bgp on router
|
API to configure bgp on router
|
||||||
@ -1219,11 +1220,17 @@ def verify_bgp_convergence(tgen, topo, dut=None):
|
|||||||
no_of_peer += 1
|
no_of_peer += 1
|
||||||
|
|
||||||
if no_of_peer == total_peer:
|
if no_of_peer == total_peer:
|
||||||
logger.info("[DUT: %s] VRF: %s, BGP is Converged for %s address-family",
|
logger.info(
|
||||||
router, vrf, addr_type)
|
"[DUT: %s] VRF: %s, BGP is Converged for %s address-family",
|
||||||
|
router,
|
||||||
|
vrf,
|
||||||
|
addr_type,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
errormsg = ("[DUT: %s] VRF: %s, BGP is not converged for %s address-family" %
|
errormsg = (
|
||||||
(router, vrf, addr_type))
|
"[DUT: %s] VRF: %s, BGP is not converged for %s address-family"
|
||||||
|
% (router, vrf, addr_type)
|
||||||
|
)
|
||||||
return errormsg
|
return errormsg
|
||||||
|
|
||||||
logger.debug("Exiting API: verify_bgp_convergence()")
|
logger.debug("Exiting API: verify_bgp_convergence()")
|
||||||
@ -2553,10 +2560,19 @@ def verify_bgp_rib(tgen, addr_type, dut, input_dict, next_hop=None, aspath=None)
|
|||||||
missing_routes = []
|
missing_routes = []
|
||||||
st_found = False
|
st_found = False
|
||||||
nh_found = False
|
nh_found = False
|
||||||
|
|
||||||
vrf = static_route.setdefault("vrf", None)
|
vrf = static_route.setdefault("vrf", None)
|
||||||
|
community = static_route.setdefault("community", None)
|
||||||
|
largeCommunity = static_route.setdefault("largeCommunity", None)
|
||||||
|
|
||||||
if vrf:
|
if vrf:
|
||||||
cmd = "{} vrf {} {}".format(command, vrf, addr_type)
|
cmd = "{} vrf {} {}".format(command, vrf, addr_type)
|
||||||
|
|
||||||
|
if community:
|
||||||
|
cmd = "{} community {}".format(cmd, community)
|
||||||
|
|
||||||
|
if largeCommunity:
|
||||||
|
cmd = "{} large-community {}".format(cmd, largeCommunity)
|
||||||
else:
|
else:
|
||||||
cmd = "{} {}".format(command, addr_type)
|
cmd = "{} {}".format(command, addr_type)
|
||||||
|
|
||||||
|
@ -2352,7 +2352,9 @@ def configure_brctl(tgen, topo, input_dict):
|
|||||||
):
|
):
|
||||||
|
|
||||||
ip_cmd_list = []
|
ip_cmd_list = []
|
||||||
cmd = "ip link add name {} type bridge stp_state {}".format(brctl_name, stp)
|
cmd = "ip link add name {} type bridge stp_state {}".format(
|
||||||
|
brctl_name, stp
|
||||||
|
)
|
||||||
|
|
||||||
logger.info("[DUT: %s]: Running command: %s", dut, cmd)
|
logger.info("[DUT: %s]: Running command: %s", dut, cmd)
|
||||||
rnode.run(cmd)
|
rnode.run(cmd)
|
||||||
@ -2821,6 +2823,260 @@ def verify_rib(
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@retry(attempts=5, wait=2, return_is_str=True, initial_wait=2)
|
||||||
|
def verify_fib_routes(tgen, addr_type, dut, input_dict, next_hop=None):
|
||||||
|
"""
|
||||||
|
Data will be read from input_dict or input JSON file, API will generate
|
||||||
|
same prefixes, which were redistributed by either create_static_routes() or
|
||||||
|
advertise_networks_using_network_command() and will verify next_hop and
|
||||||
|
each prefix/routes is present in "show ip/ipv6 fib json"
|
||||||
|
command o/p.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
* `tgen` : topogen object
|
||||||
|
* `addr_type` : ip type, ipv4/ipv6
|
||||||
|
* `dut`: Device Under Test, for which user wants to test the data
|
||||||
|
* `input_dict` : input dict, has details of static routes
|
||||||
|
* `next_hop`[optional]: next_hop which needs to be verified,
|
||||||
|
default: static
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
input_routes_r1 = {
|
||||||
|
"r1": {
|
||||||
|
"static_routes": [{
|
||||||
|
"network": ["1.1.1.1/32],
|
||||||
|
"next_hop": "Null0",
|
||||||
|
"vrf": "RED"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = result = verify_fib_routes(tgen, "ipv4, "r1", input_routes_r1)
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
errormsg(str) or True
|
||||||
|
"""
|
||||||
|
|
||||||
|
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
||||||
|
|
||||||
|
router_list = tgen.routers()
|
||||||
|
for routerInput in input_dict.keys():
|
||||||
|
for router, rnode in router_list.iteritems():
|
||||||
|
if router != dut:
|
||||||
|
continue
|
||||||
|
|
||||||
|
logger.info("Checking router %s FIB routes:", router)
|
||||||
|
|
||||||
|
# Verifying RIB routes
|
||||||
|
if addr_type == "ipv4":
|
||||||
|
command = "show ip fib"
|
||||||
|
else:
|
||||||
|
command = "show ipv6 fib"
|
||||||
|
|
||||||
|
found_routes = []
|
||||||
|
missing_routes = []
|
||||||
|
|
||||||
|
if "static_routes" in input_dict[routerInput]:
|
||||||
|
static_routes = input_dict[routerInput]["static_routes"]
|
||||||
|
|
||||||
|
for static_route in static_routes:
|
||||||
|
if "vrf" in static_route and static_route["vrf"] is not None:
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
"[DUT: {}]: Verifying routes for VRF:"
|
||||||
|
" {}".format(router, static_route["vrf"])
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd = "{} vrf {}".format(command, static_route["vrf"])
|
||||||
|
|
||||||
|
else:
|
||||||
|
cmd = "{}".format(command)
|
||||||
|
|
||||||
|
cmd = "{} json".format(cmd)
|
||||||
|
|
||||||
|
rib_routes_json = run_frr_cmd(rnode, cmd, isjson=True)
|
||||||
|
|
||||||
|
# Verifying output dictionary rib_routes_json is not empty
|
||||||
|
if bool(rib_routes_json) is False:
|
||||||
|
errormsg = "[DUT: {}]: No route found in fib".format(router)
|
||||||
|
return errormsg
|
||||||
|
|
||||||
|
network = static_route["network"]
|
||||||
|
if "no_of_ip" in static_route:
|
||||||
|
no_of_ip = static_route["no_of_ip"]
|
||||||
|
else:
|
||||||
|
no_of_ip = 1
|
||||||
|
|
||||||
|
# Generating IPs for verification
|
||||||
|
ip_list = generate_ips(network, no_of_ip)
|
||||||
|
st_found = False
|
||||||
|
nh_found = False
|
||||||
|
|
||||||
|
for st_rt in ip_list:
|
||||||
|
st_rt = str(ipaddress.ip_network(unicode(st_rt)))
|
||||||
|
|
||||||
|
_addr_type = validate_ip_address(st_rt)
|
||||||
|
if _addr_type != addr_type:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if st_rt in rib_routes_json:
|
||||||
|
st_found = True
|
||||||
|
found_routes.append(st_rt)
|
||||||
|
|
||||||
|
if next_hop:
|
||||||
|
if type(next_hop) is not list:
|
||||||
|
next_hop = [next_hop]
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
for nh in next_hop:
|
||||||
|
for nh_dict in rib_routes_json[st_rt][0][
|
||||||
|
"nexthops"
|
||||||
|
]:
|
||||||
|
if nh_dict["ip"] != nh:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
if count == len(next_hop):
|
||||||
|
nh_found = True
|
||||||
|
else:
|
||||||
|
missing_routes.append(st_rt)
|
||||||
|
errormsg = (
|
||||||
|
"Nexthop {} is Missing"
|
||||||
|
" for route {} in "
|
||||||
|
"RIB of router {}\n".format(
|
||||||
|
next_hop, st_rt, dut
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return errormsg
|
||||||
|
|
||||||
|
else:
|
||||||
|
missing_routes.append(st_rt)
|
||||||
|
|
||||||
|
if len(missing_routes) > 0:
|
||||||
|
errormsg = "[DUT: {}]: Missing route in FIB:" " {}".format(
|
||||||
|
dut, missing_routes
|
||||||
|
)
|
||||||
|
return errormsg
|
||||||
|
|
||||||
|
if nh_found:
|
||||||
|
logger.info(
|
||||||
|
"Found next_hop {} for all routes in RIB"
|
||||||
|
" of router {}\n".format(next_hop, dut)
|
||||||
|
)
|
||||||
|
|
||||||
|
if found_routes:
|
||||||
|
logger.info(
|
||||||
|
"[DUT: %s]: Verified routes in FIB, found" " routes are: %s\n",
|
||||||
|
dut,
|
||||||
|
found_routes,
|
||||||
|
)
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
if "bgp" in input_dict[routerInput]:
|
||||||
|
if (
|
||||||
|
"advertise_networks"
|
||||||
|
not in input_dict[routerInput]["bgp"]["address_family"][addr_type][
|
||||||
|
"unicast"
|
||||||
|
]
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
|
||||||
|
found_routes = []
|
||||||
|
missing_routes = []
|
||||||
|
advertise_network = input_dict[routerInput]["bgp"]["address_family"][
|
||||||
|
addr_type
|
||||||
|
]["unicast"]["advertise_networks"]
|
||||||
|
|
||||||
|
# Continue if there are no network advertise
|
||||||
|
if len(advertise_network) == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for advertise_network_dict in advertise_network:
|
||||||
|
if "vrf" in advertise_network_dict:
|
||||||
|
cmd = "{} vrf {} json".format(command, static_route["vrf"])
|
||||||
|
else:
|
||||||
|
cmd = "{} json".format(command)
|
||||||
|
|
||||||
|
rib_routes_json = run_frr_cmd(rnode, cmd, isjson=True)
|
||||||
|
|
||||||
|
# Verifying output dictionary rib_routes_json is not empty
|
||||||
|
if bool(rib_routes_json) is False:
|
||||||
|
errormsg = "No route found in rib of router {}..".format(router)
|
||||||
|
return errormsg
|
||||||
|
|
||||||
|
start_ip = advertise_network_dict["network"]
|
||||||
|
if "no_of_network" in advertise_network_dict:
|
||||||
|
no_of_network = advertise_network_dict["no_of_network"]
|
||||||
|
else:
|
||||||
|
no_of_network = 1
|
||||||
|
|
||||||
|
# Generating IPs for verification
|
||||||
|
ip_list = generate_ips(start_ip, no_of_network)
|
||||||
|
st_found = False
|
||||||
|
nh_found = False
|
||||||
|
|
||||||
|
for st_rt in ip_list:
|
||||||
|
st_rt = str(ipaddress.ip_network(unicode(st_rt)))
|
||||||
|
|
||||||
|
_addr_type = validate_ip_address(st_rt)
|
||||||
|
if _addr_type != addr_type:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if st_rt in rib_routes_json:
|
||||||
|
st_found = True
|
||||||
|
found_routes.append(st_rt)
|
||||||
|
|
||||||
|
if next_hop:
|
||||||
|
if type(next_hop) is not list:
|
||||||
|
next_hop = [next_hop]
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
for nh in next_hop:
|
||||||
|
for nh_dict in rib_routes_json[st_rt][0]["nexthops"]:
|
||||||
|
if nh_dict["ip"] != nh:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
if count == len(next_hop):
|
||||||
|
nh_found = True
|
||||||
|
else:
|
||||||
|
missing_routes.append(st_rt)
|
||||||
|
errormsg = (
|
||||||
|
"Nexthop {} is Missing"
|
||||||
|
" for route {} in "
|
||||||
|
"RIB of router {}\n".format(next_hop, st_rt, dut)
|
||||||
|
)
|
||||||
|
return errormsg
|
||||||
|
else:
|
||||||
|
missing_routes.append(st_rt)
|
||||||
|
|
||||||
|
if len(missing_routes) > 0:
|
||||||
|
errormsg = "[DUT: {}]: Missing route in FIB: " "{} \n".format(
|
||||||
|
dut, missing_routes
|
||||||
|
)
|
||||||
|
return errormsg
|
||||||
|
|
||||||
|
if nh_found:
|
||||||
|
logger.info(
|
||||||
|
"Found next_hop {} for all routes in RIB"
|
||||||
|
" of router {}\n".format(next_hop, dut)
|
||||||
|
)
|
||||||
|
|
||||||
|
if found_routes:
|
||||||
|
logger.info(
|
||||||
|
"[DUT: {}]: Verified routes FIB"
|
||||||
|
", found routes are: {}\n".format(dut, found_routes)
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def verify_admin_distance_for_static_routes(tgen, input_dict):
|
def verify_admin_distance_for_static_routes(tgen, input_dict):
|
||||||
"""
|
"""
|
||||||
API to verify admin distance for static routes as defined in input_dict/
|
API to verify admin distance for static routes as defined in input_dict/
|
||||||
|
Loading…
Reference in New Issue
Block a user