diff --git a/dockers/docker-orchagent/base_image_files/brctl b/dockers/docker-orchagent/base_image_files/brctl new file mode 100755 index 0000000000..b02d74479f --- /dev/null +++ b/dockers/docker-orchagent/base_image_files/brctl @@ -0,0 +1,4 @@ +#!/bin/bash + +docker exec -i swss brctl "$@" + diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index f8b54790c9..f36f45b555 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -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 diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 6d1476963e..acf7b247fc 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -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 %} diff --git a/files/image_config/interfaces/lag_interfaces.j2 b/files/image_config/interfaces/lag_interfaces.j2 deleted file mode 100644 index 0b5e24b618..0000000000 --- a/files/image_config/interfaces/lag_interfaces.j2 +++ /dev/null @@ -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 %} -# - diff --git a/files/image_config/interfaces/vlan_interfaces.j2 b/files/image_config/interfaces/vlan_interfaces.j2 deleted file mode 100644 index 6d85d7910e..0000000000 --- a/files/image_config/interfaces/vlan_interfaces.j2 +++ /dev/null @@ -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 %} -# diff --git a/platform/broadcom/docker-orchagent-brcm.mk b/platform/broadcom/docker-orchagent-brcm.mk index e49b67c2c2..37fdb9c66a 100644 --- a/platform/broadcom/docker-orchagent-brcm.mk +++ b/platform/broadcom/docker-orchagent-brcm.mk @@ -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 diff --git a/platform/cavium/docker-orchagent-cavm.mk b/platform/cavium/docker-orchagent-cavm.mk index 8130ca8dc1..65ddd9eac2 100644 --- a/platform/cavium/docker-orchagent-cavm.mk +++ b/platform/cavium/docker-orchagent-cavm.mk @@ -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 diff --git a/platform/centec/docker-orchagent-centec.mk b/platform/centec/docker-orchagent-centec.mk index 0613fb510d..a3738f6aa2 100644 --- a/platform/centec/docker-orchagent-centec.mk +++ b/platform/centec/docker-orchagent-centec.mk @@ -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 diff --git a/platform/mellanox/docker-orchagent-mlnx.mk b/platform/mellanox/docker-orchagent-mlnx.mk index 505804fb8c..d081e8af5f 100644 --- a/platform/mellanox/docker-orchagent-mlnx.mk +++ b/platform/mellanox/docker-orchagent-mlnx.mk @@ -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 diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index afd4538f13..7cba925928 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -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: diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 90a905c5b3..93f27a3044 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -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) diff --git a/src/sonic-swss b/src/sonic-swss index dc33b7549e..6f06b59971 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit dc33b7549e57719d7855b1f7929b38b9b519072b +Subproject commit 6f06b59971e5ee75b721d3630878ba03f28f9831