Merge pull request #8280 from kuldeepkash/bgp_convergence_test

tests: Fix bgp convergence issue mentioned in #8279
This commit is contained in:
Donald Sharp 2021-03-22 10:15:36 -04:00 committed by GitHub
commit cb39b2d4aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 144 additions and 145 deletions

View File

@ -43,6 +43,7 @@ from lib.common_config import (
run_frr_cmd,
FRRCFG_FILE,
retry,
get_ipv6_linklocal_address
)
LOGDIR = "/tmp/topotests/"
@ -446,7 +447,7 @@ def __create_bgp_unicast_neighbor(
cmd = "redistribute {}".format(redistribute["redist_type"])
redist_attr = redistribute.setdefault("attribute", None)
if redist_attr:
if isinstance(redist_attr, dict):
if type(redist_attr) is dict:
for key, value in redist_attr.items():
cmd = "{} {} {}".format(cmd, key, value)
else:
@ -528,7 +529,7 @@ def __create_l2vpn_evpn_address_family(
if advertise_data:
for address_type, unicast_type in advertise_data.items():
if isinstance(unicast_type, dict):
if type(unicast_type) is dict:
for key, value in unicast_type.items():
cmd = "advertise {} {}".format(address_type, key)
@ -555,7 +556,7 @@ def __create_l2vpn_evpn_address_family(
"ipv4"
].split("/")[0]
if isinstance(action, dict):
if type(action) is dict:
next_hop_self = action.setdefault("next_hop_self", None)
route_maps = action.setdefault("route_maps", {})
@ -977,10 +978,6 @@ def modify_bgp_config_when_bgpd_down(tgen, topo, input_dict):
router_list[router].run(cmd)
except Exception as e:
# handle any exception
logger.error("Error %s occured. Arguments %s.", e.message, e.args)
# Traceback
errormsg = traceback.format_exc()
logger.error(errormsg)
return errormsg
@ -1085,10 +1082,10 @@ def verify_bgp_convergence(tgen, topo, dut=None):
logger.debug("Entering lib API: verify_bgp_convergence()")
for router, rnode in tgen.routers().items():
if "bgp" not in topo["routers"][router]:
if dut is not None and dut != router:
continue
if dut is not None and dut != router:
if "bgp" not in topo["routers"][router]:
continue
logger.info("Verifying BGP Convergence on router %s:", router)
@ -1114,6 +1111,100 @@ def verify_bgp_convergence(tgen, topo, dut=None):
# To find neighbor ip type
bgp_addr_type = bgp_data["address_family"]
if "ipv4" in bgp_addr_type or "ipv6" in bgp_addr_type:
for addr_type in bgp_addr_type.keys():
if not check_address_types(addr_type):
continue
total_peer = 0
bgp_neighbors = bgp_addr_type[addr_type]["unicast"]["neighbor"]
for bgp_neighbor in bgp_neighbors:
total_peer += len(bgp_neighbors[bgp_neighbor]["dest_link"])
for addr_type in bgp_addr_type.keys():
if not check_address_types(addr_type):
continue
bgp_neighbors = bgp_addr_type[addr_type]["unicast"]["neighbor"]
no_of_peer = 0
for bgp_neighbor, peer_data in bgp_neighbors.items():
for dest_link in peer_data["dest_link"].keys():
data = topo["routers"][bgp_neighbor]["links"]
if dest_link in data:
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 "ipv4Unicast" in show_bgp_json[vrf]:
ipv4_data = show_bgp_json[vrf]["ipv4Unicast"][
"peers"
]
nh_state = ipv4_data[neighbor_ip]["state"]
else:
if "ipv6Unicast" in show_bgp_json[vrf]:
ipv6_data = show_bgp_json[vrf]["ipv6Unicast"][
"peers"
]
nh_state = ipv6_data[neighbor_ip]["state"]
if nh_state == "Established":
no_of_peer += 1
if "l2vpn" in bgp_addr_type:
if "neighbor" not in bgp_addr_type["l2vpn"]["evpn"]:
if no_of_peer == total_peer:
logger.info(
"[DUT: %s] VRF: %s, BGP is Converged for %s address-family",
router,
vrf,
addr_type,
)
else:
errormsg = (
"[DUT: %s] VRF: %s, BGP is not converged for %s address-family"
% (router, vrf, addr_type)
)
return errormsg
else:
if no_of_peer == total_peer:
logger.info(
"[DUT: %s] VRF: %s, BGP is Converged for %s address-family",
router,
vrf,
addr_type,
)
else:
errormsg = (
"[DUT: %s] VRF: %s, BGP is not converged for %s address-family"
% (router, vrf, addr_type)
)
return errormsg
if "l2vpn" in bgp_addr_type:
total_evpn_peer = 0
@ -1166,82 +1257,6 @@ def verify_bgp_convergence(tgen, topo, dut=None):
"for evpn peers" % (router, vrf)
)
return errormsg
else:
for addr_type in bgp_addr_type.keys():
if not check_address_types(addr_type):
continue
total_peer = 0
bgp_neighbors = bgp_addr_type[addr_type]["unicast"]["neighbor"]
for bgp_neighbor in bgp_neighbors:
total_peer += len(bgp_neighbors[bgp_neighbor]["dest_link"])
for addr_type in bgp_addr_type.keys():
if not check_address_types(addr_type):
continue
bgp_neighbors = bgp_addr_type[addr_type]["unicast"]["neighbor"]
no_of_peer = 0
for bgp_neighbor, peer_data in bgp_neighbors.items():
for dest_link in peer_data["dest_link"].keys():
data = topo["routers"][bgp_neighbor]["links"]
if dest_link in data:
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":
ipv4_data = show_bgp_json[vrf]["ipv4Unicast"][
"peers"
]
nh_state = ipv4_data[neighbor_ip]["state"]
else:
ipv6_data = show_bgp_json[vrf]["ipv6Unicast"][
"peers"
]
nh_state = ipv6_data[neighbor_ip]["state"]
if nh_state == "Established":
no_of_peer += 1
if no_of_peer == total_peer:
logger.info(
"[DUT: %s] VRF: %s, BGP is Converged for %s address-family",
router,
vrf,
addr_type,
)
else:
errormsg = (
"[DUT: %s] VRF: %s, BGP is not converged for %s address-family"
% (router, vrf, addr_type)
)
return errormsg
logger.debug("Exiting API: verify_bgp_convergence()")
return True
@ -1400,10 +1415,6 @@ def modify_as_number(tgen, topo, input_dict):
create_router_bgp(tgen, new_topo)
except Exception as e:
# handle any exception
logger.error("Error %s occured. Arguments %s.", e.message, e.args)
# Traceback
errormsg = traceback.format_exc()
logger.error(errormsg)
return errormsg
@ -2621,7 +2632,7 @@ def verify_bgp_rib(
found_routes.append(st_rt)
if next_hop and multi_nh and st_found:
if not isinstance(next_hop, list):
if type(next_hop) is not list:
next_hop = [next_hop]
list1 = next_hop
@ -2661,7 +2672,7 @@ def verify_bgp_rib(
nh_found = True
elif next_hop and multi_nh is None:
if not isinstance(next_hop, list):
if type(next_hop) is not list:
next_hop = [next_hop]
list1 = next_hop
found_hops = [
@ -4092,7 +4103,7 @@ def verify_attributes_for_evpn_routes(
errormsg = (
"[DUT: %s] RD: %s, Route : %s "
"is not present in cli json "
"output " % (dut, route)
"output " % (dut, _rd, route)
)
return errormsg
@ -4170,7 +4181,7 @@ def verify_evpn_routes(
return errormsg
for key, route_data_json in evpn_value_json.items():
if isinstance(route_data_json, dict):
if type(route_data_json) is dict:
rd_keys += 1
if prefix not in route_data_json:
missing_routes[key] = prefix
@ -4184,7 +4195,7 @@ def verify_evpn_routes(
return errormsg
for key, route_data_json in evpn_value_json.items():
if isinstance(route_data_json, dict):
if type(route_data_json) is dict:
if prefix not in route_data_json:
continue

View File

@ -1373,13 +1373,13 @@ def generate_ips(network, no_of_ips):
if start_ip == "0.0.0.0" and mask == 0 and no_of_ips == 1:
ipaddress_list.append("{}/{}".format(start_ip, mask))
return ipaddress_list
start_ip = ipaddress.IPv4Address(unicode(start_ip))
start_ip = ipaddress.IPv4Address(frr_unicode(start_ip))
step = 2 ** (32 - mask)
elif addr_type == "ipv6":
if start_ip == "0::0" and mask == 0 and no_of_ips == 1:
ipaddress_list.append("{}/{}".format(start_ip, mask))
return ipaddress_list
start_ip = ipaddress.IPv6Address(unicode(start_ip))
start_ip = ipaddress.IPv6Address(frr_unicode(start_ip))
step = 2 ** (128 - mask)
else:
return []
@ -1480,10 +1480,6 @@ def interface_status(tgen, topo, input_dict):
load_config_to_router(tgen, router)
except Exception as e:
# handle any exception
logger.error("Error %s occured. Arguments %s.", e.message, e.args)
# Traceback
errormsg = traceback.format_exc()
logger.error(errormsg)
return errormsg
@ -2442,51 +2438,6 @@ def shutdown_bringup_interface(tgen, dut, intf_name, ifaceaction=False):
interface_set_status(router_list[dut], intf_name, ifaceaction)
def stop_router(tgen, router):
"""
Router's current config would be saved to /tmp/topotest/<suite>/<router>
for each daemon and router and its daemons would be stopped.
* `tgen` : topogen object
* `router`: Device under test
"""
router_list = tgen.routers()
# Saving router config to /etc/frr, which will be loaded to router
# when it starts
router_list[router].vtysh_cmd("write memory")
# Stop router
router_list[router].stop()
def start_router(tgen, router):
"""
Router will be started and config would be loaded from
/tmp/topotest/<suite>/<router> for each daemon
* `tgen` : topogen object
* `router`: Device under test
"""
logger.debug("Entering lib API: start_router")
try:
router_list = tgen.routers()
# Router and its daemons would be started and config would
# be loaded to router for each daemon from /etc/frr
router_list[router].start()
except Exception as e:
errormsg = traceback.format_exc()
logger.error(errormsg)
return errormsg
logger.debug("Exiting lib API: start_router()")
def addKernelRoute(
tgen, router, intf, group_addr_range, next_hop=None, src=None, del_action=None
):
@ -3754,6 +3705,43 @@ def verify_bgp_community(tgen, addr_type, router, network, input_dict=None):
return True
def get_ipv6_linklocal_address(topo, node, intf):
"""
API to get the link local ipv6 address of a perticular interface
Parameters
----------
* `node`: node on which link local ip to be fetched.
* `intf` : interface for which link local ip needs to be returned.
* `topo` : base topo
Usage
-----
result = get_ipv6_linklocal_address(topo, 'r1', 'r2')
Returns link local ip of interface between r1 and r2.
Returns
-------
1) link local ipv6 address from the interface
2) errormsg - when link local ip not found
"""
tgen = get_topogen()
ext_nh = tgen.net[node].get_ipv6_linklocal()
req_nh = topo[node]['links'][intf]['interface']
llip = None
for llips in ext_nh:
if llips[0] == req_nh:
llip = llips[1]
logger.info("Link local ip found = %s", llip)
return llip
errormsg = "Failed: Link local ip not found on router {}, "\
"interface {}".format(node, intf)
return errormsg
def verify_create_community_list(tgen, input_dict):
"""
API is to verify if large community list is created for any given DUT in