Skip to content

Commit

Permalink
[chassis] [MA] Route flap fix (#10206)
Browse files Browse the repository at this point in the history
  • Loading branch information
wenyiz2021 authored and mssonicbld committed Nov 4, 2023
1 parent f0e6935 commit 50c9e70
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 11 deletions.
22 changes: 22 additions & 0 deletions tests/common/devices/multi_asic.py
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,28 @@ def get_voq_inband_interfaces(self):
)
return voq_inband_interfaces.keys()

def get_portchannel_member(self):
"""
This Function is applicable on packet Chassis, or
any dut that has PORTCHANNEL_MEMBER in config dbs.
Get PORTCHANNEL_MEMBER from config db of all asics.
Returns:
List of [portchannel]. e.g. ["PortChannel101|Ethernet104", "PortChannel01|EthernetBPxx", ...]
{} if VOQ chassis or other dut that doesn't have PORTCHANNEL_MEMBER
"""
if not self.sonichost.is_multi_asic:
return {}
pcs = {}
for asic in self.frontend_asics:
config_facts = self.config_facts(
host=self.hostname, source="running",
namespace=asic.namespace
)['ansible_facts']
pcs.update(
config_facts.get("PORTCHANNEL_MEMBER", {})
)
return pcs.keys()

def run_redis_cmd(self, argv=[], asic_index=DEFAULT_ASIC_ID):
"""
Wrapper function to call run_redis_cmd on sonic_asic.py
Expand Down
46 changes: 35 additions & 11 deletions tests/route/test_route_flap.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,35 @@ def is_dualtor(tbinfo):
return "dualtor" in tbinfo["topo"]["name"]


def get_dev_port_and_route(duthost, asichost, dst_prefix_set):
# Get internal bgp ips for later filtering
internal_bgp_ips = duthost.get_internal_bgp_peers().keys()
# Get voq inband interface for later filtering
def get_internal_interfaces(duthost):
"""
This function returns internal interfaces for any
multi-asic dut, including voq/packet chassis
"""
internal_intfs = []

# First check for packet chassis, or any dut that has PORTCHANNEL_MEMBER in config db
pcs = duthost.get_portchannel_member()
for pc in pcs:
"""
For packet chassis, 'pcs' looks like:
["PortChannel101|Ethernet104", "PortChannel01|Ethernet-BPxx",...]
"""
if 'IB' in pc or 'BP' in pc:
internal_intfs.append(pc)

# Then check for voq chassis: get voq inband interface for later filtering
voq_inband_interfaces = duthost.get_voq_inband_interfaces()
internal_intfs.append([voq_inband_interfaces])

return internal_intfs


def get_dev_port_and_route(duthost, asichost, dst_prefix_set):
dev_port = None
route_to_ping = None
# Get internal interfaces for later filtering
internal_intfs = get_internal_interfaces(duthost)
for dst_prefix in dst_prefix_set:
if dev_port:
break
Expand All @@ -219,20 +241,22 @@ def get_dev_port_and_route(duthost, asichost, dst_prefix_set):
continue
if 'ip' not in per_hop.keys():
continue
if per_hop['ip'] in internal_bgp_ips:
continue
if per_hop['interfaceName'] in voq_inband_interfaces:
continue
if 'IB' in per_hop['interfaceName'] or 'BP' in per_hop['interfaceName']:
if per_hop['interfaceName'] in internal_intfs:
continue
dev_port = per_hop['interfaceName']
port = per_hop['interfaceName']
neigh = duthost.shell("show ip int | grep -w {}".format(port))['stdout']
if neigh == '':
logger.info("{} is still internal interface, skipping".format(port))
else:
dev_port = port
break
else:
dev = json.loads(asichost.run_vtysh(cmd)['stdout'])
for per_hop in dev[route_to_ping][0]['nexthops']:
if 'interfaceName' not in per_hop.keys():
continue
if per_hop['interfaceName'] in voq_inband_interfaces:
# For chassis, even single-asic linecard could have internal interface
if per_hop['interfaceName'] in internal_intfs:
continue
if 'IB' in per_hop['interfaceName'] or 'BP' in per_hop['interfaceName']:
continue
Expand Down

0 comments on commit 50c9e70

Please sign in to comment.