[minigraph] Adjust minigraph parsing per Fine Grained ECMP matchmode changes (#6885)

To adjust config db generated via minigraph per matchmode changes in fine grained ecmp. The changes are done so that nexthop IP based filtering can occur to determine routes as requiring Fine Grained ECMP, in the past the only mode was to use the IP prefix of the route for filtering, with this matchmode change we will use nexthop IP based filtering
Azure/SONiC#727

How I did it
Change will modify config db entry created for FG_NHG to include 'match_mode': 'nexthop-based' so that nexthop IP based filtering can occur to determine routes as requiring Fine Grained ECMP. Changes also remove FG_NHG_PREFIX entry since its not needed under matchmode nexthop-based.
This commit is contained in:
anish-n 2021-03-05 10:17:56 -08:00 committed by Guohan Lu
parent 7ec9fbb678
commit e60603cd96
2 changed files with 14 additions and 32 deletions

View File

@ -146,7 +146,6 @@ def formulate_fine_grained_ecmp(version, dpg_ecmp_content, port_device_map, port
tag = "fgnhg_v6" tag = "fgnhg_v6"
port_nhip_map = dpg_ecmp_content['port_nhip_map'] port_nhip_map = dpg_ecmp_content['port_nhip_map']
nhgaddr = dpg_ecmp_content['nhgaddr']
nhg_int = dpg_ecmp_content['nhg_int'] nhg_int = dpg_ecmp_content['nhg_int']
nhip_device_map = {port_nhip_map[x]: port_device_map[x] for x in port_device_map nhip_device_map = {port_nhip_map[x]: port_device_map[x] for x in port_device_map
@ -159,20 +158,17 @@ def formulate_fine_grained_ecmp(version, dpg_ecmp_content, port_device_map, port
FG_NHG_MEMBER = {ip: {"FG_NHG": tag, "bank": bank} for ip, bank in nhip_bank_map.items()} FG_NHG_MEMBER = {ip: {"FG_NHG": tag, "bank": bank} for ip, bank in nhip_bank_map.items()}
nhip_port_map = dict(zip(port_nhip_map.values(), port_nhip_map.keys())) nhip_port_map = dict(zip(port_nhip_map.values(), port_nhip_map.keys()))
for nhip, memberinfo in FG_NHG_MEMBER.items(): for nhip, memberinfo in FG_NHG_MEMBER.items():
if nhip in nhip_port_map: if nhip in nhip_port_map:
memberinfo["link"] = port_alias_map[nhip_port_map[nhip]] memberinfo["link"] = port_alias_map[nhip_port_map[nhip]]
FG_NHG_MEMBER[nhip] = memberinfo FG_NHG_MEMBER[nhip] = memberinfo
FG_NHG_PREFIX = {nhgaddr: {"FG_NHG": tag}} FG_NHG = {tag: {"bucket_size": LCM, "match_mode": "nexthop-based"}}
FG_NHG = {tag: {"bucket_size": LCM}}
for ip in nhip_bank_map: for ip in nhip_bank_map:
neigh_key.append(str(nhg_int + "|" + ip)) neigh_key.append(str(nhg_int + "|" + ip))
NEIGH = {neigh_key: {"family": family} for neigh_key in neigh_key} NEIGH = {neigh_key: {"family": family} for neigh_key in neigh_key}
fine_grained_content = {"FG_NHG_MEMBER": FG_NHG_MEMBER, "FG_NHG": FG_NHG, "FG_NHG_PREFIX": FG_NHG_PREFIX, "NEIGH": NEIGH} fine_grained_content = {"FG_NHG_MEMBER": FG_NHG_MEMBER, "FG_NHG": FG_NHG, "NEIGH": NEIGH}
return fine_grained_content return fine_grained_content
def parse_png(png, hname, dpg_ecmp_content = None): def parse_png(png, hname, dpg_ecmp_content = None):
@ -189,7 +185,6 @@ def parse_png(png, hname, dpg_ecmp_content = None):
port_device_map = {} port_device_map = {}
png_ecmp_content = {} png_ecmp_content = {}
FG_NHG_MEMBER = {} FG_NHG_MEMBER = {}
FG_NHG_PREFIX = {}
FG_NHG = {} FG_NHG = {}
NEIGH = {} NEIGH = {}
@ -292,12 +287,10 @@ def parse_png(png, hname, dpg_ecmp_content = None):
for version, content in dpg_ecmp_content.items(): # version is ipv4 or ipv6 for version, content in dpg_ecmp_content.items(): # version is ipv4 or ipv6
fine_grained_content = formulate_fine_grained_ecmp(version, content, port_device_map, port_alias_map) # port_alias_map fine_grained_content = formulate_fine_grained_ecmp(version, content, port_device_map, port_alias_map) # port_alias_map
FG_NHG_MEMBER.update(fine_grained_content['FG_NHG_MEMBER']) FG_NHG_MEMBER.update(fine_grained_content['FG_NHG_MEMBER'])
FG_NHG_PREFIX.update(fine_grained_content['FG_NHG_PREFIX'])
FG_NHG.update(fine_grained_content['FG_NHG']) FG_NHG.update(fine_grained_content['FG_NHG'])
NEIGH.update(fine_grained_content['NEIGH']) NEIGH.update(fine_grained_content['NEIGH'])
png_ecmp_content = {"FG_NHG_PREFIX": FG_NHG_PREFIX, "FG_NHG_MEMBER": FG_NHG_MEMBER, "FG_NHG": FG_NHG, png_ecmp_content = {"FG_NHG_MEMBER": FG_NHG_MEMBER, "FG_NHG": FG_NHG, "NEIGH": NEIGH}
"NEIGH": NEIGH}
return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports, mux_cable_ports, is_storage_device, png_ecmp_content) return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports, mux_cable_ports, is_storage_device, png_ecmp_content)
@ -483,7 +476,6 @@ def parse_dpg(dpg, hname):
pcs[pcintfname] = {'members': pcmbr_list, 'min_links': str(int(math.ceil(len(pcmbr_list) * 0.75)))} pcs[pcintfname] = {'members': pcmbr_list, 'min_links': str(int(math.ceil(len(pcmbr_list) * 0.75)))}
port_nhipv4_map = {} port_nhipv4_map = {}
port_nhipv6_map = {} port_nhipv6_map = {}
nhgaddr = ["", ""]
nhg_int = "" nhg_int = ""
nhportlist = [] nhportlist = []
dpg_ecmp_content = {} dpg_ecmp_content = {}
@ -507,20 +499,12 @@ def parse_dpg(dpg, hname):
n = list(ipaddress.ip_network(UNICODE_TYPE(subnet_range), False).hosts()) n = list(ipaddress.ip_network(UNICODE_TYPE(subnet_range), False).hosts())
if a in n: if a in n:
nhg_int = ip_intfs_map[subnet_range] nhg_int = ip_intfs_map[subnet_range]
dwnstrms = child.find(str(QName(ns, "DownstreamSummarySet")))
for dwnstrm in dwnstrms.findall(str(QName(ns, "DownstreamSummary"))): ipv4_content = {"port_nhip_map": port_nhipv4_map, "nhg_int": nhg_int}
dwnstrmentry = str(ET.tostring(dwnstrm)) ipv6_content = {"port_nhip_map": port_nhipv6_map, "nhg_int": nhg_int}
if ("FineGrainedECMPGroupDestination" in dwnstrmentry):
subnet_ip = dwnstrm.find(str(QName(ns1, "Subnet"))).text
truncsubnet_ip = subnet_ip.split("/")[0]
if "." in (truncsubnet_ip):
nhgaddr[0] = subnet_ip
elif ":" in (truncsubnet_ip):
nhgaddr[1] = subnet_ip
ipv4_content = {"port_nhip_map": port_nhipv4_map, "nhgaddr": nhgaddr[0], "nhg_int": nhg_int}
ipv6_content = {"port_nhip_map": port_nhipv6_map, "nhgaddr": nhgaddr[1], "nhg_int": nhg_int}
dpg_ecmp_content['ipv4'] = ipv4_content dpg_ecmp_content['ipv4'] = ipv4_content
dpg_ecmp_content['ipv6'] = ipv6_content dpg_ecmp_content['ipv6'] = ipv6_content
vlanintfs = child.find(str(QName(ns, "VlanInterfaces"))) vlanintfs = child.find(str(QName(ns, "VlanInterfaces")))
vlans = {} vlans = {}
vlan_members = {} vlan_members = {}
@ -1490,7 +1474,6 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
if len(png_ecmp_content): if len(png_ecmp_content):
results['FG_NHG_MEMBER'] = png_ecmp_content['FG_NHG_MEMBER'] results['FG_NHG_MEMBER'] = png_ecmp_content['FG_NHG_MEMBER']
results['FG_NHG_PREFIX'] = png_ecmp_content['FG_NHG_PREFIX']
results['FG_NHG'] = png_ecmp_content['FG_NHG'] results['FG_NHG'] = png_ecmp_content['FG_NHG']
results['NEIGH'] = png_ecmp_content['NEIGH'] results['NEIGH'] = png_ecmp_content['NEIGH']

View File

@ -233,9 +233,14 @@ class TestCfgGen(TestCase):
self.assertEqual(output.strip(), "[('Vlan1000', '192.168.0.1/27'), 'Vlan1000']") self.assertEqual(output.strip(), "[('Vlan1000', '192.168.0.1/27'), 'Vlan1000']")
def test_minigraph_ecmp_fg_nhg(self): def test_minigraph_ecmp_fg_nhg(self):
argument = '-m "' + self.ecmp_graph + '" -p "' + self.mlnx_port_config + '" -v \"FG_NHG.values()|list\"' argument = '-m "' + self.ecmp_graph + '" -p "' + self.mlnx_port_config + '" -v FG_NHG'
output = self.run_script(argument) output = self.run_script(argument)
self.assertEqual(output.strip(), "[{'bucket_size': 120}, {'bucket_size': 120}]") print(output.strip())
self.assertEqual(utils.to_dict(output.strip()),
utils.to_dict(
"{'fgnhg_v4': {'match_mode': 'nexthop-based', 'bucket_size': 120}, "
"'fgnhg_v6': {'match_mode': 'nexthop-based', 'bucket_size': 120}}"
))
def test_minigraph_ecmp_members(self): def test_minigraph_ecmp_members(self):
argument = '-m "' + self.ecmp_graph + '" -p "' + self.mlnx_port_config + '" -v "FG_NHG_MEMBER.keys()|list|sort"' argument = '-m "' + self.ecmp_graph + '" -p "' + self.mlnx_port_config + '" -v "FG_NHG_MEMBER.keys()|list|sort"'
@ -254,12 +259,6 @@ class TestCfgGen(TestCase):
" 'Vlan31|200:200:200:200::2', 'Vlan31|200:200:200:200::3', 'Vlan31|200:200:200:200::4', 'Vlan31|200:200:200:200::5', " " 'Vlan31|200:200:200:200::2', 'Vlan31|200:200:200:200::3', 'Vlan31|200:200:200:200::4', 'Vlan31|200:200:200:200::5', "
"'Vlan31|200:200:200:200::6', 'Vlan31|200:200:200:200::7', 'Vlan31|200:200:200:200::8', 'Vlan31|200:200:200:200::9']") "'Vlan31|200:200:200:200::6', 'Vlan31|200:200:200:200::7', 'Vlan31|200:200:200:200::8', 'Vlan31|200:200:200:200::9']")
def test_minigraph_ecmp_prefixes(self):
argument = '-m "' + self.ecmp_graph + '" -p "' + self.mlnx_port_config + '" -v "FG_NHG_PREFIX.keys()|list|sort"'
output = self.run_script(argument)
self.assertEqual(output.strip(), "['100.50.25.12/32', 'fc:5::/128']")
def test_minigraph_portchannels(self): def test_minigraph_portchannels(self):
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v PORTCHANNEL' argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v PORTCHANNEL'
output = self.run_script(argument) output = self.run_script(argument)