Skip to content

Commit c4e806f

Browse files
authored
[202012][cherry-pick] Define SYSTEM_DEFAULTS table to control tunnel_qos_remap (#10930)
[202012][cherry-pick] Define `SYSTEM_DEFAULTS` table to control tunnel_qos_remap (#10930) Signed-off-by: bingwang <[email protected]>
1 parent ec9732a commit c4e806f

File tree

4 files changed

+1889
-9
lines changed

4 files changed

+1889
-9
lines changed

src/sonic-config-engine/minigraph.py

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ def default(self, obj):
6464

6565
def get_peer_switch_info(link_metadata, devices):
6666
peer_switch_table = {}
67-
for data in link_metadata.values():
67+
peer_switch_ip = None
68+
mux_tunnel_name = None
69+
for port, data in link_metadata.items():
6870
if "PeerSwitch" in data:
6971
peer_hostname = data["PeerSwitch"]
7072
peer_lo_addr_str = devices[peer_hostname]["lo_addr"]
@@ -73,8 +75,10 @@ def get_peer_switch_info(link_metadata, devices):
7375
peer_switch_table[peer_hostname] = {
7476
'address_ipv4': str(peer_lo_addr.network_address) if peer_lo_addr else peer_lo_addr_str
7577
}
78+
mux_tunnel_name = port
79+
peer_switch_ip = peer_switch_table[peer_hostname]['address_ipv4']
7680

77-
return peer_switch_table
81+
return peer_switch_table, mux_tunnel_name, peer_switch_ip
7882

7983
def parse_device(device):
8084
lo_prefix = None
@@ -400,6 +404,8 @@ def parse_dpg(dpg, hname):
400404
mgmtintfs = None
401405
subintfs = None
402406
tunnelintfs = defaultdict(dict)
407+
tunnelintfs_qos_remap_config = defaultdict(dict)
408+
403409
for child in dpg:
404410
"""
405411
In Multi-NPU platforms the acl intfs are defined only for the host not for individual asic.
@@ -687,6 +693,13 @@ def parse_dpg(dpg, hname):
687693
"ecn_mode": "EcnDecapsulationMode",
688694
"dscp_mode": "DifferentiatedServicesCodePointMode",
689695
"ttl_mode": "TtlMode"}
696+
697+
tunnel_qos_remap_table_key_to_mg_key_map = {
698+
"decap_dscp_to_tc_map": "DecapDscpToTcMap",
699+
"decap_tc_to_pg_map": "DecapTcToPgMap",
700+
"encap_tc_to_queue_map": "EncapTcToQueueMap",
701+
"encap_tc_to_dscp_map": "EncapTcToDscpMap"}
702+
690703
for mg_tunnel in mg_tunnels.findall(str(QName(ns, "TunnelInterface"))):
691704
tunnel_type = mg_tunnel.attrib["Type"]
692705
tunnel_name = mg_tunnel.attrib["Name"]
@@ -699,8 +712,16 @@ def parse_dpg(dpg, hname):
699712
if mg_key in mg_tunnel.attrib:
700713
tunnelintfs[tunnel_type][tunnel_name][table_key] = mg_tunnel.attrib[mg_key]
701714

702-
return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, dhcp_relay_table, pcs, pc_members, acls, vni, tunnelintfs, dpg_ecmp_content
703-
return None, None, None, None, None, None, None, None, None, None, None, None, None
715+
tunnelintfs_qos_remap_config[tunnel_type][tunnel_name] = {
716+
"tunnel_type": mg_tunnel.attrib["Type"].upper(),
717+
}
718+
719+
for table_key, mg_key in tunnel_qos_remap_table_key_to_mg_key_map.items():
720+
if mg_key in mg_tunnel.attrib:
721+
tunnelintfs_qos_remap_config[tunnel_type][tunnel_name][table_key] = mg_tunnel.attrib[mg_key]
722+
723+
return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, dhcp_relay_table, pcs, pc_members, acls, vni, tunnelintfs, dpg_ecmp_content, tunnelintfs_qos_remap_config
724+
return None, None, None, None, None, None, None, None, None, None, None, None, None, None
704725

705726
def parse_host_loopback(dpg, hname):
706727
for child in dpg:
@@ -862,6 +883,27 @@ def parse_meta(meta, hname):
862883
kube_data["ip"] = value
863884
return syslog_servers, dhcp_servers, dhcpv6_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, kube_data
864885

886+
def parse_system_defaults(meta):
887+
system_default_values = {}
888+
889+
system_defaults = meta.find(str(QName(ns1, "SystemDefaults")))
890+
891+
if system_defaults is None:
892+
return system_default_values
893+
894+
for system_default in system_defaults.findall(str(QName(ns1, "SystemDefault"))):
895+
name = system_default.find(str(QName(ns1, "Name"))).text
896+
value = system_default.find(str(QName(ns1, "Value"))).text
897+
898+
# Tunnel Qos remapping
899+
if name == "TunnelQosRemapEnabled":
900+
if value.lower() == "true":
901+
status = "enabled"
902+
else:
903+
status = "disabled"
904+
system_default_values["tunnel_qos_remap"] = {"status": status}
905+
906+
return system_default_values
865907

866908
def parse_linkmeta(meta, hname):
867909
link = meta.find(str(QName(ns, "Link")))
@@ -1124,6 +1166,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
11241166
vlan_intfs = None
11251167
pc_intfs = None
11261168
tunnel_intfs = None
1169+
tunnel_intfs_qos_remap_config = None
11271170
vlans = None
11281171
vlan_members = None
11291172
dhcp_relay_table = None
@@ -1158,6 +1201,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
11581201
is_storage_device = False
11591202
local_devices = []
11601203
kube_data = {}
1204+
system_defaults = {}
11611205

11621206
hwsku_qn = QName(ns, "HwSku")
11631207
hostname_qn = QName(ns, "Hostname")
@@ -1180,7 +1224,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
11801224
for child in root:
11811225
if asic_name is None:
11821226
if child.tag == str(QName(ns, "DpgDec")):
1183-
(intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, dhcp_relay_table, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, hostname)
1227+
(intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, dhcp_relay_table, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content, tunnel_intfs_qos_remap_config) = parse_dpg(child, hostname)
11841228
elif child.tag == str(QName(ns, "CpgDec")):
11851229
(bgp_sessions, bgp_internal_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname)
11861230
elif child.tag == str(QName(ns, "PngDec")):
@@ -1193,9 +1237,11 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
11931237
linkmetas = parse_linkmeta(child, hostname)
11941238
elif child.tag == str(QName(ns, "DeviceInfos")):
11951239
(port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku)
1240+
elif child.tag == str(QName(ns, "SystemDefaultsDeclaration")):
1241+
system_defaults = parse_system_defaults(child)
11961242
else:
11971243
if child.tag == str(QName(ns, "DpgDec")):
1198-
(intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, dhcp_relay_table, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, asic_name)
1244+
(intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, dhcp_relay_table, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content, tunnel_intfs_qos_remap_config) = parse_dpg(child, asic_name)
11991245
host_lo_intfs = parse_host_loopback(child, hostname)
12001246
elif child.tag == str(QName(ns, "CpgDec")):
12011247
(bgp_sessions, bgp_internal_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name, local_devices)
@@ -1207,6 +1253,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
12071253
linkmetas = parse_linkmeta(child, hostname)
12081254
elif child.tag == str(QName(ns, "DeviceInfos")):
12091255
(port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku)
1256+
elif child.tag == str(QName(ns, "SystemDefaultsDeclaration")):
1257+
system_defaults = parse_system_defaults(child)
12101258

12111259
# set the host device type in asic metadata also
12121260
device_type = [devices[key]['type'] for key in devices if key.lower() == hostname.lower()][0]
@@ -1241,7 +1289,10 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
12411289
}
12421290
}
12431291

1244-
results['PEER_SWITCH'] = get_peer_switch_info(linkmetas, devices)
1292+
if len(system_defaults) > 0:
1293+
results['SYSTEM_DEFAULTS'] = system_defaults
1294+
1295+
results['PEER_SWITCH'], mux_tunnel_name, peer_switch_ip = get_peer_switch_info(linkmetas, devices)
12451296

12461297
if bool(results['PEER_SWITCH']):
12471298
results['DEVICE_METADATA']['localhost']['subtype'] = 'DualToR'
@@ -1501,7 +1552,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
15011552
results['VLAN'] = vlans
15021553
results['VLAN_MEMBER'] = vlan_members
15031554

1504-
results['TUNNEL'] = get_tunnel_entries(tunnel_intfs, lo_intfs, hostname)
1555+
# Add src_ip and qos remapping config into TUNNEL table if tunnel_qos_remap is enabled
1556+
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)
15051557

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

@@ -1590,7 +1642,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
15901642

15911643
return results
15921644

1593-
def get_tunnel_entries(tunnel_intfs, lo_intfs, hostname):
1645+
def get_tunnel_entries(tunnel_intfs, tunnel_intfs_qos_remap_config, lo_intfs, tunnel_qos_remap, mux_tunnel_name, peer_switch_ip):
15941646
lo_addr = ''
15951647
# Use the first IPv4 loopback as the tunnel destination IP
15961648
for addr in lo_intfs.keys():
@@ -1603,6 +1655,11 @@ def get_tunnel_entries(tunnel_intfs, lo_intfs, hostname):
16031655
for type, tunnel_dict in tunnel_intfs.items():
16041656
for tunnel_key, tunnel_attr in tunnel_dict.items():
16051657
tunnel_attr['dst_ip'] = lo_addr
1658+
if (tunnel_qos_remap.get('status') == 'enabled') and (mux_tunnel_name == tunnel_key) and (peer_switch_ip is not None):
1659+
tunnel_attr['src_ip'] = peer_switch_ip
1660+
if tunnel_key in tunnel_intfs_qos_remap_config[type]:
1661+
tunnel_attr.update(tunnel_intfs_qos_remap_config[type][tunnel_key].items())
1662+
16061663
tunnels[tunnel_key] = tunnel_attr
16071664
return tunnels
16081665

0 commit comments

Comments
 (0)