Skip to content

Commit

Permalink
[minigraph.py]: Parse mux cable table (#5876)
Browse files Browse the repository at this point in the history
Parse device IPv6 loopback addresses when available
Add MUX_CABLE table to config DB:

'MUX_CABLE': {
	'Ethernet4': {
    	'state': 'auto',
        'server_ipv4': '10.10.10.1/32',
        'server_ipv6': 'fe80::0001/128'
	}
}
  • Loading branch information
theasianpianist authored Nov 16, 2020
1 parent 67dbbb3 commit 261a81d
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 24 deletions.
33 changes: 29 additions & 4 deletions src/sonic-config-engine/minigraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def get_peer_switch_info(link_metadata, devices):

def parse_device(device):
lo_prefix = None
lo_prefix_v6 = None
mgmt_prefix = None
d_type = None # don't shadow type()
hwsku = None
Expand All @@ -90,6 +91,8 @@ def parse_device(device):
for node in device:
if node.tag == str(QName(ns, "Address")):
lo_prefix = node.find(str(QName(ns2, "IPPrefix"))).text
elif node.tag == str(QName(ns, "AddressV6")):
lo_prefix_v6 = node.find(str(QName(ns2, "IPPrefix"))).text
elif node.tag == str(QName(ns, "ManagementAddress")):
mgmt_prefix = node.find(str(QName(ns2, "IPPrefix"))).text
elif node.tag == str(QName(ns, "Hostname")):
Expand All @@ -98,7 +101,7 @@ def parse_device(device):
hwsku = node.text
elif node.tag == str(QName(ns, "DeploymentId")):
deployment_id = node.text
return (lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id)
return (lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id)

def parse_png(png, hname):
neighbors = {}
Expand Down Expand Up @@ -160,10 +163,12 @@ def parse_png(png, hname):

if child.tag == str(QName(ns, "Devices")):
for device in child.findall(str(QName(ns, "Device"))):
(lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device)
(lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device)
device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku }
if deployment_id:
device_data['deployment_id'] = deployment_id
if lo_prefix_v6:
device_data['lo_addr_v6'] = lo_prefix_v6
devices[name] = device_data

if name == hname:
Expand Down Expand Up @@ -281,10 +286,12 @@ def parse_asic_png(png, asic_name, hostname):

if child.tag == str(QName(ns, "Devices")):
for device in child.findall(str(QName(ns, "Device"))):
(lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device)
(lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device)
device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku }
if deployment_id:
device_data['deployment_id'] = deployment_id
if lo_prefix_v6:
device_data['lo_addr_v6']= lo_prefix_v6
devices[name] = device_data
return (neighbors, devices, port_speeds)

Expand Down Expand Up @@ -1234,6 +1241,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw

results['TUNNEL'] = get_tunnel_entries(tunnel_intfs, lo_intfs, hostname)

results['MUX_CABLE'] = get_mux_cable_entries(mux_cable_ports, neighbors, devices)

for nghbr in list(neighbors.keys()):
# remove port not in port_config.ini
if nghbr not in ports:
Expand Down Expand Up @@ -1317,10 +1326,24 @@ def get_tunnel_entries(tunnel_intfs, lo_intfs, hostname):
tunnels[tunnel_key] = tunnel_attr
return tunnels

def get_mux_cable_entries(mux_cable_ports, neighbors, devices):
mux_cable_table = {}

for intf in mux_cable_ports:
if intf in neighbors:
entry = {}
neighbor = neighbors[intf]['name']
entry['state'] = 'auto'
entry['server_ipv4'] = devices[neighbor]['lo_addr']
if 'lo_addr_v6' in devices[neighbor]:
entry['server_ipv6'] = devices[neighbor]['lo_addr_v6']
mux_cable_table[intf] = entry

return mux_cable_table

def parse_device_desc_xml(filename):
root = ET.parse(filename).getroot()
(lo_prefix, mgmt_prefix, hostname, hwsku, d_type, _) = parse_device(root)
(lo_prefix, lo_prefix_v6, mgmt_prefix, hostname, hwsku, d_type, _) = parse_device(root)

