Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance traffic shift test case to verify Internal loopback is not advertise to external neighbors. #3484

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
25 changes: 18 additions & 7 deletions ansible/library/minigraph_facts.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ def parse_png(png, hname):
return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port)


def parse_loopback_intf(child):
def parse_loopback_intf(child, intfName=None):
lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces")))
lo_intfs = []
for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))):
Expand All @@ -257,6 +257,8 @@ def parse_loopback_intf(child):
ipaddr = ipn.ip
prefix_len = ipn.prefixlen
ipmask = ipn.netmask
if intfName and intfname != intfName:
continue
lo_intf = {'name': intfname, 'addr': ipaddr, 'prefixlen': prefix_len}
if isinstance(ipn, ipaddress.IPv4Network):
lo_intf['mask'] = ipmask
Expand All @@ -266,12 +268,12 @@ def parse_loopback_intf(child):
return lo_intfs


def parse_host_loopback(dpg, hname):
def parse_asic_loopback(dpg, hname):
for child in dpg:
hostname = child.find(str(QName(ns, "Hostname")))
if hostname.text.lower() != hname.lower():
continue
lo_intfs = parse_loopback_intf(child)
lo_intfs = parse_loopback_intf(child, "Loopback4096")
return lo_intfs


Expand Down Expand Up @@ -323,7 +325,7 @@ def parse_dpg(dpg, hname):
intfs.append(intf)
ports[intfname] = {'name': intfname, 'alias': intfalias}

lo_intfs = parse_loopback_intf(child)
lo_intfs = parse_loopback_intf(child, "Loopback0")

mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces")))
mgmt_intf = None
Expand Down Expand Up @@ -605,10 +607,20 @@ def parse_xml(filename, hostname, asic_name=None):
# Create inverse mapping between port name and alias
port_name_to_alias_map = {v: k for k, v in port_alias_to_name_map.iteritems()}

asic_lo_intfs = []
for child in root:
if asic_name is None:
if child.tag == str(QName(ns, "DpgDec")):
(intfs, lo_intfs, mgmt_intf, vlans, pcs, acls, dhcp_servers) = parse_dpg(child, hostname)
try:
from sonic_py_common import multi_asic
namespace_list = multi_asic.get_namespace_list()
for namespace in namespace_list:
if not namespace:
continue
asic_lo_intfs += parse_asic_loopback(child, namespace)
except:
pass
elif child.tag == str(QName(ns, "CpgDec")):
(bgp_sessions, bgp_asn, bgp_peers_with_range) = parse_cpg(child, hostname)
elif child.tag == str(QName(ns, "PngDec")):
Expand All @@ -620,7 +632,7 @@ def parse_xml(filename, hostname, asic_name=None):
else:
if child.tag == str(QName(ns, "DpgDec")):
(intfs, lo_intfs, mgmt_intf, vlans, pcs, acls, dhcp_servers) = parse_dpg(child, asic_name)
host_lo_intfs = parse_host_loopback(child, hostname)
asic_lo_intfs = parse_asic_loopback(child, asic_name)
elif child.tag == str(QName(ns, "CpgDec")):
(bgp_sessions, bgp_asn, bgp_peers_with_range) = parse_cpg(child, asic_name)
elif child.tag == str(QName(ns, "PngDec")):
Expand Down Expand Up @@ -672,8 +684,6 @@ def parse_xml(filename, hostname, asic_name=None):
else:
phyport_intfs.append(intf)

if host_lo_intfs:
lo_intfs += host_lo_intfs

results['minigraph_interfaces'] = sorted(phyport_intfs, key=lambda x: x['attachto'])
results['minigraph_vlan_interfaces'] = sorted(vlan_intfs, key=lambda x: x['attachto'])
Expand All @@ -683,6 +693,7 @@ def parse_xml(filename, hostname, asic_name=None):
results['minigraph_portchannels'] = pcs
results['minigraph_mgmt_interface'] = mgmt_intf
results['minigraph_lo_interfaces'] = lo_intfs
results['minigraph_asic_lo_interfaces'] = asic_lo_intfs
results['minigraph_acls'] = acls
results['minigraph_neighbors'] = neighbors
results['minigraph_devices'] = devices
Expand Down
3 changes: 3 additions & 0 deletions tests/bgp/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ def _setup_interfaces_t1(mg_facts, peer_count):
namespace = '-n {}'.format(conn["namespace"]) if conn["namespace"] else ''
duthost.shell("config interface %s ip add %s %s" % (namespace, conn["local_intf"], conn["local_addr"]))
ptfhost.shell("ifconfig %s %s" % (conn["neighbor_intf"], conn["neighbor_addr"]))
# Ping to resolve ARP. Needed in multi-asic (as bgpmon is running backend)
# if arp is not there TCP connection do not happen.
ptfhost.shell("ping {} -c 3 -I {}".format(local_addr, conn["neighbor_intf"]))

yield connections

Expand Down
35 changes: 23 additions & 12 deletions tests/bgp/test_traffic_shift.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,22 +123,33 @@ def verify_all_routes_announce_to_neighs(dut_host, neigh_hosts, routes_dut, ip_v
def verify_loopback_route_with_community(dut_host, neigh_hosts, ip_ver, community):
logger.info("Verifying only loopback routes are announced to bgp neighbors")
mg_facts = dut_host.minigraph_facts(host=dut_host.hostname)['ansible_facts']
for i in range(0, 2):
addr = mg_facts['minigraph_lo_interfaces'][i]['addr']
if ipaddress.IPNetwork(addr).version == 4:
lo_addr_v4 = ipaddress.IPNetwork(addr)
else:
# The IPv6 Loopback announced to neighbors is /64
lo_addr_v6 = ipaddress.IPNetwork(addr + "/64")
if 4 == ip_ver:
lo_addr = lo_addr_v4
else:
lo_addr = lo_addr_v6
lo_addr = []
internal_lo_addr = []

def parse_loopback_addr(minigraph_lo_addr, internal_loopback):
loopback_addr = []
for i in range(len(minigraph_lo_addr)):
addr = minigraph_lo_addr[i]['addr']
if ip_ver != ipaddress.IPNetwork(addr).version:
continue
if 4 == ip_ver:
loopback_addr.append(ipaddress.IPNetwork(addr))
else:
loopback_addr.append(ipaddress.IPNetwork(addr + "/64" if not internal_loopback else "/128"))

return loopback_addr

lo_addr = parse_loopback_addr(mg_facts['minigraph_lo_interfaces'], False)
internal_lo_addr = parse_loopback_addr(mg_facts['minigraph_asic_lo_interfaces'], True)

routes_on_all_eos = parse_routes_on_eos(dut_host, neigh_hosts, ip_ver)
for hostname, routes in routes_on_all_eos.iteritems():
logger.info("Verifying only loopback routes(ipv{}) are announced to {}".format(ip_ver, hostname))
for prefix, received_community in routes.iteritems():
if ipaddress.IPNetwork(prefix) != lo_addr:
if ipaddress.IPNetwork(prefix) in internal_lo_addr:
logger.warn("route for {} is found on {}, which is internal loopback address".format(prefix, hostname))
return False
if ipaddress.IPNetwork(prefix) not in lo_addr:
logger.warn("route for {} is found on {}, which is not in loopback address".format(prefix, hostname))
return False
if received_community != community:
Expand Down