Skip to content

Commit b62526c

Browse files
authored
Define SYSTEM_DEFAULTS table to control tunnel_qos_remap (#10877)
* Define SYSTEM_DEFAULTS table to control tunnel_qos_remap Signed-off-by: bingwang <[email protected]>
1 parent 9bf84fc commit b62526c

File tree

4 files changed

+1898
-13
lines changed

4 files changed

+1898
-13
lines changed

src/sonic-config-engine/minigraph.py

+74-13
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ def default(self, obj):
6666

6767
def get_peer_switch_info(link_metadata, devices):
6868
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():
7072
if "PeerSwitch" in data:
7173
peer_hostname = data["PeerSwitch"]
7274
peer_lo_addr_str = devices[peer_hostname]["lo_addr"]
@@ -75,8 +77,10 @@ def get_peer_switch_info(link_metadata, devices):
7577
peer_switch_table[peer_hostname] = {
7678
'address_ipv4': str(peer_lo_addr.network_address) if peer_lo_addr else peer_lo_addr_str
7779
}
80+
mux_tunnel_name = port
81+
peer_switch_ip = peer_switch_table[peer_hostname]['address_ipv4']
7882

79-
return peer_switch_table
83+
return peer_switch_table, mux_tunnel_name, peer_switch_ip
8084

8185

8286
def parse_device(device):
@@ -410,6 +414,8 @@ def parse_dpg(dpg, hname):
410414
mgmtintfs = None
411415
subintfs = None
412416
tunnelintfs = defaultdict(dict)
417+
tunnelintfs_qos_remap_config = defaultdict(dict)
418+
413419
for child in dpg:
414420
"""
415421
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):
717723
"ecn_mode": "EcnDecapsulationMode",
718724
"dscp_mode": "DifferentiatedServicesCodePointMode",
719725
"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+
720733
for mg_tunnel in mg_tunnels.findall(str(QName(ns, "TunnelInterface"))):
721734
tunnel_type = mg_tunnel.attrib["Type"]
722735
tunnel_name = mg_tunnel.attrib["Name"]
@@ -728,9 +741,17 @@ def parse_dpg(dpg, hname):
728741
# If the minigraph has the key, add the corresponding config DB key to the table
729742
if mg_key in mg_tunnel.attrib:
730743
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+
}
731748

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
734755

735756

736757

@@ -909,6 +930,29 @@ def parse_meta(meta, hname):
909930
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
910931

911932

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+
912956
def parse_linkmeta(meta, hname):
913957
link = meta.find(str(QName(ns, "Link")))
914958
linkmetas = {}
@@ -1200,6 +1244,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
12001244
vlan_intfs = None
12011245
pc_intfs = None
12021246
tunnel_intfs = None
1247+
tunnel_intfs_qos_remap_config = None
12031248
vlans = None
12041249
vlan_members = None
12051250
dhcp_relay_table = None
@@ -1240,6 +1285,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
12401285
local_devices = []
12411286
kube_data = {}
12421287
static_routes = {}
1288+
system_defaults = {}
12431289

12441290
hwsku_qn = QName(ns, "HwSku")
12451291
hostname_qn = QName(ns, "Hostname")
@@ -1262,7 +1308,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
12621308
for child in root:
12631309
if asic_name is None:
12641310
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)
12661312
elif child.tag == str(QName(ns, "CpgDec")):
12671313
(bgp_sessions, bgp_internal_sessions, bgp_voq_chassis_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname)
12681314
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
12751321
linkmetas = parse_linkmeta(child, hostname)
12761322
elif child.tag == str(QName(ns, "DeviceInfos")):
12771323
(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)
12781326
else:
12791327
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)
12811329
host_lo_intfs = parse_host_loopback(child, hostname)
12821330
elif child.tag == str(QName(ns, "CpgDec")):
12831331
(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
12891337
linkmetas = parse_linkmeta(child, hostname)
12901338
elif child.tag == str(QName(ns, "DeviceInfos")):
12911339
(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)
12921342

12931343
# set the host device type in asic metadata also
12941344
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
13241374
'ip': kube_data.get('ip', '')
13251375
}
13261376
}
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)
13291382

13301383
if bool(results['PEER_SWITCH']):
13311384
results['DEVICE_METADATA']['localhost']['subtype'] = 'DualToR'
@@ -1625,7 +1678,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
16251678
results['VLAN'] = vlans
16261679
results['VLAN_MEMBER'] = vlan_members
16271680

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)
16291683

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

@@ -1717,7 +1771,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
17171771

17181772
return results
17191773

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):
17211775
lo_addr = ''
17221776
# Use the first IPv4 loopback as the tunnel destination IP
17231777
for addr in lo_intfs.keys():
@@ -1730,7 +1784,14 @@ def get_tunnel_entries(tunnel_intfs, lo_intfs, hostname):
17301784
for type, tunnel_dict in tunnel_intfs.items():
17311785
for tunnel_key, tunnel_attr in tunnel_dict.items():
17321786
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+
17331793
tunnels[tunnel_key] = tunnel_attr
1794+
17341795
return tunnels
17351796

17361797
def get_mux_cable_entries(mux_cable_ports, neighbors, devices):
@@ -1754,7 +1815,7 @@ def get_mux_cable_entries(mux_cable_ports, neighbors, devices):
17541815
entry['server_ipv6'] = str(server_ipv6_lo_prefix)
17551816
mux_cable_table[intf] = entry
17561817
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)
17581819

17591820
if cable_name in devices:
17601821
cable_type = devices[cable_name].get('subtype')
@@ -1767,9 +1828,9 @@ def get_mux_cable_entries(mux_cable_ports, neighbors, devices):
17671828
soc_ipv4_prefix = ipaddress.ip_network(UNICODE_TYPE(soc_ipv4))
17681829
mux_cable_table[intf]['soc_ipv4'] = str(soc_ipv4_prefix)
17691830
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)
17711832
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)
17731834

17741835
return mux_cable_table
17751836

0 commit comments

Comments
 (0)