Skip to content

Commit

Permalink
Define SYSTEM_DEFAULTS table to control tunnel_qos_remap
Browse files Browse the repository at this point in the history
Signed-off-by: bingwang <[email protected]>
  • Loading branch information
bingwang-ms committed May 19, 2022
1 parent 0cc9fdc commit 1f0e3c2
Show file tree
Hide file tree
Showing 4 changed files with 1,892 additions and 10 deletions.
78 changes: 68 additions & 10 deletions src/sonic-config-engine/minigraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ def default(self, obj):

def get_peer_switch_info(link_metadata, devices):
peer_switch_table = {}
for data in link_metadata.values():
peer_switch_ip = None
mux_tunnel_name = None
for port, data in link_metadata.items():
if "PeerSwitch" in data:
peer_hostname = data["PeerSwitch"]
peer_lo_addr_str = devices[peer_hostname]["lo_addr"]
Expand All @@ -73,8 +75,10 @@ def get_peer_switch_info(link_metadata, devices):
peer_switch_table[peer_hostname] = {
'address_ipv4': str(peer_lo_addr.network_address) if peer_lo_addr else peer_lo_addr_str
}
mux_tunnel_name = port
peer_switch_ip = peer_switch_table[peer_hostname]['address_ipv4']

return peer_switch_table
return peer_switch_table, mux_tunnel_name, peer_switch_ip

def parse_device(device):
lo_prefix = None
Expand Down Expand Up @@ -400,6 +404,8 @@ def parse_dpg(dpg, hname):
mgmtintfs = None
subintfs = None
tunnelintfs = defaultdict(dict)
tunnelintfs_qos_remap_config = defaultdict(dict)