results = {}
results['DEVICE_METADATA'] = {'localhost': {
Expand All @@ -1329,6 +1352,8 @@ def parse_device_desc_xml(filename):
}}

results['LOOPBACK_INTERFACE'] = {('lo', lo_prefix): {}}
if lo_prefix_v6:
results['LOOPBACK_INTERFACE'] = {('lo_v6', lo_prefix_v6): {}}

mgmt_intf = {}
mgmtipn = ipaddress.ip_network(UNICODE_TYPE(mgmt_prefix), False)
Expand Down
46 changes: 46 additions & 0 deletions src/sonic-config-engine/tests/simple-sample-graph-case.xml
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,24 @@
<StartDevice>switch-02t1</StartDevice>
<StartPort>port1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase i:type="DeviceInterfaceLink">
<ElementType>DeviceInterfaceLink</ElementType>
<AutoNegotiation>true</AutoNegotiation>
<Bandwidth>25000</Bandwidth>
<EndDevice>switch-t0</EndDevice>
<EndPort>fortyGigE0/4</EndPort>
<StartDevice>server1</StartDevice>
<StartPort>port1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase i:type="DeviceInterfaceLink">
<ElementType>DeviceInterfaceLink</ElementType>
<AutoNegotiation>true</AutoNegotiation>
<Bandwidth>40000</Bandwidth>
<EndDevice>switch-t0</EndDevice>
<EndPort>fortyGigE0/8</EndPort>
<StartDevice>server2</StartDevice>
<StartPort>port1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase i:type="LogicalLink">
<ElementType>LogicalLink</ElementType>
<Bandwidth>10000</Bandwidth>
Expand Down Expand Up @@ -278,6 +296,34 @@
</ManagementAddress>
<HwSku>Force10-S6000</HwSku>
</Device>
<Device i:type="Server">
<ElementType>Server</ElementType>
<Address xmlns:d5p1="Microsoft.Search.Autopilot.NetMux">
<d5p1:IPPrefix>10.10.10.1/32</d5p1:IPPrefix>
</Address>
<AddressV6 xmlns:d5p1="Microsoft.Search.Autopilot.NetMux">
<d5p1:IPPrefix>fe80::0001/128</d5p1:IPPrefix>
</AddressV6>
<ManagementAddress xmlns:d5p1="Microsoft.Search.Autopilot.NetMux">
<d5p1:IPPrefix>10.0.0.1/32</d5p1:IPPrefix>
</ManagementAddress>
<Hostname>server1</Hostname>
<HwSku>server-sku</HwSku>
</Device>
<Device i:type="Server">
<ElementType>Server</ElementType>
<Address xmlns:d5p1="Microsoft.Search.Autopilot.NetMux">
<d5p1:IPPrefix>10.10.10.2/32</d5p1:IPPrefix>
</Address>
<AddressV6 xmlns:d5p1="Microsoft.Search.Autopilot.NetMux">
<d5p1:IPPrefix>fe80::0002/128</d5p1:IPPrefix>
</AddressV6>
<ManagementAddress xmlns:d5p1="Microsoft.Search.Autopilot.NetMux">
<d5p1:IPPrefix>10.0.0.2/32</d5p1:IPPrefix>
</ManagementAddress>
<Hostname>server2</Hostname>
<HwSku>server-sku</HwSku>
</Device>
</Devices>
</PngDec>
<LinkMetadataDeclaration>
Expand Down
2 changes: 1 addition & 1 deletion src/sonic-config-engine/tests/test_cfggen.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ def test_minigraph_neighbor_interfaces(self):
utils.to_dict(
"{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '40000', 'mux_cable': 'true'}, "
"'Ethernet0': {'lanes': '29,30,31,32', 'description': 'switch-01t1:port1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, "
"'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000', 'mux_cable': 'true'}, "
"'Ethernet4': {'lanes': '25,26,27,28', 'description': 'server1:port1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000', 'mux_cable': 'true'}, "
"'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, "
"'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, "
"'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, "
Expand Down
69 changes: 54 additions & 15 deletions src/sonic-config-engine/tests/test_minigraph_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,24 +123,41 @@ def test_minigraph_deployment_id(self):

def test_minigraph_neighbor_metadata(self):
argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_NEIGHBOR_METADATA"'

expected_table = {
'switch-01t1': {
'lo_addr': '10.1.0.186/32',
'mgmt_addr': '10.7.0.196/26',
'hwsku': 'Force10-S6000',
'type': 'LeafRouter',
'deployment_id': '2'
},
'switch2-t0': {
'hwsku': 'Force10-S6000',
'lo_addr': '25.1.1.10',
'mgmt_addr': '10.7.0.196/26',
'type': 'ToRRouter'
},
'server1': {
'hwsku': 'server-sku',
'lo_addr': '10.10.10.1/32',
'lo_addr_v6': 'fe80::0001/128',
'mgmt_addr': '10.0.0.1/32',
'type': 'Server'
},
'server2': {
'hwsku': 'server-sku',
'lo_addr': '10.10.10.2/32',
'lo_addr_v6': 'fe80::0002/128',
'mgmt_addr': '10.0.0.2/32',
'type': 'Server'
}
}
output = self.run_script(argument)
self.maxDiff = None
self.assertEqual(
utils.to_dict(output.strip()),
utils.to_dict("{" \
"'switch-01t1': {" \
"'lo_addr': '10.1.0.186/32'," \
"'mgmt_addr': '10.7.0.196/26'," \
"'hwsku': 'Force10-S6000'," \
"'type': 'LeafRouter'," \
"'deployment_id': '2'" \
"}," \
"'switch2-t0': {" \
"'hwsku': 'Force10-S6000'," \
"'lo_addr': '25.1.1.10'," \
"'mgmt_addr': '10.7.0.196/26'," \
"'type': 'ToRRouter'" \
"}" \
"}")
expected_table
)

# everflow portion is not used
Expand Down Expand Up @@ -227,3 +244,25 @@ def test_minigraph_tunnel_table(self):
utils.to_dict(output.strip()),
expected_tunnel
)

