[interfaces]: Combine vlan_interfaces and lag_interfaces file and add allow-hotplug (#381)

* [files]: Add allow-hotplug stanza to interfaces files

- start interface <interface_name> when the kernel detects
a hotplug event from the interface

ref: https://www.debian.org/doc/manuals/debian-reference/ch05.en.html

* [interfaces]: Combine vlan_interfaces and lag_interfaces file and add allow-hotplug

1. Remove vlan_interfaces and lag_interfaces file and members in teamd.j2
2. Add all interfaces to /etc/network/interfaces file
3. Add allow-hotplug stanza
4. Add up <command> to automatically add interfaces to VLAN and LAG
5. Add unique_name filter to minigraph.py to remove duplicate interface names
6. Add brctl to base image
7. Update sonic-swss submodule

Signed-off-by: Shuotian Cheng <shuche@microsoft.com>
This commit is contained in:
Shuotian Cheng 2017-03-16 11:22:40 -07:00 committed by GitHub
parent d6bfa505b3
commit 05e6b3611d
12 changed files with 95 additions and 65 deletions

View File

@ -0,0 +1,4 @@
#!/bin/bash
docker exec -i swss brctl "$@"

View File

@ -1,8 +1,6 @@
#!/bin/bash
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/interfaces.j2 >/etc/network/interfaces
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/vlan_interfaces.j2 >/etc/network/interfaces.d/vlan_interfaces
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/lag_interfaces.j2 >/etc/network/interfaces.d/lag_interfaces
ifdown eth0 && ifup eth0
ifdown lo && ifup lo

View File

@ -1,10 +1,10 @@
#
{% block banner %}
# =========== Managed by config engine DO NOT EDIT! ========================
# generated by templates/interfaces.j2 using sonic-cfggen
# file: interfaces
{% endblock %}
# =============== Managed by SONiC Config Engine DO NOT EDIT! ===============
# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen
# file: /etc/network/interfaces
#
{% endblock banner %}
{% block loopback %}
# The loopback network interface
auto lo
@ -17,7 +17,6 @@ iface lo {{ 'inet' if minigraph_lo_interface['addr'] | ipv4 else 'inet6' }} stat
#
{% endfor %}
{% endblock loopback %}
#
{% block mgmt_interface %}
# The management network interface
auto eth0
@ -25,26 +24,71 @@ auto eth0
iface eth0 inet static
address {{ minigraph_mgmt_interface['addr'] }}
netmask {{ minigraph_mgmt_interface['mask'] }}
################ management network policy routing rules
#### management port up 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
#### management port down rules"
# management port down rules
down ip route delete default via {{ minigraph_mgmt_interface['gwaddr'] }} dev eth0 table default
down ip rule delete from {{ minigraph_mgmt_interface['addr'] }}/32 table default
{# TODO: COPP policy type rules #}
{% else %}
iface eth0 inet dhcp
{% endif %}
{% endblock mgmt_interface %}
#
{% block front_panel_interface %}
{% endblock mgmt_interface %}
{% block front_panel_interfaces %}
# The switch front panel interfaces
{% for interface in minigraph_interfaces %}
auto {{ interface['alias'] }}
allow-hotplug {{ interface['alias'] }}
iface {{ interface['alias'] }} {{ 'inet' if interface['addr'] | ipv4 else 'inet6' }} static
address {{ interface['addr'] }}
netmask {{ interface['mask'] }}
#
{% endfor %}
{% endblock front_panel_interface %}
{% for vlan_interface in minigraph_vlan_interfaces|unique_name %}
{% for interface in vlan_interface['members'] %}
auto {{ interface }}
allow-hotplug {{ interface }}
iface {{ interface }} inet manual
pre-up ifconfig {{ interface }} up
post-up brctl addif {{ vlan_interface['name'] }} {{ interface }}
post-down ifconfig {{ interface }} down
#
{% endfor %}
{% endfor %}
# Add || true to suppress the error when docker-teamd starts after docker-swss
{% for pc_interface in minigraph_portchannel_interfaces|unique_name %}
{% for interface in pc_interface['members'] %}
{% if pc_interface['name'] not in pc_set %}
auto {{ interface }}
allow-hotplug {{ interface }}
iface {{ interface }} inet manual
pre-up teamdctl {{ pc_interface['name'] }} port add {{ interface }} || true
post-down ifconfig {{ interface }} down
#
{% endif %}
{% endfor %}
{% endfor %}
{% endblock front_panel_interfaces %}
{% block vlan_interfaces %}
{% for vlan_interface in minigraph_vlan_interfaces %}
auto {{ vlan_interface['name'] }}
allow-hotplug {{ vlan_interface['name'] }}
iface {{ vlan_interface['name'] }} {{ 'inet' if vlan_interface['addr'] | ipv4 else 'inet6' }} static
address {{ vlan_interface['addr'] }}
netmask {{ vlan_interface['mask'] }}
#
{% endfor %}
{% endblock vlan_interfaces %}
{% block pc_interfaces %}
{% for pc_interface in minigraph_portchannel_interfaces %}
auto {{ pc_interface['name'] }}
allow-hotplug {{ pc_interface['name'] }}
iface {{ pc_interface['name'] }} {{ 'inet' if pc_interface['addr'] | ipv4 else 'inet6' }} static
address {{ pc_interface['addr'] }}
netmask {{ pc_interface['mask'] }}
#
{% endfor %}
{% endblock pc_interfaces %}

View File

@ -1,20 +0,0 @@
#
{% block banner %}
# =========== Managed by config engine DO NOT EDIT! ========================
# generated by templates/lag_interfaces.j2 using sonic-cfggen
# file: lag_interfaces
{% endblock %}
#
{% block lag_interface %}
# The switch LAG interfaces
{% for interface in minigraph_interfaces %}
{% if 'PortChannel' in interface['alias'] %}
auto {{ interface['name'] }}
iface {{ interface['name'] }} {{ 'inet' if interface['addr'] | ipv4 else 'inet6' }} static
address {{ interface['addr'] }}
netmask {{ interface['mask'] }}
{% endif %}
{% endfor %}
{% endblock lag_interface %}
#

View File

@ -1,18 +0,0 @@
#
{% block banner %}
# =========== Managed by config engine DO NOT EDIT! ========================
# generated by templates/interfaces.j2 using sonic-cfggen
# file: vlan_interfaces
{% endblock %}
#
{% block vlan_interface %}
# The switch VLAN interfaces
{% for interface in minigraph_vlan_interfaces %}
auto {{ interface['name'] }}
iface {{ interface['name'] }} {{ 'inet' if interface['addr'] | ipv4 else 'inet6' }} static
bridge_ports {{ interface['members'] }}
address {{ interface['addr'] }}
netmask {{ interface['mask'] }}
{% endfor %}
{% endblock vlan_interface %}
#

View File

@ -16,3 +16,4 @@ $(DOCKER_ORCHAGENT_BRCM)_RUN_OPT += -v /host/machine.conf:/host/machine.conf
$(DOCKER_ORCHAGENT_BRCM)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
$(DOCKER_ORCHAGENT_BRCM)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel
$(DOCKER_ORCHAGENT_BRCM)_BASE_IMAGE_FILES += brctl:/usr/bin/brctl

View File

@ -16,3 +16,4 @@ $(DOCKER_ORCHAGENT_CAVM)_RUN_OPT += -v /host/machine.conf:/host/machine.conf
$(DOCKER_ORCHAGENT_CAVM)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
$(DOCKER_ORCHAGENT_CAVM)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel
$(DOCKER_ORCHAGENT_CAVM)_BASE_IMAGE_FILES += brctl:/usr/bin/brctl

View File

@ -16,3 +16,4 @@ $(DOCKER_ORCHAGENT_CENTEC)_RUN_OPT += -v /host/machine.conf:/host/machine.conf
$(DOCKER_ORCHAGENT_CENTEC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
$(DOCKER_ORCHAGENT_CENTEC)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel
$(DOCKER_ORCHAGENT_CENTEC)_BASE_IMAGE_FILES += brctl:/usr/bin/brctl

View File

@ -16,3 +16,4 @@ $(DOCKER_ORCHAGENT_MLNX)_RUN_OPT += -v /host/machine.conf:/host/machine.conf
$(DOCKER_ORCHAGENT_MLNX)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
$(DOCKER_ORCHAGENT_MLNX)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel
$(DOCKER_ORCHAGENT_MLNX)_BASE_IMAGE_FILES += brctl:/usr/bin/brctl

View File

@ -44,7 +44,7 @@ class minigraph_encoder(json.JSONEncoder):
if isinstance(obj, (ipaddress.IPv4Network, ipaddress.IPv6Network, ipaddress.IPv4Address, ipaddress.IPv6Address)):
return str(obj)
return json.JSONEncoder.default(self, obj)
def parse_png(png, hname):
neighbors = {}
devices = {}
@ -125,6 +125,7 @@ def parse_dpg(dpg, hname):
ipintfs = child.find(str(QName(ns, "IPInterfaces")))
intfs = []
vlan_map = {}
pc_map = {}
for ipintf in ipintfs.findall(str(QName(ns, "IPInterface"))):
intfname = ipintf.find(str(QName(ns, "AttachTo"))).text
ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text
@ -134,27 +135,31 @@ def parse_dpg(dpg, hname):
addr_bits = ipn.max_prefixlen
subnet = ipaddress.IPNetwork(str(ipn.network) + '/' + str(prefix_len))
ipmask = ipn.netmask
intf = {'addr': ipaddr, 'subnet': subnet}
if isinstance(ipn, ipaddress.IPv4Network):
intf['mask'] = ipmask
else:
intf['mask'] = str(prefix_len)
if intfname[0:4] == "Vlan":
if intfname in vlan_map:
vlan_map[intfname].append(intf)
else:
vlan_map[intfname] = [intf]
elif intfname[0:11] == "PortChannel":
if intfname in pc_map:
pc_map[intfname].append(intf)
else:
pc_map[intfname] = [intf]
else:
intf.update({'name': intfname, 'prefixlen': int(prefix_len)})
if port_alias_map.has_key(intfname):
intf['alias'] = port_alias_map[intfname]
else:
intf['alias'] = intfname
# TODO: remove peer_addr after dependency removed
ipaddr_val = int(ipn.ip)
peer_addr_val = None
@ -168,13 +173,13 @@ def parse_dpg(dpg, hname):
peer_addr_val = ipaddr_val + 1
else:
peer_addr_val = ipaddr_val - 1
if peer_addr_val is not None:
intf['peer_addr'] = ipaddress.IPAddress(peer_addr_val)
intfs.append(intf)
pcintfs = child.find(str(QName(ns, "PortChannelInterfaces")))
pc_intfs = {}
pc_intfs = []
for pcintf in pcintfs.findall(str(QName(ns, "PortChannel"))):
pcintfname = pcintf.find(str(QName(ns, "Name"))).text
pcintfmbr = pcintf.find(str(QName(ns, "AttachTo"))).text
@ -182,7 +187,10 @@ def parse_dpg(dpg, hname):
for i,member in enumerate(pcmbr_list):
if port_alias_map.has_key(member):
pcmbr_list[i] = port_alias_map[member]
pc_intfs[pcintfname] = pcmbr_list
pc_attributes = {'name': pcintfname, 'members': pcmbr_list}
for addrtuple in pc_map.get(pcintfname, []):
pc_attributes.update(addrtuple)
pc_intfs.append(copy.deepcopy(pc_attributes))
lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces")))
lo_intfs = []
@ -221,12 +229,12 @@ def parse_dpg(dpg, hname):
for i,member in enumerate(vmbr_list):
if port_alias_map.has_key(member):
vmbr_list[i] = port_alias_map[member]
vlan_attributes = {'name': vintfname, 'members': " ".join(vmbr_list), 'vlanid': vlanid}
vlan_attributes = {'name': vintfname, 'members': vmbr_list, 'vlanid': vlanid}
for addrtuple in vlan_map.get(vintfname, []):
vlan_attributes.update(addrtuple)
vlan_intfs.append(copy.deepcopy(vlan_attributes))
return intfs, lo_intfs, mgmt_intf, vlan_intfs, pc_intfs
return None, None, None, None, None
@ -284,7 +292,7 @@ def parse_meta(meta, hname):
ntp_servers = value_group
elif name == "SyslogResources":
syslog_servers = value_group
return syslog_servers, dhcp_servers, ntp_servers
return syslog_servers, dhcp_servers, ntp_servers
def get_console_info(devices, dev, port):
for k, v in devices.items():
@ -330,7 +338,7 @@ def get_alias_map_list(hwsku, platform=None):
break
if port_config == None:
return None
alias_map_list = []
with open(port_config) as data:
for line in data:

View File

@ -35,6 +35,15 @@ def is_ipv6(value):
return False
return addr.version == 6
def unique_name(l):
name_list = []
new_list = []
for item in l:
if item['name'] not in name_list:
name_list.append(item['name'])
new_list.append(item)
return new_list
def get_machine_info():
if not os.path.isfile('/host/machine.conf'):
return None
@ -91,6 +100,7 @@ def main():
env = jinja2.Environment(loader=jinja2.FileSystemLoader('/'), trim_blocks=True)
env.filters['ipv4'] = is_ipv4
env.filters['ipv6'] = is_ipv6
env.filters['unique_name'] = unique_name
template = env.get_template(template_file)
print template.render(data)

@ -1 +1 @@
Subproject commit dc33b7549e57719d7855b1f7929b38b9b519072b
Subproject commit 6f06b59971e5ee75b721d3630878ba03f28f9831