diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 425badf7f21..40b2cc1746a 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -20,11 +20,13 @@ iface lo {{ 'inet' if minigraph_lo_interface['addr'] | ipv4 else 'inet6' }} stat {% block mgmt_interface %} # The management network interface auto eth0 -{% if minigraph_mgmt_interface['addr'] %} +{% if minigraph_mgmt_interfaces | length %} +{% for minigraph_mgmt_interface in minigraph_mgmt_interfaces %} +{% if minigraph_mgmt_interface['addr'] | ipv4 %} iface eth0 inet static address {{ minigraph_mgmt_interface['addr'] }} netmask {{ minigraph_mgmt_interface['mask'] }} - ########## management network policy routing rules + ## management network policy routing rules ## # management port up rules up ip route add default via {{ minigraph_mgmt_interface['gwaddr'] }} dev eth0 table default up ip rule add from {{ minigraph_mgmt_interface['addr'] }}/32 table default @@ -39,9 +41,16 @@ iface eth0 inet static {% endfor %} {# TODO: COPP policy type rules #} {% else %} -iface eth0 inet dhcp +iface eth0 inet6 static + address {{ minigraph_mgmt_interface['addr'] }} + netmask {{ minigraph_mgmt_interface['mask'] }} {% endif %} # +{% endfor %} +{% else %} +iface eth0 inet dhcp +# +{% endif %} {% endblock mgmt_interface %} {% block front_panel_interfaces %} # The switch front panel interfaces diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 1fd16f376fa..c9cf73c417a 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -167,32 +167,23 @@ def parse_dpg(dpg, hname): intf['peer_addr'] = ipaddress.IPAddress(peer_addr_val) intfs.append(intf) - lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) - lo_intfs = [] - for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): - intfname = lointf.find(str(QName(ns, "AttachTo"))).text - ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text - ipn = ipaddress.IPNetwork(ipprefix) - ipaddr = ipn.ip - prefix_len = ipn.prefixlen - ipmask = ipn.netmask - lo_intf = {'name': intfname, 'addr': ipaddr, 'prefixlen': prefix_len} - if isinstance(ipn, ipaddress.IPv4Network): - lo_intf['mask'] = ipmask - else: - lo_intf['mask'] = str(prefix_len) - lo_intfs.append(lo_intf) - - mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) - mgmt_intf = None - for mgmtintf in mgmtintfs.findall(str(QName(ns1, "ManagementIPInterface"))): - ipprefix = mgmtintf.find(str(QName(ns1, "PrefixStr"))).text - mgmtipn = ipaddress.IPNetwork(ipprefix) - ipaddr = mgmtipn.ip - prefix_len = str(mgmtipn.prefixlen) - ipmask = mgmtipn.netmask - gwaddr = ipaddress.IPAddress(int(mgmtipn.network) + 1) - mgmt_intf = {'addr': ipaddr, 'prefixlen': prefix_len, 'mask': ipmask, 'gwaddr': gwaddr} + def _parse_ip_interface(interfaces, interface): + intfs = child.find(str(QName(ns, interfaces))) + rv = [] + for intf in intfs.findall(str(QName(ns1, interface))): + intf_name = intf.find(str(QName(ns, "AttachTo"))).text + intf_ip = ipaddress.IPNetwork(intf.find(str(QName(ns1, "PrefixStr"))).text) + intf = {'name': intf_name, 'addr': intf_ip.ip, 'prefixlen': intf_ip.prefixlen} + if intf_ip.version == 4: + intf['mask'] = intf_ip.netmask + else: + intf['mask'] = str(intf_ip.prefixlen) + intf['gwaddr'] = ipaddress.IPAddress(int(intf_ip.network) + 1) + rv.append(intf) + return rv + + lo_intfs = _parse_ip_interface("LoopbackIPInterfaces", "LoopbackIPInterface") + mgmt_intfs = _parse_ip_interface("ManagementIPInterfaces", "ManagementIPInterface") pcintfs = child.find(str(QName(ns, "PortChannelInterfaces"))) pc_intfs = [] @@ -241,7 +232,7 @@ def parse_dpg(dpg, hname): break; if acl_intfs: acls[aclname] = { 'AttachTo': acl_intfs, 'IsMirror': is_mirror } - return intfs, lo_intfs, mgmt_intf, vlans, pcs, acls + return intfs, lo_intfs, mgmt_intfs, vlans, pcs, acls return None, None, None, None, None, None @@ -404,8 +395,8 @@ def parse_xml(filename, platform=None, port_config_file=None): pc_intfs = None vlans = None pcs = None - mgmt_intf = None - lo_intf = None + lo_intfs = None + mgmt_intfs = None neighbors = None devices = None hostname = None @@ -429,7 +420,7 @@ def parse_xml(filename, platform=None, port_config_file=None): for child in root: if child.tag == str(QName(ns, "DpgDec")): - (intfs, lo_intfs, mgmt_intf, vlans, pcs, acls) = parse_dpg(child, hostname) + (intfs, lo_intfs, mgmt_intfs, vlans, pcs, acls) = parse_dpg(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range) = parse_cpg(child, hostname) elif child.tag == str(QName(ns, "PngDec")): @@ -467,7 +458,7 @@ def parse_xml(filename, platform=None, port_config_file=None): results['minigraph_ports'] = ports results['minigraph_vlans'] = vlans results['minigraph_portchannels'] = pcs - results['minigraph_mgmt_interface'] = mgmt_intf + results['minigraph_mgmt_interfaces'] = mgmt_intfs results['minigraph_lo_interfaces'] = lo_intfs results['minigraph_acls'] = acls results['minigraph_neighbors'] = neighbors diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces new file mode 100644 index 00000000000..af21a79b2f9 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -0,0 +1,263 @@ +# +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen +# file: /etc/network/interfaces +# +# The loopback network interface +auto lo +iface lo inet loopback +# Use command 'ip addr list dev lo' to check all addresses +iface lo inet static + address 10.1.0.32 + netmask 255.255.255.255 +# +iface lo inet6 static + address fc00:1::32 + netmask 128 +# +# The management network interface +auto eth0 +iface eth0 inet static + address 10.0.0.100 + netmask 255.255.255.0 + ## management network policy routing rules ## + # management port up rules + up ip route add default via 10.0.0.1 dev eth0 table default + up ip rule add from 10.0.0.100/32 table default + # management port down rules + down ip route delete default via 10.0.0.1 dev eth0 table default + down ip rule delete from 10.0.0.100/32 table default +# +iface eth0 inet6 static + address 2603:10e2:0:2903::7 + netmask 64 +# +# The switch front panel interfaces +# "|| true" is added to suppress the error when interface is already a member of VLAN +allow-hotplug fortyGigE0/4 +iface fortyGigE0/4 inet manual + pre-up ifconfig fortyGigE0/4 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/4 || true + post-down ifconfig fortyGigE0/4 down +# +allow-hotplug fortyGigE0/8 +iface fortyGigE0/8 inet manual + pre-up ifconfig fortyGigE0/8 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/8 || true + post-down ifconfig fortyGigE0/8 down +# +allow-hotplug fortyGigE0/12 +iface fortyGigE0/12 inet manual + pre-up ifconfig fortyGigE0/12 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/12 || true + post-down ifconfig fortyGigE0/12 down +# +allow-hotplug fortyGigE0/16 +iface fortyGigE0/16 inet manual + pre-up ifconfig fortyGigE0/16 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/16 || true + post-down ifconfig fortyGigE0/16 down +# +allow-hotplug fortyGigE0/20 +iface fortyGigE0/20 inet manual + pre-up ifconfig fortyGigE0/20 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/20 || true + post-down ifconfig fortyGigE0/20 down +# +allow-hotplug fortyGigE0/24 +iface fortyGigE0/24 inet manual + pre-up ifconfig fortyGigE0/24 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/24 || true + post-down ifconfig fortyGigE0/24 down +# +allow-hotplug fortyGigE0/28 +iface fortyGigE0/28 inet manual + pre-up ifconfig fortyGigE0/28 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/28 || true + post-down ifconfig fortyGigE0/28 down +# +allow-hotplug fortyGigE0/32 +iface fortyGigE0/32 inet manual + pre-up ifconfig fortyGigE0/32 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/32 || true + post-down ifconfig fortyGigE0/32 down +# +allow-hotplug fortyGigE0/36 +iface fortyGigE0/36 inet manual + pre-up ifconfig fortyGigE0/36 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/36 || true + post-down ifconfig fortyGigE0/36 down +# +allow-hotplug fortyGigE0/40 +iface fortyGigE0/40 inet manual + pre-up ifconfig fortyGigE0/40 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/40 || true + post-down ifconfig fortyGigE0/40 down +# +allow-hotplug fortyGigE0/44 +iface fortyGigE0/44 inet manual + pre-up ifconfig fortyGigE0/44 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/44 || true + post-down ifconfig fortyGigE0/44 down +# +allow-hotplug fortyGigE0/48 +iface fortyGigE0/48 inet manual + pre-up ifconfig fortyGigE0/48 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/48 || true + post-down ifconfig fortyGigE0/48 down +# +allow-hotplug fortyGigE0/52 +iface fortyGigE0/52 inet manual + pre-up ifconfig fortyGigE0/52 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/52 || true + post-down ifconfig fortyGigE0/52 down +# +allow-hotplug fortyGigE0/56 +iface fortyGigE0/56 inet manual + pre-up ifconfig fortyGigE0/56 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/56 || true + post-down ifconfig fortyGigE0/56 down +# +allow-hotplug fortyGigE0/60 +iface fortyGigE0/60 inet manual + pre-up ifconfig fortyGigE0/60 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/60 || true + post-down ifconfig fortyGigE0/60 down +# +allow-hotplug fortyGigE0/64 +iface fortyGigE0/64 inet manual + pre-up ifconfig fortyGigE0/64 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/64 || true + post-down ifconfig fortyGigE0/64 down +# +allow-hotplug fortyGigE0/68 +iface fortyGigE0/68 inet manual + pre-up ifconfig fortyGigE0/68 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/68 || true + post-down ifconfig fortyGigE0/68 down +# +allow-hotplug fortyGigE0/72 +iface fortyGigE0/72 inet manual + pre-up ifconfig fortyGigE0/72 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/72 || true + post-down ifconfig fortyGigE0/72 down +# +allow-hotplug fortyGigE0/76 +iface fortyGigE0/76 inet manual + pre-up ifconfig fortyGigE0/76 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/76 || true + post-down ifconfig fortyGigE0/76 down +# +allow-hotplug fortyGigE0/80 +iface fortyGigE0/80 inet manual + pre-up ifconfig fortyGigE0/80 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/80 || true + post-down ifconfig fortyGigE0/80 down +# +allow-hotplug fortyGigE0/84 +iface fortyGigE0/84 inet manual + pre-up ifconfig fortyGigE0/84 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/84 || true + post-down ifconfig fortyGigE0/84 down +# +allow-hotplug fortyGigE0/88 +iface fortyGigE0/88 inet manual + pre-up ifconfig fortyGigE0/88 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/88 || true + post-down ifconfig fortyGigE0/88 down +# +allow-hotplug fortyGigE0/92 +iface fortyGigE0/92 inet manual + pre-up ifconfig fortyGigE0/92 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/92 || true + post-down ifconfig fortyGigE0/92 down +# +allow-hotplug fortyGigE0/96 +iface fortyGigE0/96 inet manual + pre-up ifconfig fortyGigE0/96 up mtu 9216 + post-up brctl addif Vlan1000 fortyGigE0/96 || true + post-down ifconfig fortyGigE0/96 down +# +# "|| true" is added to suppress the error when interface is already a member of LAG +# "ip link show | grep -q master" is added to ensure interface is enslaved +allow-hotplug fortyGigE0/112 +iface fortyGigE0/112 inet manual + pre-up teamdctl PortChannel01 port add fortyGigE0/112 || true + post-up ip link show fortyGigE0/112 | grep -q master && ifconfig fortyGigE0/112 up + post-down ifconfig fortyGigE0/112 down +# +allow-hotplug fortyGigE0/116 +iface fortyGigE0/116 inet manual + pre-up teamdctl PortChannel02 port add fortyGigE0/116 || true + post-up ip link show fortyGigE0/116 | grep -q master && ifconfig fortyGigE0/116 up + post-down ifconfig fortyGigE0/116 down +# +allow-hotplug fortyGigE0/120 +iface fortyGigE0/120 inet manual + pre-up teamdctl PortChannel03 port add fortyGigE0/120 || true + post-up ip link show fortyGigE0/120 | grep -q master && ifconfig fortyGigE0/120 up + post-down ifconfig fortyGigE0/120 down +# +allow-hotplug fortyGigE0/124 +iface fortyGigE0/124 inet manual + pre-up teamdctl PortChannel04 port add fortyGigE0/124 || true + post-up ip link show fortyGigE0/124 | grep -q master && ifconfig fortyGigE0/124 up + post-down ifconfig fortyGigE0/124 down +# +# Vlan interfaces +auto Vlan1000 +iface Vlan1000 inet static + bridge_ports none + address 192.168.0.1 + netmask 255.255.255.224 +# +# Portchannel interfaces +allow-hotplug PortChannel01 +iface PortChannel01 inet static + mtu 9216 + address 10.0.0.56 + netmask 255.255.255.254 +# +allow-hotplug PortChannel01 +iface PortChannel01 inet6 static + mtu 9216 + address fc00::71 + netmask 126 +# +allow-hotplug PortChannel02 +iface PortChannel02 inet static + mtu 9216 + address 10.0.0.58 + netmask 255.255.255.254 +# +allow-hotplug PortChannel02 +iface PortChannel02 inet6 static + mtu 9216 + address fc00::75 + netmask 126 +# +allow-hotplug PortChannel03 +iface PortChannel03 inet static + mtu 9216 + address 10.0.0.60 + netmask 255.255.255.254 +# +allow-hotplug PortChannel03 +iface PortChannel03 inet6 static + mtu 9216 + address fc00::79 + netmask 126 +# +allow-hotplug PortChannel04 +iface PortChannel04 inet static + mtu 9216 + address 10.0.0.62 + netmask 255.255.255.254 +# +allow-hotplug PortChannel04 +iface PortChannel04 inet6 static + mtu 9216 + address fc00::7d + netmask 126 +# + diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index e359b4fa629..f92e5d5a4cd 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -163,6 +163,14 @@ 10.0.0.100/24 + + HostIP + eth0 + + 2603:10e2:0:2903::7/64 + + 2603:10e2:0:2903::7/64 + diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 238d8c81551..809acea0512 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -20,8 +20,9 @@ def run_script(self, argument): def test_interfaces(self): interfaces_template = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'interfaces', 'interfaces.j2') - argument = '-m "' + self.t0_minigraph + '" -p "' + self.t0_port_config + '" -t "' + interfaces_template + '"' - output = self.run_script(argument) + argument = '-m ' + self.t0_minigraph + ' -t ' + interfaces_template + ' > ' + self.output_file + self.run_script(argument) + self.assertTrue(filecmp.cmp(self.output_file, os.path.join(self.test_dir, 'sample_output', 'interfaces'))) def test_alias_map(self): alias_map_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-snmp-sv2', 'alias_map.j2')