mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-11 16:39:33 +00:00
Merge pull request #6398 from kuldeepkash/bgp_multi_vrf
tests: Add bgp-multi-vrf test suites
This commit is contained in:
commit
bda6d3729f
@ -295,7 +295,7 @@ def test_modify_ecmp_max_paths(request, ecmp_num, test_type):
|
|||||||
addr_type,
|
addr_type,
|
||||||
dut,
|
dut,
|
||||||
input_dict_1,
|
input_dict_1,
|
||||||
next_hop=NEXT_HOPS[addr_type],
|
next_hop=NEXT_HOPS[addr_type][:int(ecmp_num)],
|
||||||
protocol=protocol,
|
protocol=protocol,
|
||||||
)
|
)
|
||||||
assert result is True, "Testcase {} : Failed \n Error: {}".format(
|
assert result is True, "Testcase {} : Failed \n Error: {}".format(
|
||||||
|
@ -296,7 +296,7 @@ def test_modify_ecmp_max_paths(request, ecmp_num, test_type):
|
|||||||
addr_type,
|
addr_type,
|
||||||
dut,
|
dut,
|
||||||
input_dict_1,
|
input_dict_1,
|
||||||
next_hop=NEXT_HOPS[addr_type],
|
next_hop=NEXT_HOPS[addr_type][:int(ecmp_num)],
|
||||||
protocol=protocol,
|
protocol=protocol,
|
||||||
)
|
)
|
||||||
assert result is True, "Testcase {} : Failed \n Error: {}".format(
|
assert result is True, "Testcase {} : Failed \n Error: {}".format(
|
||||||
|
884
tests/topotests/bgp_multi_vrf_topo1/bgp_multi_vrf_topo1.json
Normal file
884
tests/topotests/bgp_multi_vrf_topo1/bgp_multi_vrf_topo1.json
Normal file
@ -0,0 +1,884 @@
|
|||||||
|
{
|
||||||
|
"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": {
|
||||||
|
"red1": {
|
||||||
|
"links": {
|
||||||
|
"r1-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_A"},
|
||||||
|
"r1-link2": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_B"}
|
||||||
|
},
|
||||||
|
"vrfs":[
|
||||||
|
{
|
||||||
|
"name": "RED_A",
|
||||||
|
"id": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RED_B",
|
||||||
|
"id": "2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bgp":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"local_as": "500",
|
||||||
|
"vrf": "RED_A",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"red1-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"red1-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local_as": "500",
|
||||||
|
"vrf": "RED_B",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"red1-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"red1-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blue1": {
|
||||||
|
"links": {
|
||||||
|
"r1-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_A"},
|
||||||
|
"r1-link2": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_B"}
|
||||||
|
},
|
||||||
|
"vrfs":[
|
||||||
|
{
|
||||||
|
"name": "BLUE_A",
|
||||||
|
"id": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BLUE_B",
|
||||||
|
"id": "2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bgp":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"local_as": "800",
|
||||||
|
"vrf": "BLUE_A",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"blue1-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"blue1-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local_as": "800",
|
||||||
|
"vrf": "BLUE_B",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"blue1-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"blue1-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"r1": {
|
||||||
|
"links": {
|
||||||
|
"red1-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_A"},
|
||||||
|
"red1-link2": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_B"},
|
||||||
|
"blue1-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_A"},
|
||||||
|
"blue1-link2": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_B"},
|
||||||
|
"r2-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_A"},
|
||||||
|
"r2-link2": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_B"},
|
||||||
|
"r2-link3": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_A"},
|
||||||
|
"r2-link4": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_B"}
|
||||||
|
},
|
||||||
|
"vrfs":[
|
||||||
|
{
|
||||||
|
"name": "RED_A",
|
||||||
|
"id": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RED_B",
|
||||||
|
"id": "2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BLUE_A",
|
||||||
|
"id": "3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BLUE_B",
|
||||||
|
"id": "4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bgp":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"local_as": "100",
|
||||||
|
"vrf": "RED_A",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"red1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link1": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link1":
|
||||||
|
{ "next_hop_self": true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"red1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link1": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link1":
|
||||||
|
{ "next_hop_self": true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local_as": "100",
|
||||||
|
"vrf": "RED_B",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"red1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link2": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link2":
|
||||||
|
{ "next_hop_self": true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"red1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link2": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link2":
|
||||||
|
{ "next_hop_self": true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local_as": "100",
|
||||||
|
"vrf": "BLUE_A",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"blue1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link1": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link3":
|
||||||
|
{ "next_hop_self": true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"blue1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link1": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link3":
|
||||||
|
{ "next_hop_self": true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local_as": "100",
|
||||||
|
"vrf": "BLUE_B",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"blue1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link2": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link4":
|
||||||
|
{ "next_hop_self": true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"blue1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link2": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r1-link4":
|
||||||
|
{ "next_hop_self": true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"r2": {
|
||||||
|
"links": {
|
||||||
|
"r1-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_A"},
|
||||||
|
"r1-link2": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_B"},
|
||||||
|
"r1-link3": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_A"},
|
||||||
|
"r1-link4": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_B"},
|
||||||
|
"r3-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_A"},
|
||||||
|
"r3-link2": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_B"},
|
||||||
|
"r3-link3": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_A"},
|
||||||
|
"r3-link4": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_B"}
|
||||||
|
},
|
||||||
|
"vrfs":[
|
||||||
|
{
|
||||||
|
"name": "RED_A",
|
||||||
|
"id": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RED_B",
|
||||||
|
"id": "2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BLUE_A",
|
||||||
|
"id": "3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BLUE_B",
|
||||||
|
"id": "4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bgp":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"local_as": "100",
|
||||||
|
"vrf": "RED_A",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link1": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link1": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local_as": "100",
|
||||||
|
"vrf": "RED_B",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link2": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link2": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local_as": "100",
|
||||||
|
"vrf": "BLUE_A",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link3": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link3": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link3": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link3": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local_as": "100",
|
||||||
|
"vrf": "BLUE_B",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link4": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link4": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r1": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link4": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"r2-link4": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"r3": {
|
||||||
|
"links": {
|
||||||
|
"r2-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_A"},
|
||||||
|
"r2-link2": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_B"},
|
||||||
|
"r2-link3": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_A"},
|
||||||
|
"r2-link4": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_B"},
|
||||||
|
"red2-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_A"},
|
||||||
|
"red2-link2": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_B"},
|
||||||
|
"blue2-link1": {"ipv4": "auto", "ipv6": "autor3", "vrf": "BLUE_A"},
|
||||||
|
"blue2-link2": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_B"}
|
||||||
|
},
|
||||||
|
"vrfs":[
|
||||||
|
{
|
||||||
|
"name": "RED_A",
|
||||||
|
"id": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RED_B",
|
||||||
|
"id": "2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BLUE_A",
|
||||||
|
"id": "3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BLUE_B",
|
||||||
|
"id": "4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bgp":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"local_as": "200",
|
||||||
|
"vrf": "RED_A",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link1": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"red2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link1": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"red2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local_as": "200",
|
||||||
|
"vrf": "RED_B",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link2": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"red2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link2": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"red2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local_as": "200",
|
||||||
|
"vrf": "BLUE_A",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link3": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"blue2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link3": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"blue2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local_as": "200",
|
||||||
|
"vrf": "BLUE_B",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link4": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"blue2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link4": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"blue2": {
|
||||||
|
"dest_link": {
|
||||||
|
"r3-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"red2": {
|
||||||
|
"links": {
|
||||||
|
"r3-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_A"},
|
||||||
|
"r3-link2": {"ipv4": "auto", "ipv6": "auto", "vrf": "RED_B"}
|
||||||
|
},
|
||||||
|
"vrfs":[
|
||||||
|
{
|
||||||
|
"name": "RED_A",
|
||||||
|
"id": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RED_B",
|
||||||
|
"id": "2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bgp":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"local_as": "500",
|
||||||
|
"vrf": "RED_A",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"red2-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"red2-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local_as": "500",
|
||||||
|
"vrf": "RED_B",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"red2-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"red2-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blue2": {
|
||||||
|
"links": {
|
||||||
|
"r3-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_A"},
|
||||||
|
"r3-link2": {"ipv4": "auto", "ipv6": "auto", "vrf": "BLUE_B"}
|
||||||
|
},
|
||||||
|
"vrfs":[
|
||||||
|
{
|
||||||
|
"name": "BLUE_A",
|
||||||
|
"id": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BLUE_B",
|
||||||
|
"id": "2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bgp":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"local_as": "800",
|
||||||
|
"vrf": "BLUE_A",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"blue2-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"blue2-link1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local_as": "800",
|
||||||
|
"vrf": "BLUE_B",
|
||||||
|
"address_family": {
|
||||||
|
"ipv4": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"blue2-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"unicast": {
|
||||||
|
"neighbor": {
|
||||||
|
"r3": {
|
||||||
|
"dest_link": {
|
||||||
|
"blue2-link2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6300
tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py
Executable file
6300
tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py
Executable file
File diff suppressed because it is too large
Load Diff
1277
tests/topotests/bgp_multi_vrf_topo2/bgp_multi_vrf_topo2.json
Normal file
1277
tests/topotests/bgp_multi_vrf_topo2/bgp_multi_vrf_topo2.json
Normal file
File diff suppressed because it is too large
Load Diff
2012
tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py
Executable file
2012
tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py
Executable file
File diff suppressed because it is too large
Load Diff
@ -75,8 +75,12 @@ def create_router_bgp(tgen, topo, input_dict=None, build=False, load_config=True
|
|||||||
"address_family": {
|
"address_family": {
|
||||||
"ipv4": {
|
"ipv4": {
|
||||||
"unicast": {
|
"unicast": {
|
||||||
"redistribute": [
|
"redistribute": [{
|
||||||
{"redist_type": "static"},
|
"redist_type": "static",
|
||||||
|
"attribute": {
|
||||||
|
"metric" : 123
|
||||||
|
}
|
||||||
|
},
|
||||||
{"redist_type": "connected"}
|
{"redist_type": "connected"}
|
||||||
],
|
],
|
||||||
"advertise_networks": [
|
"advertise_networks": [
|
||||||
@ -143,15 +147,20 @@ def create_router_bgp(tgen, topo, input_dict=None, build=False, load_config=True
|
|||||||
logger.debug("Router %s: 'bgp' not present in input_dict", router)
|
logger.debug("Router %s: 'bgp' not present in input_dict", router)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
data_all_bgp = __create_bgp_global(tgen, input_dict, router, build)
|
bgp_data_list = input_dict[router]["bgp"]
|
||||||
if data_all_bgp:
|
|
||||||
bgp_data = input_dict[router]["bgp"]
|
|
||||||
|
|
||||||
|
if type(bgp_data_list) is not list:
|
||||||
|
bgp_data_list = [bgp_data_list]
|
||||||
|
|
||||||
|
for bgp_data in bgp_data_list:
|
||||||
|
data_all_bgp = __create_bgp_global(tgen, bgp_data, router, build)
|
||||||
|
if data_all_bgp:
|
||||||
bgp_addr_data = bgp_data.setdefault("address_family", {})
|
bgp_addr_data = bgp_data.setdefault("address_family", {})
|
||||||
|
|
||||||
if not bgp_addr_data:
|
if not bgp_addr_data:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Router %s: 'address_family' not present in " "input_dict for BGP",
|
"Router %s: 'address_family' not present in "
|
||||||
|
"input_dict for BGP",
|
||||||
router,
|
router,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -170,7 +179,7 @@ def create_router_bgp(tgen, topo, input_dict=None, build=False, load_config=True
|
|||||||
data_all_bgp = __create_bgp_unicast_neighbor(
|
data_all_bgp = __create_bgp_unicast_neighbor(
|
||||||
tgen,
|
tgen,
|
||||||
topo,
|
topo,
|
||||||
input_dict,
|
bgp_data,
|
||||||
router,
|
router,
|
||||||
afi_test,
|
afi_test,
|
||||||
config_data=data_all_bgp,
|
config_data=data_all_bgp,
|
||||||
@ -186,7 +195,7 @@ def create_router_bgp(tgen, topo, input_dict=None, build=False, load_config=True
|
|||||||
logger.error(errormsg)
|
logger.error(errormsg)
|
||||||
return errormsg
|
return errormsg
|
||||||
|
|
||||||
logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
|
logger.debug("Exiting lib API: create_router_bgp()")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@ -206,19 +215,16 @@ def __create_bgp_global(tgen, input_dict, router, build=False):
|
|||||||
True or False
|
True or False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
result = False
|
||||||
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
||||||
|
|
||||||
bgp_data = input_dict[router]["bgp"]
|
bgp_data = input_dict
|
||||||
del_bgp_action = bgp_data.setdefault("delete", False)
|
del_bgp_action = bgp_data.setdefault("delete", False)
|
||||||
if del_bgp_action:
|
|
||||||
config_data = ["no router bgp"]
|
|
||||||
|
|
||||||
return config_data
|
|
||||||
|
|
||||||
config_data = []
|
config_data = []
|
||||||
|
|
||||||
if "local_as" not in bgp_data and build:
|
if "local_as" not in bgp_data and build:
|
||||||
logger.error(
|
logger.debug(
|
||||||
"Router %s: 'local_as' not present in input_dict" "for BGP", router
|
"Router %s: 'local_as' not present in input_dict" "for BGP", router
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
@ -229,6 +235,12 @@ def __create_bgp_global(tgen, input_dict, router, build=False):
|
|||||||
if vrf_id:
|
if vrf_id:
|
||||||
cmd = "{} vrf {}".format(cmd, vrf_id)
|
cmd = "{} vrf {}".format(cmd, vrf_id)
|
||||||
|
|
||||||
|
if del_bgp_action:
|
||||||
|
cmd = "no {}".format(cmd)
|
||||||
|
config_data.append(cmd)
|
||||||
|
|
||||||
|
return config_data
|
||||||
|
|
||||||
config_data.append(cmd)
|
config_data.append(cmd)
|
||||||
config_data.append("no bgp ebgp-requires-policy")
|
config_data.append("no bgp ebgp-requires-policy")
|
||||||
|
|
||||||
@ -325,12 +337,15 @@ def __create_bgp_unicast_neighbor(
|
|||||||
* `build` : Only for initial setup phase this is set as True.
|
* `build` : Only for initial setup phase this is set as True.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
result = False
|
||||||
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
||||||
|
|
||||||
add_neigh = True
|
add_neigh = True
|
||||||
|
bgp_data = input_dict
|
||||||
if "router bgp" in config_data:
|
if "router bgp" in config_data:
|
||||||
add_neigh = False
|
add_neigh = False
|
||||||
bgp_data = input_dict[router]["bgp"]["address_family"]
|
|
||||||
|
bgp_data = input_dict["address_family"]
|
||||||
|
|
||||||
for addr_type, addr_dict in bgp_data.iteritems():
|
for addr_type, addr_dict in bgp_data.iteritems():
|
||||||
if not addr_dict:
|
if not addr_dict:
|
||||||
@ -403,14 +418,19 @@ def __create_bgp_unicast_neighbor(
|
|||||||
if redistribute_data:
|
if redistribute_data:
|
||||||
for redistribute in redistribute_data:
|
for redistribute in redistribute_data:
|
||||||
if "redist_type" not in redistribute:
|
if "redist_type" not in redistribute:
|
||||||
logger.error(
|
logger.debug(
|
||||||
"Router %s: 'redist_type' not present in " "input_dict", router
|
"Router %s: 'redist_type' not present in " "input_dict", router
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
cmd = "redistribute {}".format(redistribute["redist_type"])
|
cmd = "redistribute {}".format(redistribute["redist_type"])
|
||||||
redist_attr = redistribute.setdefault("attribute", None)
|
redist_attr = redistribute.setdefault("attribute", None)
|
||||||
if redist_attr:
|
if redist_attr:
|
||||||
|
if isinstance(redist_attr, dict):
|
||||||
|
for key, value in redist_attr.items():
|
||||||
|
cmd = "{} {} {}".format(cmd, key, value)
|
||||||
|
else:
|
||||||
cmd = "{} {}".format(cmd, redist_attr)
|
cmd = "{} {}".format(cmd, redist_attr)
|
||||||
|
|
||||||
del_action = redistribute.setdefault("delete", False)
|
del_action = redistribute.setdefault("delete", False)
|
||||||
if del_action:
|
if del_action:
|
||||||
cmd = "no {}".format(cmd)
|
cmd = "no {}".format(cmd)
|
||||||
@ -453,13 +473,18 @@ def __create_bgp_neighbor(topo, input_dict, router, addr_type, add_neigh=True):
|
|||||||
config_data = []
|
config_data = []
|
||||||
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
||||||
|
|
||||||
bgp_data = input_dict[router]["bgp"]["address_family"]
|
bgp_data = input_dict["address_family"]
|
||||||
neigh_data = bgp_data[addr_type]["unicast"]["neighbor"]
|
neigh_data = bgp_data[addr_type]["unicast"]["neighbor"]
|
||||||
|
|
||||||
for name, peer_dict in neigh_data.iteritems():
|
for name, peer_dict in neigh_data.iteritems():
|
||||||
for dest_link, peer in peer_dict["dest_link"].iteritems():
|
for dest_link, peer in peer_dict["dest_link"].iteritems():
|
||||||
nh_details = topo[name]
|
nh_details = topo[name]
|
||||||
|
|
||||||
|
if "vrfs" in topo[router]:
|
||||||
|
remote_as = nh_details["bgp"][0]["local_as"]
|
||||||
|
else:
|
||||||
remote_as = nh_details["bgp"]["local_as"]
|
remote_as = nh_details["bgp"]["local_as"]
|
||||||
|
|
||||||
update_source = None
|
update_source = None
|
||||||
|
|
||||||
if dest_link in nh_details["links"].keys():
|
if dest_link in nh_details["links"].keys():
|
||||||
@ -549,7 +574,7 @@ def __create_bgp_unicast_address_family(
|
|||||||
config_data = []
|
config_data = []
|
||||||
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
||||||
|
|
||||||
bgp_data = input_dict[router]["bgp"]["address_family"]
|
bgp_data = input_dict["address_family"]
|
||||||
neigh_data = bgp_data[addr_type]["unicast"]["neighbor"]
|
neigh_data = bgp_data[addr_type]["unicast"]["neighbor"]
|
||||||
|
|
||||||
for peer_name, peer_dict in deepcopy(neigh_data).iteritems():
|
for peer_name, peer_dict in deepcopy(neigh_data).iteritems():
|
||||||
@ -605,8 +630,12 @@ def __create_bgp_unicast_address_family(
|
|||||||
allowas_in = peer.setdefault("allowas-in", None)
|
allowas_in = peer.setdefault("allowas-in", None)
|
||||||
|
|
||||||
# next-hop-self
|
# next-hop-self
|
||||||
if next_hop_self:
|
if next_hop_self is not None:
|
||||||
|
if next_hop_self is True:
|
||||||
config_data.append("{} next-hop-self".format(neigh_cxt))
|
config_data.append("{} next-hop-self".format(neigh_cxt))
|
||||||
|
else:
|
||||||
|
config_data.append("no {} next-hop-self".format(neigh_cxt))
|
||||||
|
|
||||||
# send_community
|
# send_community
|
||||||
if send_community:
|
if send_community:
|
||||||
config_data.append("{} send-community".format(neigh_cxt))
|
config_data.append("{} send-community".format(neigh_cxt))
|
||||||
@ -840,40 +869,113 @@ def verify_router_id(tgen, topo, input_dict):
|
|||||||
|
|
||||||
|
|
||||||
@retry(attempts=20, wait=2, return_is_str=True)
|
@retry(attempts=20, wait=2, return_is_str=True)
|
||||||
def verify_bgp_convergence(tgen, topo):
|
def verify_bgp_convergence(tgen, topo, dut=None):
|
||||||
"""
|
"""
|
||||||
API will verify if BGP is converged with in the given time frame.
|
API will verify if BGP is converged with in the given time frame.
|
||||||
Running "show bgp summary json" command and verify bgp neighbor
|
Running "show bgp summary json" command and verify bgp neighbor
|
||||||
state is established,
|
state is established,
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
* `tgen`: topogen object
|
* `tgen`: topogen object
|
||||||
* `topo`: input json file data
|
* `topo`: input json file data
|
||||||
* `addr_type`: ip_type, ipv4/ipv6
|
* `dut`: device under test
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
# To veriry is BGP is converged for all the routers used in
|
# To veriry is BGP is converged for all the routers used in
|
||||||
topology
|
topology
|
||||||
results = verify_bgp_convergence(tgen, topo, "ipv4")
|
results = verify_bgp_convergence(tgen, topo, dut="r1")
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
errormsg(str) or True
|
errormsg(str) or True
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
logger.debug("Entering lib API: verify_bgp_convergence()")
|
||||||
for router, rnode in tgen.routers().iteritems():
|
for router, rnode in tgen.routers().iteritems():
|
||||||
if "bgp" not in topo["routers"][router]:
|
if "bgp" not in topo["routers"][router]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logger.info("Verifying BGP Convergence on router %s", router)
|
if dut is not None and dut != router:
|
||||||
show_bgp_json = run_frr_cmd(rnode, "show bgp summary json", isjson=True)
|
continue
|
||||||
|
|
||||||
|
logger.info("Verifying BGP Convergence on router %s:", router)
|
||||||
|
show_bgp_json = run_frr_cmd(rnode, "show bgp vrf all summary json", isjson=True)
|
||||||
# Verifying output dictionary show_bgp_json is empty or not
|
# Verifying output dictionary show_bgp_json is empty or not
|
||||||
if not bool(show_bgp_json):
|
if not bool(show_bgp_json):
|
||||||
errormsg = "BGP is not running"
|
errormsg = "BGP is not running"
|
||||||
return errormsg
|
return errormsg
|
||||||
|
|
||||||
# To find neighbor ip type
|
# To find neighbor ip type
|
||||||
bgp_addr_type = topo["routers"][router]["bgp"]["address_family"]
|
bgp_data_list = topo["routers"][router]["bgp"]
|
||||||
|
|
||||||
|
if type(bgp_data_list) is not list:
|
||||||
|
bgp_data_list = [bgp_data_list]
|
||||||
|
|
||||||
|
for bgp_data in bgp_data_list:
|
||||||
|
if "vrf" in bgp_data:
|
||||||
|
vrf = bgp_data["vrf"]
|
||||||
|
if vrf is None:
|
||||||
|
vrf = "default"
|
||||||
|
else:
|
||||||
|
vrf = "default"
|
||||||
|
|
||||||
|
# To find neighbor ip type
|
||||||
|
bgp_addr_type = bgp_data["address_family"]
|
||||||
|
if "l2vpn" in bgp_addr_type:
|
||||||
|
total_evpn_peer = 0
|
||||||
|
|
||||||
|
if "neighbor" not in bgp_addr_type["l2vpn"]["evpn"]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
bgp_neighbors = bgp_addr_type["l2vpn"]["evpn"]["neighbor"]
|
||||||
|
total_evpn_peer += len(bgp_neighbors)
|
||||||
|
|
||||||
|
no_of_evpn_peer = 0
|
||||||
|
for bgp_neighbor, peer_data in bgp_neighbors.items():
|
||||||
|
for _addr_type, dest_link_dict in peer_data.items():
|
||||||
|
data = topo["routers"][bgp_neighbor]["links"]
|
||||||
|
for dest_link in dest_link_dict.keys():
|
||||||
|
if dest_link in data:
|
||||||
|
peer_details = peer_data[_addr_type][dest_link]
|
||||||
|
|
||||||
|
neighbor_ip = data[dest_link][_addr_type].split("/")[0]
|
||||||
|
nh_state = None
|
||||||
|
|
||||||
|
if (
|
||||||
|
"ipv4Unicast" in show_bgp_json[vrf]
|
||||||
|
or "ipv6Unicast" in show_bgp_json[vrf]
|
||||||
|
):
|
||||||
|
errormsg = (
|
||||||
|
"[DUT: %s] VRF: %s, "
|
||||||
|
"ipv4Unicast/ipv6Unicast"
|
||||||
|
" address-family present"
|
||||||
|
" under l2vpn" % (router, vrf)
|
||||||
|
)
|
||||||
|
return errormsg
|
||||||
|
|
||||||
|
l2VpnEvpn_data = show_bgp_json[vrf]["l2VpnEvpn"][
|
||||||
|
"peers"
|
||||||
|
]
|
||||||
|
nh_state = l2VpnEvpn_data[neighbor_ip]["state"]
|
||||||
|
|
||||||
|
if nh_state == "Established":
|
||||||
|
no_of_evpn_peer += 1
|
||||||
|
|
||||||
|
if no_of_evpn_peer == total_evpn_peer:
|
||||||
|
logger.info(
|
||||||
|
"[DUT: %s] VRF: %s, BGP is Converged for " "epvn peers",
|
||||||
|
router,
|
||||||
|
vrf,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
errormsg = (
|
||||||
|
"[DUT: %s] VRF: %s, BGP is not converged "
|
||||||
|
"for evpn peers" % (router, vrf)
|
||||||
|
)
|
||||||
|
return errormsg
|
||||||
|
else:
|
||||||
for addr_type in bgp_addr_type.keys():
|
for addr_type in bgp_addr_type.keys():
|
||||||
if not check_address_types(addr_type):
|
if not check_address_types(addr_type):
|
||||||
continue
|
continue
|
||||||
@ -890,30 +992,168 @@ def verify_bgp_convergence(tgen, topo):
|
|||||||
bgp_neighbors = bgp_addr_type[addr_type]["unicast"]["neighbor"]
|
bgp_neighbors = bgp_addr_type[addr_type]["unicast"]["neighbor"]
|
||||||
|
|
||||||
no_of_peer = 0
|
no_of_peer = 0
|
||||||
for bgp_neighbor, peer_data in bgp_neighbors.iteritems():
|
for bgp_neighbor, peer_data in bgp_neighbors.items():
|
||||||
for dest_link in peer_data["dest_link"].keys():
|
for dest_link in peer_data["dest_link"].keys():
|
||||||
data = topo["routers"][bgp_neighbor]["links"]
|
data = topo["routers"][bgp_neighbor]["links"]
|
||||||
if dest_link in data:
|
if dest_link in data:
|
||||||
neighbor_ip = data[dest_link][addr_type].split("/")[0]
|
peer_details = peer_data["dest_link"][dest_link]
|
||||||
|
# for link local neighbors
|
||||||
|
if (
|
||||||
|
"neighbor_type" in peer_details
|
||||||
|
and peer_details["neighbor_type"] == "link-local"
|
||||||
|
):
|
||||||
|
neighbor_ip = get_ipv6_linklocal_address(
|
||||||
|
topo["routers"], bgp_neighbor, dest_link
|
||||||
|
)
|
||||||
|
elif "source_link" in peer_details:
|
||||||
|
neighbor_ip = topo["routers"][bgp_neighbor][
|
||||||
|
"links"
|
||||||
|
][peer_details["source_link"]][addr_type].split(
|
||||||
|
"/"
|
||||||
|
)[
|
||||||
|
0
|
||||||
|
]
|
||||||
|
elif (
|
||||||
|
"neighbor_type" in peer_details
|
||||||
|
and peer_details["neighbor_type"] == "unnumbered"
|
||||||
|
):
|
||||||
|
neighbor_ip = data[dest_link]["peer-interface"]
|
||||||
|
else:
|
||||||
|
neighbor_ip = data[dest_link][addr_type].split("/")[
|
||||||
|
0
|
||||||
|
]
|
||||||
|
nh_state = None
|
||||||
|
|
||||||
if addr_type == "ipv4":
|
if addr_type == "ipv4":
|
||||||
ipv4_data = show_bgp_json["ipv4Unicast"]["peers"]
|
ipv4_data = show_bgp_json[vrf]["ipv4Unicast"][
|
||||||
|
"peers"
|
||||||
|
]
|
||||||
nh_state = ipv4_data[neighbor_ip]["state"]
|
nh_state = ipv4_data[neighbor_ip]["state"]
|
||||||
else:
|
else:
|
||||||
ipv6_data = show_bgp_json["ipv6Unicast"]["peers"]
|
ipv6_data = show_bgp_json[vrf]["ipv6Unicast"][
|
||||||
|
"peers"
|
||||||
|
]
|
||||||
nh_state = ipv6_data[neighbor_ip]["state"]
|
nh_state = ipv6_data[neighbor_ip]["state"]
|
||||||
|
|
||||||
if nh_state == "Established":
|
if nh_state == "Established":
|
||||||
no_of_peer += 1
|
no_of_peer += 1
|
||||||
|
|
||||||
if no_of_peer == total_peer:
|
if no_of_peer == total_peer:
|
||||||
logger.info("BGP is Converged for router %s", router)
|
logger.info("[DUT: %s] VRF: %s, BGP is Converged", router, vrf)
|
||||||
else:
|
else:
|
||||||
errormsg = "BGP is not converged for router {}".format(router)
|
errormsg = "[DUT: %s] VRF: %s, BGP is not converged" % (router, vrf)
|
||||||
return errormsg
|
return errormsg
|
||||||
|
|
||||||
logger.debug("Exiting API: verify_bgp_convergence()")
|
logger.debug("Exiting API: verify_bgp_convergence()")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@retry(attempts=3, wait=4, return_is_str=True)
|
||||||
|
def verify_bgp_community(
|
||||||
|
tgen, addr_type, router, network, input_dict=None, vrf=None, bestpath=False
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
* `vrf`: VRF name
|
||||||
|
* `bestpath`: To check best path cli
|
||||||
|
|
||||||
|
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.debug("Entering lib API: verify_bgp_community()")
|
||||||
|
if router not in tgen.routers():
|
||||||
|
return False
|
||||||
|
|
||||||
|
rnode = tgen.routers()[router]
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
"Verifying BGP community attributes on dut %s: for %s " "network %s",
|
||||||
|
router,
|
||||||
|
addr_type,
|
||||||
|
network,
|
||||||
|
)
|
||||||
|
|
||||||
|
command = "show bgp"
|
||||||
|
|
||||||
|
sleep(5)
|
||||||
|
for net in network:
|
||||||
|
if vrf:
|
||||||
|
cmd = "{} vrf {} {} {} json".format(command, vrf, addr_type, net)
|
||||||
|
elif bestpath:
|
||||||
|
cmd = "{} {} {} bestpath json".format(command, addr_type, net)
|
||||||
|
else:
|
||||||
|
cmd = "{} {} {} json".format(command, addr_type, net)
|
||||||
|
|
||||||
|
show_bgp_json = run_frr_cmd(rnode, cmd, isjson=True)
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
def modify_as_number(tgen, topo, input_dict):
|
def modify_as_number(tgen, topo, input_dict):
|
||||||
"""
|
"""
|
||||||
API reads local_as and remote_as from user defined input_dict and
|
API reads local_as and remote_as from user defined input_dict and
|
||||||
@ -1090,6 +1330,7 @@ def clear_bgp(tgen, addr_type, router, vrf=None):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
||||||
|
|
||||||
if router not in tgen.routers():
|
if router not in tgen.routers():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -1102,9 +1343,21 @@ def clear_bgp(tgen, addr_type, router, vrf=None):
|
|||||||
# Clearing BGP
|
# Clearing BGP
|
||||||
logger.info("Clearing BGP neighborship for router %s..", router)
|
logger.info("Clearing BGP neighborship for router %s..", router)
|
||||||
if addr_type == "ipv4":
|
if addr_type == "ipv4":
|
||||||
|
if vrf:
|
||||||
|
for _vrf in vrf:
|
||||||
|
run_frr_cmd(rnode, "clear ip bgp vrf {} *".format(_vrf))
|
||||||
|
else:
|
||||||
run_frr_cmd(rnode, "clear ip bgp *")
|
run_frr_cmd(rnode, "clear ip bgp *")
|
||||||
elif addr_type == "ipv6":
|
elif addr_type == "ipv6":
|
||||||
|
if vrf:
|
||||||
|
for _vrf in vrf:
|
||||||
|
run_frr_cmd(rnode, "clear bgp vrf {} ipv6 *".format(_vrf))
|
||||||
|
else:
|
||||||
run_frr_cmd(rnode, "clear bgp ipv6 *")
|
run_frr_cmd(rnode, "clear bgp ipv6 *")
|
||||||
|
else:
|
||||||
|
run_frr_cmd(rnode, "clear bgp *")
|
||||||
|
|
||||||
|
sleep(5)
|
||||||
|
|
||||||
logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
|
logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
|
||||||
|
|
||||||
@ -1698,7 +1951,6 @@ def verify_best_path_as_per_bgp_attribute(
|
|||||||
"show bgp ipv4/6 json" command will be run and verify best path according
|
"show bgp ipv4/6 json" command will be run and verify best path according
|
||||||
to shortest as-path, highest local-preference and med, lowest weight and
|
to shortest as-path, highest local-preference and med, lowest weight and
|
||||||
route origin IGP>EGP>INCOMPLETE.
|
route origin IGP>EGP>INCOMPLETE.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
* `tgen` : topogen object
|
* `tgen` : topogen object
|
||||||
@ -1707,7 +1959,6 @@ def verify_best_path_as_per_bgp_attribute(
|
|||||||
* `attribute` : calculate best path using this attribute
|
* `attribute` : calculate best path using this attribute
|
||||||
* `input_dict`: defines different routes to calculate for which route
|
* `input_dict`: defines different routes to calculate for which route
|
||||||
best path is selected
|
best path is selected
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
# To verify best path for routes 200.50.2.0/32 and 200.60.2.0/32 from
|
# To verify best path for routes 200.50.2.0/32 and 200.60.2.0/32 from
|
||||||
@ -1741,23 +1992,48 @@ def verify_best_path_as_per_bgp_attribute(
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
||||||
|
|
||||||
if router not in tgen.routers():
|
if router not in tgen.routers():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
rnode = tgen.routers()[router]
|
rnode = tgen.routers()[router]
|
||||||
|
|
||||||
command = "show bgp {} json".format(addr_type)
|
# Verifying show bgp json
|
||||||
|
command = "show bgp"
|
||||||
|
|
||||||
sleep(5)
|
sleep(2)
|
||||||
logger.info("Verifying router %s RIB for best path:", router)
|
logger.info("Verifying router %s RIB for best path:", router)
|
||||||
sh_ip_bgp_json = run_frr_cmd(rnode, command, isjson=True)
|
|
||||||
|
|
||||||
|
static_route = False
|
||||||
|
advertise_network = False
|
||||||
for route_val in input_dict.values():
|
for route_val in input_dict.values():
|
||||||
|
if "static_routes" in route_val:
|
||||||
|
static_route = True
|
||||||
|
networks = route_val["static_routes"]
|
||||||
|
else:
|
||||||
|
advertise_network = True
|
||||||
net_data = route_val["bgp"]["address_family"][addr_type]["unicast"]
|
net_data = route_val["bgp"]["address_family"][addr_type]["unicast"]
|
||||||
networks = net_data["advertise_networks"]
|
networks = net_data["advertise_networks"]
|
||||||
for network in networks:
|
|
||||||
route = network["network"]
|
|
||||||
|
|
||||||
|
for network in networks:
|
||||||
|
_network = network["network"]
|
||||||
|
no_of_ip = network.setdefault("no_of_ip", 1)
|
||||||
|
vrf = network.setdefault("vrf", None)
|
||||||
|
|
||||||
|
if vrf:
|
||||||
|
cmd = "{} vrf {}".format(command, vrf)
|
||||||
|
else:
|
||||||
|
cmd = command
|
||||||
|
|
||||||
|
cmd = "{} {}".format(cmd, addr_type)
|
||||||
|
cmd = "{} json".format(cmd)
|
||||||
|
sh_ip_bgp_json = run_frr_cmd(rnode, cmd, isjson=True)
|
||||||
|
|
||||||
|
routes = generate_ips(_network, no_of_ip)
|
||||||
|
for route in routes:
|
||||||
|
route = str(ipaddr.IPNetwork(unicode(route)))
|
||||||
|
|
||||||
|
if route in sh_ip_bgp_json["routes"]:
|
||||||
route_attributes = sh_ip_bgp_json["routes"][route]
|
route_attributes = sh_ip_bgp_json["routes"][route]
|
||||||
_next_hop = None
|
_next_hop = None
|
||||||
compare = None
|
compare = None
|
||||||
@ -1779,13 +2055,17 @@ def verify_best_path_as_per_bgp_attribute(
|
|||||||
# LOCAL_PREF attribute
|
# LOCAL_PREF attribute
|
||||||
elif attribute == "locPrf":
|
elif attribute == "locPrf":
|
||||||
# Find next_hop for the route have highest local preference
|
# Find next_hop for the route have highest local preference
|
||||||
_next_hop = max(attribute_dict, key=(lambda k: attribute_dict[k]))
|
_next_hop = max(
|
||||||
|
attribute_dict, key=(lambda k: attribute_dict[k])
|
||||||
|
)
|
||||||
compare = "HIGHEST"
|
compare = "HIGHEST"
|
||||||
|
|
||||||
# WEIGHT attribute
|
# WEIGHT attribute
|
||||||
elif attribute == "weight":
|
elif attribute == "weight":
|
||||||
# Find next_hop for the route have highest weight
|
# Find next_hop for the route have highest weight
|
||||||
_next_hop = max(attribute_dict, key=(lambda k: attribute_dict[k]))
|
_next_hop = max(
|
||||||
|
attribute_dict, key=(lambda k: attribute_dict[k])
|
||||||
|
)
|
||||||
compare = "HIGHEST"
|
compare = "HIGHEST"
|
||||||
|
|
||||||
# ORIGIN attribute
|
# ORIGIN attribute
|
||||||
@ -1793,23 +2073,32 @@ def verify_best_path_as_per_bgp_attribute(
|
|||||||
# Find next_hop for the route have IGP as origin, -
|
# Find next_hop for the route have IGP as origin, -
|
||||||
# - rule is IGP>EGP>INCOMPLETE
|
# - rule is IGP>EGP>INCOMPLETE
|
||||||
_next_hop = [
|
_next_hop = [
|
||||||
key for (key, value) in attribute_dict.iteritems() if value == "IGP"
|
key
|
||||||
|
for (key, value) in attribute_dict.iteritems()
|
||||||
|
if value == "IGP"
|
||||||
][0]
|
][0]
|
||||||
compare = ""
|
compare = ""
|
||||||
|
|
||||||
# MED attribute
|
# MED attribute
|
||||||
elif attribute == "metric":
|
elif attribute == "metric":
|
||||||
# Find next_hop for the route have LOWEST MED
|
# Find next_hop for the route have LOWEST MED
|
||||||
_next_hop = min(attribute_dict, key=(lambda k: attribute_dict[k]))
|
_next_hop = min(
|
||||||
|
attribute_dict, key=(lambda k: attribute_dict[k])
|
||||||
|
)
|
||||||
compare = "LOWEST"
|
compare = "LOWEST"
|
||||||
|
|
||||||
# Show ip route
|
# Show ip route
|
||||||
if addr_type == "ipv4":
|
if addr_type == "ipv4":
|
||||||
command = "show ip route json"
|
command_1 = "show ip route"
|
||||||
else:
|
else:
|
||||||
command = "show ipv6 route json"
|
command_1 = "show ipv6 route"
|
||||||
|
|
||||||
rib_routes_json = run_frr_cmd(rnode, command, isjson=True)
|
if vrf:
|
||||||
|
cmd = "{} vrf {} json".format(command_1, vrf)
|
||||||
|
else:
|
||||||
|
cmd = "{} json".format(command_1)
|
||||||
|
|
||||||
|
rib_routes_json = run_frr_cmd(rnode, cmd, isjson=True)
|
||||||
|
|
||||||
# Verifying output dictionary rib_routes_json is not empty
|
# Verifying output dictionary rib_routes_json is not empty
|
||||||
if not bool(rib_routes_json):
|
if not bool(rib_routes_json):
|
||||||
@ -1822,7 +2111,10 @@ def verify_best_path_as_per_bgp_attribute(
|
|||||||
if route in rib_routes_json:
|
if route in rib_routes_json:
|
||||||
st_found = True
|
st_found = True
|
||||||
# Verify next_hop in rib_routes_json
|
# Verify next_hop in rib_routes_json
|
||||||
if rib_routes_json[route][0]["nexthops"][0]["ip"] in attribute_dict:
|
if (
|
||||||
|
rib_routes_json[route][0]["nexthops"][0]["ip"]
|
||||||
|
in attribute_dict
|
||||||
|
):
|
||||||
nh_found = True
|
nh_found = True
|
||||||
else:
|
else:
|
||||||
errormsg = (
|
errormsg = (
|
||||||
@ -1965,7 +2257,7 @@ def verify_best_path_as_per_admin_distance(
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@retry(attempts=10, wait=2, return_is_str=True, initial_wait=2)
|
@retry(attempts=5, wait=2, return_is_str=True, initial_wait=2)
|
||||||
def verify_bgp_rib(tgen, addr_type, dut, input_dict, next_hop=None, aspath=None):
|
def verify_bgp_rib(tgen, addr_type, dut, input_dict, next_hop=None, aspath=None):
|
||||||
"""
|
"""
|
||||||
This API is to verify whether bgp rib has any
|
This API is to verify whether bgp rib has any
|
||||||
@ -1995,7 +2287,7 @@ def verify_bgp_rib(tgen, addr_type, dut, input_dict, next_hop=None, aspath=None)
|
|||||||
errormsg(str) or True
|
errormsg(str) or True
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
|
logger.debug("Entering lib API: verify_bgp_rib()")
|
||||||
|
|
||||||
router_list = tgen.routers()
|
router_list = tgen.routers()
|
||||||
additional_nexthops_in_required_nhs = []
|
additional_nexthops_in_required_nhs = []
|
||||||
@ -2210,7 +2502,7 @@ def verify_bgp_rib(tgen, addr_type, dut, input_dict, next_hop=None, aspath=None)
|
|||||||
"routes are: {}\n".format(dut, found_routes)
|
"routes are: {}\n".format(dut, found_routes)
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
|
logger.debug("Exiting lib API: verify_bgp_rib()")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -37,6 +37,7 @@ from lib.common_config import (
|
|||||||
create_prefix_lists,
|
create_prefix_lists,
|
||||||
create_route_maps,
|
create_route_maps,
|
||||||
create_bgp_community_lists,
|
create_bgp_community_lists,
|
||||||
|
create_vrf_cfg,
|
||||||
)
|
)
|
||||||
|
|
||||||
from lib.bgp import create_router_bgp
|
from lib.bgp import create_router_bgp
|
||||||
@ -49,7 +50,6 @@ def build_topo_from_json(tgen, topo):
|
|||||||
Reads configuration from JSON file. Adds routers, creates interface
|
Reads configuration from JSON file. Adds routers, creates interface
|
||||||
names dynamically and link routers as defined in JSON to create
|
names dynamically and link routers as defined in JSON to create
|
||||||
topology. Assigns IPs dynamically to all interfaces of each router.
|
topology. Assigns IPs dynamically to all interfaces of each router.
|
||||||
|
|
||||||
* `tgen`: Topogen object
|
* `tgen`: Topogen object
|
||||||
* `topo`: json file data
|
* `topo`: json file data
|
||||||
"""
|
"""
|
||||||
@ -203,6 +203,7 @@ def build_config_from_json(tgen, topo, save_bkup=True):
|
|||||||
|
|
||||||
func_dict = OrderedDict(
|
func_dict = OrderedDict(
|
||||||
[
|
[
|
||||||
|
("vrfs", create_vrf_cfg),
|
||||||
("links", create_interfaces_cfg),
|
("links", create_interfaces_cfg),
|
||||||
("static_routes", create_static_routes),
|
("static_routes", create_static_routes),
|
||||||
("prefix_lists", create_prefix_lists),
|
("prefix_lists", create_prefix_lists),
|
||||||
|
Loading…
Reference in New Issue
Block a user