Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[202012][cherry-pick] Define SYSTEM_DEFAULTS table to control tunnel_qos_remap #10930

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 66 additions & 9 deletions src/sonic-config-engine/minigraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,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 @@ -74,8 +76,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 @@ -401,6 +405,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 @@ -688,6 +694,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 @@ -700,8 +713,16 @@ def parse_dpg(dpg, hname):
if mg_key in mg_tunnel.attrib:
tunnelintfs[tunnel_type][tunnel_name][table_key] = mg_tunnel.attrib[mg_key]

return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, dhcp_relay_table, pcs, pc_members, acls, vni, tunnelintfs, dpg_ecmp_content
return None, None, None, None, None, None, None, None, None, None, None, None, None
tunnelintfs_qos_remap_config[tunnel_type][tunnel_name] = {
"tunnel_type": mg_tunnel.attrib["Type"].upper(),
}

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, vlans, vlan_members, dhcp_relay_table, pcs, pc_members, acls, vni, tunnelintfs, dpg_ecmp_content, tunnelintfs_qos_remap_config
return None, None, None, None, None, None, None, None, None, None, None, None, None, None

def parse_host_loopback(dpg, hname):
for child in dpg:
Expand Down Expand Up @@ -863,6 +884,27 @@ def parse_meta(meta, hname):
kube_data["ip"] = value
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

def parse_system_defaults(meta):
system_default_values = {}

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

if system_defaults is None:
return system_default_values

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")))
Expand Down Expand Up @@ -1125,6 +1167,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 @@ -1159,6 +1202,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
is_storage_device = False
local_devices = []
kube_data = {}
system_defaults = {}

# hostname is the asic_name, get the asic_id from the asic_name
if asic_name is not None:
Expand Down Expand Up @@ -1187,7 +1231,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, vlans, vlan_members, dhcp_relay_table, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, hostname)
(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)
elif child.tag == str(QName(ns, "CpgDec")):
(bgp_sessions, bgp_internal_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname)
elif child.tag == str(QName(ns, "PngDec")):
Expand All @@ -1200,9 +1244,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) = 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, vlans, vlan_members, dhcp_relay_table, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, asic_name)
(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)
host_lo_intfs = parse_host_loopback(child, hostname)
elif child.tag == str(QName(ns, "CpgDec")):
(bgp_sessions, bgp_internal_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name, local_devices)
Expand All @@ -1214,6 +1260,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) = 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 @@ -1248,7 +1296,10 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
}
}

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 @@ -1508,7 +1559,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 @@ -1597,7 +1649,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 @@ -1610,6 +1662,11 @@ 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

Expand Down
Loading