def test_minigraph_mux_cable_table(self):
argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "MUX_CABLE"'
expected_table = {
'Ethernet4': {
'state': 'auto',
'server_ipv4': '10.10.10.1/32',
'server_ipv6': 'fe80::0001/128'
},
'Ethernet8': {
'state': 'auto',
'server_ipv4': '10.10.10.2/32',
'server_ipv6': 'fe80::0002/128'
}
}

output = self.run_script(argument)
self.assertEqual(
utils.to_dict(output.strip()),
expected_table
)

8 changes: 4 additions & 4 deletions src/sonic-config-engine/tests/test_multinpu_cfggen.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ def test_frontend_asic_device_neigh_metadata(self):
output = json.loads(self.run_script(argument))
self.assertDictEqual(output, \
{'01T2': {'lo_addr': None, 'mgmt_addr': '89.139.132.40', 'hwsku': 'VM', 'type': 'SpineRouter'},
'ASIC3': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'},
'ASIC2': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}})
'ASIC3': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'},
'ASIC2': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}})

def test_backend_asic_device_neigh(self):
argument = "-m {} -p {} -n asic3 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[3])
Expand All @@ -218,8 +218,8 @@ def test_backend_device_neigh_metadata(self):
argument = "-m {} -p {} -n asic3 --var-json \"DEVICE_NEIGHBOR_METADATA\"".format(self.sample_graph, self.port_config[3])
output = json.loads(self.run_script(argument))
self.assertDictEqual(output, \
{'ASIC1': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'},
'ASIC0': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}})
{'ASIC1': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'},
'ASIC0': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}})

def test_frontend_bgp_neighbor(self):
argument = "-m {} -p {} -n asic0 --var-json \"BGP_NEIGHBOR\"".format(self.sample_graph, self.port_config[0])
Expand Down

0 comments on commit 261a81d

Please sign in to comment.