From 423177e81c5bc04ae04183b7d5571d5350346a09 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Mon, 9 Mar 2020 13:52:12 -0700 Subject: [PATCH 01/69] hostcfgd service enhancements: 1.Added support for Dynamic handling of Management port config(MTU, Speed, auto negotiation, admin status and Description config attributes), 2. Added support for Dynamic handling of Management interface config (IPv4/IPv6 DHCP client, IPv4/IPv6 default gateway, IPv4/IPv6 addresses config and respective gateways config attributes) and Management VRF handling. --- build_debian.sh | 2 + files/dhcp/dhcp_mgmt_conf.py | 42 ++ files/dhcp/dhcp_mgmt_interface | 53 +++ files/image_config/hostcfgd/hostcfgd | 548 +++++++++++++++++++++++++++ 4 files changed, 645 insertions(+) create mode 100644 files/dhcp/dhcp_mgmt_conf.py create mode 100644 files/dhcp/dhcp_mgmt_interface diff --git a/build_debian.sh b/build_debian.sh index 37db2bdeb44..401d4ccb4ea 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -442,6 +442,8 @@ sudo cp files/dhcp/sethostname6 $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/graphserviceurl $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/snmpcommunity $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/vrf $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ +sudo cp files/dhcp/dhcp_mgmt_interface $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ +sudo cp files/dhcp/dhcp_mgmt_conf.py $FILESYSTEM_ROOT/usr/bin/ if [ -f files/image_config/ntp/ntp ]; then sudo cp ./files/image_config/ntp/ntp $FILESYSTEM_ROOT/etc/init.d/ fi diff --git a/files/dhcp/dhcp_mgmt_conf.py b/files/dhcp/dhcp_mgmt_conf.py new file mode 100644 index 00000000000..25cc5a80f88 --- /dev/null +++ b/files/dhcp/dhcp_mgmt_conf.py @@ -0,0 +1,42 @@ +#!/usr/bin/python -u +# -*- coding: utf-8 -*- + +import os +import re +import sys +import subprocess +import syslog +import ipaddress +import netaddr +from swsssdk import ConfigDBConnector + +APP_MGMT_INTF_TABLE = "MGMT_INTF_TABLE" + +def update_dhcp_mgmt_ip_info(): + app_db = ConfigDBConnector() + app_db.db_connect('APPL_DB', wait_for_init=False, retry_on=True) + appdb_entry = {} + appdb_entry["NULL"] = "NULL" + + op = sys.argv[2] + plen = ipaddress.ip_network((0, sys.argv[4])).prefixlen + key = sys.argv[1] + ":" + sys.argv[3] + "/" + str(plen) + syslog.syslog(syslog.LOG_INFO, "update_dhcp_mgmt_ip_info : op - {}, key - {}".format(op, key)) + if op == "add": + app_db.set_entry(APP_MGMT_INTF_TABLE, key, appdb_entry) + elif op == "del": + app_db.delete_entry(APP_MGMT_INTF_TABLE, key) + return + +if __name__ == "__main__": + if len(sys.argv) < 5: + syslog.syslog(syslog.LOG_INFO, "number of arguments not correct") + syslog.syslog(syslog.LOG_INFO, "usage:") + syslog.syslog(syslog.LOG_INFO, "dhcp_mgmt_conf.py ") + else: + syslog.syslog(syslog.LOG_INFO, "Args : {}".format(sys.argv)) + update_dhcp_mgmt_ip_info() + + + + diff --git a/files/dhcp/dhcp_mgmt_interface b/files/dhcp/dhcp_mgmt_interface new file mode 100644 index 00000000000..fc20c88f4ec --- /dev/null +++ b/files/dhcp/dhcp_mgmt_interface @@ -0,0 +1,53 @@ +#!/bin/sh +# +# DHCLIENT exit hook for ip address update in app db +# + + +set -x + +PYTHON_PATH=/usr/bin/python +SCRIPT=/usr/bin/dhcp_mgmt_conf.py + + +dhcp_mgmt_conf_handle() { + IF_NAME=$interface + echo "dhcp_mgmt_conf_handle, interface : $IF_NAME" + + if [ "$IF_NAME" = "eth0" ]; then + echo "DHCP exit hook is called for $IF_NAME, reason : $reason" + + case $reason in + BOUND|REBOOT|BOUND6) + if [ -n "$new_ip_address" ] && [ -n "$new_subnet_mask" ]; then + + $PYTHON_PATH $SCRIPT $IF_NAME add $new_ip_address $new_subnet_mask + fi + ;; + RENEW|REBIND|RENEW6|REBIND6) + if [ -n "$old_ip_address" ] && [ -n "$old_subnet_mask" ]; then + $PYTHON_PATH $SCRIPT $IF_NAME del $old_ip_address $old_subnet_mask + fi + + if [ -n "$new_ip_address" ] && [ -n "$new_subnet_mask" ]; then + $PYTHON_PATH $SCRIPT $IF_NAME add $new_ip_address $new_subnet_mask + fi + + ;; + EXPIRE|FAIL|RELEASE|STOP) + if [ -n "$new_ip_address" ] && [ -n "$new_subnet_mask" ]; then + $PYTHON_PATH $SCRIPT $IF_NAME del $new_ip_address $new_subnet_mask + fi + + if [ -n "$old_ip_address" ] && [ -n "$old_subnet_mask" ]; then + $PYTHON_PATH $SCRIPT $IF_NAME del $old_ip_address $old_subnet_mask + fi + ;; + TIMEOUT) + ;; + esac + fi +} + +echo "dhcp_mgmt_conf" +dhcp_mgmt_conf_handle diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 4ac3be83d06..7730302c6d4 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -8,6 +8,7 @@ import syslog import copy import jinja2 import ipaddr as ipaddress +import netaddr from swsssdk import ConfigDBConnector # FILE @@ -219,6 +220,539 @@ class AaaCfg(object): with open(NSS_TACPLUS_CONF, 'w') as f: f.write(nss_tacplus_conf) +#Management interface and Management VRF config handling + +MGMT_INTF_ADMIN_STATUS_DEFAULT = "up" +CFG_MGMT_PORT_TABLE = "MGMT_PORT" +CFG_MGMT_INTF_TABLE = "MGMT_INTERFACE" +APP_MGMT_PORT_TABLE = "MGMT_PORT_TABLE" +APP_MGMT_INTF_TABLE = "MGMT_INTF_TABLE" +CFG_MGMT_VRF = "MGMT_VRF_CONFIG" +CFG_MGMT_VRF_KEY = "vrf_global" +MGMT_VRF_TABLE_ID = 5000 + +class MgmtVrfCfg: + def __init__(self, config_db): + syslog.syslog(syslog.LOG_INFO, 'Initializing MGMT VRF handler') + self.config_db = config_db + self.mgmt_vrf_table_created = False + + def create_mgmt_vrf_table(self): + if self.mgmt_vrf_table_created == False: + syslog.syslog(syslog.LOG_INFO, "Create MGMT VRF table:") + cmd = 'ip link add name mgmt type vrf table {}'.format(MGMT_VRF_TABLE_ID) + syslog.syslog(syslog.LOG_INFO, "Create MGMT VRF table, cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + self.mgmt_vrf_table_created = True + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + + def delete_mgmt_vrf_table(self): + if self.mgmt_vrf_table_created == True: + syslog.syslog(syslog.LOG_INFO, "Delete MGMT VRF table:") + cmd = 'ip link delete mgmt' + syslog.syslog(syslog.LOG_INFO, "Delete MGMT VRF table, cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + self.mgmt_vrf_table_created = False + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + + def configure_mgmt_vrf(self): + syslog.syslog(syslog.LOG_INFO, "Configure MGMT VRF:") + + self.create_mgmt_vrf_table() + + cmd = 'ip link set dev mgmt up' + syslog.syslog(syslog.LOG_INFO, "Set MGMT VRF up, cmd - {}".format(cmd)) + + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + syslog.syslog(syslog.LOG_INFO, "Add lo intf:") + cmd = 'ip link add lo-m type dummy' + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + cmd = 'ip addr add 127.0.0.1/8 dev lo-m' + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + cmd = 'ip link set lo-m up' + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + cmd = 'ip link set dev lo-m master mgmt' + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + self.bind_mgmt_intf() + + def bind_mgmt_intf(self): + syslog.syslog(syslog.LOG_INFO, "Handle MGMT intf:") + keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) + syslog.syslog(syslog.LOG_INFO, "MGMT interfaces keys: {}".format(str(keys))) + + mgmt_intf_bound = False + for it in keys: + if type(it) is unicode: + mgmt_intf_name = it + + cmd = 'ip link set dev {} master mgmt'.format(mgmt_intf_name) + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + cmd = 'sysctl -w net.ipv4.tcp_l3mdev_accept=1' + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + mgmt_intf_bound = True + break + if not mgmt_intf_bound: + syslog.syslog(syslog.LOG_ERR, "MGMT VRF: MGMT interface not bound") + else: + for it in keys: + if type(it) is unicode: + key = it + else: + key = it[0] + "|" + it[1] + + entry = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, key) + if 'gwaddr' in entry: + mgmt_intf_gwaddr = entry['gwaddr'] + cmd = 'ip route add table {} 0.0.0.0/0 via {}'.format(MGMT_VRF_TABLE_ID, mgmt_intf_gwaddr) + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + def unconfigure_mgmt_vrf(self): + syslog.syslog(syslog.LOG_INFO, "Unconfigure MGMT VRF:") + + cmd = 'ip link delete lo-m' + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + + self.delete_mgmt_vrf_table() + return + + def handle_mgmt_intf_gwaddr_cfg(self, op, ifname, gwaddr): + syslog.syslog(syslog.LOG_INFO, "Received MGMT Intf gwaddr config, op: {}, ifname: {}, gwaddr: {}".format(op, ifname, gwaddr)) + keys = self.config_db.get_keys(CFG_MGMT_VRF) + if keys: + syslog.syslog(syslog.LOG_INFO, "MGMT VRF created") + cmd = 'ip route del table {} 0.0.0.0/0'.format(MGMT_VRF_TABLE_ID) + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + pass + + if op == "ADD": + cmd = 'ip route add table {} 0.0.0.0/0 via {}'.format(MGMT_VRF_TABLE_ID, gwaddr) + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + pass + + return True + + def handle_mgmt_intf_creation(self, mgmt_intf_key): + syslog.syslog(syslog.LOG_INFO, "Received MGMT Intf creation, key: {}".format(mgmt_intf_key)) + keys = self.config_db.get_keys(CFG_MGMT_VRF) + if keys: + syslog.syslog(syslog.LOG_INFO, "MGMT VRF created") + self.bind_mgmt_intf() + + def handle_mgmt_vrf_cfg(self, key, data): + syslog.syslog(syslog.LOG_INFO, "Received MGMT VRF config, key: {}, data: {}".format(key, data)) + try: + if data: + if data['mgmtVrfEnabled'] == 'true': + self.configure_mgmt_vrf() + else: + self.unconfigure_mgmt_vrf() + else: + self.unconfigure_mgmt_vrf() + except: + syslog.syslog(syslog.LOG_ERR, "{} MGMT VRF Configuration failed.".format(key)) + + + +class MgmtIntfCfg: + def __init__(self, cfg_db, mgmt_vrf_cfg): + self.app_db = ConfigDBConnector() + self.app_db.db_connect('APPL_DB', wait_for_init=False, retry_on=True) + self.config_db = cfg_db + self.mgmt_vrf_cfg = mgmt_vrf_cfg + syslog.syslog(syslog.LOG_INFO, 'AppDB connect success') + + self.mgmt_intf_handle_default_cfg("eth0") + + def mgmt_intf_handle_default_cfg (self, ifname): + mgmt_intf = self.config_db.get_entry(CFG_MGMT_PORT_TABLE, ifname) + if mgmt_intf == {}: + mgmt_intf['mtu'] = "1500" + mgmt_intf['speed'] = "1000" + mgmt_intf['admin_status'] = MGMT_INTF_ADMIN_STATUS_DEFAULT + mgmt_intf['autoneg'] = "true" + mgmt_intf['description'] = "Management0" + syslog.syslog(syslog.LOG_INFO, "Default config populated for {}".format(ifname)) + self.config_db.set_entry(CFG_MGMT_PORT_TABLE, ifname, mgmt_intf) + + self.handle_mgmt_port_cfg(ifname, mgmt_intf) + + mgmt_intf = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, ifname) + if mgmt_intf == {}: + mgmt_intf['ipv4_dhcp_client'] = "true" + mgmt_intf['ipv6_dhcp_client'] = "true" + self.config_db.set_entry(CFG_MGMT_INTF_TABLE, ifname, mgmt_intf) + self.app_db.set_entry(APP_MGMT_INTF_TABLE, ifname, mgmt_intf) + + def mgmt_intf_mtu_set (self, ifname, mtu, appIntf): + cmd = 'ifconfig {} mtu {}'.format(ifname, mtu) + syslog.syslog(syslog.LOG_INFO, "Configure MTU, cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + appIntf['mtu'] = mtu + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + + def mgmt_intf_admin_status_set (self, ifname, admin_status, appIntf): + cmd = 'ifconfig {} {}'.format(ifname, admin_status) + syslog.syslog(syslog.LOG_INFO, "Configure admin_status, cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + appIntf['admin_status'] = admin_status + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + + def mgmt_intf_description_set (self, ifname, description, appIntf): + syslog.syslog(syslog.LOG_INFO, "Configure description, cmd - {}".format(description)) + appIntf['description'] = description + + def mgmt_intf_speed_set (self, ifname, speed, autoneg, appIntf): + duplex = "full" + cmd = 'ethtool -s {} speed {} duplex {} autoneg {}; ifup {}'.format(ifname, speed, duplex, autoneg, ifname) + syslog.syslog(syslog.LOG_INFO, "Configure SPEED, cmd - {}".format(cmd)) + + try: + subprocess.check_call(cmd, shell=True) + appIntf['speed'] = speed + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + + def mgmt_intf_autoneg_set (self, ifname, autoneg, appIntf): + an = "on" + if autoneg == "true": + an = "on" + elif autoneg == "false": + an = "off" + + cmd = "ethtool -s {} autoneg {}".format(ifname, an) + syslog.syslog(syslog.LOG_INFO, "Configure autoneg, cmd - {}".format(cmd)) + + try: + subprocess.check_call(cmd, shell=True) + appIntf['autoneg'] = autoneg + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + + def mgmt_intf_gwaddr_set(self, ifname, ip_prefix, gwaddr, op): + if not self.mgmt_vrf_cfg.handle_mgmt_intf_gwaddr_cfg(op, ifname, gwaddr): + try: + ip_conf = netaddr.IPNetwork(ip_prefix) + if op == "DELETE": + cmd = "ip route del {}/{} via {} dev {}".format(ip_conf.network, ip_conf.prefixlen, gwaddr, ifname) + else: + cmd = "ip route add {}/{} via {} dev {}".format(ip_conf.network, ip_conf.prefixlen, gwaddr, ifname) + + syslog.syslog(syslog.LOG_INFO, "Configure gwaddr , cmd : {}".format(cmd)) + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + pass + + def mgmt_intf_default_gwaddr_set (self, ifname, default_gw, op): + try: + if op == "DELETE": + cmd = "ip route del default via {} dev {}".format(default_gw, ifname) + else: + cmd = "ip route add default via {} dev {}".format(default_gw, ifname) + + syslog.syslog(syslog.LOG_INFO, "Configure Default Gateway, cmd : {}".format(cmd)) + + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + pass + + def mgmt_intf_dhclient_set (self, ifname, attr, enable): + version = "" + file_ext = "" + cmd_opt = "" + + if attr == "ipv6_dhcp_client": + version = "-6" + file_ext = "6" + cmd_opt = "-D LL" + + if enable == True: + try: + path = "/var/run/dhclient{}.{}.pid".format(file_ext, ifname) + if os.path.exists(path): + cmd = "[ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(file_ext, ifname, file_ext, ifname, file_ext, ifname) + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + pass + + try: + if enable == True: + cmd = "/sbin/dhclient {} -pf /run/dhclient{}.{}.pid -lf /var/lib/dhcp/dhclient{}.{}.leases {} -nw {} ".format(version, file_ext, ifname, file_ext, ifname, ifname, cmd_opt) + else: + cmd = "/sbin/dhclient {} -r {} && [ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(version, ifname, file_ext, ifname, file_ext, ifname, file_ext, ifname) + + syslog.syslog(syslog.LOG_INFO, "Configure dhclient , cmd : {}".format(cmd)) + + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + pass + + def mgmt_intf_ip_prefix_set (self, ifname, ip_prefix, op): + try: + if op == "DELETE": + reset_prefix = "0.0.0.0" + mgmt_conf = netaddr.IPNetwork(reset_prefix) + cmd = "ip addr del {} dev {}".format(ip_prefix, ifname) + else: + mgmt_conf = netaddr.IPNetwork(ip_prefix) + cmd = "ip addr add {} dev {}".format(ip_prefix, ifname) + + syslog.syslog(syslog.LOG_INFO, "Configure ip_prefix, op : {}, ip_prefix: {}, cmd : {}, mgmt_conf: {}".format(op, ip_prefix, cmd, mgmt_conf)) + subprocess.check_call(cmd, shell=True) + cmd = "ip rule add from {} table default".format(str(mgmt_conf.ip)) + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + pass + + def handle_mgmt_port_cfg(self, key, data): + mgmt_intf = self.app_db.get_entry(APP_MGMT_PORT_TABLE, key) + is_all = False + if mgmt_intf == {}: + is_all = True + + try: + if (('mtu' in data) and ((is_all == True) or (mgmt_intf == {}) or ('mtu' not in mgmt_intf) or (data['mtu'] != mgmt_intf['mtu']))): + self.mgmt_intf_mtu_set(key, data['mtu'], mgmt_intf) + + if (('description' in data) and ((is_all == True) or (mgmt_intf == {}) or ('description' not in mgmt_intf) or (data['description'] != mgmt_intf['description']))): + self.mgmt_intf_description_set(key, data['description'], mgmt_intf) + + if (('admin_status' in data) and ((is_all == True) or (mgmt_intf == {}) or ('admin_status' not in mgmt_intf) or (data['admin_status'] != mgmt_intf['admin_status']))): + self.mgmt_intf_admin_status_set(key, data['admin_status'], mgmt_intf) + + if (('autoneg' in data) and ((is_all == True) or (mgmt_intf == {}) or ('autoneg' not in mgmt_intf) or (data['autoneg'] != mgmt_intf['autoneg']))): + self.mgmt_intf_autoneg_set(key, data['autoneg'], mgmt_intf) + + if (('speed' in data) and ((is_all == True) or (mgmt_intf == {}) or ('speed' not in mgmt_intf) or (data['speed'] != mgmt_intf['speed']))): + autoneg = "on" + if 'autoneg' in data: + if data['autoneg'] == "false": + autoneg = "off" + self.mgmt_intf_speed_set(key, data['speed'], autoneg, mgmt_intf) + except: + syslog.syslog(syslog.LOG_ERR, "{} MGMT Port Config set failed.".format(key)) + + self.app_db.set_entry(APP_MGMT_PORT_TABLE, key, mgmt_intf) + + + def handle_mgmt_intf_cfg(self, key, data): + cur_appdb_key = key.replace('|', ':') + intf_keys = key.split("|") + cfgdb_entry = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, key) + appdb_entry = self.app_db.get_entry(APP_MGMT_INTF_TABLE, cur_appdb_key) + op = "DELETE" + keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) + + for it in keys: + if len(it) != 2: + it = (it, ) + it_key = it[0] + else: + it_key = it[0] + "|" + it[1] + + if it_key == key: + op = "CREATE" + break + + if op == "CREATE": + if cfgdb_entry != {} and appdb_entry != {}: + op = "UPDATE" + + + if (len(intf_keys) < 2): + if op == "DELETE": + cfgdb_entry['ipv4_dhcp_client'] = "true" + cfgdb_entry['ipv6_dhcp_client'] = "true" + + if (('ipv4_dhcp_client' not in appdb_entry) or (appdb_entry['ipv4_dhcp_client'] != cfgdb_entry['ipv4_dhcp_client'])): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", True) + appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] + + if (('ipv6_dhcp_client' not in appdb_entry) or (appdb_entry['ipv6_dhcp_client'] != cfgdb_entry['ipv6_dhcp_client'])): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", True) + appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] + + if ('ipv4_default_gwaddr' in appdb_entry): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DELETE") + del appdb_entry['ipv4_default_gwaddr'] + + if ('ipv6_default_gwaddr' in appdb_entry): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DELETE") + del appdb_entry['ipv6_default_gwaddr'] + + self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) + self.config_db.set_entry(CFG_MGMT_INTF_TABLE, key, cfgdb_entry) + + elif op == "CREATE": + syslog.syslog(syslog.LOG_ERR, "handle_mgmt_intf_cfg: operation is CREATE, return after vrf create handling") + self.mgmt_vrf_cfg.handle_mgmt_intf_creation(key) + + if ('ipv4_dhcp_client' in cfgdb_entry): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", cfgdb_entry['ipv4_dhcp_client'] == "true") + appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] + + if ('ipv6_dhcp_client' in cfgdb_entry): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", cfgdb_entry['ipv6_dhcp_client'] == "true") + appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] + + if ('ipv4_default_gwaddr' in cfgdb_entry): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") + appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] + + if ('ipv6_default_gwaddr' in cfgdb_entry): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") + appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] + + self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) + + elif op == "UPDATE": + if (('ipv4_dhcp_client' in cfgdb_entry) and ('ipv4_dhcp_client' not in appdb_entry)): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", cfgdb_entry['ipv4_dhcp_client'] == "true") + appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] + elif (('ipv4_dhcp_client' in cfgdb_entry) and (cfgdb_entry['ipv4_dhcp_client'] != appdb_entry['ipv4_dhcp_client'])): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", cfgdb_entry['ipv4_dhcp_client'] == "true") + appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] + + if (('ipv6_dhcp_client' in cfgdb_entry) and ('ipv6_dhcp_client' not in appdb_entry)): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", cfgdb_entry['ipv6_dhcp_client'] == "true") + appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] + elif (('ipv6_dhcp_client' in cfgdb_entry) and (cfgdb_entry['ipv6_dhcp_client'] != appdb_entry['ipv6_dhcp_client'])): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", cfgdb_entry['ipv6_dhcp_client'] == "true") + appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] + + if (('ipv4_default_gwaddr' in cfgdb_entry) and ('ipv4_default_gwaddr' not in appdb_entry)): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") + appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] + elif (('ipv4_default_gwaddr' in cfgdb_entry) and (cfgdb_entry['ipv4_default_gwaddr'] != appdb_entry['ipv4_default_gwaddr'])): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") + appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] + elif (('ipv4_default_gwaddr' not in cfgdb_entry) and ('ipv4_default_gwaddr' in appdb_entry)): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DELETE") + del appdb_entry['ipv4_default_gwaddr'] + + if (('ipv6_default_gwaddr' in cfgdb_entry) and ('ipv6_default_gwaddr' not in appdb_entry)): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") + appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] + elif (('ipv6_default_gwaddr' in cfgdb_entry) and (cfgdb_entry['ipv6_default_gwaddr'] != appdb_entry['ipv6_default_gwaddr'])): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") + appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] + elif (('ipv6_default_gwaddr' not in cfgdb_entry) and ('ipv6_default_gwaddr' in appdb_entry)): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DELETE") + del appdb_entry['ipv6_default_gwaddr'] + + self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) + else: + input_ip = ipaddress.IPNetwork(intf_keys[1]) + if op == "CREATE" or op == "UPDATE" : + self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "ADD") + if (('gwaddr' in data) and ((appdb_entry == {}) or ('gwaddr' not in appdb_entry))): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") + appdb_entry['gwaddr'] = data['gwaddr'] + elif (('gwaddr' in data) and ('gwaddr' not in cfgdb_entry) and ('gwaddr' in appdb_entry)): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'],"DELETE") + del appdb_entry['gwaddr'] + elif (('gwaddr' in data) and (data['gwaddr'] != appdb_entry['gwaddr'])): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'],"DELETE") + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") + appdb_entry['gwaddr'] = data['gwaddr'] + + if appdb_entry == {}: + appdb_entry["NULL"] = "NULL" + + self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) + + else: + self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "DELETE") + if ('gwaddr' in data): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "DELETE") + self.app_db.delete_entry(APP_MGMT_INTF_TABLE, cur_appdb_key) + + class HostConfigDaemon: def __init__(self): @@ -230,6 +764,8 @@ class HostConfigDaemon: tacacs_server = self.config_db.get_table('TACPLUS_SERVER') self.aaacfg = AaaCfg() self.aaacfg.load(aaa, tacacs_global, tacacs_server) + self.mgmtvrfcfg = MgmtVrfCfg(self.config_db) + self.mgmtcfg = MgmtIntfCfg(self.config_db, self.mgmtvrfcfg) lpbk_table = self.config_db.get_table('LOOPBACK_INTERFACE') self.iptables = Iptables() self.iptables.load(lpbk_table) @@ -262,6 +798,15 @@ class HostConfigDaemon: self.iptables.iptables_handler(key, data, add) + def mgmt_vrf_handler(self, key, data): + self.mgmtvrfcfg.handle_mgmt_vrf_cfg(key, data) + + def mgmt_port_handler(self, key, data): + self.mgmtcfg.handle_mgmt_port_cfg(key, data) + + def mgmt_intf_handler(self, key, data): + self.mgmtcfg.handle_mgmt_intf_cfg(key, data) + def feature_status_handler(self, key, data): status_data = self.config_db.get_table('FEATURE') for key in status_data.keys(): @@ -307,6 +852,9 @@ class HostConfigDaemon: self.config_db.subscribe('TACPLUS', lambda table, key, data: self.tacacs_global_handler(key, data)) self.config_db.subscribe('LOOPBACK_INTERFACE', lambda table, key, data: self.lpbk_handler(key, data)) self.config_db.subscribe('FEATURE', lambda table, key, data: self.feature_status_handler(key, data)) + self.config_db.subscribe(CFG_MGMT_VRF, lambda table, key, data: self.mgmt_vrf_handler(key, data)) + self.config_db.subscribe(CFG_MGMT_PORT_TABLE, lambda table, key, data: self.mgmt_port_handler(key, data)) + self.config_db.subscribe(CFG_MGMT_INTF_TABLE, lambda table, key, data: self.mgmt_intf_handler(key, data)) self.config_db.listen() From eacfbf61dee4eb543cda2cd01780dbad60710497 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Mon, 30 Mar 2020 13:41:23 -0700 Subject: [PATCH 02/69] Fixed issue in adding and deleting ipv6 config. --- files/image_config/hostcfgd/hostcfgd | 56 ++++++++++++++-------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 7730302c6d4..1d953f4ec0b 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -512,10 +512,11 @@ class MgmtIntfCfg: if not self.mgmt_vrf_cfg.handle_mgmt_intf_gwaddr_cfg(op, ifname, gwaddr): try: ip_conf = netaddr.IPNetwork(ip_prefix) - if op == "DELETE": - cmd = "ip route del {}/{} via {} dev {}".format(ip_conf.network, ip_conf.prefixlen, gwaddr, ifname) - else: - cmd = "ip route add {}/{} via {} dev {}".format(ip_conf.network, ip_conf.prefixlen, gwaddr, ifname) + ver = "-4" + if ip_conf.version == 6: + ver = "-6" + + cmd = "ip {} route {} {}/{} via {} dev {}".format(ver, op.lower(), ip_conf.network, ip_conf.prefixlen, gwaddr, ifname) syslog.syslog(syslog.LOG_INFO, "Configure gwaddr , cmd : {}".format(cmd)) subprocess.check_call(cmd, shell=True) @@ -525,13 +526,14 @@ class MgmtIntfCfg: def mgmt_intf_default_gwaddr_set (self, ifname, default_gw, op): try: - if op == "DELETE": - cmd = "ip route del default via {} dev {}".format(default_gw, ifname) - else: - cmd = "ip route add default via {} dev {}".format(default_gw, ifname) + ver = "-4" + mgmt_conf = netaddr.IPNetwork(default_gw) + if mgmt_conf.version == 6: + ver = "-6" - syslog.syslog(syslog.LOG_INFO, "Configure Default Gateway, cmd : {}".format(cmd)) + cmd = "ip {} route {} default via {} dev {}".format(ver, op.lower(), default_gw, ifname) + syslog.syslog(syslog.LOG_INFO, "Configure Default Gateway, cmd : {}".format(cmd)) subprocess.check_call(cmd, shell=True) except subprocess.CalledProcessError as err: syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) @@ -571,17 +573,14 @@ class MgmtIntfCfg: def mgmt_intf_ip_prefix_set (self, ifname, ip_prefix, op): try: - if op == "DELETE": - reset_prefix = "0.0.0.0" - mgmt_conf = netaddr.IPNetwork(reset_prefix) - cmd = "ip addr del {} dev {}".format(ip_prefix, ifname) - else: - mgmt_conf = netaddr.IPNetwork(ip_prefix) - cmd = "ip addr add {} dev {}".format(ip_prefix, ifname) - + ver = "-4" + mgmt_conf = netaddr.IPNetwork(ip_prefix) + if mgmt_conf.version == 6: + ver = "-6" + cmd = "ip {} addr {} {} dev {}".format(ver, op.lower(), ip_prefix, ifname) syslog.syslog(syslog.LOG_INFO, "Configure ip_prefix, op : {}, ip_prefix: {}, cmd : {}, mgmt_conf: {}".format(op, ip_prefix, cmd, mgmt_conf)) subprocess.check_call(cmd, shell=True) - cmd = "ip rule add from {} table default".format(str(mgmt_conf.ip)) + cmd = "ip {} rule {} from {} table default pref 1003".format(ver, op.lower(), str(mgmt_conf.ip)) subprocess.check_call(cmd, shell=True) except subprocess.CalledProcessError as err: syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) @@ -656,11 +655,11 @@ class MgmtIntfCfg: appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] if ('ipv4_default_gwaddr' in appdb_entry): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DEL") del appdb_entry['ipv4_default_gwaddr'] if ('ipv6_default_gwaddr' in appdb_entry): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DEL") del appdb_entry['ipv6_default_gwaddr'] self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) @@ -707,37 +706,36 @@ class MgmtIntfCfg: self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] elif (('ipv4_default_gwaddr' in cfgdb_entry) and (cfgdb_entry['ipv4_default_gwaddr'] != appdb_entry['ipv4_default_gwaddr'])): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DEL") self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] elif (('ipv4_default_gwaddr' not in cfgdb_entry) and ('ipv4_default_gwaddr' in appdb_entry)): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DEL") del appdb_entry['ipv4_default_gwaddr'] if (('ipv6_default_gwaddr' in cfgdb_entry) and ('ipv6_default_gwaddr' not in appdb_entry)): self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] elif (('ipv6_default_gwaddr' in cfgdb_entry) and (cfgdb_entry['ipv6_default_gwaddr'] != appdb_entry['ipv6_default_gwaddr'])): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DEL") self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] elif (('ipv6_default_gwaddr' not in cfgdb_entry) and ('ipv6_default_gwaddr' in appdb_entry)): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DEL") del appdb_entry['ipv6_default_gwaddr'] self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) else: - input_ip = ipaddress.IPNetwork(intf_keys[1]) if op == "CREATE" or op == "UPDATE" : self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "ADD") if (('gwaddr' in data) and ((appdb_entry == {}) or ('gwaddr' not in appdb_entry))): self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") appdb_entry['gwaddr'] = data['gwaddr'] elif (('gwaddr' in data) and ('gwaddr' not in cfgdb_entry) and ('gwaddr' in appdb_entry)): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'],"DELETE") + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'],"DEL") del appdb_entry['gwaddr'] elif (('gwaddr' in data) and (data['gwaddr'] != appdb_entry['gwaddr'])): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'],"DELETE") + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'],"DEL") self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") appdb_entry['gwaddr'] = data['gwaddr'] @@ -747,9 +745,9 @@ class MgmtIntfCfg: self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) else: - self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "DELETE") + self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "DEL") if ('gwaddr' in data): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "DELETE") + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "DEL") self.app_db.delete_entry(APP_MGMT_INTF_TABLE, cur_appdb_key) From f6fd9fb35a1dd13d4c8ba07b56ab30e3922458d0 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Tue, 21 Apr 2020 16:13:56 -0700 Subject: [PATCH 03/69] Addressed review comments, Added support for handling forced_mgmt_routes and interfaces.j2 cleaup related to mgmt interface. --- files/image_config/hostcfgd/hostcfgd | 497 ++++++++------------ files/image_config/interfaces/interfaces.j2 | 63 +-- 2 files changed, 202 insertions(+), 358 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 1d953f4ec0b..946e32c3f98 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -241,25 +241,15 @@ class MgmtVrfCfg: if self.mgmt_vrf_table_created == False: syslog.syslog(syslog.LOG_INFO, "Create MGMT VRF table:") cmd = 'ip link add name mgmt type vrf table {}'.format(MGMT_VRF_TABLE_ID) - syslog.syslog(syslog.LOG_INFO, "Create MGMT VRF table, cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) + if run_command(cmd) == True: self.mgmt_vrf_table_created = True - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) def delete_mgmt_vrf_table(self): if self.mgmt_vrf_table_created == True: syslog.syslog(syslog.LOG_INFO, "Delete MGMT VRF table:") cmd = 'ip link delete mgmt' - syslog.syslog(syslog.LOG_INFO, "Delete MGMT VRF table, cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) + if run_command(cmd) == True: self.mgmt_vrf_table_created = False - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) def configure_mgmt_vrf(self): syslog.syslog(syslog.LOG_INFO, "Configure MGMT VRF:") @@ -267,50 +257,24 @@ class MgmtVrfCfg: self.create_mgmt_vrf_table() cmd = 'ip link set dev mgmt up' - syslog.syslog(syslog.LOG_INFO, "Set MGMT VRF up, cmd - {}".format(cmd)) - - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return syslog.syslog(syslog.LOG_INFO, "Add lo intf:") cmd = 'ip link add lo-m type dummy' - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return cmd = 'ip addr add 127.0.0.1/8 dev lo-m' - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return cmd = 'ip link set lo-m up' - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return cmd = 'ip link set dev lo-m master mgmt' - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return self.bind_mgmt_intf() @@ -326,21 +290,11 @@ class MgmtVrfCfg: mgmt_intf_name = it cmd = 'ip link set dev {} master mgmt'.format(mgmt_intf_name) - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return cmd = 'sysctl -w net.ipv4.tcp_l3mdev_accept=1' - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return mgmt_intf_bound = True @@ -358,51 +312,29 @@ class MgmtVrfCfg: if 'gwaddr' in entry: mgmt_intf_gwaddr = entry['gwaddr'] cmd = 'ip route add table {} 0.0.0.0/0 via {}'.format(MGMT_VRF_TABLE_ID, mgmt_intf_gwaddr) - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return def unconfigure_mgmt_vrf(self): syslog.syslog(syslog.LOG_INFO, "Unconfigure MGMT VRF:") cmd = 'ip link delete lo-m' - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == True: + self.delete_mgmt_vrf_table() - self.delete_mgmt_vrf_table() return def handle_mgmt_intf_gwaddr_cfg(self, op, ifname, gwaddr): syslog.syslog(syslog.LOG_INFO, "Received MGMT Intf gwaddr config, op: {}, ifname: {}, gwaddr: {}".format(op, ifname, gwaddr)) keys = self.config_db.get_keys(CFG_MGMT_VRF) if keys: - syslog.syslog(syslog.LOG_INFO, "MGMT VRF created") cmd = 'ip route del table {} 0.0.0.0/0'.format(MGMT_VRF_TABLE_ID) - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) - pass + run_command(cmd) if op == "ADD": cmd = 'ip route add table {} 0.0.0.0/0 via {}'.format(MGMT_VRF_TABLE_ID, gwaddr) - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) - pass - - return True + run_command(cmd) + return True def handle_mgmt_intf_creation(self, mgmt_intf_key): syslog.syslog(syslog.LOG_INFO, "Received MGMT Intf creation, key: {}".format(mgmt_intf_key)) @@ -424,6 +356,44 @@ class MgmtVrfCfg: except: syslog.syslog(syslog.LOG_ERR, "{} MGMT VRF Configuration failed.".format(key)) + def mgmt_vrf_table_get(self): + vrf_table = 'default' + entry = self.config_db.get_entry(CFG_MGMT_VRF, CFG_MGMT_VRF_KEY) + if entry: + if (('mgmtVrfEnabled' in entry) and (entry['mgmtVrfEnabled'] == 'true')): + vrf_table = '5000' + + return vrf_table + + + + +def run_command(cmd): + syslog.syslog(syslog.LOG_INFO, "Config cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return False + + return True + +def cfg_attr_set (cmd, attr = None, value = None, appIntf = None): + + rc = run_command(cmd) + if appIntf != None and rc == True: + appIntf[attr] = value + + return rc + +def is_attr_cfg_required (attr, cfg_data, app_data, cfgAllAtrr = True): + rc = False + + if ((cfgAllAtrr == True) or (attr not in app_data) or (cfg_data[attr] != app_data[attr])): + rc = True + + return rc class MgmtIntfCfg: @@ -458,39 +428,19 @@ class MgmtIntfCfg: def mgmt_intf_mtu_set (self, ifname, mtu, appIntf): cmd = 'ifconfig {} mtu {}'.format(ifname, mtu) - syslog.syslog(syslog.LOG_INFO, "Configure MTU, cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - appIntf['mtu'] = mtu - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + cfg_attr_set(cmd, 'mtu', mtu, appIntf) def mgmt_intf_admin_status_set (self, ifname, admin_status, appIntf): cmd = 'ifconfig {} {}'.format(ifname, admin_status) - syslog.syslog(syslog.LOG_INFO, "Configure admin_status, cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - appIntf['admin_status'] = admin_status - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + cfg_attr_set(cmd, 'admin_status', admin_status, appIntf) def mgmt_intf_description_set (self, ifname, description, appIntf): - syslog.syslog(syslog.LOG_INFO, "Configure description, cmd - {}".format(description)) appIntf['description'] = description def mgmt_intf_speed_set (self, ifname, speed, autoneg, appIntf): duplex = "full" cmd = 'ethtool -s {} speed {} duplex {} autoneg {}; ifup {}'.format(ifname, speed, duplex, autoneg, ifname) - syslog.syslog(syslog.LOG_INFO, "Configure SPEED, cmd - {}".format(cmd)) - - try: - subprocess.check_call(cmd, shell=True) - appIntf['speed'] = speed - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + cfg_attr_set(cmd, 'speed', speed, appIntf) def mgmt_intf_autoneg_set (self, ifname, autoneg, appIntf): an = "on" @@ -500,44 +450,18 @@ class MgmtIntfCfg: an = "off" cmd = "ethtool -s {} autoneg {}".format(ifname, an) - syslog.syslog(syslog.LOG_INFO, "Configure autoneg, cmd - {}".format(cmd)) - - try: - subprocess.check_call(cmd, shell=True) - appIntf['autoneg'] = autoneg - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + cfg_attr_set(cmd, 'autoneg', autoneg, appIntf) def mgmt_intf_gwaddr_set(self, ifname, ip_prefix, gwaddr, op): - if not self.mgmt_vrf_cfg.handle_mgmt_intf_gwaddr_cfg(op, ifname, gwaddr): - try: - ip_conf = netaddr.IPNetwork(ip_prefix) - ver = "-4" - if ip_conf.version == 6: - ver = "-6" + vrf_table = self.mgmt_vrf_cfg.mgmt_vrf_table_get() + ip_conf = netaddr.IPNetwork(ip_prefix) + ver = "-4" + if ip_conf.version == 6: + ver = "-6" - cmd = "ip {} route {} {}/{} via {} dev {}".format(ver, op.lower(), ip_conf.network, ip_conf.prefixlen, gwaddr, ifname) + cmd = "ip {} route {} default via {} dev {} table {}".format(ver, op.lower(), gwaddr, ifname, vrf_table) + cfg_attr_set(cmd) - syslog.syslog(syslog.LOG_INFO, "Configure gwaddr , cmd : {}".format(cmd)) - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) - pass - - def mgmt_intf_default_gwaddr_set (self, ifname, default_gw, op): - try: - ver = "-4" - mgmt_conf = netaddr.IPNetwork(default_gw) - if mgmt_conf.version == 6: - ver = "-6" - - cmd = "ip {} route {} default via {} dev {}".format(ver, op.lower(), default_gw, ifname) - - syslog.syslog(syslog.LOG_INFO, "Configure Default Gateway, cmd : {}".format(cmd)) - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) - pass def mgmt_intf_dhclient_set (self, ifname, attr, enable): version = "" @@ -550,69 +474,76 @@ class MgmtIntfCfg: cmd_opt = "-D LL" if enable == True: - try: - path = "/var/run/dhclient{}.{}.pid".format(file_ext, ifname) - if os.path.exists(path): - cmd = "[ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(file_ext, ifname, file_ext, ifname, file_ext, ifname) - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - pass + path = "/var/run/dhclient{}.{}.pid".format(file_ext, ifname) + if os.path.exists(path): + cmd = "[ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(file_ext, ifname, file_ext, ifname, file_ext, ifname) + run_command(cmd) - try: - if enable == True: - cmd = "/sbin/dhclient {} -pf /run/dhclient{}.{}.pid -lf /var/lib/dhcp/dhclient{}.{}.leases {} -nw {} ".format(version, file_ext, ifname, file_ext, ifname, ifname, cmd_opt) - else: - cmd = "/sbin/dhclient {} -r {} && [ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(version, ifname, file_ext, ifname, file_ext, ifname, file_ext, ifname) - - syslog.syslog(syslog.LOG_INFO, "Configure dhclient , cmd : {}".format(cmd)) + if enable == True: + cmd = "/sbin/dhclient {} -pf /run/dhclient{}.{}.pid -lf /var/lib/dhcp/dhclient{}.{}.leases {} -nw {} ".format(version, file_ext, ifname, file_ext, ifname, ifname, cmd_opt) + else: + cmd = "/sbin/dhclient {} -r {} && [ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(version, ifname, file_ext, ifname, file_ext, ifname, file_ext, ifname) - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) - pass + run_command(cmd) def mgmt_intf_ip_prefix_set (self, ifname, ip_prefix, op): - try: - ver = "-4" - mgmt_conf = netaddr.IPNetwork(ip_prefix) - if mgmt_conf.version == 6: - ver = "-6" - cmd = "ip {} addr {} {} dev {}".format(ver, op.lower(), ip_prefix, ifname) - syslog.syslog(syslog.LOG_INFO, "Configure ip_prefix, op : {}, ip_prefix: {}, cmd : {}, mgmt_conf: {}".format(op, ip_prefix, cmd, mgmt_conf)) - subprocess.check_call(cmd, shell=True) - cmd = "ip {} rule {} from {} table default pref 1003".format(ver, op.lower(), str(mgmt_conf.ip)) - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) - pass + ver = "-4" + mgmt_conf = netaddr.IPNetwork(ip_prefix) + if mgmt_conf.version == 6: + ver = "-6" + + cmd = "ip {} addr {} {} dev {}".format(ver, op.lower(), ip_prefix, ifname) + cfg_attr_set(cmd) + + cmd = "ip {} rule {} from {} table default".format(ver, op.lower(), str(mgmt_conf.ip)) + cfg_attr_set(cmd) + + def mgmt_intf_forced_mgmt_routes_set (self, ifname, ip_prefix, forced_routes, op, app_forced_routes = []): + vrf_table = self.mgmt_vrf_cfg.mgmt_vrf_table_get() + if op == "UPDATE": + routes_add = [] + routes_del = [] + for cfg_route in forced_routes: + if cfg_route not in app_forced_routes: + routes_add.append(cfg_route) + + for cfg_route in app_forced_routes: + if cfg_route not in forced_routes: + routes_del.append(cfg_route) + + self.mgmt_intf_forced_mgmt_routes_set(ifname, ip_prefix, routes_del, "DEL") + self.mgmt_intf_forced_mgmt_routes_set(ifname, ip_prefix, routes_add, "ADD") + return routes_add + else: + for route in forced_routes: + cmd = "ip rule {} to {} table {}".format(op.lower(), route, vrf_table) + cfg_attr_set(cmd) + return forced_routes + def handle_mgmt_port_cfg(self, key, data): mgmt_intf = self.app_db.get_entry(APP_MGMT_PORT_TABLE, key) - is_all = False + cfgAllAtrr = False if mgmt_intf == {}: - is_all = True - - try: - if (('mtu' in data) and ((is_all == True) or (mgmt_intf == {}) or ('mtu' not in mgmt_intf) or (data['mtu'] != mgmt_intf['mtu']))): - self.mgmt_intf_mtu_set(key, data['mtu'], mgmt_intf) - - if (('description' in data) and ((is_all == True) or (mgmt_intf == {}) or ('description' not in mgmt_intf) or (data['description'] != mgmt_intf['description']))): - self.mgmt_intf_description_set(key, data['description'], mgmt_intf) - - if (('admin_status' in data) and ((is_all == True) or (mgmt_intf == {}) or ('admin_status' not in mgmt_intf) or (data['admin_status'] != mgmt_intf['admin_status']))): - self.mgmt_intf_admin_status_set(key, data['admin_status'], mgmt_intf) - - if (('autoneg' in data) and ((is_all == True) or (mgmt_intf == {}) or ('autoneg' not in mgmt_intf) or (data['autoneg'] != mgmt_intf['autoneg']))): - self.mgmt_intf_autoneg_set(key, data['autoneg'], mgmt_intf) - - if (('speed' in data) and ((is_all == True) or (mgmt_intf == {}) or ('speed' not in mgmt_intf) or (data['speed'] != mgmt_intf['speed']))): - autoneg = "on" - if 'autoneg' in data: - if data['autoneg'] == "false": - autoneg = "off" - self.mgmt_intf_speed_set(key, data['speed'], autoneg, mgmt_intf) - except: - syslog.syslog(syslog.LOG_ERR, "{} MGMT Port Config set failed.".format(key)) + cfgAllAttr = True + + attr_func_map = { + 'mtu' : self.mgmt_intf_mtu_set, + 'description' : self.mgmt_intf_description_set, + 'admin_status': self.mgmt_intf_admin_status_set, + 'autoneg' : self.mgmt_intf_autoneg_set, + 'speed' : self.mgmt_intf_speed_set, + } + for attr in data: + if (is_attr_cfg_required(attr, data, mgmt_intf, cfgAllAtrr) == True): + if attr == 'speed': + autoneg = "on" + if 'autoneg' in data: + if data['autoneg'] == "false": + autoneg = "off" + attr_func_map[attr](key, data[attr], autoneg, mgmt_intf) + else: + attr_func_map[attr](key, data[attr], mgmt_intf) self.app_db.set_entry(APP_MGMT_PORT_TABLE, key, mgmt_intf) @@ -620,124 +551,93 @@ class MgmtIntfCfg: def handle_mgmt_intf_cfg(self, key, data): cur_appdb_key = key.replace('|', ':') intf_keys = key.split("|") + db_key = key + if (len(intf_keys) > 1): + db_key = tuple(intf_keys) + cfgdb_entry = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, key) appdb_entry = self.app_db.get_entry(APP_MGMT_INTF_TABLE, cur_appdb_key) + cfg_keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) + app_keys = self.app_db.get_keys(APP_MGMT_INTF_TABLE) op = "DELETE" - keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) - - for it in keys: - if len(it) != 2: - it = (it, ) - it_key = it[0] + if ((db_key in cfg_keys) or (key in cfg_keys)): + if ((db_key in app_keys) or (cur_appdb_key in app_keys)): + op = "UPDATE" else: - it_key = it[0] + "|" + it[1] - - if it_key == key: op = "CREATE" - break - - if op == "CREATE": - if cfgdb_entry != {} and appdb_entry != {}: - op = "UPDATE" - if (len(intf_keys) < 2): if op == "DELETE": cfgdb_entry['ipv4_dhcp_client'] = "true" cfgdb_entry['ipv6_dhcp_client'] = "true" - - if (('ipv4_dhcp_client' not in appdb_entry) or (appdb_entry['ipv4_dhcp_client'] != cfgdb_entry['ipv4_dhcp_client'])): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", True) - appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] - - if (('ipv6_dhcp_client' not in appdb_entry) or (appdb_entry['ipv6_dhcp_client'] != cfgdb_entry['ipv6_dhcp_client'])): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", True) - appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] - - if ('ipv4_default_gwaddr' in appdb_entry): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DEL") - del appdb_entry['ipv4_default_gwaddr'] - - if ('ipv6_default_gwaddr' in appdb_entry): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DEL") - del appdb_entry['ipv6_default_gwaddr'] - - self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) self.config_db.set_entry(CFG_MGMT_INTF_TABLE, key, cfgdb_entry) - elif op == "CREATE": - syslog.syslog(syslog.LOG_ERR, "handle_mgmt_intf_cfg: operation is CREATE, return after vrf create handling") - self.mgmt_vrf_cfg.handle_mgmt_intf_creation(key) + for attr in cfgdb_entry: + if is_attr_cfg_required(attr, cfgdb_entry, appdb_entry, False): + self.mgmt_intf_dhclient_set(intf_keys[0], attr, cfgdb_entry[attr] == "true") + appdb_entry[attr] = cfgdb_entry[attr] + self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) - if ('ipv4_dhcp_client' in cfgdb_entry): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", cfgdb_entry['ipv4_dhcp_client'] == "true") - appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] - - if ('ipv6_dhcp_client' in cfgdb_entry): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", cfgdb_entry['ipv6_dhcp_client'] == "true") - appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] + else: + if op == "CREATE": + self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "ADD") + if ('gwaddr' in data): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") + appdb_entry['gwaddr'] = data['gwaddr'] - if ('ipv4_default_gwaddr' in cfgdb_entry): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") - appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] + if ('forced_mgmt_routes' in data): + forced_routes = data['forced_mgmt_routes'] + self.mgmt_intf_forced_mgmt_routes_set(intf_keys[0], intf_keys[1], forced_routes, "ADD") + appdb_entry['forced_mgmt_routes'] = data['forced_mgmt_routes'] - if ('ipv6_default_gwaddr' in cfgdb_entry): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") - appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] + if appdb_entry == {}: + appdb_entry["NULL"] = "NULL" self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) - elif op == "UPDATE": - if (('ipv4_dhcp_client' in cfgdb_entry) and ('ipv4_dhcp_client' not in appdb_entry)): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", cfgdb_entry['ipv4_dhcp_client'] == "true") - appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] - elif (('ipv4_dhcp_client' in cfgdb_entry) and (cfgdb_entry['ipv4_dhcp_client'] != appdb_entry['ipv4_dhcp_client'])): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", cfgdb_entry['ipv4_dhcp_client'] == "true") - appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] - - if (('ipv6_dhcp_client' in cfgdb_entry) and ('ipv6_dhcp_client' not in appdb_entry)): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", cfgdb_entry['ipv6_dhcp_client'] == "true") - appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] - elif (('ipv6_dhcp_client' in cfgdb_entry) and (cfgdb_entry['ipv6_dhcp_client'] != appdb_entry['ipv6_dhcp_client'])): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", cfgdb_entry['ipv6_dhcp_client'] == "true") - appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] - - if (('ipv4_default_gwaddr' in cfgdb_entry) and ('ipv4_default_gwaddr' not in appdb_entry)): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") - appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] - elif (('ipv4_default_gwaddr' in cfgdb_entry) and (cfgdb_entry['ipv4_default_gwaddr'] != appdb_entry['ipv4_default_gwaddr'])): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DEL") - self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") - appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] - elif (('ipv4_default_gwaddr' not in cfgdb_entry) and ('ipv4_default_gwaddr' in appdb_entry)): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DEL") - del appdb_entry['ipv4_default_gwaddr'] - - if (('ipv6_default_gwaddr' in cfgdb_entry) and ('ipv6_default_gwaddr' not in appdb_entry)): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") - appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] - elif (('ipv6_default_gwaddr' in cfgdb_entry) and (cfgdb_entry['ipv6_default_gwaddr'] != appdb_entry['ipv6_default_gwaddr'])): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DEL") - self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") - appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] - elif (('ipv6_default_gwaddr' not in cfgdb_entry) and ('ipv6_default_gwaddr' in appdb_entry)): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DEL") - del appdb_entry['ipv6_default_gwaddr'] + ''' + Case 1: gwaddr attribute delete case, gwaddr present in appdb entry + and not in config db entry + Case 2: gwaddr attribute add case, gwaddr is present in config db + entry but not in appdb entry + case 3: gwaddr attribute modify case, gwaddr present in both config + and app db entry but they are different + ''' + if ('gwaddr' not in cfgdb_entry): + if ('gwaddr' in appdb_entry): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'],"DEL") + del appdb_entry['gwaddr'] + else: + if ('gwaddr' not in appdb_entry): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], cfgdb_entry['gwaddr'], "ADD") + elif (cfgdb_entry['gwaddr'] != appdb_entry['gwaddr']): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'],"DEL") + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], cfgdb_entry['gwaddr'], "ADD") - self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) - else: - if op == "CREATE" or op == "UPDATE" : - self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "ADD") - if (('gwaddr' in data) and ((appdb_entry == {}) or ('gwaddr' not in appdb_entry))): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") - appdb_entry['gwaddr'] = data['gwaddr'] - elif (('gwaddr' in data) and ('gwaddr' not in cfgdb_entry) and ('gwaddr' in appdb_entry)): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'],"DEL") - del appdb_entry['gwaddr'] - elif (('gwaddr' in data) and (data['gwaddr'] != appdb_entry['gwaddr'])): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'],"DEL") - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") - appdb_entry['gwaddr'] = data['gwaddr'] + appdb_entry['gwaddr'] = cfgdb_entry['gwaddr'] + + ''' + Handle forced routes config UPDATE operation + ''' + cfg_forced_routes = [] + app_forced_routes = [] + if ('forced_mgmt_routes' in cfgdb_entry): + cfg_forced_routes = cfgdb_entry['forced_mgmt_routes'] + if ('forced_mgmt_routes' in appdb_entry): + app_forced_routes = appdb_entry['forced_mgmt_routes'] + + ''' + check is forced_mgmt_routes present in config db or app db entry + handle update case. + ''' + if (len(cfg_forced_routes) > 0 or len(app_forced_routes) > 0): + cfg_forced_routes = self.mgmt_intf_forced_mgmt_routes_set(intf_keys[0], intf_keys[1], + cfg_forced_routes, op, app_forced_routes) + + if len(cfg_forced_routes) == 0: + del appdb_entry['forced_mgmt_routes'] + else: + appdb_entry['forced_mgmt_routes'] = cfgdb_entry['forced_mgmt_routes'] if appdb_entry == {}: appdb_entry["NULL"] = "NULL" @@ -746,8 +646,13 @@ class MgmtIntfCfg: else: self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "DEL") - if ('gwaddr' in data): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "DEL") + if ('gwaddr' in appdb_entry): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'], "DEL") + + if ('forced_mgmt_routes' in appdb_entry): + forced_routes = appdb_entry['forced_mgmt_routes'] + self.mgmt_intf_forced_mgmt_routes_set(intf_keys[0], intf_keys[1], forced_routes, "DEL") + self.app_db.delete_entry(APP_MGMT_INTF_TABLE, cur_appdb_key) diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index dbb2b1f3418..33f6b11c753 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -5,19 +5,7 @@ # file: /etc/network/interfaces # {% endblock banner %} -{% block mgmt_vrf %} -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} -auto mgmt -iface mgmt - vrf-table 5000 -# The loopback network interface for mgmt VRF that is required for applications like NTP - up ip link add lo-m type dummy - up ip link set dev lo-m master mgmt - up ip addr add 127.0.0.1/8 dev lo-m - up ip link set lo-m up - down ip link delete dev lo-m -{% endif %} -{% endblock mgmt_vrf %} + {% block loopback %} # The loopback network interface auto lo @@ -57,55 +45,6 @@ iface {{ port }} inet6 dhcp {% endif %} {% endfor %} {% endif %} - -{% else %} -{% if MGMT_INTERFACE %} -{% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} -iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static - address {{ prefix | ip }} - netmask {{ prefix | netmask if prefix | ipv4 else prefix | prefixlen }} -{% set vrf_table = 'default' %} -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} -{% set vrf_table = '5000' %} - vrf mgmt -{% endif %} - ########## management network policy routing rules - # management port up rules - up ip {{ '-4' if prefix | ipv4 else '-6' }} route add default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} metric 201 - up ip {{ '-4' if prefix | ipv4 else '-6' }} route add {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} - up ip {{ '-4' if prefix | ipv4 else '-6' }} rule add from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} - up cgcreate -g l3mdev:mgmt - up cgset -r l3mdev.master-device=mgmt mgmt -{% endif %} -{% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} - up ip rule add to {{ route }} table {{ vrf_table }} -{% endfor %} - # management port down rules - pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} - pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} - pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} - down cgdelete -g l3mdev:mgmt -{% endif %} -{% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} - pre-down ip rule delete to {{ route }} table {{ vrf_table }} -{% endfor %} -{# TODO: COPP policy type rules #} -{% endfor %} -{% else %} -iface eth0 inet dhcp - metric 202 -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} - vrf mgmt - up cgcreate -g l3mdev:mgmt - up cgset -r l3mdev.master-device=mgmt mgmt - down cgdelete -g l3mdev:mgmt -{% endif %} -iface eth0 inet6 dhcp - up sysctl net.ipv6.conf.eth0.accept_ra=1 - down sysctl net.ipv6.conf.eth0.accept_ra=0 -{% endif %} {% endif %} # source /etc/network/interfaces.d/* From 3a82ade3ef59270aefc28ada260342f4d273b275 Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Tue, 21 Apr 2020 17:09:41 -0700 Subject: [PATCH 04/69] [docker]: Enabled ipv6 in dockers when using docker bridge network (#4426) Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- files/build_templates/docker_image_ctl.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 6067c58f41e..c48d72ea1f4 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -74,6 +74,7 @@ function postStartAction() { {%- if docker_container_name == "database" %} if [ "$DEV" ]; then + docker exec -i database$DEV sysctl -w net.ipv6.conf.all.disable_ipv6=0 link_namespace $DEV fi # Wait until redis starts From 4cd75405b4d9292b4d63ca9f1651f9feb234ddf5 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Tue, 21 Apr 2020 17:33:21 -0700 Subject: [PATCH 05/69] Removed unused imports. --- files/dhcp/dhcp_mgmt_conf.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/files/dhcp/dhcp_mgmt_conf.py b/files/dhcp/dhcp_mgmt_conf.py index 25cc5a80f88..c582dd83856 100644 --- a/files/dhcp/dhcp_mgmt_conf.py +++ b/files/dhcp/dhcp_mgmt_conf.py @@ -1,13 +1,9 @@ #!/usr/bin/python -u # -*- coding: utf-8 -*- -import os -import re import sys -import subprocess import syslog import ipaddress -import netaddr from swsssdk import ConfigDBConnector APP_MGMT_INTF_TABLE = "MGMT_INTF_TABLE" From 43e80f7c2a54591fcbdce22651a7932413ffa527 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 22 Apr 2020 11:02:38 -0700 Subject: [PATCH 06/69] [doc]: ask the motivation of the PR (#4462) it is important to understand the motivation of the PR. what I did is usually the PR title, so remove. Signed-off-by: Guohan Lu --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 2ac7d9e4773..b86fef4c0ae 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -10,7 +10,7 @@ If this is a bug fix, make sure your description includes "fixes #xxxx", or Please provide the following information: --> -**- What I did** +**- Why I did it** **- How I did it** From 45c88d128749bb646b44f6a0c5ace42f5b3b548a Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 22 Apr 2020 11:03:16 -0700 Subject: [PATCH 07/69] [kvm]: disable pmon daemons on kvm vs platform (#4461) hardware daemons are not supported in kvm vs platform now admin@vlab-01:/usr/share/sonic/device/x86_64-kvm_x86_64-r0$ docker exec -it pmon bash root@vlab-01:/# supervisorctl status fancontrol STOPPED Not started lm-sensors STOPPED Not started rsyslogd RUNNING pid 23, uptime 0:03:09 start.sh EXITED Apr 22 09:07 AM supervisor-proc-exit-listener RUNNING pid 17, uptime 0:03:10 Signed-off-by: Guohan Lu --- .../virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json diff --git a/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json b/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json new file mode 100644 index 00000000000..c6a21eb19fc --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json @@ -0,0 +1,7 @@ +{ + "skip_ledd": true, + "skip_xcvrd": true, + "skip_psud": true, + "skip_syseepromd": true, + "skip_thermalctld": true +} From c5e98443ba84a9a0c667f83572c2074dbf01b4a7 Mon Sep 17 00:00:00 2001 From: chihhan123 <56335706+chihhan123@users.noreply.github.com> Date: Thu, 23 Apr 2020 02:47:04 +0800 Subject: [PATCH 08/69] [device/acction] Support AS9716-32D(R0BA) (#4449) - add led_proc_init.soc - update config.bcm --- .../Accton-AS9716-32D/sai.profile | 2 +- .../th3-as9716-32x400G.config.bcm | 1287 +++++++++++++++++ .../custom_led.bin | Bin 0 -> 2044 bytes .../led_proc_init.soc | 3 + 4 files changed, 1291 insertions(+), 1 deletion(-) create mode 100644 device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/th3-as9716-32x400G.config.bcm create mode 100644 device/accton/x86_64-accton_as9716_32d-r0/custom_led.bin create mode 100644 device/accton/x86_64-accton_as9716_32d-r0/led_proc_init.soc diff --git a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile index be39b1f961f..b366aeaa93c 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile +++ b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/th3-as9716-32x400G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-as9716-32x400G.config.bcm \ No newline at end of file diff --git a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/th3-as9716-32x400G.config.bcm b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/th3-as9716-32x400G.config.bcm new file mode 100644 index 00000000000..5850f4ce4d7 --- /dev/null +++ b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/th3-as9716-32x400G.config.bcm @@ -0,0 +1,1287 @@ +pbmp_xport_xe.0=0x3ffffffffffffffffffffffffffffffffffffffe + +# Reference specfic +parity_correction=1 +parity_enable=1 +phy_null=1 +#pll_bypass=1 +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 +l2xmsg_mode.0=1 +l2_mem_entries.0=8192 +l3_alpm_enable.0=2 +l3_mem_entries.0=16384 +mmu_port_num_mc_queue.0=1 +module_64ports.0=1 +multicast_l2_range.0=511 +oversubscribe_mode=1 + +# Platform specfic +arl_clean_timeout_usec=15000000 +asf_mem_profile.0=2 +bcm_num_cos.0=8 +bcm_stat_flags=1 +bcm_stat_jumbo.0=9236 +cdma_timeout_usec.0=15000000 +dma_desc_timeout_usec.0=15000000 +dpr_clock_frequency.0=1000 +max_vp_lags.0=0 +miim_intr_enable.0=0 +sram_scan_enable.0=0 +tdma_timeout_usec.0=15000000 +tslam_timeout_usec.0=15000000 + +#BC0# +dport_map_port_1=81 +dport_map_port_2=82 +dport_map_port_3=83 +dport_map_port_4=84 +portmap_1=1:400 +phy_chain_rx_lane_map_physical{1.0}=0x45301726 +phy_chain_rx_lane_map_physical{2.0}=0x45301726 +phy_chain_rx_lane_map_physical{3.0}=0x45301726 +phy_chain_rx_lane_map_physical{4.0}=0x45301726 +phy_chain_rx_lane_map_physical{5.0}=0x45301726 +phy_chain_rx_lane_map_physical{6.0}=0x45301726 +phy_chain_rx_lane_map_physical{7.0}=0x45301726 +phy_chain_rx_lane_map_physical{8.0}=0x45301726 +phy_chain_tx_lane_map_physical{1.0}=0x23761450 +phy_chain_tx_lane_map_physical{2.0}=0x23761450 +phy_chain_tx_lane_map_physical{3.0}=0x23761450 +phy_chain_tx_lane_map_physical{4.0}=0x23761450 +phy_chain_tx_lane_map_physical{5.0}=0x23761450 +phy_chain_tx_lane_map_physical{6.0}=0x23761450 +phy_chain_tx_lane_map_physical{7.0}=0x23761450 +phy_chain_tx_lane_map_physical{8.0}=0x23761450 +serdes_core_rx_polarity_flip_physical{1}=0xA9 +serdes_core_rx_polarity_flip_physical{2}=0xA9 +serdes_core_rx_polarity_flip_physical{3}=0xA9 +serdes_core_rx_polarity_flip_physical{4}=0xA9 +serdes_core_rx_polarity_flip_physical{5}=0xA9 +serdes_core_rx_polarity_flip_physical{6}=0xA9 +serdes_core_rx_polarity_flip_physical{7}=0xA9 +serdes_core_rx_polarity_flip_physical{8}=0xA9 +serdes_core_tx_polarity_flip_physical{1}=0x7E +serdes_core_tx_polarity_flip_physical{2}=0x7E +serdes_core_tx_polarity_flip_physical{3}=0x7E +serdes_core_tx_polarity_flip_physical{4}=0x7E +serdes_core_tx_polarity_flip_physical{5}=0x7E +serdes_core_tx_polarity_flip_physical{6}=0x7E +serdes_core_tx_polarity_flip_physical{7}=0x7E +serdes_core_tx_polarity_flip_physical{8}=0x7E + +#BC1# +dport_map_port_5=85 +dport_map_port_6=86 +dport_map_port_7=87 +dport_map_port_8=88 +portmap_5=9:400 +phy_chain_rx_lane_map_physical{9.0}=0x12650374 +phy_chain_rx_lane_map_physical{10.0}=0x12650374 +phy_chain_rx_lane_map_physical{11.0}=0x12650374 +phy_chain_rx_lane_map_physical{12.0}=0x12650374 +phy_chain_rx_lane_map_physical{13.0}=0x12650374 +phy_chain_rx_lane_map_physical{14.0}=0x12650374 +phy_chain_rx_lane_map_physical{15.0}=0x12650374 +phy_chain_rx_lane_map_physical{16.0}=0x12650374 +phy_chain_tx_lane_map_physical{9.0}=0x70146253 +phy_chain_tx_lane_map_physical{10.0}=0x70146253 +phy_chain_tx_lane_map_physical{11.0}=0x70146253 +phy_chain_tx_lane_map_physical{12.0}=0x70146253 +phy_chain_tx_lane_map_physical{13.0}=0x70146253 +phy_chain_tx_lane_map_physical{14.0}=0x70146253 +phy_chain_tx_lane_map_physical{15.0}=0x70146253 +phy_chain_tx_lane_map_physical{16.0}=0x70146253 +serdes_core_rx_polarity_flip_physical{9}=0x5A +serdes_core_rx_polarity_flip_physical{10}=0x5A +serdes_core_rx_polarity_flip_physical{11}=0x5A +serdes_core_rx_polarity_flip_physical{12}=0x5A +serdes_core_rx_polarity_flip_physical{13}=0x5A +serdes_core_rx_polarity_flip_physical{14}=0x5A +serdes_core_rx_polarity_flip_physical{15}=0x5A +serdes_core_rx_polarity_flip_physical{16}=0x5A +serdes_core_tx_polarity_flip_physical{9}=0x76 +serdes_core_tx_polarity_flip_physical{10}=0x76 +serdes_core_tx_polarity_flip_physical{11}=0x76 +serdes_core_tx_polarity_flip_physical{12}=0x76 +serdes_core_tx_polarity_flip_physical{13}=0x76 +serdes_core_tx_polarity_flip_physical{14}=0x76 +serdes_core_tx_polarity_flip_physical{15}=0x76 +serdes_core_tx_polarity_flip_physical{16}=0x76 + +#BC2# +dport_map_port_9=89 +dport_map_port_10=90 +dport_map_port_11=91 +dport_map_port_12=92 +portmap_9=17:400 +phy_chain_rx_lane_map_physical{17.0}=0x40572136 +phy_chain_rx_lane_map_physical{18.0}=0x40572136 +phy_chain_rx_lane_map_physical{19.0}=0x40572136 +phy_chain_rx_lane_map_physical{20.0}=0x40572136 +phy_chain_rx_lane_map_physical{21.0}=0x40572136 +phy_chain_rx_lane_map_physical{22.0}=0x40572136 +phy_chain_rx_lane_map_physical{23.0}=0x40572136 +phy_chain_rx_lane_map_physical{24.0}=0x40572136 +phy_chain_tx_lane_map_physical{17.0}=0x75324160 +phy_chain_tx_lane_map_physical{18.0}=0x75324160 +phy_chain_tx_lane_map_physical{19.0}=0x75324160 +phy_chain_tx_lane_map_physical{20.0}=0x75324160 +phy_chain_tx_lane_map_physical{21.0}=0x75324160 +phy_chain_tx_lane_map_physical{22.0}=0x75324160 +phy_chain_tx_lane_map_physical{23.0}=0x75324160 +phy_chain_tx_lane_map_physical{24.0}=0x75324160 +serdes_core_rx_polarity_flip_physical{17}=0x78 +serdes_core_rx_polarity_flip_physical{18}=0x78 +serdes_core_rx_polarity_flip_physical{19}=0x78 +serdes_core_rx_polarity_flip_physical{20}=0x78 +serdes_core_rx_polarity_flip_physical{21}=0x78 +serdes_core_rx_polarity_flip_physical{22}=0x78 +serdes_core_rx_polarity_flip_physical{23}=0x78 +serdes_core_rx_polarity_flip_physical{24}=0x78 +serdes_core_tx_polarity_flip_physical{17}=0x3B +serdes_core_tx_polarity_flip_physical{18}=0x3B +serdes_core_tx_polarity_flip_physical{19}=0x3B +serdes_core_tx_polarity_flip_physical{20}=0x3B +serdes_core_tx_polarity_flip_physical{21}=0x3B +serdes_core_tx_polarity_flip_physical{22}=0x3B +serdes_core_tx_polarity_flip_physical{23}=0x3B +serdes_core_tx_polarity_flip_physical{24}=0x3B + +#BC3# +dport_map_port_13=93 +dport_map_port_14=94 +dport_map_port_15=95 +dport_map_port_16=96 +portmap_13=25:400 +phy_chain_rx_lane_map_physical{25.0}=0x20576143 +phy_chain_rx_lane_map_physical{26.0}=0x20576143 +phy_chain_rx_lane_map_physical{27.0}=0x20576143 +phy_chain_rx_lane_map_physical{28.0}=0x20576143 +phy_chain_rx_lane_map_physical{29.0}=0x20576143 +phy_chain_rx_lane_map_physical{30.0}=0x20576143 +phy_chain_rx_lane_map_physical{31.0}=0x20576143 +phy_chain_rx_lane_map_physical{32.0}=0x20576143 +phy_chain_tx_lane_map_physical{25.0}=0x43716520 +phy_chain_tx_lane_map_physical{26.0}=0x43716520 +phy_chain_tx_lane_map_physical{27.0}=0x43716520 +phy_chain_tx_lane_map_physical{28.0}=0x43716520 +phy_chain_tx_lane_map_physical{29.0}=0x43716520 +phy_chain_tx_lane_map_physical{30.0}=0x43716520 +phy_chain_tx_lane_map_physical{31.0}=0x43716520 +phy_chain_tx_lane_map_physical{32.0}=0x43716520 +serdes_core_rx_polarity_flip_physical{25}=0xF8 +serdes_core_rx_polarity_flip_physical{26}=0xF8 +serdes_core_rx_polarity_flip_physical{27}=0xF8 +serdes_core_rx_polarity_flip_physical{28}=0xF8 +serdes_core_rx_polarity_flip_physical{29}=0xF8 +serdes_core_rx_polarity_flip_physical{30}=0xF8 +serdes_core_rx_polarity_flip_physical{31}=0xF8 +serdes_core_rx_polarity_flip_physical{32}=0xF8 +serdes_core_tx_polarity_flip_physical{25}=0x6E +serdes_core_tx_polarity_flip_physical{26}=0x6E +serdes_core_tx_polarity_flip_physical{27}=0x6E +serdes_core_tx_polarity_flip_physical{28}=0x6E +serdes_core_tx_polarity_flip_physical{29}=0x6E +serdes_core_tx_polarity_flip_physical{30}=0x6E +serdes_core_tx_polarity_flip_physical{31}=0x6E +serdes_core_tx_polarity_flip_physical{32}=0x6E + +#BC4# +dport_map_port_24=37 +dport_map_port_25=38 +dport_map_port_26=39 +dport_map_port_27=40 +portmap_24=33:400 +phy_chain_rx_lane_map_physical{33.0}=0x47205361 +phy_chain_rx_lane_map_physical{34.0}=0x47205361 +phy_chain_rx_lane_map_physical{35.0}=0x47205361 +phy_chain_rx_lane_map_physical{36.0}=0x47205361 +phy_chain_rx_lane_map_physical{37.0}=0x47205361 +phy_chain_rx_lane_map_physical{38.0}=0x47205361 +phy_chain_rx_lane_map_physical{39.0}=0x47205361 +phy_chain_rx_lane_map_physical{40.0}=0x47205361 +phy_chain_tx_lane_map_physical{33.0}=0x01452736 +phy_chain_tx_lane_map_physical{34.0}=0x01452736 +phy_chain_tx_lane_map_physical{35.0}=0x01452736 +phy_chain_tx_lane_map_physical{36.0}=0x01452736 +phy_chain_tx_lane_map_physical{37.0}=0x01452736 +phy_chain_tx_lane_map_physical{38.0}=0x01452736 +phy_chain_tx_lane_map_physical{39.0}=0x01452736 +phy_chain_tx_lane_map_physical{40.0}=0x01452736 +serdes_core_rx_polarity_flip_physical{33}=0x87 +serdes_core_rx_polarity_flip_physical{34}=0x87 +serdes_core_rx_polarity_flip_physical{35}=0x87 +serdes_core_rx_polarity_flip_physical{36}=0x87 +serdes_core_rx_polarity_flip_physical{37}=0x87 +serdes_core_rx_polarity_flip_physical{38}=0x87 +serdes_core_rx_polarity_flip_physical{39}=0x87 +serdes_core_rx_polarity_flip_physical{40}=0x87 +serdes_core_tx_polarity_flip_physical{33}=0x27 +serdes_core_tx_polarity_flip_physical{34}=0x27 +serdes_core_tx_polarity_flip_physical{35}=0x27 +serdes_core_tx_polarity_flip_physical{36}=0x27 +serdes_core_tx_polarity_flip_physical{37}=0x27 +serdes_core_tx_polarity_flip_physical{38}=0x27 +serdes_core_tx_polarity_flip_physical{39}=0x27 +serdes_core_tx_polarity_flip_physical{40}=0x27 + +#BC5# +dport_map_port_20=33 +dport_map_port_21=34 +dport_map_port_22=35 +dport_map_port_23=36 +portmap_20=41:400 +phy_chain_rx_lane_map_physical{41.0}=0x45013726 +phy_chain_rx_lane_map_physical{42.0}=0x45013726 +phy_chain_rx_lane_map_physical{43.0}=0x45013726 +phy_chain_rx_lane_map_physical{44.0}=0x45013726 +phy_chain_rx_lane_map_physical{45.0}=0x45013726 +phy_chain_rx_lane_map_physical{46.0}=0x45013726 +phy_chain_rx_lane_map_physical{47.0}=0x45013726 +phy_chain_rx_lane_map_physical{48.0}=0x45013726 +phy_chain_tx_lane_map_physical{41.0}=0x10273564 +phy_chain_tx_lane_map_physical{42.0}=0x10273564 +phy_chain_tx_lane_map_physical{43.0}=0x10273564 +phy_chain_tx_lane_map_physical{44.0}=0x10273564 +phy_chain_tx_lane_map_physical{45.0}=0x10273564 +phy_chain_tx_lane_map_physical{46.0}=0x10273564 +phy_chain_tx_lane_map_physical{47.0}=0x10273564 +phy_chain_tx_lane_map_physical{48.0}=0x10273564 +serdes_core_rx_polarity_flip_physical{41}=0x99 +serdes_core_rx_polarity_flip_physical{42}=0x99 +serdes_core_rx_polarity_flip_physical{43}=0x99 +serdes_core_rx_polarity_flip_physical{44}=0x99 +serdes_core_rx_polarity_flip_physical{45}=0x99 +serdes_core_rx_polarity_flip_physical{46}=0x99 +serdes_core_rx_polarity_flip_physical{47}=0x99 +serdes_core_rx_polarity_flip_physical{48}=0x99 +serdes_core_tx_polarity_flip_physical{41}=0xA8 +serdes_core_tx_polarity_flip_physical{42}=0xA8 +serdes_core_tx_polarity_flip_physical{43}=0xA8 +serdes_core_tx_polarity_flip_physical{44}=0xA8 +serdes_core_tx_polarity_flip_physical{45}=0xA8 +serdes_core_tx_polarity_flip_physical{46}=0xA8 +serdes_core_tx_polarity_flip_physical{47}=0xA8 +serdes_core_tx_polarity_flip_physical{48}=0xA8 + +#BC6# +dport_map_port_28=41 +dport_map_port_29=42 +dport_map_port_30=43 +dport_map_port_31=44 +portmap_28=49:400 +phy_chain_rx_lane_map_physical{49.0}=0x04571326 +phy_chain_rx_lane_map_physical{50.0}=0x04571326 +phy_chain_rx_lane_map_physical{51.0}=0x04571326 +phy_chain_rx_lane_map_physical{52.0}=0x04571326 +phy_chain_rx_lane_map_physical{53.0}=0x04571326 +phy_chain_rx_lane_map_physical{54.0}=0x04571326 +phy_chain_rx_lane_map_physical{55.0}=0x04571326 +phy_chain_rx_lane_map_physical{56.0}=0x04571326 +phy_chain_tx_lane_map_physical{49.0}=0x51230764 +phy_chain_tx_lane_map_physical{50.0}=0x51230764 +phy_chain_tx_lane_map_physical{51.0}=0x51230764 +phy_chain_tx_lane_map_physical{52.0}=0x51230764 +phy_chain_tx_lane_map_physical{53.0}=0x51230764 +phy_chain_tx_lane_map_physical{54.0}=0x51230764 +phy_chain_tx_lane_map_physical{55.0}=0x51230764 +phy_chain_tx_lane_map_physical{56.0}=0x51230764 +serdes_core_rx_polarity_flip_physical{49}=0xB2 +serdes_core_rx_polarity_flip_physical{50}=0xB2 +serdes_core_rx_polarity_flip_physical{51}=0xB2 +serdes_core_rx_polarity_flip_physical{52}=0xB2 +serdes_core_rx_polarity_flip_physical{53}=0xB2 +serdes_core_rx_polarity_flip_physical{54}=0xB2 +serdes_core_rx_polarity_flip_physical{55}=0xB2 +serdes_core_rx_polarity_flip_physical{56}=0xB2 +serdes_core_tx_polarity_flip_physical{49}=0x88 +serdes_core_tx_polarity_flip_physical{50}=0x88 +serdes_core_tx_polarity_flip_physical{51}=0x88 +serdes_core_tx_polarity_flip_physical{52}=0x88 +serdes_core_tx_polarity_flip_physical{53}=0x88 +serdes_core_tx_polarity_flip_physical{54}=0x88 +serdes_core_tx_polarity_flip_physical{55}=0x88 +serdes_core_tx_polarity_flip_physical{56}=0x88 + +#BC7# +dport_map_port_32=45 +dport_map_port_33=46 +dport_map_port_34=47 +dport_map_port_35=48 +portmap_32=57:400 +phy_chain_rx_lane_map_physical{57.0}=0x01675243 +phy_chain_rx_lane_map_physical{58.0}=0x01675243 +phy_chain_rx_lane_map_physical{59.0}=0x01675243 +phy_chain_rx_lane_map_physical{60.0}=0x01675243 +phy_chain_rx_lane_map_physical{61.0}=0x01675243 +phy_chain_rx_lane_map_physical{62.0}=0x01675243 +phy_chain_rx_lane_map_physical{63.0}=0x01675243 +phy_chain_rx_lane_map_physical{64.0}=0x01675243 +phy_chain_tx_lane_map_physical{57.0}=0x37106425 +phy_chain_tx_lane_map_physical{58.0}=0x37106425 +phy_chain_tx_lane_map_physical{59.0}=0x37106425 +phy_chain_tx_lane_map_physical{60.0}=0x37106425 +phy_chain_tx_lane_map_physical{61.0}=0x37106425 +phy_chain_tx_lane_map_physical{62.0}=0x37106425 +phy_chain_tx_lane_map_physical{63.0}=0x37106425 +phy_chain_tx_lane_map_physical{64.0}=0x37106425 +serdes_core_rx_polarity_flip_physical{57}=0x9C +serdes_core_rx_polarity_flip_physical{58}=0x9C +serdes_core_rx_polarity_flip_physical{59}=0x9C +serdes_core_rx_polarity_flip_physical{60}=0x9C +serdes_core_rx_polarity_flip_physical{61}=0x9C +serdes_core_rx_polarity_flip_physical{62}=0x9C +serdes_core_rx_polarity_flip_physical{63}=0x9C +serdes_core_rx_polarity_flip_physical{64}=0x9C +serdes_core_tx_polarity_flip_physical{57}=0x4F +serdes_core_tx_polarity_flip_physical{58}=0x4F +serdes_core_tx_polarity_flip_physical{59}=0x4F +serdes_core_tx_polarity_flip_physical{60}=0x4F +serdes_core_tx_polarity_flip_physical{61}=0x4F +serdes_core_tx_polarity_flip_physical{62}=0x4F +serdes_core_tx_polarity_flip_physical{63}=0x4F +serdes_core_tx_polarity_flip_physical{64}=0x4F + +#BC8# +dport_map_port_44=5 +dport_map_port_45=6 +dport_map_port_46=7 +dport_map_port_47=8 +portmap_44=65:400 +phy_chain_rx_lane_map_physical{65.0}=0x56024713 +phy_chain_rx_lane_map_physical{66.0}=0x56024713 +phy_chain_rx_lane_map_physical{67.0}=0x56024713 +phy_chain_rx_lane_map_physical{68.0}=0x56024713 +phy_chain_rx_lane_map_physical{69.0}=0x56024713 +phy_chain_rx_lane_map_physical{70.0}=0x56024713 +phy_chain_rx_lane_map_physical{71.0}=0x56024713 +phy_chain_rx_lane_map_physical{72.0}=0x56024713 +phy_chain_tx_lane_map_physical{65.0}=0x12673504 +phy_chain_tx_lane_map_physical{66.0}=0x12673504 +phy_chain_tx_lane_map_physical{67.0}=0x12673504 +phy_chain_tx_lane_map_physical{68.0}=0x12673504 +phy_chain_tx_lane_map_physical{69.0}=0x12673504 +phy_chain_tx_lane_map_physical{70.0}=0x12673504 +phy_chain_tx_lane_map_physical{71.0}=0x12673504 +phy_chain_tx_lane_map_physical{72.0}=0x12673504 +serdes_core_rx_polarity_flip_physical{65}=0x4B +serdes_core_rx_polarity_flip_physical{66}=0x4B +serdes_core_rx_polarity_flip_physical{67}=0x4B +serdes_core_rx_polarity_flip_physical{68}=0x4B +serdes_core_rx_polarity_flip_physical{69}=0x4B +serdes_core_rx_polarity_flip_physical{70}=0x4B +serdes_core_rx_polarity_flip_physical{71}=0x4B +serdes_core_rx_polarity_flip_physical{72}=0x4B +serdes_core_tx_polarity_flip_physical{65}=0xB7 +serdes_core_tx_polarity_flip_physical{66}=0xB7 +serdes_core_tx_polarity_flip_physical{67}=0xB7 +serdes_core_tx_polarity_flip_physical{68}=0xB7 +serdes_core_tx_polarity_flip_physical{69}=0xB7 +serdes_core_tx_polarity_flip_physical{70}=0xB7 +serdes_core_tx_polarity_flip_physical{71}=0xB7 +serdes_core_tx_polarity_flip_physical{72}=0xB7 + +#BC9# +dport_map_port_40=1 +dport_map_port_41=2 +dport_map_port_42=3 +dport_map_port_43=4 +portmap_40=73:400 +phy_chain_rx_lane_map_physical{73.0}=0x45231607 +phy_chain_rx_lane_map_physical{74.0}=0x45231607 +phy_chain_rx_lane_map_physical{75.0}=0x45231607 +phy_chain_rx_lane_map_physical{76.0}=0x45231607 +phy_chain_rx_lane_map_physical{77.0}=0x45231607 +phy_chain_rx_lane_map_physical{78.0}=0x45231607 +phy_chain_rx_lane_map_physical{79.0}=0x45231607 +phy_chain_rx_lane_map_physical{80.0}=0x45231607 +phy_chain_tx_lane_map_physical{73.0}=0x04273165 +phy_chain_tx_lane_map_physical{74.0}=0x04273165 +phy_chain_tx_lane_map_physical{75.0}=0x04273165 +phy_chain_tx_lane_map_physical{76.0}=0x04273165 +phy_chain_tx_lane_map_physical{77.0}=0x04273165 +phy_chain_tx_lane_map_physical{78.0}=0x04273165 +phy_chain_tx_lane_map_physical{79.0}=0x04273165 +phy_chain_tx_lane_map_physical{80.0}=0x04273165 +serdes_core_rx_polarity_flip_physical{73}=0x9C +serdes_core_rx_polarity_flip_physical{74}=0x9C +serdes_core_rx_polarity_flip_physical{75}=0x9C +serdes_core_rx_polarity_flip_physical{76}=0x9C +serdes_core_rx_polarity_flip_physical{77}=0x9C +serdes_core_rx_polarity_flip_physical{78}=0x9C +serdes_core_rx_polarity_flip_physical{79}=0x9C +serdes_core_rx_polarity_flip_physical{80}=0x9C +serdes_core_tx_polarity_flip_physical{73}=0xAC +serdes_core_tx_polarity_flip_physical{74}=0xAC +serdes_core_tx_polarity_flip_physical{75}=0xAC +serdes_core_tx_polarity_flip_physical{76}=0xAC +serdes_core_tx_polarity_flip_physical{77}=0xAC +serdes_core_tx_polarity_flip_physical{78}=0xAC +serdes_core_tx_polarity_flip_physical{79}=0xAC +serdes_core_tx_polarity_flip_physical{80}=0xAC + +#BC10# +dport_map_port_48=9 +dport_map_port_49=10 +dport_map_port_50=11 +dport_map_port_51=12 +portmap_48=81:400 +phy_chain_rx_lane_map_physical{81.0}=0x20563147 +phy_chain_rx_lane_map_physical{82.0}=0x20563147 +phy_chain_rx_lane_map_physical{83.0}=0x20563147 +phy_chain_rx_lane_map_physical{84.0}=0x20563147 +phy_chain_rx_lane_map_physical{85.0}=0x20563147 +phy_chain_rx_lane_map_physical{86.0}=0x20563147 +phy_chain_rx_lane_map_physical{87.0}=0x20563147 +phy_chain_rx_lane_map_physical{88.0}=0x20563147 +phy_chain_tx_lane_map_physical{81.0}=0x53216704 +phy_chain_tx_lane_map_physical{82.0}=0x53216704 +phy_chain_tx_lane_map_physical{83.0}=0x53216704 +phy_chain_tx_lane_map_physical{84.0}=0x53216704 +phy_chain_tx_lane_map_physical{85.0}=0x53216704 +phy_chain_tx_lane_map_physical{86.0}=0x53216704 +phy_chain_tx_lane_map_physical{87.0}=0x53216704 +phy_chain_tx_lane_map_physical{88.0}=0x53216704 +serdes_core_rx_polarity_flip_physical{81}=0xE1 +serdes_core_rx_polarity_flip_physical{82}=0xE1 +serdes_core_rx_polarity_flip_physical{83}=0xE1 +serdes_core_rx_polarity_flip_physical{84}=0xE1 +serdes_core_rx_polarity_flip_physical{85}=0xE1 +serdes_core_rx_polarity_flip_physical{86}=0xE1 +serdes_core_rx_polarity_flip_physical{87}=0xE1 +serdes_core_rx_polarity_flip_physical{88}=0xE1 +serdes_core_tx_polarity_flip_physical{81}=0xA2 +serdes_core_tx_polarity_flip_physical{82}=0xA2 +serdes_core_tx_polarity_flip_physical{83}=0xA2 +serdes_core_tx_polarity_flip_physical{84}=0xA2 +serdes_core_tx_polarity_flip_physical{85}=0xA2 +serdes_core_tx_polarity_flip_physical{86}=0xA2 +serdes_core_tx_polarity_flip_physical{87}=0xA2 +serdes_core_tx_polarity_flip_physical{88}=0xA2 + +#BC11# +dport_map_port_52=13 +dport_map_port_53=14 +dport_map_port_54=15 +dport_map_port_55=16 +portmap_52=89:400 +phy_chain_rx_lane_map_physical{89.0}=0x02514376 +phy_chain_rx_lane_map_physical{90.0}=0x02514376 +phy_chain_rx_lane_map_physical{91.0}=0x02514376 +phy_chain_rx_lane_map_physical{92.0}=0x02514376 +phy_chain_rx_lane_map_physical{93.0}=0x02514376 +phy_chain_rx_lane_map_physical{94.0}=0x02514376 +phy_chain_rx_lane_map_physical{95.0}=0x02514376 +phy_chain_rx_lane_map_physical{96.0}=0x02514376 +phy_chain_tx_lane_map_physical{89.0}=0x64012735 +phy_chain_tx_lane_map_physical{90.0}=0x64012735 +phy_chain_tx_lane_map_physical{91.0}=0x64012735 +phy_chain_tx_lane_map_physical{92.0}=0x64012735 +phy_chain_tx_lane_map_physical{93.0}=0x64012735 +phy_chain_tx_lane_map_physical{94.0}=0x64012735 +phy_chain_tx_lane_map_physical{95.0}=0x64012735 +phy_chain_tx_lane_map_physical{96.0}=0x64012735 +serdes_core_rx_polarity_flip_physical{89}=0xE2 +serdes_core_rx_polarity_flip_physical{90}=0xE2 +serdes_core_rx_polarity_flip_physical{91}=0xE2 +serdes_core_rx_polarity_flip_physical{92}=0xE2 +serdes_core_rx_polarity_flip_physical{93}=0xE2 +serdes_core_rx_polarity_flip_physical{94}=0xE2 +serdes_core_rx_polarity_flip_physical{95}=0xE2 +serdes_core_rx_polarity_flip_physical{96}=0xE2 +serdes_core_tx_polarity_flip_physical{89}=0xCF +serdes_core_tx_polarity_flip_physical{90}=0xCF +serdes_core_tx_polarity_flip_physical{91}=0xCF +serdes_core_tx_polarity_flip_physical{92}=0xCF +serdes_core_tx_polarity_flip_physical{93}=0xCF +serdes_core_tx_polarity_flip_physical{94}=0xCF +serdes_core_tx_polarity_flip_physical{95}=0xCF +serdes_core_tx_polarity_flip_physical{96}=0xCF + +#BC12# +dport_map_port_60=17 +dport_map_port_61=18 +dport_map_port_62=19 +dport_map_port_63=20 +portmap_60=97:400 +phy_chain_rx_lane_map_physical{97.0}=0x51276034 +phy_chain_rx_lane_map_physical{98.0}=0x51276034 +phy_chain_rx_lane_map_physical{99.0}=0x51276034 +phy_chain_rx_lane_map_physical{100.0}=0x51276034 +phy_chain_rx_lane_map_physical{101.0}=0x51276034 +phy_chain_rx_lane_map_physical{102.0}=0x51276034 +phy_chain_rx_lane_map_physical{103.0}=0x51276034 +phy_chain_rx_lane_map_physical{104.0}=0x51276034 +phy_chain_tx_lane_map_physical{97.0}=0x05476321 +phy_chain_tx_lane_map_physical{98.0}=0x05476321 +phy_chain_tx_lane_map_physical{99.0}=0x05476321 +phy_chain_tx_lane_map_physical{100.0}=0x05476321 +phy_chain_tx_lane_map_physical{101.0}=0x05476321 +phy_chain_tx_lane_map_physical{102.0}=0x05476321 +phy_chain_tx_lane_map_physical{103.0}=0x05476321 +phy_chain_tx_lane_map_physical{104.0}=0x05476321 +serdes_core_rx_polarity_flip_physical{97}=0x8E +serdes_core_rx_polarity_flip_physical{98}=0x8E +serdes_core_rx_polarity_flip_physical{99}=0x8E +serdes_core_rx_polarity_flip_physical{100}=0x8E +serdes_core_rx_polarity_flip_physical{101}=0x8E +serdes_core_rx_polarity_flip_physical{102}=0x8E +serdes_core_rx_polarity_flip_physical{103}=0x8E +serdes_core_rx_polarity_flip_physical{104}=0x8E +serdes_core_tx_polarity_flip_physical{97}=0xC8 +serdes_core_tx_polarity_flip_physical{98}=0xC8 +serdes_core_tx_polarity_flip_physical{99}=0xC8 +serdes_core_tx_polarity_flip_physical{100}=0xC8 +serdes_core_tx_polarity_flip_physical{101}=0xC8 +serdes_core_tx_polarity_flip_physical{102}=0xC8 +serdes_core_tx_polarity_flip_physical{103}=0xC8 +serdes_core_tx_polarity_flip_physical{104}=0xC8 + +#BC13# +dport_map_port_64=21 +dport_map_port_65=22 +dport_map_port_66=23 +dport_map_port_67=24 +portmap_64=105:400 +phy_chain_rx_lane_map_physical{105.0}=0x74126503 +phy_chain_rx_lane_map_physical{106.0}=0x74126503 +phy_chain_rx_lane_map_physical{107.0}=0x74126503 +phy_chain_rx_lane_map_physical{108.0}=0x74126503 +phy_chain_rx_lane_map_physical{109.0}=0x74126503 +phy_chain_rx_lane_map_physical{110.0}=0x74126503 +phy_chain_rx_lane_map_physical{111.0}=0x74126503 +phy_chain_rx_lane_map_physical{112.0}=0x74126503 +phy_chain_tx_lane_map_physical{105.0}=0x75236140 +phy_chain_tx_lane_map_physical{106.0}=0x75236140 +phy_chain_tx_lane_map_physical{107.0}=0x75236140 +phy_chain_tx_lane_map_physical{108.0}=0x75236140 +phy_chain_tx_lane_map_physical{109.0}=0x75236140 +phy_chain_tx_lane_map_physical{110.0}=0x75236140 +phy_chain_tx_lane_map_physical{111.0}=0x75236140 +phy_chain_tx_lane_map_physical{112.0}=0x75236140 +serdes_core_rx_polarity_flip_physical{105}=0x96 +serdes_core_rx_polarity_flip_physical{106}=0x96 +serdes_core_rx_polarity_flip_physical{107}=0x96 +serdes_core_rx_polarity_flip_physical{108}=0x96 +serdes_core_rx_polarity_flip_physical{109}=0x96 +serdes_core_rx_polarity_flip_physical{110}=0x96 +serdes_core_rx_polarity_flip_physical{111}=0x96 +serdes_core_rx_polarity_flip_physical{112}=0x96 +serdes_core_tx_polarity_flip_physical{105}=0xE1 +serdes_core_tx_polarity_flip_physical{106}=0xE1 +serdes_core_tx_polarity_flip_physical{107}=0xE1 +serdes_core_tx_polarity_flip_physical{108}=0xE1 +serdes_core_tx_polarity_flip_physical{109}=0xE1 +serdes_core_tx_polarity_flip_physical{110}=0xE1 +serdes_core_tx_polarity_flip_physical{111}=0xE1 +serdes_core_tx_polarity_flip_physical{112}=0xE1 + +#BC14# +dport_map_port_68=25 +dport_map_port_69=26 +dport_map_port_70=27 +dport_map_port_71=28 +portmap_68=113:400 +phy_chain_rx_lane_map_physical{113.0}=0x32461057 +phy_chain_rx_lane_map_physical{114.0}=0x32461057 +phy_chain_rx_lane_map_physical{115.0}=0x32461057 +phy_chain_rx_lane_map_physical{116.0}=0x32461057 +phy_chain_rx_lane_map_physical{117.0}=0x32461057 +phy_chain_rx_lane_map_physical{118.0}=0x32461057 +phy_chain_rx_lane_map_physical{119.0}=0x32461057 +phy_chain_rx_lane_map_physical{120.0}=0x32461057 +phy_chain_tx_lane_map_physical{113.0}=0x54107362 +phy_chain_tx_lane_map_physical{114.0}=0x54107362 +phy_chain_tx_lane_map_physical{115.0}=0x54107362 +phy_chain_tx_lane_map_physical{116.0}=0x54107362 +phy_chain_tx_lane_map_physical{117.0}=0x54107362 +phy_chain_tx_lane_map_physical{118.0}=0x54107362 +phy_chain_tx_lane_map_physical{119.0}=0x54107362 +phy_chain_tx_lane_map_physical{120.0}=0x54107362 +serdes_core_rx_polarity_flip_physical{113}=0x47 +serdes_core_rx_polarity_flip_physical{114}=0x47 +serdes_core_rx_polarity_flip_physical{115}=0x47 +serdes_core_rx_polarity_flip_physical{116}=0x47 +serdes_core_rx_polarity_flip_physical{117}=0x47 +serdes_core_rx_polarity_flip_physical{118}=0x47 +serdes_core_rx_polarity_flip_physical{119}=0x47 +serdes_core_rx_polarity_flip_physical{120}=0x47 +serdes_core_tx_polarity_flip_physical{113}=0xBD +serdes_core_tx_polarity_flip_physical{114}=0xBD +serdes_core_tx_polarity_flip_physical{115}=0xBD +serdes_core_tx_polarity_flip_physical{116}=0xBD +serdes_core_tx_polarity_flip_physical{117}=0xBD +serdes_core_tx_polarity_flip_physical{118}=0xBD +serdes_core_tx_polarity_flip_physical{119}=0xBD +serdes_core_tx_polarity_flip_physical{120}=0xBD + +#BC15# +dport_map_port_72=29 +dport_map_port_73=30 +dport_map_port_74=31 +dport_map_port_75=32 +portmap_72=121:400 +phy_chain_rx_lane_map_physical{121.0}=0x75342610 +phy_chain_rx_lane_map_physical{122.0}=0x75342610 +phy_chain_rx_lane_map_physical{123.0}=0x75342610 +phy_chain_rx_lane_map_physical{124.0}=0x75342610 +phy_chain_rx_lane_map_physical{125.0}=0x75342610 +phy_chain_rx_lane_map_physical{126.0}=0x75342610 +phy_chain_rx_lane_map_physical{127.0}=0x75342610 +phy_chain_rx_lane_map_physical{128.0}=0x75342610 +phy_chain_tx_lane_map_physical{121.0}=0x24617350 +phy_chain_tx_lane_map_physical{122.0}=0x24617350 +phy_chain_tx_lane_map_physical{123.0}=0x24617350 +phy_chain_tx_lane_map_physical{124.0}=0x24617350 +phy_chain_tx_lane_map_physical{125.0}=0x24617350 +phy_chain_tx_lane_map_physical{126.0}=0x24617350 +phy_chain_tx_lane_map_physical{127.0}=0x24617350 +phy_chain_tx_lane_map_physical{128.0}=0x24617350 +serdes_core_rx_polarity_flip_physical{121}=0x36 +serdes_core_rx_polarity_flip_physical{122}=0x36 +serdes_core_rx_polarity_flip_physical{123}=0x36 +serdes_core_rx_polarity_flip_physical{124}=0x36 +serdes_core_rx_polarity_flip_physical{125}=0x36 +serdes_core_rx_polarity_flip_physical{126}=0x36 +serdes_core_rx_polarity_flip_physical{127}=0x36 +serdes_core_rx_polarity_flip_physical{128}=0x36 +serdes_core_tx_polarity_flip_physical{121}=0x7F +serdes_core_tx_polarity_flip_physical{122}=0x7F +serdes_core_tx_polarity_flip_physical{123}=0x7F +serdes_core_tx_polarity_flip_physical{124}=0x7F +serdes_core_tx_polarity_flip_physical{125}=0x7F +serdes_core_tx_polarity_flip_physical{126}=0x7F +serdes_core_tx_polarity_flip_physical{127}=0x7F +serdes_core_tx_polarity_flip_physical{128}=0x7F + +#BC16# +dport_map_port_80=49 +dport_map_port_81=50 +dport_map_port_82=51 +dport_map_port_83=52 +portmap_80=129:400 +phy_chain_rx_lane_map_physical{129.0}=0x45302716 +phy_chain_rx_lane_map_physical{130.0}=0x45302716 +phy_chain_rx_lane_map_physical{131.0}=0x45302716 +phy_chain_rx_lane_map_physical{132.0}=0x45302716 +phy_chain_rx_lane_map_physical{133.0}=0x45302716 +phy_chain_rx_lane_map_physical{134.0}=0x45302716 +phy_chain_rx_lane_map_physical{135.0}=0x45302716 +phy_chain_rx_lane_map_physical{136.0}=0x45302716 +phy_chain_tx_lane_map_physical{129.0}=0x24763150 +phy_chain_tx_lane_map_physical{130.0}=0x24763150 +phy_chain_tx_lane_map_physical{131.0}=0x24763150 +phy_chain_tx_lane_map_physical{132.0}=0x24763150 +phy_chain_tx_lane_map_physical{133.0}=0x24763150 +phy_chain_tx_lane_map_physical{134.0}=0x24763150 +phy_chain_tx_lane_map_physical{135.0}=0x24763150 +phy_chain_tx_lane_map_physical{136.0}=0x24763150 +serdes_core_rx_polarity_flip_physical{129}=0xA3 +serdes_core_rx_polarity_flip_physical{130}=0xA3 +serdes_core_rx_polarity_flip_physical{131}=0xA3 +serdes_core_rx_polarity_flip_physical{132}=0xA3 +serdes_core_rx_polarity_flip_physical{133}=0xA3 +serdes_core_rx_polarity_flip_physical{134}=0xA3 +serdes_core_rx_polarity_flip_physical{135}=0xA3 +serdes_core_rx_polarity_flip_physical{136}=0xA3 +serdes_core_tx_polarity_flip_physical{129}=0x5C +serdes_core_tx_polarity_flip_physical{130}=0x5C +serdes_core_tx_polarity_flip_physical{131}=0x5C +serdes_core_tx_polarity_flip_physical{132}=0x5C +serdes_core_tx_polarity_flip_physical{133}=0x5C +serdes_core_tx_polarity_flip_physical{134}=0x5C +serdes_core_tx_polarity_flip_physical{135}=0x5C +serdes_core_tx_polarity_flip_physical{136}=0x5C + +#BC17# +dport_map_port_84=53 +dport_map_port_85=54 +dport_map_port_86=55 +dport_map_port_87=56 +portmap_84=137:400 +phy_chain_rx_lane_map_physical{137.0}=0x12460357 +phy_chain_rx_lane_map_physical{138.0}=0x12460357 +phy_chain_rx_lane_map_physical{139.0}=0x12460357 +phy_chain_rx_lane_map_physical{140.0}=0x12460357 +phy_chain_rx_lane_map_physical{141.0}=0x12460357 +phy_chain_rx_lane_map_physical{142.0}=0x12460357 +phy_chain_rx_lane_map_physical{143.0}=0x12460357 +phy_chain_rx_lane_map_physical{144.0}=0x12460357 +phy_chain_tx_lane_map_physical{137.0}=0x70135462 +phy_chain_tx_lane_map_physical{138.0}=0x70135462 +phy_chain_tx_lane_map_physical{139.0}=0x70135462 +phy_chain_tx_lane_map_physical{140.0}=0x70135462 +phy_chain_tx_lane_map_physical{141.0}=0x70135462 +phy_chain_tx_lane_map_physical{142.0}=0x70135462 +phy_chain_tx_lane_map_physical{143.0}=0x70135462 +phy_chain_tx_lane_map_physical{144.0}=0x70135462 +serdes_core_rx_polarity_flip_physical{137}=0x4B +serdes_core_rx_polarity_flip_physical{138}=0x4B +serdes_core_rx_polarity_flip_physical{139}=0x4B +serdes_core_rx_polarity_flip_physical{140}=0x4B +serdes_core_rx_polarity_flip_physical{141}=0x4B +serdes_core_rx_polarity_flip_physical{142}=0x4B +serdes_core_rx_polarity_flip_physical{143}=0x4B +serdes_core_rx_polarity_flip_physical{144}=0x4B +serdes_core_tx_polarity_flip_physical{137}=0xF8 +serdes_core_tx_polarity_flip_physical{138}=0xF8 +serdes_core_tx_polarity_flip_physical{139}=0xF8 +serdes_core_tx_polarity_flip_physical{140}=0xF8 +serdes_core_tx_polarity_flip_physical{141}=0xF8 +serdes_core_tx_polarity_flip_physical{142}=0xF8 +serdes_core_tx_polarity_flip_physical{143}=0xF8 +serdes_core_tx_polarity_flip_physical{144}=0xF8 + +#BC18# +dport_map_port_88=57 +dport_map_port_89=58 +dport_map_port_90=59 +dport_map_port_91=60 +portmap_88=145:400 +phy_chain_rx_lane_map_physical{145.0}=0x20563147 +phy_chain_rx_lane_map_physical{146.0}=0x20563147 +phy_chain_rx_lane_map_physical{147.0}=0x20563147 +phy_chain_rx_lane_map_physical{148.0}=0x20563147 +phy_chain_rx_lane_map_physical{149.0}=0x20563147 +phy_chain_rx_lane_map_physical{150.0}=0x20563147 +phy_chain_rx_lane_map_physical{151.0}=0x20563147 +phy_chain_rx_lane_map_physical{152.0}=0x20563147 +phy_chain_tx_lane_map_physical{145.0}=0x54126073 +phy_chain_tx_lane_map_physical{146.0}=0x54126073 +phy_chain_tx_lane_map_physical{147.0}=0x54126073 +phy_chain_tx_lane_map_physical{148.0}=0x54126073 +phy_chain_tx_lane_map_physical{149.0}=0x54126073 +phy_chain_tx_lane_map_physical{150.0}=0x54126073 +phy_chain_tx_lane_map_physical{151.0}=0x54126073 +phy_chain_tx_lane_map_physical{152.0}=0x54126073 +serdes_core_rx_polarity_flip_physical{145}=0xE1 +serdes_core_rx_polarity_flip_physical{146}=0xE1 +serdes_core_rx_polarity_flip_physical{147}=0xE1 +serdes_core_rx_polarity_flip_physical{148}=0xE1 +serdes_core_rx_polarity_flip_physical{149}=0xE1 +serdes_core_rx_polarity_flip_physical{150}=0xE1 +serdes_core_rx_polarity_flip_physical{151}=0xE1 +serdes_core_rx_polarity_flip_physical{152}=0xE1 +serdes_core_tx_polarity_flip_physical{145}=0xD5 +serdes_core_tx_polarity_flip_physical{146}=0xD5 +serdes_core_tx_polarity_flip_physical{147}=0xD5 +serdes_core_tx_polarity_flip_physical{148}=0xD5 +serdes_core_tx_polarity_flip_physical{149}=0xD5 +serdes_core_tx_polarity_flip_physical{150}=0xD5 +serdes_core_tx_polarity_flip_physical{151}=0xD5 +serdes_core_tx_polarity_flip_physical{152}=0xD5 + +#BC19# +dport_map_port_92=61 +dport_map_port_93=62 +dport_map_port_94=63 +dport_map_port_95=64 +portmap_92=153:400 +phy_chain_rx_lane_map_physical{153.0}=0x10652473 +phy_chain_rx_lane_map_physical{154.0}=0x10652473 +phy_chain_rx_lane_map_physical{155.0}=0x10652473 +phy_chain_rx_lane_map_physical{156.0}=0x10652473 +phy_chain_rx_lane_map_physical{157.0}=0x10652473 +phy_chain_rx_lane_map_physical{158.0}=0x10652473 +phy_chain_rx_lane_map_physical{159.0}=0x10652473 +phy_chain_rx_lane_map_physical{160.0}=0x10652473 +phy_chain_tx_lane_map_physical{153.0}=0x15036427 +phy_chain_tx_lane_map_physical{154.0}=0x15036427 +phy_chain_tx_lane_map_physical{155.0}=0x15036427 +phy_chain_tx_lane_map_physical{156.0}=0x15036427 +phy_chain_tx_lane_map_physical{157.0}=0x15036427 +phy_chain_tx_lane_map_physical{158.0}=0x15036427 +phy_chain_tx_lane_map_physical{159.0}=0x15036427 +phy_chain_tx_lane_map_physical{160.0}=0x15036427 +serdes_core_rx_polarity_flip_physical{153}=0xB1 +serdes_core_rx_polarity_flip_physical{154}=0xB1 +serdes_core_rx_polarity_flip_physical{155}=0xB1 +serdes_core_rx_polarity_flip_physical{156}=0xB1 +serdes_core_rx_polarity_flip_physical{157}=0xB1 +serdes_core_rx_polarity_flip_physical{158}=0xB1 +serdes_core_rx_polarity_flip_physical{159}=0xB1 +serdes_core_rx_polarity_flip_physical{160}=0xB1 +serdes_core_tx_polarity_flip_physical{153}=0x5E +serdes_core_tx_polarity_flip_physical{154}=0x5E +serdes_core_tx_polarity_flip_physical{155}=0x5E +serdes_core_tx_polarity_flip_physical{156}=0x5E +serdes_core_tx_polarity_flip_physical{157}=0x5E +serdes_core_tx_polarity_flip_physical{158}=0x5E +serdes_core_tx_polarity_flip_physical{159}=0x5E +serdes_core_tx_polarity_flip_physical{160}=0x5E + +#BC20# +dport_map_port_104=69 +dport_map_port_105=70 +dport_map_port_106=71 +dport_map_port_107=72 +portmap_104=161:400 +phy_chain_rx_lane_map_physical{161.0}=0x70125643 +phy_chain_rx_lane_map_physical{162.0}=0x70125643 +phy_chain_rx_lane_map_physical{163.0}=0x70125643 +phy_chain_rx_lane_map_physical{164.0}=0x70125643 +phy_chain_rx_lane_map_physical{165.0}=0x70125643 +phy_chain_rx_lane_map_physical{166.0}=0x70125643 +phy_chain_rx_lane_map_physical{167.0}=0x70125643 +phy_chain_rx_lane_map_physical{168.0}=0x70125643 +phy_chain_tx_lane_map_physical{161.0}=0x21073456 +phy_chain_tx_lane_map_physical{162.0}=0x21073456 +phy_chain_tx_lane_map_physical{163.0}=0x21073456 +phy_chain_tx_lane_map_physical{164.0}=0x21073456 +phy_chain_tx_lane_map_physical{165.0}=0x21073456 +phy_chain_tx_lane_map_physical{166.0}=0x21073456 +phy_chain_tx_lane_map_physical{167.0}=0x21073456 +phy_chain_tx_lane_map_physical{168.0}=0x21073456 +serdes_core_rx_polarity_flip_physical{161}=0x27 +serdes_core_rx_polarity_flip_physical{162}=0x27 +serdes_core_rx_polarity_flip_physical{163}=0x27 +serdes_core_rx_polarity_flip_physical{164}=0x27 +serdes_core_rx_polarity_flip_physical{165}=0x27 +serdes_core_rx_polarity_flip_physical{166}=0x27 +serdes_core_rx_polarity_flip_physical{167}=0x27 +serdes_core_rx_polarity_flip_physical{168}=0x27 +serdes_core_tx_polarity_flip_physical{161}=0x5 +serdes_core_tx_polarity_flip_physical{162}=0x5 +serdes_core_tx_polarity_flip_physical{163}=0x5 +serdes_core_tx_polarity_flip_physical{164}=0x5 +serdes_core_tx_polarity_flip_physical{165}=0x5 +serdes_core_tx_polarity_flip_physical{166}=0x5 +serdes_core_tx_polarity_flip_physical{167}=0x5 +serdes_core_tx_polarity_flip_physical{168}=0x5 + +#BC21# +dport_map_port_100=65 +dport_map_port_101=66 +dport_map_port_102=67 +dport_map_port_103=68 +portmap_100=169:400 +phy_chain_rx_lane_map_physical{169.0}=0x27416350 +phy_chain_rx_lane_map_physical{170.0}=0x27416350 +phy_chain_rx_lane_map_physical{171.0}=0x27416350 +phy_chain_rx_lane_map_physical{172.0}=0x27416350 +phy_chain_rx_lane_map_physical{173.0}=0x27416350 +phy_chain_rx_lane_map_physical{174.0}=0x27416350 +phy_chain_rx_lane_map_physical{175.0}=0x27416350 +phy_chain_rx_lane_map_physical{176.0}=0x27416350 +phy_chain_tx_lane_map_physical{169.0}=0x36570412 +phy_chain_tx_lane_map_physical{170.0}=0x36570412 +phy_chain_tx_lane_map_physical{171.0}=0x36570412 +phy_chain_tx_lane_map_physical{172.0}=0x36570412 +phy_chain_tx_lane_map_physical{173.0}=0x36570412 +phy_chain_tx_lane_map_physical{174.0}=0x36570412 +phy_chain_tx_lane_map_physical{175.0}=0x36570412 +phy_chain_tx_lane_map_physical{176.0}=0x36570412 +serdes_core_rx_polarity_flip_physical{169}=0x3C +serdes_core_rx_polarity_flip_physical{170}=0x3C +serdes_core_rx_polarity_flip_physical{171}=0x3C +serdes_core_rx_polarity_flip_physical{172}=0x3C +serdes_core_rx_polarity_flip_physical{173}=0x3C +serdes_core_rx_polarity_flip_physical{174}=0x3C +serdes_core_rx_polarity_flip_physical{175}=0x3C +serdes_core_rx_polarity_flip_physical{176}=0x3C +serdes_core_tx_polarity_flip_physical{169}=0x7D +serdes_core_tx_polarity_flip_physical{170}=0x7D +serdes_core_tx_polarity_flip_physical{171}=0x7D +serdes_core_tx_polarity_flip_physical{172}=0x7D +serdes_core_tx_polarity_flip_physical{173}=0x7D +serdes_core_tx_polarity_flip_physical{174}=0x7D +serdes_core_tx_polarity_flip_physical{175}=0x7D +serdes_core_tx_polarity_flip_physical{176}=0x7D + +#BC22# +dport_map_port_108=73 +dport_map_port_109=74 +dport_map_port_110=75 +dport_map_port_111=76 +portmap_108=177:400 +phy_chain_rx_lane_map_physical{177.0}=0x04153726 +phy_chain_rx_lane_map_physical{178.0}=0x04153726 +phy_chain_rx_lane_map_physical{179.0}=0x04153726 +phy_chain_rx_lane_map_physical{180.0}=0x04153726 +phy_chain_rx_lane_map_physical{181.0}=0x04153726 +phy_chain_rx_lane_map_physical{182.0}=0x04153726 +phy_chain_rx_lane_map_physical{183.0}=0x04153726 +phy_chain_rx_lane_map_physical{184.0}=0x04153726 +phy_chain_tx_lane_map_physical{177.0}=0x47305162 +phy_chain_tx_lane_map_physical{178.0}=0x47305162 +phy_chain_tx_lane_map_physical{179.0}=0x47305162 +phy_chain_tx_lane_map_physical{180.0}=0x47305162 +phy_chain_tx_lane_map_physical{181.0}=0x47305162 +phy_chain_tx_lane_map_physical{182.0}=0x47305162 +phy_chain_tx_lane_map_physical{183.0}=0x47305162 +phy_chain_tx_lane_map_physical{184.0}=0x47305162 +serdes_core_rx_polarity_flip_physical{177}=0x96 +serdes_core_rx_polarity_flip_physical{178}=0x96 +serdes_core_rx_polarity_flip_physical{179}=0x96 +serdes_core_rx_polarity_flip_physical{180}=0x96 +serdes_core_rx_polarity_flip_physical{181}=0x96 +serdes_core_rx_polarity_flip_physical{182}=0x96 +serdes_core_rx_polarity_flip_physical{183}=0x96 +serdes_core_rx_polarity_flip_physical{184}=0x96 +serdes_core_tx_polarity_flip_physical{177}=0xE9 +serdes_core_tx_polarity_flip_physical{178}=0xE9 +serdes_core_tx_polarity_flip_physical{179}=0xE9 +serdes_core_tx_polarity_flip_physical{180}=0xE9 +serdes_core_tx_polarity_flip_physical{181}=0xE9 +serdes_core_tx_polarity_flip_physical{182}=0xE9 +serdes_core_tx_polarity_flip_physical{183}=0xE9 +serdes_core_tx_polarity_flip_physical{184}=0xE9 + +#BC23# +dport_map_port_112=77 +dport_map_port_113=78 +dport_map_port_114=79 +dport_map_port_115=80 +portmap_112=185:400 +phy_chain_rx_lane_map_physical{185.0}=0x02561347 +phy_chain_rx_lane_map_physical{186.0}=0x02561347 +phy_chain_rx_lane_map_physical{187.0}=0x02561347 +phy_chain_rx_lane_map_physical{188.0}=0x02561347 +phy_chain_rx_lane_map_physical{189.0}=0x02561347 +phy_chain_rx_lane_map_physical{190.0}=0x02561347 +phy_chain_rx_lane_map_physical{191.0}=0x02561347 +phy_chain_rx_lane_map_physical{192.0}=0x02561347 +phy_chain_tx_lane_map_physical{185.0}=0x50327614 +phy_chain_tx_lane_map_physical{186.0}=0x50327614 +phy_chain_tx_lane_map_physical{187.0}=0x50327614 +phy_chain_tx_lane_map_physical{188.0}=0x50327614 +phy_chain_tx_lane_map_physical{189.0}=0x50327614 +phy_chain_tx_lane_map_physical{190.0}=0x50327614 +phy_chain_tx_lane_map_physical{191.0}=0x50327614 +phy_chain_tx_lane_map_physical{192.0}=0x50327614 +serdes_core_rx_polarity_flip_physical{185}=0xE1 +serdes_core_rx_polarity_flip_physical{186}=0xE1 +serdes_core_rx_polarity_flip_physical{187}=0xE1 +serdes_core_rx_polarity_flip_physical{188}=0xE1 +serdes_core_rx_polarity_flip_physical{189}=0xE1 +serdes_core_rx_polarity_flip_physical{190}=0xE1 +serdes_core_rx_polarity_flip_physical{191}=0xE1 +serdes_core_rx_polarity_flip_physical{192}=0xE1 +serdes_core_tx_polarity_flip_physical{185}=0x0 +serdes_core_tx_polarity_flip_physical{186}=0x0 +serdes_core_tx_polarity_flip_physical{187}=0x0 +serdes_core_tx_polarity_flip_physical{188}=0x0 +serdes_core_tx_polarity_flip_physical{189}=0x0 +serdes_core_tx_polarity_flip_physical{190}=0x0 +serdes_core_tx_polarity_flip_physical{191}=0x0 +serdes_core_tx_polarity_flip_physical{192}=0x0 + +#BC24# +dport_map_port_124=101 +dport_map_port_125=102 +dport_map_port_126=103 +dport_map_port_127=104 +portmap_124=193:400 +phy_chain_rx_lane_map_physical{193.0}=0x74126503 +phy_chain_rx_lane_map_physical{194.0}=0x74126503 +phy_chain_rx_lane_map_physical{195.0}=0x74126503 +phy_chain_rx_lane_map_physical{196.0}=0x74126503 +phy_chain_rx_lane_map_physical{197.0}=0x74126503 +phy_chain_rx_lane_map_physical{198.0}=0x74126503 +phy_chain_rx_lane_map_physical{199.0}=0x74126503 +phy_chain_rx_lane_map_physical{200.0}=0x74126503 +phy_chain_tx_lane_map_physical{193.0}=0x43571620 +phy_chain_tx_lane_map_physical{194.0}=0x43571620 +phy_chain_tx_lane_map_physical{195.0}=0x43571620 +phy_chain_tx_lane_map_physical{196.0}=0x43571620 +phy_chain_tx_lane_map_physical{197.0}=0x43571620 +phy_chain_tx_lane_map_physical{198.0}=0x43571620 +phy_chain_tx_lane_map_physical{199.0}=0x43571620 +phy_chain_tx_lane_map_physical{200.0}=0x43571620 +serdes_core_rx_polarity_flip_physical{193}=0x69 +serdes_core_rx_polarity_flip_physical{194}=0x69 +serdes_core_rx_polarity_flip_physical{195}=0x69 +serdes_core_rx_polarity_flip_physical{196}=0x69 +serdes_core_rx_polarity_flip_physical{197}=0x69 +serdes_core_rx_polarity_flip_physical{198}=0x69 +serdes_core_rx_polarity_flip_physical{199}=0x69 +serdes_core_rx_polarity_flip_physical{200}=0x69 +serdes_core_tx_polarity_flip_physical{193}=0xC4 +serdes_core_tx_polarity_flip_physical{194}=0xC4 +serdes_core_tx_polarity_flip_physical{195}=0xC4 +serdes_core_tx_polarity_flip_physical{196}=0xC4 +serdes_core_tx_polarity_flip_physical{197}=0xC4 +serdes_core_tx_polarity_flip_physical{198}=0xC4 +serdes_core_tx_polarity_flip_physical{199}=0xC4 +serdes_core_tx_polarity_flip_physical{200}=0xC4 + +#BC25# +dport_map_port_120=97 +dport_map_port_121=98 +dport_map_port_122=99 +dport_map_port_123=100 +portmap_120=201:400 +phy_chain_rx_lane_map_physical{201.0}=0x45031726 +phy_chain_rx_lane_map_physical{202.0}=0x45031726 +phy_chain_rx_lane_map_physical{203.0}=0x45031726 +phy_chain_rx_lane_map_physical{204.0}=0x45031726 +phy_chain_rx_lane_map_physical{205.0}=0x45031726 +phy_chain_rx_lane_map_physical{206.0}=0x45031726 +phy_chain_rx_lane_map_physical{207.0}=0x45031726 +phy_chain_rx_lane_map_physical{208.0}=0x45031726 +phy_chain_tx_lane_map_physical{201.0}=0x23761450 +phy_chain_tx_lane_map_physical{202.0}=0x23761450 +phy_chain_tx_lane_map_physical{203.0}=0x23761450 +phy_chain_tx_lane_map_physical{204.0}=0x23761450 +phy_chain_tx_lane_map_physical{205.0}=0x23761450 +phy_chain_tx_lane_map_physical{206.0}=0x23761450 +phy_chain_tx_lane_map_physical{207.0}=0x23761450 +phy_chain_tx_lane_map_physical{208.0}=0x23761450 +serdes_core_rx_polarity_flip_physical{201}=0x99 +serdes_core_rx_polarity_flip_physical{202}=0x99 +serdes_core_rx_polarity_flip_physical{203}=0x99 +serdes_core_rx_polarity_flip_physical{204}=0x99 +serdes_core_rx_polarity_flip_physical{205}=0x99 +serdes_core_rx_polarity_flip_physical{206}=0x99 +serdes_core_rx_polarity_flip_physical{207}=0x99 +serdes_core_rx_polarity_flip_physical{208}=0x99 +serdes_core_tx_polarity_flip_physical{201}=0x7F +serdes_core_tx_polarity_flip_physical{202}=0x7F +serdes_core_tx_polarity_flip_physical{203}=0x7F +serdes_core_tx_polarity_flip_physical{204}=0x7F +serdes_core_tx_polarity_flip_physical{205}=0x7F +serdes_core_tx_polarity_flip_physical{206}=0x7F +serdes_core_tx_polarity_flip_physical{207}=0x7F +serdes_core_tx_polarity_flip_physical{208}=0x7F + +#BC26# +dport_map_port_132=109 +dport_map_port_133=110 +dport_map_port_134=111 +dport_map_port_135=112 +portmap_132=209:400 +phy_chain_rx_lane_map_physical{209.0}=0x46150723 +phy_chain_rx_lane_map_physical{210.0}=0x46150723 +phy_chain_rx_lane_map_physical{211.0}=0x46150723 +phy_chain_rx_lane_map_physical{212.0}=0x46150723 +phy_chain_rx_lane_map_physical{213.0}=0x46150723 +phy_chain_rx_lane_map_physical{214.0}=0x46150723 +phy_chain_rx_lane_map_physical{215.0}=0x46150723 +phy_chain_rx_lane_map_physical{216.0}=0x46150723 +phy_chain_tx_lane_map_physical{209.0}=0x12603754 +phy_chain_tx_lane_map_physical{210.0}=0x12603754 +phy_chain_tx_lane_map_physical{211.0}=0x12603754 +phy_chain_tx_lane_map_physical{212.0}=0x12603754 +phy_chain_tx_lane_map_physical{213.0}=0x12603754 +phy_chain_tx_lane_map_physical{214.0}=0x12603754 +phy_chain_tx_lane_map_physical{215.0}=0x12603754 +phy_chain_tx_lane_map_physical{216.0}=0x12603754 +serdes_core_rx_polarity_flip_physical{209}=0xE1 +serdes_core_rx_polarity_flip_physical{210}=0xE1 +serdes_core_rx_polarity_flip_physical{211}=0xE1 +serdes_core_rx_polarity_flip_physical{212}=0xE1 +serdes_core_rx_polarity_flip_physical{213}=0xE1 +serdes_core_rx_polarity_flip_physical{214}=0xE1 +serdes_core_rx_polarity_flip_physical{215}=0xE1 +serdes_core_rx_polarity_flip_physical{216}=0xE1 +serdes_core_tx_polarity_flip_physical{209}=0x29 +serdes_core_tx_polarity_flip_physical{210}=0x29 +serdes_core_tx_polarity_flip_physical{211}=0x29 +serdes_core_tx_polarity_flip_physical{212}=0x29 +serdes_core_tx_polarity_flip_physical{213}=0x29 +serdes_core_tx_polarity_flip_physical{214}=0x29 +serdes_core_tx_polarity_flip_physical{215}=0x29 +serdes_core_tx_polarity_flip_physical{216}=0x29 + +#BC27# +dport_map_port_128=105 +dport_map_port_129=106 +dport_map_port_130=107 +dport_map_port_131=108 +portmap_128=217:400 +phy_chain_rx_lane_map_physical{217.0}=0x46127503 +phy_chain_rx_lane_map_physical{218.0}=0x46127503 +phy_chain_rx_lane_map_physical{219.0}=0x46127503 +phy_chain_rx_lane_map_physical{220.0}=0x46127503 +phy_chain_rx_lane_map_physical{221.0}=0x46127503 +phy_chain_rx_lane_map_physical{222.0}=0x46127503 +phy_chain_rx_lane_map_physical{223.0}=0x46127503 +phy_chain_rx_lane_map_physical{224.0}=0x46127503 +phy_chain_tx_lane_map_physical{217.0}=0x54273016 +phy_chain_tx_lane_map_physical{218.0}=0x54273016 +phy_chain_tx_lane_map_physical{219.0}=0x54273016 +phy_chain_tx_lane_map_physical{220.0}=0x54273016 +phy_chain_tx_lane_map_physical{221.0}=0x54273016 +phy_chain_tx_lane_map_physical{222.0}=0x54273016 +phy_chain_tx_lane_map_physical{223.0}=0x54273016 +phy_chain_tx_lane_map_physical{224.0}=0x54273016 +serdes_core_rx_polarity_flip_physical{217}=0xE1 +serdes_core_rx_polarity_flip_physical{218}=0xE1 +serdes_core_rx_polarity_flip_physical{219}=0xE1 +serdes_core_rx_polarity_flip_physical{220}=0xE1 +serdes_core_rx_polarity_flip_physical{221}=0xE1 +serdes_core_rx_polarity_flip_physical{222}=0xE1 +serdes_core_rx_polarity_flip_physical{223}=0xE1 +serdes_core_rx_polarity_flip_physical{224}=0xE1 +serdes_core_tx_polarity_flip_physical{217}=0x5B +serdes_core_tx_polarity_flip_physical{218}=0x5B +serdes_core_tx_polarity_flip_physical{219}=0x5B +serdes_core_tx_polarity_flip_physical{220}=0x5B +serdes_core_tx_polarity_flip_physical{221}=0x5B +serdes_core_tx_polarity_flip_physical{222}=0x5B +serdes_core_tx_polarity_flip_physical{223}=0x5B +serdes_core_tx_polarity_flip_physical{224}=0x5B + +#BC28# +dport_map_port_144=117 +dport_map_port_145=118 +dport_map_port_146=119 +dport_map_port_147=120 +portmap_144=225:400 +phy_chain_rx_lane_map_physical{225.0}=0x52761340 +phy_chain_rx_lane_map_physical{226.0}=0x52761340 +phy_chain_rx_lane_map_physical{227.0}=0x52761340 +phy_chain_rx_lane_map_physical{228.0}=0x52761340 +phy_chain_rx_lane_map_physical{229.0}=0x52761340 +phy_chain_rx_lane_map_physical{230.0}=0x52761340 +phy_chain_rx_lane_map_physical{231.0}=0x52761340 +phy_chain_rx_lane_map_physical{232.0}=0x52761340 +phy_chain_tx_lane_map_physical{225.0}=0x53462107 +phy_chain_tx_lane_map_physical{226.0}=0x53462107 +phy_chain_tx_lane_map_physical{227.0}=0x53462107 +phy_chain_tx_lane_map_physical{228.0}=0x53462107 +phy_chain_tx_lane_map_physical{229.0}=0x53462107 +phy_chain_tx_lane_map_physical{230.0}=0x53462107 +phy_chain_tx_lane_map_physical{231.0}=0x53462107 +phy_chain_tx_lane_map_physical{232.0}=0x53462107 +serdes_core_rx_polarity_flip_physical{225}=0x3C +serdes_core_rx_polarity_flip_physical{226}=0x3C +serdes_core_rx_polarity_flip_physical{227}=0x3C +serdes_core_rx_polarity_flip_physical{228}=0x3C +serdes_core_rx_polarity_flip_physical{229}=0x3C +serdes_core_rx_polarity_flip_physical{230}=0x3C +serdes_core_rx_polarity_flip_physical{231}=0x3C +serdes_core_rx_polarity_flip_physical{232}=0x3C +serdes_core_tx_polarity_flip_physical{225}=0x71 +serdes_core_tx_polarity_flip_physical{226}=0x71 +serdes_core_tx_polarity_flip_physical{227}=0x71 +serdes_core_tx_polarity_flip_physical{228}=0x71 +serdes_core_tx_polarity_flip_physical{229}=0x71 +serdes_core_tx_polarity_flip_physical{230}=0x71 +serdes_core_tx_polarity_flip_physical{231}=0x71 +serdes_core_tx_polarity_flip_physical{232}=0x71 + +#BC29# +dport_map_port_140=113 +dport_map_port_141=114 +dport_map_port_142=115 +dport_map_port_143=116 +portmap_140=233:400 +phy_chain_rx_lane_map_physical{233.0}=0x45021736 +phy_chain_rx_lane_map_physical{234.0}=0x45021736 +phy_chain_rx_lane_map_physical{235.0}=0x45021736 +phy_chain_rx_lane_map_physical{236.0}=0x45021736 +phy_chain_rx_lane_map_physical{237.0}=0x45021736 +phy_chain_rx_lane_map_physical{238.0}=0x45021736 +phy_chain_rx_lane_map_physical{239.0}=0x45021736 +phy_chain_rx_lane_map_physical{240.0}=0x45021736 +phy_chain_tx_lane_map_physical{233.0}=0x20465371 +phy_chain_tx_lane_map_physical{234.0}=0x20465371 +phy_chain_tx_lane_map_physical{235.0}=0x20465371 +phy_chain_tx_lane_map_physical{236.0}=0x20465371 +phy_chain_tx_lane_map_physical{237.0}=0x20465371 +phy_chain_tx_lane_map_physical{238.0}=0x20465371 +phy_chain_tx_lane_map_physical{239.0}=0x20465371 +phy_chain_tx_lane_map_physical{240.0}=0x20465371 +serdes_core_rx_polarity_flip_physical{233}=0x8B +serdes_core_rx_polarity_flip_physical{234}=0x8B +serdes_core_rx_polarity_flip_physical{235}=0x8B +serdes_core_rx_polarity_flip_physical{236}=0x8B +serdes_core_rx_polarity_flip_physical{237}=0x8B +serdes_core_rx_polarity_flip_physical{238}=0x8B +serdes_core_rx_polarity_flip_physical{239}=0x8B +serdes_core_rx_polarity_flip_physical{240}=0x8B +serdes_core_tx_polarity_flip_physical{233}=0x35 +serdes_core_tx_polarity_flip_physical{234}=0x35 +serdes_core_tx_polarity_flip_physical{235}=0x35 +serdes_core_tx_polarity_flip_physical{236}=0x35 +serdes_core_tx_polarity_flip_physical{237}=0x35 +serdes_core_tx_polarity_flip_physical{238}=0x35 +serdes_core_tx_polarity_flip_physical{239}=0x35 +serdes_core_tx_polarity_flip_physical{240}=0x35 + +#BC30# +dport_map_port_152=125 +dport_map_port_153=126 +dport_map_port_154=127 +dport_map_port_155=128 +portmap_152=241:400 +phy_chain_rx_lane_map_physical{241.0}=0x65721403 +phy_chain_rx_lane_map_physical{242.0}=0x65721403 +phy_chain_rx_lane_map_physical{243.0}=0x65721403 +phy_chain_rx_lane_map_physical{244.0}=0x65721403 +phy_chain_rx_lane_map_physical{245.0}=0x65721403 +phy_chain_rx_lane_map_physical{246.0}=0x65721403 +phy_chain_rx_lane_map_physical{247.0}=0x65721403 +phy_chain_rx_lane_map_physical{248.0}=0x65721403 +phy_chain_tx_lane_map_physical{241.0}=0x32647150 +phy_chain_tx_lane_map_physical{242.0}=0x32647150 +phy_chain_tx_lane_map_physical{243.0}=0x32647150 +phy_chain_tx_lane_map_physical{244.0}=0x32647150 +phy_chain_tx_lane_map_physical{245.0}=0x32647150 +phy_chain_tx_lane_map_physical{246.0}=0x32647150 +phy_chain_tx_lane_map_physical{247.0}=0x32647150 +phy_chain_tx_lane_map_physical{248.0}=0x32647150 +serdes_core_rx_polarity_flip_physical{241}=0x8D +serdes_core_rx_polarity_flip_physical{242}=0x8D +serdes_core_rx_polarity_flip_physical{243}=0x8D +serdes_core_rx_polarity_flip_physical{244}=0x8D +serdes_core_rx_polarity_flip_physical{245}=0x8D +serdes_core_rx_polarity_flip_physical{246}=0x8D +serdes_core_rx_polarity_flip_physical{247}=0x8D +serdes_core_rx_polarity_flip_physical{248}=0x8D +serdes_core_tx_polarity_flip_physical{241}=0x35 +serdes_core_tx_polarity_flip_physical{242}=0x35 +serdes_core_tx_polarity_flip_physical{243}=0x35 +serdes_core_tx_polarity_flip_physical{244}=0x35 +serdes_core_tx_polarity_flip_physical{245}=0x35 +serdes_core_tx_polarity_flip_physical{246}=0x35 +serdes_core_tx_polarity_flip_physical{247}=0x35 +serdes_core_tx_polarity_flip_physical{248}=0x35 + +#BC31# +dport_map_port_148=121 +dport_map_port_149=122 +dport_map_port_150=123 +dport_map_port_151=124 +portmap_148=249:400 +phy_chain_rx_lane_map_physical{249.0}=0x13560247 +phy_chain_rx_lane_map_physical{250.0}=0x13560247 +phy_chain_rx_lane_map_physical{251.0}=0x13560247 +phy_chain_rx_lane_map_physical{252.0}=0x13560247 +phy_chain_rx_lane_map_physical{253.0}=0x13560247 +phy_chain_rx_lane_map_physical{254.0}=0x13560247 +phy_chain_rx_lane_map_physical{255.0}=0x13560247 +phy_chain_rx_lane_map_physical{256.0}=0x13560247 +phy_chain_tx_lane_map_physical{249.0}=0x10456273 +phy_chain_tx_lane_map_physical{250.0}=0x10456273 +phy_chain_tx_lane_map_physical{251.0}=0x10456273 +phy_chain_tx_lane_map_physical{252.0}=0x10456273 +phy_chain_tx_lane_map_physical{253.0}=0x10456273 +phy_chain_tx_lane_map_physical{254.0}=0x10456273 +phy_chain_tx_lane_map_physical{255.0}=0x10456273 +phy_chain_tx_lane_map_physical{256.0}=0x10456273 +serdes_core_rx_polarity_flip_physical{249}=0x2D +serdes_core_rx_polarity_flip_physical{250}=0x2D +serdes_core_rx_polarity_flip_physical{251}=0x2D +serdes_core_rx_polarity_flip_physical{252}=0x2D +serdes_core_rx_polarity_flip_physical{253}=0x2D +serdes_core_rx_polarity_flip_physical{254}=0x2D +serdes_core_rx_polarity_flip_physical{255}=0x2D +serdes_core_rx_polarity_flip_physical{256}=0x2D +serdes_core_tx_polarity_flip_physical{249}=0xD6 +serdes_core_tx_polarity_flip_physical{250}=0xD6 +serdes_core_tx_polarity_flip_physical{251}=0xD6 +serdes_core_tx_polarity_flip_physical{252}=0xD6 +serdes_core_tx_polarity_flip_physical{253}=0xD6 +serdes_core_tx_polarity_flip_physical{254}=0xD6 +serdes_core_tx_polarity_flip_physical{255}=0xD6 +serdes_core_tx_polarity_flip_physical{256}=0xD6 + +#dport_map_port_38=129 +#portmap_38=257:10 +#dport_map_port_118=130 +#portmap_118=258:10 diff --git a/device/accton/x86_64-accton_as9716_32d-r0/custom_led.bin b/device/accton/x86_64-accton_as9716_32d-r0/custom_led.bin new file mode 100644 index 0000000000000000000000000000000000000000..07cfab044f60a214db558d0c7b274a5ad359d5a9 GIT binary patch literal 2044 zcmZA23s_TS9LMqZYy&1Lf>**Lo^6V#sN50_im}(7nq9WaTBS9~(ku%t)393Kp;ETz`8@A`=lu73-}CM{&)ZZ#T1vTX z^PF0f+Flhlq0O=`7L)X`UQ^Z*M{~gA5!Mo4l24?#JymkV=vrAP+`}}ruPT~OG@A#{ z&<$BLd`_9`vkyELuzNbwEv%9Ld{?FHss6Wre`|k%9NN;K?MZFz&n7?py!@T5{pa#i zM-8z}^NBt=zEsyd8LKLp;Y_ijWi>X@RCwB`I%E{r6pL7NW{ty7=kbdi*3-jd&Z?5# z&YNLr>kQ{sq*xm#35%t)gRQKzy{)FSv9z#vC2G>Hzb+{fkU9D{G8+xHPQqTvf$Ur8tkc|s5 z7&#aMwp*~>g6$S;x8N@jmmnW@+=tnigZnWT58y$}LnR)ahhc z;}yJ$*YG;Fq5*HBb#1B@^s3ekvx8Ep`YwrGd;h(ia&BLN-J37ydeUC|ARxByA$ z4i!C+jGoY-umB@=Q@@8jcpo3&Lwp23-oo41jvd&EcknKD;R}3;udomM@io3d2mySI zPw*-B;xl}XAb!9R{D_}$6hGq^G~oam@huMGJA98rIE+8gjMMlNf8lS05!vKp49D>+ ze!~g;j*~crbD#M7*}5{cXnaiWzB-|q(s~AKM28XE$F7x%t;*?598=+Rj4iN>P9Y=T zixS6GD4OWsE>M(MT_O6L1BHpZS~`?;L&&I!kU@)Y*pW~A*<538u+E&?GdM>iw4@p| zHPo7%yt2SxOHBGV+wi~aJryO6qJnKnXR?JR8iHgu)lZbga-Np_jZqg#MVlpg zT{Y2ry_{vMmM*iBvcPFvo~sU*E2R=rvXvZ{G-Xsu(@^_v;{anI#%guM`P+sJ)JB`l zVfM#|6l%p{aTxruAu+%lu*(cJd~#|yNA0 zhwvM#jcNUYUHl>~I^dQ4oQq|OJ3%*OB=~x{V)fe7{r=_D4*1>VTXX9&d%62X~=qH6P6&V+Sx1Ls0G9L|rN4X5f& zY6mr0?V|VPIa9)Mo}-Byg-t(FB6@d Date: Wed, 22 Apr 2020 19:41:48 -0700 Subject: [PATCH 09/69] [platform-modules]: set debian control depends on unsigned kernel package (#4466) Signed-off-by: Guohan Lu --- platform/barefoot/bfn-modules/debian/control | 2 +- .../debian/control | 2 +- .../debian/control | 2 +- .../sonic-platform-modules-bfn/debian/control | 2 +- .../debian/control | 2 +- platform/broadcom/saibcm-modules/debian/control | 2 +- .../debian/control | 4 ++-- .../sonic-platform-modules-cel/debian/control | 8 ++++---- .../sonic-platform-modules-dell/debian/control | 14 +++++++------- .../sonic-platform-modules-delta/debian/control | 10 +++++----- .../sonic-platform-modules-inventec/debian/control | 12 ++++++------ .../sonic-platform-modules-mitac/debian/control | 2 +- .../cavium/cavm_platform_modules/DEBIAN/control | 2 +- .../sonic-platform-modules-e582/debian/control | 4 ++-- .../sonic-platform-modules-cel/debian/control | 2 +- .../sonic-platform-modules-delta/debian/control | 2 +- platform/nephos/nephos-modules/debian/control | 2 +- .../sonic-platform-modules-accton/debian/control | 2 +- .../sonic-platform-modules-cig/debian/control | 6 +++--- .../sonic-platform-modules-pegatron/debian/control | 2 +- 20 files changed, 42 insertions(+), 42 deletions(-) diff --git a/platform/barefoot/bfn-modules/debian/control b/platform/barefoot/bfn-modules/debian/control index 32c161f1332..13a3b72a03b 100644 --- a/platform/barefoot/bfn-modules/debian/control +++ b/platform/barefoot/bfn-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: bfn-modules Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for bfn asic for mmap diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control index 19e4cdba062..9a512bd0e14 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-montara Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control index 2137d1ef912..1538a704180 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-newport Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel module for bfn platform fpga and scripts for the devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/control b/platform/barefoot/sonic-platform-modules-bfn/debian/control index ff942dc3722..639db9110df 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control index 58628bff07a..63857c09353 100644 --- a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: platform-modules-wnc-osw1800 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/saibcm-modules/debian/control b/platform/broadcom/saibcm-modules/debian/control index eca9977fcd9..72542564abf 100644 --- a/platform/broadcom/saibcm-modules/debian/control +++ b/platform/broadcom/saibcm-modules/debian/control @@ -10,5 +10,5 @@ Standards-Version: 3.9.3 Package: opennsl-modules Architecture: amd64 Section: main -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for broadcom SAI diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control index 65333e6a099..55533f735a5 100644 --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: sonic-platform-alphanetworks-snh60a0-320fv2 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-alphanetworks-snh60b0-640f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index 4062cf452d1..b69c44beab6 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -7,21 +7,21 @@ Standards-Version: 3.9.3 Package: platform-modules-dx010 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-haliburton Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-seastone2 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as led, sfp Package: platform-modules-silverstone Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as led, sfp. diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index a052f72f989..6a0ab0e7d2a 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -7,35 +7,35 @@ Standards-Version: 3.9.3 Package: platform-modules-s6000 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9100 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s6100 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9264f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5232f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5248f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9332f Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/control b/platform/broadcom/sonic-platform-modules-delta/debian/control index 2974bd42a6a..6ab0f3cf2f4 100644 --- a/platform/broadcom/sonic-platform-modules-delta/debian/control +++ b/platform/broadcom/sonic-platform-modules-delta/debian/control @@ -7,25 +7,25 @@ Standards-Version: 3.9.3 Package: platform-modules-ag9032v1 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9064 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag5648 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-et-6248brb Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9032v2a Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as syseeprom, sfp diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/control b/platform/broadcom/sonic-platform-modules-inventec/debian/control index fc9492fe931..31a6e67d098 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -7,30 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-d7032q28b Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7054q28b Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6254qs Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6556 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6356 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7264q28b Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led diff --git a/platform/broadcom/sonic-platform-modules-mitac/debian/control b/platform/broadcom/sonic-platform-modules-mitac/debian/control index 8f738a42eb4..b693fb382a8 100644 --- a/platform/broadcom/sonic-platform-modules-mitac/debian/control +++ b/platform/broadcom/sonic-platform-modules-mitac/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-mitac-ly1200-32x Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/cavium/cavm_platform_modules/DEBIAN/control b/platform/cavium/cavm_platform_modules/DEBIAN/control index cac08ec8f4e..233aa9ec7ba 100755 --- a/platform/cavium/cavm_platform_modules/DEBIAN/control +++ b/platform/cavium/cavm_platform_modules/DEBIAN/control @@ -1,6 +1,6 @@ Package: cavm-platform-modules Version: 1.0 Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Maintainer: Nadiya.Stetskovych@cavium.com Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/centec/sonic-platform-modules-e582/debian/control b/platform/centec/sonic-platform-modules-e582/debian/control index 44ffddfa0d6..1c31c94244e 100644 --- a/platform/centec/sonic-platform-modules-e582/debian/control +++ b/platform/centec/sonic-platform-modules-e582/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: platform-modules-e582-48x2q4z Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-e582-48x6q Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/innovium/sonic-platform-modules-cel/debian/control b/platform/innovium/sonic-platform-modules-cel/debian/control index 9794ba7c7ce..30baa323c36 100755 --- a/platform/innovium/sonic-platform-modules-cel/debian/control +++ b/platform/innovium/sonic-platform-modules-cel/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: platform-modules-midstone-200i Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices diff --git a/platform/innovium/sonic-platform-modules-delta/debian/control b/platform/innovium/sonic-platform-modules-delta/debian/control index e4ce62b2f9b..7395157d35f 100644 --- a/platform/innovium/sonic-platform-modules-delta/debian/control +++ b/platform/innovium/sonic-platform-modules-delta/debian/control @@ -7,7 +7,7 @@ Standards-Version: 3.9.3 Package: platform-modules-et-c032if Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/nephos-modules/debian/control b/platform/nephos/nephos-modules/debian/control index f5799a93fd0..8450eeae1e0 100644 --- a/platform/nephos/nephos-modules/debian/control +++ b/platform/nephos/nephos-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: nephos-modules Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for nephos asic diff --git a/platform/nephos/sonic-platform-modules-accton/debian/control b/platform/nephos/sonic-platform-modules-accton/debian/control index 35c3fc19159..a1068b7a7c5 100755 --- a/platform/nephos/sonic-platform-modules-accton/debian/control +++ b/platform/nephos/sonic-platform-modules-accton/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: sonic-platform-accton-as7116-54x Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-cig/debian/control b/platform/nephos/sonic-platform-modules-cig/debian/control index 87f0d09fecd..0c70d57ddbf 100644 --- a/platform/nephos/sonic-platform-modules-cig/debian/control +++ b/platform/nephos/sonic-platform-modules-cig/debian/control @@ -7,15 +7,15 @@ Standards-Version: 3.9.3 Package: sonic-platform-cig-cs6436-56p Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-cig-cs6436-54p Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-cig-cs5435-54p Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-pegatron/debian/control b/platform/nephos/sonic-platform-modules-pegatron/debian/control index bb4727a79b6..4fed2d1aa15 100755 --- a/platform/nephos/sonic-platform-modules-pegatron/debian/control +++ b/platform/nephos/sonic-platform-modules-pegatron/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-pegatron-porsche Architecture: amd64 -Depends: linux-image-4.19.0-6-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp From 91293780971a16a12b4a7b232437bcd8496869ac Mon Sep 17 00:00:00 2001 From: jostar-yang Date: Thu, 23 Apr 2020 13:54:48 +0800 Subject: [PATCH 10/69] [accton/as9716-32d] add support get_transceiver_change_event (#4105) Co-authored-by: Jostar Yang --- .../plugins/sfputil.py | 97 +++++++++++++++++-- .../modules/accton_as9716_32d_cpld.c | 74 ++++++++++++++ 2 files changed, 164 insertions(+), 7 deletions(-) diff --git a/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py index bc3297471c5..9cec97c44fb 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py @@ -5,6 +5,8 @@ try: import time + import os + import sys, getopt from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -141,10 +143,91 @@ def reset(self, port_num): return True - def get_transceiver_change_event(self): - """ - TODO: This function need to be implemented - when decide to support monitoring SFP(Xcvrd) - on this platform. - """ - raise NotImplementedError \ No newline at end of file + def get_cpld_interrupt(self): + port_dict={} + for i in range(0,4): + if i==0 or i==1: + cpld_i2c_path = self.BASE_CPLD1_PATH + "cpld_intr_" + str(i+1) + else: + cpld_i2c_path = self.BASE_CPLD2_PATH + "cpld_intr_" +str(i+1) + + start_i=(i*8) + end_i=(i*8+8) + try: + val_file = open(cpld_i2c_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + + for k in range (start_i, end_i): + port_dict[k]=0 + return port_dict + + status = val_file.readline().rstrip() + val_file.close() + status=status.strip() + status= int(status, 16) + + interrupt_status = ~(status & 0xff) + if interrupt_status: + port_shift=0 + for k in range (start_i, end_i): + if interrupt_status & (0x1< 0: + timeout = timeout / float(1000) # Convert to secs + else: + print "get_transceiver_change_event:Invalid timeout value", timeout + return False, {} + + end_time = start_time + timeout + if start_time > end_time: + print 'get_transceiver_change_event:' \ + 'time wrap / invalid timeout value', timeout + + return False, {} # Time wrap or possibly incorrect timeout + + #for i in range(self.port_start, self.port_end+1): + # ori_present[i]=self.get_presence(i) + + while timeout >= 0: + change_status=0 + + port_dict = self.get_cpld_interrupt() + present=0 + for key, value in port_dict.iteritems(): + if value==1: + present=self.get_presence(key) + change_status=1 + if present: + port_dict[key]='1' + else: + port_dict[key]='0' + + if change_status: + return True, port_dict + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + return True, {} + print "get_evt_change_event: Should not reach here." + return False, {} \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/accton_as9716_32d_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/accton_as9716_32d_cpld.c index 874bdc33bea..d473bb45241 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/accton_as9716_32d_cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/accton_as9716_32d_cpld.c @@ -72,6 +72,7 @@ MODULE_DEVICE_TABLE(i2c, as9716_32d_cpld_id); #define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index #define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index #define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index +#define CPLD_INTR_ATTR_ID(index) CPLD_INTR_##index enum as9716_32d_cpld_sysfs_attributes { CPLD_VERSION, @@ -149,10 +150,17 @@ enum as9716_32d_cpld_sysfs_attributes { TRANSCEIVER_RESET_ATTR_ID(30), TRANSCEIVER_RESET_ATTR_ID(31), TRANSCEIVER_RESET_ATTR_ID(32), + CPLD_INTR_ATTR_ID(1), + CPLD_INTR_ATTR_ID(2), + CPLD_INTR_ATTR_ID(3), + CPLD_INTR_ATTR_ID(4), + }; /* sysfs attributes for hwmon */ +static ssize_t show_interrupt(struct device *dev, struct device_attribute *da, + char *buf); static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, @@ -188,6 +196,11 @@ static int as9716_32d_cpld_write_internal(struct i2c_client *client, u8 reg, u8 static SENSOR_DEVICE_ATTR(module_reset_##index, S_IWUSR | S_IRUGO, get_mode_reset, set_mode_reset, MODULE_RESET_##index) #define DECLARE_TRANSCEIVER_RESET_ATTR(index) &sensor_dev_attr_module_reset_##index.dev_attr.attr +/*cpld interrupt*/ +#define DECLARE_CPLD_DEVICE_INTR_ATTR(index) \ + static SENSOR_DEVICE_ATTR(cpld_intr_##index, S_IRUGO, show_interrupt, NULL, CPLD_INTR_##index) +#define DECLARE_CPLD_INTR_ATTR(index) &sensor_dev_attr_cpld_intr_##index.dev_attr.attr + static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); @@ -261,6 +274,10 @@ DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(29); DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(30); DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(31); DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(32); +DECLARE_CPLD_DEVICE_INTR_ATTR(1); +DECLARE_CPLD_DEVICE_INTR_ATTR(2); +DECLARE_CPLD_DEVICE_INTR_ATTR(3); +DECLARE_CPLD_DEVICE_INTR_ATTR(4); @@ -309,6 +326,8 @@ static struct attribute *as9716_32d_cpld1_attributes[] = { DECLARE_TRANSCEIVER_RESET_ATTR(14), DECLARE_TRANSCEIVER_RESET_ATTR(15), DECLARE_TRANSCEIVER_RESET_ATTR(16), + DECLARE_CPLD_INTR_ATTR(1), + DECLARE_CPLD_INTR_ATTR(2), NULL }; @@ -355,6 +374,8 @@ static struct attribute *as9716_32d_cpld2_attributes[] = { DECLARE_TRANSCEIVER_RESET_ATTR(30), DECLARE_TRANSCEIVER_RESET_ATTR(31), DECLARE_TRANSCEIVER_RESET_ATTR(32), + DECLARE_CPLD_INTR_ATTR(3), + DECLARE_CPLD_INTR_ATTR(4), NULL }; @@ -363,6 +384,47 @@ static const struct attribute_group as9716_32d_cpld2_group = { }; +static ssize_t show_interrupt(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as9716_32d_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0; + + switch (attr->index) + { + case CPLD_INTR_1: + reg = 0x10; + break; + case CPLD_INTR_3: + reg = 0x10; + break; + case CPLD_INTR_2: + reg = 0x11; + break; + case CPLD_INTR_4: + reg = 0x11; + break; + default: + return -ENODEV; + } + mutex_lock(&data->update_lock); + status = as9716_32d_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "0x%x\n", status); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + + static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf) { @@ -723,9 +785,21 @@ static int as9716_32d_cpld_probe(struct i2c_client *client, break; case as9716_32d_cpld1: group = &as9716_32d_cpld1_group; + /*Set interrupt mask to 0, and then can get intr from 0x8*/ + status=as9716_32d_cpld_write_internal(client, 0x9, 0x0); + if (status < 0) + { + dev_dbg(&client->dev, "cpld1 reg 0x9 err %d\n", status); + } break; case as9716_32d_cpld2: group = &as9716_32d_cpld2_group; + /*Set interrupt mask to 0, and then can get intr from 0x8*/ + status=as9716_32d_cpld_write_internal(client, 0x9, 0x0); + if (status < 0) + { + dev_dbg(&client->dev, "cpld2 reg 0x65 err %d\n", status); + } break; case as9716_32d_cpld_cpu: /* Disable CPLD reset to avoid DUT will be reset. From 057ced03910a78f02402828a6d7000f513fc2a30 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 23 Apr 2020 09:42:22 -0700 Subject: [PATCH 11/69] [bgpcfgd]: Split one bgp mega-template to chunks. (#4143) The one big bgp configuration template was splitted into chunks. Currently we have three types of bgp neighbor peers: general bgp peers. They are represented by CONFIG_DB::BGP_NEIGHBOR table entries dynamic bgp peers. They are represented by CONFIG_DB::BGP_PEER_RANGE table entries monitors bgp peers. They are represented by CONFIG_DB::BGP_MONITORS table entries This PR introduces three templates for each peer type: bgp policies: represent policieas that will be applied to the bgp peer-group (ip prefix-lists, route-maps, etc) bgp peer-group: represent bgp peer group which has common configuration for the bgp peer type and uses bgp routing policy from the previous item bgp peer-group instance: represent bgp configuration, which will be used to instatiate a bgp peer-group for the bgp peer-type. Usually this one is simple, consist of the referral to the bgp peer-group, bgp peer description and bgp peer ip address. This PR redefined constant.yml file. Now this file has a setting for to use or don't use bgp_neighbor metadata. This file has more parameters for now, which are not used. They will be used in the next iteration of bgpcfgd. Currently all tests have been disabled. I'm going to create next PR with the tests right after this PR is merged. I'm going to introduce better bgpcfgd in a short time. It will include support of dynamic changes for the templates. FIX:: #4231 --- dockers/docker-fpm-frr/Dockerfile.j2 | 2 +- dockers/docker-fpm-frr/TSA | 44 +- dockers/docker-fpm-frr/TSB | 39 +- dockers/docker-fpm-frr/TSC | 51 +- dockers/docker-fpm-frr/bgpcfgd | 1235 ++++++++++++----- dockers/docker-fpm-frr/bgpd.conf.default.j2 | 180 --- .../docker-fpm-frr/bgpd.tsa.isolate.conf.j2 | 10 - .../docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 | 6 - dockers/docker-fpm-frr/frr.conf.j2 | 18 - .../{ => frr/bgpd}/bgpd.conf.j2 | 12 +- .../docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 81 ++ ...gpd.spine_chassis_frontend_router.conf.j2} | 0 .../bgpd/templates/dynamic/instance.conf.j2 | 38 + .../bgpd/templates/dynamic/peer-group.conf.j2 | 7 + .../bgpd/templates/dynamic/policies.conf.j2 | 9 + .../bgpd/templates/general/instance.conf.j2} | 27 +- .../bgpd/templates/general/peer-group.conf.j2 | 24 + .../bgpd/templates/general/policies.conf.j2 | 30 + .../bgpd/templates/monitors/instance.conf.j2 | 13 + .../templates/monitors/peer-group.conf.j2 | 12 + .../bgpd/templates/monitors/policies.conf.j2 | 9 + .../frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 | 5 + .../frr/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 | 3 + .../{ => frr/common}/daemons.common.conf.j2 | 2 + .../frr/common/functions.conf.j2 | 23 + dockers/docker-fpm-frr/frr/frr.conf.j2 | 19 + dockers/docker-fpm-frr/{ => frr}/isolate.j2 | 0 .../{ => frr/staticd}/staticd.conf.j2 | 2 +- .../staticd}/staticd.default_route.conf.j2 | 0 dockers/docker-fpm-frr/{ => frr}/unisolate.j2 | 0 .../{ => frr/zebra}/zebra.conf.j2 | 4 +- .../frr/zebra/zebra.interfaces.conf.j2 | 25 + .../frr/zebra/zebra.set_src.conf.j2 | 8 + dockers/docker-fpm-frr/start.sh | 6 +- .../docker-fpm-frr/zebra.interfaces.conf.j2 | 60 - files/image_config/constants/constants.yml | 32 +- src/sonic-config-engine/.gitignore | 2 + src/sonic-config-engine/sonic-cfggen | 6 +- .../tests/sample_output/bgpd_frr.conf | 68 +- .../tests/sample_output/frr.conf | 78 +- .../tests/sample_output/staticd_frr.conf | 4 +- .../sample_output/t2-chassis-fe-bgpd.conf | 48 +- .../t2-chassis-fe-vni-zebra.conf | 13 +- .../sample_output/t2-chassis-fe-zebra.conf | 13 +- .../tests/sample_output/zebra_frr.conf | 19 +- src/sonic-config-engine/tests/test_frr.py | 13 +- .../tests/test_j2files_t2_chassis_fe.py | 13 +- 47 files changed, 1463 insertions(+), 850 deletions(-) delete mode 100644 dockers/docker-fpm-frr/bgpd.conf.default.j2 delete mode 100644 dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 delete mode 100644 dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 delete mode 100644 dockers/docker-fpm-frr/frr.conf.j2 rename dockers/docker-fpm-frr/{ => frr/bgpd}/bgpd.conf.j2 (50%) create mode 100644 dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 rename dockers/docker-fpm-frr/{bgpd.conf.spine_chassis_frontend_router.j2 => frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2} (100%) create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/peer-group.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/policies.conf.j2 rename dockers/docker-fpm-frr/{bgpd.peer.conf.j2 => frr/bgpd/templates/general/instance.conf.j2} (64%) mode change 100755 => 100644 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/monitors/instance.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/monitors/peer-group.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/monitors/policies.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 rename dockers/docker-fpm-frr/{ => frr/common}/daemons.common.conf.j2 (71%) create mode 100644 dockers/docker-fpm-frr/frr/common/functions.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/frr.conf.j2 rename dockers/docker-fpm-frr/{ => frr}/isolate.j2 (100%) rename dockers/docker-fpm-frr/{ => frr/staticd}/staticd.conf.j2 (85%) rename dockers/docker-fpm-frr/{ => frr/staticd}/staticd.default_route.conf.j2 (100%) rename dockers/docker-fpm-frr/{ => frr}/unisolate.j2 (100%) rename dockers/docker-fpm-frr/{ => frr/zebra}/zebra.conf.j2 (63%) create mode 100644 dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/zebra/zebra.set_src.conf.j2 delete mode 100644 dockers/docker-fpm-frr/zebra.interfaces.conf.j2 create mode 100644 src/sonic-config-engine/.gitignore diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index c382df3c2ba..21318c7a63a 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -39,8 +39,8 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /debs ~/.cache +COPY ["frr", "/usr/share/sonic/templates"] COPY ["bgpcfgd", "start.sh", "/usr/bin/"] -COPY ["*.j2", "/usr/share/sonic/templates/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["snmp.conf", "/etc/snmp/frr.conf"] COPY ["TSA", "/usr/bin/TSA"] diff --git a/dockers/docker-fpm-frr/TSA b/dockers/docker-fpm-frr/TSA index 1d74757b2d5..441765694a4 100755 --- a/dockers/docker-fpm-frr/TSA +++ b/dockers/docker-fpm-frr/TSA @@ -1,22 +1,38 @@ #!/bin/bash -c=0 -config=$(vtysh -c "show run") -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$((c+$?)) +function check_not_installed() +{ + c=0 + config=$(vtysh -c "show run") + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + echo "$config" | grep -q "route-map $route_map_name permit 2" + c=$((c+$?)) + echo "$config" | grep -q "route-map $route_map_name deny 3" + c=$((c+$?)) + done + return $c +} -if [[ $c -eq 4 ]]; +check_not_installed +not_installed=$? +if [[ $not_installed -ne 0 ]]; then TSA_FILE=$(mktemp) - sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.tsa.isolate.conf.j2 > "$TSA_FILE" - vtysh -f "$TSA_FILE" - rm -f "$TSA_FILE" + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + case "$route_map_name" in + *V4*) + ip_version=V4 + ;; + *V6*) + ip_version=V6 + ;; + esac + sonic-cfggen -d -a "{\"route_map_name\":\"$route_map_name\", \"ip_version\": \"$ip_version\"}" -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd/tsa/bgpd.tsa.isolate.conf.j2 > "$TSA_FILE" + vtysh -f "$TSA_FILE" + rm -f "$TSA_FILE" + done echo "System Mode: Normal -> Maintenance" else echo "System is already in Maintenance mode" diff --git a/dockers/docker-fpm-frr/TSB b/dockers/docker-fpm-frr/TSB index 83ead86952c..84a3c183e65 100755 --- a/dockers/docker-fpm-frr/TSB +++ b/dockers/docker-fpm-frr/TSB @@ -1,22 +1,33 @@ #!/bin/bash -c=0 -config=$(vtysh -c "show run") -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$((c+$?)) +function check_installed() +{ + c=0 + e=0 + config=$(vtysh -c "show run") + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + echo "$config" | grep -q "route-map $route_map_name permit 2" + c=$((c+$?)) + e=$((e+1)) + echo "$config" | grep -q "route-map $route_map_name deny 3" + c=$((c+$?)) + e=$((e+1)) + done + return $((e-c)) +} -if [[ $c -eq 0 ]]; +check_installed +installed=$? +if [[ $installed -ne 0 ]]; then TSB_FILE=$(mktemp) - sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.tsa.unisolate.conf.j2 > "$TSB_FILE" - vtysh -f "$TSB_FILE" - rm -f "$TSB_FILE" + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + sonic-cfggen -d -a "{\"route_map_name\":\"$route_map_name\"}" -t /usr/share/sonic/templates/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 > "$TSB_FILE" + vtysh -f "$TSB_FILE" + rm -f "$TSB_FILE" + done echo "System Mode: Maintenance -> Normal" else echo "System is already in Normal mode" diff --git a/dockers/docker-fpm-frr/TSC b/dockers/docker-fpm-frr/TSC index c79f4bb2a41..3a3ad73d00b 100755 --- a/dockers/docker-fpm-frr/TSC +++ b/dockers/docker-fpm-frr/TSC @@ -1,21 +1,48 @@ #!/bin/bash +function check_not_installed() +{ + c=0 + config=$(vtysh -c "show run") + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + echo "$config" | grep -q "route-map $route_map_name permit 2" + c=$((c+$?)) + echo "$config" | grep -q "route-map $route_map_name deny 3" + c=$((c+$?)) + done + return $c +} + +function check_installed() +{ + c=0 + e=0 + config=$(vtysh -c "show run") + for route_map_name in $(echo "$config" | sed -ne 's/ neighbor \S* route-map \(\S*\) out/\1/p'); + do + echo "$config" | grep -q "route-map $route_map_name permit 2" + c=$((c+$?)) + e=$((e+1)) + echo "$config" | grep -q "route-map $route_map_name deny 3" + c=$((c+$?)) + e=$((e+1)) + done + return $((e-c)) +} + echo "Traffic Shift Check:" -c=0 -config=$(vtysh -c "show run") -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$((c+$?)) -echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$((c+$?)) -if [[ $c -eq 4 ]]; +check_not_installed +not_installed=$? + +check_installed +installed=$? + +if [[ $installed -eq 0 ]]; then echo "System Mode: Normal" -elif [[ $c -eq 0 ]]; +elif [[ $not_installed -eq 0 ]]; then echo "System Mode: Maintenance" else diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 4e638def47b..be290dfc41c 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -10,10 +10,11 @@ import traceback import os import tempfile import json -from collections import defaultdict +from collections import defaultdict, OrderedDict from pprint import pprint -from pprint import pformat +from functools import partial +import yaml import jinja2 import netaddr from swsscommon import swsscommon @@ -23,35 +24,178 @@ g_run = True g_debug = False -def run_command(command, shell=False): - str_cmd = " ".join(command) +def log_debug(msg): + """ Send a message msg to the syslog as DEBUG """ if g_debug: - syslog.syslog(syslog.LOG_DEBUG, "execute command {}.".format(str_cmd)) + syslog.syslog(syslog.LOG_DEBUG, msg) + +def log_notice(msg): + """ Send a message msg to the syslog as NOTICE """ + syslog.syslog(syslog.LOG_NOTICE, msg) + +def log_info(msg): + """ Send a message msg to the syslog as INFO """ + syslog.syslog(syslog.LOG_INFO, msg) + +def log_warn(msg): + """ Send a message msg to the syslog as WARNING """ + syslog.syslog(syslog.LOG_WARNING, msg) + +def log_err(msg): + """ Send a message msg to the syslog as ERR """ + syslog.syslog(syslog.LOG_ERR, msg) + +def log_crit(msg): + """ Send a message msg to the syslog as CRIT """ + syslog.syslog(syslog.LOG_CRIT, msg) + + +def run_command(command, shell=False, hide_errors=False): + """ + Run a linux command. The command is defined as a list. See subprocess.Popen documentation on format + :param command: command to execute. Type: List of strings + :param shell: execute the command through shell when True. Type: Boolean + :param hide_errors: don't report errors to syslog when True. Type: Boolean + :return: Tuple: integer exit code from the command, stdout as a string, stderr as a string + """ + log_debug("execute command '%s'." % str(command)) p = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() if p.returncode != 0: - syslog.syslog(syslog.LOG_ERR, 'command execution returned {}. Command: "{}", stdout: "{}", stderr: "{}"'.format(p.returncode, str_cmd, stdout, stderr)) + if not hide_errors: + print_tuple = p.returncode, str(command), stdout, stderr + log_err("command execution returned %d. Command: '%s', stdout: '%s', stderr: '%s'" % print_tuple) return p.returncode, stdout, stderr +class ConfigMgr(object): + """ The class represents frr configuration """ + def __init__(self): + self.current_config = None + + def reset(self): + """ Reset stored config """ + self.current_config = None + + def update(self): + """ Read current config from FRR """ + self.current_config = None + ret_code, out, err = run_command(["vtysh", "-c", "show running-config"]) + if ret_code != 0: + log_crit("can't update running config: rc=%d out='%s' err='%s'" % (ret_code, out, err)) + return + self.current_config = self.to_canonical(out) + + def push(self, cmd): + """ + Push new changes to FRR + :param cmd: configuration change for FRR. Type: String + :return: True if change was applied successfully, False otherwise + """ + return self.write(cmd) + + def write(self, cmd): + """ + Write configuration change to FRR. + :param cmd: new configuration to write into FRR. Type: String + :return: True if change was applied successfully, False otherwise + """ + fd, tmp_filename = tempfile.mkstemp(dir='/tmp') + os.close(fd) + with open(tmp_filename, 'w') as fp: + fp.write("%s\n" % cmd) + command = ["vtysh", "-f", tmp_filename] + ret_code, out, err = run_command(command) + if not g_debug: + os.remove(tmp_filename) + if ret_code != 0: + err_tuple = str(cmd), ret_code, out, err + log_err("ConfigMgr::push(): can't push configuration '%s', rc='%d', stdout='%s', stderr='%s'" % err_tuple) + if ret_code == 0: + self.current_config = None # invalidate config + return ret_code == 0 + + @staticmethod + def to_canonical(raw_config): + """ + Convert FRR config into canonical format + :param raw_config: config in frr format + :return: frr config in canonical format + """ + parsed_config = [] + cur_offset = 0 + lines = raw_config.split("\n") + cur_path = [lines[0]] + for line in lines: + if line.strip().startswith('!') or line.strip() == '': + continue + n_spaces = ConfigMgr.count_spaces(line) + s_line = line.strip() + assert(n_spaces == cur_offset or (n_spaces + 1) == cur_offset or (n_spaces - 1) == cur_offset) + if n_spaces == cur_offset: + cur_path[-1] = s_line + elif n_spaces > cur_offset: + cur_path.append(s_line) + elif n_spaces < cur_offset: + cur_path = cur_path[:-2] + cur_path.append(s_line) + parsed_config.append(cur_path[:]) + cur_offset = n_spaces + return parsed_config + + @staticmethod + def count_spaces(line): + """ Count leading spaces in the line """ + return len(line) - len(line.lstrip()) + + @staticmethod + def from_canonical(canonical_config): + """ + Convert config from canonical format into FRR raw format + :param canonical_config: config in a canonical format + :return: config in the FRR raw format + """ + out = "" + for lines in canonical_config: + spaces = len(lines) - 1 + out += " " * spaces + lines[-1] + "\n" + + return out + + class TemplateFabric(object): + """ Fabric for rendering jinja2 templates """ def __init__(self): j2_template_paths = ['/usr/share/sonic/templates'] j2_loader = jinja2.FileSystemLoader(j2_template_paths) - j2_env = jinja2.Environment(loader=j2_loader, trim_blocks=True) + j2_env = jinja2.Environment(loader=j2_loader, trim_blocks=False) j2_env.filters['ipv4'] = self.is_ipv4 j2_env.filters['ipv6'] = self.is_ipv6 + j2_env.filters['pfx_filter'] = self.pfx_filter + for attr in ['ip', 'network', 'prefixlen', 'netmask']: + j2_env.filters[attr] = partial(self.prefix_attr, attr) self.env = j2_env def from_file(self, filename): + """ + Read a template from a file + :param filename: filename of the file. Type String + :return: Jinja2 template object + """ return self.env.get_template(filename) def from_string(self, tmpl): + """ + Read a template from a string + :param tmpl: Text representation of Jinja2 template + :return: Jinja2 template object + """ return self.env.from_string(tmpl) @staticmethod def is_ipv4(value): + """ Return True if the value is an ipv4 address """ if not value: return False if isinstance(value, netaddr.IPNetwork): @@ -59,12 +203,13 @@ class TemplateFabric(object): else: try: addr = netaddr.IPNetwork(str(value)) - except: + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): return False return addr.version == 4 @staticmethod def is_ipv6(value): + """ Return True if the value is an ipv6 address """ if not value: return False if isinstance(value, netaddr.IPNetwork): @@ -72,56 +217,70 @@ class TemplateFabric(object): else: try: addr = netaddr.IPNetwork(str(value)) - except: + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): return False return addr.version == 6 + @staticmethod + def prefix_attr(attr, value): + """ + Extract attribute from IPNetwork object + :param attr: attribute to extract + :param value: the string representation of ip prefix which will be converted to IPNetwork. + :return: the value of the extracted attribute + """ + if not value: + return None + else: + try: + prefix = netaddr.IPNetwork(str(value)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + return None + return str(getattr(prefix, attr)) -class Daemon(object): - SELECT_TIMEOUT = 1000 - - def __init__(self): - self.db_connectors = {} - self.selector = swsscommon.Select() - self.callbacks = defaultdict(lambda : defaultdict(list)) # db -> table -> [] - self.subscribers = set() - - def add_manager(self, db_name, table_name, callback): - db = swsscommon.SonicDBConfig.getDbId(db_name) - if db not in self.db_connectors: - self.db_connectors[db] = swsscommon.DBConnector(db_name, 0) + @staticmethod + def pfx_filter(value): + """INTERFACE Table can have keys in one of the two formats: + string or tuple - This filter skips the string keys and only + take into account the tuple. + For eg - VLAN_INTERFACE|Vlan1000 vs VLAN_INTERFACE|Vlan1000|192.168.0.1/21 + """ + table = OrderedDict() - if table_name not in self.callbacks[db]: - conn = self.db_connectors[db] - subscriber = swsscommon.SubscriberStateTable(conn, table_name) - self.subscribers.add(subscriber) - self.selector.addSelectable(subscriber) - self.callbacks[db][table_name].append(callback) + if not value: + return table - def run(self): - while g_run: - state, _ = self.selector.select(Daemon.SELECT_TIMEOUT) - if state == self.selector.TIMEOUT: + for key, val in value.items(): + if not isinstance(key, tuple): continue - elif state == self.selector.ERROR: - raise Exception("Received error from select") - - for subscriber in self.subscribers: - key, op, fvs = subscriber.pop() - if not key: - continue - if g_debug: - syslog.syslog(syslog.LOG_DEBUG, "Received message : {}".format((key, op, fvs))) - for callback in self.callbacks[subscriber.getDbConnector().getDbId()][subscriber.getTableName()]: - callback(key, op, dict(fvs)) + table[key] = val + return table class Directory(object): + """ This class stores values and notifies callbacks which were registered to be executed as soon + as some value is changed. This class works as DB cache mostly """ def __init__(self): - self.data = defaultdict(dict) - self.notify = defaultdict(lambda: defaultdict(list)) + self.data = defaultdict(dict) # storage. A key is a slot name, a value is a dictionary with data + self.notify = defaultdict(lambda: defaultdict(list)) # registered callbacks: slot -> path -> handlers[] + + @staticmethod + def get_slot_name(db, table): + """ Convert db, table pair into a slot name """ + return db + "__" + table def path_traverse(self, slot, path): + """ + Traverse a path in the storage. + If the path is an empty string, it returns a value as it is. + If the path is not an empty string, the method will traverse through the dictionary value. + Example: + self.data["key_1"] = { "abc": { "cde": { "fgh": "val_1", "ijk": "val_2" } } } + self.path_traverse("key_1", "abc/cde") will return True, { "fgh": "val_1", "ijk": "val_2" } + :param slot: storage key + :param path: storage path as a string where each internal key is separated by '/' + :return: a pair: True if the path was found, object if it was found + """ if slot not in self.data: return False, None elif path == '': @@ -133,77 +292,229 @@ class Directory(object): d = d[p] return True, d - def path_exist(self, slot, path): + def path_exist(self, db, table, path): + """ + Check if the path exists in the storage + :param db: db name + :param table: table name + :param path: requested path + :return: True if the path is available, False otherwise + """ + slot = self.get_slot_name(db, table) return self.path_traverse(slot, path)[0] - def get_path(self, slot, path): + def get_path(self, db, table, path): + """ + Return the requested path from the storage + :param db: db name + :param table: table name + :param path: requested path + :return: object if the path was found, None otherwise + """ + slot = self.get_slot_name(db, table) return self.path_traverse(slot, path)[1] - def put(self, slot, key, value): + def put(self, db, table, key, value): + """ + Put information into the storage. Notify handlers which are dependant to the information + :param db: db name + :param table: table name + :param key: key to change + :param value: value to put + :return: + """ + slot = self.get_slot_name(db, table) self.data[slot][key] = value if slot in self.notify: for path in self.notify[slot].keys(): - if self.path_exist(slot, path): + if self.path_exist(db, table, path): for handler in self.notify[slot][path]: handler() - def get(self, slot, key): + def get(self, db, table, key): + """ + Get a value from the storage + :param db: db name + :param table: table name + :param key: ket to get + :return: value for the key + """ + slot = self.get_slot_name(db, table) return self.data[slot][key] - def remove(self, slot, key): + def get_slot(self, db, table): + """ + Get an object from the storage + :param db: db name + :param table: table name + :return: object for the slot + """ + slot = self.get_slot_name(db, table) + return self.data[slot] + + def remove(self, db, table, key): + """ + Remove a value from the storage + :param db: db name + :param table: table name + :param key: key to remove + """ + slot = self.get_slot_name(db, table) if slot in self.data: if key in self.data[slot]: del self.data[slot][key] else: - syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) + log_err("Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) else: - syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) + log_err("Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) - def remove_slot(self, slot, key): + def remove_slot(self, db, table): + """ + Remove an object from the storage + :param db: db name + :param table: table name + """ + slot = self.get_slot_name(db, table) if slot in self.data: del self.data[slot] else: - syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove slot '%s'. The slot doesn't exist" % slot) - - def get_slot(self, slot): - return self.data[slot] + log_err("Directory: Can't remove slot '%s'. The slot doesn't exist" % slot) - def available_slot(self, slot): + def available(self, db, table): + """ + Check if the table is available + :param db: db name + :param table: table name + :return: True if the slot is available, False if not + """ + slot = self.get_slot_name(db, table) return slot in self.data def available_deps(self, deps): + """ + Check if all items from the deps list is available in the storage + :param deps: list of dependencies + :return: True if all dependencies are presented, False otherwise + """ res = True - for slot, path in deps: - res = res and self.path_exist(slot, path) + for db, table, path in deps: + res = res and self.path_exist(db, table, path) return res def subscribe(self, deps, handler): - for slot, path in deps: + """ + Subscribe the handler to be run as soon as all dependencies are presented + :param deps: + :param handler: + :return: + """ + for db, table, path in deps: + slot = self.get_slot_name(db, table) self.notify[slot][path].append(handler) +class Runner(object): + """ Implements main io-loop of the application + It will run event handlers inside of Manager objects + when corresponding db/table is updated + """ + SELECT_TIMEOUT = 1000 + + def __init__(self): + """ Constructor """ + self.db_connectors = {} + self.selector = swsscommon.Select() + self.callbacks = defaultdict(lambda: defaultdict(list)) # db -> table -> handlers[] + self.subscribers = set() + + def add_manager(self, manager): + """ + Add a manager to the Runner. + As soon as new events will be receiving by Runner, + handlers of corresponding objects will be executed + :param manager: an object implementing Manager + """ + db_name = manager.get_database() + table_name = manager.get_table_name() + db = swsscommon.SonicDBConfig.getDbId(db_name) + if db not in self.db_connectors: + self.db_connectors[db] = swsscommon.DBConnector(db_name, 0) + + if table_name not in self.callbacks[db]: + conn = self.db_connectors[db] + subscriber = swsscommon.SubscriberStateTable(conn, table_name) + self.subscribers.add(subscriber) + self.selector.addSelectable(subscriber) + self.callbacks[db][table_name].append(manager.handler) + + def run(self): + """ Main loop """ + while g_run: + state, _ = self.selector.select(Runner.SELECT_TIMEOUT) + if state == self.selector.TIMEOUT: + continue + elif state == self.selector.ERROR: + raise Exception("Received error from select") + + for subscriber in self.subscribers: + key, op, fvs = subscriber.pop() + if not key: + continue + log_debug("Received message : '%s'" % str((key, op, fvs))) + for callback in self.callbacks[subscriber.getDbConnector().getDbId()][subscriber.getTableName()]: + callback(key, op, dict(fvs)) + + class Manager(object): - def __init__(self, daemon, directory, deps, database, table_name): - self.directory = directory + """ This class represents a SONiC DB table """ + def __init__(self, common_objs, deps, database, table_name): + """ + Initialize class + :param common_objs: common object dictionary + :param deps: dependencies list + :param database: database name + :param table_name: table name + """ + self.directory = common_objs['directory'] + self.cfg_mgr = common_objs['cfg_mgr'] + self.constants = common_objs['constants'] self.deps = deps + self.db_name = database + self.table_name = table_name self.set_queue = [] - daemon.add_manager(database, table_name, self.handler) - directory.subscribe(deps, self.on_deps_change) + self.directory.subscribe(deps, self.on_deps_change) # subscribe this class method on directory changes + + def get_database(self): + """ Return associated database """ + return self.db_name + + def get_table_name(self): + """ Return associated table name""" + return self.table_name def handler(self, key, op, data): + """ + This method is executed on each add/remove event on the table. + :param key: key of the table entry + :param op: operation on the table entry. Could be either 'SET' or 'DEL' + :param data: associated data of the event. Empty for 'DEL' operation. + """ if op == swsscommon.SET_COMMAND: - if self.directory.available_deps(self.deps): + if self.directory.available_deps(self.deps): # all required dependencies are set in the Directory? res = self.set_handler(key, data) - if not res: + if not res: # set handler returned False, which means it is not ready to process is. Save it for later. + log_debug("'SET' handler returned NOT_READY for the Manager: %s" % self.__class__) self.set_queue.append((key, data)) else: + log_debug("Not all dependencies are met for the Manager: %s" % self.__class__) self.set_queue.append((key, data)) elif op == swsscommon.DEL_COMMAND: self.del_handler(key) else: - syslog.syslog(syslog.LOG_ERR, 'Invalid operation "%s" for key "%s"' % (op, key)) + log_err("Invalid operation '%s' for key '%s'" % (op, key)) def on_deps_change(self): + """ This method is being executed on every dependency change """ if not self.directory.available_deps(self.deps): return new_queue = [] @@ -214,286 +525,407 @@ class Manager(object): self.set_queue = new_queue def set_handler(self, key, data): - syslog.syslog(syslog.LOG_ERR, "%s wasn't implemented for %s" % (self.__name__, self.__class__)) + """ Placeholder for 'SET' command """ + log_err("set_handler() wasn't implemented for %s" % self.__class__.__name__) def del_handler(self, key): - syslog.syslog(syslog.LOG_ERR, "%s wasn't implemented for %s" % (self.__name__, self.__class__)) + """ Placeholder for 'DEL' command """ + log_err("del_handler wasn't implemented for %s" % self.__class__.__name__) -class BGPDeviceMetaMgr(Manager): - def __init__(self, daemon, directory): - super(BGPDeviceMetaMgr, self).__init__( - daemon, - directory, +class BGPDataBaseMgr(Manager): + """ This class updates the Directory object when db table is updated """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(BGPDataBaseMgr, self).__init__( + common_objs, [], - "CONFIG_DB", - swsscommon.CFG_DEVICE_METADATA_TABLE_NAME + db, + table, ) def set_handler(self, key, data): - if key != "localhost" or "bgp_asn" not in data: - return - if self.directory.path_exist("meta", "localhost/bgp_asn"): - bgp_asn = self.directory.get_path("meta", "localhost/bgp_asn") - if bgp_asn == data["bgp_asn"]: - return - self.directory.put("meta", key, data) + """ Implementation of 'SET' command for this class """ + self.directory.put(self.db_name, self.table_name, key, data) return True def del_handler(self, key): - self.directory.remove("meta", key) + """ Implementation of 'DEL' command for this class """ + self.directory.remove(self.db_name, self.table_name, key) -class BGPNeighborMetaMgr(Manager): - def __init__(self, daemon, directory): - super(BGPNeighborMetaMgr, self).__init__( - daemon, - directory, +class InterfaceMgr(Manager): + """ This class updates the Directory object when interface-related table is updated """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(InterfaceMgr, self).__init__( + common_objs, [], - "CONFIG_DB", - swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME + db, + table, ) def set_handler(self, key, data): - self.directory.put("neigmeta", key, data) - + """ Implementation of 'SET' command. + Similar to BGPDataBaseMgr but enriches data object with additional data """ + # Interface table can have two keys, + # one with ip prefix and one without ip prefix + if '|' in key: + interface_name, network_str = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network_str)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + log_warn("Subnet '%s' format is wrong for interface '%s'" % (network_str, data["interface"])) + return True + data["interface"] = interface_name + data["prefixlen"] = str(network.prefixlen) + ip = str(network.ip) + self.directory.put("LOCAL", "local_addresses", ip, data) + self.directory.put(self.db_name, self.table_name, key, data) + self.directory.put("LOCAL", "interfaces", key, data) return True def del_handler(self, key): - self.directory.remove("neigmeta", key) - - -class BGPPeerMgr(Manager): - def __init__(self, daemon, directory): - super(BGPPeerMgr, self).__init__( - daemon, - directory, - [ - ("meta", "localhost/bgp_asn"), - ("neigmeta", ""), - ("local_addresses", ""), - ("interfaces", ""), - ], - "CONFIG_DB", - swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME - ) - self.peers = self.load_peers() - fabric = TemplateFabric() - self.templates = { - "add": fabric.from_file('bgpd.peer.conf.j2'), - "delete": fabric.from_string('no neighbor {{ neighbor_addr }}'), - "shutdown": fabric.from_string('neighbor {{ neighbor_addr }} shutdown'), - "no shutdown": fabric.from_string('no neighbor {{ neighbor_addr }} shutdown'), - } + """ Implementation of 'DEL' command + Also removes data object enrichment """ + if '|' in key: + interface, network = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + log_warn("Subnet '%s' format is wrong for interface '%s'" % (network, interface)) + return + ip = str(network.ip) + self.directory.remove("LOCAL", "local_addresses", ip) + self.directory.remove(self.db_name, self.table_name, key) + self.directory.remove("LOCAL", "interfaces", key) - def set_handler(self, key, data): - key = self.normalize_key(key) - vrf, nbr = key.split('|', 1) - if key not in self.peers: - cmd = None - if "local_addr" not in data: - syslog.syslog(syslog.LOG_WARNING, 'Peer {}. Error in missing required attribute "local_addr"'.format(key)) - else: - # The bgp session that belongs to a vnet cannot be advertised as the default BGP session. - # So we need to check whether this bgp session belongs to a vnet. - interface = InterfaceMgr.get_local_interface(self.directory, data["local_addr"]) - if not interface: - syslog.syslog(syslog.LOG_INFO, - 'Peer {} with local address {} wait for the corresponding interface to be set'.format( - key, - data["local_addr"] - ) - ) - return False - vnet = InterfaceMgr.get_vnet(interface) - if vnet: - # Ignore the bgp session that is in a vnet - syslog.syslog( - syslog.LOG_INFO, - 'Ignore the BGP peer {} as the interface {} is in vnet {}'.format( - key, - interface, - vnet - ) - ) - return True +class BGPPeerGroupMgr(object): + """ This class represents peer-group and routing policy for the peer_type """ + def __init__(self, common_objs, base_template): + """ + Construct the object + :param common_objs: common objects + :param base_template: path to the directory with Jinja2 templates + """ + self.cfg_mgr = common_objs['cfg_mgr'] + self.constants = common_objs['constants'] + tf = common_objs['tf'] + self.policy_template = tf.from_file(base_template + "policies.conf.j2") + self.peergroup_template = tf.from_file(base_template + "peer-group.conf.j2") - neigmeta = self.directory.get_slot("neigmeta") - if 'name' in data and data["name"] not in neigmeta: - syslog.syslog(syslog.LOG_INFO, - 'Peer {} with neighbor name {} wait for the corresponding neighbor metadata to be set'.format( - key, - data["name"] - ) - ) - return False - try: - cmd = self.templates["add"].render( - DEVICE_METADATA=self.directory.get_slot("meta"), - DEVICE_NEIGHBOR_METADATA=neigmeta, - neighbor_addr=nbr, - bgp_session=data - ) - except: - syslog.syslog(syslog.LOG_ERR, 'Peer {}. Error in rendering the template for "SET" command {}'.format(key, data)) - return True - if cmd is not None: - rc = self.apply_op(cmd, vrf) - if rc: - self.peers.add(key) - syslog.syslog(syslog.LOG_INFO, 'Peer {} added with attributes {}'.format(key, data)) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {} wasn't added.".format(key)) - else: - # when the peer is already configured we support "shutdown/no shutdown" - # commands for the peers only - if "admin_status" in data: - if data['admin_status'] == 'up': - rc = self.apply_op(self.templates["no shutdown"].render(neighbor_addr=nbr), vrf) - if rc: - syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "up"'.format(key)) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {} admin state wasn't set to 'up'.".format(key)) - elif data['admin_status'] == 'down': - rc = self.apply_op(self.templates["shutdown"].render(neighbor_addr=nbr), vrf) - if rc: - syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "down"'.format(key)) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {} admin state wasn't set to 'down'.".format(key)) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {}: Can't update the peer. has wrong attribute value attr['admin_status'] = '{}'".format(key, data['admin_status'])) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {}: Can't update the peer. No 'admin_status' attribute in the request".format(key)) - return True + def update(self, name, **kwargs): + """ + Update peer-group and routing policy for the peer with the name + :param name: name of the peer. Used for logging only + :param kwargs: dictionary with parameters for rendering + """ + rc_policy = self.update_policy(name, **kwargs) + rc_pg = self.update_pg(name, **kwargs) + return rc_policy and rc_pg - def del_handler(self, key): - key = self.normalize_key(key) - vrf, nbr = key.split('|', 1) - if key not in self.peers: - syslog.syslog(syslog.LOG_WARNING, 'Peer {} has not been found'.format(key)) - return - cmd = self.templates["delete"].render(neighbor_addr=nbr) - rc = self.apply_op(cmd, vrf) - if rc: - syslog.syslog(syslog.LOG_INFO, 'Peer {} has been removed'.format(key)) - self.peers.remove(key) - else: - syslog.syslog(syslog.LOG_ERR, "Peer {} hasn't been removed".format(key)) + def update_policy(self, name, **kwargs): + """ + Update routing policy for the peer + :param name: name of the peer. Used for logging only + :param kwargs: dictionary with parameters for rendering + """ + try: + policy = self.policy_template.render(**kwargs) + except jinja2.TemplateError as e: + log_err("Can't render policy template name: '%s': %s" % (name, str(e))) + return False - def apply_op(self, cmd, vrf): - bgp_asn = self.directory.get_slot("meta")["localhost"]["bgp_asn"] - fd, tmp_filename = tempfile.mkstemp(dir='/tmp') - os.close(fd) - with open(tmp_filename, 'w') as fp: - if vrf == 'default': - fp.write('router bgp %s\n' % bgp_asn) - else: - fp.write('router bgp %s vrf %s\n' % (bgp_asn, vrf)) - fp.write("%s\n" % cmd) + return self.update_entity(policy, "Routing policy for peer '%s'" % name) - command = ["vtysh", "-f", tmp_filename] - rc, _, _ = run_command(command) - os.remove(tmp_filename) - return rc == 0 + def update_pg(self, name, **kwargs): + """ + Update peer-group for the peer + :param name: name of the peer. Used for logging only + :param kwargs: dictionary with parameters for rendering + """ + try: + pg = self.peergroup_template.render(**kwargs) + except jinja2.TemplateError as e: + log_err("Can't render peer-group template: '%s': %s" % (name, str(e))) + return False - @staticmethod - def normalize_key(key): - if '|' not in key: - return 'default|' + key + if kwargs['vrf'] == 'default': + cmd = ('router bgp %s\n' % kwargs['bgp_asn']) + pg else: - return key + cmd = ('router bgp %s vrf %s\n' % (kwargs['bgp_asn'], kwargs['vrf'])) + pg - @staticmethod - def load_peers(): - vrfs = [] - command = ["vtysh", "-c", "show bgp vrfs json"] - rc, out, err = run_command(command) - if rc == 0: - js_vrf = json.loads(out) - vrfs = js_vrf['vrfs'].keys() + return self.update_entity(cmd, "Peer-group for peer '%s'" % name) - peers = set() - for vrf in vrfs: - command = ["vtysh", "-c", 'show bgp vrf {} neighbors json'.format(vrf)] - rc, out, err = run_command(command) - if rc == 0: - js_bgp = json.loads(out) - for nbr in js_bgp.keys(): - peers.add((vrf, nbr)) + def update_entity(self, cmd, txt): + """ + Send commands to FRR + :param cmd: commands to send in a raw form + :param txt: text for the syslog output + :return: + """ + ret_code = self.cfg_mgr.push(cmd) + if ret_code: + log_info("%s was updated" % txt) + else: + log_err("Can't update %s" % txt) + return ret_code - return peers +class BGPPeerMgrBase(Manager): + """ Manager of BGP peers """ + def __init__(self, common_objs, db_name, table_name, peer_type): + """ + Initialize the object + :param common_objs: common objects + :param table_name: name of the table with peers + :param peer_type: type of the peers. It is used to find right templates + """ + self.common_objs = common_objs + self.constants = self.common_objs["constants"] + self.fabric = common_objs['tf'] + self.peer_type = peer_type -class InterfaceMgr(Manager): - def __init__(self, daemon, directory, interface_table = swsscommon.CFG_INTF_TABLE_NAME): - super(InterfaceMgr, self).__init__( - daemon, - directory, - [], - "CONFIG_DB", - interface_table + base_template = "bgpd/templates/" + self.constants["bgp"]["peers"][peer_type]["template_dir"] + "/" + self.templates = { + "add": self.fabric.from_file(base_template + "instance.conf.j2"), + "delete": self.fabric.from_string('no neighbor {{ neighbor_addr }}'), + "shutdown": self.fabric.from_string('neighbor {{ neighbor_addr }} shutdown'), + "no shutdown": self.fabric.from_string('no neighbor {{ neighbor_addr }} shutdown'), + } + + deps = [ + ("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/bgp_asn"), + ("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME, "Loopback0"), + ("LOCAL", "local_addresses", ""), + ("LOCAL", "interfaces", ""), + ] + + self.check_neig_meta = 'bgp' in self.constants \ + and 'use_neighbors_meta' in self.constants['bgp'] \ + and self.constants['bgp']['use_neighbors_meta'] + self.check_deployment_id = 'bgp' in self.constants \ + and 'use_deployment_id' in self.constants['bgp'] \ + and self.constants['bgp']['use_deployment_id'] + + if self.check_neig_meta: + deps.append(("CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME, "")) + + if self.check_deployment_id: + deps.append(("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/deployment_id")) + + super(BGPPeerMgrBase, self).__init__( + common_objs, + deps, + db_name, + table_name, ) + self.peers = self.load_peers() + self.peer_group_mgr = BGPPeerGroupMgr(self.common_objs, base_template) + return + def set_handler(self, key, data): - # Interface table can have two keys, - # one with ip prefix and one without ip prefix - if '|' in key: - data = {} - data["interface"], network = key.split('|', 1) - try: - network = netaddr.IPNetwork(str(network)) - except: - syslog.syslog( - syslog.LOG_WARNING, - 'Subnet {} format is wrong for interface {}'.format( - network, - data["interface"] - ) - ) + """ + It runs on 'SET' command + :param key: key of the changed table + :param data: the data associated with the change + """ + vrf, nbr = self.split_key(key) + if key not in self.peers: + return self.add_peer(vrf, nbr, data) + else: + return self.update_peer(vrf, nbr, data) + + def add_peer(self, vrf, nbr, data): + """ + Add a peer into FRR. This is used if the peer is not existed in FRR yet + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param data: associated data + :return: True if this adding was successful, False otherwise + """ + print_data = vrf, nbr, data + bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] + # + lo0_ipv4 = self.get_lo0_ipv4() + if lo0_ipv4 is None: + log_warn("Loopback0 ipv4 address is not presented yet") + return False + # + if "local_addr" not in data: + log_warn("Peer %s. Missing attribute 'local_addr'" % nbr) + else: + # The bgp session that belongs to a vnet cannot be advertised as the default BGP session. + # So we need to check whether this bgp session belongs to a vnet. + interface = self.get_local_interface(data["local_addr"]) + if not interface: + print_data = nbr, data["local_addr"] + log_debug("Peer '%s' with local address '%s' wait for the corresponding interface to be set" % print_data) return False - data["prefixlen"] = str(network.prefixlen) - ip = str(network.ip) - self.directory.put("local_addresses", ip, data) + vnet = self.get_vnet(interface) + if vnet: + # Ignore the bgp session that is in a vnet + log_info("Ignore the BGP peer '%s' as the interface '%s' is in vnet '%s'" % (nbr, interface, vnet)) + return True + + kwargs = { + 'CONFIG_DB__DEVICE_METADATA': self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME), + 'constants': self.constants, + 'bgp_asn': bgp_asn, + 'vrf': vrf, + 'neighbor_addr': nbr, + 'bgp_session': data, + 'loopback0_ipv4': lo0_ipv4, + } + if self.check_neig_meta: + neigmeta = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME) + if 'name' in data and data["name"] not in neigmeta: + log_info("DEVICE_NEIGHBOR_METADATA is not ready for neighbor '%s' - '%s'" % (nbr, data['name'])) + return False + kwargs['CONFIG_DB__DEVICE_NEIGHBOR_METADATA'] = neigmeta + + tag = data['name'] if 'name' in data else nbr + self.peer_group_mgr.update(tag, **kwargs) + + try: + cmd = self.templates["add"].render(**kwargs) + except jinja2.TemplateError as e: + msg = "Peer '(%s|%s)'. Error in rendering the template for 'SET' command '%s'" % print_data + log_err("%s: %s" % (msg, str(e))) + return True + if cmd is not None: + ret_code = self.apply_op(cmd, vrf) + key = (vrf, nbr) + if ret_code: + self.peers.add(key) + log_info("Peer '(%s|%s)' added with attributes '%s'" % print_data) + else: + log_err("Peer '(%s|%s)' wasn't added." % (vrf, nbr)) + + return True + + def update_peer(self, vrf, nbr, data): + """ + Update a peer. This is used when the peer is already in the FRR + Update support only "admin_status" for now + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param data: associated data + :return: True if this adding was successful, False otherwise + """ + if "admin_status" in data: + self.change_admin_status(vrf, nbr, data) else: - self.directory.put("interfaces", key, data) + log_err("Peer '(%s|%s)': Can't update the peer. Only 'admin_status' attribute is supported" % (vrf, nbr)) + return True + def change_admin_status(self, vrf, nbr, data): + """ + Change admin status of a peer + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param data: associated data + :return: True if this adding was successful, False otherwise + """ + if data['admin_status'] == 'up': + self.apply_admin_status(vrf, nbr, "no shutdown", "up") + elif data['admin_status'] == 'down': + self.apply_admin_status(vrf, nbr, "shutdown", "down") + else: + print_data = vrf, nbr, data['admin_status'] + log_err("Peer '%s|%s': Can't update the peer. It has wrong attribute value attr['admin_status'] = '%s'" % print_data) + + def apply_admin_status(self, vrf, nbr, template_name, admin_state): + """ + Render admin state template and apply the command to the FRR + :param vrf: vrf name. Name is equal "default" for the global vrf + :param nbr: neighbor ip address (name for dynamic peer type) + :param template_name: name of the template to render + :param admin_state: desired admin state + :return: True if this adding was successful, False otherwise + """ + print_data = vrf, nbr, admin_state + ret_code = self.apply_op(self.templates[template_name].render(neighbor_addr=nbr), vrf) + if ret_code: + log_info("Peer '%s|%s' admin state is set to '%s'" % print_data) + else: + log_err("Can't set peer '%s|%s' admin state to '%s'." % print_data) + def del_handler(self, key): - if '|' in key: - interface, network = key.split('|', 1) - try: - network = netaddr.IPNetwork(str(network)) - except: - syslog.syslog( - syslog.LOG_WARNING, - 'Subnet {} format is wrong for interface {}'.format( - network, - interface - ) - ) - return False - ip = str(network.ip) - self.directory.remove("local_addresses", ip) + """ + 'DEL' handler for the BGP PEER tables + :param key: key of the neighbor + """ + vrf, nbr = self.split_key(key) + if key not in self.peers: + log_warn("Peer '(%s|%s)' has not been found" % (vrf, nbr)) + return + cmd = self.templates["delete"].render(neighbor_addr=nbr) + ret_code = self.apply_op(cmd, vrf) + if ret_code: + log_info("Peer '(%s|%s)' has been removed" % (vrf, nbr)) + self.peers.remove(key) else: - self.directory.remove("interfaces", key) + log_err("Peer '(%s|%s)' hasn't been removed" % (vrf, nbr)) - @staticmethod - def get_local_interface(directory, local_addr): + def apply_op(self, cmd, vrf): + """ + Push commands cmd into FRR + :param cmd: commands in raw format + :param vrf: vrf where the commands should be applied + :return: True if no errors, False if there are errors + """ + bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] + if vrf == 'default': + cmd = ('router bgp %s\n' % bgp_asn) + cmd + else: + cmd = ('router bgp %s vrf %s\n' % (bgp_asn, vrf)) + cmd + return self.cfg_mgr.push(cmd) + + def get_lo0_ipv4(self): """ - @summary: Get interface according to the local address from the directory - @param directory: Directory object that stored metadata of interfaces - @param local_addr: Local address of the interface - @return: Return the metadata of the interface with the local address + Extract Loopback0 ipv4 address from the Directory + :return: ipv4 address for Loopback0, None if nothing found + """ + loopback0_ipv4 = None + for loopback in self.directory.get_slot("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME).iterkeys(): + if loopback.startswith("Loopback0|"): + loopback0_prefix_str = loopback.replace("Loopback0|", "") + loopback0_ip_str = loopback0_prefix_str[:loopback0_prefix_str.find('/')] + if TemplateFabric.is_ipv4(loopback0_ip_str): + loopback0_ipv4 = loopback0_ip_str + break + + return loopback0_ipv4 + + def get_local_interface(self, local_addr): + """ + Get interface according to the local address from the directory + :param: directory: Directory object that stored metadata of interfaces + :param: local_addr: Local address of the interface + :return: Return the metadata of the interface with the local address If the interface has not been set, return None """ - local_addresses = directory.get_slot("local_addresses") + local_addresses = self.directory.get_slot("LOCAL", "local_addresses") # Check if the local address of this bgp session has been set if local_addr not in local_addresses: return None local_address = local_addresses[local_addr] - interfaces = directory.get_slot("interfaces") + interfaces = self.directory.get_slot("LOCAL", "interfaces") # Check if the information for the interface of this local address has been set if local_address.has_key("interface") and local_address["interface"] in interfaces: return interfaces[local_address["interface"]] @@ -503,9 +935,9 @@ class InterfaceMgr(Manager): @staticmethod def get_vnet(interface): """ - @summary: Get the VNet name of the interface - @param interface: The metadata of the interface - @return: Return the vnet name of the interface if this interface belongs to a vnet, + Get the VNet name of the interface + :param: interface: The metadata of the interface + :return: Return the vnet name of the interface if this interface belongs to a vnet, Otherwise return None """ if interface.has_key("vnet_name") and interface["vnet_name"]: @@ -513,65 +945,166 @@ class InterfaceMgr(Manager): else: return None + @staticmethod + def split_key(key): + """ + Split key into ip address and vrf name. If there is no vrf, "default" would be return for vrf + :param key: key to split + :return: vrf name extracted from the key, peer ip address extracted from the key + """ + if '|' not in key: + return 'default', key + else: + return tuple(key.split('|', 1)) -class LoopbackInterfaceMgr(InterfaceMgr): - def __init__(self, daemon, directory): - super(LoopbackInterfaceMgr, self).__init__( - daemon, - directory, - swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME - ) - + @staticmethod + def load_peers(): + """ + Load peers from FRR. + :return: set of peers, which are already installed in FRR + """ + command = ["vtysh", "-c", "show bgp vrfs json"] + ret_code, out, err = run_command(command) + if ret_code == 0: + js_vrf = json.loads(out) + vrfs = js_vrf['vrfs'].keys() + else: + log_crit("Can't read bgp vrfs: %s" % err) + raise Exception("Can't read bgp vrfs: %s" % err) + peers = set() + for vrf in vrfs: + command = ["vtysh", "-c", 'show bgp vrf %s neighbors json' % str(vrf)] + ret_code, out, err = run_command(command) + if ret_code == 0: + js_bgp = json.loads(out) + for nbr in js_bgp.keys(): + peers.add((vrf, nbr)) + else: + log_crit("Can't read vrf '%s' neighbors: %s" % (vrf, str(err))) + raise Exception("Can't read vrf '%s' neighbors: %s" % (vrf, str(err))) -class VlanInterfaceMgr(InterfaceMgr): - def __init__(self, daemon, directory): - super(VlanInterfaceMgr, self).__init__( - daemon, - directory, - swsscommon.CFG_VLAN_INTF_TABLE_NAME - ) + return peers -class PortChannelInterfaceMgr(InterfaceMgr): - def __init__(self, daemon, directory): - super(PortChannelInterfaceMgr, self).__init__( - daemon, - directory, - swsscommon.CFG_LAG_INTF_TABLE_NAME +class ZebraSetSrc(Manager): + """ This class initialize "set src" settings for zebra """ + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + super(ZebraSetSrc, self).__init__( + common_objs, + [], + db, + table, ) + tf = common_objs['tf'] + self.zebra_set_src_template = tf.from_file("zebra/zebra.set_src.conf.j2") + self.lo_ipv4 = None + self.lo_ipv6 = None + def set_handler(self, key, data): + """ Implementation of 'SET' command for this class """ + self.directory.put(self.db_name, self.table_name, key, data) + # + if key.startswith("Loopback0|") and "state" in data and data["state"] == "ok": + ip_addr_w_mask = key.replace("Loopback0|", "") + slash_pos = ip_addr_w_mask.rfind("/") + if slash_pos == -1: + log_err("Wrong Loopback0 ip address: '%s'" % ip_addr_w_mask) + return True + ip_addr = ip_addr_w_mask[:slash_pos] + try: + if TemplateFabric.is_ipv4(ip_addr) and self.lo_ipv4 is None: + self.lo_ipv4 = ip_addr + txt = self.zebra_set_src_template.render(rm_name="RM_SET_SRC", lo_ip=ip_addr, ip_proto="") + elif TemplateFabric.is_ipv6(ip_addr) and self.lo_ipv6 is None: + self.lo_ipv6 = ip_addr + txt = self.zebra_set_src_template.render(rm_name="RM_SET_SRC6", lo_ip=ip_addr, ip_proto="v6") + else: + log_err("Got ambiguous ip address '%s'" % ip_addr) + return True + except jinja2.TemplateError as e: + log_err("Error while rendering 'set src' template: %s" % str(e)) + return True + if self.cfg_mgr.push(txt): + log_info("The 'set src' configuration with Loopback0 ip '%s' was pushed" % ip_addr) + else: + log_err("The 'set src' configuration with Loopback0 ip '%s' wasn't pushed" % ip_addr) + return True -def wait_for_bgpd(): - # wait for 20 seconds - stop_time = datetime.datetime.now() + datetime.timedelta(seconds=20) - syslog.syslog(syslog.LOG_INFO, "Start waiting for bgpd: %s" % str(datetime.datetime.now())) + def del_handler(self, key): + """ Implementation of 'DEL' command for this class """ + self.directory.remove(self.db_name, self.table_name, key) + log_warn("Delete command is not supported for 'zebra set src' templates") + + +def wait_for_daemons(daemons, seconds): + """ + Wait until FRR daemons are ready for requests + :param daemons: list of FRR daemons to wait + :param seconds: number of seconds to wait, until raise an error + """ + stop_time = datetime.datetime.now() + datetime.timedelta(seconds=seconds) + log_info("Start waiting for FRR daemons: %s" % str(datetime.datetime.now())) while datetime.datetime.now() < stop_time: - rc, out, err = run_command(["vtysh", "-c", "show daemons"]) - if rc == 0 and "bgpd" in out: - syslog.syslog(syslog.LOG_INFO, "bgpd connected to vtysh: %s" % str(datetime.datetime.now())) + ret_code, out, err = run_command(["vtysh", "-c", "show daemons"], hide_errors=True) + if ret_code == 0 and all(daemon in out for daemon in daemons): + log_info("All required daemons have connected to vtysh: %s" % str(datetime.datetime.now())) return - time.sleep(0.1) # sleep 100 ms - raise RuntimeError("bgpd hasn't been started in 20 seconds") + else: + log_warn("Can't read daemon status from FRR: %s" % str(err)) + time.sleep(0.1) # sleep 100 ms + raise RuntimeError("FRR daemons hasn't been started in %d seconds" % seconds) + + +def read_constants(): + """ Read file with constants values from /etc/sonic/constants.yml """ + with open('/etc/sonic/constants.yml') as fp: + content = yaml.load(fp) + if "constants" not in content: + log_crit("/etc/sonic/constants.yml doesn't have 'constants' key") + raise Exception("/etc/sonic/constants.yml doesn't have 'constants' key") + return content["constants"] def main(): + """ Main function """ + wait_for_daemons(["bgpd", "zebra", "staticd"], seconds=20) + # + common_objs = { + 'directory': Directory(), + 'cfg_mgr': ConfigMgr(), + 'tf': TemplateFabric(), + 'constants': read_constants(), + } managers = [ - BGPDeviceMetaMgr, - BGPNeighborMetaMgr, - BGPPeerMgr, - InterfaceMgr, - LoopbackInterfaceMgr, - VlanInterfaceMgr, - PortChannelInterfaceMgr, + # Config DB managers + BGPDataBaseMgr(common_objs, "CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME), + BGPDataBaseMgr(common_objs, "CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME), + # Interface managers + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_INTF_TABLE_NAME), + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME), + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_VLAN_INTF_TABLE_NAME), + InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LAG_INTF_TABLE_NAME), + # State DB managers + ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME), + # Peer Managers + BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general"), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors"), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic"), ] - wait_for_bgpd() - daemon = Daemon() - directory = Directory() - manager_instanses = [ manager(daemon, directory) for manager in managers ] - daemon.run() + runner = Runner() + for mgr in managers: + runner.add_manager(mgr) + runner.run() -def signal_handler(signum, frame): +def signal_handler(_, __): # signal_handler(signum, frame) + """ signal handler """ global g_run g_run = False @@ -584,13 +1117,17 @@ if __name__ == '__main__': signal.signal(signal.SIGINT, signal_handler) main() except KeyboardInterrupt: - syslog.syslog(syslog.LOG_NOTICE, "Keyboard interrupt") - except RuntimeError as e: - syslog.syslog(syslog.LOG_CRIT, "%s" % str(e)) + log_notice("Keyboard interrupt") + except RuntimeError as exc: + log_crit(str(exc)) rc = -2 - except Exception as e: - syslog.syslog(syslog.LOG_CRIT, "Got an exception %s: Traceback: %s" % (str(e), traceback.format_exc())) + if g_debug: + raise + except Exception as exc: + log_crit("Got an exception %s: Traceback: %s" % (str(exc), traceback.format_exc())) rc = -1 + if g_debug: + raise finally: syslog.closelog() try: diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 deleted file mode 100644 index 2bf80b80a78..00000000000 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ /dev/null @@ -1,180 +0,0 @@ -! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} -{% block bgp_init %} -! -! bgp multiple-instance -! -route-map FROM_BGP_SPEAKER_V4 permit 10 -! -route-map TO_BGP_SPEAKER_V4 deny 10 -! -{# generate loopback prefix-lists #} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} -ip prefix-list PL_LoopbackV4 permit {{ prefix | ip }}/32 -{% elif prefix | ipv6 and name == 'Loopback0' %} -ipv6 prefix-list PL_LoopbackV6 permit {{ prefix | replace('/128', '/64') | ip_network }}/64 -{% endif %} -{% endfor %} -! -{# generate default peer route-maps #} -! -route-map TO_BGP_PEER_V4 permit 100 -! -route-map TO_BGP_PEER_V6 permit 100 -! -{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} -route-map HIDE_INTERNAL permit 10 - set community local-AS -! -{% endif %} -{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} -route-map OVERRIDE_ORIGINATOR_ID permit 10 -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - set originator-id {{ prefix | ip }} -{% endif %} -{% endfor %} -! -{% endif %} -{% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} -route-map FROM_BGPMON deny 10 -! -route-map TO_BGPMON permit 10 -! -{% endif %} -! -route-map ISOLATE permit 10 - set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }} -! -route-map set-next-hop-global-v6 permit 10 - set ipv6 next-hop prefer-global -! -router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} -{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} - redistribute connected route-map HIDE_INTERNAL -{% endif %} - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast - bgp graceful-restart restart-time 240 - bgp graceful-restart -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - bgp graceful-restart preserve-fw-state -{% endif %} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - bgp router-id {{ prefix | ip }} -{% endif %} -{% endfor %} -{# advertise loopback #} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - network {{ prefix | ip }}/32 -{% elif prefix | ipv6 and name == 'Loopback0' %} - address-family ipv6 - network {{ prefix | ip }}/64 - exit-address-family -{% endif %} -{% endfor %} -{% endblock bgp_init %} -{% endif %} -{% block vlan_advertisement %} -{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} -{% if prefix | ipv4 %} - network {{ prefix }} -{% elif prefix | ipv6 %} - address-family ipv6 - network {{ prefix }} - exit-address-family -{% endif %} -{% endfor %} -{% endblock vlan_advertisement %} -{% block maximum_paths %} - address-family ipv4 - maximum-paths 64 - exit-address-family - address-family ipv6 - maximum-paths 64 - exit-address-family -{% endblock maximum_paths %} -{% block peers_peer_group %} - neighbor PEER_V4 peer-group - neighbor PEER_V6 peer-group - address-family ipv4 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor PEER_V4 allowas-in 1 -{% endif %} - neighbor PEER_V4 soft-reconfiguration inbound - neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - exit-address-family - address-family ipv6 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor PEER_V6 allowas-in 1 -{% endif %} - neighbor PEER_V6 soft-reconfiguration inbound - neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - exit-address-family -{% endblock peers_peer_group %} -{% block bgp_peers_with_range %} -{% if BGP_PEER_RANGE %} -{% for bgp_peer in BGP_PEER_RANGE.values() %} - neighbor {{ bgp_peer['name'] }} peer-group - neighbor {{ bgp_peer['name'] }} passive -{% if bgp_peer['peer_asn'] is defined %} - neighbor {{ bgp_peer['name'] }} remote-as {{ bgp_peer['peer_asn'] }} -{% else %} - neighbor {{ bgp_peer['name'] }} remote-as {{ constants.deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']] }} -{% endif %} - neighbor {{ bgp_peer['name'] }} ebgp-multihop 255 - neighbor {{ bgp_peer['name'] }} soft-reconfiguration inbound -{% if bgp_peer['src_address'] is defined %} - neighbor {{ bgp_peer['name'] }} update-source {{ bgp_peer['src_address'] | ip }} -{% else %} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if name == 'Loopback1' %} - neighbor {{ bgp_peer['name'] }} update-source {{ prefix | ip }} -{% endif %} -{% endfor %} -{% endif %} - neighbor {{ bgp_peer['name'] }} route-map FROM_BGP_SPEAKER_V4 in - neighbor {{ bgp_peer['name'] }} route-map TO_BGP_SPEAKER_V4 out -{% for ip_range in bgp_peer['ip_range'] %} - bgp listen range {{ip_range}} peer-group {{ bgp_peer['name'] }} -{% endfor %} - address-family ipv4 - neighbor {{ bgp_peer['name'] }} activate - exit-address-family - address-family ipv6 - neighbor {{ bgp_peer['name'] }} activate - exit-address-family -{% endfor %} -{% endif %} -{% endblock bgp_peers_with_range %} -{% block bgp_monitors %} -{% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} - neighbor BGPMON peer-group -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - neighbor BGPMON update-source {{ prefix | ip }} -{% endif %} -{% endfor %} - neighbor BGPMON route-map FROM_BGPMON in - neighbor BGPMON route-map TO_BGPMON out - neighbor BGPMON send-community - neighbor BGPMON maximum-prefix 1 -{% for neighbor_addr, bgp_session in BGP_MONITORS.items() %} - neighbor {{ neighbor_addr }} remote-as {{ DEVICE_METADATA['localhost']['bgp_asn'] }} - neighbor {{ neighbor_addr }} peer-group BGPMON - neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} - neighbor {{ neighbor_addr }} activate -{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} - neighbor {{ neighbor_addr }} route-map OVERRIDE_ORIGINATOR_ID in -{% endif %} - address-family ipv6 - neighbor {{ neighbor_addr }} activate - exit-address-family -{% endfor %} -{% endif %} -{% endblock bgp_monitors %} -! diff --git a/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 b/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 deleted file mode 100644 index 9cd61b89907..00000000000 --- a/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 +++ /dev/null @@ -1,10 +0,0 @@ -route-map TO_BGP_PEER_V4 permit 2 - match ip address prefix-list PL_LoopbackV4 - set community {{ constants.traffic_shift_community }} -route-map TO_BGP_PEER_V4 deny 3 -! -route-map TO_BGP_PEER_V6 permit 2 - match ipv6 address prefix-list PL_LoopbackV6 - set community {{ constants.traffic_shift_community }} -route-map TO_BGP_PEER_V6 deny 3 -! diff --git a/dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 b/dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 deleted file mode 100644 index 25d7c49125e..00000000000 --- a/dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 +++ /dev/null @@ -1,6 +0,0 @@ -no route-map TO_BGP_PEER_V4 permit 2 -no route-map TO_BGP_PEER_V4 deny 3 -! -no route-map TO_BGP_PEER_V6 permit 2 -no route-map TO_BGP_PEER_V6 deny 3 -! diff --git a/dockers/docker-fpm-frr/frr.conf.j2 b/dockers/docker-fpm-frr/frr.conf.j2 deleted file mode 100644 index afa40ad8ba7..00000000000 --- a/dockers/docker-fpm-frr/frr.conf.j2 +++ /dev/null @@ -1,18 +0,0 @@ -! -{% block banner %} -! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/frr/frr.conf.j2 with config DB data -! file: frr.conf -! -{% endblock banner %} -! -{% include "daemons.common.conf.j2" %} -! -agentx -! -{% include "zebra.interfaces.conf.j2" %} -! -{% include "staticd.default_route.conf.j2" %} -! -{% include "bgpd.conf.default.j2" %} -! diff --git a/dockers/docker-fpm-frr/bgpd.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.conf.j2 similarity index 50% rename from dockers/docker-fpm-frr/bgpd.conf.j2 rename to dockers/docker-fpm-frr/frr/bgpd/bgpd.conf.j2 index b4b2cd59c9b..85182e5430e 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.conf.j2 @@ -1,4 +1,8 @@ ! +! template: bgpd/bgpd.conf.j2 +! +{% from "common/functions.conf.j2" import get_ipv4_loopback_address, get_ipv6_loopback_address %} +! {% block banner %} ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== ! generated by templates/quagga/bgpd.conf.j2 with config DB data @@ -6,13 +10,15 @@ ! {% endblock banner %} ! -{% include "daemons.common.conf.j2" %} +{% include "common/daemons.common.conf.j2" %} ! agentx ! {% if DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} -{% include "bgpd.conf.spine_chassis_frontend_router.j2" %} +{% include "bgpd.spine_chassis_frontend_router.conf.j2" %} {% endif %} ! -{% include "bgpd.conf.default.j2" %} +{% include "bgpd.main.conf.j2" %} +! +! end of template: bgpd/bgpd.conf.j2 ! diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 new file mode 100644 index 00000000000..4a4f06b0d0f --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -0,0 +1,81 @@ +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32 +! +{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") != 'None' %} +ipv6 prefix-list PL_LoopbackV6 permit {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | replace('/128', '/64') | ip_network }}/64 +{% endif %} +! +! +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +{% endif %} +! +router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} +! +{% block bgp_init %} + bgp log-neighbor-changes + no bgp default ipv4-unicast +! +{% if constants.bgp.multipath_relax.enabled is defined and constants.bgp.multipath_relax.enabled %} + bgp bestpath as-path multipath-relax +{% endif %} +! +{% if constants.bgp.graceful_restart.enabled is defined and constants.bgp.graceful_restart.enabled %} + bgp graceful-restart restart-time {{ constants.bgp.graceful_restart.restart_time | default(240) }} + bgp graceful-restart + bgp graceful-restart preserve-fw-state +{% endif %} +! +{# set router-id #} + bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }} +! +{# advertise loopback #} + network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32 +! +{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") != 'None' %} + address-family ipv6 + network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/64 + exit-address-family +{% endif %} +{% endblock bgp_init %} +! +{% block vlan_advertisement %} +{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} + network {{ prefix }} +{% elif prefix | ipv6 %} + address-family ipv6 + network {{ prefix }} + exit-address-family +{% endif %} +{% endfor %} +{% endblock vlan_advertisement %} +! +! +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} + redistribute connected route-map HIDE_INTERNAL +{% endif %} +! +{% if constants.bgp.maximum_paths.enabled is defined and constants.bgp.maximum_paths.enabled %} +{% block maximum_paths %} + address-family ipv4 + maximum-paths {{ constants.bgp.maximum_paths.ipv4 | default(64) }} + exit-address-family + address-family ipv6 + maximum-paths {{ constants.bgp.maximum_paths.ipv6 | default(64) }} + exit-address-family +{% endblock maximum_paths %} +{% endif %} +! +! end of template: bgpd/bgpd.main.conf.j2 +! diff --git a/dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 similarity index 100% rename from dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 rename to dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 new file mode 100644 index 00000000000..efb1546dac4 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/instance.conf.j2 @@ -0,0 +1,38 @@ +! +! template: bgpd/templates/dynamic/instance.conf.j2 +! +{% from "common/functions.conf.j2" import get_ipv4_loopback_address %} +! + neighbor {{ bgp_session['name'] }} peer-group + neighbor {{ bgp_session['name'] }} passive + neighbor {{ bgp_session['name'] }} ebgp-multihop 255 + neighbor {{ bgp_session['name'] }} soft-reconfiguration inbound + neighbor {{ bgp_session['name'] }} route-map FROM_BGP_SPEAKER in + neighbor {{ bgp_session['name'] }} route-map TO_BGP_SPEAKER out +! +{% if bgp_session['peer_asn'] is defined %} + neighbor {{ bgp_session['name'] }} remote-as {{ bgp_session['peer_asn'] }} +{% else %} + neighbor {{ bgp_session['name'] }} remote-as {{ constants.deployment_id_asn_map[CONFIG_DB__DEVICE_METADATA['localhost']['deployment_id']] }} +{% endif %} +! +{# FIXME: bgp_session['ip_range'] check the type #} +{% for ip_range in bgp_session['ip_range'].split(',') %} + bgp listen range {{ ip_range }} peer-group {{ bgp_session['name'] }} +{% endfor %} +! +{% if bgp_session['src_address'] is defined %} + neighbor {{ bgp_session['name'] }} update-source {{ bgp_session['src_address'] | ip }} +{% else %} + neighbor {{ bgp_session['name'] }} update-source {{ get_ipv4_loopback_address(CONFIG_DB__LOOPBACK_INTERFACE, "Loopback1") | ip }} +{% endif %} +! + address-family ipv4 + neighbor {{ bgp_session['name'] }} activate + exit-address-family + address-family ipv6 + neighbor {{ bgp_session['name'] }} activate + exit-address-family +! +! end of template: bgpd/templates/BGP_SPEAKER/instance.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/peer-group.conf.j2 new file mode 100644 index 00000000000..86d5c029722 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/peer-group.conf.j2 @@ -0,0 +1,7 @@ +! +! template: bgpd/templates/BGP_SPEAKER/peer-group.conf.j2 +! +! nothing is here +! +! end of template: bgpd/templates/BGP_SPEAKER/peer-group.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/policies.conf.j2 new file mode 100644 index 00000000000..17ca09ec2a3 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/dynamic/policies.conf.j2 @@ -0,0 +1,9 @@ +! +! template: bgpd/templates/BGP_SPEAKER/policies.conf.j2 +! +route-map FROM_BGP_SPEAKER permit 10 +! +route-map TO_BGP_SPEAKER deny 1 +! +! end of template: bgpd/templates/BGP_SPEAKER/policies.conf.j2 +! diff --git a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 old mode 100755 new mode 100644 similarity index 64% rename from dockers/docker-fpm-frr/bgpd.peer.conf.j2 rename to dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 index bcc520f6b2d..7abeabba0a7 --- a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 @@ -1,4 +1,6 @@ -{% block bgp_peer %} +! +! template: bgpd/templates/general/instance.conf.j2 +! neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} {# set the bgp neighbor timers if they have not default values #} @@ -6,27 +8,34 @@ or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} {% endif %} -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} +! +{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and CONFIG_DB__DEVICE_METADATA['localhost'].has_key('default_bgp_status') and CONFIG_DB__DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} neighbor {{ neighbor_addr }} shutdown {% endif %} +! {% if neighbor_addr | ipv4 %} address-family ipv4 neighbor {{ neighbor_addr }} peer-group PEER_V4 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} + neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V4_INT in +{% endif %} {% elif neighbor_addr | ipv6 %} address-family ipv6 -{% if bgp_session['asn'] != DEVICE_METADATA['localhost']['bgp_asn'] %} - neighbor {{ neighbor_addr }} route-map set-next-hop-global-v6 in -{% endif %} neighbor {{ neighbor_addr }} peer-group PEER_V6 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} + neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V6_INT in +{% endif %} {% endif %} +! {% if bgp_session['rrclient'] | int != 0 %} neighbor {{ neighbor_addr }} route-reflector-client {% endif %} +! {% if bgp_session['nhopself'] | int != 0 %} neighbor {{ neighbor_addr }} next-hop-self {% endif %} -{% if bgp_session["asn"] == DEVICE_METADATA['localhost']['bgp_asn'] - and DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} +! +{% if bgp_session["asn"] == bgp_asn and CONFIG_DB__DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} address-family l2vpn evpn neighbor {{ neighbor_addr }} activate advertise-all-vni @@ -34,4 +43,6 @@ {% endif %} neighbor {{ neighbor_addr }} activate exit-address-family -{% endblock bgp_peer %} +! +! end of template: bgpd/templates/general/instance.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 new file mode 100644 index 00000000000..551274902de --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 @@ -0,0 +1,24 @@ +! +! template: bgpd/templates/general/peer-group.conf.j2 +! + neighbor PEER_V4 peer-group + neighbor PEER_V6 peer-group + address-family ipv4 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} + neighbor PEER_V4 allowas-in 1 +{% endif %} + neighbor PEER_V4 soft-reconfiguration inbound + neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in + neighbor PEER_V4 route-map TO_BGP_PEER_V4 out + exit-address-family + address-family ipv6 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} + neighbor PEER_V6 allowas-in 1 +{% endif %} + neighbor PEER_V6 soft-reconfiguration inbound + neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in + neighbor PEER_V6 route-map TO_BGP_PEER_V6 out + exit-address-family +! +! end of template: bgpd/templates/general/peer-group.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 new file mode 100644 index 00000000000..0c7b17c207b --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -0,0 +1,30 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +! +! +route-map FROM_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V4 permit 100 +! +! +route-map FROM_BGP_PEER_V6 permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} +route-map FROM_BGP_PEER_V4_INT permit 2 + set originator-id {{ loopback0_ipv4 | ip }} +! +route-map FROM_BGP_PEER_V6_INT permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6_INT permit 2 + set originator-id {{ loopback0_ipv4 | ip }} +{% endif %} +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/instance.conf.j2 new file mode 100644 index 00000000000..0aa22a3a7f8 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/instance.conf.j2 @@ -0,0 +1,13 @@ +! +! template: bgpd/templates/monitors/instance.conf.j2 +! + neighbor {{ neighbor_addr }} remote-as {{ bgp_asn }} + neighbor {{ neighbor_addr }} peer-group BGPMON + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} + neighbor {{ neighbor_addr }} activate + address-family ipv6 + neighbor {{ neighbor_addr }} activate + exit-address-family +! +! end of template: bgpd/templates/BGPMON/instance.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/peer-group.conf.j2 new file mode 100644 index 00000000000..a3627861901 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/peer-group.conf.j2 @@ -0,0 +1,12 @@ +! +! template: bgpd/templates/BGPMON/peer-group.conf.j2 +! + neighbor BGPMON peer-group + neighbor BGPMON update-source {{ loopback0_ipv4 | ip }} + neighbor BGPMON route-map FROM_BGPMON in + neighbor BGPMON route-map TO_BGPMON out + neighbor BGPMON send-community + neighbor BGPMON maximum-prefix 1 +! +! end of template: bgpd/templates/BGPMON/peer-group.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/policies.conf.j2 new file mode 100644 index 00000000000..8d53991064d --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/monitors/policies.conf.j2 @@ -0,0 +1,9 @@ +! +! template: bgpd/templates/BGPMON/policies.conf.j2 +! +route-map FROM_BGPMON deny 10 +! +route-map TO_BGPMON permit 10 +! +! end of template: bgpd/templates/BGPMON/policies.conf.j2 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 new file mode 100644 index 00000000000..88b1c5acb2e --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.isolate.conf.j2 @@ -0,0 +1,5 @@ +route-map {{ route_map_name }} permit 2 + match ip address prefix-list PL_Loopback{{ ip_version }} + set community {{ constants.bgp.traffic_shift_community }} +route-map {{ route_map_name }} deny 3 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 new file mode 100644 index 00000000000..22244b3ac88 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/tsa/bgpd.tsa.unisolate.conf.j2 @@ -0,0 +1,3 @@ +no route-map {{ route_map_name }} permit 2 +no route-map {{ route_map_name }} deny 3 +! diff --git a/dockers/docker-fpm-frr/daemons.common.conf.j2 b/dockers/docker-fpm-frr/frr/common/daemons.common.conf.j2 similarity index 71% rename from dockers/docker-fpm-frr/daemons.common.conf.j2 rename to dockers/docker-fpm-frr/frr/common/daemons.common.conf.j2 index 23eb5184f5e..1c3efdfa72f 100644 --- a/dockers/docker-fpm-frr/daemons.common.conf.j2 +++ b/dockers/docker-fpm-frr/frr/common/daemons.common.conf.j2 @@ -1,3 +1,4 @@ +! template: common/daemons.common.conf.j2 ! {% block sys_init %} hostname {{ DEVICE_METADATA['localhost']['hostname'] }} @@ -10,3 +11,4 @@ log syslog informational log facility local4 {% endblock logging %} ! +! end of template: common/daemons.common.conf.j2 diff --git a/dockers/docker-fpm-frr/frr/common/functions.conf.j2 b/dockers/docker-fpm-frr/frr/common/functions.conf.j2 new file mode 100644 index 00000000000..9857f068fe9 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/common/functions.conf.j2 @@ -0,0 +1,23 @@ +{% macro get_ipv4_loopback_address(interfaces, loopbackname) -%} +{% set L = namespace(ip=None) %} +{% for name, prefix in interfaces|pfx_filter %} +{% if name == loopbackname %} +{% if prefix | ipv4 %} +{% set L.ip = prefix %} +{% endif %} +{% endif %} +{% endfor %} +{{ L.ip }} +{%- endmacro %} + +{% macro get_ipv6_loopback_address(interfaces, loopbackname) -%} +{% set L = namespace(ip=None) %} +{% for name, prefix in interfaces|pfx_filter %} +{% if name == loopbackname %} +{% if prefix | ipv6 %} +{% set L.ip = prefix %} +{% endif %} +{% endif %} +{% endfor %} +{{ L.ip }} +{%- endmacro %} diff --git a/dockers/docker-fpm-frr/frr/frr.conf.j2 b/dockers/docker-fpm-frr/frr/frr.conf.j2 new file mode 100644 index 00000000000..9e5def4ba01 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/frr.conf.j2 @@ -0,0 +1,19 @@ +! +{% block banner %} +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr.conf.j2 with config DB data +! file: frr.conf +! +{% endblock banner %} +! +{% include "common/daemons.common.conf.j2" %} +{% from "common/functions.conf.j2" import get_ipv4_loopback_address, get_ipv6_loopback_address %} +! +agentx +! +{% include "zebra/zebra.interfaces.conf.j2" %} +! +{% include "staticd/staticd.default_route.conf.j2" %} +! +{% include "bgpd/bgpd.main.conf.j2" %} +! diff --git a/dockers/docker-fpm-frr/isolate.j2 b/dockers/docker-fpm-frr/frr/isolate.j2 similarity index 100% rename from dockers/docker-fpm-frr/isolate.j2 rename to dockers/docker-fpm-frr/frr/isolate.j2 diff --git a/dockers/docker-fpm-frr/staticd.conf.j2 b/dockers/docker-fpm-frr/frr/staticd/staticd.conf.j2 similarity index 85% rename from dockers/docker-fpm-frr/staticd.conf.j2 rename to dockers/docker-fpm-frr/frr/staticd/staticd.conf.j2 index 4e39e17d7db..932871dfce4 100644 --- a/dockers/docker-fpm-frr/staticd.conf.j2 +++ b/dockers/docker-fpm-frr/frr/staticd/staticd.conf.j2 @@ -6,7 +6,7 @@ ! {% endblock banner %} ! -{% include "daemons.common.conf.j2" %} +{% include "common/daemons.common.conf.j2" %} ! {% include "staticd.default_route.conf.j2" %} ! diff --git a/dockers/docker-fpm-frr/staticd.default_route.conf.j2 b/dockers/docker-fpm-frr/frr/staticd/staticd.default_route.conf.j2 similarity index 100% rename from dockers/docker-fpm-frr/staticd.default_route.conf.j2 rename to dockers/docker-fpm-frr/frr/staticd/staticd.default_route.conf.j2 diff --git a/dockers/docker-fpm-frr/unisolate.j2 b/dockers/docker-fpm-frr/frr/unisolate.j2 similarity index 100% rename from dockers/docker-fpm-frr/unisolate.j2 rename to dockers/docker-fpm-frr/frr/unisolate.j2 diff --git a/dockers/docker-fpm-frr/zebra.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.conf.j2 similarity index 63% rename from dockers/docker-fpm-frr/zebra.conf.j2 rename to dockers/docker-fpm-frr/frr/zebra/zebra.conf.j2 index 8c1c6f96484..51d998e90d3 100644 --- a/dockers/docker-fpm-frr/zebra.conf.j2 +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.conf.j2 @@ -1,12 +1,12 @@ ! {% block banner %} ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data +! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! {% endblock banner %} ! -{% include "daemons.common.conf.j2" %} +{% include "common/daemons.common.conf.j2" %} ! {% include "zebra.interfaces.conf.j2" %} ! diff --git a/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 new file mode 100644 index 00000000000..484efeba585 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 @@ -0,0 +1,25 @@ +! +{% block vrf %} +{% if VNET is defined %} +{% for vnet_name, vnet_metadata in VNET.iteritems() %} +vrf {{ vnet_name }} +vni {{ vnet_metadata['vni'] }} +! +{% endfor %} +{% endif %} +{% endblock vrf %} +! +{% block interfaces %} +! Enable link-detect (default disabled) +{% for (name, prefix) in INTERFACE|pfx_filter %} +interface {{ name }} +link-detect +! +{% endfor %} +{% for pc in PORTCHANNEL %} +interface {{ pc }} +link-detect +! +{% endfor %} +{% endblock interfaces %} +! diff --git a/dockers/docker-fpm-frr/frr/zebra/zebra.set_src.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.set_src.conf.j2 new file mode 100644 index 00000000000..4dce3250ed1 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.set_src.conf.j2 @@ -0,0 +1,8 @@ +! +! Set ip source to loopback for bgp learned routes +! +route-map {{ rm_name }} permit 10 + set src {{ lo_ip }} +! +ip{{ ip_proto }} protocol bgp route-map {{ rm_name }} +! diff --git a/dockers/docker-fpm-frr/start.sh b/dockers/docker-fpm-frr/start.sh index b3cef5e6324..aa72b36e5ce 100755 --- a/dockers/docker-fpm-frr/start.sh +++ b/dockers/docker-fpm-frr/start.sh @@ -5,9 +5,9 @@ mkdir -p /etc/frr CONFIG_TYPE=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["docker_routing_config_mode"]'` if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "separated" ]; then - sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/frr/bgpd.conf - sonic-cfggen -d -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/frr/zebra.conf - sonic-cfggen -d -t /usr/share/sonic/templates/staticd.conf.j2 > /etc/frr/staticd.conf + sonic-cfggen -d -t /usr/share/sonic/templates/bgpd/bgpd.conf.j2 -y /etc/sonic/constants.yml > /etc/frr/bgpd.conf + sonic-cfggen -d -t /usr/share/sonic/templates/zebra/zebra.conf.j2 > /etc/frr/zebra.conf + sonic-cfggen -d -t /usr/share/sonic/templates/staticd/staticd.conf.j2 > /etc/frr/staticd.conf echo "no service integrated-vtysh-config" > /etc/frr/vtysh.conf rm -f /etc/frr/frr.conf elif [ "$CONFIG_TYPE" == "unified" ]; then diff --git a/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 b/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 deleted file mode 100644 index 4a089e4dc72..00000000000 --- a/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 +++ /dev/null @@ -1,60 +0,0 @@ -! -{% block vrf %} -{% if VNET is defined %} -{% for vnet_name, vnet_metadata in VNET.iteritems() %} -vrf {{ vnet_name }} -vni {{ vnet_metadata['vni'] }} -! -{% endfor %} -{% endif %} -{% endblock vrf %} -! -{% block interfaces %} -! Enable link-detect (default disabled) -{% for (name, prefix) in INTERFACE|pfx_filter %} -interface {{ name }} -link-detect -! -{% endfor %} -{% for pc in PORTCHANNEL %} -interface {{ pc }} -link-detect -! -{% endfor %} -{% endblock interfaces %} -! -{% block source_loopback %} -{% set lo_ipv4_addrs = [] %} -{% set lo_ipv6_addrs = [] %} -{% if LOOPBACK_INTERFACE %} -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if name == 'Loopback0' %} -{% if prefix | ipv6 %} -{% if lo_ipv6_addrs.append(prefix) %} -{% endif %} -{% else %} -{% if lo_ipv4_addrs.append(prefix) %} -{% endif %} -{% endif %} -{% endif %} -{% endfor %} -{% endif %} -! Set ip source to loopback for bgp learned routes -{% if lo_ipv4_addrs|length > 0 -%} -route-map RM_SET_SRC permit 10 - set src {{ lo_ipv4_addrs[0] | ip }} -! -{% endif %} -{% if lo_ipv6_addrs|length > 0 %} -route-map RM_SET_SRC6 permit 10 - set src {{ lo_ipv6_addrs[0] | ip }} -! -{% endif %} -ip protocol bgp route-map RM_SET_SRC -! -{% if lo_ipv6_addrs|length > 0 %} -ipv6 protocol bgp route-map RM_SET_SRC6 -! -{% endif %} -{% endblock source_loopback %} -! diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index 3834717a8bf..3e1b76be015 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -1,4 +1,34 @@ constants: deployment_id_asn_map: "1" : 65432 - traffic_shift_community: 12345:12345 + "2" : 65433 + bgp: + traffic_shift_community: 12345:12345 + families: + - ipv4 + - ipv6 + use_deployment_id: false + use_neighbors_meta: false + graceful_restart: + enabled: true + restart_time: 240 + multipath_relax: + enabled: true + maximum_paths: + enabled: true + ipv4: 64 + ipv6: 64 + peers: + general: # peer_type + db_table: "BGP_NEIGHBOR" + template_dir: "general" + monitors: # peer_type + enabled: true + db_table: "BGP_MONITORS" + peer_group: "BGPMON" + template_dir: "monitors" + dynamic: # peer_type + enabled: true + db_table: "BGP_PEER_RANGE" + peer_group: "BGP_SPEAKER" + template_dir: "dynamic" diff --git a/src/sonic-config-engine/.gitignore b/src/sonic-config-engine/.gitignore new file mode 100644 index 00000000000..e41d5b085e5 --- /dev/null +++ b/src/sonic-config-engine/.gitignore @@ -0,0 +1,2 @@ +dist/ +tests/output diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index dddfde32428..1a94a47c0f9 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -204,6 +204,7 @@ def main(): parser.add_argument("-s", "--redis-unix-sock-file", help="unix sock file for redis connection") group = parser.add_mutually_exclusive_group() group.add_argument("-t", "--template", help="render the data with the template file") + parser.add_argument("-T", "--template_dir", help="search base for the template files", action='store') group.add_argument("-v", "--var", help="print the value of a variable, support jinja2 expression") group.add_argument("--var-json", help="print the value of a variable, in json format") group.add_argument("-w", "--write-to-db", help="write config into configdb", action='store_true') @@ -273,9 +274,12 @@ def main(): }}} deep_update(data, hardware_data) - if args.template != None: + if args.template is not None: template_file = os.path.abspath(args.template) paths = ['/', '/usr/share/sonic/templates', os.path.dirname(template_file)] + if args.template_dir is not None: + template_dir = os.path.abspath(args.template_dir) + paths.append(template_dir) loader = jinja2.FileSystemLoader(paths) redis_bcc = RedisBytecodeCache(SonicV2Connector(host='127.0.0.1')) diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf index 566d6384fcf..1f0f97e2ff5 100644 --- a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf @@ -1,9 +1,13 @@ ! +! template: bgpd/bgpd.conf.j2 +! +! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== ! generated by templates/quagga/bgpd.conf.j2 with config DB data ! file: bgpd.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname switch-t0 password zebra @@ -11,79 +15,57 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! agentx ! ! ! +! template: bgpd/bgpd.main.conf.j2 ! ! bgp multiple-instance ! -route-map FROM_BGP_SPEAKER_V4 permit 10 +! BGP configuration ! -route-map TO_BGP_SPEAKER_V4 deny 10 +! TSA configuration ! ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 -ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 -! -! -route-map TO_BGP_PEER_V4 permit 100 -! -route-map TO_BGP_PEER_V6 permit 100 -! -route-map FROM_BGPMON deny 10 -! -route-map TO_BGPMON permit 10 ! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 ! -route-map ISOLATE permit 10 - set as-path prepend 65100 ! -route-map set-next-hop-global-v6 permit 10 - set ipv6 next-hop prefer-global ! router bgp 65100 +! bgp log-neighbor-changes - bgp bestpath as-path multipath-relax no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! bgp graceful-restart restart-time 240 bgp graceful-restart bgp graceful-restart preserve-fw-state +! bgp router-id 10.1.0.32 +! network 10.1.0.32/32 +! address-family ipv6 network fc00:1::32/64 exit-address-family +! network 192.168.0.1/27 +! +! +! address-family ipv4 maximum-paths 64 exit-address-family address-family ipv6 maximum-paths 64 exit-address-family - neighbor PEER_V4 peer-group - neighbor PEER_V6 peer-group - address-family ipv4 - neighbor PEER_V4 allowas-in 1 - neighbor PEER_V4 soft-reconfiguration inbound - neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - exit-address-family - address-family ipv6 - neighbor PEER_V6 allowas-in 1 - neighbor PEER_V6 soft-reconfiguration inbound - neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - exit-address-family - neighbor BGPMON peer-group - neighbor BGPMON update-source 10.1.0.32 - neighbor BGPMON route-map FROM_BGPMON in - neighbor BGPMON route-map TO_BGPMON out - neighbor BGPMON send-community - neighbor BGPMON maximum-prefix 1 - neighbor 10.20.30.40 remote-as 65100 - neighbor 10.20.30.40 peer-group BGPMON - neighbor 10.20.30.40 description BGPMonitor - neighbor 10.20.30.40 activate - address-family ipv6 - neighbor 10.20.30.40 activate - exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 !! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/src/sonic-config-engine/tests/sample_output/frr.conf b/src/sonic-config-engine/tests/sample_output/frr.conf index 47855ce7c84..07354c6cf65 100644 --- a/src/sonic-config-engine/tests/sample_output/frr.conf +++ b/src/sonic-config-engine/tests/sample_output/frr.conf @@ -1,9 +1,10 @@ ! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/frr/frr.conf.j2 with config DB data +! generated by templates/frr.conf.j2 with config DB data ! file: frr.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname switch-t0 password zebra @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! agentx ! ! @@ -29,93 +31,55 @@ link-detect interface PortChannel04 link-detect ! -! -! Set ip source to loopback for bgp learned routes -route-map RM_SET_SRC permit 10 - set src 10.1.0.32 -! - -route-map RM_SET_SRC6 permit 10 - set src fc00:1::32 -! -ip protocol bgp route-map RM_SET_SRC -! -ipv6 protocol bgp route-map RM_SET_SRC6 -! !! ! ! set static default route to mgmt gateway as a backup to learned default ip route 0.0.0.0/0 10.0.0.1 200 !! ! +! template: bgpd/bgpd.main.conf.j2 ! ! bgp multiple-instance ! -route-map FROM_BGP_SPEAKER_V4 permit 10 +! BGP configuration ! -route-map TO_BGP_SPEAKER_V4 deny 10 +! TSA configuration ! ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 -ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 -! -! -route-map TO_BGP_PEER_V4 permit 100 -! -route-map TO_BGP_PEER_V6 permit 100 -! -route-map FROM_BGPMON deny 10 -! -route-map TO_BGPMON permit 10 ! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 ! -route-map ISOLATE permit 10 - set as-path prepend 65100 ! -route-map set-next-hop-global-v6 permit 10 - set ipv6 next-hop prefer-global ! router bgp 65100 +! bgp log-neighbor-changes - bgp bestpath as-path multipath-relax no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! bgp graceful-restart restart-time 240 bgp graceful-restart bgp graceful-restart preserve-fw-state +! bgp router-id 10.1.0.32 +! network 10.1.0.32/32 +! address-family ipv6 network fc00:1::32/64 exit-address-family +! network 192.168.0.1/27 +! +! +! address-family ipv4 maximum-paths 64 exit-address-family address-family ipv6 maximum-paths 64 exit-address-family - neighbor PEER_V4 peer-group - neighbor PEER_V6 peer-group - address-family ipv4 - neighbor PEER_V4 allowas-in 1 - neighbor PEER_V4 soft-reconfiguration inbound - neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - exit-address-family - address-family ipv6 - neighbor PEER_V6 allowas-in 1 - neighbor PEER_V6 soft-reconfiguration inbound - neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - exit-address-family - neighbor BGPMON peer-group - neighbor BGPMON update-source 10.1.0.32 - neighbor BGPMON route-map FROM_BGPMON in - neighbor BGPMON route-map TO_BGPMON out - neighbor BGPMON send-community - neighbor BGPMON maximum-prefix 1 - neighbor 10.20.30.40 remote-as 65100 - neighbor 10.20.30.40 peer-group BGPMON - neighbor 10.20.30.40 description BGPMonitor - neighbor 10.20.30.40 activate - address-family ipv6 - neighbor 10.20.30.40 activate - exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 !! diff --git a/src/sonic-config-engine/tests/sample_output/staticd_frr.conf b/src/sonic-config-engine/tests/sample_output/staticd_frr.conf index 12a81de8212..31a11d8578a 100644 --- a/src/sonic-config-engine/tests/sample_output/staticd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/staticd_frr.conf @@ -4,6 +4,7 @@ ! file: staticd.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname switch-t0 password zebra @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! ! ! set static default route to mgmt gateway as a backup to learned default ip route 0.0.0.0/0 10.0.0.1 200 diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf index b0b5e2cb119..dd79ae3950b 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf @@ -1,9 +1,13 @@ ! +! template: bgpd/bgpd.conf.j2 +! +! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== ! generated by templates/quagga/bgpd.conf.j2 with config DB data ! file: bgpd.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname SpineFront01 password zebra @@ -11,7 +15,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! agentx ! ! @@ -37,49 +42,46 @@ router bgp 4000 vrf VnetFE exit-address-family !! ! +! template: bgpd/bgpd.main.conf.j2 ! ! bgp multiple-instance ! -route-map FROM_BGP_SPEAKER_V4 permit 10 +! BGP configuration ! -route-map TO_BGP_SPEAKER_V4 deny 10 +! TSA configuration ! ip prefix-list PL_LoopbackV4 permit 4.0.0.0/32 ! ! -route-map TO_BGP_PEER_V4 permit 100 -! -route-map TO_BGP_PEER_V6 permit 100 -! -! -route-map ISOLATE permit 10 - set as-path prepend 4000 ! -route-map set-next-hop-global-v6 permit 10 - set ipv6 next-hop prefer-global ! router bgp 4000 +! bgp log-neighbor-changes - bgp bestpath as-path multipath-relax no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! bgp graceful-restart restart-time 240 bgp graceful-restart + bgp graceful-restart preserve-fw-state +! bgp router-id 4.0.0.0 +! network 4.0.0.0/32 +! +! +! +! +! address-family ipv4 maximum-paths 64 exit-address-family address-family ipv6 maximum-paths 64 exit-address-family - neighbor PEER_V4 peer-group - neighbor PEER_V6 peer-group - address-family ipv4 - neighbor PEER_V4 soft-reconfiguration inbound - neighbor PEER_V4 route-map TO_BGP_PEER_V4 out - exit-address-family - address-family ipv6 - neighbor PEER_V6 soft-reconfiguration inbound - neighbor PEER_V6 route-map TO_BGP_PEER_V6 out - exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 !! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf index bd2b5c84f47..180a0e9fab8 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf @@ -1,9 +1,10 @@ ! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data +! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname SpineFront01 password zebra @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! ! vrf VnetFE vni 9000 @@ -27,11 +29,4 @@ link-detect interface Ethernet8 link-detect ! -! -! Set ip source to loopback for bgp learned routes -route-map RM_SET_SRC permit 10 - set src 4.0.0.0 -! -ip protocol bgp route-map RM_SET_SRC -! !! diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf index e047fcd64f2..661b2726825 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf @@ -1,9 +1,10 @@ ! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data +! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname SpineFront01 password zebra @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! ! vrf VnetFE vni 8000 @@ -27,11 +29,4 @@ link-detect interface Ethernet8 link-detect ! -! -! Set ip source to loopback for bgp learned routes -route-map RM_SET_SRC permit 10 - set src 4.0.0.0 -! -ip protocol bgp route-map RM_SET_SRC -! !! diff --git a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf b/src/sonic-config-engine/tests/sample_output/zebra_frr.conf index 690f609dafc..e3d0c2d55bc 100644 --- a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/zebra_frr.conf @@ -1,9 +1,10 @@ ! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data +! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname switch-t0 password zebra @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! ! ! ! Enable link-detect (default disabled) @@ -27,17 +29,4 @@ link-detect interface PortChannel04 link-detect ! -! -! Set ip source to loopback for bgp learned routes -route-map RM_SET_SRC permit 10 - set src 10.1.0.32 -! - -route-map RM_SET_SRC6 permit 10 - set src fc00:1::32 -! -ip protocol bgp route-map RM_SET_SRC -! -ipv6 protocol bgp route-map RM_SET_SRC6 -! !! diff --git a/src/sonic-config-engine/tests/test_frr.py b/src/sonic-config-engine/tests/test_frr.py index fcbff063b13..dd41e171176 100644 --- a/src/sonic-config-engine/tests/test_frr.py +++ b/src/sonic-config-engine/tests/test_frr.py @@ -37,8 +37,11 @@ def run_diff(self, file1, file2): return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) def run_case(self, template, target): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', template) - cmd = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file + template_dir = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', "frr") + conf_template = os.path.join(template_dir, template) + constants = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'constants', 'constants.yml') + cmd_args = self.t0_minigraph, self.t0_port_config, constants, conf_template, template_dir, self.output_file + cmd = "-m %s -p %s -y %s -t %s -T %s > %s" % cmd_args self.run_script(cmd) original_filename = os.path.join(self.test_dir, 'sample_output', target) @@ -52,11 +55,11 @@ def test_config_frr(self): self.assertTrue(*self.run_case('frr.conf.j2', 'frr.conf')) def test_bgpd_frr(self): - self.assertTrue(*self.run_case('bgpd.conf.j2', 'bgpd_frr.conf')) + self.assertTrue(*self.run_case('bgpd/bgpd.conf.j2', 'bgpd_frr.conf')) def test_zebra_frr(self): - self.assertTrue(*self.run_case('zebra.conf.j2', 'zebra_frr.conf')) + self.assertTrue(*self.run_case('zebra/zebra.conf.j2', 'zebra_frr.conf')) def test_staticd_frr(self): - self.assertTrue(*self.run_case('staticd.conf.j2', 'staticd_frr.conf')) + self.assertTrue(*self.run_case('staticd/staticd.conf.j2', 'staticd_frr.conf')) diff --git a/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py b/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py index 41ac347e2b1..a3c50b8a263 100644 --- a/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py +++ b/src/sonic-config-engine/tests/test_j2files_t2_chassis_fe.py @@ -30,8 +30,11 @@ def run_diff(self, file1, file2): return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) def run_case(self, minigraph, template, target): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', template) - cmd = '-m ' + minigraph + ' -p ' + self.t2_chassis_fe_port_config + ' -t ' + conf_template + ' > ' + self.output_file + template_dir = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', "frr") + conf_template = os.path.join(template_dir, template) + constants = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'constants', 'constants.yml') + cmd_args = minigraph, self.t2_chassis_fe_port_config, constants, conf_template, template_dir, self.output_file + cmd = "-m %s -p %s -y %s -t %s -T %s > %s" % cmd_args self.run_script(cmd) original_filename = os.path.join(self.test_dir, 'sample_output', target) @@ -42,13 +45,13 @@ def run_case(self, minigraph, template, target): # Test zebra.conf in FRR docker for a T2 chassis frontend (fe) def test_t2_chassis_fe_zebra_frr(self): - self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'zebra.conf.j2', 't2-chassis-fe-zebra.conf')) + self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'zebra/zebra.conf.j2', 't2-chassis-fe-zebra.conf')) # Test zebra.conf in FRR docker for a T2 chassis frontend (fe) switch with specified VNI def test_t2_chassis_fe_vni_zebra_frr(self): - self.assertTrue(*self.run_case(self.t2_chassis_fe_vni_minigraph, 'zebra.conf.j2', 't2-chassis-fe-vni-zebra.conf')) + self.assertTrue(*self.run_case(self.t2_chassis_fe_vni_minigraph, 'zebra/zebra.conf.j2', 't2-chassis-fe-vni-zebra.conf')) # Test bgpd.conf in FRR docker for a T2 chassis frontend (fe) def test_t2_chassis_frontend_bgpd_frr(self): - self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'bgpd.conf.j2', 't2-chassis-fe-bgpd.conf')) + self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'bgpd/bgpd.conf.j2', 't2-chassis-fe-bgpd.conf')) From 4adf243260b19f7a80f595a1b8aa99981f3a1e4c Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Fri, 24 Apr 2020 12:43:56 -0700 Subject: [PATCH 12/69] Fix docker restapi start issue, undefined error (#4475) --- dockers/docker-sonic-restapi/restapi.sh | 5 ++++- rules/docker-restapi.mk | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dockers/docker-sonic-restapi/restapi.sh b/dockers/docker-sonic-restapi/restapi.sh index 61778e3245d..d009507a7bc 100755 --- a/dockers/docker-sonic-restapi/restapi.sh +++ b/dockers/docker-sonic-restapi/restapi.sh @@ -3,7 +3,10 @@ RESTAPI_ARGS="" while true do - client_auth=`sonic-cfggen -d -v "RESTAPI['config']['client_auth']"` + has_client_auth=$(sonic-cfggen -d -v "1 if RESTAPI and RESTAPI['config']") + if [ "$has_client_auth" == "1" ]; then + client_auth=$(sonic-cfggen -d -v "RESTAPI['config']['client_auth']") + fi if [[ $client_auth == 'true' ]]; then certs=`sonic-cfggen -d -v "RESTAPI['certs']"` allow_insecure=`sonic-cfggen -d -v "RESTAPI['config']['allow_insecure']"` diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk index 09bbd03d8fd..b472e00491d 100644 --- a/rules/docker-restapi.mk +++ b/rules/docker-restapi.mk @@ -18,7 +18,6 @@ endif $(DOCKER_RESTAPI)_CONTAINER_NAME = restapi $(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t -$(DOCKER_RESTAPI)_RUN_OPT += --network="host" $(DOCKER_RESTAPI)_RUN_OPT += -v /var/run/redis/redis.sock:/var/run/redis/redis.sock $(DOCKER_RESTAPI)_RUN_OPT += -v /etc/sonic/certificates:/etc/sonic/certificates:ro $(DOCKER_RESTAPI)_RUN_OPT += -p=8081:8081/tcp From c56752a5f8b6e39e1cdd8754d1db0f536109018e Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 25 Apr 2020 10:52:38 -0700 Subject: [PATCH 13/69] [build]: add sonic-slave-run target to run any cmds inside sonic-slave-docekr (#4481) example: ``` SONIC_RUN_CMDS="gzip -d -c target/sonic-vs.img.gz > target/sonic-vs.img;\ qemu-img convert target/sonic-vs.img -O vhdx -o subformat=dynamic target/sonic-vs.vhdx"\ BLDENV=buster make -f Makefile.work sonic-slave-run ``` Signed-off-by: Guohan Lu --- Makefile.work | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Makefile.work b/Makefile.work index 6f63652423a..d9703000ddb 100644 --- a/Makefile.work +++ b/Makefile.work @@ -251,6 +251,16 @@ sonic-slave-bash : $(DOCKER_BUILD) ; } @$(DOCKER_RUN) -t $(SLAVE_IMAGE):$(SLAVE_TAG) bash +sonic-slave-run : + @$(OVERLAY_MODULE_CHECK) + @docker inspect --type image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) &> /dev/null || \ + { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Building... ; \ + $(DOCKER_BASE_BUILD) ; } + @docker inspect --type image $(SLAVE_IMAGE):$(SLAVE_TAG) &> /dev/null || \ + { echo Image $(SLAVE_IMAGE):$(SLAVE_TAG) not found. Building... ; \ + $(DOCKER_BUILD) ; } + @$(DOCKER_RUN) -t $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_RUN_CMDS)" + showtag: @echo $(SLAVE_IMAGE):$(SLAVE_TAG) @echo $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) From e75da77f35815947ea39c66e4c21a5077f168f51 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Sun, 26 Apr 2020 01:54:45 +0700 Subject: [PATCH 14/69] [device/celestica]: Fix sfp index on dx010 platform api (#4346) --- .../sonic_platform/chassis.py | 24 +++++++++++++++++-- .../sonic_platform/sfp.py | 12 +++++----- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py index 7db46e55bd8..91e3dc0bf46 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -56,8 +56,7 @@ def __init__(self): thermal = Thermal(index) self._thermal_list.append(thermal) # sfp index start from 1 - self._sfp_list.append(None) - for index in range(1, NUM_SFP+1): + for index in range(0, NUM_SFP): sfp = Sfp(index) self._sfp_list.append(sfp) for index in range(0, NUM_COMPONENT): @@ -159,3 +158,24 @@ def get_watchdog(self): self._watchdog = Watchdog() return self._watchdog + + def get_sfp(self, index): + """ + Retrieves sfp represented by (1-based) index + Args: + index: An integer, the index (1-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 1. + For example, 1 for Ethernet0, 2 for Ethernet4 and so on. + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + # The index will start from 1 + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list))) + return sfp diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py index 04fb36b72b8..330d925fd8a 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py @@ -100,7 +100,7 @@ class Sfp(SfpBase): def __init__(self, sfp_index): # Init index self.index = sfp_index - self.port_num = self.index + self.port_num = self.index + 1 # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' @@ -593,7 +593,7 @@ def get_lpmode(self): reg_value = int(content, 16) # Determind if port_num start from 1 or 0 - bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + bit_index = self.index # Mask off the bit corresponding to our port mask = (1 << bit_index) @@ -710,7 +710,7 @@ def reset(self): reg_value = int(content, 16) # Determind if port_num start from 1 or 0 - bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + bit_index = self.index # Mask off the bit corresponding to our port mask = (1 << bit_index) @@ -823,7 +823,7 @@ def set_lpmode(self, lpmode): reg_value = int(content, 16) # Determind if port_num start from 1 or 0 - bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + bit_index = self.index # Mask off the bit corresponding to our port mask = (1 << bit_index) @@ -907,7 +907,7 @@ def get_presence(self): reg_value = int(content, 16) # Determind if port_num start from 1 or 0 - bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + bit_index = self.index # Mask off the bit corresponding to our port mask = (1 << bit_index) @@ -942,4 +942,4 @@ def get_status(self): Returns: A boolean value, True if device is operating properly, False if not """ - return self.get_presence() and self.get_transceiver_bulk_status() + return self.get_presence() and not self.get_reset_status() From ac6cfb115fe37c6f7878595995619e80045f7c7b Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Sun, 26 Apr 2020 14:39:55 +0300 Subject: [PATCH 15/69] [Mellanox] Add a new Mellanox platform x86_64-mlnx_msn3420 and new SKU ACS-MSN3420 (#4436) * New SKU support for MSN3420 Signed-off-by: Shlomi Bitton Conflicts: device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py * Add CPLD's * Symlink fixes and semantics * Adding new platform at end of lines --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 4 +- .../ACS-MSN3420/buffers.json.j2 | 1 + .../ACS-MSN3420/buffers_defaults_t0.j2 | 1 + .../ACS-MSN3420/buffers_defaults_t1.j2 | 1 + .../ACS-MSN3420/pg_profile_lookup.ini | 1 + .../ACS-MSN3420/port_config.ini | 61 +++ .../ACS-MSN3420/qos.json.j2 | 1 + .../ACS-MSN3420/sai.profile | 1 + .../ACS-MSN3420/sai_3420.xml | 442 ++++++++++++++++++ .../x86_64-mlnx_msn3420-r0/default_sku | 1 + .../platform_components.json | 12 + .../x86_64-mlnx_msn3420-r0/platform_reboot | 1 + .../x86_64-mlnx_msn3420-r0/platform_wait | 1 + .../x86_64-mlnx_msn3420-r0/plugins/eeprom.py | 1 + .../x86_64-mlnx_msn3420-r0/plugins/psuutil.py | 1 + .../plugins/sfplpmget.py | 1 + .../plugins/sfplpmset.py | 1 + .../plugins/sfpreset.py | 1 + .../x86_64-mlnx_msn3420-r0/plugins/sfputil.py | 1 + .../pmon_daemon_control.json | 1 + .../x86_64-mlnx_msn3420-r0/sensors.conf | 113 +++++ .../sonic_platform/chassis.py | 4 +- .../mlnx-platform-api/sonic_platform/psu.py | 4 +- .../sonic_platform/thermal.py | 18 +- 24 files changed, 667 insertions(+), 7 deletions(-) create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers.json.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t0.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t1.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/qos.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai.profile create mode 100644 device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai_3420.xml create mode 100644 device/mellanox/x86_64-mlnx_msn3420-r0/default_sku create mode 100644 device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/platform_reboot create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/platform_wait create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/plugins/eeprom.py create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/plugins/psuutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmget.py create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmset.py create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfpreset.py create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfputil.py create mode 120000 device/mellanox/x86_64-mlnx_msn3420-r0/pmon_daemon_control.json create mode 100644 device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index b5f2a335b09..9e5ca408326 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -41,8 +41,8 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700': 0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0} -port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] +hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5} +port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1), (0, 48, 59, 60, 1)] def log_info(msg, also_print_to_console=False): syslog.openlog("sfputil") diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers.json.j2 new file mode 120000 index 00000000000..7888381852d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t0.j2 new file mode 120000 index 00000000000..85f0b6b6b35 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t1.j2 new file mode 120000 index 00000000000..3bb496a5103 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/pg_profile_lookup.ini new file mode 120000 index 00000000000..252ae8d4149 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/pg_profile_lookup.ini @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini new file mode 100644 index 00000000000..df63cbe39ac --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/port_config.ini @@ -0,0 +1,61 @@ +# name lanes alias index +Ethernet0 0 etp1 0 +Ethernet4 4 etp2 1 +Ethernet8 8 etp3 2 +Ethernet12 12 etp4 3 +Ethernet16 16 etp5 4 +Ethernet20 20 etp6 5 +Ethernet24 24 etp7 6 +Ethernet28 28 etp8 7 +Ethernet32 32 etp9 8 +Ethernet36 36 etp10 9 +Ethernet40 40 etp11 10 +Ethernet44 44 etp12 11 +Ethernet48 48 etp13 12 +Ethernet52 52 etp14 13 +Ethernet56 56 etp15 14 +Ethernet60 60 etp16 15 +Ethernet64 64 etp17 16 +Ethernet68 68 etp18 17 +Ethernet72 72 etp19 18 +Ethernet76 76 etp20 19 +Ethernet80 80 etp21 20 +Ethernet84 84 etp22 21 +Ethernet88 88 etp23 22 +Ethernet92 92 etp24 23 +Ethernet96 96 etp25 24 +Ethernet100 100 etp26 25 +Ethernet104 104 etp27 26 +Ethernet108 108 etp28 27 +Ethernet112 112 etp29 28 +Ethernet116 116 etp30 29 +Ethernet120 120 etp31 30 +Ethernet124 124 etp32 31 +Ethernet128 128 etp33 32 +Ethernet132 132 etp34 33 +Ethernet136 136 etp35 34 +Ethernet140 140 etp36 35 +Ethernet144 144 etp37 36 +Ethernet148 148 etp38 37 +Ethernet152 152 etp39 38 +Ethernet156 156 etp40 39 +Ethernet160 160 etp41 40 +Ethernet164 164 etp42 41 +Ethernet168 168 etp43 42 +Ethernet172 172 etp44 43 +Ethernet176 176 etp45 44 +Ethernet180 180 etp46 45 +Ethernet184 184 etp47 46 +Ethernet188 188 etp48 47 +Ethernet192 192,193,194,195 etp49 48 +Ethernet196 196,197,198,199 etp50 49 +Ethernet200 200,201,202,203 etp51 50 +Ethernet204 204,205,206,207 etp52 51 +Ethernet208 208,209,210,211 etp53 52 +Ethernet212 212,213,214,215 etp54 53 +Ethernet216 216,217,218,219 etp55 54 +Ethernet220 220,221,222,223 etp56 55 +Ethernet224 224,225,226,227 etp57 56 +Ethernet228 228,229,230,231 etp58 57 +Ethernet232 232,233,234,235 etp59 58 +Ethernet236 236,237,238,239 etp60 59 diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/qos.json.j2 new file mode 120000 index 00000000000..379f542893f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/qos.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai.profile b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai.profile new file mode 100644 index 00000000000..a30106c8674 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3420.xml diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai_3420.xml b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai_3420.xml new file mode 100644 index 00000000000..5064ee3ef81 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/ACS-MSN3420/sai_3420.xml @@ -0,0 +1,442 @@ + + + + + + 00:02:03:04:05:80 + + + 1 + + + 60 + + + + + 105 + 1 + 0 + + + 0 + + + 64 + + + 106 + 1 + 1 + 0 + 64 + + + 49 + 1 + 2 + 0 + 64 + + + 113 + 1 + 3 + 0 + 64 + + + 114 + 1 + 4 + 0 + 64 + + + 50 + 1 + 5 + 0 + 64 + + + 115 + 1 + 6 + 0 + 64 + + + 116 + 1 + 7 + 0 + 64 + + + 41 + 1 + 8 + 0 + 64 + + + 121 + 1 + 9 + 0 + 64 + + + 122 + 1 + 10 + 0 + 64 + + + 42 + 1 + 11 + 0 + 64 + + + 123 + 1 + 12 + 0 + 64 + + + 124 + 1 + 13 + 0 + 64 + + + 43 + 1 + 14 + 0 + 64 + + + 57 + 1 + 15 + 0 + 64 + + + 58 + 1 + 16 + 0 + 64 + + + 44 + 1 + 17 + 0 + 64 + + + 59 + 1 + 18 + 0 + 64 + + + 60 + 1 + 19 + 0 + 64 + + + 33 + 1 + 20 + 0 + 64 + + + 51 + 1 + 21 + 0 + 64 + + + 52 + 1 + 22 + 0 + 64 + + + 34 + 1 + 23 + 0 + 64 + + + 53 + 1 + 24 + 0 + 64 + + + 54 + 1 + 25 + 0 + 64 + + + 35 + 1 + 26 + 0 + 64 + + + 45 + 1 + 27 + 0 + 64 + + + 46 + 1 + 28 + 0 + 64 + + + 36 + 1 + 29 + 0 + 64 + + + 47 + 1 + 30 + 0 + 64 + + + 48 + 1 + 31 + 0 + 64 + + + 1 + 1 + 32 + 0 + 64 + + + 37 + 1 + 33 + 0 + 64 + + + 38 + 1 + 34 + 0 + 64 + + + 2 + 1 + 35 + 0 + 64 + + + 39 + 1 + 36 + 0 + 64 + + + 40 + 1 + 37 + 0 + 64 + + + 3 + 1 + 38 + 0 + 64 + + + 4 + 1 + 39 + 0 + 64 + + + 5 + 1 + 40 + 0 + 64 + + + 6 + 1 + 41 + 0 + 64 + + + 7 + 1 + 42 + 0 + 64 + + + 8 + 1 + 43 + 0 + 64 + + + 9 + 1 + 44 + 0 + 64 + + + 10 + 1 + 45 + 0 + 64 + + + 11 + 1 + 46 + 0 + 64 + + + 12 + 1 + 47 + 0 + 64 + + + 17 + 4 + 48 + 3 + 1536 + + + 21 + 4 + 49 + 3 + 1536 + + + 25 + 4 + 50 + 3 + 1536 + + + 29 + 4 + 51 + 3 + 1536 + + + 89 + 4 + 52 + 3 + 1536 + + + 93 + 4 + 53 + 3 + 1536 + + + 81 + 4 + 54 + 3 + 1536 + + + 85 + 4 + 55 + 3 + 1536 + + + 73 + 4 + 56 + 3 + 1536 + + + 77 + 4 + 57 + 3 + 1536 + + + 65 + 4 + 58 + 3 + 1536 + + + 69 + 4 + 59 + 3 + 1536 + + + + \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/default_sku b/device/mellanox/x86_64-mlnx_msn3420-r0/default_sku new file mode 100644 index 00000000000..a572bdce4e5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/default_sku @@ -0,0 +1 @@ +ACS-MSN3420 t1 diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json new file mode 100644 index 00000000000..f3ea5918a09 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json @@ -0,0 +1,12 @@ +{ + "chassis": { + "x86_64-mlnx_msn3420-r0": { + "component": { + "BIOS": { }, + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_reboot new file mode 120000 index 00000000000..43c8ea56749 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_reboot @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_reboot \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_wait new file mode 120000 index 00000000000..4b30bd42985 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_wait @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_wait \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/eeprom.py new file mode 120000 index 00000000000..b4e2a6a6167 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/eeprom.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/psuutil.py new file mode 120000 index 00000000000..9f724238a8d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/psuutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmget.py new file mode 120000 index 00000000000..2e84f435abd --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmget.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmset.py new file mode 120000 index 00000000000..6a88bac3046 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfplpmset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfpreset.py new file mode 120000 index 00000000000..fef2063e349 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfpreset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfpreset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfputil.py new file mode 120000 index 00000000000..45909b880fc --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfputil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn3420-r0/pmon_daemon_control.json new file mode 120000 index 00000000000..435a2ce7c0b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/pmon_daemon_control.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf new file mode 100644 index 00000000000..5718ff99518 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf @@ -0,0 +1,113 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN3420 +################################################################################ + +# Temperature sensors +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" + +bus "i2c-7" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-*-49" + label temp1 "Ambient Fan Side Temp (air intake)" + chip "tmp102-i2c-*-4a" + label temp1 "Ambient Port Side Temp (air exhaust)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-15-49" + label temp1 "Ambient COMEX Temp" + +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 4)" + chip "tps53679-i2c-*-70" + label in1 "PMIC-1 PSU 12V Rail (in)" + label in2 "PMIC-1 PSU 12V Rail (in)" + label in3 "PMIC-1 COMEX 1.8V Rail (out)" + label in4 "PMIC-1 COMEX 1.05V Rail (out)" + label temp1 "PMIC-1 Temp 1" + label temp2 "PMIC-1 Temp 2" + label power1 "PMIC-1 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-1 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-1 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-1 COMEX 1.05V Rail Curr (out)" + chip "tps53679-i2c-*-71" + label in1 "PMIC-2 PSU 12V Rail (in)" + label in2 "PMIC-2 PSU 12V Rail (in)" + label in3 "PMIC-2 COMEX 1.8V Rail (out)" + label in4 "PMIC-2 COMEX 1.05V Rail (out)" + label temp1 "PMIC-2 Temp 1" + label temp2 "PMIC-2 Temp 2" + label power1 "PMIC-2 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-2 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-2 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-2 COMEX 1.05V Rail Curr (out)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tps53679-i2c-*-58" + label in1 "PMIC-3 PSU 12V Rail (in)" + label in2 "PMIC-3 PSU 12V Rail (in)" + label in3 "PMIC-3 COMEX 1.8V Rail (out)" + label in4 "PMIC-3 COMEX 1.05V Rail (out)" + label temp1 "PMIC-3 Temp 1" + label temp2 "PMIC-3 Temp 2" + label power1 "PMIC-3 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-3 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-3 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-3 COMEX 1.05V Rail Curr (out)" + chip "tps53679-i2c-*-61" + label in1 "PMIC-4 PSU 12V Rail (in)" + label in2 "PMIC-4 PSU 12V Rail (in)" + label in3 "PMIC-4 COMEX 1.8V Rail (out)" + label in4 "PMIC-4 COMEX 1.05V Rail (out)" + label temp1 "PMIC-4 Temp 1" + label temp2 "PMIC-4 Temp 2" + label power1 "PMIC-4 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-4 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-4 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-4 COMEX 1.05V Rail Curr (out)" + +# Power supplies +bus "i2c-4" "i2c-1-mux (chan_id 3)" + chip "dps460-i2c-*-58" + label in1 "PSU-1 220V Rail (in)" + label in2 "PSU-1 12V Rail (out)" + label fan1 "PSU-1 Fan 1" + label temp1 "PSU-1 Temp 1" + label temp2 "PSU-1 Temp 2" + label temp3 "PSU-1 Temp 3" + label power1 "PSU-1 220V Rail Pwr (in)" + label power2 "PSU-1 12V Rail Pwr (out)" + label curr1 "PSU-1 220V Rail Curr (in)" + label curr2 "PSU-1 12V Rail Curr (out)" + chip "dps460-i2c-*-59" + label in1 "PSU-2 220V Rail (in)" + label in2 "PSU-2 12V Rail (out)" + label fan1 "PSU-2 Fan 1" + label temp1 "PSU-2 Temp 1" + label temp2 "PSU-2 Temp 2" + label temp3 "PSU-2 Temp 3" + label power1 "PSU-2 220V Rail Pwr (in)" + label power2 "PSU-2 12V Rail Pwr (out)" + label curr1 "PSU-2 220V Rail Curr (in)" + label curr2 "PSU-2 12V Rail Curr (out)" + +# Chassis fans +chip "mlxreg_fan-isa-*" + label fan1 "Chassis Fan Drawer-1 Tach 1" + label fan2 "Chassis Fan Drawer-1 Tach 2" + label fan3 "Chassis Fan Drawer-2 Tach 1" + label fan4 "Chassis Fan Drawer-2 Tach 2" + label fan5 "Chassis Fan Drawer-3 Tach 1" + label fan6 "Chassis Fan Drawer-3 Tach 2" + label fan7 "Chassis Fan Drawer-4 Tach 1" + label fan8 "Chassis Fan Drawer-4 Tach 2" + label fan9 "Chassis Fan Drawer-5 Tach 1" + label fan10 "Chassis Fan Drawer-5 Tach 2" + label fan11 "Chassis Fan Drawer-6 Tach 1" + label fan12 "Chassis Fan Drawer-6 Tach 2" + +# Miscellaneous +chip "*-virtual-*" + ignore temp1 diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index d47110ed8f4..c3642331d19 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -50,8 +50,8 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0} -port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] +hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5} +port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1), (0, 48, 59, 60, 1)] class Chassis(ChassisBase): """Platform-specific Chassis class""" diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 3f2fee433fa..6931cc0657c 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -37,7 +37,7 @@ # in most SKUs the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively. # but there are exceptions which will be handled by the following dictionary -hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1, 'ACS-MSN4700': 1} +hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1, 'ACS-MSN4700': 1, 'ACS-MSN3420': 1} psu_profile_list = [ # default filename convention { @@ -45,7 +45,7 @@ PSU_VOLTAGE : "power/psu{}_volt", PSU_POWER : "power/psu{}_power" }, - # for 3700, 3700c, 3800, 4700 + # for 3420, 3700, 3700c, 3800, 4700 { PSU_CURRENT : "power/psu{}_curr", PSU_VOLTAGE : "power/psu{}_volt_out2", diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 39f91913fe1..a9c11848f5d 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -124,7 +124,7 @@ THERMAL_API_GET_HIGH_THRESHOLD ] -hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8} +hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8, 'ACS-MSN3420': 9} thermal_profile_list = [ # 2700 { @@ -264,6 +264,22 @@ THERMAL_DEV_FAN_AMBIENT ] ) + }, + # 3420 + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_MODULE:(1, 60), + THERMAL_DEV_CATEGORY_PSU:(1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_COMEX_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT + ] + ) } ] From e363293ac0a03e0db7785c89f6fb71c13ff56831 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Tue, 28 Apr 2020 03:47:44 +0800 Subject: [PATCH 16/69] [Mellanox]Mellanox-SN3800-D112C8 support warm-reboot (#4482) --- .../Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml index 102842d7227..a72edb85633 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 64 From b26814f6434ecaa00918216a492ac90b32a0e841 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Tue, 28 Apr 2020 11:52:57 +0800 Subject: [PATCH 17/69] [Mellanox] Adjust dynamic minimum fan speed algorithm (#4476) * remove air flow direction from dynamic minimum algorithm * adjust minimum table according to thermal data --- .../sonic_platform/device_data.py | 53 +++++-------------- .../sonic_platform/thermal.py | 9 +--- .../sonic_platform/thermal_actions.py | 3 +- .../sonic_platform/thermal_conditions.py | 7 +-- .../tests/test_thermal_policy.py | 13 ++--- 5 files changed, 21 insertions(+), 64 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py index f006281c511..35b1f14d5bf 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py @@ -2,34 +2,22 @@ 'x86_64-mlnx_msn2700-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:40":13, "41:120":15}, - "p2c_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16}, - "c2p_trust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, - "c2p_untrust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, - "unk_trust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, - "unk_untrust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16} + "unk_trust": {"-127:30":13, "31:40":14 , "41:120":15}, + "unk_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16} } } }, 'x86_64-mlnx_msn2740-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:120":13}, - "p2c_untrust": {"-127:35":13, "36:40":14 , "41:120":15}, - "c2p_trust": {"-127:120":13}, - "c2p_untrust": {"-127:15":13, "16:30":14 , "31:35":15, "36:120":17}, "unk_trust": {"-127:120":13}, - "unk_untrust": {"-127:15":13, "16:30":14 , "31:35":15, "36:120":17}, + "unk_untrust": {"-127:15":13, "16:25":14 , "26:30":15, "31:120":17}, } } }, 'x86_64-mlnx_msn2100-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:120":12}, - "p2c_untrust": {"-127:15":12, "16:25":13, "26:30":14, "31:35":15, "36:120":16}, - "c2p_trust": {"-127:40":12, "41:120":13}, - "c2p_untrust": {"-127:40":12, "41:120":13}, "unk_trust": {"-127:40":12, "41:120":13}, "unk_untrust": {"-127:15":12, "16:25":13, "26:30":14, "31:35":15, "36:120":16} } @@ -38,22 +26,14 @@ 'x86_64-mlnx_msn2410-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:40":13, "41:120":15}, - "p2c_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16}, - "c2p_trust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, - "c2p_untrust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, - "unk_trust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16}, - "unk_untrust": {"-127:20":13, "21:25":14 , "26:30":15, "31:120":16} + "unk_trust": {"-127:30":13, "31:40":14 , "41:120":15}, + "unk_untrust": {"-127:25":13, "26:30":14 , "31:35":15, "36:120":16} } } }, 'x86_64-mlnx_msn2010-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:120":12}, - "p2c_untrust": {"-127:15":12, "16:20":13, "21:30":14, "31:35":15, "36:120":16}, - "c2p_trust": {"-127:120":12}, - "c2p_untrust": {"-127:20":12, "21:25":13 , "26:30":14, "31:35":15, "36:120":16}, "unk_trust": {"-127:120":12}, "unk_untrust": {"-127:15":12, "16:20":13 , "21:30":14, "31:35":15, "36:120":16} } @@ -62,10 +42,6 @@ 'x86_64-mlnx_msn3700-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:25":12, "26:40":13 , "41:120":14}, - "p2c_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, - "c2p_trust": {"-127:25":12, "26:40":13 , "41:120":14}, - "c2p_untrust": {"-127:25":12, "26:40":13 , "41:120":14}, "unk_trust": {"-127:25":12, "26:40":13 , "41:120":14}, "unk_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, } @@ -74,28 +50,25 @@ 'x86_64-mlnx_msn3700c-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:25":12, "26:40":13 , "41:120":14}, - "p2c_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, - "c2p_trust": {"-127:25":12, "26:40":13 , "41:120":14}, - "c2p_untrust": {"-127:25":12, "26:40":13 , "41:120":14}, - "unk_trust": {"-127:25":12, "26:40":13 , "41:120":14}, - "unk_untrust": {"-127:15":12, "16:30":13 , "31:35":14, "36:40":15, "41:120":16}, + "unk_trust": {"-127:40":12, "41:120":13}, + "unk_untrust": {"-127:10":12, "11:20":13 , "21:30":14, "31:35":15, "36:120":16}, } } }, 'x86_64-mlnx_msn3800-r0': { 'thermal': { 'minimum_table': { - "p2c_trust": {"-127:35":12, "36:120":13}, - "p2c_untrust": {"-127:0":12, "1:10":13 , "11:15":14, "16:20":15, "21:35":16, "36:120":17}, - "c2p_trust": {"-127:30":12, "31:40":13 , "41:120":14}, - "c2p_untrust": {"-127:20":12, "21:30":13 , "31:35":14, "36:40":15, "41:120":16}, "unk_trust": {"-127:30":12, "31:40":13 , "41:120":14}, "unk_untrust": {"-127:0":12, "1:10":13 , "11:15":14, "16:20":15, "21:35":16, "36:120":17}, } } }, 'x86_64-mlnx_msn4700-r0': { - + 'thermal': { + 'minimum_table': { + "unk_trust": {"-127:120":16}, + "unk_untrust": {"-127:120":16}, + } + } } } \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index a9c11848f5d..d4b9d56dc19 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -567,16 +567,11 @@ def check_module_temperature_trustable(cls): return 'trust' @classmethod - def get_air_flow_direction(cls): + def get_min_amb_temperature(cls): fan_ambient_path = join(HW_MGMT_THERMAL_ROOT, THERMAL_DEV_FAN_AMBIENT) port_ambient_path = join(HW_MGMT_THERMAL_ROOT, THERMAL_DEV_PORT_AMBIENT) # if there is any exception, let it raise fan_ambient_temp = int(cls._read_generic_file(fan_ambient_path, 0)) port_ambient_temp = int(cls._read_generic_file(port_ambient_path, 0)) - if fan_ambient_temp > port_ambient_temp: - return 'p2c', fan_ambient_temp - elif fan_ambient_temp < port_ambient_temp: - return 'c2p', port_ambient_temp - else: - return 'unk', fan_ambient_temp + return fan_ambient_temp if fan_ambient_temp < port_ambient_temp else port_ambient_temp diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py index 1f8292763dd..3a4d5f2a8a6 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_actions.py @@ -154,10 +154,9 @@ def execute(self, thermal_info_dict): if chassis.platform_name not in DEVICE_DATA or 'thermal' not in DEVICE_DATA[chassis.platform_name] or 'minimum_table' not in DEVICE_DATA[chassis.platform_name]['thermal']: Fan.min_cooling_level = ChangeMinCoolingLevelAction.UNKNOWN_SKU_COOLING_LEVEL else: - air_flow_dir = MinCoolingLevelChangeCondition.air_flow_dir trust_state = MinCoolingLevelChangeCondition.trust_state temperature = MinCoolingLevelChangeCondition.temperature - minimum_table = DEVICE_DATA[chassis.platform_name]['thermal']['minimum_table']['{}_{}'.format(air_flow_dir, trust_state)] + minimum_table = DEVICE_DATA[chassis.platform_name]['thermal']['minimum_table']['unk_{}'.format(trust_state)] for key, cooling_level in minimum_table.items(): temp_range = key.split(':') diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py index 6bd2d282862..94e18a2e00b 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal_conditions.py @@ -78,14 +78,13 @@ def is_match(self, thermal_info_dict): class MinCoolingLevelChangeCondition(ThermalPolicyConditionBase): trust_state = None - air_flow_dir = None temperature = None def is_match(self, thermal_info_dict): from .thermal import Thermal trust_state = Thermal.check_module_temperature_trustable() - air_flow_dir, temperature = Thermal.get_air_flow_direction() + temperature = Thermal.get_min_amb_temperature() temperature = temperature / 1000 change_cooling_level = False @@ -93,10 +92,6 @@ def is_match(self, thermal_info_dict): MinCoolingLevelChangeCondition.trust_state = trust_state change_cooling_level = True - if air_flow_dir != MinCoolingLevelChangeCondition.air_flow_dir: - MinCoolingLevelChangeCondition.air_flow_dir = air_flow_dir - change_cooling_level = True - if temperature != MinCoolingLevelChangeCondition.temperature: MinCoolingLevelChangeCondition.temperature = temperature change_cooling_level = True diff --git a/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py b/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py index 835d7a495bb..87fac359b2f 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_thermal_policy.py @@ -482,10 +482,9 @@ def test_dynamic_minimum_policy(thermal_manager): condition = policy.conditions[MinCoolingLevelChangeCondition] action = policy.actions[ChangeMinCoolingLevelAction] Thermal.check_module_temperature_trustable = MagicMock(return_value='trust') - Thermal.get_air_flow_direction = MagicMock(return_value=('p2c', 35000)) + Thermal.get_min_amb_temperature = MagicMock(return_value=35000) assert condition.is_match(None) assert MinCoolingLevelChangeCondition.trust_state == 'trust' - assert MinCoolingLevelChangeCondition.air_flow_dir == 'p2c' assert MinCoolingLevelChangeCondition.temperature == 35 assert not condition.is_match(None) @@ -493,11 +492,7 @@ def test_dynamic_minimum_policy(thermal_manager): assert condition.is_match(None) assert MinCoolingLevelChangeCondition.trust_state == 'untrust' - Thermal.get_air_flow_direction = MagicMock(return_value=('c2p', 35000)) - assert condition.is_match(None) - assert MinCoolingLevelChangeCondition.air_flow_dir == 'c2p' - - Thermal.get_air_flow_direction = MagicMock(return_value=('c2p', 25000)) + Thermal.get_min_amb_temperature = MagicMock(return_value=25000) assert condition.is_match(None) assert MinCoolingLevelChangeCondition.temperature == 25 @@ -515,5 +510,5 @@ def test_dynamic_minimum_policy(thermal_manager): chassis.platform_name = 'x86_64-mlnx_msn2700-r0' action.execute(thermal_info_dict) - assert Fan.min_cooling_level == 4 - Fan.set_cooling_level.assert_called_with(4, 5) + assert Fan.min_cooling_level == 3 + Fan.set_cooling_level.assert_called_with(3, 5) From 72af55564556119a72e6f10a554cdf34baf7cfdf Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Mon, 27 Apr 2020 21:48:09 -0700 Subject: [PATCH 18/69] Parse Device region field in Minigraph (#4486) --- src/sonic-config-engine/minigraph.py | 9 +++++++-- .../tests/simple-sample-graph-metadata.xml | 5 +++++ src/sonic-config-engine/tests/test_cfggen.py | 5 +++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index c640d137861..71f6bb9fc72 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -419,6 +419,7 @@ def parse_meta(meta, hname): mgmt_routes = [] erspan_dst = [] deployment_id = None + region = None device_metas = meta.find(str(QName(ns, "Devices"))) for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): if device.find(str(QName(ns1, "Name"))).text.lower() == hname.lower(): @@ -441,7 +442,9 @@ def parse_meta(meta, hname): erspan_dst = value_group elif name == "DeploymentId": deployment_id = value - return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id + elif name == "Region": + region = value + return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region def parse_deviceinfo(meta, hwsku): port_speeds = {} @@ -599,6 +602,7 @@ def parse_xml(filename, platform=None, port_config_file=None): erspan_dst = [] bgp_peers_with_range = None deployment_id = None + region = None hwsku_qn = QName(ns, "HwSku") hostname_qn = QName(ns, "Hostname") @@ -623,7 +627,7 @@ def parse_xml(filename, platform=None, port_config_file=None): elif child.tag == str(QName(ns, "UngDec")): (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): - (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id) = parse_meta(child, hostname) + (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region) = parse_meta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) @@ -632,6 +636,7 @@ def parse_xml(filename, platform=None, port_config_file=None): results['DEVICE_METADATA'] = {'localhost': { 'bgp_asn': bgp_asn, 'deployment_id': deployment_id, + 'region': region, 'docker_routing_config_mode': docker_routing_config_mode, 'hostname': hostname, 'hwsku': hwsku, diff --git a/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml index 1b1da1ff178..db103e13480 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml @@ -215,6 +215,11 @@ 1 + + Region + + usfoo + ErspanDestinationIpv4 diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 7f5eb155092..07769e0bf61 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -53,6 +53,11 @@ def test_minigraph_sku(self): output = self.run_script(argument) self.assertEqual(output.strip(), 'Force10-Z9100') + def test_minigraph_region(self): + argument = '-v "DEVICE_METADATA[\'localhost\'][\'region\']" -m "' + self.sample_graph_metadata + '"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'usfoo') + def test_print_data(self): argument = '-m "' + self.sample_graph + '" --print-data' output = self.run_script(argument) From a60a203b75b02a1a83694a9bf2273ad3dc72be7f Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Tue, 28 Apr 2020 00:57:59 -0700 Subject: [PATCH 19/69] [dhcpmon] Filter DHCP O/A Messages of Neighboring Vlans (#4469) * [dhcpmon] Filter DHCP O/A Messages of Neighboring Vlans This code fixes a bug where two or more vlans exist. Cross contamination happens for DHCP packets Offer/Ack when received on shared northbound links. The code filters out those packet based on dst IP equal Vlan loopback IP. signed-off-by: Tamer Ahmed --- src/dhcpmon/src/dhcp_device.c | 185 ++++++++++++++++++++++++---------- src/dhcpmon/src/dhcp_device.h | 38 +++++-- src/dhcpmon/src/dhcp_devman.c | 33 +++++- src/dhcpmon/src/dhcp_devman.h | 19 +++- src/dhcpmon/src/dhcp_mon.c | 10 +- src/dhcpmon/src/dhcp_mon.h | 2 +- src/dhcpmon/src/main.c | 4 +- 7 files changed, 212 insertions(+), 79 deletions(-) diff --git a/src/dhcpmon/src/dhcp_device.c b/src/dhcpmon/src/dhcp_device.c index aa0c0f835cb..554a1dcf0a9 100644 --- a/src/dhcpmon/src/dhcp_device.c +++ b/src/dhcpmon/src/dhcp_device.c @@ -33,6 +33,23 @@ #define DHCP_START_OFFSET (UDP_START_OFFSET + sizeof(struct udphdr)) /** Start of DHCP Options segment of a captured frame */ #define DHCP_OPTIONS_HEADER_SIZE 240 +/** Offset of DHCP GIADDR */ +#define DHCP_GIADDR_OFFSET 24 + +/** + * DHCP message types + **/ +typedef enum +{ + DHCP_MESSAGE_TYPE_DISCOVER = 1, + DHCP_MESSAGE_TYPE_OFFER = 2, + DHCP_MESSAGE_TYPE_REQUEST = 3, + DHCP_MESSAGE_TYPE_DECLINE = 4, + DHCP_MESSAGE_TYPE_ACK = 5, + DHCP_MESSAGE_TYPE_NAK = 6, + DHCP_MESSAGE_TYPE_RELEASE = 7, + DHCP_MESSAGE_TYPE_INFORM = 8 +} dhcp_message_type; #define OP_LDHA (BPF_LD | BPF_H | BPF_ABS) /** bpf ldh Abs */ #define OP_LDHI (BPF_LD | BPF_H | BPF_IND) /** bpf ldh Ind */ @@ -43,8 +60,9 @@ #define OP_JSET (BPF_JMP | BPF_JSET | BPF_K) /** bpf jset */ #define OP_LDXB (BPF_LDX | BPF_B | BPF_MSH) /** bpf ldxb */ -/** Berkley Packet Fitler program for "udp and (port 67 or port 68)". This program is obtained suing the following - * tcpdump command: 'tcpdump -dd "udp and (port 67 or port 68)"' +/** Berkeley Packet Filter program for "udp and (port 67 or port 68)". + * This program is obtained using the following command tcpdump: + * `tcpdump -dd "udp and (port 67 or port 68)"` */ static struct sock_filter dhcp_bpf_code[] = { {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x0000000c}, // (000) ldh [12] @@ -90,47 +108,63 @@ static dhcp_device_counters_t glob_counters_snapshot[DHCP_DIR_COUNT] = { }; /** - * @code handle_dhcp_option_53(context, dhcp_option, dir); + * @code handle_dhcp_option_53(context, dhcp_option, dir, iphdr, dhcphdr); * * @brief handle the logic related to DHCP option 53 * * @param context Device (interface) context * @param dhcp_option pointer to DHCP option buffer space * @param dir packet direction + * @param iphdr pointer to packet IP header + * @param dhcphdr pointer to DHCP header * * @return none */ -static void handle_dhcp_option_53(dhcp_device_context_t *context, const u_char *dhcp_option, dhcp_packet_direction_t dir) +static void handle_dhcp_option_53(dhcp_device_context_t *context, + const u_char *dhcp_option, + dhcp_packet_direction_t dir, + struct ip *iphdr, + uint8_t *dhcphdr) { + in_addr_t giaddr; switch (dhcp_option[2]) { - case 1: + case DHCP_MESSAGE_TYPE_DISCOVER: + giaddr = ntohl(dhcphdr[DHCP_GIADDR_OFFSET] << 24 | dhcphdr[DHCP_GIADDR_OFFSET + 1] << 16 | + dhcphdr[DHCP_GIADDR_OFFSET + 2] << 8 | dhcphdr[DHCP_GIADDR_OFFSET + 3]); context->counters[dir].discover++; - if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + if ((context->vlan_ip == giaddr && context->is_uplink && dir == DHCP_TX) || + (!context->is_uplink && dir == DHCP_RX && iphdr->ip_dst.s_addr == INADDR_BROADCAST)) { glob_counters[dir].discover++; } break; - case 2: + case DHCP_MESSAGE_TYPE_OFFER: context->counters[dir].offer++; - if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + if ((context->vlan_ip == iphdr->ip_dst.s_addr && context->is_uplink && dir == DHCP_RX) || + (!context->is_uplink && dir == DHCP_TX)) { glob_counters[dir].offer++; } break; - case 3: + case DHCP_MESSAGE_TYPE_REQUEST: + giaddr = ntohl(dhcphdr[DHCP_GIADDR_OFFSET] << 24 | dhcphdr[DHCP_GIADDR_OFFSET + 1] << 16 | + dhcphdr[DHCP_GIADDR_OFFSET + 2] << 8 | dhcphdr[DHCP_GIADDR_OFFSET + 3]); context->counters[dir].request++; - if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + if ((context->vlan_ip == giaddr && context->is_uplink && dir == DHCP_TX) || + (!context->is_uplink && dir == DHCP_RX && iphdr->ip_dst.s_addr == INADDR_BROADCAST)) { glob_counters[dir].request++; } break; - case 5: + case DHCP_MESSAGE_TYPE_ACK: context->counters[dir].ack++; - if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + if ((context->vlan_ip == iphdr->ip_dst.s_addr && context->is_uplink && dir == DHCP_RX) || + (!context->is_uplink && dir == DHCP_TX)) { glob_counters[dir].ack++; } break; - case 4: // type: Decline - case 6 ... 8: - // type: NAK, Release, Inform + case DHCP_MESSAGE_TYPE_DECLINE: + case DHCP_MESSAGE_TYPE_NAK: + case DHCP_MESSAGE_TYPE_RELEASE: + case DHCP_MESSAGE_TYPE_INFORM: break; default: syslog(LOG_WARNING, "handle_dhcp_option_53(%s): Unknown DHCP option 53 type %d", context->intf, dhcp_option[2]); @@ -146,7 +180,6 @@ static void handle_dhcp_option_53(dhcp_device_context_t *context, const u_char * * @param fd socket to read from * @param event libevent triggered event * @param arg user provided argument for callback (interface context) - * @param packet pointer to packet data * * @return none */ @@ -158,7 +191,9 @@ static void read_callback(int fd, short event, void *arg) while ((event == EV_READ) && ((buffer_sz = recv(fd, context->buffer, context->snaplen, MSG_DONTWAIT)) > 0)) { struct ether_header *ethhdr = (struct ether_header*) context->buffer; + struct ip *iphdr = (struct ip*) (context->buffer + IP_START_OFFSET); struct udphdr *udp = (struct udphdr*) (context->buffer + UDP_START_OFFSET); + uint8_t *dhcphdr = context->buffer + DHCP_START_OFFSET; int dhcp_option_offset = DHCP_START_OFFSET + DHCP_OPTIONS_HEADER_SIZE; if ((buffer_sz > UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) && @@ -181,7 +216,7 @@ static void read_callback(int fd, short event, void *arg) { case 53: if (offset < (dhcp_option_sz + 2)) { - handle_dhcp_option_53(context, &dhcp_option[offset], dir); + handle_dhcp_option_53(context, &dhcp_option[offset], dir, iphdr, dhcphdr); } stop_dhcp_processing = 1; // break while loop since we are only interested in Option 53 break; @@ -260,31 +295,21 @@ static void dhcp_print_counters(dhcp_device_counters_t *counters) } /** - * @code init_socket(context, intf, snaplen, base); + * @code init_socket(context, intf); * * @brief initializes socket, bind it to interface and bpf prgram, and * associate with libevent base * * @param context pointer to device (interface) context * @param intf interface name - * @param snaplen length of packet capture - * @param base libevent base * * @return 0 on success, otherwise for failure */ -static int init_socket(dhcp_device_context_t *context, - const char *intf, - size_t snaplen, - struct event_base *base) +static int init_socket(dhcp_device_context_t *context, const char *intf) { int rv = -1; do { - if (snaplen < UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) { - syslog(LOG_ALERT, "init_socket(%s): snap length is too low to capture DHCP options", intf); - break; - } - context->sock = socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, htons(ETH_P_ALL)); if (context->sock < 0) { syslog(LOG_ALERT, "socket: failed to open socket with '%s'\n", strerror(errno)); @@ -301,25 +326,6 @@ static int init_socket(dhcp_device_context_t *context, break; } - if (setsockopt(context->sock, SOL_SOCKET, SO_ATTACH_FILTER, &dhcp_sock_bfp, sizeof(dhcp_sock_bfp)) != 0) { - syslog(LOG_ALERT, "setsockopt: failed to attach filter with '%s'\n", strerror(errno)); - break; - } - - context->buffer = (uint8_t *) malloc(snaplen); - if (context->buffer == NULL) { - syslog(LOG_ALERT, "malloc: failed to allocate memory for socket buffer '%s'\n", strerror(errno)); - break; - } - context->snaplen = snaplen; - - struct event *ev = event_new(base, context->sock, EV_READ | EV_PERSIST, read_callback, context); - if (ev == NULL) { - syslog(LOG_ALERT, "event_new: failed to allocate memory for libevent event '%s'\n", strerror(errno)); - break; - } - event_add(ev, NULL); - strncpy(context->intf, intf, sizeof(context->intf) - 1); context->intf[sizeof(context->intf) - 1] = '\0'; @@ -377,15 +383,32 @@ static int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context) } /** - * @code dhcp_device_init(context, intf, snaplen, is_uplink, base); + * @code dhcp_device_get_ip(context); + * + * @brief Accessor method + * + * @param context pointer to device (interface) context + * + * @return interface IP + */ +int dhcp_device_get_ip(dhcp_device_context_t *context, in_addr_t *ip) +{ + int rv = -1; + + if (context != NULL && ip != NULL) { + *ip = context->ip; + rv = 0; + } + + return rv; +} + +/** + * @code dhcp_device_init(context, intf, is_uplink); * * @brief initializes device (interface) that handles packet capture per interface. */ -int dhcp_device_init(dhcp_device_context_t **context, - const char *intf, - int snaplen, - uint8_t is_uplink, - struct event_base *base) +int dhcp_device_init(dhcp_device_context_t **context, const char *intf, uint8_t is_uplink) { int rv = -1; dhcp_device_context_t *dev_context = NULL; @@ -394,8 +417,8 @@ int dhcp_device_init(dhcp_device_context_t **context, dev_context = (dhcp_device_context_t *) malloc(sizeof(dhcp_device_context_t)); if (dev_context != NULL) { - if ((init_socket(dev_context, intf, snaplen, base) == 0) && - (initialize_intf_mac_and_ip_addr(dev_context) == 0 ) ) { + if ((init_socket(dev_context, intf) == 0) && + (initialize_intf_mac_and_ip_addr(dev_context) == 0)) { dev_context->is_uplink = is_uplink; @@ -414,6 +437,56 @@ int dhcp_device_init(dhcp_device_context_t **context, return rv; } +/** + * @code dhcp_device_start_capture(context, snaplen, base, vlan_ip); + * + * @brief starts packet capture on this interface + */ +int dhcp_device_start_capture(dhcp_device_context_t *context, + size_t snaplen, + struct event_base *base, + in_addr_t vlan_ip) +{ + int rv = -1; + + do { + if (context == NULL) { + syslog(LOG_ALERT, "NULL interface context pointer'\n"); + break; + } + + if (snaplen < UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) { + syslog(LOG_ALERT, "dhcp_device_start_capture(%s): snap length is too low to capture DHCP options", context->intf); + break; + } + + context->vlan_ip = vlan_ip; + + context->buffer = (uint8_t *) malloc(snaplen); + if (context->buffer == NULL) { + syslog(LOG_ALERT, "malloc: failed to allocate memory for socket buffer '%s'\n", strerror(errno)); + break; + } + context->snaplen = snaplen; + + if (setsockopt(context->sock, SOL_SOCKET, SO_ATTACH_FILTER, &dhcp_sock_bfp, sizeof(dhcp_sock_bfp)) != 0) { + syslog(LOG_ALERT, "setsockopt: failed to attach filter with '%s'\n", strerror(errno)); + break; + } + + struct event *ev = event_new(base, context->sock, EV_READ | EV_PERSIST, read_callback, context); + if (ev == NULL) { + syslog(LOG_ALERT, "event_new: failed to allocate memory for libevent event '%s'\n", strerror(errno)); + break; + } + event_add(ev, NULL); + + rv = 0; + } while (0); + + return rv; +} + /** * @code dhcp_device_shutdown(context); * diff --git a/src/dhcpmon/src/dhcp_device.h b/src/dhcpmon/src/dhcp_device.h index 04113eeabdc..bc1582d46a8 100644 --- a/src/dhcpmon/src/dhcp_device.h +++ b/src/dhcpmon/src/dhcp_device.h @@ -49,6 +49,7 @@ typedef struct int sock; /** Raw socket associated with this device/interface */ in_addr_t ip; /** network address of this device (interface) */ uint8_t mac[ETHER_ADDR_LEN]; /** hardware address of this device (interface) */ + in_addr_t vlan_ip; /** Vlan IP address */ uint8_t is_uplink; /** north interface? */ char intf[IF_NAMESIZE]; /** device (interface) name */ uint8_t *buffer; /** buffer used to read socket data */ @@ -60,23 +61,48 @@ typedef struct } dhcp_device_context_t; /** - * @code dhcp_device_init(context, intf, snaplen, timeout_ms, is_uplink, base); + * @code dhcp_device_get_ip(context, ip); + * + * @brief Accessor method + * + * @param context pointer to device (interface) context + * @param ip(out) pointer to device IP + * + * @return 0 on success, otherwise for failure + */ +int dhcp_device_get_ip(dhcp_device_context_t *context, in_addr_t *ip); + +/** + * @code dhcp_device_init(context, intf, is_uplink); * * @brief initializes device (interface) that handles packet capture per interface. * * @param context(inout) pointer to device (interface) context * @param intf interface name - * @param snaplen length of packet capture * @param is_uplink uplink interface - * @param base pointer to libevent base * * @return 0 on success, otherwise for failure */ int dhcp_device_init(dhcp_device_context_t **context, const char *intf, - int snaplen, - uint8_t is_uplink, - struct event_base *base); + uint8_t is_uplink); + +/** + * @code dhcp_device_start_capture(context, snaplen, base, vlan_ip); + * + * @brief starts packet capture on this interface + * + * @param context pointer to device (interface) context + * @param snaplen length of packet capture + * @param base pointer to libevent base + * @param vlan_ip vlan IP address + * + * @return 0 on success, otherwise for failure + */ +int dhcp_device_start_capture(dhcp_device_context_t *context, + size_t snaplen, + struct event_base *base, + in_addr_t vlan_ip); /** * @code dhcp_device_shutdown(context); diff --git a/src/dhcpmon/src/dhcp_devman.c b/src/dhcpmon/src/dhcp_devman.c index c19cbde591b..077ed210a29 100644 --- a/src/dhcpmon/src/dhcp_devman.c +++ b/src/dhcpmon/src/dhcp_devman.c @@ -28,6 +28,23 @@ static uint32_t dhcp_num_south_intf = 0; /** dhcp_num_north_intf number of north interfaces */ static uint32_t dhcp_num_north_intf = 0; +/** On Device vlan interface IP address corresponding vlan downlink IP + * This IP is used to filter Offer/Ack packet coming from DHCP server */ +static in_addr_t vlan_ip = 0; + +/** vlan interface name */ +static char vlan_intf[IF_NAMESIZE] = "Undefined"; + +/** + * @code dhcp_devman_get_vlan_intf(); + * + * Accessor method + */ +const char* dhcp_devman_get_vlan_intf() +{ + return vlan_intf; +} + /** * @code dhcp_devman_init(); * @@ -65,7 +82,7 @@ void dhcp_devman_shutdown() } /** - * @code dhcp_devman_add_intf(name, uplink); + * @code dhcp_devman_add_intf(name, is_uplink); * * @brief adds interface to the device manager. */ @@ -84,9 +101,15 @@ int dhcp_devman_add_intf(const char *name, uint8_t is_uplink) assert(dhcp_num_south_intf <= 1); } - LIST_INSERT_HEAD(&intfs, dev, entry); + rv = dhcp_device_init(&dev->dev_context, dev->name, dev->is_uplink); + if (rv == 0 && !is_uplink) { + rv = dhcp_device_get_ip(dev->dev_context, &vlan_ip); - rv = 0; + strncpy(vlan_intf, name, sizeof(vlan_intf) - 1); + vlan_intf[sizeof(vlan_intf) - 1] = '\0'; + } + + LIST_INSERT_HEAD(&intfs, dev, entry); } else { syslog(LOG_ALERT, "malloc: failed to allocate memory for intf '%s'\n", name); @@ -100,14 +123,14 @@ int dhcp_devman_add_intf(const char *name, uint8_t is_uplink) * * @brief start packet capture on the devman interface list */ -int dhcp_devman_start_capture(int snaplen, struct event_base *base) +int dhcp_devman_start_capture(size_t snaplen, struct event_base *base) { int rv = -1; struct intf *int_ptr; if ((dhcp_num_south_intf == 1) && (dhcp_num_north_intf >= 1)) { LIST_FOREACH(int_ptr, &intfs, entry) { - rv = dhcp_device_init(&int_ptr->dev_context, int_ptr->name, snaplen, int_ptr->is_uplink, base); + rv = dhcp_device_start_capture(int_ptr->dev_context, snaplen, base, vlan_ip); if (rv == 0) { syslog(LOG_INFO, "Capturing DHCP packets on interface %s, ip: 0x%08x, mac [%02x:%02x:%02x:%02x:%02x:%02x] \n", diff --git a/src/dhcpmon/src/dhcp_devman.h b/src/dhcpmon/src/dhcp_devman.h index a0753b4b93a..2f66fa407ca 100644 --- a/src/dhcpmon/src/dhcp_devman.h +++ b/src/dhcpmon/src/dhcp_devman.h @@ -31,29 +31,38 @@ void dhcp_devman_init(); */ void dhcp_devman_shutdown(); +/** + * @code dhcp_devman_get_vlan_intf(); + * + * @brief Accessor method + * + * @return pointer to vlan ip interface name + */ +const char* dhcp_devman_get_vlan_intf(); + /** * @code dhcp_devman_add_intf(name, uplink); * * @brief adds interface to the device manager. * - * @param name interface name - * @param is_uplink true for uplink (north) interface + * @param name interface name + * @param is_uplink true for uplink (north) interface * * @return 0 on success, nonzero otherwise */ int dhcp_devman_add_intf(const char *name, uint8_t is_uplink); /** - * @code dhcp_devman_start_capture(snaplen, timeout_ms); + * @code dhcp_devman_start_capture(snaplen, base); * * @brief start packet capture on the devman interface list * - * @param snaplen packet capture snap length + * @param snaplen packet packet capture snap length * @param base libevent base * * @return 0 on success, nonzero otherwise */ -int dhcp_devman_start_capture(int snaplen, struct event_base *base); +int dhcp_devman_start_capture(size_t snaplen, struct event_base *base); /** * @code dhcp_devman_get_status(); diff --git a/src/dhcpmon/src/dhcp_mon.c b/src/dhcpmon/src/dhcp_mon.c index dc0a7d94f14..623bc46f527 100644 --- a/src/dhcpmon/src/dhcp_mon.c +++ b/src/dhcpmon/src/dhcp_mon.c @@ -36,13 +36,13 @@ static struct event *ev_sigterm; * * @param fd libevent socket * @param event event triggered - * @param arg pointer user provided context (libevent base) + * @param arg pointer to user provided context (libevent base) * * @return none */ static void signal_callback(evutil_socket_t fd, short event, void *arg) { - syslog(LOG_ALERT, "Received signal %d\n", event); + syslog(LOG_ALERT, "Received signal %s\n", strsignal(fd)); dhcp_devman_print_status(); dhcp_mon_stop(); } @@ -67,7 +67,9 @@ static void timeout_callback(evutil_socket_t fd, short event, void *arg) { case DHCP_MON_STATUS_UNHEALTHY: if (++count > dhcp_unhealthy_max_count) { - syslog(LOG_ALERT, "DHCP Relay is not healthy after %d health checks\n", count); + syslog(LOG_ALERT, "dhcpmon detected disparity in DHCP Relay behavior. Failure count: %d for vlan: '%s'\n", + count, dhcp_devman_get_vlan_intf()); + dhcp_devman_print_status(); } break; case DHCP_MON_STATUS_HEALTHY: @@ -151,7 +153,7 @@ void dhcp_mon_shutdown() * * @brief start monitoring DHCP Relay */ -int dhcp_mon_start(int snaplen) +int dhcp_mon_start(size_t snaplen) { int rv = -1; diff --git a/src/dhcpmon/src/dhcp_mon.h b/src/dhcpmon/src/dhcp_mon.h index 44d361b32ec..ae8911ab51f 100644 --- a/src/dhcpmon/src/dhcp_mon.h +++ b/src/dhcpmon/src/dhcp_mon.h @@ -40,7 +40,7 @@ void dhcp_mon_shutdown(); * * @return 0 upon success, otherwise upon failure */ -int dhcp_mon_start(int snaplen); +int dhcp_mon_start(size_t snaplen); /** * @code dhcp_mon_stop(); diff --git a/src/dhcpmon/src/main.c b/src/dhcpmon/src/main.c index 11eab6ee9ea..9d155393a6e 100644 --- a/src/dhcpmon/src/main.c +++ b/src/dhcpmon/src/main.c @@ -21,7 +21,7 @@ #include "dhcp_devman.h" /** dhcpmon_default_snaplen: default snap length of packet being captured */ -static const uint32_t dhcpmon_default_snaplen = 65535; +static const size_t dhcpmon_default_snaplen = 65535; /** dhcpmon_default_health_check_window: default value for a time window, during which DHCP DORA packet counts are being * collected */ static const uint32_t dhcpmon_default_health_check_window = 12; @@ -109,7 +109,7 @@ int main(int argc, char **argv) int i; int window_interval = dhcpmon_default_health_check_window; int max_unhealthy_count = dhcpmon_default_unhealthy_max_count; - uint32_t snaplen = dhcpmon_default_snaplen; + size_t snaplen = dhcpmon_default_snaplen; int make_daemon = 0; setlogmask(LOG_UPTO(LOG_INFO)); From 0409a32abe6591142e6819ff10eaf91044f39c1b Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Tue, 28 Apr 2020 18:15:19 +0300 Subject: [PATCH 20/69] [mellanox]: Align CPLD component with latest hw-mgmt. (#4485) Signed-off-by: Nazarii Hnydyn --- platform/mellanox/mlnx-platform-api/sonic_platform/component.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 13e3953a03a..d5937b63286 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -232,7 +232,7 @@ class ComponentCPLD(Component): CPLD_NUMBER_FILE = '/var/run/hw-management/config/cpld_num' CPLD_PART_NUMBER_FILE = '/var/run/hw-management/system/cpld{}_pn' CPLD_VERSION_FILE = '/var/run/hw-management/system/cpld{}_version' - CPLD_VERSION_MINOR_FILE = '/var/run/hw-management/system/cpld{}_version_minor' + CPLD_VERSION_MINOR_FILE = '/var/run/hw-management/system/cpld{}_version_min' CPLD_NUMBER_MAX_LENGTH = 1 CPLD_PART_NUMBER_MAX_LENGTH = 6 From a40fe3ba15c38719dfa8b7010eade6be138fed23 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Wed, 29 Apr 2020 01:46:19 +0530 Subject: [PATCH 21/69] [DellEMC] S6100-Fix i2C ISMT issue (#4330) * [DellEMC] S6100-Fix i2C ISMT issue * Modified the retry condition for bit bang --- .../s6100/scripts/fast-reboot_plugin | 1 + .../s6100/scripts/pcisysfs.py | 91 +++++++++++++++++++ .../s6100/scripts/s6100_bitbang_reset.sh | 59 ++++++++++++ .../s6100/scripts/s6100_i2c_enumeration.sh | 1 + 4 files changed, 152 insertions(+) create mode 100755 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_bitbang_reset.sh diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin index d385be3bc68..e32747c7fed 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin @@ -4,3 +4,4 @@ if [[ -d /sys/devices/platform/SMF.512/hwmon/ ]]; then cd /sys/devices/platform/SMF.512/hwmon/* echo 0xcc > mb_poweron_reason fi +/usr/local/bin/s6100_i2c_enumeration.sh deinit & > /dev/null diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py new file mode 100755 index 00000000000..767b66f43b6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py @@ -0,0 +1,91 @@ +#! /usr/bin/python + +import struct +import sys +import getopt +from os import * +from mmap import * + +def usage(): + ''' This is the Usage Method ''' + + print '\t\t pcisysfs.py --get --offset --res ' + print '\t\t pcisysfs.py --set --val --offset --res ' + sys.exit(1) + +def pci_mem_read(mm,offset): + mm.seek(offset) + read_data_stream=mm.read(4) + print "" + reg_val=struct.unpack('I',read_data_stream) + print "reg_val read:%x"%reg_val + return reg_val + +def pci_mem_write(mm,offset,data): + mm.seek(offset) + #print "data to write:%x"%data + mm.write(struct.pack('I',data)) + +def pci_set_value(resource,val,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_write(mm,offset,val) + close(fd) + +def pci_get_value(resource,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_read(mm,offset) + close(fd) + +def main(argv): + + ''' The main function will read the user input from the + command line argument and process the request ''' + + opts = '' + val = '' + choice = '' + resource = '' + offset = '' + + try: + opts, args = getopt.getopt(argv, "hgsv:" , \ + ["val=","res=","offset=","help", "get", "set"]) + + except getopt.GetoptError: + usage() + + for opt,arg in opts: + + if opt in ('-h','--help'): + choice = 'help' + + elif opt in ('-g', '--get'): + choice = 'get' + + elif opt in ('-s', '--set'): + choice = 'set' + + elif opt == '--res': + resource = arg + + elif opt == '--val': + val = int(arg,16) + + elif opt == '--offset': + offset = int(arg,16) + + if choice == 'set' and val != '' and offset !='' and resource !='': + pci_set_value(resource,val,offset) + + elif choice == 'get' and offset != '' and resource !='': + pci_get_value(resource,offset) + + else: + usage() + +#Calling the main method +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_bitbang_reset.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_bitbang_reset.sh new file mode 100644 index 00000000000..ff49c0a0f78 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_bitbang_reset.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# Script to unfreeze a stuck I2C controller, by bit-banging a STOP cycle on the bus + +bit_bang_recovery() +{ + +# Clear the ERRSTS +pcisysfs.py --set --val 0xffffffff --offset 0x018 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + +#Enable I2C bit-banging +pcisysfs.py --set --val 0x80000000 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + +count=1 +while [ $count -le 9 ]; +do + # Bit-bang an I2C STOP cycle + + # SCL=0, SDA=0 + pcisysfs.py --set --val 0x80000000 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + + sleep 0.01 + + # SCL=1, SDA=0 + pcisysfs.py --set --val 0x80000002 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + + sleep 0.01 + + # SCL=1, SDA=1 + pcisysfs.py --set --val 0x80000003 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + + sleep 1 + + # Check I2C DBSTS register + mctrl=$((`pcisysfs.py --get --offset 0x108 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) + msts=$((`pcisysfs.py --get --offset 0x10c --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) + dbsts=$((`pcisysfs.py --get --offset 0x38c --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) + msts_ip=$((msts&0x1)) + + mctrl=$((10#$mctrl)) + if [ $msts_ip = 0 ]; then + logger -p NOTICE "I2C_bitbang-Bit banging done on I2C bus" + logger -p NOTICE "After I2C_bitbang- MCTRL:$(printf "0x%x" $mctrl)","MSTS:$(printf "0x%x" $msts)","DBSTS:$(printf "0x%x" $dbsts)" + break + fi + count=$(( $count + 1 )) +done + +#Disable I2C bit-banging +pcisysfs.py --set --val 0x00000003 --offset 0x388 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 + +} + +mctrl=$((`pcisysfs.py --get --offset 0x108 --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) +msts=$((`pcisysfs.py --get --offset 0x10c --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) +dbsts=$((`pcisysfs.py --get --offset 0x38c --res /sys/devices/pci0000\:00/0000\:00\:13.0/resource0 | sed 's/^.*:/0x/'`)) +logger -p NOTICE "Before I2C_bitbang- MCTRL:$(printf "0x%x" $mctrl)","MSTS:$(printf "0x%x" $msts)","DBSTS:$(printf "0x%x" $dbsts)" +sleep 2 +bit_bang_recovery diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh index 04cff29ea7a..af91f378339 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_i2c_enumeration.sh @@ -245,6 +245,7 @@ if [[ "$1" == "init" ]]; then sys_eeprom "new_device" switch_board_eeprom "new_device" switch_board_cpld "new_device" + /usr/local/bin/s6100_bitbang_reset.sh switch_board_qsfp_mux "new_device" switch_board_sfp "new_device" switch_board_qsfp "new_device" From fc55329b220e21a25dd145197002a356ef271641 Mon Sep 17 00:00:00 2001 From: joyas-joseph <51463120+joyas-joseph@users.noreply.github.com> Date: Tue, 28 Apr 2020 15:57:13 -0700 Subject: [PATCH 22/69] [mgmt-framework]: convert mgmt-framework to use buster docker (#4480) This change adds support to build dockers using buster as base. - Define docker-base-buster using docker-base-stretch as starting point - Define docker-config-engine-buster using docker-config-engine-stretch as starting point. - sonic-mgmt-framework docker is updated to build using buster as base Signed-off-by: Joyas Joseph --- dockers/docker-base-buster/Dockerfile.j2 | 98 +++++++++++++++++++ dockers/docker-base-buster/LICENSE | 13 +++ dockers/docker-base-buster/dpkg_01_drop | 30 ++++++ dockers/docker-base-buster/etc/rsyslog.conf | 76 ++++++++++++++ .../etc/rsyslog.d/supervisor.conf | 9 ++ .../etc/supervisor/supervisord.conf | 33 +++++++ .../docker-base-buster/no-check-valid-until | 4 + .../no_install_recommend_suggest | 5 + dockers/docker-base-buster/root/.vimrc | 2 + dockers/docker-base-buster/sources.list | 8 ++ dockers/docker-base-buster/sources.list.arm64 | 7 ++ dockers/docker-base-buster/sources.list.armhf | 7 ++ .../docker-config-engine-buster/Dockerfile.j2 | 50 ++++++++++ .../docker-sonic-mgmt-framework/Dockerfile.j2 | 8 +- rules/docker-base-buster.dep | 10 ++ rules/docker-base-buster.mk | 17 ++++ rules/docker-config-engine-buster.dep | 10 ++ rules/docker-config-engine-buster.mk | 13 +++ rules/docker-sonic-mgmt-framework.mk | 8 +- slave.mk | 12 +-- 20 files changed, 402 insertions(+), 18 deletions(-) create mode 100644 dockers/docker-base-buster/Dockerfile.j2 create mode 100644 dockers/docker-base-buster/LICENSE create mode 100644 dockers/docker-base-buster/dpkg_01_drop create mode 100644 dockers/docker-base-buster/etc/rsyslog.conf create mode 100644 dockers/docker-base-buster/etc/rsyslog.d/supervisor.conf create mode 100644 dockers/docker-base-buster/etc/supervisor/supervisord.conf create mode 100644 dockers/docker-base-buster/no-check-valid-until create mode 100644 dockers/docker-base-buster/no_install_recommend_suggest create mode 100644 dockers/docker-base-buster/root/.vimrc create mode 100644 dockers/docker-base-buster/sources.list create mode 100644 dockers/docker-base-buster/sources.list.arm64 create mode 100644 dockers/docker-base-buster/sources.list.armhf create mode 100644 dockers/docker-config-engine-buster/Dockerfile.j2 create mode 100644 rules/docker-base-buster.dep create mode 100644 rules/docker-base-buster.mk create mode 100644 rules/docker-config-engine-buster.dep create mode 100644 rules/docker-config-engine-buster.mk diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 new file mode 100644 index 00000000000..de78845c62b --- /dev/null +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -0,0 +1,98 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +{% if CONFIGURED_ARCH == "armhf" %} +FROM multiarch/debian-debootstrap:armhf-buster +{% elif CONFIGURED_ARCH == "arm64" %} +FROM multiarch/debian-debootstrap:arm64-buster +{% else %} +FROM debian:buster +{% endif %} + +# Clean documentation in FROM image +RUN find /usr/share/doc -depth \( -type f -o -type l \) ! -name copyright | xargs rm || true + +# Clean doc directories that are empty or only contain empty directories +RUN while [ -n "$(find /usr/share/doc -depth -type d -empty -print -exec rmdir {} +)" ]; do :; done && \ + rm -rf \ + /usr/share/man/* \ + /usr/share/groff/* \ + /usr/share/info/* \ + /usr/share/lintian/* \ + /usr/share/linda/* \ + /var/cache/man/* \ + /usr/share/locale/* + +# Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +# Configure data sources for apt/dpkg +COPY ["dpkg_01_drop", "/etc/dpkg/dpkg.cfg.d/01_drop"] +{% if CONFIGURED_ARCH == "armhf" %} +COPY ["sources.list.armhf", "/etc/apt/sources.list"] +{% elif CONFIGURED_ARCH == "arm64" %} +COPY ["sources.list.arm64", "/etc/apt/sources.list"] +{% else %} +COPY ["sources.list", "/etc/apt/sources.list"] +{% endif %} +COPY ["no_install_recommend_suggest", "/etc/apt/apt.conf.d"] +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] + +# Update apt cache and +# pre-install fundamental packages +RUN apt-get update && \ + apt-get -y install \ + less \ + perl \ + procps \ + python \ + rsyslog \ + vim-tiny \ +# Install dependencies of supervisor + python-pkg-resources \ + python-meld3 \ +# dependencies of redis-tools + libatomic1 \ + libjemalloc2 \ + liblua5.1-0 \ + lua-bitop \ + lua-cjson \ +# common dependencies + libpython2.7 \ + libdaemon0 \ + libdbus-1-3 \ + libjansson4 + +# ip and ifconfig utility missing in docker for arm arch +RUN apt-get -y install \ + iproute2 \ + net-tools + +RUN mkdir -p /etc/supervisor /var/log/supervisor + +RUN apt-get -y purge \ + exim4 \ + exim4-base \ + exim4-config \ + exim4-daemon-light + +{% if docker_base_buster_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_base_buster_debs.split(' '), "/debs/") }} + +# Install built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_base_buster_debs.split(' ')) }} +{%- endif %} + +# Clean up apt +# Remove /var/lib/apt/lists/*, could be obsoleted for derived images +RUN apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /var/lib/apt/lists/* /tmp/* + +COPY ["etc/rsyslog.conf", "/etc/rsyslog.conf"] +COPY ["etc/rsyslog.d/*", "/etc/rsyslog.d/"] +COPY ["root/.vimrc", "/root/.vimrc"] + +RUN ln /usr/bin/vim.tiny /usr/bin/vim + +COPY ["etc/supervisor/supervisord.conf", "/etc/supervisor/"] diff --git a/dockers/docker-base-buster/LICENSE b/dockers/docker-base-buster/LICENSE new file mode 100644 index 00000000000..03d8f31e513 --- /dev/null +++ b/dockers/docker-base-buster/LICENSE @@ -0,0 +1,13 @@ +Copyright 2016 Microsoft, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/dockers/docker-base-buster/dpkg_01_drop b/dockers/docker-base-buster/dpkg_01_drop new file mode 100644 index 00000000000..d749943797d --- /dev/null +++ b/dockers/docker-base-buster/dpkg_01_drop @@ -0,0 +1,30 @@ +## Drop unnecessary files +## ref: https://wiki.ubuntu.com/ReducingDiskFootprint + +## Documentation +path-exclude /usr/share/doc/* +# we need to keep copyright files for legal reasons +path-include /usr/share/doc/*/copyright +path-exclude /usr/share/man/* +path-exclude /usr/share/groff/* +path-exclude /usr/share/info/* +# lintian stuff is small, but really unnecessary +path-exclude /usr/share/lintian/* +path-exclude /usr/share/linda/* + +## Translations +path-exclude /usr/share/locale/* + +## Landscape +path-exclude /usr/share/pyshared/twisted/test* +path-exclude /usr/lib/python*/dist-packages/twisted/test* +path-exclude /usr/share/pyshared/twisted/*/test* +path-exclude /usr/lib/python*/dist-packages/twisted/*/test* + +## install the configuration file if it’s currently missing +force-confmiss +## combined with confold: overwrite configuration files that you have not modified +force-confdef +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +force-confold + diff --git a/dockers/docker-base-buster/etc/rsyslog.conf b/dockers/docker-base-buster/etc/rsyslog.conf new file mode 100644 index 00000000000..ef249229ab1 --- /dev/null +++ b/dockers/docker-base-buster/etc/rsyslog.conf @@ -0,0 +1,76 @@ +# +# /etc/rsyslog.conf Configuration file for rsyslog. +# +# For more information see +# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html + + +################# +#### MODULES #### +################# + +$ModLoad imuxsock # provides support for local system logging + +# +# Set a rate limit on messages from the container +# +$SystemLogRateLimitInterval 300 +$SystemLogRateLimitBurst 20000 + +#$ModLoad imklog # provides kernel logging support +#$ModLoad immark # provides --MARK-- message capability + +# provides UDP syslog reception +#$ModLoad imudp +#$UDPServerRun 514 + +# provides TCP syslog reception +#$ModLoad imtcp +#$InputTCPServerRun 514 + + +########################### +#### GLOBAL DIRECTIVES #### +########################### + +# Set remote syslog server +template (name="ForwardFormatInContainer" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%") +*.* action(type="omfwd" target="127.0.0.1" port="514" protocol="udp" Template="ForwardFormatInContainer") + +# +# Use traditional timestamp format. +# To enable high precision timestamps, comment out the following line. +# +#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat + +# Define a custom template +$template SONiCFileFormat,"%TIMESTAMP%.%timestamp:::date-subseconds% %HOSTNAME% %syslogseverity-text:::uppercase% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" +$ActionFileDefaultTemplate SONiCFileFormat + +# +# Set the default permissions for all log files. +# +$FileOwner root +$FileGroup adm +$FileCreateMode 0640 +$DirCreateMode 0755 +$Umask 0022 + +# +# Where to place spool and state files +# +$WorkDirectory /var/spool/rsyslog + +# +# Include all config files in /etc/rsyslog.d/ +# +$IncludeConfig /etc/rsyslog.d/*.conf + +# +# Suppress duplicate messages and report "message repeated n times" +# +$RepeatedMsgReduction on + +############### +#### RULES #### +############### diff --git a/dockers/docker-base-buster/etc/rsyslog.d/supervisor.conf b/dockers/docker-base-buster/etc/rsyslog.d/supervisor.conf new file mode 100644 index 00000000000..7c7a64d7afe --- /dev/null +++ b/dockers/docker-base-buster/etc/rsyslog.d/supervisor.conf @@ -0,0 +1,9 @@ +$ModLoad imfile + +$InputFileName /var/log/supervisor/supervisord.log +$InputFileTag supervisord +$InputFileStateFile state-supervisor +$InputFileSeverity info +$InputFileFacility local0 +$InputFilePersistStateInterval 1 +$InputRunFileMonitor diff --git a/dockers/docker-base-buster/etc/supervisor/supervisord.conf b/dockers/docker-base-buster/etc/supervisor/supervisord.conf new file mode 100644 index 00000000000..5d1010e8fa4 --- /dev/null +++ b/dockers/docker-base-buster/etc/supervisor/supervisord.conf @@ -0,0 +1,33 @@ +; supervisor config file + +[unix_http_server] +file=/var/run/supervisor.sock ; (the path to the socket file) +chmod=0700 ; socket file mode (default 0700) +username=dummy +password=dummy + +[supervisord] +logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) +pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) +childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) +user=root + +; the below section must remain in the config file for RPC +; (supervisorctl/web interface) to work, additional interfaces may be +; added by defining them in separate rpcinterface: sections +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisorctl] +serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket +username=dummy +password=dummy + +; The [include] section can just contain the "files" setting. This +; setting can list multiple files (separated by whitespace or +; newlines). It can also contain wildcards. The filenames are +; interpreted as relative to this file. Included files *cannot* +; include files themselves. + +[include] +files = /etc/supervisor/conf.d/*.conf diff --git a/dockers/docker-base-buster/no-check-valid-until b/dockers/docker-base-buster/no-check-valid-until new file mode 100644 index 00000000000..c7c25d017f7 --- /dev/null +++ b/dockers/docker-base-buster/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/dockers/docker-base-buster/no_install_recommend_suggest b/dockers/docker-base-buster/no_install_recommend_suggest new file mode 100644 index 00000000000..b5bca577de1 --- /dev/null +++ b/dockers/docker-base-buster/no_install_recommend_suggest @@ -0,0 +1,5 @@ +# Instruct apt-get to NOT install "recommended" or "suggested" packages by +# default when installing a package. + +APT::Install-Recommends "false"; +APT::Install-Suggests "false"; diff --git a/dockers/docker-base-buster/root/.vimrc b/dockers/docker-base-buster/root/.vimrc new file mode 100644 index 00000000000..5c1ba8a04f4 --- /dev/null +++ b/dockers/docker-base-buster/root/.vimrc @@ -0,0 +1,2 @@ +" enable vim features +set nocompatible diff --git a/dockers/docker-base-buster/sources.list b/dockers/docker-base-buster/sources.list new file mode 100644 index 00000000000..4a94e3161ab --- /dev/null +++ b/dockers/docker-base-buster/sources.list @@ -0,0 +1,8 @@ +## Debian mirror on Microsoft Azure +## Ref: http://debian-archive.trafficmanager.net/ + +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free +deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free +deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ buster/updates main contrib non-free +deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ buster-backports main contrib non-free diff --git a/dockers/docker-base-buster/sources.list.arm64 b/dockers/docker-base-buster/sources.list.arm64 new file mode 100644 index 00000000000..b92971dccea --- /dev/null +++ b/dockers/docker-base-buster/sources.list.arm64 @@ -0,0 +1,7 @@ +## Debian mirror for ARM repo + +# ARM repo +deb [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=arm64] http://deb.debian.org/debian buster main contrib non-free +deb [arch=arm64] http://security.debian.org buster/updates main contrib non-free +deb-src [arch=arm64] http://security.debian.org buster/updates main contrib non-free diff --git a/dockers/docker-base-buster/sources.list.armhf b/dockers/docker-base-buster/sources.list.armhf new file mode 100644 index 00000000000..e28fd605678 --- /dev/null +++ b/dockers/docker-base-buster/sources.list.armhf @@ -0,0 +1,7 @@ +## Debian mirror for ARM repo + +# ARM repo +deb [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb-src [arch=armhf] http://deb.debian.org/debian buster main contrib non-free +deb [arch=armhf] http://security.debian.org buster/updates main contrib non-free +deb-src [arch=armhf] http://security.debian.org buster/updates main contrib non-free diff --git a/dockers/docker-config-engine-buster/Dockerfile.j2 b/dockers/docker-config-engine-buster/Dockerfile.j2 new file mode 100644 index 00000000000..e24414a0fc2 --- /dev/null +++ b/dockers/docker-config-engine-buster/Dockerfile.j2 @@ -0,0 +1,50 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-base-buster + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y \ + # Dependencies for sonic-cfggen + python-lxml \ + python-yaml \ + python-bitarray \ + python-pip \ + python-dev \ + python-natsort \ + apt-utils \ + python-setuptools + +RUN pip install --upgrade pip + +RUN pip install \ + netaddr \ + ipaddr \ + jinja2 \ + pyangbind==0.6.0 + +{% if docker_config_engine_buster_debs.strip() %} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_config_engine_buster_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_config_engine_buster_debs.split(' ')) }} +{% endif %} + +{% if docker_config_engine_buster_whls.strip() %} +# Copy locally-built Python wheel dependencies +{{ copy_files("python-wheels/", docker_config_engine_buster_whls.split(' '), "/python-wheels/") }} + +# Install locally-built Python wheel dependencies +{{ install_python_wheels(docker_config_engine_buster_whls.split(' ')) }} +{% endif %} + +## Clean up +RUN apt-get purge -y \ + python-pip \ + python-dev && \ + apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /debs /python-wheels diff --git a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 index 08c819c1cc1..f581a5bc4b6 100644 --- a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -10,18 +10,12 @@ RUN apt-get update RUN pip install connexion==1.1.15 \ setuptools==21.0.0 \ grpcio-tools==1.20.0 \ - pyangbind==0.6.0 \ certifi==2017.4.17 \ python-dateutil==2.6.0 \ six==1.11.0 \ urllib3==1.21.1 - -## Install redis-tools dependencies -## TODO: implicitly install dependencies -RUN apt-get -y install libjemalloc1 libatomic1 liblua5.1-0 lua-bitop lua-cjson - COPY \ {% for deb in docker_sonic_mgmt_framework_debs.split(' ') -%} debs/{{ deb }}{{' '}} diff --git a/rules/docker-base-buster.dep b/rules/docker-base-buster.dep new file mode 100644 index 00000000000..2cfd2403f7f --- /dev/null +++ b/rules/docker-base-buster.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_BASE_BUSTER)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-base-buster.mk rules/docker-base-buster.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_BASE_BUSTER)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_BASE_BUSTER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_BASE_BUSTER)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-base-buster.mk b/rules/docker-base-buster.mk new file mode 100644 index 00000000000..e1f02d19f30 --- /dev/null +++ b/rules/docker-base-buster.mk @@ -0,0 +1,17 @@ +# Docker base image (based on Debian Buster) + +DOCKER_BASE_BUSTER = docker-base-buster.gz +$(DOCKER_BASE_BUSTER)_PATH = $(DOCKERS_PATH)/docker-base-buster + +$(DOCKER_BASE_BUSTER)_DEPENDS += $(SUPERVISOR) $(REDIS_TOOLS) +$(DOCKER_BASE_BUSTER)_DEPENDS += $(SOCAT) + +GDB = gdb +GDBSERVER = gdbserver +VIM = vim +OPENSSH = openssh-client +SSHPASS = sshpass +STRACE = strace +$(DOCKER_BASE_BUSTER)_DBG_IMAGE_PACKAGES += $(GDB) $(GDBSERVER) $(VIM) $(OPENSSH) $(SSHPASS) $(STRACE) + +SONIC_DOCKER_IMAGES += $(DOCKER_BASE_BUSTER) diff --git a/rules/docker-config-engine-buster.dep b/rules/docker-config-engine-buster.dep new file mode 100644 index 00000000000..ae1ec40ccc9 --- /dev/null +++ b/rules/docker-config-engine-buster.dep @@ -0,0 +1,10 @@ + +DPATH := $($(DOCKER_CONFIG_ENGINE_BUSTER)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-config-engine-buster.mk rules/docker-config-engine-buster.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_CONFIG_ENGINE_BUSTER)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_CONFIG_ENGINE_BUSTER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_CONFIG_ENGINE_BUSTER)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/docker-config-engine-buster.mk b/rules/docker-config-engine-buster.mk new file mode 100644 index 00000000000..cd4703e578a --- /dev/null +++ b/rules/docker-config-engine-buster.mk @@ -0,0 +1,13 @@ +# docker image for sonic config engine + +DOCKER_CONFIG_ENGINE_BUSTER = docker-config-engine-buster.gz +$(DOCKER_CONFIG_ENGINE_BUSTER)_PATH = $(DOCKERS_PATH)/docker-config-engine-buster + +$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SWSSSDK_PY2) +$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +$(DOCKER_CONFIG_ENGINE_BUSTER)_LOAD_DOCKERS += $(DOCKER_BASE_BUSTER) + +$(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS = $($(DOCKER_BASE_BUSTER)_DBG_DEPENDS) +$(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES = $($(DOCKER_BASE_BUSTER)_DBG_IMAGE_PACKAGES) + +SONIC_DOCKER_IMAGES += $(DOCKER_CONFIG_ENGINE_BUSTER) diff --git a/rules/docker-sonic-mgmt-framework.mk b/rules/docker-sonic-mgmt-framework.mk index f07b8d023d2..b0e11c89f51 100644 --- a/rules/docker-sonic-mgmt-framework.mk +++ b/rules/docker-sonic-mgmt-framework.mk @@ -7,22 +7,20 @@ DOCKER_MGMT_FRAMEWORK_DBG = $(DOCKER_MGMT_FRAMEWORK_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_MGMT_FRAMEWORK)_PATH = $(DOCKERS_PATH)/$(DOCKER_MGMT_FRAMEWORK_STEM) $(DOCKER_MGMT_FRAMEWORK)_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK) -$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK_DBG) SONIC_DOCKER_IMAGES += $(DOCKER_MGMT_FRAMEWORK) -$(DOCKER_MGMT_FRAMEWORK)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) -$(DOCKER_MGMT_FRAMEWORK)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_MGMT_FRAMEWORK)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) +$(DOCKER_MGMT_FRAMEWORK)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) ifeq ($(ENABLE_MGMT_FRAMEWORK), y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_MGMT_FRAMEWORK) -SONIC_STRETCH_DOCKERS += $(DOCKER_MGMT_FRAMEWORK) endif SONIC_DOCKER_DBG_IMAGES += $(DOCKER_MGMT_FRAMEWORK_DBG) ifeq ($(ENABLE_MGMT_FRAMEWORK), y) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_MGMT_FRAMEWORK_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_MGMT_FRAMEWORK_DBG) endif $(DOCKER_MGMT_FRAMEWORK)_CONTAINER_NAME = mgmt-framework diff --git a/slave.mk b/slave.mk index 098a5f12f06..eff78eba7da 100644 --- a/slave.mk +++ b/slave.mk @@ -638,15 +638,15 @@ ifeq ($(BLDENV),stretch) STRETCH_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) STRETCH_DBG_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DBG_DOCKERS), $(patsubst %.gz,%-$(DBG_IMAGE_MARK).gz, $(STRETCH_DOCKER_IMAGES))) else - DOCKER_IMAGES := $(SONIC_DOCKER_IMAGES) - DOCKER_DBG_IMAGES := $(SONIC_DOCKER_DBG_IMAGES) + DOCKER_IMAGES = $(filter-out $(SONIC_JESSIE_DOCKERS) $(SONIC_STRETCH_DOCKERS),$(SONIC_DOCKER_IMAGES)) + DOCKER_DBG_IMAGES = $(filter-out $(SONIC_JESSIE_DBG_DOCKERS) $(SONIC_STRETCH_DBG_DOCKERS), $(SONIC_DOCKER_DBG_IMAGES)) endif endif -$(foreach IMAGE,$(SONIC_STRETCH_DOCKERS), $(eval $(IMAGE)_DEBS_PATH := $(STRETCH_DEBS_PATH))) -$(foreach IMAGE,$(SONIC_STRETCH_DOCKERS), $(eval $(IMAGE)_FILES_PATH := $(STRETCH_FILES_PATH))) -$(foreach IMAGE,$(SONIC_STRETCH_DBG_DOCKERS), $(eval $(IMAGE)_DEBS_PATH := $(STRETCH_DEBS_PATH))) -$(foreach IMAGE,$(SONIC_STRETCH_DBG_DOCKERS), $(eval $(IMAGE)_FILES_PATH := $(STRETCH_FILES_PATH))) +$(foreach IMAGE,$(DOCKER_IMAGES), $(eval $(IMAGE)_DEBS_PATH := $(DEBS_PATH))) +$(foreach IMAGE,$(DOCKER_IMAGES), $(eval $(IMAGE)_FILES_PATH := $(FILES_PATH))) +$(foreach IMAGE,$(DOCKER_DBG_IMAGES), $(eval $(IMAGE)_DEBS_PATH := $(DEBS_PATH))) +$(foreach IMAGE,$(DOCKER_DBG_IMAGES), $(eval $(IMAGE)_FILES_PATH := $(FILES_PATH))) # Targets for building docker images $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform docker-start \ From 93ade1d96b167af67adf3cedc818d92b252a3b46 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Tue, 28 Apr 2020 20:32:22 -0700 Subject: [PATCH 23/69] [Multi-ASIC] To pass the asic instance ID to orchagent, Advance the swss, swss-common submodules. (#4465) * Multi-ASIC platforms will have the ID field in the DEVICE_METADATA, which will be pulled and will be used when starting the orchagent process with the new option [-i INST_ID] This is currently added only for Broadcom ASIC based platforms * Making the asic instance ID passing global across asics/platforms. Also changed the config DB id field to asic_id * Minor updates * Advance sonic-swss submodule * Advance swss_common submodule as well due to dependencies --- dockers/docker-orchagent/orchagent.sh | 16 ++++++++++++++++ src/sonic-swss | 2 +- src/sonic-swss-common | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index e4e28a347a3..917205f3ebf 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -17,6 +17,22 @@ ORCHAGENT_ARGS="-d /var/log/swss " # Set orchagent pop batch size to 8192 ORCHAGENT_ARGS+="-b 8192 " +# Check if there is an "asic_id field" in the DEVICE_METADATA in configDB. +#"DEVICE_METADATA": { +# "localhost": { +# .... +# "asic_id": "0", +# } +#}, +# ID field could be integers just to denote the asic instance like 0,1,2... +# OR could be PCI device ID's which will be strings like "03:00.0" +# depending on what the SAI/SDK expects. +asic_id=`sonic-cfggen -d -v DEVICE_METADATA.localhost.asic_id` +if [ -n "$asic_id" ] +then + ORCHAGENT_ARGS+="-i $asic_id " +fi + # Add platform specific arguments if necessary if [ "$platform" == "broadcom" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" diff --git a/src/sonic-swss b/src/sonic-swss index 412c5ebd176..382905381d5 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 412c5ebd1762f94afc51b1129f54a27a53f132bb +Subproject commit 382905381d547a3c050ec23ef9bd611bb2dea67a diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 7ee11792342..6889c0aba53 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 7ee11792342f2673ea6905952d556e3f9a27234d +Subproject commit 6889c0aba53c96c1935374e5a442e12a97941eee From 0895033ee67e9559f2f21e246224d58cd43ea91a Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 29 Apr 2020 00:19:29 -0700 Subject: [PATCH 24/69] [sonic-utilities] Update submodule (#4492) * src/sonic-utilities 798ce2f...7ce5b62 (19): > [utility] Filter FDB entries (#890) > [fast reboot] set a fast-reboot DB flag (#887) > [show] Add 'ip/ipv6 bgp network' commands (#888) > [Vxlan] : adding show vnet/vxlan cmds (#880) > [show][bgp] Use only 'show ip bgp' as the base and use bgp_frr_v4 file for FRR routing stack (#884) > Revert "[config] Implement a process level lock (#857)" (#882) > [generate_dump] Dump systemd specific information (#602) > [config] Implement a process level lock (#857) > [fwutil]: Update Command-Reference.md. (#876) > Add platform options to 'show techsupport' command (#865) > [doc]: add ltgm and jenkins badge (#875) > Fix even more Python warnings (#873) > [showtech]: dump docker stats (#864) > Fix more Python warnings (#869) > Fix Python warnings (#867) > Fixes bug for PFCWD feature parameters (#838) > Explicitly specify command names with underscores (continued) (#852) > [watermarkstat] Fix issue of fields overwritten before display (#862) > [pfc] Add command line to enable/disable/show PFC (#796) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 798ce2fa0b1..7ce5b62404b 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 798ce2fa0b1b9a6e12deaa141c39a92c17b809e8 +Subproject commit 7ce5b62404b150782fd4a275ab3460566fa32a49 From 087e5fbf784593398e110be47d027de2e19af361 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 29 Apr 2020 11:07:08 -0700 Subject: [PATCH 25/69] [build]: build missing stretch dockers when debug build is enabled (#4494) $DOCKER_IMAGES_FOR_INSTALLERS contains all dockers to be included in the image. If INSTALL_DEBUG_TOOLS=y, then it contains debug docker images as well non-debug docker images when there is no debug version of that docker image. $STRETCH_DOCKER_IMAGES will have the non-debug docker images needed by the image. $STRETCH_DBG_DOCKER_IMAGES should contain the debug version of the docker images. Signed-off-by: Guohan Lu --- slave.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slave.mk b/slave.mk index eff78eba7da..f30260157ff 100644 --- a/slave.mk +++ b/slave.mk @@ -630,13 +630,13 @@ ifeq ($(BLDENV),) DOCKER_IMAGES := $(SONIC_JESSIE_DOCKERS) DOCKER_DBG_IMAGES := $(SONIC_JESSIE_DBG_DOCKERS) JESSIE_DOCKER_IMAGES = $(filter $(SONIC_JESSIE_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) - JESSIE_DBG_DOCKER_IMAGES = $(filter $(SONIC_JESSIE_DBG_DOCKERS), $(patsubst %.gz,%-$(DBG_IMAGE_MARK).gz, $(JESSIE_DOCKER_IMAGES))) + JESSIE_DBG_DOCKER_IMAGES = $(filter $(SONIC_JESSIE_DBG_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) else ifeq ($(BLDENV),stretch) DOCKER_IMAGES := $(SONIC_STRETCH_DOCKERS) DOCKER_DBG_IMAGES := $(SONIC_STRETCH_DBG_DOCKERS) STRETCH_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) - STRETCH_DBG_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DBG_DOCKERS), $(patsubst %.gz,%-$(DBG_IMAGE_MARK).gz, $(STRETCH_DOCKER_IMAGES))) + STRETCH_DBG_DOCKER_IMAGES = $(filter $(SONIC_STRETCH_DBG_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_DOCKER_TARGETS)) else DOCKER_IMAGES = $(filter-out $(SONIC_JESSIE_DOCKERS) $(SONIC_STRETCH_DOCKERS),$(SONIC_DOCKER_IMAGES)) DOCKER_DBG_IMAGES = $(filter-out $(SONIC_JESSIE_DBG_DOCKERS) $(SONIC_STRETCH_DBG_DOCKERS), $(SONIC_DOCKER_DBG_IMAGES)) From 4c55adfd6ea3663d885540dadabd2daff57df32c Mon Sep 17 00:00:00 2001 From: jianjundong <47590965+jianjundong@users.noreply.github.com> Date: Thu, 30 Apr 2020 02:10:35 +0800 Subject: [PATCH 26/69] [iccpd]: ICCPD support IPv6 ND (#4422) accomplish it according MCLAG HLD document, the principle is similar to IPv4 ARP. --- src/iccpd/include/iccp_cmd_show.h | 1 + src/iccpd/include/iccp_csm.h | 4 +- src/iccpd/include/iccp_ifm.h | 3 +- src/iccpd/include/iccp_netlink.h | 20 + src/iccpd/include/mlacp_fsm.h | 3 + src/iccpd/include/mlacp_link_handler.h | 12 +- src/iccpd/include/mlacp_sync_prepare.h | 1 + src/iccpd/include/mlacp_sync_update.h | 3 +- src/iccpd/include/mlacp_tlv.h | 27 +- src/iccpd/include/msg_format.h | 3 +- src/iccpd/include/port.h | 3 + src/iccpd/include/system.h | 1 + src/iccpd/src/iccp_cmd_show.c | 68 +++- src/iccpd/src/iccp_ifm.c | 496 +++++++++++++++++------ src/iccpd/src/iccp_netlink.c | 528 +++++++++++++++++++------ src/iccpd/src/mclagdctl/mclagdctl.c | 58 +++ src/iccpd/src/mclagdctl/mclagdctl.h | 12 + src/iccpd/src/mlacp_fsm.c | 92 ++++- src/iccpd/src/mlacp_link_handler.c | 372 ++++++++--------- src/iccpd/src/mlacp_sync_prepare.c | 63 ++- src/iccpd/src/mlacp_sync_update.c | 304 +++++++++++--- src/iccpd/src/port.c | 3 +- src/iccpd/src/scheduler.c | 2 +- src/iccpd/src/system.c | 3 + 24 files changed, 1604 insertions(+), 478 deletions(-) diff --git a/src/iccpd/include/iccp_cmd_show.h b/src/iccpd/include/iccp_cmd_show.h index 0fedca7cddd..a41fbadf8c7 100644 --- a/src/iccpd/include/iccp_cmd_show.h +++ b/src/iccpd/include/iccp_cmd_show.h @@ -29,6 +29,7 @@ extern int iccp_mclag_config_dump(char * *buf, int *num, int mclag_id); extern int iccp_arp_dump(char * *buf, int *num, int mclag_id); +extern int iccp_ndisc_dump(char * *buf, int *num, int mclag_id); extern int iccp_mac_dump(char * *buf, int *num, int mclag_id); extern int iccp_local_if_dump(char * *buf, int *num, int mclag_id); extern int iccp_peer_if_dump(char * *buf, int *num, int mclag_id); diff --git a/src/iccpd/include/iccp_csm.h b/src/iccpd/include/iccp_csm.h index 9cf1022dd10..96e36637193 100644 --- a/src/iccpd/include/iccp_csm.h +++ b/src/iccpd/include/iccp_csm.h @@ -45,7 +45,9 @@ #ifndef INET_ADDRSTRLEN #define INET_ADDRSTRLEN 16 #endif /* INET_ADDRSTRLEN */ - +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN 46 +#endif /* INET6_ADDRSTRLEN */ /* For socket binding */ #define ICCP_TCP_PORT 8888 #define MAX_ACCEPT_CONNETIONS 20 diff --git a/src/iccpd/include/iccp_ifm.h b/src/iccpd/include/iccp_ifm.h index 7fbb1a8cf4f..bbb1af67ee9 100644 --- a/src/iccpd/include/iccp_ifm.h +++ b/src/iccpd/include/iccp_ifm.h @@ -28,9 +28,10 @@ int iccp_sys_local_if_list_get_init(); -int iccp_arp_get_init(); +int iccp_neigh_get_init(); void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, uint8_t mac_addr[ETHER_ADDR_LEN]); +void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, uint8_t mac_addr[ETHER_ADDR_LEN]); int do_one_neigh_request(struct nlmsghdr *n); diff --git a/src/iccpd/include/iccp_netlink.h b/src/iccpd/include/iccp_netlink.h index 612a1859591..a4f321736d0 100644 --- a/src/iccpd/include/iccp_netlink.h +++ b/src/iccpd/include/iccp_netlink.h @@ -31,6 +31,25 @@ #include "../include/system.h" #include "../include/port.h" +#include +#include + +#define NDISC_NEIGHBOUR_ADVERTISEMENT 136 +#define ND_OPT_TARGET_LL_ADDR 2 +#define NEXTHDR_ICMP 58 + +struct nd_msg +{ + struct icmp6_hdr icmph; + struct in6_addr target; + __u8 opt[0]; +}; + +struct in6_pktinfo +{ + struct in6_addr ipi6_addr; /* src/dst IPv6 address */ + unsigned int ipi6_ifindex; /* send/recv interface index */ +}; int iccp_get_port_member_list(struct LocalInterface* lif); void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg); @@ -41,6 +60,7 @@ int iccp_init_netlink_event_fd(struct System *sys); int iccp_handle_events(struct System * sys); void update_if_ipmac_on_standby(struct LocalInterface* lif_po); int iccp_sys_local_if_list_get_addr(); +int iccp_netlink_neighbor_request(int family, uint8_t *addr, int add, uint8_t *mac, char *portname); int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInterface *lif); #endif diff --git a/src/iccpd/include/mlacp_fsm.h b/src/iccpd/include/mlacp_fsm.h index 6442d9ff560..b335e78cd00 100644 --- a/src/iccpd/include/mlacp_fsm.h +++ b/src/iccpd/include/mlacp_fsm.h @@ -53,6 +53,7 @@ enum MLACP_SYNC_STATE MLACP_SYNC_AGGINFO, MLACP_SYNC_PEERLINKINFO, MLACP_SYNC_ARP_INFO, + MLACP_SYNC_NDISC_INFO, MLACP_SYNC_DONE, }; @@ -85,6 +86,8 @@ struct mLACP TAILQ_HEAD(mlacp_msg_list, Msg) mlacp_msg_list; TAILQ_HEAD(arp_msg_list, Msg) arp_msg_list; TAILQ_HEAD(arp_info_list, Msg) arp_list; + TAILQ_HEAD(ndisc_msg_list, Msg) ndisc_msg_list; + TAILQ_HEAD(ndisc_info_list, Msg) ndisc_list; TAILQ_HEAD(mac_msg_list, Msg) mac_msg_list; TAILQ_HEAD(mac_info_list, Msg) mac_list; diff --git a/src/iccpd/include/mlacp_link_handler.h b/src/iccpd/include/mlacp_link_handler.h index 55892d1861c..624b4111a7e 100644 --- a/src/iccpd/include/mlacp_link_handler.h +++ b/src/iccpd/include/mlacp_link_handler.h @@ -43,17 +43,17 @@ void set_peerlink_mlag_port_learn(struct LocalInterface *lif, int enable); void peerlink_port_isolate_cleanup(struct CSM* csm); void update_peerlink_isolate_from_all_csm_lif(struct CSM* csm); -int mlacp_fsm_arp_set(char *ifname, uint32_t ip, char *mac); -int mlacp_fsm_arp_del(char *ifname, uint32_t ip); -void del_mac_from_chip(struct MACMsg* mac_msg); -void add_mac_to_chip(struct MACMsg* mac_msg, uint8_t mac_type); -uint8_t set_mac_local_age_flag(struct CSM *csm, struct MACMsg* mac_msg, uint8_t set ); -void iccp_get_fdb_change_from_syncd( void); +void del_mac_from_chip(struct MACMsg *mac_msg); +void add_mac_to_chip(struct MACMsg *mac_msg, uint8_t mac_type); +uint8_t set_mac_local_age_flag(struct CSM *csm, struct MACMsg *mac_msg, uint8_t set); +void iccp_get_fdb_change_from_syncd(void); extern int mclagd_ctl_sock_create(); extern int mclagd_ctl_sock_accept(int fd); extern int mclagd_ctl_interactive_process(int client_fd); +extern int parseMacString(const char *str_mac, uint8_t *bin_mac); char *show_ip_str(uint32_t ipv4_addr); +char *show_ipv6_str(char *ipv6_addr); void syncd_info_close(); int iccp_connect_syncd(); diff --git a/src/iccpd/include/mlacp_sync_prepare.h b/src/iccpd/include/mlacp_sync_prepare.h index f4ea7a419f5..17cd8f26015 100644 --- a/src/iccpd/include/mlacp_sync_prepare.h +++ b/src/iccpd/include/mlacp_sync_prepare.h @@ -46,6 +46,7 @@ int mlacp_prepare_for_sync_data_tlv(struct CSM* csm, char* buf, size_t max_buf_s int mlacp_prepare_for_sys_config(struct CSM* csm, char* buf, size_t max_buf_size); int mlacp_prepare_for_mac_info_to_peer(struct CSM* csm, char* buf, size_t max_buf_size, struct MACMsg* mac_msg, int count); int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, struct ARPMsg* arp_msg, int count); +int mlacp_prepare_for_ndisc_info(struct CSM *csm, char *buf, size_t max_buf_size, struct NDISCMsg *ndisc_msg, int count); int mlacp_prepare_for_heartbeat(struct CSM* csm, char* buf, size_t max_buf_size); int mlacp_prepare_for_Aggport_state(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* local_if); int mlacp_prepare_for_Aggport_config(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* lif, int purge_flag); diff --git a/src/iccpd/include/mlacp_sync_update.h b/src/iccpd/include/mlacp_sync_update.h index d42abe216af..2a5d5b598d0 100644 --- a/src/iccpd/include/mlacp_sync_update.h +++ b/src/iccpd/include/mlacp_sync_update.h @@ -36,12 +36,13 @@ int mlacp_fsm_update_system_conf(struct CSM* csm, mLACPSysConfigTLV* tlv); int mlacp_fsm_update_Aggport_state(struct CSM* csm, mLACPAggPortStateTLV* tlv); int mlacp_fsm_update_arp_info(struct CSM* csm, struct mLACPARPInfoTLV* tlv); +int mlacp_fsm_update_ndisc_info(struct CSM *csm, struct mLACPNDISCInfoTLV* tlv); int mlacp_fsm_update_heartbeat(struct CSM* csm, struct mLACPHeartbeatTLV* tlv); int mlacp_fsm_update_warmboot(struct CSM* csm, struct mLACPWarmbootTLV* tlv); void mlacp_enqueue_arp(struct CSM* csm, struct Msg* msg); - +void mlacp_enqueue_ndisc(struct CSM *csm, struct Msg* msg); int mlacp_fsm_update_Agg_conf(struct CSM* csm, mLACPAggConfigTLV* portconf); int mlacp_fsm_update_port_channel_info(struct CSM* csm, struct mLACPPortChannelInfoTLV* tlv); int mlacp_fsm_update_peerlink_info(struct CSM* csm, struct mLACPPeerLinkInfoTLV* tlv); diff --git a/src/iccpd/include/mlacp_tlv.h b/src/iccpd/include/mlacp_tlv.h index 86bce2e0e94..7d3a4e18e4e 100644 --- a/src/iccpd/include/mlacp_tlv.h +++ b/src/iccpd/include/mlacp_tlv.h @@ -374,6 +374,14 @@ struct ARPMsg uint8_t mac_addr[ETHER_ADDR_LEN]; }; +struct NDISCMsg +{ + uint8_t op_type; + char ifname[MAX_L_PORT_NAME]; + uint32_t ipv6_addr[4]; + uint8_t mac_addr[ETHER_ADDR_LEN]; +}; + /* * ARP Information TLV */ @@ -385,6 +393,17 @@ struct mLACPARPInfoTLV struct ARPMsg ArpEntry[0]; } __attribute__ ((packed)); +/* + * NDISC Information TLV + */ +struct mLACPNDISCInfoTLV +{ + ICCParameter icc_parameter; + /* Local Interface ID */ + uint16_t num_of_entry; + struct NDISCMsg NdiscEntry[0]; +} __attribute__ ((packed)); + /* * NOS: STP Information TLV */ @@ -413,11 +432,11 @@ struct mLACPWarmbootTLV uint8_t warmboot; } __attribute__ ((packed)); -enum ARP_OP_TYPE +enum NEIGH_OP_TYPE { - ARP_SYNC_LIF, - ARP_SYNC_ADD, - ARP_SYNC_DEL, + NEIGH_SYNC_LIF, + NEIGH_SYNC_ADD, + NEIGH_SYNC_DEL, }; enum MAC_AGE_TYPE diff --git a/src/iccpd/include/msg_format.h b/src/iccpd/include/msg_format.h index 5f4deb18772..1af8bf8a46a 100644 --- a/src/iccpd/include/msg_format.h +++ b/src/iccpd/include/msg_format.h @@ -98,7 +98,8 @@ #define TLV_T_MLACP_STP_INFO 0x1037//no support #define TLV_T_MLACP_MAC_INFO 0x1038 #define TLV_T_MLACP_WARMBOOT_FLAG 0x1039 -#define TLV_T_MLACP_LIST_END 0x104a //list end +#define TLV_T_MLACP_NDISC_INFO 0x103A +#define TLV_T_MLACP_LIST_END 0x104a // list end /* Debug */ static char* get_tlv_type_string(int type) diff --git a/src/iccpd/include/port.h b/src/iccpd/include/port.h index bdcaf66a68a..dbd9d45fa83 100644 --- a/src/iccpd/include/port.h +++ b/src/iccpd/include/port.h @@ -102,6 +102,8 @@ struct LocalInterface uint8_t state; uint32_t ipv4_addr; uint8_t prefixlen; + uint32_t ipv6_addr[4]; + uint8_t prefixlen_v6; uint8_t l3_mode; uint8_t l3_mac_addr[ETHER_ADDR_LEN]; @@ -139,6 +141,7 @@ int local_if_is_l3_mode(struct LocalInterface* local_if); void local_if_init(struct LocalInterface*); void local_if_finalize(struct LocalInterface*); +void ether_mac_set_addr_with_if_name(char *name, uint8_t* mac); struct PeerInterface* peer_if_create(struct CSM* csm, int peer_if_number, int type); struct PeerInterface* peer_if_find_by_name(struct CSM* csm, char* name); diff --git a/src/iccpd/include/system.h b/src/iccpd/include/system.h index bb89dbb2f3c..3ee314d253a 100644 --- a/src/iccpd/include/system.h +++ b/src/iccpd/include/system.h @@ -58,6 +58,7 @@ struct System int sync_fd; int sync_ctrl_fd; int arp_receive_fd; + int ndisc_receive_fd; int epoll_fd; struct nl_sock * genric_sock; diff --git a/src/iccpd/src/iccp_cmd_show.c b/src/iccpd/src/iccp_cmd_show.c index e25a653e74b..b0a60fb5f49 100644 --- a/src/iccpd/src/iccp_cmd_show.c +++ b/src/iccpd/src/iccp_cmd_show.c @@ -177,7 +177,7 @@ int iccp_arp_dump(char * *buf, int *num, int mclag_id) mclagd_arp.op_type = iccpd_arp->op_type; memcpy(mclagd_arp.ifname, iccpd_arp->ifname, strlen(iccpd_arp->ifname)); - memcpy(mclagd_arp.ipv4_addr, show_ip_str(htonl(iccpd_arp->ipv4_addr)), 16); + memcpy(mclagd_arp.ipv4_addr, show_ip_str(iccpd_arp->ipv4_addr), 16); memcpy(mclagd_arp.mac_addr, iccpd_arp->mac_addr, 6); memcpy(arp_buf + MCLAGD_REPLY_INFO_HDR + arp_num * sizeof(struct mclagd_arp_msg), @@ -204,6 +204,72 @@ int iccp_arp_dump(char * *buf, int *num, int mclag_id) return EXEC_TYPE_SUCCESS; } +int iccp_ndisc_dump(char * *buf, int *num, int mclag_id) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct NDISCMsg *iccpd_ndisc = NULL; + struct mclagd_ndisc_msg mclagd_ndisc; + int ndisc_num = 0; + int id_exist = 0; + char *ndisc_buf = NULL; + int ndisc_buf_size = MCLAGDCTL_CMD_SIZE; + + if (!(sys = system_get_instance())) + { + ICCPD_LOG_INFO(__FUNCTION__, "cannot find sys!\n"); + return EXEC_TYPE_NO_EXIST_SYS; + } + + ndisc_buf = (char *)malloc(ndisc_buf_size); + if (!ndisc_buf) + return EXEC_TYPE_FAILED; + + LIST_FOREACH(csm, &(sys->csm_list), next) + { + if (mclag_id > 0) + { + if (csm->mlag_id == mclag_id) + id_exist = 1; + else + continue; + } + + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + memset(&mclagd_ndisc, 0, sizeof(struct mclagd_ndisc_msg)); + iccpd_ndisc = (struct NDISCMsg *)msg->buf; + + mclagd_ndisc.op_type = iccpd_ndisc->op_type; + memcpy(mclagd_ndisc.ifname, iccpd_ndisc->ifname, strlen(iccpd_ndisc->ifname)); + memcpy(mclagd_ndisc.ipv6_addr, show_ipv6_str((char *)iccpd_ndisc->ipv6_addr), 46); + memcpy(mclagd_ndisc.mac_addr, iccpd_ndisc->mac_addr, 6); + + memcpy(ndisc_buf + MCLAGD_REPLY_INFO_HDR + ndisc_num * sizeof(struct mclagd_ndisc_msg), + &mclagd_ndisc, sizeof(struct mclagd_ndisc_msg)); + + ndisc_num++; + + if ((ndisc_num + 1) * sizeof(struct mclagd_ndisc_msg) > (ndisc_buf_size - MCLAGD_REPLY_INFO_HDR)) + { + ndisc_buf_size += MCLAGDCTL_CMD_SIZE; + ndisc_buf = (char *)realloc(ndisc_buf, ndisc_buf_size); + if (!ndisc_buf) + return EXEC_TYPE_FAILED; + } + } + } + + *buf = ndisc_buf; + *num = ndisc_num; + + if (mclag_id > 0 && !id_exist) + return EXEC_TYPE_NO_EXIST_MCLAGID; + + return EXEC_TYPE_SUCCESS; +} + int iccp_mac_dump(char * *buf, int *num, int mclag_id) { struct System *sys = NULL; diff --git a/src/iccpd/src/iccp_ifm.c b/src/iccpd/src/iccp_ifm.c index cf874366b97..5cfbfe81ffd 100644 --- a/src/iccpd/src/iccp_ifm.c +++ b/src/iccpd/src/iccp_ifm.c @@ -137,34 +137,21 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int memset(buf, 0, MAX_BUFSIZE); msg_len = sizeof(struct ARPMsg); arp_msg = (struct ARPMsg*)&buf; - arp_msg->op_type = ARP_SYNC_LIF; + arp_msg->op_type = NEIGH_SYNC_LIF; sprintf(arp_msg->ifname, "%s", arp_lif->name); if (tb[NDA_DST]) memcpy(&arp_msg->ipv4_addr, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); if (tb[NDA_LLADDR]) memcpy(arp_msg->mac_addr, RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR])); - arp_msg->ipv4_addr = ntohl(arp_msg->ipv4_addr); + arp_msg->ipv4_addr = arp_msg->ipv4_addr; - ICCPD_LOG_DEBUG(__FUNCTION__, "ARP type %s, state (%04X)(%d) ifindex [%d] (%s) ip %s, mac [%02X:%02X:%02X:%02X:%02X:%02X]", + ICCPD_LOG_NOTICE(__FUNCTION__, "ARP type %s, state (%04X)(%d) ifindex [%d] (%s) ip %s, mac [%02X:%02X:%02X:%02X:%02X:%02X]", msgtype == RTM_NEWNEIGH ? "New":"Del", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state), ndm->ndm_ifindex, arp_lif->name, - show_ip_str(htonl(arp_msg->ipv4_addr)), - arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]); - - /*Debug*/ - #if 0 - /* dump receive kernel ARP req*/ - fprintf(stderr, "\n======== Kernel ARP ==========\n"); - fprintf(stderr, " Type = [%d] (New=%d, Del=%d)\n", msgtype, RTM_NEWNEIGH, RTM_DELNEIGH); - fprintf(stderr, " State = (%04X)(%d)\n", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state)); - fprintf(stderr, " ifindex = [%d] (%s)\n", ndm->ndm_ifindex, arp_msg->ifname); - fprintf(stderr, " IP = [%s]\n", show_ip_str(htonl(arp_msg->ipv4_addr))); - fprintf(stderr, " MAC = [%02X:%02X:%02X:%02X:%02X:%02X]\n", - arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], - arp_msg->mac_addr[4], arp_msg->mac_addr[5]); - fprintf(stderr, "==============================\n"); - #endif + show_ip_str(arp_msg->ipv4_addr), + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], + arp_msg->mac_addr[5]); /* Find MLACP itf, member of port-channel*/ LIST_FOREACH(csm, &(sys->csm_list), next) @@ -228,7 +215,7 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int free(msg->buf); free(msg); msg = NULL; - ICCPD_LOG_DEBUG(__FUNCTION__, "Delete ARP %s", show_ip_str(htonl(arp_msg->ipv4_addr))); + ICCPD_LOG_DEBUG(__FUNCTION__, "Delete ARP %s", show_ip_str(arp_msg->ipv4_addr)); } else { @@ -242,7 +229,7 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int arp_info->op_type = arp_msg->op_type; sprintf(arp_info->ifname, "%s", arp_msg->ifname); memcpy(arp_info->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN); - ICCPD_LOG_DEBUG(__FUNCTION__, "Update ARP for %s", show_ip_str(htonl(arp_msg->ipv4_addr))); + ICCPD_LOG_DEBUG(__FUNCTION__, "Update ARP for %s", show_ip_str(arp_msg->ipv4_addr)); } } break; @@ -256,31 +243,31 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int /* enquene lif_msg (add)*/ if (!msg) { - arp_msg->op_type = ARP_SYNC_LIF; + arp_msg->op_type = NEIGH_SYNC_LIF; if (iccp_csm_init_msg(&msg, (char*)arp_msg, msg_len) == 0) { mlacp_enqueue_arp(csm, msg); /*ICCPD_LOG_DEBUG(__FUNCTION__, "ARP-list enqueue: %s, add %s", - arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + arp_msg->ifname, show_ip_str(arp_msg->ipv4_addr));*/ } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP-list: %s, add %s", - arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr))); + arp_msg->ifname, show_ip_str(arp_msg->ipv4_addr)); } /* enqueue iccp_msg (add)*/ if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) { - arp_msg->op_type = ARP_SYNC_ADD; + arp_msg->op_type = NEIGH_SYNC_ADD; if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0) { TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[ADD] message for %s", - show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] message for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + show_ip_str(arp_msg->ipv4_addr)); } } @@ -289,58 +276,218 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int /* enqueue iccp_msg (delete)*/ if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) { - arp_msg->op_type = ARP_SYNC_DEL; + arp_msg->op_type = NEIGH_SYNC_DEL; if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0) { TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[DEL] message for %s", - show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[DEL] message for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + show_ip_str(arp_msg->ipv4_addr)); } } - /*Debug: dump for dequeue ARP Info*/ - #if 0 - fprintf(stderr, "\n======== ARP Info List ========\n"); - TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + return; +} + +static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int msgtype) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL, *ndisc_info = NULL; + struct VLAN_ID *vlan_id_list = NULL; + struct Msg *msg_send = NULL; + + char buf[MAX_BUFSIZE]; + size_t msg_len = 0; + + struct LocalInterface *lif_po = NULL, *ndisc_lif = NULL; + + int verify_neigh = 0; + int neigh_update = 0; + + if (!(sys = system_get_instance())) + return; + + /* Find local itf */ + if (!(ndisc_lif = local_if_find_by_ifindex(ndm->ndm_ifindex))) + return; + + /* create NDISC msg */ + memset(buf, 0, MAX_BUFSIZE); + msg_len = sizeof(struct NDISCMsg); + ndisc_msg = (struct NDISCMsg *)&buf; + ndisc_msg->op_type = NEIGH_SYNC_LIF; + sprintf(ndisc_msg->ifname, "%s", ndisc_lif->name); + if (tb[NDA_DST]) + memcpy(&ndisc_msg->ipv6_addr, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); + if (tb[NDA_LLADDR]) + memcpy(ndisc_msg->mac_addr, RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR])); + + ICCPD_LOG_NOTICE(__FUNCTION__, "ndisc type %s, state (%04X)(%d), ifindex [%d] (%s), ip %s, mac [%02X:%02X:%02X:%02X:%02X:%02X]", + msgtype == RTM_NEWNEIGH ? "New" : "Del", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state), + ndm->ndm_ifindex, ndisc_lif->name, + show_ipv6_str((char *)ndisc_msg->ipv6_addr), + ndisc_msg->mac_addr[0], ndisc_msg->mac_addr[1], ndisc_msg->mac_addr[2], ndisc_msg->mac_addr[3], ndisc_msg->mac_addr[4], + ndisc_msg->mac_addr[5]); + + /* Find MLACP itf, member of port-channel */ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type != IF_T_PORT_CHANNEL) + continue; + + if (!local_if_is_l3_mode(lif_po)) + { + /* Is the L2 MLAG itf belong to a vlan? */ + LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next) + { + if (!(vlan_id_list->vlan_itf && vlan_id_list->vlan_itf->ifindex == ndm->ndm_ifindex)) + continue; + break; + } + + if (!vlan_id_list) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled member port of vlan %s", vlan_id_list->vlan_itf->name); + } + else + { + /* Is the ND belong to a L3 mode MLAG itf? */ + if (ndm->ndm_ifindex != lif_po->ifindex) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled intf %s", lif_po->name); + } + + verify_neigh = 1; + + break; + } + + if (lif_po) + break; + } + + if (!(csm && lif_po)) + return; + if (!verify_neigh) + return; + + /* update lif ND */ + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) { - arp_msg = (struct ARPMsg*)msg->buf; - fprintf(stderr, "type %d,ifname %s , ip %s\n", arp_msg->op_type, arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr))); + ndisc_info = (struct NDISCMsg *)msg->buf; + + if (memcmp(&ndisc_info->ipv6_addr, &ndisc_msg->ipv6_addr, 16) != 0) + continue; + + if (msgtype == RTM_DELNEIGH) + { + /* delete ND */ + TAILQ_REMOVE(&MLACP(csm).ndisc_list, msg, tail); + free(msg->buf); + free(msg); + msg = NULL; + ICCPD_LOG_DEBUG(__FUNCTION__, "Delete neighbor %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + else + { + /* update ND */ + if (ndisc_info->op_type != ndisc_info->op_type + || strcmp(ndisc_info->ifname, ndisc_info->ifname) != 0 + || memcmp(ndisc_info->mac_addr, ndisc_info->mac_addr, ETHER_ADDR_LEN) != 0) + { + neigh_update = 1; + ndisc_info->op_type = ndisc_msg->op_type; + sprintf(ndisc_info->ifname, "%s", ndisc_msg->ifname); + memcpy(ndisc_info->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN); + ICCPD_LOG_DEBUG(__FUNCTION__, "Update neighbor for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + } + break; } - fprintf(stderr, "==============================\n"); - #endif - /*TEST dump for dequeue ARP message*/ - #if 0 + if (msg && !neigh_update) + return; - while (MLACP(csm).arp_updated && !TAILQ_EMPTY(&(MLACP(csm).arp_msg_list))) + if (msgtype != RTM_DELNEIGH) { - msg = TAILQ_FIRST(&(MLACP(csm).arp_msg_list)); - TAILQ_REMOVE(&(MLACP(csm).arp_msg_list), msg, tail); - arp_msg = (struct ARPMsg *)msg->buf; - fprintf(stderr, "\n======== Dequeue ARP ========\n"); - fprintf(stderr, " Type = [%d]\n", arp_msg->op_type); - fprintf(stderr, " State = (%04X)(%d)\n", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state)); - fprintf(stderr, " ifname = [%s]\n", arp_msg->ifname); - fprintf(stderr, " IP = [%s]\n", show_ip_str(arp_msg->ipv4_addr)); - fprintf(stderr, " MAC = [%02X:%02X:%02X:%02X:%02X:%02X]\n", - arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], - arp_msg->mac_addr[4], arp_msg->mac_addr[5]); - fprintf(stderr, "==============================\n"); - free(msg->buf); - free(msg); + /* enquene lif_msg (add) */ + if (!msg) + { + ndisc_msg->op_type = NEIGH_SYNC_LIF; + if (iccp_csm_init_msg(&msg, (char *)ndisc_msg, msg_len) == 0) + { + mlacp_enqueue_ndisc(csm, msg); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Ndisc-list enqueue: %s, add %s", ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue Ndisc-list: %s, add %s", + ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + + /* enqueue iccp_msg (add) */ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + ndisc_msg->op_type = NEIGH_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue Ndisc[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue Ndisc[ADD] message for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + + } } + else + { + /* enqueue iccp_msg (delete) */ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + ndisc_msg->op_type = NEIGH_SYNC_DEL; + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue Ndisc[DEL] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue Ndisc[DEL] message for [%x:%x:%x:%x]", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); - MLACP(csm).arp_updated = 0; - #endif + } + } return; } +int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta, int len, unsigned short flags) +{ + unsigned short type; + + memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); + while (RTA_OK(rta, len)) + { + type = rta->rta_type & ~flags; + if ((type <= max) && (!tb[type])) + tb[type] = rta; + rta = RTA_NEXT(rta, len); + } + return 0; +} + +int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) +{ + return parse_rtattr_flags(tb, max, rta, len, 0); +} + void ifm_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, int len) { while (RTA_OK(rta, len)) @@ -392,11 +539,14 @@ int do_one_neigh_request(struct nlmsghdr *n) do_arp_learn_from_kernel(ndm, tb, n->nlmsg_type); } + if (ndm->ndm_family == AF_INET6) + { + do_ndisc_learn_from_kernel(ndm, tb, n->nlmsg_type); + } return(0); } -/*Handle arp received from kernel*/ -static int iccp_arp_valid_handler(struct nl_msg *msg, void *arg) +static int iccp_neigh_valid_handler(struct nl_msg *msg, void *arg) { struct nlmsghdr *nlh = nlmsg_hdr(msg); @@ -405,8 +555,7 @@ static int iccp_arp_valid_handler(struct nl_msg *msg, void *arg) return 0; } -/*Get kernel arp information during initialization*/ -int iccp_arp_get_init() +int iccp_neigh_get_init() { struct System *sys = NULL; struct nl_cb *cb; @@ -440,7 +589,7 @@ int iccp_arp_get_init() return -ENOMEM; } - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_arp_valid_handler, sys); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_neigh_valid_handler, sys); ret = nl_recvmsgs(sys->route_sock, cb); nl_cb_put(cb); @@ -485,27 +634,16 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui memset(buf, 0, MAX_BUFSIZE); msg_len = sizeof(struct ARPMsg); arp_msg = (struct ARPMsg*)&buf; - arp_msg->op_type = ARP_SYNC_LIF; + arp_msg->op_type = NEIGH_SYNC_LIF; sprintf(arp_msg->ifname, "%s", arp_lif->name); memcpy(&arp_msg->ipv4_addr, &addr, 4); memcpy(arp_msg->mac_addr, mac_addr, 6); ICCPD_LOG_DEBUG(__FUNCTION__, "ARP ifindex [%d] (%s) ip %s mac [%02X:%02X:%02X:%02X:%02X:%02X]", ifindex, arp_lif->name, - show_ip_str(htonl(arp_msg->ipv4_addr)), - arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]); - /*Debug*/ - #if 0 - /* dump receive kernel ARP req*/ - fprintf(stderr, "\n======== Kernel ARP Update==========\n"); - fprintf(stderr, " Type = (New=%d)\n", RTM_NEWNEIGH); - fprintf(stderr, " ifindex = [%d] (%s)\n", ifindex, arp_lif->name); - fprintf(stderr, " IP = [%s]\n", show_ip_str(htonl(arp_msg->ipv4_addr))); - fprintf(stderr, " MAC = [%02X:%02X:%02X:%02X:%02X:%02X]\n", - arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], - arp_msg->mac_addr[4], arp_msg->mac_addr[5]); - fprintf(stderr, "==============================\n"); - #endif + show_ip_str(arp_msg->ipv4_addr), + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], + arp_msg->mac_addr[5]); /* Find MLACP itf, member of port-channel*/ LIST_FOREACH(csm, &(sys->csm_list), next) @@ -556,7 +694,7 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui if (iccp_check_if_addr_from_netlink(AF_INET, &addr, arp_lif)) { ICCPD_LOG_DEBUG(__FUNCTION__, "ARP %s is identical with the ip address of interface %s", - show_ip_str(htonl(arp_msg->ipv4_addr)), arp_lif->name); + show_ip_str(arp_msg->ipv4_addr), arp_lif->name); return; } @@ -576,8 +714,9 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui arp_info->op_type = arp_msg->op_type; sprintf(arp_info->ifname, "%s", arp_msg->ifname); memcpy(arp_info->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN); - ICCPD_LOG_DEBUG(__FUNCTION__, "Update ARP for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + ICCPD_LOG_NOTICE(__FUNCTION__, "Update ARP for %s by ARP reply, intf %s mac [%02X:%02X:%02X:%02X:%02X:%02X]", + show_ip_str(arp_msg->ipv4_addr), arp_msg->ifname, + arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]); } break; } @@ -585,36 +724,196 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui /* enquene lif_msg (add)*/ if (!msg) { - arp_msg->op_type = ARP_SYNC_LIF; + arp_msg->op_type = NEIGH_SYNC_LIF; if (iccp_csm_init_msg(&msg, (char*)arp_msg, msg_len) == 0) { mlacp_enqueue_arp(csm, msg); /*ICCPD_LOG_DEBUG(__FUNCTION__, "ARP-list enqueue: %s, add %s", - arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + arp_msg->ifname, show_ip_str(arp_msg->ipv4_addr));*/ } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP-list: %s, add %s", - arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr))); + arp_msg->ifname, show_ip_str(arp_msg->ipv4_addr)); } /* enqueue iccp_msg (add)*/ if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) { - arp_msg->op_type = ARP_SYNC_ADD; + arp_msg->op_type = NEIGH_SYNC_ADD; if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0) { TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[ADD] for %s", - show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] message for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + show_ip_str(arp_msg->ipv4_addr)); } return; } +void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, uint8_t mac_addr[ETHER_ADDR_LEN]) +{ + struct System *sys = NULL; + struct CSM *csm = NULL; + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL, *ndisc_info = NULL; + struct VLAN_ID *vlan_id_list = NULL; + struct Msg *msg_send = NULL; + char mac_str[18] = ""; + uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + char buf[MAX_BUFSIZE]; + size_t msg_len = 0; + + struct LocalInterface *lif_po = NULL, *ndisc_lif = NULL; + + int verify_ndisc = 0; + + if (!(sys = system_get_instance())) + return; + + /* Find local itf */ + if (!(ndisc_lif = local_if_find_by_ifindex(ifindex))) + return; + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); + + /* create Ndisc msg */ + memset(buf, 0, MAX_BUFSIZE); + msg_len = sizeof(struct NDISCMsg); + ndisc_msg = (struct NDISCMsg *)&buf; + ndisc_msg->op_type = NEIGH_SYNC_LIF; + sprintf(ndisc_msg->ifname, "%s", ndisc_lif->name); + memcpy((char *)ndisc_msg->ipv6_addr, ipv6_addr, 16); + memcpy(ndisc_msg->mac_addr, mac_addr, ETHER_ADDR_LEN); + + ICCPD_LOG_DEBUG(__FUNCTION__, "nd ifindex [%d] (%s) ip %s mac %s", + ifindex, ndisc_lif->name, show_ipv6_str(ipv6_addr), mac_str); + + /* Find MLACP itf, member of port-channel */ + LIST_FOREACH(csm, &(sys->csm_list), next) + { + LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next) + { + if (lif_po->type != IF_T_PORT_CHANNEL) + continue; + + if (!local_if_is_l3_mode(lif_po)) + { + /* Is the L2 MLAG itf belong to a vlan? */ + LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next) + { + if (!(vlan_id_list->vlan_itf && vlan_id_list->vlan_itf->ifindex == ifindex)) + continue; + break; + } + + if (!vlan_id_list) + continue; + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled port %s of vlan %s", lif_po->name, vlan_id_list->vlan_itf->name); + } + else + { + /* Is the ND belong to a L3 mode MLAG itf? */ + if (ifindex != lif_po->ifindex) + continue; + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled port %s", lif_po->name); + } + + verify_ndisc = 1; + + break; + } + + if (lif_po) + break; + } + + if (!(csm && lif_po)) + return; + if (!verify_ndisc) + return; + + if (iccp_check_if_addr_from_netlink(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, ndisc_lif)) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "NA %s is identical with the ipv6 address of interface %s", + show_ipv6_str((char *)ndisc_msg->ipv6_addr), ndisc_lif->name); + return; + } + + /* update lif ND */ + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + ndisc_info = (struct NDISCMsg *)msg->buf; + + if (memcmp((char *)ndisc_info->ipv6_addr, (char *)ndisc_msg->ipv6_addr, 16) != 0) + continue; + + /* If MAC addr is NULL, use the old one */ + if (memcmp(mac_addr, null_mac, ETHER_ADDR_LEN) == 0) + { + memcpy(ndisc_msg->mac_addr, ndisc_info->mac_addr, ETHER_ADDR_LEN); + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", ndisc_info->mac_addr[0], ndisc_info->mac_addr[1], + ndisc_info->mac_addr[2], ndisc_info->mac_addr[3], ndisc_info->mac_addr[4], ndisc_info->mac_addr[5]); + } + + /* update ND */ + if (ndisc_info->op_type != ndisc_msg->op_type + || strcmp(ndisc_info->ifname, ndisc_msg->ifname) != 0 + || memcmp(ndisc_info->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN) != 0) + { + ndisc_info->op_type = ndisc_msg->op_type; + sprintf(ndisc_info->ifname, "%s", ndisc_msg->ifname); + memcpy(ndisc_info->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN); + ICCPD_LOG_DEBUG(__FUNCTION__, "Update ND for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + break; + } + + /* enquene lif_msg (add) */ + if (!msg) + { + /* If MAC addr is NULL, and same ipv6 item is not exist in ndisc_list */ + if (memcmp(mac_addr, null_mac, ETHER_ADDR_LEN) == 0) + { + return; + } + + ndisc_msg->op_type = NEIGH_SYNC_LIF; + if (iccp_csm_init_msg(&msg, (char *)ndisc_msg, msg_len) == 0) + { + mlacp_enqueue_ndisc(csm, msg); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "NDISC-list enqueue: %s, add %s", ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue NDISC-list: %s, add %s", ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + + if (iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 1, ndisc_msg->mac_addr, ndisc_msg->ifname) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to add ND entry(%s, %s, %s) to kernel", + ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr), mac_str); + return; + } + + /* enqueue iccp_msg (add) */ + if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) + { + ndisc_msg->op_type = NEIGH_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, msg_len) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ND[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ND[ADD] message for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + + return; +} void iccp_from_netlink_port_state_handler( char * ifname, int state) { struct CSM *csm = NULL; @@ -656,29 +955,6 @@ void iccp_from_netlink_port_state_handler( char * ifname, int state) return; } -int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta, - int len, unsigned short flags) -{ - unsigned short type; - - memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); - - while (RTA_OK(rta, len)) - { - type = rta->rta_type & ~flags; - if ((type <= max) && (!tb[type])) - tb[type] = rta; - rta = RTA_NEXT(rta, len); - } - - return 0; -} - -int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) -{ - return parse_rtattr_flags(tb, max, rta, len, 0); -} - void iccp_parse_if_vlan_info_from_netlink(struct nlmsghdr *n) { struct LocalInterface *lif = NULL; @@ -759,4 +1035,4 @@ void iccp_parse_if_vlan_info_from_netlink(struct nlmsghdr *n) n = NLMSG_NEXT(n, msglen); } -} \ No newline at end of file +} diff --git a/src/iccpd/src/iccp_netlink.c b/src/iccpd/src/iccp_netlink.c index ec8971d0cee..002c254ae9c 100644 --- a/src/iccpd/src/iccp_netlink.c +++ b/src/iccpd/src/iccp_netlink.c @@ -35,15 +35,18 @@ #include #include #include +#include +#include #include #include -#include #include #include #include #include #include +#include +#include #include "../include/system.h" #include "../include/iccp_ifm.h" @@ -53,6 +56,8 @@ #include "../include/scheduler.h" #include "../include/mlacp_link_handler.h" #include "../include/msg_format.h" +#include "../include/iccp_netlink.h" + /** * SECTION: Netlink helpers */ @@ -324,13 +329,6 @@ int iccp_get_portchannel_member_list_handler(struct nl_msg *msg, void * arg) { memset(local_if->portchannel_member_buf, 0, 512); memcpy(local_if->portchannel_member_buf, temp_buf, sizeof(local_if->portchannel_member_buf) - 1); - #if 0 - if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) - { - /*peerlink portchannel member changed*/ - update_peerlink_isolate_from_all_csm_lif(csm); - } - #endif } } } @@ -491,7 +489,7 @@ void iccp_set_interface_ipadd_mac(struct LocalInterface *lif, char * mac_addr ) dst_len = strlen(mac_addr); memcpy(sub_msg->data, mac_addr, dst_len); - ICCPD_LOG_DEBUG(__FUNCTION__, "If name %s ip %s mac %s", lif->name, show_ip_str(htonl(lif->ipv4_addr)), sub_msg->data); + ICCPD_LOG_NOTICE(__FUNCTION__, "If name %s ip %s mac %s", lif->name, show_ip_str(htonl(lif->ipv4_addr)), sub_msg->data); sub_msg->op_len = dst_len; msg_hdr->len += sizeof(mclag_sub_option_hdr_t); @@ -504,6 +502,51 @@ void iccp_set_interface_ipadd_mac(struct LocalInterface *lif, char * mac_addr ) return; } +int iccp_netlink_if_startup_set(uint32_t ifindex) +{ + struct rtnl_link *link; + int err; + struct System *sys = NULL; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + link = rtnl_link_alloc(); + if (!link) + return -ENOMEM; + + rtnl_link_set_ifindex(link, ifindex); + rtnl_link_set_flags(link, IFF_UP); + + err = rtnl_link_change(sys->route_sock, link, link, 0); + +errout: + rtnl_link_put(link); + return err; +} + +int iccp_netlink_if_shutdown_set(uint32_t ifindex) +{ + struct rtnl_link *link; + int err; + struct System *sys = NULL; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + link = rtnl_link_alloc(); + if (!link) + return -ENOMEM; + + rtnl_link_set_ifindex(link, ifindex); + rtnl_link_unset_flags(link, IFF_UP); + + err = rtnl_link_change(sys->route_sock, link, link, 0); + +errout: + rtnl_link_put(link); + return err; +} void update_if_ipmac_on_standby(struct LocalInterface* lif_po) { struct CSM* csm; @@ -535,7 +578,7 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po) /*Backup old sysmac*/ memcpy(lif_po->mac_addr_ori, lif_po->mac_addr, ETHER_ADDR_LEN); - ICCPD_LOG_DEBUG(__FUNCTION__, + ICCPD_LOG_NOTICE(__FUNCTION__, "%s Change the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X].", (csm->role_type == STP_ROLE_STANDBY) ? "Standby" : "Active", lif_po->name, lif_po->mac_addr[0], lif_po->mac_addr[1], lif_po->mac_addr[2], lif_po->mac_addr[3], lif_po->mac_addr[4], lif_po->mac_addr[5], @@ -546,6 +589,10 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po) { ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", lif_po->name, ret); } + + /* Refresh link local address according the new MAC */ + iccp_netlink_if_shutdown_set(lif_po->ifindex); + iccp_netlink_if_startup_set(lif_po->ifindex); } /*Set portchannel ip mac */ @@ -576,8 +623,12 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po) { ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", vlan->vlan_itf->name, ret); } - - iccp_set_interface_ipadd_mac(vlan->vlan_itf, macaddr ); + + /* Refresh link local address according the new MAC */ + iccp_netlink_if_shutdown_set(vlan->vlan_itf->ifindex); + iccp_netlink_if_startup_set(vlan->vlan_itf->ifindex); + + iccp_set_interface_ipadd_mac(vlan->vlan_itf, macaddr); memcpy(vlan->vlan_itf->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN); } } @@ -611,7 +662,7 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) /*Recover mac to origin mac, it is the 'mac' value in 'localhost' currently*/ if (memcmp( lif_po->mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN) != 0) { - ICCPD_LOG_DEBUG(__FUNCTION__, + ICCPD_LOG_NOTICE(__FUNCTION__, "%s Recover the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X].", (csm->role_type == STP_ROLE_STANDBY) ? "Standby" : "Active", lif_po->name, lif_po->mac_addr[0], lif_po->mac_addr[1], lif_po->mac_addr[2], lif_po->mac_addr[3], lif_po->mac_addr[4], lif_po->mac_addr[5], @@ -622,6 +673,10 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) { ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", lif_po->name, ret); } + + /* Refresh link local address according the new MAC */ + iccp_netlink_if_shutdown_set(lif_po->ifindex); + iccp_netlink_if_startup_set(lif_po->ifindex); } /*Set portchannel ip mac */ @@ -648,6 +703,10 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", vlan->vlan_itf->name, ret); } + /* Refresh link local address according the new MAC */ + iccp_netlink_if_shutdown_set(vlan->vlan_itf->ifindex); + iccp_netlink_if_startup_set(vlan->vlan_itf->ifindex); + iccp_set_interface_ipadd_mac(vlan->vlan_itf, macaddr); memcpy(vlan->vlan_itf->l3_mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN); } @@ -657,6 +716,80 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) return; } +int iccp_netlink_neighbor_request(int family, uint8_t *addr, int add, uint8_t *mac, char *portname) +{ + struct System *sys = NULL; + struct rtnl_neigh *neigh = NULL; + struct nl_addr *nl_addr_mac = NULL; + struct nl_addr *nl_addr_dst = NULL; + struct LocalInterface *lif = NULL; + struct nl_cache *link_cache; + char mac_str[18] = ""; + int err = 0; + + if (!(sys = system_get_instance())) + return MCLAG_ERROR; + + lif = local_if_find_by_name(portname); + if (!lif) + return MCLAG_ERROR; + + neigh = rtnl_neigh_alloc(); + if (!neigh) + { + ICCPD_LOG_INFO(__FUNCTION__, "Unable to allocate neighbour object"); + return MCLAG_ERROR; + } + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + ICCPD_LOG_NOTICE(__FUNCTION__, "Notify kernel %s %s entry(ip:%s, mac:%s, intf:%s)", + add ? "add" : "del", (family == AF_INET) ? "ARP" : "ND", + (family == AF_INET) ? show_ip_str(*((int *)addr)) : show_ipv6_str(addr), mac_str, portname); + + nl_addr_mac = nl_addr_build(AF_LLC, (void *)mac, ETHER_ADDR_LEN); + if (!nl_addr_mac) + { + err = MCLAG_ERROR; + goto errout; + } + + if (family == AF_INET) + nl_addr_dst = nl_addr_build(family, (void *)addr, 4); + else + nl_addr_dst = nl_addr_build(family, (void *)addr, 16); + + if (!nl_addr_dst) + { + err = MCLAG_ERROR; + goto errout; + } + + rtnl_neigh_set_lladdr(neigh, nl_addr_mac); + rtnl_neigh_set_dst(neigh, nl_addr_dst); + rtnl_neigh_set_ifindex(neigh, lif->ifindex); + rtnl_neigh_set_state(neigh, NUD_REACHABLE); + + if (add) + { + if ((err = rtnl_neigh_add(sys->route_sock, neigh, NLM_F_REPLACE | NLM_F_CREATE)) < 0) + ICCPD_LOG_WARN(__FUNCTION__, "Add %s (ip:%s, mac:%s) error, err = %d", (family == AF_INET) ? "ARP" : "ND", + (family == AF_INET) ? show_ip_str(*((int *)addr)) : show_ipv6_str(addr), mac_str, err); + } + else + { + if ((err = rtnl_neigh_delete(sys->route_sock, neigh, 0)) < 0) + ICCPD_LOG_WARN(__FUNCTION__, "Del %s (ip:%s, mac:%s) error, err = %d", (family == AF_INET) ? "ARP" : "ND", + (family == AF_INET) ? show_ip_str(*((int *)addr)) : show_ipv6_str(addr), mac_str, err); + } + +errout: + nl_addr_put(nl_addr_mac); + nl_addr_put(nl_addr_dst); + rtnl_neigh_put(neigh); + return err; +} + void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg) { struct rtnl_link *link; @@ -789,6 +922,103 @@ void iccp_event_handler_obj_input_dellink(struct nl_object *obj, void *arg) return; } +void iccp_event_handler_obj_input_newaddr(struct nl_object *obj, void *arg) +{ + struct rtnl_addr *addr; + struct nl_addr *nl_addr; + struct LocalInterface *lif; + uint32_t ifindex; + char addrStr[65] = { 0 }; + char addr_null[16] = { 0 }; + addr = (struct rtnl_addr *)obj; + + ifindex = rtnl_addr_get_ifindex(addr); + nl_addr = rtnl_addr_get_local(addr); + + if (!(lif = local_if_find_by_ifindex(ifindex))) + return; + + if (rtnl_addr_get_family(addr) == AF_INET) + { + lif->ipv4_addr = *(uint32_t *) nl_addr_get_binary_addr(nl_addr); + lif->prefixlen = nl_addr_get_prefixlen(nl_addr); + lif->l3_mode = 1; + lif->port_config_sync = 1; + if (memcmp((char *)lif->ipv6_addr, addr_null, 16) == 0) + update_if_ipmac_on_standby(lif); + ICCPD_LOG_DEBUG(__FUNCTION__, "Ifname %s index %d address %s", lif->name, lif->ifindex, show_ip_str(lif->ipv4_addr)); + } + else if (rtnl_addr_get_family(addr) == AF_INET6) + { + if (memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "FE80", 4) == 0 + || memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "fe80", 4) == 0) + return; + + memcpy((char *)lif->ipv6_addr, nl_addr_get_binary_addr(nl_addr), 16); + lif->prefixlen = nl_addr_get_prefixlen(nl_addr); + lif->l3_mode = 1; + lif->port_config_sync = 1; + if (lif->ipv4_addr == 0) + update_if_ipmac_on_standby(lif); + ICCPD_LOG_DEBUG(__FUNCTION__, "Ifname %s index %d address %s", lif->name, lif->ifindex, show_ipv6_str((char *)lif->ipv6_addr)); + } + + return; +} + +void iccp_event_handler_obj_input_deladdr(struct nl_object *obj, void *arg) +{ + struct rtnl_addr *addr; + struct nl_addr *nl_addr; + struct LocalInterface *lif; + uint32_t ifindex; + char addr_null[16] = { 0 }; + + addr = (struct rtnl_addr *)obj; + + ifindex = rtnl_addr_get_ifindex(addr); + nl_addr = rtnl_addr_get_local(addr); + + if (!(lif = local_if_find_by_ifindex(ifindex))) + return; + + if (rtnl_addr_get_family(addr) == AF_INET) + { + lif->ipv4_addr = 0; + lif->prefixlen = 0; + } + else if (rtnl_addr_get_family(addr) == AF_INET6) + { + if (memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "FE80", 4) == 0 + || memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "fe80", 4) == 0) + return; + + memset((char *)lif->ipv6_addr, 0, 16); + lif->prefixlen_v6 = 0; + } + + if (lif->ipv4_addr == 0 && memcmp((char *)lif->ipv6_addr, addr_null, 16) == 0) + { + lif->l3_mode = 0; + memset(lif->l3_mac_addr, 0, ETHER_ADDR_LEN); + } + + return; +} + +int iccp_addr_valid_handler(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + unsigned int event = 0; + if (nlh->nlmsg_type != RTM_NEWADDR) + return 0; + + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newaddr, &event) < 0) + ICCPD_LOG_ERR(__FUNCTION__, "Unknown message type."); + + return 0; +} + int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInterface *lif) { struct @@ -893,61 +1123,6 @@ int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInter return 0; } -int iccp_local_if_addr_update(struct nl_msg *msg, void *arg) -{ - int len; - struct ifaddrmsg *ifa; - struct LocalInterface *lif; - - struct nlmsghdr *n = nlmsg_hdr(msg); - - if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) - return 0; - - ifa = NLMSG_DATA(n); - - if (ifa->ifa_family != AF_INET ) - return 0; - - lif = local_if_find_by_ifindex(ifa->ifa_index); - if (!lif) - { - return 0; - } - - if (n->nlmsg_type == RTM_DELADDR) - { - lif->ipv4_addr = 0; - lif->prefixlen = 0; - lif->l3_mode = 0; - memset(lif->l3_mac_addr, 0, ETHER_ADDR_LEN); - } - - len = n->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg)); - if (len < 0) - return 0; - - struct rtattr *rth = IFA_RTA(ifa); - int rtl = IFA_PAYLOAD(n); - - while (rtl && RTA_OK(rth, rtl)) - { - if (rth->rta_type == IFA_ADDRESS) - { - uint32_t ipaddr = ntohl(*((uint32_t *)RTA_DATA(rth))); - lif->ipv4_addr = ipaddr; - lif->prefixlen = ifa->ifa_prefixlen; - lif->l3_mode = 1; - lif->port_config_sync = 1; - update_if_ipmac_on_standby(lif); - ICCPD_LOG_DEBUG(__FUNCTION__, "If name %s index %d ip %s", lif->name, lif->ifindex, show_ip_str(htonl(lif->ipv4_addr))); - } - rth = RTA_NEXT(rth, rtl); - } - - return 0; -} - int iccp_sys_local_if_list_get_addr() { struct System *sys = NULL; @@ -983,7 +1158,7 @@ int iccp_sys_local_if_list_get_addr() return -ENOMEM; } - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_local_if_addr_update, sys); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_addr_valid_handler, sys); ret = nl_recvmsgs(sys->route_sock, cb); nl_cb_put(cb); if (ret < 0) @@ -1022,9 +1197,13 @@ static int iccp_route_event_handler(struct nl_msg *msg, void *arg) break; case RTM_NEWADDR: - iccp_local_if_addr_update(msg, NULL); + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newaddr, NULL) < 0) + ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type(RTM_NEWADDR)."); + break; + case RTM_DELADDR: + if (nl_msg_parse(msg, &iccp_event_handler_obj_input_deladdr, NULL) < 0) + ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type(RTM_DELADDR)."); break; - default: return NL_OK; } @@ -1048,6 +1227,53 @@ static int iccp_genric_event_handler(struct nl_msg *msg, void *arg) return NL_SKIP; } +int iccp_make_nd_socket(void) +{ + int sock; + int ret; + int val; + struct icmp6_filter filter; + + sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + + if (sock < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to create nd socket"); + return MCLAG_ERROR; + } + + val = 1; +#ifdef IPV6_RECVPKTINFO /* 2292bis-01 */ + if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(val)) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set IPV6_RECVPKTINFO for nd socket"); + close(sock); + return MCLAG_ERROR; + } +#else /* RFC2292 */ + if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, &val, sizeof(val)) < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set IPV6_PKTINFO for nd socket"); + close(sock); + return MCLAG_ERROR; + } +#endif + + ICMP6_FILTER_SETBLOCKALL(&filter); + ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter); + + ret = setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(struct icmp6_filter)); + + if (ret < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to set ICMP6_FILTER"); + close(sock); + return MCLAG_ERROR; + } + + return sock; +} + /*init netlink socket*/ int iccp_system_init_netlink_socket() { @@ -1135,45 +1361,7 @@ int iccp_system_init_netlink_socket() ICCPD_LOG_ERR(__FUNCTION__, "Failed to set buffer size of netlink event sock."); goto err_return; } -#if 0 - sys->family = genl_ctrl_resolve(sys->genric_sock, TEAM_GENL_NAME); - while (sys->family < 0) - { - sleep(1); - log_err_period++; - /*If no portchannel configuration, teamd will not started, genl_ctrl_resolve() will return <0 forever */ - /*Only log error message 5 times*/ - if (log_err_period == 1 && log_err_time < 5) - { - ICCPD_LOG_ERR(__FUNCTION__, "Failed to resolve netlink family. %d of TEAM_GENL_NAME %s ", sys->family, TEAM_GENL_NAME); - log_err_time++; - } - else - { - /*Log error message every 30s per time*/ - if (log_err_period == 30) - log_err_period = 0; - } - - sys->family = genl_ctrl_resolve(sys->genric_sock, TEAM_GENL_NAME); - } - - grp_id = genl_ctrl_resolve_grp(sys->genric_sock, TEAM_GENL_NAME, - TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME); - if (grp_id < 0) - { - ICCPD_LOG_ERR(__FUNCTION__, "Failed to resolve netlink multicast groups. %d", grp_id); - goto err_return; - } - - err = nl_socket_add_membership(sys->genric_event_sock, grp_id); - if (err < 0) - { - ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); - goto err_return; - } -#endif nl_socket_disable_seq_check(sys->genric_event_sock); nl_socket_modify_cb(sys->genric_event_sock, NL_CB_VALID, NL_CB_CUSTOM, iccp_genric_event_handler, sys); @@ -1202,8 +1390,13 @@ int iccp_system_init_netlink_socket() ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); goto err_return; } - - /*receive arp packet socket*/ + err = nl_socket_add_membership(sys->route_event_sock, RTNLGRP_IPV6_IFADDR); + if (err < 0) + { + ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); + goto err_return; + } + /* receive arp packet socket */ sys->arp_receive_fd = socket(PF_PACKET, SOCK_DGRAM, 0); if (sys->arp_receive_fd < 0) { @@ -1225,6 +1418,13 @@ int iccp_system_init_netlink_socket() } } + sys->ndisc_receive_fd = iccp_make_nd_socket(); + + if (sys->ndisc_receive_fd < 0) + { + goto err_return; + } + goto succes_return; err_return: @@ -1295,6 +1495,11 @@ static int iccp_get_receive_arp_packet_sock_fd(struct System *sys) return sys->arp_receive_fd; } +static int iccp_get_receive_ndisc_packet_sock_fd(struct System *sys) +{ + return sys->ndisc_receive_fd; +} + static int iccp_receive_arp_packet_handler(struct System *sys) { unsigned char buf[1024]; @@ -1328,7 +1533,100 @@ static int iccp_receive_arp_packet_handler(struct System *sys) memcpy(mac_addr, (char*)(a + 1), ETHER_ADDR_LEN); memcpy(&addr, (char*)(a + 1) + a->ar_hln, 4); - do_arp_update_from_reply_packet(ifindex, ntohl(addr), mac_addr); + do_arp_update_from_reply_packet(ifindex, addr, mac_addr); + + return 0; +} + +int iccp_receive_ndisc_packet_handler(struct System *sys) +{ + uint8_t buf[4096]; + uint8_t adata[1024]; + struct sockaddr_in6 from; + unsigned int ifindex = 0; + struct msghdr msg; + struct iovec iov; + struct cmsghdr *cmsgptr; + struct nd_msg *ndmsg = NULL; + struct nd_opt_hdr *nd_opt = NULL; + struct in6_addr target; + uint8_t mac_addr[ETHER_ADDR_LEN]; + int8_t *opt = NULL; + int opt_len = 0, l = 0; + int len; + + memset(mac_addr, 0, ETHER_ADDR_LEN); + + /* Fill in message and iovec. */ + msg.msg_name = (void *)(&from); + msg.msg_namelen = sizeof(struct sockaddr_in6); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = (void *)adata; + msg.msg_controllen = sizeof adata; + iov.iov_base = buf; + iov.iov_len = 4096; + + len = recvmsg(sys->ndisc_receive_fd, &msg, 0); + + if (len < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Ndisc recvmsg error!"); + return MCLAG_ERROR; + } + + if (msg.msg_controllen >= sizeof(struct cmsghdr)) + for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) + { + /* I want interface index which this packet comes from. */ + if (cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_PKTINFO) + { + struct in6_pktinfo *ptr; + + ptr = (struct in6_pktinfo *)CMSG_DATA(cmsgptr); + ifindex = ptr->ipi6_ifindex; + } + } + + ndmsg = (struct nd_msg *)buf; + + if (ndmsg->icmph.icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT) + return 0; + + memcpy((char *)(&target), (char *)(&ndmsg->target), sizeof(struct in6_addr)); + + opt = (char *)ndmsg->opt; + + opt_len = len - sizeof(struct nd_msg); + + if (opt && opt_len > 0) + { + while (opt_len) + { + if (opt_len < sizeof(struct nd_opt_hdr)) + return 0; + + nd_opt = (struct nd_opt_hdr *)opt; + + l = nd_opt->nd_opt_len << 3; + + if (l == 0) + return 0; + + if (nd_opt->nd_opt_type == ND_OPT_TARGET_LL_ADDR) + { + memcpy(mac_addr, (char *)((char *)nd_opt + sizeof(struct nd_opt_hdr)), ETHER_ADDR_LEN); + break; + } + + opt += l; + opt_len -= l; + } + } + + /* ICCPD_LOG_DEBUG(__FUNCTION__, "Recv na pkt(%s,%02X:%02X:%02X:%02X:%02X:%02X)!", show_ipv6_str((char *)&target), mac_addr[0], mac_addr[1], + mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); */ + do_ndisc_update_from_reply_packet(ifindex, (char *)&target, mac_addr); return 0; } @@ -1412,7 +1710,11 @@ static const struct iccp_eventfd iccp_eventfds[] = { { .get_fd = iccp_get_receive_arp_packet_sock_fd, .event_handler = iccp_receive_arp_packet_handler, - } + }, + { + .get_fd = iccp_get_receive_ndisc_packet_sock_fd, + .event_handler = iccp_receive_ndisc_packet_handler, + } }; /* \cond HIDDEN_SYMBOLS */ diff --git a/src/iccpd/src/mclagdctl/mclagdctl.c b/src/iccpd/src/mclagdctl/mclagdctl.c index 7c5d7284066..6e897727887 100644 --- a/src/iccpd/src/mclagdctl/mclagdctl.c +++ b/src/iccpd/src/mclagdctl/mclagdctl.c @@ -65,6 +65,14 @@ static struct command_type command_types[] = .enca_msg = mclagdctl_enca_dump_arp, .parse_msg = mclagdctl_parse_dump_arp, }, + { + .id = ID_CMDTYPE_D_A, + .parent_id = ID_CMDTYPE_D, + .info_type = INFO_TYPE_DUMP_NDISC, + .name = "nd", + .enca_msg = mclagdctl_enca_dump_ndisc, + .parse_msg = mclagdctl_parse_dump_ndisc, + }, { .id = ID_CMDTYPE_D_A, .parent_id = ID_CMDTYPE_D, @@ -290,6 +298,24 @@ int mclagdctl_enca_dump_arp(char *msg, int mclag_id, int argc, char **argv) return 1; } +int mclagdctl_enca_dump_ndisc(char *msg, int mclag_id, int argc, char **argv) +{ + struct mclagdctl_req_hdr req; + + if (mclag_id <= 0) + { + fprintf(stderr, "Need to specify mclag-id through the parameter i !\n"); + return MCLAG_ERROR; + } + + memset(&req, 0, sizeof(struct mclagdctl_req_hdr)); + req.info_type = INFO_TYPE_DUMP_NDISC; + req.mclag_id = mclag_id; + memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr)); + + return 1; +} + int mclagdctl_parse_dump_arp(char *msg, int data_len) { struct mclagd_arp_msg * arp_info = NULL; @@ -322,6 +348,38 @@ int mclagdctl_parse_dump_arp(char *msg, int data_len) return 0; } +int mclagdctl_parse_dump_ndisc(char *msg, int data_len) +{ + struct mclagd_ndisc_msg *ndisc_info = NULL; + int len = 0; + int count = 0; + + fprintf(stdout, "%-6s", "No."); + fprintf(stdout, "%-52s", "IPv6"); + fprintf(stdout, "%-20s", "MAC"); + fprintf(stdout, "%-20s", "DEV"); + fprintf(stdout, "\n"); + + len = sizeof(struct mclagd_ndisc_msg); + + for (; data_len >= len; data_len -= len, count++) + { + ndisc_info = (struct mclagd_ndisc_msg *)(msg + len * count); + + fprintf(stdout, "%-6d", count + 1); + fprintf(stdout, "%-52s", ndisc_info->ipv6_addr); + fprintf(stdout, "%02x:%02x:%02x:%02x:%02x:%02x", + ndisc_info->mac_addr[0], ndisc_info->mac_addr[1], + ndisc_info->mac_addr[2], ndisc_info->mac_addr[3], + ndisc_info->mac_addr[4], ndisc_info->mac_addr[5]); + fprintf(stdout, " "); + fprintf(stdout, "%-20s", ndisc_info->ifname); + fprintf(stdout, "\n"); + } + + return 0; +} + int mclagdctl_enca_dump_mac(char *msg, int mclag_id, int argc, char **argv) { struct mclagdctl_req_hdr req; diff --git a/src/iccpd/src/mclagdctl/mclagdctl.h b/src/iccpd/src/mclagdctl/mclagdctl.h index 1b8c6f278cc..91155ecb732 100644 --- a/src/iccpd/src/mclagdctl/mclagdctl.h +++ b/src/iccpd/src/mclagdctl/mclagdctl.h @@ -25,6 +25,7 @@ #define MCLAGDCTL_MAX_L_PORT_NANE 32 #define MCLAGDCTL_INET_ADDR_LEN 32 +#define MCLAGDCTL_INET6_ADDR_LEN 64 #define MCLAGDCTL_ETHER_ADDR_LEN 6 #define MCLAGDCTL_PORT_MEMBER_BUF_LEN 512 #define ETHER_ADDR_STR_LEN 18 @@ -62,6 +63,7 @@ enum mclagdctl_notify_peer_type INFO_TYPE_NONE = 0, INFO_TYPE_DUMP_STATE, INFO_TYPE_DUMP_ARP, + INFO_TYPE_DUMP_NDISC, INFO_TYPE_DUMP_MAC, INFO_TYPE_DUMP_LOCAL_PORTLIST, INFO_TYPE_DUMP_PEER_PORTLIST, @@ -137,6 +139,14 @@ struct mclagd_arp_msg unsigned char mac_addr[MCLAGDCTL_ETHER_ADDR_LEN]; }; +struct mclagd_ndisc_msg +{ + char op_type; + char ifname[MCLAGDCTL_MAX_L_PORT_NANE]; + char ipv6_addr[MCLAGDCTL_INET6_ADDR_LEN]; + unsigned char mac_addr[MCLAGDCTL_ETHER_ADDR_LEN]; +}; + struct mclagd_mac_msg { unsigned char op_type;/*add or del*/ @@ -186,7 +196,9 @@ struct mclagd_peer_if extern int mclagdctl_enca_dump_state(char *msg, int mclag_id, int argc, char **argv); extern int mclagdctl_parse_dump_state(char *msg, int data_len); extern int mclagdctl_enca_dump_arp(char *msg, int mclag_id, int argc, char **argv); +extern int mclagdctl_enca_dump_ndisc(char *msg, int mclag_id, int argc, char **argv); extern int mclagdctl_parse_dump_arp(char *msg, int data_len); +extern int mclagdctl_parse_dump_ndisc(char *msg, int data_len); extern int mclagdctl_enca_dump_mac(char *msg, int mclag_id, int argc, char **argv); extern int mclagdctl_parse_dump_mac(char *msg, int data_len); extern int mclagdctl_enca_dump_local_portlist(char *msg, int mclag_id, int argc, char **argv); diff --git a/src/iccpd/src/mlacp_fsm.c b/src/iccpd/src/mlacp_fsm.c index f479b75f36c..c56eb905173 100644 --- a/src/iccpd/src/mlacp_fsm.c +++ b/src/iccpd/src/mlacp_fsm.c @@ -101,12 +101,14 @@ * ***************************************/ static char *mlacp_state(struct CSM* csm); static void mlacp_resync_arp(struct CSM* csm); +static void mlacp_resync_ndisc(struct CSM* csm); static void mlacp_resync_mac(struct CSM* csm); /* Sync Sender APIs*/ static void mlacp_sync_send_sysConf(struct CSM* csm); static void mlacp_sync_send_aggConf(struct CSM* csm); static void mlacp_sync_send_aggState(struct CSM* csm); static void mlacp_sync_send_syncArpInfo(struct CSM* csm); +static void mlacp_sync_send_syncNdiscInfo(struct CSM* csm); static void mlacp_sync_send_heartbeat(struct CSM* csm); static void mlacp_sync_send_syncDoneData(struct CSM* csm); /* Sync Reciever APIs*/ @@ -204,7 +206,7 @@ static void mlacp_sync_send_aggState(struct CSM* csm) return; } #define MAX_MAC_ENTRY_NUM 30 -#define MAX_ARP_ENTRY_NUM 40 +#define MAX_NEIGH_ENTRY_NUM 40 static void mlacp_sync_send_syncMacInfo(struct CSM* csm) { int msg_len = 0; @@ -253,7 +255,7 @@ static void mlacp_sync_send_syncArpInfo(struct CSM* csm) count++; free(msg->buf); free(msg); - if (count >= MAX_ARP_ENTRY_NUM) + if (count >= MAX_NEIGH_ENTRY_NUM) { iccp_csm_send(csm, g_csm_buf, msg_len); count = 0; @@ -268,6 +270,37 @@ static void mlacp_sync_send_syncArpInfo(struct CSM* csm) return; } +static void mlacp_sync_send_syncNdiscInfo(struct CSM *csm) +{ + int msg_len = 0; + struct Msg *msg = NULL; + int count = 0; + + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + + while (!TAILQ_EMPTY(&(MLACP(csm).ndisc_msg_list))) + { + msg = TAILQ_FIRST(&(MLACP(csm).ndisc_msg_list)); + TAILQ_REMOVE(&(MLACP(csm).ndisc_msg_list), msg, tail); + + msg_len = mlacp_prepare_for_ndisc_info(csm, g_csm_buf, CSM_BUFFER_SIZE, (struct NDISCMsg *)msg->buf, count); + count++; + free(msg->buf); + free(msg); + if (count >= MAX_NEIGH_ENTRY_NUM) + { + iccp_csm_send(csm, g_csm_buf, msg_len); + count = 0; + memset(g_csm_buf, 0, CSM_BUFFER_SIZE); + } + /* ICCPD_LOG_DEBUG("mlacp_fsm", " [SYNC_Send] NDInfo,len=[%d]", msg_len); */ + } + + if (count) + iccp_csm_send(csm, g_csm_buf, msg_len); + + return; +} static void mlacp_sync_send_syncPortChannelInfo(struct CSM* csm) { struct System* sys = NULL; @@ -353,7 +386,7 @@ static void mlacp_sync_recv_sysConf(struct CSM* csm, struct Msg* msg) if (mlacp_fsm_update_system_conf(csm, sysconf) == MCLAG_ERROR) { /*NOTE: we just change the node ID local side without sending NAK msg*/ - ICCPD_LOG_DEBUG(__FUNCTION__, "Same Node ID = %d, send NAK", MLACP(csm).remote_system.node_id); + ICCPD_LOG_WARN(__FUNCTION__, "Same Node ID = %d, send NAK", MLACP(csm).remote_system.node_id); mlacp_sync_send_nak_handler(csm, msg); } @@ -476,6 +509,15 @@ static void mlacp_sync_recv_arpInfo(struct CSM* csm, struct Msg* msg) return; } +static void mlacp_sync_recv_ndiscInfo(struct CSM *csm, struct Msg *msg) +{ + struct mLACPNDISCInfoTLV *ndisc_info = NULL; + + ndisc_info = (struct mLACPNDISCInfoTLV *)&(msg->buf[sizeof(ICCHdr)]); + mlacp_fsm_update_ndisc_info(csm, ndisc_info); + + return; +} static void mlacp_sync_recv_stpInfo(struct CSM* csm, struct Msg* msg) { /*Don't support currently*/ @@ -520,6 +562,7 @@ void mlacp_init(struct CSM* csm, int all) MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list); PIF_QUEUE_REINIT(MLACP(csm).pif_list); LIF_PURGE_QUEUE_REINIT(MLACP(csm).lif_purge_list); @@ -528,6 +571,7 @@ void mlacp_init(struct CSM* csm, int all) { /* if no clean all, keep the arp info & local interface info for next connection*/ MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_list); LIF_QUEUE_REINIT(MLACP(csm).lif_list); @@ -551,8 +595,10 @@ void mlacp_finalize(struct CSM* csm) /* msg destroy*/ MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_list); /* remove lif & lif-purge queue */ @@ -590,6 +636,7 @@ void mlacp_fsm_transit(struct CSM* csm) { MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list); + MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_msg_list); MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list); MLACP(csm).current_state = MLACP_STATE_INIT; } @@ -651,6 +698,7 @@ void mlacp_fsm_transit(struct CSM* csm) MLACP(csm).wait_for_sync_data = 0; MLACP(csm).current_state = MLACP_STATE_STAGE1; mlacp_resync_arp(csm); + mlacp_resync_ndisc(csm); } switch (MLACP(csm).current_state) @@ -788,7 +836,7 @@ static void mlacp_resync_arp(struct CSM* csm) TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) { arp_msg = (struct ARPMsg*)msg->buf; - arp_msg->op_type = ARP_SYNC_ADD; + arp_msg->op_type = NEIGH_SYNC_ADD; if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, sizeof(struct ARPMsg)) == 0) { TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail); @@ -797,6 +845,31 @@ static void mlacp_resync_arp(struct CSM* csm) } } +/****************************************** +* When peerlink ready, prepare the NDISCMsg +* +******************************************/ +static void mlacp_resync_ndisc(struct CSM *csm) +{ + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL; + struct Msg *msg_send = NULL; + + /* recover ndisc info sync from peer */ + if (!TAILQ_EMPTY(&(MLACP(csm).ndisc_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + ndisc_msg->op_type = NEIGH_SYNC_ADD; + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, sizeof(struct NDISCMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + } + } + } +} + /***************************************** * NAK handler * @@ -928,6 +1001,10 @@ static void mlacp_sync_receiver_handler(struct CSM* csm, struct Msg* msg) mlacp_sync_recv_arpInfo(csm, msg); break; + case TLV_T_MLACP_NDISC_INFO: + mlacp_sync_recv_ndiscInfo(csm, msg); + break; + case TLV_T_MLACP_STP_INFO: mlacp_sync_recv_stpInfo(csm, msg); break; @@ -980,6 +1057,10 @@ static void mlacp_sync_sender_handler(struct CSM* csm) mlacp_sync_send_syncArpInfo(csm); break; + case MLACP_SYNC_NDISC_INFO: + mlacp_sync_send_syncNdiscInfo(csm); + break; + case MLACP_SYNC_DONE: mlacp_sync_send_syncDoneData(csm); break; @@ -1194,6 +1275,9 @@ static void mlacp_exchange_handler(struct CSM* csm, struct Msg* msg) /* Send ARP info if any*/ mlacp_sync_send_syncArpInfo(csm); + /* Send Ndisc info if any */ + mlacp_sync_send_syncNdiscInfo(csm); + /*If peer is warm reboot*/ if (csm->peer_warm_reboot_time != 0) { diff --git a/src/iccpd/src/mlacp_link_handler.c b/src/iccpd/src/mlacp_link_handler.c index 66a75c4b862..8bc533e387b 100644 --- a/src/iccpd/src/mlacp_link_handler.c +++ b/src/iccpd/src/mlacp_link_handler.c @@ -39,6 +39,7 @@ #include "../include/iccp_csm.h" #include "mclagdctl/mclagdctl.h" #include "../include/iccp_cmd_show.h" +#include "../include/iccp_netlink.h" /***************************************** * Enum * @@ -50,12 +51,12 @@ typedef enum route_manipulate_type ROUTE_DEL } ROUTE_MANIPULATE_TYPE_E; - /***************************************** * Global * * ***************************************/ char g_ipv4_str[INET_ADDRSTRLEN]; +char g_ipv6_str[INET6_ADDRSTRLEN]; /***************************************** * Tool : show ip string @@ -72,6 +73,14 @@ char *show_ip_str(uint32_t ipv4_addr) return g_ipv4_str; } +char *show_ipv6_str(char *ipv6_addr) +{ + memset(g_ipv6_str, 0, sizeof(g_ipv6_str)); + inet_ntop(AF_INET6, ipv6_addr, g_ipv6_str, INET6_ADDRSTRLEN); + + return g_ipv6_str; +} + static int getHwAddr(char *buff, char *mac) { int i = 0; @@ -95,107 +104,6 @@ static int getHwAddr(char *buff, char *mac) return 0; } -/* Set an entry in the ARP cache. */ -int mlacp_fsm_arp_set(char *ifname, uint32_t ip, char *mac) -{ - struct arpreq arpreq; - struct sockaddr_in *sin; - struct in_addr ina; - int flags; - int rc; - int sock_fd = 0; - - ICCPD_LOG_DEBUG(__FUNCTION__, "Set arp entry for IP:%s MAC:%s ifname:%s", show_ip_str(htonl(ip)), mac, ifname); - - if (ifname == NULL || ip == 0 || mac == NULL) - { - return MCLAG_ERROR; - } - - /*you must add this becasue some system will return "Invlid argument" - because some argument isn't zero */ - memset(&arpreq, 0, sizeof(struct arpreq)); - sin = (struct sockaddr_in *)&arpreq.arp_pa; - memset(sin, 0, sizeof(struct sockaddr_in)); - sin->sin_family = AF_INET; - ina.s_addr = htonl(ip); - memcpy(&sin->sin_addr, (char *)&ina, sizeof(struct in_addr)); - - if (getHwAddr((char *)arpreq.arp_ha.sa_data, mac) < 0) - { - return MCLAG_ERROR; - } - - strncpy(arpreq.arp_dev, ifname, 15); - - flags = ATF_COM; //note, must set flag, if not,you will get error - - arpreq.arp_flags = flags; - - sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (sock_fd < 0) - { - return MCLAG_ERROR; - } - - rc = ioctl(sock_fd, SIOCSARP, &arpreq); - if (rc < 0) - { - close(sock_fd); - return MCLAG_ERROR; - } - - close(sock_fd); - - return 0; -} - -/* Delete an entry from the ARP cache. */ -int mlacp_fsm_arp_del(char *ifname, uint32_t ip) -{ - struct arpreq arpreq; - struct sockaddr_in *sin; - struct in_addr ina; - int rc; - int sock_fd = 0; - - ICCPD_LOG_DEBUG(__FUNCTION__, "Del arp entry for IP : %s ifname:%s", show_ip_str(htonl(ip)), ifname); - - if (ifname == NULL || ip == 0) - { - return MCLAG_ERROR; - } - - /*you must add this becasue some system will return "Invlid argument" - because some argument isn't zero */ - memset(&arpreq, 0, sizeof(struct arpreq)); - - sin = (struct sockaddr_in *)&arpreq.arp_pa; - memset(sin, 0, sizeof(struct sockaddr_in)); - sin->sin_family = AF_INET; - ina.s_addr = htonl(ip); - memcpy(&sin->sin_addr, (char *)&ina, sizeof(struct in_addr)); - - strncpy(arpreq.arp_dev, ifname, 15); - - sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (sock_fd < 0) - { - return MCLAG_ERROR; - } - - rc = ioctl(sock_fd, SIOCDARP, &arpreq); - if (rc < 0) - { - close(sock_fd); - return MCLAG_ERROR; - } - - close(sock_fd); - - return 0; -} - static int arp_set_handler(struct CSM* csm, struct LocalInterface* lif, int add) @@ -223,7 +131,7 @@ static int arp_set_handler(struct CSM* csm, arp_msg = (struct ARPMsg*)msg->buf; /* only process add*/ - if (arp_msg->op_type == ARP_SYNC_DEL) + if (arp_msg->op_type == NEIGH_SYNC_DEL) continue; /* find the ARP for lif_list*/ @@ -233,9 +141,9 @@ static int arp_set_handler(struct CSM* csm, sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]); - mlacp_fsm_arp_set(arp_msg->ifname, arp_msg->ipv4_addr, mac_str); + iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_msg->ipv4_addr, 1, arp_msg->mac_addr, arp_msg->ifname); /*ICCPD_LOG_DEBUG(__FUNCTION__, "Add dynamic ARP to kernel [%s]", - show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } goto done; @@ -250,19 +158,82 @@ static int arp_set_handler(struct CSM* csm, continue; /* don't process del*/ - if (arp_msg->op_type == ARP_SYNC_DEL) + if (arp_msg->op_type == NEIGH_SYNC_DEL) continue; /* link broken, del all dynamic arp on the lif*/ - mlacp_fsm_arp_del(arp_msg->ifname, arp_msg->ipv4_addr); + iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_msg->ipv4_addr, 0, arp_msg->mac_addr, arp_msg->ifname); /*ICCPD_LOG_DEBUG(__FUNCTION__, "Del dynamic ARP [%s]", - show_ip_str(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } done: return 0; } +static int ndisc_set_handler(struct CSM *csm, struct LocalInterface *lif, int add) +{ + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL; + char mac_str[18] = ""; + + if (!csm || !lif) + return 0; + + if (add) + goto add_ndisc; + else + goto del_ndisc; + + /* Process Add */ +add_ndisc: + if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) + return 0; + + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + mac_str[0] = '\0'; + ndisc_msg = (struct NDISCMsg *)msg->buf; + + /* only process add */ + if (ndisc_msg->op_type == NEIGH_SYNC_DEL) + continue; + + /* find the ND for lif_list */ + if (strcmp(lif->name, ndisc_msg->ifname) != 0) + continue; + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", ndisc_msg->mac_addr[0], ndisc_msg->mac_addr[1], ndisc_msg->mac_addr[2], + ndisc_msg->mac_addr[3], ndisc_msg->mac_addr[4], ndisc_msg->mac_addr[5]); + + iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 1, ndisc_msg->mac_addr, ndisc_msg->ifname); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Add dynamic ND to kernel [%s]", show_ipv6_str((char *)ndisc_msg->ipv6_addr));*/ + } + goto done; + +del_ndisc: + /* Process Del */ + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + + /* find the ND for lif_list */ + if (strcmp(lif->name, ndisc_msg->ifname) != 0) + continue; + + /* don't process del */ + if (ndisc_msg->op_type == NEIGH_SYNC_DEL) + continue; + + /* link broken, del all dynamic ndisc on the lif */ + iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 0, ndisc_msg->mac_addr, ndisc_msg->ifname); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Del dynamic ND [%s]", show_ipv6_str((char *)ndisc_msg->ipv6_addr));*/ + } + +done: + return 0; +} + /***************************************** * Port-Channel Status Handler * @@ -286,20 +257,13 @@ static void set_route_by_linux_route(struct CSM* csm, return; sprintf(ipv4_dest_str, "%s", show_ip_str(htonl(local_if->ipv4_addr))); - ptr = strrchr(ipv4_dest_str, '.'); strcpy(ptr, ".0\0"); + ptr = strrchr(ipv4_dest_str, '.'); + strcpy(ptr, ".0\0"); -#if 1 - /* set gw route*/ - /*sprintf(syscmd, "ip route %s %s/%d proto static metric 200 nexthop via %s > /dev/null 2>&1",*/ + /* set gw route */ + /* sprintf(syscmd, "ip route %s %s/%d proto static metric 200 nexthop via %s > /dev/null 2>&1", */ sprintf(syscmd, "ip route %s %s/%d metric 200 nexthop via %s > /dev/null 2>&1", - (is_add) ? "add" : "del", ipv4_dest_str, local_if->prefixlen, - csm->peer_ip); -#else - // set interface route - sprintf(syscmd, "route %s -net %s/%d %s > /dev/null 2>&1", - (is_add) ? "add" : "del", ipv4_dest_str, local_if->prefixlen, - local_if->name); -#endif + (is_add) ? "add" : "del", ipv4_dest_str, local_if->prefixlen, csm->peer_ip); ret = system(syscmd); ICCPD_LOG_DEBUG(__FUNCTION__, "%s ret = %d", syscmd, ret); @@ -374,12 +338,14 @@ static void set_l3_itf_state(struct CSM *csm, if (strncmp(set_l3_local_if->name, VLAN_PREFIX, 4) != 0) { arp_set_handler(csm, set_l3_local_if, 0); /* del arp*/ + ndisc_set_handler(csm, set_l3_local_if, 0); /* del nd */ } } else if (route_type == ROUTE_DEL) { /*set_route_by_linux_route(csm, set_l3_local_if, 0);*/ /*del static route by linux route tool*/ arp_set_handler(csm, set_l3_local_if, 1); /* add arp*/ + ndisc_set_handler(csm, set_l3_local_if, 1); /* add nd */ } } @@ -428,7 +394,7 @@ static void mlacp_clean_fdb(void) if (sys->sync_fd) write(sys->sync_fd, msg_buf, msg_hdr->len); - ICCPD_LOG_DEBUG(__FUNCTION__, "Notify mclagsyncd to clear FDB"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Notify mclagsyncd to clear FDB"); return; } @@ -467,7 +433,7 @@ void set_peerlink_mlag_port_learn(struct LocalInterface *lif, int enable) msg_hdr->len += sizeof(mclag_sub_option_hdr_t); msg_hdr->len += sub_msg->op_len; - ICCPD_LOG_DEBUG(__FUNCTION__, "Send %s port MAC learn msg to mclagsyncd for %s", + ICCPD_LOG_NOTICE(__FUNCTION__, "Send %s port MAC learn msg to mclagsyncd for %s", sub_msg->op_type == MCLAG_SUB_OPTION_TYPE_MAC_LEARN_DISABLE ? "DISABLE":"ENABLE", lif->name); /*send msg*/ @@ -489,12 +455,12 @@ static void set_peerlink_mlag_port_kernel_forward( sprintf(cmd, "ebtables %s FORWARD -i %s -o %s -j DROP", "-D", csm->peer_link_if->name, lif->name); - ICCPD_LOG_DEBUG(__FUNCTION__, " ebtable cmd %s", cmd ); + ICCPD_LOG_NOTICE(__FUNCTION__, " ebtable cmd %s", cmd ); system(cmd); sprintf(cmd, "ebtables %s FORWARD -i %s -o %s -j DROP", (enable) ? "-A" : "-D", csm->peer_link_if->name, lif->name); - ICCPD_LOG_DEBUG(__FUNCTION__, " ebtable cmd %s", cmd ); + ICCPD_LOG_NOTICE(__FUNCTION__, " ebtable cmd %s", cmd ); system(cmd); return; @@ -600,11 +566,11 @@ void update_peerlink_isolate_from_all_csm_lif( if (dst_len) { memcpy(sub_msg->data, mlag_po_buf, dst_len); - ICCPD_LOG_DEBUG(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port %s", csm->peer_link_if->name, mlag_po_buf); + ICCPD_LOG_NOTICE(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port %s", csm->peer_link_if->name, mlag_po_buf); } else { - ICCPD_LOG_DEBUG(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port is NULL", csm->peer_link_if->name); + ICCPD_LOG_NOTICE(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port is NULL", csm->peer_link_if->name); } /*send msg*/ @@ -902,7 +868,7 @@ void syn_arp_info_to_peer(struct CSM *csm, struct LocalInterface *local_if) continue; arp_msg = (struct ARPMsg*)msg->buf; - arp_msg->op_type = ARP_SYNC_ADD; + arp_msg->op_type = NEIGH_SYNC_ADD; if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, sizeof(struct ARPMsg)) == 0) { @@ -912,13 +878,46 @@ void syn_arp_info_to_peer(struct CSM *csm, struct LocalInterface *local_if) } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + show_ip_str(arp_msg->ipv4_addr)); } } return; } +void syn_ndisc_info_to_peer(struct CSM *csm, struct LocalInterface *local_if) +{ + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL, *ndisc_info = NULL; + struct Msg *msg_send = NULL; + + if (!csm || !local_if) + return; + + if (!TAILQ_EMPTY(&(MLACP(csm).ndisc_list))) + { + TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail) + { + ndisc_info = (struct NDISCMsg *)msg->buf; + + if (strcmp(ndisc_info->ifname, local_if->name) != 0) + continue; + + ndisc_msg = (struct NDISCMsg *)msg->buf; + ndisc_msg->op_type = NEIGH_SYNC_ADD; + + if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, sizeof(struct NDISCMsg)) == 0) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail); + /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ND[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));*/ + } + else + ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ND[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); + } + } + + return; +} void update_stp_peer_link(struct CSM *csm, struct PeerInterface *pif, int po_state, int new_create) @@ -948,6 +947,7 @@ void update_stp_peer_link(struct CSM *csm, if (po_state == 1 && lif->po_active == 1) { syn_arp_info_to_peer(csm, lif); + syn_ndisc_info_to_peer(csm, lif); } } else @@ -972,6 +972,7 @@ void update_stp_peer_link(struct CSM *csm, if (po_state == 1 && lif->po_active == 1) { syn_arp_info_to_peer(csm, vlan->vlan_itf); + syn_ndisc_info_to_peer(csm, vlan->vlan_itf); } } } @@ -1034,7 +1035,7 @@ void iccp_send_fdb_entry_to_syncd( struct MACMsg* mac_msg, uint8_t mac_type) mac_info->op_type = mac_msg->op_type; msg_hdr->len = sizeof(struct IccpSyncdHDr) + sizeof(struct mclag_fdb_info); - ICCPD_LOG_DEBUG(__FUNCTION__, "Send mac %s msg to mclagsyncd, vid %d ; ifname %s ; mac %s; type %s", + ICCPD_LOG_NOTICE(__FUNCTION__, "Send mac %s msg to mclagsyncd, vid %d ; ifname %s ; mac %s; type %s", mac_info->op_type == MAC_SYNC_ADD ? "add" : "del", mac_info->vid, mac_info->port_name, mac_info->mac, mac_info->type == MAC_TYPE_STATIC ? "static" : "dynamic"); /*send msg*/ @@ -1141,7 +1142,7 @@ static void update_l2_mac_state(struct CSM *csm, /*portchannel down*/ if (po_state == 0) { - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, age local MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s down, age local MAC %s vlan-id %d", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1); @@ -1180,7 +1181,7 @@ static void update_l2_mac_state(struct CSM *csm, memcpy(mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); } - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, redirect MAC %s vlan-id %d to peer-link %s", + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s down, redirect MAC %s vlan-id %d to peer-link %s", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, csm->peer_itf_name); } else @@ -1188,7 +1189,7 @@ static void update_l2_mac_state(struct CSM *csm, /*peer-link is not configured, del mac from ASIC, mac still in mac_list*/ del_mac_from_chip(mac_msg); - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, peer-link is not configured: MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s down, peer-link is not configured: MAC %s vlan-id %d", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); } } @@ -1199,7 +1200,7 @@ static void update_l2_mac_state(struct CSM *csm, /*when this portchannel up, recover the mac back*/ if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0) { - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s up, redirect MAC %s vlan-id %d from peerlink to %s", + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s up, redirect MAC %s vlan-id %d from peerlink to %s", mac_msg->origin_ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->origin_ifname); /*Remove MAC_AGE_LOCAL flag*/ @@ -1215,7 +1216,7 @@ static void update_l2_mac_state(struct CSM *csm, { /*this may be peerlink is not configured and portchannel is down*/ /*when this portchannel up, add the mac back to ASIC*/ - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s up, add MAC %s vlan-id %d to ASIC", + ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s up, add MAC %s vlan-id %d to ASIC", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); /*Remove MAC_AGE_LOCAL flag*/ @@ -1319,7 +1320,7 @@ static void mlacp_fix_bridge_mac(struct CSM* csm) /*The Bridge mac can not be the same as peer system id, so fix the Bridge MAC address here.*/ sprintf(syscmd, "ip link set dev Bridge address %s > /dev/null 2>&1", macaddr); ret = system(syscmd); - ICCPD_LOG_DEBUG(__FUNCTION__, " %s ret = %d", syscmd, ret); + ICCPD_LOG_NOTICE(__FUNCTION__, " %s ret = %d", syscmd, ret); } return; @@ -1345,7 +1346,7 @@ void mlacp_peer_conn_handler(struct CSM* csm) { /*If peer reconnected, reset peer disconnect time*/ csm->warm_reboot_disconn_time = 0; - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer warm reboot and reconnect, reset peer disconnect time!"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot and reconnect, reset peer disconnect time!"); } if (csm->peer_link_if) @@ -1368,36 +1369,10 @@ void mlacp_peer_conn_handler(struct CSM* csm) mlacp_conn_handler_fdb(csm); -#if 0 - // When peer-link ready, suppose all MLAG link are alive - LIST_FOREACH(pif, &(MLACP(csm).pif_list), mlacp_next) - { - pif->po_active = 1; - } -#endif LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) { if (lif->type == IF_T_PORT_CHANNEL) { -#if 0 - if (local_if_is_l3_mode(lif)) - { - set_route_by_linux_route( csm, lif, 1); - } - else - { - LIST_FOREACH(vlan, &(lif->vlan_list), port_next) - { - if (!vlan->vlan_itf) - continue; - if (!local_if_is_l3_mode(vlan->vlan_itf)) - continue; - - set_route_by_linux_route(csm, vlan->vlan_itf, 1); /* add static route by linux route tool*/ - } - } -#endif - mlacp_portchannel_state_handler(csm, lif, (lif->state == PORT_STATE_UP) ? 1 : 0); } } @@ -1432,7 +1407,7 @@ void mlacp_peer_disconn_handler(struct CSM* csm) /*peer connection must be establised again within 90s from last disconnection for peer warm reboot*/ time(&csm->warm_reboot_disconn_time); - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer warm reboot and disconnect, recover to normal reboot for next time!"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot and disconnect, recover to normal reboot for next time!"); return; } @@ -1448,7 +1423,7 @@ void mlacp_peer_disconn_handler(struct CSM* csm) if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0 && mac_msg->age_flag != (MAC_AGE_LOCAL | MAC_AGE_PEER)) continue; - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer disconnect, del MAC for peer-link: %s, MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer disconnect, del MAC for peer-link: %s, MAC %s vlan-id %d", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); /*Send mac del message to mclagsyncd, may be already deleted*/ @@ -1493,7 +1468,7 @@ void mlacp_peerlink_up_handler(struct CSM* csm) if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0) continue; - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer link up, add MAC to ASIC for peer-link: %s, MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer link up, add MAC to ASIC for peer-link: %s, MAC %s vlan-id %d", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); /*Send mac add message to mclagsyncd, local age flag is already set*/ @@ -1520,7 +1495,7 @@ void mlacp_peerlink_down_handler(struct CSM* csm) if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0) continue; - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer link down, del MAC for peer-link: %s, MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer link down, del MAC for peer-link: %s, MAC %s vlan-id %d", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1); @@ -1686,17 +1661,7 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch mac_msg->age_flag = 0; - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC msg from mclagsyncd, vid %d mac %s port %s optype %s ", vid, mac_str, ifname, op_type == MAC_SYNC_ADD ? "add" : "del"); - /*Debug*/ - #if 0 - /* dump receive MAC info*/ - fprintf(stderr, "\n======== MAC Update==========\n"); - fprintf(stderr, " MAC = %s\n", mac_str); - fprintf(stderr, " vlan id = %d\n", vid); - fprintf(stderr, " fdb type = %s\n", fdb_type == MAC_TYPE_STATIC ? "static" : "dynamic"); - fprintf(stderr, " op type = %s\n", op_type == MAC_SYNC_ADD ? "add" : "del"); - fprintf(stderr, "==============================\n"); - #endif + ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC msg from mclagsyncd, vid %d mac %s port %s optype %s ", vid, mac_str, ifname, op_type == MAC_SYNC_ADD ? "add" : "del"); /* Find MLACP itf, may be mclag enabled port-channel*/ LIST_FOREACH(csm, &(sys->csm_list), next) @@ -1868,7 +1833,7 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch /*peer-link learn mac is control by iccpd, ignore the chip del info*/ add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC); - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s(peer-link is up), add back %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC del msg: %s(peer-link is up), add back %s vlan-id %d", mac_info->ifname, mac_info->mac_str, mac_info->vid); } @@ -1890,7 +1855,7 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch } else { - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s, del %s vlan-id %d, peer is not age, add back to chip", + ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC del msg: %s, del %s vlan-id %d, peer is not age, add back to chip", mac_info->ifname, mac_info->mac_str, mac_info->vid); mac_info->fdb_type = MAC_TYPE_DYNAMIC; @@ -1905,7 +1870,7 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP) { add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC); - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s(down), del %s vlan-id %d, redirect to peer-link", + ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC del msg: %s(down), del %s vlan-id %d, redirect to peer-link", mac_info->ifname, mac_info->mac_str, mac_info->vid); } } @@ -1984,6 +1949,9 @@ char * mclagd_ctl_cmd_str(int req_type) case INFO_TYPE_DUMP_ARP: return "dump arp"; + case INFO_TYPE_DUMP_NDISC: + return "dump nd"; + case INFO_TYPE_DUMP_MAC: return "dump mac"; @@ -2205,6 +2173,46 @@ void mclagd_ctl_handle_dump_arp(int client_fd, int mclag_id) return; } +void mclagd_ctl_handle_dump_ndisc(int client_fd, int mclag_id) +{ + char *Pbuf = NULL; + char buf[512] = { 0 }; + int ndisc_num = 0; + int ret = 0; + struct mclagd_reply_hdr *hd = NULL; + int len_tmp = 0; + + ret = iccp_ndisc_dump(&Pbuf, &ndisc_num, mclag_id); + if (ret != EXEC_TYPE_SUCCESS) + { + len_tmp = sizeof(struct mclagd_reply_hdr); + memcpy(buf, &len_tmp, sizeof(int)); + hd = (struct mclagd_reply_hdr *)(buf + sizeof(int)); + hd->exec_result = ret; + hd->info_type = INFO_TYPE_DUMP_NDISC; + hd->data_len = 0; + mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR); + + if (Pbuf) + free(Pbuf); + + return; + } + + hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int)); + hd->exec_result = EXEC_TYPE_SUCCESS; + hd->info_type = INFO_TYPE_DUMP_NDISC; + hd->data_len = ndisc_num * sizeof(struct mclagd_ndisc_msg); + len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr)); + memcpy(Pbuf, &len_tmp, sizeof(int)); + mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len); + + if (Pbuf) + free(Pbuf); + + return; +} + void mclagd_ctl_handle_dump_mac(int client_fd, int mclag_id) { char * Pbuf = NULL; @@ -2375,6 +2383,10 @@ int mclagd_ctl_interactive_process(int client_fd) mclagd_ctl_handle_dump_arp(client_fd, req->mclag_id); break; + case INFO_TYPE_DUMP_NDISC: + mclagd_ctl_handle_dump_ndisc(client_fd, req->mclag_id); + break; + case INFO_TYPE_DUMP_MAC: mclagd_ctl_handle_dump_mac(client_fd, req->mclag_id); break; diff --git a/src/iccpd/src/mlacp_sync_prepare.c b/src/iccpd/src/mlacp_sync_prepare.c index f40a59884e4..a278af51928 100644 --- a/src/iccpd/src/mlacp_sync_prepare.c +++ b/src/iccpd/src/mlacp_sync_prepare.c @@ -326,7 +326,7 @@ int mlacp_prepare_for_mac_info_to_peer(struct CSM* csm, char* buf, size_t max_bu sprintf(MacData->ifname, "%s", mac_msg->origin_ifname); MacData->vid = htons(mac_msg->vid); - ICCPD_LOG_DEBUG(__FUNCTION__, "Send MAC messge to peer, port %s mac = %s, vid = %d, type = %s count %d ", mac_msg->origin_ifname, + ICCPD_LOG_NOTICE(__FUNCTION__, "Send MAC messge to peer, port %s mac = %s, vid = %d, type = %s count %d ", mac_msg->origin_ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type == MAC_SYNC_ADD ? "add" : "del", count); return msg_len; @@ -374,11 +374,64 @@ int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, ArpData->op_type = arp_msg->op_type; sprintf(ArpData->ifname, "%s", arp_msg->ifname); - ArpData->ipv4_addr = htonl(arp_msg->ipv4_addr); + ArpData->ipv4_addr = arp_msg->ipv4_addr; memcpy(ArpData->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN); - ICCPD_LOG_DEBUG(__FUNCTION__, "Send ARP messge to peer, if name %s mac %02x:%02x:%02x:%02x:%02x:%02x IP %s", ArpData->ifname, ArpData->mac_addr[0], ArpData->mac_addr[1], ArpData->mac_addr[2], - ArpData->mac_addr[3], ArpData->mac_addr[4], ArpData->mac_addr[5], show_ip_str( ArpData->ipv4_addr)); + ICCPD_LOG_NOTICE(__FUNCTION__, "Send ARP messge to peer, if name %s mac %02x:%02x:%02x:%02x:%02x:%02x IP %s", ArpData->ifname, ArpData->mac_addr[0], ArpData->mac_addr[1], ArpData->mac_addr[2], + ArpData->mac_addr[3], ArpData->mac_addr[4], ArpData->mac_addr[5], show_ip_str(ArpData->ipv4_addr)); + + return msg_len; +} + +/***************************************** +* Preprare Sync NDISC-Info TLV +* +* ***************************************/ +int mlacp_prepare_for_ndisc_info(struct CSM *csm, char *buf, size_t max_buf_size, struct NDISCMsg *ndisc_msg, int count) +{ + + struct mLACPNDISCInfoTLV *tlv = NULL; + size_t msg_len = 0; + size_t tlv_len = 0; + ICCHdr *icc_hdr = NULL; + struct NDISCMsg *NdiscData; + + if (!csm) + return -1; + if (!buf) + return -1; + + tlv_len = sizeof(struct mLACPNDISCInfoTLV) + sizeof(struct NDISCMsg) * (count + 1); + + if ((msg_len = sizeof(ICCHdr) + tlv_len) > max_buf_size) + return -1; + + /* ICC header */ + icc_hdr = (ICCHdr *)buf; + mlacp_fill_icc_header(csm, icc_hdr, msg_len); + + /* Prepare for ND information TLV */ + tlv = (struct mLACPNDISCInfoTLV *)&buf[sizeof(ICCHdr)]; + tlv->icc_parameter.len = htons(tlv_len - sizeof(ICCParameter)); + tlv->num_of_entry = htons(count + 1); + + if (count == 0) + { + tlv->icc_parameter.u_bit = 0; + tlv->icc_parameter.f_bit = 0; + tlv->icc_parameter.type = htons(TLV_T_MLACP_NDISC_INFO); + } + + NdiscData = (struct mLACPMACData *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPNDISCInfoTLV) + sizeof(struct NDISCMsg) * count]; + + NdiscData->op_type = ndisc_msg->op_type; + sprintf(NdiscData->ifname, "%s", ndisc_msg->ifname); + memcpy(NdiscData->ipv6_addr, ndisc_msg->ipv6_addr, 32); + memcpy(NdiscData->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN); + + ICCPD_LOG_NOTICE(__FUNCTION__, "Send ND messge to peer, if name %s mac =%02x:%02x:%02x:%02x:%02x:%02x IPv6 %s", NdiscData->ifname, + NdiscData->mac_addr[0], NdiscData->mac_addr[1], NdiscData->mac_addr[2], NdiscData->mac_addr[3], NdiscData->mac_addr[4], + NdiscData->mac_addr[5], show_ipv6_str((char *)NdiscData->ipv6_addr)); return msg_len; } @@ -597,7 +650,7 @@ int mlacp_prepare_for_warm_reboot(struct CSM* csm, char* buf, size_t max_buf_siz tlv->icc_parameter.len = htons(sizeof(struct mLACPWarmbootTLV) - sizeof(ICCParameter)); tlv->warmboot = 0x1; - ICCPD_LOG_DEBUG(__FUNCTION__, "Send warm reboot notification to peer!"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Send warm reboot notification to peer!"); return msg_len; } diff --git a/src/iccpd/src/mlacp_sync_update.c b/src/iccpd/src/mlacp_sync_update.c index 40dc3318788..b82fc1c16cb 100644 --- a/src/iccpd/src/mlacp_sync_update.c +++ b/src/iccpd/src/mlacp_sync_update.c @@ -33,6 +33,7 @@ #include "../include/mlacp_link_handler.h" #include "../include/iccp_consistency_check.h" #include "../include/port.h" +#include "../include/iccp_netlink.h" /***************************************** * Port-Conf Update * @@ -166,7 +167,7 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * struct LocalInterface* local_if = NULL; uint8_t from_mclag_intf = 0;/*0: orphan port, 1: MCLAG port*/ - ICCPD_LOG_INFO(__FUNCTION__, + ICCPD_LOG_NOTICE(__FUNCTION__, "Received MAC Info, port[%s] vid[%d] MAC[%s] type[%s]", MacData->ifname, ntohs(MacData->vid), MacData->mac_str, MacData->type == MAC_SYNC_ADD ? "add" : "del"); @@ -266,27 +267,7 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC); } } - - #if 0 - mac_msg->op_type = MAC_SYNC_ACK; - if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0) - { - /*Reply mac ack message to peer, peer will clean MAC_AGE_PEER flag*/ - TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail); - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv ADD, MAC-msg-list enqueue: %s, add %s vlan-id %d, op_type %d", - mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type); - } - #endif - } - #if 0 - else if (tlv->type == MAC_SYNC_ACK) - { - /*Clean the MAC_AGE_PEER flag*/ - mac_msg->age_flag &= ~MAC_AGE_PEER; - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv ACK, Remove peer age flag:%d ifname %s, add %s vlan-id %d, op_type %d", - mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type); } - #endif break; } @@ -332,7 +313,7 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * if (strlen(csm->peer_itf_name) == 0) { - ICCPD_LOG_DEBUG(__FUNCTION__, "From orphan port or portchannel is down, but peer-link is not configured: ifname %s, MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "From orphan port or portchannel is down, but peer-link is not configured: ifname %s, MAC %s vlan-id %d", mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); /*if orphan port mac but no peerlink, don't keep this mac*/ @@ -344,7 +325,7 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * /*Redirect the mac to peer-link*/ memcpy(&mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); - ICCPD_LOG_DEBUG(__FUNCTION__, "Redirect to peerlink for orphan port or portchannel is down, Add local age flag: %d ifname %s, MAC %s vlan-id %d", + ICCPD_LOG_NOTICE(__FUNCTION__, "Redirect to peerlink for orphan port or portchannel is down, Add local age flag: %d ifname %s, MAC %s vlan-id %d", mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid); } } @@ -371,17 +352,6 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * /*from MCLAG port and the local port is up*/ add_mac_to_chip(mac_msg, mac_msg->fdb_type); } - - #if 0 - mac_msg->op_type = MAC_SYNC_ACK; - if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0) - { - /*Reply mac ack message to peer, peer will clean MAC_AGE_PEER flag*/ - TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail); - ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, op_type %d", - mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type); - } - #endif } } @@ -422,7 +392,7 @@ void mlacp_enqueue_arp(struct CSM* csm, struct Msg* msg) return; arp_msg = (struct ARPMsg*)msg->buf; - if (arp_msg->op_type != ARP_SYNC_DEL) + if (arp_msg->op_type != NEIGH_SYNC_DEL) { TAILQ_INSERT_TAIL(&(MLACP(csm).arp_list), msg, tail); } @@ -430,6 +400,32 @@ void mlacp_enqueue_arp(struct CSM* csm, struct Msg* msg) return; } +/***************************************** + * Tool : Add Ndisc Info into ndisc list + * + ****************************************/ +void mlacp_enqueue_ndisc(struct CSM *csm, struct Msg *msg) +{ + struct NDISCMsg *ndisc_msg = NULL; + + if (!csm) + { + if (msg) + free(msg); + return; + } + if (!msg) + return; + + ndisc_msg = (struct NDISCMsg *)msg->buf; + if (ndisc_msg->op_type != NEIGH_SYNC_DEL) + { + TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_list), msg, tail); + } + + return; +} + /***************************************** * ARP-Info Update * ***************************************/ @@ -449,7 +445,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", arp_entry->mac_addr[0], arp_entry->mac_addr[1], arp_entry->mac_addr[2], arp_entry->mac_addr[3], arp_entry->mac_addr[4], arp_entry->mac_addr[5]); - ICCPD_LOG_INFO(__FUNCTION__, + ICCPD_LOG_NOTICE(__FUNCTION__, "Received ARP Info, intf[%s] IP[%s], MAC[%02x:%02x:%02x:%02x:%02x:%02x]", arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), arp_entry->mac_addr[0], arp_entry->mac_addr[1], arp_entry->mac_addr[2], @@ -537,9 +533,9 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) /* set dynamic ARP*/ if (set_arp_flag == 1) { - if (arp_entry->op_type == ARP_SYNC_ADD) + if (arp_entry->op_type == NEIGH_SYNC_ADD) { - if (mlacp_fsm_arp_set(arp_entry->ifname, ntohl(arp_entry->ipv4_addr), mac_str) < 0) + if (iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_entry->ipv4_addr, 1, arp_entry->mac_addr, arp_entry->ifname) < 0) { ICCPD_LOG_WARN(__FUNCTION__, "ARP add failure for %s %s %s", arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str); @@ -548,7 +544,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) } else { - if (mlacp_fsm_arp_del(arp_entry->ifname, ntohl(arp_entry->ipv4_addr)) < 0) + if (iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_entry->ipv4_addr, 0, arp_entry->mac_addr, arp_entry->ifname) < 0) { ICCPD_LOG_WARN(__FUNCTION__, "ARP delete failure for %s %s %s", arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str); @@ -561,7 +557,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) } else { - ICCPD_LOG_DEBUG(__FUNCTION__, "Failure: port-channel is not alive"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Failure: port-channel is not alive"); /*TODO Set static route through peer-link or just skip it?*/ } @@ -569,7 +565,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) TAILQ_FOREACH(msg, &(MLACP(csm).arp_list), tail) { arp_msg = (struct ARPMsg*)msg->buf; - if (arp_msg->ipv4_addr == ntohl(arp_entry->ipv4_addr)) + if (arp_msg->ipv4_addr == arp_entry->ipv4_addr) { /*arp_msg->op_type = tlv->type;*/ sprintf(arp_msg->ifname, "%s", arp_entry->ifname); @@ -579,18 +575,18 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) } /* delete/add ARP list*/ - if (msg && arp_entry->op_type == ARP_SYNC_DEL) + if (msg && arp_entry->op_type == NEIGH_SYNC_DEL) { TAILQ_REMOVE(&(MLACP(csm).arp_list), msg, tail); free(msg->buf); free(msg); /*ICCPD_LOG_INFO(__FUNCTION__, "Del arp queue successfully");*/ } - else if (!msg && arp_entry->op_type == ARP_SYNC_ADD) + else if (!msg && arp_entry->op_type == NEIGH_SYNC_ADD) { arp_msg = (struct ARPMsg*)&arp_data; sprintf(arp_msg->ifname, "%s", arp_entry->ifname); - arp_msg->ipv4_addr = ntohl(arp_entry->ipv4_addr); + arp_msg->ipv4_addr = arp_entry->ipv4_addr; arp_msg->op_type = arp_entry->op_type; memcpy(arp_msg->mac_addr, arp_entry->mac_addr, ETHER_ADDR_LEN); if (iccp_csm_init_msg(&msg, (char*)arp_msg, sizeof(struct ARPMsg)) == 0) @@ -604,7 +600,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) TAILQ_FOREACH(msg, &(MLACP(csm).arp_msg_list), tail) { arp_msg = (struct ARPMsg*)msg->buf; - if (arp_msg->ipv4_addr == ntohl(arp_entry->ipv4_addr)) + if (arp_msg->ipv4_addr == arp_entry->ipv4_addr) break; } @@ -617,7 +613,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) TAILQ_FOREACH(msg, &(MLACP(csm).arp_msg_list), tail) { arp_msg = (struct ARPMsg*)msg->buf; - if (arp_msg->ipv4_addr == ntohl(arp_entry->ipv4_addr)) + if (arp_msg->ipv4_addr == arp_entry->ipv4_addr) break; } } @@ -641,6 +637,216 @@ int mlacp_fsm_update_arp_info(struct CSM* csm, struct mLACPARPInfoTLV* tlv) } } +/***************************************** +* NDISC-Info Update +* ***************************************/ +int mlacp_fsm_update_ndisc_entry(struct CSM *csm, struct NDISCMsg *ndisc_entry) +{ + struct Msg *msg = NULL; + struct NDISCMsg *ndisc_msg = NULL, ndisc_data; + struct LocalInterface *local_if; + struct LocalInterface *peer_link_if = NULL; + struct VLAN_ID *vlan_id_list = NULL; + int set_ndisc_flag = 0; + char mac_str[18] = ""; + + if (!csm || !ndisc_entry) + return MCLAG_ERROR; + + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", ndisc_entry->mac_addr[0], ndisc_entry->mac_addr[1], ndisc_entry->mac_addr[2], + ndisc_entry->mac_addr[3], ndisc_entry->mac_addr[4], ndisc_entry->mac_addr[5]); + + ICCPD_LOG_NOTICE(__FUNCTION__, + "Received ND Info, intf[%s] IP[%s], MAC[%s]", ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str); + + if (strncmp(ndisc_entry->ifname, "Vlan", 4) == 0) + { + peer_link_if = local_if_find_by_name(csm->peer_itf_name); + + if (peer_link_if && !local_if_is_l3_mode(peer_link_if)) + { + /* Is peer-linlk itf belong to a vlan the same as peer? */ + LIST_FOREACH(vlan_id_list, &(peer_link_if->vlan_list), port_next) + { + if (!vlan_id_list->vlan_itf) + continue; + if (strcmp(vlan_id_list->vlan_itf->name, ndisc_entry->ifname) != 0) + continue; + if (!local_if_is_l3_mode(vlan_id_list->vlan_itf)) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, + "ND is learnt from intf %s, peer-link %s is the member of this vlan", + vlan_id_list->vlan_itf->name, peer_link_if->name); + + /* Peer-link belong to L3 vlan is alive, set the NDISC info */ + set_ndisc_flag = 1; + + break; + } + } + } + + if (set_ndisc_flag == 0) + { + LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next) + { + if (local_if->type == IF_T_PORT_CHANNEL) + { + if (!local_if_is_l3_mode(local_if)) + { + /* Is the L2 MLAG itf belong to a vlan the same as peer? */ + LIST_FOREACH(vlan_id_list, &(local_if->vlan_list), port_next) + { + if (!vlan_id_list->vlan_itf) + continue; + if (strcmp(vlan_id_list->vlan_itf->name, ndisc_entry->ifname) != 0) + continue; + if (!local_if_is_l3_mode(vlan_id_list->vlan_itf)) + continue; + + ICCPD_LOG_DEBUG(__FUNCTION__, + "ND is learnt from intf %s, %s is the member of this vlan", vlan_id_list->vlan_itf->name, local_if->name); + break; + } + + if (vlan_id_list && local_if->po_active == 1) + { + /* Any po of L3 vlan is alive, set the NDISC info */ + set_ndisc_flag = 1; + break; + } + } + else + { + /* Is the ARP belong to a L3 mode MLAG itf? */ + if (strcmp(local_if->name, ndisc_entry->ifname) == 0) + { + ICCPD_LOG_DEBUG(__FUNCTION__, "ND is learnt from mclag L3 intf %s", local_if->name); + if (local_if->po_active == 1) + { + /* po is alive, set the NDISC info */ + set_ndisc_flag = 1; + break; + } + } + else + { + continue; + } + } + } + } + } + + /* set dynamic Ndisc */ + if (set_ndisc_flag == 1) + { + if (ndisc_entry->op_type == NEIGH_SYNC_ADD) + { + if (iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_entry->ipv6_addr, 1, ndisc_entry->mac_addr, ndisc_entry->ifname) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to add nd entry(%s %s %s) to kernel", + ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str); + return MCLAG_ERROR; + } + + } + else + { + if (iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_entry->ipv6_addr, 0, ndisc_entry->mac_addr, ndisc_entry->ifname) < 0) + { + ICCPD_LOG_WARN(__FUNCTION__, "Failed to delete nd entry(%s %s %s) from kernel", + ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str); + return MCLAG_ERROR; + } + + } + + /* ICCPD_LOG_DEBUG(__FUNCTION__, "NDISC update for %s %s %s", ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str); */ + } + else + { + ICCPD_LOG_DEBUG(__FUNCTION__, "Failure: port-channel is not alive"); + /* TODO Set static route through peer-link or just skip it? */ + } + + /* update NDISC list */ + TAILQ_FOREACH(msg, &(MLACP(csm).ndisc_list), tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + if (memcmp((char *)ndisc_msg->ipv6_addr, (char *)ndisc_entry->ipv6_addr, 16) == 0) + { + /* ndisc_msg->op_type = tlv->type; */ + sprintf(ndisc_msg->ifname, "%s", ndisc_entry->ifname); + memcpy(ndisc_msg->mac_addr, ndisc_entry->mac_addr, ETHER_ADDR_LEN); + break; + } + } + + /* delete/add NDISC list */ + if (msg && ndisc_entry->op_type == NEIGH_SYNC_DEL) + { + TAILQ_REMOVE(&(MLACP(csm).ndisc_list), msg, tail); + free(msg->buf); + free(msg); + /* ICCPD_LOG_INFO(__FUNCTION__, "Del ndisc queue successfully"); */ + } + else if (!msg && ndisc_entry->op_type == NEIGH_SYNC_ADD) + { + ndisc_msg = (struct NDISCMsg *)&ndisc_data; + sprintf(ndisc_msg->ifname, "%s", ndisc_entry->ifname); + memcpy((char *)ndisc_msg->ipv6_addr, (char *)ndisc_entry->ipv6_addr, 16); + ndisc_msg->op_type = ndisc_entry->op_type; + memcpy(ndisc_msg->mac_addr, ndisc_entry->mac_addr, ETHER_ADDR_LEN); + if (iccp_csm_init_msg(&msg, (char *)ndisc_msg, sizeof(struct NDISCMsg)) == 0) + { + mlacp_enqueue_ndisc(csm, msg); + /* ICCPD_LOG_INFO(__FUNCTION__, "Add ndisc queue successfully"); */ + } + } + + /* remove all NDISC msg queue, when receive peer's NDISC list at the same time */ + TAILQ_FOREACH(msg, &(MLACP(csm).ndisc_msg_list), tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + if (memcmp((char *)ndisc_msg->ipv6_addr, (char *)ndisc_entry->ipv6_addr, 16) == 0) + break; + } + + while (msg) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + TAILQ_REMOVE(&(MLACP(csm).ndisc_msg_list), msg, tail); + free(msg->buf); + free(msg); + TAILQ_FOREACH(msg, &(MLACP(csm).ndisc_msg_list), tail) + { + ndisc_msg = (struct NDISCMsg *)msg->buf; + if (memcmp((char *)ndisc_msg->ipv6_addr, (char *)ndisc_entry->ipv6_addr, 16) == 0) + break; + } + } + + return 0; +} + +int mlacp_fsm_update_ndisc_info(struct CSM *csm, struct mLACPNDISCInfoTLV *tlv) +{ + int count = 0; + int i; + + if (!csm || !tlv) + return MCLAG_ERROR; + count = ntohs(tlv->num_of_entry); + ICCPD_LOG_INFO(__FUNCTION__, "Received NDISC Info count %d ", count); + + for (i = 0; i < count; i++) + { + mlacp_fsm_update_ndisc_entry(csm, &(tlv->NdiscEntry[i])); + } +} + /***************************************** * Port-Channel-Info Update * ***************************************/ @@ -703,10 +909,10 @@ int mlacp_fsm_update_peerlink_info(struct CSM* csm, } if (csm->peer_link_if->type != tlv->port_type) - ICCPD_LOG_DEBUG(__FUNCTION__, "Peerlink port type of peer %d is not same with local %d !", tlv->port_type, csm->peer_link_if->type); + ICCPD_LOG_NOTICE(__FUNCTION__, "Peerlink port type of peer %d is not same with local %d !", tlv->port_type, csm->peer_link_if->type); if (tlv->port_type == IF_T_VXLAN && strncmp(csm->peer_itf_name, tlv->if_name, strlen(csm->peer_itf_name))) - ICCPD_LOG_DEBUG(__FUNCTION__, "Peerlink port is vxlan port, but peerlink port of peer %s is not same with local %s !", tlv->if_name, csm->peer_itf_name); + ICCPD_LOG_NOTICE(__FUNCTION__, "Peerlink port is vxlan port, but peerlink port of peer %s is not same with local %s !", tlv->if_name, csm->peer_itf_name); return 0; } @@ -733,7 +939,7 @@ int mlacp_fsm_update_warmboot(struct CSM* csm, struct mLACPWarmbootTLV* tlv) return MCLAG_ERROR; time(&csm->peer_warm_reboot_time); - ICCPD_LOG_DEBUG(__FUNCTION__, "Receive warm reboot notification from peer!"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Receive warm reboot notification from peer!"); return 0; } diff --git a/src/iccpd/src/port.c b/src/iccpd/src/port.c index 1414a1f86c8..ce23515a00c 100644 --- a/src/iccpd/src/port.c +++ b/src/iccpd/src/port.c @@ -329,11 +329,12 @@ void local_if_destroy(char *ifname) int local_if_is_l3_mode(struct LocalInterface* local_if) { int ret = 0; + char addr_null[16] = { 0 }; if (local_if == NULL) return 0; - if (local_if->ipv4_addr != 0) + if (local_if->ipv4_addr != 0 || memcmp(local_if->ipv6_addr, addr_null, 16) != 0) ret = 1; return ret; diff --git a/src/iccpd/src/scheduler.c b/src/iccpd/src/scheduler.c index 9d08e137dce..c1a1532ccfe 100644 --- a/src/iccpd/src/scheduler.c +++ b/src/iccpd/src/scheduler.c @@ -312,7 +312,7 @@ void scheduler_init() iccp_config_from_file(sys->config_file_path); /*Get kernel ARP info */ - iccp_arp_get_init(); + iccp_neigh_get_init(); if (iccp_connect_syncd() < 0) { diff --git a/src/iccpd/src/system.c b/src/iccpd/src/system.c index 9665b416ca5..33aca67f807 100644 --- a/src/iccpd/src/system.c +++ b/src/iccpd/src/system.c @@ -57,6 +57,7 @@ void system_init(struct System* sys) sys->sync_fd = -1; sys->sync_ctrl_fd = -1; sys->arp_receive_fd = -1; + sys->ndisc_receive_fd = -1; sys->epoll_fd = -1; sys->family = -1; sys->warmboot_start = 0; @@ -132,6 +133,8 @@ void system_finalize() close(sys->sync_ctrl_fd); if (sys->arp_receive_fd > 0) close(sys->arp_receive_fd); + if (sys->ndisc_receive_fd > 0) + close(sys->ndisc_receive_fd); if (sys->sig_pipe_r > 0) close(sys->sig_pipe_r); if (sys->sig_pipe_w > 0) From 00383051f434aca23cf7d02c1db160479a7ac4d6 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 29 Apr 2020 22:45:46 -0700 Subject: [PATCH 27/69] [docker-iccpd]: disable iccpd build by default (#4502) Signed-off-by: Guohan Lu --- rules/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/config b/rules/config index c893a580b67..ab8a6941426 100644 --- a/rules/config +++ b/rules/config @@ -117,7 +117,7 @@ DEFAULT_VS_PREPARE_MEM = yes # ENABLE_ICCPD - build docker-iccpd for mclag support -ENABLE_ICCPD = y +ENABLE_ICCPD = n # ENABLE_SYSTEM_SFLOW - build docker-sonic-sflow for sFlow support ENABLE_SFLOW = y From a539cf2f4694190a631f848e67da57f1c52b306d Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 30 Apr 2020 05:58:03 +0000 Subject: [PATCH 28/69] [build]: remove -t for non-tty terminal Signed-off-by: Guohan Lu --- Makefile.work | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.work b/Makefile.work index d9703000ddb..ca98222c169 100644 --- a/Makefile.work +++ b/Makefile.work @@ -259,7 +259,7 @@ sonic-slave-run : @docker inspect --type image $(SLAVE_IMAGE):$(SLAVE_TAG) &> /dev/null || \ { echo Image $(SLAVE_IMAGE):$(SLAVE_TAG) not found. Building... ; \ $(DOCKER_BUILD) ; } - @$(DOCKER_RUN) -t $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_RUN_CMDS)" + @$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_RUN_CMDS)" showtag: @echo $(SLAVE_IMAGE):$(SLAVE_TAG) From e1ba5b0f5fa64b2eecebf9056f2cd075428ceaf6 Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Thu, 30 Apr 2020 00:25:49 -0700 Subject: [PATCH 29/69] [docker-restapi]: add restapi config to config Db (#4495) --- rules/docker-restapi.mk | 2 +- src/sonic-config-engine/minigraph.py | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk index b472e00491d..bd91aabd86c 100644 --- a/rules/docker-restapi.mk +++ b/rules/docker-restapi.mk @@ -19,7 +19,7 @@ endif $(DOCKER_RESTAPI)_CONTAINER_NAME = restapi $(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t $(DOCKER_RESTAPI)_RUN_OPT += -v /var/run/redis/redis.sock:/var/run/redis/redis.sock -$(DOCKER_RESTAPI)_RUN_OPT += -v /etc/sonic/certificates:/etc/sonic/certificates:ro +$(DOCKER_RESTAPI)_RUN_OPT += -v /etc/sonic/credentials:/etc/sonic/credentials:ro $(DOCKER_RESTAPI)_RUN_OPT += -p=8081:8081/tcp $(DOCKER_RESTAPI)_RUN_OPT += -p=8090:8090/tcp diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 71f6bb9fc72..8f91fbe5c31 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -836,7 +836,19 @@ def parse_xml(filename, platform=None, port_config_file=None): 'ca_crt': '/etc/sonic/telemetry/dsmsroot.cer' } } - + results['RESTAPI'] = { + 'config': { + 'client_auth': 'true', + 'allow_insecure': 'false', + 'log_level': 'trace' + }, + 'certs': { + 'server_crt': '/etc/sonic/credentials/restapiserver.crt', + 'server_key': '/etc/sonic/credentials/restapiserver.key', + 'client_ca_crt': '/etc/sonic/credentials/restapiclient.crt', + 'client_crt_cname': 'client.restapi.sonic' + } + } # Do not configure the minigraph's mirror session, which is currently unused # mirror_sessions = {} # if erspan_dst: From b6291372d98e47f9aaa5dd6c393ee4e02d3aa1ac Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Thu, 30 Apr 2020 10:30:11 +0300 Subject: [PATCH 30/69] [Mellanox] Add a new Mellanox platform x86_64-mlnx_msn4600c and new SKU ACS-MSN4600C (#4483) * New SKU support for MSN4600C Signed-off-by: Shlomi Bitton --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 2 +- .../ACS-MSN4600C/buffers.json.j2 | 1 + .../ACS-MSN4600C/buffers_defaults_t0.j2 | 1 + .../ACS-MSN4600C/buffers_defaults_t1.j2 | 1 + .../ACS-MSN4600C/pg_profile_lookup.ini | 1 + .../ACS-MSN4600C/port_config.ini | 65 +++ .../ACS-MSN4600C/qos.json.j2 | 1 + .../ACS-MSN4600C/sai.profile | 1 + .../ACS-MSN4600C/sai_4600C.xml | 470 ++++++++++++++++++ .../x86_64-mlnx_msn4600c-r0/default_sku | 1 + .../platform_components.json | 12 + .../x86_64-mlnx_msn4600c-r0/platform_reboot | 1 + .../x86_64-mlnx_msn4600c-r0/platform_wait | 1 + .../x86_64-mlnx_msn4600c-r0/plugins/eeprom.py | 1 + .../plugins/psuutil.py | 1 + .../plugins/sfplpmget.py | 1 + .../plugins/sfplpmset.py | 1 + .../plugins/sfpreset.py | 1 + .../plugins/sfputil.py | 1 + .../pmon_daemon_control.json | 1 + .../x86_64-mlnx_msn4600c-r0/sensors.conf | 193 +++++++ .../sonic_platform/chassis.py | 2 +- .../mlnx-platform-api/sonic_platform/psu.py | 2 +- .../sonic_platform/thermal.py | 18 +- 24 files changed, 776 insertions(+), 4 deletions(-) create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers.json.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t0.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t1.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/qos.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai.profile create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai_4600C.xml create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/default_sku create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/platform_reboot create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/platform_wait create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/eeprom.py create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/psuutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmget.py create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmset.py create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfpreset.py create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfputil.py create mode 120000 device/mellanox/x86_64-mlnx_msn4600c-r0/pmon_daemon_control.json create mode 100644 device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 9e5ca408326..647d967f84a 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -41,7 +41,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5} +hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5, 'ACS-MSN4600C': 4} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1), (0, 48, 59, 60, 1)] def log_info(msg, also_print_to_console=False): diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers.json.j2 new file mode 120000 index 00000000000..f46e9600153 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t0.j2 new file mode 120000 index 00000000000..ddb883a1daa --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t1.j2 new file mode 120000 index 00000000000..f8bbb6e631e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/pg_profile_lookup.ini new file mode 120000 index 00000000000..88e51ceae04 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/pg_profile_lookup.ini @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini new file mode 100644 index 00000000000..7ccff5a8da4 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini @@ -0,0 +1,65 @@ +# name lanes alias index +Ethernet0 0,1,2,3 etp1 0 +Ethernet8 8,9,10,11 etp2 1 +Ethernet16 16,17,18,19 etp3 2 +Ethernet24 24,25,26,27 etp4 3 +Ethernet32 32,33,34,35 etp5 4 +Ethernet40 40,41,42,43 etp6 5 +Ethernet48 48,49,50,51 etp7 6 +Ethernet56 56,57,58,59 etp8 7 +Ethernet64 64,65,66,67 etp9 8 +Ethernet72 72,73,74,75 etp10 9 +Ethernet80 80,81,82,83 etp11 10 +Ethernet88 88,89,90,91 etp12 11 +Ethernet96 96,97,98,99 etp13 12 +Ethernet104 104,105,106,107 etp14 13 +Ethernet112 112,113,114,115 etp15 14 +Ethernet120 120,121,122,123 etp16 15 +Ethernet128 128,129,130,131 etp17 16 +Ethernet136 136,137,138,139 etp18 17 +Ethernet144 144,145,146,147 etp19 18 +Ethernet152 152,153,154,155 etp20 19 +Ethernet160 160,161,162,163 etp21 20 +Ethernet168 168,169,170,171 etp22 21 +Ethernet176 176,177,178,179 etp23 22 +Ethernet184 184,185,186,187 etp24 23 +Ethernet192 192,193,194,195 etp25 24 +Ethernet200 200,201,202,203 etp26 25 +Ethernet208 208,209,210,211 etp27 26 +Ethernet216 216,217,218,219 etp28 27 +Ethernet224 224,225,226,227 etp29 28 +Ethernet232 232,233,234,235 etp30 29 +Ethernet240 240,241,242,243 etp31 30 +Ethernet248 248,249,250,251 etp32 31 +Ethernet256 256,257,258,259 etp33 32 +Ethernet264 264,265,266,267 etp34 33 +Ethernet272 272,273,274,275 etp35 34 +Ethernet280 280,281,282,283 etp36 35 +Ethernet288 288,289,290,291 etp37 36 +Ethernet296 296,297,298,299 etp38 37 +Ethernet304 304,305,306,307 etp39 38 +Ethernet312 312,313,314,315 etp40 39 +Ethernet320 320,321,322,323 etp41 40 +Ethernet328 328,329,330,331 etp42 41 +Ethernet336 336,337,338,339 etp43 42 +Ethernet344 344,345,346,347 etp44 43 +Ethernet352 352,353,354,355 etp45 44 +Ethernet360 360,361,362,363 etp46 45 +Ethernet368 368,369,370,371 etp47 46 +Ethernet376 376,377,378,379 etp48 47 +Ethernet384 384,385,386,387 etp49 48 +Ethernet392 392,393,394,395 etp50 49 +Ethernet400 400,401,402,403 etp51 50 +Ethernet408 408,409,410,411 etp52 51 +Ethernet416 416,417,418,419 etp53 52 +Ethernet424 424,425,426,427 etp54 53 +Ethernet432 432,433,434,435 etp55 54 +Ethernet440 440,441,442,443 etp56 55 +Ethernet448 448,449,450,451 etp57 56 +Ethernet456 456,457,458,459 etp58 57 +Ethernet464 464,465,466,467 etp59 58 +Ethernet472 472,473,474,475 etp60 59 +Ethernet480 480,481,482,483 etp61 60 +Ethernet488 488,489,490,491 etp62 61 +Ethernet496 496,497,498,499 etp63 62 +Ethernet504 504,505,506,507 etp64 63 diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/qos.json.j2 new file mode 120000 index 00000000000..8633303ece7 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/qos.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai.profile b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai.profile new file mode 100644 index 00000000000..e9d1e3e5f59 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4600C.xml diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai_4600C.xml b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai_4600C.xml new file mode 100644 index 00000000000..02d0ed6ccd8 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/sai_4600C.xml @@ -0,0 +1,470 @@ + + + + + + 00:02:03:04:05:80 + + + 1 + + + 64 + + + + + 105 + 4 + 0 + + + 3 + + + 1536 + + + 107 + 4 + 1 + 3 + 1536 + + + 109 + 4 + 2 + 3 + 1536 + + + 111 + 4 + 3 + 3 + 1536 + + + 97 + 4 + 4 + 3 + 1536 + + + 99 + 4 + 5 + 3 + 1536 + + + 101 + 4 + 6 + 3 + 1536 + + + 103 + 4 + 7 + 3 + 1536 + + + 121 + 4 + 8 + 3 + 1536 + + + 123 + 4 + 9 + 3 + 1536 + + + 125 + 4 + 10 + 3 + 1536 + + + 127 + 4 + 11 + 3 + 1536 + + + 113 + 4 + 12 + 3 + 1536 + + + 115 + 4 + 13 + 3 + 1536 + + + 117 + 4 + 14 + 3 + 1536 + + + 119 + 4 + 15 + 3 + 1536 + + + 89 + 4 + 16 + 3 + 1536 + + + 91 + 4 + 17 + 3 + 1536 + + + 93 + 4 + 18 + 3 + 1536 + + + 95 + 4 + 19 + 3 + 1536 + + + 81 + 4 + 20 + 3 + 1536 + + + 83 + 4 + 21 + 3 + 1536 + + + 85 + 4 + 22 + 3 + 1536 + + + 87 + 4 + 23 + 3 + 1536 + + + 73 + 4 + 24 + 3 + 1536 + + + 75 + 4 + 25 + 3 + 1536 + + + 77 + 4 + 26 + 3 + 1536 + + + 79 + 4 + 27 + 3 + 1536 + + + 65 + 4 + 28 + 3 + 1536 + + + 67 + 4 + 29 + 3 + 1536 + + + 69 + 4 + 30 + 3 + 1536 + + + 71 + 4 + 31 + 3 + 1536 + + + 5 + 4 + 32 + 3 + 1536 + + + 7 + 4 + 33 + 3 + 1536 + + + 1 + 4 + 34 + 3 + 1536 + + + 3 + 4 + 35 + 3 + 1536 + + + 13 + 4 + 36 + 3 + 1536 + + + 15 + 4 + 37 + 3 + 1536 + + + 9 + 4 + 38 + 3 + 1536 + + + 11 + 4 + 39 + 3 + 1536 + + + 21 + 4 + 40 + 3 + 1536 + + + 23 + 4 + 41 + 3 + 1536 + + + 17 + 4 + 42 + 3 + 1536 + + + 19 + 4 + 43 + 3 + 1536 + + + 29 + 4 + 44 + 3 + 1536 + + + 31 + 4 + 45 + 3 + 1536 + + + 25 + 4 + 46 + 3 + 1536 + + + 27 + 4 + 47 + 3 + 1536 + + + 53 + 4 + 48 + 3 + 1536 + + + 55 + 4 + 49 + 3 + 1536 + + + 49 + 4 + 50 + 3 + 1536 + + + 51 + 4 + 51 + 3 + 1536 + + + 61 + 4 + 52 + 3 + 1536 + + + 63 + 4 + 53 + 3 + 1536 + + + 57 + 4 + 54 + 3 + 1536 + + + 59 + 4 + 55 + 3 + 1536 + + + 37 + 4 + 56 + 3 + 1536 + + + 39 + 4 + 57 + 3 + 1536 + + + 33 + 4 + 58 + 3 + 1536 + + + 35 + 4 + 59 + 3 + 1536 + + + 45 + 4 + 60 + 3 + 1536 + + + 47 + 4 + 61 + 3 + 1536 + + + 41 + 4 + 62 + 3 + 1536 + + + 43 + 4 + 63 + 3 + 1536 + + + + \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/default_sku b/device/mellanox/x86_64-mlnx_msn4600c-r0/default_sku new file mode 100644 index 00000000000..451382f6d8b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/default_sku @@ -0,0 +1 @@ +ACS-MSN4600C t1 diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json new file mode 100644 index 00000000000..300a3827a0c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json @@ -0,0 +1,12 @@ +{ + "chassis": { + "x86_64-mlnx_msn4600c-r0": { + "component": { + "BIOS": { }, + "CPLD1": { }, + "CPLD2": { }, + "CPLD3": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_reboot new file mode 120000 index 00000000000..43c8ea56749 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_reboot @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_reboot \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_wait new file mode 120000 index 00000000000..4b30bd42985 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_wait @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_wait \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/eeprom.py new file mode 120000 index 00000000000..b4e2a6a6167 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/eeprom.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/psuutil.py new file mode 120000 index 00000000000..9f724238a8d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/psuutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmget.py new file mode 120000 index 00000000000..2e84f435abd --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmget.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmset.py new file mode 120000 index 00000000000..6a88bac3046 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfplpmset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfpreset.py new file mode 120000 index 00000000000..fef2063e349 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfpreset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfpreset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfputil.py new file mode 120000 index 00000000000..45909b880fc --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfputil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/pmon_daemon_control.json new file mode 120000 index 00000000000..435a2ce7c0b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/pmon_daemon_control.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf new file mode 100644 index 00000000000..b2f942ffa5f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf @@ -0,0 +1,193 @@ +################################################################################ +# Copyright (c) 2020 Mellanox Technologies +# +# Platform specific sensors config for SN4600C +################################################################################ + +# Temperature sensors +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" + +bus "i2c-7" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-*-49" + label temp1 "Ambient Fan Side Temp (air intake)" + chip "tmp102-i2c-*-4a" + label temp1 "Ambient Port Side Temp (air exhaust)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-15-49" + label temp1 "Ambient COMEX Temp" + +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 4)" + chip "xdpe12284-i2c-*-62" + label in1 "PMIC-1 PSU 12V Rail (in)" + label in2 "PMIC-1 PSU 12V Rail (in)" + label in3 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail (out)" + ignore in4 + label temp1 "PMIC-1 Temp 1" + label temp2 "PMIC-1 Temp 2" + label power1 "PMIC-1 ASIC 12V VCORE_MAIN Rail Pwr (in)" + ignore power2 + label power3 "PMIC-1 ASIC 12V VCORE_MAIN Rail Pwr (out)" + ignore power4 + label curr1 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Curr (in)" + ignore curr2 + label curr3 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Curr (out)" + ignore curr4 + chip "xdpe12284-i2c-*-64" + label in1 "PMIC-2 PSU 12V Rail (in)" + label in2 "PMIC-2 PSU 12V Rail (in)" + label in3 "PMIC-2 ASIC 1.8V MAIN Rail (out)" + label in4 "PMIC-2 ASIC 1.2V MAIN Rail (out)" + label temp1 "PMIC-2 Temp 1" + label temp2 "PMIC-2 Temp 2" + label power1 "PMIC-2 ASIC 1.8V MAIN Rail Pwr (in)" + label power2 "PMIC-2 ASIC 1.2V MAIN Rail Pwr (in)" + label power3 "PMIC-2 ASIC 1.8V MAIN Rail Pwr (out)" + label power4 "PMIC-2 ASIC 1.2V MAIN Rail Pwr (out)" + label curr1 "PMIC-2 ASIC 1.8V MAIN Rail Curr (in)" + label curr2 "PMIC-2 ASIC 1.2V MAIN Rail Curr (in)" + label curr3 "PMIC-2 ASIC 1.8V MAIN Rail Curr (out)" + label curr4 "PMIC-2 ASIC 1.2V MAIN Rail Curr (out)" + chip "xdpe12284-i2c-*-66" + label in1 "PMIC-3 PSU 12V Rail (in)" + label in2 "PMIC-3 PSU 12V Rail (in)" + label in3 "PMIC-3 ASIC 0.85V MAIN Rail (out)" + label in4 "PMIC-3 ASIC 1.8V MAIN Rail (out)" + label temp1 "PMIC-3 Temp 1" + label temp2 "PMIC-3 Temp 2" + label power1 "PMIC-3 ASIC 12V MAIN Rail Pwr (in)" + label power2 "PMIC-3 ASIC 12V MAIN Rail Pwr (in)" + label power3 "PMIC-3 ASIC 0.85V MAIN Rail Pwr (out)" + label power4 "PMIC-3 ASIC 1.8V MAIN Rail Pwr (out)" + label curr1 "PMIC-3 ASIC 12V MAIN Rail Curr (in)" + label curr2 "PMIC-3 ASIC 12V MAIN Rail Curr (in)" + label curr3 "PMIC-3 ASIC 0.85V MAIN Rail Curr (out)" + label curr4 "PMIC-3 ASIC 1.8V MAIN Rail Curr (out)" + chip "xdpe12284-i2c-*-68" + label in1 "PMIC-4 PSU 12V Rail (in)" + label in2 "PMIC-4 PSU 12V Rail (in)" + label in3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-4 ASIC 1.8V T6_7 Rail (out)" + label temp1 "PMIC-4 Temp 1" + label temp2 "PMIC-4 Temp 2" + label power1 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-4 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-4 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-4 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-4 ASIC 1.8V T6_7 Rail Curr (out)" + chip "xdpe12284-i2c-*-6a" + label in1 "PMIC-5 PSU 12V Rail (in)" + label in2 "PMIC-5 PSU 12V Rail (in)" + label in3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-5 ASIC 1.8V T6_7 Rail (out)" + label temp1 "PMIC-5 Temp 1" + label temp2 "PMIC-5 Temp 2" + label power1 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-5 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-5 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-5 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-5 ASIC 1.8V T6_7 Rail Curr (out)" + chip "xdpe12284-i2c-*-6c" + label in1 "PMIC-6 PSU 12V Rail (in)" + label in2 "PMIC-6 PSU 12V Rail (in)" + label in3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-6 ASIC 1.8V T6_7 Rail (out)" + label temp1 "PMIC-6 Temp 1" + label temp2 "PMIC-6 Temp 2" + label power1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (out)" + chip "xdpe12284-i2c-*-6e" + label in1 "PMIC-7 PSU 12V Rail (in)" + label in2 "PMIC-7 PSU 12V Rail (in)" + label in3 "PMIC-7 ASIC 1.2V VCORE_T6_7 Rail (out)" + label in4 "PMIC-7 ASIC 1.2V T6_7 Rail (out)" + label temp1 "PMIC-7 Temp 1" + label temp2 "PMIC-7 Temp 2" + label power1 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-7 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-7 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-7 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-7 ASIC 1.8V T6_7 Rail Curr (out)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tps53679-i2c-*-58" + label in1 "PMIC-8 PSU 12V Rail (in)" + label in2 "PMIC-8 PSU 12V Rail (in)" + label in3 "PMIC-8 COMEX 1.8V Rail (out)" + label in4 "PMIC-8 COMEX 1.05V Rail (out)" + label temp1 "PMIC-8 Temp 1" + label temp2 "PMIC-8 Temp 2" + label power1 "PMIC-8 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-8 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-8 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-8 COMEX 1.05V Rail Curr (out)" + chip "tps53679-i2c-*-61" + label in1 "PMIC-9 PSU 12V Rail (in)" + label in2 "PMIC-9 PSU 12V Rail (in)" + label in3 "PMIC-9 COMEX 1.2V Rail (out)" + ignore in4 + label temp1 "PMIC-9 Temp 1" + label temp2 "PMIC-9 Temp 2" + label power1 "PMIC-9 COMEX 1.2V Rail Pwr (out)" + ignore power2 + label curr1 "PMIC-9 COMEX 1.2V Rail Curr (out)" + ignore curr2 + +# Power supplies +bus "i2c-4" "i2c-1-mux (chan_id 3)" + chip "dps460-i2c-*-58" + label in1 "PSU-2(R) 220V Rail (in)" + label in2 "PSU-2(R) 220V Rail (in)" + label in3 "PSU-2(R) 12V Rail (out)" + label fan1 "PSU-2(R) Fan 1" + ignore fan2 + ignore fan3 + label temp1 "PSU-2(R) Temp 1" + label temp2 "PSU-2(R) Temp 2" + label temp3 "PSU-2(R) Temp 3" + label power1 "PSU-2(R) 220V Rail Pwr (in)" + label power2 "PSU-2(R) 12V Rail Pwr (out)" + label curr1 "PSU-2(R) 220V Rail Curr (in)" + label curr2 "PSU-2(R) 12V Rail Curr (out)" + chip "dps460-i2c-*-59" + label in1 "PSU-1(L) 220V Rail (in)" + label in2 "PSU-1(L) 220V Rail (in)" + label in3 "PSU-1(L) 12V Rail (out)" + label fan1 "PSU-1(L) Fan 1" + ignore fan2 + ignore fan3 + label temp1 "PSU-1(L) Temp 1" + label temp2 "PSU-1(L) Temp 2" + label temp3 "PSU-1(L) Temp 3" + label power1 "PSU-1(L) 220V Rail Pwr (in)" + label power2 "PSU-1(L) 12V Rail Pwr (out)" + label curr1 "PSU-1(L) 220V Rail Curr (in)" + label curr2 "PSU-1(L) 12V Rail Curr (out)" + +# Chassis fans +chip "mlxreg_fan-isa-*" + label fan1 "Chassis Fan Drawer-1" + label fan2 "Chassis Fan Drawer-2" + label fan3 "Chassis Fan Drawer-3" + +# Miscellaneous +chip "*-virtual-*" + ignore temp1 diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index c3642331d19..5ecf3c150de 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -50,7 +50,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5} +hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0, 'ACS-MSN3420': 5, 'ACS-MSN4600C': 4} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1), (0, 48, 59, 60, 1)] class Chassis(ChassisBase): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 6931cc0657c..158be0c059e 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -37,7 +37,7 @@ # in most SKUs the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively. # but there are exceptions which will be handled by the following dictionary -hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1, 'ACS-MSN4700': 1, 'ACS-MSN3420': 1} +hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1, 'ACS-MSN4700': 1, 'ACS-MSN3420': 1, 'ACS-MSN4600C': 1} psu_profile_list = [ # default filename convention { diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index d4b9d56dc19..be91cf9d523 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -124,7 +124,7 @@ THERMAL_API_GET_HIGH_THRESHOLD ] -hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8, 'ACS-MSN3420': 9} +hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8, 'ACS-MSN3420': 9, 'ACS-MSN4600C': 9} thermal_profile_list = [ # 2700 { @@ -280,6 +280,22 @@ THERMAL_DEV_FAN_AMBIENT ] ) + }, + # 4600C + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_MODULE:(1, 64), + THERMAL_DEV_CATEGORY_PSU:(1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_COMEX_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT + ] + ) } ] From 799f22d4c72b92637cc2be6f5f7dcde81e7b1a94 Mon Sep 17 00:00:00 2001 From: Olivier Singla <47356901+olivier-singla@users.noreply.github.com> Date: Thu, 30 Apr 2020 03:33:20 -0400 Subject: [PATCH 31/69] [baseimage]: Run fsck filesystem check support prior mounting filesystem (#4431) * Run fsck filesystem check support prior mounting filesystem If the filesystem become non clean ("dirty"), SONiC does not run fsck to repair and mark it as clean again. This patch adds the functionality to run fsck on each boot, prior to the filesystem being mounted. This allows the filesystem to be repaired if needed. Note that if the filesystem is maked as clean, fsck does nothing and simply return so this is perfectly fine to call fsck every time prior to mount the filesystem. How to verify this patch (using bash): Using an image without this patch: Make the filesystem "dirty" (not clean) [we are making the assumption that filesystem is stored in /dev/sda3 - Please adjust depending of the platform] [do this only on a test platform!] dd if=/dev/sda3 of=superblock bs=1 count=2048 printf "$(printf '\\x%02X' 2)" | dd of="superblock" bs=1 seek=1082 count=1 conv=notrunc &> /dev/null dd of=/dev/sda3 if=superblock bs=1 count=2048 Verify that filesystem is not clean tune2fs -l /dev/sda3 | grep "Filesystem state:" reboot and verify that the filesystem is still not clean Redo the same test with an image with this patch, and verify that at next reboot the filesystem is repaired and becomes clean. fsck log is stored on syslog, using the string FSCK as markup. --- build_debian.sh | 4 ++++ files/image_config/platform/rc.local | 6 +++++ files/initramfs-tools/fsck-rootfs | 34 ++++++++++++++++++++++++++++ files/initramfs-tools/union-mount.j2 | 7 ++++++ 4 files changed, 51 insertions(+) create mode 100644 files/initramfs-tools/fsck-rootfs diff --git a/build_debian.sh b/build_debian.sh index 1b7024a304e..a805d34b939 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -165,6 +165,10 @@ sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/arista- sudo cp files/initramfs-tools/resize-rootfs $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/resize-rootfs sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/resize-rootfs +# Hook into initramfs: run fsck to repair a non-clean filesystem prior to be mounted +sudo cp files/initramfs-tools/fsck-rootfs $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/fsck-rootfs +sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/fsck-rootfs + ## Hook into initramfs: after partition mount and loop file mount ## 1. Prepare layered file system ## 2. Bind-mount docker working directory (docker overlay storage cannot work over overlay rootfs) diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index 2884270b787..ad67f0ff425 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -340,4 +340,10 @@ if [ -f $FIRST_BOOT_FILE ]; then firsttime_exit fi +# Copy the fsck log into syslog +if [ -f /var/log/fsck.log.gz ]; then + gunzip -d -c /var/log/fsck.log.gz | logger -t "FSCK" + rm -f /var/log/fsck.log.gz +fi + exit 0 diff --git a/files/initramfs-tools/fsck-rootfs b/files/initramfs-tools/fsck-rootfs new file mode 100644 index 00000000000..25b1c096aa5 --- /dev/null +++ b/files/initramfs-tools/fsck-rootfs @@ -0,0 +1,34 @@ +#!/bin/sh + +case $1 in + prereqs) + exit 0 + ;; +esac + +# Extract kernel parameters +root_val="" +set -- $(cat /proc/cmdline) +for x in "$@"; do + case "$x" in + root=*) + root_val="${x#root=}" + ;; + esac +done + +# Check the filesystem we are using +if [ ! -z $root_val ]; then + fstype=$(blkid -o value -s TYPE $root_val) + case "$fstype" in + ext4) + cmd="fsck.ext4 -v -p" + ;; + ext3) + cmd="fsck.ext3 -v -p" + ;; + esac + if [ ! -z "$cmd" ]; then + $cmd $root_val 2>&1 | gzip -c > /tmp/fsck.log.gz + fi +fi diff --git a/files/initramfs-tools/union-mount.j2 b/files/initramfs-tools/union-mount.j2 index 0fadb9a73ed..5e33e176087 100644 --- a/files/initramfs-tools/union-mount.j2 +++ b/files/initramfs-tools/union-mount.j2 @@ -85,5 +85,12 @@ then mount -t tmpfs -o rw,nosuid,nodev,size=${varlogsize}M tmpfs ${rootmnt}/var/log [ -f ${rootmnt}/host/disk-img/var-log.ext4 ] && rm -rf ${rootmnt}/host/disk-img/var-log.ext4 else + [ -f ${rootmnt}/host/disk-img/var-log.ext4 ] && fsck.ext4 -v -p ${rootmnt}/host/disk-img/var-log.ext4 2>&1 \ + | gzip -c >> /tmp/fsck.log.gz [ -f ${rootmnt}/host/disk-img/var-log.ext4 ] && mount -t ext4 -o loop,rw ${rootmnt}/host/disk-img/var-log.ext4 ${rootmnt}/var/log fi + +## fscklog file: /tmp will be lost when overlayfs is mounted +if [ -f /tmp/fsck.log.gz ]; then + mv /tmp/fsck.log.gz ${rootmnt}/var/log +fi From 685064464002add5b6b20c6ca4f9d59975c51955 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 30 Apr 2020 17:17:58 +0000 Subject: [PATCH 32/69] [vs]: add missing dvslib link for the vs test Signed-off-by: Guohan Lu --- platform/vs/tests/dvslib | 1 + 1 file changed, 1 insertion(+) create mode 120000 platform/vs/tests/dvslib diff --git a/platform/vs/tests/dvslib b/platform/vs/tests/dvslib new file mode 120000 index 00000000000..4bab298a180 --- /dev/null +++ b/platform/vs/tests/dvslib @@ -0,0 +1 @@ +../../../src/sonic-swss/tests/dvslib \ No newline at end of file From a87bf4df838d67ba92ace223e50b0e9cd288c698 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Fri, 1 May 2020 01:30:58 +0800 Subject: [PATCH 33/69] [Mellanox] Fix error in sensors.conf for 3700/3700c/3800 (#4506) --- .../x86_64-mlnx_msn3700-r0/sensors.conf | 30 +++++++------ .../x86_64-mlnx_msn3700c-r0/sensors.conf | 30 +++++++------ .../x86_64-mlnx_msn3800-r0/sensors.conf | 42 +++++++++++-------- 3 files changed, 58 insertions(+), 44 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3700-r0/sensors.conf index 376d079390a..28a889aa27d 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/sensors.conf @@ -22,9 +22,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power controllers bus "i2c-5" "i2c-1-mux (chan_id 4)" chip "tps53679-i2c-*-70" - label in1 "PMIC-1 PSU 12V Rail (in)" - label in2 "PMIC-1 ASIC 0.8V VCORE Rail (out)" - label in3 "PMIC-1 ASIC 1.2V Rail (out)" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 ASIC 0.8V VCORE Rail (out)" + label in4 "PMIC-1 ASIC 1.2V Rail (out)" label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" label power1 "PMIC-1 ASIC 0.8V VCORE Rail Pwr (out)" @@ -32,10 +33,11 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-1 ASIC 0.8V VCORE Rail Curr (out)" label curr2 "PMIC-1 ASIC 1.2V Rail Curr (out)" chip "tps53679-i2c-*-71" - label in1 "PMIC-2 PSU 12V Rail (in)" - label in2 "PMIC-2 ASIC 3.3V Rail (out)" - compute in2 (1.5)*@, @/(1.5) - label in3 "PMIC-2 ASIC 1.8V Rail (out)" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 ASIC 3.3V Rail (out)" + compute in3 (1.5)*@, @/(1.5) + label in4 "PMIC-2 ASIC 1.8V Rail (out)" label temp1 "PMIC-2 Temp 1" label temp2 "PMIC-2 Temp 2" label power1 "PMIC-2 ASIC 3.3V Rail Pwr (out)" @@ -45,9 +47,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-3 PSU 12V Rail (in)" - label in2 "PMIC-3 COMEX 1.8V Rail (out)" - label in3 "PMIC-3 COMEX 1.05V Rail (out)" + label in1 "PMIC-3 PSU 12V Rail (in1)" + label in2 "PMIC-3 PSU 12V Rail (in2)" + label in3 "PMIC-3 COMEX 1.8V Rail (out)" + label in4 "PMIC-3 COMEX 1.05V Rail (out)" label temp1 "PMIC-3 Temp 1" label temp2 "PMIC-3 Temp 2" label power1 "PMIC-3 COMEX 1.8V Rail Pwr (out)" @@ -55,9 +58,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" label curr1 "PMIC-3 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-3 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-4 PSU 12V Rail (in)" - label in2 "PMIC-4 COMEX 1.2V Rail (out)" - ignore in3 + label in1 "PMIC-4 PSU 12V Rail (in1)" + label in2 "PMIC-4 PSU 12V Rail (in2)" + label in3 "PMIC-4 COMEX 1.2V Rail (out)" + ignore in4 label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" label power1 "PMIC-4 COMEX 1.2V Rail Pwr (out)" diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3700c-r0/sensors.conf index 7efcefc5f74..3c58e27f3e6 100644 --- a/device/mellanox/x86_64-mlnx_msn3700c-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/sensors.conf @@ -22,9 +22,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power controllers bus "i2c-5" "i2c-1-mux (chan_id 4)" chip "tps53679-i2c-*-70" - label in1 "PMIC-1 PSU 12V Rail (in)" - label in2 "PMIC-1 ASIC 0.8V VCORE Rail (out)" - label in3 "PMIC-1 ASIC 1.2V Rail (out)" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 ASIC 0.8V VCORE Rail (out)" + label in4 "PMIC-1 ASIC 1.2V Rail (out)" label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" label power1 "PMIC-1 ASIC 0.8V VCORE Rail Pwr (out)" @@ -32,10 +33,11 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-1 ASIC 0.8V VCORE Rail Curr (out)" label curr2 "PMIC-1 ASIC 1.2V Rail Curr (out)" chip "tps53679-i2c-*-71" - label in1 "PMIC-2 PSU 12V Rail (in)" - label in2 "PMIC-2 ASIC 3.3V Rail (out)" - compute in2 (1.5)*@, @/(1.5) - label in3 "PMIC-2 ASIC 1.8V Rail (out)" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 ASIC 3.3V Rail (out)" + compute in3 (1.5)*@, @/(1.5) + label in4 "PMIC-2 ASIC 1.8V Rail (out)" label temp1 "PMIC-2 Temp 1" label temp2 "PMIC-2 Temp 2" label power1 "PMIC-2 ASIC 3.3V Rail Pwr (out)" @@ -45,9 +47,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-3 PSU 12V Rail (in)" - label in2 "PMIC-3 COMEX 1.8V Rail (out)" - label in3 "PMIC-3 COMEX 1.05V Rail (out)" + label in1 "PMIC-3 PSU 12V Rail (in1)" + label in2 "PMIC-3 PSU 12V Rail (in2)" + label in3 "PMIC-3 COMEX 1.8V Rail (out)" + label in4 "PMIC-3 COMEX 1.05V Rail (out)" label temp1 "PMIC-3 Temp 1" label temp2 "PMIC-3 Temp 2" label power1 "PMIC-3 COMEX 1.8V Rail Pwr (out)" @@ -55,9 +58,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" label curr1 "PMIC-3 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-3 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-4 PSU 12V Rail (in)" - label in2 "PMIC-4 COMEX 1.2V Rail (out)" - ignore in3 + label in1 "PMIC-4 PSU 12V Rail (in1)" + label in2 "PMIC-4 PSU 12V Rail (in2)" + label in3 "PMIC-4 COMEX 1.2V Rail (out)" + ignore in4 label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" label power1 "PMIC-4 COMEX 1.2V Rail Pwr (out)" diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn3800-r0/sensors.conf index fab58890adf..9777c5e8439 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/sensors.conf @@ -22,9 +22,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power controllers bus "i2c-5" "i2c-1-mux (chan_id 4)" chip "tps53679-i2c-*-70" - label in1 "PMIC-1 PSU 12V Rail (in)" - label in2 "PMIC-1 ASIC 0.8V VCORE Rail (out)" - label in3 "PMIC-1 ASIC 1.2V Rail (out)" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 ASIC 0.8V VCORE Rail (out)" + label in4 "PMIC-1 ASIC 1.2V Rail (out)" label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" label power1 "PMIC-1 ASIC 0.8V VCORE Rail Pwr (out)" @@ -32,9 +33,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-1 ASIC 0.8V VCORE Rail Curr (out)" label curr2 "PMIC-1 ASIC 1.2V Rail Curr (out)" chip "tps53679-i2c-*-71" - label in1 "PMIC-2 PSU 12V Rail (in)" - label in2 "PMIC-2 GB 0.8V Rail (out)" - label in3 "PMIC-2 GB 1.125V Rail (out)" + label in1 "PMIC-2 PSU 12V Rail (in1)" + label in2 "PMIC-2 PSU 12V Rail (in2)" + label in3 "PMIC-2 GB 0.8V Rail (out)" + label in4 "PMIC-2 GB 1.125V Rail (out)" label temp1 "PMIC-2 Temp 1" label temp2 "PMIC-2 Temp 2" label power1 "PMIC-2 GB 0.8V Rail Pwr (out)" @@ -42,9 +44,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-2 GB 0.8V Rail Curr (out)" label curr2 "PMIC-2 GB 1.125V Rail Curr (out)" chip "tps53679-i2c-*-72" - label in1 "PMIC-3 PSU 12V Rail (in)" - label in2 "PMIC-3 ASIC 1.8V Rail (out)" - ignore in3 + label in1 "PMIC-3 PSU 12V Rail (in1)" + label in2 "PMIC-3 PSU 12V Rail (in2)" + label in3 "PMIC-3 ASIC 1.8V Rail (out)" + ignore in4 label temp1 "PMIC-3 Temp 1" label temp2 "PMIC-3 Temp 2" label power1 "PMIC-3 ASIC 1.8V Rail Pwr (out)" @@ -52,9 +55,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" label curr1 "PMIC-3 ASIC 1.8V Rail Curr (out)" ignore curr2 chip "tps53679-i2c-*-73" - label in1 "PMIC-4 PSU 12V Rail (in)" - label in2 "PMIC-4 GB 0.8V Rail (out)" - label in3 "PMIC-4 GB 1.125V Rail (out)" + label in1 "PMIC-4 PSU 12V Rail (in1)" + label in2 "PMIC-4 PSU 12V Rail (in2)" + label in3 "PMIC-4 GB 0.8V Rail (out)" + label in4 "PMIC-4 GB 1.125V Rail (out)" label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" label power1 "PMIC-4 GB 0.8V Rail Pwr (out)" @@ -64,9 +68,10 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-5 PSU 12V Rail (in)" - label in2 "PMIC-5 COMEX 1.8V Rail (out)" - label in3 "PMIC-5 COMEX 1.05V Rail (out)" + label in1 "PMIC-5 PSU 12V Rail (in1)" + label in2 "PMIC-5 PSU 12V Rail (in2)" + label in3 "PMIC-5 COMEX 1.8V Rail (out)" + label in4 "PMIC-5 COMEX 1.05V Rail (out)" label temp1 "PMIC-5 Temp 1" label temp2 "PMIC-5 Temp 2" label power1 "PMIC-5 COMEX 1.8V Rail Pwr (out)" @@ -74,9 +79,10 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" label curr1 "PMIC-5 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-5 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-6 PSU 12V Rail (in)" - label in2 "PMIC-6 COMEX 1.2V Rail (out)" - ignore in3 + label in1 "PMIC-6 PSU 12V Rail (in1)" + label in2 "PMIC-6 PSU 12V Rail (in2)" + label in3 "PMIC-6 COMEX 1.2V Rail (out)" + ignore in4 label temp1 "PMIC-6 Temp 1" label temp2 "PMIC-6 Temp 2" label power1 "PMIC-6 COMEX 1.2V Rail Pwr (out)" From 80a025a7c20f5d04112352a48fd049e687be76e0 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Thu, 30 Apr 2020 12:06:19 -0700 Subject: [PATCH 34/69] [arista] update platform driver submodules (#4512) - Add Makefile rules to build debug containers for SWI images - Fix some platform API implementation for xcvrd and thermalctld - Improvements to arista diag command - Miscellaneous refactors Co-authored-by: Maxime Lorrillere --- platform/barefoot/one-aboot.mk | 5 +++++ platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/one-aboot.mk | 5 +++++ platform/broadcom/sonic-platform-modules-arista | 2 +- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/one-aboot.mk b/platform/barefoot/one-aboot.mk index 4e5e808d2ab..a2cdf2ac039 100644 --- a/platform/barefoot/one-aboot.mk +++ b/platform/barefoot/one-aboot.mk @@ -11,5 +11,10 @@ $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(ARISTA_PLATFORM_MODULE_DRIVERS) \ $(ARISTA_PLATFORM_MODULE_PYTHON2) \ $(ARISTA_PLATFORM_MODULE_PYTHON3) \ $(ARISTA_PLATFORM_MODULE) +ifeq ($(INSTALL_DEBUG_TOOLS),y) +$(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) +$(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) +else $(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) +endif SONIC_INSTALLERS += $(SONIC_ONE_ABOOT_IMAGE) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index ab4e8e17e61..c52f43edbe2 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit ab4e8e17e610e23d66b024fbf27bd83b41edf44c +Subproject commit c52f43edbe2ec842d5a807c71a4aba453ce60490 diff --git a/platform/broadcom/one-aboot.mk b/platform/broadcom/one-aboot.mk index f68319ab644..959cda20907 100644 --- a/platform/broadcom/one-aboot.mk +++ b/platform/broadcom/one-aboot.mk @@ -6,5 +6,10 @@ $(SONIC_ONE_ABOOT_IMAGE)_IMAGE_TYPE = aboot $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(BRCM_OPENNSL_KERNEL) $(ARISTA_PLATFORM_MODULE_DRIVERS) $(ARISTA_PLATFORM_MODULE_PYTHON2) $(ARISTA_PLATFORM_MODULE_PYTHON3) $(ARISTA_PLATFORM_MODULE) $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(PHY_CREDO) $(SONIC_ONE_ABOOT_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) +ifeq ($(INSTALL_DEBUG_TOOLS),y) +$(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) +$(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) +else $(SONIC_ONE_ABOOT_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) +endif SONIC_INSTALLERS += $(SONIC_ONE_ABOOT_IMAGE) diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index ab4e8e17e61..c52f43edbe2 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit ab4e8e17e610e23d66b024fbf27bd83b41edf44c +Subproject commit c52f43edbe2ec842d5a807c71a4aba453ce60490 From 4c210f0d02d7dc5a8ca54a4a6c526c0c1c5b0fb0 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Fri, 1 May 2020 03:42:01 +0800 Subject: [PATCH 35/69] [Mellanox] Enhancement for support PSU LED management (#4467) --- .../mlnx-platform-api/sonic_platform/psu.py | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 158be0c059e..1486dc0bc85 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -81,6 +81,8 @@ def __init__(self, psu_index, sku): self.psu_current = None self.psu_power = None self.psu_presence = None + self.psu_temp = None + self.psu_temp_threshold = None else: self.always_presence = False psu_voltage = filemap[PSU_VOLTAGE].format(self.index) @@ -99,6 +101,9 @@ def __init__(self, psu_index, sku): psu_presence = os.path.join(self.psu_path, psu_presence) self.psu_presence = psu_presence + self.psu_temp = os.path.join(self.psu_path, 'thermal/psu{}_temp'.format(self.index)) + self.psu_temp_threshold = os.path.join(self.psu_path, 'thermal/psu{}_temp_max'.format(self.index)) + # unplugable PSU has no FAN if sku not in hwsku_dict_with_unplugable_psu: fan = Fan(False, psu_index, psu_index, True) @@ -307,3 +312,59 @@ def get_power_available_status(self): else: return True, "" + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + if self.psu_temp is not None and self.get_powergood_status(): + try: + temp = self._read_generic_file(self.psu_temp, 0) + return float(temp) / 1000 + except Exception as e: + logger.log_info("Fail to get temperature for PSU {} due to - {}".format(self._name, repr(e))) + + return None + + def get_temperature_high_threshold(self): + """ + Retrieves the high threshold temperature of PSU + + Returns: + A float number, the high threshold temperature of PSU in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + if self.psu_temp_threshold is not None and self.get_powergood_status(): + try: + temp_threshold = self._read_generic_file(self.psu_temp_threshold, 0) + return float(temp_threshold) / 1000 + except Exception as e: + logger.log_info("Fail to get temperature threshold for PSU {} due to - {}".format(self._name, repr(e))) + + return None + + def get_voltage_high_threshold(self): + """ + Retrieves the high threshold PSU voltage output + + Returns: + A float number, the high threshold output voltage in volts, + e.g. 12.1 + """ + # hw-management doesn't expose those sysfs for now + raise NotImplementedError + + def get_voltage_low_threshold(self): + """ + Retrieves the low threshold PSU voltage output + + Returns: + A float number, the low threshold output voltage in volts, + e.g. 12.1 + """ + # hw-management doesn't expose those sysfs for now + raise NotImplementedError + From 2153caef59bb940097d4060e02fd5841fa5a0b7b Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Thu, 30 Apr 2020 22:45:12 +0300 Subject: [PATCH 36/69] [submodule]: Advance sonic-platform-common. (#4513) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commits on Mar 20, 2020 SFP(sff8472 attributes) transciever eeprom attribute support. (#74) 9b1dea5 Commits on Mar 22, 2020 Detect an SFP adapter in a QSFP port, and instantiate an SFP object i… 116eeec Commits on Apr 13, 2020 [component]: Introduce new firmware management API. 2632a59 Commits on Apr 16, 2020 [Chassis base] Add sfp error event definition (#80) f1f00ec Commits on Apr 24, 2020 [component]: Update firmware management API. 777901f [component]: Extend docstrings for firmware management API. b066ec7 Commits on Apr 30, 2020 [component]: Fix review comments. d96344e Merge pull request #82 from nazariig/master-component-firmware-api 28c39c5 Signed-off-by: Nazarii Hnydyn --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index dc59b105ff2..28c39c55666 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit dc59b105ff234bd89b9042c934b17c10b9b261f7 +Subproject commit 28c39c55666dcaef10f62492906c1399eec4ccba From 86bc8aec5f3fda41c1fc9ae5d14deddec9d3ee6d Mon Sep 17 00:00:00 2001 From: lguohan Date: Thu, 30 Apr 2020 12:50:59 -0700 Subject: [PATCH 37/69] [vs]: dynamically create front panel ports in vs docker (#4499) currently, vs docker always create 32 front panel ports. when vs docker starts, it first detects the peer links in the namespace and then setup equal number of front panel interfaces as the peer links. Signed-off-by: Guohan Lu --- files/build_templates/buffers_config.j2 | 2 +- platform/vs/README.vsdocker.md | 40 ++++--------------------- platform/vs/create_vnet.sh | 30 +++++++++++++++---- platform/vs/docker-sonic-vs/start.sh | 19 +++++++++++- 4 files changed, 50 insertions(+), 41 deletions(-) diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index a5212d979fc..ba4dcf49e81 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -7,7 +7,7 @@ def {%- endmacro -%} {# Determine device topology and filename postfix #} -{%- if DEVICE_METADATA is defined %} +{%- if DEVICE_METADATA is defined and DEVICE_METADATA['localhost']['type'] is defined %} {%- set switch_role = DEVICE_METADATA['localhost']['type'] %} {%- if switch_role.lower() == 'torrouter' %} {%- set filename_postfix = 't0' %} diff --git a/platform/vs/README.vsdocker.md b/platform/vs/README.vsdocker.md index 42e1cafc846..694631f095d 100644 --- a/platform/vs/README.vsdocker.md +++ b/platform/vs/README.vsdocker.md @@ -1,42 +1,12 @@ HOWTO Use Virtual Switch (Docker) -1. Create a docker with 32 front panel port +1. Create a docker with two front panel ports ``` $ docker run -id --name sw debian bash -$ sudo ./create_vnet.sh sw +$ sudo ./create_vnet.sh -n 2 sw $ ip netns list -sw-srv31 (id: 37) -sw-srv30 (id: 35) -sw-srv29 (id: 34) -sw-srv28 (id: 33) -sw-srv27 (id: 32) -sw-srv26 (id: 31) -sw-srv25 (id: 30) -sw-srv24 (id: 29) -sw-srv23 (id: 28) -sw-srv22 (id: 27) -sw-srv21 (id: 26) -sw-srv20 (id: 25) -sw-srv19 (id: 24) -sw-srv18 (id: 23) -sw-srv17 (id: 22) -sw-srv16 (id: 21) -sw-srv15 (id: 20) -sw-srv14 (id: 19) -sw-srv13 (id: 18) -sw-srv12 (id: 17) -sw-srv11 (id: 16) -sw-srv10 (id: 15) -sw-srv9 (id: 14) -sw-srv8 (id: 13) -sw-srv7 (id: 12) -sw-srv6 (id: 11) -sw-srv5 (id: 10) -sw-srv4 (id: 9) -sw-srv3 (id: 8) -sw-srv2 (id: 7) sw-srv1 (id: 6) sw-srv0 (id: 5) ``` @@ -51,8 +21,10 @@ $ docker run --privileged --network container:sw --name vs -d docker-sonic-vs ``` $ docker exec -it vs bash -root@2e9b5c2dc2a2:/# ifconfig Ethernet0 10.0.0.0/31 up -root@2e9b5c2dc2a2:/# ifconfig Ethernet4 10.0.0.2/31 up +root@2e9b5c2dc2a2:/# config interface ip add Ethernet0 10.0.0.0/31 +root@2e9b5c2dc2a2:/# config interface ip add Ethernet4 10.0.0.2/31 +root@2e9b5c2dc2a2:/# config interface startup Ethernet0 +root@2e9b5c2dc2a2:/# config interface startup Ethernet4 ``` 4. Setup IP in the server network namespace diff --git a/platform/vs/create_vnet.sh b/platform/vs/create_vnet.sh index 4746e16cbba..2217bbbd022 100755 --- a/platform/vs/create_vnet.sh +++ b/platform/vs/create_vnet.sh @@ -1,4 +1,24 @@ -#!/bin/bash +#!/bin/bash -e + +usage() { + echo "Usage: $0 [-n ] swname" 1>&2 + exit 1 +} + +SERVERS=2 + +while getopts ":n:" opt; do + case $opt in + n) + SERVERS=$((OPTARG)) + ;; + *) + usage + ;; + esac +done + +shift $((OPTIND-1)) SWNAME=$1 @@ -6,9 +26,8 @@ pid=$(docker inspect --format '{{.State.Pid}}' $SWNAME) echo Seting up servers -SERVERS=31 -for srv in `seq 0 $SERVERS`; do +for srv in `seq 0 $((SERVERS-1))`; do SRV="$SWNAME-srv$srv" @@ -24,9 +43,10 @@ for srv in `seq 0 $SERVERS`; do IF="eth$((srv+1))" - ip link add ${SRV}eth0 type veth peer name $IF + ip link add ${SRV}eth0 type veth peer name $SWNAME-$IF ip link set ${SRV}eth0 netns $SRV - ip link set $IF netns ${pid} + ip link set $SWNAME-$IF netns ${pid} + nsenter -t $pid -n ip link set dev $SWNAME-$IF name $IF echo "Bring ${SRV}eth0 up" $NSS ip link set dev ${SRV}eth0 name eth0 diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index f8fcf974b65..54d585f29e2 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -7,6 +7,23 @@ HWSKU=Force10-S6000 ln -sf /usr/share/sonic/device/$PLATFORM/$HWSKU /usr/share/sonic/hwsku +pushd /usr/share/sonic/hwsku + +# filter available front panel ports in lanemap.ini +[ -f lanemap.ini.orig ] || cp lanemap.ini lanemap.ini.orig +for p in $(ip link show | grep -oE "eth[0-9]+" | grep -v eth0); do + grep ^$p: lanemap.ini.orig +done > lanemap.ini + +# filter available sonic front panel ports in port_config.ini +[ -f port_config.ini.orig ] || cp port_config.ini port_config.ini.orig +grep ^# port_config.ini.orig > port_config.ini +for lanes in $(awk -F ':' '{print $2}' lanemap.ini); do + grep -E "\s$lanes\s" port_config.ini.orig +done >> port_config.ini + +popd + [ -d /etc/sonic ] || mkdir -p /etc/sonic SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') @@ -17,7 +34,7 @@ if [ -f /etc/sonic/config_db.json ]; then mv /tmp/config_db.json /etc/sonic/config_db.json else # generate and merge buffers configuration into config file - sonic-cfggen -t /usr/share/sonic/hwsku/buffers.json.j2 > /tmp/buffers.json + sonic-cfggen -k $HWSKU -p /usr/share/sonic/hwsku/port_config.ini -t /usr/share/sonic/hwsku/buffers.json.j2 > /tmp/buffers.json sonic-cfggen -j /etc/sonic/init_cfg.json -t /usr/share/sonic/hwsku/qos.json.j2 > /tmp/qos.json sonic-cfggen -p /usr/share/sonic/hwsku/port_config.ini -k $HWSKU --print-data > /tmp/ports.json sonic-cfggen -j /etc/sonic/init_cfg.json -j /tmp/buffers.json -j /tmp/qos.json -j /tmp/ports.json --print-data > /etc/sonic/config_db.json From aca5bec842a7ab1e530a54239e96debce74fb147 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Thu, 30 Apr 2020 13:09:24 -0700 Subject: [PATCH 38/69] [sonic-py-swsssdk/snmpagent] update submodule for sonic-py-swsssdk / snmpagent (#4421) * [sonic-py-swsssdk] update submodule for sonic-py-swsssdk * update snmpagent submodule * [sonic-py-swsssdk] update submodule for namespace changes --- src/sonic-py-swsssdk | 2 +- src/sonic-snmpagent | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index df617345d80..b9cee360c2a 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit df617345d807bc01e3f5740fdfdc4b9799f1cf63 +Subproject commit b9cee360c2a1b64f46dbc035579bd7cbd9959878 diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 862e51ab85d..7632ee89caa 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 862e51ab85d48290082adfcbb801bfbbe3a95bf3 +Subproject commit 7632ee89caa8a485d68ce389f60f202fce197579 From 352a39742a733296141f6529dcf68fe9f0aa2823 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Fri, 1 May 2020 01:46:21 +0300 Subject: [PATCH 39/69] [mellanox]: MSN4700 support 8 lanes 400G with new SAI/SDK/FW (#4509) Update SAI/SDK/FW and MSN4700 device files to support 8 lanes 400G Update SAI to 1.16.3 Update SDK to 4.4.0914 Update FW to *.2007.1112 Update MSN4700 device files to support 8 lanes 400G --- .../ACS-MSN4700/port_config.ini | 66 +++++++++---------- .../ACS-MSN4700/sai.profile | 2 +- .../{sai_4700_100G.xml => sai_4700.xml} | 64 +++++++++--------- platform/mellanox/fw.mk | 6 +- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- .../sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 8 files changed, 73 insertions(+), 73 deletions(-) rename device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/{sai_4700_100G.xml => sai_4700.xml} (88%) diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini index 1e1906ff0ef..2a14b4a79eb 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini @@ -1,33 +1,33 @@ -# name lanes alias -Ethernet0 0,1,2,3 etp1 -Ethernet4 4,5,6,7 etp2 -Ethernet8 8,9,10,11 etp3 -Ethernet12 12,13,14,15 etp4 -Ethernet16 16,17,18,19 etp5 -Ethernet20 20,21,22,23 etp6 -Ethernet24 24,25,26,27 etp7 -Ethernet28 28,29,30,31 etp8 -Ethernet32 32,33,34,35 etp9 -Ethernet36 36,37,38,39 etp10 -Ethernet40 40,41,42,43 etp11 -Ethernet44 44,45,46,47 etp12 -Ethernet48 48,49,50,51 etp13 -Ethernet52 52,53,54,55 etp14 -Ethernet56 56,57,58,59 etp15 -Ethernet60 60,61,62,63 etp16 -Ethernet64 64,65,66,67 etp17 -Ethernet68 68,69,70,71 etp18 -Ethernet72 72,73,74,75 etp19 -Ethernet76 76,77,78,79 etp20 -Ethernet80 80,81,82,83 etp21 -Ethernet84 84,85,86,87 etp22 -Ethernet88 88,89,90,91 etp23 -Ethernet92 92,93,94,95 etp24 -Ethernet96 96,97,98,99 etp25 -Ethernet100 100,101,102,103 etp26 -Ethernet104 104,105,106,107 etp27 -Ethernet108 108,109,110,111 etp28 -Ethernet112 112,113,114,115 etp29 -Ethernet116 116,117,118,119 etp30 -Ethernet120 120,121,122,123 etp31 -Ethernet124 124,125,126,127 etp32 +# name lanes alias index +Ethernet0 0,1,2,3,4,5,6,7 etp1 0 +Ethernet8 8,9,10,11,12,13,14,15 etp2 1 +Ethernet16 16,17,18,19,20,21,22,23 etp3 2 +Ethernet24 24,25,26,27,28,29,30,31 etp4 3 +Ethernet32 32,33,34,35,36,37,38,39 etp5 4 +Ethernet40 40,41,42,43,44,45,46,47 etp6 5 +Ethernet48 48,49,50,51,52,53,54,55 etp7 6 +Ethernet56 56,57,58,59,60,61,62,63 etp8 7 +Ethernet64 64,65,66,67,68,69,70,71 etp9 8 +Ethernet72 72,73,74,75,76,77,78,79 etp10 9 +Ethernet80 80,81,82,83,84,85,86,87 etp11 10 +Ethernet88 88,89,90,91,92,93,94,95 etp12 11 +Ethernet96 96,97,98,99,100,101,102,103 etp13 12 +Ethernet104 104,105,106,107,108,109,110,111 etp14 13 +Ethernet112 112,113,114,115,116,117,118,119 etp15 14 +Ethernet120 120,121,122,123,124,125,126,127 etp16 15 +Ethernet128 128,129,130,131,132,133,134,135 etp17 16 +Ethernet136 136,137,138,139,140,141,142,143 etp18 17 +Ethernet144 144,145,146,147,148,149,150,151 etp19 18 +Ethernet152 152,153,154,155,156,157,158,159 etp20 19 +Ethernet160 160,161,162,163,164,165,166,167 etp21 20 +Ethernet168 168,169,170,171,172,173,174,175 etp22 21 +Ethernet176 176,177,178,179,180,181,182,183 etp23 22 +Ethernet184 184,185,186,187,188,189,190,191 etp24 23 +Ethernet192 192,193,194,195,196,197,198,199 etp25 24 +Ethernet200 200,201,202,203,204,205,206,207 etp26 25 +Ethernet208 208,209,210,211,212,213,214,215 etp27 26 +Ethernet216 216,217,218,219,220,221,222,223 etp28 27 +Ethernet224 224,225,226,227,228,229,230,231 etp29 28 +Ethernet232 232,233,234,235,236,237,238,239 etp30 29 +Ethernet240 240,241,242,243,244,245,246,247 etp31 30 +Ethernet248 248,249,250,251,252,253,254,255 etp32 31 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile index 31b3fd09ddd..d145093cab9 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4700_100G.xml +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4700.xml diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml similarity index 88% rename from device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml rename to device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml index a76e23d5d11..177a79d13d6 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml @@ -12,189 +12,189 @@ 1 - 4 + 8 17 3 1536 5 - 4 + 8 16 3 1536 9 - 4 + 8 19 3 1536 13 - 4 + 8 18 3 1536 17 - 4 + 8 21 3 1536 21 - 4 + 8 20 3 1536 25 - 4 + 8 23 3 1536 29 - 4 + 8 22 3 1536 33 - 4 + 8 29 3 1536 37 - 4 + 8 28 3 1536 41 - 4 + 8 31 3 1536 45 - 4 + 8 30 3 1536 49 - 4 + 8 25 3 1536 53 - 4 + 8 24 3 1536 57 - 4 + 8 27 3 1536 61 - 4 + 8 26 3 1536 65 - 4 + 8 14 3 1536 69 - 4 + 8 15 3 1536 73 - 4 + 8 12 3 1536 77 - 4 + 8 13 3 1536 81 - 4 + 8 10 3 1536 85 - 4 + 8 11 3 1536 89 - 4 + 8 8 3 1536 93 - 4 + 8 9 3 1536 97 - 4 + 8 2 3 1536 101 - 4 + 8 3 3 1536 105 - 4 + 8 0 @@ -205,35 +205,35 @@ 109 - 4 + 8 1 3 1536 113 - 4 + 8 6 3 1536 117 - 4 + 8 7 3 1536 121 - 4 + 8 4 3 1536 125 - 4 + 8 5 3 1536 diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index faa3b3f239b..c8f4b225857 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,17 +11,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2007.0872 +MLNX_SPC_FW_VERSION = 13.2007.1112 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2007.0872 +MLNX_SPC2_FW_VERSION = 29.2007.1112 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2007.0872 +MLNX_SPC3_FW_VERSION = 30.2007.1112 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 275445bd80e..65b0e47ae7f 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.16.2-master +MLNX_SAI_VERSION = SAIRel1.16.3-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index 5eb3e143e3d..57b07cbbeea 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit 5eb3e143e3da934b30fd9b66126a6ab626f1b15e +Subproject commit 57b07cbbeea8953c2df96cbd7f0d022691c9eaa5 diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 1d7da850581..3160d980ff7 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit 1d7da850581ff0dd79990ae1c5bcb174d4272267 +Subproject commit 3160d980ff766addb459e1ff0f81778516eb55a0 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 4b6212b147d..c63c327cc40 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.4.0880 +MLNX_SDK_VERSION = 4.4.0914 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 81f4c81f0ce98471992a55a2170a9ad0eda9dd1a Mon Sep 17 00:00:00 2001 From: Sabareesh-Kumar-Anandan <59681634+Sabareesh-Kumar-Anandan@users.noreply.github.com> Date: Fri, 1 May 2020 04:17:03 +0530 Subject: [PATCH 40/69] [build]: changing debian names based on Architecture (#4508) Replacing "amd64" with $PLATFORM_ARCH variable Fix for compiling marvell-armhf arch Signed-off-by: Sabareesh Kumar Anandan --- rules/iccpd.mk | 2 +- rules/iptables.mk | 10 +++++----- rules/sonic-mgmt-framework.mk | 4 ++-- src/iccpd/Makefile | 4 +++- src/iptables/Makefile | 8 ++++---- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/rules/iccpd.mk b/rules/iccpd.mk index 1923a9a2a62..26d3adf1dd6 100644 --- a/rules/iccpd.mk +++ b/rules/iccpd.mk @@ -2,7 +2,7 @@ ICCPD_VERSION = 0.0.5 -ICCPD = iccpd_$(ICCPD_VERSION)_amd64.deb +ICCPD = iccpd_$(ICCPD_VERSION)_$(CONFIGURED_ARCH).deb $(ICCPD)_DEPENDS += $(LIBNL_GENL3_DEV) $(LIBNL_CLI_DEV) $(ICCPD)_RDEPENDS += $(LIBNL_GENL3) $(LIBNL_CLI) $(ICCPD)_SRC_PATH = $(SRC_PATH)/iccpd diff --git a/rules/iptables.mk b/rules/iptables.mk index fbd7ccd70c0..a166f5817a8 100644 --- a/rules/iptables.mk +++ b/rules/iptables.mk @@ -4,20 +4,20 @@ IPTABLES_VERSION = 1.6.0+snapshot20161117 IPTABLES_VERSION_SUFFIX = 6 IPTABLES_VERSION_FULL = $(IPTABLES_VERSION)-$(IPTABLES_VERSION_SUFFIX) -IPTABLES = iptables_$(IPTABLES_VERSION_FULL)_amd64.deb +IPTABLES = iptables_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(IPTABLES)_SRC_PATH = $(SRC_PATH)/iptables SONIC_MAKE_DEBS += $(IPTABLES) -IPTABLESIP4TC = libip4tc0_$(IPTABLES_VERSION_FULL)_amd64.deb +IPTABLESIP4TC = libip4tc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIP4TC))) -IPTABLESIP6TC = libip6tc0_$(IPTABLES_VERSION_FULL)_amd64.deb +IPTABLESIP6TC = libip6tc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIP6TC))) -IPTABLESIPTC = libiptc0_$(IPTABLES_VERSION_FULL)_amd64.deb +IPTABLESIPTC = libiptc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIPTC))) -IPXTABLES12 = libxtables12_$(IPTABLES_VERSION_FULL)_amd64.deb +IPXTABLES12 = libxtables12_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(IPTABLES),$(IPXTABLES12))) # Export these variables so they can be used in a sub-make diff --git a/rules/sonic-mgmt-framework.mk b/rules/sonic-mgmt-framework.mk index a57ce6b1b08..d3536edcfb6 100644 --- a/rules/sonic-mgmt-framework.mk +++ b/rules/sonic-mgmt-framework.mk @@ -2,13 +2,13 @@ ifeq ($(ENABLE_MGMT_FRAMEWORK), y) -SONIC_MGMT_FRAMEWORK = sonic-mgmt-framework_1.0-01_amd64.deb +SONIC_MGMT_FRAMEWORK = sonic-mgmt-framework_1.0-01_$(CONFIGURED_ARCH).deb $(SONIC_MGMT_FRAMEWORK)_SRC_PATH = $(SRC_PATH)/sonic-mgmt-framework $(SONIC_MGMT_FRAMEWORK)_DEPENDS = $(LIBYANG_DEV) $(LIBYANG) $(SONIC_MGMT_FRAMEWORK)_RDEPENDS = $(LIBYANG) SONIC_DPKG_DEBS += $(SONIC_MGMT_FRAMEWORK) -SONIC_MGMT_FRAMEWORK_DBG = sonic-mgmt-framework-dbg_1.0-01_amd64.deb +SONIC_MGMT_FRAMEWORK_DBG = sonic-mgmt-framework-dbg_1.0-01_$(CONFIGURED_ARCH).deb $(SONIC_MGMT_FRAMEWORK_DBG)_DEPENDS += $(SONIC_MGMT_FRAMEWORK) $(SONIC_MGMT_FRAMEWORK_DBG)_RDEPENDS += $(SONIC_MGMT_FRAMEWORK) $(eval $(call add_derived_package,$(SONIC_MGMT_FRAMEWORK),$(SONIC_MGMT_FRAMEWORK_DBG))) diff --git a/src/iccpd/Makefile b/src/iccpd/Makefile index 401ff394d14..b8f5c19ddf5 100644 --- a/src/iccpd/Makefile +++ b/src/iccpd/Makefile @@ -2,7 +2,7 @@ SHELL = /bin/bash .SHELLFLAGS += -e -MAIN_TARGET = iccpd_$(ICCPD_VERSION)_amd64.deb +MAIN_TARGET = iccpd_$(ICCPD_VERSION)_$(CONFIGURED_ARCH).deb DEB_PATH = debian all: iccpd-build mclagdctl-build @@ -24,6 +24,8 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : chmod +x $(DEB_PATH)/usr/bin/mclagdctl md5sum $(DEB_PATH)/usr/bin/iccpd > $(DEB_PATH)/DEBIAN/md5sums md5sum $(DEB_PATH)/usr/bin/mclagdctl >> $(DEB_PATH)/DEBIAN/md5sums + sed -i "s/Package: .*/Package: iccpd-$(ICCPD_VERSION)-$(CONFIGURED_ARCH)/g" $(DEB_PATH)/DEBIAN/control + sed -i "s/Architecture: .*/Architecture: $(CONFIGURED_ARCH)/g" $(DEB_PATH)/DEBIAN/control dpkg-deb -b $(DEB_PATH) $(DEST)/$(MAIN_TARGET) clean: iccpd-clean mclagdctl-clean diff --git a/src/iptables/Makefile b/src/iptables/Makefile index 60154c19ddb..3268ab5afea 100644 --- a/src/iptables/Makefile +++ b/src/iptables/Makefile @@ -3,10 +3,10 @@ SHELL = /bin/bash .SHELLFLAGS += -e MAIN_TARGET = $(IPTABLES) -DERIVED_TARGETS = libip4tc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ - libip6tc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ - libiptc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ - libxtables12_$(IPTABLES_VERSION_FULL)_amd64.deb +DERIVED_TARGETS = libip4tc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ + libip6tc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ + libiptc0_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ + libxtables12_$(IPTABLES_VERSION_FULL)_$(CONFIGURED_ARCH).deb IPTABLES_URL = http://deb.debian.org/debian/pool/main/i/iptables From 46161ca0e091e8298e529d04aa136d744507398e Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 30 Apr 2020 15:48:42 -0700 Subject: [PATCH 41/69] [sonic-utilities][sonic-ztp] Update submodules (#4501) * src/sonic-utilities 7ce5b62...3471926 (4): > Make `config` command support abbreviation. (#893) > [fwutil]: Fix firmware update command. (#895) > [doc]: ZTP configuration and show commands (#866) > Allow show ztp to display non-sensitive information visible to > non-root user (#872) * src/sonic-ztp 374c9e8...c959371 (2): > Fix ztp profile unit test (#14) > Create a shadow ZTP data json file accessible to non-root user (#13) --- src/sonic-utilities | 2 +- src/sonic-ztp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 7ce5b62404b..3471926f6e4 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 7ce5b62404b150782fd4a275ab3460566fa32a49 +Subproject commit 3471926f6e49f801676183f01f62fc8d0b64eeb4 diff --git a/src/sonic-ztp b/src/sonic-ztp index 374c9e804a9..c959371ece3 160000 --- a/src/sonic-ztp +++ b/src/sonic-ztp @@ -1 +1 @@ -Subproject commit 374c9e804a9f434cdb58fa7afe0c3f6201bfe56f +Subproject commit c959371ece3baebff2d3d748aba863de87b1d0a8 From cbc75fe4c85fd01aded0bacb283c8bbf62adf2f8 Mon Sep 17 00:00:00 2001 From: Sujin Kang Date: Thu, 30 Apr 2020 15:51:34 -0700 Subject: [PATCH 42/69] [pmon]: Fix the continous syseepromd autorestart issue on 201911 (#4478) - Remove syseepromd from the critical process of pmon docker - Fix supervisor autorestart configuration of syseepromd --- dockers/docker-platform-monitor/critical_processes | 1 - .../docker-pmon.supervisord.conf.j2 | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/dockers/docker-platform-monitor/critical_processes b/dockers/docker-platform-monitor/critical_processes index 788ba53f3ec..9798dffc4c2 100644 --- a/dockers/docker-platform-monitor/critical_processes +++ b/dockers/docker-platform-monitor/critical_processes @@ -1,4 +1,3 @@ ledd xcvrd psud -syseepromd diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index 87b6808a744..c79a13005f3 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -86,10 +86,10 @@ startsecs=0 command=/usr/bin/syseepromd priority=8 autostart=false -autorestart=true +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog -startsecs=0 +startsecs=10 {% endif %} {% if not skip_thermalctld %} @@ -97,8 +97,8 @@ startsecs=0 command=/usr/bin/thermalctld priority=9 autostart=false -autorestart=true +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog -startsecs=0 +startsecs=10 {% endif %} From 451121678928a4c0f0ea8a0743ffe9a2beb7371b Mon Sep 17 00:00:00 2001 From: rkdevi27 <54701695+rkdevi27@users.noreply.github.com> Date: Fri, 1 May 2020 11:28:09 +0530 Subject: [PATCH 43/69] Ssd mitigation changes (#4214) * ssd_mitigation_changes * ssd_mitigation_changes * ssd_mitigation_changes * ssd_mitigation_changes --- files/image_config/fstrim/fstrim.service | 1 + 1 file changed, 1 insertion(+) diff --git a/files/image_config/fstrim/fstrim.service b/files/image_config/fstrim/fstrim.service index cf740d3af34..0383b5fa010 100644 --- a/files/image_config/fstrim/fstrim.service +++ b/files/image_config/fstrim/fstrim.service @@ -3,4 +3,5 @@ Description=Discard unused blocks [Service] Type=oneshot +ExecStartPre=/usr/bin/log_ssd_health ExecStart=/sbin/fstrim -av From 506e9546c9d38a5e0e17c12e7e769e29d17e8849 Mon Sep 17 00:00:00 2001 From: dereksun01 <52683998+dereksun01@users.noreply.github.com> Date: Fri, 1 May 2020 20:27:32 +0800 Subject: [PATCH 44/69] [device] Upgrade as4630_54pe for new platform (#4268) - Add port auto-negotiation attribute. - Add CPLD command to disable mode. --- .../Accton-AS4630-54PE/port_config.ini | 110 +++++++++--------- .../utils/accton_as4630_54pe_util.py | 14 ++- 2 files changed, 67 insertions(+), 57 deletions(-) diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini index aabb372bf64..f8965dfe41d 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini +++ b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini @@ -1,55 +1,55 @@ -# name lanes alias index speed -Ethernet0 26 thousandE1 1 1000 -Ethernet1 25 thousandE2 2 1000 -Ethernet2 28 thousandE3 3 1000 -Ethernet3 27 thousandE4 4 1000 -Ethernet4 30 thousandE5 5 1000 -Ethernet5 29 thousandE6 6 1000 -Ethernet6 32 thousandE7 7 1000 -Ethernet7 31 thousandE8 8 1000 -Ethernet8 38 thousandE9 9 1000 -Ethernet9 37 thousandE10 10 1000 -Ethernet10 40 thousandE11 11 1000 -Ethernet11 39 thousandE12 12 1000 -Ethernet12 34 thousandE13 13 1000 -Ethernet13 33 thousandE14 14 1000 -Ethernet14 36 thousandE15 15 1000 -Ethernet15 35 thousandE16 16 1000 -Ethernet16 46 thousandE17 17 1000 -Ethernet17 45 thousandE18 18 1000 -Ethernet18 48 thousandE19 19 1000 -Ethernet19 47 thousandE20 20 1000 -Ethernet20 42 thousandE21 21 1000 -Ethernet21 41 thousandE22 22 1000 -Ethernet22 44 thousandE23 23 1000 -Ethernet23 43 thousandE24 24 1000 -Ethernet24 2 thousandE25 25 1000 -Ethernet25 1 thousandE26 26 1000 -Ethernet26 4 thousandE27 27 1000 -Ethernet27 3 thousandE28 28 1000 -Ethernet28 6 thousandE29 29 1000 -Ethernet29 5 thousandE30 30 1000 -Ethernet30 8 thousandE31 31 1000 -Ethernet31 7 thousandE32 32 1000 -Ethernet32 10 thousandE33 33 1000 -Ethernet33 9 thousandE34 34 1000 -Ethernet34 12 thousandE35 35 1000 -Ethernet35 11 thousandE36 36 1000 -Ethernet36 14 thousandE37 37 1000 -Ethernet37 13 thousandE38 38 1000 -Ethernet38 16 thousandE39 39 1000 -Ethernet39 15 thousandE40 40 1000 -Ethernet40 18 thousandE41 41 1000 -Ethernet41 17 thousandE42 42 1000 -Ethernet42 20 thousandE43 43 1000 -Ethernet43 19 thousandE44 44 1000 -Ethernet44 22 thousandE45 45 1000 -Ethernet45 21 thousandE46 46 1000 -Ethernet46 24 thousandE47 47 1000 -Ethernet47 23 thousandE48 48 1000 -Ethernet48 67 twentyfiveGigE49 49 25000 -Ethernet49 66 twentyfiveGigE50 50 25000 -Ethernet50 65 twentyfiveGigE51 51 25000 -Ethernet51 68 twentyfiveGigE52 52 25000 -Ethernet52 73,74,75,76 hundredGigE53 53 100000 -Ethernet56 69,70,71,72 hundredGigE54 54 100000 +# name lanes alias index speed autoneg +Ethernet0 26 thousandE1 1 1000 1 +Ethernet1 25 thousandE2 2 1000 1 +Ethernet2 28 thousandE3 3 1000 1 +Ethernet3 27 thousandE4 4 1000 1 +Ethernet4 30 thousandE5 5 1000 1 +Ethernet5 29 thousandE6 6 1000 1 +Ethernet6 32 thousandE7 7 1000 1 +Ethernet7 31 thousandE8 8 1000 1 +Ethernet8 38 thousandE9 9 1000 1 +Ethernet9 37 thousandE10 10 1000 1 +Ethernet10 40 thousandE11 11 1000 1 +Ethernet11 39 thousandE12 12 1000 1 +Ethernet12 34 thousandE13 13 1000 1 +Ethernet13 33 thousandE14 14 1000 1 +Ethernet14 36 thousandE15 15 1000 1 +Ethernet15 35 thousandE16 16 1000 1 +Ethernet16 46 thousandE17 17 1000 1 +Ethernet17 45 thousandE18 18 1000 1 +Ethernet18 48 thousandE19 19 1000 1 +Ethernet19 47 thousandE20 20 1000 1 +Ethernet20 42 thousandE21 21 1000 1 +Ethernet21 41 thousandE22 22 1000 1 +Ethernet22 44 thousandE23 23 1000 1 +Ethernet23 43 thousandE24 24 1000 1 +Ethernet24 2 thousandE25 25 1000 1 +Ethernet25 1 thousandE26 26 1000 1 +Ethernet26 4 thousandE27 27 1000 1 +Ethernet27 3 thousandE28 28 1000 1 +Ethernet28 6 thousandE29 29 1000 1 +Ethernet29 5 thousandE30 30 1000 1 +Ethernet30 8 thousandE31 31 1000 1 +Ethernet31 7 thousandE32 32 1000 1 +Ethernet32 10 thousandE33 33 1000 1 +Ethernet33 9 thousandE34 34 1000 1 +Ethernet34 12 thousandE35 35 1000 1 +Ethernet35 11 thousandE36 36 1000 1 +Ethernet36 14 thousandE37 37 1000 1 +Ethernet37 13 thousandE38 38 1000 1 +Ethernet38 16 thousandE39 39 1000 1 +Ethernet39 15 thousandE40 40 1000 1 +Ethernet40 18 thousandE41 41 1000 1 +Ethernet41 17 thousandE42 42 1000 1 +Ethernet42 20 thousandE43 43 1000 1 +Ethernet43 19 thousandE44 44 1000 1 +Ethernet44 22 thousandE45 45 1000 1 +Ethernet45 21 thousandE46 46 1000 1 +Ethernet46 24 thousandE47 47 1000 1 +Ethernet47 23 thousandE48 48 1000 1 +Ethernet48 67 twentyfiveGigE49 49 25000 0 +Ethernet49 66 twentyfiveGigE50 50 25000 0 +Ethernet50 65 twentyfiveGigE51 51 25000 0 +Ethernet51 68 twentyfiveGigE52 52 25000 0 +Ethernet52 73,74,75,76 hundredGigE53 53 100000 0 +Ethernet56 69,70,71,72 hundredGigE54 54 100000 0 diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py index 2f73726f846..fbfa46377fa 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py @@ -17,7 +17,6 @@ """ Usage: %(scriptName)s [options] command object - options: -h | --help : this help message -d | --debug : run with debug mode @@ -108,7 +107,12 @@ 'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', ] - +# Disable CPLD debug mode +cpld_set =[ +'i2cset -y -f 3 0x60 0x2a 0xff', +'i2cset -y -f 3 0x60 0x2b 0xff', +'i2cset -y -f 3 0x60 0x86 0x89' +] FORCE = 0 logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) @@ -353,6 +357,12 @@ def do_install(): return status else: print PROJECT_NAME.upper()+" devices detected...." + + for i in range(len(cpld_set)): + status, output = log_os_system(cpld_set[i], 1) + if status: + if FORCE == 0: + return status return def do_uninstall(): From 3f1c3dda991b318c8d3a93c26b7e88d8135401f5 Mon Sep 17 00:00:00 2001 From: dereksun01 <52683998+dereksun01@users.noreply.github.com> Date: Fri, 1 May 2020 20:36:04 +0800 Subject: [PATCH 45/69] [device/accton] Modify as8000 configuration (#4446) --- .../config_16Q_FEC544_EVTA_100G.bcm | 4 +++ .../config_16Q_FEC544_EVTB_100G.bcm | 26 +++---------------- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTA_100G.bcm b/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTA_100G.bcm index 9f4066cc736..a9dfbd4797e 100755 --- a/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTA_100G.bcm +++ b/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTA_100G.bcm @@ -15,6 +15,10 @@ dpr_clock_frequency=1000 device_clock_frequency=1325 port_flex_enable=1 +l3_alpm_enable=2 +l3_mem_entries=983040 +ipv6_lpm_128b_enable=1 + #firmware load method, use fast load load_firmware=0x2 diff --git a/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTB_100G.bcm b/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTB_100G.bcm index a72f22bbfd9..676dcdd89bd 100755 --- a/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTB_100G.bcm +++ b/device/accton/x86_64-accton_minipack-r0/Accton-MINIPACK/config_16Q_FEC544_EVTB_100G.bcm @@ -15,6 +15,10 @@ dpr_clock_frequency=1000 device_clock_frequency=1325 port_flex_enable=1 +l3_alpm_enable=2 +l3_mem_entries=983040 +ipv6_lpm_128b_enable=1 + #firmware load method, use fast load load_firmware=0x2 @@ -1463,25 +1467,3 @@ serdes_core_tx_polarity_flip_physical{254}=0x7E serdes_core_tx_polarity_flip_physical{255}=0x7E serdes_core_tx_polarity_flip_physical{256}=0x7E -dport_map_port_38=299 -portmap_38=257:10 - -dport_map_port_118=300 -portmap_118=258:10 - -portmap_19=259:10 - -portmap_39=260:10 - -portmap_59=261:10 - -portmap_79=262:10 - -portmap_99=263:10 - -portmap_119=264:10 - -portmap_139=265:10 - -portmap_159=266:10 - From 34cad97f30fe136d4d9685a9a6ac33250fcbd571 Mon Sep 17 00:00:00 2001 From: dereksun01 <52683998+dereksun01@users.noreply.github.com> Date: Fri, 1 May 2020 21:34:54 +0800 Subject: [PATCH 46/69] [device] Modify configuration and add led_proc_init.soc (#4418) - Modify configuration file path in sai.profile. - Modify configuration file for as7726_32x. - Add led_proc_init.soc and custom_led.bin --- .../Accton-AS7726-32X/sai.profile | 2 +- .../td3-as7726-32x100G.config.bcm | 16 +++++++++------- .../x86_64-accton_as7726_32x-r0/custom_led.bin | Bin 0 -> 1212 bytes .../led_proc_init.soc | 4 ++++ 4 files changed, 14 insertions(+), 8 deletions(-) create mode 100755 device/accton/x86_64-accton_as7726_32x-r0/custom_led.bin create mode 100644 device/accton/x86_64-accton_as7726_32x-r0/led_proc_init.soc diff --git a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile index 46f5cb3bf85..461cdd76c4d 100644 --- a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile +++ b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as7726-32x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7726-32x100G.config.bcm diff --git a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm index 16cbb8d341e..49838f4b0be 100755 --- a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm +++ b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm @@ -11,26 +11,28 @@ mem_cache_enable=0 l2_mem_entries=32768 l3_mem_entries=16384 -fpem_mem_entries=131072 +fpem_mem_entries=16384 l2xmsg_mode=1 # Platform specfic bcm_num_cos=8 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 +ifp_inports_support_enable=1 ipv6_lpm_128b_enable=0x1 l3_max_ecmp_mode=1 -#l3_alpm_enable=2 +l3_alpm_enable=2 lpm_scaling_enable=0 max_vp_lags=0 miim_intr_enable=0 module_64ports=1 +port_flex_enable=1 schan_intr_enable=0 stable_size=0x5500000 tdma_timeout_usec=3000000 skip_L2_USER_ENTRY=0 bcm_tunnel_term_compatible_mode=1 - +l3_alpm_ipv6_128b_bkt_rsvd=1 phy_an_c73=1 dport_map_port_1=1 @@ -100,10 +102,10 @@ portmap_115=113:100 portmap_119=117:100 portmap_123=121:100 portmap_127=125:100 -portmap_66=129:10:m -portmap_130=128:10:m -portmap_65=130:10 -portmap_131=131:10 +#portmap_66=129:10:m +#portmap_130=128:10:m +#portmap_65=130:10 +#portmap_131=131:10 phy_chain_rx_lane_map_physical{1.0}=0x1320 phy_chain_rx_lane_map_physical{5.0}=0x0123 diff --git a/device/accton/x86_64-accton_as7726_32x-r0/custom_led.bin b/device/accton/x86_64-accton_as7726_32x-r0/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..73dcf0e085dca7dd6a5ed729da4bf9b1ef737e34 GIT binary patch literal 1212 zcmZwE&2JM&7{~FMwegxjfRF+S8DO0SN-zyjQ<{VVjyH@8fu^y6lDI(Z(AF(&ao^nl=ElmiEZWQj@$F3Z<(sG#cMqtVPW^Za&Zt5+wc z{Hjq2TZHoMzlo9T&4fQvh&^+~`sD+E1x3M99jZq~l&B6q^>2@M{zIjSN;L9v&6%w| zc4g@Ph_LPS;`U5>QTwIz{d6=G$_#|knM;|O%*^P_3Ex!p#qE`qJgM&Wo zfkqtfVlVcgANz3t?_mJ%V-N`>aS(@a7$4vWhA@m2KEzQR!*PrtjSNO{0w3XHe1a@K z#b-E)&+!Gm#3|(P6~4wd_!i&cd;EYg{D{*ygR?k?^SFRKBnCcJ@8Y{nLB z#hZv=8{WcpybXS_;1`P??7%zNiCx%@C?>K)EwVc}=B&Qhn~P8D`h3AyFdQh)4;y7+ znPHzREm<)v??Ep9q8T!Ko@6nYj<5Q-RzZUc# z;^5Gz+FA}N@5wDsZm`^3|4d6s^kj>}({@TUsn)2l#`R>Z!Chh(b-@gj4OO8rWu&9rr3SV4 zb=!v4C4Jjj}A2O!;@-R!)8Y8PfcY=nS~^`Ggmhe#fXdIwh4;>tCAf z-#ynqMgJDJ=YRT}|MoZNe^0zf*f*CDoJ&Y}!XS}*HC2pGb8a>6jccEw9FycW##&u+ z&!Rrs_b7W(Z6Uvd*J+#0U)lfgKQB8OYkVcY#MjqPG`w`fT8E|HH2FcYeQr|UBdd1X c+ITwKP%4Sv6ULOf{);Z^KXvtn=XtxI0}9Fx{r~^~ literal 0 HcmV?d00001 diff --git a/device/accton/x86_64-accton_as7726_32x-r0/led_proc_init.soc b/device/accton/x86_64-accton_as7726_32x-r0/led_proc_init.soc new file mode 100644 index 00000000000..1b1e6403d90 --- /dev/null +++ b/device/accton/x86_64-accton_as7726_32x-r0/led_proc_init.soc @@ -0,0 +1,4 @@ + +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin +led auto on +led start From aafe825c50b2e1af9465e39347621fa8be0f3e79 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Fri, 1 May 2020 09:22:09 -0700 Subject: [PATCH 47/69] Addressed review comments. --- files/dhcp/dhcp_mgmt_conf.py | 4 -- files/image_config/hostcfgd/hostcfgd | 60 +++++++++------------------- 2 files changed, 19 insertions(+), 45 deletions(-) diff --git a/files/dhcp/dhcp_mgmt_conf.py b/files/dhcp/dhcp_mgmt_conf.py index c582dd83856..9503d7c4ce0 100644 --- a/files/dhcp/dhcp_mgmt_conf.py +++ b/files/dhcp/dhcp_mgmt_conf.py @@ -32,7 +32,3 @@ def update_dhcp_mgmt_ip_info(): else: syslog.syslog(syslog.LOG_INFO, "Args : {}".format(sys.argv)) update_dhcp_mgmt_ip_info() - - - - diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 0b713dfcc25..4f573a9426b 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -252,15 +252,12 @@ class MgmtVrfCfg: self.mgmt_vrf_table_created = False def configure_mgmt_vrf(self): - syslog.syslog(syslog.LOG_INFO, "Configure MGMT VRF:") - self.create_mgmt_vrf_table() cmd = 'ip link set dev mgmt up' if run_command(cmd) == False: return - syslog.syslog(syslog.LOG_INFO, "Add lo intf:") cmd = 'ip link add lo-m type dummy' if run_command(cmd) == False: return @@ -280,9 +277,7 @@ class MgmtVrfCfg: self.bind_mgmt_intf() def bind_mgmt_intf(self): - syslog.syslog(syslog.LOG_INFO, "Handle MGMT intf:") keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) - syslog.syslog(syslog.LOG_INFO, "MGMT interfaces keys: {}".format(str(keys))) mgmt_intf_bound = False for it in keys: @@ -293,31 +288,24 @@ class MgmtVrfCfg: if run_command(cmd) == False: return - cmd = 'sysctl -w net.ipv4.tcp_l3mdev_accept=1' - if run_command(cmd) == False: - return - mgmt_intf_bound = True break - if not mgmt_intf_bound: - syslog.syslog(syslog.LOG_ERR, "MGMT VRF: MGMT interface not bound") - else: - for it in keys: - if type(it) is unicode: - key = it - else: - key = it[0] + "|" + it[1] + return mgmt_intf_bound - entry = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, key) - if 'gwaddr' in entry: - mgmt_intf_gwaddr = entry['gwaddr'] - cmd = 'ip route add table {} 0.0.0.0/0 via {}'.format(MGMT_VRF_TABLE_ID, mgmt_intf_gwaddr) - if run_command(cmd) == False: - return + def mgmt_vrf_add_default_routes(self): + keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) + for it in keys: + if type(it) is unicode: + continue - def unconfigure_mgmt_vrf(self): - syslog.syslog(syslog.LOG_INFO, "Unconfigure MGMT VRF:") + key = it[0] + "|" + it[1] + + entry = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, key) + if 'gwaddr' in entry: + mgmt_intf_gwaddr = entry['gwaddr'] + self.handle_mgmt_intf_gwaddr_cfg("ADD", it[0], mgmt_intf_gwaddr) + def unconfigure_mgmt_vrf(self): cmd = 'ip link delete lo-m' if run_command(cmd) == True: self.delete_mgmt_vrf_table() @@ -325,7 +313,7 @@ class MgmtVrfCfg: return def handle_mgmt_intf_gwaddr_cfg(self, op, ifname, gwaddr): - syslog.syslog(syslog.LOG_INFO, "Received MGMT Intf gwaddr config, op: {}, ifname: {}, gwaddr: {}".format(op, ifname, gwaddr)) + rc = False keys = self.config_db.get_keys(CFG_MGMT_VRF) if keys: cmd = 'ip route del table {} 0.0.0.0/0'.format(MGMT_VRF_TABLE_ID) @@ -334,17 +322,17 @@ class MgmtVrfCfg: if op == "ADD": cmd = 'ip route add table {} 0.0.0.0/0 via {}'.format(MGMT_VRF_TABLE_ID, gwaddr) run_command(cmd) - return True + rc = True + + return rc def handle_mgmt_intf_creation(self, mgmt_intf_key): - syslog.syslog(syslog.LOG_INFO, "Received MGMT Intf creation, key: {}".format(mgmt_intf_key)) keys = self.config_db.get_keys(CFG_MGMT_VRF) if keys: - syslog.syslog(syslog.LOG_INFO, "MGMT VRF created") - self.bind_mgmt_intf() + if self.bind_mgmt_intf() == True: + self.mgmt_vrf_add_default_routes() def handle_mgmt_vrf_cfg(self, key, data): - syslog.syslog(syslog.LOG_INFO, "Received MGMT VRF config, key: {}, data: {}".format(key, data)) try: if data: if data['mgmtVrfEnabled'] == 'true': @@ -365,9 +353,6 @@ class MgmtVrfCfg: return vrf_table - - - def run_command(cmd): syslog.syslog(syslog.LOG_INFO, "Config cmd - {}".format(cmd)) try: @@ -380,7 +365,6 @@ def run_command(cmd): return True def cfg_attr_set (cmd, attr = None, value = None, appIntf = None): - rc = run_command(cmd) if appIntf != None and rc == True: appIntf[attr] = value @@ -395,15 +379,12 @@ def is_attr_cfg_required (attr, cfg_data, app_data, cfgAllAtrr = True): return rc - class MgmtIntfCfg: def __init__(self, cfg_db, mgmt_vrf_cfg): self.app_db = ConfigDBConnector() self.app_db.db_connect('APPL_DB', wait_for_init=False, retry_on=True) self.config_db = cfg_db self.mgmt_vrf_cfg = mgmt_vrf_cfg - syslog.syslog(syslog.LOG_INFO, 'AppDB connect success') - self.mgmt_intf_handle_default_cfg("eth0") def mgmt_intf_handle_default_cfg (self, ifname): @@ -462,7 +443,6 @@ class MgmtIntfCfg: cmd = "ip {} route {} default via {} dev {} table {}".format(ver, op.lower(), gwaddr, ifname, vrf_table) cfg_attr_set(cmd) - def mgmt_intf_dhclient_set (self, ifname, attr, enable): version = "" file_ext = "" @@ -520,7 +500,6 @@ class MgmtIntfCfg: cfg_attr_set(cmd) return forced_routes - def handle_mgmt_port_cfg(self, key, data): mgmt_intf = self.app_db.get_entry(APP_MGMT_PORT_TABLE, key) cfgAllAtrr = False @@ -547,7 +526,6 @@ class MgmtIntfCfg: self.app_db.set_entry(APP_MGMT_PORT_TABLE, key, mgmt_intf) - def handle_mgmt_intf_cfg(self, key, data): cur_appdb_key = key.replace('|', ':') intf_keys = key.split("|") From c55603f494736b1464823e32520438af11e89dcc Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 1 May 2020 11:20:33 -0700 Subject: [PATCH 48/69] [build]: add docker-ptf-* as stretch docker targets (#4516) Signed-off-by: Guohan Lu --- platform/barefoot/docker-ptf-bfn.mk | 1 + platform/broadcom/docker-ptf-brcm.mk | 1 + platform/cavium/docker-ptf-cavm.mk | 1 + platform/centec/docker-ptf-centec.mk | 1 + platform/innovium/docker-ptf-invm.mk | 1 + platform/marvell-arm64/docker-ptf-mrvl.mk | 1 + platform/marvell-armhf/docker-ptf-mrvl.mk | 1 + platform/mellanox/docker-ptf-mlnx.mk | 1 + platform/nephos/docker-ptf-nephos.mk | 1 + 9 files changed, 9 insertions(+) diff --git a/platform/barefoot/docker-ptf-bfn.mk b/platform/barefoot/docker-ptf-bfn.mk index 573e9cd9cff..752e7345752 100644 --- a/platform/barefoot/docker-ptf-bfn.mk +++ b/platform/barefoot/docker-ptf-bfn.mk @@ -3,3 +3,4 @@ DOCKER_PTF_BFN = docker-ptf-bfn.gz $(DOCKER_PTF_BFN)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_BFN)_LOAD_DOCKERS += $(DOCKER_PTF) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_BFN) diff --git a/platform/broadcom/docker-ptf-brcm.mk b/platform/broadcom/docker-ptf-brcm.mk index 510f21e8a43..35780aea76c 100644 --- a/platform/broadcom/docker-ptf-brcm.mk +++ b/platform/broadcom/docker-ptf-brcm.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_BRCM)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_BRCM)_DEPENDS += $(PYTHON_SAITHRIFT) $(DOCKER_PTF_BRCM)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_BRCM) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_BRCM) diff --git a/platform/cavium/docker-ptf-cavm.mk b/platform/cavium/docker-ptf-cavm.mk index 4665345586a..ea96fd050bf 100644 --- a/platform/cavium/docker-ptf-cavm.mk +++ b/platform/cavium/docker-ptf-cavm.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_CAVM)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_CAVM)_DEPENDS += $(PYTHON_SAITHRIFT_CAVM) $(DOCKER_PTF_CAVM)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_CAVM) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_CAVM) diff --git a/platform/centec/docker-ptf-centec.mk b/platform/centec/docker-ptf-centec.mk index 3d4fe50e5f1..47284f71756 100644 --- a/platform/centec/docker-ptf-centec.mk +++ b/platform/centec/docker-ptf-centec.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_CENTEC)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_CENTEC)_DEPENDS += $(PYTHON_SAITHRIFT) $(DOCKER_PTF_CENTEC)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_CENTEC) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_CENTEC) diff --git a/platform/innovium/docker-ptf-invm.mk b/platform/innovium/docker-ptf-invm.mk index 6c81734676f..53ba41e9d38 100755 --- a/platform/innovium/docker-ptf-invm.mk +++ b/platform/innovium/docker-ptf-invm.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_INVM)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_INVM)_DEPENDS += $(PYTHON_SAITHRIFT_INVM) $(DOCKER_PTF_INVM)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_INVM) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_INVM) diff --git a/platform/marvell-arm64/docker-ptf-mrvl.mk b/platform/marvell-arm64/docker-ptf-mrvl.mk index 69dff4a90dd..72c860aec86 100644 --- a/platform/marvell-arm64/docker-ptf-mrvl.mk +++ b/platform/marvell-arm64/docker-ptf-mrvl.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_MRVL)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_MRVL)_DEPENDS += $(PYTHON_SAITHRIFT) $(DOCKER_PTF_MRVL)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_MRVL) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_MRVL) diff --git a/platform/marvell-armhf/docker-ptf-mrvl.mk b/platform/marvell-armhf/docker-ptf-mrvl.mk index 69dff4a90dd..72c860aec86 100644 --- a/platform/marvell-armhf/docker-ptf-mrvl.mk +++ b/platform/marvell-armhf/docker-ptf-mrvl.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_MRVL)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_MRVL)_DEPENDS += $(PYTHON_SAITHRIFT) $(DOCKER_PTF_MRVL)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_MRVL) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_MRVL) diff --git a/platform/mellanox/docker-ptf-mlnx.mk b/platform/mellanox/docker-ptf-mlnx.mk index f6d17e72fcf..eaaa54897d8 100644 --- a/platform/mellanox/docker-ptf-mlnx.mk +++ b/platform/mellanox/docker-ptf-mlnx.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_MLNX)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_MLNX)_DEPENDS += $(PYTHON_SAITHRIFT) $(DOCKER_PTF_MLNX)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_MLNX) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_MLNX) diff --git a/platform/nephos/docker-ptf-nephos.mk b/platform/nephos/docker-ptf-nephos.mk index 7fbbd271cf6..15855bc89a1 100644 --- a/platform/nephos/docker-ptf-nephos.mk +++ b/platform/nephos/docker-ptf-nephos.mk @@ -5,3 +5,4 @@ $(DOCKER_PTF_NEPHOS)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_NEPHOS)_DEPENDS += $(PYTHON_SAITHRIFT_NEPHOS) $(DOCKER_PTF_NEPHOS)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_NEPHOS) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_NEPHOS) From 30bbbbf24f0ce2a063259a27511a8babf45f546e Mon Sep 17 00:00:00 2001 From: shlomibitton <60430976+shlomibitton@users.noreply.github.com> Date: Sat, 2 May 2020 20:37:14 +0300 Subject: [PATCH 49/69] hw-mgmt_V.7.0000.3034 integration (#4519) Signed-off-by: Shlomi Bitton --- platform/mellanox/hw-management.mk | 2 +- platform/mellanox/hw-management/hw-mgmt | 2 +- src/sonic-linux-kernel | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index cc27126cf80..3fa1667fec1 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 7.0000.3020 +MLNX_HW_MANAGEMENT_VERSION = 7.0000.3034 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index 5e0a3410bf2..39f66b8e199 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit 5e0a3410bf2167af0f63ba85cd4158a0be9f1443 +Subproject commit 39f66b8e1997868bbec297d7ae38f4e4ccc9009d diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 187bb4aa046..57f0a4e0539 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 187bb4aa046c26f2fe508e71dc74c230d316838b +Subproject commit 57f0a4e053960db216232b6f3b15c0f5b41b88c2 From 49df4b7a02c8a06ae04e2b5e9cc9c82123953596 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Sat, 2 May 2020 14:02:25 -0700 Subject: [PATCH 50/69] Addressed review comments and fixed build issue --- files/image_config/hostcfgd/hostcfgd | 27 ++++++++++--- .../interfaces/interfaces-config.sh | 5 --- .../tests/sample_output/interfaces | 29 +------------- .../tests/sample_output/mvrf_interfaces | 40 +------------------ 4 files changed, 24 insertions(+), 77 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 4f573a9426b..290c4c17020 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -366,7 +366,7 @@ def run_command(cmd): def cfg_attr_set (cmd, attr = None, value = None, appIntf = None): rc = run_command(cmd) - if appIntf != None and rc == True: + if appIntf != None: appIntf[attr] = value return rc @@ -385,6 +385,7 @@ class MgmtIntfCfg: self.app_db.db_connect('APPL_DB', wait_for_init=False, retry_on=True) self.config_db = cfg_db self.mgmt_vrf_cfg = mgmt_vrf_cfg + self.mgmt_cfg_appdb_cleanup() self.mgmt_intf_handle_default_cfg("eth0") def mgmt_intf_handle_default_cfg (self, ifname): @@ -400,19 +401,35 @@ class MgmtIntfCfg: self.handle_mgmt_port_cfg(ifname, mgmt_intf) - mgmt_intf = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, ifname) - if mgmt_intf == {}: + keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) + if len(keys) == 0: + mgmt_intf = {} mgmt_intf['ipv4_dhcp_client'] = "true" mgmt_intf['ipv6_dhcp_client'] = "true" self.config_db.set_entry(CFG_MGMT_INTF_TABLE, ifname, mgmt_intf) self.app_db.set_entry(APP_MGMT_INTF_TABLE, ifname, mgmt_intf) + else: + for it in keys: + if type(it) is unicode: + key = it + else: + key = it[0] + "|" + it[1] + data = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, key) + self.handle_mgmt_intf_cfg(key, data) + + def mgmt_cfg_appdb_cleanup (self): + tbl_list = [APP_MGMT_PORT_TABLE, APP_MGMT_INTF_TABLE] + for tbl in tbl_list: + keys = self.app_db.get_keys(tbl) + for key in keys: + self.app_db.delete_entry(tbl, key) def mgmt_intf_mtu_set (self, ifname, mtu, appIntf): cmd = 'ifconfig {} mtu {}'.format(ifname, mtu) cfg_attr_set(cmd, 'mtu', mtu, appIntf) def mgmt_intf_admin_status_set (self, ifname, admin_status, appIntf): - cmd = 'ifconfig {} {}'.format(ifname, admin_status) + cmd = 'ip link set {} {}'.format(ifname, admin_status) cfg_attr_set(cmd, 'admin_status', admin_status, appIntf) def mgmt_intf_description_set (self, ifname, description, appIntf): @@ -420,7 +437,7 @@ class MgmtIntfCfg: def mgmt_intf_speed_set (self, ifname, speed, autoneg, appIntf): duplex = "full" - cmd = 'ethtool -s {} speed {} duplex {} autoneg {}; ifup {}'.format(ifname, speed, duplex, autoneg, ifname) + cmd = 'ifdown --force {}; ethtool -s {} speed {} duplex {} autoneg {}; ifup --force {}'.format(ifname, ifname, speed, duplex, autoneg, ifname) cfg_attr_set(cmd, 'speed', speed, appIntf) def mgmt_intf_autoneg_set (self, ifname, autoneg, appIntf): diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index b5352745a7e..407afe57a36 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -1,7 +1,5 @@ #!/bin/bash -ifdown --force eth0 - # Check if ZTP DHCP policy has been installed if [ -e /etc/network/ifupdown2/policy.d/ztp_dhcp.json ]; then # Obtain port operational state information @@ -21,9 +19,6 @@ fi # Create /e/n/i file for existing and active interfaces sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces -[ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid -[ -f /var/run/dhclient6.eth0.pid ] && kill `cat /var/run/dhclient6.eth0.pid` && rm -f /var/run/dhclient6.eth0.pid - for intf_pid in $(ls -1 /var/run/dhclient*.Ethernet*.pid 2> /dev/null); do [ -f ${intf_pid} ] && kill `cat ${intf_pid}` && rm -f ${intf_pid} done diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces index 07fd7a522c3..a62b41b3a76 100644 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -3,40 +3,13 @@ # 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 # The management network interface auto eth0 -iface eth0 inet static - address 10.0.0.100 - netmask 255.255.255.0 - network 10.0.0.0 - broadcast 10.0.0.255 - ########## management network policy routing rules - # management port up rules - up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 - up ip -4 route add 10.0.0.0/24 dev eth0 table default - up ip -4 rule add from 10.0.0.100/32 table default - # management port down rules - pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default - pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default - pre-down ip -4 rule delete from 10.0.0.100/32 table default -iface eth0 inet6 static - address 2603:10e2:0:2902::8 - netmask 64 - network 2603:10e2:0:2902:: - broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff - ########## management network policy routing rules - # management port up rules - up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table default metric 201 - up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table default - up ip -6 rule add from 2603:10e2:0:2902::8/128 table default - # management port down rules - pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default - pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default - pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table default # source /etc/network/interfaces.d/* # diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces index 085f5111c3f..a62b41b3a76 100644 --- a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces @@ -3,51 +3,13 @@ # generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen # file: /etc/network/interfaces # -auto mgmt -iface mgmt - vrf-table 5000 -# The loopback network interface for mgmt VRF that is required for applications like NTP - up ip link add lo-m type dummy - up ip link set dev lo-m master mgmt - up ip addr add 127.0.0.1/8 dev lo-m - up ip link set lo-m up - down ip link delete dev lo-m + # The loopback network interface auto lo iface lo inet loopback # The management network interface auto eth0 -iface eth0 inet static - address 10.0.0.100 - netmask 255.255.255.0 - network 10.0.0.0 - broadcast 10.0.0.255 - vrf mgmt - ########## management network policy routing rules - # management port up rules - up ip -4 route add default via 10.0.0.1 dev eth0 table 5000 metric 201 - up ip -4 route add 10.0.0.0/24 dev eth0 table 5000 - up ip -4 rule add from 10.0.0.100/32 table 5000 - # management port down rules - pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 - pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 - pre-down ip -4 rule delete from 10.0.0.100/32 table 5000 -iface eth0 inet6 static - address 2603:10e2:0:2902::8 - netmask 64 - network 2603:10e2:0:2902:: - broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff - vrf mgmt - ########## management network policy routing rules - # management port up rules - up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table 5000 metric 201 - up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table 5000 - up ip -6 rule add from 2603:10e2:0:2902::8/128 table 5000 - # management port down rules - pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table 5000 - pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table 5000 - pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table 5000 # source /etc/network/interfaces.d/* # From e8748ebf1bc1e6e6a25b6d6ca5200c2cea5f83ef Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Mon, 4 May 2020 09:34:35 -0700 Subject: [PATCH 51/69] [submodule]: advance sonic-utilities submodule (#4523) c2facd8 [show] Fix abbreviations for 'show ip bgp ...' commands (#901) cb68e7d Add support for multi-ASIC devices (#877) 44ed6e9 Improved route_check tool and adopt to 20191130 image. (#898) 6fba8db [psushow] Add a column to display LED color to show platform psustatus output (#886) e747456 ssd_mitigation_changes (#829) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 3471926f6e4..c2facd8488f 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 3471926f6e49f801676183f01f62fc8d0b64eeb4 +Subproject commit c2facd8488f023f98cab2c06d849c21cefc6fcf5 From 86e13907b423928e06ae72500cac090712304b01 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Mon, 4 May 2020 15:00:07 -0700 Subject: [PATCH 52/69] Update golang version for 1.11.5 to 1.14.2 (#4520) --- sonic-slave-buster/Dockerfile.j2 | 2 +- sonic-slave-jessie/Dockerfile.j2 | 2 +- sonic-slave-stretch/Dockerfile.j2 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 4cb0fe102aa..cf6d61f4b12 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -316,7 +316,7 @@ RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confold" RUN apt-get -y build-dep linux # For gobgp and telemetry build -RUN export VERSION=1.11.5 \ +RUN export VERSION=1.14.2 \ {%- if CONFIGURED_ARCH == "armhf" %} && wget https://storage.googleapis.com/golang/go$VERSION.linux-armv6l.tar.gz \ && tar -C /usr/local -xzf go$VERSION.linux-armv6l.tar.gz \ diff --git a/sonic-slave-jessie/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 index 0e59310fc30..b2626f33ce9 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -278,7 +278,7 @@ RUN apt-get -y build-dep linux {%- endif %} # For gobgp and telemetry build -RUN export VERSION=1.11.5 \ +RUN export VERSION=1.14.2 \ {%- if CONFIGURED_ARCH == "armhf" %} && wget https://storage.googleapis.com/golang/go$VERSION.linux-armv6l.tar.gz \ && tar -C /usr/local -xzf go$VERSION.linux-armv6l.tar.gz \ diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index af5f441c884..a02a39ed93c 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -315,7 +315,7 @@ RUN apt-get -t stretch-backports install -y debhelper RUN apt-get -y build-dep linux # For gobgp and telemetry build -RUN export VERSION=1.11.5 \ +RUN export VERSION=1.14.2 \ {%- if CONFIGURED_ARCH == "armhf" %} && wget https://storage.googleapis.com/golang/go$VERSION.linux-armv6l.tar.gz \ && tar -C /usr/local -xzf go$VERSION.linux-armv6l.tar.gz \ From 8ac1c60b2a3d1c902b12dc174f3afb13a710cda9 Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Mon, 4 May 2020 16:15:15 -0700 Subject: [PATCH 53/69] [config engine] Parser changes to support parsing of multi-asic device minigraph (#4222) - Changes to minigraph.py to parse minigraph.xml of a multi asic platform - Changes to portconfig.py to parse additional column "asic_port_name" in port_config.ini - Add a new option -n to sonic-cfggen for multi asic platforms - Add unit tests for config generation for multi asic platforms Signed-off-by: SuvarnaMeenakshi Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-config-engine/minigraph.py | 223 ++- src/sonic-config-engine/portconfig.py | 22 +- src/sonic-config-engine/sonic-cfggen | 35 +- src/sonic-config-engine/sonic_device_util.py | 49 +- .../tests/multi_npu_data/sample-minigraph.xml | 1214 +++++++++++++++++ .../multi_npu_data/sample_port_config-0.ini | 9 + .../multi_npu_data/sample_port_config-1.ini | 9 + .../multi_npu_data/sample_port_config-2.ini | 9 + .../multi_npu_data/sample_port_config-3.ini | 9 + .../tests/test_multinpu_cfggen.py | 221 +++ 10 files changed, 1753 insertions(+), 47 deletions(-) create mode 100644 src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml create mode 100644 src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini create mode 100644 src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini create mode 100644 src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini create mode 100644 src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini create mode 100644 src/sonic-config-engine/tests/test_multinpu_cfggen.py diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 8f91fbe5c31..8ff4944c5d1 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -14,6 +14,7 @@ from lxml.etree import QName from portconfig import get_port_config +from sonic_device_util import get_npu_id_from_name """minigraph.py version_added: "1.9" @@ -118,14 +119,13 @@ def parse_png(png, hname): startport = link.find(str(QName(ns, "StartPort"))).text bandwidth_node = link.find(str(QName(ns, "Bandwidth"))) bandwidth = bandwidth_node.text if bandwidth_node is not None else None - if enddevice.lower() == hname.lower(): if port_alias_map.has_key(endport): endport = port_alias_map[endport] neighbors[endport] = {'name': startdevice, 'port': startport} if bandwidth: port_speeds[endport] = bandwidth - else: + elif startdevice.lower() == hname.lower(): if port_alias_map.has_key(startport): startport = port_alias_map[startport] neighbors[startport] = {'name': enddevice, 'port': endport} @@ -159,9 +159,103 @@ def parse_png(png, hname): return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports) +def parse_asic_external_link(link, asic_name, hostname): + neighbors = {} + port_speeds = {} + enddevice = link.find(str(QName(ns, "EndDevice"))).text + endport = link.find(str(QName(ns, "EndPort"))).text + startdevice = link.find(str(QName(ns, "StartDevice"))).text + startport = link.find(str(QName(ns, "StartPort"))).text + bandwidth_node = link.find(str(QName(ns, "Bandwidth"))) + bandwidth = bandwidth_node.text if bandwidth_node is not None else None + # if chassis internal is false, the interface name will be + # interface alias which should be converted to asic port name + if (enddevice.lower() == hostname.lower()): + if ((port_alias_asic_map.has_key(endport)) and + (asic_name.lower() in port_alias_asic_map[endport].lower())): + endport = port_alias_asic_map[endport] + neighbors[port_alias_map[endport]] = {'name': startdevice, 'port': startport} + if bandwidth: + port_speeds[port_alias_map[endport]] = bandwidth + elif (startdevice.lower() == hostname.lower()): + if ((port_alias_asic_map.has_key(startport)) and + (asic_name.lower() in port_alias_asic_map[startport].lower())): + startport = port_alias_asic_map[startport] + neighbors[port_alias_map[startport]] = {'name': enddevice, 'port': endport} + if bandwidth: + port_speeds[port_alias_map[startport]] = bandwidth + + return neighbors, port_speeds + +def parse_asic_internal_link(link, asic_name, hostname): + neighbors = {} + port_speeds = {} + enddevice = link.find(str(QName(ns, "EndDevice"))).text + endport = link.find(str(QName(ns, "EndPort"))).text + startdevice = link.find(str(QName(ns, "StartDevice"))).text + startport = link.find(str(QName(ns, "StartPort"))).text + bandwidth_node = link.find(str(QName(ns, "Bandwidth"))) + bandwidth = bandwidth_node.text if bandwidth_node is not None else None + if ((enddevice.lower() == asic_name.lower()) and + (startdevice.lower() != hostname.lower())): + if port_alias_map.has_key(endport): + endport = port_alias_map[endport] + neighbors[endport] = {'name': startdevice, 'port': startport} + if bandwidth: + port_speeds[endport] = bandwidth + elif ((startdevice.lower() == asic_name.lower()) and + (enddevice.lower() != hostname.lower())): + if port_alias_map.has_key(startport): + startport = port_alias_map[startport] + neighbors[startport] = {'name': enddevice, 'port': endport} + if bandwidth: + port_speeds[startport] = bandwidth + + return neighbors, port_speeds + +def parse_asic_png(png, asic_name, hostname): + neighbors = {} + devices = {} + port_speeds = {} + for child in png: + if child.tag == str(QName(ns, "DeviceInterfaceLinks")): + for link in child.findall(str(QName(ns, "DeviceLinkBase"))): + # Chassis internal node is used in multi-asic device or chassis minigraph + # where the minigraph will contain the internal asic connectivity and + # external neighbor information. The ChassisInternal node will be used to + # determine if the link is internal to the device or chassis. + chassis_internal_node = link.find(str(QName(ns, "ChassisInternal"))) + chassis_internal = chassis_internal_node.text if chassis_internal_node is not None else "false" + + # If the link is an external link include the external neighbor + # information in ASIC ports table + if chassis_internal.lower() == "false": + ext_neighbors, ext_port_speeds = parse_asic_external_link(link, asic_name, hostname) + neighbors.update(ext_neighbors) + port_speeds.update(ext_port_speeds) + else: + int_neighbors, int_port_speeds = parse_asic_internal_link(link, asic_name, hostname) + neighbors.update(int_neighbors) + port_speeds.update(int_port_speeds) + + if child.tag == str(QName(ns, "Devices")): + for device in child.findall(str(QName(ns, "Device"))): + (lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device) + device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku } + if deployment_id: + device_data['deployment_id'] = deployment_id + devices[name] = device_data + return (neighbors, devices, port_speeds) def parse_dpg(dpg, hname): for child in dpg: + """In Multi-NPU platforms the acl intfs are defined only for the host not for individual asic. + There is just one aclintf node in the minigraph + Get the aclintfs node first. + """ + if child.find(str(QName(ns, "AclInterfaces"))) is not None: + aclintfs = child.find(str(QName(ns, "AclInterfaces"))) + hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text.lower() != hname.lower(): continue @@ -254,7 +348,6 @@ def parse_dpg(dpg, hname): vlan_attributes['alias'] = vintfname vlans[sonic_vlan_name] = vlan_attributes - aclintfs = child.find(str(QName(ns, "AclInterfaces"))) acls = {} for aclintf in aclintfs.findall(str(QName(ns, "AclInterface"))): if aclintf.find(str(QName(ns, "InAcl"))) is not None: @@ -369,7 +462,7 @@ def parse_cpg(cpg, hname): 'keepalive': keepalive, 'nhopself': nhopself } - else: + elif start_router.lower() == hname.lower(): bgp_sessions[end_peer.lower()] = { 'name': end_router, 'local_addr': start_peer.lower(), @@ -446,6 +539,19 @@ def parse_meta(meta, hname): region = value return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region +def parse_asic_meta(meta, hname): + sub_role = None + device_metas = meta.find(str(QName(ns, "Devices"))) + for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): + if device.find(str(QName(ns1, "Name"))).text.lower() == hname.lower(): + properties = device.find(str(QName(ns1, "Properties"))) + for device_property in properties.findall(str(QName(ns1, "DeviceProperty"))): + name = device_property.find(str(QName(ns1, "Name"))).text + value = device_property.find(str(QName(ns1, "Value"))).text + if name == "SubRole": + sub_role = value + return sub_role + def parse_deviceinfo(meta, hwsku): port_speeds = {} port_descriptions = {} @@ -480,8 +586,7 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m lo_network = ipaddress.IPNetwork(lo[1]) if lo_network.version == 4: lo_addr = str(lo_network.ip) - break - + break results['VXLAN_TUNNEL'] = {chassis_vxlan_tunnel: { 'src_ip': lo_addr }} @@ -520,7 +625,7 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m for pc_member in pc_members: if pc_member[0] == pc_intf: intf_name = pc_member[1] - break + break if intf_name == None: print >> sys.stderr, 'Warning: cannot find any interfaces that belong to %s' % (pc_intf) @@ -567,8 +672,16 @@ def filter_acl_mirror_table_bindings(acls, neighbors, port_channels): # Main functions # ############################################################################### - -def parse_xml(filename, platform=None, port_config_file=None): +def parse_xml(filename, platform=None, port_config_file=None, asic_name=None): + """ Parse minigraph xml file. + + Keyword arguments: + filename -- minigraph file name + platform -- device platform + port_config_file -- port config file name + asic_name -- asic name; to parse multi-asic device minigraph to + generate asic specific configuration. + """ root = ET.parse(filename).getroot() mini_graph_path = filename @@ -588,7 +701,7 @@ def parse_xml(filename, platform=None, port_config_file=None): lo_intfs = None neighbors = None devices = None - hostname = None + sub_role = None docker_routing_config_mode = "separated" port_speeds_default = {} port_speed_png = {} @@ -603,6 +716,13 @@ def parse_xml(filename, platform=None, port_config_file=None): bgp_peers_with_range = None deployment_id = None region = None + hostname = None + + #hostname is the asic_name, get the asic_id from the asic_name + if asic_name is not None: + asic_id = get_npu_id_from_name(asic_name) + else: + asic_id = None hwsku_qn = QName(ns, "HwSku") hostname_qn = QName(ns, "Hostname") @@ -615,34 +735,59 @@ def parse_xml(filename, platform=None, port_config_file=None): if child.tag == str(docker_routing_config_mode_qn): docker_routing_config_mode = child.text - (ports, alias_map) = get_port_config(hwsku, platform, port_config_file) + (ports, alias_map, alias_asic_map) = get_port_config(hwsku=hwsku, platform=platform, port_config_file=port_config_file, asic=asic_id) port_alias_map.update(alias_map) + port_alias_asic_map.update(alias_asic_map) + for child in root: - if child.tag == str(QName(ns, "DpgDec")): - (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, hostname) - elif child.tag == str(QName(ns, "CpgDec")): - (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) - elif child.tag == str(QName(ns, "PngDec")): - (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports) = parse_png(child, hostname) - elif child.tag == str(QName(ns, "UngDec")): - (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname) - elif child.tag == str(QName(ns, "MetadataDeclaration")): - (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region) = parse_meta(child, hostname) - elif child.tag == str(QName(ns, "DeviceInfos")): - (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) - - current_device = [devices[key] for key in devices if key.lower() == hostname.lower()][0] + if asic_name is None: + if child.tag == str(QName(ns, "DpgDec")): + (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, hostname) + elif child.tag == str(QName(ns, "CpgDec")): + (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) + elif child.tag == str(QName(ns, "PngDec")): + (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports) = parse_png(child, hostname) + elif child.tag == str(QName(ns, "UngDec")): + (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, device_hostname) + elif child.tag == str(QName(ns, "MetadataDeclaration")): + (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region) = parse_meta(child, hostname) + elif child.tag == str(QName(ns, "DeviceInfos")): + (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) + else: + if child.tag == str(QName(ns, "DpgDec")): + (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, asic_name) + elif child.tag == str(QName(ns, "CpgDec")): + (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name) + elif child.tag == str(QName(ns, "PngDec")): + (neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname) + elif child.tag == str(QName(ns, "MetadataDeclaration")): + (sub_role) = parse_asic_meta(child, asic_name) + elif child.tag == str(QName(ns, "DeviceInfos")): + (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) + + if asic_name is None: + current_device = [devices[key] for key in devices if key.lower() == hostname.lower()][0] + name = hostname + else: + current_device = [devices[key] for key in devices if key.lower() == asic_name.lower()][0] + name = asic_name + results = {} results['DEVICE_METADATA'] = {'localhost': { 'bgp_asn': bgp_asn, 'deployment_id': deployment_id, 'region': region, 'docker_routing_config_mode': docker_routing_config_mode, - 'hostname': hostname, + 'hostname': name, 'hwsku': hwsku, 'type': current_device['type'] } } + # for this hostname, if sub_role is defined, add sub_role in + # device_metadata + if sub_role is not None: + current_device['sub_role'] = sub_role + results['DEVICE_METADATA']['localhost']['sub_role'] = sub_role results['BGP_NEIGHBOR'] = bgp_sessions results['BGP_MONITORS'] = bgp_monitors results['BGP_PEER_RANGE'] = bgp_peers_with_range @@ -703,9 +848,11 @@ def parse_xml(filename, platform=None, port_config_file=None): for port_name in port_speed_png: # not consider port not in port_config.ini - if port_name not in ports: - print >> sys.stderr, "Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name - continue + #If no port_config_file is found ports is empty so ignore this error + if port_config_file is not None: + if port_name not in ports: + print >> sys.stderr, "Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name + continue ports.setdefault(port_name, {})['speed'] = port_speed_png[port_name] @@ -809,11 +956,14 @@ def parse_xml(filename, platform=None, port_config_file=None): for nghbr in neighbors.keys(): # remove port not in port_config.ini if nghbr not in ports: - print >> sys.stderr, "Warning: ignore interface '%s' in DEVICE_NEIGHBOR as it is not in the port_config.ini" % nghbr + if port_config_file is not None: + print >> sys.stderr, "Warning: ignore interface '%s' in DEVICE_NEIGHBOR as it is not in the port_config.ini" % nghbr del neighbors[nghbr] - results['DEVICE_NEIGHBOR'] = neighbors - results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key.lower() != hostname.lower() } + if asic_name is None: + results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key.lower() != hostname.lower() } + else: + results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key in {device['name'] for device in neighbors.values()} } results['SYSLOG_SERVER'] = dict((item, {}) for item in syslog_servers) results['DHCP_SERVER'] = dict((item, {}) for item in dhcp_servers) results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers) @@ -890,8 +1040,17 @@ def parse_device_desc_xml(filename): return results +def parse_asic_sub_role(filename, asic_name): + if not os.path.isfile(filename): + return None + root = ET.parse(filename).getroot() + for child in root: + if child.tag == str(QName(ns, "MetadataDeclaration")): + sub_role = parse_asic_meta(child, asic_name) + return sub_role port_alias_map = {} +port_alias_asic_map = {} def print_parse_xml(filename): diff --git a/src/sonic-config-engine/portconfig.py b/src/sonic-config-engine/portconfig.py index db2baa30817..87e13687ed5 100644 --- a/src/sonic-config-engine/portconfig.py +++ b/src/sonic-config-engine/portconfig.py @@ -3,11 +3,13 @@ import sys -def get_port_config_file_name(hwsku=None, platform=None): +def get_port_config_file_name(hwsku=None, platform=None, asic=None): port_config_candidates = [] port_config_candidates.append('/usr/share/sonic/hwsku/port_config.ini') if hwsku: if platform: + if asic: + port_config_candidates.append(os.path.join('/usr/share/sonic/device', platform, hwsku, asic,'port_config.ini')) port_config_candidates.append(os.path.join('/usr/share/sonic/device', platform, hwsku, 'port_config.ini')) port_config_candidates.append(os.path.join('/usr/share/sonic/platform', hwsku, 'port_config.ini')) port_config_candidates.append(os.path.join('/usr/share/sonic', hwsku, 'port_config.ini')) @@ -17,17 +19,19 @@ def get_port_config_file_name(hwsku=None, platform=None): return None -def get_port_config(hwsku=None, platform=None, port_config_file=None): + +def get_port_config(hwsku=None, platform=None, port_config_file=None, asic=None): if not port_config_file: - port_config_file = get_port_config_file_name(hwsku, platform) + port_config_file = get_port_config_file_name(hwsku, platform, asic) if not port_config_file: - return ({}, {}) + return ({}, {}, {}) return parse_port_config_file(port_config_file) def parse_port_config_file(port_config_file): ports = {} port_alias_map = {} + port_alias_asic_map = {} # Default column definition titles = ['name', 'lanes', 'alias', 'index'] with open(port_config_file) as data: @@ -49,6 +53,14 @@ def parse_port_config_file(port_config_file): data.setdefault('alias', name) ports[name] = data port_alias_map[data['alias']] = name - return (ports, port_alias_map) + # asic_port_name to sonic_name mapping also included in + # port_alias_map + if (('asic_port_name' in data) and + (data['asic_port_name'] != name)): + port_alias_map[data['asic_port_name']] = name + # alias to asic_port_name mapping + if 'asic_port_name' in data: + port_alias_asic_map[data['alias']] = data['asic_port_name'].strip() + return (ports, port_alias_map, port_alias_asic_map) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 1a94a47c0f9..d8936a83f72 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -37,10 +37,12 @@ from functools import partial from minigraph import minigraph_encoder from minigraph import parse_xml from minigraph import parse_device_desc_xml +from minigraph import parse_asic_sub_role from portconfig import get_port_config from sonic_device_util import get_machine_info from sonic_device_util import get_platform_info from sonic_device_util import get_system_mac +from sonic_device_util import get_npu_id_from_name from config_samples import generate_sample_config from config_samples import get_available_config from swsssdk import SonicV2Connector, ConfigDBConnector @@ -195,6 +197,7 @@ def main(): group.add_argument("-m", "--minigraph", help="minigraph xml file", nargs='?', const='/etc/sonic/minigraph.xml') group.add_argument("-M", "--device-description", help="device description xml file") group.add_argument("-k", "--hwsku", help="HwSKU") + parser.add_argument("-n", "--namespace", help="namespace name, used with -m or -k", nargs='?', const=None) parser.add_argument("-p", "--port-config", help="port config file, used with -m or -k", nargs='?', const=None) parser.add_argument("-y", "--yaml", help="yaml file that contains additional variables", action='append', default=[]) parser.add_argument("-j", "--json", help="json file that contains additional variables", action='append', default=[]) @@ -222,13 +225,18 @@ def main(): data = {} hwsku = args.hwsku + asic_name = args.namespace + asic_id = None + if asic_name is not None: + asic_id = get_npu_id_from_name(asic_name) + if hwsku is not None: hardware_data = {'DEVICE_METADATA': {'localhost': { 'hwsku': hwsku }}} deep_update(data, hardware_data) - (ports, _) = get_port_config(hwsku, platform, args.port_config) + (ports, _, _) = get_port_config(hwsku, platform, args.port_config, asic_id) if not ports: print('Failed to get port config', file=sys.stderr) sys.exit(1) @@ -242,11 +250,11 @@ def main(): minigraph = args.minigraph if platform: if args.port_config != None: - deep_update(data, parse_xml(minigraph, platform, args.port_config)) + deep_update(data, parse_xml(minigraph, platform, args.port_config, asic_name=asic_name)) else: - deep_update(data, parse_xml(minigraph, platform)) + deep_update(data, parse_xml(minigraph, platform, asic_name=asic_name)) else: - deep_update(data, parse_xml(minigraph, port_config_file=args.port_config)) + deep_update(data, parse_xml(minigraph, port_config_file=args.port_config, asic_name=asic_name)) if args.device_description != None: deep_update(data, parse_device_desc_xml(args.device_description)) @@ -267,11 +275,28 @@ def main(): configdb.connect() deep_update(data, FormatConverter.db_to_output(configdb.get_config())) + + # the minigraph file must be provided to get the mac address for backend asics if args.platform_info: + asic_role = None + if asic_name is not None: + if args.minigraph is not None: + asic_role = parse_asic_sub_role(args.minigraph, asic_name) + + if asic_role is not None and asic_role.lower() == "backend": + mac = get_system_mac(namespace=asic_name) + else: + mac = get_system_mac() + else: + mac = get_system_mac() + hardware_data = {'DEVICE_METADATA': {'localhost': { 'platform': platform, - 'mac': get_system_mac() + 'mac': mac, }}} + # The ID needs to be passed to the SAI to identify the asic. + if asic_name is not None: + hardware_data['DEVICE_METADATA']['localhost'].update(asic_id=asic_id) deep_update(data, hardware_data) if args.template is not None: diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index ba57d22f58e..03bd7027a46 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -3,7 +3,8 @@ import yaml import subprocess import re - +from natsort import natsorted +import glob DOCUMENTATION = ''' --- module: sonic_device_util @@ -17,6 +18,9 @@ TODO: this file shall be renamed and moved to other places in future to have it shared with multiple applications. ''' +SONIC_DEVICE_PATH = '/usr/share/sonic/device' +NPU_NAME_PREFIX = 'asic' +NAMESPACE_PATH_GLOB = '/run/netns/*' def get_machine_info(): if not os.path.isfile('/host/machine.conf'): return None @@ -27,7 +31,38 @@ def get_machine_info(): if len(tokens) < 2: continue machine_vars[tokens[0]] = tokens[1].strip() - return machine_vars + return machine_vars + +def get_npu_id_from_name(npu_name): + if npu_name.startswith(NPU_NAME_PREFIX): + return npu_name[len(NPU_NAME_PREFIX):] + else: + return None + +def get_num_npus(): + platform = get_platform_info(get_machine_info()) + asic_conf_file_path = os.path.join(SONIC_DEVICE_PATH, platform, 'asic.conf') + if not os.path.isfile(asic_conf_file_path): + return 1 + with open(asic_conf_file_path) as asic_conf_file: + for line in asic_conf_file: + tokens = line.split('=') + if len(tokens) < 2: + continue + if tokens[0].lower() == 'num_asic': + num_npus = tokens[1].strip() + return num_npus + +def get_namespaces(): + """ + In a multi NPU platform, each NPU is in a Linux Namespace. + This method returns list of all the Namespace present on the device + """ + ns_list = [] + for path in glob.glob(NAMESPACE_PATH_GLOB): + ns = os.path.basename(path) + ns_list.append(ns) + return natsorted(ns_list) def get_platform_info(machine_info): if machine_info != None: @@ -51,7 +86,7 @@ def get_sonic_version_info(): def valid_mac_address(mac): return bool(re.match("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", mac)) -def get_system_mac(): +def get_system_mac(namespace=None): version_info = get_sonic_version_info() if (version_info['asic_type'] == 'mellanox'): @@ -73,10 +108,14 @@ def get_system_mac(): # Try valid mac in eeprom, else fetch it from eth0 platform = get_platform_info(get_machine_info()) hwsku = get_machine_info()['onie_machine'] - profile_cmd = 'cat /usr/share/sonic/device/' + platform +'/'+ hwsku +'/profile.ini | cut -f2 -d=' + profile_cmd = 'cat' + SONIC_DEVICE_PATH + '/' + platform +'/'+ hwsku +'/profile.ini | cut -f2 -d=' hw_mac_entry_cmds = [ profile_cmd, "sudo decode-syseeprom -m", "ip link show eth0 | grep ether | awk '{print $2}'" ] else: - hw_mac_entry_cmds = [ "ip link show eth0 | grep ether | awk '{print $2}'" ] + mac_address_cmd = "cat /sys/class/net/eth0/address" + if namespace is not None: + mac_address_cmd = "sudo ip netns exec {} {}".format(namespace, mac_address_cmd) + + hw_mac_entry_cmds = [mac_address_cmd] for get_mac_cmd in hw_mac_entry_cmds: proc = subprocess.Popen(get_mac_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml new file mode 100644 index 00000000000..118202d9b52 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml @@ -0,0 +1,1214 @@ + + + + + + false + multi_npu_platform_01 + 10.0.0.0 + 01T2 + 10.0.0.1 + 1 + 10 + 3 + + + multi_npu_platform_01 + FC00::1 + 01T2 + FC00::2 + 1 + 10 + 3 + + + false + multi_npu_platform_01 + 10.0.0.8 + 05T2 + 10.0.0.9 + 1 + 10 + 3 + + + multi_npu_platform_01 + FC00::9 + 05T2 + FC00::A + 1 + 10 + 3 + + + BGPSession + false + ASIC2 + 10.1.0.0 + ASIC0 + 10.1.0.1 + 1 + 0 + 0 + + + BGPSession + false + ASIC2 + 10.1.0.4 + ASIC1 + 10.1.0.5 + 1 + 0 + 0 + + + BGPSession + false + ASIC3 + 10.1.0.2 + ASIC0 + 10.1.0.3 + 1 + 0 + 0 + + + BGPSession + false + ASIC3 + 10.1.0.6 + ASIC1 + 10.1.0.7 + 1 + 0 + 0 + + + false + ASIC0 + 10.0.0.0 + 01T2 + 10.0.0.1 + 1 + 10 + 3 + + + ASIC0 + FC00::1 + 01T2 + FC00::2 + 1 + 10 + 3 + + + false + ASIC1 + 10.0.0.8 + 05T2 + 10.0.0.9 + 1 + 10 + 3 + + + ASIC1 + FC00::9 + 05T2 + FC00::A + 1 + 10 + 3 + + + + + 65100 + multi_npu_platform_01 + + +
10.0.0.1
+ + + +
+ +
10.0.0.9
+ + + +
+
+ +
+ + 65100 + + ASIC0 + + + BGPPeer +
10.1.0.1
+ + + +
+ + BGPPeer +
10.1.0.3
+ + + +
+ + BGPPeer +
10.0.0.1
+ + + +
+ + BGPPeer +
FC00::1
+ + + +
+
+ +
+ + 65100 + + ASIC1 + + + BGPPeer +
10.1.0.5
+ + + +
+ + BGPPeer +
10.1.0.7
+ + + +
+ + BGPPeer +
10.0.0.9
+ + + +
+ + BGPPeer +
FC00::A
+ + + +
+
+ +
+ + 65100 + + ASIC2 + + + BGPPeer +
10.1.0.0
+ + + +
+ + BGPPeer +
10.1.0.4
+ + + +
+
+ +
+ + 65100 + + ASIC3 + + + BGPPeer +
10.1.0.2
+ + + +
+ + BGPPeer +
10.1.0.6
+ + + +
+
+ +
+ + 65200 + 01T2 + + + + 65200 + 05T2 + + +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + HostIP1 + Loopback0 + + FC00:1::32/128 + + FC00:1::32/128 + + + + + HostIP + eth0 + + 3.10.147.150/23 + + 3.10.147.150/23 + + + V6HostIP + eth0 + + FC00:2::32/64 + + FC00:2::32/64 + + + + + + + multi_npu_platform_01 + + + PortChannel0002 + Ethernet1/1;Ethernet1/2 + + + + PortChannel0008 + Ethernet1/5;Ethernet1/6 + + + + + + + + PortChannel0002 + 10.0.0.0/31 + + + + PortChannel0002 + FC00::1/126 + + + + PortChannel0008 + 10.0.0.8/31 + + + + PortChannel0008 + FC00::9/126 + + + + + + SNMP_ACL + SNMP + SNMP + + + ERSPAN + Everflow + Everflow + + + ERSPANV6 + EverflowV6 + EverflowV6 + + + VTY_LINE + ssh-only + SSH + + + ;PortChannel0002;PortChannel0008 + DataAcl + DataPlane + + + + + + + + + + LoopbackInterface + HostIP + Loopback0 + + 8.0.0.0/32 + + 8.0.0.0/32 + + + + + + + + ASIC0 + + + PortChannelInterface + PortChannel4001 + Eth4-ASIC0;Eth5-ASIC0 + + + + PortChannelInterface + PortChannel4002 + Eth6-ASIC0;Eth7-ASIC0 + + + + PortChannelInterface + PortChannel0002 + Eth0-ASIC0;Eth1-ASIC0 + + + + + + + + IPInterface + + PortChannel4001 + 10.1.0.1/31 + + + IPInterface + + PortChannel4002 + 10.1.0.3/31 + + + + PortChannel0002 + 10.0.0.0/31 + + + + PortChannel0002 + FC00::1/126 + + + + + + + + + + + + LoopbackInterface + HostIP + Loopback0 + + 8.0.0.1/32 + + 8.0.0.1/32 + + + + + + + + ASIC1 + + + PortChannelInterface + PortChannel4003 + Eth4-ASIC1;Eth5-ASIC1 + + + + PortChannelInterface + PortChannel4004 + Eth6-ASIC1;Eth7-ASIC1 + + + + PortChannel0008 + Eth0-ASIC1;Eth1-ASIC1 + + + + + + + + IPInterface + + PortChannel4003 + 10.1.0.5/31 + + + IPInterface + + PortChannel4004 + 10.1.0.7/31 + + + + PortChannel0008 + 10.0.0.8/31 + + + + PortChannel0008 + FC00::9/126 + + + + + + + + + + + + LoopbackInterface + HostIP + Loopback0 + + 8.0.0.4/32 + + 8.0.0.4/32 + + + + + + + + ASIC2 + + + PortChannelInterface + PortChannel4009 + Eth0-ASIC2;Eth1-ASIC2 + + + + PortChannelInterface + PortChannel4010 + Eth2-ASIC2;Eth3-ASIC2 + + + + + + + + IPInterface + + PortChannel4009 + 10.1.0.0/31 + + + IPInterface + + PortChannel4010 + 10.1.0.4/31 + + + + + + + + + + + + LoopbackInterface + HostIP + Loopback0 + + 8.0.0.5/32 + + 8.0.0.5/32 + + + + + + + + ASIC3 + + + PortChannelInterface + PortChannel4013 + Eth0-ASIC3;Eth1-ASIC3 + + + + PortChannelInterface + PortChannel4014 + Eth2-ASIC3;Eth3-ASIC3 + + + + + + + + IPInterface + + PortChannel4013 + 10.1.0.2/31 + + + IPInterface + + PortChannel4014 + 10.1.0.6/31 + + + + + + + + + + + + DeviceInterfaceLink + 01T2 + Ethernet1 + multi_npu_platform_01 + Ethernet1/1 + + + DeviceInterfaceLink + 01T2 + Ethernet2 + multi_npu_platform_01 + Ethernet1/2 + + + DeviceInterfaceLink + 05T2 + Ethernet1 + multi_npu_platform_01 + Ethernet1/8 + + + DeviceInterfaceLink + 05T2 + Ethernet2 + multi_npu_platform_01 + Ethernet1/9 + + + DeviceInterfaceLink + 40000 + true + ASIC2 + Eth0-ASIC2 + true + ASIC0 + Eth4-ASIC0 + true + + + DeviceInterfaceLink + 40000 + true + ASIC2 + Eth1-ASIC2 + true + ASIC0 + Eth5-ASIC0 + true + + + DeviceInterfaceLink + 40000 + true + ASIC3 + Eth0-ASIC3 + true + ASIC0 + Eth6-ASIC0 + true + + + DeviceInterfaceLink + 40000 + true + ASIC3 + Eth1-ASIC3 + true + ASIC0 + Eth7-ASIC0 + true + + + DeviceInterfaceLink + 40000 + true + ASIC2 + Eth2-ASIC2 + true + ASIC1 + Eth4-ASIC1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC2 + Eth3-ASIC2 + true + ASIC1 + Eth5-ASIC1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC3 + Eth2-ASIC3 + true + ASIC1 + Eth6-ASIC1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC3 + Eth3-ASIC3 + true + ASIC1 + Eth7-ASIC1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC0 + Eth0-ASIC0 + true + multi_npu_platform_01 + Ethernet1/1 + true + + + DeviceInterfaceLink + 40000 + true + ASIC0 + Eth1-ASIC0 + true + multi_npu_platform_01 + Ethernet1/2 + true + + + DeviceInterfaceLink + 40000 + true + ASIC0 + Eth2-ASIC0 + true + multi_npu_platform_01 + Ethernet1/3 + true + + + DeviceInterfaceLink + 40000 + true + ASIC0 + Eth3-ASIC0 + true + multi_npu_platform_01 + Ethernet1/4 + true + + + DeviceInterfaceLink + 40000 + true + ASIC1 + Eth0-ASIC1 + true + multi_npu_platform_01 + Ethernet1/5 + true + + + DeviceInterfaceLink + 40000 + true + ASIC1 + Eth1-ASIC1 + true + multi_npu_platform_01 + Ethernet1/6 + true + + + DeviceInterfaceLink + 40000 + true + ASIC1 + Eth2-ASIC1 + true + multi_npu_platform_01 + Ethernet1/7 + true + + + DeviceInterfaceLink + 40000 + true + ASIC1 + Eth3-ASIC1 + true + multi_npu_platform_01 + Ethernet1/8 + true + + + + + multi_npu_platform_01 + multi-npu-01 + + 3.10.147.150 + + + + 07T2 + + 89.139.132.43 + + VM + + + 01T2 + + 89.139.132.40 + + VM + + + 05T2 + + 89.139.132.42 + + VM + + + 03T2 + + 89.139.132.41 + + VM + + + Asic +
+ 0.0.0.0/0 +
+ + ::/0 + + + + + + + + + + 0.0.0.0/0 + + + ::/0 + + + ASIC0 + multi-npu-asic +
+ + Asic +
+ 0.0.0.0/0 +
+ + ::/0 + + + + + + + + + + 0.0.0.0/0 + + + ::/0 + + + ASIC1 + multi-npu-asic +
+ + Asic +
+ 0.0.0.0/0 +
+ + ::/0 + + + + + + + + + + 0.0.0.0/0 + + + ::/0 + + + ASIC2 + multi-npu-asic +
+ + Asic +
+ 0.0.0.0/0 +
+ + ::/0 + + + + + + + + + + 0.0.0.0/0 + + + ::/0 + + + ASIC3 + multi-npu-asic +
+
+
+ + + true + + + DeviceInterface + + true + true + 1 + Ethernet1/1 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/2 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/3 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/4 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/5 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/6 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/7 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + true + 1 + Ethernet1/8 + + false + 0 + 0 + 40000 + + + true + 0 + multi-npu-01 + + + + + + + multi_npu_platform_01 + + + DeploymentId + + 1 + + + QosProfile + + Profile0 + + + DhcpResources + + 169.118.23.1;169.118.23.2;169.118.23.3;169.118.23.4;169.118.23.5;169.118.23.6;169.118.23.7;169.118.23.8;169.118.23.9;169.118.23.10;169.118.23.11;169.118.23.12;169.118.23.13;169.118.23.14;169.118.23.15;169.118.23.16;169.118.23.17;169.118.23.18;169.118.23.19;169.118.23.20;169.118.23.21;169.118.23.22;169.118.23.23;169.118.23.24;169.118.23.25;169.118.23.26;169.118.23.27;169.118.23.28;169.118.23.29;169.118.23.30;169.118.23.31;169.118.23.32;169.118.23.33;169.118.23.34;169.118.23.35;169.118.23.36;169.118.23.37;169.118.23.38;169.118.23.39;169.118.23.40;169.118.23.41;169.118.23.42;169.118.23.43;169.118.23.44;169.118.23.45;169.118.23.46;169.118.23.47;169.118.23.48 + + + NtpResources + + 17.39.1.129;17.39.1.130 + + + SnmpResources + + 71.49.219.98 + + + SyslogResources + + 71.49.219.8;123.46.98.21 + + + TacacsGroup + + Starlab + + + TacacsServer + + 123.46.98.21 + + + ForcedMgmtRoutes + + 71.49.219.98/31;71.49.219.8;123.46.98.16/28;10.3.149.170/31;40.122.216.24;13.91.48.226;71.49.219.14 + + + ErspanDestinationIpv4 + + 10.20.6.16 + + + + + ASIC0 + + + SubRole + + FrontEnd + + + + + ASIC1 + + + SubRole + + FrontEnd + + + + + ASIC2 + + + SubRole + + FrontEnd + + + + + ASIC3 + + + SubRole + + FrontEnd + + + + + ASIC2 + + + SubRole + + BackEnd + + + + + ASIC3 + + + SubRole + + BackEnd + + + + + + + multi_npu_platform_01 + multi-npu-01 +
diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini new file mode 100644 index 00000000000..3fe912c98c4 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini @@ -0,0 +1,9 @@ +# name lanes alias asic_port_name +Ethernet0 33,34,35,36 Ethernet1/1 Eth0-ASIC0 +Ethernet4 29,30,31,32 Ethernet1/2 Eth1-ASIC0 +Ethernet8 41,42,43,44 Ethernet1/3 Eth2-ASIC0 +Ethernet12 37,38,39,40 Ethernet1/4 Eth3-ASIC0 +Ethernet-BP0 13,14,15,16 Ethernet-BP0 Eth4-ASIC0 +Ethernet-BP4 17,18,19,20 Ethernet-BP4 Eth5-ASIC0 +Ethernet-BP8 21,22,23,24 Ethernet-BP8 Eth6-ASIC0 +Ethernet-BP12 25,26,27,28 Ethernet-BP12 Eth7-ASIC0 \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini new file mode 100644 index 00000000000..c496e0712a4 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini @@ -0,0 +1,9 @@ +# name lanes alias asic_port_name +Ethernet16 33,34,35,36 Ethernet1/5 Eth0-ASIC1 +Ethernet20 29,30,31,32 Ethernet1/6 Eth1-ASIC1 +Ethernet24 41,42,43,44 Ethernet1/7 Eth2-ASIC1 +Ethernet28 37,38,39,40 Ethernet1/8 Eth3-ASIC1 +Ethernet-BP16 13,14,15,16 Ethernet-BP16 Eth4-ASIC1 +Ethernet-BP20 17,18,19,20 Ethernet-BP20 Eth5-ASIC1 +Ethernet-BP24 21,22,23,24 Ethernet-BP24 Eth6-ASIC1 +Ethernet-BP28 25,26,27,28 Ethernet-BP28 Eth7-ASIC1 \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini new file mode 100644 index 00000000000..4ae0575835a --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini @@ -0,0 +1,9 @@ +# name lanes alias asic_port_name +Ethernet-BP256 61,62,63,64 Ethernet-BP256 Eth0-ASIC2 +Ethernet-BP260 57,58,59,60 Ethernet-BP260 Eth1-ASIC2 +Ethernet-BP264 53,54,55,56 Ethernet-BP264 Eth2-ASIC2 +Ethernet-BP268 49,50,51,52 Ethernet-BP268 Eth3-ASIC2 +Ethernet-BP272 45,46,47,48 Ethernet-BP272 Eth4-ASIC2 +Ethernet-BP276 41,42,43,44 Ethernet-BP276 Eth5-ASIC2 +Ethernet-BP280 37,38,39,40 Ethernet-BP280 Eth6-ASIC2 +Ethernet-BP284 33,34,35,36 Ethernet-BP284 Eth7-ASIC2 \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini new file mode 100644 index 00000000000..8f45ed14946 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini @@ -0,0 +1,9 @@ +# name lanes alias asic_port_name +Ethernet-BP384 29,30,31,32 Ethernet-BP384 Eth0-ASIC3 +Ethernet-BP388 25,26,27,28 Ethernet-BP388 Eth1-ASIC3 +Ethernet-BP392 21,22,23,24 Ethernet-BP392 Eth2-ASIC3 +Ethernet-BP396 17,18,19,20 Ethernet-BP396 Eth3-ASIC3 +Ethernet-BP400 13,14,15,16 Ethernet-BP400 Eth4-ASIC3 +Ethernet-BP404 9,10,11,12 Ethernet-BP404 Eth5-ASIC3 +Ethernet-BP408 5,6,7,8 Ethernet-BP408 Eth6-ASIC3 +Ethernet-BP412 1,2,3,4 Ethernet-BP412 Eth7-ASIC3 \ No newline at end of file diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py new file mode 100644 index 00000000000..6facae0451d --- /dev/null +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -0,0 +1,221 @@ +import unittest +from unittest import TestCase +import subprocess +import os +import json +import yaml + +SKU = 'multi-npu-01' +ASIC_SKU = 'multi-npu-asic' +NUM_ASIC = 4 +HOSTNAME = 'multi_npu_platform_01' + + +class TestMultiNpuCfgGen(TestCase): + + def setUp(self): + self.test_dir = os.path.dirname(os.path.realpath(__file__)) + self.test_data_dir = os.path.join(self.test_dir, 'multi_npu_data') + self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.sample_graph = os.path.join(self.test_data_dir, 'sample-minigraph.xml') + self.port_config = [] + for asic in range(NUM_ASIC): + self.port_config.append(os.path.join(self.test_data_dir, "sample_port_config-{}.ini".format(asic))) + + def run_script(self, argument, check_stderr=False): + print '\n Running sonic-cfggen ' + argument + if check_stderr: + output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + linecount = output.strip().count('\n') + if linecount <= 0: + print ' Output: ' + output.strip() + else: + print ' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output)) + return output + + def run_diff(self, file1, file2): + return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) + + def run_script_for_asic(self,argument,asic, port_config=None): + argument = "{} -n asic{} ".format(argument, asic) + if port_config: + argument += "-p {}".format(port_config) + output = self.run_script(argument) + return output + + def test_dummy_run(self): + argument = '' + output = self.run_script(argument) + self.assertEqual(output, '') + + def test_hwsku(self): + argument = "-v \"DEVICE_METADATA[\'localhost\'][\'hwsku\']\" -m \"{}\"".format(self.sample_graph) + output = self.run_script(argument) + self.assertEqual(output.strip(), SKU) + for asic in range(NUM_ASIC): + output = self.run_script_for_asic(argument, asic) + self.assertEqual(output.strip(), SKU) + + def test_print_data(self): + argument = "-m \"{}\" --print-data".format(self.sample_graph) + output = self.run_script(argument) + self.assertGreater(len(output.strip()) , 0) + for asic in range(NUM_ASIC): + output = self.run_script_for_asic(argument, asic) + self.assertGreater(len(output.strip()) , 0) + + def test_additional_json_data(self): + argument = '-a \'{"key1":"value1"}\' -v key1' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'value1') + for asic in range(NUM_ASIC): + output = self.run_script_for_asic(argument, asic) + self.assertEqual(output.strip(), 'value1') + + def test_read_yaml(self): + argument = '-v yml_item -y ' + os.path.join(self.test_dir, 'test.yml') + output = yaml.load(self.run_script(argument)) + self.assertListEqual(output, ['value1', 'value2']) + for asic in range(NUM_ASIC): + output = yaml.load(self.run_script_for_asic(argument, asic)) + self.assertListEqual(output, ['value1', 'value2']) + + def test_render_template(self): + argument = '-y ' + os.path.join(self.test_dir, 'test.yml') + ' -t ' + os.path.join(self.test_dir, 'test.j2') + output = self.run_script(argument) + self.assertEqual(output.strip(), 'value1\nvalue2') + for asic in range(NUM_ASIC): + output = self.run_script_for_asic(argument, asic) + self.assertEqual(output.strip(), 'value1\nvalue2') + + def test_metadata_tacacs(self): + argument = '-m "' + self.sample_graph + '" --var-json "TACPLUS_SERVER"' + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {'123.46.98.21': {'priority': '1', 'tcp_port': '49'}}) + #TACPLUS_SERVER not present in the asic configuration. + for asic in range(NUM_ASIC): + output = json.loads(self.run_script_for_asic(argument, asic, self.port_config[asic])) + self.assertDictEqual(output, {}) + + def test_metadata_ntp(self): + argument = '-m "' + self.sample_graph + '" --var-json "NTP_SERVER"' + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {'17.39.1.130': {}, '17.39.1.129': {}}) + #NTP data is present only in the host config + for asic in range(NUM_ASIC): + output = json.loads(self.run_script_for_asic(argument, asic, self.port_config[asic])) + print "Log:asic{} sku {}".format(asic,output) + self.assertDictEqual(output, {}) + + def test_mgmt_port(self): + argument = '-m "' + self.sample_graph + '" --var-json "MGMT_PORT"' + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {'eth0': {'alias': 'eth0', 'admin_status': 'up'}}) + for asic in range(NUM_ASIC): + output = json.loads(self.run_script_for_asic(argument, asic, self.port_config[asic])) + self.assertDictEqual(output, {}) + + def test_frontend_asic_portchannels(self): + argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'PortChannel0002': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet0', 'Ethernet4'], 'mtu': '9100'}, + 'PortChannel4001': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet-BP0', 'Ethernet-BP4'], 'mtu': '9100'}, + 'PortChannel4002': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet-BP8', 'Ethernet-BP12'], 'mtu': '9100'}}) + + def test_backend_asic_portchannels(self): + argument = "-m {} -p {} -n asic3 --var-json \"PORTCHANNEL\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'PortChannel4013': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet-BP384', 'Ethernet-BP388'], 'mtu': '9100'}, + 'PortChannel4014': {'admin_status': 'up', 'min_links': '2', 'members': ['Ethernet-BP392', 'Ethernet-BP396'], 'mtu': '9100'}}) + + def test_frontend_asic_portchannel_mem(self): + argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL_MEMBER\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertListEqual(output.keys(), \ + ['PortChannel4002|Ethernet-BP8', 'PortChannel0002|Ethernet0', 'PortChannel0002|Ethernet4', 'PortChannel4002|Ethernet-BP12', 'PortChannel4001|Ethernet-BP0', 'PortChannel4001|Ethernet-BP4']) + + def test_backend_asic_portchannels_mem(self): + argument = "-m {} -p {} -n asic3 --var-json \"PORTCHANNEL_MEMBER\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertListEqual(output.keys(), \ + ['PortChannel4013|Ethernet-BP384', 'PortChannel4014|Ethernet-BP392', 'PortChannel4014|Ethernet-BP396', 'PortChannel4013|Ethernet-BP388']) + + def test_frontend_asic_portchannel_intf(self): + argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL_INTERFACE\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertListEqual(output.keys(), \ + ['PortChannel4001|10.1.0.1/31', 'PortChannel0002|FC00::1/126', 'PortChannel4002|10.1.0.3/31', 'PortChannel0002', 'PortChannel0002|10.0.0.0/31', 'PortChannel4001', 'PortChannel4002']) + + def test_backend_asic_portchannel_intf(self): + argument = "-m {} -p {} -n asic3 --var-json \"PORTCHANNEL_INTERFACE\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertListEqual(output.keys(), \ + ['PortChannel4013', 'PortChannel4013|10.1.0.2/31', 'PortChannel4014', 'PortChannel4014|10.1.0.6/31']) + + def test_frontend_asic_device_neigh(self): + argument = "-m {} -p {} -n asic0 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'Ethernet0': {'name': '01T2', 'port': 'Ethernet1'}, + 'Ethernet4': {'name': '01T2', 'port': 'Ethernet2'}, + 'Ethernet-BP4': {'name': 'ASIC2', 'port': 'Eth1-ASIC2'}, + 'Ethernet-BP12': {'name': 'ASIC3', 'port': 'Eth1-ASIC3'}, + 'Ethernet-BP0': {'name': 'ASIC2', 'port': 'Eth0-ASIC2'}, + 'Ethernet-BP8': {'name': 'ASIC3', 'port': 'Eth0-ASIC3'}}) + + def test_frontend_asic_device_neigh_metadata(self): + argument = "-m {} -p {} -n asic0 --var-json \"DEVICE_NEIGHBOR_METADATA\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'01T2': {'lo_addr': None, 'mgmt_addr': '89.139.132.40', 'hwsku': 'VM', 'type': 'SpineRouter'}, + 'ASIC3': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, + 'ASIC2': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}}) + + def test_backend_asic_device_neigh(self): + argument = "-m {} -p {} -n asic3 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'Ethernet-BP396': {'name': 'ASIC1', 'port': 'Eth7-ASIC1'}, + 'Ethernet-BP384': {'name': 'ASIC0', 'port': 'Eth6-ASIC0'}, + 'Ethernet-BP392': {'name': 'ASIC1', 'port': 'Eth6-ASIC1'}, + 'Ethernet-BP388': {'name': 'ASIC0', 'port': 'Eth7-ASIC0'}}) + + def test_backend_device_neigh_metadata(self): + argument = "-m {} -p {} -n asic3 --var-json \"DEVICE_NEIGHBOR_METADATA\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'ASIC1': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, + 'ASIC0': {'lo_addr': '0.0.0.0/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}}) + + def test_frontend_bgp_neighbor(self): + argument = "-m {} -p {} -n asic0 --var-json \"BGP_NEIGHBOR\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'10.0.0.1': {'rrclient': 0, 'name': '01T2', 'local_addr': '10.0.0.0', 'nhopself': 0, 'holdtime': '10', 'asn': '65200', 'keepalive': '3'}, + '10.1.0.0': {'rrclient': 0, 'name': 'ASIC2', 'local_addr': '10.1.0.1', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}, + 'fc00::2': {'rrclient': 0, 'name': '01T2', 'local_addr': 'fc00::1', 'nhopself': 0, 'holdtime': '10', 'asn': '65200', 'keepalive': '3'}, + '10.1.0.2': {'rrclient': 0, 'name': 'ASIC3', 'local_addr': '10.1.0.3', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}}) + + def test_backend_asic_bgp_neighbor(self): + argument = "-m {} -p {} -n asic3 --var-json \"BGP_NEIGHBOR\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + {'10.1.0.7': {'rrclient': 0, 'name': 'ASIC1', 'local_addr': '10.1.0.6', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}, + '10.1.0.3': {'rrclient': 0, 'name': 'ASIC0', 'local_addr': '10.1.0.2', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0'}}) + + def test_device_asic_metadata(self): + argument = "-m {} --var-json DEVICE_METADATA".format(self.sample_graph) + for asic in range(NUM_ASIC): + output = json.loads(self.run_script_for_asic(argument, asic,self.port_config[asic])) + asic_name = "asic{}".format(asic) + self.assertEqual(output['localhost']['hostname'], asic_name) + self.assertEqual(output['localhost']['type'], 'Asic') + if asic == 0 or asic == 1: + self.assertEqual(output['localhost']['sub_role'], 'FrontEnd') + else: + self.assertEqual(output['localhost']['sub_role'], 'BackEnd') From 35998ba5cf2192eae1d0ef58f2d34a94833cdcb5 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Mon, 4 May 2020 23:01:50 -0700 Subject: [PATCH 54/69] Added default mgmt routes and rules --- files/image_config/hostcfgd/hostcfgd | 38 ++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 290c4c17020..141881e4d88 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -429,9 +429,15 @@ class MgmtIntfCfg: cfg_attr_set(cmd, 'mtu', mtu, appIntf) def mgmt_intf_admin_status_set (self, ifname, admin_status, appIntf): + if (admin_status != "up"): + self.handle_admin_status_change(ifname, "DEL") + cmd = 'ip link set {} {}'.format(ifname, admin_status) cfg_attr_set(cmd, 'admin_status', admin_status, appIntf) + if (admin_status == "up"): + self.handle_admin_status_change(ifname, "ADD") + def mgmt_intf_description_set (self, ifname, description, appIntf): appIntf['description'] = description @@ -450,14 +456,36 @@ class MgmtIntfCfg: cmd = "ethtool -s {} autoneg {}".format(ifname, an) cfg_attr_set(cmd, 'autoneg', autoneg, appIntf) + def handle_admin_status_change(self, ifname, oper): + keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) + for it in keys: + if type(it) is unicode: + continue + + if it[0] == ifname: + data = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, it) + if ('gwaddr' in data): + self.mgmt_intf_gwaddr_set(ifname, it[1], data['gwaddr'], oper) + + self.mgmt_intf_ip_prefix_set(ifname, it[1], oper) + + if ('forced_mgmt_routes' in data): + forced_routes = data['forced_mgmt_routes'] + self.mgmt_intf_forced_mgmt_routes_set(ifname, it[1], forced_routes, oper) + + + def mgmt_intf_gwaddr_set(self, ifname, ip_prefix, gwaddr, op): vrf_table = self.mgmt_vrf_cfg.mgmt_vrf_table_get() ip_conf = netaddr.IPNetwork(ip_prefix) ver = "-4" + ext = "" if ip_conf.version == 6: ver = "-6" + if op.lower() == "add": + ext = "metric 201" - cmd = "ip {} route {} default via {} dev {} table {}".format(ver, op.lower(), gwaddr, ifname, vrf_table) + cmd = "ip {} route {} default via {} dev {} table {} {}".format(ver, op.lower(), gwaddr, ifname, vrf_table, ext) cfg_attr_set(cmd) def mgmt_intf_dhclient_set (self, ifname, attr, enable): @@ -484,15 +512,21 @@ class MgmtIntfCfg: run_command(cmd) def mgmt_intf_ip_prefix_set (self, ifname, ip_prefix, op): + vrf_table = self.mgmt_vrf_cfg.mgmt_vrf_table_get() ver = "-4" + plen = "32" mgmt_conf = netaddr.IPNetwork(ip_prefix) if mgmt_conf.version == 6: ver = "-6" + plen = "128" cmd = "ip {} addr {} {} dev {}".format(ver, op.lower(), ip_prefix, ifname) cfg_attr_set(cmd) - cmd = "ip {} rule {} from {} table default".format(ver, op.lower(), str(mgmt_conf.ip)) + cmd = "ip {} route {} {}/{} dev {} table {}".format(ver, op.lower(), str(mgmt_conf.network), mgmt_conf.prefixlen, ifname, vrf_table) + cfg_attr_set(cmd) + + cmd = "ip {} rule {} from {}/{} table {}".format(ver, op.lower(), str(mgmt_conf.ip), plen, vrf_table) cfg_attr_set(cmd) def mgmt_intf_forced_mgmt_routes_set (self, ifname, ip_prefix, forced_routes, op, app_forced_routes = []): From d2386626d0d19c3db47d73f6d09eae4297907d08 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Mon, 4 May 2020 23:15:04 -0700 Subject: [PATCH 55/69] Addressed issuses reported LGTM analysis --- files/image_config/hostcfgd/hostcfgd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 141881e4d88..739a8c39a75 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -371,10 +371,10 @@ def cfg_attr_set (cmd, attr = None, value = None, appIntf = None): return rc -def is_attr_cfg_required (attr, cfg_data, app_data, cfgAllAtrr = True): +def is_attr_cfg_required (attr, cfg_data, app_data, cfgAllAttr = True): rc = False - if ((cfgAllAtrr == True) or (attr not in app_data) or (cfg_data[attr] != app_data[attr])): + if ((cfgAllAttr == True) or (attr not in app_data) or (cfg_data[attr] != app_data[attr])): rc = True return rc @@ -553,7 +553,7 @@ class MgmtIntfCfg: def handle_mgmt_port_cfg(self, key, data): mgmt_intf = self.app_db.get_entry(APP_MGMT_PORT_TABLE, key) - cfgAllAtrr = False + cfgAllAttr = False if mgmt_intf == {}: cfgAllAttr = True @@ -565,7 +565,7 @@ class MgmtIntfCfg: 'speed' : self.mgmt_intf_speed_set, } for attr in data: - if (is_attr_cfg_required(attr, data, mgmt_intf, cfgAllAtrr) == True): + if (is_attr_cfg_required(attr, data, mgmt_intf, cfgAllAttr) == True): if attr == 'speed': autoneg = "on" if 'autoneg' in data: From 8671fd175f943d584003fe1304d8f4fe2b60e6ba Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Mon, 4 May 2020 23:55:18 -0700 Subject: [PATCH 56/69] Addressed issuses reported LGTM analysis --- files/image_config/hostcfgd/hostcfgd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 739a8c39a75..b181dc18076 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -341,7 +341,7 @@ class MgmtVrfCfg: self.unconfigure_mgmt_vrf() else: self.unconfigure_mgmt_vrf() - except: + except Exception as inst: syslog.syslog(syslog.LOG_ERR, "{} MGMT VRF Configuration failed.".format(key)) def mgmt_vrf_table_get(self): From 6c9dd7674d1105e01a134c79c86210ecd0823444 Mon Sep 17 00:00:00 2001 From: Srideep Date: Tue, 5 May 2020 01:22:10 -0600 Subject: [PATCH 57/69] [device] DellEMC s5232f 50G hwsku support (#4525) * [device] DellEmc S5232 support for new hwsku C8D48 8 100G ports and 48 50G ports * 10G ports update for S5232 hwsku-C8D48 Signed-off-by: Srideep Devireddy --- .../DellEMC-S5232f-C8D48/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 37 ++ .../buffers_defaults_t1.j2 | 37 ++ .../DellEMC-S5232f-C8D48/custom_led.bin | Bin 0 -> 468 bytes .../DellEMC-S5232f-C8D48/linkscan_led_fw.bin | Bin 0 -> 4752 bytes .../pg_profile_lookup.ini | 17 + .../DellEMC-S5232f-C8D48/port_config.ini | 59 ++ .../DellEMC-S5232f-C8D48/qos.json.j2 | 1 + .../DellEMC-S5232f-C8D48/sai.profile | 1 + .../DellEMC-S5232f-C8D48/sai_preinit_cmd.soc | 2 + .../td3-s5232f-8x100G+48x50G.config.bcm | 572 ++++++++++++++++++ 11 files changed, 728 insertions(+) create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers.json.j2 create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 create mode 100755 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/custom_led.bin create mode 100755 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/linkscan_led_fw.bin create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/pg_profile_lookup.ini create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/qos.json.j2 create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers.json.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers.json.j2 new file mode 100644 index 00000000000..0b1cb2c541b --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 new file mode 100644 index 00000000000..98ec91a9b69 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 @@ -0,0 +1,37 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "28550336", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_pool": { + "size": "28550336", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "static", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 new file mode 100644 index 00000000000..98ec91a9b69 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 @@ -0,0 +1,37 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "28550336", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_pool": { + "size": "28550336", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "static", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_pool]", + "size":"0", + "mode": "dynamic", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/custom_led.bin b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..49e559cd9813f2cb9191012b36a295f1f3f54b97 GIT binary patch literal 468 zcmeycHQp`E&DYJv?ZcMV4W8ai8Bz%z-mV$42_8NSN*?|U%8Y7T+!|C@xiPD4a7%UL zbzq+A;J49@<$;1W<3$#8pu7pAkzxhY#7+j*3{OeE4#sJTZZjS1GWeX>E;s^B&dp%Z zmAR1UCiTD(XcOaHJtxr%6E`(z+TUbR+w7L;#-bYMX6oc{p*4eP-pW{3OJAoyO=_v{QgZSITm-V92!5~4F0w3#l*ct<5LJz!Ll z0@9M+voaWsW+gBxA5LISbWn0iWKwEMJe=sL%$(Gu?3~n;#GrgQ>2UJl6yXOD8`(73 zFES}IJYZ6Ebz_`o>U8Mh(dQ5uPR%bD4!f;=&bq;7&jh!bZj0PjyM5Su!0n191H%a* zb^+oQ8yFZE7@3$^SlQS)IJvlac=`AR1cih}M8(7Lc_u%BBP>XV&mcy p5|ffsQq$5iGPAOCa`W;F3X6(MO3TVCDyyn%YU}D7nt*OV0sz^yjTHa@ literal 0 HcmV?d00001 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/linkscan_led_fw.bin b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/linkscan_led_fw.bin new file mode 100755 index 0000000000000000000000000000000000000000..c2fa94a2d8cb11161cc337d00971e7267f08d32e GIT binary patch literal 4752 zcmaJ_4|G#in*ZL*|2Azy+Zoc5mX}c4ms;y9bU~1VuX%Wzlomn{XHEp&d8tKTnBvB> z%HVL0w1veY2raU1fYDXQGj>L1twf-LK>ACNH@80|S?svbx_ZETxT>#+6b|1DM`fa;u@ByR;umx^v8u#B3D!DlgZfM^@ z;Q;c^CBFRwxWf(h0db9cb%)D8;5XPQf3Q6mUeN{hti;<`5lVrrmYc;Qy%8&k$0esUPf5^pEmrRaCQ5>lU|3K3 zr6M~d&ndNCPHCN$VW{M$G_VWhSET{5B|!Nf3bgqjlKxF>69W<@dTaslHxkr?($3@9f)U^Wp8I?dAP#Xi(n{(v#pLdvHVpyOKV3O=eY&!rwi^YNJ~#b0Mezf zI8YW4El%n~i#;Glq0$F679Wg2a3Nk6-FqK|dsPRe9~;xLep^T|n4| zM}ZMDJigRXy{WEe<3sl3%m zEqzV|)+pDaM~r(YKiKaQ+x$w(p)3_&N?5}G($OuAxadhOYTpvkIm&6TaHeArwcr*i ztUmMzTGr*qz(Liqj90K)yKU?IbYptTNGuUc__yEZP*+Eb!i$~YfGTgDU#K9wm9=jY z+7Puqj{-(TfwOGtWM{ARysLOZm&g1=X92-m-|8LgRc94s0;gqaB)^7vLbqfQ?Gp~I z2S?QEU2?a;TL*jJ?6r_!yE-@6UXXuZN59qU*o33s_Vj<(!*ap)>98L5j_q+%!)5X} z0d43usZTO;FnrdvU;>iIa!|$Byy4PKQj9jP^3{zcBftP#g7%FHsRSeka}TgnKeTv(Nk>v)X2T%vuw1?#&>UazzOlu4CpEm!1tUhHS|K(E zRn&35X2_*QJ81HpS110*3aw~`b92;jf3>Hk&C1SO;ZJ!hyf(+zz_2E?DsKns*upr# zX3Ps_Y}q>jp23_sys%C)Q~@vu_mLAQ;rBHNCx%^LPChCPS)KD%+KBt#g;vs@=m$-F z)jb}A=F-kuXwJm6acHJxuv4LeJ`cL~%tJ;KtlgH8Sz+CwRAQ{$@ zC&%0vp=alGuv&K3=#cK2a}o=_{~F)M7BfW|ZCnE=t}B|V&%6zX1rT~(?F{y7^Uy|#BYnVY_uLLWIbfV;UrKZiq) zw2ngZ_gVAHz*t`yfcL6?;al-&xABHynZVn&c#GMuC;MTQ&tt6eoAxBFeHymc8KnDUL1Ve~zPH<4S|DfWQ)^<&l;{MKSKhLc=B%JYXwJp2lv#Fz=x>H=s0p#>N^0_)iF(V$RH;QAZS0=C5 z!`YoSbMuWURhN%tY5S01#@d29P7Y)rM_n&Fp=!G?7r;m{kjj;NHk1%80ahzBsK;$t z8tVi{(h-VTML-M5`?CyU@BWUH9l!3$KJ0EJNFk^8TpH`_4wVbqLggW3HF+Mv$abtS zMp4DD`W}8ww)Z=HLr$&J_uhnGlGV=Rw|J;|eAV~xw(REb@CL*u!=bVLxQD-zJG;Q~ zAThr(0!E^6k8rGytnapM^=bHZZjM{$vk6Q1hrPSK=Eg6kpze8`1rBxIKC*VbNNRk$ zeGihIJ}cq)W`4{?%lGmx3%kADwq=dirh@1vg4f*i5n9iRe#W_H6UlIk8|pxMa%?HC zZ<8gWq~1`purS7M1Ut9#Ak@2azBhdmiTZxb)BMveN~V^ky&jv{nVf=KHF*R<-?zI} zZT@wP_s|ZQf#qIv!$|zT_9`OO1Z34&FlY)sC2|m zI7Iwyt|VTd$`s=~b(^A@r#eu!nEY{~4s*@syD;A^tS&-v{Iq&AOy{ILG;xkY}`J4;py_miEv z2LAP;mBPjz{gGFM8~U9ll|KKo0@9dAw)g4#3dkdW0ePfnf8V#rBR%K)pm`zg(~?K( zcf7ydwPP`VbkS?NttH*I#X>i(ceH4s@P1GKj#q@Jo;MkgPDXO*E$thqVHnmDE~upR z3h81+3O$HYBypX4R9x4AHHh+575OiUyzP*`!>?m+OeuJHrW(e?J2k6_Bti0e=ASL2 z`2IYj=IGOS%Q#@Ycpt;2F_Pi9lKR7p4(Pmp=OPrITa?uDSq({w%^jFG@hdf>MSpe@ zDx{?TIKz-!WK0^DRte)M3l~&R)xj{-FX>WJ6S+m5z*=Ng#)+Jg`Yc!N_DiGfR<|m% zxJyZWknhzK5v34CCZMEFWjKtGLS(QrSP3yQ7UUx%n=xQy82u*Mj^|_Zd|c4^xERT( zanXuCMWr!_4N>Kc2jC3GwCZo?%CP@-fVL7fp3OvuIr!(9o2$VuGKbv`QmDP#W(&3V z1o8}GWi^l?_gbQrDpw4Qab!&^=Kl;|+h%%Oe*nx?UzBo~i@X_%Pz*Tj5-pGNlt9Ht z`2oQ$wxGr!xju6{p;5ErN-mPd^MsC6ww4mL60{xpjAs0+G5p|FMnQmY2_Pkjg za<$3jS4qd->S5OkS$nmJZIXLgCe{>pxvf@Cc6G?Es+i6Jp`~%&T~R&gx=l7-UF)`3 zS$Qpv6~~M?wlKa1XD^lSz#ckQj6J3CCeo7E%4_L@zMQBpJUxY|ID}}2YxDJl2ES$! zT70GwdVGGJFyQmcgbAP55=Hp@94k54VI+V%TaKPuc1cqY&)g8;R#X0Lv^%ZA#Pe)g zr!W5Tf<+9d)gALT&MwN=1(mv0(UNkk5h}e-Nhb=_7G-*#l9X$SRvd-oP+F}uJo=rQ z&qnTl;yl2r;eDYO4BHguc>z7x#h=vpkCk-0e6gR$GzStPmHqK0F;>Ei(LG`@aU7MK* zwoja<;bXTwKWfx4; zko)f43LjayvsT1oNOcI=EjZhLghxNuk0v`Yovp&;>m+9 z-G}#73)Z_N?k(dT5ErBhk&bHPbd3e?_kWI|AG4a+?elm2WJKSgcUwe#M|t&xaRSyw zDdu+ZgM=6Pt7~YzkpJHd9XGy%dLDH?QLSo){j2}O*o@P&3-E4& X`cUsHXR!vGk^Z4y?GFw9z}SBSTZoUr literal 0 HcmV?d00001 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/pg_profile_lookup.ini b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/pg_profile_lookup.ini new file mode 100644 index 00000000000..aedda37a887 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -3 2288 + 25000 5m 1248 2288 53248 -3 2288 + 40000 5m 1248 2288 66560 -3 2288 + 50000 5m 1248 2288 90272 -3 2288 + 100000 5m 1248 2288 165568 -3 2288 + 10000 40m 1248 2288 37024 -3 2288 + 25000 40m 1248 2288 53248 -3 2288 + 40000 40m 1248 2288 71552 -3 2288 + 50000 40m 1248 2288 96096 -3 2288 + 100000 40m 1248 2288 177632 -3 2288 + 10000 300m 1248 2288 46176 -3 2288 + 25000 300m 1248 2288 79040 -3 2288 + 40000 300m 1248 2288 108160 -3 2288 + 50000 300m 1248 2288 141856 -3 2288 + 100000 300m 1248 2288 268736 -3 2288 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini new file mode 100644 index 00000000000..b7a336827ff --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/port_config.ini @@ -0,0 +1,59 @@ +# name lanes alias index speed +Ethernet0 1,2 fiftyGigE1/1/1 1 50000 +Ethernet2 3,4 fiftyGigE1/1/2 1 50000 +Ethernet4 5,6 fiftyGigE1/2/1 2 50000 +Ethernet6 7,8 fiftyGigE1/2/2 2 50000 +Ethernet8 9,10 fiftyGigE1/3/1 3 50000 +Ethernet10 11,12 fiftyGigE1/3/2 3 50000 +Ethernet12 13,14 fiftyGigE1/4/1 4 50000 +Ethernet14 15,16 fiftyGigE1/4/2 4 50000 +Ethernet16 17,18 fiftyGigE1/5/1 5 50000 +Ethernet18 19,20 fiftyGigE1/5/2 5 50000 +Ethernet20 21,22 fiftyGigE1/6/1 6 50000 +Ethernet22 23,24 fiftyGigE1/6/2 6 50000 +Ethernet24 25,26,27,28 hundredGigE1/7 7 100000 +Ethernet28 29,30,31,32 hundredGigE1/8 8 100000 +Ethernet32 33,34,35,36 hundredGigE1/9 9 100000 +Ethernet36 37,38,39,40 hundredGigE1/10 10 100000 +Ethernet40 41,42 fiftyGigE1/11/1 11 50000 +Ethernet42 43,44 fiftyGigE1/11/2 11 50000 +Ethernet44 45,46 fiftyGigE1/12/1 12 50000 +Ethernet46 47,48 fiftyGigE1/12/2 12 50000 +Ethernet48 49,50 fiftyGigE1/13/1 13 50000 +Ethernet50 51,52 fiftyGigE1/13/2 13 50000 +Ethernet52 53,54 fiftyGigE1/14/1 14 50000 +Ethernet54 55,56 fiftyGigE1/14/2 14 50000 +Ethernet56 57,58 fiftyGigE1/15/1 15 50000 +Ethernet58 59,60 fiftyGigE1/15/2 15 50000 +Ethernet60 61,62 fiftyGigE1/16/1 16 50000 +Ethernet62 63,64 fiftyGigE1/16/2 16 50000 +Ethernet64 65,66 fiftyGigE1/17/1 17 50000 +Ethernet66 67,68 fiftyGigE1/17/2 17 50000 +Ethernet68 69,70 fiftyGigE1/18/1 18 50000 +Ethernet70 71,72 fiftyGigE1/18/2 18 50000 +Ethernet72 73,74 fiftyGigE1/19/1 19 50000 +Ethernet74 75,76 fiftyGigE1/19/2 19 50000 +Ethernet76 77,78 fiftyGigE1/20/1 20 50000 +Ethernet78 79,80 fiftyGigE1/20/2 20 50000 +Ethernet80 81,82 fiftyGigE1/21/1 21 50000 +Ethernet82 83,84 fiftyGigE1/21/2 21 50000 +Ethernet84 85,86 fiftyGigE1/22/1 22 50000 +Ethernet86 87,88 fiftyGigE1/22/2 22 50000 +Ethernet88 89,90 fiftyGigE1/23/1 23 50000 +Ethernet90 91,92 fiftyGigE1/23/2 23 50000 +Ethernet92 93,94 fiftyGigE1/24/1 24 50000 +Ethernet94 95,96 fiftyGigE1/24/2 24 50000 +Ethernet96 97,98 fiftyGigE1/25/1 25 50000 +Ethernet98 99,100 fiftyGigE1/25/2 25 50000 +Ethernet100 101,102 fiftyGigE1/26/1 26 50000 +Ethernet102 103,104 fiftyGigE1/26/2 26 50000 +Ethernet104 105,106,107,108 hundredGigE1/27 27 100000 +Ethernet108 109,110,111,112 hundredGigE1/28 28 100000 +Ethernet112 113,114,115,116 hundredGigE1/29 29 100000 +Ethernet116 117,118,119,120 hundredGigE1/30 30 100000 +Ethernet120 121,122 fiftyGigE1/31/1 31 50000 +Ethernet122 123,124 fiftyGigE1/31/2 31 50000 +Ethernet124 125,126 fiftyGigE1/32/1 32 50000 +Ethernet126 127,128 fiftyGigE1/32/2 32 50000 +Ethernet128 129 tenGigE1/33 33 10000 +Ethernet129 128 tenGigE1/34 34 10000 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/qos.json.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/qos.json.j2 new file mode 100644 index 00000000000..3e548325ea3 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile new file mode 100644 index 00000000000..0daed30c3bc --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-8x100G+48x50G.config.bcm diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai_preinit_cmd.soc new file mode 100644 index 00000000000..4d62900f898 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm new file mode 100644 index 00000000000..cf0bfd043ee --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm @@ -0,0 +1,572 @@ +os=unix + +core_clock_frequency=1525 +dpp_clock_ratio=2:3 + +parity_enable=1 +parity_correction=1 +tdma_intr_enable=1 +schan_intr_enable=0 +tdma_intr_enable=1 +miim_intr_enable=1 +stat_if_parity_enable=1 + +port_flex_enable=1 +port_flex_enable_66=0 +port_flex_enable_130=0 +phy_an_c73=3 +phy_an_c73_66=0 +phy_an_c73_130=0 + +module_64ports=0 +table_dma_enable=1 +tdma_timeout_usec=5000000 +mmu_lossless=0 +pdma_descriptor_prefetch_enable=1 +pktdma_poll_mode_channel_bitmap=1 + +l2xmsg_mode=1 +l2xmsg_hostbuf_size=8192 +ipv6_lpm_128b_enable=1 +max_vp_lags=0 + +l3_alpm_enable=2 +l2_mem_entries=32768 +l3_mem_entries=16384 +l3_max_ecmp_mode=1 + +bcm_tunnel_term_compatible_mode=1 +ifp_inports_support_enable=1 + +stable_size=0x5500000 + +oversubscribe_mode=1 +pbmp_oversubscribe=0x6fffffffffffffffdfffffffffffffffe +pbmp_xport_xe=0x6fffffffffffffffdfffffffffffffffe + + +portmap_1.0=1:50:2 +portmap_3.0=3:50:2 +portmap_5.0=5:50:2 +portmap_7.0=7:50:2 +portmap_9.0=9:50:2 +portmap_11.0=11:50:2 +portmap_13.0=13:50:2 +portmap_15.0=15:50:2 +portmap_17.0=17:50:2 +portmap_19.0=19:50:2 +portmap_21.0=21:50:2 +portmap_23.0=23:50:2 +portmap_25.0=25:100 +portmap_29.0=29:100 +portmap_33.0=33:100 +portmap_37.0=37:100 +portmap_41.0=41:50:2 +portmap_43.0=43:50:2 +portmap_45.0=45:50:2 +portmap_47.0=47:50:2 +portmap_49.0=49:50:2 +portmap_51.0=51:50:2 +portmap_53.0=53:50:2 +portmap_55.0=55:50:2 +portmap_57.0=57:50:2 +portmap_59.0=59:50:2 +portmap_61.0=61:50:2 +portmap_63.0=63:50:2 +portmap_67.0=65:50:2 +portmap_69.0=67:50:2 +portmap_71.0=69:50:2 +portmap_73.0=71:50:2 +portmap_75.0=73:50:2 +portmap_77.0=75:50:2 +portmap_79.0=77:50:2 +portmap_81.0=79:50:2 +portmap_83.0=81:50:2 +portmap_85.0=83:50:2 +portmap_87.0=85:50:2 +portmap_89.0=87:50:2 +portmap_91.0=89:50:2 +portmap_93.0=91:50:2 +portmap_95.0=93:50:2 +portmap_97.0=95:50:2 +portmap_99.0=97:50:2 +portmap_101.0=99:50:2 +portmap_103.0=101:50:2 +portmap_105.0=103:50:2 +portmap_107.0=105:100 +portmap_111.0=109:100 +portmap_115.0=113:100 +portmap_119.0=117:100 +portmap_123.0=121:50:2 +portmap_125.0=123:50:2 +portmap_127.0=125:50:2 +portmap_129.0=127:50:2 +portmap_130.0=128:10:m +portmap_66.0=129:10:m + + +phy_chain_tx_lane_map_physical{1.0}=0x0132 +phy_chain_rx_lane_map_physical{1.0}=0x3210 +phy_chain_tx_lane_map_physical{5.0}=0x2301 +phy_chain_rx_lane_map_physical{5.0}=0x2031 +phy_chain_tx_lane_map_physical{9.0}=0x0132 +phy_chain_rx_lane_map_physical{9.0}=0x3210 +phy_chain_tx_lane_map_physical{13.0}=0x3201 +phy_chain_rx_lane_map_physical{13.0}=0x2031 +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{17.0}=0x3210 +phy_chain_tx_lane_map_physical{21.0}=0x2301 +phy_chain_rx_lane_map_physical{21.0}=0x2031 +phy_chain_tx_lane_map_physical{25.0}=0x0123 +phy_chain_rx_lane_map_physical{25.0}=0x3210 +phy_chain_tx_lane_map_physical{29.0}=0x3201 +phy_chain_rx_lane_map_physical{29.0}=0x2031 +phy_chain_tx_lane_map_physical{33.0}=0x0213 +phy_chain_rx_lane_map_physical{33.0}=0x1302 +phy_chain_tx_lane_map_physical{37.0}=0x1302 +phy_chain_rx_lane_map_physical{37.0}=0x2031 +phy_chain_tx_lane_map_physical{41.0}=0x0231 +phy_chain_rx_lane_map_physical{41.0}=0x3120 +phy_chain_tx_lane_map_physical{45.0}=0x1302 +phy_chain_rx_lane_map_physical{45.0}=0x2031 +phy_chain_tx_lane_map_physical{49.0}=0x2103 +phy_chain_rx_lane_map_physical{49.0}=0x3120 +phy_chain_tx_lane_map_physical{53.0}=0x2301 +phy_chain_rx_lane_map_physical{53.0}=0x2031 +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_rx_lane_map_physical{57.0}=0x2301 +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{61.0}=0x1032 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{65.0}=0x1023 +phy_chain_tx_lane_map_physical{69.0}=0x0123 +phy_chain_rx_lane_map_physical{69.0}=0x1302 +phy_chain_tx_lane_map_physical{73.0}=0x2301 +phy_chain_rx_lane_map_physical{73.0}=0x1032 +phy_chain_tx_lane_map_physical{77.0}=0x2013 +phy_chain_rx_lane_map_physical{77.0}=0x3120 +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_rx_lane_map_physical{81.0}=0x2031 +phy_chain_tx_lane_map_physical{85.0}=0x0123 +phy_chain_rx_lane_map_physical{85.0}=0x2130 +phy_chain_tx_lane_map_physical{89.0}=0x2301 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_tx_lane_map_physical{93.0}=0x0312 +phy_chain_rx_lane_map_physical{93.0}=0x2310 +phy_chain_tx_lane_map_physical{97.0}=0x2301 +phy_chain_rx_lane_map_physical{97.0}=0x1032 +phy_chain_tx_lane_map_physical{101.0}=0x0123 +phy_chain_rx_lane_map_physical{101.0}=0x3210 +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_rx_lane_map_physical{105.0}=0x1032 +phy_chain_tx_lane_map_physical{109.0}=0x0123 +phy_chain_rx_lane_map_physical{109.0}=0x3210 +phy_chain_tx_lane_map_physical{113.0}=0x2301 +phy_chain_rx_lane_map_physical{113.0}=0x2031 +phy_chain_tx_lane_map_physical{117.0}=0x0123 +phy_chain_rx_lane_map_physical{117.0}=0x3210 +phy_chain_tx_lane_map_physical{121.0}=0x2301 +phy_chain_rx_lane_map_physical{121.0}=0x1032 +phy_chain_tx_lane_map_physical{125.0}=0x0123 +phy_chain_rx_lane_map_physical{125.0}=0x3210 +phy_chain_tx_lane_map_physical{129.0}=0x3210 +phy_chain_rx_lane_map_physical{129.0}=0x0231 +phy_chain_tx_lane_map_physical{128.0}=0x3210 +phy_chain_rx_lane_map_physical{128.0}=0x0231 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x0 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x1 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x1 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_tx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x0 +phy_chain_tx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_tx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_rx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x0 +phy_chain_tx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x0 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x0 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x1 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x0 +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_rx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 +phy_chain_rx_polarity_flip_physical{112.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_rx_polarity_flip_physical{120.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 +phy_chain_tx_polarity_flip_physical{129.0}=0x1 +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_tx_polarity_flip_physical{130.0}=0x0 +phy_chain_rx_polarity_flip_physical{130.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x1 +phy_chain_rx_polarity_flip_physical{131.0}=0x1 +phy_chain_tx_polarity_flip_physical{132.0}=0x0 +phy_chain_rx_polarity_flip_physical{132.0}=0x1 +dport_map_enable=1 +dport_map_port_1=1 +dport_map_port_2=2 +dport_map_port_3=3 +dport_map_port_4=4 +dport_map_port_5=5 +dport_map_port_6=6 +dport_map_port_7=7 +dport_map_port_8=8 +dport_map_port_9=9 +dport_map_port_10=10 +dport_map_port_11=11 +dport_map_port_12=12 +dport_map_port_13=13 +dport_map_port_14=14 +dport_map_port_15=15 +dport_map_port_16=16 +dport_map_port_17=17 +dport_map_port_18=18 +dport_map_port_19=19 +dport_map_port_20=20 +dport_map_port_21=21 +dport_map_port_22=22 +dport_map_port_23=23 +dport_map_port_24=24 +dport_map_port_25=25 +dport_map_port_26=26 +dport_map_port_27=27 +dport_map_port_28=28 +dport_map_port_29=29 +dport_map_port_30=30 +dport_map_port_31=31 +dport_map_port_32=32 +dport_map_port_33=33 +dport_map_port_34=34 +dport_map_port_35=35 +dport_map_port_36=36 +dport_map_port_37=37 +dport_map_port_38=38 +dport_map_port_39=39 +dport_map_port_40=40 +dport_map_port_41=41 +dport_map_port_42=42 +dport_map_port_43=43 +dport_map_port_44=44 +dport_map_port_45=45 +dport_map_port_46=46 +dport_map_port_47=47 +dport_map_port_48=48 +dport_map_port_49=49 +dport_map_port_50=50 +dport_map_port_51=51 +dport_map_port_52=52 +dport_map_port_53=53 +dport_map_port_54=54 +dport_map_port_55=55 +dport_map_port_56=56 +dport_map_port_57=57 +dport_map_port_58=58 +dport_map_port_59=59 +dport_map_port_60=60 +dport_map_port_61=61 +dport_map_port_62=62 +dport_map_port_63=63 +dport_map_port_64=64 +dport_map_port_67=65 +dport_map_port_68=66 +dport_map_port_69=67 +dport_map_port_70=68 +dport_map_port_71=69 +dport_map_port_72=70 +dport_map_port_73=71 +dport_map_port_74=72 +dport_map_port_75=73 +dport_map_port_76=74 +dport_map_port_77=75 +dport_map_port_78=76 +dport_map_port_79=77 +dport_map_port_80=78 +dport_map_port_81=79 +dport_map_port_82=80 +dport_map_port_83=81 +dport_map_port_84=82 +dport_map_port_85=83 +dport_map_port_86=84 +dport_map_port_87=85 +dport_map_port_88=86 +dport_map_port_89=87 +dport_map_port_90=88 +dport_map_port_91=89 +dport_map_port_92=90 +dport_map_port_93=91 +dport_map_port_94=92 +dport_map_port_95=93 +dport_map_port_96=94 +dport_map_port_97=95 +dport_map_port_98=96 +dport_map_port_99=97 +dport_map_port_100=98 +dport_map_port_101=99 +dport_map_port_102=100 +dport_map_port_103=101 +dport_map_port_104=102 +dport_map_port_105=103 +dport_map_port_106=104 +dport_map_port_107=105 +dport_map_port_108=106 +dport_map_port_109=107 +dport_map_port_110=108 +dport_map_port_111=109 +dport_map_port_112=110 +dport_map_port_113=111 +dport_map_port_114=112 +dport_map_port_115=113 +dport_map_port_116=114 +dport_map_port_117=115 +dport_map_port_118=116 +dport_map_port_119=117 +dport_map_port_120=118 +dport_map_port_121=119 +dport_map_port_122=120 +dport_map_port_123=121 +dport_map_port_124=122 +dport_map_port_125=123 +dport_map_port_126=124 +dport_map_port_127=125 +dport_map_port_129=126 +dport_map_port_66=127 +dport_map_port_130=128 + +mmu_init_config="TD3-DEFAULT-LOSSLESS-P3P4" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc + From 5307f9448e2090a3b8a61c64ea2faf0e2f4a262a Mon Sep 17 00:00:00 2001 From: Myron Sosyak <49795530+msosyak@users.noreply.github.com> Date: Tue, 5 May 2020 12:05:17 +0300 Subject: [PATCH 58/69] [devices] skip_fancontrol for wedge 100 barefoot platforms (#4528) --- .../x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json | 3 ++- .../x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json index d00d924bcd1..ae8601e866b 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json @@ -1,7 +1,8 @@ { + "skip_fancontrol": true, "skip_thermalctld": true, "skip_ledd": true, "skip_xcvrd": false, "skip_psud": false, - "skip_syseepromd": false + "skip_syseepromd": false } diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json index d00d924bcd1..ae8601e866b 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json @@ -1,7 +1,8 @@ { + "skip_fancontrol": true, "skip_thermalctld": true, "skip_ledd": true, "skip_xcvrd": false, "skip_psud": false, - "skip_syseepromd": false + "skip_syseepromd": false } From f0c13d36033b49e2af634a0226c86cd9b2d31bfe Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Tue, 5 May 2020 13:50:08 -0700 Subject: [PATCH 59/69] Fixed issue in handling net.ipv6.conf.eth0.accept_ra sysctl --- files/image_config/hostcfgd/hostcfgd | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index b181dc18076..3b66dd794a0 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -464,11 +464,10 @@ class MgmtIntfCfg: if it[0] == ifname: data = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, it) + self.mgmt_intf_ip_prefix_set(ifname, it[1], oper) if ('gwaddr' in data): self.mgmt_intf_gwaddr_set(ifname, it[1], data['gwaddr'], oper) - self.mgmt_intf_ip_prefix_set(ifname, it[1], oper) - if ('forced_mgmt_routes' in data): forced_routes = data['forced_mgmt_routes'] self.mgmt_intf_forced_mgmt_routes_set(ifname, it[1], forced_routes, oper) @@ -505,11 +504,15 @@ class MgmtIntfCfg: run_command(cmd) if enable == True: + cmd = 'sysctl net.ipv6.conf.eth0.accept_ra=1' + run_command(cmd) cmd = "/sbin/dhclient {} -pf /run/dhclient{}.{}.pid -lf /var/lib/dhcp/dhclient{}.{}.leases {} -nw {} ".format(version, file_ext, ifname, file_ext, ifname, ifname, cmd_opt) + run_command(cmd) else: cmd = "/sbin/dhclient {} -r {} && [ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(version, ifname, file_ext, ifname, file_ext, ifname, file_ext, ifname) - - run_command(cmd) + run_command(cmd) + cmd = 'sysctl net.ipv6.conf.eth0.accept_ra=0' + run_command(cmd) def mgmt_intf_ip_prefix_set (self, ifname, ip_prefix, op): vrf_table = self.mgmt_vrf_cfg.mgmt_vrf_table_get() From 53c00bacc612f3b2241f91833a43de8697520a2f Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Mon, 9 Mar 2020 13:52:12 -0700 Subject: [PATCH 60/69] hostcfgd service enhancements: 1.Added support for Dynamic handling of Management port config(MTU, Speed, auto negotiation, admin status and Description config attributes), 2. Added support for Dynamic handling of Management interface config (IPv4/IPv6 DHCP client, IPv4/IPv6 default gateway, IPv4/IPv6 addresses config and respective gateways config attributes) and Management VRF handling. --- build_debian.sh | 2 + files/dhcp/dhcp_mgmt_conf.py | 42 ++ files/dhcp/dhcp_mgmt_interface | 53 +++ files/image_config/hostcfgd/hostcfgd | 548 +++++++++++++++++++++++++++ 4 files changed, 645 insertions(+) create mode 100644 files/dhcp/dhcp_mgmt_conf.py create mode 100644 files/dhcp/dhcp_mgmt_interface diff --git a/build_debian.sh b/build_debian.sh index a805d34b939..4dc206c9d0f 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -457,6 +457,8 @@ sudo cp files/dhcp/sethostname6 $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/graphserviceurl $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/snmpcommunity $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/vrf $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ +sudo cp files/dhcp/dhcp_mgmt_interface $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ +sudo cp files/dhcp/dhcp_mgmt_conf.py $FILESYSTEM_ROOT/usr/bin/ if [ -f files/image_config/ntp/ntp ]; then sudo cp ./files/image_config/ntp/ntp $FILESYSTEM_ROOT/etc/init.d/ fi diff --git a/files/dhcp/dhcp_mgmt_conf.py b/files/dhcp/dhcp_mgmt_conf.py new file mode 100644 index 00000000000..25cc5a80f88 --- /dev/null +++ b/files/dhcp/dhcp_mgmt_conf.py @@ -0,0 +1,42 @@ +#!/usr/bin/python -u +# -*- coding: utf-8 -*- + +import os +import re +import sys +import subprocess +import syslog +import ipaddress +import netaddr +from swsssdk import ConfigDBConnector + +APP_MGMT_INTF_TABLE = "MGMT_INTF_TABLE" + +def update_dhcp_mgmt_ip_info(): + app_db = ConfigDBConnector() + app_db.db_connect('APPL_DB', wait_for_init=False, retry_on=True) + appdb_entry = {} + appdb_entry["NULL"] = "NULL" + + op = sys.argv[2] + plen = ipaddress.ip_network((0, sys.argv[4])).prefixlen + key = sys.argv[1] + ":" + sys.argv[3] + "/" + str(plen) + syslog.syslog(syslog.LOG_INFO, "update_dhcp_mgmt_ip_info : op - {}, key - {}".format(op, key)) + if op == "add": + app_db.set_entry(APP_MGMT_INTF_TABLE, key, appdb_entry) + elif op == "del": + app_db.delete_entry(APP_MGMT_INTF_TABLE, key) + return + +if __name__ == "__main__": + if len(sys.argv) < 5: + syslog.syslog(syslog.LOG_INFO, "number of arguments not correct") + syslog.syslog(syslog.LOG_INFO, "usage:") + syslog.syslog(syslog.LOG_INFO, "dhcp_mgmt_conf.py ") + else: + syslog.syslog(syslog.LOG_INFO, "Args : {}".format(sys.argv)) + update_dhcp_mgmt_ip_info() + + + + diff --git a/files/dhcp/dhcp_mgmt_interface b/files/dhcp/dhcp_mgmt_interface new file mode 100644 index 00000000000..fc20c88f4ec --- /dev/null +++ b/files/dhcp/dhcp_mgmt_interface @@ -0,0 +1,53 @@ +#!/bin/sh +# +# DHCLIENT exit hook for ip address update in app db +# + + +set -x + +PYTHON_PATH=/usr/bin/python +SCRIPT=/usr/bin/dhcp_mgmt_conf.py + + +dhcp_mgmt_conf_handle() { + IF_NAME=$interface + echo "dhcp_mgmt_conf_handle, interface : $IF_NAME" + + if [ "$IF_NAME" = "eth0" ]; then + echo "DHCP exit hook is called for $IF_NAME, reason : $reason" + + case $reason in + BOUND|REBOOT|BOUND6) + if [ -n "$new_ip_address" ] && [ -n "$new_subnet_mask" ]; then + + $PYTHON_PATH $SCRIPT $IF_NAME add $new_ip_address $new_subnet_mask + fi + ;; + RENEW|REBIND|RENEW6|REBIND6) + if [ -n "$old_ip_address" ] && [ -n "$old_subnet_mask" ]; then + $PYTHON_PATH $SCRIPT $IF_NAME del $old_ip_address $old_subnet_mask + fi + + if [ -n "$new_ip_address" ] && [ -n "$new_subnet_mask" ]; then + $PYTHON_PATH $SCRIPT $IF_NAME add $new_ip_address $new_subnet_mask + fi + + ;; + EXPIRE|FAIL|RELEASE|STOP) + if [ -n "$new_ip_address" ] && [ -n "$new_subnet_mask" ]; then + $PYTHON_PATH $SCRIPT $IF_NAME del $new_ip_address $new_subnet_mask + fi + + if [ -n "$old_ip_address" ] && [ -n "$old_subnet_mask" ]; then + $PYTHON_PATH $SCRIPT $IF_NAME del $old_ip_address $old_subnet_mask + fi + ;; + TIMEOUT) + ;; + esac + fi +} + +echo "dhcp_mgmt_conf" +dhcp_mgmt_conf_handle diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index edbbacca86c..91a79fd000c 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -8,6 +8,7 @@ import syslog import copy import jinja2 import ipaddr as ipaddress +import netaddr from swsssdk import ConfigDBConnector # FILE @@ -219,6 +220,539 @@ class AaaCfg(object): with open(NSS_TACPLUS_CONF, 'w') as f: f.write(nss_tacplus_conf) +#Management interface and Management VRF config handling + +MGMT_INTF_ADMIN_STATUS_DEFAULT = "up" +CFG_MGMT_PORT_TABLE = "MGMT_PORT" +CFG_MGMT_INTF_TABLE = "MGMT_INTERFACE" +APP_MGMT_PORT_TABLE = "MGMT_PORT_TABLE" +APP_MGMT_INTF_TABLE = "MGMT_INTF_TABLE" +CFG_MGMT_VRF = "MGMT_VRF_CONFIG" +CFG_MGMT_VRF_KEY = "vrf_global" +MGMT_VRF_TABLE_ID = 5000 + +class MgmtVrfCfg: + def __init__(self, config_db): + syslog.syslog(syslog.LOG_INFO, 'Initializing MGMT VRF handler') + self.config_db = config_db + self.mgmt_vrf_table_created = False + + def create_mgmt_vrf_table(self): + if self.mgmt_vrf_table_created == False: + syslog.syslog(syslog.LOG_INFO, "Create MGMT VRF table:") + cmd = 'ip link add name mgmt type vrf table {}'.format(MGMT_VRF_TABLE_ID) + syslog.syslog(syslog.LOG_INFO, "Create MGMT VRF table, cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + self.mgmt_vrf_table_created = True + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + + def delete_mgmt_vrf_table(self): + if self.mgmt_vrf_table_created == True: + syslog.syslog(syslog.LOG_INFO, "Delete MGMT VRF table:") + cmd = 'ip link delete mgmt' + syslog.syslog(syslog.LOG_INFO, "Delete MGMT VRF table, cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + self.mgmt_vrf_table_created = False + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + + def configure_mgmt_vrf(self): + syslog.syslog(syslog.LOG_INFO, "Configure MGMT VRF:") + + self.create_mgmt_vrf_table() + + cmd = 'ip link set dev mgmt up' + syslog.syslog(syslog.LOG_INFO, "Set MGMT VRF up, cmd - {}".format(cmd)) + + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + syslog.syslog(syslog.LOG_INFO, "Add lo intf:") + cmd = 'ip link add lo-m type dummy' + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + cmd = 'ip addr add 127.0.0.1/8 dev lo-m' + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + cmd = 'ip link set lo-m up' + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + cmd = 'ip link set dev lo-m master mgmt' + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + self.bind_mgmt_intf() + + def bind_mgmt_intf(self): + syslog.syslog(syslog.LOG_INFO, "Handle MGMT intf:") + keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) + syslog.syslog(syslog.LOG_INFO, "MGMT interfaces keys: {}".format(str(keys))) + + mgmt_intf_bound = False + for it in keys: + if type(it) is unicode: + mgmt_intf_name = it + + cmd = 'ip link set dev {} master mgmt'.format(mgmt_intf_name) + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + cmd = 'sysctl -w net.ipv4.tcp_l3mdev_accept=1' + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + mgmt_intf_bound = True + break + if not mgmt_intf_bound: + syslog.syslog(syslog.LOG_ERR, "MGMT VRF: MGMT interface not bound") + else: + for it in keys: + if type(it) is unicode: + key = it + else: + key = it[0] + "|" + it[1] + + entry = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, key) + if 'gwaddr' in entry: + mgmt_intf_gwaddr = entry['gwaddr'] + cmd = 'ip route add table {} 0.0.0.0/0 via {}'.format(MGMT_VRF_TABLE_ID, mgmt_intf_gwaddr) + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return + + def unconfigure_mgmt_vrf(self): + syslog.syslog(syslog.LOG_INFO, "Unconfigure MGMT VRF:") + + cmd = 'ip link delete lo-m' + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + + self.delete_mgmt_vrf_table() + return + + def handle_mgmt_intf_gwaddr_cfg(self, op, ifname, gwaddr): + syslog.syslog(syslog.LOG_INFO, "Received MGMT Intf gwaddr config, op: {}, ifname: {}, gwaddr: {}".format(op, ifname, gwaddr)) + keys = self.config_db.get_keys(CFG_MGMT_VRF) + if keys: + syslog.syslog(syslog.LOG_INFO, "MGMT VRF created") + cmd = 'ip route del table {} 0.0.0.0/0'.format(MGMT_VRF_TABLE_ID) + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + pass + + if op == "ADD": + cmd = 'ip route add table {} 0.0.0.0/0 via {}'.format(MGMT_VRF_TABLE_ID, gwaddr) + syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + pass + + return True + + def handle_mgmt_intf_creation(self, mgmt_intf_key): + syslog.syslog(syslog.LOG_INFO, "Received MGMT Intf creation, key: {}".format(mgmt_intf_key)) + keys = self.config_db.get_keys(CFG_MGMT_VRF) + if keys: + syslog.syslog(syslog.LOG_INFO, "MGMT VRF created") + self.bind_mgmt_intf() + + def handle_mgmt_vrf_cfg(self, key, data): + syslog.syslog(syslog.LOG_INFO, "Received MGMT VRF config, key: {}, data: {}".format(key, data)) + try: + if data: + if data['mgmtVrfEnabled'] == 'true': + self.configure_mgmt_vrf() + else: + self.unconfigure_mgmt_vrf() + else: + self.unconfigure_mgmt_vrf() + except: + syslog.syslog(syslog.LOG_ERR, "{} MGMT VRF Configuration failed.".format(key)) + + + +class MgmtIntfCfg: + def __init__(self, cfg_db, mgmt_vrf_cfg): + self.app_db = ConfigDBConnector() + self.app_db.db_connect('APPL_DB', wait_for_init=False, retry_on=True) + self.config_db = cfg_db + self.mgmt_vrf_cfg = mgmt_vrf_cfg + syslog.syslog(syslog.LOG_INFO, 'AppDB connect success') + + self.mgmt_intf_handle_default_cfg("eth0") + + def mgmt_intf_handle_default_cfg (self, ifname): + mgmt_intf = self.config_db.get_entry(CFG_MGMT_PORT_TABLE, ifname) + if mgmt_intf == {}: + mgmt_intf['mtu'] = "1500" + mgmt_intf['speed'] = "1000" + mgmt_intf['admin_status'] = MGMT_INTF_ADMIN_STATUS_DEFAULT + mgmt_intf['autoneg'] = "true" + mgmt_intf['description'] = "Management0" + syslog.syslog(syslog.LOG_INFO, "Default config populated for {}".format(ifname)) + self.config_db.set_entry(CFG_MGMT_PORT_TABLE, ifname, mgmt_intf) + + self.handle_mgmt_port_cfg(ifname, mgmt_intf) + + mgmt_intf = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, ifname) + if mgmt_intf == {}: + mgmt_intf['ipv4_dhcp_client'] = "true" + mgmt_intf['ipv6_dhcp_client'] = "true" + self.config_db.set_entry(CFG_MGMT_INTF_TABLE, ifname, mgmt_intf) + self.app_db.set_entry(APP_MGMT_INTF_TABLE, ifname, mgmt_intf) + + def mgmt_intf_mtu_set (self, ifname, mtu, appIntf): + cmd = 'ifconfig {} mtu {}'.format(ifname, mtu) + syslog.syslog(syslog.LOG_INFO, "Configure MTU, cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + appIntf['mtu'] = mtu + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + + def mgmt_intf_admin_status_set (self, ifname, admin_status, appIntf): + cmd = 'ifconfig {} {}'.format(ifname, admin_status) + syslog.syslog(syslog.LOG_INFO, "Configure admin_status, cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + appIntf['admin_status'] = admin_status + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + + def mgmt_intf_description_set (self, ifname, description, appIntf): + syslog.syslog(syslog.LOG_INFO, "Configure description, cmd - {}".format(description)) + appIntf['description'] = description + + def mgmt_intf_speed_set (self, ifname, speed, autoneg, appIntf): + duplex = "full" + cmd = 'ethtool -s {} speed {} duplex {} autoneg {}; ifup {}'.format(ifname, speed, duplex, autoneg, ifname) + syslog.syslog(syslog.LOG_INFO, "Configure SPEED, cmd - {}".format(cmd)) + + try: + subprocess.check_call(cmd, shell=True) + appIntf['speed'] = speed + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + + def mgmt_intf_autoneg_set (self, ifname, autoneg, appIntf): + an = "on" + if autoneg == "true": + an = "on" + elif autoneg == "false": + an = "off" + + cmd = "ethtool -s {} autoneg {}".format(ifname, an) + syslog.syslog(syslog.LOG_INFO, "Configure autoneg, cmd - {}".format(cmd)) + + try: + subprocess.check_call(cmd, shell=True) + appIntf['autoneg'] = autoneg + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + + def mgmt_intf_gwaddr_set(self, ifname, ip_prefix, gwaddr, op): + if not self.mgmt_vrf_cfg.handle_mgmt_intf_gwaddr_cfg(op, ifname, gwaddr): + try: + ip_conf = netaddr.IPNetwork(ip_prefix) + if op == "DELETE": + cmd = "ip route del {}/{} via {} dev {}".format(ip_conf.network, ip_conf.prefixlen, gwaddr, ifname) + else: + cmd = "ip route add {}/{} via {} dev {}".format(ip_conf.network, ip_conf.prefixlen, gwaddr, ifname) + + syslog.syslog(syslog.LOG_INFO, "Configure gwaddr , cmd : {}".format(cmd)) + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + pass + + def mgmt_intf_default_gwaddr_set (self, ifname, default_gw, op): + try: + if op == "DELETE": + cmd = "ip route del default via {} dev {}".format(default_gw, ifname) + else: + cmd = "ip route add default via {} dev {}".format(default_gw, ifname) + + syslog.syslog(syslog.LOG_INFO, "Configure Default Gateway, cmd : {}".format(cmd)) + + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + pass + + def mgmt_intf_dhclient_set (self, ifname, attr, enable): + version = "" + file_ext = "" + cmd_opt = "" + + if attr == "ipv6_dhcp_client": + version = "-6" + file_ext = "6" + cmd_opt = "-D LL" + + if enable == True: + try: + path = "/var/run/dhclient{}.{}.pid".format(file_ext, ifname) + if os.path.exists(path): + cmd = "[ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(file_ext, ifname, file_ext, ifname, file_ext, ifname) + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + pass + + try: + if enable == True: + cmd = "/sbin/dhclient {} -pf /run/dhclient{}.{}.pid -lf /var/lib/dhcp/dhclient{}.{}.leases {} -nw {} ".format(version, file_ext, ifname, file_ext, ifname, ifname, cmd_opt) + else: + cmd = "/sbin/dhclient {} -r {} && [ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(version, ifname, file_ext, ifname, file_ext, ifname, file_ext, ifname) + + syslog.syslog(syslog.LOG_INFO, "Configure dhclient , cmd : {}".format(cmd)) + + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + pass + + def mgmt_intf_ip_prefix_set (self, ifname, ip_prefix, op): + try: + if op == "DELETE": + reset_prefix = "0.0.0.0" + mgmt_conf = netaddr.IPNetwork(reset_prefix) + cmd = "ip addr del {} dev {}".format(ip_prefix, ifname) + else: + mgmt_conf = netaddr.IPNetwork(ip_prefix) + cmd = "ip addr add {} dev {}".format(ip_prefix, ifname) + + syslog.syslog(syslog.LOG_INFO, "Configure ip_prefix, op : {}, ip_prefix: {}, cmd : {}, mgmt_conf: {}".format(op, ip_prefix, cmd, mgmt_conf)) + subprocess.check_call(cmd, shell=True) + cmd = "ip rule add from {} table default".format(str(mgmt_conf.ip)) + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + pass + + def handle_mgmt_port_cfg(self, key, data): + mgmt_intf = self.app_db.get_entry(APP_MGMT_PORT_TABLE, key) + is_all = False + if mgmt_intf == {}: + is_all = True + + try: + if (('mtu' in data) and ((is_all == True) or (mgmt_intf == {}) or ('mtu' not in mgmt_intf) or (data['mtu'] != mgmt_intf['mtu']))): + self.mgmt_intf_mtu_set(key, data['mtu'], mgmt_intf) + + if (('description' in data) and ((is_all == True) or (mgmt_intf == {}) or ('description' not in mgmt_intf) or (data['description'] != mgmt_intf['description']))): + self.mgmt_intf_description_set(key, data['description'], mgmt_intf) + + if (('admin_status' in data) and ((is_all == True) or (mgmt_intf == {}) or ('admin_status' not in mgmt_intf) or (data['admin_status'] != mgmt_intf['admin_status']))): + self.mgmt_intf_admin_status_set(key, data['admin_status'], mgmt_intf) + + if (('autoneg' in data) and ((is_all == True) or (mgmt_intf == {}) or ('autoneg' not in mgmt_intf) or (data['autoneg'] != mgmt_intf['autoneg']))): + self.mgmt_intf_autoneg_set(key, data['autoneg'], mgmt_intf) + + if (('speed' in data) and ((is_all == True) or (mgmt_intf == {}) or ('speed' not in mgmt_intf) or (data['speed'] != mgmt_intf['speed']))): + autoneg = "on" + if 'autoneg' in data: + if data['autoneg'] == "false": + autoneg = "off" + self.mgmt_intf_speed_set(key, data['speed'], autoneg, mgmt_intf) + except: + syslog.syslog(syslog.LOG_ERR, "{} MGMT Port Config set failed.".format(key)) + + self.app_db.set_entry(APP_MGMT_PORT_TABLE, key, mgmt_intf) + + + def handle_mgmt_intf_cfg(self, key, data): + cur_appdb_key = key.replace('|', ':') + intf_keys = key.split("|") + cfgdb_entry = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, key) + appdb_entry = self.app_db.get_entry(APP_MGMT_INTF_TABLE, cur_appdb_key) + op = "DELETE" + keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) + + for it in keys: + if len(it) != 2: + it = (it, ) + it_key = it[0] + else: + it_key = it[0] + "|" + it[1] + + if it_key == key: + op = "CREATE" + break + + if op == "CREATE": + if cfgdb_entry != {} and appdb_entry != {}: + op = "UPDATE" + + + if (len(intf_keys) < 2): + if op == "DELETE": + cfgdb_entry['ipv4_dhcp_client'] = "true" + cfgdb_entry['ipv6_dhcp_client'] = "true" + + if (('ipv4_dhcp_client' not in appdb_entry) or (appdb_entry['ipv4_dhcp_client'] != cfgdb_entry['ipv4_dhcp_client'])): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", True) + appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] + + if (('ipv6_dhcp_client' not in appdb_entry) or (appdb_entry['ipv6_dhcp_client'] != cfgdb_entry['ipv6_dhcp_client'])): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", True) + appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] + + if ('ipv4_default_gwaddr' in appdb_entry): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DELETE") + del appdb_entry['ipv4_default_gwaddr'] + + if ('ipv6_default_gwaddr' in appdb_entry): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DELETE") + del appdb_entry['ipv6_default_gwaddr'] + + self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) + self.config_db.set_entry(CFG_MGMT_INTF_TABLE, key, cfgdb_entry) + + elif op == "CREATE": + syslog.syslog(syslog.LOG_ERR, "handle_mgmt_intf_cfg: operation is CREATE, return after vrf create handling") + self.mgmt_vrf_cfg.handle_mgmt_intf_creation(key) + + if ('ipv4_dhcp_client' in cfgdb_entry): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", cfgdb_entry['ipv4_dhcp_client'] == "true") + appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] + + if ('ipv6_dhcp_client' in cfgdb_entry): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", cfgdb_entry['ipv6_dhcp_client'] == "true") + appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] + + if ('ipv4_default_gwaddr' in cfgdb_entry): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") + appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] + + if ('ipv6_default_gwaddr' in cfgdb_entry): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") + appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] + + self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) + + elif op == "UPDATE": + if (('ipv4_dhcp_client' in cfgdb_entry) and ('ipv4_dhcp_client' not in appdb_entry)): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", cfgdb_entry['ipv4_dhcp_client'] == "true") + appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] + elif (('ipv4_dhcp_client' in cfgdb_entry) and (cfgdb_entry['ipv4_dhcp_client'] != appdb_entry['ipv4_dhcp_client'])): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", cfgdb_entry['ipv4_dhcp_client'] == "true") + appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] + + if (('ipv6_dhcp_client' in cfgdb_entry) and ('ipv6_dhcp_client' not in appdb_entry)): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", cfgdb_entry['ipv6_dhcp_client'] == "true") + appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] + elif (('ipv6_dhcp_client' in cfgdb_entry) and (cfgdb_entry['ipv6_dhcp_client'] != appdb_entry['ipv6_dhcp_client'])): + self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", cfgdb_entry['ipv6_dhcp_client'] == "true") + appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] + + if (('ipv4_default_gwaddr' in cfgdb_entry) and ('ipv4_default_gwaddr' not in appdb_entry)): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") + appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] + elif (('ipv4_default_gwaddr' in cfgdb_entry) and (cfgdb_entry['ipv4_default_gwaddr'] != appdb_entry['ipv4_default_gwaddr'])): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") + appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] + elif (('ipv4_default_gwaddr' not in cfgdb_entry) and ('ipv4_default_gwaddr' in appdb_entry)): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DELETE") + del appdb_entry['ipv4_default_gwaddr'] + + if (('ipv6_default_gwaddr' in cfgdb_entry) and ('ipv6_default_gwaddr' not in appdb_entry)): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") + appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] + elif (('ipv6_default_gwaddr' in cfgdb_entry) and (cfgdb_entry['ipv6_default_gwaddr'] != appdb_entry['ipv6_default_gwaddr'])): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") + appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] + elif (('ipv6_default_gwaddr' not in cfgdb_entry) and ('ipv6_default_gwaddr' in appdb_entry)): + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DELETE") + del appdb_entry['ipv6_default_gwaddr'] + + self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) + else: + input_ip = ipaddress.IPNetwork(intf_keys[1]) + if op == "CREATE" or op == "UPDATE" : + self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "ADD") + if (('gwaddr' in data) and ((appdb_entry == {}) or ('gwaddr' not in appdb_entry))): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") + appdb_entry['gwaddr'] = data['gwaddr'] + elif (('gwaddr' in data) and ('gwaddr' not in cfgdb_entry) and ('gwaddr' in appdb_entry)): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'],"DELETE") + del appdb_entry['gwaddr'] + elif (('gwaddr' in data) and (data['gwaddr'] != appdb_entry['gwaddr'])): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'],"DELETE") + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") + appdb_entry['gwaddr'] = data['gwaddr'] + + if appdb_entry == {}: + appdb_entry["NULL"] = "NULL" + + self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) + + else: + self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "DELETE") + if ('gwaddr' in data): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "DELETE") + self.app_db.delete_entry(APP_MGMT_INTF_TABLE, cur_appdb_key) + + class HostConfigDaemon: def __init__(self): @@ -230,6 +764,8 @@ class HostConfigDaemon: tacacs_server = self.config_db.get_table('TACPLUS_SERVER') self.aaacfg = AaaCfg() self.aaacfg.load(aaa, tacacs_global, tacacs_server) + self.mgmtvrfcfg = MgmtVrfCfg(self.config_db) + self.mgmtcfg = MgmtIntfCfg(self.config_db, self.mgmtvrfcfg) lpbk_table = self.config_db.get_table('LOOPBACK_INTERFACE') self.iptables = Iptables() self.iptables.load(lpbk_table) @@ -262,6 +798,15 @@ class HostConfigDaemon: self.iptables.iptables_handler(key, data, add) + def mgmt_vrf_handler(self, key, data): + self.mgmtvrfcfg.handle_mgmt_vrf_cfg(key, data) + + def mgmt_port_handler(self, key, data): + self.mgmtcfg.handle_mgmt_port_cfg(key, data) + + def mgmt_intf_handler(self, key, data): + self.mgmtcfg.handle_mgmt_intf_cfg(key, data) + def feature_status_handler(self, key, data): status_data = self.config_db.get_table('FEATURE') for key in status_data.keys(): @@ -307,6 +852,9 @@ class HostConfigDaemon: self.config_db.subscribe('TACPLUS', lambda table, key, data: self.tacacs_global_handler(key, data)) self.config_db.subscribe('LOOPBACK_INTERFACE', lambda table, key, data: self.lpbk_handler(key, data)) self.config_db.subscribe('FEATURE', lambda table, key, data: self.feature_status_handler(key, data)) + self.config_db.subscribe(CFG_MGMT_VRF, lambda table, key, data: self.mgmt_vrf_handler(key, data)) + self.config_db.subscribe(CFG_MGMT_PORT_TABLE, lambda table, key, data: self.mgmt_port_handler(key, data)) + self.config_db.subscribe(CFG_MGMT_INTF_TABLE, lambda table, key, data: self.mgmt_intf_handler(key, data)) self.config_db.listen() From a2d97226fc428bb916d662df2e69e720cefda5b3 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Mon, 30 Mar 2020 13:41:23 -0700 Subject: [PATCH 61/69] Fixed issue in adding and deleting ipv6 config. --- files/image_config/hostcfgd/hostcfgd | 56 ++++++++++++++-------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 91a79fd000c..a3d78227a78 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -512,10 +512,11 @@ class MgmtIntfCfg: if not self.mgmt_vrf_cfg.handle_mgmt_intf_gwaddr_cfg(op, ifname, gwaddr): try: ip_conf = netaddr.IPNetwork(ip_prefix) - if op == "DELETE": - cmd = "ip route del {}/{} via {} dev {}".format(ip_conf.network, ip_conf.prefixlen, gwaddr, ifname) - else: - cmd = "ip route add {}/{} via {} dev {}".format(ip_conf.network, ip_conf.prefixlen, gwaddr, ifname) + ver = "-4" + if ip_conf.version == 6: + ver = "-6" + + cmd = "ip {} route {} {}/{} via {} dev {}".format(ver, op.lower(), ip_conf.network, ip_conf.prefixlen, gwaddr, ifname) syslog.syslog(syslog.LOG_INFO, "Configure gwaddr , cmd : {}".format(cmd)) subprocess.check_call(cmd, shell=True) @@ -525,13 +526,14 @@ class MgmtIntfCfg: def mgmt_intf_default_gwaddr_set (self, ifname, default_gw, op): try: - if op == "DELETE": - cmd = "ip route del default via {} dev {}".format(default_gw, ifname) - else: - cmd = "ip route add default via {} dev {}".format(default_gw, ifname) + ver = "-4" + mgmt_conf = netaddr.IPNetwork(default_gw) + if mgmt_conf.version == 6: + ver = "-6" - syslog.syslog(syslog.LOG_INFO, "Configure Default Gateway, cmd : {}".format(cmd)) + cmd = "ip {} route {} default via {} dev {}".format(ver, op.lower(), default_gw, ifname) + syslog.syslog(syslog.LOG_INFO, "Configure Default Gateway, cmd : {}".format(cmd)) subprocess.check_call(cmd, shell=True) except subprocess.CalledProcessError as err: syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) @@ -571,17 +573,14 @@ class MgmtIntfCfg: def mgmt_intf_ip_prefix_set (self, ifname, ip_prefix, op): try: - if op == "DELETE": - reset_prefix = "0.0.0.0" - mgmt_conf = netaddr.IPNetwork(reset_prefix) - cmd = "ip addr del {} dev {}".format(ip_prefix, ifname) - else: - mgmt_conf = netaddr.IPNetwork(ip_prefix) - cmd = "ip addr add {} dev {}".format(ip_prefix, ifname) - + ver = "-4" + mgmt_conf = netaddr.IPNetwork(ip_prefix) + if mgmt_conf.version == 6: + ver = "-6" + cmd = "ip {} addr {} {} dev {}".format(ver, op.lower(), ip_prefix, ifname) syslog.syslog(syslog.LOG_INFO, "Configure ip_prefix, op : {}, ip_prefix: {}, cmd : {}, mgmt_conf: {}".format(op, ip_prefix, cmd, mgmt_conf)) subprocess.check_call(cmd, shell=True) - cmd = "ip rule add from {} table default".format(str(mgmt_conf.ip)) + cmd = "ip {} rule {} from {} table default pref 1003".format(ver, op.lower(), str(mgmt_conf.ip)) subprocess.check_call(cmd, shell=True) except subprocess.CalledProcessError as err: syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) @@ -656,11 +655,11 @@ class MgmtIntfCfg: appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] if ('ipv4_default_gwaddr' in appdb_entry): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DEL") del appdb_entry['ipv4_default_gwaddr'] if ('ipv6_default_gwaddr' in appdb_entry): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DEL") del appdb_entry['ipv6_default_gwaddr'] self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) @@ -707,37 +706,36 @@ class MgmtIntfCfg: self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] elif (('ipv4_default_gwaddr' in cfgdb_entry) and (cfgdb_entry['ipv4_default_gwaddr'] != appdb_entry['ipv4_default_gwaddr'])): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DEL") self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] elif (('ipv4_default_gwaddr' not in cfgdb_entry) and ('ipv4_default_gwaddr' in appdb_entry)): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DEL") del appdb_entry['ipv4_default_gwaddr'] if (('ipv6_default_gwaddr' in cfgdb_entry) and ('ipv6_default_gwaddr' not in appdb_entry)): self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] elif (('ipv6_default_gwaddr' in cfgdb_entry) and (cfgdb_entry['ipv6_default_gwaddr'] != appdb_entry['ipv6_default_gwaddr'])): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DEL") self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] elif (('ipv6_default_gwaddr' not in cfgdb_entry) and ('ipv6_default_gwaddr' in appdb_entry)): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DELETE") + self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DEL") del appdb_entry['ipv6_default_gwaddr'] self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) else: - input_ip = ipaddress.IPNetwork(intf_keys[1]) if op == "CREATE" or op == "UPDATE" : self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "ADD") if (('gwaddr' in data) and ((appdb_entry == {}) or ('gwaddr' not in appdb_entry))): self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") appdb_entry['gwaddr'] = data['gwaddr'] elif (('gwaddr' in data) and ('gwaddr' not in cfgdb_entry) and ('gwaddr' in appdb_entry)): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'],"DELETE") + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'],"DEL") del appdb_entry['gwaddr'] elif (('gwaddr' in data) and (data['gwaddr'] != appdb_entry['gwaddr'])): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'],"DELETE") + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'],"DEL") self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") appdb_entry['gwaddr'] = data['gwaddr'] @@ -747,9 +745,9 @@ class MgmtIntfCfg: self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) else: - self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "DELETE") + self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "DEL") if ('gwaddr' in data): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "DELETE") + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "DEL") self.app_db.delete_entry(APP_MGMT_INTF_TABLE, cur_appdb_key) From ffb660e3abfea89c6c9e3c99c9fa1801db700e0f Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Tue, 21 Apr 2020 16:13:56 -0700 Subject: [PATCH 62/69] Addressed review comments, Added support for handling forced_mgmt_routes and interfaces.j2 cleaup related to mgmt interface. --- files/image_config/hostcfgd/hostcfgd | 497 ++++++++------------ files/image_config/interfaces/interfaces.j2 | 55 +-- 2 files changed, 202 insertions(+), 350 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index a3d78227a78..0b713dfcc25 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -241,25 +241,15 @@ class MgmtVrfCfg: if self.mgmt_vrf_table_created == False: syslog.syslog(syslog.LOG_INFO, "Create MGMT VRF table:") cmd = 'ip link add name mgmt type vrf table {}'.format(MGMT_VRF_TABLE_ID) - syslog.syslog(syslog.LOG_INFO, "Create MGMT VRF table, cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) + if run_command(cmd) == True: self.mgmt_vrf_table_created = True - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) def delete_mgmt_vrf_table(self): if self.mgmt_vrf_table_created == True: syslog.syslog(syslog.LOG_INFO, "Delete MGMT VRF table:") cmd = 'ip link delete mgmt' - syslog.syslog(syslog.LOG_INFO, "Delete MGMT VRF table, cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) + if run_command(cmd) == True: self.mgmt_vrf_table_created = False - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) def configure_mgmt_vrf(self): syslog.syslog(syslog.LOG_INFO, "Configure MGMT VRF:") @@ -267,50 +257,24 @@ class MgmtVrfCfg: self.create_mgmt_vrf_table() cmd = 'ip link set dev mgmt up' - syslog.syslog(syslog.LOG_INFO, "Set MGMT VRF up, cmd - {}".format(cmd)) - - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return syslog.syslog(syslog.LOG_INFO, "Add lo intf:") cmd = 'ip link add lo-m type dummy' - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return cmd = 'ip addr add 127.0.0.1/8 dev lo-m' - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return cmd = 'ip link set lo-m up' - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return cmd = 'ip link set dev lo-m master mgmt' - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return self.bind_mgmt_intf() @@ -326,21 +290,11 @@ class MgmtVrfCfg: mgmt_intf_name = it cmd = 'ip link set dev {} master mgmt'.format(mgmt_intf_name) - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return cmd = 'sysctl -w net.ipv4.tcp_l3mdev_accept=1' - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return mgmt_intf_bound = True @@ -358,51 +312,29 @@ class MgmtVrfCfg: if 'gwaddr' in entry: mgmt_intf_gwaddr = entry['gwaddr'] cmd = 'ip route add table {} 0.0.0.0/0 via {}'.format(MGMT_VRF_TABLE_ID, mgmt_intf_gwaddr) - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == False: return def unconfigure_mgmt_vrf(self): syslog.syslog(syslog.LOG_INFO, "Unconfigure MGMT VRF:") cmd = 'ip link delete lo-m' - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + if run_command(cmd) == True: + self.delete_mgmt_vrf_table() - self.delete_mgmt_vrf_table() return def handle_mgmt_intf_gwaddr_cfg(self, op, ifname, gwaddr): syslog.syslog(syslog.LOG_INFO, "Received MGMT Intf gwaddr config, op: {}, ifname: {}, gwaddr: {}".format(op, ifname, gwaddr)) keys = self.config_db.get_keys(CFG_MGMT_VRF) if keys: - syslog.syslog(syslog.LOG_INFO, "MGMT VRF created") cmd = 'ip route del table {} 0.0.0.0/0'.format(MGMT_VRF_TABLE_ID) - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) - pass + run_command(cmd) if op == "ADD": cmd = 'ip route add table {} 0.0.0.0/0 via {}'.format(MGMT_VRF_TABLE_ID, gwaddr) - syslog.syslog(syslog.LOG_INFO, "cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) - pass - - return True + run_command(cmd) + return True def handle_mgmt_intf_creation(self, mgmt_intf_key): syslog.syslog(syslog.LOG_INFO, "Received MGMT Intf creation, key: {}".format(mgmt_intf_key)) @@ -424,6 +356,44 @@ class MgmtVrfCfg: except: syslog.syslog(syslog.LOG_ERR, "{} MGMT VRF Configuration failed.".format(key)) + def mgmt_vrf_table_get(self): + vrf_table = 'default' + entry = self.config_db.get_entry(CFG_MGMT_VRF, CFG_MGMT_VRF_KEY) + if entry: + if (('mgmtVrfEnabled' in entry) and (entry['mgmtVrfEnabled'] == 'true')): + vrf_table = '5000' + + return vrf_table + + + + +def run_command(cmd): + syslog.syslog(syslog.LOG_INFO, "Config cmd - {}".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" + .format(err.cmd, err.returncode, err.output)) + return False + + return True + +def cfg_attr_set (cmd, attr = None, value = None, appIntf = None): + + rc = run_command(cmd) + if appIntf != None and rc == True: + appIntf[attr] = value + + return rc + +def is_attr_cfg_required (attr, cfg_data, app_data, cfgAllAtrr = True): + rc = False + + if ((cfgAllAtrr == True) or (attr not in app_data) or (cfg_data[attr] != app_data[attr])): + rc = True + + return rc class MgmtIntfCfg: @@ -458,39 +428,19 @@ class MgmtIntfCfg: def mgmt_intf_mtu_set (self, ifname, mtu, appIntf): cmd = 'ifconfig {} mtu {}'.format(ifname, mtu) - syslog.syslog(syslog.LOG_INFO, "Configure MTU, cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - appIntf['mtu'] = mtu - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + cfg_attr_set(cmd, 'mtu', mtu, appIntf) def mgmt_intf_admin_status_set (self, ifname, admin_status, appIntf): cmd = 'ifconfig {} {}'.format(ifname, admin_status) - syslog.syslog(syslog.LOG_INFO, "Configure admin_status, cmd - {}".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - appIntf['admin_status'] = admin_status - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + cfg_attr_set(cmd, 'admin_status', admin_status, appIntf) def mgmt_intf_description_set (self, ifname, description, appIntf): - syslog.syslog(syslog.LOG_INFO, "Configure description, cmd - {}".format(description)) appIntf['description'] = description def mgmt_intf_speed_set (self, ifname, speed, autoneg, appIntf): duplex = "full" cmd = 'ethtool -s {} speed {} duplex {} autoneg {}; ifup {}'.format(ifname, speed, duplex, autoneg, ifname) - syslog.syslog(syslog.LOG_INFO, "Configure SPEED, cmd - {}".format(cmd)) - - try: - subprocess.check_call(cmd, shell=True) - appIntf['speed'] = speed - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" - .format(err.cmd, err.returncode, err.output)) + cfg_attr_set(cmd, 'speed', speed, appIntf) def mgmt_intf_autoneg_set (self, ifname, autoneg, appIntf): an = "on" @@ -500,44 +450,18 @@ class MgmtIntfCfg: an = "off" cmd = "ethtool -s {} autoneg {}".format(ifname, an) - syslog.syslog(syslog.LOG_INFO, "Configure autoneg, cmd - {}".format(cmd)) - - try: - subprocess.check_call(cmd, shell=True) - appIntf['autoneg'] = autoneg - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) + cfg_attr_set(cmd, 'autoneg', autoneg, appIntf) def mgmt_intf_gwaddr_set(self, ifname, ip_prefix, gwaddr, op): - if not self.mgmt_vrf_cfg.handle_mgmt_intf_gwaddr_cfg(op, ifname, gwaddr): - try: - ip_conf = netaddr.IPNetwork(ip_prefix) - ver = "-4" - if ip_conf.version == 6: - ver = "-6" + vrf_table = self.mgmt_vrf_cfg.mgmt_vrf_table_get() + ip_conf = netaddr.IPNetwork(ip_prefix) + ver = "-4" + if ip_conf.version == 6: + ver = "-6" - cmd = "ip {} route {} {}/{} via {} dev {}".format(ver, op.lower(), ip_conf.network, ip_conf.prefixlen, gwaddr, ifname) + cmd = "ip {} route {} default via {} dev {} table {}".format(ver, op.lower(), gwaddr, ifname, vrf_table) + cfg_attr_set(cmd) - syslog.syslog(syslog.LOG_INFO, "Configure gwaddr , cmd : {}".format(cmd)) - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) - pass - - def mgmt_intf_default_gwaddr_set (self, ifname, default_gw, op): - try: - ver = "-4" - mgmt_conf = netaddr.IPNetwork(default_gw) - if mgmt_conf.version == 6: - ver = "-6" - - cmd = "ip {} route {} default via {} dev {}".format(ver, op.lower(), default_gw, ifname) - - syslog.syslog(syslog.LOG_INFO, "Configure Default Gateway, cmd : {}".format(cmd)) - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) - pass def mgmt_intf_dhclient_set (self, ifname, attr, enable): version = "" @@ -550,69 +474,76 @@ class MgmtIntfCfg: cmd_opt = "-D LL" if enable == True: - try: - path = "/var/run/dhclient{}.{}.pid".format(file_ext, ifname) - if os.path.exists(path): - cmd = "[ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(file_ext, ifname, file_ext, ifname, file_ext, ifname) - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - pass + path = "/var/run/dhclient{}.{}.pid".format(file_ext, ifname) + if os.path.exists(path): + cmd = "[ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(file_ext, ifname, file_ext, ifname, file_ext, ifname) + run_command(cmd) - try: - if enable == True: - cmd = "/sbin/dhclient {} -pf /run/dhclient{}.{}.pid -lf /var/lib/dhcp/dhclient{}.{}.leases {} -nw {} ".format(version, file_ext, ifname, file_ext, ifname, ifname, cmd_opt) - else: - cmd = "/sbin/dhclient {} -r {} && [ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(version, ifname, file_ext, ifname, file_ext, ifname, file_ext, ifname) - - syslog.syslog(syslog.LOG_INFO, "Configure dhclient , cmd : {}".format(cmd)) + if enable == True: + cmd = "/sbin/dhclient {} -pf /run/dhclient{}.{}.pid -lf /var/lib/dhcp/dhclient{}.{}.leases {} -nw {} ".format(version, file_ext, ifname, file_ext, ifname, ifname, cmd_opt) + else: + cmd = "/sbin/dhclient {} -r {} && [ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(version, ifname, file_ext, ifname, file_ext, ifname, file_ext, ifname) - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) - pass + run_command(cmd) def mgmt_intf_ip_prefix_set (self, ifname, ip_prefix, op): - try: - ver = "-4" - mgmt_conf = netaddr.IPNetwork(ip_prefix) - if mgmt_conf.version == 6: - ver = "-6" - cmd = "ip {} addr {} {} dev {}".format(ver, op.lower(), ip_prefix, ifname) - syslog.syslog(syslog.LOG_INFO, "Configure ip_prefix, op : {}, ip_prefix: {}, cmd : {}, mgmt_conf: {}".format(op, ip_prefix, cmd, mgmt_conf)) - subprocess.check_call(cmd, shell=True) - cmd = "ip {} rule {} from {} table default pref 1003".format(ver, op.lower(), str(mgmt_conf.ip)) - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}".format(err.cmd, err.returncode, err.output)) - pass + ver = "-4" + mgmt_conf = netaddr.IPNetwork(ip_prefix) + if mgmt_conf.version == 6: + ver = "-6" + + cmd = "ip {} addr {} {} dev {}".format(ver, op.lower(), ip_prefix, ifname) + cfg_attr_set(cmd) + + cmd = "ip {} rule {} from {} table default".format(ver, op.lower(), str(mgmt_conf.ip)) + cfg_attr_set(cmd) + + def mgmt_intf_forced_mgmt_routes_set (self, ifname, ip_prefix, forced_routes, op, app_forced_routes = []): + vrf_table = self.mgmt_vrf_cfg.mgmt_vrf_table_get() + if op == "UPDATE": + routes_add = [] + routes_del = [] + for cfg_route in forced_routes: + if cfg_route not in app_forced_routes: + routes_add.append(cfg_route) + + for cfg_route in app_forced_routes: + if cfg_route not in forced_routes: + routes_del.append(cfg_route) + + self.mgmt_intf_forced_mgmt_routes_set(ifname, ip_prefix, routes_del, "DEL") + self.mgmt_intf_forced_mgmt_routes_set(ifname, ip_prefix, routes_add, "ADD") + return routes_add + else: + for route in forced_routes: + cmd = "ip rule {} to {} table {}".format(op.lower(), route, vrf_table) + cfg_attr_set(cmd) + return forced_routes + def handle_mgmt_port_cfg(self, key, data): mgmt_intf = self.app_db.get_entry(APP_MGMT_PORT_TABLE, key) - is_all = False + cfgAllAtrr = False if mgmt_intf == {}: - is_all = True - - try: - if (('mtu' in data) and ((is_all == True) or (mgmt_intf == {}) or ('mtu' not in mgmt_intf) or (data['mtu'] != mgmt_intf['mtu']))): - self.mgmt_intf_mtu_set(key, data['mtu'], mgmt_intf) - - if (('description' in data) and ((is_all == True) or (mgmt_intf == {}) or ('description' not in mgmt_intf) or (data['description'] != mgmt_intf['description']))): - self.mgmt_intf_description_set(key, data['description'], mgmt_intf) - - if (('admin_status' in data) and ((is_all == True) or (mgmt_intf == {}) or ('admin_status' not in mgmt_intf) or (data['admin_status'] != mgmt_intf['admin_status']))): - self.mgmt_intf_admin_status_set(key, data['admin_status'], mgmt_intf) - - if (('autoneg' in data) and ((is_all == True) or (mgmt_intf == {}) or ('autoneg' not in mgmt_intf) or (data['autoneg'] != mgmt_intf['autoneg']))): - self.mgmt_intf_autoneg_set(key, data['autoneg'], mgmt_intf) - - if (('speed' in data) and ((is_all == True) or (mgmt_intf == {}) or ('speed' not in mgmt_intf) or (data['speed'] != mgmt_intf['speed']))): - autoneg = "on" - if 'autoneg' in data: - if data['autoneg'] == "false": - autoneg = "off" - self.mgmt_intf_speed_set(key, data['speed'], autoneg, mgmt_intf) - except: - syslog.syslog(syslog.LOG_ERR, "{} MGMT Port Config set failed.".format(key)) + cfgAllAttr = True + + attr_func_map = { + 'mtu' : self.mgmt_intf_mtu_set, + 'description' : self.mgmt_intf_description_set, + 'admin_status': self.mgmt_intf_admin_status_set, + 'autoneg' : self.mgmt_intf_autoneg_set, + 'speed' : self.mgmt_intf_speed_set, + } + for attr in data: + if (is_attr_cfg_required(attr, data, mgmt_intf, cfgAllAtrr) == True): + if attr == 'speed': + autoneg = "on" + if 'autoneg' in data: + if data['autoneg'] == "false": + autoneg = "off" + attr_func_map[attr](key, data[attr], autoneg, mgmt_intf) + else: + attr_func_map[attr](key, data[attr], mgmt_intf) self.app_db.set_entry(APP_MGMT_PORT_TABLE, key, mgmt_intf) @@ -620,124 +551,93 @@ class MgmtIntfCfg: def handle_mgmt_intf_cfg(self, key, data): cur_appdb_key = key.replace('|', ':') intf_keys = key.split("|") + db_key = key + if (len(intf_keys) > 1): + db_key = tuple(intf_keys) + cfgdb_entry = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, key) appdb_entry = self.app_db.get_entry(APP_MGMT_INTF_TABLE, cur_appdb_key) + cfg_keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) + app_keys = self.app_db.get_keys(APP_MGMT_INTF_TABLE) op = "DELETE" - keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) - - for it in keys: - if len(it) != 2: - it = (it, ) - it_key = it[0] + if ((db_key in cfg_keys) or (key in cfg_keys)): + if ((db_key in app_keys) or (cur_appdb_key in app_keys)): + op = "UPDATE" else: - it_key = it[0] + "|" + it[1] - - if it_key == key: op = "CREATE" - break - - if op == "CREATE": - if cfgdb_entry != {} and appdb_entry != {}: - op = "UPDATE" - if (len(intf_keys) < 2): if op == "DELETE": cfgdb_entry['ipv4_dhcp_client'] = "true" cfgdb_entry['ipv6_dhcp_client'] = "true" - - if (('ipv4_dhcp_client' not in appdb_entry) or (appdb_entry['ipv4_dhcp_client'] != cfgdb_entry['ipv4_dhcp_client'])): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", True) - appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] - - if (('ipv6_dhcp_client' not in appdb_entry) or (appdb_entry['ipv6_dhcp_client'] != cfgdb_entry['ipv6_dhcp_client'])): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", True) - appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] - - if ('ipv4_default_gwaddr' in appdb_entry): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DEL") - del appdb_entry['ipv4_default_gwaddr'] - - if ('ipv6_default_gwaddr' in appdb_entry): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DEL") - del appdb_entry['ipv6_default_gwaddr'] - - self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) self.config_db.set_entry(CFG_MGMT_INTF_TABLE, key, cfgdb_entry) - elif op == "CREATE": - syslog.syslog(syslog.LOG_ERR, "handle_mgmt_intf_cfg: operation is CREATE, return after vrf create handling") - self.mgmt_vrf_cfg.handle_mgmt_intf_creation(key) + for attr in cfgdb_entry: + if is_attr_cfg_required(attr, cfgdb_entry, appdb_entry, False): + self.mgmt_intf_dhclient_set(intf_keys[0], attr, cfgdb_entry[attr] == "true") + appdb_entry[attr] = cfgdb_entry[attr] + self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) - if ('ipv4_dhcp_client' in cfgdb_entry): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", cfgdb_entry['ipv4_dhcp_client'] == "true") - appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] - - if ('ipv6_dhcp_client' in cfgdb_entry): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", cfgdb_entry['ipv6_dhcp_client'] == "true") - appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] + else: + if op == "CREATE": + self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "ADD") + if ('gwaddr' in data): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") + appdb_entry['gwaddr'] = data['gwaddr'] - if ('ipv4_default_gwaddr' in cfgdb_entry): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") - appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] + if ('forced_mgmt_routes' in data): + forced_routes = data['forced_mgmt_routes'] + self.mgmt_intf_forced_mgmt_routes_set(intf_keys[0], intf_keys[1], forced_routes, "ADD") + appdb_entry['forced_mgmt_routes'] = data['forced_mgmt_routes'] - if ('ipv6_default_gwaddr' in cfgdb_entry): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") - appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] + if appdb_entry == {}: + appdb_entry["NULL"] = "NULL" self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) - elif op == "UPDATE": - if (('ipv4_dhcp_client' in cfgdb_entry) and ('ipv4_dhcp_client' not in appdb_entry)): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", cfgdb_entry['ipv4_dhcp_client'] == "true") - appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] - elif (('ipv4_dhcp_client' in cfgdb_entry) and (cfgdb_entry['ipv4_dhcp_client'] != appdb_entry['ipv4_dhcp_client'])): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv4_dhcp_client", cfgdb_entry['ipv4_dhcp_client'] == "true") - appdb_entry['ipv4_dhcp_client'] = cfgdb_entry['ipv4_dhcp_client'] - - if (('ipv6_dhcp_client' in cfgdb_entry) and ('ipv6_dhcp_client' not in appdb_entry)): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", cfgdb_entry['ipv6_dhcp_client'] == "true") - appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] - elif (('ipv6_dhcp_client' in cfgdb_entry) and (cfgdb_entry['ipv6_dhcp_client'] != appdb_entry['ipv6_dhcp_client'])): - self.mgmt_intf_dhclient_set(intf_keys[0], "ipv6_dhcp_client", cfgdb_entry['ipv6_dhcp_client'] == "true") - appdb_entry['ipv6_dhcp_client'] = cfgdb_entry['ipv6_dhcp_client'] - - if (('ipv4_default_gwaddr' in cfgdb_entry) and ('ipv4_default_gwaddr' not in appdb_entry)): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") - appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] - elif (('ipv4_default_gwaddr' in cfgdb_entry) and (cfgdb_entry['ipv4_default_gwaddr'] != appdb_entry['ipv4_default_gwaddr'])): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DEL") - self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv4_default_gwaddr'], "ADD") - appdb_entry['ipv4_default_gwaddr'] = cfgdb_entry['ipv4_default_gwaddr'] - elif (('ipv4_default_gwaddr' not in cfgdb_entry) and ('ipv4_default_gwaddr' in appdb_entry)): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv4_default_gwaddr'], "DEL") - del appdb_entry['ipv4_default_gwaddr'] - - if (('ipv6_default_gwaddr' in cfgdb_entry) and ('ipv6_default_gwaddr' not in appdb_entry)): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") - appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] - elif (('ipv6_default_gwaddr' in cfgdb_entry) and (cfgdb_entry['ipv6_default_gwaddr'] != appdb_entry['ipv6_default_gwaddr'])): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DEL") - self.mgmt_intf_default_gwaddr_set(intf_keys[0], cfgdb_entry['ipv6_default_gwaddr'], "ADD") - appdb_entry['ipv6_default_gwaddr'] = cfgdb_entry['ipv6_default_gwaddr'] - elif (('ipv6_default_gwaddr' not in cfgdb_entry) and ('ipv6_default_gwaddr' in appdb_entry)): - self.mgmt_intf_default_gwaddr_set(intf_keys[0], appdb_entry['ipv6_default_gwaddr'], "DEL") - del appdb_entry['ipv6_default_gwaddr'] + ''' + Case 1: gwaddr attribute delete case, gwaddr present in appdb entry + and not in config db entry + Case 2: gwaddr attribute add case, gwaddr is present in config db + entry but not in appdb entry + case 3: gwaddr attribute modify case, gwaddr present in both config + and app db entry but they are different + ''' + if ('gwaddr' not in cfgdb_entry): + if ('gwaddr' in appdb_entry): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'],"DEL") + del appdb_entry['gwaddr'] + else: + if ('gwaddr' not in appdb_entry): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], cfgdb_entry['gwaddr'], "ADD") + elif (cfgdb_entry['gwaddr'] != appdb_entry['gwaddr']): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'],"DEL") + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], cfgdb_entry['gwaddr'], "ADD") - self.app_db.set_entry(APP_MGMT_INTF_TABLE, cur_appdb_key, appdb_entry) - else: - if op == "CREATE" or op == "UPDATE" : - self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "ADD") - if (('gwaddr' in data) and ((appdb_entry == {}) or ('gwaddr' not in appdb_entry))): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") - appdb_entry['gwaddr'] = data['gwaddr'] - elif (('gwaddr' in data) and ('gwaddr' not in cfgdb_entry) and ('gwaddr' in appdb_entry)): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'],"DEL") - del appdb_entry['gwaddr'] - elif (('gwaddr' in data) and (data['gwaddr'] != appdb_entry['gwaddr'])): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'],"DEL") - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "ADD") - appdb_entry['gwaddr'] = data['gwaddr'] + appdb_entry['gwaddr'] = cfgdb_entry['gwaddr'] + + ''' + Handle forced routes config UPDATE operation + ''' + cfg_forced_routes = [] + app_forced_routes = [] + if ('forced_mgmt_routes' in cfgdb_entry): + cfg_forced_routes = cfgdb_entry['forced_mgmt_routes'] + if ('forced_mgmt_routes' in appdb_entry): + app_forced_routes = appdb_entry['forced_mgmt_routes'] + + ''' + check is forced_mgmt_routes present in config db or app db entry + handle update case. + ''' + if (len(cfg_forced_routes) > 0 or len(app_forced_routes) > 0): + cfg_forced_routes = self.mgmt_intf_forced_mgmt_routes_set(intf_keys[0], intf_keys[1], + cfg_forced_routes, op, app_forced_routes) + + if len(cfg_forced_routes) == 0: + del appdb_entry['forced_mgmt_routes'] + else: + appdb_entry['forced_mgmt_routes'] = cfgdb_entry['forced_mgmt_routes'] if appdb_entry == {}: appdb_entry["NULL"] = "NULL" @@ -746,8 +646,13 @@ class MgmtIntfCfg: else: self.mgmt_intf_ip_prefix_set(intf_keys[0], intf_keys[1], "DEL") - if ('gwaddr' in data): - self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], data['gwaddr'], "DEL") + if ('gwaddr' in appdb_entry): + self.mgmt_intf_gwaddr_set(intf_keys[0], intf_keys[1], appdb_entry['gwaddr'], "DEL") + + if ('forced_mgmt_routes' in appdb_entry): + forced_routes = appdb_entry['forced_mgmt_routes'] + self.mgmt_intf_forced_mgmt_routes_set(intf_keys[0], intf_keys[1], forced_routes, "DEL") + self.app_db.delete_entry(APP_MGMT_INTF_TABLE, cur_appdb_key) diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index dbedd5e9418..33f6b11c753 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -5,19 +5,7 @@ # file: /etc/network/interfaces # {% endblock banner %} -{% block mgmt_vrf %} -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} -auto mgmt -iface mgmt - vrf-table 5000 -# The loopback network interface for mgmt VRF that is required for applications like NTP - up ip link add lo-m type dummy - up ip link set dev lo-m master mgmt - up ip addr add 127.0.0.1/8 dev lo-m - up ip link set lo-m up - down ip link delete dev lo-m -{% endif %} -{% endblock mgmt_vrf %} + {% block loopback %} # The loopback network interface auto lo @@ -57,47 +45,6 @@ iface {{ port }} inet6 dhcp {% endif %} {% endfor %} {% endif %} - -{% else %} -{% if MGMT_INTERFACE %} -{% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} -iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static - address {{ prefix | ip }} - netmask {{ prefix | netmask if prefix | ipv4 else prefix | prefixlen }} - network {{ prefix | network }} - broadcast {{ prefix | broadcast }} -{% set vrf_table = 'default' %} -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} -{% set vrf_table = '5000' %} - vrf mgmt -{% endif %} - ########## management network policy routing rules - # management port up rules - up ip {{ '-4' if prefix | ipv4 else '-6' }} route add default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} metric 201 - up ip {{ '-4' if prefix | ipv4 else '-6' }} route add {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} - up ip {{ '-4' if prefix | ipv4 else '-6' }} rule add from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} -{% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} - up ip rule add to {{ route }} table {{ vrf_table }} -{% endfor %} - # management port down rules - pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} - pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} - pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} -{% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} - pre-down ip rule delete to {{ route }} table {{ vrf_table }} -{% endfor %} -{# TODO: COPP policy type rules #} -{% endfor %} -{% else %} -iface eth0 inet dhcp - metric 202 -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} - vrf mgmt -{% endif %} -iface eth0 inet6 dhcp - up sysctl net.ipv6.conf.eth0.accept_ra=1 - down sysctl net.ipv6.conf.eth0.accept_ra=0 -{% endif %} {% endif %} # source /etc/network/interfaces.d/* From 424ab53a0e29c40afe4ca788caf41c2c273a9655 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Tue, 21 Apr 2020 17:33:21 -0700 Subject: [PATCH 63/69] Removed unused imports. --- files/dhcp/dhcp_mgmt_conf.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/files/dhcp/dhcp_mgmt_conf.py b/files/dhcp/dhcp_mgmt_conf.py index 25cc5a80f88..c582dd83856 100644 --- a/files/dhcp/dhcp_mgmt_conf.py +++ b/files/dhcp/dhcp_mgmt_conf.py @@ -1,13 +1,9 @@ #!/usr/bin/python -u # -*- coding: utf-8 -*- -import os -import re import sys -import subprocess import syslog import ipaddress -import netaddr from swsssdk import ConfigDBConnector APP_MGMT_INTF_TABLE = "MGMT_INTF_TABLE" From d3faf453458a2d5e2b73ea2555798a4b5cbfc515 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Fri, 1 May 2020 09:22:09 -0700 Subject: [PATCH 64/69] Addressed review comments. --- files/dhcp/dhcp_mgmt_conf.py | 4 -- files/image_config/hostcfgd/hostcfgd | 60 +++++++++------------------- 2 files changed, 19 insertions(+), 45 deletions(-) diff --git a/files/dhcp/dhcp_mgmt_conf.py b/files/dhcp/dhcp_mgmt_conf.py index c582dd83856..9503d7c4ce0 100644 --- a/files/dhcp/dhcp_mgmt_conf.py +++ b/files/dhcp/dhcp_mgmt_conf.py @@ -32,7 +32,3 @@ def update_dhcp_mgmt_ip_info(): else: syslog.syslog(syslog.LOG_INFO, "Args : {}".format(sys.argv)) update_dhcp_mgmt_ip_info() - - - - diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 0b713dfcc25..4f573a9426b 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -252,15 +252,12 @@ class MgmtVrfCfg: self.mgmt_vrf_table_created = False def configure_mgmt_vrf(self): - syslog.syslog(syslog.LOG_INFO, "Configure MGMT VRF:") - self.create_mgmt_vrf_table() cmd = 'ip link set dev mgmt up' if run_command(cmd) == False: return - syslog.syslog(syslog.LOG_INFO, "Add lo intf:") cmd = 'ip link add lo-m type dummy' if run_command(cmd) == False: return @@ -280,9 +277,7 @@ class MgmtVrfCfg: self.bind_mgmt_intf() def bind_mgmt_intf(self): - syslog.syslog(syslog.LOG_INFO, "Handle MGMT intf:") keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) - syslog.syslog(syslog.LOG_INFO, "MGMT interfaces keys: {}".format(str(keys))) mgmt_intf_bound = False for it in keys: @@ -293,31 +288,24 @@ class MgmtVrfCfg: if run_command(cmd) == False: return - cmd = 'sysctl -w net.ipv4.tcp_l3mdev_accept=1' - if run_command(cmd) == False: - return - mgmt_intf_bound = True break - if not mgmt_intf_bound: - syslog.syslog(syslog.LOG_ERR, "MGMT VRF: MGMT interface not bound") - else: - for it in keys: - if type(it) is unicode: - key = it - else: - key = it[0] + "|" + it[1] + return mgmt_intf_bound - entry = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, key) - if 'gwaddr' in entry: - mgmt_intf_gwaddr = entry['gwaddr'] - cmd = 'ip route add table {} 0.0.0.0/0 via {}'.format(MGMT_VRF_TABLE_ID, mgmt_intf_gwaddr) - if run_command(cmd) == False: - return + def mgmt_vrf_add_default_routes(self): + keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) + for it in keys: + if type(it) is unicode: + continue - def unconfigure_mgmt_vrf(self): - syslog.syslog(syslog.LOG_INFO, "Unconfigure MGMT VRF:") + key = it[0] + "|" + it[1] + + entry = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, key) + if 'gwaddr' in entry: + mgmt_intf_gwaddr = entry['gwaddr'] + self.handle_mgmt_intf_gwaddr_cfg("ADD", it[0], mgmt_intf_gwaddr) + def unconfigure_mgmt_vrf(self): cmd = 'ip link delete lo-m' if run_command(cmd) == True: self.delete_mgmt_vrf_table() @@ -325,7 +313,7 @@ class MgmtVrfCfg: return def handle_mgmt_intf_gwaddr_cfg(self, op, ifname, gwaddr): - syslog.syslog(syslog.LOG_INFO, "Received MGMT Intf gwaddr config, op: {}, ifname: {}, gwaddr: {}".format(op, ifname, gwaddr)) + rc = False keys = self.config_db.get_keys(CFG_MGMT_VRF) if keys: cmd = 'ip route del table {} 0.0.0.0/0'.format(MGMT_VRF_TABLE_ID) @@ -334,17 +322,17 @@ class MgmtVrfCfg: if op == "ADD": cmd = 'ip route add table {} 0.0.0.0/0 via {}'.format(MGMT_VRF_TABLE_ID, gwaddr) run_command(cmd) - return True + rc = True + + return rc def handle_mgmt_intf_creation(self, mgmt_intf_key): - syslog.syslog(syslog.LOG_INFO, "Received MGMT Intf creation, key: {}".format(mgmt_intf_key)) keys = self.config_db.get_keys(CFG_MGMT_VRF) if keys: - syslog.syslog(syslog.LOG_INFO, "MGMT VRF created") - self.bind_mgmt_intf() + if self.bind_mgmt_intf() == True: + self.mgmt_vrf_add_default_routes() def handle_mgmt_vrf_cfg(self, key, data): - syslog.syslog(syslog.LOG_INFO, "Received MGMT VRF config, key: {}, data: {}".format(key, data)) try: if data: if data['mgmtVrfEnabled'] == 'true': @@ -365,9 +353,6 @@ class MgmtVrfCfg: return vrf_table - - - def run_command(cmd): syslog.syslog(syslog.LOG_INFO, "Config cmd - {}".format(cmd)) try: @@ -380,7 +365,6 @@ def run_command(cmd): return True def cfg_attr_set (cmd, attr = None, value = None, appIntf = None): - rc = run_command(cmd) if appIntf != None and rc == True: appIntf[attr] = value @@ -395,15 +379,12 @@ def is_attr_cfg_required (attr, cfg_data, app_data, cfgAllAtrr = True): return rc - class MgmtIntfCfg: def __init__(self, cfg_db, mgmt_vrf_cfg): self.app_db = ConfigDBConnector() self.app_db.db_connect('APPL_DB', wait_for_init=False, retry_on=True) self.config_db = cfg_db self.mgmt_vrf_cfg = mgmt_vrf_cfg - syslog.syslog(syslog.LOG_INFO, 'AppDB connect success') - self.mgmt_intf_handle_default_cfg("eth0") def mgmt_intf_handle_default_cfg (self, ifname): @@ -462,7 +443,6 @@ class MgmtIntfCfg: cmd = "ip {} route {} default via {} dev {} table {}".format(ver, op.lower(), gwaddr, ifname, vrf_table) cfg_attr_set(cmd) - def mgmt_intf_dhclient_set (self, ifname, attr, enable): version = "" file_ext = "" @@ -520,7 +500,6 @@ class MgmtIntfCfg: cfg_attr_set(cmd) return forced_routes - def handle_mgmt_port_cfg(self, key, data): mgmt_intf = self.app_db.get_entry(APP_MGMT_PORT_TABLE, key) cfgAllAtrr = False @@ -547,7 +526,6 @@ class MgmtIntfCfg: self.app_db.set_entry(APP_MGMT_PORT_TABLE, key, mgmt_intf) - def handle_mgmt_intf_cfg(self, key, data): cur_appdb_key = key.replace('|', ':') intf_keys = key.split("|") From 55445c400305186adc3ec34b5c559c2fc6793ad1 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Sat, 2 May 2020 14:02:25 -0700 Subject: [PATCH 65/69] Addressed review comments and fixed build issue --- files/image_config/hostcfgd/hostcfgd | 27 ++++++++++--- .../interfaces/interfaces-config.sh | 5 --- .../tests/sample_output/interfaces | 29 +------------- .../tests/sample_output/mvrf_interfaces | 40 +------------------ 4 files changed, 24 insertions(+), 77 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 4f573a9426b..290c4c17020 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -366,7 +366,7 @@ def run_command(cmd): def cfg_attr_set (cmd, attr = None, value = None, appIntf = None): rc = run_command(cmd) - if appIntf != None and rc == True: + if appIntf != None: appIntf[attr] = value return rc @@ -385,6 +385,7 @@ class MgmtIntfCfg: self.app_db.db_connect('APPL_DB', wait_for_init=False, retry_on=True) self.config_db = cfg_db self.mgmt_vrf_cfg = mgmt_vrf_cfg + self.mgmt_cfg_appdb_cleanup() self.mgmt_intf_handle_default_cfg("eth0") def mgmt_intf_handle_default_cfg (self, ifname): @@ -400,19 +401,35 @@ class MgmtIntfCfg: self.handle_mgmt_port_cfg(ifname, mgmt_intf) - mgmt_intf = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, ifname) - if mgmt_intf == {}: + keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) + if len(keys) == 0: + mgmt_intf = {} mgmt_intf['ipv4_dhcp_client'] = "true" mgmt_intf['ipv6_dhcp_client'] = "true" self.config_db.set_entry(CFG_MGMT_INTF_TABLE, ifname, mgmt_intf) self.app_db.set_entry(APP_MGMT_INTF_TABLE, ifname, mgmt_intf) + else: + for it in keys: + if type(it) is unicode: + key = it + else: + key = it[0] + "|" + it[1] + data = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, key) + self.handle_mgmt_intf_cfg(key, data) + + def mgmt_cfg_appdb_cleanup (self): + tbl_list = [APP_MGMT_PORT_TABLE, APP_MGMT_INTF_TABLE] + for tbl in tbl_list: + keys = self.app_db.get_keys(tbl) + for key in keys: + self.app_db.delete_entry(tbl, key) def mgmt_intf_mtu_set (self, ifname, mtu, appIntf): cmd = 'ifconfig {} mtu {}'.format(ifname, mtu) cfg_attr_set(cmd, 'mtu', mtu, appIntf) def mgmt_intf_admin_status_set (self, ifname, admin_status, appIntf): - cmd = 'ifconfig {} {}'.format(ifname, admin_status) + cmd = 'ip link set {} {}'.format(ifname, admin_status) cfg_attr_set(cmd, 'admin_status', admin_status, appIntf) def mgmt_intf_description_set (self, ifname, description, appIntf): @@ -420,7 +437,7 @@ class MgmtIntfCfg: def mgmt_intf_speed_set (self, ifname, speed, autoneg, appIntf): duplex = "full" - cmd = 'ethtool -s {} speed {} duplex {} autoneg {}; ifup {}'.format(ifname, speed, duplex, autoneg, ifname) + cmd = 'ifdown --force {}; ethtool -s {} speed {} duplex {} autoneg {}; ifup --force {}'.format(ifname, ifname, speed, duplex, autoneg, ifname) cfg_attr_set(cmd, 'speed', speed, appIntf) def mgmt_intf_autoneg_set (self, ifname, autoneg, appIntf): diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index b5352745a7e..407afe57a36 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -1,7 +1,5 @@ #!/bin/bash -ifdown --force eth0 - # Check if ZTP DHCP policy has been installed if [ -e /etc/network/ifupdown2/policy.d/ztp_dhcp.json ]; then # Obtain port operational state information @@ -21,9 +19,6 @@ fi # Create /e/n/i file for existing and active interfaces sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces -[ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid -[ -f /var/run/dhclient6.eth0.pid ] && kill `cat /var/run/dhclient6.eth0.pid` && rm -f /var/run/dhclient6.eth0.pid - for intf_pid in $(ls -1 /var/run/dhclient*.Ethernet*.pid 2> /dev/null); do [ -f ${intf_pid} ] && kill `cat ${intf_pid}` && rm -f ${intf_pid} done diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces index 07fd7a522c3..a62b41b3a76 100644 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -3,40 +3,13 @@ # 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 # The management network interface auto eth0 -iface eth0 inet static - address 10.0.0.100 - netmask 255.255.255.0 - network 10.0.0.0 - broadcast 10.0.0.255 - ########## management network policy routing rules - # management port up rules - up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 - up ip -4 route add 10.0.0.0/24 dev eth0 table default - up ip -4 rule add from 10.0.0.100/32 table default - # management port down rules - pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default - pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default - pre-down ip -4 rule delete from 10.0.0.100/32 table default -iface eth0 inet6 static - address 2603:10e2:0:2902::8 - netmask 64 - network 2603:10e2:0:2902:: - broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff - ########## management network policy routing rules - # management port up rules - up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table default metric 201 - up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table default - up ip -6 rule add from 2603:10e2:0:2902::8/128 table default - # management port down rules - pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default - pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default - pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table default # source /etc/network/interfaces.d/* # diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces index 085f5111c3f..a62b41b3a76 100644 --- a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces @@ -3,51 +3,13 @@ # generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen # file: /etc/network/interfaces # -auto mgmt -iface mgmt - vrf-table 5000 -# The loopback network interface for mgmt VRF that is required for applications like NTP - up ip link add lo-m type dummy - up ip link set dev lo-m master mgmt - up ip addr add 127.0.0.1/8 dev lo-m - up ip link set lo-m up - down ip link delete dev lo-m + # The loopback network interface auto lo iface lo inet loopback # The management network interface auto eth0 -iface eth0 inet static - address 10.0.0.100 - netmask 255.255.255.0 - network 10.0.0.0 - broadcast 10.0.0.255 - vrf mgmt - ########## management network policy routing rules - # management port up rules - up ip -4 route add default via 10.0.0.1 dev eth0 table 5000 metric 201 - up ip -4 route add 10.0.0.0/24 dev eth0 table 5000 - up ip -4 rule add from 10.0.0.100/32 table 5000 - # management port down rules - pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 - pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 - pre-down ip -4 rule delete from 10.0.0.100/32 table 5000 -iface eth0 inet6 static - address 2603:10e2:0:2902::8 - netmask 64 - network 2603:10e2:0:2902:: - broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff - vrf mgmt - ########## management network policy routing rules - # management port up rules - up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table 5000 metric 201 - up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table 5000 - up ip -6 rule add from 2603:10e2:0:2902::8/128 table 5000 - # management port down rules - pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table 5000 - pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table 5000 - pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table 5000 # source /etc/network/interfaces.d/* # From 7ca8e39eff0303f9e2106890d2a9d18f5c89db4a Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Mon, 4 May 2020 23:01:50 -0700 Subject: [PATCH 66/69] Added default mgmt routes and rules --- files/image_config/hostcfgd/hostcfgd | 38 ++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 290c4c17020..141881e4d88 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -429,9 +429,15 @@ class MgmtIntfCfg: cfg_attr_set(cmd, 'mtu', mtu, appIntf) def mgmt_intf_admin_status_set (self, ifname, admin_status, appIntf): + if (admin_status != "up"): + self.handle_admin_status_change(ifname, "DEL") + cmd = 'ip link set {} {}'.format(ifname, admin_status) cfg_attr_set(cmd, 'admin_status', admin_status, appIntf) + if (admin_status == "up"): + self.handle_admin_status_change(ifname, "ADD") + def mgmt_intf_description_set (self, ifname, description, appIntf): appIntf['description'] = description @@ -450,14 +456,36 @@ class MgmtIntfCfg: cmd = "ethtool -s {} autoneg {}".format(ifname, an) cfg_attr_set(cmd, 'autoneg', autoneg, appIntf) + def handle_admin_status_change(self, ifname, oper): + keys = self.config_db.get_keys(CFG_MGMT_INTF_TABLE) + for it in keys: + if type(it) is unicode: + continue + + if it[0] == ifname: + data = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, it) + if ('gwaddr' in data): + self.mgmt_intf_gwaddr_set(ifname, it[1], data['gwaddr'], oper) + + self.mgmt_intf_ip_prefix_set(ifname, it[1], oper) + + if ('forced_mgmt_routes' in data): + forced_routes = data['forced_mgmt_routes'] + self.mgmt_intf_forced_mgmt_routes_set(ifname, it[1], forced_routes, oper) + + + def mgmt_intf_gwaddr_set(self, ifname, ip_prefix, gwaddr, op): vrf_table = self.mgmt_vrf_cfg.mgmt_vrf_table_get() ip_conf = netaddr.IPNetwork(ip_prefix) ver = "-4" + ext = "" if ip_conf.version == 6: ver = "-6" + if op.lower() == "add": + ext = "metric 201" - cmd = "ip {} route {} default via {} dev {} table {}".format(ver, op.lower(), gwaddr, ifname, vrf_table) + cmd = "ip {} route {} default via {} dev {} table {} {}".format(ver, op.lower(), gwaddr, ifname, vrf_table, ext) cfg_attr_set(cmd) def mgmt_intf_dhclient_set (self, ifname, attr, enable): @@ -484,15 +512,21 @@ class MgmtIntfCfg: run_command(cmd) def mgmt_intf_ip_prefix_set (self, ifname, ip_prefix, op): + vrf_table = self.mgmt_vrf_cfg.mgmt_vrf_table_get() ver = "-4" + plen = "32" mgmt_conf = netaddr.IPNetwork(ip_prefix) if mgmt_conf.version == 6: ver = "-6" + plen = "128" cmd = "ip {} addr {} {} dev {}".format(ver, op.lower(), ip_prefix, ifname) cfg_attr_set(cmd) - cmd = "ip {} rule {} from {} table default".format(ver, op.lower(), str(mgmt_conf.ip)) + cmd = "ip {} route {} {}/{} dev {} table {}".format(ver, op.lower(), str(mgmt_conf.network), mgmt_conf.prefixlen, ifname, vrf_table) + cfg_attr_set(cmd) + + cmd = "ip {} rule {} from {}/{} table {}".format(ver, op.lower(), str(mgmt_conf.ip), plen, vrf_table) cfg_attr_set(cmd) def mgmt_intf_forced_mgmt_routes_set (self, ifname, ip_prefix, forced_routes, op, app_forced_routes = []): From 903ad51fc05bd31da0ad356f3e52469b19ae2d0f Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Mon, 4 May 2020 23:15:04 -0700 Subject: [PATCH 67/69] Addressed issuses reported LGTM analysis --- files/image_config/hostcfgd/hostcfgd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 141881e4d88..739a8c39a75 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -371,10 +371,10 @@ def cfg_attr_set (cmd, attr = None, value = None, appIntf = None): return rc -def is_attr_cfg_required (attr, cfg_data, app_data, cfgAllAtrr = True): +def is_attr_cfg_required (attr, cfg_data, app_data, cfgAllAttr = True): rc = False - if ((cfgAllAtrr == True) or (attr not in app_data) or (cfg_data[attr] != app_data[attr])): + if ((cfgAllAttr == True) or (attr not in app_data) or (cfg_data[attr] != app_data[attr])): rc = True return rc @@ -553,7 +553,7 @@ class MgmtIntfCfg: def handle_mgmt_port_cfg(self, key, data): mgmt_intf = self.app_db.get_entry(APP_MGMT_PORT_TABLE, key) - cfgAllAtrr = False + cfgAllAttr = False if mgmt_intf == {}: cfgAllAttr = True @@ -565,7 +565,7 @@ class MgmtIntfCfg: 'speed' : self.mgmt_intf_speed_set, } for attr in data: - if (is_attr_cfg_required(attr, data, mgmt_intf, cfgAllAtrr) == True): + if (is_attr_cfg_required(attr, data, mgmt_intf, cfgAllAttr) == True): if attr == 'speed': autoneg = "on" if 'autoneg' in data: From 07eb6ad1e92dba3a0e46d58265e23ca563a8bbc0 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Mon, 4 May 2020 23:55:18 -0700 Subject: [PATCH 68/69] Addressed issuses reported LGTM analysis --- files/image_config/hostcfgd/hostcfgd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 739a8c39a75..b181dc18076 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -341,7 +341,7 @@ class MgmtVrfCfg: self.unconfigure_mgmt_vrf() else: self.unconfigure_mgmt_vrf() - except: + except Exception as inst: syslog.syslog(syslog.LOG_ERR, "{} MGMT VRF Configuration failed.".format(key)) def mgmt_vrf_table_get(self): From 6513b328d7ecee03cc74c362c3b3a36eb9b55a11 Mon Sep 17 00:00:00 2001 From: Ravi Vasanthm Date: Tue, 5 May 2020 13:50:08 -0700 Subject: [PATCH 69/69] Fixed issue in handling net.ipv6.conf.eth0.accept_ra sysctl --- files/image_config/hostcfgd/hostcfgd | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index b181dc18076..3b66dd794a0 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -464,11 +464,10 @@ class MgmtIntfCfg: if it[0] == ifname: data = self.config_db.get_entry(CFG_MGMT_INTF_TABLE, it) + self.mgmt_intf_ip_prefix_set(ifname, it[1], oper) if ('gwaddr' in data): self.mgmt_intf_gwaddr_set(ifname, it[1], data['gwaddr'], oper) - self.mgmt_intf_ip_prefix_set(ifname, it[1], oper) - if ('forced_mgmt_routes' in data): forced_routes = data['forced_mgmt_routes'] self.mgmt_intf_forced_mgmt_routes_set(ifname, it[1], forced_routes, oper) @@ -505,11 +504,15 @@ class MgmtIntfCfg: run_command(cmd) if enable == True: + cmd = 'sysctl net.ipv6.conf.eth0.accept_ra=1' + run_command(cmd) cmd = "/sbin/dhclient {} -pf /run/dhclient{}.{}.pid -lf /var/lib/dhcp/dhclient{}.{}.leases {} -nw {} ".format(version, file_ext, ifname, file_ext, ifname, ifname, cmd_opt) + run_command(cmd) else: cmd = "/sbin/dhclient {} -r {} && [ -f /var/run/dhclient{}.{}.pid ] && kill `cat /var/run/dhclient{}.{}.pid` && rm -f /var/run/dhclient{}.{}.pid".format(version, ifname, file_ext, ifname, file_ext, ifname, file_ext, ifname) - - run_command(cmd) + run_command(cmd) + cmd = 'sysctl net.ipv6.conf.eth0.accept_ra=0' + run_command(cmd) def mgmt_intf_ip_prefix_set (self, ifname, ip_prefix, op): vrf_table = self.mgmt_vrf_cfg.mgmt_vrf_table_get()