From 27fb241012f580c4d563dcf2442008b908c4e36e Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Fri, 30 Oct 2020 20:17:54 +0000 Subject: [PATCH] [minigraph.py]: Address review comments * Allow tunnel dst_ip from multiple loopback IPs (the first IPv4 loopback IP is used) * Remove restrictions on tunnel types parsed * Only add fields to tunnel table if the corresponding minigraph attributes are present Signed-off-by: Lawrence Lee --- src/sonic-config-engine/minigraph.py | 38 +++++++++++++------ .../tests/test_minigraph_case.py | 4 +- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 4ebda5c10a42..0d28a63a8e89 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -1,6 +1,7 @@ from __future__ import print_function import calendar +from ipaddress import IPv4Address, ip_address import math import os import sys @@ -476,15 +477,22 @@ def parse_dpg(dpg, hname): mg_tunnels = child.find(str(QName(ns, "TunnelInterfaces"))) if mg_tunnels is not None: + table_key_to_mg_key_map = {"encap_ecn_mode": "EcnEncapsulationMode", + "ecn_mode": "EcnDecapsulationMode", + "dscp_mode": "DifferentiatedServicesCodePointMode", + "ttl_mode": "TtlMode"} for mg_tunnel in mg_tunnels.findall(str(QName(ns, "TunnelInterface"))): - tunnel_num = "".join([x for x in mg_tunnel.attrib["Name"] if x.isdigit()]) - tunnelintfs[mg_tunnel.attrib["Type"]]["MUX_TUNNEL_{}".format(tunnel_num)] = { + tunnel_type = mg_tunnel.attrib["Type"] + tunnel_name = mg_tunnel.attrib["Name"] + tunnelintfs[tunnel_type][tunnel_name] = { "tunnel_type": mg_tunnel.attrib["Type"].upper(), - "encap_ecn_mode": mg_tunnel.attrib["EcnEncapsulationMode"], - "ecn_mode": mg_tunnel.attrib["EcnDecapsulationMode"], - "dscp_mode": mg_tunnel.attrib["DifferentiatedServicesCodePointMode"], - "ttl_mode": mg_tunnel.attrib["TtlMode"] } + + for table_key, mg_key in table_key_to_mg_key_map.items(): + # 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] + return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnelintfs return None, None, None, None, None, None, None, None, None, None @@ -1146,7 +1154,7 @@ 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_ipinip_tunnels(tunnel_intfs, devices, hostname) + results['TUNNEL'] = get_tunnel_entries(tunnel_intfs, lo_intfs, hostname) for nghbr in list(neighbors.keys()): # remove port not in port_config.ini @@ -1215,13 +1223,19 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw return results -def get_ipinip_tunnels(tunnel_intfs, devices, hostname): +def get_tunnel_entries(tunnel_intfs, lo_intfs, hostname): + lo_addr = '' + # Use the first IPv4 loopback as the tunnel destination IP + for addr in lo_intfs.keys(): + if "." in addr[1]: + lo_addr = addr[1] + break + tunnels = {} for type, tunnel_dict in tunnel_intfs.items(): - if type == "IPInIP": - for tunnel_key, tunnel_attr in tunnel_dict.items(): - tunnel_attr['dst_ip'] = devices[hostname]['lo_addr'] - tunnels[tunnel_key] = tunnel_attr + for tunnel_key, tunnel_attr in tunnel_dict.items(): + tunnel_attr['dst_ip'] = lo_addr + tunnels[tunnel_key] = tunnel_attr return tunnels diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index d2d4adca6354..66e887269b82 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -189,9 +189,9 @@ def test_minigraph_tunnel_table(self): result = minigraph.parse_xml(self.sample_graph, self.port_config) argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "TUNNEL"' expected_tunnel = { - "MUX_TUNNEL_0": { + "MuxTunnel0": { "tunnel_type": "IPINIP", - "dst_ip": "26.1.1.10", + "dst_ip": "10.1.0.32/32", "dscp_mode": "uniform", "encap_ecn_mode": "standard", "ecn_mode": "copy_from_outer",