@@ -66,7 +66,9 @@ def default(self, obj):
66
66
67
67
def get_peer_switch_info (link_metadata , devices ):
68
68
peer_switch_table = {}
69
- for data in link_metadata .values ():
69
+ peer_switch_ip = None
70
+ mux_tunnel_name = None
71
+ for port , data in link_metadata .items ():
70
72
if "PeerSwitch" in data :
71
73
peer_hostname = data ["PeerSwitch" ]
72
74
peer_lo_addr_str = devices [peer_hostname ]["lo_addr" ]
@@ -75,8 +77,10 @@ def get_peer_switch_info(link_metadata, devices):
75
77
peer_switch_table [peer_hostname ] = {
76
78
'address_ipv4' : str (peer_lo_addr .network_address ) if peer_lo_addr else peer_lo_addr_str
77
79
}
80
+ mux_tunnel_name = port
81
+ peer_switch_ip = peer_switch_table [peer_hostname ]['address_ipv4' ]
78
82
79
- return peer_switch_table
83
+ return peer_switch_table , mux_tunnel_name , peer_switch_ip
80
84
81
85
82
86
def parse_device (device ):
@@ -410,6 +414,8 @@ def parse_dpg(dpg, hname):
410
414
mgmtintfs = None
411
415
subintfs = None
412
416
tunnelintfs = defaultdict (dict )
417
+ tunnelintfs_qos_remap_config = defaultdict (dict )
418
+
413
419
for child in dpg :
414
420
"""
415
421
In Multi-NPU platforms the acl intfs are defined only for the host not for individual asic.
@@ -717,6 +723,13 @@ def parse_dpg(dpg, hname):
717
723
"ecn_mode" : "EcnDecapsulationMode" ,
718
724
"dscp_mode" : "DifferentiatedServicesCodePointMode" ,
719
725
"ttl_mode" : "TtlMode" }
726
+
727
+ tunnel_qos_remap_table_key_to_mg_key_map = {
728
+ "decap_dscp_to_tc_map" : "DecapDscpToTcMap" ,
729
+ "decap_tc_to_pg_map" : "DecapTcToPgMap" ,
730
+ "encap_tc_to_queue_map" : "EncapTcToQueueMap" ,
731
+ "encap_tc_to_dscp_map" : "EncapTcToDscpMap" }
732
+
720
733
for mg_tunnel in mg_tunnels .findall (str (QName (ns , "TunnelInterface" ))):
721
734
tunnel_type = mg_tunnel .attrib ["Type" ]
722
735
tunnel_name = mg_tunnel .attrib ["Name" ]
@@ -728,9 +741,17 @@ def parse_dpg(dpg, hname):
728
741
# If the minigraph has the key, add the corresponding config DB key to the table
729
742
if mg_key in mg_tunnel .attrib :
730
743
tunnelintfs [tunnel_type ][tunnel_name ][table_key ] = mg_tunnel .attrib [mg_key ]
744
+
745
+ tunnelintfs_qos_remap_config [tunnel_type ][tunnel_name ] = {
746
+ "tunnel_type" : mg_tunnel .attrib ["Type" ].upper (),
747
+ }
731
748
732
- return intfs , lo_intfs , mvrf , mgmt_intf , voq_inband_intfs , vlans , vlan_members , dhcp_relay_table , pcs , pc_members , acls , vni , tunnelintfs , dpg_ecmp_content , static_routes
733
- return None , None , None , None , None , None , None , None , None , None , None , None , None , None , None
749
+ for table_key , mg_key in tunnel_qos_remap_table_key_to_mg_key_map .items ():
750
+ if mg_key in mg_tunnel .attrib :
751
+ tunnelintfs_qos_remap_config [tunnel_type ][tunnel_name ][table_key ] = mg_tunnel .attrib [mg_key ]
752
+
753
+ return intfs , lo_intfs , mvrf , mgmt_intf , voq_inband_intfs , vlans , vlan_members , dhcp_relay_table , pcs , pc_members , acls , vni , tunnelintfs , dpg_ecmp_content , static_routes , tunnelintfs_qos_remap_config
754
+ return None , None , None , None , None , None , None , None , None , None , None , None , None , None , None , None
734
755
735
756
736
757
@@ -909,6 +930,29 @@ def parse_meta(meta, hname):
909
930
return syslog_servers , dhcp_servers , dhcpv6_servers , ntp_servers , tacacs_servers , mgmt_routes , erspan_dst , deployment_id , region , cloudtype , resource_type , downstream_subrole , switch_id , switch_type , max_cores , kube_data
910
931
911
932
933
+ def parse_system_defaults (meta ):
934
+ system_default_values = {}
935
+
936
+ system_defaults = meta .find (str (QName (ns1 , "SystemDefaults" )))
937
+
938
+ if system_defaults is None :
939
+ return system_default_values
940
+
941
+ for system_default in system_defaults .findall (str (QName (ns1 , "SystemDefault" ))):
942
+ name = system_default .find (str (QName (ns1 , "Name" ))).text
943
+ value = system_default .find (str (QName (ns1 , "Value" ))).text
944
+
945
+ # Tunnel Qos remapping
946
+ if name == "TunnelQosRemapEnabled" :
947
+ if value .lower () == "true" :
948
+ status = "enabled"
949
+ else :
950
+ status = "disabled"
951
+ system_default_values ["tunnel_qos_remap" ] = {"status" : status }
952
+
953
+ return system_default_values
954
+
955
+
912
956
def parse_linkmeta (meta , hname ):
913
957
link = meta .find (str (QName (ns , "Link" )))
914
958
linkmetas = {}
@@ -1200,6 +1244,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
1200
1244
vlan_intfs = None
1201
1245
pc_intfs = None
1202
1246
tunnel_intfs = None
1247
+ tunnel_intfs_qos_remap_config = None
1203
1248
vlans = None
1204
1249
vlan_members = None
1205
1250
dhcp_relay_table = None
@@ -1240,6 +1285,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
1240
1285
local_devices = []
1241
1286
kube_data = {}
1242
1287
static_routes = {}
1288
+ system_defaults = {}
1243
1289
1244
1290
hwsku_qn = QName (ns , "HwSku" )
1245
1291
hostname_qn = QName (ns , "Hostname" )
@@ -1262,7 +1308,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
1262
1308
for child in root :
1263
1309
if asic_name is None :
1264
1310
if child .tag == str (QName (ns , "DpgDec" )):
1265
- (intfs , lo_intfs , mvrf , mgmt_intf , voq_inband_intfs , vlans , vlan_members , dhcp_relay_table , pcs , pc_members , acls , vni , tunnel_intfs , dpg_ecmp_content , static_routes ) = parse_dpg (child , hostname )
1311
+ (intfs , lo_intfs , mvrf , mgmt_intf , voq_inband_intfs , vlans , vlan_members , dhcp_relay_table , pcs , pc_members , acls , vni , tunnel_intfs , dpg_ecmp_content , static_routes , tunnel_intfs_qos_remap_config ) = parse_dpg (child , hostname )
1266
1312
elif child .tag == str (QName (ns , "CpgDec" )):
1267
1313
(bgp_sessions , bgp_internal_sessions , bgp_voq_chassis_sessions , bgp_asn , bgp_peers_with_range , bgp_monitors ) = parse_cpg (child , hostname )
1268
1314
elif child .tag == str (QName (ns , "PngDec" )):
@@ -1275,9 +1321,11 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
1275
1321
linkmetas = parse_linkmeta (child , hostname )
1276
1322
elif child .tag == str (QName (ns , "DeviceInfos" )):
1277
1323
(port_speeds_default , port_descriptions , sys_ports ) = parse_deviceinfo (child , hwsku )
1324
+ elif child .tag == str (QName (ns , "SystemDefaultsDeclaration" )):
1325
+ system_defaults = parse_system_defaults (child )
1278
1326
else :
1279
1327
if child .tag == str (QName (ns , "DpgDec" )):
1280
- (intfs , lo_intfs , mvrf , mgmt_intf , voq_inband_intfs , vlans , vlan_members , dhcp_relay_table , pcs , pc_members , acls , vni , tunnel_intfs , dpg_ecmp_content , static_routes ) = parse_dpg (child , asic_name )
1328
+ (intfs , lo_intfs , mvrf , mgmt_intf , voq_inband_intfs , vlans , vlan_members , dhcp_relay_table , pcs , pc_members , acls , vni , tunnel_intfs , dpg_ecmp_content , static_routes , tunnel_intfs_qos_remap_config ) = parse_dpg (child , asic_name )
1281
1329
host_lo_intfs = parse_host_loopback (child , hostname )
1282
1330
elif child .tag == str (QName (ns , "CpgDec" )):
1283
1331
(bgp_sessions , bgp_internal_sessions , bgp_voq_chassis_sessions , bgp_asn , bgp_peers_with_range , bgp_monitors ) = parse_cpg (child , asic_name , local_devices )
@@ -1289,6 +1337,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
1289
1337
linkmetas = parse_linkmeta (child , hostname )
1290
1338
elif child .tag == str (QName (ns , "DeviceInfos" )):
1291
1339
(port_speeds_default , port_descriptions , sys_ports ) = parse_deviceinfo (child , hwsku )
1340
+ elif child .tag == str (QName (ns , "SystemDefaultsDeclaration" )):
1341
+ system_defaults = parse_system_defaults (child )
1292
1342
1293
1343
# set the host device type in asic metadata also
1294
1344
device_type = [devices [key ]['type' ] for key in devices if key .lower () == hostname .lower ()][0 ]
@@ -1324,8 +1374,11 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
1324
1374
'ip' : kube_data .get ('ip' , '' )
1325
1375
}
1326
1376
}
1327
-
1328
- results ['PEER_SWITCH' ] = get_peer_switch_info (linkmetas , devices )
1377
+
1378
+ if len (system_defaults ) > 0 :
1379
+ results ['SYSTEM_DEFAULTS' ] = system_defaults
1380
+
1381
+ results ['PEER_SWITCH' ], mux_tunnel_name , peer_switch_ip = get_peer_switch_info (linkmetas , devices )
1329
1382
1330
1383
if bool (results ['PEER_SWITCH' ]):
1331
1384
results ['DEVICE_METADATA' ]['localhost' ]['subtype' ] = 'DualToR'
@@ -1625,7 +1678,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
1625
1678
results ['VLAN' ] = vlans
1626
1679
results ['VLAN_MEMBER' ] = vlan_members
1627
1680
1628
- results ['TUNNEL' ] = get_tunnel_entries (tunnel_intfs , lo_intfs , hostname )
1681
+ # Add src_ip and qos remapping config into TUNNEL table if tunnel_qos_remap is enabled
1682
+ results ['TUNNEL' ] = get_tunnel_entries (tunnel_intfs , tunnel_intfs_qos_remap_config , lo_intfs , system_defaults .get ('tunnel_qos_remap' , {}), mux_tunnel_name , peer_switch_ip )
1629
1683
1630
1684
results ['MUX_CABLE' ] = get_mux_cable_entries (mux_cable_ports , neighbors , devices )
1631
1685
@@ -1717,7 +1771,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
1717
1771
1718
1772
return results
1719
1773
1720
- def get_tunnel_entries (tunnel_intfs , lo_intfs , hostname ):
1774
+ def get_tunnel_entries (tunnel_intfs , tunnel_intfs_qos_remap_config , lo_intfs , tunnel_qos_remap , mux_tunnel_name , peer_switch_ip ):
1721
1775
lo_addr = ''
1722
1776
# Use the first IPv4 loopback as the tunnel destination IP
1723
1777
for addr in lo_intfs .keys ():
@@ -1730,7 +1784,14 @@ def get_tunnel_entries(tunnel_intfs, lo_intfs, hostname):
1730
1784
for type , tunnel_dict in tunnel_intfs .items ():
1731
1785
for tunnel_key , tunnel_attr in tunnel_dict .items ():
1732
1786
tunnel_attr ['dst_ip' ] = lo_addr
1787
+
1788
+ if (tunnel_qos_remap .get ('status' ) == 'enabled' ) and (mux_tunnel_name == tunnel_key ) and (peer_switch_ip is not None ):
1789
+ tunnel_attr ['src_ip' ] = peer_switch_ip
1790
+ if tunnel_key in tunnel_intfs_qos_remap_config [type ]:
1791
+ tunnel_attr .update (tunnel_intfs_qos_remap_config [type ][tunnel_key ].items ())
1792
+
1733
1793
tunnels [tunnel_key ] = tunnel_attr
1794
+
1734
1795
return tunnels
1735
1796
1736
1797
def get_mux_cable_entries (mux_cable_ports , neighbors , devices ):
@@ -1754,7 +1815,7 @@ def get_mux_cable_entries(mux_cable_ports, neighbors, devices):
1754
1815
entry ['server_ipv6' ] = str (server_ipv6_lo_prefix )
1755
1816
mux_cable_table [intf ] = entry
1756
1817
else :
1757
- print ("Warning: no server IPv4 loopback found for {}, skipping mux cable table entry" .format (neighbor ))
1818
+ print ("Warning: no server IPv4 loopback found for {}, skipping mux cable table entry" .format (neighbor ), file = sys . stderr )
1758
1819
1759
1820
if cable_name in devices :
1760
1821
cable_type = devices [cable_name ].get ('subtype' )
@@ -1767,9 +1828,9 @@ def get_mux_cable_entries(mux_cable_ports, neighbors, devices):
1767
1828
soc_ipv4_prefix = ipaddress .ip_network (UNICODE_TYPE (soc_ipv4 ))
1768
1829
mux_cable_table [intf ]['soc_ipv4' ] = str (soc_ipv4_prefix )
1769
1830
else :
1770
- print ("Warning: skip parsing device %s for mux cable entry, cable type %s not supported" % (cable_name , cable_type ))
1831
+ print ("Warning: skip parsing device %s for mux cable entry, cable type %s not supported" % (cable_name , cable_type ), file = sys . stderr )
1771
1832
else :
1772
- print ("Warning: skip parsing device %s for mux cable entry, device definition not found" % cable_name )
1833
+ print ("Warning: skip parsing device %s for mux cable entry, device definition not found" % cable_name , file = sys . stderr )
1773
1834
1774
1835
return mux_cable_table
1775
1836
0 commit comments