for child in dpg:
"""
In Multi-NPU platforms the acl intfs are defined only for the host not for individual asic.
Expand Down Expand Up @@ -707,6 +713,13 @@ def parse_dpg(dpg, hname):
"ecn_mode": "EcnDecapsulationMode",
"dscp_mode": "DifferentiatedServicesCodePointMode",
"ttl_mode": "TtlMode"}

tunnel_qos_remap_table_key_to_mg_key_map = {
"decap_dscp_to_tc_map": "DecapDscpToTcMap",
"decap_tc_to_pg_map": "DecapTcToPgMap",
"encap_tc_to_queue_map": "EncapTcToQueueMap",
"encap_tc_to_dscp_map": "EncapTcToDscpMap"}

for mg_tunnel in mg_tunnels.findall(str(QName(ns, "TunnelInterface"))):
tunnel_type = mg_tunnel.attrib["Type"]
tunnel_name = mg_tunnel.attrib["Name"]
Expand All @@ -718,9 +731,17 @@ def parse_dpg(dpg, hname):
# If the minigraph has the key, add the corresponding config DB key to the table
if mg_key in mg_tunnel.attrib:
tunnelintfs[tunnel_type][tunnel_name][table_key] = mg_tunnel.attrib[mg_key]

tunnelintfs_qos_remap_config[tunnel_type][tunnel_name] = {
"tunnel_type": mg_tunnel.attrib["Type"].upper(),
}

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
return None, None, None, None, None, None, None, None, None, None, None, None, None, None, None
for table_key, mg_key in tunnel_qos_remap_table_key_to_mg_key_map.items():
if mg_key in mg_tunnel.attrib:
tunnelintfs_qos_remap_config[tunnel_type][tunnel_name][table_key] = mg_tunnel.attrib[mg_key]

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
return None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None



Expand Down Expand Up @@ -899,6 +920,26 @@ def parse_meta(meta, hname):
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


def parse_system_defaults(meta):
system_default_values = {}

system_defaults = meta.find(str(QName(ns1, "SystemDefaults")))

for system_default in system_defaults.findall(str(QName(ns1, "SystemDefault"))):
name = system_default.find(str(QName(ns1, "Name"))).text
value = system_default.find(str(QName(ns1, "Value"))).text

# Tunnel Qos remapping
if name == "TunnelQosRemapEnabled":
if value.lower() == "true":
status = "enabled"
else:
status = "disabled"
system_default_values["tunnel_qos_remap"] = {"status": status}

return system_default_values


def parse_linkmeta(meta, hname):
link = meta.find(str(QName(ns, "Link")))
linkmetas = {}
Expand Down Expand Up @@ -1190,6 +1231,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
vlan_intfs = None
pc_intfs = None
tunnel_intfs = None
tunnel_intfs_qos_remap_config = None
vlans = None
vlan_members = None
dhcp_relay_table = None
Expand Down Expand Up @@ -1230,6 +1272,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
local_devices = []
kube_data = {}
static_routes = {}
system_defaults = {}

hwsku_qn = QName(ns, "HwSku")
hostname_qn = QName(ns, "Hostname")
Expand All @@ -1252,7 +1295,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
for child in root:
if asic_name is None:
if child.tag == str(QName(ns, "DpgDec")):
(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)
(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)
elif child.tag == str(QName(ns, "CpgDec")):
(bgp_sessions, bgp_internal_sessions, bgp_voq_chassis_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname)
elif child.tag == str(QName(ns, "PngDec")):
Expand All @@ -1265,9 +1308,11 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
linkmetas = parse_linkmeta(child, hostname)
elif child.tag == str(QName(ns, "DeviceInfos")):
(port_speeds_default, port_descriptions, sys_ports) = parse_deviceinfo(child, hwsku)
elif child.tag == str(QName(ns, "SystemDefaultsDeclaration")):
system_defaults = parse_system_defaults(child)
else:
if child.tag == str(QName(ns, "DpgDec")):
(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)
(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)
host_lo_intfs = parse_host_loopback(child, hostname)
elif child.tag == str(QName(ns, "CpgDec")):
(bgp_sessions, bgp_internal_sessions, bgp_voq_chassis_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name, local_devices)
Expand All @@ -1279,6 +1324,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
linkmetas = parse_linkmeta(child, hostname)
elif child.tag == str(QName(ns, "DeviceInfos")):
(port_speeds_default, port_descriptions, sys_ports) = parse_deviceinfo(child, hwsku)
elif child.tag == str(QName(ns, "SystemDefaultsDeclaration")):
system_defaults = parse_system_defaults(child)

# set the host device type in asic metadata also
device_type = [devices[key]['type'] for key in devices if key.lower() == hostname.lower()][0]
Expand Down Expand Up @@ -1314,8 +1361,11 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
'ip': kube_data.get('ip', '')
}
}

results['PEER_SWITCH'] = get_peer_switch_info(linkmetas, devices)

if len(system_defaults) > 0:
results['SYSTEM_DEFAULTS'] = system_defaults

results['PEER_SWITCH'], mux_tunnel_name, peer_switch_ip = get_peer_switch_info(linkmetas, devices)

if bool(results['PEER_SWITCH']):
results['DEVICE_METADATA']['localhost']['subtype'] = 'DualToR'
Expand Down Expand Up @@ -1609,7 +1659,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
results['VLAN'] = vlans
results['VLAN_MEMBER'] = vlan_members

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

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

Expand Down Expand Up @@ -1701,7 +1752,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw

return results

def get_tunnel_entries(tunnel_intfs, lo_intfs, hostname):
def get_tunnel_entries(tunnel_intfs, tunnel_intfs_qos_remap_config, lo_intfs, tunnel_qos_remap, mux_tunnel_name, peer_switch_ip):
lo_addr = ''
# Use the first IPv4 loopback as the tunnel destination IP
for addr in lo_intfs.keys():
Expand All @@ -1714,7 +1765,14 @@ def get_tunnel_entries(tunnel_intfs, lo_intfs, hostname):
for type, tunnel_dict in tunnel_intfs.items():
for tunnel_key, tunnel_attr in tunnel_dict.items():
tunnel_attr['dst_ip'] = lo_addr

if (tunnel_qos_remap.get('status') == 'enabled') and (mux_tunnel_name == tunnel_key) and (peer_switch_ip is not None):
tunnel_attr['src_ip'] = peer_switch_ip
if tunnel_key in tunnel_intfs_qos_remap_config[type]:
tunnel_attr.update(tunnel_intfs_qos_remap_config[type][tunnel_key].items())

tunnels[tunnel_key] = tunnel_attr

return tunnels

def get_mux_cable_entries(mux_cable_ports, neighbors, devices):
Expand Down
Loading

0 comments on commit 1f0e3c2

Please sign in to comment.