def clear_bsrp_data(tgen, topo): """ clear bsm databas after test" Parameters ---------- * `tgen`: topogen object Usage ----- result = clear_bsrp_data(tgen, topo) Returns ------- errormsg(str) or True """ for dut in tgen.routers(): rnode = tgen.routers()[dut] logger.info("[DUT: %s]: clear_bsrp_data") run_frr_cmd(rnode, "clear ip pim bsr-data") return True
def clear_ospf(tgen, router): """ This API is to clear ospf neighborship by running clear ip ospf interface * command, Parameters ---------- * `tgen`: topogen object * `router`: device under test Usage ----- clear_ospf(tgen, "r1") """ logger.debug("Entering lib API: clear_ospf()") if router not in tgen.routers(): return False rnode = tgen.routers()[router] # Clearing OSPF logger.info("Clearing ospf process for router %s..", router) run_frr_cmd(rnode, "clear ip ospf interface ") logger.debug("Exiting lib API: clear_ospf()")
def verify_ospf6_neighbor(tgen, topo): """ This API is to verify ospf neighborship by running show ip ospf neighbour command, Parameters ---------- * `tgen` : Topogen object * `topo` : json file data Usage ----- Check FULL neighbors. verify_ospf_neighbor(tgen, topo) result = verify_ospf_neighbor(tgen, topo) Returns ------- True or False (Error Message) """ logger.debug("Entering lib API: verify_ospf6_neighbor()") result = False for router, rnode in tgen.routers().items(): if "ospf6" not in topo["routers"][router]: continue logger.info("Verifying OSPF6 neighborship on router %s:", router) show_ospf_json = run_frr_cmd(rnode, "show ipv6 ospf6 neighbor json", isjson=True) if not show_ospf_json: return "OSPF6 is not running" ospf_nbr_list = topo["routers"][router]["ospf6"]["neighbors"] no_of_peer = 0 for ospf_nbr in ospf_nbr_list: ospf_nbr_rid = topo["routers"][ospf_nbr]["ospf6"]["router_id"] for neighbor in show_ospf_json["neighbors"]: if neighbor["neighborId"] == ospf_nbr_rid: nh_state = neighbor["state"] break else: return "[DUT: {}] OSPF6 peer {} missing".format( router, data_rid) if nh_state == "Full": no_of_peer += 1 if no_of_peer == len(ospf_nbr_list): logger.info("[DUT: {}] OSPF6 is Converged".format(router)) result = True else: return "[DUT: {}] OSPF6 is not Converged".format(router) logger.debug("Exiting API: verify_ospf6_neighbor()") return result
def verify_ospf_database(tgen, dut, input_dict, cmd="show ip ospf database json"): del tgen show_ospf_json = run_frr_cmd(dut, cmd, isjson=True) if not bool(show_ospf_json): return "ospf is not running" result = json_cmp(show_ospf_json, input_dict) return str(result) if result else None
def verify_ospf_interface(tgen, topo, dut=None, lan=False, input_dict=None): """ This API is to verify ospf routes by running show ip ospf interface command. Parameters ---------- * `tgen` : Topogen object * `topo` : topology descriptions * `dut`: device under test * `lan`: if set to true this interface belongs to LAN. * `input_dict` : Input dict data, required when configuring from testcase Usage ----- input_dict= { 'r0': { 'links':{ 's1': { 'ospf':{ 'priority':98, 'timerDeadSecs': 4, 'area': '0.0.0.3', 'mcastMemberOspfDesignatedRouters': True, 'mcastMemberOspfAllRouters': True, 'ospfEnabled': True, } } } } } result = verify_ospf_interface(tgen, topo, dut=dut, input_dict=input_dict) Returns ------- True or False (Error Message) """ logger.debug("Entering lib API: verify_ospf_interface()") result = False for router, rnode in tgen.routers().items(): if "ospf" not in topo["routers"][router]: continue if dut is not None and dut != router: continue logger.info("Verifying OSPF interface on router %s:", router) show_ospf_json = run_frr_cmd(rnode, "show ip ospf interface json", isjson=True) # Verifying output dictionary show_ospf_json is empty or not if not bool(show_ospf_json): errormsg = "OSPF is not running" return errormsg # To find neighbor ip type ospf_intf_data = input_dict[router]["links"] for ospf_intf, intf_data in ospf_intf_data.items(): intf = topo["routers"][router]["links"][ospf_intf]["interface"] if intf in show_ospf_json["interfaces"]: for intf_attribute in intf_data["ospf"]: if (intf_data["ospf"][intf_attribute] == show_ospf_json[ "interfaces"][intf][intf_attribute]): logger.info( "[DUT: %s] OSPF interface %s: %s is %s", router, intf, intf_attribute, intf_data["ospf"][intf_attribute], ) else: errormsg = "[DUT: {}] OSPF interface {}: {} is {}, \ Expected is {}".format( router, intf, intf_attribute, intf_data["ospf"][intf_attribute], show_ospf_json["interfaces"][intf][intf_attribute], ) return errormsg result = True logger.debug("Exiting API: verify_ospf_interface()") return result
def verify_ospf_rib(tgen, dut, input_dict, next_hop=None, tag=None, metric=None, fib=None): """ This API is to verify ospf routes by running show ip ospf route command. Parameters ---------- * `tgen` : Topogen object * `dut`: device under test * `input_dict` : Input dict data, required when configuring from testcase * `next_hop` : next to be verified * `tag` : tag to be verified * `metric` : metric to be verified * `fib` : True if the route is installed in FIB. Usage ----- input_dict = { "r1": { "static_routes": [ { "network": ip_net, "no_of_ip": 1, "routeType": "N" } ] } } result = verify_ospf_rib(tgen, dut, input_dict,next_hop=nh) Returns ------- True or False (Error Message) """ logger.info("Entering lib API: verify_ospf_rib()") result = False router_list = tgen.routers() additional_nexthops_in_required_nhs = [] found_hops = [] for routerInput in input_dict.keys(): for router, rnode in router_list.items(): if router != dut: continue logger.info("Checking router %s RIB:", router) # Verifying RIB routes command = "show ip ospf route" found_routes = [] missing_routes = [] if ("static_routes" in input_dict[routerInput] or "prefix" in input_dict[routerInput]): if "prefix" in input_dict[routerInput]: static_routes = input_dict[routerInput]["prefix"] else: static_routes = input_dict[routerInput]["static_routes"] for static_route in static_routes: cmd = "{}".format(command) cmd = "{} json".format(cmd) ospf_rib_json = run_frr_cmd(rnode, cmd, isjson=True) # Verifying output dictionary ospf_rib_json is not empty if bool(ospf_rib_json) is False: errormsg = ("[DUT: {}] No routes found in OSPF route " "table".format(router)) return errormsg network = static_route["network"] no_of_ip = static_route.setdefault("no_of_ip", 1) _tag = static_route.setdefault("tag", None) _rtype = static_route.setdefault("routeType", None) # 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(ipaddr.IPNetwork(frr_unicode(st_rt))) _addr_type = validate_ip_address(st_rt) if _addr_type != "ipv4": continue if st_rt in ospf_rib_json: st_found = True found_routes.append(st_rt) if fib and next_hop: if type(next_hop) is not list: next_hop = [next_hop] for mnh in range(0, len(ospf_rib_json[st_rt])): if ("fib" in ospf_rib_json[st_rt][mnh] ["nexthops"][0]): found_hops.append([ rib_r["ip"] for rib_r in ospf_rib_json[st_rt] [mnh]["nexthops"] ]) if found_hops[0]: missing_list_of_nexthops = set( found_hops[0]).difference(next_hop) additional_nexthops_in_required_nhs = set( next_hop).difference(found_hops[0]) if additional_nexthops_in_required_nhs: logger.info( "Nexthop " "%s is not active for route %s in " "RIB of router %s\n", additional_nexthops_in_required_nhs, st_rt, dut, ) errormsg = ( "Nexthop {} is not active" " for route {} in RIB of router" " {}\n".format( additional_nexthops_in_required_nhs, st_rt, dut, )) return errormsg else: nh_found = True elif next_hop and fib is None: if type(next_hop) is not list: next_hop = [next_hop] found_hops = [ rib_r["ip"] for rib_r in ospf_rib_json[st_rt]["nexthops"] ] if found_hops: missing_list_of_nexthops = set( found_hops).difference(next_hop) additional_nexthops_in_required_nhs = set( next_hop).difference(found_hops) if additional_nexthops_in_required_nhs: logger.info( "Missing nexthop %s for route" " %s in RIB of router %s\n", additional_nexthops_in_required_nhs, st_rt, dut, ) errormsg = ( "Nexthop {} is Missing for " "route {} in RIB of router {}\n". format( additional_nexthops_in_required_nhs, st_rt, dut, )) return errormsg else: nh_found = True if _rtype: if "routeType" not in ospf_rib_json[st_rt]: errormsg = ( "[DUT: {}]: routeType missing" " for route {} in OSPF RIB \n".format( dut, st_rt)) return errormsg elif _rtype != ospf_rib_json[st_rt][ "routeType"]: errormsg = ( "[DUT: {}]: routeType mismatch" " for route {} in OSPF RIB \n".format( dut, st_rt)) return errormsg else: logger.info("[DUT: {}]: Found routeType {}" " for route {}".format( dut, _rtype, st_rt)) if tag: if "tag" not in ospf_rib_json[st_rt]: errormsg = ("[DUT: {}]: tag is not" " present for" " route {} in RIB \n".format( dut, st_rt)) return errormsg if _tag != ospf_rib_json[st_rt]["tag"]: errormsg = ("[DUT: {}]: tag value {}" " is not matched for" " route {} in RIB \n".format( dut, _tag, st_rt, )) return errormsg if metric is not None: if "type2cost" not in ospf_rib_json[st_rt]: errormsg = ("[DUT: {}]: metric is" " not present for" " route {} in RIB \n".format( dut, st_rt)) return errormsg if metric != ospf_rib_json[st_rt]["type2cost"]: errormsg = ("[DUT: {}]: metric value " "{} is not matched for " "route {} in RIB \n".format( dut, metric, st_rt, )) return errormsg else: missing_routes.append(st_rt) if nh_found: logger.info("[DUT: {}]: Found next_hop {} for all OSPF" " routes in RIB".format(router, next_hop)) if len(missing_routes) > 0: errormsg = "[DUT: {}]: Missing route in RIB, " "routes: {}".format( dut, missing_routes) return errormsg if found_routes: logger.info( "[DUT: %s]: Verified routes in RIB, found" " routes are: %s\n", dut, found_routes, ) result = True logger.info("Exiting lib API: verify_ospf_rib()") return result
def verify_ospf_neighbor(tgen, topo, dut=None, input_dict=None, lan=False): """ This API is to verify ospf neighborship by running show ip ospf neighbour command, Parameters ---------- * `tgen` : Topogen object * `topo` : json file data * `dut`: device under test * `input_dict` : Input dict data, required when configuring from testcase * `lan` : verify neighbors in lan topology Usage ----- 1. To check FULL neighbors. verify_ospf_neighbor(tgen, topo, dut=dut) 2. To check neighbors with their roles. input_dict = { "r0": { "ospf": { "neighbors": { "r1": { "state": "Full", "role": "DR" }, "r2": { "state": "Full", "role": "DROther" }, "r3": { "state": "Full", "role": "DROther" } } } } } result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True) Returns ------- True or False (Error Message) """ logger.debug("Entering lib API: verify_ospf_neighbor()") result = False if input_dict: for router, rnode in tgen.routers().items(): if "ospf" not in topo["routers"][router]: continue if dut is not None and dut != router: continue logger.info("Verifying OSPF neighborship on router %s:", router) show_ospf_json = run_frr_cmd(rnode, "show ip ospf neighbor all json", isjson=True) # Verifying output dictionary show_ospf_json is empty or not if not bool(show_ospf_json): errormsg = "OSPF is not running" return errormsg ospf_data_list = input_dict[router]["ospf"] ospf_nbr_list = ospf_data_list["neighbors"] for ospf_nbr, nbr_data in ospf_nbr_list.items(): data_ip = topo["routers"][ospf_nbr]["links"] data_rid = topo["routers"][ospf_nbr]["ospf"]["router_id"] if ospf_nbr in data_ip: nbr_details = nbr_data[ospf_nbr] elif lan: for switch in topo["switches"]: if "ospf" in topo["switches"][switch]["links"][router]: neighbor_ip = data_ip[switch]["ipv4"].split("/")[0] else: continue else: neighbor_ip = data_ip[router]["ipv4"].split("/")[0] nh_state = None neighbor_ip = neighbor_ip.lower() nbr_rid = data_rid try: nh_state = show_ospf_json[nbr_rid][0]["state"].split( "/")[0] intf_state = show_ospf_json[nbr_rid][0]["state"].split( "/")[1] except KeyError: errormsg = "[DUT: {}] OSPF peer {} missing".format( router, nbr_rid) return errormsg nbr_state = nbr_data.setdefault("state", None) nbr_role = nbr_data.setdefault("role", None) if nbr_state: if nbr_state == nh_state: logger.info( "[DUT: {}] OSPF Nbr is {}:{} State {}".format( router, ospf_nbr, nbr_rid, nh_state)) result = True else: errormsg = ("[DUT: {}] OSPF is not Converged, neighbor" " state is {}".format(router, nh_state)) return errormsg if nbr_role: if nbr_role == intf_state: logger.info( "[DUT: {}] OSPF Nbr is {}: {} Role {}".format( router, ospf_nbr, nbr_rid, nbr_role)) else: errormsg = ("[DUT: {}] OSPF is not Converged with rid" "{}, role is {}".format( router, nbr_rid, intf_state)) return errormsg continue else: for router, rnode in tgen.routers().items(): if "ospf" not in topo["routers"][router]: continue if dut is not None and dut != router: continue logger.info("Verifying OSPF neighborship on router %s:", router) show_ospf_json = run_frr_cmd(rnode, "show ip ospf neighbor all json", isjson=True) # Verifying output dictionary show_ospf_json is empty or not if not bool(show_ospf_json): errormsg = "OSPF is not running" return errormsg ospf_data_list = topo["routers"][router]["ospf"] ospf_neighbors = ospf_data_list["neighbors"] total_peer = 0 total_peer = len(ospf_neighbors.keys()) no_of_ospf_nbr = 0 ospf_nbr_list = ospf_data_list["neighbors"] no_of_peer = 0 for ospf_nbr, nbr_data in ospf_nbr_list.items(): if nbr_data: data_ip = topo["routers"][nbr_data["nbr"]]["links"] data_rid = topo["routers"][ nbr_data["nbr"]]["ospf"]["router_id"] else: data_ip = topo["routers"][ospf_nbr]["links"] data_rid = topo["routers"][ospf_nbr]["ospf"]["router_id"] if ospf_nbr in data_ip: nbr_details = nbr_data[ospf_nbr] elif lan: for switch in topo["switches"]: if "ospf" in topo["switches"][switch]["links"][router]: neighbor_ip = data_ip[switch]["ipv4"].split("/")[0] else: continue else: neighbor_ip = data_ip[router]["ipv4"].split("/")[0] nh_state = None neighbor_ip = neighbor_ip.lower() nbr_rid = data_rid try: nh_state = show_ospf_json[nbr_rid][0]["state"].split( "/")[0] except KeyError: errormsg = "[DUT: {}] OSPF peer {} missing,from " "{} ".format( router, nbr_rid, ospf_nbr) return errormsg if nh_state == "Full": no_of_peer += 1 if no_of_peer == total_peer: logger.info("[DUT: {}] OSPF is Converged".format(router)) result = True else: errormsg = "[DUT: {}] OSPF is not Converged".format(router) return errormsg logger.debug("Exiting API: verify_ospf_neighbor()") return result
def verify_ospf_summary(tgen, topo, dut, input_dict): """ This API is to verify ospf routes by running show ip ospf interface command. Parameters ---------- * `tgen` : Topogen object * `topo` : topology descriptions * `dut`: device under test * `input_dict` : Input dict data, required when configuring from testcase Usage ----- input_dict = { "11.0.0.0/8": { "Summary address": "11.0.0.0/8", "Metric-type": "E2", "Metric": 20, "Tag": 0, "External route count": 5 } } result = verify_ospf_summary(tgen, topo, dut, input_dict) Returns ------- True or False (Error Message) """ logger.debug("Entering lib API: verify_ospf_summary()") result = False router = dut logger.info("Verifying OSPF summary on router %s:", router) if "ospf" not in topo["routers"][dut]: errormsg = "[DUT: {}] OSPF is not configured on the router.".format( router) return errormsg rnode = tgen.routers()[dut] show_ospf_json = run_frr_cmd(rnode, "show ip ospf summary detail json", isjson=True) # Verifying output dictionary show_ospf_json is empty or not if not bool(show_ospf_json): errormsg = "OSPF is not running" return errormsg # To find neighbor ip type ospf_summary_data = input_dict for ospf_summ, summ_data in ospf_summary_data.items(): if ospf_summ not in show_ospf_json: continue summary = ospf_summary_data[ospf_summ]["Summary address"] if summary in show_ospf_json: for summ in summ_data: if summ_data[summ] == show_ospf_json[summary][summ]: logger.info( "[DUT: %s] OSPF summary %s:%s is %s", router, summary, summ, summ_data[summ], ) result = True else: errormsg = ("[DUT: {}] OSPF summary {}:{} is %s, " "Expected is {}".format( router, summary, summ, show_ospf_json[summary][summ])) return errormsg logger.debug("Exiting API: verify_ospf_summary()") return result
def verify_ospf_database(tgen, topo, dut, input_dict): """ This API is to verify ospf lsa's by running show ip ospf database command. Parameters ---------- * `tgen` : Topogen object * `dut`: device under test * `input_dict` : Input dict data, required when configuring from testcase * `topo` : next to be verified Usage ----- input_dict = { "areas": { "0.0.0.0": { "Router Link States": { "100.1.1.0-100.1.1.0": { "LSID": "100.1.1.0", "Advertised router": "100.1.1.0", "LSA Age": 130, "Sequence Number": "80000006", "Checksum": "a703", "Router links": 3 } }, "Net Link States": { "10.0.0.2-100.1.1.1": { "LSID": "10.0.0.2", "Advertised router": "100.1.1.1", "LSA Age": 137, "Sequence Number": "80000001", "Checksum": "9583" } }, }, } } result = verify_ospf_database(tgen, topo, dut, input_dict) Returns ------- True or False (Error Message) """ result = False router = dut logger.debug("Entering lib API: verify_ospf_database()") if "ospf" not in topo["routers"][dut]: errormsg = "[DUT: {}] OSPF is not configured on the router.".format( dut) return errormsg rnode = tgen.routers()[dut] logger.info("Verifying OSPF interface on router %s:", dut) show_ospf_json = run_frr_cmd(rnode, "show ip ospf database json", isjson=True) # Verifying output dictionary show_ospf_json is empty or not if not bool(show_ospf_json): errormsg = "OSPF is not running" return errormsg # for inter and inter lsa's ospf_db_data = input_dict.setdefault("areas", None) ospf_external_lsa = input_dict.setdefault("AS External Link States", None) if ospf_db_data: for ospf_area, area_lsa in ospf_db_data.items(): if ospf_area in show_ospf_json["areas"]: if "Router Link States" in area_lsa: for lsa in area_lsa["Router Link States"]: if (lsa in show_ospf_json["areas"][ospf_area] ["Router Link States"]): logger.info( "[DUT: %s] OSPF LSDB area %s:Router " "LSA %s", router, ospf_area, lsa, ) result = True else: errormsg = ( "[DUT: {}] OSPF LSDB area {}: expected" " Router LSA is {}".format( router, ospf_area, lsa)) return errormsg if "Net Link States" in area_lsa: for lsa in area_lsa["Net Link States"]: if lsa in show_ospf_json["areas"][ospf_area][ "Net Link States"]: logger.info( "[DUT: %s] OSPF LSDB area %s:Network " "LSA %s", router, ospf_area, lsa, ) result = True else: errormsg = ( "[DUT: {}] OSPF LSDB area {}: expected" " Network LSA is {}".format( router, ospf_area, lsa)) return errormsg if "Summary Link States" in area_lsa: for lsa in area_lsa["Summary Link States"]: if (lsa in show_ospf_json["areas"][ospf_area] ["Summary Link States"]): logger.info( "[DUT: %s] OSPF LSDB area %s:Summary " "LSA %s", router, ospf_area, lsa, ) result = True else: errormsg = ( "[DUT: {}] OSPF LSDB area {}: expected" " Summary LSA is {}".format( router, ospf_area, lsa)) return errormsg if "ASBR-Summary Link States" in area_lsa: for lsa in area_lsa["ASBR-Summary Link States"]: if (lsa in show_ospf_json["areas"][ospf_area] ["ASBR-Summary Link States"]): logger.info( "[DUT: %s] OSPF LSDB area %s:ASBR Summary " "LSA %s", router, ospf_area, lsa, ) result = True else: errormsg = ( "[DUT: {}] OSPF LSDB area {}: expected" " ASBR Summary LSA is {}".format( router, ospf_area, lsa)) return errormsg if ospf_external_lsa: for ospf_ext_lsa, ext_lsa_data in ospf_external_lsa.items(): if ospf_ext_lsa in show_ospf_json["AS External Link States"]: logger.info("[DUT: %s] OSPF LSDB:External LSA %s", router, ospf_ext_lsa) result = True else: errormsg = ("[DUT: {}] OSPF LSDB : expected" " External LSA is {}".format(router, ospf_ext_lsa)) return errormsg logger.debug("Exiting API: verify_ospf_database()") return result
def verify_stale_routes_list(tgen, addr_type, dut, input_dict): """ This API is use verify Stale routes on refering the network with next hop value Parameters ---------- * `tgen`: topogen object * `dut`: input dut router name * `addr_type` : ip type ipv4/ipv6 * `input_dict` : input dict, has details of static routes Usage ----- dut = 'r1' input_dict = { "r3": { "static_routes": [ { "network": [NETWORK1_1[addr_type]], "no_of_ip": 2, "vrf": "RED" } ] } } result = verify_stale_routes_list(tgen, addr_type, dut, input_dict) Returns ------- errormsg(str) or True """ logger.debug("Entering lib API: verify_stale_routes_list()") router_list = tgen.routers() additional_nexthops_in_required_nhs = [] list1 = [] list2 = [] found_hops = [] for routerInput in input_dict.keys(): for router, rnode in router_list.items(): if router != dut: continue # Verifying RIB routes command = "show bgp" # Static routes sleep(2) logger.info('Checking router {} BGP RIB:'.format(dut)) if 'static_routes' in input_dict[routerInput]: static_routes = input_dict[routerInput]["static_routes"] for static_route in static_routes: found_routes = [] missing_routes = [] st_found = False nh_found = False vrf = static_route.setdefault("vrf", None) community = static_route.setdefault("community", None) largeCommunity = \ static_route.setdefault("largeCommunity", None) if vrf: cmd = "{} vrf {} {}".\ format(command, vrf, addr_type) if community: cmd = "{} community {}".\ format(cmd, community) if largeCommunity: cmd = "{} large-community {}".\ format(cmd, largeCommunity) else: cmd = "{} {}".\ format(command, addr_type) 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) == False: errormsg = "[DUT: {}]: No route found in rib of router". \ format(router) return errormsg elif "warning" in rib_routes_json: errormsg = "[DUT: {}]: {}". \ format(router, rib_routes_json["warning"]) 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) for st_rt in ip_list: st_rt = str(ipaddress.ip_network(st_rt)) _addr_type = validate_ip_address(st_rt) if _addr_type != addr_type: continue if st_rt in rib_routes_json["routes"]: st_found = True found_routes.append(st_rt) for mnh in range(0, len(rib_routes_json[ 'routes'][st_rt])): found_hops.append([rib_r[ "ip"] for rib_r in rib_routes_json[ 'routes'][st_rt][ mnh]["nexthops"]]) return found_hops else: return 'error msg - no hops found'