[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:
parent
7ec9fbb678
commit
e60603cd96
@ -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']
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user