From 97aee026de217cdfd46e938b8f5c82bfef44bb21 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Tue, 22 Sep 2020 11:23:42 +0300 Subject: [PATCH 01/78] [logrotate] create separate logrotate.d config for update-alternatives (#5382) To fix the following error when running `logrotate /etc/logrotate.conf` : ``` error: dpkg:10 duplicate log entry for /var/log/alternatives.log error: found error in file dpkg, skipping ``` update-alternatives is provided with dedicated logrotate config in newer dpkg package versions (probably starting from buster) Signed-off-by: Volodymyr Boyko --- files/image_config/logrotate/logrotate.d/alternatives | 9 +++++++++ files/image_config/logrotate/logrotate.d/dpkg | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 files/image_config/logrotate/logrotate.d/alternatives diff --git a/files/image_config/logrotate/logrotate.d/alternatives b/files/image_config/logrotate/logrotate.d/alternatives new file mode 100644 index 000000000000..7c4c93c85834 --- /dev/null +++ b/files/image_config/logrotate/logrotate.d/alternatives @@ -0,0 +1,9 @@ +/var/log/alternatives.log { + size 100k + rotate 1 + compress + delaycompress + missingok + notifempty + create 644 root root +} diff --git a/files/image_config/logrotate/logrotate.d/dpkg b/files/image_config/logrotate/logrotate.d/dpkg index 5e24c7ed74e1..51b8f46fe105 100644 --- a/files/image_config/logrotate/logrotate.d/dpkg +++ b/files/image_config/logrotate/logrotate.d/dpkg @@ -7,12 +7,3 @@ notifempty create 644 root root } -/var/log/alternatives.log { - size 100k - rotate 1 - compress - delaycompress - missingok - notifempty - create 644 root root -} From dd008d012ce9baa77422d4f12f846785fef8eff2 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Tue, 22 Sep 2020 08:24:45 +0000 Subject: [PATCH 02/78] DellEMC: PCIe config files for S6000, S6100 (#5321) To support "pcieutil pcie-check" command in DellEMC S6000, S6100. --- .../plugins/pcie.yaml | 65 +++++++++++++++++++ .../plugins/pcie.yaml | 55 ++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 device/dell/x86_64-dell_s6000_s1220-r0/plugins/pcie.yaml create mode 100644 device/dell/x86_64-dell_s6100_c2538-r0/plugins/pcie.yaml diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/plugins/pcie.yaml b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/pcie.yaml new file mode 100644 index 000000000000..9c4bea46730a --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/pcie.yaml @@ -0,0 +1,65 @@ +- bus: '00' + dev: '01' + fn: '0' + id: 0c46 + name: 'PCI bridge: Intel Corporation Atom Processor S1200 PCI Express Root Port 1' +- bus: '00' + dev: '02' + fn: '0' + id: 0c47 + name: 'PCI bridge: Intel Corporation Atom Processor S1200 PCI Express Root Port 2' +- bus: '00' + dev: '03' + fn: '0' + id: 0c48 + name: 'PCI bridge: Intel Corporation Atom Processor S1200 PCI Express Root Port 3' +- bus: '00' + dev: '04' + fn: '0' + id: 0c49 + name: 'PCI bridge: Intel Corporation Atom Processor S1200 PCI Express Root Port 4' +- bus: '00' + dev: 0e + fn: '0' + id: 0c54 + name: 'IOMMU: Intel Corporation Atom Processor S1200 Internal' +- bus: '00' + dev: '13' + fn: '0' + id: 0c59 + name: 'System peripheral: Intel Corporation Atom Processor S1200 SMBus 2.0 Controller 0' +- bus: '00' + dev: '13' + fn: '1' + id: 0c5a + name: 'System peripheral: Intel Corporation Atom Processor S1200 SMBus 2.0 Controller 1' +- bus: '01' + dev: '00' + fn: '0' + id: b850 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56850 Switch ASIC' +- bus: '02' + dev: '00' + fn: '0' + id: '9170' + name: 'SATA controller: Marvell Technology Group Ltd. Device 9170' +- bus: '03' + dev: '00' + fn: '0' + id: 400a + name: 'PCI bridge: Pericom Semiconductor PI7C9X442SL PCI Express Bridge Port' +- bus: '04' + dev: '01' + fn: '0' + id: 400a + name: 'PCI bridge: Pericom Semiconductor PI7C9X442SL PCI Express Bridge Port' +- bus: '04' + dev: '02' + fn: '0' + id: 400a + name: 'PCI bridge: Pericom Semiconductor PI7C9X442SL PCI Express Bridge Port' +- bus: 08 + dev: '00' + fn: '0' + id: 10d3 + name: 'Ethernet controller: Intel Corporation 82574L Gigabit Network Connection' diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/pcie.yaml b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/pcie.yaml new file mode 100644 index 000000000000..650610c7b557 --- /dev/null +++ b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/pcie.yaml @@ -0,0 +1,55 @@ +- bus: '00' + dev: '01' + fn: '0' + id: 1f10 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 1' +- bus: '00' + dev: '02' + fn: '0' + id: 1f11 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 2' +- bus: '00' + dev: '03' + fn: '0' + id: 1f12 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 3' +- bus: '00' + dev: '04' + fn: '0' + id: 1f13 + name: 'PCI bridge: Intel Corporation Atom processor C2000 PCIe Root Port 4' +- bus: '00' + dev: 0f + fn: '0' + id: 1f16 + name: 'IOMMU: Intel Corporation Atom processor C2000 RCEC' +- bus: '00' + dev: '13' + fn: '0' + id: 1f15 + name: 'System peripheral: Intel Corporation Atom processor C2000 SMBus 2.0' +- bus: '00' + dev: '14' + fn: '0' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354' +- bus: '00' + dev: '14' + fn: '1' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354' +- bus: '00' + dev: '14' + fn: '2' + id: 1f41 + name: 'Ethernet controller: Intel Corporation Ethernet Connection I354' +- bus: '01' + dev: '00' + fn: '0' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC' +- bus: '01' + dev: '00' + fn: '1' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC' From a7f4bfa96d58e367415d8169c965613775e7c0d6 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Tue, 22 Sep 2020 08:32:17 -0700 Subject: [PATCH 03/78] Enabling ipv6 support on docker container network. This is needed (#5418) for ipv6 communication between container and host in multi-asic platforms. Address is assign is private address space of fd::/80 with prefix len selected as 80 so that last 48 bits can be container mac address and and you prevent NDP neighbor cache invalidation issues in the Docker layer. Ref: https://docs.docker.com/config/daemon/ipv6/ Ref:https://medium.com/@skleeschulte/how-to-enable-ipv6-for-docker-containers-on-ubuntu-18-04-c68394a219a2 Signed-off-by: Abhishek Dosi Co-authored-by: Abhishek Dosi --- files/docker/docker.service.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/docker/docker.service.conf b/files/docker/docker.service.conf index e9ba55c8afa8..7debd85a50ac 100644 --- a/files/docker/docker.service.conf +++ b/files/docker/docker.service.conf @@ -1,3 +1,3 @@ [Service] ExecStart= -ExecStart=/usr/bin/dockerd -H unix:// --storage-driver=overlay2 --bip=240.127.1.1/24 --iptables=false +ExecStart=/usr/bin/dockerd -H unix:// --storage-driver=overlay2 --bip=240.127.1.1/24 --iptables=false --ipv6=true --fixed-cidr-v6=fd00::/80 From 75e4258508e63d865ec509b19eae4fc29bb05f6a Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Tue, 22 Sep 2020 08:34:02 -0700 Subject: [PATCH 04/78] Enhanced Feature Table state enable/disable for multi-asic platforms. (#5358) * Enhanced Feature Table state enable/disbale for multi-asic platforms. In Multi-asic for some features we can service per asic so we need to get list of all services. Also updated logic to return if any one of systemctl command return failure and make sure syslog of feature getting enable/disable only come when all commads are sucessful. Moved the service list get api from sonic-util to sonic-py-common Signed-off-by: Abhishek Dosi * Make sure to retun None for both service list in case of error. Signed-off-by: Abhishek Dosi * Return empty list as fail condition Signed-off-by: Abhishek Dosi * Address Review Comments. Made init_cfg.json.j2 knowledegable of Feature service is global scope or per asic scope Signed-off-by: Abhishek Dosi * Fix merge conflict * Address Review Comment. Signed-off-by: Abhishek Dosi Co-authored-by: Abhishek Dosi --- files/build_templates/init_cfg.json.j2 | 2 + files/image_config/hostcfgd/hostcfgd | 104 +++++++++++++++---------- 2 files changed, 65 insertions(+), 41 deletions(-) diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 7126f2648d74..07ff9b1b3a72 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -39,6 +39,8 @@ "{{feature}}": { "state": "{{state}}", "has_timer" : {{has_timer | lower()}}, + "has_global_scope": {% if feature + '.service' in installer_services.split(' ') %}true{% else %}false{% endif %}, + "has_per_asic_scope": {% if feature + '@.service' in installer_services.split(' ') %}true{% else %}false{% endif %}, "auto_restart": "{{autorestart}}", "high_mem_alert": "disabled" }{% if not loop.last %},{% endif -%} diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 2c66598e3581..2b505ee5a0ee 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -10,6 +10,7 @@ import copy import jinja2 import ipaddr as ipaddress from swsssdk import ConfigDBConnector +from sonic_py_common import device_info # FILE PAM_AUTH_CONF = "/etc/pam.d/common-auth-sonic" @@ -42,45 +43,6 @@ def obfuscate(data): return data -def update_feature_state(feature_name, state, has_timer): - feature_suffixes = ["service"] + (["timer"] if ast.literal_eval(has_timer) else []) - if state == "enabled": - start_cmds = [] - for suffix in feature_suffixes: - start_cmds.append("sudo systemctl unmask {}.{}".format(feature_name, suffix)) - # If feature has timer associated with it, start/enable corresponding systemd .timer unit - # otherwise, start/enable corresponding systemd .service unit - start_cmds.append("sudo systemctl enable {}.{}".format(feature_name, feature_suffixes[-1])) - start_cmds.append("sudo systemctl start {}.{}".format(feature_name, feature_suffixes[-1])) - for cmd in start_cmds: - syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" - .format(err.cmd, err.returncode, err.output)) - continue - syslog.syslog(syslog.LOG_INFO, "Feature '{}.{}' is enabled and started" - .format(feature_name, feature_suffixes[-1])) - elif state == "disabled": - stop_cmds = [] - for suffix in reversed(feature_suffixes): - stop_cmds.append("sudo systemctl stop {}.{}".format(feature_name, suffix)) - stop_cmds.append("sudo systemctl disable {}.{}".format(feature_name, suffix)) - stop_cmds.append("sudo systemctl mask {}.{}".format(feature_name, suffix)) - for cmd in stop_cmds: - syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) - try: - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" - .format(err.cmd, err.returncode, err.output)) - continue - syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(feature_name)) - else: - syslog.syslog(syslog.LOG_ERR, "Unexpected state value '{}' for feature '{}'" - .format(state, feature_name)) - class Iptables(object): def __init__(self): @@ -279,6 +241,66 @@ class HostConfigDaemon: lpbk_table = self.config_db.get_table('LOOPBACK_INTERFACE') self.iptables = Iptables() self.iptables.load(lpbk_table) + self.is_multi_npu = device_info.is_multi_npu() + + def update_feature_state(self, feature_name, state, feature_table): + has_timer = ast.literal_eval(feature_table[feature_name].get('has_timer', 'False')) + has_global_scope = ast.literal_eval(feature_table[feature_name].get('has_global_scope', 'True')) + has_per_asic_scope = ast.literal_eval(feature_table[feature_name].get('has_per_asic_scope', 'False')) + + # Create feature name suffix depending feature is running in host or namespace or in both + feature_name_suffix_list = (([feature_name] if has_global_scope or not self.is_multi_npu else []) + + ([(feature_name + '@' + str(asic_inst)) for asic_inst in range(device_info.get_num_npus()) + if has_per_asic_scope and self.is_multi_npu])) + + if not feature_name_suffix_list: + syslog.syslog(syslog.LOG_ERR, "Feature '{}' service not available" + .format(feature_name)) + + feature_suffixes = ["service"] + (["timer"] if has_timer else []) + + if state == "enabled": + start_cmds = [] + for feature_name_suffix in feature_name_suffix_list: + for suffix in feature_suffixes: + start_cmds.append("sudo systemctl unmask {}.{}".format(feature_name_suffix, suffix)) + # If feature has timer associated with it, start/enable corresponding systemd .timer unit + # otherwise, start/enable corresponding systemd .service unit + start_cmds.append("sudo systemctl enable {}.{}".format(feature_name_suffix, feature_suffixes[-1])) + start_cmds.append("sudo systemctl start {}.{}".format(feature_name_suffix, feature_suffixes[-1])) + for cmd in start_cmds: + syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" + .format(err.cmd, err.returncode, err.output)) + syslog.syslog(syslog.LOG_ERR, "Feature '{}.{}' failed to be enabled and started" + .format(feature_name, feature_suffixes[-1])) + return + syslog.syslog(syslog.LOG_INFO, "Feature '{}.{}' is enabled and started" + .format(feature_name, feature_suffixes[-1])) + elif state == "disabled": + stop_cmds = [] + for feature_name_suffix in feature_name_suffix_list: + for suffix in reversed(feature_suffixes): + stop_cmds.append("sudo systemctl stop {}.{}".format(feature_name_suffix, suffix)) + stop_cmds.append("sudo systemctl disable {}.{}".format(feature_name_suffix, suffix)) + stop_cmds.append("sudo systemctl mask {}.{}".format(feature_name_suffix, suffix)) + for cmd in stop_cmds: + syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) + try: + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" + .format(err.cmd, err.returncode, err.output)) + syslog.syslog(syslog.LOG_ERR, "Feature '{}' failed to be stopped and disabled".format(feature_name)) + return + syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(feature_name)) + else: + syslog.syslog(syslog.LOG_ERR, "Unexpected state value '{}' for feature '{}'" + .format(state, feature_name)) + def update_all_feature_states(self): feature_table = self.config_db.get_table('FEATURE') @@ -292,7 +314,7 @@ class HostConfigDaemon: syslog.syslog(syslog.LOG_WARNING, "Eanble state of feature '{}' is None".format(feature_name)) continue - update_feature_state(feature_name, state, feature_table[feature_name].get('has_timer', 'False')) + self.update_feature_state(feature_name, state, feature_table) def aaa_handler(self, key, data): self.aaacfg.aaa_update(key, data) @@ -334,7 +356,7 @@ class HostConfigDaemon: syslog.syslog(syslog.LOG_WARNING, "Enable state of feature '{}' is None".format(feature_name)) return - update_feature_state(feature_name, state, feature_table[feature_name].get('has_timer', 'False')) + self.update_feature_state(feature_name, state, feature_table) def start(self): # Update all feature states once upon starting From c8277a4ebaacc35862fb3f390a2af9d1636cbd3b Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 23 Sep 2020 00:10:18 +0800 Subject: [PATCH 05/78] Update buffer configuration for SKUs based on SN3800 (#5320) C64: 32 100G down links and 32 100G up links. D112C8: 112 50G down links and 8 100G up links. D24C52: 24 50G down links, 20 100G down links, and 32 100G up links. D28C50: 28 50G down links, 18 100G down links, and 32 100G up links. Signed-off-by: Stephen Sun --- .../buffers_defaults_t0.j2 | 99 ++++++++++++++++++- .../buffers_defaults_t1.j2 | 99 ++++++++++++++++++- .../buffers_defaults_t0.j2 | 4 +- .../buffers_defaults_t1.j2 | 4 +- .../buffers_defaults_t0.j2 | 99 ++++++++++++++++++- .../buffers_defaults_t1.j2 | 99 ++++++++++++++++++- .../buffers_defaults_t0.j2 | 99 ++++++++++++++++++- .../buffers_defaults_t1.j2 | 99 ++++++++++++++++++- 8 files changed, 592 insertions(+), 10 deletions(-) mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 deleted file mode 120000 index 53fa14be9027..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 +++ /dev/null @@ -1 +0,0 @@ -../Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..33c89f0e8e75 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t0.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '23343104' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '23343104' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 deleted file mode 120000 index ad442959ddca..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 +++ /dev/null @@ -1 +0,0 @@ -../Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..3347e2abffa5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-C64/buffers_defaults_t1.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '19410944' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '19410944' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 index 5296eb8ede88..009f1d5ef5cc 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 @@ -1,7 +1,7 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '28856320' %} +{% set ingress_lossless_pool_size = '16576512' %} {% set egress_lossless_pool_size = '34287552' %} -{% set egress_lossy_pool_size = '28856320' %} +{% set egress_lossy_pool_size = '16576512' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 index 95b119a59f97..ae340eb2e6e2 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 @@ -1,7 +1,7 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '27586560' %} +{% set ingress_lossless_pool_size = '14790656' %} {% set egress_lossless_pool_size = '34287552' %} -{% set egress_lossy_pool_size = '27586560' %} +{% set egress_lossy_pool_size = '14790656' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 deleted file mode 120000 index 53fa14be9027..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 +++ /dev/null @@ -1 +0,0 @@ -../Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..3edc53505912 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t0.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '21819392' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '21819392' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 deleted file mode 120000 index ad442959ddca..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 +++ /dev/null @@ -1 +0,0 @@ -../Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c946d5ae9631 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/buffers_defaults_t1.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '17862656' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '17862656' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 deleted file mode 120000 index 53fa14be9027..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 +++ /dev/null @@ -1 +0,0 @@ -../Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..19df7a7e066f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t0.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '21565440' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '21565440' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 deleted file mode 120000 index ad442959ddca..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 +++ /dev/null @@ -1 +0,0 @@ -../Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..40768657a4e4 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/buffers_defaults_t1.j2 @@ -0,0 +1,98 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '17604608' %} +{% set egress_lossless_pool_size = '34287552' %} +{% set egress_lossy_pool_size = '17604608' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"9216", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} From 9feba88455d39f823b16c47390e98550f4c1d31d Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Tue, 22 Sep 2020 09:37:03 -0700 Subject: [PATCH 06/78] [mgmt] Fix Azure CLI install behind proxy (#5407) Signed-off-by: Danny Allen --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index f5c650c8daf7..59a237b2cb22 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -97,6 +97,9 @@ RUN apt-get update \ && apt-get update \ && apt-get install -y docker-ce-cli +# Install Azure CLI +RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash + # Install Microsoft Azure Kusto Library for Python RUN pip install azure-kusto-data==0.0.13 \ azure-kusto-ingest==0.0.13 @@ -154,10 +157,10 @@ RUN chmod go= /var/$user/.ssh -R RUN echo "$user ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers USER $user - -# Install Azure CLI WORKDIR /var/$user -RUN curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash + +# Add az symlink for backwards compatibility +RUN mkdir bin && ln -s /usr/bin/az bin/az # Install Virtual Environments RUN python -m virtualenv --system-site-packages env-201811 From a6a10f05b7322f03eb3b19b3dcac8f3149343cf2 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Tue, 22 Sep 2020 11:21:12 -0700 Subject: [PATCH 07/78] In SAI 3.5 by default we are supporting 256 Group with 64 Memeber each. (#5400) However in SAI 3.7 default behaviout got changes to 128 Group and 128 Memeber each. This change is to make sure we are using same ECMP Group/Memeber Per Group for 3.7 also so that behaviour is consistent. Signed-off-by: Abhishek Dosi --- .../x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile | 1 + .../x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile | 1 + .../x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile | 1 + .../x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile | 1 + .../x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile | 1 + .../x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile | 1 + .../x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile | 1 + .../Accton-AS7312-54XS/sai.profile | 1 + .../Accton-AS7315-27XB/sai.profile | 1 + .../x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile | 1 + .../x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile | 1 + .../x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile | 1 + .../Accton-AS7716-32XB/sai.profile | 1 + .../x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile | 1 + .../x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile | 1 + .../x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile | 3 ++- .../Alphanetworks-SNH60A0-320FV2/sai.profile | 1 + .../Alphanetworks-SNH60B0-640F/sai.profile | 1 + .../x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile | 1 + .../Arista-7050QX-32S-S4Q31/sai.profile | 1 + .../Arista-7050CX3-32S-C32/sai.profile | 1 + .../x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile | 1 + .../Arista-7060CX-32S-D48C8/sai.profile | 1 + .../Arista-7060CX-32S-Q24C8/sai.profile | 1 + .../Arista-7060CX-32S-Q32/sai.profile.j2 | 1 + .../Arista-7060CX-32S-T96C8/sai.profile | 1 + .../x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile | 1 + .../x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile | 1 + .../x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile | 1 + .../x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile | 1 + .../x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile | 1 + .../x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile | 1 + .../Arista-7280CR3-C28S8/sai.profile | 1 + .../x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile | 1 + device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile | 1 + .../x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile | 1 + .../x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 | 1 + .../x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile | 1 + .../celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile | 1 + .../x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile | 1 + .../x86_64-cel_silverstone-r0/Silverstone/sai.profile | 1 + .../x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 | 1 + .../x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile | 1 + .../x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile | 1 + .../DellEMC-S5232f-C32/sai.profile | 1 + .../DellEMC-S5232f-C8D48/sai.profile | 1 + .../DellEMC-S5232f-P-100G/sai.profile | 1 + .../DellEMC-S5232f-P-10G/sai.profile | 1 + .../DellEMC-S5232f-P-25G/sai.profile | 1 + .../DellEMC-S5248f-P-10G/sai.profile | 1 + .../DellEMC-S5248f-P-25G/sai.profile | 1 + .../DellEMC-Z9264f-C64/sai.profile | 1 + .../DellEMC-Z9264f-C8D112/sai.profile | 1 + .../DellEMC-Z9264f-Q64/sai.profile.j2 | 1 + .../DellEMC-Z9332f-C32/sai.profile | 1 + .../DellEMC-Z9332f-O32/sai.profile | 1 + device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile | 1 + .../delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile | 1 + .../x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile | 1 + device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile | 1 + device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile | 1 + .../x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile | 1 + .../x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile | 1 + .../INGRASYS-S8810-32Q/sai.profile | 1 + .../INGRASYS-S8900-54XC/sai.profile | 1 + .../INGRASYS-S8900-64XC/sai.profile | 1 + .../x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile | 1 + .../INGRASYS-S9200-64X/sai.profile | 1 + .../Juniper-QFX5200-32C-S/sai.profile | 1 + .../x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile | 1 + .../MiTAC-LY1200-B32H0-C3/sai.profile | 1 + .../x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile | 1 + .../x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile | 1 + .../x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile | 1 + .../x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile | 1 + .../x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile | 1 + 76 files changed, 77 insertions(+), 1 deletion(-) diff --git a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile index aec436d22608..9020d35fda23 100755 --- a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile +++ b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as5712-72x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile index dc4f243953bf..3c78aab15dcb 100644 --- a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile +++ b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as5812t-72x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile index 063814c1fcb3..0ec3aa1896cf 100755 --- a/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile +++ b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as5812-72x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile index 44dc691640be..124811980e70 100755 --- a/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile +++ b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/sai.profile @@ -1,2 +1,3 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/mv2-as5835t-48x10G+6x100G.config.bcm SAI_BOARD_CONFIG_PATH=/etc/accton +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile b/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile index 8b795f81c4f2..744c6571f7c7 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile +++ b/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/etc/bcm/mv2-as5835-48x10G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile b/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile index 22432e548b4a..6f2a70f146ca 100644 --- a/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile +++ b/device/accton/x86_64-accton_as6712_32x-r0/Accton-AS6712-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as6712-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile b/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile index 31aefe2c2905..54cdc34801dd 100644 --- a/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile +++ b/device/accton/x86_64-accton_as7312_54x-r0/Accton-AS7312-54X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7312-48x25G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/sai.profile b/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/sai.profile index 31aefe2c2905..54cdc34801dd 100644 --- a/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/sai.profile +++ b/device/accton/x86_64-accton_as7312_54xs-r0/Accton-AS7312-54XS/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7312-48x25G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/sai.profile b/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/sai.profile index 191b27dac2f8..551599b5eba9 100644 --- a/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/sai.profile +++ b/device/accton/x86_64-accton_as7315_27xb-r0/Accton-AS7315-27XB/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/qax-as7315-20x10G+4x25G+3x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile index 47e3107477a2..eb932199dfab 100755 --- a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile +++ b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7326-48x25G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile b/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile index 28953a08f205..6e4d11fb7292 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile +++ b/device/accton/x86_64-accton_as7712_32x-r0/Accton-AS7712-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7712-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile b/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile index 65944732653c..794c15a5c95a 100644 --- a/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile +++ b/device/accton/x86_64-accton_as7716_32x-r0/Accton-AS7716-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7716-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/sai.profile b/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/sai.profile index 65944732653c..794c15a5c95a 100755 --- a/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/sai.profile +++ b/device/accton/x86_64-accton_as7716_32xb-r0/Accton-AS7716-32XB/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-as7716-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 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 461cdd76c4d5..276f982e3e3d 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,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7726-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile index 30fc08adde62..7c7d74d3ce9e 100644 --- a/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile +++ b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-as7816-64x25G-48x100G_row1.config.bcm +SAI_NUM_ECMP_MEMBERS=64 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 b366aeaa93c9..60f0d4b11d63 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,2 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-as9716-32x400G.config.bcm \ No newline at end of file +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-as9716-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/Alphanetworks-SNH60A0-320FV2/sai.profile b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/Alphanetworks-SNH60A0-320FV2/sai.profile index b6e792ad0a18..66d99a8450c3 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/Alphanetworks-SNH60A0-320FV2/sai.profile +++ b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/Alphanetworks-SNH60A0-320FV2/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-snh60a0-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/Alphanetworks-SNH60B0-640F/sai.profile b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/Alphanetworks-SNH60B0-640F/sai.profile index 04555733c028..0abb91695d5d 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/Alphanetworks-SNH60B0-640F/sai.profile +++ b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/Alphanetworks-SNH60B0-640F/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-snh60b0-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile index 6479c4c14d3f..cbaa8cdfd51a 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-a7050-qx32s-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile index 9a50433cabdc..0be2fc5e0f45 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-a7050-q31s4-31x40G-4x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile index d359ffc15cba..7d96f190de73 100644 --- a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-a7050cx3-32s-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile index 4f8c558b0885..66f88f894c30 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-32x100G-t1.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile index 87b4ffdadd6d..692f79decc1f 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-8x100G+48x50G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/sai.profile b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/sai.profile index 42e0c57347a2..08abf1198948 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/sai.profile +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-8x100G+24x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 index 638fd28b0765..e2ad59262cdd 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 @@ -11,3 +11,4 @@ {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/sai.profile b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/sai.profile index d54a263e72b6..f9a1e2bdc4d6 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/sai.profile +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-T96C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-8x100G+96x25G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile index 8f820cb0f066..9d051624c589 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-a7060px4-32-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile index 2163c4be9057..c9a6b4d330ce 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-a7060px4-o32-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile index 74aea949c3b7..2607bef50850 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-a7260cx3-64-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile index 235f2423df82..166f5c5b6e1a 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-a7260cx3-64-112x50G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile index db64a26b47da..a89cba46c3d1 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-a7260cx3-64-64x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile index bf99bb0ad4d2..17ef703d798d 100644 --- a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile +++ b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32d4-40x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile index 7e699b10430e..f0554cdb874f 100644 --- a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile index 130a3f8c4cbd..ac1394486c61 100644 --- a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32p4-40x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile b/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile index e80e0d4c89b0..9e6a31e3d1e9 100644 --- a/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile +++ b/device/broadcom/x86_64-bcm_xlr-r0/BCM956960K/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th_32x100.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile b/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile index f467f997fe62..a98bdc993e73 100644 --- a/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile +++ b/device/celestica/x86_64-cel_e1031-r0/Celestica-E1031-T48S4/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/helix4-e1031-48x1G+4x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 index abc2daefd04e..21bf6cd6e737 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 @@ -11,3 +11,4 @@ {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile index 46d96b2fd905..50220639519c 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-seastone-dx010-48x50G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile index ea150bf237c3..b57101d114f0 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-seastone_2-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile index bc7681f0272f..483e85c0c1fa 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-128x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile index 1915eb9b35a1..550bfe181df4 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 index df3cbb558294..d2c794277098 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 @@ -11,3 +11,4 @@ {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile index a690c3ff8b94..1076ddfe28f4 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-z9100-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile index 182624c19bd4..b277ae5f0bde 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-z9100-8x100G-48x50G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai.profile index e5362a7aef00..3491c7700c24 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai.profile +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 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 index 0daed30c3bc2..b9703d137bb9 100644 --- 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 @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-8x100G+48x50G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai.profile index e5362a7aef00..3491c7700c24 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai.profile +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai.profile index 947af7ebacc3..166a0fa8c8bc 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai.profile +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-96x10G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai.profile b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai.profile index ae09492f0e76..0c5cf8ca671a 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai.profile +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-96x25G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile index 52afc687173c..72f420de5d40 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5248f-10g.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile index 4753ec3886c4..eb9a3cb196fe 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5248f-25g.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile index 0a4fed041752..c6e99b771db6 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile index 7bf21827cd19..a6a351387d56 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-8x100G-112x50G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 index 66859a473733..bfb71fa71e3c 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 @@ -11,3 +11,4 @@ {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile index 1c58f69c7e03..bdc55873e429 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-z9332f-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile index 19cd5cb02839..26867a291b00 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-z9332f-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile b/device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile index 094e2d2cda01..98876a9c2a39 100644 --- a/device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile +++ b/device/delta/x86_64-delta_ag5648-r0/Delta-ag5648/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-ag5648-48x25G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile b/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile index c77b2bf79a34..a1ec3ca258df 100644 --- a/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile +++ b/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-ag9032v1-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile index f0eccb028258..0d3c85f8f38a 100644 --- a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile +++ b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ag9032v2a-32x100G+1x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile index 21f013773e61..2fc46808b555 100644 --- a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile +++ b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-ag9064-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile index 9d3f2cccc2da..2da82c5bffa5 100644 --- a/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile +++ b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-agc032-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/delta/x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile b/device/delta/x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile index 726e1b6dc667..20e067d8eda7 100644 --- a/device/delta/x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile +++ b/device/delta/x86_64-delta_et-6248brb-r0/Delta-et-6248brb/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/etc/bcm/helix4-et-6248brb-48x1G+2x10G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/facebook/x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile b/device/facebook/x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile index b5586b7ba24c..426284150a0d 100644 --- a/device/facebook/x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile +++ b/device/facebook/x86_64-facebook_wedge100-r0/Facebook-W100-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-wedge100-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/INGRASYS-S8810-32Q/sai.profile b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/INGRASYS-S8810-32Q/sai.profile index 42315ee4ea6a..3205cd2d6ad9 100644 --- a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/INGRASYS-S8810-32Q/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/INGRASYS-S8810-32Q/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s8810-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/sai.profile b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/sai.profile index 29db3ecd1624..607f20f329a6 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-s8900-48x25G+6x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/sai.profile b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/sai.profile index 77a0e3efa431..1100f7199a3e 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-s8900-48x25G+16x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile b/device/ingrasys/x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile index 14a36af5f554..11c0ae1ab636 100644 --- a/device/ingrasys/x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s9100-r0/INGRASYS-S9100-C32/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-s9100-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile index 5404ca338ffd..d16307aa360d 100644 --- a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-s9200-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile index 4bcf21c09c41..9852552d899e 100644 --- a/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-qfx5200-32x100g.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile index dca8c2f68c04..768a7fa47ad4 100644 --- a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-qfx5210-64x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/sai.profile b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/sai.profile index a58c3ac6eabf..c32774b9677c 100644 --- a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/sai.profile +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-ly1200-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile index fbd01105a4f3..219465108df8 100755 --- a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile +++ b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/Quanta-IX1B-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-ix1b-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile index 8088d09edc12..367f18e369fa 100644 --- a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile +++ b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ix7-32x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile index faf28ace4c10..62ee26ea8c15 100644 --- a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile +++ b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ix8-48x25G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile index 04b43d5a4d33..936f0d0cddcf 100644 --- a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile +++ b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-ix8c-48x25G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile index 54b62b1d097c..70397851c909 100644 --- a/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile @@ -1 +1,2 @@ SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-ix9-32x400G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 From a0afe2fc1608a0b352352bb4389b90921ba56c55 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Wed, 23 Sep 2020 03:57:32 +0530 Subject: [PATCH 08/78] Dell S6100 fix mux issue (#5414) - Why I did it For fixing PCA MUX attachment issue in Dell S6100 platform. - How I did it Wait till IOM MUX powered up properly and start I2C enumeration. --- .../common/dell_pmc.c | 34 +++++++++++++++ .../s6100/scripts/iom_power_off.sh | 18 ++++---- .../s6100/scripts/iom_power_on.sh | 2 + .../s6100/scripts/s6100_i2c_enumeration.sh | 43 ++++++++++++++++++- 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c index da4f451700eb..8206f20a1867 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c @@ -174,6 +174,12 @@ /* Mailbox PowerOn Reason */ #define TRACK_POWERON_REASON 0x05FF +/* CPU Set IO Modules */ +#define CPU_IOM1_CTRL_FLAG 0x04D9 +#define CPU_IOM2_CTRL_FLAG 0x04DA +#define CPU_IOM3_CTRL_FLAG 0x04DB +#define CPU_IOM4_CTRL_FLAG 0x04DC + unsigned long *mmio; static struct kobject *dell_kobj; @@ -752,6 +758,25 @@ static ssize_t show_psu_fan(struct device *dev, return sprintf(buf, "%d\n", ret); } +static ssize_t show_cpu_iom_control(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int cpu_iom_status; + + if(index == 0) + cpu_iom_status = smf_read_reg(data, CPU_IOM1_CTRL_FLAG); + else if (index == 1) + cpu_iom_status = smf_read_reg(data, CPU_IOM2_CTRL_FLAG); + else if (index == 2) + cpu_iom_status = smf_read_reg(data, CPU_IOM3_CTRL_FLAG); + else if (index == 3) + cpu_iom_status = smf_read_reg(data, CPU_IOM4_CTRL_FLAG); + + return sprintf(buf, "%x\n", cpu_iom_status); +} + static umode_t smf_fanin_is_visible(struct kobject *kobj, @@ -2033,6 +2058,11 @@ static SENSOR_DEVICE_ATTR(fan9_serialno, S_IRUGO, show_ppid, NULL, 4); static SENSOR_DEVICE_ATTR(iom_status, S_IRUGO, show_voltage, NULL, 44); static SENSOR_DEVICE_ATTR(iom_presence, S_IRUGO, show_voltage, NULL, 45); +static SENSOR_DEVICE_ATTR(cpu_iom1_control, S_IRUGO, show_cpu_iom_control, NULL, 0); +static SENSOR_DEVICE_ATTR(cpu_iom2_control, S_IRUGO, show_cpu_iom_control, NULL, 1); +static SENSOR_DEVICE_ATTR(cpu_iom3_control, S_IRUGO, show_cpu_iom_control, NULL, 2); +static SENSOR_DEVICE_ATTR(cpu_iom4_control, S_IRUGO, show_cpu_iom_control, NULL, 3); + static SENSOR_DEVICE_ATTR(psu1_presence, S_IRUGO, show_psu, NULL, 1); static SENSOR_DEVICE_ATTR(psu2_presence, S_IRUGO, show_psu, NULL, 6); static SENSOR_DEVICE_ATTR(psu1_serialno, S_IRUGO, show_ppid, NULL, 10); @@ -2082,6 +2112,10 @@ static struct attribute *smf_dell_attrs[] = { &sensor_dev_attr_fan7_serialno.dev_attr.attr, &sensor_dev_attr_fan9_serialno.dev_attr.attr, &sensor_dev_attr_current_total_power.dev_attr.attr, + &sensor_dev_attr_cpu_iom1_control.dev_attr.attr, + &sensor_dev_attr_cpu_iom2_control.dev_attr.attr, + &sensor_dev_attr_cpu_iom3_control.dev_attr.attr, + &sensor_dev_attr_cpu_iom4_control.dev_attr.attr, NULL }; diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh index a7671cfe589c..077d760fdfc0 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh @@ -2,15 +2,15 @@ #This script is used to power off IO modules # IOM can be controlled via SMF using mailbox registers # write 0x2 to 0x04D9 to power off IOM 1 -./io_rd_wr.py --set --val 0x04 --offset 0x210 -./io_rd_wr.py --set --val 0xd9 --offset 0x211 -./io_rd_wr.py --set --val 0x2 --offset 0x213 +io_rd_wr.py --set --val 0x04 --offset 0x210 +io_rd_wr.py --set --val 0xd9 --offset 0x211 +io_rd_wr.py --set --val 0x2 --offset 0x213 # write 0x2 to 0x04DA to power off IOM 2 -./io_rd_wr.py --set --val 0xda --offset 0x211 -./io_rd_wr.py --set --val 0x2 --offset 0x213 +io_rd_wr.py --set --val 0xda --offset 0x211 +io_rd_wr.py --set --val 0x2 --offset 0x213 # write 0x2 to 0x04DB to power off IOM 3 -./io_rd_wr.py --set --val 0xdb --offset 0x211 -./io_rd_wr.py --set --val 0x2 --offset 0x213 +io_rd_wr.py --set --val 0xdb --offset 0x211 +io_rd_wr.py --set --val 0x2 --offset 0x213 # write 0x2 to 0x04DC to power off IOM 4 -./io_rd_wr.py --set --val 0xdc --offset 0x211 -./io_rd_wr.py --set --val 0x2 --offset 0x213 +io_rd_wr.py --set --val 0xdc --offset 0x211 +io_rd_wr.py --set --val 0x2 --offset 0x213 diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh index 3d31170803e1..80b876c216ec 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh @@ -15,3 +15,5 @@ # write 0x1 to 0x04DC to power up IOM 4 /usr/local/bin/io_rd_wr.py --set --val 0xdc --offset 0x211 /usr/local/bin/io_rd_wr.py --set --val 0x1 --offset 0x213 +#Delay for SMF to power on IOMs +sleep 3 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 af91f378339e..d00fec233eaa 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 @@ -239,17 +239,58 @@ reset_muxes() { init_devnum +check_iom_status() +{ + SMF_DIR="/sys/devices/platform/SMF.512/hwmon/*" + count=0 + iom_sta=0 + MAX_IOM_STARTUP_DELAY=50 + + if [ -d $SMF_DIR ]; then + iom_status=$(cat $SMF_DIR/iom_status) + cpu_iom1_sta=$(cat $SMF_DIR/cpu_iom1_control) + cpu_iom2_sta=$(cat $SMF_DIR/cpu_iom2_control) + cpu_iom3_sta=$(cat $SMF_DIR/cpu_iom3_control) + cpu_iom4_sta=$(cat $SMF_DIR/cpu_iom4_control) + cpu_iom_sta=$(( cpu_iom1_sta|cpu_iom2_sta|cpu_iom3_sta|cpu_iom4_sta )) + echo "Started polling IOM status" + while [ "$iom_status" != "f0" -o "$cpu_iom_sta" != "0" ]; + do + if [ "$count" -gt "$MAX_IOM_STARTUP_DELAY" ];then + echo "IOM is taking longer than expected to power up.Aborting. + iom_status- $iom_status cpu_iom_sta1- $cpu_iom1_sta cpu_iom_sta2- $cpu_iom2_sta + cpu_iom_sta3- $cpu_iom3_sta cpu_iom_sta4- $cpu_iom4_sta " + iom_sta=1 + break + fi + cpu_iom1_sta=$(cat $SMF_DIR/cpu_iom1_control) + cpu_iom2_sta=$(cat $SMF_DIR/cpu_iom2_control) + cpu_iom3_sta=$(cat $SMF_DIR/cpu_iom3_control) + cpu_iom4_sta=$(cat $SMF_DIR/cpu_iom4_control) + cpu_iom_sta=$(( cpu_iom1_sta|cpu_iom2_sta|cpu_iom3_sta|cpu_iom4_sta )) + iom_status=$(cat $SMF_DIR/iom_status) + sleep .1 + count=`expr $count + 1` + done + + if [ "$iom_sta" != "1" ];then + echo "All IOM's are UP" + fi + fi +} + if [[ "$1" == "init" ]]; then cpu_board_mux "new_device" switch_board_mux "new_device" sys_eeprom "new_device" switch_board_eeprom "new_device" switch_board_cpld "new_device" - /usr/local/bin/s6100_bitbang_reset.sh + check_iom_status switch_board_qsfp_mux "new_device" switch_board_sfp "new_device" switch_board_qsfp "new_device" switch_board_qsfp_lpmode "disable" + /usr/local/bin/s6100_bitbang_reset.sh xcvr_presence_interrupts "enable" elif [[ "$1" == "deinit" ]]; then xcvr_presence_interrupts "disable" From f2194010f8765ebf863d2d7cc92bdabdf0476465 Mon Sep 17 00:00:00 2001 From: vdahiya12 <67608553+vdahiya12@users.noreply.github.com> Date: Tue, 22 Sep 2020 17:12:51 -0700 Subject: [PATCH 09/78] [MSN2700] Add platform.json file containing platform hardware facts (#5189) As part of Platform api testing for multiple platforms, this pull request adds a platform.json file which contains all the static data for Mellanox-2700 platform. This file would provide all the platform specific data required for testing of all the Platform tests . As part of testing the API's the values of static/default objects within this specific platform file will be compared against the values returned by calling the Platform specific API's in a typical platform test --- .../x86_64-mlnx_msn2700-r0/platform.json | 311 ++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/platform.json diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/platform.json b/device/mellanox/x86_64-mlnx_msn2700-r0/platform.json new file mode 100644 index 000000000000..cdb3e52fd682 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/platform.json @@ -0,0 +1,311 @@ +{ + "chassis": { + "name": "MSN2700", + "components": [ + { + "name": "ONIE" + }, + { + "name": "SSD" + }, + { + "name": "BIOS" + }, + { + "name": "CPLD1" + }, + { + "name": "CPLD2" + }, + { + "name": "CPLD3" + } + ], + "fans": [], + "fan_drawers": [ + { + "name": "drawer1", + "fans": [ + { + "name": "fan1" + }, + { + "name": "fan2" + } + ] + }, + { + "name": "drawer2", + "fans": [ + { + "name": "fan3" + }, + { + "name": "fan4" + } + ] + }, + { + "name": "drawer3", + "fans": [ + { + "name": "fan5" + }, + { + "name": "fan6" + } + ] + }, + { + "name": "drawer4", + "fans": [ + { + "name": "fan7" + }, + { + "name": "fan8" + } + ] + } + ], + "psus": [ + { + "name": "PSU 1", + "fans": [ + { + "name": "psu_1_fan_1" + } + ] + }, + { + "name": "PSU 2", + "fans": [ + { + "name": "psu_2_fan_1" + } + ] + } + ], + "thermals": [ + { + "name": "ASIC" + }, + { + "name": "Ambient Fan Side Temp" + }, + { + "name": "Ambient Port Side Temp" + }, + { + "name": "CPU Core 0 Temp" + }, + { + "name": "CPU Core 1 Temp" + }, + { + "name": "CPU Pack Temp" + }, + { + "name": "PSU-1 Temp" + }, + { + "name": "PSU-2 Temp" + }, + { + "name": "xSFP module 1 Temp" + }, + { + "name": "xSFP module 2 Temp" + }, + { + "name": "xSFP module 3 Temp" + }, + { + "name": "xSFP module 4 Temp" + }, + { + "name": "xSFP module 5 Temp" + }, + { + "name": "xSFP module 6 Temp" + }, + { + "name": "xSFP module 7 Temp" + }, + { + "name": "xSFP module 8 Temp" + }, + { + "name": "xSFP module 9 Temp" + }, + { + "name": "xSFP module 10 Temp" + }, + { + "name": "xSFP module 11 Temp" + }, + { + "name": "xSFP module 12 Temp" + }, + { + "name": "xSFP module 13 Temp" + }, + { + "name": "xSFP module 14 Temp" + }, + { + "name": "xSFP module 15 Temp" + }, + { + "name": "xSFP module 16 Temp" + }, + { + "name": "xSFP module 17 Temp" + }, + { + "name": "xSFP module 18 Temp" + }, + { + "name": "xSFP module 19 Temp" + }, + { + "name": "xSFP module 20 Temp" + }, + { + "name": "xSFP module 21 Temp" + }, + { + "name": "xSFP module 22 Temp" + }, + { + "name": "xSFP module 23 Temp" + }, + { + "name": "xSFP module 24 Temp" + }, + { + "name": "xSFP module 25 Temp" + }, + { + "name": "xSFP module 26 Temp" + }, + { + "name": "xSFP module 27 Temp" + }, + { + "name": "xSFP module 28 Temp" + }, + { + "name": "xSFP module 29 Temp" + }, + { + "name": "xSFP module 30 Temp" + }, + { + "name": "xSFP module 31 Temp" + }, + { + "name": "xSFP module 32 Temp" + } + ], + "sfps": [ + { + "name": "sfp1" + }, + { + "name": "sfp2" + }, + { + "name": "sfp3" + }, + { + "name": "sfp4" + }, + { + "name": "sfp5" + }, + { + "name": "sfp6" + }, + { + "name": "sfp7" + }, + { + "name": "sfp8" + }, + { + "name": "sfp9" + }, + { + "name": "sfp10" + }, + { + "name": "sfp11" + }, + { + "name": "sfp12" + }, + { + "name": "sfp13" + }, + { + "name": "sfp14" + }, + { + "name": "sfp15" + }, + { + "name": "sfp16" + }, + { + "name": "sfp17" + }, + { + "name": "sfp18" + }, + { + "name": "sfp19" + }, + { + "name": "sfp20" + }, + { + "name": "sfp21" + }, + { + "name": "sfp22" + }, + { + "name": "sfp23" + }, + { + "name": "sfp24" + }, + { + "name": "sfp25" + }, + { + "name": "sfp26" + }, + { + "name": "sfp27" + }, + { + "name": "sfp28" + }, + { + "name": "sfp29" + }, + { + "name": "sfp30" + }, + { + "name": "sfp31" + }, + { + "name": "sfp32" + } + ] + }, + "interfaces": {} +} From 7eda531ffd512d1cb8e21f7a509a28601c3fd48e Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Tue, 22 Sep 2020 18:39:14 -0700 Subject: [PATCH 10/78] [mgmt] Install ip command in mgmt docker (#5430) Signed-off-by: Danny Allen --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 59a237b2cb22..c4d43c56c0b7 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -9,6 +9,7 @@ RUN apt-get update && apt-get install -y build-essential \ gcc \ git \ inetutils-ping \ + iproute2 \ libffi-dev \ libssl-dev \ libxml2 \ From 12d56adbfab24b49301224ea5d3b3803834fee40 Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Wed, 23 Sep 2020 16:47:10 +0200 Subject: [PATCH 11/78] [docker-sonic-vs]: Add libzmq5 to docker-sonic-vs (#5431) libzmq5 is tcp/ipc communication library, needed by sairedis/syncd to communicate, as a new way (compared to current REDIS channel) to exchange messages which is faster than REDIS library and allows synchronous mode this library is required in sairedis repo, swss repo, sonic-buildimage and sonic-build-tools to make it work --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 96d006883bd2..55c68a049ae1 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -47,7 +47,8 @@ RUN apt-get install -y net-tools \ iptables \ python3-pip \ jq \ - python-m2crypto + python-m2crypto \ + libzmq5 # install redis-server RUN curl -o redis-tools_6.0.6-1~bpo10+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/redis/redis-tools_6.0.6-1~bpo10+1_amd64.deb?sv=2015-04-05&sr=b&sig=73zbmjkf3pi%2Bn0R8Hy7CWT2EUvOAyzM5aLYJWCLySGM%3D&se=2030-09-06T19%3A44%3A59Z&sp=r" From 0483255e8231714055d41ca18103f24c42226cfc Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 23 Sep 2020 08:07:09 -0700 Subject: [PATCH 12/78] Fix the build issue when port2cable lenth define in (#5437) buffer_default_*.j2 because of which internal cable length never gets define and cause failure in test case test_multinpu_cfggen.py Signed-off-by: Abhishek Dosi Co-authored-by: Abhishek Dosi --- files/build_templates/buffers_config.j2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index f8733ed8e587..0eb976599a53 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -34,7 +34,6 @@ def {%- else %} {%- set ports2cable = { 'torrouter_server' : '5m', - 'internal' : '5m', 'leafrouter_torrouter' : '40m', 'spinerouter_leafrouter' : '300m' } @@ -50,6 +49,9 @@ def {%- set neighbor_role = neighbor.type %} {%- if 'asic' == neighbor_role | lower %} {%- set roles1 = 'internal' %} + {%- if 'internal' not in ports2cable %} + {%- set _ = ports2cable.update({'internal': '5m'}) %} + {%- endif -%} {%- else %} {%- set roles1 = switch_role + '_' + neighbor_role %} {%- set roles2 = neighbor_role + '_' + switch_role %} From 04c709d27fbc59880454519da357f1cf23409cf5 Mon Sep 17 00:00:00 2001 From: gechiang <62408185+gechiang@users.noreply.github.com> Date: Wed, 23 Sep 2020 09:40:49 -0700 Subject: [PATCH 13/78] Fix bgpmon.py packaging issue for console_scripts entry point (#5436) * Fix bgpmon.py packaging issue for console_scripts entry point * renamed directory from bgpmon_proj to bgpmon --- src/sonic-bgpcfgd/bgpmon/__init__.py | 0 src/sonic-bgpcfgd/{ => bgpmon}/bgpmon.py | 0 src/sonic-bgpcfgd/setup.py | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 src/sonic-bgpcfgd/bgpmon/__init__.py rename src/sonic-bgpcfgd/{ => bgpmon}/bgpmon.py (100%) diff --git a/src/sonic-bgpcfgd/bgpmon/__init__.py b/src/sonic-bgpcfgd/bgpmon/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-bgpcfgd/bgpmon.py b/src/sonic-bgpcfgd/bgpmon/bgpmon.py similarity index 100% rename from src/sonic-bgpcfgd/bgpmon.py rename to src/sonic-bgpcfgd/bgpmon/bgpmon.py diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index 2f485592c712..29d441e09a66 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -12,7 +12,7 @@ scripts=['bgpcfgd'], entry_points={ 'console_scripts': [ - 'bgpmon = bgpmon:main', + 'bgpmon = bgpmon.bgpmon:main', ] }, install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], From 418e437d793d841c6238d9ff0dff155b54b6ccdd Mon Sep 17 00:00:00 2001 From: Venkatesan Mahalingam <34145258+venkatmahalingam@users.noreply.github.com> Date: Wed, 23 Sep 2020 09:55:09 -0700 Subject: [PATCH 14/78] [caclmgrd] Add support to allow/deny any IP/IPv6 protocol packets coming to CPU based on source IP (#4591) Add support to allow/deny packets coming to CPU based on source IP, regardless of destination port --- files/image_config/caclmgrd/caclmgrd | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index ed6064b9696f..d7951677bee1 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -68,6 +68,10 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): "SSH": { "ip_protocols": ["tcp"], "dst_ports": ["22"] + }, + "ANY": { + "ip_protocols": ["any"], + "dst_ports": ["0"] } } @@ -375,14 +379,19 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): for ip_protocol in ip_protocols: for dst_port in dst_ports: rule_cmd = "ip6tables" if table_ip_version == 6 else "iptables" - rule_cmd += " -A INPUT -p {}".format(ip_protocol) + rule_cmd += " -A INPUT" + if ip_protocol != "any": + rule_cmd += " -p {}".format(ip_protocol) + if "SRC_IPV6" in rule_props and rule_props["SRC_IPV6"]: rule_cmd += " -s {}".format(rule_props["SRC_IPV6"]) elif "SRC_IP" in rule_props and rule_props["SRC_IP"]: rule_cmd += " -s {}".format(rule_props["SRC_IP"]) - rule_cmd += " --dport {}".format(dst_port) + # Destination port 0 is reserved/unused port, so, using it to apply the rule to all ports. + if dst_port != "0": + rule_cmd += " --dport {}".format(dst_port) # If there are TCP flags present and ip protocol is TCP, append them if ip_protocol == "tcp" and "TCP_FLAGS" in rule_props and rule_props["TCP_FLAGS"]: From ec9281be7656793bcc3cc2f1b5e077c592ea4704 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 23 Sep 2020 19:24:59 -0700 Subject: [PATCH 15/78] [sonic-platform-common][sonic-platform-daemons][sonic-snmpagent][sonic-utilities] Update submodules (#5435) Update Python-based submodules to include updated dependencies in setup.py files. * src/sonic-platform-common 14c6e53...7255d3a (2): > [setup.py] Update dependenices (#120) > [sfputilbase|sfputilhelper] fix value unpack error due to port_alias_asic_map in portconfig.py file (#116) * src/sonic-platform-daemons e1842b2...1aaffcc (2): > Add 'wheel' package to 'setup_requires' list (#95) > [thermalctld] Fix issue: thermalctld should be auto restarted when being killed (#94) * src/sonic-snmpagent 1a2b62a...5957460 (1): > [setup.py] Add 'wheel' to 'setup_requires' (#160) * src/sonic-utilities 2244d7b...2f79ac1 (4): > [show] Add missing import to fix `show ip interfaces` (#1126) > Fixed config load_minigrpah not working for Multi-asic platfroms. (#1123) > Add CLI for configuring synchronous mode (#1094) > [setup.py] Update dependencies (#1125) --- src/sonic-platform-common | 2 +- src/sonic-platform-daemons | 2 +- src/sonic-snmpagent | 2 +- src/sonic-utilities | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 14c6e53ecb86..7255d3a7a2dd 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 14c6e53ecb861e124e2b45a7b65875ffac1b949e +Subproject commit 7255d3a7a2ddea52cd88dcf0512ea1587ea63e6e diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index e1842b2dff48..1aaffcc98fc5 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit e1842b2dff481735ab42a7b0fd5594c24b7018e9 +Subproject commit 1aaffcc98fc56574a2d8b3ce3a7c50c4a6e8f8fc diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 1a2b62a93028..5957460b9f1b 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 1a2b62a93028642ad77ce8c0f356d093850d0343 +Subproject commit 5957460b9f1b5bc2657ded3a0bb4d84016c08da9 diff --git a/src/sonic-utilities b/src/sonic-utilities index 2244d7bec687..2f79ac135018 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 2244d7bec687fe7f72c3a8565dacdefd47deba0d +Subproject commit 2f79ac135018b62a2a04e031c5221799fcaa2dc4 From a56ad41b9ed83fc529135caa62929dff8e95decb Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Wed, 23 Sep 2020 20:01:58 -0700 Subject: [PATCH 16/78] [mgmt] Install dhclient in sonic-mgmt docker (#5447) Signed-off-by: Danny Allen --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index c4d43c56c0b7..736d83d2b4e2 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -10,6 +10,7 @@ RUN apt-get update && apt-get install -y build-essential \ git \ inetutils-ping \ iproute2 \ + isc-dhcp-client \ libffi-dev \ libssl-dev \ libxml2 \ From 4ec83b25bc4bf5f119d8c297a715836c95588f93 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Wed, 23 Sep 2020 22:41:07 -0700 Subject: [PATCH 17/78] [arista]: Add new 48x50G + 8x100G hwsku for Lodoga (#5452) --- .../Arista-7050CX3-32S-D48C8/port_config.ini | 57 ++ .../Arista-7050CX3-32S-D48C8/sai.profile | 2 + .../td3-a7050cx3-32s-48x50G+8x100G.config.bcm | 545 ++++++++++++++++++ 3 files changed, 604 insertions(+) create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/port_config.ini create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/sai.profile create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/td3-a7050cx3-32s-48x50G+8x100G.config.bcm diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/port_config.ini b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/port_config.ini new file mode 100644 index 000000000000..25670f87d9cc --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 1,2 Ethernet1/1 1 50000 +Ethernet2 3,4 Ethernet1/3 1 50000 +Ethernet4 5,6 Ethernet2/1 2 50000 +Ethernet6 7,8 Ethernet2/3 2 50000 +Ethernet8 9,10 Ethernet3/1 3 50000 +Ethernet10 11,12 Ethernet3/3 3 50000 +Ethernet12 13,14 Ethernet4/1 4 50000 +Ethernet14 15,16 Ethernet4/3 4 50000 +Ethernet16 21,22 Ethernet5/1 5 50000 +Ethernet18 23,24 Ethernet5/3 5 50000 +Ethernet20 17,18 Ethernet6/1 6 50000 +Ethernet22 19,20 Ethernet6/3 6 50000 +Ethernet24 25,26,27,28 Ethernet7/1 7 100000 +Ethernet28 29,30,31,32 Ethernet8/1 8 100000 +Ethernet32 37,38,39,40 Ethernet9/1 9 100000 +Ethernet36 33,34,35,36 Ethernet10/1 10 100000 +Ethernet40 41,42 Ethernet11/1 11 50000 +Ethernet42 43,44 Ethernet11/3 11 50000 +Ethernet44 45,46 Ethernet12/1 12 50000 +Ethernet46 47,48 Ethernet12/3 12 50000 +Ethernet48 53,54 Ethernet13/1 13 50000 +Ethernet50 55,56 Ethernet13/3 13 50000 +Ethernet52 49,50 Ethernet14/1 14 50000 +Ethernet54 51,52 Ethernet14/3 14 50000 +Ethernet56 57,58 Ethernet15/1 15 50000 +Ethernet58 59,60 Ethernet15/3 15 50000 +Ethernet60 61,62 Ethernet16/1 16 50000 +Ethernet62 63,64 Ethernet16/3 16 50000 +Ethernet64 69,70 Ethernet17/1 17 50000 +Ethernet66 71,72 Ethernet17/3 17 50000 +Ethernet68 65,66 Ethernet18/1 18 50000 +Ethernet70 67,68 Ethernet18/3 18 50000 +Ethernet72 73,74 Ethernet19/1 19 50000 +Ethernet74 75,76 Ethernet19/3 19 50000 +Ethernet76 77,78 Ethernet20/1 20 50000 +Ethernet78 79,80 Ethernet20/3 20 50000 +Ethernet80 85,86 Ethernet21/1 21 50000 +Ethernet82 87,88 Ethernet21/3 21 50000 +Ethernet84 81,82 Ethernet22/1 22 50000 +Ethernet86 83,84 Ethernet22/3 22 50000 +Ethernet88 89,90,91,92 Ethernet23/1 23 100000 +Ethernet92 93,94,95,96 Ethernet24/1 24 100000 +Ethernet96 101,102,103,104 Ethernet25/1 25 100000 +Ethernet100 97,98,99,100 Ethernet26/1 26 100000 +Ethernet104 105,106 Ethernet27/1 27 50000 +Ethernet106 107,108 Ethernet27/3 27 50000 +Ethernet108 109,110 Ethernet28/1 28 50000 +Ethernet110 111,112 Ethernet28/3 28 50000 +Ethernet112 117,118 Ethernet29/1 29 50000 +Ethernet114 119,120 Ethernet29/3 29 50000 +Ethernet116 113,114 Ethernet30/1 30 50000 +Ethernet118 115,116 Ethernet30/3 30 50000 +Ethernet120 121,122 Ethernet31/1 31 50000 +Ethernet122 123,124 Ethernet31/3 31 50000 +Ethernet124 125,126 Ethernet32/1 32 50000 +Ethernet126 127,128 Ethernet32/3 32 50000 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/sai.profile b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/sai.profile new file mode 100644 index 000000000000..1865041f8d9f --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-a7050cx3-32s-48x50G+8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/td3-a7050cx3-32s-48x50G+8x100G.config.bcm b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/td3-a7050cx3-32s-48x50G+8x100G.config.bcm new file mode 100644 index 000000000000..2b7da96358d5 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/td3-a7050cx3-32s-48x50G+8x100G.config.bcm @@ -0,0 +1,545 @@ +arl_clean_timeout_usec=15000000 +asf_mem_profile=2 +bcm_num_cos=8 +bcm_stat_flags=1 +bcm_stat_jumbo=9236 +bcm_tunnel_term_compatible_mode=1 +cdma_timeout_usec=15000000 +core_clock_frequency=1525 +dma_desc_timeout_usec=15000000 +dpp_clock_ratio=2:3 +fpem_mem_entries=0 +higig2_hdr_mode=1 +ifp_inports_support_enable=1 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l2xmsg_mode=1 +l3_alpm_enable=2 +l3_max_ecmp_mode=1 +l3_mem_entries=16384 +max_vp_lags=0 +miim_intr_enable=0 +module_64ports=1 +multicast_l2_range=16383 +multicast_l3_range=0 +os=unix +oversubscribe_mode=1 +pbmp_xport_xe=0x7ffffffffffffffffffffffffffffffffe +PHY_AN_ALLOW_PLL_CHANGE=1 +phy_an_c37_130=2 +phy_an_c37_66=2 +phy_an_c73=1 +port_flex_enable=1 +port_init_autoneg=0 +port_phy_addr=0xff +robust_hash_disable_egress_vlan=1 +robust_hash_disable_mpls=1 +robust_hash_disable_vlan=1 +stable_size=0x5500000 +tdma_timeout_usec=15000000 +tslam_timeout_usec=15000000 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_rx_lane_map_physical{5.0}=0x3120 +phy_chain_rx_lane_map_physical{9.0}=0x3120 +phy_chain_rx_lane_map_physical{13.0}=0x3120 +phy_chain_rx_lane_map_physical{17.0}=0x1203 +phy_chain_rx_lane_map_physical{21.0}=0x3120 +phy_chain_rx_lane_map_physical{25.0}=0x3120 +phy_chain_rx_lane_map_physical{29.0}=0x3120 +phy_chain_rx_lane_map_physical{33.0}=0x1203 +phy_chain_rx_lane_map_physical{37.0}=0x3120 +phy_chain_rx_lane_map_physical{41.0}=0x3120 +phy_chain_rx_lane_map_physical{45.0}=0x3120 +phy_chain_rx_lane_map_physical{49.0}=0x1203 +phy_chain_rx_lane_map_physical{53.0}=0x3120 +phy_chain_rx_lane_map_physical{57.0}=0x3120 +phy_chain_rx_lane_map_physical{61.0}=0x3120 +phy_chain_rx_lane_map_physical{65.0}=0x2130 +phy_chain_rx_lane_map_physical{69.0}=0x0213 +phy_chain_rx_lane_map_physical{73.0}=0x2031 +phy_chain_rx_lane_map_physical{77.0}=0x0213 +phy_chain_rx_lane_map_physical{81.0}=0x2130 +phy_chain_rx_lane_map_physical{85.0}=0x0213 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_rx_lane_map_physical{93.0}=0x0213 +phy_chain_rx_lane_map_physical{97.0}=0x2130 +phy_chain_rx_lane_map_physical{101.0}=0x0213 +phy_chain_rx_lane_map_physical{105.0}=0x2031 +phy_chain_rx_lane_map_physical{109.0}=0x0213 +phy_chain_rx_lane_map_physical{113.0}=0x2130 +phy_chain_rx_lane_map_physical{117.0}=0x0213 +phy_chain_rx_lane_map_physical{121.0}=0x2031 +phy_chain_rx_lane_map_physical{125.0}=0x0213 +phy_chain_rx_lane_map_physical{129.0}=0x3210 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x0 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{56.0}=0x0 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{81.0}=0x1 +phy_chain_rx_polarity_flip_physical{82.0}=0x1 +phy_chain_rx_polarity_flip_physical{83.0}=0x0 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x1 +phy_chain_rx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{90.0}=0x1 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{109.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x1 +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_rx_polarity_flip_physical{131.0}=0x0 +phy_chain_tx_lane_map_physical{1.0}=0x3021 +phy_chain_tx_lane_map_physical{5.0}=0x1203 +phy_chain_tx_lane_map_physical{9.0}=0x0213 +phy_chain_tx_lane_map_physical{13.0}=0x0213 +phy_chain_tx_lane_map_physical{17.0}=0x2031 +phy_chain_tx_lane_map_physical{21.0}=0x0213 +phy_chain_tx_lane_map_physical{25.0}=0x2031 +phy_chain_tx_lane_map_physical{29.0}=0x1203 +phy_chain_tx_lane_map_physical{33.0}=0x2031 +phy_chain_tx_lane_map_physical{37.0}=0x0213 +phy_chain_tx_lane_map_physical{41.0}=0x2031 +phy_chain_tx_lane_map_physical{45.0}=0x1203 +phy_chain_tx_lane_map_physical{49.0}=0x2031 +phy_chain_tx_lane_map_physical{53.0}=0x0213 +phy_chain_tx_lane_map_physical{57.0}=0x2031 +phy_chain_tx_lane_map_physical{61.0}=0x1203 +phy_chain_tx_lane_map_physical{65.0}=0x1302 +phy_chain_tx_lane_map_physical{69.0}=0x1302 +phy_chain_tx_lane_map_physical{73.0}=0x1302 +phy_chain_tx_lane_map_physical{77.0}=0x2130 +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_tx_lane_map_physical{85.0}=0x3120 +phy_chain_tx_lane_map_physical{89.0}=0x1302 +phy_chain_tx_lane_map_physical{93.0}=0x2130 +phy_chain_tx_lane_map_physical{97.0}=0x1302 +phy_chain_tx_lane_map_physical{101.0}=0x3120 +phy_chain_tx_lane_map_physical{105.0}=0x1302 +phy_chain_tx_lane_map_physical{109.0}=0x2130 +phy_chain_tx_lane_map_physical{113.0}=0x1302 +phy_chain_tx_lane_map_physical{117.0}=0x3120 +phy_chain_tx_lane_map_physical{121.0}=0x1302 +phy_chain_tx_lane_map_physical{125.0}=0x3120 +phy_chain_tx_lane_map_physical{129.0}=0x3210 +phy_chain_tx_polarity_flip_physical{1.0}=0x1 +phy_chain_tx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x1 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_tx_polarity_flip_physical{20.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_tx_polarity_flip_physical{37.0}=0x0 +phy_chain_tx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x0 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x1 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x1 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_tx_polarity_flip_physical{81.0}=0x1 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x1 +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_tx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x1 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 +phy_chain_tx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{111.0}=0x0 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x0 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x1 +phy_chain_tx_polarity_flip_physical{119.0}=0x0 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_tx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_tx_polarity_flip_physical{129.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x0 +portmap_1=1:50:2 +portmap_3=3:50:2 +portmap_5=5:50:2 +portmap_7=7:50:2 +portmap_9=9:50:2 +portmap_11=11:50:2 +portmap_13=13:50:2 +portmap_15=15:50:2 +portmap_17=17:50:2 +portmap_19=19:50:2 +portmap_21=21:50:2 +portmap_23=23:50:2 +portmap_25=25:100 +portmap_29=29:100 +portmap_33=33:100 +portmap_37=37:100 +portmap_41=41:50:2 +portmap_43=43:50:2 +portmap_45=45:50:2 +portmap_47=47:50:2 +portmap_49=49:50:2 +portmap_51=51:50:2 +portmap_53=53:50:2 +portmap_55=55:50:2 +portmap_57=57:50:2 +portmap_59=59:50:2 +portmap_61=61:50:2 +portmap_63=63:50:2 +# skip 2 +portmap_67=65:50:2 +portmap_69=67:50:2 +portmap_71=69:50:2 +portmap_73=71:50:2 +portmap_75=73:50:2 +portmap_77=75:50:2 +portmap_79=77:50:2 +portmap_81=79:50:2 +portmap_83=81:50:2 +portmap_85=83:50:2 +portmap_87=85:50:2 +portmap_89=87:50:2 +portmap_91=89:100 +portmap_95=93:100 +portmap_99=97:100 +portmap_103=101:100 +portmap_107=105:50:2 +portmap_109=107:50:2 +portmap_111=109:50:2 +portmap_113=111:50:2 +portmap_115=113:50:2 +portmap_117=115:50:2 +portmap_119=117:50:2 +portmap_121=119:50:2 +portmap_123=121:50:2 +portmap_125=123:50:2 +portmap_127=125:50:2 +portmap_129=127:50:2 +serdes_core_rx_polarity_flip_physical{1}=0x8 +serdes_core_rx_polarity_flip_physical{5}=0x2 +serdes_core_rx_polarity_flip_physical{9}=0xc +serdes_core_rx_polarity_flip_physical{13}=0x3 +serdes_core_rx_polarity_flip_physical{17}=0x4 +serdes_core_rx_polarity_flip_physical{21}=0x3 +serdes_core_rx_polarity_flip_physical{25}=0x6 +serdes_core_rx_polarity_flip_physical{29}=0x3 +serdes_core_rx_polarity_flip_physical{33}=0x4 +serdes_core_rx_polarity_flip_physical{37}=0x3 +serdes_core_rx_polarity_flip_physical{41}=0xc +serdes_core_rx_polarity_flip_physical{45}=0x3 +serdes_core_rx_polarity_flip_physical{49}=0x4 +serdes_core_rx_polarity_flip_physical{53}=0x3 +serdes_core_rx_polarity_flip_physical{57}=0xc +serdes_core_rx_polarity_flip_physical{61}=0x3 +serdes_core_rx_polarity_flip_physical{65}=0xb +serdes_core_rx_polarity_flip_physical{69}=0xc +serdes_core_rx_polarity_flip_physical{73}=0x7 +serdes_core_rx_polarity_flip_physical{77}=0xc +serdes_core_rx_polarity_flip_physical{81}=0xb +serdes_core_rx_polarity_flip_physical{85}=0xc +serdes_core_rx_polarity_flip_physical{89}=0x7 +serdes_core_rx_polarity_flip_physical{93}=0xc +serdes_core_rx_polarity_flip_physical{97}=0xb +serdes_core_rx_polarity_flip_physical{101}=0x9 +serdes_core_rx_polarity_flip_physical{105}=0x7 +serdes_core_rx_polarity_flip_physical{109}=0xc +serdes_core_rx_polarity_flip_physical{113}=0xb +serdes_core_rx_polarity_flip_physical{117}=0xc +serdes_core_rx_polarity_flip_physical{121}=0x7 +serdes_core_rx_polarity_flip_physical{125}=0xc +serdes_core_rx_polarity_flip_physical{129}=0x0 +serdes_core_tx_polarity_flip_physical{1}=0x3 +serdes_core_tx_polarity_flip_physical{5}=0xb +serdes_core_tx_polarity_flip_physical{9}=0x3 +serdes_core_tx_polarity_flip_physical{13}=0xb +serdes_core_tx_polarity_flip_physical{17}=0x0 +serdes_core_tx_polarity_flip_physical{21}=0x3 +serdes_core_tx_polarity_flip_physical{25}=0x4 +serdes_core_tx_polarity_flip_physical{29}=0xc +serdes_core_tx_polarity_flip_physical{33}=0xf +serdes_core_tx_polarity_flip_physical{37}=0xc +serdes_core_tx_polarity_flip_physical{41}=0xe +serdes_core_tx_polarity_flip_physical{45}=0xc +serdes_core_tx_polarity_flip_physical{49}=0xf +serdes_core_tx_polarity_flip_physical{53}=0xc +serdes_core_tx_polarity_flip_physical{57}=0xe +serdes_core_tx_polarity_flip_physical{61}=0xc +serdes_core_tx_polarity_flip_physical{65}=0xf +serdes_core_tx_polarity_flip_physical{69}=0xe +serdes_core_tx_polarity_flip_physical{73}=0xe +serdes_core_tx_polarity_flip_physical{77}=0xc +serdes_core_tx_polarity_flip_physical{81}=0xf +serdes_core_tx_polarity_flip_physical{85}=0xc +serdes_core_tx_polarity_flip_physical{89}=0xe +serdes_core_tx_polarity_flip_physical{93}=0xc +serdes_core_tx_polarity_flip_physical{97}=0xf +serdes_core_tx_polarity_flip_physical{101}=0x6 +serdes_core_tx_polarity_flip_physical{105}=0x1 +serdes_core_tx_polarity_flip_physical{109}=0x3 +serdes_core_tx_polarity_flip_physical{113}=0x0 +serdes_core_tx_polarity_flip_physical{117}=0x3 +serdes_core_tx_polarity_flip_physical{121}=0x1 +serdes_core_tx_polarity_flip_physical{125}=0x3 +serdes_core_tx_polarity_flip_physical{129}=0x0 +serdes_preemphasis_1=0x45808 +serdes_preemphasis_3=0x45808 +serdes_preemphasis_5=0x45808 +serdes_preemphasis_7=0x45808 +serdes_preemphasis_9=0x45808 +serdes_preemphasis_11=0x45808 +serdes_preemphasis_13=0x45808 +serdes_preemphasis_15=0x45808 +serdes_preemphasis_17=0x45808 +serdes_preemphasis_19=0x45808 +serdes_preemphasis_21=0x45808 +serdes_preemphasis_23=0x45808 +serdes_preemphasis_25=0xd3e05 +serdes_preemphasis_29=0xd3e05 +serdes_preemphasis_33=0xb3403 +serdes_preemphasis_37=0x93603 +serdes_preemphasis_41=0x580c +serdes_preemphasis_43=0x580c +serdes_preemphasis_45=0x580c +serdes_preemphasis_47=0x580c +serdes_preemphasis_49=0x580c +serdes_preemphasis_51=0x580c +serdes_preemphasis_53=0x580c +serdes_preemphasis_55=0x580c +serdes_preemphasis_57=0x580c +serdes_preemphasis_59=0x580c +serdes_preemphasis_61=0x580c +serdes_preemphasis_63=0x580c +serdes_preemphasis_67=0x580c +serdes_preemphasis_69=0x580c +serdes_preemphasis_71=0x580c +serdes_preemphasis_73=0x580c +serdes_preemphasis_75=0x580c +serdes_preemphasis_77=0x580c +serdes_preemphasis_79=0x580c +serdes_preemphasis_81=0x580c +serdes_preemphasis_83=0x580c +serdes_preemphasis_85=0x580c +serdes_preemphasis_87=0x580c +serdes_preemphasis_89=0x580c +serdes_preemphasis_91=0x93603 +serdes_preemphasis_95=0xd3e05 +serdes_preemphasis_99=0xb3403 +serdes_preemphasis_103=0xd3e05 +serdes_preemphasis_107=0x85804 +serdes_preemphasis_109=0x85804 +serdes_preemphasis_111=0x85804 +serdes_preemphasis_113=0x85804 +serdes_preemphasis_115=0x85804 +serdes_preemphasis_117=0x85804 +serdes_preemphasis_119=0x85804 +serdes_preemphasis_121=0x85804 +serdes_preemphasis_123=0x85804 +serdes_preemphasis_125=0x85804 +serdes_preemphasis_127=0x85804 +serdes_preemphasis_129=0x85804 From 623d5c08c183966509153b0af52c860c745df89f Mon Sep 17 00:00:00 2001 From: Syd Logan Date: Thu, 24 Sep 2020 01:08:55 -0700 Subject: [PATCH 18/78] [submodule]: update sonic-swss-common/sonic-sairedis (#5449) Update to pick up changes needed for VS gearbox - sonic-sairedis - meta/saiserialize.cpp - Fix typo at SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT32 (#662) - syncd/scripts/gbsyncd_start.sh - Rename physyncd_startup.sh/physyncd_startup.py to gbsyncd_startup.sh/gbsyncd_startup.py (#661) - syncd/scripts/gbsyncd_startup.py - Rename physyncd_startup.sh/physyncd_startup.py to gbsyncd_startup.sh/gbsyncd_startup.py (#661) - sonic-swss-common - common/database_config.json - Add restapi DB (#386) - common/redispipeline.h - Throw proper exceptions when talking with Redis (#384) - common/redisreply.cpp - Throw proper exceptions when talking with Redis (#384) - common/redisreply.h - Throw proper exceptions when talking with Redis (#384) - common/schema.h - Add restapi DB (#386) - common/table.cpp - Add restapi DB (#386) Signed-off-by Syd Logan syd.logan@broadcom.com --- src/sonic-sairedis | 2 +- src/sonic-swss-common | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 6117cf5549e0..b6e5a140ff3c 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 6117cf5549e01cf188f3dfbd52fb447dfef9e5ad +Subproject commit b6e5a140ff3c25e31622edac038c41dc145fbf35 diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 2b9a00fffd90..3751c81071c2 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 2b9a00fffd90d0efe258e9e10fdd4e859ac190d5 +Subproject commit 3751c81071c204fa737e6b3e6ea29f7413330370 From 8c8773bee6d58abd0f8c05893064efff2bb5da76 Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Thu, 24 Sep 2020 11:12:23 -0700 Subject: [PATCH 19/78] [sonic-snmpagent]: Advance submodule (#5454) - Implementation changes for CiscoBgp4MIB (#158) Signed-off-by: SuvarnaMeenakshi --- src/sonic-snmpagent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 5957460b9f1b..51b09a8afe83 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 5957460b9f1b5bc2657ded3a0bb4d84016c08da9 +Subproject commit 51b09a8afe833443aca0fecd86962c2338b38c0d From 39edac5b956b4d841718b2106411b3fda2d53298 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 24 Sep 2020 11:13:05 -0700 Subject: [PATCH 20/78] [Centec] Update critical_processes file to use new syntax~ (#5450) This file was added recently, but was created using the old syntax. Update to the new syntax. --- platform/centec-arm64/docker-syncd-centec/critical_processes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/centec-arm64/docker-syncd-centec/critical_processes b/platform/centec-arm64/docker-syncd-centec/critical_processes index 6082f242b872..bdd6903c5690 100644 --- a/platform/centec-arm64/docker-syncd-centec/critical_processes +++ b/platform/centec-arm64/docker-syncd-centec/critical_processes @@ -1 +1 @@ -syncd +program:syncd From 224cc3953f00cd8c0fe13837244c6eceac372b8a Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Thu, 24 Sep 2020 11:32:16 -0700 Subject: [PATCH 21/78] [CLI][Multi ASIC] update get_all_namespace to return current namespace (#5446) --- .../sonic_py_common/multi_asic.py | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index d5925ea37de2..0b2b1d9da9b8 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -136,10 +136,38 @@ def get_asic_id_from_name(asic_name): raise ValueError('Unknown asic namespace name {}'.format(asic_name)) +def get_current_namespace(): + """ + This API returns the network namespace in which it is + invoked. In case of global namepace the API returns None + """ + + net_namespace = None + command = ["/bin/ip netns identify", str(os.getpid())] + proc = subprocess.Popen(command, + stdout=subprocess.PIPE, + shell=True, + stderr=subprocess.STDOUT) + try: + stdout, stderr = proc.communicate() + if proc.returncode != 0: + raise RuntimeError( + "Command {} failed with stderr {}".format(command, stderr) + ) + if stdout.rstrip('\n') != "": + net_namespace = stdout.rstrip('\n') + except OSError as e: + raise OSError("Error running command {}".format(command)) + + return net_namespace + + def get_namespaces_from_linux(): """ In a multi asic platform, each ASIC is in a Linux Namespace. - This method returns list of all the Namespace present on the device + This method returns the asic namespace under which this is invoked, + if namespace is None (global namespace) it returns list of all + the Namespace present on the device Note: It is preferable to use this function only when config_db is not available. When configdb is available use get_all_namespaces() @@ -147,6 +175,10 @@ def get_namespaces_from_linux(): Returns: List of the namespaces present in the system """ + current_ns = get_current_namespace() + if current_ns: + return [current_ns] + ns_list = [] for path in glob.glob(NAMESPACE_PATH_GLOB): ns = os.path.basename(path) From b43f1129b4a41347cbf15b8ee072d8bc9e0eb853 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Thu, 24 Sep 2020 14:57:42 -0700 Subject: [PATCH 22/78] [swss] Start Restore Neighbor After SWSS Config (#5451) SWSS config script restore ARP/FDB/Routes. Restore neighbor script uses config DB ARP information to restore ARP entries and so needs to be started after swssconfig exits. signed-off-by: Tamer Ahmed --- dockers/docker-orchagent/supervisord.conf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index f8c68337f0c0..521b221c5fc1 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -47,29 +47,29 @@ stderr_logfile=syslog dependent_startup=true dependent_startup_wait_for=portsyncd:running -[program:restore_neighbors] -command=/usr/bin/restore_neighbors.py +[program:swssconfig] +command=/usr/bin/swssconfig.sh priority=5 autostart=false -autorestart=false -startsecs=0 +autorestart=unexpected startretries=0 +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog dependent_startup=true dependent_startup_wait_for=orchagent:running -[program:swssconfig] -command=/usr/bin/swssconfig.sh +[program:restore_neighbors] +command=/usr/bin/restore_neighbors.py priority=6 autostart=false -autorestart=unexpected -startretries=0 +autorestart=false startsecs=0 +startretries=0 stdout_logfile=syslog stderr_logfile=syslog dependent_startup=true -dependent_startup_wait_for=orchagent:running +dependent_startup_wait_for=swssconfig:exited [program:neighsyncd] command=/usr/bin/neighsyncd From 13cec4c48609ca389155b77c9351814d9d2203ef Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Fri, 25 Sep 2020 00:28:28 -0700 Subject: [PATCH 23/78] [Monit] Unmonitor the processes in containers which are disabled. (#5153) We want to let Monit to unmonitor the processes in containers which are disabled in `FEATURE` table such that Monit will not generate false alerting messages into the syslog. Signed-off-by: Yong Zhao --- .../base_image_files/monit_database | 4 +- .../docker-fpm-frr/base_image_files/monit_bgp | 24 ++++---- .../docker-lldp/base_image_files/monit_lldp | 12 ++-- .../base_image_files/monit_swss | 42 +++++++------- .../docker-sflow/base_image_files/monit_sflow | 4 +- .../docker-snmp/base_image_files/monit_snmp | 8 +-- .../base_image_files/monit_restapi | 4 +- .../base_image_files/monit_telemetry | 8 +-- .../docker-teamd/base_image_files/monit_teamd | 11 ++++ .../build_templates/sonic_debian_extension.j2 | 5 ++ files/image_config/monit/process_checker | 57 +++++++++++++++++++ .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 8 +-- .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 4 +- .../base_image_files/monit_syncd | 8 +-- rules/docker-teamd.mk | 1 + 21 files changed, 149 insertions(+), 75 deletions(-) create mode 100644 dockers/docker-teamd/base_image_files/monit_teamd create mode 100755 files/image_config/monit/process_checker diff --git a/dockers/docker-database/base_image_files/monit_database b/dockers/docker-database/base_image_files/monit_database index c5508922864e..c1addd8a6f05 100644 --- a/dockers/docker-database/base_image_files/monit_database +++ b/dockers/docker-database/base_image_files/monit_database @@ -3,5 +3,5 @@ ## process list: ## redis_server ############################################################################### -check process redis_server matching "/usr/bin/redis-server" - if does not exist for 5 times within 5 cycles then alert +check program database|redis_server with path "/usr/bin/process_checker database /usr/bin/redis-server" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-fpm-frr/base_image_files/monit_bgp b/dockers/docker-fpm-frr/base_image_files/monit_bgp index b9726c619582..46ddc629013e 100644 --- a/dockers/docker-fpm-frr/base_image_files/monit_bgp +++ b/dockers/docker-fpm-frr/base_image_files/monit_bgp @@ -8,20 +8,20 @@ ## bgpcfgd ## bgpmon ############################################################################### -check process zebra matching "/usr/lib/frr/zebra" - if does not exist for 5 times within 5 cycles then alert +check program bgp|zebra with path "/usr/bin/process_checker bgp /usr/lib/frr/zebra" + if status != 0 for 5 times within 5 cycles then alert -check process fpmsyncd matching "fpmsyncd" - if does not exist for 5 times within 5 cycles then alert +check program bgp|fpmsyncd with path "/usr/bin/process_checker bgp fpmsyncd" + if status != 0 for 5 times within 5 cycles then alert -check process bgpd matching "/usr/lib/frr/bgpd" - if does not exist for 5 times within 5 cycles then alert +check program bgp|bgpd with path "/usr/bin/process_checker bgp /usr/lib/frr/bgpd" + if status != 0 for 5 times within 5 cycles then alert -check process staticd matching "/usr/lib/frr/staticd" - if does not exist for 5 times within 5 cycles then alert +check program bgp|staticd with path "/usr/bin/process_checker bgp /usr/lib/frr/staticd" + if status != 0 for 5 times within 5 cycles then alert -check process bgpcfgd matching "python /usr/local/bin/bgpcfgd" - if does not exist for 5 times within 5 cycles then alert +check program bgp|bgpcfgd with path "/usr/bin/process_checker bgp /usr/bin/python /usr/local/bin/bgpcfgd" + if status != 0 for 5 times within 5 cycles then alert -check process bgpmon matching "python /usr/local/bin/bgpmon" - if does not exist for 5 times within 5 cycles then alert +check program bgp|bgpmon with path "/usr/bin/process_checker bgp python /usr/local/bin/bgpmon" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-lldp/base_image_files/monit_lldp b/dockers/docker-lldp/base_image_files/monit_lldp index 200c52c7d332..194fa14a3088 100644 --- a/dockers/docker-lldp/base_image_files/monit_lldp +++ b/dockers/docker-lldp/base_image_files/monit_lldp @@ -5,11 +5,11 @@ ## lldp-syncd ## lldpmgrd ############################################################################### -check process lldpd_monitor matching "lldpd: " - if does not exist for 5 times within 5 cycles then alert +check program lldp|lldpd_monitor with path "/usr/bin/process_checker lldp lldpd:" + if status != 0 for 5 times within 5 cycles then alert -check process lldp_syncd matching "python2 -m lldp_syncd" - if does not exist for 5 times within 5 cycles then alert +check program lldp|lldp_syncd with path "/usr/bin/process_checker lldp python2 -m lldp_syncd" + if status != 0 for 5 times within 5 cycles then alert -check process lldpmgrd matching "python /usr/bin/lldpmgrd" - if does not exist for 5 times within 5 cycles then alert +check program lldp|lldpmgrd with path "/usr/bin/process_checker lldp python /usr/bin/lldpmgrd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-orchagent/base_image_files/monit_swss b/dockers/docker-orchagent/base_image_files/monit_swss index 5928dbd4ddb0..f5f4389f3fe4 100644 --- a/dockers/docker-orchagent/base_image_files/monit_swss +++ b/dockers/docker-orchagent/base_image_files/monit_swss @@ -11,33 +11,33 @@ ## buffermgrd ## nbrmgrd ## vxlanmgrd -############################################################################### -check process orchagent matching "/usr/bin/orchagent -d /var/log/swss" - if does not exist for 5 times within 5 cycles then alert +############################################################################## +check program swss|orchagent with path "/usr/bin/process_checker swss /usr/bin/orchagent -d /var/log/swss" + if status != 0 for 5 times within 5 cycles then alert -check process portsyncd matching "/usr/bin/portsyncd" - if does not exist for 5 times within 5 cycles then alert +check program swss|portsyncd with path "/usr/bin/process_checker swss /usr/bin/portsyncd" + if status != 0 for 5 times within 5 cycles then alert -check process neighsyncd matching "/usr/bin/neighsyncd" - if does not exist for 5 times within 5 cycles then alert +check program swss|neighsyncd with path "/usr/bin/process_checker swss /usr/bin/neighsyncd" + if status != 0 for 5 times within 5 cycles then alert -check process vrfmgrd matching "/usr/bin/vrfmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|vrfmgrd with path "/usr/bin/process_checker swss /usr/bin/vrfmgrd" + if status != 0 for 5 times within 5 cycles then alert -check process vlanmgrd matching "/usr/bin/vlanmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|vlanmgrd with path "/usr/bin/process_checker swss /usr/bin/vlanmgrd" + if status != 0 for 5 times within 5 cycles then alert -check process intfmgrd matching "/usr/bin/intfmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|intfmgrd with path "/usr/bin/process_checker swss /usr/bin/intfmgrd" + if status != 0 for 5 times within 5 cycles then alert -check process portmgrd matching "/usr/bin/portmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|portmgrd with path "/usr/bin/process_checker swss /usr/bin/portmgrd" + if status != 0 for 5 times within 5 cycles then alert -check process buffermgrd matching "/usr/bin/buffermgrd -l" - if does not exist for 5 times within 5 cycles then alert +check program swss|buffermgrd with path "/usr/bin/process_checker swss /usr/bin/buffermgrd -l" + if status != 0 for 5 times within 5 cycles then alert -check process nbrmgrd matching "/usr/bin/nbrmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|nbrmgrd with path "/usr/bin/process_checker swss /usr/bin/nbrmgrd" + if status != 0 for 5 times within 5 cycles then alert -check process vxlanmgrd matching "/usr/bin/vxlanmgrd" - if does not exist for 5 times within 5 cycles then alert +check program swss|vxlanmgrd with path "/usr/bin/process_checker swss /usr/bin/vxlanmgrd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-sflow/base_image_files/monit_sflow b/dockers/docker-sflow/base_image_files/monit_sflow index d041f81001ea..217f2e625835 100644 --- a/dockers/docker-sflow/base_image_files/monit_sflow +++ b/dockers/docker-sflow/base_image_files/monit_sflow @@ -3,5 +3,5 @@ ## process list: ## sflowmgrd ############################################################################### -check process sflowmgrd matching "/usr/bin/sflowmgrd" - if does not exist for 5 times within 5 cycles then alert +check program sflow|sflowmgrd with path "/usr/bin/process_checker sflow /usr/bin/sflowmgrd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-snmp/base_image_files/monit_snmp b/dockers/docker-snmp/base_image_files/monit_snmp index cfb1a2b66831..a943985abcef 100644 --- a/dockers/docker-snmp/base_image_files/monit_snmp +++ b/dockers/docker-snmp/base_image_files/monit_snmp @@ -4,8 +4,8 @@ ## snmpd ## snmpd_subagent ############################################################################### -check process snmpd matching "/usr/sbin/snmpd\s" - if does not exist for 5 times within 5 cycles then alert +check program snmp|snmpd with path "/usr/bin/process_checker snmp /usr/sbin/snmpd" + if status != 0 for 5 times within 5 cycles then alert -check process snmp_subagent matching "python3 -m sonic_ax_impl" - if does not exist for 5 times within 5 cycles then alert +check program snmp|snmp_subagent with path "/usr/bin/process_checker snmp python3.6 -m sonic_ax_impl" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-sonic-restapi/base_image_files/monit_restapi b/dockers/docker-sonic-restapi/base_image_files/monit_restapi index 2e90baf30d57..84e4366f4ac5 100644 --- a/dockers/docker-sonic-restapi/base_image_files/monit_restapi +++ b/dockers/docker-sonic-restapi/base_image_files/monit_restapi @@ -3,5 +3,5 @@ ## process list: ## restapi ############################################################################### -check process restapi matching "/usr/sbin/go-server-server" - if does not exist for 5 times within 5 cycles then alert +check program restapi|restapi with path "/usr/bin/process_checker restapi /usr/sbin/go-server-server" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry index a82c652f8179..7365ce51d1fd 100644 --- a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry +++ b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry @@ -4,8 +4,8 @@ ## telemetry ## dialout_client ############################################################################### -check process telemetry matching "/usr/sbin/telemetry" - if does not exist for 5 times within 5 cycles then alert +check program telemetry|telemetry with path "/usr/bin/process_checker telemetry /usr/sbin/telemetry" + if status != 0 for 5 times within 5 cycles then alert -check process dialout_client matching "/usr/sbin/dialout_client_cli" - if does not exist for 5 times within 5 cycles then alert +check program telemetry|dialout_client with path "/usr/bin/process_checker telemetry /usr/sbin/dialout_client_cli" + if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-teamd/base_image_files/monit_teamd b/dockers/docker-teamd/base_image_files/monit_teamd new file mode 100644 index 000000000000..256482aef2bf --- /dev/null +++ b/dockers/docker-teamd/base_image_files/monit_teamd @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for teamd container +## process list: +## teamsyncd +## teammgrd +############################################################################### +check program teamd|teamsyncd with path "/usr/bin/process_checker teamd /usr/bin/teamsyncd" + if status != 0 for 5 times within 5 cycles then alert + +check program teamd|teammgrd with path "/usr/bin/process_checker teamd /usr/bin/teammgrd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 2fbd6687d800..36b521af8215 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -116,6 +116,9 @@ sudo rm -rf $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY2_WHEEL_NAME # Install Python module for ipaddress sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install ipaddress +# Install Python module for psutil +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install psutil + # Install SwSS SDK Python 3 package # Note: the scripts will be overwritten by corresponding Python 2 package if [ -e {{swsssdk_py3_wheel_path}} ]; then @@ -239,6 +242,8 @@ sudo cp $IMAGE_CONFIGS/monit/monitrc $FILESYSTEM_ROOT/etc/monit/ sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/monitrc sudo cp $IMAGE_CONFIGS/monit/conf.d/* $FILESYSTEM_ROOT/etc/monit/conf.d/ sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/conf.d/* +sudo cp $IMAGE_CONFIGS/monit/process_checker $FILESYSTEM_ROOT/usr/bin/ +sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/process_checker # Copy crontabs sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/ diff --git a/files/image_config/monit/process_checker b/files/image_config/monit/process_checker new file mode 100755 index 000000000000..ba48e37729aa --- /dev/null +++ b/files/image_config/monit/process_checker @@ -0,0 +1,57 @@ +#!/usr/bin/python +import argparse +import sys +import syslog + +import psutil +import swsssdk + + +def check_process_existence(container_name, process_cmdline): + """ + @summary: Check whether the process in the specified container is running or not and + an alerting message will written into syslog if it failed to run. + """ + config_db = swsssdk.ConfigDBConnector() + config_db.connect() + feature_table = config_db.get_table("FEATURE") + + if container_name in feature_table.keys(): + # We look into the 'FEATURE' table to verify whether the container is disabled or not. + # If the container is diabled, we exit. + if ("state" in feature_table[container_name].keys() + and feature_table[container_name]["state"] == "disabled"): + sys.exit(0) + else: + # We leveraged the psutil library to help us check whether the process is running or not. + # If the process entity is found in process tree and it is also in the 'running' or 'sleeping' + # state, then it will be marked as 'running'. + is_running = False + for process in psutil.process_iter(["cmdline", "status"]): + if ((' '.join(process.cmdline())).startswith(process_cmdline) and process.status() in ["running", "sleeping"]): + is_running = True + break + + if not is_running: + # If this script is run by Monit, then the following output will be appended to + # Monit's syslog message. + print("'{}' is not running.".format(process_cmdline)) + sys.exit(1) + else: + syslog.syslog(syslog.LOG_ERR, "container '{}' is not included in SONiC image or the given container name is invalid!" + .format(container_name)) + + +def main(): + parser = argparse.ArgumentParser(description="Check whether the process in the specified \ + container is running and an alerting message will be written into syslog if it \ + failed to run.", usage="/usr/bin/process_checker ") + parser.add_argument("container_name", help="container name") + parser.add_argument("process_cmdline", nargs=argparse.REMAINDER, help="process command line") + args = parser.parse_args() + + check_process_existence(args.container_name, ' '.join(args.process_cmdline)) + + +if __name__ == '__main__': + main() diff --git a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd +++ b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd index 81c0b6ef6bc6..119548770096 100644 --- a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd @@ -4,8 +4,8 @@ ## syncd ## dsserve ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert -check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" - if does not exist for 5 times within 5 cycles then alert +check program syncd|dsserve with path "/usr/bin/process_checker syncd /usr/bin/dsserve /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd +++ b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd +++ b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd index 75391f90ac32..14789c67c3b8 100644 --- a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd +++ b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd index 81c0b6ef6bc6..119548770096 100644 --- a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd +++ b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd @@ -4,8 +4,8 @@ ## syncd ## dsserve ############################################################################### -check process syncd matching "/usr/bin/syncd\s" - if does not exist for 5 times within 5 cycles then alert +check program syncd|syncd with path "/usr/bin/process_checker syncd /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert -check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" - if does not exist for 5 times within 5 cycles then alert +check program syncd|dsserve with path "/usr/bin/process_checker syncd /usr/bin/dsserve /usr/bin/syncd" + if status != 0 for 5 times within 5 cycles then alert diff --git a/rules/docker-teamd.mk b/rules/docker-teamd.mk index c0fe6bfb6bb1..5442d5bf6b3f 100644 --- a/rules/docker-teamd.mk +++ b/rules/docker-teamd.mk @@ -27,4 +27,5 @@ $(DOCKER_TEAMD)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TEAMD)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_TEAMD)_BASE_IMAGE_FILES += teamdctl:/usr/bin/teamdctl +$(DOCKER_TEAMD)_BASE_IMAGE_FILES += monit_teamd:/etc/monit/conf.d $(DOCKER_TEAMD)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From 584e2223dc0b3b7986ad448d34ca9e6dc3f8e4ca Mon Sep 17 00:00:00 2001 From: bingwang-ms <66248323+bingwang-ms@users.noreply.github.com> Date: Fri, 25 Sep 2020 20:19:18 +0800 Subject: [PATCH 24/78] Fix exception when attempting to write a datetime to db (#5467) redis-py 3.0 used in master branch only accepts user data as bytes, strings or numbers (ints, longs and floats). Attempting to specify a key or a value as any other type will raise a DataError exception. This PR address the issue bt converting datetime to str --- files/image_config/procdockerstatsd/procdockerstatsd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/files/image_config/procdockerstatsd/procdockerstatsd index 00501f810072..b7dd1705db4c 100755 --- a/files/image_config/procdockerstatsd/procdockerstatsd +++ b/files/image_config/procdockerstatsd/procdockerstatsd @@ -184,9 +184,9 @@ class ProcDockerStats(daemon_base.DaemonBase): self.update_dockerstats_command() datetimeobj = datetime.now() # Adding key to store latest update time. - self.update_state_db('DOCKER_STATS|LastUpdateTime', 'lastupdate', datetimeobj) + self.update_state_db('DOCKER_STATS|LastUpdateTime', 'lastupdate', str(datetimeobj)) self.update_processstats_command() - self.update_state_db('PROCESS_STATS|LastUpdateTime', 'lastupdate', datetimeobj) + self.update_state_db('PROCESS_STATS|LastUpdateTime', 'lastupdate', str(datetimeobj)) # Data need to be updated every 2 mins. hence adding delay of 120 seconds time.sleep(120) From 0311a4a03799348963e71c08e0f3aca95aeeb17c Mon Sep 17 00:00:00 2001 From: Syd Logan Date: Fri, 25 Sep 2020 08:32:44 -0700 Subject: [PATCH 25/78] Add gearbox phy device files and a new physyncd docker to support VS gearbox phy feature (#4851) * buildimage: Add gearbox phy device files and a new physyncd docker to support VS gearbox phy feature * scripts and configuration needed to support a second syncd docker (physyncd) * physyncd supports gearbox device and phy SAI APIs and runs multiple instances of syncd, one per phy in the device * support for VS target (sonic-sairedis vslib has been extended to support a virtual BCM81724 gearbox PHY). HLD is located at https://github.com/Azure/SONiC/blob/b817a12fd89520d3fd26bbc5897487928e7f6de7/doc/gearbox/gearbox_mgr_design.md **- Why I did it** This work is part of the gearbox phy joint effort between Microsoft and Broadcom, and is based on multi-switch support in sonic-sairedis. **- How I did it** Overall feature was implemented across several projects. The collective pull requests (some in late stages of review at this point): https://github.com/Azure/sonic-utilities/pull/931 - CLI (merged) https://github.com/Azure/sonic-swss-common/pull/347 - Minor changes (merged) https://github.com/Azure/sonic-swss/pull/1321 - gearsyncd, config parsers, changes to orchargent to create gearbox phy on supported systems https://github.com/Azure/sonic-sairedis/pull/624 - physyncd, virtual BCM81724 gearbox phy added to vslib **- How to verify it** In a vslib build: root@sonic:/home/admin# show gearbox interfaces status PHY Id Interface MAC Lanes MAC Lane Speed PHY Lanes PHY Lane Speed Line Lanes Line Lane Speed Oper Admin -------- ----------- --------------- ---------------- --------------- ---------------- ------------ ----------------- ------ ------- 1 Ethernet48 121,122,123,124 25G 200,201,202,203 25G 204,205 50G down down 1 Ethernet49 125,126,127,128 25G 206,207,208,209 25G 210,211 50G down down 1 Ethernet50 69,70,71,72 25G 212,213,214,215 25G 216 100G down down In addition, docker ps | grep phy should show a physyncd docker running. Signed-off-by: syd.logan@broadcom.com --- device/virtual/x86_64-kvm_x86_64-r0/README.md | 88 +++ .../brcm_gearbox_vs/buffers.json.j2 | 3 + .../brcm_gearbox_vs/buffers_defaults_def.j2 | 45 ++ .../brcm_gearbox_vs/buffers_defaults_t0.j2 | 45 ++ .../brcm_gearbox_vs/buffers_defaults_t1.j2 | 45 ++ .../brcm_gearbox_vs/context_config.json | 32 + .../brcm_gearbox_vs/gearbox_config.json | 38 ++ .../brcm_gearbox_vs/lanemap.ini | 32 + .../brcm_gearbox_vs/pg_profile_lookup.ini | 17 + .../brcm_gearbox_vs/phy1_config_1.json | 168 +++++ .../brcm_gearbox_vs/port_config.ini | 33 + .../brcm_gearbox_vs/qos.json.j2 | 1 + .../brcm_gearbox_vs/sai.profile | 5 + .../td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../docker-database/database_config.json.j2 | 15 + dockers/docker-orchagent/supervisord.conf | 12 + files/build_templates/gbsyncd.service.j2 | 18 + .../build_templates/sonic_debian_extension.j2 | 4 +- files/scripts/gbsyncd.sh | 45 ++ files/scripts/syncd.sh | 122 +--- files/scripts/syncd_common.sh | 141 ++++ platform/template/docker-gbsyncd-base.mk | 30 + platform/vs/docker-gbsyncd-vs.dep | 11 + platform/vs/docker-gbsyncd-vs.mk | 14 + platform/vs/docker-gbsyncd-vs/Dockerfile.j2 | 34 + .../vs/docker-gbsyncd-vs/critical_processes | 1 + platform/vs/docker-gbsyncd-vs/start.sh | 21 + .../vs/docker-gbsyncd-vs/supervisord.conf | 48 ++ .../vs/docker-sonic-vs/database_config.json | 17 +- platform/vs/gbsyncd-vs.mk | 14 + platform/vs/rules.mk | 1 + src/sonic-device-data/Makefile | 3 + src/sonic-device-data/src/pai.vs_profile | 7 + 33 files changed, 1639 insertions(+), 117 deletions(-) create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/README.md create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/context_config.json create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/gearbox_config.json create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/phy1_config_1.json create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/td2-s6000-32x40G.config.bcm create mode 100644 files/build_templates/gbsyncd.service.j2 create mode 100755 files/scripts/gbsyncd.sh create mode 100755 files/scripts/syncd_common.sh create mode 100644 platform/template/docker-gbsyncd-base.mk create mode 100644 platform/vs/docker-gbsyncd-vs.dep create mode 100644 platform/vs/docker-gbsyncd-vs.mk create mode 100644 platform/vs/docker-gbsyncd-vs/Dockerfile.j2 create mode 100644 platform/vs/docker-gbsyncd-vs/critical_processes create mode 100755 platform/vs/docker-gbsyncd-vs/start.sh create mode 100644 platform/vs/docker-gbsyncd-vs/supervisord.conf create mode 100644 platform/vs/gbsyncd-vs.mk create mode 100644 src/sonic-device-data/src/pai.vs_profile diff --git a/device/virtual/x86_64-kvm_x86_64-r0/README.md b/device/virtual/x86_64-kvm_x86_64-r0/README.md new file mode 100644 index 000000000000..0347432d67b4 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/README.md @@ -0,0 +1,88 @@ +# Changing the virtual device + +You can control the hw sku and default factory configuration for the VS image +by modifying the content of the file default_sku in this directory. + +The format of default_sku is a single line: + +``` + +``` + +## Allowable values for hw_key + +| hw_key | Device | +| ------ | ------ | +| Force10-S6000 | Dell Force10 S6000| +| brcm_gearbox_vs | Similar to Force10-S6000, but implements a virtual BRCM81724 Gearbox Phy | + +## Allowable values for default_preset + +These include "t1", "l2", and "empty". See the file +sonic-buildimage/src/sonic-config-engine/config_samples.py for details on how +each default_preset value is interpreted. + +# Changing the hwsku of an existing VS switch + +To change the default hwsku for a VS image that has already been built and installed, follow these steps: + +- Edit /usr/share/sonic/device/x86_64-kvm_x86_64-r0/default_sku. For details, see the section below (Device Specific Documentation) +- Edit /etc/sonic/config_db.json, and change the "hwsku" key in DEVICE_METADATA:localhost to match the hw_key used in default_sku. Example: + + "DEVICE_METADATA": { + "localhost": { + ... + "hwsku": "brcm_gearbox_vs", + ... + } + }, + ... +- Reboot the switch +- Use "show platform summary" to verify, and follow any steps specific to the platform, as needed, such as those described below for the brcm_gearbox_vs hwsku. + +# Device Specific Documentation + +For general info on building, see https://github.com/Azure/sonic-buildimage/blob/master/README.md + +## Force-10-S6000 + +This is the default VS for SONiC. To enable, set contents of default_sku to: + +``` +Force10-S6000 t1 +``` + +To build: + +``` +make init +make configure PLATFORM=vs +make target/sonic-vs.img.gz +``` + +## brcm_gearbox_vs + +This sku simulates a device with a Broadcom BRCM81724 gearbox PHY. To enable, +set default_sku to: + + +``` +brcm_gearbox_vs t1 +``` + +To build (same as Force-10-S6000): + +``` +make init +make configure PLATFORM=vs +make target/sonic-vs.img.gz +``` + +To verify, install and bring up SONiC. There will be a new gbsyncd docker +which is designed to respond to configuration directed towards the gearbox phy +"switch". swss will create that gearbox switch on startup after detecting the +gearbox is present (this is done by a short lived gearsyncd that runs in the +swss docker). + +The commands "show gearbox interfaces status" and "show gearbox phys status" can be +used to verify the virtual gearbox phy has been created. See https://github.com/Azure/sonic-utilities/blob/master/doc/Command-Reference.md#gearbox for details. diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/context_config.json b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/context_config.json new file mode 100644 index 000000000000..9f9f80ba0d36 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/context_config.json @@ -0,0 +1,32 @@ +{ + "CONTEXTS": [ + { + "guid" : 0, + "name" : "sw0", + "dbAsic" : "ASIC_DB", + "dbCounters" : "COUNTERS_DB", + "dbFlex": "FLEX_COUNTER_DB", + "dbState" : "STATE_DB", + "switches": [ + { + "index" : 0, + "hwinfo" : "" + } + ] + }, + { + "guid" : 1, + "name" : "phy1", + "dbAsic" : "GB_ASIC_DB", + "dbCounters" : "GB_COUNTERS_DB", + "dbFlex": "GB_FLEX_COUNTER_DB", + "dbState" : "STATE_DB", + "switches": [ + { + "index" : 1, + "hwinfo" : "" + } + ] + } + ] +} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/gearbox_config.json b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/gearbox_config.json new file mode 100644 index 000000000000..2de95c4d806d --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/gearbox_config.json @@ -0,0 +1,38 @@ +{ + "phys": [ + { + "phy_id": 1, + "name": "sesto-1", + "address": "0x1000", + "lib_name": "libsai_phy_sesto-1.so", + "firmware_path": "/tmp/phy-sesto-1.bin", + "config_file": "/usr/share/sonic/hwsku/phy1_config_1.json", + "sai_init_config_file": "/usr/share/sonic/hwsku/sesto-1.bcm", + "phy_access": "mdio", + "bus_id": 0 + } + ], + "interfaces": [ + { + "name": "Ethernet0", + "index": 0, + "phy_id" : 1, + "system_lanes": [200,201], + "line_lanes": [206] + }, + { + "name": "Ethernet4", + "index": 1, + "phy_id" : 1, + "system_lanes": [202,203], + "line_lanes": [207] + }, + { + "name": "Ethernet8", + "index": 2, + "phy_id" : 1, + "system_lanes": [204,205], + "line_lanes": [208] + } + ] +} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/phy1_config_1.json b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/phy1_config_1.json new file mode 100644 index 000000000000..1b81394e9936 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/phy1_config_1.json @@ -0,0 +1,168 @@ +{ + "lanes": [ + { + "index": 200, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0200" + }, + { + "index": 201, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0201" + }, + { + "index": 202, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0202" + }, + { + "index": 203, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0203" + }, + { + "index": 204, + "local_lane_id": 0, + "system_side": false, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 200, + "mdio_addr": "0x0204" + }, + { + "index": 205, + "local_lane_id": 0, + "system_side": false, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 202, + "mdio_addr": "0x0205" + }, + { + "index": 206, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0206" + }, + { + "index": 207, + "local_lane_id": 0, + "system_side": false, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0207" + }, + { + "index": 208, + "local_lane_id": 0, + "system_side": true, + "tx_polarity": 0, + "rx_polarity": 0, + "line_tx_lanemap": 0, + "line_rx_lanemap": 0, + "line_to_system_lanemap": 0, + "mdio_addr": "0x0208" + } + ], + "ports": [ + { + "index": 0, + "mdio_addr": "0x2000", + "system_speed": 20000, + "system_fec": "none", + "system_auto_neg": true, + "system_loopback": "none", + "system_training": false, + "line_speed": 40000, + "line_fec": "none", + "line_auto_neg": true, + "line_media_type": "fiber", + "line_intf_type": "none", + "line_loopback": "none", + "line_training": false, + "line_adver_speed": [], + "line_adver_fec": [], + "line_adver_auto_neg": false, + "line_adver_asym_pause": false, + "line_adver_media_type": "fiber" + }, + { + "index": 1, + "mdio_addr": "0x3000", + "system_speed": 20000, + "system_fec": "none", + "system_auto_neg": true, + "system_loopback": "none", + "system_training": false, + "line_speed": 40000, + "line_fec": "none", + "line_auto_neg": true, + "line_media_type": "fiber", + "line_intf_type": "none", + "line_loopback": "none", + "line_training": false, + "line_adver_speed": [], + "line_adver_fec": [], + "line_adver_auto_neg": false, + "line_adver_asym_pause": false, + "line_adver_media_type": "fiber" + }, + { + "index": 2, + "mdio_addr": "0x4000", + "system_speed": 20000, + "system_fec": "none", + "system_auto_neg": true, + "system_loopback": "none", + "system_training": false, + "line_speed": 40000, + "line_fec": "none", + "line_auto_neg": true, + "line_media_type": "fiber", + "line_intf_type": "none", + "line_loopback": "none", + "line_training": false, + "line_adver_speed": [], + "line_adver_fec": [], + "line_adver_auto_neg": false, + "line_adver_asym_pause": false, + "line_adver_media_type": "fiber" + } + ] +} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/sai.profile new file mode 100644 index 000000000000..bfc466f27e54 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/sai.profile @@ -0,0 +1,5 @@ +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/brcm_gearbox_vs/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/dockers/docker-database/database_config.json.j2 b/dockers/docker-database/database_config.json.j2 index 242b065eb398..a24252ed810d 100644 --- a/dockers/docker-database/database_config.json.j2 +++ b/dockers/docker-database/database_config.json.j2 @@ -57,6 +57,21 @@ "id" : 8, "separator": "|", "instance" : "redis" + }, + "GB_ASIC_DB" : { + "id" : 9, + "separator": "|", + "instance" : "redis" + }, + "GB_COUNTERS_DB" : { + "id" : 10, + "separator": "|", + "instance" : "redis" + }, + "GB_FLEX_COUNTER_DB" : { + "id" : 11, + "separator": "|", + "instance" : "redis" } }, "VERSION" : "1.0" diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 521b221c5fc1..780a4d790464 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -27,6 +27,18 @@ stdout_logfile=syslog stderr_logfile=syslog dependent_startup=true +[program:gearsyncd] +command=/usr/bin/gearsyncd -p /usr/share/sonic/hwsku/gearbox_config.json +priority=3 +autostart=false +autorestart=false +startsecs=0 +startretries=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + [program:portsyncd] command=/usr/bin/portsyncd priority=3 diff --git a/files/build_templates/gbsyncd.service.j2 b/files/build_templates/gbsyncd.service.j2 new file mode 100644 index 000000000000..e1080ae7d526 --- /dev/null +++ b/files/build_templates/gbsyncd.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=gbsyncd service +Requires=database.service updategraph.service +ConditionPathExists=!/usr/share/sonic/hwsku/gearbox_config.json +After=database.service updategraph.service +After=interfaces-config.service +After=swss.service +Before=ntp-config.service + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/gbsyncd.sh start +ExecStart=/usr/local/bin/gbsyncd.sh wait +ExecStop=/usr/local/bin/gbsyncd.sh stop + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 36b521af8215..eac1e2ba352a 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -1,6 +1,6 @@ #!/bin/bash ## This script is to automate loading of vendor specific docker images -## and instalation of configuration files and vendor specific packages +## and installation of configuration files and vendor specific packages ## to debian file system. ## ## USAGE: @@ -535,6 +535,8 @@ sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys # Copy service scripts (swss, syncd, bgp, radv) sudo LANG=C cp $SCRIPTS_DIR/swss.sh $FILESYSTEM_ROOT/usr/local/bin/swss.sh sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh +sudo LANG=C cp $SCRIPTS_DIR/syncd_common.sh $FILESYSTEM_ROOT/usr/local/bin/syncd_common.sh +sudo LANG=C cp $SCRIPTS_DIR/gbsyncd.sh $FILESYSTEM_ROOT/usr/local/bin/gbsyncd.sh sudo LANG=C cp $SCRIPTS_DIR/bgp.sh $FILESYSTEM_ROOT/usr/local/bin/bgp.sh sudo LANG=C cp $SCRIPTS_DIR/radv.sh $FILESYSTEM_ROOT/usr/local/bin/radv.sh diff --git a/files/scripts/gbsyncd.sh b/files/scripts/gbsyncd.sh new file mode 100755 index 000000000000..996fbf8cdf31 --- /dev/null +++ b/files/scripts/gbsyncd.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +. /usr/local/bin/syncd_common.sh + +function startplatform() { + : +} + +function waitplatform() { + : +} + +function stopplatform1() { + : +} + +function stopplatform2() { + : +} + +OP=$1 +DEV=$2 + +SERVICE="gbsyncd" +PEER="swss" +DEBUGLOG="/tmp/swss-gbsyncd-debug$DEV.log" +LOCKFILE="/tmp/swss-gbsyncd-lock$DEV" +NAMESPACE_PREFIX="asic" +if [ "$DEV" ]; then + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" +else + NET_NS="" + SONIC_DB_CLI="sonic-db-cli" +fi + +case "$1" in + start|wait|stop) + $1 + ;; + *) + echo "Usage: $0 {start|wait|stop}" + exit 1 + ;; +esac diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 87a39b71ae7b..22fa992b8e80 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -1,96 +1,8 @@ #!/bin/bash +. /usr/local/bin/syncd_common.sh -function debug() -{ - /usr/bin/logger $1 - /bin/echo `date` "- $1" >> ${DEBUGLOG} -} - -function lock_service_state_change() -{ - debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" - - exec {LOCKFD}>${LOCKFILE} - /usr/bin/flock -x ${LOCKFD} - trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 - - debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" -} - -function unlock_service_state_change() -{ - debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" - /usr/bin/flock -u ${LOCKFD} -} - -function check_warm_boot() -{ - SYSTEM_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` - # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. - if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then - WARM_BOOT="true" - else - WARM_BOOT="false" - fi -} - -function wait_for_database_service() -{ - # Wait for redis server start before database clean - until [[ $($SONIC_DB_CLI PING | grep -c PONG) -gt 0 ]]; do - sleep 1; - done - - # Wait for configDB initialization - until [[ $($SONIC_DB_CLI CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; - do sleep 1; - done -} - -function getBootType() -{ - # same code snippet in files/build_templates/docker_image_ctl.j2 - case "$(cat /proc/cmdline)" in - *SONIC_BOOT_TYPE=warm*) - TYPE='warm' - ;; - *SONIC_BOOT_TYPE=fastfast*) - TYPE='fastfast' - ;; - *SONIC_BOOT_TYPE=fast*|*fast-reboot*) - # check that the key exists - if [[ $($SONIC_DB_CLI STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then - TYPE='fast' - else - TYPE='cold' - fi - ;; - *) - TYPE='cold' - esac - echo "${TYPE}" -} - -start() { - debug "Starting ${SERVICE}$DEV service..." - - lock_service_state_change - - mkdir -p /host/warmboot - - wait_for_database_service - check_warm_boot - - debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." - - if [[ x"$WARM_BOOT" == x"true" ]]; then - # Leave a mark for syncd scripts running inside docker. - touch /host/warmboot/warm-starting - else - rm -f /host/warmboot/warm-starting - fi +function startplatform() { # platform specific tasks @@ -119,35 +31,18 @@ start() { /etc/init.d/xpnet.sh start fi fi - - # start service docker - /usr/bin/${SERVICE}.sh start $DEV - debug "Started ${SERVICE} service..." - - unlock_service_state_change } -wait() { +function waitplatform() { + if [[ x"$sonic_asic_platform" == x"mellanox" ]]; then debug "Starting pmon service..." /bin/systemctl start pmon debug "Started pmon service" fi - /usr/bin/${SERVICE}.sh wait $DEV } -stop() { - debug "Stopping ${SERVICE}$DEV service..." - - lock_service_state_change - check_warm_boot - debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." - - if [[ x"$WARM_BOOT" == x"true" ]]; then - TYPE=warm - else - TYPE=cold - fi +function stopplatform1() { if [[ x$sonic_asic_platform == x"mellanox" ]] && [[ x$TYPE == x"cold" ]]; then debug "Stopping pmon service ahead of syncd..." @@ -177,10 +72,9 @@ stop() { /usr/bin/docker exec -i syncd$DEV /bin/sync debug "Finished ${TYPE} shutdown syncd process ..." fi +} - /usr/bin/${SERVICE}.sh stop $DEV - debug "Stopped ${SERVICE}$DEV service..." - +function stopplatform2() { # platform specific tasks if [[ x"$WARM_BOOT" != x"true" ]]; then @@ -192,8 +86,6 @@ stop() { /etc/init.d/xpnet.sh start fi fi - - unlock_service_state_change } OP=$1 diff --git a/files/scripts/syncd_common.sh b/files/scripts/syncd_common.sh new file mode 100755 index 000000000000..0e9fc8ac2d7a --- /dev/null +++ b/files/scripts/syncd_common.sh @@ -0,0 +1,141 @@ +#!/bin/bash + +# +# common functions used by "syncd" scipts (syncd.sh, gbsyncd.sh, etc..) +# scripts using this must provide implementations of the following functions: +# +# startplatform +# waitplatform +# stopplatform1 and stopplatform2 +# +# For examples of these, see gbsyncd.sh and syncd.sh. +# + +function debug() +{ + /usr/bin/logger $1 + /bin/echo `date` "- $1" >> ${DEBUGLOG} +} + +function lock_service_state_change() +{ + debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" + + exec {LOCKFD}>${LOCKFILE} + /usr/bin/flock -x ${LOCKFD} + trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 + + debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" +} + +function unlock_service_state_change() +{ + debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" + /usr/bin/flock -u ${LOCKFD} +} + +function check_warm_boot() +{ + SYSTEM_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. + if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then + WARM_BOOT="true" + else + WARM_BOOT="false" + fi +} + +function wait_for_database_service() +{ + # Wait for redis server start before database clean + until [[ $($SONIC_DB_CLI PING | grep -c PONG) -gt 0 ]]; do + sleep 1; + done + + # Wait for configDB initialization + until [[ $($SONIC_DB_CLI CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + do sleep 1; + done +} + +function getBootType() +{ + # same code snippet in files/build_templates/docker_image_ctl.j2 + case "$(cat /proc/cmdline)" in + *SONIC_BOOT_TYPE=warm*) + TYPE='warm' + ;; + *SONIC_BOOT_TYPE=fastfast*) + TYPE='fastfast' + ;; + *SONIC_BOOT_TYPE=fast*|*fast-reboot*) + # check that the key exists + if [[ $($SONIC_DB_CLI STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + TYPE='fast' + else + TYPE='cold' + fi + ;; + *) + TYPE='cold' + esac + echo "${TYPE}" +} + +start() { + debug "Starting ${SERVICE}$DEV service..." + + lock_service_state_change + + mkdir -p /host/warmboot + + wait_for_database_service + check_warm_boot + + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + + if [[ x"$WARM_BOOT" == x"true" ]]; then + # Leave a mark for syncd scripts running inside docker. + touch /host/warmboot/warm-starting + else + rm -f /host/warmboot/warm-starting + fi + + startplatform + + # start service docker + /usr/bin/${SERVICE}.sh start $DEV + debug "Started ${SERVICE} service..." + + unlock_service_state_change +} + +wait() { + waitplatform + + /usr/bin/${SERVICE}.sh wait $DEV +} + +stop() { + debug "Stopping ${SERVICE}$DEV service..." + + lock_service_state_change + check_warm_boot + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + + if [[ x"$WARM_BOOT" == x"true" ]]; then + TYPE=warm + else + TYPE=cold + fi + + stopplatform1 + + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." + + stopplatform2 + + unlock_service_state_change +} diff --git a/platform/template/docker-gbsyncd-base.mk b/platform/template/docker-gbsyncd-base.mk new file mode 100644 index 000000000000..aa4f574141b2 --- /dev/null +++ b/platform/template/docker-gbsyncd-base.mk @@ -0,0 +1,30 @@ +# docker image for gbsyncd + + +DOCKER_GBSYNCD_BASE_STEM = docker-gbsyncd-$(DOCKER_GBSYNCD_PLATFORM_CODE) +DOCKER_GBSYNCD_BASE = $(DOCKER_GBSYNCD_BASE_STEM).gz +DOCKER_GBSYNCD_BASE_DBG = $(DOCKER_GBSYNCD_BASE_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_GBSYNCD_BASE)_PATH = $(PLATFORM_PATH)/docker-gbsyncd-$(DOCKER_GBSYNCD_PLATFORM_CODE) + +$(DOCKER_GBSYNCD_BASE)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) + +$(DOCKER_GBSYNCD_BASE)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) + +$(DOCKER_GBSYNCD_BASE)_DBG_DEPENDS += $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) + +$(DOCKER_GBSYNCD_BASE)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) + +SONIC_DOCKER_IMAGES += $(DOCKER_GBSYNCD_BASE) +SONIC_BUSTER_DOCKERS += $(DOCKER_GBSYNCD_BASE) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_GBSYNCD_BASE) + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_GBSYNCD_BASE_DBG) +SONIC_BUSTER_DBG_DOCKERS += $(DOCKER_GBSYNCD_BASE_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_GBSYNCD_BASE_DBG) + +$(DOCKER_GBSYNCD_BASE)_CONTAINER_NAME = gbsyncd +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += --net=host --privileged -t +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro + diff --git a/platform/vs/docker-gbsyncd-vs.dep b/platform/vs/docker-gbsyncd-vs.dep new file mode 100644 index 000000000000..a3db18642abf --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs.dep @@ -0,0 +1,11 @@ +#DPKG FRK +DPATH := $($(DOCKER_GBSYNCD_BASE)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/vs/docker-gbsyncd-vs.mk platform/vs/docker-gbsyncd-vs.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_GBSYNCD_BASE)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_GBSYNCD_BASE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_GBSYNCD_BASE)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_GBSYNCD_BASE),$(DOCKER_GBSYNCD_BASE_DBG))) diff --git a/platform/vs/docker-gbsyncd-vs.mk b/platform/vs/docker-gbsyncd-vs.mk new file mode 100644 index 000000000000..2013132d6281 --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs.mk @@ -0,0 +1,14 @@ +# docker image for vs gbsyncd + +DOCKER_GBSYNCD_PLATFORM_CODE = vs +include $(PLATFORM_PATH)/../template/docker-gbsyncd-base.mk + +$(DOCKER_GBSYNCD_BASE)_DEPENDS += $(SYNCD_VS) + +$(DOCKER_GBSYNCD_BASE)_DBG_DEPENDS += $(SYNCD_VS_DBG) \ + $(LIBSWSSCOMMON_DBG) \ + $(LIBSAIMETADATA_DBG) \ + $(LIBSAIREDIS_DBG) \ + $(LIBSAIVS_DBG) + +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 b/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 new file mode 100644 index 000000000000..316466dfb4ea --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 @@ -0,0 +1,34 @@ +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 + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update + +RUN apt-get install -f -y iproute2=4.20.0-2 libcap2-bin=1:2.25-2 + +COPY \ +{% for deb in docker_gbsyncd_vs_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN dpkg -i \ +{% for deb in docker_gbsyncd_vs_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor %} + +COPY ["start.sh", "/usr/bin/"] + +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] + +## Clean up +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN rm -rf /debs + +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/platform/vs/docker-gbsyncd-vs/critical_processes b/platform/vs/docker-gbsyncd-vs/critical_processes new file mode 100644 index 000000000000..bdd6903c5690 --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs/critical_processes @@ -0,0 +1 @@ +program:syncd diff --git a/platform/vs/docker-gbsyncd-vs/start.sh b/platform/vs/docker-gbsyncd-vs/start.sh new file mode 100755 index 000000000000..e59a2322bbf8 --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs/start.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +HWSKU_DIR=/usr/share/sonic/hwsku + +mkdir -p /etc/sai.d/ + +# Create/Copy the pai.profile to /etc/sai.d/pai.profile +if [ -f $HWSKU_DIR/pai.profile.j2 ]; then + sonic-cfggen -d -t $HWSKU_DIR/pai.profile.j2 > /etc/sai.d/pai.profile +else + if [ -f $HWSKU_DIR/pai.profile ]; then + cp $HWSKU_DIR/pai.profile /etc/sai.d/pai.profile + fi +fi + +# Create/Copy the gearbox configs to /etc/sai.d +if [[ x"$sonic_asic_platform" == x"broadcom" ]]; then + if [ -d $HWSKU_DIR/gearbox ]; then + cp $HWSKU_DIR/gearbox/*.bcm /etc/sai.d/. + fi +fi diff --git a/platform/vs/docker-gbsyncd-vs/supervisord.conf b/platform/vs/docker-gbsyncd-vs/supervisord.conf new file mode 100644 index 000000000000..6ba7ecbbdda2 --- /dev/null +++ b/platform/vs/docker-gbsyncd-vs/supervisord.conf @@ -0,0 +1,48 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name gbsyncd +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=2 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +[program:syncd] +command=/usr/bin/gbsyncd_start.sh +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited diff --git a/platform/vs/docker-sonic-vs/database_config.json b/platform/vs/docker-sonic-vs/database_config.json index f3ed663a402b..73f4c43462a6 100644 --- a/platform/vs/docker-sonic-vs/database_config.json +++ b/platform/vs/docker-sonic-vs/database_config.json @@ -58,9 +58,24 @@ "separator": "|", "instance" : "redis" }, - "CHASSIS_DB" : { + "GB_ASIC_DB" : { "id" : 8, "separator": "|", + "instance" : "redis" + }, + "GB_COUNTERS_DB" : { + "id" : 9, + "separator": "|", + "instance" : "redis" + }, + "GB_FLEX_COUNTER_DB" : { + "id" : 10, + "separator": "|", + "instance" : "redis" + }, + "CHASSIS_DB" : { + "id" : 11, + "separator": "|", "instance" : "redis_chassis" } }, diff --git a/platform/vs/gbsyncd-vs.mk b/platform/vs/gbsyncd-vs.mk new file mode 100644 index 000000000000..2013132d6281 --- /dev/null +++ b/platform/vs/gbsyncd-vs.mk @@ -0,0 +1,14 @@ +# docker image for vs gbsyncd + +DOCKER_GBSYNCD_PLATFORM_CODE = vs +include $(PLATFORM_PATH)/../template/docker-gbsyncd-base.mk + +$(DOCKER_GBSYNCD_BASE)_DEPENDS += $(SYNCD_VS) + +$(DOCKER_GBSYNCD_BASE)_DBG_DEPENDS += $(SYNCD_VS_DBG) \ + $(LIBSWSSCOMMON_DBG) \ + $(LIBSAIMETADATA_DBG) \ + $(LIBSAIREDIS_DBG) \ + $(LIBSAIVS_DBG) + +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/vs/rules.mk b/platform/vs/rules.mk index d91f487a5edb..66e8bad5fe78 100644 --- a/platform/vs/rules.mk +++ b/platform/vs/rules.mk @@ -2,6 +2,7 @@ include $(PLATFORM_PATH)/syncd-vs.mk include $(PLATFORM_PATH)/sonic-version.mk include $(PLATFORM_PATH)/docker-sonic-vs.mk include $(PLATFORM_PATH)/docker-syncd-vs.mk +include $(PLATFORM_PATH)/docker-gbsyncd-vs.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/onie.mk include $(PLATFORM_PATH)/kvm-image.mk diff --git a/src/sonic-device-data/Makefile b/src/sonic-device-data/Makefile index ecac92b00e0e..3de9c27c041d 100644 --- a/src/sonic-device-data/Makefile +++ b/src/sonic-device-data/Makefile @@ -19,6 +19,9 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : cp -Lr $$d device/x86_64-kvm_x86_64-r0/ ; \ cp ./sai.vs_profile device/x86_64-kvm_x86_64-r0/$$(basename $$d)/sai.profile; \ grep -v ^# device/x86_64-kvm_x86_64-r0/$$(basename $$d)/port_config.ini | awk '{i=i+1;print "eth"i":"$$2}' > device/x86_64-kvm_x86_64-r0/$$(basename $$d)/lanemap.ini + cp ./pai.vs_profile device/x86_64-kvm_x86_64-r0/$$(basename $$d)/pai.profile; \ + grep -v ^# device/x86_64-kvm_x86_64-r0/$$(basename $$d)/port_config.ini | awk '{i=i+1;print "eth"i":"$$2}' > device/x86_64-kvm_x86_64-r0/$$(basename $$d)/lanemap.ini + done; # Build the package diff --git a/src/sonic-device-data/src/pai.vs_profile b/src/sonic-device-data/src/pai.vs_profile new file mode 100644 index 000000000000..9c99c42a1627 --- /dev/null +++ b/src/sonic-device-data/src/pai.vs_profile @@ -0,0 +1,7 @@ +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM81724 +SAI_VS_SAI_SWITCH_TYPE=SAI_SWITCH_TYPE_PHY +SAI_VS_HOSTIF_USE_TAP_DEVICE=false +SAI_VS_USE_BCMSIM_LINK_MON=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini From b5bcfef0132103b73b7e3013a52cd1de9141b057 Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Fri, 25 Sep 2020 09:20:09 -0700 Subject: [PATCH 26/78] Update conf DB with CA cert & rename ca_crt field (#5448) --- dockers/docker-sonic-restapi/restapi.sh | 6 +++--- src/sonic-config-engine/minigraph.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dockers/docker-sonic-restapi/restapi.sh b/dockers/docker-sonic-restapi/restapi.sh index d009507a7bc3..3a0997a2e66a 100755 --- a/dockers/docker-sonic-restapi/restapi.sh +++ b/dockers/docker-sonic-restapi/restapi.sh @@ -18,10 +18,10 @@ do if [[ -n "$certs" ]]; then SERVER_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['server_crt']"` SERVER_KEY=`sonic-cfggen -d -v "RESTAPI['certs']['server_key']"` - CLIENT_CA_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['client_ca_crt']"` + CA_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['ca_crt']"` CLIENT_CRT_CNAME=`sonic-cfggen -d -v "RESTAPI['certs']['client_crt_cname']"` - if [[ -f $SERVER_CRT && -f $SERVER_KEY && -f $CLIENT_CA_CRT ]]; then - RESTAPI_ARGS+=" -enablehttps=true -servercert=$SERVER_CRT -serverkey=$SERVER_KEY -clientcert=$CLIENT_CA_CRT -clientcertcommonname=$CLIENT_CRT_CNAME" + if [[ -f $SERVER_CRT && -f $SERVER_KEY && -f $CA_CRT ]]; then + RESTAPI_ARGS+=" -enablehttps=true -servercert=$SERVER_CRT -serverkey=$SERVER_KEY -clientcert=$CA_CRT -clientcertcommonname=$CLIENT_CRT_CNAME" break fi fi diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 4bc76c6aa6fe..2e3ba9da21a8 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -1139,7 +1139,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw 'certs': { 'server_crt': '/etc/sonic/credentials/restapiserver.crt', 'server_key': '/etc/sonic/credentials/restapiserver.key', - 'client_ca_crt': '/etc/sonic/credentials/restapiclient.crt', + 'ca_crt': '/etc/sonic/credentials/restapica.crt', 'client_crt_cname': 'client.restapi.sonic' } } From 43a8368874e5c4b347102bb65fd35105e8035872 Mon Sep 17 00:00:00 2001 From: gechiang <62408185+gechiang@users.noreply.github.com> Date: Fri, 25 Sep 2020 10:25:11 -0700 Subject: [PATCH 27/78] make bgpmon autorestart enabled by supervisord (#5460) --- dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 index de6879c43725..9c379404bc1a 100644 --- a/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 +++ b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 @@ -88,7 +88,7 @@ dependent_startup_wait_for=bgpd:running command=/usr/local/bin/bgpmon priority=6 autostart=false -autorestart=false +autorestart=true startsecs=0 stdout_logfile=syslog stderr_logfile=syslog From ccc3d755352e97f4a9a817cf59aa1f8ee9208c94 Mon Sep 17 00:00:00 2001 From: Sangita Maity Date: Fri, 25 Sep 2020 12:47:45 -0700 Subject: [PATCH 28/78] [portconfig] Fallback to port_config.ini if hwsku.json is not available (#5434) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **- Why I did it** As discussed, This PR covers the below points. 1. Give precedence to platform.json only if both platform.json and hwsku.json file exist. In case only platform.json exists, we don’t allow breakout for that HWSKU and fallback to port_config.ini. **- How I did it** check for `hwsku.json` file presence under get_path_to_port_config_file function. Signed-off-by: Sangita Maity --- src/sonic-py-common/sonic_py_common/device_info.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index f6b25de55ab5..4d1c9f862953 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -20,6 +20,9 @@ PORT_CONFIG_FILE = "port_config.ini" PLATFORM_JSON_FILE = "platform.json" +# HwSKU configuration file name +HWSKU_JSON_FILE = 'hwsku.json' + # Multi-NPU constants # TODO: Move Multi-ASIC-related functions and constants to a "multi_asic.py" module NPU_NAME_PREFIX = "asic" @@ -247,8 +250,13 @@ def get_path_to_port_config_file(hwsku=None, asic=None): port_config_candidates = [] - # Check for 'platform.json' file presence first - port_config_candidates.append(os.path.join(platform_path, PLATFORM_JSON_FILE)) + # Check for 'hwsku.json' file presence first + hwsku_json_file = os.path.join(hwsku_path, HWSKU_JSON_FILE) + + # if 'hwsku.json' file is available, Check for 'platform.json' file presence, + # if 'platform.json' is available, APPEND it. Otherwise, SKIP it. + if os.path.isfile(hwsku_json_file): + port_config_candidates.append(os.path.join(platform_path, PLATFORM_JSON_FILE)) # Check for 'port_config.ini' file presence in a few locations if asic: From dd02437d7f44844dafb874fec051059d32ad13db Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 25 Sep 2020 19:18:05 -0700 Subject: [PATCH 29/78] [sonic-platform-common] Update submodule (#5470) * src/sonic-platform-common 7255d3a...111dcf7 (2): > [EEPROM] Add new function part_number_str to TlvInfoDecoder (#121) > Fix fp_port_index error to get correct index type (#111) --- 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 7255d3a7a2dd..111dcf702cf3 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 7255d3a7a2ddea52cd88dcf0512ea1587ea63e6e +Subproject commit 111dcf702cf33e621455f3040a8682f2649b7b60 From f2e8187400d3bcb76686c4d9bb7eb5838f9c0abd Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Sat, 26 Sep 2020 06:40:21 +0300 Subject: [PATCH 30/78] [build]: Add build badge for Barefoot 202006 build (#4923) Signed-off-by: Volodymyr Boyko --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 9c80a3b2055c..b59d2d49d45d 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,10 @@ [![P4](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all/badge/icon?subject=P4)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all) [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all/badge/icon?subject=VS)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all) +*202006 builds*: + +[![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-202006/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-202006/) + *201911 builds*: [![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/) From 0a19cb4de58ba53f05cfce9c13f80573737a1252 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sun, 27 Sep 2020 02:20:43 +0800 Subject: [PATCH 31/78] [Mellanox] Refactor platform API to remove dependency on database (#5468) **- Why I did it** - Platform API implementation using sonic-cfggen to get platform name and SKU name, which will fail when the database is not available. - Chassis name is not correctly assigned, it shall be assigned with EEPROM TLV "Product Name", instead of SKU name - Chassis model is not implemented, it shall be assigned with EEPROM TLV "Part Number" **- How I did it** 1. Chassis > - Get platform name from /host/machine.conf > - Remove get SKU name with sonic-cfggen > - Get Chassis name and model from EEPROM TLV "Product Name" and "Part Number" > - Add function to return model 2. EEPROM > - Add function to return product name and part number 3. Platform > - Init EEPROM on the host side, so also can get the Chassis name model from EEPROM on the host side. --- .../sonic_platform/chassis.py | 44 +++++++------------ .../sonic_platform/eeprom.py | 34 +++++++++++++- .../sonic_platform/platform.py | 1 + 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 68c3fe16a86a..630b35903dff 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -18,7 +18,6 @@ import sys import io import re - import subprocess import syslog except ImportError as e: raise ImportError (str(e) + "- required module not found") @@ -27,9 +26,6 @@ MLNX_NUM_PSU = 2 -GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" -GET_PLATFORM_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.platform" - EEPROM_CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' EEPROM_CACHE_FILE = 'syseeprom_cache' @@ -61,18 +57,12 @@ class Chassis(ChassisBase): def __init__(self): super(Chassis, self).__init__() - # Initialize SKU name and Platform name - self.sku_name = self._get_sku_name() - self.platform_name = self._get_platform_name() - - mi = device_info.get_machine_info() - if mi is not None: - self.name = mi['onie_platform'] - self.platform_name = device_info.get_platform() - else: - self.name = self.sku_name - self.platform_name = self._get_platform_name() + self.name = "Undefined" + self.model = "Undefined" + # Initialize Platform name + self.platform_name = device_info.get_platform() + # move the initialization of each components to their dedicated initializer # which will be called from platform self.sfp_module_initialized = False @@ -148,6 +138,9 @@ def initialize_eeprom(self): from eeprom import Eeprom # Initialize EEPROM self._eeprom = Eeprom() + # Get chassis name and model from eeprom + self.name = self._eeprom.get_product_name() + self.model = self._eeprom.get_part_number() def initialize_components(self): @@ -173,6 +166,15 @@ def get_name(self): return self.name + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + return self.model + ############################################## # SFP methods ############################################## @@ -244,18 +246,6 @@ def _extract_num_of_fans_and_fan_drawers(self): return num_of_fan, num_of_drawer - - def _get_sku_name(self): - p = subprocess.Popen(GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) - out, err = p.communicate() - return out.rstrip('\n') - - - def _get_platform_name(self): - p = subprocess.Popen(GET_PLATFORM_CMD, shell=True, stdout=subprocess.PIPE) - out, err = p.communicate() - return out.rstrip('\n') - def _get_port_position_tuple_by_platform_name(self): position_tuple = port_position_tuple_list[platform_dict_port[self.platform_name]] return position_tuple diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py index 23f4b8b3444c..413388d20385 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py @@ -80,13 +80,21 @@ def _load_eeprom(self): pass self._base_mac = self.mgmtaddrstr(eeprom) - if self._base_mac == None: + if self._base_mac is None: self._base_mac = "Undefined." self._serial_str = self.serial_number_str(eeprom) - if self._serial_str == None: + if self._serial_str is None: self._serial_str = "Undefined." + self._product_name = self.modelstr(eeprom) + if self._product_name is None: + self._product_name = "Undefined." + + self._part_number = self.part_number_str(eeprom) + if self._part_number is None: + self._part_number = "Undefined." + original_stdout = sys.stdout sys.stdout = StringIO() self.decode_eeprom(eeprom) @@ -135,6 +143,28 @@ def get_serial_number(self): self._load_eeprom() return self._serial_str + def get_product_name(self): + """ + Retrieves the hardware product name for the chassis + + Returns: + A string containing the hardware product name for this chassis. + """ + if not self._eeprom_loaded: + self._load_eeprom() + return self._product_name + + def get_part_number(self): + """ + Retrieves the hardware part number for the chassis + + Returns: + A string containing the hardware part number for this chassis. + """ + if not self._eeprom_loaded: + self._load_eeprom() + return self._part_number + def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py index 6073ce5faed9..d80c28996a7a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py @@ -20,6 +20,7 @@ def __init__(self): self._chassis = Chassis() self._chassis.initialize_components() self._chassis.initizalize_system_led() + self._chassis.initialize_eeprom() else: self._chassis = Chassis() self._chassis.initialize_psu() From a92986c60557651c8a37858a5b8d0acd430ceb7b Mon Sep 17 00:00:00 2001 From: jostar-yang Date: Sun, 27 Sep 2020 02:21:31 +0800 Subject: [PATCH 32/78] [as7326-56x]Fix port_eeprom i2c mapping (#5466) **- Why I did it** There is error i2c mapping for port 11,12 and port 19, 20. **- How I did it** Fix to correct i2c mapping Co-authored-by: Jostar Yang --- .../accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py index 553e48fdd2a9..f9e0aae1b2a9 100644 --- a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py @@ -47,16 +47,16 @@ class SfpUtil(SfpUtilBase): 8: 50, 9: 48, 10: 49, - 11: 51, - 12: 52, + 11: 52, + 12: 51, 13: 53, 14: 56, 15: 55, 16: 54, 17: 58, 18: 57, - 19: 59, - 20: 60, + 19: 60, + 20: 59, 21: 61, 22: 63, 23: 62, From 4006ce711fa6545b0870186ffa05d4df24edb8b7 Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Sat, 26 Sep 2020 12:14:30 -0700 Subject: [PATCH 33/78] [Multi-Asic] Forward SNMP requests received on front panel interface to SNMP agent in host. (#5420) * [Multi-Asic] Forward SNMP requests destined to loopback IP, and coming in through the front panel interface present in the network namespace, to SNMP agent running in the linux host. * Updates based on comments * Further updates in docker_image_ctl.j2 and caclmgrd * Change the variable for net config file. * Updated the comments in the code. * No need to clean up the exising NAT rules if present, which could be created by some other process. * Delete our rule first and add it back, to take care of caclmgrd restart. Another benefit is that we delete only our rules, rather than earlier approach of "iptables -F" which cleans up all rules. * Keeping the original logic to clean the NAT entries, to revist when NAT feature added in namespace. * Missing updates to log_info call. --- files/build_templates/docker_image_ctl.j2 | 4 ++ files/image_config/caclmgrd/caclmgrd | 58 +++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 182f7008cc87..71decb3fa906 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -91,6 +91,10 @@ function postStartAction() { {%- if docker_container_name == "database" %} if [ "$DEV" ]; then + # Enable the forwarding on eth0 interface in namespace. + SYSCTL_NET_CONFIG="/etc/sysctl.d/sysctl-net.conf" + docker exec -i database$DEV sed -i -e "s/^net.ipv4.conf.eth0.forwarding=0/net.ipv4.conf.eth0.forwarding=1/; + s/^net.ipv6.conf.eth0.forwarding=0/net.ipv6.conf.eth0.forwarding=1/" $SYSCTL_NET_CONFIG docker exec -i database$DEV sysctl --system -e link_namespace $DEV fi diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index d7951677bee1..b2fa5efaea61 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -85,7 +85,9 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): self.config_db_map[''].connect() self.iptables_cmd_ns_prefix[''] = "" self.namespace_mgmt_ip = self.get_namespace_mgmt_ip(self.iptables_cmd_ns_prefix[''], '') + self.namespace_mgmt_ipv6 = self.get_namespace_mgmt_ipv6(self.iptables_cmd_ns_prefix[''], '') self.namespace_docker_mgmt_ip = {} + self.namespace_docker_mgmt_ipv6 = {} namespaces = device_info.get_all_namespaces() for front_asic_namespace in namespaces['front_ns']: self.config_db_map[front_asic_namespace] = ConfigDBConnector(use_unix_socket_path=True, namespace=front_asic_namespace) @@ -93,11 +95,15 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): self.iptables_cmd_ns_prefix[front_asic_namespace] = "ip netns exec " + front_asic_namespace + " " self.namespace_docker_mgmt_ip[front_asic_namespace] = self.get_namespace_mgmt_ip(self.iptables_cmd_ns_prefix[front_asic_namespace], front_asic_namespace) + self.namespace_docker_mgmt_ipv6[front_asic_namespace] = self.get_namespace_mgmt_ipv6(self.iptables_cmd_ns_prefix[front_asic_namespace], + front_asic_namespace) for back_asic_namespace in namespaces['back_ns']: self.iptables_cmd_ns_prefix[back_asic_namespace] = "ip netns exec " + back_asic_namespace + " " self.namespace_docker_mgmt_ip[back_asic_namespace] = self.get_namespace_mgmt_ip(self.iptables_cmd_ns_prefix[back_asic_namespace], back_asic_namespace) + self.namespace_docker_mgmt_ipv6[back_asic_namespace] = self.get_namespace_mgmt_ipv6(self.iptables_cmd_ns_prefix[back_asic_namespace], + back_asic_namespace) def get_namespace_mgmt_ip(self, iptable_ns_cmd_prefix, namespace): ip_address_get_command = iptable_ns_cmd_prefix + "ip -4 -o addr show " + ("eth0" if namespace else "docker0") +\ @@ -105,6 +111,11 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): return self.run_commands([ip_address_get_command]) + def get_namespace_mgmt_ipv6(self, iptable_ns_cmd_prefix, namespace): + ipv6_address_get_command = iptable_ns_cmd_prefix + "ip -6 -o addr show scope global " + ("eth0" if namespace else "docker0") +\ + " | awk '{print $4}' | cut -d'/' -f1 | head -1" + return self.run_commands([ipv6_address_get_command]) + def run_commands(self, commands): """ Given a list of shell commands, run them in order @@ -206,6 +217,39 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): (docker_mgmt_ip, self.namespace_mgmt_ip)) return allow_internal_docker_ip_cmds + def generate_fwd_snmp_traffic_from_namespace_to_host_commands(self, namespace): + """ + The below SNAT and DNAT rules are added in asic namespace in multi-ASIC platforms. It helps to forward the SNMP request coming + in through the front panel interfaces created/present in the asic namespace to the SNMP Agent running in SNMP container in + linux host network namespace. The external IP addresses are NATed to the internal docker IP addresses for the SNMP Agent to respond. + """ + fwd_snmp_traffic_from_namespace_to_host_cmds = [] + + if namespace: + # IPv4 rules + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + "iptables -t nat -X") + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + "iptables -t nat -F") + + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + + "iptables -t nat -A PREROUTING -p udp --dport {} -j DNAT --to-destination {}".format + (self.ACL_SERVICES['SNMP']['dst_ports'][0], self.namespace_mgmt_ip)) + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + + "iptables -t nat -A POSTROUTING -p udp --dport {} -j SNAT --to-source {}".format + (self.ACL_SERVICES['SNMP']['dst_ports'][0], self.namespace_docker_mgmt_ip[namespace])) + + # IPv6 rules + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + "ip6tables -t nat -X") + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + "ip6tables -t nat -F") + + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + + "ip6tables -t nat -A PREROUTING -p udp --dport {} -j DNAT --to-destination {}".format + (self.ACL_SERVICES['SNMP']['dst_ports'][0], self.namespace_mgmt_ipv6)) + fwd_snmp_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] + + "ip6tables -t nat -A POSTROUTING -p udp --dport {} -j SNAT --to-source {}".format + (self.ACL_SERVICES['SNMP']['dst_ports'][0], self.namespace_docker_mgmt_ipv6[namespace])) + + return fwd_snmp_traffic_from_namespace_to_host_cmds + def is_rule_ipv4(self, rule_props): if (("SRC_IP" in rule_props and rule_props["SRC_IP"]) or ("DST_IP" in rule_props and rule_props["DST_IP"])): @@ -438,6 +482,19 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): self.run_commands(iptables_cmds) + def update_control_plane_nat_acls(self, namespace): + """ + Convenience wrapper which programs the NAT rules for allowing the + snmp traffic coming on the front panel interface + """ + # Add iptables commands to allow front panel snmp traffic + iptables_cmds = self.generate_fwd_snmp_traffic_from_namespace_to_host_commands(namespace) + self.log_info("Issuing the following iptables commands:") + for cmd in iptables_cmds: + self.log_info(" " + cmd) + + self.run_commands(iptables_cmds) + def run(self): # Select Time-out for 10 Seconds SELECT_TIMEOUT_MS = 1000 * 10 @@ -462,6 +519,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): for namespace in self.config_db_map.keys(): # Unconditionally update control plane ACLs once at start on given namespace self.update_control_plane_acls(namespace) + self.update_control_plane_nat_acls(namespace) # Connect to Config DB of given namespace acl_db_connector = swsscommon.DBConnector("CONFIG_DB", 0, False, namespace) # Subscribe to notifications when ACL tables changes From 6eed0820c8014135e987d1615c14670b4d785f7f Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Sun, 27 Sep 2020 10:47:43 -0700 Subject: [PATCH 34/78] [bgp] Add 'allow list' manager feature (#5309) implements a new feature: "BGP Allow list." This feature allows us to control which IP prefixes are going to be advertised via ebgp from the routes received from EBGP neighbors. --- .../bgpd/templates/general/peer-group.conf.j2 | 2 +- .../bgpd/templates/general/policies.conf.j2 | 27 + files/image_config/constants/constants.yml | 12 + rules/sonic_bgpcfgd.mk | 3 +- src/sonic-bgpcfgd/.gitignore | 1 + src/sonic-bgpcfgd/app/allow_list.py | 632 ++++++++++++++++++ src/sonic-bgpcfgd/app/config.py | 20 +- src/sonic-bgpcfgd/app/directory.py | 159 +++++ src/sonic-bgpcfgd/app/manager.py | 71 ++ src/sonic-bgpcfgd/app/vars.py | 2 +- src/sonic-bgpcfgd/bgpcfgd | 7 +- src/sonic-bgpcfgd/pytest.ini | 2 + src/sonic-bgpcfgd/setup.py | 3 +- .../data/general/policies.conf/param_all.json | 13 +- .../general/policies.conf/param_base.json | 11 +- .../general/policies.conf/param_deny.json | 17 + .../general/policies.conf/result_all.conf | 14 + .../general/policies.conf/result_deny.conf | 39 ++ src/sonic-bgpcfgd/tests/test_allow_list.py | 469 +++++++++++++ .../tests/test_ipv6_nexthop_global.py | 29 +- src/sonic-bgpcfgd/tests/util.py | 4 +- 21 files changed, 1515 insertions(+), 22 deletions(-) create mode 100644 src/sonic-bgpcfgd/app/allow_list.py create mode 100644 src/sonic-bgpcfgd/app/directory.py create mode 100644 src/sonic-bgpcfgd/app/manager.py create mode 100644 src/sonic-bgpcfgd/pytest.ini create mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf create mode 100644 src/sonic-bgpcfgd/tests/test_allow_list.py 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 index b0acd1b2a460..5790d47a5a8a 100644 --- 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 @@ -24,7 +24,7 @@ {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V6 allowas-in 1 neighbor PEER_V6_INT allowas-in 1 - {% endif %} +{% endif %} {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor PEER_V6_INT route-reflector-client {% endif %} 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 index c545cf272892..4c27db4a466a 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -3,6 +3,33 @@ ! ! ! +{% if constants.bgp.allow_list is defined and constants.bgp.allow_list.enabled is defined and constants.bgp.allow_list.enabled %} +{% if constants.bgp.allow_list.default_action is defined and constants.bgp.allow_list.default_action.strip() == 'deny' %} +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community no-export additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community no-export additive +{% else %} +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community {{ constants.bgp.allow_list.drop_community }} additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community {{ constants.bgp.allow_list.drop_community }} additive +{% endif %} +! +route-map FROM_BGP_PEER_V4 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! +{% endif %} +! +! +! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index 3e1b76be0157..074956ff8396 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -18,6 +18,18 @@ constants: enabled: true ipv4: 64 ipv6: 64 + allow_list: + enabled: true + default_action: "permit" # or "deny" + drop_community: 5060:12345 # value of the community to identify a prefix to drop. Make sense only with allow_list_default_action equal to 'permit' + default_pl_rules: + v4: + - "deny 0.0.0.0/0 le 17" + - "permit 127.0.0.1/32" + v6: + - "deny 0::/0 le 59" + - "deny 0::/0 ge 65" + - "permit fe80::/64" peers: general: # peer_type db_table: "BGP_NEIGHBOR" diff --git a/rules/sonic_bgpcfgd.mk b/rules/sonic_bgpcfgd.mk index 32abbd5af948..7a9cae29cf19 100644 --- a/rules/sonic_bgpcfgd.mk +++ b/rules/sonic_bgpcfgd.mk @@ -6,6 +6,7 @@ $(SONIC_BGPCFGD)_SRC_PATH = $(SRC_PATH)/sonic-bgpcfgd # of sonic-config-engine and bgpcfgd explicitly calls sonic-cfggen # as part of its unit tests. # TODO: Refactor unit tests so that these dependencies are not needed -$(SONIC_BGPCFGD)_DEPENDS += $(SWSSSDK_PY2) $(SONIC_PY_COMMON_PY2) +$(SONIC_BGPCFGD)_DEPENDS += $(SONIC_PY_COMMON_PY2) +$(SONIC_BGPCFGD)_DEBS_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) $(SONIC_BGPCFGD)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_BGPCFGD) diff --git a/src/sonic-bgpcfgd/.gitignore b/src/sonic-bgpcfgd/.gitignore index bb1ba531d1d6..920a1b3ae499 100644 --- a/src/sonic-bgpcfgd/.gitignore +++ b/src/sonic-bgpcfgd/.gitignore @@ -6,3 +6,4 @@ app/*.pyc tests/*.pyc tests/__pycache__/ .idea +.coverage diff --git a/src/sonic-bgpcfgd/app/allow_list.py b/src/sonic-bgpcfgd/app/allow_list.py new file mode 100644 index 000000000000..2637d6999244 --- /dev/null +++ b/src/sonic-bgpcfgd/app/allow_list.py @@ -0,0 +1,632 @@ +""" +Implementation of "allow-list" feature +""" +import re + +from app.log import log_debug, log_info, log_err, log_warn +from app.template import TemplateFabric +from app.manager import Manager +from app.util import run_command + +class BGPAllowListMgr(Manager): + """ This class initialize "AllowList" settings """ + ALLOW_ADDRESS_PL_NAME_TMPL = "ALLOW_ADDRESS_%d_%s" # template for a name for the ALLOW_ADDRESS prefix-list ??? + EMPTY_COMMUNITY = "empty" + PL_NAME_TMPL = "PL_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s_V%s" + COMMUNITY_NAME_TMPL = "COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s" + RM_NAME_TMPL = "ALLOW_LIST_DEPLOYMENT_ID_%d_V%s" + ROUTE_MAP_ENTRY_WITH_COMMUNITY_START = 10 + ROUTE_MAP_ENTRY_WITH_COMMUNITY_END = 29990 + ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START = 30000 + ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END = 65530 + + V4 = "v4" # constant for af enum: V4 + V6 = "v6" # constant for af enum: V6 + + 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(BGPAllowListMgr, self).__init__( + common_objs, + [], + db, + table, + ) + self.cfg_mgr = common_objs["cfg_mgr"] + self.constants = common_objs["constants"] + self.key_re = re.compile(r"^DEPLOYMENT_ID\|\d+\|\S+$|^DEPLOYMENT_ID\|\d+$") + self.enabled = self.__get_enabled() + self.__load_constant_lists() + + def set_handler(self, key, data): + """ + Manager method which runs on receiving 'SET' message + :param key: ket of the 'SET' message + :param data: data of the 'SET' message + :return: True if the message was executed, False - the message should be postponed. + """ + if not self.enabled: + log_warn("BGPAllowListMgr::Received 'SET' command, but this feature is disabled in constants") + return True + if not self.__set_handler_validate(key, data): + return True + key = key.replace("DEPLOYMENT_ID|", "") + deployment_id, community_value = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) + deployment_id = int(deployment_id) + prefixes_v4 = [] + prefixes_v6 = [] + if "prefixes_v4" in data: + prefixes_v4 = str(data['prefixes_v4']).split(",") + if "prefixes_v6" in data: + prefixes_v6 = str(data['prefixes_v6']).split(",") + self.__update_policy(deployment_id, community_value, prefixes_v4, prefixes_v6) + return True + + def __set_handler_validate(self, key, data): + """ + Validate parameters of a "Set" message + :param key: ket of the 'SET' message + :param data: data of the 'SET' message + :return: True if parameters are valid, False if parameters are invalid + """ + if data is None: + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message without data") + return False + if not self.key_re.match(key): + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid key: '%s'" % key) + return False + prefixes_v4 = [] + prefixes_v6 = [] + if "prefixes_v4" in data: + prefixes_v4 = str(data["prefixes_v4"]).split(",") + if not all(TemplateFabric.is_ipv4(prefix) for prefix in prefixes_v4): + arguments = "prefixes_v4", str(data["prefixes_v4"]) + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) + return False + if "prefixes_v6" in data: + prefixes_v6 = str(data["prefixes_v6"]).split(",") + if not all(TemplateFabric.is_ipv6(prefix) for prefix in prefixes_v6): + arguments = "prefixes_v6", str(data["prefixes_v6"]) + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) + return False + if not prefixes_v4 and not prefixes_v6: + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with no prefixes specified: %s" % str(data)) + return False + return True + + def del_handler(self, key): + """ + Manager method which runs on "DEL" message + :param key: a key of "DEL" message + """ + if not self.enabled: + log_warn("BGPAllowListMgr::Received 'DEL' command, but this feature is disabled in constants") + return + if not self.__del_handler_validate(key): + return + key = key.replace('DEPLOYMENT_ID|', '') + deployment_id, community = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) + deployment_id = int(deployment_id) + self.__remove_policy(deployment_id, community) + + def __del_handler_validate(self, key): + """ + Validate "DEL" method parameters + :param key: a key of "DEL" message + :return: True if parameters are valid, False if parameters are invalid + """ + if not self.key_re.match(key): + log_err("BGPAllowListMgr::Received BGP ALLOWED 'DEL' message with invalid key: '$s'" % key) + return False + return True + + def __update_policy(self, deployment_id, community_value, prefixes_v4, prefixes_v6): + """ + Update "allow list" policy with parameters + :param deployment_id: deployment id which policy will be changed + :param community_value: community value to match for the updated policy + :param prefixes_v4: a list of v4 prefixes for the updated policy + :param prefixes_v6: a list of v6 prefixes for the updated policy + """ + # update all related entries with the information + info = deployment_id, community_value, str(prefixes_v4), str(prefixes_v6) + msg = "BGPAllowListMgr::Updating 'Allow list' policy." + msg += " deployment_id '%s'. community: '%s'" + msg += " prefix_v4 '%s'. prefix_v6: '%s'" + log_info(msg % info) + names = self.__generate_names(deployment_id, community_value) + self.cfg_mgr.update() + cmds = [] + cmds += self.__update_prefix_list(self.V4, names['pl_v4'], prefixes_v4) + cmds += self.__update_prefix_list(self.V6, names['pl_v6'], prefixes_v6) + cmds += self.__update_community(names['community'], community_value) + cmds += self.__update_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) + cmds += self.__update_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) + if cmds: + rc = self.cfg_mgr.push_list(cmds) + rc = rc and self.__restart_peers(deployment_id) + log_debug("BGPAllowListMgr::__update_policy. The peers were updated: rc=%s" % rc) + else: + log_debug("BGPAllowListMgr::__update_policy. Nothing to update") + log_info("BGPAllowListMgr::Done") + + def __remove_policy(self, deployment_id, community_value): + """ + Remove "allow list" policy for given deployment_id and community_value + :param deployment_id: deployment id which policy will be removed + :param community_value: community value to match for the removed policy + """ + # remove all related entries from the configuration + # put default rule to the route-map + info = deployment_id, community_value + msg = "BGPAllowListMgr::Removing 'Allow list' policy." + msg += " deployment_id '%s'. community: '%s'" + log_info(msg % info) + + names = self.__generate_names(deployment_id, community_value) + self.cfg_mgr.update() + cmds = [] + cmds += self.__remove_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) + cmds += self.__remove_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) + cmds += self.__remove_prefix_list(self.V4, names['pl_v4']) + cmds += self.__remove_prefix_list(self.V6, names['pl_v6']) + cmds += self.__remove_community(names['community']) + if cmds: + rc = self.cfg_mgr.push_list(cmds) + rc = rc and self.__restart_peers(deployment_id) + log_debug("BGPAllowListMgr::__remove_policy. 'Allow list' policy was removed. rc:%s" % rc) + else: + log_debug("BGPAllowListMgr::__remove_policy. Nothing to remove") + log_info('BGPAllowListMgr::Done') + + @staticmethod + def __generate_names(deployment_id, community_value): + """ + Generate prefix-list names for a given peer_ip and community value + :param deployment_id: deployment_id for which we're going to filter prefixes + :param community_value: community, which we want to use to filter prefixes + :return: a dictionary with names + """ + if community_value == BGPAllowListMgr.EMPTY_COMMUNITY: + community_name = BGPAllowListMgr.EMPTY_COMMUNITY + else: + community_name = BGPAllowListMgr.COMMUNITY_NAME_TMPL % (deployment_id, community_value) + names = { + "pl_v4": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '4'), + "pl_v6": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '6'), + "rm_v4": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '4'), + "rm_v6": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '6'), + "community": community_name, + } + arguments = deployment_id, community_value, str(names) + log_debug("BGPAllowListMgr::__generate_names. deployment_id: %d, community: %s. names: %s" % arguments) + return names + + def __update_prefix_list(self, af, pl_name, allow_list): + """ + Create or update a prefix-list with name pl_name. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :param pl_name: prefix-list name + :param allow_list: prefix-list entries + :return: True if updating was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + constant_list = self.__get_constant_list(af) + allow_list = self.__to_prefix_list(allow_list) + log_debug("BGPAllowListMgr::__update_prefix_list. af='%s' prefix-list name=%s" % (af, pl_name)) + exist, correct = self.__is_prefix_list_valid(af, pl_name, allow_list, constant_list) + if correct: + log_debug("BGPAllowListMgr::__update_prefix_list. the prefix-list '%s' exists and correct" % pl_name) + return [] + family = self.__af_to_family(af) + cmds = [] + seq_no = 10 + if exist: + cmds.append('no %s prefix-list %s' % (family, pl_name)) + for entry in constant_list + allow_list: + cmds.append('%s prefix-list %s seq %d %s' % (family, pl_name, seq_no, entry)) + seq_no += 10 + return cmds + + def __remove_prefix_list(self, af, pl_name): + """ + Remove prefix-list in the address-family af. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :param pl_name: list of prefix-list names + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + log_debug("BGPAllowListMgr::__remove_prefix_lists. af='%s' pl_names='%s'" % (af, pl_name)) + exist, _ = self.__is_prefix_list_valid(af, pl_name, [], []) + if not exist: + log_debug("BGPAllowListMgr::__remove_prefix_lists: prefix_list '%s' not found" % pl_name) + return [] + family = self.__af_to_family(af) + return ["no %s prefix-list %s" % (family, pl_name)] + + def __is_prefix_list_valid(self, af, pl_name, allow_list, constant_list): + """ + Check that a prefix list exists and it has valid entries + :param af: address family of the checked prefix-list + :param pl_name: prefix-list name + :param allow_list: a prefix-list which must be a part of the valid prefix list + :param constant_list: a constant list which must be on top of each "allow" prefix list on the device + :return: a tuple. The first element of the tuple has True if the prefix-list exists, False otherwise, + The second element of the tuple has True if the prefix-list contains correct entries, False if not + """ + assert af == self.V4 or af == self.V6 + family = self.__af_to_family(af) + match_string = '%s prefix-list %s seq ' % (family, pl_name) + conf = self.cfg_mgr.get_text() + if not any(line.strip().startswith(match_string) for line in conf): + return False, False # if the prefix list is not exists, it is not correct + constant_set = set(constant_list) + allow_set = set(allow_list) + for line in conf: + if line.startswith(match_string): + found = line[len(match_string):].strip().split(' ') + rule = " ".join(found[1:]) + if rule in constant_set: + constant_set.discard(rule) + elif rule in allow_set: + if constant_set: + return True, False # Not everything from constant set is presented + else: + allow_set.discard(rule) + return True, len(allow_set) == 0 # allow_set should be presented all + + def __update_community(self, community_name, community_value): + """ + Update community for a peer + :param community_name: name of the community to update + :param community_value: community value for the peer + :return: True if operation was successful, False otherwise + """ + log_debug("BGPAllowListMgr::__update_community. community_name='%s' community='%s'" % (community_name, community_value)) + if community_value == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community + log_debug("BGPAllowListMgr::__update_community. Empty community. exiting") + return [] + cmds = [] + exists, found_community_value = self.__is_community_presented(community_name) + if exists: + if community_value == found_community_value: + log_debug("BGPAllowListMgr::__update_community. community '%s' is already presented" % community_name) + return [] + else: + msg = "BGPAllowListMgr::__update_community. " + msg += "community '%s' is already presented, but community value should be updated" % community_name + log_debug(msg) + cmds.append("no bgp community-list standard %s" % community_name) + cmds.append('bgp community-list standard %s permit %s' % (community_name, community_value)) + return cmds + + def __remove_community(self, community_name): + """ + Remove community for a peer + :param community_name: community value for the peer + :return: True if operation was successful, False otherwise + """ + log_debug("BGPAllowListMgr::__remove_community. community='%s'" % community_name) + if community_name == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community + log_debug("BGPAllowListMgr::__remove_community. There is nothing to remove in empty community") + return [] + exists, _ = self.__is_community_presented(community_name) + if not exists: + log_debug("BGPAllowListMgr::__remove_community. Community is already removed.") + return [] + return ['no bgp community-list standard %s' % community_name] + + def __is_community_presented(self, community_name): + """ + Return True if community for the peer_ip exists + :param community_name: community value for the peer + :return: A tuple. First element: True if operation was successful, False otherwise + Second element: community value if the first element is True no value otherwise + """ + log_debug("BGPAllowListMgr::__is_community_presented. community='%s'" % community_name) + match_string = 'bgp community-list standard %s permit ' % community_name + conf = self.cfg_mgr.get_text() + found = [line.strip() for line in conf if line.strip().startswith(match_string)] + if not found: + return False, None + community_value = found[0].replace(match_string, '') + return True, community_value + + def __update_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): + """ + Add or update a "Allow address" route-map entry with the parameters + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + info = af, route_map_name, allow_address_pl_name, community_name + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) + entries = self.__parse_allow_route_map_entries(af, route_map_name) + found, _ = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) + if found: + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. route-map='%s' is already found" % route_map_name) + return [] + seq_number = self.__find_next_seq_number(entries.keys(), community_name != self.EMPTY_COMMUNITY, route_map_name) + info = af, seq_number, allow_address_pl_name, community_name + out = "af='%s' seqno='%d' Allow pl='%s' cl='%s'" % info + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. %s" % out) + ip_version = "" if af == self.V4 else "v6" + cmds = [ + 'route-map %s permit %d' % (route_map_name, seq_number), + ' match ip%s address prefix-list %s' % (ip_version, allow_address_pl_name) + ] + if not community_name.endswith(self.EMPTY_COMMUNITY): + cmds.append(" match community %s" % community_name) + return cmds + + def __remove_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): + """ + Add or update a "Allow address" route-map entry with the parameters + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + info = af, route_map_name, allow_address_pl_name, community_name + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) + entries = self.__parse_allow_route_map_entries(af, route_map_name) + found, seq_number = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) + if not found: + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. Not found route-map '%s' entry" % allow_address_pl_name) + return [] + return ['no route-map %s permit %d' % (route_map_name, seq_number)] + + @staticmethod + def __find_route_map_entry(entries, allow_address_pl_name, community_name): + """ + Find route-map entry with given allow_address prefix list name and community name in the parsed route-map. + :param entries: entries of parsed route-map + :param allow_address_pl_name: name of the "allow address" prefix-list + :param community_name: name of the "allow address" community name + :return: a tuple. The first element of the tuple is True, if the route-map entry was found, False otherwise. + The second element of the tuple has a sequence number of the entry. + """ + for sequence_number, values in entries.items(): + if sequence_number == 65535: + continue + allow_list_presented = values['pl_allow_list'] == allow_address_pl_name + community_presented = values['community'] == community_name + if allow_list_presented and community_presented: + log_debug("BGPAllowListMgr::__find_route_map_entry. found route-map '%s' entry" % allow_address_pl_name) + return True, sequence_number + return False, None + + def __parse_allow_route_map_entries(self, af, route_map_name): + """ + Parse "Allow list" route-map entries. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: A tuple, First element: True if operation was successful, False otherwise + Second element: list of object with parsed route-map entries + """ + assert af == self.V4 or af == self.V6 + log_debug("BGPAllowListMgr::__parse_allow_route_map_entries. af='%s', rm='%s'" % (af, route_map_name)) + match_string = 'route-map %s permit ' % route_map_name + entries = {} + inside_route_map = False + route_map_seq_number = None + pl_allow_list_name = None + community_name = self.EMPTY_COMMUNITY + if af == self.V4: + match_pl_allow_list = 'match ip address prefix-list ' + else: # self.V6 + match_pl_allow_list = 'match ipv6 address prefix-list ' + match_community = 'match community ' + conf = self.cfg_mgr.get_text() + for line in conf + [""]: + if inside_route_map: + if line.strip().startswith(match_pl_allow_list): + pl_allow_list_name = line.strip()[len(match_pl_allow_list):] + continue + elif line.strip().startswith(match_community): + community_name = line.strip()[len(match_community):] + continue + else: + if pl_allow_list_name is not None: + entries[route_map_seq_number] = { + 'pl_allow_list': pl_allow_list_name, + 'community': community_name, + } + else: + if route_map_seq_number != 65535: + log_warn("BGPAllowListMgr::Found incomplete route-map '%s' entry. seq_no=%d" % (route_map_name, route_map_seq_number)) + inside_route_map = False + pl_allow_list_name = None + community_name = self.EMPTY_COMMUNITY + route_map_seq_number = None + if line.startswith(match_string): + found = line[len(match_string):] + assert found.isdigit() + route_map_seq_number = int(found) + inside_route_map = True + return entries + + @staticmethod + def __find_next_seq_number(seq_numbers, has_community, route_map_name): + """ + Find a next available "Allow list" route-map entry number + :param seq_numbers: a list of already used sequence numbers + :param has_community: True, if the route-map entry has community + :return: next available route-map sequence number + """ + used_sequence_numbers = set(seq_numbers) + sequence_number = None + if has_community: # put entries without communities after 29999 + start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_START + end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_END + else: + start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START + end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END + for i in range(start_seq, end_seq, 10): + if i not in used_sequence_numbers: + sequence_number = i + break + if sequence_number is None: + raise RuntimeError("No free sequence numbers for '%s'" % route_map_name) + info = sequence_number, "yes" if has_community else "no" + log_debug("BGPAllowListMgr::__find_next_seq_number '%d' has_community='%s'" % info) + return sequence_number + + def __extract_peer_group_names(self): + """ + Extract names of all peer-groups defined in the config + :return: list of peer-group names + """ + # Find all peer-groups entries + re_peer_group = re.compile(r'^\s*neighbor (\S+) peer-group$') + peer_groups = [] + for line in self.cfg_mgr.get_text(): + result = re_peer_group.match(line) + if result: + peer_groups.append(result.group(1)) + return peer_groups + + def __get_peer_group_to_route_map(self, peer_groups): + """ + Extract names of route-maps which is connected to peer-groups defines as peer_groups + :peer_groups: a list of peer-group names + :return: dictionary where key is a peer-group, value is a route-map name which is defined as route-map in + for the peer_group. + """ + pg_2_rm = {} + for pg in peer_groups: + re_peer_group_rm = re.compile(r'^\s*neighbor %s route-map (\S+) in$' % pg) + for line in self.cfg_mgr.get_text(): + result = re_peer_group_rm.match(line) + if result: + pg_2_rm[pg] = result.group(1) + break + return pg_2_rm + + def __get_route_map_calls(self, rms): + """ + Find mapping between route-maps and route-map call names, defined for the route-maps + :rms: a set with route-map names + :return: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map + """ + rm_2_call = {} + re_rm = re.compile(r'^route-map (\S+) permit \d+$') + re_call = re.compile(r'^\s*call (\S+)$') + inside_name = None + for line in self.cfg_mgr.get_text(): + if inside_name: + inside_result = re_call.match(line) + if inside_result: + rm_2_call[inside_name] = inside_result.group(1) + inside_name = None + continue + result = re_rm.match(line) + if not result: + continue + inside_name = None + if result.group(1) not in rms: + continue + inside_name = result.group(1) + return rm_2_call + + def __get_peer_group_to_restart(self, deployment_id, pg_2_rm, rm_2_call): + """ + Get peer_groups which are assigned to deployment_id + :deployment_id: deployment_id number + :pg_2_rm: a dictionary where key is a peer-group, value is a route-map name which is defined as route-map in + for the peer_group. + :rm_2_call: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map + """ + ret = set() + target_allow_list_prefix = 'ALLOW_LIST_DEPLOYMENT_ID_%d_V' % deployment_id + for peer_group, route_map in pg_2_rm.items(): + if route_map in rm_2_call: + if rm_2_call[route_map].startswith(target_allow_list_prefix): + ret.add(peer_group) + return list(ret) + + def __find_peer_group_by_deployment_id(self, deployment_id): + """ + Deduce peer-group names which are connected to devices with requested deployment_id + :param deployment_id: deployment_id number + :return: a list of peer-groups which a used by devices with requested deployment_id number + """ + self.cfg_mgr.update() + peer_groups = self.__extract_peer_group_names() + pg_2_rm = self.__get_peer_group_to_route_map(peer_groups) + rm_2_call = self.__get_route_map_calls(set(pg_2_rm.values())) + ret = self.__get_peer_group_to_restart(deployment_id, pg_2_rm, rm_2_call) + return list(ret) + + def __restart_peers(self, deployment_id): + """ + Restart peer-groups with requested deployment_id + :param deployment_id: deployment_id number + """ + log_info("BGPAllowListMgr::Restart peers with deployment_id=%d" % deployment_id) + peer_groups = self.__find_peer_group_by_deployment_id(deployment_id) + rv = True + if peer_groups: + for peer_group in peer_groups: + no_error, _, _ = run_command(["vtysh", "-c", "clear bgp peer-group %s soft in" % peer_group]) + rv = no_error == 0 and rv + else: + no_error, _, _ = run_command(["vtysh", "-c", "clear bgp * soft in"]) + rv = no_error == 0 + return rv + + def __get_enabled(self): + """ + Load enable/disabled property from constants + :return: True if enabled, False otherwise + """ + return 'bgp' in self.constants \ + and 'allow_list' in self.constants["bgp"] \ + and "enabled" in self.constants["bgp"]["allow_list"] \ + and self.constants["bgp"]["allow_list"]["enabled"] + + def __load_constant_lists(self): + """ + Load default prefix-list entries from constants.yml file + """ + if 'bgp' in self.constants and 'allow_list' in self.constants["bgp"] \ + and "default_pl_rules" in self.constants["bgp"]["allow_list"]: + obj = self.constants["bgp"]["allow_list"]["default_pl_rules"] + if "v4" in obj: + self.constants_v4 = obj["v4"] + else: + self.constants_v4 = [] + if "v6" in obj: + self.constants_v6 = obj["v6"] + else: + self.constants_v6 = [] + + def __get_constant_list(self, af): + """ + Return loaded default prefix-list entries bases on address family + :param af: address family + :return: default prefix-list entries + """ + if af == self.V4: + return self.constants_v4 + else: + return self.constants_v6 + + @staticmethod + def __to_prefix_list(allow_list): + """ + Convert "allow list" prefix list, to a prefix-list rules + :param allow_list: "allow list" prefix list + :return: prefix-list rules + """ + return ["permit %s ge %d" % (prefix, int(prefix.split("/")[1])+1) for prefix in allow_list] + + def __af_to_family(self, af): + """ + Convert address family into prefix list family + :param af: address family + :return: prefix list ip family + """ + return 'ip' if af == self.V4 else 'ipv6' diff --git a/src/sonic-bgpcfgd/app/config.py b/src/sonic-bgpcfgd/app/config.py index 26639fe75e89..a0c1329f832e 100644 --- a/src/sonic-bgpcfgd/app/config.py +++ b/src/sonic-bgpcfgd/app/config.py @@ -10,19 +10,33 @@ class ConfigMgr(object): """ The class represents frr configuration """ def __init__(self): self.current_config = None + self.current_config_raw = None def reset(self): """ Reset stored config """ self.current_config = None + self.current_config_raw = None def update(self): """ Read current config from FRR """ self.current_config = None + self.current_config_raw = None ret_code, out, err = run_command(["vtysh", "-c", "show running-config"]) if ret_code != 0: + # FIXME: should we throw exception here? 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) + text = [] + for line in out.split('\n'): + if line.lstrip().startswith('!'): + continue + text.append(line) + text += [" "] # Add empty line to have something to work on, if there is no text + self.current_config_raw = text + self.current_config = self.to_canonical(out) # FIXME: use test as an input + + def push_list(self, cmdlist): + return self.push("\n".join(cmdlist)) def push(self, cmd): """ @@ -51,8 +65,12 @@ def write(self, cmd): 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 + self.current_config_raw = None return ret_code == 0 + def get_text(self): + return self.current_config_raw + @staticmethod def to_canonical(raw_config): """ diff --git a/src/sonic-bgpcfgd/app/directory.py b/src/sonic-bgpcfgd/app/directory.py new file mode 100644 index 000000000000..d27ec64256e3 --- /dev/null +++ b/src/sonic-bgpcfgd/app/directory.py @@ -0,0 +1,159 @@ +from collections import defaultdict + +from app.log import log_err + + +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) # 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 == '': + return True, self.data[slot] + d = self.data[slot] + for p in path.split("/"): + if p not in d: + return False, None + d = d[p] + return True, d + + 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, 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, 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(db, table, path): + for handler in self.notify[slot][path]: + handler() + + 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 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: + log_err("Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) + else: + log_err("Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) + + 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: + log_err("Directory: Can't remove slot '%s'. The slot doesn't exist" % 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 db, table, path in deps: + res = res and self.path_exist(db, table, path) + return res + + def subscribe(self, deps, handler): + """ + 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) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/manager.py b/src/sonic-bgpcfgd/app/manager.py new file mode 100644 index 000000000000..ba45029b5120 --- /dev/null +++ b/src/sonic-bgpcfgd/app/manager.py @@ -0,0 +1,71 @@ +from swsscommon import swsscommon + +from app.log import log_debug, log_err + + +class Manager(object): + """ 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 = [] + 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): # all required dependencies are set in the Directory? + res = self.set_handler(key, data) + 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: + 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 = [] + for key, data in self.set_queue: + res = self.set_handler(key, data) + if not res: + new_queue.append((key, data)) + self.set_queue = new_queue + + def set_handler(self, key, data): + """ Placeholder for 'SET' command """ + log_err("set_handler() wasn't implemented for %s" % self.__class__.__name__) + + def del_handler(self, key): + """ Placeholder for 'DEL' command """ + log_err("del_handler wasn't implemented for %s" % self.__class__.__name__) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/vars.py b/src/sonic-bgpcfgd/app/vars.py index 11377fc87f93..18bee5578e25 100644 --- a/src/sonic-bgpcfgd/app/vars.py +++ b/src/sonic-bgpcfgd/app/vars.py @@ -1 +1 @@ -g_debug = False +g_debug = True # FIXME: read from env variable, or from constants diff --git a/src/sonic-bgpcfgd/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd index 3bedd8679004..59dc35c25e21 100755 --- a/src/sonic-bgpcfgd/bgpcfgd +++ b/src/sonic-bgpcfgd/bgpcfgd @@ -15,10 +15,13 @@ import jinja2 import netaddr from swsscommon import swsscommon +from app.directory import Directory +from app.manager import Manager from app.vars import g_debug from app.log import log_debug, log_notice, log_info, log_warn, log_err, log_crit from app.template import TemplateFabric from app.config import ConfigMgr +from app.allow_list import BGPAllowListMgr from app.util import run_command g_run = True @@ -846,7 +849,7 @@ def wait_for_daemons(daemons, 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) + content = yaml.load(fp) # FIXME: , Loader=yaml.FullLoader) 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") @@ -878,6 +881,8 @@ def main(): BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", True), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), + # AllowList Managers + BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), ] runner = Runner() for mgr in managers: diff --git a/src/sonic-bgpcfgd/pytest.ini b/src/sonic-bgpcfgd/pytest.ini new file mode 100644 index 000000000000..639ceb636af9 --- /dev/null +++ b/src/sonic-bgpcfgd/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +addopts = --cov=app --cov-report term diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index 29d441e09a66..fc0839dff7fc 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -16,5 +16,6 @@ ] }, install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], - setup_requires=['pytest-runner', 'pytest'], + setup_requires=['pytest-runner'], + test_requires=['pytest', 'pytest-cov'], ) diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json index 148456fe960f..08f1eef63267 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json @@ -4,5 +4,14 @@ "sub_role": "BackEnd" } }, - "loopback0_ipv4": "10.10.10.10/32" -} \ No newline at end of file + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": true, + "default_action": "permit", + "drop_community": "12345:12345" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json index 53bf5572eff3..958c9b0fbd4b 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json @@ -4,5 +4,12 @@ "sub_role": "NotBackEnd" } }, - "loopback0_ipv4": "10.10.10.10/32" -} \ No newline at end of file + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": false + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json new file mode 100644 index 000000000000..669810960c92 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json @@ -0,0 +1,17 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "BackEnd" + } + }, + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": true, + "default_action": "deny", + "drop_community": "12345:12345" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf index 1e3288b9a7da..9e6c32b17ead 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf @@ -1,6 +1,20 @@ ! ! template: bgpd/templates/general/policies.conf.j2 ! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community 12345:12345 additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community 12345:12345 additive +! +route-map FROM_BGP_PEER_V4 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf new file mode 100644 index 000000000000..6e0389fc1886 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf @@ -0,0 +1,39 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community no-export additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community no-export additive +! +route-map FROM_BGP_PEER_V4 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! +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 +! +route-map FROM_BGP_PEER_V4_INT permit 2 + set originator-id 10.10.10.10 +! +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 10.10.10.10 +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/test_allow_list.py b/src/sonic-bgpcfgd/tests/test_allow_list.py new file mode 100644 index 000000000000..196a28a1aa18 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_allow_list.py @@ -0,0 +1,469 @@ +from app.allow_list import BGPAllowListMgr +from app.directory import Directory +from app.template import TemplateFabric +import app +from mock import MagicMock + + +global_constants = { + "bgp": { + "allow_list": { + "enabled": True, + "default_pl_rules": { + "v4": [ "deny 0.0.0.0/0 le 17" ], + "v6": [ + "deny 0::/0 le 59", + "deny 0::/0 ge 65" + ] + } + } + } +} + +def set_del_test(op, args, currect_config, expected_config): + set_del_test.push_list_called = False + def push_list(args): + set_del_test.push_list_called = True + assert args == expected_config + return True + # + app.allow_list.run_command = lambda cmd: (0, "", "") + # + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.push_list = push_list + cfg_mgr.get_text.return_value = currect_config + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + if op == "SET": + mgr.set_handler(*args) + elif op == "DEL": + mgr.del_handler(*args) + else: + assert False, "Wrong operation" + if expected_config: + assert set_del_test.push_list_called, "cfg_mgr.push_list wasn't called" + else: + assert not set_del_test.push_list_called, "cfg_mgr.push_list was called" + +def test_set_handler_with_community(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64", + }), + [], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + ] + ) + +def test_set_handler_no_community(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }), + [], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + ] + ) + +def test_del_handler_with_community(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + "" + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'no bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + ] + ) + +def test_del_handler_no_community(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + " " + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + ] + ) + +def test_set_handler_with_community_data_is_already_presented(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + "" + ], + [] + ) + +def test_set_handler_no_community_data_is_already_presented(): + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.get_text.return_value = [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + "" + ] + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + mgr.set_handler("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }) + assert not cfg_mgr.push_list.called, "cfg_mgr.push_list was called, but it shouldn't have been" + +def test_del_handler_with_community_no_data(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [""], + [] + ) + +def test_del_handler_no_community_no_data(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5",), + [""], + [] + ) + +def test_set_handler_with_community_update_prefixes_add(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16,80.90.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64,fc02::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + "" + ], + [ + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 40 permit 80.90.0.0/16 ge 17', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 50 permit fc02::/64 ge 65', + ] + ) + +def test_set_handler_no_community_update_prefixes_add(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16,80.90.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64,fc02::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + "" + ], + [ + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 40 permit 80.90.0.0/16 ge 17', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 50 permit fc02::/64 ge 65', + ] + ) + +def test___set_handler_validate(): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + data = { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + } + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", None) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID1|5|1010:2020", data) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|z|1010:2020", data) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "20.20.30.0/24,40.50.0.0/16", + }) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "fc01:20::/64,fc01:30::/64", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }) + +def test___find_peer_group_by_deployment_id(): + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.get_text.return_value = [ + 'router bgp 64601', + ' neighbor BGPSLBPassive peer-group', + ' neighbor BGPSLBPassive remote-as 65432', + ' neighbor BGPSLBPassive passive', + ' neighbor BGPSLBPassive ebgp-multihop 255', + ' neighbor BGPSLBPassive update-source 10.1.0.32', + ' neighbor PEER_V4 peer-group', + ' neighbor PEER_V4_INT peer-group', + ' neighbor PEER_V6 peer-group', + ' neighbor PEER_V6_INT peer-group', + ' neighbor 10.0.0.1 remote-as 64802', + ' neighbor 10.0.0.1 peer-group PEER_V4', + ' neighbor 10.0.0.1 description ARISTA01T1', + ' neighbor 10.0.0.1 timers 3 10', + ' neighbor fc00::2 remote-as 64802', + ' neighbor fc00::2 peer-group PEER_V6', + ' neighbor fc00::2 description ARISTA01T1', + ' neighbor fc00::2 timers 3 10', + ' address-family ipv4 unicast', + ' neighbor BGPSLBPassive activate', + ' neighbor BGPSLBPassive soft-reconfiguration inbound', + ' neighbor BGPSLBPassive route-map FROM_BGP_SPEAKER in', + ' neighbor BGPSLBPassive route-map TO_BGP_SPEAKER out', + ' neighbor PEER_V4 soft-reconfiguration inbound', + ' neighbor PEER_V4 allowas-in 1', + ' neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in', + ' neighbor PEER_V4 route-map TO_BGP_PEER_V4 out', + ' neighbor PEER_V4_INT soft-reconfiguration inbound', + ' neighbor PEER_V4_INT allowas-in 1', + ' neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in', + ' neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out', + ' neighbor 10.0.0.1 activate', + ' exit-address-family', + ' address-family ipv6 unicast', + ' neighbor BGPSLBPassive activate', + ' neighbor PEER_V6 soft-reconfiguration inbound', + ' neighbor PEER_V6 allowas-in 1', + ' neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in', + ' neighbor PEER_V6 route-map TO_BGP_PEER_V6 out', + ' neighbor PEER_V6_INT soft-reconfiguration inbound', + ' neighbor PEER_V6_INT allowas-in 1', + ' neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in', + ' neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out', + ' neighbor fc00::2 activate', + ' exit-address-family', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 10', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535', + ' set community 5060:12345 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 10', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535', + ' set community 5060:12345 additive', + 'route-map FROM_BGP_PEER_V4 permit 100', + 'route-map FROM_BGP_PEER_V4 permit 2', + ' call ALLOW_LIST_DEPLOYMENT_ID_0_V4', + ' on-match next', + 'route-map FROM_BGP_PEER_V6 permit 1', + ' set ipv6 next-hop prefer-global ', + 'route-map FROM_BGP_PEER_V6 permit 100', + 'route-map FROM_BGP_PEER_V6 permit 2', + ' call ALLOW_LIST_DEPLOYMENT_ID_0_V6', + ' on-match next', + 'route-map FROM_BGP_SPEAKER permit 10', + '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', + 'route-map TO_BGP_PEER_V4 permit 100', + 'route-map TO_BGP_PEER_V6 permit 100', + 'route-map TO_BGP_SPEAKER deny 1', + ] + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + values = mgr._BGPAllowListMgr__find_peer_group_by_deployment_id(0) + assert values == ['PEER_V4_INT', 'PEER_V6_INT', 'PEER_V6', 'PEER_V4'] + +def test___restart_peers_found_deployment_id(): + test___restart_peers_found_deployment_id.run_command_counter = 0 + def run_command(cmd): + output = [ + ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_1 soft in'], + ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_2 soft in'], + ] + desired_value = output[test___restart_peers_found_deployment_id.run_command_counter] + assert cmd == desired_value + test___restart_peers_found_deployment_id.run_command_counter += 1 + return 0, "", "" + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') + mocked.return_value = ["BGP_TEST_PEER_GROUP_1", "BGP_TEST_PEER_GROUP_2"] + mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked + app.allow_list.run_command = run_command + rc = mgr._BGPAllowListMgr__restart_peers(5) + assert rc + +def test___restart_peers_not_found_deployment_id(): + def run_command(cmd): + assert cmd == ['vtysh', '-c', 'clear bgp * soft in'] + return 0, "", "" + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') + mocked.return_value = [] + mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked + app.allow_list.run_command = run_command + rc = mgr._BGPAllowListMgr__restart_peers(5) + assert rc + +# FIXME: more testcases for coverage diff --git a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py index bc6d01cdb536..686b1ade65e1 100644 --- a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py +++ b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py @@ -77,21 +77,30 @@ def extract_rm_from_peer_group(path, peer_group_name): return list(rm_set) def check_routemap_in_file(filename, route_map_name): - route_map_re = re.compile(r'^route-map\s+%s\s+(\S+)' % route_map_name) + route_map_re = re.compile(r'^route-map\s+%s\s+permit\s+(\d+)' % route_map_name) set_re = re.compile(r'set ipv6 next-hop prefer-global') with open(filename) as fp: lines = [line.strip() for line in fp if not line.strip().startswith('!') and line.strip() != ''] - found_first_entry = False + found_entry = False + found_seq_no = None + route_map_entries = {} for line in lines: - err_msg = "route-map %s doesn't have mandatory 'set ipv6 next-hop prefer-global' entry as the first rule" % route_map_name - assert not (found_first_entry and line.startswith("route-map")), err_msg - if found_first_entry and set_re.match(line): - break # We're good + if found_entry: + route_map_entries[found_seq_no] = set_re.match(line) is not None + found_entry = False + found_seq_no = None if route_map_re.match(line): - err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name - assert route_map_re.match(line).group(1) == 'permit', err_msg - found_first_entry = True - return found_first_entry + found_seq_no = None + seq_n_txt = route_map_re.match(line).group(1) + assert seq_n_txt.isdigit(), "wrong sequence number for line '%s'" % line + found_seq_no = int(seq_n_txt) + assert found_seq_no not in route_map_entries, "Route-map has duplicate entries: %s - %d" % (route_map_name, found_seq_no) + found_entry = True + results = [route_map_entries[seq] for seq in sorted(route_map_entries.keys())] + if (len(results)): + err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name + assert results[0], err_msg + return len(results) > 0 def check_routemap(path, route_map_name): result_files = load_results(path, "policies.conf") diff --git a/src/sonic-bgpcfgd/tests/util.py b/src/sonic-bgpcfgd/tests/util.py index 0bc12b060aec..aa6c62a56b5f 100644 --- a/src/sonic-bgpcfgd/tests/util.py +++ b/src/sonic-bgpcfgd/tests/util.py @@ -5,7 +5,7 @@ def load_constants(): with open(CONSTANTS_PATH) as f: - data = yaml.load(f) + data = yaml.load(f) # FIXME" , Loader=yaml.FullLoader) result = {} assert "constants" in data, "'constants' key not found in constants.yml" assert "bgp" in data["constants"], "'bgp' key not found in constants.yml" @@ -13,4 +13,4 @@ def load_constants(): for name, value in data["constants"]["bgp"]["peers"].items(): assert "template_dir" in value, "'template_dir' key not found for peer '%s'" % name result[name] = value["template_dir"] - return result \ No newline at end of file + return result From e3f81596061e6a1a1419a4ce93601e8e0fa44afc Mon Sep 17 00:00:00 2001 From: bingwang-ms <66248323+bingwang-ms@users.noreply.github.com> Date: Mon, 28 Sep 2020 02:31:45 +0800 Subject: [PATCH 35/78] [sonic_py_common] Fix exception in daemon_base.py (#5472) There is a syntax error (self is missing for log_info and log_warning) in signal_handler in daemon_base.py, which causes an exception --- src/sonic-py-common/sonic_py_common/daemon_base.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/daemon_base.py b/src/sonic-py-common/sonic_py_common/daemon_base.py index 97bf3011b6e4..818be5fa4305 100644 --- a/src/sonic-py-common/sonic_py_common/daemon_base.py +++ b/src/sonic-py-common/sonic_py_common/daemon_base.py @@ -44,15 +44,15 @@ def __init__(self, log_identifier): # Default signal handler; can be overridden by subclass def signal_handler(self, sig, frame): if sig == signal.SIGHUP: - log_info("DaemonBase: Caught SIGHUP - ignoring...") + self.log_info("DaemonBase: Caught SIGHUP - ignoring...") elif sig == signal.SIGINT: - log_info("DaemonBase: Caught SIGINT - exiting...") + self.log_info("DaemonBase: Caught SIGINT - exiting...") sys.exit(128 + sig) elif sig == signal.SIGTERM: - log_info("DaemonBase: Caught SIGTERM - exiting...") + self.log_info("DaemonBase: Caught SIGTERM - exiting...") sys.exit(128 + sig) else: - log_warning("DaemonBase: Caught unhandled signal '{}'".format(sig)) + self.log_warning("DaemonBase: Caught unhandled signal '{}'".format(sig)) # Loads platform specific platform module from source def load_platform_util(self, module_name, class_name): From e412338743366969d2639f9e37943ae36e7271c7 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 28 Sep 2020 22:00:29 -0700 Subject: [PATCH 36/78] Revert "[bgp] Add 'allow list' manager feature (#5309)" This reverts commit 6eed0820c8014135e987d1615c14670b4d785f7f. --- .../bgpd/templates/general/peer-group.conf.j2 | 2 +- .../bgpd/templates/general/policies.conf.j2 | 27 - files/image_config/constants/constants.yml | 12 - rules/sonic_bgpcfgd.mk | 3 +- src/sonic-bgpcfgd/.gitignore | 1 - src/sonic-bgpcfgd/app/allow_list.py | 632 ------------------ src/sonic-bgpcfgd/app/config.py | 20 +- src/sonic-bgpcfgd/app/directory.py | 159 ----- src/sonic-bgpcfgd/app/manager.py | 71 -- src/sonic-bgpcfgd/app/vars.py | 2 +- src/sonic-bgpcfgd/bgpcfgd | 7 +- src/sonic-bgpcfgd/pytest.ini | 2 - src/sonic-bgpcfgd/setup.py | 3 +- .../data/general/policies.conf/param_all.json | 13 +- .../general/policies.conf/param_base.json | 11 +- .../general/policies.conf/param_deny.json | 17 - .../general/policies.conf/result_all.conf | 14 - .../general/policies.conf/result_deny.conf | 39 -- src/sonic-bgpcfgd/tests/test_allow_list.py | 469 ------------- .../tests/test_ipv6_nexthop_global.py | 29 +- src/sonic-bgpcfgd/tests/util.py | 4 +- 21 files changed, 22 insertions(+), 1515 deletions(-) delete mode 100644 src/sonic-bgpcfgd/app/allow_list.py delete mode 100644 src/sonic-bgpcfgd/app/directory.py delete mode 100644 src/sonic-bgpcfgd/app/manager.py delete mode 100644 src/sonic-bgpcfgd/pytest.ini delete mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json delete mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf delete mode 100644 src/sonic-bgpcfgd/tests/test_allow_list.py 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 index 5790d47a5a8a..b0acd1b2a460 100644 --- 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 @@ -24,7 +24,7 @@ {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V6 allowas-in 1 neighbor PEER_V6_INT allowas-in 1 -{% endif %} + {% endif %} {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor PEER_V6_INT route-reflector-client {% endif %} 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 index 4c27db4a466a..c545cf272892 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -3,33 +3,6 @@ ! ! ! -{% if constants.bgp.allow_list is defined and constants.bgp.allow_list.enabled is defined and constants.bgp.allow_list.enabled %} -{% if constants.bgp.allow_list.default_action is defined and constants.bgp.allow_list.default_action.strip() == 'deny' %} -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 - set community no-export additive -! -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 - set community no-export additive -{% else %} -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 - set community {{ constants.bgp.allow_list.drop_community }} additive -! -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 - set community {{ constants.bgp.allow_list.drop_community }} additive -{% endif %} -! -route-map FROM_BGP_PEER_V4 permit 2 - call ALLOW_LIST_DEPLOYMENT_ID_0_V4 - on-match next -! -route-map FROM_BGP_PEER_V6 permit 2 - call ALLOW_LIST_DEPLOYMENT_ID_0_V6 - on-match next -! -{% endif %} -! -! -! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index 074956ff8396..3e1b76be0157 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -18,18 +18,6 @@ constants: enabled: true ipv4: 64 ipv6: 64 - allow_list: - enabled: true - default_action: "permit" # or "deny" - drop_community: 5060:12345 # value of the community to identify a prefix to drop. Make sense only with allow_list_default_action equal to 'permit' - default_pl_rules: - v4: - - "deny 0.0.0.0/0 le 17" - - "permit 127.0.0.1/32" - v6: - - "deny 0::/0 le 59" - - "deny 0::/0 ge 65" - - "permit fe80::/64" peers: general: # peer_type db_table: "BGP_NEIGHBOR" diff --git a/rules/sonic_bgpcfgd.mk b/rules/sonic_bgpcfgd.mk index 7a9cae29cf19..32abbd5af948 100644 --- a/rules/sonic_bgpcfgd.mk +++ b/rules/sonic_bgpcfgd.mk @@ -6,7 +6,6 @@ $(SONIC_BGPCFGD)_SRC_PATH = $(SRC_PATH)/sonic-bgpcfgd # of sonic-config-engine and bgpcfgd explicitly calls sonic-cfggen # as part of its unit tests. # TODO: Refactor unit tests so that these dependencies are not needed -$(SONIC_BGPCFGD)_DEPENDS += $(SONIC_PY_COMMON_PY2) -$(SONIC_BGPCFGD)_DEBS_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) +$(SONIC_BGPCFGD)_DEPENDS += $(SWSSSDK_PY2) $(SONIC_PY_COMMON_PY2) $(SONIC_BGPCFGD)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_BGPCFGD) diff --git a/src/sonic-bgpcfgd/.gitignore b/src/sonic-bgpcfgd/.gitignore index 920a1b3ae499..bb1ba531d1d6 100644 --- a/src/sonic-bgpcfgd/.gitignore +++ b/src/sonic-bgpcfgd/.gitignore @@ -6,4 +6,3 @@ app/*.pyc tests/*.pyc tests/__pycache__/ .idea -.coverage diff --git a/src/sonic-bgpcfgd/app/allow_list.py b/src/sonic-bgpcfgd/app/allow_list.py deleted file mode 100644 index 2637d6999244..000000000000 --- a/src/sonic-bgpcfgd/app/allow_list.py +++ /dev/null @@ -1,632 +0,0 @@ -""" -Implementation of "allow-list" feature -""" -import re - -from app.log import log_debug, log_info, log_err, log_warn -from app.template import TemplateFabric -from app.manager import Manager -from app.util import run_command - -class BGPAllowListMgr(Manager): - """ This class initialize "AllowList" settings """ - ALLOW_ADDRESS_PL_NAME_TMPL = "ALLOW_ADDRESS_%d_%s" # template for a name for the ALLOW_ADDRESS prefix-list ??? - EMPTY_COMMUNITY = "empty" - PL_NAME_TMPL = "PL_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s_V%s" - COMMUNITY_NAME_TMPL = "COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s" - RM_NAME_TMPL = "ALLOW_LIST_DEPLOYMENT_ID_%d_V%s" - ROUTE_MAP_ENTRY_WITH_COMMUNITY_START = 10 - ROUTE_MAP_ENTRY_WITH_COMMUNITY_END = 29990 - ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START = 30000 - ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END = 65530 - - V4 = "v4" # constant for af enum: V4 - V6 = "v6" # constant for af enum: V6 - - 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(BGPAllowListMgr, self).__init__( - common_objs, - [], - db, - table, - ) - self.cfg_mgr = common_objs["cfg_mgr"] - self.constants = common_objs["constants"] - self.key_re = re.compile(r"^DEPLOYMENT_ID\|\d+\|\S+$|^DEPLOYMENT_ID\|\d+$") - self.enabled = self.__get_enabled() - self.__load_constant_lists() - - def set_handler(self, key, data): - """ - Manager method which runs on receiving 'SET' message - :param key: ket of the 'SET' message - :param data: data of the 'SET' message - :return: True if the message was executed, False - the message should be postponed. - """ - if not self.enabled: - log_warn("BGPAllowListMgr::Received 'SET' command, but this feature is disabled in constants") - return True - if not self.__set_handler_validate(key, data): - return True - key = key.replace("DEPLOYMENT_ID|", "") - deployment_id, community_value = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) - deployment_id = int(deployment_id) - prefixes_v4 = [] - prefixes_v6 = [] - if "prefixes_v4" in data: - prefixes_v4 = str(data['prefixes_v4']).split(",") - if "prefixes_v6" in data: - prefixes_v6 = str(data['prefixes_v6']).split(",") - self.__update_policy(deployment_id, community_value, prefixes_v4, prefixes_v6) - return True - - def __set_handler_validate(self, key, data): - """ - Validate parameters of a "Set" message - :param key: ket of the 'SET' message - :param data: data of the 'SET' message - :return: True if parameters are valid, False if parameters are invalid - """ - if data is None: - log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message without data") - return False - if not self.key_re.match(key): - log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid key: '%s'" % key) - return False - prefixes_v4 = [] - prefixes_v6 = [] - if "prefixes_v4" in data: - prefixes_v4 = str(data["prefixes_v4"]).split(",") - if not all(TemplateFabric.is_ipv4(prefix) for prefix in prefixes_v4): - arguments = "prefixes_v4", str(data["prefixes_v4"]) - log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) - return False - if "prefixes_v6" in data: - prefixes_v6 = str(data["prefixes_v6"]).split(",") - if not all(TemplateFabric.is_ipv6(prefix) for prefix in prefixes_v6): - arguments = "prefixes_v6", str(data["prefixes_v6"]) - log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) - return False - if not prefixes_v4 and not prefixes_v6: - log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with no prefixes specified: %s" % str(data)) - return False - return True - - def del_handler(self, key): - """ - Manager method which runs on "DEL" message - :param key: a key of "DEL" message - """ - if not self.enabled: - log_warn("BGPAllowListMgr::Received 'DEL' command, but this feature is disabled in constants") - return - if not self.__del_handler_validate(key): - return - key = key.replace('DEPLOYMENT_ID|', '') - deployment_id, community = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) - deployment_id = int(deployment_id) - self.__remove_policy(deployment_id, community) - - def __del_handler_validate(self, key): - """ - Validate "DEL" method parameters - :param key: a key of "DEL" message - :return: True if parameters are valid, False if parameters are invalid - """ - if not self.key_re.match(key): - log_err("BGPAllowListMgr::Received BGP ALLOWED 'DEL' message with invalid key: '$s'" % key) - return False - return True - - def __update_policy(self, deployment_id, community_value, prefixes_v4, prefixes_v6): - """ - Update "allow list" policy with parameters - :param deployment_id: deployment id which policy will be changed - :param community_value: community value to match for the updated policy - :param prefixes_v4: a list of v4 prefixes for the updated policy - :param prefixes_v6: a list of v6 prefixes for the updated policy - """ - # update all related entries with the information - info = deployment_id, community_value, str(prefixes_v4), str(prefixes_v6) - msg = "BGPAllowListMgr::Updating 'Allow list' policy." - msg += " deployment_id '%s'. community: '%s'" - msg += " prefix_v4 '%s'. prefix_v6: '%s'" - log_info(msg % info) - names = self.__generate_names(deployment_id, community_value) - self.cfg_mgr.update() - cmds = [] - cmds += self.__update_prefix_list(self.V4, names['pl_v4'], prefixes_v4) - cmds += self.__update_prefix_list(self.V6, names['pl_v6'], prefixes_v6) - cmds += self.__update_community(names['community'], community_value) - cmds += self.__update_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) - cmds += self.__update_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) - if cmds: - rc = self.cfg_mgr.push_list(cmds) - rc = rc and self.__restart_peers(deployment_id) - log_debug("BGPAllowListMgr::__update_policy. The peers were updated: rc=%s" % rc) - else: - log_debug("BGPAllowListMgr::__update_policy. Nothing to update") - log_info("BGPAllowListMgr::Done") - - def __remove_policy(self, deployment_id, community_value): - """ - Remove "allow list" policy for given deployment_id and community_value - :param deployment_id: deployment id which policy will be removed - :param community_value: community value to match for the removed policy - """ - # remove all related entries from the configuration - # put default rule to the route-map - info = deployment_id, community_value - msg = "BGPAllowListMgr::Removing 'Allow list' policy." - msg += " deployment_id '%s'. community: '%s'" - log_info(msg % info) - - names = self.__generate_names(deployment_id, community_value) - self.cfg_mgr.update() - cmds = [] - cmds += self.__remove_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) - cmds += self.__remove_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) - cmds += self.__remove_prefix_list(self.V4, names['pl_v4']) - cmds += self.__remove_prefix_list(self.V6, names['pl_v6']) - cmds += self.__remove_community(names['community']) - if cmds: - rc = self.cfg_mgr.push_list(cmds) - rc = rc and self.__restart_peers(deployment_id) - log_debug("BGPAllowListMgr::__remove_policy. 'Allow list' policy was removed. rc:%s" % rc) - else: - log_debug("BGPAllowListMgr::__remove_policy. Nothing to remove") - log_info('BGPAllowListMgr::Done') - - @staticmethod - def __generate_names(deployment_id, community_value): - """ - Generate prefix-list names for a given peer_ip and community value - :param deployment_id: deployment_id for which we're going to filter prefixes - :param community_value: community, which we want to use to filter prefixes - :return: a dictionary with names - """ - if community_value == BGPAllowListMgr.EMPTY_COMMUNITY: - community_name = BGPAllowListMgr.EMPTY_COMMUNITY - else: - community_name = BGPAllowListMgr.COMMUNITY_NAME_TMPL % (deployment_id, community_value) - names = { - "pl_v4": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '4'), - "pl_v6": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '6'), - "rm_v4": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '4'), - "rm_v6": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '6'), - "community": community_name, - } - arguments = deployment_id, community_value, str(names) - log_debug("BGPAllowListMgr::__generate_names. deployment_id: %d, community: %s. names: %s" % arguments) - return names - - def __update_prefix_list(self, af, pl_name, allow_list): - """ - Create or update a prefix-list with name pl_name. - :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list - :param pl_name: prefix-list name - :param allow_list: prefix-list entries - :return: True if updating was successful, False otherwise - """ - assert af == self.V4 or af == self.V6 - constant_list = self.__get_constant_list(af) - allow_list = self.__to_prefix_list(allow_list) - log_debug("BGPAllowListMgr::__update_prefix_list. af='%s' prefix-list name=%s" % (af, pl_name)) - exist, correct = self.__is_prefix_list_valid(af, pl_name, allow_list, constant_list) - if correct: - log_debug("BGPAllowListMgr::__update_prefix_list. the prefix-list '%s' exists and correct" % pl_name) - return [] - family = self.__af_to_family(af) - cmds = [] - seq_no = 10 - if exist: - cmds.append('no %s prefix-list %s' % (family, pl_name)) - for entry in constant_list + allow_list: - cmds.append('%s prefix-list %s seq %d %s' % (family, pl_name, seq_no, entry)) - seq_no += 10 - return cmds - - def __remove_prefix_list(self, af, pl_name): - """ - Remove prefix-list in the address-family af. - :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list - :param pl_name: list of prefix-list names - :return: True if operation was successful, False otherwise - """ - assert af == self.V4 or af == self.V6 - log_debug("BGPAllowListMgr::__remove_prefix_lists. af='%s' pl_names='%s'" % (af, pl_name)) - exist, _ = self.__is_prefix_list_valid(af, pl_name, [], []) - if not exist: - log_debug("BGPAllowListMgr::__remove_prefix_lists: prefix_list '%s' not found" % pl_name) - return [] - family = self.__af_to_family(af) - return ["no %s prefix-list %s" % (family, pl_name)] - - def __is_prefix_list_valid(self, af, pl_name, allow_list, constant_list): - """ - Check that a prefix list exists and it has valid entries - :param af: address family of the checked prefix-list - :param pl_name: prefix-list name - :param allow_list: a prefix-list which must be a part of the valid prefix list - :param constant_list: a constant list which must be on top of each "allow" prefix list on the device - :return: a tuple. The first element of the tuple has True if the prefix-list exists, False otherwise, - The second element of the tuple has True if the prefix-list contains correct entries, False if not - """ - assert af == self.V4 or af == self.V6 - family = self.__af_to_family(af) - match_string = '%s prefix-list %s seq ' % (family, pl_name) - conf = self.cfg_mgr.get_text() - if not any(line.strip().startswith(match_string) for line in conf): - return False, False # if the prefix list is not exists, it is not correct - constant_set = set(constant_list) - allow_set = set(allow_list) - for line in conf: - if line.startswith(match_string): - found = line[len(match_string):].strip().split(' ') - rule = " ".join(found[1:]) - if rule in constant_set: - constant_set.discard(rule) - elif rule in allow_set: - if constant_set: - return True, False # Not everything from constant set is presented - else: - allow_set.discard(rule) - return True, len(allow_set) == 0 # allow_set should be presented all - - def __update_community(self, community_name, community_value): - """ - Update community for a peer - :param community_name: name of the community to update - :param community_value: community value for the peer - :return: True if operation was successful, False otherwise - """ - log_debug("BGPAllowListMgr::__update_community. community_name='%s' community='%s'" % (community_name, community_value)) - if community_value == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community - log_debug("BGPAllowListMgr::__update_community. Empty community. exiting") - return [] - cmds = [] - exists, found_community_value = self.__is_community_presented(community_name) - if exists: - if community_value == found_community_value: - log_debug("BGPAllowListMgr::__update_community. community '%s' is already presented" % community_name) - return [] - else: - msg = "BGPAllowListMgr::__update_community. " - msg += "community '%s' is already presented, but community value should be updated" % community_name - log_debug(msg) - cmds.append("no bgp community-list standard %s" % community_name) - cmds.append('bgp community-list standard %s permit %s' % (community_name, community_value)) - return cmds - - def __remove_community(self, community_name): - """ - Remove community for a peer - :param community_name: community value for the peer - :return: True if operation was successful, False otherwise - """ - log_debug("BGPAllowListMgr::__remove_community. community='%s'" % community_name) - if community_name == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community - log_debug("BGPAllowListMgr::__remove_community. There is nothing to remove in empty community") - return [] - exists, _ = self.__is_community_presented(community_name) - if not exists: - log_debug("BGPAllowListMgr::__remove_community. Community is already removed.") - return [] - return ['no bgp community-list standard %s' % community_name] - - def __is_community_presented(self, community_name): - """ - Return True if community for the peer_ip exists - :param community_name: community value for the peer - :return: A tuple. First element: True if operation was successful, False otherwise - Second element: community value if the first element is True no value otherwise - """ - log_debug("BGPAllowListMgr::__is_community_presented. community='%s'" % community_name) - match_string = 'bgp community-list standard %s permit ' % community_name - conf = self.cfg_mgr.get_text() - found = [line.strip() for line in conf if line.strip().startswith(match_string)] - if not found: - return False, None - community_value = found[0].replace(match_string, '') - return True, community_value - - def __update_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): - """ - Add or update a "Allow address" route-map entry with the parameters - :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list - :return: True if operation was successful, False otherwise - """ - assert af == self.V4 or af == self.V6 - info = af, route_map_name, allow_address_pl_name, community_name - log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) - entries = self.__parse_allow_route_map_entries(af, route_map_name) - found, _ = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) - if found: - log_debug("BGPAllowListMgr::__update_allow_route_map_entry. route-map='%s' is already found" % route_map_name) - return [] - seq_number = self.__find_next_seq_number(entries.keys(), community_name != self.EMPTY_COMMUNITY, route_map_name) - info = af, seq_number, allow_address_pl_name, community_name - out = "af='%s' seqno='%d' Allow pl='%s' cl='%s'" % info - log_debug("BGPAllowListMgr::__update_allow_route_map_entry. %s" % out) - ip_version = "" if af == self.V4 else "v6" - cmds = [ - 'route-map %s permit %d' % (route_map_name, seq_number), - ' match ip%s address prefix-list %s' % (ip_version, allow_address_pl_name) - ] - if not community_name.endswith(self.EMPTY_COMMUNITY): - cmds.append(" match community %s" % community_name) - return cmds - - def __remove_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): - """ - Add or update a "Allow address" route-map entry with the parameters - :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list - :return: True if operation was successful, False otherwise - """ - assert af == self.V4 or af == self.V6 - info = af, route_map_name, allow_address_pl_name, community_name - log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) - entries = self.__parse_allow_route_map_entries(af, route_map_name) - found, seq_number = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) - if not found: - log_debug("BGPAllowListMgr::__update_allow_route_map_entry. Not found route-map '%s' entry" % allow_address_pl_name) - return [] - return ['no route-map %s permit %d' % (route_map_name, seq_number)] - - @staticmethod - def __find_route_map_entry(entries, allow_address_pl_name, community_name): - """ - Find route-map entry with given allow_address prefix list name and community name in the parsed route-map. - :param entries: entries of parsed route-map - :param allow_address_pl_name: name of the "allow address" prefix-list - :param community_name: name of the "allow address" community name - :return: a tuple. The first element of the tuple is True, if the route-map entry was found, False otherwise. - The second element of the tuple has a sequence number of the entry. - """ - for sequence_number, values in entries.items(): - if sequence_number == 65535: - continue - allow_list_presented = values['pl_allow_list'] == allow_address_pl_name - community_presented = values['community'] == community_name - if allow_list_presented and community_presented: - log_debug("BGPAllowListMgr::__find_route_map_entry. found route-map '%s' entry" % allow_address_pl_name) - return True, sequence_number - return False, None - - def __parse_allow_route_map_entries(self, af, route_map_name): - """ - Parse "Allow list" route-map entries. - :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list - :return: A tuple, First element: True if operation was successful, False otherwise - Second element: list of object with parsed route-map entries - """ - assert af == self.V4 or af == self.V6 - log_debug("BGPAllowListMgr::__parse_allow_route_map_entries. af='%s', rm='%s'" % (af, route_map_name)) - match_string = 'route-map %s permit ' % route_map_name - entries = {} - inside_route_map = False - route_map_seq_number = None - pl_allow_list_name = None - community_name = self.EMPTY_COMMUNITY - if af == self.V4: - match_pl_allow_list = 'match ip address prefix-list ' - else: # self.V6 - match_pl_allow_list = 'match ipv6 address prefix-list ' - match_community = 'match community ' - conf = self.cfg_mgr.get_text() - for line in conf + [""]: - if inside_route_map: - if line.strip().startswith(match_pl_allow_list): - pl_allow_list_name = line.strip()[len(match_pl_allow_list):] - continue - elif line.strip().startswith(match_community): - community_name = line.strip()[len(match_community):] - continue - else: - if pl_allow_list_name is not None: - entries[route_map_seq_number] = { - 'pl_allow_list': pl_allow_list_name, - 'community': community_name, - } - else: - if route_map_seq_number != 65535: - log_warn("BGPAllowListMgr::Found incomplete route-map '%s' entry. seq_no=%d" % (route_map_name, route_map_seq_number)) - inside_route_map = False - pl_allow_list_name = None - community_name = self.EMPTY_COMMUNITY - route_map_seq_number = None - if line.startswith(match_string): - found = line[len(match_string):] - assert found.isdigit() - route_map_seq_number = int(found) - inside_route_map = True - return entries - - @staticmethod - def __find_next_seq_number(seq_numbers, has_community, route_map_name): - """ - Find a next available "Allow list" route-map entry number - :param seq_numbers: a list of already used sequence numbers - :param has_community: True, if the route-map entry has community - :return: next available route-map sequence number - """ - used_sequence_numbers = set(seq_numbers) - sequence_number = None - if has_community: # put entries without communities after 29999 - start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_START - end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_END - else: - start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START - end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END - for i in range(start_seq, end_seq, 10): - if i not in used_sequence_numbers: - sequence_number = i - break - if sequence_number is None: - raise RuntimeError("No free sequence numbers for '%s'" % route_map_name) - info = sequence_number, "yes" if has_community else "no" - log_debug("BGPAllowListMgr::__find_next_seq_number '%d' has_community='%s'" % info) - return sequence_number - - def __extract_peer_group_names(self): - """ - Extract names of all peer-groups defined in the config - :return: list of peer-group names - """ - # Find all peer-groups entries - re_peer_group = re.compile(r'^\s*neighbor (\S+) peer-group$') - peer_groups = [] - for line in self.cfg_mgr.get_text(): - result = re_peer_group.match(line) - if result: - peer_groups.append(result.group(1)) - return peer_groups - - def __get_peer_group_to_route_map(self, peer_groups): - """ - Extract names of route-maps which is connected to peer-groups defines as peer_groups - :peer_groups: a list of peer-group names - :return: dictionary where key is a peer-group, value is a route-map name which is defined as route-map in - for the peer_group. - """ - pg_2_rm = {} - for pg in peer_groups: - re_peer_group_rm = re.compile(r'^\s*neighbor %s route-map (\S+) in$' % pg) - for line in self.cfg_mgr.get_text(): - result = re_peer_group_rm.match(line) - if result: - pg_2_rm[pg] = result.group(1) - break - return pg_2_rm - - def __get_route_map_calls(self, rms): - """ - Find mapping between route-maps and route-map call names, defined for the route-maps - :rms: a set with route-map names - :return: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map - """ - rm_2_call = {} - re_rm = re.compile(r'^route-map (\S+) permit \d+$') - re_call = re.compile(r'^\s*call (\S+)$') - inside_name = None - for line in self.cfg_mgr.get_text(): - if inside_name: - inside_result = re_call.match(line) - if inside_result: - rm_2_call[inside_name] = inside_result.group(1) - inside_name = None - continue - result = re_rm.match(line) - if not result: - continue - inside_name = None - if result.group(1) not in rms: - continue - inside_name = result.group(1) - return rm_2_call - - def __get_peer_group_to_restart(self, deployment_id, pg_2_rm, rm_2_call): - """ - Get peer_groups which are assigned to deployment_id - :deployment_id: deployment_id number - :pg_2_rm: a dictionary where key is a peer-group, value is a route-map name which is defined as route-map in - for the peer_group. - :rm_2_call: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map - """ - ret = set() - target_allow_list_prefix = 'ALLOW_LIST_DEPLOYMENT_ID_%d_V' % deployment_id - for peer_group, route_map in pg_2_rm.items(): - if route_map in rm_2_call: - if rm_2_call[route_map].startswith(target_allow_list_prefix): - ret.add(peer_group) - return list(ret) - - def __find_peer_group_by_deployment_id(self, deployment_id): - """ - Deduce peer-group names which are connected to devices with requested deployment_id - :param deployment_id: deployment_id number - :return: a list of peer-groups which a used by devices with requested deployment_id number - """ - self.cfg_mgr.update() - peer_groups = self.__extract_peer_group_names() - pg_2_rm = self.__get_peer_group_to_route_map(peer_groups) - rm_2_call = self.__get_route_map_calls(set(pg_2_rm.values())) - ret = self.__get_peer_group_to_restart(deployment_id, pg_2_rm, rm_2_call) - return list(ret) - - def __restart_peers(self, deployment_id): - """ - Restart peer-groups with requested deployment_id - :param deployment_id: deployment_id number - """ - log_info("BGPAllowListMgr::Restart peers with deployment_id=%d" % deployment_id) - peer_groups = self.__find_peer_group_by_deployment_id(deployment_id) - rv = True - if peer_groups: - for peer_group in peer_groups: - no_error, _, _ = run_command(["vtysh", "-c", "clear bgp peer-group %s soft in" % peer_group]) - rv = no_error == 0 and rv - else: - no_error, _, _ = run_command(["vtysh", "-c", "clear bgp * soft in"]) - rv = no_error == 0 - return rv - - def __get_enabled(self): - """ - Load enable/disabled property from constants - :return: True if enabled, False otherwise - """ - return 'bgp' in self.constants \ - and 'allow_list' in self.constants["bgp"] \ - and "enabled" in self.constants["bgp"]["allow_list"] \ - and self.constants["bgp"]["allow_list"]["enabled"] - - def __load_constant_lists(self): - """ - Load default prefix-list entries from constants.yml file - """ - if 'bgp' in self.constants and 'allow_list' in self.constants["bgp"] \ - and "default_pl_rules" in self.constants["bgp"]["allow_list"]: - obj = self.constants["bgp"]["allow_list"]["default_pl_rules"] - if "v4" in obj: - self.constants_v4 = obj["v4"] - else: - self.constants_v4 = [] - if "v6" in obj: - self.constants_v6 = obj["v6"] - else: - self.constants_v6 = [] - - def __get_constant_list(self, af): - """ - Return loaded default prefix-list entries bases on address family - :param af: address family - :return: default prefix-list entries - """ - if af == self.V4: - return self.constants_v4 - else: - return self.constants_v6 - - @staticmethod - def __to_prefix_list(allow_list): - """ - Convert "allow list" prefix list, to a prefix-list rules - :param allow_list: "allow list" prefix list - :return: prefix-list rules - """ - return ["permit %s ge %d" % (prefix, int(prefix.split("/")[1])+1) for prefix in allow_list] - - def __af_to_family(self, af): - """ - Convert address family into prefix list family - :param af: address family - :return: prefix list ip family - """ - return 'ip' if af == self.V4 else 'ipv6' diff --git a/src/sonic-bgpcfgd/app/config.py b/src/sonic-bgpcfgd/app/config.py index a0c1329f832e..26639fe75e89 100644 --- a/src/sonic-bgpcfgd/app/config.py +++ b/src/sonic-bgpcfgd/app/config.py @@ -10,33 +10,19 @@ class ConfigMgr(object): """ The class represents frr configuration """ def __init__(self): self.current_config = None - self.current_config_raw = None def reset(self): """ Reset stored config """ self.current_config = None - self.current_config_raw = None def update(self): """ Read current config from FRR """ self.current_config = None - self.current_config_raw = None ret_code, out, err = run_command(["vtysh", "-c", "show running-config"]) if ret_code != 0: - # FIXME: should we throw exception here? log_crit("can't update running config: rc=%d out='%s' err='%s'" % (ret_code, out, err)) return - text = [] - for line in out.split('\n'): - if line.lstrip().startswith('!'): - continue - text.append(line) - text += [" "] # Add empty line to have something to work on, if there is no text - self.current_config_raw = text - self.current_config = self.to_canonical(out) # FIXME: use test as an input - - def push_list(self, cmdlist): - return self.push("\n".join(cmdlist)) + self.current_config = self.to_canonical(out) def push(self, cmd): """ @@ -65,12 +51,8 @@ def write(self, cmd): 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 - self.current_config_raw = None return ret_code == 0 - def get_text(self): - return self.current_config_raw - @staticmethod def to_canonical(raw_config): """ diff --git a/src/sonic-bgpcfgd/app/directory.py b/src/sonic-bgpcfgd/app/directory.py deleted file mode 100644 index d27ec64256e3..000000000000 --- a/src/sonic-bgpcfgd/app/directory.py +++ /dev/null @@ -1,159 +0,0 @@ -from collections import defaultdict - -from app.log import log_err - - -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) # 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 == '': - return True, self.data[slot] - d = self.data[slot] - for p in path.split("/"): - if p not in d: - return False, None - d = d[p] - return True, d - - 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, 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, 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(db, table, path): - for handler in self.notify[slot][path]: - handler() - - 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 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: - log_err("Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) - else: - log_err("Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) - - 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: - log_err("Directory: Can't remove slot '%s'. The slot doesn't exist" % 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 db, table, path in deps: - res = res and self.path_exist(db, table, path) - return res - - def subscribe(self, deps, handler): - """ - 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) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/manager.py b/src/sonic-bgpcfgd/app/manager.py deleted file mode 100644 index ba45029b5120..000000000000 --- a/src/sonic-bgpcfgd/app/manager.py +++ /dev/null @@ -1,71 +0,0 @@ -from swsscommon import swsscommon - -from app.log import log_debug, log_err - - -class Manager(object): - """ 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 = [] - 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): # all required dependencies are set in the Directory? - res = self.set_handler(key, data) - 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: - 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 = [] - for key, data in self.set_queue: - res = self.set_handler(key, data) - if not res: - new_queue.append((key, data)) - self.set_queue = new_queue - - def set_handler(self, key, data): - """ Placeholder for 'SET' command """ - log_err("set_handler() wasn't implemented for %s" % self.__class__.__name__) - - def del_handler(self, key): - """ Placeholder for 'DEL' command """ - log_err("del_handler wasn't implemented for %s" % self.__class__.__name__) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/vars.py b/src/sonic-bgpcfgd/app/vars.py index 18bee5578e25..11377fc87f93 100644 --- a/src/sonic-bgpcfgd/app/vars.py +++ b/src/sonic-bgpcfgd/app/vars.py @@ -1 +1 @@ -g_debug = True # FIXME: read from env variable, or from constants +g_debug = False diff --git a/src/sonic-bgpcfgd/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd index 59dc35c25e21..3bedd8679004 100755 --- a/src/sonic-bgpcfgd/bgpcfgd +++ b/src/sonic-bgpcfgd/bgpcfgd @@ -15,13 +15,10 @@ import jinja2 import netaddr from swsscommon import swsscommon -from app.directory import Directory -from app.manager import Manager from app.vars import g_debug from app.log import log_debug, log_notice, log_info, log_warn, log_err, log_crit from app.template import TemplateFabric from app.config import ConfigMgr -from app.allow_list import BGPAllowListMgr from app.util import run_command g_run = True @@ -849,7 +846,7 @@ def wait_for_daemons(daemons, 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) # FIXME: , Loader=yaml.FullLoader) + 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") @@ -881,8 +878,6 @@ def main(): BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", True), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), - # AllowList Managers - BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), ] runner = Runner() for mgr in managers: diff --git a/src/sonic-bgpcfgd/pytest.ini b/src/sonic-bgpcfgd/pytest.ini deleted file mode 100644 index 639ceb636af9..000000000000 --- a/src/sonic-bgpcfgd/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -addopts = --cov=app --cov-report term diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index fc0839dff7fc..29d441e09a66 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -16,6 +16,5 @@ ] }, install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], - setup_requires=['pytest-runner'], - test_requires=['pytest', 'pytest-cov'], + setup_requires=['pytest-runner', 'pytest'], ) diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json index 08f1eef63267..148456fe960f 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json @@ -4,14 +4,5 @@ "sub_role": "BackEnd" } }, - "loopback0_ipv4": "10.10.10.10/32", - "constants": { - "bgp": { - "allow_list": { - "enabled": true, - "default_action": "permit", - "drop_community": "12345:12345" - } - } - } -} + "loopback0_ipv4": "10.10.10.10/32" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json index 958c9b0fbd4b..53bf5572eff3 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json @@ -4,12 +4,5 @@ "sub_role": "NotBackEnd" } }, - "loopback0_ipv4": "10.10.10.10/32", - "constants": { - "bgp": { - "allow_list": { - "enabled": false - } - } - } -} + "loopback0_ipv4": "10.10.10.10/32" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json deleted file mode 100644 index 669810960c92..000000000000 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "CONFIG_DB__DEVICE_METADATA": { - "localhost": { - "sub_role": "BackEnd" - } - }, - "loopback0_ipv4": "10.10.10.10/32", - "constants": { - "bgp": { - "allow_list": { - "enabled": true, - "default_action": "deny", - "drop_community": "12345:12345" - } - } - } -} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf index 9e6c32b17ead..1e3288b9a7da 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf @@ -1,20 +1,6 @@ ! ! template: bgpd/templates/general/policies.conf.j2 ! -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 - set community 12345:12345 additive -! -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 - set community 12345:12345 additive -! -route-map FROM_BGP_PEER_V4 permit 2 - call ALLOW_LIST_DEPLOYMENT_ID_0_V4 - on-match next -! -route-map FROM_BGP_PEER_V6 permit 2 - call ALLOW_LIST_DEPLOYMENT_ID_0_V6 - on-match next -! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf deleted file mode 100644 index 6e0389fc1886..000000000000 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf +++ /dev/null @@ -1,39 +0,0 @@ -! -! template: bgpd/templates/general/policies.conf.j2 -! -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 - set community no-export additive -! -route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 - set community no-export additive -! -route-map FROM_BGP_PEER_V4 permit 2 - call ALLOW_LIST_DEPLOYMENT_ID_0_V4 - on-match next -! -route-map FROM_BGP_PEER_V6 permit 2 - call ALLOW_LIST_DEPLOYMENT_ID_0_V6 - on-match next -! -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 -! -route-map FROM_BGP_PEER_V4_INT permit 2 - set originator-id 10.10.10.10 -! -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 10.10.10.10 -! -! end of template: bgpd/templates/general/policies.conf.j2 -! diff --git a/src/sonic-bgpcfgd/tests/test_allow_list.py b/src/sonic-bgpcfgd/tests/test_allow_list.py deleted file mode 100644 index 196a28a1aa18..000000000000 --- a/src/sonic-bgpcfgd/tests/test_allow_list.py +++ /dev/null @@ -1,469 +0,0 @@ -from app.allow_list import BGPAllowListMgr -from app.directory import Directory -from app.template import TemplateFabric -import app -from mock import MagicMock - - -global_constants = { - "bgp": { - "allow_list": { - "enabled": True, - "default_pl_rules": { - "v4": [ "deny 0.0.0.0/0 le 17" ], - "v6": [ - "deny 0::/0 le 59", - "deny 0::/0 ge 65" - ] - } - } - } -} - -def set_del_test(op, args, currect_config, expected_config): - set_del_test.push_list_called = False - def push_list(args): - set_del_test.push_list_called = True - assert args == expected_config - return True - # - app.allow_list.run_command = lambda cmd: (0, "", "") - # - cfg_mgr = MagicMock() - cfg_mgr.update.return_value = None - cfg_mgr.push_list = push_list - cfg_mgr.get_text.return_value = currect_config - common_objs = { - 'directory': Directory(), - 'cfg_mgr': cfg_mgr, - 'tf': TemplateFabric(), - 'constants': global_constants, - } - mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") - if op == "SET": - mgr.set_handler(*args) - elif op == "DEL": - mgr.del_handler(*args) - else: - assert False, "Wrong operation" - if expected_config: - assert set_del_test.push_list_called, "cfg_mgr.push_list wasn't called" - else: - assert not set_del_test.push_list_called, "cfg_mgr.push_list was called" - -def test_set_handler_with_community(): - set_del_test( - "SET", - ("DEPLOYMENT_ID|5|1010:2020", { - "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", - "prefixes_v6": "fc00:20::/64,fc00:30::/64", - }), - [], - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', - 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - ] - ) - -def test_set_handler_no_community(): - set_del_test( - "SET", - ("DEPLOYMENT_ID|5", { - "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", - "prefixes_v6": "fc01:20::/64,fc01:30::/64", - }), - [], - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', - ] - ) - -def test_del_handler_with_community(): - set_del_test( - "DEL", - ("DEPLOYMENT_ID|5|1010:2020",), - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', - 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - "" - ], - [ - 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', - 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', - 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', - 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', - 'no bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - ] - ) - -def test_del_handler_no_community(): - set_del_test( - "DEL", - ("DEPLOYMENT_ID|5",), - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', - " " - ], - [ - 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', - 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', - 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', - 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', - ] - ) - -def test_set_handler_with_community_data_is_already_presented(): - set_del_test( - "SET", - ("DEPLOYMENT_ID|5|1010:2020", { - "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", - "prefixes_v6": "fc00:20::/64,fc00:30::/64", - }), - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', - 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - "" - ], - [] - ) - -def test_set_handler_no_community_data_is_already_presented(): - cfg_mgr = MagicMock() - cfg_mgr.update.return_value = None - cfg_mgr.get_text.return_value = [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', - "" - ] - common_objs = { - 'directory': Directory(), - 'cfg_mgr': cfg_mgr, - 'tf': TemplateFabric(), - 'constants': global_constants, - } - mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") - mgr.set_handler("DEPLOYMENT_ID|5", { - "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", - "prefixes_v6": "fc01:20::/64,fc01:30::/64", - }) - assert not cfg_mgr.push_list.called, "cfg_mgr.push_list was called, but it shouldn't have been" - -def test_del_handler_with_community_no_data(): - set_del_test( - "DEL", - ("DEPLOYMENT_ID|5|1010:2020",), - [""], - [] - ) - -def test_del_handler_no_community_no_data(): - set_del_test( - "DEL", - ("DEPLOYMENT_ID|5",), - [""], - [] - ) - -def test_set_handler_with_community_update_prefixes_add(): - set_del_test( - "SET", - ("DEPLOYMENT_ID|5|1010:2020", { - "prefixes_v4": "10.20.30.0/24,30.50.0.0/16,80.90.0.0/16", - "prefixes_v6": "fc00:20::/64,fc00:30::/64,fc02::/64", - }), - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', - 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', - "" - ], - [ - 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 40 permit 80.90.0.0/16 ge 17', - 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 50 permit fc02::/64 ge 65', - ] - ) - -def test_set_handler_no_community_update_prefixes_add(): - set_del_test( - "SET", - ("DEPLOYMENT_ID|5", { - "prefixes_v4": "20.20.30.0/24,40.50.0.0/16,80.90.0.0/16", - "prefixes_v6": "fc01:20::/64,fc01:30::/64,fc02::/64", - }), - [ - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', - "" - ], - [ - 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', - 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 40 permit 80.90.0.0/16 ge 17', - 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', - 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 50 permit fc02::/64 ge 65', - ] - ) - -def test___set_handler_validate(): - cfg_mgr = MagicMock() - common_objs = { - 'directory': Directory(), - 'cfg_mgr': cfg_mgr, - 'tf': TemplateFabric(), - 'constants': global_constants, - } - mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") - data = { - "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", - "prefixes_v6": "fc01:20::/64,fc01:30::/64", - } - assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", None) - assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID1|5|1010:2020", data) - assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|z|1010:2020", data) - assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { - "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", - "prefixes_v6": "20.20.30.0/24,40.50.0.0/16", - }) - assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { - "prefixes_v4": "fc01:20::/64,fc01:30::/64", - "prefixes_v6": "fc01:20::/64,fc01:30::/64", - }) - -def test___find_peer_group_by_deployment_id(): - cfg_mgr = MagicMock() - cfg_mgr.update.return_value = None - cfg_mgr.get_text.return_value = [ - 'router bgp 64601', - ' neighbor BGPSLBPassive peer-group', - ' neighbor BGPSLBPassive remote-as 65432', - ' neighbor BGPSLBPassive passive', - ' neighbor BGPSLBPassive ebgp-multihop 255', - ' neighbor BGPSLBPassive update-source 10.1.0.32', - ' neighbor PEER_V4 peer-group', - ' neighbor PEER_V4_INT peer-group', - ' neighbor PEER_V6 peer-group', - ' neighbor PEER_V6_INT peer-group', - ' neighbor 10.0.0.1 remote-as 64802', - ' neighbor 10.0.0.1 peer-group PEER_V4', - ' neighbor 10.0.0.1 description ARISTA01T1', - ' neighbor 10.0.0.1 timers 3 10', - ' neighbor fc00::2 remote-as 64802', - ' neighbor fc00::2 peer-group PEER_V6', - ' neighbor fc00::2 description ARISTA01T1', - ' neighbor fc00::2 timers 3 10', - ' address-family ipv4 unicast', - ' neighbor BGPSLBPassive activate', - ' neighbor BGPSLBPassive soft-reconfiguration inbound', - ' neighbor BGPSLBPassive route-map FROM_BGP_SPEAKER in', - ' neighbor BGPSLBPassive route-map TO_BGP_SPEAKER out', - ' neighbor PEER_V4 soft-reconfiguration inbound', - ' neighbor PEER_V4 allowas-in 1', - ' neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in', - ' neighbor PEER_V4 route-map TO_BGP_PEER_V4 out', - ' neighbor PEER_V4_INT soft-reconfiguration inbound', - ' neighbor PEER_V4_INT allowas-in 1', - ' neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in', - ' neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out', - ' neighbor 10.0.0.1 activate', - ' exit-address-family', - ' address-family ipv6 unicast', - ' neighbor BGPSLBPassive activate', - ' neighbor PEER_V6 soft-reconfiguration inbound', - ' neighbor PEER_V6 allowas-in 1', - ' neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in', - ' neighbor PEER_V6 route-map TO_BGP_PEER_V6 out', - ' neighbor PEER_V6_INT soft-reconfiguration inbound', - ' neighbor PEER_V6_INT allowas-in 1', - ' neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in', - ' neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out', - ' neighbor fc00::2 activate', - ' exit-address-family', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 10', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V4', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 30000', - ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V4', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535', - ' set community 5060:12345 additive', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 10', - ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V6', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 30000', - ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V6', - 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535', - ' set community 5060:12345 additive', - 'route-map FROM_BGP_PEER_V4 permit 100', - 'route-map FROM_BGP_PEER_V4 permit 2', - ' call ALLOW_LIST_DEPLOYMENT_ID_0_V4', - ' on-match next', - 'route-map FROM_BGP_PEER_V6 permit 1', - ' set ipv6 next-hop prefer-global ', - 'route-map FROM_BGP_PEER_V6 permit 100', - 'route-map FROM_BGP_PEER_V6 permit 2', - ' call ALLOW_LIST_DEPLOYMENT_ID_0_V6', - ' on-match next', - 'route-map FROM_BGP_SPEAKER permit 10', - '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', - 'route-map TO_BGP_PEER_V4 permit 100', - 'route-map TO_BGP_PEER_V6 permit 100', - 'route-map TO_BGP_SPEAKER deny 1', - ] - common_objs = { - 'directory': Directory(), - 'cfg_mgr': cfg_mgr, - 'tf': TemplateFabric(), - 'constants': global_constants, - } - mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") - values = mgr._BGPAllowListMgr__find_peer_group_by_deployment_id(0) - assert values == ['PEER_V4_INT', 'PEER_V6_INT', 'PEER_V6', 'PEER_V4'] - -def test___restart_peers_found_deployment_id(): - test___restart_peers_found_deployment_id.run_command_counter = 0 - def run_command(cmd): - output = [ - ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_1 soft in'], - ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_2 soft in'], - ] - desired_value = output[test___restart_peers_found_deployment_id.run_command_counter] - assert cmd == desired_value - test___restart_peers_found_deployment_id.run_command_counter += 1 - return 0, "", "" - cfg_mgr = MagicMock() - common_objs = { - 'directory': Directory(), - 'cfg_mgr': cfg_mgr, - 'tf': TemplateFabric(), - 'constants': global_constants, - } - mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") - mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') - mocked.return_value = ["BGP_TEST_PEER_GROUP_1", "BGP_TEST_PEER_GROUP_2"] - mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked - app.allow_list.run_command = run_command - rc = mgr._BGPAllowListMgr__restart_peers(5) - assert rc - -def test___restart_peers_not_found_deployment_id(): - def run_command(cmd): - assert cmd == ['vtysh', '-c', 'clear bgp * soft in'] - return 0, "", "" - cfg_mgr = MagicMock() - common_objs = { - 'directory': Directory(), - 'cfg_mgr': cfg_mgr, - 'tf': TemplateFabric(), - 'constants': global_constants, - } - mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") - mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') - mocked.return_value = [] - mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked - app.allow_list.run_command = run_command - rc = mgr._BGPAllowListMgr__restart_peers(5) - assert rc - -# FIXME: more testcases for coverage diff --git a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py index 686b1ade65e1..bc6d01cdb536 100644 --- a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py +++ b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py @@ -77,30 +77,21 @@ def extract_rm_from_peer_group(path, peer_group_name): return list(rm_set) def check_routemap_in_file(filename, route_map_name): - route_map_re = re.compile(r'^route-map\s+%s\s+permit\s+(\d+)' % route_map_name) + route_map_re = re.compile(r'^route-map\s+%s\s+(\S+)' % route_map_name) set_re = re.compile(r'set ipv6 next-hop prefer-global') with open(filename) as fp: lines = [line.strip() for line in fp if not line.strip().startswith('!') and line.strip() != ''] - found_entry = False - found_seq_no = None - route_map_entries = {} + found_first_entry = False for line in lines: - if found_entry: - route_map_entries[found_seq_no] = set_re.match(line) is not None - found_entry = False - found_seq_no = None + err_msg = "route-map %s doesn't have mandatory 'set ipv6 next-hop prefer-global' entry as the first rule" % route_map_name + assert not (found_first_entry and line.startswith("route-map")), err_msg + if found_first_entry and set_re.match(line): + break # We're good if route_map_re.match(line): - found_seq_no = None - seq_n_txt = route_map_re.match(line).group(1) - assert seq_n_txt.isdigit(), "wrong sequence number for line '%s'" % line - found_seq_no = int(seq_n_txt) - assert found_seq_no not in route_map_entries, "Route-map has duplicate entries: %s - %d" % (route_map_name, found_seq_no) - found_entry = True - results = [route_map_entries[seq] for seq in sorted(route_map_entries.keys())] - if (len(results)): - err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name - assert results[0], err_msg - return len(results) > 0 + err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name + assert route_map_re.match(line).group(1) == 'permit', err_msg + found_first_entry = True + return found_first_entry def check_routemap(path, route_map_name): result_files = load_results(path, "policies.conf") diff --git a/src/sonic-bgpcfgd/tests/util.py b/src/sonic-bgpcfgd/tests/util.py index aa6c62a56b5f..0bc12b060aec 100644 --- a/src/sonic-bgpcfgd/tests/util.py +++ b/src/sonic-bgpcfgd/tests/util.py @@ -5,7 +5,7 @@ def load_constants(): with open(CONSTANTS_PATH) as f: - data = yaml.load(f) # FIXME" , Loader=yaml.FullLoader) + data = yaml.load(f) result = {} assert "constants" in data, "'constants' key not found in constants.yml" assert "bgp" in data["constants"], "'bgp' key not found in constants.yml" @@ -13,4 +13,4 @@ def load_constants(): for name, value in data["constants"]["bgp"]["peers"].items(): assert "template_dir" in value, "'template_dir' key not found for peer '%s'" % name result[name] = value["template_dir"] - return result + return result \ No newline at end of file From e3a0feaa472a1684d60052c67d4a47fbaca23bba Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Tue, 29 Sep 2020 12:39:53 -0700 Subject: [PATCH 37/78] Vtysh support for multi asic (#5479) Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- dockers/docker-fpm-frr/base_image_files/vtysh | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/dockers/docker-fpm-frr/base_image_files/vtysh b/dockers/docker-fpm-frr/base_image_files/vtysh index 24016bd96b2c..e4efeb454cb3 100755 --- a/dockers/docker-fpm-frr/base_image_files/vtysh +++ b/dockers/docker-fpm-frr/base_image_files/vtysh @@ -1,4 +1,37 @@ #!/bin/bash +# read SONiC immutable variables +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + +function help() +{ + echo -e "Usage: $0 -n [0 to $(($NUM_ASIC-1))] [OPTION]... " 1>&2; exit 1; +} + +DEV="" +PLATFORM=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} + +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +[ -f $ASIC_CONF ] && . $ASIC_CONF + +if [[ ($NUM_ASIC -gt 1) ]]; then + while getopts ":n:h:" opt; do + case "${opt}" in + h) help + ;; + n) DEV=${OPTARG} + [ $DEV -lt $NUM_ASIC -a $DEV -ge 0 ] || help + ;; + esac + done + + if [ -z "${DEV}" ]; then + help + fi + + # Skip the arguments -n while passing to docker command + shift 2 +fi # Determine whether stdout is on a terminal if [ -t 1 ] ; then @@ -7,10 +40,10 @@ if [ -t 1 ] ; then TTY=$(tty) function cleanup { - docker exec -i bgp pkill -HUP -f "vtysh $TTY" + docker exec -i bgp$DEV pkill -HUP -f "vtysh $TTY" } trap cleanup HUP - docker exec -ti bgp vtysh "$TTY" "$@" + docker exec -ti bgp$DEV vtysh "$TTY" "$@" else - docker exec -i bgp vtysh "$@" + docker exec -i bgp$DEV vtysh "$@" fi From d71a4efe3bac20d0a68b1e88b564a2c1f20741d5 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Tue, 29 Sep 2020 23:57:54 +0300 Subject: [PATCH 38/78] [sonic-platform-common] Install Python 3 package in host OS and PMon container (#5461) Signed-off-by: Volodymyr Boyko --- dockers/docker-platform-monitor/Dockerfile.j2 | 5 +++++ dockers/docker-platform-monitor/start.sh | 17 +++++++++++++++++ dockers/dockerfile-macros.j2 | 19 ++++++++++++++++++- .../build_templates/sonic_debian_extension.j2 | 6 ++++++ rules/docker-platform-monitor.mk | 3 +++ slave.mk | 2 ++ 6 files changed, 51 insertions(+), 1 deletion(-) diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index 884fd565c3a4..b3af66971938 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -11,6 +11,7 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y \ python-pip \ + python3-dev \ ipmitool \ librrd8 \ librrd-dev \ @@ -21,6 +22,9 @@ RUN apt-get update && \ i2c-tools && \ pip install enum34 +# Install python3 required packages +RUN python3 -m pip install --no-cache-dir setuptools wheel + {% if docker_platform_monitor_debs.strip() -%} # Copy locally-built Debian package dependencies {{ copy_files("debs/", docker_platform_monitor_debs.split(' '), "/debs/") }} @@ -47,6 +51,7 @@ RUN apt-get update && \ # Clean up RUN apt-get purge -y \ + python3-dev \ python-pip && \ apt-get clean -y && \ apt-get autoclean -y && \ diff --git a/dockers/docker-platform-monitor/start.sh b/dockers/docker-platform-monitor/start.sh index 58e481476b93..0884266e2308 100755 --- a/dockers/docker-platform-monitor/start.sh +++ b/dockers/docker-platform-monitor/start.sh @@ -31,3 +31,20 @@ if [ $? -ne 0 ]; then echo "Error: Unable to locate ${SONIC_PLATFORM_WHEEL}" fi fi + +# If the python3 sonic-platform package is not installed, try to install it +python3 -m pip show sonic-platform > /dev/null 2>&1 +if [ $? -ne 0 ]; then + SONIC_PLATFORM_WHEEL="/usr/share/sonic/platform/sonic_platform-1.0-py3-none-any.whl" + echo "sonic-platform package not installed, attempting to install..." + if [ -e ${SONIC_PLATFORM_WHEEL} ]; then + python3 -m pip install ${SONIC_PLATFORM_WHEEL} + if [ $? -eq 0 ]; then + echo "Successfully installed ${SONIC_PLATFORM_WHEEL}" + else + echo "Error: Failed to install ${SONIC_PLATFORM_WHEEL}" + fi + else + echo "Error: Unable to locate ${SONIC_PLATFORM_WHEEL}" + fi +fi diff --git a/dockers/dockerfile-macros.j2 b/dockers/dockerfile-macros.j2 index 8a4a3ae01411..5952d59f566f 100644 --- a/dockers/dockerfile-macros.j2 +++ b/dockers/dockerfile-macros.j2 @@ -5,7 +5,7 @@ RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return {%- endfor %} {%- endmacro %} -{% macro install_python_wheels(packages) -%} +{% macro install_python2_wheels(packages) -%} RUN cd /python-wheels/ && pip install {{ packages | join(' ') }} {%- endmacro %} @@ -13,6 +13,23 @@ RUN cd /python-wheels/ && pip install {{ packages | join(' ') }} RUN cd /python-wheels/ && pip3 install {{ packages | join(' ') }} {%- endmacro %} +{% macro install_python_wheels(packages) -%} +{%- set py2_pkgs, py3_pkgs = [], [] %} +{%- for pkg in packages %} + {%- if 'py3' in pkg %} + {{- py3_pkgs.append(pkg) or '' }} + {%- else %} + {{- py2_pkgs.append(pkg) or '' }} + {%- endif %} +{%- endfor %} +{%- if py3_pkgs | length %} +{{ install_python3_wheels(py3_pkgs) }} +{%- endif %} +{%- if py2_pkgs | length %} +{{ install_python2_wheels(py2_pkgs) }} +{%- endif %} +{%- endmacro %} + {% macro copy_files(prefix, files, dest) -%} COPY \ {%- for file in files %} diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index eac1e2ba352a..b40be7c13f79 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -172,6 +172,12 @@ sudo cp {{platform_common_py2_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $PLATFORM_COMMON_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME +# Install sonic-platform-common Python 3 package +PLATFORM_COMMON_PY3_WHEEL_NAME=$(basename {{platform_common_py3_wheel_path}}) +sudo cp {{platform_common_py3_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY3_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $PLATFORM_COMMON_PY3_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY3_WHEEL_NAME + # Install Debian packages and their dependencies which are needed by sonic-utilities sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f python-m2crypto diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index 72f9e145d6d4..e864f42a7072 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -11,8 +11,11 @@ ifeq ($(CONFIGURED_PLATFORM),barefoot) $(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(PYTHON_THRIFT) endif $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY3) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SWSSSDK_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SWSSSDK_PY3) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) +$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_LEDD) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PCIED) diff --git a/slave.mk b/slave.mk index 2d45b2c1e13f..b9cebdf9a169 100644 --- a/slave.mk +++ b/slave.mk @@ -813,6 +813,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3)) \ @@ -851,6 +852,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export swsssdk_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY2))" export swsssdk_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY3))" export platform_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2))" + export platform_common_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY3))" export redis_dump_load_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2))" export redis_dump_load_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY3))" export install_debug_image="$(INSTALL_DEBUG_TOOLS)" From 79bda7d0d6649ab26dbab22266f6da3faeffdb3e Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 30 Sep 2020 03:23:09 +0300 Subject: [PATCH 39/78] [monit]: Fix process checker. (#5480) Signed-off-by: Nazarii Hnydyn --- dockers/docker-fpm-frr/base_image_files/monit_bgp | 2 +- dockers/docker-snmp/base_image_files/monit_snmp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dockers/docker-fpm-frr/base_image_files/monit_bgp b/dockers/docker-fpm-frr/base_image_files/monit_bgp index 46ddc629013e..4567d45e3c48 100644 --- a/dockers/docker-fpm-frr/base_image_files/monit_bgp +++ b/dockers/docker-fpm-frr/base_image_files/monit_bgp @@ -23,5 +23,5 @@ check program bgp|staticd with path "/usr/bin/process_checker bgp /usr/lib/frr/s check program bgp|bgpcfgd with path "/usr/bin/process_checker bgp /usr/bin/python /usr/local/bin/bgpcfgd" if status != 0 for 5 times within 5 cycles then alert -check program bgp|bgpmon with path "/usr/bin/process_checker bgp python /usr/local/bin/bgpmon" +check program bgp|bgpmon with path "/usr/bin/process_checker bgp /usr/bin/python /usr/local/bin/bgpmon" if status != 0 for 5 times within 5 cycles then alert diff --git a/dockers/docker-snmp/base_image_files/monit_snmp b/dockers/docker-snmp/base_image_files/monit_snmp index a943985abcef..b1725378c0b8 100644 --- a/dockers/docker-snmp/base_image_files/monit_snmp +++ b/dockers/docker-snmp/base_image_files/monit_snmp @@ -7,5 +7,5 @@ check program snmp|snmpd with path "/usr/bin/process_checker snmp /usr/sbin/snmpd" if status != 0 for 5 times within 5 cycles then alert -check program snmp|snmp_subagent with path "/usr/bin/process_checker snmp python3.6 -m sonic_ax_impl" +check program snmp|snmp_subagent with path "/usr/bin/process_checker snmp python3 -m sonic_ax_impl" if status != 0 for 5 times within 5 cycles then alert From c55bb03cfca04e4c4153cf1c40f6844dec4633d1 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Mon, 28 Sep 2020 19:20:15 -0700 Subject: [PATCH 40/78] [build] Add Support For Python 3 Build CONiC config gen requires jinja2<3.0.0 for stretch and byangbind versions 0.60.0/0.80.1 for Python 2/3 respectively. byangbind is installed in the build docker because when it installed it pulls enum34 as dependent package which is not required for Python 3 and it breaks the build. signed-off-by: Tamer Ahmed --- sonic-slave-buster/Dockerfile.j2 | 10 +++++++--- sonic-slave-stretch/Dockerfile.j2 | 13 ++++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 88f905cb0f8a..11d79278230e 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -242,7 +242,9 @@ RUN apt-get update && apt-get install -y \ sphinx-common \ python3-sphinx \ # For sonic config engine testing + python-dev \ python-lxml \ + python3-lxml \ python-jinja2 \ python-netaddr \ python-ipaddr \ @@ -362,9 +364,11 @@ RUN pip install \ crc16 # For sonic config engine testing -RUN pip install pyangbind==0.6.0 -# Note: force upgrade debian packaged jinja2, if installed -RUN pip install --force-reinstall --upgrade "jinja2>=2.10" +# Install pyangbind here, outside sonic-config-engine dependencies, as pyangbind causes enum34 to be installed. +# enum34 causes Python 're' package to not work properly as it redefines an incompatible enum.py module +# https://github.com/robshakir/pyangbind/issues/232 +RUN pip3 install pyangbind==0.8.1 +RUN pip3 uninstall -y enum34 # For templating RUN pip install j2cli==0.3.10 diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index d372450f0181..fb685a2adcf5 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -241,7 +241,9 @@ RUN apt-get update && apt-get install -y \ sphinx-common \ python3-sphinx \ # For sonic config engine testing + python-dev \ python-lxml \ + python3-lxml \ python-jinja2 \ python-netaddr \ python-ipaddr \ @@ -341,10 +343,15 @@ RUN pip install \ ctypesgen==0.r125 \ crc16 +# Note: Stick with Jinja2 2.x branch as the 3.x dropped support for Python 2.7 +RUN pip install --force-reinstall --upgrade "Jinja2<3.0.0" + # For sonic config engine testing -RUN pip install pyangbind==0.6.0 -# Note: force upgrade debian packaged jinja2, if installed -RUN pip install --force-reinstall --upgrade "jinja2>=2.10" +# Install pyangbind here, outside sonic-config-engine dependencies, as pyangbind causes enum34 to be installed. +# enum34 causes Python 're' package to not work properly as it redefines an incompatible enum.py module +# https://github.com/robshakir/pyangbind/issues/232 +RUN pip3 install pyangbind==0.8.1 +RUN pip3 uninstall -y enum34 # For templating RUN pip install j2cli==0.3.10 From 9122d16dd28c36d10a05ce0b30d81ff6273f1c63 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Mon, 28 Sep 2020 20:07:39 -0700 Subject: [PATCH 41/78] [cfggen] Remove NatSorted Natural sorting of SONiC config gen output consumes lot of CPU cycles. The sole use of natsorted was to make test comparison easier and so, the natsorting logic is now relocated to the test suite. As a result sonic-cfggen gained nearly 1 sec per call since we no longer import natsorted module! singed-off-by: Tamer Ahmed --- .../data/sonic-cfggen/bgpd.conf.j2/all.conf | 12 +- .../sonic-cfggen/bgpd.main.conf.j2/all.conf | 6 +- .../bgpd.main.conf.j2/defaults.conf | 6 +- .../base.conf | 20 +- .../data/sonic-cfggen/frr.conf.j2/all.conf | 15 +- .../data/sonic-cfggen/zebra/interfaces.conf | 6 +- .../tests/data/sonic-cfggen/zebra/zebra.conf | 10 +- src/sonic-config-engine/__init__.py | 0 src/sonic-config-engine/sonic-cfggen | 51 +-- src/sonic-config-engine/tests/common_utils.py | 30 ++ .../tests/multi_npu_data/ipinip.json | 2 +- .../tests/sample_output/bgpd_quagga.conf | 44 +- .../tests/sample_output/buffers-dell6100.json | 418 +++++++++--------- .../docker-dhcp-relay.supervisord.conf | 4 +- .../tests/sample_output/frr.conf | 4 +- .../tests/sample_output/ipinip.json | 4 +- .../tests/sample_output/l2switch.json | 236 +++++----- .../tests/sample_output/ports.json | 14 +- .../t2-chassis-fe-vni-zebra.conf | 4 +- .../sample_output/t2-chassis-fe-zebra.conf | 4 +- .../tests/sample_output/wait_for_intf.sh | 2 +- .../tests/sample_output/zebra_frr.conf | 4 +- .../tests/sample_output/zebra_quagga.conf | 4 +- src/sonic-config-engine/tests/test_cfggen.py | 290 +++++++----- .../tests/test_cfggen_platformJson.py | 16 +- .../tests/test_cfggen_t2_chassis_fe.py | 45 +- .../tests/test_minigraph_case.py | 27 +- .../tests/test_multinpu_cfggen.py | 46 +- 28 files changed, 742 insertions(+), 582 deletions(-) create mode 100644 src/sonic-config-engine/__init__.py create mode 100644 src/sonic-config-engine/tests/common_utils.py diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf index e417e10d61f5..6d79e4c2264d 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf @@ -1,10 +1,12 @@ ! ! 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 new_hostname @@ -17,6 +19,8 @@ log facility local4 ! end of template: common/daemons.common.conf.j2! agentx ! +! +! ! template: bgpd/bgpd.main.conf.j2 ! ! bgp multiple-instance @@ -29,14 +33,15 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.1/24 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.1/24 ! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::1/64 +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 5 permit fc01::1/64 ! ! route-map HIDE_INTERNAL permit 10 set community local-AS ! +! router bgp 55555 ! bgp log-neighbor-changes @@ -56,10 +61,11 @@ router bgp 55555 network fc00::1/64 exit-address-family ! - network 10.10.10.1/24 address-family ipv6 network fc01::1/64 exit-address-family + network 10.10.10.1/24 +! ! address-family ipv4 redistribute connected route-map HIDE_INTERNAL diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf index c4e18c5ae258..d771ff49c92d 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf @@ -11,14 +11,15 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.1/24 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.1/24 ! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::1/64 +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 15 permit fc01::1/64 ! ! route-map HIDE_INTERNAL permit 10 set community local-AS ! +! router bgp 55555 ! bgp log-neighbor-changes @@ -42,6 +43,7 @@ router bgp 55555 address-family ipv6 network fc01::1/64 exit-address-family +! ! address-family ipv4 redistribute connected route-map HIDE_INTERNAL diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf index e1f9c8489cb4..e9296f8627d9 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf @@ -11,14 +11,15 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.1/24 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.1/24 ! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::1/64 +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 15 permit fc01::1/64 ! ! route-map HIDE_INTERNAL permit 10 set community local-AS ! +! router bgp 55555 ! bgp log-neighbor-changes @@ -42,6 +43,7 @@ router bgp 55555 address-family ipv6 network fc01::1/64 exit-address-family +! ! address-family ipv4 redistribute connected route-map HIDE_INTERNAL diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf index 581eb107ec23..2f543715299c 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf @@ -1,6 +1,6 @@ ! ! Vnet BGP instance -router bgp 555 vrf First +router bgp 555 vrf Second no bgp default ipv4-unicast bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -8,17 +8,17 @@ router bgp 555 vrf First bgp graceful-restart restart-time 240 bgp graceful-restart bgp router-id 10.20.30.40 - neighbor 10.10.10.1 remote-as 10 - neighbor 10.10.10.1 description session1 + neighbor 20.20.20.1 remote-as 20 + neighbor 20.20.20.1 description session2 address-family ipv4 unicast - neighbor 10.10.10.1 activate - neighbor 10.10.10.1 soft-reconfiguration inbound + neighbor 20.20.20.1 activate + neighbor 20.20.20.1 soft-reconfiguration inbound maximum-paths 64 exit-address-family address-family l2vpn evpn advertise ipv4 unicast exit-address-family -router bgp 555 vrf Second +router bgp 555 vrf First no bgp default ipv4-unicast bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -26,11 +26,11 @@ router bgp 555 vrf Second bgp graceful-restart restart-time 240 bgp graceful-restart bgp router-id 10.20.30.40 - neighbor 20.20.20.1 remote-as 20 - neighbor 20.20.20.1 description session2 + neighbor 10.10.10.1 remote-as 10 + neighbor 10.10.10.1 description session1 address-family ipv4 unicast - neighbor 20.20.20.1 activate - neighbor 20.20.20.1 soft-reconfiguration inbound + neighbor 10.10.10.1 activate + neighbor 10.10.10.1 soft-reconfiguration inbound maximum-paths 64 exit-address-family address-family l2vpn evpn diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf index b1596909c788..1ed40fab744f 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf @@ -3,6 +3,7 @@ ! generated by templates/frr.conf.j2 with config DB data ! file: frr.conf ! +! ! template: common/daemons.common.conf.j2 ! hostname test_hostname @@ -15,11 +16,13 @@ log facility local4 ! end of template: common/daemons.common.conf.j2! agentx ! +! +! ! Enable link-detect (default disabled) -interface Ethernet0 +interface Ethernet4 link-detect ! -interface Ethernet4 +interface Ethernet0 link-detect ! interface PortChannel10 @@ -46,14 +49,15 @@ ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 ! ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 ! -ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.1/24 +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 10 permit 10.10.10.1/24 ! -ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::1/64 +ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 5 permit fc01::1/64 ! ! route-map HIDE_INTERNAL permit 10 set community local-AS ! +! router bgp 55555 ! bgp log-neighbor-changes @@ -73,10 +77,11 @@ router bgp 55555 network fc00::1/64 exit-address-family ! - network 10.10.10.1/24 address-family ipv6 network fc01::1/64 exit-address-family + network 10.10.10.1/24 +! ! address-family ipv4 redistribute connected route-map HIDE_INTERNAL diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf index 919c35085b5c..766509971224 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf @@ -1,9 +1,10 @@ ! +! ! Enable link-detect (default disabled) -interface Ethernet0 +interface Ethernet4 link-detect ! -interface Ethernet4 +interface Ethernet0 link-detect ! interface PortChannel10 @@ -12,3 +13,4 @@ link-detect interface PortChannel20 link-detect ! +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf index f7b30f214d4d..9f185edc2109 100644 --- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf @@ -3,6 +3,7 @@ ! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! +! ! template: common/daemons.common.conf.j2 ! hostname new_hostname @@ -14,17 +15,18 @@ log facility local4 ! ! end of template: common/daemons.common.conf.j2! ! +vrf Second +vni 20 +! vrf First vni 10 ! -vrf Second -vni 20 ! ! Enable link-detect (default disabled) -interface Ethernet0 +interface Ethernet4 link-detect ! -interface Ethernet4 +interface Ethernet0 link-detect ! interface PortChannel10 diff --git a/src/sonic-config-engine/__init__.py b/src/sonic-config-engine/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 3e4e661f6adc..fb547acd6927 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -16,8 +16,6 @@ See usage string for detail description for arguments. """ from __future__ import print_function -import sys -sys.path.insert(0, "/usr/local/lib/python2.7/dist-packages") # monkey patch re.compile to do lazy regular expression compilation. # This is done to improve import time of jinja2, yaml, natsort modules, because they @@ -28,28 +26,24 @@ sys.path.insert(0, "/usr/local/lib/python2.7/dist-packages") # FIXME: remove this once sonic-cfggen and templates dependencies are replaced with a faster approach import lazy_re -import sys -import os.path import argparse -import yaml +import contextlib import jinja2 -import netaddr import json -import contextlib +import netaddr +import os.path +import sys +import yaml + +from collections import OrderedDict +from config_samples import generate_sample_config, get_available_config 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 minigraph import minigraph_encoder, parse_xml, parse_device_desc_xml, parse_asic_sub_role from portconfig import get_port_config, get_breakout_mode +from redis_bcc import RedisBytecodeCache from sonic_py_common.multi_asic import get_asic_id_from_name, is_multi_asic from sonic_py_common import device_info -from config_samples import generate_sample_config -from config_samples import get_available_config from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig, ConfigDBPipeConnector -from redis_bcc import RedisBytecodeCache -from collections import OrderedDict -from natsort import natsorted #TODO: Remove STR_TYPE once SONiC moves to Python 3.x PY3x = sys.version_info >= (3, 0) @@ -166,9 +160,7 @@ TODO(taoyl): Current version of config db only supports BGP admin states. @staticmethod def to_serialized(data, lookup_key = None): if type(data) is dict: - data = OrderedDict(natsorted(data.items())) - - if lookup_key != None: + if lookup_key is not None: newData = {} for key in data.keys(): if ((type(key) is STR_TYPE and lookup_key == key) or (type(key) is tuple and lookup_key in key)): @@ -280,7 +272,7 @@ def main(): platform = device_info.get_platform() db_kwargs = {} - if args.redis_unix_sock_file != None: + if args.redis_unix_sock_file is not None: db_kwargs['unix_socket_path'] = args.redis_unix_sock_file data = {} @@ -314,17 +306,17 @@ def main(): _process_json(args, data) - if args.minigraph != None: + if args.minigraph is not None: minigraph = args.minigraph if platform: - if args.port_config != None: + if args.port_config is not None: deep_update(data, parse_xml(minigraph, platform, args.port_config, asic_name=asic_name, hwsku_config_file=args.hwsku_config)) else: deep_update(data, parse_xml(minigraph, platform, asic_name=asic_name)) else: deep_update(data, parse_xml(minigraph, port_config_file=args.port_config, asic_name=asic_name, hwsku_config_file=args.hwsku_config)) - if args.device_description != None: + if args.device_description is not None: deep_update(data, parse_device_desc_xml(args.device_description)) for yaml_file in args.yaml: @@ -335,7 +327,7 @@ def main(): additional_data = yaml.load(stream) deep_update(data, FormatConverter.to_deserialized(additional_data)) - if args.additional_data != None: + if args.additional_data is not None: deep_update(data, json.loads(args.additional_data)) if args.from_db: @@ -379,22 +371,21 @@ def main(): for template_file, _ in args.template: paths.append(os.path.dirname(os.path.abspath(template_file))) env = _get_jinja2_env(paths) - sorted_data = sort_data(data) for template_file, dest_file in args.template: template = env.get_template(os.path.basename(template_file)) - template_data = template.render(sorted_data) + template_data = template.render(data) if dest_file == "config-db": deep_update(data, FormatConverter.to_deserialized(json.loads(template_data))) else: with smart_open(dest_file, 'w') as df: print(template_data, file=df) - if args.var != None: + if args.var is not None: template = jinja2.Template('{{' + args.var + '}}') print(template.render(data)) - if args.var_json != None and args.var_json in data: - if args.key != None: + if args.var_json is not None and args.var_json in data: + if args.key is not None: print(json.dumps(FormatConverter.to_serialized(data[args.var_json], args.key), indent=4, cls=minigraph_encoder)) else: print(json.dumps(FormatConverter.to_serialized(data[args.var_json]), indent=4, cls=minigraph_encoder)) @@ -411,7 +402,7 @@ def main(): if args.print_data: print(json.dumps(FormatConverter.to_serialized(data), indent=4, cls=minigraph_encoder)) - if args.preset != None: + if args.preset is not None: data = generate_sample_config(data, args.preset) print(json.dumps(FormatConverter.to_serialized(data), indent=4, cls=minigraph_encoder)) diff --git a/src/sonic-config-engine/tests/common_utils.py b/src/sonic-config-engine/tests/common_utils.py new file mode 100644 index 000000000000..f75584471eb4 --- /dev/null +++ b/src/sonic-config-engine/tests/common_utils.py @@ -0,0 +1,30 @@ +import json +import re +import sys + + +def tuple_to_str(tuplestr): + """ Convert Python tuple '('elem1', 'elem2')' representation into string on the for "elem1|elem2" """ + def to_str(tupleobj): + tupleobj = re.sub(r"([\(\)])", '"', tupleobj.group(0)) + return re.sub(r"( *, *)", '|', tupleobj).replace("'", '') + + return re.sub(r"(\(.*?\))", to_str, tuplestr) + +def to_dict(dictstr): + """ Convert string represention of Python dict into dict """ + # handle tuple elements + dictstr = tuple_to_str(dictstr) + + return json.loads(dictstr.replace("'", '"')) + +def liststr_to_dict(liststr): + """ Convert string represention of Python list into dict with list key and sorted liststr as its value """ + # handle tuple elements + liststr = tuple_to_str(liststr) + + list_obj = json.loads("{\"list\":" + liststr.replace("'", '"') +'}') + list_obj["list"] = sorted(list_obj["list"]) + + return list_obj + diff --git a/src/sonic-config-engine/tests/multi_npu_data/ipinip.json b/src/sonic-config-engine/tests/multi_npu_data/ipinip.json index 0f8396e63b30..d48dcba30bd3 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/ipinip.json +++ b/src/sonic-config-engine/tests/multi_npu_data/ipinip.json @@ -2,7 +2,7 @@ { "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { "tunnel_type":"IPINIP", - "dst_ip":"10.1.0.32,8.0.0.0,10.0.0.0,10.1.0.1,10.1.0.3", + "dst_ip":"8.0.0.0,10.1.0.32,10.1.0.3,10.0.0.0,10.1.0.1", "dscp_mode":"pipe", "ecn_mode":"copy_from_outer", "ttl_mode":"pipe" diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf b/src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf index ebffcaa7c24d..f75d9de9a30e 100644 --- a/src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf +++ b/src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf @@ -23,19 +23,11 @@ router bgp 65100 bgp graceful-restart restart-time 240 bgp graceful-restart 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 10.1.0.32/32 network 192.168.0.1/27 - neighbor 10.0.0.57 remote-as 64600 - neighbor 10.0.0.57 description ARISTA01T1 - address-family ipv4 - neighbor 10.0.0.57 allowas-in 1 - neighbor 10.0.0.57 activate - neighbor 10.0.0.57 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family neighbor 10.0.0.59 remote-as 64600 neighbor 10.0.0.59 description ARISTA02T1 address-family ipv4 @@ -60,14 +52,6 @@ router bgp 65100 neighbor 10.0.0.63 soft-reconfiguration inbound maximum-paths 64 exit-address-family - neighbor fc00::7a remote-as 64600 - neighbor fc00::7a description ARISTA03T1 - address-family ipv6 - neighbor fc00::7a allowas-in 1 - neighbor fc00::7a activate - neighbor fc00::7a soft-reconfiguration inbound - maximum-paths 64 - exit-address-family neighbor fc00::7e remote-as 64600 neighbor fc00::7e description ARISTA04T1 address-family ipv6 @@ -76,12 +60,20 @@ router bgp 65100 neighbor fc00::7e soft-reconfiguration inbound maximum-paths 64 exit-address-family - neighbor fc00::72 remote-as 64600 - neighbor fc00::72 description ARISTA01T1 + neighbor fc00::7a remote-as 64600 + neighbor fc00::7a description ARISTA03T1 address-family ipv6 - neighbor fc00::72 allowas-in 1 - neighbor fc00::72 activate - neighbor fc00::72 soft-reconfiguration inbound + neighbor fc00::7a allowas-in 1 + neighbor fc00::7a activate + neighbor fc00::7a soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.57 remote-as 64600 + neighbor 10.0.0.57 description ARISTA01T1 + address-family ipv4 + neighbor 10.0.0.57 allowas-in 1 + neighbor 10.0.0.57 activate + neighbor 10.0.0.57 soft-reconfiguration inbound maximum-paths 64 exit-address-family neighbor fc00::76 remote-as 64600 @@ -92,6 +84,14 @@ router bgp 65100 neighbor fc00::76 soft-reconfiguration inbound maximum-paths 64 exit-address-family + neighbor fc00::72 remote-as 64600 + neighbor fc00::72 description ARISTA01T1 + address-family ipv6 + neighbor fc00::72 allowas-in 1 + neighbor fc00::72 activate + neighbor fc00::72 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family ! maximum-paths 64 ! diff --git a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json index 5cf0472f3f11..56de7500c1ad 100644 --- a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json +++ b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json @@ -2,56 +2,21 @@ { "CABLE_LENGTH": { "AZURE": { - "Ethernet0": "5m", - "Ethernet1": "5m", + "Ethernet8": "5m", + "Ethernet9": "5m", "Ethernet2": "5m", "Ethernet3": "5m", - "Ethernet4": "5m", - "Ethernet5": "5m", + "Ethernet0": "5m", + "Ethernet1": "5m", "Ethernet6": "5m", "Ethernet7": "5m", - "Ethernet8": "5m", - "Ethernet9": "5m", - "Ethernet10": "5m", - "Ethernet11": "5m", - "Ethernet12": "5m", - "Ethernet13": "5m", - "Ethernet14": "5m", - "Ethernet15": "5m", - "Ethernet16": "5m", - "Ethernet17": "5m", - "Ethernet18": "5m", - "Ethernet19": "5m", - "Ethernet20": "5m", - "Ethernet21": "5m", - "Ethernet22": "5m", - "Ethernet23": "5m", - "Ethernet24": "5m", - "Ethernet25": "5m", - "Ethernet26": "5m", - "Ethernet27": "5m", - "Ethernet28": "5m", - "Ethernet29": "5m", - "Ethernet30": "5m", - "Ethernet31": "5m", - "Ethernet32": "5m", - "Ethernet33": "5m", - "Ethernet34": "5m", - "Ethernet35": "5m", - "Ethernet36": "5m", - "Ethernet37": "5m", - "Ethernet38": "5m", - "Ethernet39": "5m", - "Ethernet40": "5m", - "Ethernet41": "5m", - "Ethernet42": "5m", - "Ethernet43": "5m", - "Ethernet44": "5m", - "Ethernet45": "5m", + "Ethernet4": "5m", + "Ethernet5": "5m", "Ethernet46": "5m", - "Ethernet47": "5m", - "Ethernet48": "5m", - "Ethernet49": "5m", + "Ethernet34": "5m", + "Ethernet22": "5m", + "Ethernet58": "5m", + "Ethernet59": "5m", "Ethernet50": "5m", "Ethernet51": "5m", "Ethernet52": "5m", @@ -60,12 +25,47 @@ "Ethernet55": "5m", "Ethernet56": "5m", "Ethernet57": "5m", - "Ethernet58": "5m", - "Ethernet59": "5m", - "Ethernet60": "5m", + "Ethernet38": "5m", + "Ethernet39": "5m", + "Ethernet18": "5m", + "Ethernet19": "5m", + "Ethernet14": "5m", + "Ethernet15": "5m", + "Ethernet16": "5m", + "Ethernet17": "5m", + "Ethernet10": "5m", + "Ethernet11": "5m", + "Ethernet12": "5m", + "Ethernet35": "5m", + "Ethernet37": "5m", + "Ethernet32": "5m", + "Ethernet33": "5m", + "Ethernet30": "5m", + "Ethernet31": "5m", + "Ethernet49": "5m", + "Ethernet48": "5m", + "Ethernet47": "5m", + "Ethernet36": "5m", + "Ethernet45": "5m", + "Ethernet44": "5m", + "Ethernet43": "5m", + "Ethernet42": "5m", + "Ethernet41": "5m", + "Ethernet40": "5m", + "Ethernet29": "5m", + "Ethernet28": "5m", "Ethernet61": "5m", + "Ethernet60": "5m", + "Ethernet63": "5m", "Ethernet62": "5m", - "Ethernet63": "5m" + "Ethernet21": "5m", + "Ethernet20": "5m", + "Ethernet23": "5m", + "Ethernet13": "5m", + "Ethernet25": "5m", + "Ethernet24": "5m", + "Ethernet27": "5m", + "Ethernet26": "5m" } }, @@ -105,16 +105,16 @@ } }, "BUFFER_PG": { - "Ethernet0|0": { + "Ethernet8|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet1|0": { + "Ethernet9|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet4|0": { + "Ethernet0|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet5|0": { + "Ethernet1|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, "Ethernet6|0": { @@ -123,64 +123,64 @@ "Ethernet7|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet8|0": { + "Ethernet4|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet9|0": { + "Ethernet5|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet10|0": { + "Ethernet58|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet11|0": { + "Ethernet52|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet12|0": { + "Ethernet53|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet13|0": { + "Ethernet54|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet14|0": { + "Ethernet55|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet15|0": { + "Ethernet56|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet16|0": { + "Ethernet57|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet17|0": { + "Ethernet38|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet20|0": { + "Ethernet39|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet21|0": { + "Ethernet32|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet22|0": { + "Ethernet15|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet23|0": { + "Ethernet16|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet24|0": { + "Ethernet17|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet25|0": { + "Ethernet36|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet26|0": { + "Ethernet37|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet27|0": { + "Ethernet12|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet28|0": { + "Ethernet13|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet29|0": { + "Ethernet14|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, "Ethernet30|0": { @@ -189,67 +189,67 @@ "Ethernet31|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet32|0": { + "Ethernet48|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet36|0": { + "Ethernet10|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet37|0": { + "Ethernet42|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet38|0": { + "Ethernet41|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet39|0": { + "Ethernet40|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet40|0": { + "Ethernet29|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet41|0": { + "Ethernet28|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet42|0": { + "Ethernet11|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet48|0": { + "Ethernet21|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet52|0": { + "Ethernet20|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet53|0": { + "Ethernet23|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet54|0": { + "Ethernet22|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet55|0": { + "Ethernet25|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet56|0": { + "Ethernet24|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet57|0": { + "Ethernet27|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "Ethernet58|0": { + "Ethernet26|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, "BUFFER_QUEUE": { - "Ethernet0|3-4": { + "Ethernet8|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet1|3-4": { + "Ethernet9|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet4|3-4": { + "Ethernet0|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet5|3-4": { + "Ethernet1|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, "Ethernet6|3-4": { @@ -258,64 +258,64 @@ "Ethernet7|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet8|3-4": { + "Ethernet4|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet9|3-4": { + "Ethernet5|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet10|3-4": { + "Ethernet58|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet11|3-4": { + "Ethernet52|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet12|3-4": { + "Ethernet53|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet13|3-4": { + "Ethernet54|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet14|3-4": { + "Ethernet55|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet15|3-4": { + "Ethernet56|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet16|3-4": { + "Ethernet57|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet17|3-4": { + "Ethernet38|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet20|3-4": { + "Ethernet39|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet21|3-4": { + "Ethernet32|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet22|3-4": { + "Ethernet15|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet23|3-4": { + "Ethernet16|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet24|3-4": { + "Ethernet17|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet25|3-4": { + "Ethernet36|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet26|3-4": { + "Ethernet37|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet27|3-4": { + "Ethernet12|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet28|3-4": { + "Ethernet13|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet29|3-4": { + "Ethernet14|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, "Ethernet30|3-4": { @@ -324,64 +324,64 @@ "Ethernet31|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet32|3-4": { + "Ethernet48|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet36|3-4": { + "Ethernet10|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet37|3-4": { + "Ethernet42|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet38|3-4": { + "Ethernet41|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet39|3-4": { + "Ethernet40|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet40|3-4": { + "Ethernet29|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet41|3-4": { + "Ethernet28|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet42|3-4": { + "Ethernet11|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet48|3-4": { + "Ethernet21|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet52|3-4": { + "Ethernet20|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet53|3-4": { + "Ethernet23|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet54|3-4": { + "Ethernet22|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet55|3-4": { + "Ethernet25|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet56|3-4": { + "Ethernet24|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet57|3-4": { + "Ethernet27|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet58|3-4": { + "Ethernet26|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet0|0-2": { + "Ethernet8|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet1|0-2": { + "Ethernet9|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet4|0-2": { + "Ethernet0|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet5|0-2": { + "Ethernet1|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, "Ethernet6|0-2": { @@ -390,64 +390,64 @@ "Ethernet7|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet8|0-2": { + "Ethernet4|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet9|0-2": { + "Ethernet5|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet10|0-2": { + "Ethernet58|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet11|0-2": { + "Ethernet52|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet12|0-2": { + "Ethernet53|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet13|0-2": { + "Ethernet54|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet14|0-2": { + "Ethernet55|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet15|0-2": { + "Ethernet56|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet16|0-2": { + "Ethernet57|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet17|0-2": { + "Ethernet38|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet20|0-2": { + "Ethernet39|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet21|0-2": { + "Ethernet32|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet22|0-2": { + "Ethernet15|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet23|0-2": { + "Ethernet16|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet24|0-2": { + "Ethernet17|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet25|0-2": { + "Ethernet36|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet26|0-2": { + "Ethernet37|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet27|0-2": { + "Ethernet12|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet28|0-2": { + "Ethernet13|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet29|0-2": { + "Ethernet14|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, "Ethernet30|0-2": { @@ -456,64 +456,64 @@ "Ethernet31|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet32|0-2": { + "Ethernet48|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet36|0-2": { + "Ethernet10|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet37|0-2": { + "Ethernet42|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet38|0-2": { + "Ethernet41|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet39|0-2": { + "Ethernet40|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet40|0-2": { + "Ethernet29|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet41|0-2": { + "Ethernet28|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet42|0-2": { + "Ethernet11|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet48|0-2": { + "Ethernet21|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet52|0-2": { + "Ethernet20|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet53|0-2": { + "Ethernet23|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet54|0-2": { + "Ethernet22|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet55|0-2": { + "Ethernet25|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet56|0-2": { + "Ethernet24|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet57|0-2": { + "Ethernet27|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet58|0-2": { + "Ethernet26|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet0|5-6": { + "Ethernet8|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet1|5-6": { + "Ethernet9|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet4|5-6": { + "Ethernet0|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet5|5-6": { + "Ethernet1|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, "Ethernet6|5-6": { @@ -522,64 +522,64 @@ "Ethernet7|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet8|5-6": { + "Ethernet4|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet9|5-6": { + "Ethernet5|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet10|5-6": { + "Ethernet58|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet11|5-6": { + "Ethernet52|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet12|5-6": { + "Ethernet53|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet13|5-6": { + "Ethernet54|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet14|5-6": { + "Ethernet55|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet15|5-6": { + "Ethernet56|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet16|5-6": { + "Ethernet57|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet17|5-6": { + "Ethernet38|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet20|5-6": { + "Ethernet39|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet21|5-6": { + "Ethernet32|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet22|5-6": { + "Ethernet15|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet23|5-6": { + "Ethernet16|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet24|5-6": { + "Ethernet17|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet25|5-6": { + "Ethernet36|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet26|5-6": { + "Ethernet37|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet27|5-6": { + "Ethernet12|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet28|5-6": { + "Ethernet13|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet29|5-6": { + "Ethernet14|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, "Ethernet30|5-6": { @@ -588,52 +588,52 @@ "Ethernet31|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet32|5-6": { + "Ethernet48|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet36|5-6": { + "Ethernet10|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet37|5-6": { + "Ethernet42|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet38|5-6": { + "Ethernet41|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet39|5-6": { + "Ethernet40|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet40|5-6": { + "Ethernet29|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet41|5-6": { + "Ethernet28|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet42|5-6": { + "Ethernet11|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet48|5-6": { + "Ethernet21|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet52|5-6": { + "Ethernet20|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet53|5-6": { + "Ethernet23|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet54|5-6": { + "Ethernet22|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet55|5-6": { + "Ethernet25|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet56|5-6": { + "Ethernet24|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet57|5-6": { + "Ethernet27|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet58|5-6": { + "Ethernet26|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index 3e485f4ddc35..be52694b78c5 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf @@ -42,7 +42,7 @@ dependent_startup_wait_for=rsyslogd:running programs=isc-dhcp-relay-Vlan1000 [program:isc-dhcp-relay-Vlan1000] -command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 192.0.0.1 192.0.0.2 +command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -iu PortChannel01 192.0.0.1 192.0.0.2 priority=3 autostart=false autorestart=false @@ -56,7 +56,7 @@ dependent_startup_wait_for=start:exited programs=dhcpmon-Vlan1000 [program:dhcpmon-Vlan1000] -command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -im eth0 +command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -iu PortChannel01 -im eth0 priority=4 autostart=false autorestart=false diff --git a/src/sonic-config-engine/tests/sample_output/frr.conf b/src/sonic-config-engine/tests/sample_output/frr.conf index 6e8573e9ba9d..1df7344a9d92 100644 --- a/src/sonic-config-engine/tests/sample_output/frr.conf +++ b/src/sonic-config-engine/tests/sample_output/frr.conf @@ -19,13 +19,13 @@ agentx ! ! ! Enable link-detect (default disabled) -interface PortChannel01 +interface PortChannel03 link-detect ! interface PortChannel02 link-detect ! -interface PortChannel03 +interface PortChannel01 link-detect ! interface PortChannel04 diff --git a/src/sonic-config-engine/tests/sample_output/ipinip.json b/src/sonic-config-engine/tests/sample_output/ipinip.json index e4028ea01a2d..c93564de77e9 100644 --- a/src/sonic-config-engine/tests/sample_output/ipinip.json +++ b/src/sonic-config-engine/tests/sample_output/ipinip.json @@ -2,7 +2,7 @@ { "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { "tunnel_type":"IPINIP", - "dst_ip":"10.1.0.32,10.0.0.56,10.0.0.58,10.0.0.60,10.0.0.62,192.168.0.1", + "dst_ip":"10.1.0.32,10.0.0.58,10.0.0.60,10.0.0.62,10.0.0.56,192.168.0.1", "dscp_mode":"pipe", "ecn_mode":"copy_from_outer", "ttl_mode":"pipe" @@ -13,7 +13,7 @@ { "TUNNEL_DECAP_TABLE:IPINIP_V6_TUNNEL" : { "tunnel_type":"IPINIP", - "dst_ip":"fc00:1::32,fc00::71,fc00::75,fc00::79,fc00::7d", + "dst_ip":"fc00:1::32,fc00::7d,fc00::79,fc00::71,fc00::75", "dscp_mode":"pipe", "ecn_mode":"copy_from_outer", "ttl_mode":"pipe" diff --git a/src/sonic-config-engine/tests/sample_output/l2switch.json b/src/sonic-config-engine/tests/sample_output/l2switch.json index fd83589153ea..1c9e0ebbcd2e 100644 --- a/src/sonic-config-engine/tests/sample_output/l2switch.json +++ b/src/sonic-config-engine/tests/sample_output/l2switch.json @@ -1,6 +1,11 @@ { "DEVICE_METADATA": {"localhost": {"hwsku": "Mellanox-SN2700"}}, "PORT": { + "Ethernet8": { + "alias": "fortyGigE0/8", + "lanes": "37,38,39,40", + "admin_status": "up" + }, "Ethernet0": { "alias": "fortyGigE0/0", "lanes": "29,30,31,32", @@ -11,59 +16,44 @@ "lanes": "25,26,27,28", "admin_status": "up" }, - "Ethernet8": { - "alias": "fortyGigE0/8", - "lanes": "37,38,39,40", - "admin_status": "up" - }, - "Ethernet12": { - "alias": "fortyGigE0/12", - "lanes": "33,34,35,36", - "admin_status": "up" - }, - "Ethernet16": { - "alias": "fortyGigE0/16", - "lanes": "41,42,43,44", - "admin_status": "up" - }, - "Ethernet20": { - "alias": "fortyGigE0/20", - "lanes": "45,46,47,48", + "Ethernet108": { + "alias": "fortyGigE0/108", + "lanes": "81,82,83,84", "admin_status": "up" }, - "Ethernet24": { - "alias": "fortyGigE0/24", - "lanes": "5,6,7,8", + "Ethernet100": { + "alias": "fortyGigE0/100", + "lanes": "125,126,127,128", "admin_status": "up" }, - "Ethernet28": { - "alias": "fortyGigE0/28", - "lanes": "1,2,3,4", + "Ethernet104": { + "alias": "fortyGigE0/104", + "lanes": "85,86,87,88", "admin_status": "up" }, - "Ethernet32": { - "alias": "fortyGigE0/32", - "lanes": "9,10,11,12", + "Ethernet68": { + "alias": "fortyGigE0/68", + "lanes": "69,70,71,72", "admin_status": "up" }, - "Ethernet36": { - "alias": "fortyGigE0/36", - "lanes": "13,14,15,16", + "Ethernet96": { + "alias": "fortyGigE0/96", + "lanes": "121,122,123,124", "admin_status": "up" }, - "Ethernet40": { - "alias": "fortyGigE0/40", - "lanes": "21,22,23,24", + "Ethernet124": { + "alias": "fortyGigE0/124", + "lanes": "101,102,103,104", "admin_status": "up" }, - "Ethernet44": { - "alias": "fortyGigE0/44", - "lanes": "17,18,19,20", + "Ethernet92": { + "alias": "fortyGigE0/92", + "lanes": "113,114,115,116", "admin_status": "up" }, - "Ethernet48": { - "alias": "fortyGigE0/48", - "lanes": "49,50,51,52", + "Ethernet120": { + "alias": "fortyGigE0/120", + "lanes": "97,98,99,100", "admin_status": "up" }, "Ethernet52": { @@ -76,9 +66,14 @@ "lanes": "61,62,63,64", "admin_status": "up" }, - "Ethernet60": { - "alias": "fortyGigE0/60", - "lanes": "57,58,59,60", + "Ethernet76": { + "alias": "fortyGigE0/76", + "lanes": "73,74,75,76", + "admin_status": "up" + }, + "Ethernet72": { + "alias": "fortyGigE0/72", + "lanes": "77,78,79,80", "admin_status": "up" }, "Ethernet64": { @@ -86,29 +81,24 @@ "lanes": "65,66,67,68", "admin_status": "up" }, - "Ethernet68": { - "alias": "fortyGigE0/68", - "lanes": "69,70,71,72", - "admin_status": "up" - }, - "Ethernet72": { - "alias": "fortyGigE0/72", - "lanes": "77,78,79,80", + "Ethernet32": { + "alias": "fortyGigE0/32", + "lanes": "9,10,11,12", "admin_status": "up" }, - "Ethernet76": { - "alias": "fortyGigE0/76", - "lanes": "73,74,75,76", + "Ethernet16": { + "alias": "fortyGigE0/16", + "lanes": "41,42,43,44", "admin_status": "up" }, - "Ethernet80": { - "alias": "fortyGigE0/80", - "lanes": "105,106,107,108", + "Ethernet36": { + "alias": "fortyGigE0/36", + "lanes": "13,14,15,16", "admin_status": "up" }, - "Ethernet84": { - "alias": "fortyGigE0/84", - "lanes": "109,110,111,112", + "Ethernet12": { + "alias": "fortyGigE0/12", + "lanes": "33,34,35,36", "admin_status": "up" }, "Ethernet88": { @@ -116,49 +106,59 @@ "lanes": "117,118,119,120", "admin_status": "up" }, - "Ethernet92": { - "alias": "fortyGigE0/92", - "lanes": "113,114,115,116", + "Ethernet116": { + "alias": "fortyGigE0/116", + "lanes": "93,94,95,96", "admin_status": "up" }, - "Ethernet96": { - "alias": "fortyGigE0/96", - "lanes": "121,122,123,124", + "Ethernet80": { + "alias": "fortyGigE0/80", + "lanes": "105,106,107,108", "admin_status": "up" }, - "Ethernet100": { - "alias": "fortyGigE0/100", - "lanes": "125,126,127,128", + "Ethernet112": { + "alias": "fortyGigE0/112", + "lanes": "89,90,91,92", "admin_status": "up" }, - "Ethernet104": { - "alias": "fortyGigE0/104", - "lanes": "85,86,87,88", + "Ethernet84": { + "alias": "fortyGigE0/84", + "lanes": "109,110,111,112", "admin_status": "up" }, - "Ethernet108": { - "alias": "fortyGigE0/108", - "lanes": "81,82,83,84", + "Ethernet48": { + "alias": "fortyGigE0/48", + "lanes": "49,50,51,52", "admin_status": "up" }, - "Ethernet112": { - "alias": "fortyGigE0/112", - "lanes": "89,90,91,92", + "Ethernet44": { + "alias": "fortyGigE0/44", + "lanes": "17,18,19,20", "admin_status": "up" }, - "Ethernet116": { - "alias": "fortyGigE0/116", - "lanes": "93,94,95,96", + "Ethernet40": { + "alias": "fortyGigE0/40", + "lanes": "21,22,23,24", "admin_status": "up" }, - "Ethernet120": { - "alias": "fortyGigE0/120", - "lanes": "97,98,99,100", + "Ethernet28": { + "alias": "fortyGigE0/28", + "lanes": "1,2,3,4", "admin_status": "up" }, - "Ethernet124": { - "alias": "fortyGigE0/124", - "lanes": "101,102,103,104", + "Ethernet60": { + "alias": "fortyGigE0/60", + "lanes": "57,58,59,60", + "admin_status": "up" + }, + "Ethernet20": { + "alias": "fortyGigE0/20", + "lanes": "45,46,47,48", + "admin_status": "up" + }, + "Ethernet24": { + "alias": "fortyGigE0/24", + "lanes": "5,6,7,8", "admin_status": "up" } }, @@ -168,43 +168,37 @@ } }, "VLAN_MEMBER": { - "Vlan1000|Ethernet0": { - "tagging_mode": "untagged" - }, - "Vlan1000|Ethernet4": { - "tagging_mode": "untagged" - }, "Vlan1000|Ethernet8": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet12": { + "Vlan1000|Ethernet0": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet16": { + "Vlan1000|Ethernet4": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet20": { + "Vlan1000|Ethernet108": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet24": { + "Vlan1000|Ethernet100": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet28": { + "Vlan1000|Ethernet104": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet32": { + "Vlan1000|Ethernet68": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet36": { + "Vlan1000|Ethernet96": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet40": { + "Vlan1000|Ethernet124": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet44": { + "Vlan1000|Ethernet92": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet48": { + "Vlan1000|Ethernet120": { "tagging_mode": "untagged" }, "Vlan1000|Ethernet52": { @@ -213,55 +207,61 @@ "Vlan1000|Ethernet56": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet60": { + "Vlan1000|Ethernet76": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet64": { + "Vlan1000|Ethernet72": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet68": { + "Vlan1000|Ethernet64": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet72": { + "Vlan1000|Ethernet32": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet76": { + "Vlan1000|Ethernet16": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet80": { + "Vlan1000|Ethernet36": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet84": { + "Vlan1000|Ethernet12": { "tagging_mode": "untagged" }, "Vlan1000|Ethernet88": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet92": { + "Vlan1000|Ethernet116": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet96": { + "Vlan1000|Ethernet80": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet100": { + "Vlan1000|Ethernet112": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet104": { + "Vlan1000|Ethernet84": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet108": { + "Vlan1000|Ethernet48": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet112": { + "Vlan1000|Ethernet44": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet116": { + "Vlan1000|Ethernet40": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet120": { + "Vlan1000|Ethernet28": { "tagging_mode": "untagged" }, - "Vlan1000|Ethernet124": { + "Vlan1000|Ethernet60": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet20": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet24": { "tagging_mode": "untagged" } } diff --git a/src/sonic-config-engine/tests/sample_output/ports.json b/src/sonic-config-engine/tests/sample_output/ports.json index 36f5ad117c39..0e174972fbe4 100644 --- a/src/sonic-config-engine/tests/sample_output/ports.json +++ b/src/sonic-config-engine/tests/sample_output/ports.json @@ -1,4 +1,11 @@ [ + { + "PORT_TABLE:Ethernet8": { + "speed": "1000", + "description": "Interface description" + }, + "OP": "SET" + }, { "PORT_TABLE:Ethernet0": { "speed": "10000", @@ -13,13 +20,6 @@ }, "OP": "SET" }, - { - "PORT_TABLE:Ethernet8": { - "speed": "1000", - "description": "Interface description" - }, - "OP": "SET" - }, { "PORT_TABLE:Ethernet12": { "speed": "100000", 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 180a0e9fab89..653cc1510fb0 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 @@ -20,13 +20,13 @@ vni 9000 ! ! ! Enable link-detect (default disabled) -interface Ethernet0 +interface Ethernet8 link-detect ! interface Ethernet4 link-detect ! -interface Ethernet8 +interface Ethernet0 link-detect ! !! 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 661b27268255..a521da917d45 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 @@ -20,13 +20,13 @@ vni 8000 ! ! ! Enable link-detect (default disabled) -interface Ethernet0 +interface Ethernet8 link-detect ! interface Ethernet4 link-detect ! -interface Ethernet8 +interface Ethernet0 link-detect ! !! diff --git a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh index 6d90afa60ad7..2af5cee2f005 100644 --- a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh +++ b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh @@ -24,8 +24,8 @@ function wait_until_iface_ready # Wait for all interfaces with IPv4 addresses to be up and ready wait_until_iface_ready Vlan1000 192.168.0.1/27 -wait_until_iface_ready PortChannel01 10.0.0.56/31 wait_until_iface_ready PortChannel02 10.0.0.58/31 wait_until_iface_ready PortChannel03 10.0.0.60/31 wait_until_iface_ready PortChannel04 10.0.0.62/31 +wait_until_iface_ready PortChannel01 10.0.0.56/31 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 e3d0c2d55bc3..ee48a4e53cae 100644 --- a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/zebra_frr.conf @@ -17,13 +17,13 @@ log facility local4 ! ! ! Enable link-detect (default disabled) -interface PortChannel01 +interface PortChannel03 link-detect ! interface PortChannel02 link-detect ! -interface PortChannel03 +interface PortChannel01 link-detect ! interface PortChannel04 diff --git a/src/sonic-config-engine/tests/sample_output/zebra_quagga.conf b/src/sonic-config-engine/tests/sample_output/zebra_quagga.conf index aa3486b0163a..b1b791b252e8 100644 --- a/src/sonic-config-engine/tests/sample_output/zebra_quagga.conf +++ b/src/sonic-config-engine/tests/sample_output/zebra_quagga.conf @@ -9,13 +9,13 @@ password zebra enable password zebra ! ! Enable link-detect (default disabled) -interface PortChannel01 +interface PortChannel03 link-detect ! interface PortChannel02 link-detect ! -interface PortChannel03 +interface PortChannel01 link-detect ! interface PortChannel04 diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index fcdb7e9f2475..1fb231a96864 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -1,8 +1,11 @@ -from unittest import TestCase import json import subprocess import os +import tests.common_utils as utils + +from unittest import TestCase + TOR_ROUTER = 'ToRRouter' BACKEND_TOR_ROUTER = 'BackEndToRRouter' @@ -94,18 +97,23 @@ def test_additional_json_data(self): def test_additional_json_data_level1_key(self): argument = '-a \'{"k1":{"k11":"v11","k12":"v12"}, "k2":{"k22":"v22"}}\' --var-json k1' output = self.run_script(argument) - self.assertEqual(output.strip(), '{\n "k11": "v11", \n "k12": "v12"\n}') + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict('{\n "k11": "v11", \n "k12": "v12"\n}')) def test_additional_json_data_level2_key(self): argument = '-a \'{"k1":{"k11":"v11","k12":"v12"},"k2":{"k22":"v22"}}\' --var-json k1 -K k11' output = self.run_script(argument) - self.assertEqual(output.strip(), '{\n "k11": "v11"\n}') + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict('{\n "k11": "v11"\n}')) def test_var_json_data(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" --var-json VLAN_MEMBER' output = self.run_script(argument) - self.assertEqual(output.strip(), '{\n "Vlan1000|Ethernet8": {\n "tagging_mode": "untagged"\n },' - ' \n "Vlan2020|Ethernet12": {\n "tagging_mode": "tagged"\n }\n}') + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + '{\n "Vlan1000|Ethernet8": {\n "tagging_mode": "untagged"\n },' + ' \n "Vlan2020|Ethernet12": {\n "tagging_mode": "tagged"\n }\n}' + ) + ) def test_read_yaml(self): argument = '-v yml_item -y ' + os.path.join(self.test_dir, 'test.yml') @@ -147,16 +155,20 @@ def test_template_json_batch_mode(self): def test_minigraph_acl(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v ACL_TABLE' output = self.run_script(argument, True) - self.assertEqual(output.strip(), "Warning: Ignoring Control Plane ACL NTP_ACL without type\n" - "{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, " - "'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOW'}, " - "'EVERFLOW_EGRESS': {'stage': 'egress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOW_EGRESS'}, " - "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT', 'stage': 'ingress'}, " - "'DATAACLINGRESS': {'stage': 'ingress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04'], 'policy_desc': 'DATAACLINGRESS'}, " - "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL', 'stage': 'ingress'}, " - "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL', 'stage': 'ingress'}, " - "'DATAACLEGRESS': {'stage': 'egress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02'], 'policy_desc': 'DATAACLEGRESS'}, " - "'EVERFLOWV6': {'stage': 'ingress', 'type': 'MIRRORV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOWV6'}}") + self.assertEqual( + utils.to_dict(output.strip().replace("Warning: Ignoring Control Plane ACL NTP_ACL without type\n", '')), + utils.to_dict( + "{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, " + "'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOW'}, " + "'EVERFLOW_EGRESS': {'stage': 'egress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOW_EGRESS'}, " + "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT', 'stage': 'ingress'}, " + "'DATAACLINGRESS': {'stage': 'ingress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04'], 'policy_desc': 'DATAACLINGRESS'}, " + "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL', 'stage': 'ingress'}, " + "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL', 'stage': 'ingress'}, " + "'DATAACLEGRESS': {'stage': 'egress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02'], 'policy_desc': 'DATAACLEGRESS'}, " + "'EVERFLOWV6': {'stage': 'ingress', 'type': 'MIRRORV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4', 'Ethernet100'], 'policy_desc': 'EVERFLOWV6'}}" + ) + ) # everflow portion is not used # def test_minigraph_everflow(self): @@ -167,7 +179,10 @@ def test_minigraph_acl(self): def test_minigraph_mgmt_ports(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v MGMT_PORT' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'eth0': {'alias': 'Management0', 'admin_status': 'up'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'eth0': {'alias': 'Management0', 'admin_status': 'up'}}") + ) def test_minigraph_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "INTERFACE.keys()"' @@ -177,16 +192,22 @@ def test_minigraph_interfaces(self): def test_minigraph_vlans(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN' output = self.run_script(argument) - self.assertEqual(output.strip(), - "{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}, " - "'Vlan2020': {'alias': 'kk1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '2020'}}") - + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}, " + "'Vlan2020': {'alias': 'kk1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '2020'}}" + ) + ) def test_minigraph_vlan_members(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN_MEMBER' output = self.run_script(argument) - self.assertEqual(output.strip(), "{('Vlan1000', 'Ethernet8'): {'tagging_mode': 'untagged'}, " - "('Vlan2020', 'Ethernet12'): {'tagging_mode': 'tagged'}}") + self.assertEqual( + output.strip(), + "{('Vlan1000', 'Ethernet8'): {'tagging_mode': 'untagged'}, " + "('Vlan2020', 'Ethernet12'): {'tagging_mode': 'tagged'}}" + ) def test_minigraph_vlan_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()"' @@ -196,27 +217,42 @@ def test_minigraph_vlan_interfaces(self): def test_minigraph_portchannels(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v PORTCHANNEL' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'PortChannel01': {'admin_status': 'up', 'min_links': '1', 'members': ['Ethernet4'], 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'PortChannel01': {'admin_status': 'up', 'min_links': '1', 'members': ['Ethernet4'], 'mtu': '9100'}}") + ) def test_minigraph_portchannel_with_more_member(self): argument = '-m "' + self.sample_graph_pc_test + '" -p "' + self.port_config + '" -v PORTCHANNEL' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'PortChannel01': {'admin_status': 'up', 'min_links': '3', 'members': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124'], 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'PortChannel01': {'admin_status': 'up', 'min_links': '3', 'members': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124'], 'mtu': '9100'}}") + ) def test_minigraph_portchannel_members(self): argument = '-m "' + self.sample_graph_pc_test + '" -p "' + self.port_config + '" -v "PORTCHANNEL_MEMBER.keys()"' output = self.run_script(argument) - self.assertEqual(output.strip(), "[('PortChannel01', 'Ethernet120'), ('PortChannel01', 'Ethernet116'), ('PortChannel01', 'Ethernet124'), ('PortChannel01', 'Ethernet112')]") + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("[('PortChannel01', 'Ethernet120'), ('PortChannel01', 'Ethernet116'), ('PortChannel01', 'Ethernet124'), ('PortChannel01', 'Ethernet112')]") + ) def test_minigraph_portchannel_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORTCHANNEL_INTERFACE.keys()"' output = self.run_script(argument) - self.assertEqual(output.strip(), "['PortChannel01', ('PortChannel01', '10.0.0.56/31'), ('PortChannel01', 'FC00::71/126')]") + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['PortChannel01', ('PortChannel01', '10.0.0.56/31'), ('PortChannel01', 'FC00::71/126')]") + ) def test_minigraph_neighbors(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "DEVICE_NEIGHBOR[\'Ethernet124\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}") + ) # FIXME: This test depends heavily on the ordering of the interfaces and # it is not at all intuitive what that ordering should be. Could make it @@ -224,39 +260,57 @@ def test_minigraph_neighbors(self): def test_minigraph_extra_neighbors(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v DEVICE_NEIGHBOR' output = self.run_script(argument) - self.assertEqual(output.strip(), \ + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( "{'Ethernet124': {'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}, " "'Ethernet120': {'name': 'ARISTA03T1', 'port': 'Ethernet1/1'}, " "'Ethernet4': {'name': 'Servers0', 'port': 'eth0'}, " "'Ethernet116': {'name': 'ARISTA02T1', 'port': 'Ethernet1/1'}, " "'Ethernet100': {'name': 'Servers100', 'port': 'eth0'}, " "'Ethernet112': {'name': 'ARISTA01T1', 'port': 'Ethernet1/1'}}") + ) def test_minigraph_port_description(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet124\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}") + ) def test_minigraph_port_fec_disabled(self): # Test for FECDisabled argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet4\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '25,26,27,28', 'description': 'Servers0:eth0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '100000'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '25,26,27,28', 'description': 'Servers0:eth0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '100000'}") + ) def test_minigraph_port_rs(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet124\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}") + ) def test_minigraph_bgp(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "BGP_NEIGHBOR[\'10.0.0.59\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'rrclient': 0, 'name': 'ARISTA02T1', 'local_addr': '10.0.0.58', 'nhopself': 0, 'holdtime': '180', 'asn': '64600', 'keepalive': '60'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'rrclient': 0, 'name': 'ARISTA02T1', 'local_addr': '10.0.0.58', 'nhopself': 0, 'holdtime': '180', 'asn': '64600', 'keepalive': '60'}") + ) def test_minigraph_peers_with_range(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v BGP_PEER_RANGE.values\(\)' output = self.run_script(argument) - self.assertEqual(output.strip(), "[{'src_address': '10.1.0.32', 'name': 'BGPSLBPassive', 'ip_range': ['10.10.10.10/26', '100.100.100.100/26']}]") + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("[{'src_address': '10.1.0.32', 'name': 'BGPSLBPassive', 'ip_range': ['10.10.10.10/26', '100.100.100.100/26']}]") + ) def test_minigraph_deployment_id(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'deployment_id\']"' @@ -266,86 +320,100 @@ def test_minigraph_deployment_id(self): def test_minigraph_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet8\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '1000'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '1000'}") + ) argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet12\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'lanes': '33,34,35,36', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '100000', 'description': 'Interface description'}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'lanes': '33,34,35,36', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '100000', 'description': 'Interface description'}") + ) def test_minigraph_neighbor_interfaces(self): argument = '-m "' + self.sample_graph_simple_case + '" -p "' + self.port_config + '" -v "PORT"' output = self.run_script(argument) - self.assertEqual(output.strip(), \ - "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '40000'}, " - "'Ethernet0': {'lanes': '29,30,31,32', 'description': 'switch-01t1:port1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, " - "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000'}, " - "'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, " - "'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, " - "'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, " - "'Ethernet68': {'alias': 'fortyGigE0/68', 'pfc_asym': 'off', 'lanes': '69,70,71,72', 'description': 'fortyGigE0/68', 'mtu': '9100'}, " - "'Ethernet96': {'alias': 'fortyGigE0/96', 'pfc_asym': 'off', 'lanes': '121,122,123,124', 'description': 'fortyGigE0/96', 'mtu': '9100'}, " - "'Ethernet124': {'alias': 'fortyGigE0/124', 'pfc_asym': 'off', 'lanes': '101,102,103,104', 'description': 'fortyGigE0/124', 'mtu': '9100'}, " - "'Ethernet92': {'alias': 'fortyGigE0/92', 'pfc_asym': 'off', 'lanes': '113,114,115,116', 'description': 'fortyGigE0/92', 'mtu': '9100'}, " - "'Ethernet120': {'alias': 'fortyGigE0/120', 'pfc_asym': 'off', 'lanes': '97,98,99,100', 'description': 'fortyGigE0/120', 'mtu': '9100'}, " - "'Ethernet52': {'alias': 'fortyGigE0/52', 'pfc_asym': 'off', 'lanes': '53,54,55,56', 'description': 'fortyGigE0/52', 'mtu': '9100'}, " - "'Ethernet56': {'alias': 'fortyGigE0/56', 'pfc_asym': 'off', 'lanes': '61,62,63,64', 'description': 'fortyGigE0/56', 'mtu': '9100'}, " - "'Ethernet76': {'alias': 'fortyGigE0/76', 'pfc_asym': 'off', 'lanes': '73,74,75,76', 'description': 'fortyGigE0/76', 'mtu': '9100'}, " - "'Ethernet72': {'alias': 'fortyGigE0/72', 'pfc_asym': 'off', 'lanes': '77,78,79,80', 'description': 'fortyGigE0/72', 'mtu': '9100'}, " - "'Ethernet64': {'alias': 'fortyGigE0/64', 'pfc_asym': 'off', 'lanes': '65,66,67,68', 'description': 'fortyGigE0/64', 'mtu': '9100'}, " - "'Ethernet32': {'alias': 'fortyGigE0/32', 'pfc_asym': 'off', 'lanes': '9,10,11,12', 'description': 'fortyGigE0/32', 'mtu': '9100'}, " - "'Ethernet16': {'alias': 'fortyGigE0/16', 'pfc_asym': 'off', 'lanes': '41,42,43,44', 'description': 'fortyGigE0/16', 'mtu': '9100'}, " - "'Ethernet36': {'alias': 'fortyGigE0/36', 'pfc_asym': 'off', 'lanes': '13,14,15,16', 'description': 'fortyGigE0/36', 'mtu': '9100'}, " - "'Ethernet12': {'lanes': '33,34,35,36', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '10000'}, " - "'Ethernet88': {'alias': 'fortyGigE0/88', 'pfc_asym': 'off', 'lanes': '117,118,119,120', 'description': 'fortyGigE0/88', 'mtu': '9100'}, " - "'Ethernet116': {'alias': 'fortyGigE0/116', 'pfc_asym': 'off', 'lanes': '93,94,95,96', 'description': 'fortyGigE0/116', 'mtu': '9100'}, " - "'Ethernet80': {'alias': 'fortyGigE0/80', 'pfc_asym': 'off', 'lanes': '105,106,107,108', 'description': 'fortyGigE0/80', 'mtu': '9100'}, " - "'Ethernet112': {'alias': 'fortyGigE0/112', 'pfc_asym': 'off', 'lanes': '89,90,91,92', 'description': 'fortyGigE0/112', 'mtu': '9100'}, " - "'Ethernet84': {'alias': 'fortyGigE0/84', 'pfc_asym': 'off', 'lanes': '109,110,111,112', 'description': 'fortyGigE0/84', 'mtu': '9100'}, " - "'Ethernet48': {'alias': 'fortyGigE0/48', 'pfc_asym': 'off', 'lanes': '49,50,51,52', 'description': 'fortyGigE0/48', 'mtu': '9100'}, " - "'Ethernet44': {'alias': 'fortyGigE0/44', 'pfc_asym': 'off', 'lanes': '17,18,19,20', 'description': 'fortyGigE0/44', 'mtu': '9100'}, " - "'Ethernet40': {'alias': 'fortyGigE0/40', 'pfc_asym': 'off', 'lanes': '21,22,23,24', 'description': 'fortyGigE0/40', 'mtu': '9100'}, " - "'Ethernet28': {'alias': 'fortyGigE0/28', 'pfc_asym': 'off', 'lanes': '1,2,3,4', 'description': 'fortyGigE0/28', 'mtu': '9100'}, " - "'Ethernet60': {'alias': 'fortyGigE0/60', 'pfc_asym': 'off', 'lanes': '57,58,59,60', 'description': 'fortyGigE0/60', 'mtu': '9100'}, " - "'Ethernet20': {'alias': 'fortyGigE0/20', 'pfc_asym': 'off', 'lanes': '45,46,47,48', 'description': 'fortyGigE0/20', 'mtu': '9100'}, " - "'Ethernet24': {'alias': 'fortyGigE0/24', 'pfc_asym': 'off', 'lanes': '5,6,7,8', 'description': 'fortyGigE0/24', 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '40000'}, " + "'Ethernet0': {'lanes': '29,30,31,32', 'description': 'switch-01t1:port1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, " + "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000'}, " + "'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, " + "'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, " + "'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, " + "'Ethernet68': {'alias': 'fortyGigE0/68', 'pfc_asym': 'off', 'lanes': '69,70,71,72', 'description': 'fortyGigE0/68', 'mtu': '9100'}, " + "'Ethernet96': {'alias': 'fortyGigE0/96', 'pfc_asym': 'off', 'lanes': '121,122,123,124', 'description': 'fortyGigE0/96', 'mtu': '9100'}, " + "'Ethernet124': {'alias': 'fortyGigE0/124', 'pfc_asym': 'off', 'lanes': '101,102,103,104', 'description': 'fortyGigE0/124', 'mtu': '9100'}, " + "'Ethernet92': {'alias': 'fortyGigE0/92', 'pfc_asym': 'off', 'lanes': '113,114,115,116', 'description': 'fortyGigE0/92', 'mtu': '9100'}, " + "'Ethernet120': {'alias': 'fortyGigE0/120', 'pfc_asym': 'off', 'lanes': '97,98,99,100', 'description': 'fortyGigE0/120', 'mtu': '9100'}, " + "'Ethernet52': {'alias': 'fortyGigE0/52', 'pfc_asym': 'off', 'lanes': '53,54,55,56', 'description': 'fortyGigE0/52', 'mtu': '9100'}, " + "'Ethernet56': {'alias': 'fortyGigE0/56', 'pfc_asym': 'off', 'lanes': '61,62,63,64', 'description': 'fortyGigE0/56', 'mtu': '9100'}, " + "'Ethernet76': {'alias': 'fortyGigE0/76', 'pfc_asym': 'off', 'lanes': '73,74,75,76', 'description': 'fortyGigE0/76', 'mtu': '9100'}, " + "'Ethernet72': {'alias': 'fortyGigE0/72', 'pfc_asym': 'off', 'lanes': '77,78,79,80', 'description': 'fortyGigE0/72', 'mtu': '9100'}, " + "'Ethernet64': {'alias': 'fortyGigE0/64', 'pfc_asym': 'off', 'lanes': '65,66,67,68', 'description': 'fortyGigE0/64', 'mtu': '9100'}, " + "'Ethernet32': {'alias': 'fortyGigE0/32', 'pfc_asym': 'off', 'lanes': '9,10,11,12', 'description': 'fortyGigE0/32', 'mtu': '9100'}, " + "'Ethernet16': {'alias': 'fortyGigE0/16', 'pfc_asym': 'off', 'lanes': '41,42,43,44', 'description': 'fortyGigE0/16', 'mtu': '9100'}, " + "'Ethernet36': {'alias': 'fortyGigE0/36', 'pfc_asym': 'off', 'lanes': '13,14,15,16', 'description': 'fortyGigE0/36', 'mtu': '9100'}, " + "'Ethernet12': {'lanes': '33,34,35,36', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '10000'}, " + "'Ethernet88': {'alias': 'fortyGigE0/88', 'pfc_asym': 'off', 'lanes': '117,118,119,120', 'description': 'fortyGigE0/88', 'mtu': '9100'}, " + "'Ethernet116': {'alias': 'fortyGigE0/116', 'pfc_asym': 'off', 'lanes': '93,94,95,96', 'description': 'fortyGigE0/116', 'mtu': '9100'}, " + "'Ethernet80': {'alias': 'fortyGigE0/80', 'pfc_asym': 'off', 'lanes': '105,106,107,108', 'description': 'fortyGigE0/80', 'mtu': '9100'}, " + "'Ethernet112': {'alias': 'fortyGigE0/112', 'pfc_asym': 'off', 'lanes': '89,90,91,92', 'description': 'fortyGigE0/112', 'mtu': '9100'}, " + "'Ethernet84': {'alias': 'fortyGigE0/84', 'pfc_asym': 'off', 'lanes': '109,110,111,112', 'description': 'fortyGigE0/84', 'mtu': '9100'}, " + "'Ethernet48': {'alias': 'fortyGigE0/48', 'pfc_asym': 'off', 'lanes': '49,50,51,52', 'description': 'fortyGigE0/48', 'mtu': '9100'}, " + "'Ethernet44': {'alias': 'fortyGigE0/44', 'pfc_asym': 'off', 'lanes': '17,18,19,20', 'description': 'fortyGigE0/44', 'mtu': '9100'}, " + "'Ethernet40': {'alias': 'fortyGigE0/40', 'pfc_asym': 'off', 'lanes': '21,22,23,24', 'description': 'fortyGigE0/40', 'mtu': '9100'}, " + "'Ethernet28': {'alias': 'fortyGigE0/28', 'pfc_asym': 'off', 'lanes': '1,2,3,4', 'description': 'fortyGigE0/28', 'mtu': '9100'}, " + "'Ethernet60': {'alias': 'fortyGigE0/60', 'pfc_asym': 'off', 'lanes': '57,58,59,60', 'description': 'fortyGigE0/60', 'mtu': '9100'}, " + "'Ethernet20': {'alias': 'fortyGigE0/20', 'pfc_asym': 'off', 'lanes': '45,46,47,48', 'description': 'fortyGigE0/20', 'mtu': '9100'}, " + "'Ethernet24': {'alias': 'fortyGigE0/24', 'pfc_asym': 'off', 'lanes': '5,6,7,8', 'description': 'fortyGigE0/24', 'mtu': '9100'}}" + ) + ) def test_minigraph_extra_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT"' output = self.run_script(argument) - self.assertEqual(output.strip(), \ - "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '1000'}, " - "'Ethernet0': {'lanes': '29,30,31,32', 'description': 'fortyGigE0/0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, " - "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000'}, " - "'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, " - "'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, " - "'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, " - "'Ethernet68': {'alias': 'fortyGigE0/68', 'pfc_asym': 'off', 'lanes': '69,70,71,72', 'description': 'fortyGigE0/68', 'mtu': '9100'}, " - "'Ethernet96': {'alias': 'fortyGigE0/96', 'pfc_asym': 'off', 'lanes': '121,122,123,124', 'description': 'fortyGigE0/96', 'mtu': '9100'}, " - "'Ethernet124': {'alias': 'fortyGigE0/124', 'pfc_asym': 'off', 'lanes': '101,102,103,104', 'description': 'fortyGigE0/124', 'mtu': '9100'}, " - "'Ethernet92': {'alias': 'fortyGigE0/92', 'pfc_asym': 'off', 'lanes': '113,114,115,116', 'description': 'fortyGigE0/92', 'mtu': '9100'}, " - "'Ethernet120': {'alias': 'fortyGigE0/120', 'pfc_asym': 'off', 'lanes': '97,98,99,100', 'description': 'fortyGigE0/120', 'mtu': '9100'}, " - "'Ethernet52': {'alias': 'fortyGigE0/52', 'pfc_asym': 'off', 'lanes': '53,54,55,56', 'description': 'fortyGigE0/52', 'mtu': '9100'}, " - "'Ethernet56': {'alias': 'fortyGigE0/56', 'pfc_asym': 'off', 'lanes': '61,62,63,64', 'description': 'fortyGigE0/56', 'mtu': '9100'}, " - "'Ethernet76': {'alias': 'fortyGigE0/76', 'pfc_asym': 'off', 'lanes': '73,74,75,76', 'description': 'fortyGigE0/76', 'mtu': '9100'}, " - "'Ethernet72': {'alias': 'fortyGigE0/72', 'pfc_asym': 'off', 'lanes': '77,78,79,80', 'description': 'fortyGigE0/72', 'mtu': '9100'}, " - "'Ethernet64': {'alias': 'fortyGigE0/64', 'pfc_asym': 'off', 'lanes': '65,66,67,68', 'description': 'fortyGigE0/64', 'mtu': '9100'}, " - "'Ethernet32': {'alias': 'fortyGigE0/32', 'pfc_asym': 'off', 'lanes': '9,10,11,12', 'description': 'fortyGigE0/32', 'mtu': '9100'}, " - "'Ethernet16': {'alias': 'fortyGigE0/16', 'pfc_asym': 'off', 'lanes': '41,42,43,44', 'description': 'fortyGigE0/16', 'mtu': '9100'}, " - "'Ethernet36': {'alias': 'fortyGigE0/36', 'pfc_asym': 'off', 'lanes': '13,14,15,16', 'description': 'fortyGigE0/36', 'mtu': '9100'}, " - "'Ethernet12': {'lanes': '33,34,35,36', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '100000', 'description': 'Interface description'}, " - "'Ethernet88': {'alias': 'fortyGigE0/88', 'pfc_asym': 'off', 'lanes': '117,118,119,120', 'description': 'fortyGigE0/88', 'mtu': '9100'}, " - "'Ethernet116': {'alias': 'fortyGigE0/116', 'pfc_asym': 'off', 'lanes': '93,94,95,96', 'description': 'fortyGigE0/116', 'mtu': '9100'}, " - "'Ethernet80': {'alias': 'fortyGigE0/80', 'pfc_asym': 'off', 'lanes': '105,106,107,108', 'description': 'fortyGigE0/80', 'mtu': '9100'}, " - "'Ethernet112': {'alias': 'fortyGigE0/112', 'pfc_asym': 'off', 'lanes': '89,90,91,92', 'description': 'fortyGigE0/112', 'mtu': '9100'}, " - "'Ethernet84': {'alias': 'fortyGigE0/84', 'pfc_asym': 'off', 'lanes': '109,110,111,112', 'description': 'fortyGigE0/84', 'mtu': '9100'}, " - "'Ethernet48': {'alias': 'fortyGigE0/48', 'pfc_asym': 'off', 'lanes': '49,50,51,52', 'description': 'fortyGigE0/48', 'mtu': '9100'}, " - "'Ethernet44': {'alias': 'fortyGigE0/44', 'pfc_asym': 'off', 'lanes': '17,18,19,20', 'description': 'fortyGigE0/44', 'mtu': '9100'}, " - "'Ethernet40': {'alias': 'fortyGigE0/40', 'pfc_asym': 'off', 'lanes': '21,22,23,24', 'description': 'fortyGigE0/40', 'mtu': '9100'}, " - "'Ethernet28': {'alias': 'fortyGigE0/28', 'pfc_asym': 'off', 'lanes': '1,2,3,4', 'description': 'fortyGigE0/28', 'mtu': '9100'}, " - "'Ethernet60': {'alias': 'fortyGigE0/60', 'pfc_asym': 'off', 'lanes': '57,58,59,60', 'description': 'fortyGigE0/60', 'mtu': '9100'}, " - "'Ethernet20': {'alias': 'fortyGigE0/20', 'pfc_asym': 'off', 'lanes': '45,46,47,48', 'description': 'fortyGigE0/20', 'mtu': '9100'}, " - "'Ethernet24': {'alias': 'fortyGigE0/24', 'pfc_asym': 'off', 'lanes': '5,6,7,8', 'description': 'fortyGigE0/24', 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '1000'}, " + "'Ethernet0': {'lanes': '29,30,31,32', 'description': 'fortyGigE0/0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, " + "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000'}, " + "'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, " + "'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, " + "'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, " + "'Ethernet68': {'alias': 'fortyGigE0/68', 'pfc_asym': 'off', 'lanes': '69,70,71,72', 'description': 'fortyGigE0/68', 'mtu': '9100'}, " + "'Ethernet96': {'alias': 'fortyGigE0/96', 'pfc_asym': 'off', 'lanes': '121,122,123,124', 'description': 'fortyGigE0/96', 'mtu': '9100'}, " + "'Ethernet124': {'alias': 'fortyGigE0/124', 'pfc_asym': 'off', 'lanes': '101,102,103,104', 'description': 'fortyGigE0/124', 'mtu': '9100'}, " + "'Ethernet92': {'alias': 'fortyGigE0/92', 'pfc_asym': 'off', 'lanes': '113,114,115,116', 'description': 'fortyGigE0/92', 'mtu': '9100'}, " + "'Ethernet120': {'alias': 'fortyGigE0/120', 'pfc_asym': 'off', 'lanes': '97,98,99,100', 'description': 'fortyGigE0/120', 'mtu': '9100'}, " + "'Ethernet52': {'alias': 'fortyGigE0/52', 'pfc_asym': 'off', 'lanes': '53,54,55,56', 'description': 'fortyGigE0/52', 'mtu': '9100'}, " + "'Ethernet56': {'alias': 'fortyGigE0/56', 'pfc_asym': 'off', 'lanes': '61,62,63,64', 'description': 'fortyGigE0/56', 'mtu': '9100'}, " + "'Ethernet76': {'alias': 'fortyGigE0/76', 'pfc_asym': 'off', 'lanes': '73,74,75,76', 'description': 'fortyGigE0/76', 'mtu': '9100'}, " + "'Ethernet72': {'alias': 'fortyGigE0/72', 'pfc_asym': 'off', 'lanes': '77,78,79,80', 'description': 'fortyGigE0/72', 'mtu': '9100'}, " + "'Ethernet64': {'alias': 'fortyGigE0/64', 'pfc_asym': 'off', 'lanes': '65,66,67,68', 'description': 'fortyGigE0/64', 'mtu': '9100'}, " + "'Ethernet32': {'alias': 'fortyGigE0/32', 'pfc_asym': 'off', 'lanes': '9,10,11,12', 'description': 'fortyGigE0/32', 'mtu': '9100'}, " + "'Ethernet16': {'alias': 'fortyGigE0/16', 'pfc_asym': 'off', 'lanes': '41,42,43,44', 'description': 'fortyGigE0/16', 'mtu': '9100'}, " + "'Ethernet36': {'alias': 'fortyGigE0/36', 'pfc_asym': 'off', 'lanes': '13,14,15,16', 'description': 'fortyGigE0/36', 'mtu': '9100'}, " + "'Ethernet12': {'lanes': '33,34,35,36', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/12', 'admin_status': 'up', 'speed': '100000', 'description': 'Interface description'}, " + "'Ethernet88': {'alias': 'fortyGigE0/88', 'pfc_asym': 'off', 'lanes': '117,118,119,120', 'description': 'fortyGigE0/88', 'mtu': '9100'}, " + "'Ethernet116': {'alias': 'fortyGigE0/116', 'pfc_asym': 'off', 'lanes': '93,94,95,96', 'description': 'fortyGigE0/116', 'mtu': '9100'}, " + "'Ethernet80': {'alias': 'fortyGigE0/80', 'pfc_asym': 'off', 'lanes': '105,106,107,108', 'description': 'fortyGigE0/80', 'mtu': '9100'}, " + "'Ethernet112': {'alias': 'fortyGigE0/112', 'pfc_asym': 'off', 'lanes': '89,90,91,92', 'description': 'fortyGigE0/112', 'mtu': '9100'}, " + "'Ethernet84': {'alias': 'fortyGigE0/84', 'pfc_asym': 'off', 'lanes': '109,110,111,112', 'description': 'fortyGigE0/84', 'mtu': '9100'}, " + "'Ethernet48': {'alias': 'fortyGigE0/48', 'pfc_asym': 'off', 'lanes': '49,50,51,52', 'description': 'fortyGigE0/48', 'mtu': '9100'}, " + "'Ethernet44': {'alias': 'fortyGigE0/44', 'pfc_asym': 'off', 'lanes': '17,18,19,20', 'description': 'fortyGigE0/44', 'mtu': '9100'}, " + "'Ethernet40': {'alias': 'fortyGigE0/40', 'pfc_asym': 'off', 'lanes': '21,22,23,24', 'description': 'fortyGigE0/40', 'mtu': '9100'}, " + "'Ethernet28': {'alias': 'fortyGigE0/28', 'pfc_asym': 'off', 'lanes': '1,2,3,4', 'description': 'fortyGigE0/28', 'mtu': '9100'}, " + "'Ethernet60': {'alias': 'fortyGigE0/60', 'pfc_asym': 'off', 'lanes': '57,58,59,60', 'description': 'fortyGigE0/60', 'mtu': '9100'}, " + "'Ethernet20': {'alias': 'fortyGigE0/20', 'pfc_asym': 'off', 'lanes': '45,46,47,48', 'description': 'fortyGigE0/20', 'mtu': '9100'}, " + "'Ethernet24': {'alias': 'fortyGigE0/24', 'pfc_asym': 'off', 'lanes': '5,6,7,8', 'description': 'fortyGigE0/24', 'mtu': '9100'}}" + ) + ) # everflow portion is not used # def test_metadata_everflow(self): @@ -356,12 +424,15 @@ def test_minigraph_extra_ethernet_interfaces(self): def test_metadata_tacacs(self): argument = '-m "' + self.sample_graph_metadata + '" -p "' + self.port_config + '" -v "TACPLUS_SERVER"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'10.0.10.7': {'priority': '1', 'tcp_port': '49'}, '10.0.10.8': {'priority': '1', 'tcp_port': '49'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'10.0.10.7': {'priority': '1', 'tcp_port': '49'}, '10.0.10.8': {'priority': '1', 'tcp_port': '49'}}") + ) def test_metadata_ntp(self): argument = '-m "' + self.sample_graph_metadata + '" -p "' + self.port_config + '" -v "NTP_SERVER"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'10.0.10.1': {}, '10.0.10.2': {}}") + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict("{'10.0.10.1': {}, '10.0.10.2': {}}")) def test_minigraph_vnet(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VNET"' @@ -376,7 +447,10 @@ def test_minigraph_vxlan(self): def test_minigraph_bgp_mon(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "BGP_MONITORS"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'10.20.30.40': {'rrclient': 0, 'name': 'BGPMonitor', 'local_addr': '10.1.0.32', 'nhopself': 0, 'holdtime': '10', 'asn': '0', 'keepalive': '3'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'10.20.30.40': {'rrclient': 0, 'name': 'BGPMonitor', 'local_addr': '10.1.0.32', 'nhopself': 0, 'holdtime': '10', 'asn': '0', 'keepalive': '3'}}") + ) def test_minigraph_sub_port_interfaces(self, check_stderr=True): try: @@ -414,13 +488,17 @@ def test_minigraph_sub_port_interfaces(self, check_stderr=True): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN_SUB_INTERFACE' output = self.run_script(argument) print(output.strip()) - self.assertEqual(output.strip(), \ + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( "{('PortChannel01.10', '10.0.0.56/31'): {}, " "'Ethernet0.10': {'admin_status': 'up'}, " "('Ethernet0.10', '10.0.0.58/31'): {}, " "('PortChannel01.10', 'FC00::71/126'): {}, " "'PortChannel01.10': {'admin_status': 'up'}, " - "('Ethernet0.10', 'FC00::75/126'): {}}") + "('Ethernet0.10', 'FC00::75/126'): {}}" + ) + ) finally: print('\n Change device type back to %s' % (TOR_ROUTER)) diff --git a/src/sonic-config-engine/tests/test_cfggen_platformJson.py b/src/sonic-config-engine/tests/test_cfggen_platformJson.py index dedddadde1cd..751da15caeb6 100644 --- a/src/sonic-config-engine/tests/test_cfggen_platformJson.py +++ b/src/sonic-config-engine/tests/test_cfggen_platformJson.py @@ -1,8 +1,12 @@ -from unittest import TestCase -import subprocess -import os -import json import ast +import json +import os +import subprocess + +import tests.common_utils as utils + +from unittest import TestCase + # Global Variable PLATFORM_OUTPUT_FILE = "platform_output.json" @@ -54,12 +58,12 @@ def test_platform_json_specific_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT[\'Ethernet8\']"' output = self.run_script(argument) expected = "{'index': '3', 'lanes': '8', 'description': 'Eth3/1', 'admin_status': 'up', 'mtu': '9100', 'alias': 'Eth3/1', 'pfc_asym': 'off', 'speed': '25000'}" - self.assertEqual(output.strip(), expected) + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict(expected)) argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT[\'Ethernet112\']"' output = self.run_script(argument) expected = "{'index': '29', 'lanes': '112', 'description': 'Eth29/1', 'admin_status': 'up', 'mtu': '9100', 'alias': 'Eth29/1', 'pfc_asym': 'off', 'speed': '25000'}" - self.assertEqual(output.strip(), expected) + self.assertEqual(utils.to_dict(output.strip()), utils.to_dict(expected)) # Check all Interface with it's proper configuration as per platform.json def test_platform_json_all_ethernet_interfaces(self): diff --git a/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py b/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py index c13575d25690..d0a4f2c0de59 100644 --- a/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py +++ b/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py @@ -1,6 +1,10 @@ -from unittest import TestCase -import subprocess import os +import subprocess + +import tests.common_utils as utils + +from unittest import TestCase + class TestCfgGenT2ChassisFe(TestCase): @@ -34,24 +38,31 @@ def test_minigraph_t2_chassis_fe_type(self): def test_minigraph_t2_chassis_fe_interfaces(self): argument = '-m "' + self.sample_graph_t2_chassis_fe + '" -p "' + self.t2_chassis_fe_port_config + '" -v "INTERFACE"' output = self.run_script(argument) - self.assertEqual(output.strip(), - "{'Ethernet8': {}, " - "('Ethernet8', '172.16.0.9/30'): {}, " - "'Ethernet0': {'vnet_name': 'VnetFE'}, " - "('Ethernet4', '172.16.0.1/30'): {}, " - "('Ethernet0', '192.168.0.2/30'): {}, " - "'Ethernet4': {}}") - + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'Ethernet8': {}, " + "('Ethernet8', '172.16.0.9/30'): {}, " + "'Ethernet0': {'vnet_name': 'VnetFE'}, " + "('Ethernet4', '172.16.0.1/30'): {}, " + "('Ethernet0', '192.168.0.2/30'): {}, " + "'Ethernet4': {}}" + ) + ) def test_minigraph_t2_chassis_fe_pc_interfaces(self): argument = '-m "' + self.sample_graph_t2_chassis_fe_pc + '" -p "' + self.t2_chassis_fe_port_config + '" -v "PORTCHANNEL_INTERFACE"' output = self.run_script(argument) - self.assertEqual(output.strip(), - "{'PortChannel8': {}, " - "('PortChannel0', '192.168.0.2/30'): {}, " - "('PortChannel4', '172.16.0.1/30'): {}, " - "'PortChannel4': {}, " - "('PortChannel8', '172.16.0.9/30'): {}, " - "'PortChannel0': {'vnet_name': 'VnetFE'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict( + "{'PortChannel8': {}, " + "('PortChannel0', '192.168.0.2/30'): {}, " + "('PortChannel4', '172.16.0.1/30'): {}, " + "'PortChannel4': {}, " + "('PortChannel8', '172.16.0.9/30'): {}, " + "'PortChannel0': {'vnet_name': 'VnetFE'}}" + ) + ) # Test a minigraph file where VNI is not specified # Default VNI is 8000 diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index b1b6024df8b5..3f5fd46bf55e 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -1,6 +1,10 @@ -from unittest import TestCase -import subprocess import os +import subprocess + +import tests.common_utils as utils + +from unittest import TestCase + class TestCfgGenCaseInsensitive(TestCase): @@ -73,7 +77,10 @@ def test_minigraph_interfaces(self): def test_minigraph_vlans(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v VLAN' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}}") + ) def test_minigraph_vlan_members(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v VLAN_MEMBER' @@ -88,12 +95,17 @@ def test_minigraph_vlan_interfaces(self): def test_minigraph_portchannels(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v PORTCHANNEL' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'PortChannel01': {'admin_status': 'up', 'min_links': '1', 'members': ['Ethernet4'], 'mtu': '9100'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'PortChannel01': {'admin_status': 'up', 'min_links': '1', 'members': ['Ethernet4'], 'mtu': '9100'}}") + ) def test_minigraph_console_port(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v CONSOLE_PORT' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'1': {'baud_rate': '9600', 'remote_device': 'managed_device', 'flow_control': 1}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'1': {'baud_rate': '9600', 'remote_device': 'managed_device', 'flow_control': 1}}")) def test_minigraph_deployment_id(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'deployment_id\']"' @@ -103,7 +115,10 @@ def test_minigraph_deployment_id(self): def test_minigraph_neighbor_metadata(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_NEIGHBOR_METADATA"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'switch-01t1': {'lo_addr': '10.1.0.186/32', 'mgmt_addr': '10.7.0.196/26', 'hwsku': 'Force10-S6000', 'type': 'LeafRouter', 'deployment_id': '2'}}") + self.assertEqual( + utils.to_dict(output.strip()), + utils.to_dict("{'switch-01t1': {'lo_addr': '10.1.0.186/32', 'mgmt_addr': '10.7.0.196/26', 'hwsku': 'Force10-S6000', 'type': 'LeafRouter', 'deployment_id': '2'}}") + ) # everflow portion is not used # def test_metadata_everflow(self): diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 77e79a2b5fe1..bb2f93a0880e 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -1,10 +1,14 @@ -import unittest -from unittest import TestCase -import subprocess -import os import json -import yaml +import os import shutil +import subprocess +import unittest +import yaml + +import tests.common_utils as utils + +from unittest import TestCase + SKU = 'multi-npu-01' ASIC_SKU = 'multi-npu-asic' @@ -136,27 +140,35 @@ def test_backend_asic_portchannels(self): 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(list(output.keys()), \ - ['PortChannel4002|Ethernet-BP8', 'PortChannel0002|Ethernet0', 'PortChannel0002|Ethernet4', 'PortChannel4002|Ethernet-BP12', 'PortChannel4001|Ethernet-BP0', 'PortChannel4001|Ethernet-BP4']) + output = self.run_script(argument) + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['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(list(output.keys()), \ - ['PortChannel4013|Ethernet-BP384', 'PortChannel4014|Ethernet-BP392', 'PortChannel4014|Ethernet-BP396', 'PortChannel4013|Ethernet-BP388']) + output = self.run_script(argument) + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['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(list(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']) + output = self.run_script(argument) + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['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(list(output.keys()), \ - ['PortChannel4013', 'PortChannel4013|10.1.0.2/31', 'PortChannel4014', 'PortChannel4014|10.1.0.6/31']) + output = self.run_script(argument) + self.assertEqual( + utils.liststr_to_dict(output.strip()), + utils.liststr_to_dict("['PortChannel4013', 'PortChannel4013|10.1.0.2/31', 'PortChannel4014', 'PortChannel4014|10.1.0.6/31']") + ) def test_frontend_asic_ports(self): argument = "-m {} -p {} -n asic0 --var-json \"PORT\"".format(self.sample_graph, self.port_config[0]) From 6754635010396d91622947958a2a96725db10ea6 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Mon, 28 Sep 2020 20:21:46 -0700 Subject: [PATCH 42/78] [cfggen] Make Jinja2 Template Python 3 Compatible Jinja2 templates rendered using Python 3 interpreter, are required to conform with Python 3 new semantics. singed-off-by: Tamer Ahmed --- .../bgpd.spine_chassis_frontend_router.conf.j2 | 14 +++++++------- .../docker-fpm-frr/frr/common/functions.conf.j2 | 4 ++-- .../frr/zebra/zebra.interfaces.conf.j2 | 2 +- dockers/docker-fpm-quagga/bgpd.conf.j2 | 8 ++++---- dockers/docker-lldp/lldpd.conf.j2 | 4 ++-- dockers/docker-orchagent/ports.json.j2 | 2 +- src/sonic-config-engine/data/l2switch.j2 | 2 +- src/sonic-config-engine/tests/test_cfggen.py | 12 ++++++------ .../tests/test_cfggen_platformJson.py | 2 +- .../tests/test_minigraph_case.py | 4 ++-- .../tests/test_multinpu_cfggen.py | 8 ++++---- 11 files changed, 31 insertions(+), 31 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 index afb621b0bf61..94dacbc3af78 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 @@ -3,7 +3,7 @@ ! Vnet BGP instance {% set interfaces_in_vnets = [] %} {% block vnet_bgp_instance %} -{% for vnet_name, vnet_metadata in VNET.iteritems() %} +{% for vnet_name, vnet_metadata in VNET.items() %} router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} no bgp default ipv4-unicast bgp log-neighbor-changes @@ -19,9 +19,9 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} {% endfor %} {# Got interfaces that belong this vnet #} {% set interfaces_in_vnet = [] %} -{% for (key, metadata) in INTERFACE.iteritems() %} -{% if metadata.has_key("vnet_name") and metadata["vnet_name"] == vnet_name %} -{% for (name_prefix_pair, metadata) in INTERFACE.iteritems() %} +{% for (key, metadata) in INTERFACE.items() %} +{% if "vnet_name" in metadata and metadata["vnet_name"] == vnet_name %} +{% for (name_prefix_pair, metadata) in INTERFACE.items() %} {% if key == name_prefix_pair[0] %} {% if interfaces_in_vnet.append( name_prefix_pair[1] | ip ) %} {% endif %} @@ -32,8 +32,8 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} {% endif %} {% endfor %} {# Each bgp neighbors #} -{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} -{% if bgp_session.has_key("local_addr") and bgp_session["local_addr"] in interfaces_in_vnet %} +{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.items() %} +{% if "local_addr" in bgp_session and bgp_session["local_addr"] in interfaces_in_vnet %} {% if bgp_session['asn'] | int != 0 %} neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} @@ -42,7 +42,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} 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 'admin_status' in bgp_session and bgp_session['admin_status'] == 'down' or 'admin_status' not in bgp_session and 'default_bgp_status' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} neighbor {{ neighbor_addr }} shutdown {% endif %} {% if neighbor_addr | ipv4 %} diff --git a/dockers/docker-fpm-frr/frr/common/functions.conf.j2 b/dockers/docker-fpm-frr/frr/common/functions.conf.j2 index 2049e1141429..34700db329ca 100644 --- a/dockers/docker-fpm-frr/frr/common/functions.conf.j2 +++ b/dockers/docker-fpm-frr/frr/common/functions.conf.j2 @@ -25,8 +25,8 @@ {% macro get_vnet_interfaces(interfaces) -%} {% set L = namespace(intfs=[]) %} {% set vnet_intfs = [] %} -{% for (key, metadata) in interfaces.iteritems() %} -{% if metadata.has_key("vnet_name") %} +{% for (key, metadata) in interfaces.items() %} +{% if "vnet_name" in metadata %} {% set vnet_intfs = vnet_intfs.append(key) %} {% endif %} {% endfor %} diff --git a/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 index 484efeba5850..7526239db8a6 100644 --- a/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 @@ -1,7 +1,7 @@ ! {% block vrf %} {% if VNET is defined %} -{% for vnet_name, vnet_metadata in VNET.iteritems() %} +{% for vnet_name, vnet_metadata in VNET.items() %} vrf {{ vnet_name }} vni {{ vnet_metadata['vni'] }} ! diff --git a/dockers/docker-fpm-quagga/bgpd.conf.j2 b/dockers/docker-fpm-quagga/bgpd.conf.j2 index 2f4c741303a4..8c838f8ffc9d 100644 --- a/dockers/docker-fpm-quagga/bgpd.conf.j2 +++ b/dockers/docker-fpm-quagga/bgpd.conf.j2 @@ -14,7 +14,7 @@ log facility local4 ! enable password {# {{ en_passwd }} TODO: param needed #} {% endblock system_init %} ! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} +{% if 'bgp_asn' in DEVICE_METADATA['localhost'] %} {% block bgp_init %} ! ! bgp multiple-instance @@ -58,7 +58,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endfor %} {% endblock vlan_advertisement %} {% block bgp_sessions %} -{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} +{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.items() %} {% if bgp_session['asn'] | int != 0 %} neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} @@ -67,7 +67,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} 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 'admin_status' in bgp_session and bgp_session['admin_status'] == 'down' or 'admin_status' not in bgp_session and 'default_bgp_status' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} neighbor {{ neighbor_addr }} shutdown {% endif %} {% if neighbor_addr | ipv4 %} @@ -131,7 +131,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} {% endblock bgp_peers_with_range %} ! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} +{% if 'bgp_asn' in DEVICE_METADATA['localhost'] %} maximum-paths 64 ! route-map ISOLATE permit 10 diff --git a/dockers/docker-lldp/lldpd.conf.j2 b/dockers/docker-lldp/lldpd.conf.j2 index d5b6dba8700c..421400037bbf 100644 --- a/dockers/docker-lldp/lldpd.conf.j2 +++ b/dockers/docker-lldp/lldpd.conf.j2 @@ -1,7 +1,7 @@ {% if MGMT_INTERFACE %} {# If MGMT port alias is available, use it for port ID subtype, otherwise use port name #} -{% set mgmt_port_name = MGMT_INTERFACE.keys()[0][0] %} -{% set ipv4 = MGMT_INTERFACE.keys()[0][1].split('/')[0] %} +{% set mgmt_port_name = (MGMT_INTERFACE.keys()|list)[0][0] %} +{% set ipv4 = (MGMT_INTERFACE.keys()|list)[0][1].split('/')[0] %} {% if MGMT_PORT and MGMT_PORT[mgmt_port_name] and MGMT_PORT[mgmt_port_name].alias %} configure ports eth0 lldp portidsubtype local {{ MGMT_PORT[mgmt_port_name].alias }} {% else %} diff --git a/dockers/docker-orchagent/ports.json.j2 b/dockers/docker-orchagent/ports.json.j2 index b10d4d58a43d..296d97cde07b 100644 --- a/dockers/docker-orchagent/ports.json.j2 +++ b/dockers/docker-orchagent/ports.json.j2 @@ -2,7 +2,7 @@ {% set ports_with_speed_set=[] %} {% if PORT %} {% for port in PORT %} -{% if PORT[port].has_key('speed') %} +{% if 'speed' in PORT[port] %} {%- if ports_with_speed_set.append(port) -%}{%- endif -%} {%- endif -%} {% endfor %} diff --git a/src/sonic-config-engine/data/l2switch.j2 b/src/sonic-config-engine/data/l2switch.j2 index c9f166b6798b..86dca30cb739 100644 --- a/src/sonic-config-engine/data/l2switch.j2 +++ b/src/sonic-config-engine/data/l2switch.j2 @@ -2,7 +2,7 @@ "DEVICE_METADATA": {{ DEVICE_METADATA | tojson }}, {% set ns = {'firstPrinted': False} -%} "PORT": { - {%- for key,value in PORT.iteritems() -%} + {%- for key,value in PORT.items() -%} {%- if ns.firstPrinted %},{% endif %} "{{ key }}": { diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 1fb231a96864..d42438e61c25 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -58,7 +58,7 @@ def test_device_desc(self): self.assertEqual(output.strip(), 'ACS-MSN2700') def test_device_desc_mgmt_ip(self): - argument = '-v "MGMT_INTERFACE.keys()[0]" -M "' + self.sample_device_desc + '"' + argument = '-v "(MGMT_INTERFACE.keys()|list)[0]" -M "' + self.sample_device_desc + '"' output = self.run_script(argument) self.assertEqual(output.strip(), "('eth0', '10.0.1.5/28')") @@ -185,7 +185,7 @@ def test_minigraph_mgmt_ports(self): ) def test_minigraph_interfaces(self): - argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "INTERFACE.keys()"' + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "INTERFACE.keys()|list"' output = self.run_script(argument) self.assertEqual(output.strip(), "[('Ethernet0', '10.0.0.58/31'), 'Ethernet0', ('Ethernet0', 'FC00::75/126')]") @@ -210,7 +210,7 @@ def test_minigraph_vlan_members(self): ) def test_minigraph_vlan_interfaces(self): - argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()"' + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()|list"' output = self.run_script(argument) self.assertEqual(output.strip(), "[('Vlan1000', '192.168.0.1/27'), 'Vlan1000']") @@ -231,7 +231,7 @@ def test_minigraph_portchannel_with_more_member(self): ) def test_minigraph_portchannel_members(self): - argument = '-m "' + self.sample_graph_pc_test + '" -p "' + self.port_config + '" -v "PORTCHANNEL_MEMBER.keys()"' + argument = '-m "' + self.sample_graph_pc_test + '" -p "' + self.port_config + '" -v "PORTCHANNEL_MEMBER.keys()|list"' output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), @@ -239,7 +239,7 @@ def test_minigraph_portchannel_members(self): ) def test_minigraph_portchannel_interfaces(self): - argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORTCHANNEL_INTERFACE.keys()"' + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORTCHANNEL_INTERFACE.keys()|list"' output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), @@ -305,7 +305,7 @@ def test_minigraph_bgp(self): ) def test_minigraph_peers_with_range(self): - argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v BGP_PEER_RANGE.values\(\)' + argument = "-m " + self.sample_graph_bgp_speaker + " -p " + self.port_config + " -v \"BGP_PEER_RANGE.values()|list\"" output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), diff --git a/src/sonic-config-engine/tests/test_cfggen_platformJson.py b/src/sonic-config-engine/tests/test_cfggen_platformJson.py index 751da15caeb6..34fde9a8e5ca 100644 --- a/src/sonic-config-engine/tests/test_cfggen_platformJson.py +++ b/src/sonic-config-engine/tests/test_cfggen_platformJson.py @@ -46,7 +46,7 @@ def test_print_data(self): # Check whether all interfaces present or not as per platform.json def test_platform_json_interfaces_keys(self): - argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT.keys()"' + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -S "' + self.hwsku_json + '" -v "PORT.keys()|list"' output = self.run_script(argument) expected = "['Ethernet8', 'Ethernet9', 'Ethernet36', 'Ethernet98', 'Ethernet0', 'Ethernet6', 'Ethernet4', 'Ethernet109', 'Ethernet108', 'Ethernet18', 'Ethernet100', 'Ethernet34', 'Ethernet104', 'Ethernet106', 'Ethernet94', 'Ethernet126', 'Ethernet96', 'Ethernet124', 'Ethernet90', 'Ethernet91', 'Ethernet92', 'Ethernet93', 'Ethernet50', 'Ethernet51', 'Ethernet52', 'Ethernet53', 'Ethernet54', 'Ethernet99', 'Ethernet56', 'Ethernet113', 'Ethernet76', 'Ethernet74', 'Ethernet39', 'Ethernet72', 'Ethernet73', 'Ethernet70', 'Ethernet71', 'Ethernet32', 'Ethernet33', 'Ethernet16', 'Ethernet111', 'Ethernet10', 'Ethernet11', 'Ethernet12', 'Ethernet13', 'Ethernet58', 'Ethernet19', 'Ethernet59', 'Ethernet38', 'Ethernet78', 'Ethernet68', 'Ethernet14', 'Ethernet89', 'Ethernet88', 'Ethernet118', 'Ethernet119', 'Ethernet116', 'Ethernet114', 'Ethernet80', 'Ethernet112', 'Ethernet86', 'Ethernet110', 'Ethernet84', 'Ethernet31', 'Ethernet49', 'Ethernet48', 'Ethernet46', 'Ethernet30', 'Ethernet29', 'Ethernet40', 'Ethernet120', 'Ethernet28', 'Ethernet66', 'Ethernet60', 'Ethernet64', 'Ethernet44', 'Ethernet20', 'Ethernet79', 'Ethernet69', 'Ethernet24', 'Ethernet26']" diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 3f5fd46bf55e..505d5cfcbf7f 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -70,7 +70,7 @@ def test_render_template(self): # self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '10.0.100.1'}}") def test_minigraph_interfaces(self): - argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v \'INTERFACE.keys()\'' + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v \'INTERFACE.keys()|list\'' output = self.run_script(argument) self.assertEqual(output.strip(), "[('Ethernet0', '10.0.0.58/31'), 'Ethernet0', ('Ethernet0', 'FC00::75/126')]") @@ -88,7 +88,7 @@ def test_minigraph_vlan_members(self): self.assertEqual(output.strip(), "{('Vlan1000', 'Ethernet8'): {'tagging_mode': 'untagged'}}") def test_minigraph_vlan_interfaces(self): - argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()"' + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()|list"' output = self.run_script(argument) self.assertEqual(output.strip(), "[('Vlan1000', '192.168.0.1/27'), 'Vlan1000']") diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index bb2f93a0880e..2aa212e30aae 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -139,7 +139,7 @@ def test_backend_asic_portchannels(self): '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]) + argument = "-m {} -p {} -n asic0 -v \"PORTCHANNEL_MEMBER.keys()|list\"".format(self.sample_graph, self.port_config[0]) output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), @@ -147,7 +147,7 @@ def test_frontend_asic_portchannel_mem(self): ) def test_backend_asic_portchannels_mem(self): - argument = "-m {} -p {} -n asic3 --var-json \"PORTCHANNEL_MEMBER\"".format(self.sample_graph, self.port_config[3]) + argument = "-m {} -p {} -n asic3 -v \"PORTCHANNEL_MEMBER.keys()|list\"".format(self.sample_graph, self.port_config[3]) output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), @@ -155,7 +155,7 @@ def test_backend_asic_portchannels_mem(self): ) def test_frontend_asic_portchannel_intf(self): - argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL_INTERFACE\"".format(self.sample_graph, self.port_config[0]) + argument = "-m {} -p {} -n asic0 -v \"PORTCHANNEL_INTERFACE.keys()|list\"".format(self.sample_graph, self.port_config[0]) output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), @@ -163,7 +163,7 @@ def test_frontend_asic_portchannel_intf(self): ) def test_backend_asic_portchannel_intf(self): - argument = "-m {} -p {} -n asic3 --var-json \"PORTCHANNEL_INTERFACE\"".format(self.sample_graph, self.port_config[3]) + argument = "-m {} -p {} -n asic3 -v \"PORTCHANNEL_INTERFACE.keys()|list\"".format(self.sample_graph, self.port_config[3]) output = self.run_script(argument) self.assertEqual( utils.liststr_to_dict(output.strip()), From 99ffce6b57209de4ec66e7eabf004571c9c708c7 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Mon, 28 Sep 2020 22:23:48 -0700 Subject: [PATCH 43/78] [cfggen] Move Python 2 Test Data to Py2 Folder Rendering templates show different orders when rendered using Python 2 vs Python 3. This PR prepare for Python 3 packaging by creating new dir 'py2' for Python 2 rendered test cases. singed-off-by: Tamer Ahmed --- src/sonic-config-engine/tests/common_utils.py | 2 ++ .../multi_npu_data/{ => py2}/ipinip.json | 0 .../sample_output/{ => py2}/bgpd_frr.conf | 0 .../sample_output/{ => py2}/bgpd_quagga.conf | 0 .../{ => py2}/buffers-dell6100.json | 0 .../docker-dhcp-relay.supervisord.conf | 0 .../tests/sample_output/{ => py2}/frr.conf | 0 .../tests/sample_output/{ => py2}/interfaces | 0 .../tests/sample_output/{ => py2}/ipinip.json | 0 .../sample_output/{ => py2}/l2switch.json | 0 .../tests/sample_output/{ => py2}/lldpd.conf | 0 .../sample_output/{ => py2}/mvrf_interfaces | 0 .../tests/sample_output/{ => py2}/ports.json | 0 .../{ => py2}/qos-arista7050.json | 0 .../sample_output/{ => py2}/qos-dell6100.json | 0 .../sample_output/{ => py2}/staticd_frr.conf | 0 .../{ => py2}/t2-chassis-fe-bgpd.conf | 0 .../{ => py2}/t2-chassis-fe-vni-zebra.conf | 0 .../{ => py2}/t2-chassis-fe-zebra.conf | 0 .../sample_output/{ => py2}/wait_for_intf.sh | 0 .../sample_output/{ => py2}/zebra_frr.conf | 0 .../sample_output/{ => py2}/zebra_quagga.conf | 0 src/sonic-config-engine/tests/test_frr.py | 11 +++--- src/sonic-config-engine/tests/test_j2files.py | 34 ++++++++++--------- .../tests/test_j2files_t2_chassis_fe.py | 8 +++-- 25 files changed, 32 insertions(+), 23 deletions(-) rename src/sonic-config-engine/tests/multi_npu_data/{ => py2}/ipinip.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/bgpd_frr.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/bgpd_quagga.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/buffers-dell6100.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/docker-dhcp-relay.supervisord.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/frr.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/interfaces (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/ipinip.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/l2switch.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/lldpd.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/mvrf_interfaces (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/ports.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/qos-arista7050.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/qos-dell6100.json (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/staticd_frr.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/t2-chassis-fe-bgpd.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/t2-chassis-fe-vni-zebra.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/t2-chassis-fe-zebra.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/wait_for_intf.sh (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/zebra_frr.conf (100%) rename src/sonic-config-engine/tests/sample_output/{ => py2}/zebra_quagga.conf (100%) diff --git a/src/sonic-config-engine/tests/common_utils.py b/src/sonic-config-engine/tests/common_utils.py index f75584471eb4..142bf2f4dde1 100644 --- a/src/sonic-config-engine/tests/common_utils.py +++ b/src/sonic-config-engine/tests/common_utils.py @@ -2,6 +2,8 @@ import re import sys +PY3x = sys.version_info >= (3, 0) +PYvX_DIR = "py3" if PY3x else "py2" def tuple_to_str(tuplestr): """ Convert Python tuple '('elem1', 'elem2')' representation into string on the for "elem1|elem2" """ diff --git a/src/sonic-config-engine/tests/multi_npu_data/ipinip.json b/src/sonic-config-engine/tests/multi_npu_data/py2/ipinip.json similarity index 100% rename from src/sonic-config-engine/tests/multi_npu_data/ipinip.json rename to src/sonic-config-engine/tests/multi_npu_data/py2/ipinip.json diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/bgpd_frr.conf rename to src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf b/src/sonic-config-engine/tests/sample_output/py2/bgpd_quagga.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/bgpd_quagga.conf rename to src/sonic-config-engine/tests/sample_output/py2/bgpd_quagga.conf diff --git a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/py2/buffers-dell6100.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/buffers-dell6100.json rename to src/sonic-config-engine/tests/sample_output/py2/buffers-dell6100.json diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf rename to src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf diff --git a/src/sonic-config-engine/tests/sample_output/frr.conf b/src/sonic-config-engine/tests/sample_output/py2/frr.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/frr.conf rename to src/sonic-config-engine/tests/sample_output/py2/frr.conf diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/py2/interfaces similarity index 100% rename from src/sonic-config-engine/tests/sample_output/interfaces rename to src/sonic-config-engine/tests/sample_output/py2/interfaces diff --git a/src/sonic-config-engine/tests/sample_output/ipinip.json b/src/sonic-config-engine/tests/sample_output/py2/ipinip.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/ipinip.json rename to src/sonic-config-engine/tests/sample_output/py2/ipinip.json diff --git a/src/sonic-config-engine/tests/sample_output/l2switch.json b/src/sonic-config-engine/tests/sample_output/py2/l2switch.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/l2switch.json rename to src/sonic-config-engine/tests/sample_output/py2/l2switch.json diff --git a/src/sonic-config-engine/tests/sample_output/lldpd.conf b/src/sonic-config-engine/tests/sample_output/py2/lldpd.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/lldpd.conf rename to src/sonic-config-engine/tests/sample_output/py2/lldpd.conf diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces similarity index 100% rename from src/sonic-config-engine/tests/sample_output/mvrf_interfaces rename to src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces diff --git a/src/sonic-config-engine/tests/sample_output/ports.json b/src/sonic-config-engine/tests/sample_output/py2/ports.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/ports.json rename to src/sonic-config-engine/tests/sample_output/py2/ports.json diff --git a/src/sonic-config-engine/tests/sample_output/qos-arista7050.json b/src/sonic-config-engine/tests/sample_output/py2/qos-arista7050.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/qos-arista7050.json rename to src/sonic-config-engine/tests/sample_output/py2/qos-arista7050.json diff --git a/src/sonic-config-engine/tests/sample_output/qos-dell6100.json b/src/sonic-config-engine/tests/sample_output/py2/qos-dell6100.json similarity index 100% rename from src/sonic-config-engine/tests/sample_output/qos-dell6100.json rename to src/sonic-config-engine/tests/sample_output/py2/qos-dell6100.json diff --git a/src/sonic-config-engine/tests/sample_output/staticd_frr.conf b/src/sonic-config-engine/tests/sample_output/py2/staticd_frr.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/staticd_frr.conf rename to src/sonic-config-engine/tests/sample_output/py2/staticd_frr.conf diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-bgpd.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf rename to src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-bgpd.conf diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-vni-zebra.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf rename to src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-vni-zebra.conf diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-zebra.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/t2-chassis-fe-zebra.conf rename to src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-zebra.conf diff --git a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/py2/wait_for_intf.sh similarity index 100% rename from src/sonic-config-engine/tests/sample_output/wait_for_intf.sh rename to src/sonic-config-engine/tests/sample_output/py2/wait_for_intf.sh diff --git a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf b/src/sonic-config-engine/tests/sample_output/py2/zebra_frr.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/zebra_frr.conf rename to src/sonic-config-engine/tests/sample_output/py2/zebra_frr.conf diff --git a/src/sonic-config-engine/tests/sample_output/zebra_quagga.conf b/src/sonic-config-engine/tests/sample_output/py2/zebra_quagga.conf similarity index 100% rename from src/sonic-config-engine/tests/sample_output/zebra_quagga.conf rename to src/sonic-config-engine/tests/sample_output/py2/zebra_quagga.conf diff --git a/src/sonic-config-engine/tests/test_frr.py b/src/sonic-config-engine/tests/test_frr.py index e43fcb95789b..ef7c4b06f7db 100644 --- a/src/sonic-config-engine/tests/test_frr.py +++ b/src/sonic-config-engine/tests/test_frr.py @@ -1,8 +1,11 @@ -from unittest import TestCase -import subprocess -import os import filecmp +import os +import subprocess +import sys + +import tests.common_utils as utils +from unittest import TestCase class TestCfgGen(TestCase): def setUp(self): @@ -44,7 +47,7 @@ def run_case(self, template, target): 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) + original_filename = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, target) r = filecmp.cmp(original_filename, self.output_file) diff_output = self.run_diff(original_filename, self.output_file) if not r else "" diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index db5c1cf3a91a..8ce55f2c4427 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -1,10 +1,12 @@ import filecmp -import os -import subprocess import json +import os import shutil +import subprocess from unittest import TestCase +import tests.common_utils as utils + class TestJ2Files(TestCase): def setUp(self): @@ -34,42 +36,42 @@ def test_interfaces(self): interfaces_template = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'interfaces', 'interfaces.j2') argument = '-m ' + self.t0_minigraph + ' -a \'{\"hwaddr\":\"e4:1d:2d:a5:f3:ad\"}\' -t ' + interfaces_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'interfaces'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'interfaces'), self.output_file)) argument = '-m ' + self.t0_mvrf_minigraph + ' -a \'{\"hwaddr\":\"e4:1d:2d:a5:f3:ad\"}\' -t ' + interfaces_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'mvrf_interfaces'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'mvrf_interfaces'), self.output_file)) def test_ports_json(self): ports_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ports.json.j2') argument = '-m ' + self.simple_minigraph + ' -p ' + self.t0_port_config + ' -t ' + ports_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'ports.json'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'ports.json'), self.output_file)) def test_dhcp_relay(self): # Test generation of wait_for_intf.sh template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-dhcp-relay', 'wait_for_intf.sh.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + template_path + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'wait_for_intf.sh'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'wait_for_intf.sh'), self.output_file)) # Test generation of docker-dhcp-relay.supervisord.conf template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-dhcp-relay', 'docker-dhcp-relay.supervisord.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + template_path + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'docker-dhcp-relay.supervisord.conf'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'docker-dhcp-relay.supervisord.conf'), self.output_file)) def test_lldp(self): lldpd_conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-lldp', 'lldpd.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + lldpd_conf_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'lldpd.conf'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'lldpd.conf'), self.output_file)) def test_bgpd_quagga(self): conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-quagga', 'bgpd.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file self.run_script(argument) - original_filename = os.path.join(self.test_dir, 'sample_output', 'bgpd_quagga.conf') + original_filename = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'bgpd_quagga.conf') r = filecmp.cmp(original_filename, self.output_file) diff_output = self.run_diff(original_filename, self.output_file) if not r else "" self.assertTrue(r, "Diff:\n" + diff_output) @@ -78,21 +80,21 @@ def test_zebra_quagga(self): conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-quagga', 'zebra.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'zebra_quagga.conf'), self.output_file)) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'zebra_quagga.conf'), self.output_file)) def test_ipinip(self): ipinip_file = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ipinip.json.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + ipinip_file + ' > ' + self.output_file self.run_script(argument) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'ipinip.json') + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'ipinip.json') assert filecmp.cmp(sample_output_file, self.output_file) def test_l2switch_template(self): argument = '-k Mellanox-SN2700 -t ' + os.path.join(self.test_dir, '../data/l2switch.j2') + ' -p ' + self.t0_port_config + ' > ' + self.output_file self.run_script(argument) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'l2switch.json') + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'l2switch.json') self.assertTrue(filecmp.cmp(sample_output_file, self.output_file)) @@ -112,7 +114,7 @@ def test_qos_arista7050_render_template(self): qos_config_file_new = os.path.join(arista_dir_path, 'qos_config.j2') os.remove(qos_config_file_new) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'qos-arista7050.json') + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'qos-arista7050.json') assert filecmp.cmp(sample_output_file, self.output_file) def test_qos_dell6100_render_template(self): @@ -131,7 +133,7 @@ def test_qos_dell6100_render_template(self): qos_config_file_new = os.path.join(dell_dir_path, 'qos_config.j2') os.remove(qos_config_file_new) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'qos-dell6100.json') + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'qos-dell6100.json') assert filecmp.cmp(sample_output_file, self.output_file) def test_buffers_dell6100_render_template(self): @@ -150,7 +152,7 @@ def test_buffers_dell6100_render_template(self): buffers_config_file_new = os.path.join(dell_dir_path, 'buffers_config.j2') os.remove(buffers_config_file_new) - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'buffers-dell6100.json') + sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'buffers-dell6100.json') assert filecmp.cmp(sample_output_file, self.output_file) def test_ipinip_multi_asic(self): @@ -158,7 +160,7 @@ def test_ipinip_multi_asic(self): argument = '-m ' + self.multi_asic_minigraph + ' -p ' + self.multi_asic_port_config + ' -t ' + ipinip_file + ' -n asic0 ' + ' > ' + self.output_file print(argument) self.run_script(argument) - sample_output_file = os.path.join(self.test_dir, 'multi_npu_data', 'ipinip.json') + sample_output_file = os.path.join(self.test_dir, 'multi_npu_data', utils.PYvX_DIR, 'ipinip.json') assert filecmp.cmp(sample_output_file, self.output_file) def tearDown(self): 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 776d362c9514..b185f58a8c81 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 @@ -1,10 +1,12 @@ import filecmp -import os -import subprocess import json +import os import shutil +import subprocess from unittest import TestCase +import tests.common_utils as utils + class TestJ2FilesT2ChassisFe(TestCase): def setUp(self): @@ -37,7 +39,7 @@ def run_case(self, minigraph, template, target): 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) + original_filename = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, target) r = filecmp.cmp(original_filename, self.output_file) diff_output = self.run_diff(original_filename, self.output_file) if not r else "" From 110f7b7817f3d1eca844a76af24e001b6077abf1 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Mon, 28 Sep 2020 22:34:39 -0700 Subject: [PATCH 44/78] [cfggen] Build Python 2 And Python 3 Wheel Packages This builds Python 2&3 wheel packages for sonic-cfggen script. singed-off-by: Tamer Ahmed --- .../build_templates/sonic_debian_extension.j2 | 8 +- platform/mellanox/mlnx-platform-api.mk | 2 +- rules/docker-config-engine-buster.mk | 2 +- rules/docker-config-engine-stretch.mk | 2 +- rules/docker-config-engine.mk | 2 +- rules/sonic-config.dep | 18 +- rules/sonic-config.mk | 21 +- rules/sonic-platform-common.mk | 2 +- rules/sonic-utilities.mk | 4 +- slave.mk | 6 +- src/sonic-config-engine/config_samples.py | 1 - src/sonic-config-engine/minigraph.py | 10 +- src/sonic-config-engine/portconfig.py | 1 - src/sonic-config-engine/setup.py | 68 +- src/sonic-config-engine/sonic-cfggen | 23 +- src/sonic-config-engine/tests/common_utils.py | 1 + .../tests/multi_npu_data/py3/ipinip.json | 23 + .../tests/sample_output/py3/bgpd_frr.conf | 73 + .../tests/sample_output/py3/bgpd_quagga.conf | 100 ++ .../sample_output/py3/buffers-dell6100.json | 640 ++++++++ .../py3/docker-dhcp-relay.supervisord.conf | 69 + .../tests/sample_output/py3/frr.conf | 87 + .../tests/sample_output/py3/interfaces | 46 + .../tests/sample_output/py3/ipinip.json | 23 + .../tests/sample_output/py3/l2switch.json | 268 +++ .../tests/sample_output/py3/lldpd.conf | 3 + .../tests/sample_output/py3/mvrf_interfaces | 57 + .../tests/sample_output/py3/ports.json | 30 + .../sample_output/py3/qos-arista7050.json | 977 +++++++++++ .../tests/sample_output/py3/qos-dell6100.json | 1457 +++++++++++++++++ .../tests/sample_output/py3/staticd_frr.conf | 20 + .../sample_output/py3/t2-chassis-fe-bgpd.conf | 87 + .../py3/t2-chassis-fe-vni-zebra.conf | 32 + .../py3/t2-chassis-fe-zebra.conf | 32 + .../tests/sample_output/py3/wait_for_intf.sh | 31 + .../tests/sample_output/py3/zebra_frr.conf | 32 + .../tests/sample_output/py3/zebra_quagga.conf | 44 + src/sonic-config-engine/tests/test_cfggen.py | 5 +- .../tests/test_cfggen_pfx_filter.py | 10 +- .../tests/test_cfggen_platformJson.py | 5 +- .../tests/test_cfggen_t2_chassis_fe.py | 5 +- src/sonic-config-engine/tests/test_frr.py | 6 +- src/sonic-config-engine/tests/test_j2files.py | 9 +- .../tests/test_j2files_t2_chassis_fe.py | 9 +- .../tests/test_minigraph_case.py | 5 +- .../tests/test_multinpu_cfggen.py | 5 +- 46 files changed, 4285 insertions(+), 76 deletions(-) create mode 100644 src/sonic-config-engine/tests/multi_npu_data/py3/ipinip.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/bgpd_quagga.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/buffers-dell6100.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/frr.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/interfaces create mode 100644 src/sonic-config-engine/tests/sample_output/py3/ipinip.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/l2switch.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/lldpd.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces create mode 100644 src/sonic-config-engine/tests/sample_output/py3/ports.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/qos-arista7050.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/qos-dell6100.json create mode 100644 src/sonic-config-engine/tests/sample_output/py3/staticd_frr.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/wait_for_intf.sh create mode 100644 src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/zebra_quagga.conf diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index b40be7c13f79..0878c2801433 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -147,10 +147,10 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC sudo rm -rf $FILESYSTEM_ROOT/$SONIC_PY_COMMON_PY3_WHEEL_NAME # Install SONiC config engine Python package -CONFIG_ENGINE_WHEEL_NAME=$(basename {{config_engine_wheel_path}}) -sudo cp {{config_engine_wheel_path}} $FILESYSTEM_ROOT/$CONFIG_ENGINE_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $CONFIG_ENGINE_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_WHEEL_NAME +CONFIG_ENGINE_PY2_WHEEL_NAME=$(basename {{config_engine_py2_wheel_path}}) +sudo cp {{config_engine_py2_wheel_path}} $FILESYSTEM_ROOT/$CONFIG_ENGINE_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $CONFIG_ENGINE_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_PY2_WHEEL_NAME # Install sonic-yang-models py3 package, install dependencies sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang_*.deb diff --git a/platform/mellanox/mlnx-platform-api.mk b/platform/mellanox/mlnx-platform-api.mk index 4abc0fda8d19..b350329b00e1 100644 --- a/platform/mellanox/mlnx-platform-api.mk +++ b/platform/mellanox/mlnx-platform-api.mk @@ -3,7 +3,7 @@ SONIC_PLATFORM_API_PY2 = mlnx_platform_api-1.0-py2-none-any.whl $(SONIC_PLATFORM_API_PY2)_SRC_PATH = $(PLATFORM_PATH)/mlnx-platform-api $(SONIC_PLATFORM_API_PY2)_PYTHON_VERSION = 2 -$(SONIC_PLATFORM_API_PY2)_DEPENDS = $(SONIC_PY_COMMON_PY2) $(SONIC_PLATFORM_COMMON_PY2) $(SONIC_CONFIG_ENGINE) +$(SONIC_PLATFORM_API_PY2)_DEPENDS = $(SONIC_PY_COMMON_PY2) $(SONIC_PLATFORM_COMMON_PY2) $(SONIC_CONFIG_ENGINE_PY2) SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2) export mlnx_platform_api_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2))" diff --git a/rules/docker-config-engine-buster.mk b/rules/docker-config-engine-buster.mk index ac84f92edd9b..1f101236cd96 100644 --- a/rules/docker-config-engine-buster.mk +++ b/rules/docker-config-engine-buster.mk @@ -5,7 +5,7 @@ $(DOCKER_CONFIG_ENGINE_BUSTER)_PATH = $(DOCKERS_PATH)/docker-config-engine-buste $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) -$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_CONFIG_ENGINE_BUSTER)_LOAD_DOCKERS += $(DOCKER_BASE_BUSTER) $(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS = $($(DOCKER_BASE_BUSTER)_DBG_DEPENDS) diff --git a/rules/docker-config-engine-stretch.mk b/rules/docker-config-engine-stretch.mk index 497593a316de..075905998730 100644 --- a/rules/docker-config-engine-stretch.mk +++ b/rules/docker-config-engine-stretch.mk @@ -4,7 +4,7 @@ DOCKER_CONFIG_ENGINE_STRETCH = docker-config-engine-stretch.gz $(DOCKER_CONFIG_ENGINE_STRETCH)_PATH = $(DOCKERS_PATH)/docker-config-engine-stretch $(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) -$(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +$(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_CONFIG_ENGINE_STRETCH)_LOAD_DOCKERS += $(DOCKER_BASE_STRETCH) $(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS = $($(DOCKER_BASE_STRETCH)_DBG_DEPENDS) diff --git a/rules/docker-config-engine.mk b/rules/docker-config-engine.mk index 5d65314b6727..56a9c9755e7b 100644 --- a/rules/docker-config-engine.mk +++ b/rules/docker-config-engine.mk @@ -4,6 +4,6 @@ DOCKER_CONFIG_ENGINE = docker-config-engine.gz $(DOCKER_CONFIG_ENGINE)_PATH = $(DOCKERS_PATH)/docker-config-engine $(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) -$(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +$(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_CONFIG_ENGINE)_LOAD_DOCKERS += $(DOCKER_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_CONFIG_ENGINE) diff --git a/rules/sonic-config.dep b/rules/sonic-config.dep index f4c74d075d51..a606bb1301df 100644 --- a/rules/sonic-config.dep +++ b/rules/sonic-config.dep @@ -1,10 +1,20 @@ +# SONIC_CONFIG_ENGINE_PY2 package -SPATH := $($(SONIC_CONFIG_ENGINE)_SRC_PATH) +SPATH := $($(SONIC_CONFIG_ENGINE_PY2)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-config.mk rules/sonic-config.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) DEP_FILES += $(shell git ls-files $(SPATH)) -$(SONIC_CONFIG_ENGINE)_CACHE_MODE := GIT_CONTENT_SHA -$(SONIC_CONFIG_ENGINE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) -$(SONIC_CONFIG_ENGINE)_DEP_FILES := $(DEP_FILES) +$(SONIC_CONFIG_ENGINE_PY2)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_CONFIG_ENGINE_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_CONFIG_ENGINE_PY2)_DEP_FILES := $(DEP_FILES) + +# SONIC_CONFIG_ENGINE_PY3 package + +SPATH := $($(SONIC_CONFIG_ENGINE_PY3)_SRC_PATH) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_CONFIG_ENGINE_PY3)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_CONFIG_ENGINE_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_CONFIG_ENGINE_PY3)_DEP_FILES := $(DEP_FILES) diff --git a/rules/sonic-config.mk b/rules/sonic-config.mk index 3adb460f58d8..f7ff06286455 100644 --- a/rules/sonic-config.mk +++ b/rules/sonic-config.mk @@ -1,7 +1,16 @@ -# sonic-config-engine package +# SONIC_CONFIG_ENGINE_PY2 package -SONIC_CONFIG_ENGINE = sonic_config_engine-1.0-py2-none-any.whl -$(SONIC_CONFIG_ENGINE)_SRC_PATH = $(SRC_PATH)/sonic-config-engine -$(SONIC_CONFIG_ENGINE)_DEPENDS += $(SWSSSDK_PY2) $(SONIC_PY_COMMON_PY2) -$(SONIC_CONFIG_ENGINE)_PYTHON_VERSION = 2 -SONIC_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +SONIC_CONFIG_ENGINE_PY2 = sonic_config_engine-1.0-py2-none-any.whl +$(SONIC_CONFIG_ENGINE_PY2)_SRC_PATH = $(SRC_PATH)/sonic-config-engine +$(SONIC_CONFIG_ENGINE_PY2)_DEPENDS += $(SWSSSDK_PY2) $(SONIC_PY_COMMON_PY2) +$(SONIC_CONFIG_ENGINE_PY2)_PYTHON_VERSION = 2 +SONIC_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) + + +# SONIC_CONFIG_ENGINE_PY3 package + +SONIC_CONFIG_ENGINE_PY3 = sonic_config_engine-1.0-py3-none-any.whl +$(SONIC_CONFIG_ENGINE_PY3)_SRC_PATH = $(SRC_PATH)/sonic-config-engine +$(SONIC_CONFIG_ENGINE_PY3)_DEPENDS += $(SWSSSDK_PY3) $(SONIC_PY_COMMON_PY3) +$(SONIC_CONFIG_ENGINE_PY3)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY3) diff --git a/rules/sonic-platform-common.mk b/rules/sonic-platform-common.mk index c7ab75d9f875..a734abfd6d72 100644 --- a/rules/sonic-platform-common.mk +++ b/rules/sonic-platform-common.mk @@ -3,7 +3,7 @@ SONIC_PLATFORM_COMMON_PY2 = sonic_platform_common-1.0-py2-none-any.whl $(SONIC_PLATFORM_COMMON_PY2)_SRC_PATH = $(SRC_PATH)/sonic-platform-common $(SONIC_PLATFORM_COMMON_PY2)_PYTHON_VERSION = 2 -$(SONIC_PLATFORM_COMMON_PY2)_DEPENDS += $(SONIC_PY_COMMON_PY2) $(SONIC_CONFIG_ENGINE) +$(SONIC_PLATFORM_COMMON_PY2)_DEPENDS += $(SONIC_PY_COMMON_PY2) $(SONIC_CONFIG_ENGINE_PY2) SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY2) # Als build sonic-platform-common into python3 wheel, so we can use PSU code in SNMP docker diff --git a/rules/sonic-utilities.mk b/rules/sonic-utilities.mk index 614602b8507b..3de3de02f0ad 100644 --- a/rules/sonic-utilities.mk +++ b/rules/sonic-utilities.mk @@ -12,8 +12,8 @@ $(SONIC_UTILITIES_PY2)_SRC_PATH = $(SRC_PATH)/sonic-utilities $(SONIC_UTILITIES_PY2)_PYTHON_VERSION = 2 $(SONIC_UTILITIES_PY2)_DEPENDS += $(SONIC_PY_COMMON_PY2) \ $(SONIC_PY_COMMON_PY3) \ - $(SWSSSDK_PY2) \ - $(SONIC_CONFIG_ENGINE) \ + $(SWSSSDK_PY2) \ + $(SONIC_CONFIG_ENGINE_PY2) \ $(SONIC_YANG_MGMT_PY) \ $(SONIC_YANG_MODELS_PY3) $(SONIC_UTILITIES_PY2)_DEBS_DEPENDS = $(LIBYANG) \ diff --git a/slave.mk b/slave.mk index b9cebdf9a169..8eb78494ce3d 100644 --- a/slave.mk +++ b/slave.mk @@ -811,7 +811,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_UTILITIES_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY3)) \ - $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE_PY2)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) \ @@ -848,7 +849,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export installer_images="$(addprefix $(TARGET_PATH)/,$($*_DOCKERS))" export sonic_py_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY2))" export sonic_py_common_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY3))" - export config_engine_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE))" + export config_engine_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE_PY2))" + export config_engine_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE_PY3))" export swsssdk_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY2))" export swsssdk_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SWSSSDK_PY3))" export platform_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2))" diff --git a/src/sonic-config-engine/config_samples.py b/src/sonic-config-engine/config_samples.py index 42c545488c50..3c3ace884652 100644 --- a/src/sonic-config-engine/config_samples.py +++ b/src/sonic-config-engine/config_samples.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python import os import sys from natsort import natsorted diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 2e3ba9da21a8..7ab7c41cd2b1 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python from __future__ import print_function + import calendar import math import os @@ -922,7 +922,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw results['BGP_PEER_RANGE'] = bgp_peers_with_range if mgmt_routes: # TODO: differentiate v4 and v6 - iter(mgmt_intf.values()).next()['forced_mgmt_routes'] = mgmt_routes + next(iter(mgmt_intf.values()))['forced_mgmt_routes'] = mgmt_routes results['MGMT_PORT'] = {} results['MGMT_INTERFACE'] = {} mgmt_intf_count = 0 @@ -1044,7 +1044,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw if port_config_file: port_set = set(ports.keys()) - for (pc_name, mbr_map) in pcs.items(): + for (pc_name, mbr_map) in list(pcs.items()): # remove portchannels that contain ports not existing in port_config.ini # when port_config.ini exists if not set(mbr_map['members']).issubset(port_set): @@ -1059,7 +1059,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw results['PORTCHANNEL'] = pcs results['PORTCHANNEL_MEMBER'] = pc_members - for pc_intf in pc_intfs.keys(): + for pc_intf in list(pc_intfs.keys()): # remove portchannels not in PORTCHANNEL dictionary if isinstance(pc_intf, tuple) and pc_intf[0] not in pcs: print("Warning: ignore '%s' interface '%s' as '%s' is not in the valid PortChannel list" % (pc_intf[0], pc_intf[1], pc_intf[0]), file=sys.stderr) @@ -1097,7 +1097,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw results['VLAN'] = vlans results['VLAN_MEMBER'] = vlan_members - for nghbr in neighbors.keys(): + for nghbr in list(neighbors.keys()): # remove port not in port_config.ini if nghbr not in ports: if port_config_file is not None: diff --git a/src/sonic-config-engine/portconfig.py b/src/sonic-config-engine/portconfig.py index df1decece763..1a49e4fd1cd4 100644 --- a/src/sonic-config-engine/portconfig.py +++ b/src/sonic-config-engine/portconfig.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python try: import os import sys diff --git a/src/sonic-config-engine/setup.py b/src/sonic-config-engine/setup.py index 8ddcb62d1ab0..e1940d4c0683 100755 --- a/src/sonic-config-engine/setup.py +++ b/src/sonic-config-engine/setup.py @@ -1,52 +1,65 @@ -#!/usr/bin/env python +import glob from setuptools import setup -import os.path -import unittest -import glob -def get_test_suite(): - test_loader = unittest.TestLoader() - test_suite = test_loader.discover('tests', pattern='*.py') - return test_suite +from tests.common_utils import PY3x + +dependencies = [ +# Python 2 or 3 dependencies + 'future', + 'ipaddr', + 'lxml', + 'netaddr', + 'pyyaml', + 'sonic-py-common', + ] + ([ +# Python 3 dependencies +# pyangbind v0.8.1 pull down enum43 which causes 're' package to malfunction. +# Python3 has enum module and so pyangbind should be installed outside +# dependencies section of setuptools followed by uninstall of enum43 +# 'pyangbind==0.8.1', + 'Jinja2>=2.10', + ] if PY3x + else [ +# Python 2 dependencies +# Jinja2 v3.0.0+ dropped support for Python 2.7 and causes setuptools to +# malfunction on stretch slave docker. + 'Jinja2<3.0.0', + 'pyangbind==0.6.0', + ]) setup( name = 'sonic-config-engine', version = '1.0', description = 'Utilities for generating SONiC configuration files', - author='Taoyu Li', - author_email='taoyl@microsoft.com', + author = 'Taoyu Li', + author_email = 'taoyl@microsoft.com', url = 'https://github.com/Azure/sonic-buildimage', py_modules = [ - 'portconfig', + 'config_samples', + 'lazy_re', 'minigraph', 'openconfig_acl', - 'config_samples', + 'portconfig', 'redis_bcc', - 'lazy_re', ], scripts = [ 'sonic-cfggen', ], - install_requires = [ - 'future', - 'ipaddr', - 'jinja2>=2.10', - 'lxml', - 'netaddr', - 'pyyaml', - 'pyangbind==0.6.0', - 'sonic-py-common', - ], - test_suite = 'setup.get_test_suite', + install_requires = dependencies, data_files = [ ('/usr/share/sonic/templates', glob.glob('data/*')), ], - python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', - classifiers=[ + setup_requires= [ + 'pytest-runner', + ], + tests_require=[ + 'pytest', + ], + classifiers = [ 'Intended Audience :: Developers', 'Natural Language :: English', - "Programming Language :: Python :: 2", + 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.5', @@ -54,5 +67,6 @@ def get_test_suite(): 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', ], + keywords = 'SONiC sonic-cfggen config-engine PYTHON python' ) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index fb547acd6927..892647a757ac 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -45,9 +45,17 @@ from sonic_py_common.multi_asic import get_asic_id_from_name, is_multi_asic from sonic_py_common import device_info from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig, ConfigDBPipeConnector -#TODO: Remove STR_TYPE once SONiC moves to Python 3.x + PY3x = sys.version_info >= (3, 0) -STR_TYPE = str if PY3x else unicode + +#TODO: Remove STR_TYPE, FILE_TYPE once SONiC moves to Python 3.x +if PY3x: + from io import IOBase + STR_TYPE = str + FILE_TYPE = IOBase +else: + STR_TYPE = unicode + FILE_TYPE = file def sort_by_port_index(value): if not value: @@ -168,7 +176,8 @@ TODO(taoyl): Current version of config db only supports BGP admin states. break return newData - for key in data.keys(): + current_keys = list(data.keys()) + for key in current_keys: new_key = ConfigDBConnector.serialize_key(key) if new_key != key: data[new_key] = data.pop(key) @@ -179,7 +188,8 @@ TODO(taoyl): Current version of config db only supports BGP admin states. def to_deserialized(data): for table in data: if type(data[table]) is dict: - for key in data[table].keys(): + current_keys = list(data[table].keys()) + for key in current_keys: new_key = ConfigDBConnector.deserialize_key(key) if new_key != key: data[table][new_key] = data[table].pop(key) @@ -195,6 +205,7 @@ def deep_update(dst, src): dst[key] = value return dst +# sort_data is required as it is being imported by config/config_mgmt module in sonic_utilities def sort_data(data): for table in data: if type(data[table]) is dict: @@ -206,11 +217,11 @@ def smart_open(filename=None, mode=None): """ Provide contextual file descriptor of filename if it is not a file descriptor """ - smart_file = open(filename, mode) if not isinstance(filename, file) else filename + smart_file = open(filename, mode) if not isinstance(filename, FILE_TYPE) else filename try: yield smart_file finally: - if not isinstance(filename, file): + if not isinstance(filename, FILE_TYPE): smart_file.close() def _process_json(args, data): diff --git a/src/sonic-config-engine/tests/common_utils.py b/src/sonic-config-engine/tests/common_utils.py index 142bf2f4dde1..3d8a3029dad9 100644 --- a/src/sonic-config-engine/tests/common_utils.py +++ b/src/sonic-config-engine/tests/common_utils.py @@ -4,6 +4,7 @@ PY3x = sys.version_info >= (3, 0) PYvX_DIR = "py3" if PY3x else "py2" +PYTHON_INTERPRETTER = "python3" if PY3x else "python2" def tuple_to_str(tuplestr): """ Convert Python tuple '('elem1', 'elem2')' representation into string on the for "elem1|elem2" """ diff --git a/src/sonic-config-engine/tests/multi_npu_data/py3/ipinip.json b/src/sonic-config-engine/tests/multi_npu_data/py3/ipinip.json new file mode 100644 index 000000000000..dd72ec55fee2 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/py3/ipinip.json @@ -0,0 +1,23 @@ +[ + { + "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"8.0.0.0,10.1.0.32,10.1.0.1,10.1.0.3,10.0.0.0", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } + , + { + "TUNNEL_DECAP_TABLE:IPINIP_V6_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"fd00:1::32,fc00:1::32,fc00::1", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf new file mode 100644 index 000000000000..60fd3ded8444 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf @@ -0,0 +1,73 @@ +! +! 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 +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 +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 +! +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.1/27 +! +! +! +router bgp 65100 +! + bgp log-neighbor-changes + 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 +! +! 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/py3/bgpd_quagga.conf b/src/sonic-config-engine/tests/sample_output/py3/bgpd_quagga.conf new file mode 100644 index 000000000000..16eb6095463b --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/bgpd_quagga.conf @@ -0,0 +1,100 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! +hostname switch-t0 +password zebra +log syslog informational +log facility local4 +! enable password ! +! +! bgp multiple-instance +! +route-map FROM_BGP_SPEAKER_V4 permit 10 +! +route-map TO_BGP_SPEAKER_V4 deny 10 +! +router bgp 65100 + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + 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 + neighbor 10.0.0.57 remote-as 64600 + neighbor 10.0.0.57 description ARISTA01T1 + address-family ipv4 + neighbor 10.0.0.57 allowas-in 1 + neighbor 10.0.0.57 activate + neighbor 10.0.0.57 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::72 remote-as 64600 + neighbor fc00::72 description ARISTA01T1 + address-family ipv6 + neighbor fc00::72 allowas-in 1 + neighbor fc00::72 activate + neighbor fc00::72 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.59 remote-as 64600 + neighbor 10.0.0.59 description ARISTA02T1 + address-family ipv4 + neighbor 10.0.0.59 allowas-in 1 + neighbor 10.0.0.59 activate + neighbor 10.0.0.59 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::76 remote-as 64600 + neighbor fc00::76 description ARISTA02T1 + address-family ipv6 + neighbor fc00::76 allowas-in 1 + neighbor fc00::76 activate + neighbor fc00::76 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.61 remote-as 64600 + neighbor 10.0.0.61 description ARISTA03T1 + address-family ipv4 + neighbor 10.0.0.61 allowas-in 1 + neighbor 10.0.0.61 activate + neighbor 10.0.0.61 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::7a remote-as 64600 + neighbor fc00::7a description ARISTA03T1 + address-family ipv6 + neighbor fc00::7a allowas-in 1 + neighbor fc00::7a activate + neighbor fc00::7a soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor 10.0.0.63 remote-as 64600 + neighbor 10.0.0.63 description ARISTA04T1 + address-family ipv4 + neighbor 10.0.0.63 allowas-in 1 + neighbor 10.0.0.63 activate + neighbor 10.0.0.63 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + neighbor fc00::7e remote-as 64600 + neighbor fc00::7e description ARISTA04T1 + address-family ipv6 + neighbor fc00::7e allowas-in 1 + neighbor fc00::7e activate + neighbor fc00::7e soft-reconfiguration inbound + maximum-paths 64 + exit-address-family +! +maximum-paths 64 +! +route-map ISOLATE permit 10 +set as-path prepend 65100 +! diff --git a/src/sonic-config-engine/tests/sample_output/py3/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/py3/buffers-dell6100.json new file mode 100644 index 000000000000..39fb042cc4cb --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/buffers-dell6100.json @@ -0,0 +1,640 @@ + +{ + "CABLE_LENGTH": { + "AZURE": { + "Ethernet0": "5m", + "Ethernet1": "5m", + "Ethernet2": "5m", + "Ethernet3": "5m", + "Ethernet4": "5m", + "Ethernet5": "5m", + "Ethernet6": "5m", + "Ethernet7": "5m", + "Ethernet8": "5m", + "Ethernet9": "5m", + "Ethernet10": "5m", + "Ethernet11": "5m", + "Ethernet12": "5m", + "Ethernet13": "5m", + "Ethernet14": "5m", + "Ethernet15": "5m", + "Ethernet16": "5m", + "Ethernet17": "5m", + "Ethernet18": "5m", + "Ethernet19": "5m", + "Ethernet20": "5m", + "Ethernet21": "5m", + "Ethernet22": "5m", + "Ethernet23": "5m", + "Ethernet24": "5m", + "Ethernet25": "5m", + "Ethernet26": "5m", + "Ethernet27": "5m", + "Ethernet28": "5m", + "Ethernet29": "5m", + "Ethernet30": "5m", + "Ethernet31": "5m", + "Ethernet32": "5m", + "Ethernet33": "5m", + "Ethernet34": "5m", + "Ethernet35": "5m", + "Ethernet36": "5m", + "Ethernet37": "5m", + "Ethernet38": "5m", + "Ethernet39": "5m", + "Ethernet40": "5m", + "Ethernet41": "5m", + "Ethernet42": "5m", + "Ethernet43": "5m", + "Ethernet44": "5m", + "Ethernet45": "5m", + "Ethernet46": "5m", + "Ethernet47": "5m", + "Ethernet48": "5m", + "Ethernet49": "5m", + "Ethernet50": "5m", + "Ethernet51": "5m", + "Ethernet52": "5m", + "Ethernet53": "5m", + "Ethernet54": "5m", + "Ethernet55": "5m", + "Ethernet56": "5m", + "Ethernet57": "5m", + "Ethernet58": "5m", + "Ethernet59": "5m", + "Ethernet60": "5m", + "Ethernet61": "5m", + "Ethernet62": "5m", + "Ethernet63": "5m" + } + }, + + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10875072", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_lossy_pool": { + "size": "9243812", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "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_lossless_pool]", + "size":"1518", + "static_th":"15982720" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "Ethernet0|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet1|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet4|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet5|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet16|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet17|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet20|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet21|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet6|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet7|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet8|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet9|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet10|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet11|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet12|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet13|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet14|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet15|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet32|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet36|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet37|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet38|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet39|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet40|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet41|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet42|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet22|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet23|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet24|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet25|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet26|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet27|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet28|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet29|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet30|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet31|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet48|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet52|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet53|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet54|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet55|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet56|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet57|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet58|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + + "BUFFER_QUEUE": { + "Ethernet0|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet1|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet4|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet5|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet16|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet17|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet20|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet21|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet6|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet7|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet8|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet9|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet10|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet11|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet12|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet13|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet14|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet15|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet32|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet36|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet37|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet38|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet39|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet40|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet41|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet42|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet22|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet23|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet24|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet25|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet26|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet27|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet28|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet29|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet30|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet31|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet48|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet52|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet53|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet54|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet55|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet56|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet57|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet58|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet0|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet1|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet4|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet5|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet16|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet17|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet20|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet21|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet6|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet7|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet8|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet9|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet10|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet11|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet12|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet13|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet14|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet15|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet32|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet36|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet37|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet38|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet39|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet40|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet41|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet42|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet22|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet23|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet24|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet25|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet26|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet27|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet28|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet29|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet30|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet31|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet48|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet52|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet53|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet54|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet55|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet56|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet57|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet58|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet0|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet1|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet4|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet5|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet16|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet17|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet20|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet21|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet6|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet7|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet8|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet9|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet10|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet11|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet12|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet13|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet14|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet15|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet32|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet36|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet37|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet38|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet39|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet40|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet41|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet42|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet22|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet23|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet24|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet25|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet26|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet27|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet28|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet29|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet30|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet31|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet48|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet52|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet53|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet54|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet55|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet56|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet57|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet58|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf new file mode 100644 index 000000000000..3e485f4ddc35 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf @@ -0,0 +1,69 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=50 + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=2 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + +[group:isc-dhcp-relay] +programs=isc-dhcp-relay-Vlan1000 + +[program:isc-dhcp-relay-Vlan1000] +command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 192.0.0.1 192.0.0.2 +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited + + +[group:dhcpmon] +programs=dhcpmon-Vlan1000 + +[program:dhcpmon-Vlan1000] +command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -im eth0 +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=isc-dhcp-relay-Vlan1000:running + + + diff --git a/src/sonic-config-engine/tests/sample_output/py3/frr.conf b/src/sonic-config-engine/tests/sample_output/py3/frr.conf new file mode 100644 index 000000000000..6e8573e9ba9d --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/frr.conf @@ -0,0 +1,87 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr.conf.j2 with config DB data +! file: frr.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! +! +! Enable link-detect (default disabled) +interface PortChannel01 +link-detect +! +interface PortChannel02 +link-detect +! +interface PortChannel03 +link-detect +! +interface PortChannel04 +link-detect +! +!! +! +! 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 +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 +! +ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 192.168.0.1/27 +! +! +! +router bgp 65100 +! + bgp log-neighbor-changes + 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 +! +! end of template: bgpd/bgpd.main.conf.j2 +!! diff --git a/src/sonic-config-engine/tests/sample_output/py3/interfaces b/src/sonic-config-engine/tests/sample_output/py3/interfaces new file mode 100644 index 000000000000..f5929119703c --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/interfaces @@ -0,0 +1,46 @@ +# +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen +# file: /etc/network/interfaces +# +# The loopback network interface +auto lo +iface lo inet loopback + address 127.0.0.1 + netmask 255.255.0.0 + post-up ip addr del 127.0.0.1/8 dev lo + +# 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/py3/ipinip.json b/src/sonic-config-engine/tests/sample_output/py3/ipinip.json new file mode 100644 index 000000000000..e4028ea01a2d --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/ipinip.json @@ -0,0 +1,23 @@ +[ + { + "TUNNEL_DECAP_TABLE:IPINIP_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"10.1.0.32,10.0.0.56,10.0.0.58,10.0.0.60,10.0.0.62,192.168.0.1", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } + , + { + "TUNNEL_DECAP_TABLE:IPINIP_V6_TUNNEL" : { + "tunnel_type":"IPINIP", + "dst_ip":"fc00:1::32,fc00::71,fc00::75,fc00::79,fc00::7d", + "dscp_mode":"pipe", + "ecn_mode":"copy_from_outer", + "ttl_mode":"pipe" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/py3/l2switch.json b/src/sonic-config-engine/tests/sample_output/py3/l2switch.json new file mode 100644 index 000000000000..fd83589153ea --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/l2switch.json @@ -0,0 +1,268 @@ +{ + "DEVICE_METADATA": {"localhost": {"hwsku": "Mellanox-SN2700"}}, + "PORT": { + "Ethernet0": { + "alias": "fortyGigE0/0", + "lanes": "29,30,31,32", + "admin_status": "up" + }, + "Ethernet4": { + "alias": "fortyGigE0/4", + "lanes": "25,26,27,28", + "admin_status": "up" + }, + "Ethernet8": { + "alias": "fortyGigE0/8", + "lanes": "37,38,39,40", + "admin_status": "up" + }, + "Ethernet12": { + "alias": "fortyGigE0/12", + "lanes": "33,34,35,36", + "admin_status": "up" + }, + "Ethernet16": { + "alias": "fortyGigE0/16", + "lanes": "41,42,43,44", + "admin_status": "up" + }, + "Ethernet20": { + "alias": "fortyGigE0/20", + "lanes": "45,46,47,48", + "admin_status": "up" + }, + "Ethernet24": { + "alias": "fortyGigE0/24", + "lanes": "5,6,7,8", + "admin_status": "up" + }, + "Ethernet28": { + "alias": "fortyGigE0/28", + "lanes": "1,2,3,4", + "admin_status": "up" + }, + "Ethernet32": { + "alias": "fortyGigE0/32", + "lanes": "9,10,11,12", + "admin_status": "up" + }, + "Ethernet36": { + "alias": "fortyGigE0/36", + "lanes": "13,14,15,16", + "admin_status": "up" + }, + "Ethernet40": { + "alias": "fortyGigE0/40", + "lanes": "21,22,23,24", + "admin_status": "up" + }, + "Ethernet44": { + "alias": "fortyGigE0/44", + "lanes": "17,18,19,20", + "admin_status": "up" + }, + "Ethernet48": { + "alias": "fortyGigE0/48", + "lanes": "49,50,51,52", + "admin_status": "up" + }, + "Ethernet52": { + "alias": "fortyGigE0/52", + "lanes": "53,54,55,56", + "admin_status": "up" + }, + "Ethernet56": { + "alias": "fortyGigE0/56", + "lanes": "61,62,63,64", + "admin_status": "up" + }, + "Ethernet60": { + "alias": "fortyGigE0/60", + "lanes": "57,58,59,60", + "admin_status": "up" + }, + "Ethernet64": { + "alias": "fortyGigE0/64", + "lanes": "65,66,67,68", + "admin_status": "up" + }, + "Ethernet68": { + "alias": "fortyGigE0/68", + "lanes": "69,70,71,72", + "admin_status": "up" + }, + "Ethernet72": { + "alias": "fortyGigE0/72", + "lanes": "77,78,79,80", + "admin_status": "up" + }, + "Ethernet76": { + "alias": "fortyGigE0/76", + "lanes": "73,74,75,76", + "admin_status": "up" + }, + "Ethernet80": { + "alias": "fortyGigE0/80", + "lanes": "105,106,107,108", + "admin_status": "up" + }, + "Ethernet84": { + "alias": "fortyGigE0/84", + "lanes": "109,110,111,112", + "admin_status": "up" + }, + "Ethernet88": { + "alias": "fortyGigE0/88", + "lanes": "117,118,119,120", + "admin_status": "up" + }, + "Ethernet92": { + "alias": "fortyGigE0/92", + "lanes": "113,114,115,116", + "admin_status": "up" + }, + "Ethernet96": { + "alias": "fortyGigE0/96", + "lanes": "121,122,123,124", + "admin_status": "up" + }, + "Ethernet100": { + "alias": "fortyGigE0/100", + "lanes": "125,126,127,128", + "admin_status": "up" + }, + "Ethernet104": { + "alias": "fortyGigE0/104", + "lanes": "85,86,87,88", + "admin_status": "up" + }, + "Ethernet108": { + "alias": "fortyGigE0/108", + "lanes": "81,82,83,84", + "admin_status": "up" + }, + "Ethernet112": { + "alias": "fortyGigE0/112", + "lanes": "89,90,91,92", + "admin_status": "up" + }, + "Ethernet116": { + "alias": "fortyGigE0/116", + "lanes": "93,94,95,96", + "admin_status": "up" + }, + "Ethernet120": { + "alias": "fortyGigE0/120", + "lanes": "97,98,99,100", + "admin_status": "up" + }, + "Ethernet124": { + "alias": "fortyGigE0/124", + "lanes": "101,102,103,104", + "admin_status": "up" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000" + } + }, + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet12": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet16": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet20": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet24": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet28": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet32": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet36": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet40": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet44": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet48": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet52": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet56": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet60": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet64": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet68": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet72": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet76": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet80": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet84": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet88": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet92": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet96": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet100": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet104": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet108": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet112": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet116": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet120": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet124": { + "tagging_mode": "untagged" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py3/lldpd.conf b/src/sonic-config-engine/tests/sample_output/py3/lldpd.conf new file mode 100644 index 000000000000..d28ec8418362 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/lldpd.conf @@ -0,0 +1,3 @@ +configure ports eth0 lldp portidsubtype local eth0 +configure system ip management pattern 10.0.0.100 +configure system hostname switch-t0 diff --git a/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces new file mode 100644 index 000000000000..49d307aa2df7 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces @@ -0,0 +1,57 @@ +# +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# 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/16 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 + address 127.0.0.1 + netmask 255.255.0.0 + post-up ip addr del 127.0.0.1/8 dev lo + +# 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/* +# + diff --git a/src/sonic-config-engine/tests/sample_output/py3/ports.json b/src/sonic-config-engine/tests/sample_output/py3/ports.json new file mode 100644 index 000000000000..36f5ad117c39 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/ports.json @@ -0,0 +1,30 @@ +[ + { + "PORT_TABLE:Ethernet0": { + "speed": "10000", + "description": "fortyGigE0/0" + }, + "OP": "SET" + }, + { + "PORT_TABLE:Ethernet4": { + "speed": "25000", + "description": "fortyGigE0/4" + }, + "OP": "SET" + }, + { + "PORT_TABLE:Ethernet8": { + "speed": "1000", + "description": "Interface description" + }, + "OP": "SET" + }, + { + "PORT_TABLE:Ethernet12": { + "speed": "100000", + "description": "Interface description" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/py3/qos-arista7050.json b/src/sonic-config-engine/tests/sample_output/py3/qos-arista7050.json new file mode 100644 index 000000000000..aa05ef4ec36c --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/qos-arista7050.json @@ -0,0 +1,977 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0" : "1", + "1" : "1", + "2" : "1", + "3" : "3", + "4" : "4", + "5" : "2", + "6" : "1", + "7" : "1", + "8" : "0", + "9" : "1", + "10": "1", + "11": "1", + "12": "1", + "13": "1", + "14": "1", + "15": "1", + "16": "1", + "17": "1", + "18": "1", + "19": "1", + "20": "1", + "21": "1", + "22": "1", + "23": "1", + "24": "1", + "25": "1", + "26": "1", + "27": "1", + "28": "1", + "29": "1", + "30": "1", + "31": "1", + "32": "1", + "33": "1", + "34": "1", + "35": "1", + "36": "1", + "37": "1", + "38": "1", + "39": "1", + "40": "1", + "41": "1", + "42": "1", + "43": "1", + "44": "1", + "45": "1", + "46": "5", + "47": "1", + "48": "6", + "49": "1", + "50": "1", + "51": "1", + "52": "1", + "53": "1", + "54": "1", + "55": "1", + "56": "1", + "57": "1", + "58": "1", + "59": "1", + "60": "1", + "61": "1", + "62": "1", + "63": "1" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "14" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "15" + } + }, + "PORT_QOS_MAP": { + "Ethernet4": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet8": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet12": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet16": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet20": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet24": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet28": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet32": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet36": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet40": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet44": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet48": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet52": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet56": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet60": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet64": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet68": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet72": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet76": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet80": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet84": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet88": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet92": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet96": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet112": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet116": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet120": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet124": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "1048576", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, + "QUEUE": { + "Ethernet4|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet44|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet60|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet64|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet68|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet72|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet76|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet80|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet84|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet88|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet92|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet96|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet112|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet116|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet120|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet124|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet44|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet60|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet64|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet68|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet72|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet76|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet80|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet84|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet88|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet92|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet96|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet112|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet116|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet120|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet124|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet44|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet60|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet64|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet68|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet72|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet76|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet80|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet84|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet88|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet92|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet96|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet112|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet116|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet120|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet124|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py3/qos-dell6100.json b/src/sonic-config-engine/tests/sample_output/py3/qos-dell6100.json new file mode 100644 index 000000000000..75d9b3a87eee --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/qos-dell6100.json @@ -0,0 +1,1457 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0" : "1", + "1" : "1", + "2" : "1", + "3" : "3", + "4" : "4", + "5" : "2", + "6" : "1", + "7" : "1", + "8" : "0", + "9" : "1", + "10": "1", + "11": "1", + "12": "1", + "13": "1", + "14": "1", + "15": "1", + "16": "1", + "17": "1", + "18": "1", + "19": "1", + "20": "1", + "21": "1", + "22": "1", + "23": "1", + "24": "1", + "25": "1", + "26": "1", + "27": "1", + "28": "1", + "29": "1", + "30": "1", + "31": "1", + "32": "1", + "33": "1", + "34": "1", + "35": "1", + "36": "1", + "37": "1", + "38": "1", + "39": "1", + "40": "1", + "41": "1", + "42": "1", + "43": "1", + "44": "1", + "45": "1", + "46": "5", + "47": "1", + "48": "6", + "49": "1", + "50": "1", + "51": "1", + "52": "1", + "53": "1", + "54": "1", + "55": "1", + "56": "1", + "57": "1", + "58": "1", + "59": "1", + "60": "1", + "61": "1", + "62": "1", + "63": "1" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "14" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "15" + } + }, + "PORT_QOS_MAP": { + "Ethernet0": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet1": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet4": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet5": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet6": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet7": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet8": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet9": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet10": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet11": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet12": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet13": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet14": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet15": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet16": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet17": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet20": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet21": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet22": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet23": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet24": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet25": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet26": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet27": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet28": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet29": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet30": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet31": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet32": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet36": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet37": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet38": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet39": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet40": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet41": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet42": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet48": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet52": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet53": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet54": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet55": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet56": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet57": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet58": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable" : "true", + "wred_yellow_enable" : "true", + "wred_red_enable" : "true", + "ecn" : "ecn_all", + "green_max_threshold" : "2097152", + "green_min_threshold" : "250000", + "yellow_max_threshold" : "2097152", + "yellow_min_threshold" : "1048576", + "red_max_threshold" : "2097152", + "red_min_threshold" : "1048576", + "green_drop_probability" : "5", + "yellow_drop_probability": "5", + "red_drop_probability" : "5" + } + }, + "QUEUE": { + "Ethernet0|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet1|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet5|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet6|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet7|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet9|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet10|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet11|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet13|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet14|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet15|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet17|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet21|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet22|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet23|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet25|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet26|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet27|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet29|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet30|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet31|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet37|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet38|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet39|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet41|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet42|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet53|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet54|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet55|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet57|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet58|3": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet1|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet4|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet5|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet6|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet7|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet8|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet9|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet10|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet11|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet12|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet13|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet14|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet15|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet16|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet17|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet20|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet21|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet22|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet23|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet24|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet25|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet26|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet27|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet28|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet29|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet30|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet31|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet32|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet36|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet37|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet38|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet39|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet40|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet41|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet42|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet48|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet52|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet53|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet54|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet55|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet56|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet57|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet58|4": { + "scheduler" : "[SCHEDULER|scheduler.1]", + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|0": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|1": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|2": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|5": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet0|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet4|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet5|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet6|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet7|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet8|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet9|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet10|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet11|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet12|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet13|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet14|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet15|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet16|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet17|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet20|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet21|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet22|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet23|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet24|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet25|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet26|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet27|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet28|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet29|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet30|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet31|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet32|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet36|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet37|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet38|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet39|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet40|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet41|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet42|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet48|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet52|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet53|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet54|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet55|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet56|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet57|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet58|6": { + "scheduler": "[SCHEDULER|scheduler.0]" + } + } +} diff --git a/src/sonic-config-engine/tests/sample_output/py3/staticd_frr.conf b/src/sonic-config-engine/tests/sample_output/py3/staticd_frr.conf new file mode 100644 index 000000000000..31a11d8578aa --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/staticd_frr.conf @@ -0,0 +1,20 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr/staticd.conf.j2 using config DB data +! file: staticd.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname switch-t0 +password zebra +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/py3/t2-chassis-fe-bgpd.conf b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf new file mode 100644 index 000000000000..dd79ae3950bb --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf @@ -0,0 +1,87 @@ +! +! 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 +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! +! Vnet BGP instance +router bgp 4000 vrf VnetFE + no bgp default ipv4-unicast + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp router-id 4.0.0.0 + neighbor 192.168.0.1 remote-as 3000 + neighbor 192.168.0.1 description Leaf01 + neighbor 192.168.0.1 timers 3 10 + address-family ipv4 unicast + neighbor 192.168.0.1 activate + neighbor 192.168.0.1 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + address-family l2vpn evpn + advertise ipv4 unicast + exit-address-family +!! +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 4.0.0.0/32 +! +! +! +! +router bgp 4000 +! + bgp log-neighbor-changes + 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 +! +! 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/py3/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf new file mode 100644 index 000000000000..180a0e9fab89 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-vni-zebra.conf @@ -0,0 +1,32 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname SpineFront01 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +vrf VnetFE +vni 9000 +! +! +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface Ethernet8 +link-detect +! +!! diff --git a/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf new file mode 100644 index 000000000000..661b27268255 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-zebra.conf @@ -0,0 +1,32 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +! template: common/daemons.common.conf.j2 +! +hostname SpineFront01 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +vrf VnetFE +vni 8000 +! +! +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface Ethernet8 +link-detect +! +!! diff --git a/src/sonic-config-engine/tests/sample_output/py3/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/py3/wait_for_intf.sh new file mode 100644 index 000000000000..6d90afa60ad7 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/wait_for_intf.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +function wait_until_iface_ready +{ + IFACE_NAME=$1 + IFACE_CIDR=$2 + + echo "Waiting until interface ${IFACE_NAME} is ready..." + + # Wait for the interface to come up + # (i.e., interface is present in STATE_DB and state is "ok") + while true; do + RESULT=$(sonic-db-cli STATE_DB HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) + if [ x"$RESULT" == x"ok" ]; then + break + fi + + sleep 1 + done + + echo "Interface ${IFACE_NAME} is ready!" +} + + +# Wait for all interfaces with IPv4 addresses to be up and ready +wait_until_iface_ready Vlan1000 192.168.0.1/27 +wait_until_iface_ready PortChannel01 10.0.0.56/31 +wait_until_iface_ready PortChannel02 10.0.0.58/31 +wait_until_iface_ready PortChannel03 10.0.0.60/31 +wait_until_iface_ready PortChannel04 10.0.0.62/31 + diff --git a/src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf b/src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf new file mode 100644 index 000000000000..e3d0c2d55bc3 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/zebra_frr.conf @@ -0,0 +1,32 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! 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 +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +! +! Enable link-detect (default disabled) +interface PortChannel01 +link-detect +! +interface PortChannel02 +link-detect +! +interface PortChannel03 +link-detect +! +interface PortChannel04 +link-detect +! +!! diff --git a/src/sonic-config-engine/tests/sample_output/py3/zebra_quagga.conf b/src/sonic-config-engine/tests/sample_output/py3/zebra_quagga.conf new file mode 100644 index 000000000000..aa3486b0163a --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/zebra_quagga.conf @@ -0,0 +1,44 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +hostname switch-t0 +password zebra +enable password zebra +! +! Enable link-detect (default disabled) +interface PortChannel01 +link-detect +! +interface PortChannel02 +link-detect +! +interface PortChannel03 +link-detect +! +interface PortChannel04 +link-detect +! +! +! 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 +! +! 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 +! +! +log syslog informational +log facility local4 +! + diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index d42438e61c25..ebaba3394f27 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -13,7 +13,7 @@ class TestCfgGen(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.sample_graph = os.path.join(self.test_dir, 'sample_graph.xml') self.sample_graph_t0 = os.path.join(self.test_dir, 't0-sample-graph.xml') self.sample_graph_simple = os.path.join(self.test_dir, 'simple-sample-graph.xml') @@ -40,6 +40,9 @@ def run_script(self, argument, check_stderr=False): else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: print(' Output: ' + output.strip()) diff --git a/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py b/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py index 8ffd72907b21..1ac2b7f7f5f3 100644 --- a/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py +++ b/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py @@ -1,11 +1,17 @@ -from unittest import TestCase import subprocess +import tests.common_utils as utils + +from unittest import TestCase + + class TestPfxFilter(TestCase): def test_comprehensive(self): # Generate output data_dir = "tests/data/pfx_filter" - cmd = "./sonic-cfggen -j %s/param_1.json -t %s/tmpl_1.txt.j2 > /tmp/result_1.txt" % (data_dir, data_dir) + cmd = "{} ./sonic-cfggen -j {}/param_1.json -t {}/tmpl_1.txt.j2 > /tmp/result_1.txt".format( + utils.PYTHON_INTERPRETTER, data_dir, data_dir + ) subprocess.check_output(cmd, shell=True) # Compare outputs cmd = "diff -u tests/data/pfx_filter/result_1.txt /tmp/result_1.txt" diff --git a/src/sonic-config-engine/tests/test_cfggen_platformJson.py b/src/sonic-config-engine/tests/test_cfggen_platformJson.py index 34fde9a8e5ca..254ec77ae00d 100644 --- a/src/sonic-config-engine/tests/test_cfggen_platformJson.py +++ b/src/sonic-config-engine/tests/test_cfggen_platformJson.py @@ -15,7 +15,7 @@ class TestCfgGenPlatformJson(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.sample_graph_simple = os.path.join(self.test_dir, 'simple-sample-graph.xml') self.platform_json = os.path.join(self.test_dir, 'sample_platform.json') self.hwsku_json = os.path.join(self.test_dir, 'sample_hwsku.json') @@ -27,6 +27,9 @@ def run_script(self, argument, check_stderr=False): else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: print(' Output: ' + output.strip()) diff --git a/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py b/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py index d0a4f2c0de59..a3d6d02a7ff2 100644 --- a/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py +++ b/src/sonic-config-engine/tests/test_cfggen_t2_chassis_fe.py @@ -10,7 +10,7 @@ class TestCfgGenT2ChassisFe(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.sample_graph_t2_chassis_fe = os.path.join(self.test_dir, 't2-chassis-fe-graph.xml') self.sample_graph_t2_chassis_fe_vni = os.path.join(self.test_dir, 't2-chassis-fe-graph-vni.xml') self.sample_graph_t2_chassis_fe_pc = os.path.join(self.test_dir, 't2-chassis-fe-graph-pc.xml') @@ -23,6 +23,9 @@ def run_script(self, argument, check_stderr=False): else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: print(' Output: ' + output.strip()) diff --git a/src/sonic-config-engine/tests/test_frr.py b/src/sonic-config-engine/tests/test_frr.py index ef7c4b06f7db..386ce42e0242 100644 --- a/src/sonic-config-engine/tests/test_frr.py +++ b/src/sonic-config-engine/tests/test_frr.py @@ -1,7 +1,6 @@ import filecmp import os import subprocess -import sys import tests.common_utils as utils @@ -10,7 +9,7 @@ class TestCfgGen(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.t0_minigraph = os.path.join(self.test_dir, 't0-sample-graph.xml') self.t0_port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini') self.output_file = os.path.join(self.test_dir, 'output') @@ -29,6 +28,9 @@ def run_script(self, argument, check_stderr=False): else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: print(' Output: ' + output.strip()) diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 8ce55f2c4427..30e1f1ca26bf 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -11,7 +11,7 @@ class TestJ2Files(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.simple_minigraph = os.path.join(self.test_dir, 'simple-sample-graph.xml') self.t0_minigraph = os.path.join(self.test_dir, 't0-sample-graph.xml') self.t0_mvrf_minigraph = os.path.join(self.test_dir, 't0-sample-graph-mvrf.xml') @@ -27,7 +27,12 @@ def setUp(self): def run_script(self, argument): print('CMD: sonic-cfggen ' + argument) - return subprocess.check_output(self.script_file + ' ' + argument, shell=True) + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + if utils.PY3x: + output = output.decode() + + return output def run_diff(self, file1, file2): return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) 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 b185f58a8c81..e6bc82941bf6 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 @@ -11,7 +11,7 @@ class TestJ2FilesT2ChassisFe(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.t2_chassis_fe_minigraph = os.path.join(self.test_dir, 't2-chassis-fe-graph.xml') self.t2_chassis_fe_vni_minigraph = os.path.join(self.test_dir, 't2-chassis-fe-graph-vni.xml') self.t2_chassis_fe_pc_minigraph = os.path.join(self.test_dir, 't2-chassis-fe-graph-pc.xml') @@ -26,7 +26,12 @@ def tearDown(self): def run_script(self, argument): print('CMD: sonic-cfggen ' + argument) - return subprocess.check_output(self.script_file + ' ' + argument, shell=True) + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + if utils.PY3x: + output = output.decode() + + return output def run_diff(self, file1, file2): return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 505d5cfcbf7f..f9c390b6536a 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -10,7 +10,7 @@ class TestCfgGenCaseInsensitive(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) - self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen') self.sample_graph = os.path.join(self.test_dir, 'simple-sample-graph-case.xml') self.port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini') @@ -21,6 +21,9 @@ def run_script(self, argument, check_stderr=False): else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: print(' Output: ' + output.strip()) diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 2aa212e30aae..8c2e59d99ba7 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -21,7 +21,7 @@ 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.script_file = utils.PYTHON_INTERPRETTER + ' ' + 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): @@ -34,6 +34,9 @@ def run_script(self, argument, check_stderr=False): else: output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if utils.PY3x: + output = output.decode() + linecount = output.strip().count('\n') if linecount <= 0: print(' Output: ' + output.strip()) From 57a584997ae2a44174e6ee725885a8a906c46847 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Mon, 28 Sep 2020 22:52:18 -0700 Subject: [PATCH 45/78] [cfggen] Iterative Version Of Deep Update Avoiding recursive update of maps as it consumes stack frames. This PR introduces iterative version of deep_update method. signed-off-by: Tamer Ahmed --- src/sonic-config-engine/sonic-cfggen | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 892647a757ac..de99d2523027 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -197,12 +197,16 @@ TODO(taoyl): Current version of config db only supports BGP admin states. def deep_update(dst, src): - for key, value in src.items(): - if isinstance(value, dict): - node = dst.setdefault(key, {}) - deep_update(node, value) - else: - dst[key] = value + """ Deep update of dst dict with contest of src dict""" + pending_nodes = [(dst, src)] + while len(pending_nodes) > 0: + d, s = pending_nodes.pop(0) + for key, value in s.items(): + if isinstance(value, dict): + node = d.setdefault(key, type(value)()) + pending_nodes.append((node, value)) + else: + d[key] = value return dst # sort_data is required as it is being imported by config/config_mgmt module in sonic_utilities From b01879b44bdb0f5628ca23e1908e46b27bb5b563 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Wed, 30 Sep 2020 13:42:20 -0700 Subject: [PATCH 46/78] [sonic-py-swsssdk] update submodule for changing redis_client index from db_id to db_name (#5512) --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 91cc6c651e90..3ef02a1e357b 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 91cc6c651e903b65b95838dc3b2cd1d2751c63b6 +Subproject commit 3ef02a1e357b8ce7cbf58e39c775f1f75e69be04 From 1f0f751d4d0849faaa91faa8783123a4482245b8 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 30 Sep 2020 22:35:52 -0700 Subject: [PATCH 47/78] [bgpcfgd]: Don't use neighbor metadata in bgpmon sessions (#5506) **- Why I did it** BGP_MONITORS sessions don't have corresponding DEVICE_NEIGHBOR_METADATA CONFIG_DB entries in the minigraphs. Prevent bgpcfgd to wait on such entries for BGP_MONITORS sessions. **- How I did it** Set constructor argument to False that means - don't wait for device neighbors metadata info for BGP_MONITORS **- How to verify it** Build an image, write on your device, use a minigraph with BGP_MONITORS sessions. Check that sessions are populated in the config. --- src/sonic-bgpcfgd/bgpcfgd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-bgpcfgd/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd index 3bedd8679004..6f52ac1626e6 100755 --- a/src/sonic-bgpcfgd/bgpcfgd +++ b/src/sonic-bgpcfgd/bgpcfgd @@ -876,7 +876,7 @@ def main(): ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME), # Peer Managers BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True), - BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", True), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", False), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), ] runner = Runner() From 87d73e282ebe7b23da00f239c07c7b12bc26d0c9 Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Thu, 1 Oct 2020 11:16:47 +0200 Subject: [PATCH 48/78] [sonic-slave]: Add libzmq to sonic-slave dockers (#5515) --- sonic-slave-buster/Dockerfile.j2 | 2 ++ sonic-slave-stretch/Dockerfile.j2 | 2 ++ 2 files changed, 4 insertions(+) diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 index 11d79278230e..34ef905a7752 100644 --- a/sonic-slave-buster/Dockerfile.j2 +++ b/sonic-slave-buster/Dockerfile.j2 @@ -67,6 +67,8 @@ RUN apt-get update && apt-get install -y \ perl-modules \ libswitch-perl \ dh-systemd \ + libzmq5 \ + libzmq3-dev \ # For quagga build libreadline-dev \ texlive-latex-base \ diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index fb685a2adcf5..54cf2c890021 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -67,6 +67,8 @@ RUN apt-get update && apt-get install -y \ perl-modules \ libswitch-perl \ dh-systemd \ + libzmq5 \ + libzmq3-dev \ # For quagga build libreadline-dev \ texlive-latex-base \ From 30f5557d36d13e0b7ff655b41f7371f089b755d9 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Thu, 1 Oct 2020 23:24:35 -0700 Subject: [PATCH 49/78] Fix generate_l2_config: don't override hostname or device role (ToRRouter) (#5510) * Fix generate_l2_config: don't override hostname because sonic-cfggen may not read from Redis. Fix test_l2switch_template test case to test preset l2 feature. * Improve test script: compare json files with sort_keys * Revert changes on sample_output * Remove members field in VLAN section. Fix test assertTrue statement. --- src/sonic-config-engine/config_samples.py | 6 ------ src/sonic-config-engine/tests/test_j2files.py | 9 ++++++--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/sonic-config-engine/config_samples.py b/src/sonic-config-engine/config_samples.py index 3c3ace884652..99341642961f 100644 --- a/src/sonic-config-engine/config_samples.py +++ b/src/sonic-config-engine/config_samples.py @@ -41,13 +41,7 @@ def generate_empty_config(data): return new_data def generate_l2_config(data): - if 'hostname' not in data['DEVICE_METADATA']['localhost']: - data['DEVICE_METADATA']['localhost']['hostname'] = 'sonic' - if 'type' not in data['DEVICE_METADATA']['localhost']: - data['DEVICE_METADATA']['localhost']['type'] = 'ToRRouter' data['VLAN'] = {'Vlan1000': {'vlanid': '1000'}} - vp = natsorted(list(data['PORT'].keys())) - data['VLAN']['Vlan1000'].setdefault('members', vp) data['VLAN_MEMBER'] = {} for port in natsorted(data['PORT']): data['PORT'][port].setdefault('admin_status', 'up') diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 30e1f1ca26bf..98bb2437628d 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -96,12 +96,15 @@ def test_ipinip(self): assert filecmp.cmp(sample_output_file, self.output_file) def test_l2switch_template(self): - argument = '-k Mellanox-SN2700 -t ' + os.path.join(self.test_dir, '../data/l2switch.j2') + ' -p ' + self.t0_port_config + ' > ' + self.output_file - self.run_script(argument) + argument = '-k Mellanox-SN2700 --preset l2 -p ' + self.t0_port_config + output = self.run_script(argument) + output_json = json.loads(output) sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'l2switch.json') + with open(sample_output_file) as sample_output_fd: + sample_output_json = json.load(sample_output_fd) - self.assertTrue(filecmp.cmp(sample_output_file, self.output_file)) + self.assertTrue(json.dumps(sample_output_json, sort_keys=True) == json.dumps(output_json, sort_keys=True)) def test_qos_arista7050_render_template(self): arista_dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', 'arista', 'x86_64-arista_7050_qx32s', 'Arista-7050-QX-32S') From a24b581d80bac9179c63675f1541559d3e48f660 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 2 Oct 2020 09:05:43 -0700 Subject: [PATCH 50/78] [Arista] Add pcie.yaml configuration file for a few platforms (#5527) * Add pcie.yaml configuration for Gardena * Add pcie.yaml configuration for Upperlake * Add pcie.yaml configuration for Clearlake * Add pcie.yaml configuration for Lodoga --- .../arista/x86_64-arista_7050_qx32s/plugins | 1 - .../plugins/eeprom.py | 1 + .../plugins/led_control.py | 1 + .../plugins/pcie.yaml | 135 ++++++ .../plugins/psuutil.py | 1 + .../plugins/sfputil.py | 1 + .../arista/x86_64-arista_7050cx3_32s/plugins | 1 - .../plugins/eeprom.py | 1 + .../plugins/led_control.py | 1 + .../plugins/pcie.yaml | 133 ++++++ .../plugins/psuutil.py | 1 + .../plugins/sfputil.py | 1 + .../arista/x86_64-arista_7060_cx32s/plugins | 1 - .../plugins/eeprom.py | 1 + .../plugins/led_control.py | 1 + .../plugins/pcie.yaml | 140 ++++++ .../plugins/psuutil.py | 1 + .../plugins/sfputil.py | 1 + .../arista/x86_64-arista_7260cx3_64/plugins | 1 - .../plugins/eeprom.py | 1 + .../plugins/led_control.py | 1 + .../plugins/pcie.yaml | 426 ++++++++++++++++++ .../plugins/psuutil.py | 1 + .../plugins/sfputil.py | 1 + 24 files changed, 850 insertions(+), 4 deletions(-) delete mode 120000 device/arista/x86_64-arista_7050_qx32s/plugins create mode 120000 device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py create mode 120000 device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py create mode 100644 device/arista/x86_64-arista_7050_qx32s/plugins/pcie.yaml create mode 120000 device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py create mode 120000 device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py delete mode 120000 device/arista/x86_64-arista_7050cx3_32s/plugins create mode 120000 device/arista/x86_64-arista_7050cx3_32s/plugins/eeprom.py create mode 120000 device/arista/x86_64-arista_7050cx3_32s/plugins/led_control.py create mode 100644 device/arista/x86_64-arista_7050cx3_32s/plugins/pcie.yaml create mode 120000 device/arista/x86_64-arista_7050cx3_32s/plugins/psuutil.py create mode 120000 device/arista/x86_64-arista_7050cx3_32s/plugins/sfputil.py delete mode 120000 device/arista/x86_64-arista_7060_cx32s/plugins create mode 120000 device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py create mode 120000 device/arista/x86_64-arista_7060_cx32s/plugins/led_control.py create mode 100644 device/arista/x86_64-arista_7060_cx32s/plugins/pcie.yaml create mode 120000 device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py create mode 120000 device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py delete mode 120000 device/arista/x86_64-arista_7260cx3_64/plugins create mode 120000 device/arista/x86_64-arista_7260cx3_64/plugins/eeprom.py create mode 120000 device/arista/x86_64-arista_7260cx3_64/plugins/led_control.py create mode 100644 device/arista/x86_64-arista_7260cx3_64/plugins/pcie.yaml create mode 120000 device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py create mode 120000 device/arista/x86_64-arista_7260cx3_64/plugins/sfputil.py diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins b/device/arista/x86_64-arista_7050_qx32s/plugins deleted file mode 120000 index 5fbbf98a6284..000000000000 --- a/device/arista/x86_64-arista_7050_qx32s/plugins +++ /dev/null @@ -1 +0,0 @@ -../x86_64-arista_common/plugins/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py b/device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py new file mode 120000 index 000000000000..35cfaff3de4e --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/eeprom.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py b/device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py new file mode 120000 index 000000000000..8d733780117e --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/led_control.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/pcie.yaml b/device/arista/x86_64-arista_7050_qx32s/plugins/pcie.yaml new file mode 100644 index 000000000000..d40522ff4998 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/pcie.yaml @@ -0,0 +1,135 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '1536' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Root + Complex' +- bus: '00' + dev: '01' + fn: '0' + id: '9831' + name: 'VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Kabini + [Radeon HD 8400E]' +- bus: '00' + dev: '02' + fn: '0' + id: '1538' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 0' +- bus: '00' + dev: '02' + fn: '1' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '2' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '3' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '4' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '5' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '11' + fn: '0' + id: '7801' + name: 'SATA controller: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI + mode] (rev 40)' +- bus: '00' + dev: '12' + fn: '0' + id: '7807' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB OHCI Controller + (rev 39)' +- bus: '00' + dev: '12' + fn: '2' + id: '7808' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB EHCI Controller + (rev 39)' +- bus: '00' + dev: '14' + fn: '0' + id: 780b + name: 'SMBus: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller (rev 3a)' +- bus: '00' + dev: '14' + fn: '3' + id: 780e + name: 'ISA bridge: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge (rev 11)' +- bus: '00' + dev: '14' + fn: '7' + id: '7813' + name: 'SD Host controller: Advanced Micro Devices, Inc. [AMD] FCH SD Flash Controller + (rev 01)' +- bus: '00' + dev: '18' + fn: '0' + id: '1530' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 0' +- bus: '00' + dev: '18' + fn: '1' + id: '1531' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 1' +- bus: '00' + dev: '18' + fn: '2' + id: '1532' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 2' +- bus: '00' + dev: '18' + fn: '3' + id: '1533' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 3' +- bus: '00' + dev: '18' + fn: '4' + id: '1534' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 4' +- bus: '00' + dev: '18' + fn: '5' + id: '1535' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Function + 5' +- bus: '01' + dev: '00' + fn: '0' + id: b850 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56850 Switch ASIC (rev + 03)' +- bus: '02' + dev: '00' + fn: '0' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 01)' +- bus: '04' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py b/device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py new file mode 120000 index 000000000000..2b0024ade969 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/psuutil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py b/device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py new file mode 120000 index 000000000000..c333e23763d7 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/sfputil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins b/device/arista/x86_64-arista_7050cx3_32s/plugins deleted file mode 120000 index 789a45fcace9..000000000000 --- a/device/arista/x86_64-arista_7050cx3_32s/plugins +++ /dev/null @@ -1 +0,0 @@ -../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/eeprom.py b/device/arista/x86_64-arista_7050cx3_32s/plugins/eeprom.py new file mode 120000 index 000000000000..35cfaff3de4e --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/eeprom.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/led_control.py b/device/arista/x86_64-arista_7050cx3_32s/plugins/led_control.py new file mode 120000 index 000000000000..8d733780117e --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/led_control.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/led_control.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/pcie.yaml b/device/arista/x86_64-arista_7050cx3_32s/plugins/pcie.yaml new file mode 100644 index 000000000000..f56c87185f3c --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/pcie.yaml @@ -0,0 +1,133 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '1566' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Root Complex' +- bus: '00' + dev: '00' + fn: '2' + id: '1567' + name: 'IOMMU: Advanced Micro Devices, Inc. [AMD] Mullins IOMMU' +- bus: '00' + dev: '02' + fn: '0' + id: 156b + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Host Bridge' +- bus: '00' + dev: '02' + fn: '1' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '2' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '3' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '4' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '5' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: 08 + fn: '0' + id: '1537' + name: 'Encryption controller: Advanced Micro Devices, Inc. [AMD] Kabini/Mullins + PSP-Platform Security Processor' +- bus: '00' + dev: '11' + fn: '0' + id: '7801' + name: 'SATA controller: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI + mode] (rev 40)' +- bus: '00' + dev: '12' + fn: '0' + id: '7808' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB EHCI Controller + (rev 39)' +- bus: '00' + dev: '14' + fn: '0' + id: 780b + name: 'SMBus: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller (rev 42)' +- bus: '00' + dev: '14' + fn: '3' + id: 780e + name: 'ISA bridge: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge (rev 11)' +- bus: '00' + dev: '14' + fn: '7' + id: '7813' + name: 'SD Host controller: Advanced Micro Devices, Inc. [AMD] FCH SD Flash Controller + (rev 01)' +- bus: '00' + dev: '18' + fn: '0' + id: '1580' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 0' +- bus: '00' + dev: '18' + fn: '1' + id: '1581' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 1' +- bus: '00' + dev: '18' + fn: '2' + id: '1582' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 2' +- bus: '00' + dev: '18' + fn: '3' + id: '1583' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 3' +- bus: '00' + dev: '18' + fn: '4' + id: '1584' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 4' +- bus: '00' + dev: '18' + fn: '5' + id: '1585' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 5' +- bus: '01' + dev: '00' + fn: '0' + id: b870 + name: 'Ethernet controller: Broadcom Limited Device b870 (rev 01)' +- bus: '02' + dev: '00' + fn: '0' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 01)' +- bus: '04' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/psuutil.py b/device/arista/x86_64-arista_7050cx3_32s/plugins/psuutil.py new file mode 120000 index 000000000000..2b0024ade969 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/psuutil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins/sfputil.py b/device/arista/x86_64-arista_7050cx3_32s/plugins/sfputil.py new file mode 120000 index 000000000000..c333e23763d7 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/sfputil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins b/device/arista/x86_64-arista_7060_cx32s/plugins deleted file mode 120000 index 5fbbf98a6284..000000000000 --- a/device/arista/x86_64-arista_7060_cx32s/plugins +++ /dev/null @@ -1 +0,0 @@ -../x86_64-arista_common/plugins/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py b/device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py new file mode 120000 index 000000000000..35cfaff3de4e --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/eeprom.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/led_control.py b/device/arista/x86_64-arista_7060_cx32s/plugins/led_control.py new file mode 120000 index 000000000000..8d733780117e --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/led_control.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/led_control.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/pcie.yaml b/device/arista/x86_64-arista_7060_cx32s/plugins/pcie.yaml new file mode 100644 index 000000000000..a988a7d1c5fc --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/pcie.yaml @@ -0,0 +1,140 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '1566' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Root Complex' +- bus: '00' + dev: '00' + fn: '2' + id: '1567' + name: 'IOMMU: Advanced Micro Devices, Inc. [AMD] Mullins IOMMU' +- bus: '00' + dev: '02' + fn: '0' + id: 156b + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Host Bridge' +- bus: '00' + dev: '02' + fn: '1' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '2' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '3' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '4' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: '02' + fn: '5' + id: '1439' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 16h Processor Functions + 5:1' +- bus: '00' + dev: 08 + fn: '0' + id: '1537' + name: 'Encryption controller: Advanced Micro Devices, Inc. [AMD] Kabini/Mullins + PSP-Platform Security Processor' +- bus: '00' + dev: '11' + fn: '0' + id: '7801' + name: 'SATA controller: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI + mode] (rev 40)' +- bus: '00' + dev: '12' + fn: '0' + id: '7808' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB EHCI Controller + (rev 39)' +- bus: '00' + dev: '14' + fn: '0' + id: 780b + name: 'SMBus: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller (rev 42)' +- bus: '00' + dev: '14' + fn: '3' + id: 780e + name: 'ISA bridge: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge (rev 11)' +- bus: '00' + dev: '14' + fn: '7' + id: '7813' + name: 'SD Host controller: Advanced Micro Devices, Inc. [AMD] FCH SD Flash Controller + (rev 01)' +- bus: '00' + dev: '18' + fn: '0' + id: '1580' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 0' +- bus: '00' + dev: '18' + fn: '1' + id: '1581' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 1' +- bus: '00' + dev: '18' + fn: '2' + id: '1582' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 2' +- bus: '00' + dev: '18' + fn: '3' + id: '1583' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 3' +- bus: '00' + dev: '18' + fn: '4' + id: '1584' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 4' +- bus: '00' + dev: '18' + fn: '5' + id: '1585' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Family 16h (Models 30h-3fh) + Processor Function 5' +- bus: '01' + dev: '00' + fn: '0' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC (rev + 12)' +- bus: '01' + dev: '00' + fn: '1' + id: b960 + name: 'Ethernet controller: Broadcom Limited Broadcom BCM56960 Switch ASIC (rev + 12)' +- bus: '02' + dev: '00' + fn: '0' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 01)' +- bus: '04' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py b/device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py new file mode 120000 index 000000000000..2b0024ade969 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/psuutil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py b/device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py new file mode 120000 index 000000000000..c333e23763d7 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/sfputil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins b/device/arista/x86_64-arista_7260cx3_64/plugins deleted file mode 120000 index 5fbbf98a6284..000000000000 --- a/device/arista/x86_64-arista_7260cx3_64/plugins +++ /dev/null @@ -1 +0,0 @@ -../x86_64-arista_common/plugins/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/eeprom.py b/device/arista/x86_64-arista_7260cx3_64/plugins/eeprom.py new file mode 120000 index 000000000000..35cfaff3de4e --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/eeprom.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/led_control.py b/device/arista/x86_64-arista_7260cx3_64/plugins/led_control.py new file mode 120000 index 000000000000..8d733780117e --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/led_control.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/led_control.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/pcie.yaml b/device/arista/x86_64-arista_7260cx3_64/plugins/pcie.yaml new file mode 100644 index 000000000000..a2540013703e --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/pcie.yaml @@ -0,0 +1,426 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '01' + fn: '1' + id: 6f03 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 03)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 03)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 03)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 03)' +- bus: '00' + dev: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: 1c + fn: '0' + id: 8c10 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #1 (rev d5)' +- bus: '00' + dev: 1c + fn: '4' + id: 8c18 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #5 (rev d5)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '00' + dev: 1f + fn: '6' + id: 8c24 + name: 'Signal processing controller: Intel Corporation 8 Series Chipset Family Thermal + Management Controller (rev 05)' +- bus: '01' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' +- bus: '02' + dev: '00' + fn: '0' + id: '1682' + name: 'Ethernet controller: Broadcom Limited NetXtreme BCM57762 Gigabit Ethernet + PCIe (rev 20)' +- bus: '03' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '03' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '03' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '03' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '04' + dev: '00' + fn: '0' + id: 15a7 + name: 'Ethernet controller: Intel Corporation Device 15a7' +- bus: '04' + dev: '00' + fn: '1' + id: 15a7 + name: 'Ethernet controller: Intel Corporation Device 15a7' +- bus: '06' + dev: '00' + fn: '0' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 01)' +- bus: '07' + dev: '00' + fn: '0' + id: b971 + name: 'Ethernet controller: Broadcom Limited Device b971 (rev 11)' +- bus: '07' + dev: '00' + fn: '1' + id: b971 + name: 'Ethernet controller: Broadcom Limited Device b971 (rev 11)' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '3' + id: '0001' + name: 'System peripheral: Arastra Inc. Device 0001 (rev 03)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 03)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 03)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 03)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 03)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 03)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 03)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py b/device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py new file mode 120000 index 000000000000..2b0024ade969 --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/psuutil.py \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/sfputil.py b/device/arista/x86_64-arista_7260cx3_64/plugins/sfputil.py new file mode 120000 index 000000000000..c333e23763d7 --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-arista_common/plugins/sfputil.py \ No newline at end of file From dda98023e3e982580091f6f185ff2df77a2148c8 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Fri, 2 Oct 2020 09:06:30 -0700 Subject: [PATCH 51/78] [Submodule update] sonic swss (#5489) be51ebc533cbe92a885c584b4611ffc92d10ea36 Add IPv6 key item support to request parser (#1449) 76e22516bffe45d577ab9cce4f5d96687140fe75 When teamd feature state is disabled the Netdevice created by teamd were (#1450) 6aa97ce7982b78a26803908c0ce12302e51df793 Use .clear() after std::move() (#1444) d5757db5d896aa2405f6cbf9f4c150f46b27aa4e Add libzmq to README dependencies (#1447) c7b262ee61973a48943603810c8246a2471d1862 Add libzmq to Makefiles (#1443) 0b2e59ab6b909e5ea06013da03215f0d1af1e618 [drop counters] Clarify log messages for initial counter setup (#1445) 003cf24353c845ef708d192b7da8d571537671e1 [dvs] Refactor and add buffer pool wm test (#1446) 2f5d2d99dfae506333bddda9de2f289f92bb889b [acl] Remove Ethertype from L3V6 qualifiers (#1433) f7b974f7fc6474a6493a7b6d0676e17caffa6165 Fix issue: bufferorch only pass the first attribute to sai when setting attribute (#1442) Signed-off-by: Abhishek Dosi --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index b4938a5519d6..be51ebc533cb 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit b4938a5519d633ac22eac5e1ea27820d1e665239 +Subproject commit be51ebc533cbe92a885c584b4611ffc92d10ea36 From 8418bd3df3a1d0e6ebf15bcfd41d2be034454b65 Mon Sep 17 00:00:00 2001 From: Ciju Rajan K <53076238+ciju-juniper@users.noreply.github.com> Date: Fri, 2 Oct 2020 21:36:55 +0530 Subject: [PATCH 52/78] [Juniper] Updating platform documentation (#5478) This patch set updates the documentation for QFX5200 & QFX5210 Juniper switching platforms. Signed-off-by: Ciju Rajan K --- .../sonic-platform-modules-juniper/README.md | 78 +++++++----- .../qfx5200/utils/README | 119 +++++++++++------- 2 files changed, 123 insertions(+), 74 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-juniper/README.md b/platform/broadcom/sonic-platform-modules-juniper/README.md index 2b43eee68271..3a661cef8eeb 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/README.md +++ b/platform/broadcom/sonic-platform-modules-juniper/README.md @@ -1,30 +1,27 @@ -Juniper Networks Platform Support for SONiC Readme -================================================== +Juniper Networks Platform Support for SONiC +=========================================== -This readme provides information on how to install and upgrade ONIE and SONiC images on the Juniper Networks QFX5210-64C-S switch. +This readme provides information on how to install and upgrade ONIE and SONiC images on the Juniper Networks switches. -Note: The QFX5210-64C-S switch ships with ONIE and SONiC images preinstalled. - -## Purpose - -This package contains kernel drivers, a python library, and a python script to provide platform support for Juniper Networks QFX5210-64C-S switch. +Note: Switches ship with ONIE and SONiC images preinstalled. ## Supported platforms -The following Juniper Networks platform is supported for the SONiC operating system: +The following Juniper Networks platforms are supported for the SONiC operating system: - QFX5210-64C-S + - QFX5200-32C-S -## Installing ONIE on QFX5210-64C-S Switch - -The following information describes how to install ONIE on the Juniper Networks QFX5210-64C-S switch. +## Building and Installing ONIE -To install ONIE on Juniper Networks QFX5210-64C-S switch, you need to: +ONIE is the bootloader used and it's a prerequisite to install ONIE on the switches before installing SONiC. 1. Cross compile ONIE -To compile ONIE, you need to change the directories to "build-config" and then type "make MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all". +To compile ONIE, you need to change the directories to "build-config" and then based on the platform issue the following commands + +a) For QFX5210-64C-S platform, invoke "make MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all". For example: @@ -33,6 +30,8 @@ For example: $ make -j4 MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all ``` +b) For QFX5200-32C-S platform, invoke "make MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5200 all". + ONIE binaries are located at the directory /build/images. The following command shows how to navigate the directory to view the ONIE binaries: ``` @@ -50,6 +49,8 @@ total 40740 Note: Use the following command to build a demo target: +For example: + ``` $ make -j4 MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 all demo ``` @@ -65,20 +66,22 @@ You can install these binary files by using the 'onie-nos-install' command to te Use the following command for make clean: +For example: + ``` $ make machine-clean MACHINEROOT=../machine/juniper MACHINE=juniper_qfx5210 ``` -## Installing ONIE on a New QFX5210-64C-S Switch +## Installing ONIE -The following information describes on how to install ONIE on the Juniper Networks QFX5210-64C-S switch. You can do a fresh install of ONIE image on the QFX5210-64C-S switch, or recover an existing ONIE image from the QFX5210-64C-S switch that has been corrupted. - -To install ONIE on a new QFX5210-64C-S switch, you can use one of the following ONIE recovery images: +To install ONIE on a new switch, you can use one of the following ONIE recovery images: 1) ..iso -- Hybrid ISO image. 2) ..efi64.pxe -- PXE image for UEFI64 machines. +Note: Second method is not applicable for QFX5200-32C-S + ## Creating an ISO Recovery Image @@ -101,11 +104,11 @@ You can find the correct "/dev/sdX" by validating the "dmesg" output after inser 1) Booting from a USB Memory Device -To boot from an external USB memory device connected to the QFX5210-64C-S switch, you need to: +To boot from an external USB memory device connected to the switch, you need to: -a. Insert the USB memory device to the USB port of the QFX5210-64C-S switch. +a. Insert the USB memory device to the USB port of the switch. -b. Power on the QFX5210-64C-S switch and enter the BIOS configuration by pressing the Esc key, as displayed in the console screen. +b. Power on the switch and enter the BIOS configuration by pressing the Esc key, as displayed in the console screen. c. Set the hard drive boot order as follows: @@ -134,7 +137,7 @@ c. Set the hard drive boot order as follows: d. Go to "Save & Exit" in the BIOS screen and from the Boot Override option select the USB memory device (For example, JetFlashTranscend 8GB 8.07). -e. After a few seconds, the QFX5210-64C-S switch would restart and boot from the USB memory device and then you will see the following on the console screen: +e. After a few seconds, the switch would restart and boot from the USB memory device and then you will see the following on the console screen: ``` GNU GRUB version 2.02~beta2+e4a1fe391 @@ -168,6 +171,8 @@ g. Select "ONIE: Rescue" to enter the ONIE recovery command-line shell (Optional 2) Recovering ONIE using PXE-UEFI64 Recovery Image +Note: This section is only applicable for QFX5210-64C-S platform. + You can use the onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe image to recover the ONIE image through UEFI PXE. The onie-recovery-x86_64-juniper_qfx5210-r0.efi64.pxe is made for the QFX5210-64C-S switch that has a PXE client which is based on UEFI64. @@ -192,12 +197,12 @@ The following links provide more information about ONIE: ## SONiC Build Process: -The instruction on how to build an ONIE compatible network operating system (NOS) installer image for Juniper Networks QFX5210-64C-S switch, and how to build docker images running inside the NOS is available at https://github.com/Azure/sonic-buildimage#usage. +The instruction on how to build an ONIE compatible network operating system (NOS) installer image for Juniper Networks switches, and how to build docker images running inside the NOS is available at https://github.com/Azure/sonic-buildimage#usage. -## Install SONiC on the Juniper Networks QFX5210-64C-S switch: +## Install SONiC on the Juniper Networks switch:es -You need to copy the SONiC image sonic-broadcom.bin to the Juniper Networks QFX5210-64C-S switch. You can copy the sonic-broadcom.bin to an USB memory device and insert it to the USB port of the QFX5210-64C-S switch. You can also use the 'scp' command to copy the sonic-broadcom.bin image to the QFX5210-64C-S switch over the network. +You need to copy the SONiC image 'sonic-broadcom.bin' to the switch. You can copy the sonic-broadcom.bin to an USB memory device and insert it to the USB port of the switch. You can also use the 'scp' command to copy the sonic-broadcom.bin image to the switch over the network. Note: Unmount the USB memory device after copying the sonic-broadcom.bin. For example, umount /dev/sdX, where X is the name of the drive of the USB memory device. @@ -210,7 +215,7 @@ ONIE:/var/tmp # onie-nos-install /var/tmp/sonic-broadcom.bin ## Booting SONiC -The QFX5210-64C-S switch restarts automatically after the SONiC image has been successfully installed. +The switch restarts automatically after the SONiC image has been successfully installed. 1) Select SONiC from the GRUB boot manager. @@ -239,35 +244,44 @@ The QFX5210-64C-S switch restarts automatically after the SONiC image has been s 2. At the SONiC login prompt, enter the username as admin and password as YourPaSsWoRd. -You can now start configuring the Juniper Networks QFX5210-64C-S switch running SONiC as its operating system. +You can now start configuring the Juniper Networks switch running SONiC as its operating system. ## Upgrading SONiC image To upgrade the SONiC operating system to a latest version, you need to: - 1. Copy the latest image of the SONiC image to the QFX5210-64C-S switch. + 1. Copy the latest image of the SONiC image to the switch. 2. Run the following command from the directory where the latest SONiC image has been copied. ``` $ sudo ./sonic-braodcom.bin ``` +or + +``` +$ sudo sonic-installer ./sonic-broadcom.bin -y +``` + ## Uninstalling SONiC image -To unintall SONiC operating system from QFX5210-64C-S switch, you need to: +To unintall SONiC operating system from the switch, you need to: - 1. Reboot the QFX5210-64C-S switch. + 1. Reboot the switch. 2. Go to the ONIE GRUB menu and then select ONIE: Uninstall OS option to uninstall SONiC. -For more details on drivers and platform scripts see https://github.com/Azure/sonic-buildimage/blob/master/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README +For more details on drivers and platform scripts see the following links: + +1) QFX5210-64C-S: https://github.com/Azure/sonic-buildimage/blob/master/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README + +2) QFX5200-32C-S: https://github.com/Azure/sonic-buildimage/blob/master/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README ## Related Documentation for SONiC: The following links provide more information about SONiC: 1. SONiC documentation: https://github.com/azure/sonic/wiki. - 2. Learn about QFX5210-64C-S SONiC platform: https://github.com/Azure/sonic-buildimage/blob/master/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README ## Viewing the Device Revision of the FRU Model from IDEEPROM diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README index ec9ebe97f0ee..558410def831 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README @@ -1,5 +1,5 @@ -Copyright (c) 2019, Juniper Networks, Inc. +Copyright (c) 2020, Juniper Networks, Inc. All rights reserved. Front panel LEDs @@ -30,44 +30,93 @@ accepted. System FANs =========== -There are 4 fans and each of the fan has 2 fan modules. Overall there are -8 fans in the system. +There are 5 fans and each of the fan has 2 fan modules. Overall there are +10 fans in the system. These fans are controlled by ADT7470 driver. -Fan controls can be found in /sys/bus/i2c/devices/17-0068. All the fans -are controlled by one duty cycle value, ranges from 0 to 100 +Fan controls can be found in + /sys/bus/i2c/devices/7-002c + /sys/bus/i2c/devices/7-002e + /sys/bus/i2c/devices/7-002f -Fan duty cycle can be controlled through /sys/bus/i2c/devices/17-0068/pwm1 +For example, the complete path to driver control files will be + /sys/bus/i2c/devices/7-002c/hwmon/hwmon12 -Fan module presence is given by /sys/bus/i2c/devices/17-0068/fan[1-4]_present +Fan duty cycle can be controlled through 'pwm1', 'pwm2', 'pwm3', 'pwm4' sysfs files. + +For example, these are the absolute paths to the control files + + /sys/bus/i2c/devices/7-002c/hwmon/hwmon*/pwm1 7-002c controls 2 fan modules + /sys/bus/i2c/devices/7-002c/hwmon/hwmon*/pwm2 + /sys/bus/i2c/devices/7-002c/hwmon/hwmon*/pwm3 + /sys/bus/i2c/devices/7-002c/hwmon/hwmon*/pwm4 + + /sys/bus/i2c/devices/7-002e/hwmon/hwmon*/pwm1 7-002e controls 2 fan modules + /sys/bus/i2c/devices/7-002e/hwmon/hwmon*/pwm2 + /sys/bus/i2c/devices/7-002e/hwmon/hwmon*/pwm3 + /sys/bus/i2c/devices/7-002e/hwmon/hwmon*/pwm4 + + /sys/bus/i2c/devices/7-002f/hwmon/hwmon*/pwm1 7-002c controls only 1 fan module + /sys/bus/i2c/devices/7-002f/hwmon/hwmon*/pwm2 + +For convenience, it will be represented as +/sys/bus/i2c/devices/7-002[c/e/f]/hwmon/hwmon*/pwm[1-4] + +Fan speed is given by +/sys/bus/i2c/devices/7-002[c/e/f]/hwmon/hwmon*/fan[1-4]_input + +Fan module presence is given by +/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan[0-4]_present file. A value of '1' indicate that fan is present & a value of '0' otherwise. -Fan rotation direction is given by /sys/bus/i2c/devices/17-0068/fan[1-4]_direction. -A value of '0' indicate the direction is AFO (Front to back airflow) or Airflow -out. A value of '1' indicate that direction is AFI (Back to front airflow) or +Fan rotation direction is given by +/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan[0-4]_type +A value of '1' indicate the direction is AFO (Front to back airflow) or Airflow +out. A value of '0' indicate that direction is AFI (Back to front airflow) or Airflow in. -Fan speed is given by fan[1-4]_input Temperature sensors =================== -There are 6 temperature sensors. The readings are available in -/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input +There are 10 temperature sensors. Kernel driver tmp401 is used for +reading temeperature sensors. + +The readings are available in + +/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/5-0049/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/5-004a/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/5-004b/hwmon/hwmon*/temp1_input + +/sys/bus/i2c/devices/6-0048/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/6-0049/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/6-004a/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/6-004b/hwmon/hwmon*/temp1_input + +/sys/bus/i2c/devices/7-0048/hwmon/hwmon*/temp1_input +/sys/bus/i2c/devices/7-0049/hwmon/hwmon*/temp1_input System PSUs =========== -There are two independent PSUs. These are controlled by a dedicated CPLD. -The status registers are mapped under /sys/bus/i2c/devices/9-0050 and -/sys/bus/i2c/devices/10-0053. +There are two independent PSUs. These are controlled by TMC fpga. + +PSU presence is given by jnx-tmc-psu dirver and is available at +/sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/psu-tmc.15/psu*_present +A value of '1' indicate PSU is present and a value of '0' otherwise. + +PSU monitoring data is provided by jnx-psu-monitor driver and is available at +/sys/bus/i2c/devices/3-0058 +/sys/bus/i2c/devices/4-0058 SFPs ==== -There are 64 QSFP+ modules supported in qfx5210 platform. EEPORMs will be -mapped under /sys/bus/i2c/devices/[25-88]-0050/ sysfs directory. +There are 32 QSFP+ modules supported in qfx5200 platform. EEPORMs will be +mapped under /sys/bus/i2c/devices/[14-45]-0050/ sysfs directory. -FEC should be turned on for 100G SR optics and should be turned off for -100G LR optics. If the optic is changed, please update the entry and -reload the configuration. If the FEC mode is not set as per the optic -type the port may not link up or work properly. +FEC should be turned on for 100G SR4 & PSM4 optics and should +be turned off for 100G LR4 optics. If the FEC mode is not set +as per the optic type the port may not link up or work properly. +In some cases while interoperating between other NOSs & traffic +generators, FEC need to be enabled even for 100G DAC cables. As an example, see this configuration for FEC for 100G SR4 optics in /etc/sonic/config_db.json @@ -85,33 +134,19 @@ As an example, see this configuration for FEC for 100G SR4 optics in Sensor details ============== LM75 supported sensor modules will be available under 'sensors' command. -If you want to get all the sensor data including the SFPs & LEDs, you can -invoke 'sudo juniper_qfx5210_util.py show' -Platform poweroff +Platform reboot ================= -Linux poweroff commands such as 'poweroff', 'shutdown', 'halt', etc. will not -power off qfx5210 platform as there are custom CPLDs control the power off -sequences. So acpi poweroff hooks are added for powering off the qfx5210. The -following messages are displayed in the console towards end of poweroff -sequence: - - [ 52.500807] System halt/power_off - [ 52.866331] reboot: Power down - [ 52.903257] pm_power_off: qfx5210_cpld_power_off - -Once the above messages are seen, you can safely remove the power to the system. - -Similarly platform reboot sequences are in place for system reboot. The following +Platform reboot sequences are in place for system reboot. The following messages are displayed in the console when the system is rebooted: - [ 6053.163363] System restart: qfx5210_cpld_soft_reset + [ 6053.163363] System restart: qfx5200_cpu_reset Platform monitoring daemon ========================== -“juniper_qfx5210_monitor.py” is the platform monitoring script. -It implements the qfx5210 EM policy. This script will run as system service +“juniper_qfx5200_monitor.py” is the platform monitoring script. +It implements the qfx5200 EM policy. This script will run as system service and monitor the temperature sensors in every 20 seconds. Based on the EM policy thresholds, it controls the fan rpm, manage alarm leds, and -shutdown the box. +shutdown the box in case of any over heating. From c0bbb7b63dd4ab4622bc1ee9abf4024801456cec Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Fri, 2 Oct 2020 09:09:38 -0700 Subject: [PATCH 53/78] Fix python expception of missing subprocess (#5503) Signed-off-by: Abhishek Dosi --- src/sonic-py-common/sonic_py_common/multi_asic.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index 0b2b1d9da9b8..cb80635dbc0a 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -1,5 +1,6 @@ import glob import os +import subprocess from natsort import natsorted from swsssdk import ConfigDBConnector From db6fa1d2938a1bdb1e66a9ba96b22b5111055424 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 2 Oct 2020 09:16:05 -0700 Subject: [PATCH 54/78] [led]: Skip ledinit if there is no led_proc_init.soc file for broadcom platform (#5483) Some platforms don't leverage the brcm led coprocessor. However ledinit will try to load a non existing file and exit with an error code. This change is a cosmetic fix mostly. - How to verify it Boot a platform without the configuration and verify in the syslog that the exit status of ledinit is 0 Boot a platform with the configuration and verify in the syslog that the exit status of ledinit is 0 and the leds are working. Verified by adding a dumb led_proc_init.soc on an Arista platform which usually doesn't use it. --- platform/broadcom/docker-syncd-brcm/start_led.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/platform/broadcom/docker-syncd-brcm/start_led.sh b/platform/broadcom/docker-syncd-brcm/start_led.sh index 01d25cded8ea..964aa23eb04f 100755 --- a/platform/broadcom/docker-syncd-brcm/start_led.sh +++ b/platform/broadcom/docker-syncd-brcm/start_led.sh @@ -2,6 +2,12 @@ PLATFORM_DIR=/usr/share/sonic/platform SYNCD_SOCKET_FILE=/var/run/sswsyncd/sswsyncd.socket +LED_PROC_INIT_SOC=${PLATFORM_DIR}/led_proc_init.soc + +if [ ! -f "$LED_PROC_INIT_SOC" ]; then + echo "No soc led configuration found under $LED_SOC_INIT_SOC" + exit 0 +fi # Function: wait until syncd has created the socket for bcmcmd to connect to wait_syncd() { @@ -30,8 +36,8 @@ wait_syncd() { } # If this platform has an initialization file for the Broadcom LED microprocessor, load it -if [[ -r ${PLATFORM_DIR}/led_proc_init.soc && ! -f /var/warmboot/warm-starting ]]; then +if [[ -r "$LED_PROC_INIT_SOC" && ! -f /var/warmboot/warm-starting ]]; then wait_syncd fi -/usr/bin/bcmcmd -t 60 "rcload /usr/share/sonic/platform/led_proc_init.soc" +/usr/bin/bcmcmd -t 60 "rcload $LED_PROC_INIT_SOC" From e15e6a8313c99b29bc2fdb5e62f8808c5c93440f Mon Sep 17 00:00:00 2001 From: anish-n <44376847+anish-n@users.noreply.github.com> Date: Fri, 2 Oct 2020 09:25:29 -0700 Subject: [PATCH 55/78] [config-reload]: Add logic to clean up FG_ROUTE state db table during reload (#5518) Cleanup FG_ROUTE state db table during reload --- files/scripts/swss.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 0ef605fd83c8..129e5d148dc8 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -147,7 +147,7 @@ start() { $SONIC_DB_CLI ASIC_DB FLUSHDB $SONIC_DB_CLI COUNTERS_DB FLUSHDB $SONIC_DB_CLI FLEX_COUNTER_DB FLUSHDB - clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" + clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*', 'FG_ROUTE_TABLE*'" fi # start service docker From ffae82f8be6b8024784cd868882e9b1362522092 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 2 Oct 2020 10:06:04 -0700 Subject: [PATCH 56/78] [bgp] Add 'allow list' manager feature (#5513) implements a new feature: "BGP Allow list." This feature allows us to control which IP prefixes are going to be advertised via ebgp from the routes received from EBGP neighbors. --- .../bgpd/templates/general/peer-group.conf.j2 | 2 +- .../bgpd/templates/general/policies.conf.j2 | 27 + files/image_config/constants/constants.yml | 12 + rules/sonic_bgpcfgd.mk | 2 +- src/sonic-bgpcfgd/.gitignore | 1 + src/sonic-bgpcfgd/app/allow_list.py | 632 ++++++++++++++++++ src/sonic-bgpcfgd/app/config.py | 20 +- src/sonic-bgpcfgd/app/directory.py | 159 +++++ src/sonic-bgpcfgd/app/manager.py | 71 ++ src/sonic-bgpcfgd/app/vars.py | 2 +- src/sonic-bgpcfgd/bgpcfgd | 7 +- src/sonic-bgpcfgd/pytest.ini | 2 + src/sonic-bgpcfgd/setup.py | 3 +- .../data/general/policies.conf/param_all.json | 13 +- .../general/policies.conf/param_base.json | 11 +- .../general/policies.conf/param_deny.json | 17 + .../general/policies.conf/result_all.conf | 14 + .../general/policies.conf/result_deny.conf | 39 ++ src/sonic-bgpcfgd/tests/test_allow_list.py | 482 +++++++++++++ .../tests/test_ipv6_nexthop_global.py | 29 +- src/sonic-bgpcfgd/tests/util.py | 4 +- 21 files changed, 1527 insertions(+), 22 deletions(-) create mode 100644 src/sonic-bgpcfgd/app/allow_list.py create mode 100644 src/sonic-bgpcfgd/app/directory.py create mode 100644 src/sonic-bgpcfgd/app/manager.py create mode 100644 src/sonic-bgpcfgd/pytest.ini create mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json create mode 100644 src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf create mode 100644 src/sonic-bgpcfgd/tests/test_allow_list.py 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 index b0acd1b2a460..5790d47a5a8a 100644 --- 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 @@ -24,7 +24,7 @@ {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor PEER_V6 allowas-in 1 neighbor PEER_V6_INT allowas-in 1 - {% endif %} +{% endif %} {% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} neighbor PEER_V6_INT route-reflector-client {% endif %} 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 index c545cf272892..4c27db4a466a 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -3,6 +3,33 @@ ! ! ! +{% if constants.bgp.allow_list is defined and constants.bgp.allow_list.enabled is defined and constants.bgp.allow_list.enabled %} +{% if constants.bgp.allow_list.default_action is defined and constants.bgp.allow_list.default_action.strip() == 'deny' %} +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community no-export additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community no-export additive +{% else %} +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community {{ constants.bgp.allow_list.drop_community }} additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community {{ constants.bgp.allow_list.drop_community }} additive +{% endif %} +! +route-map FROM_BGP_PEER_V4 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! +{% endif %} +! +! +! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index 3e1b76be0157..074956ff8396 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -18,6 +18,18 @@ constants: enabled: true ipv4: 64 ipv6: 64 + allow_list: + enabled: true + default_action: "permit" # or "deny" + drop_community: 5060:12345 # value of the community to identify a prefix to drop. Make sense only with allow_list_default_action equal to 'permit' + default_pl_rules: + v4: + - "deny 0.0.0.0/0 le 17" + - "permit 127.0.0.1/32" + v6: + - "deny 0::/0 le 59" + - "deny 0::/0 ge 65" + - "permit fe80::/64" peers: general: # peer_type db_table: "BGP_NEIGHBOR" diff --git a/rules/sonic_bgpcfgd.mk b/rules/sonic_bgpcfgd.mk index 32abbd5af948..17e2c7b3f780 100644 --- a/rules/sonic_bgpcfgd.mk +++ b/rules/sonic_bgpcfgd.mk @@ -6,6 +6,6 @@ $(SONIC_BGPCFGD)_SRC_PATH = $(SRC_PATH)/sonic-bgpcfgd # of sonic-config-engine and bgpcfgd explicitly calls sonic-cfggen # as part of its unit tests. # TODO: Refactor unit tests so that these dependencies are not needed -$(SONIC_BGPCFGD)_DEPENDS += $(SWSSSDK_PY2) $(SONIC_PY_COMMON_PY2) +$(SONIC_BGPCFGD)_DEPENDS += $(SONIC_PY_COMMON_PY2) $(SONIC_BGPCFGD)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_BGPCFGD) diff --git a/src/sonic-bgpcfgd/.gitignore b/src/sonic-bgpcfgd/.gitignore index bb1ba531d1d6..920a1b3ae499 100644 --- a/src/sonic-bgpcfgd/.gitignore +++ b/src/sonic-bgpcfgd/.gitignore @@ -6,3 +6,4 @@ app/*.pyc tests/*.pyc tests/__pycache__/ .idea +.coverage diff --git a/src/sonic-bgpcfgd/app/allow_list.py b/src/sonic-bgpcfgd/app/allow_list.py new file mode 100644 index 000000000000..2637d6999244 --- /dev/null +++ b/src/sonic-bgpcfgd/app/allow_list.py @@ -0,0 +1,632 @@ +""" +Implementation of "allow-list" feature +""" +import re + +from app.log import log_debug, log_info, log_err, log_warn +from app.template import TemplateFabric +from app.manager import Manager +from app.util import run_command + +class BGPAllowListMgr(Manager): + """ This class initialize "AllowList" settings """ + ALLOW_ADDRESS_PL_NAME_TMPL = "ALLOW_ADDRESS_%d_%s" # template for a name for the ALLOW_ADDRESS prefix-list ??? + EMPTY_COMMUNITY = "empty" + PL_NAME_TMPL = "PL_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s_V%s" + COMMUNITY_NAME_TMPL = "COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_%d_COMMUNITY_%s" + RM_NAME_TMPL = "ALLOW_LIST_DEPLOYMENT_ID_%d_V%s" + ROUTE_MAP_ENTRY_WITH_COMMUNITY_START = 10 + ROUTE_MAP_ENTRY_WITH_COMMUNITY_END = 29990 + ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START = 30000 + ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END = 65530 + + V4 = "v4" # constant for af enum: V4 + V6 = "v6" # constant for af enum: V6 + + 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(BGPAllowListMgr, self).__init__( + common_objs, + [], + db, + table, + ) + self.cfg_mgr = common_objs["cfg_mgr"] + self.constants = common_objs["constants"] + self.key_re = re.compile(r"^DEPLOYMENT_ID\|\d+\|\S+$|^DEPLOYMENT_ID\|\d+$") + self.enabled = self.__get_enabled() + self.__load_constant_lists() + + def set_handler(self, key, data): + """ + Manager method which runs on receiving 'SET' message + :param key: ket of the 'SET' message + :param data: data of the 'SET' message + :return: True if the message was executed, False - the message should be postponed. + """ + if not self.enabled: + log_warn("BGPAllowListMgr::Received 'SET' command, but this feature is disabled in constants") + return True + if not self.__set_handler_validate(key, data): + return True + key = key.replace("DEPLOYMENT_ID|", "") + deployment_id, community_value = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) + deployment_id = int(deployment_id) + prefixes_v4 = [] + prefixes_v6 = [] + if "prefixes_v4" in data: + prefixes_v4 = str(data['prefixes_v4']).split(",") + if "prefixes_v6" in data: + prefixes_v6 = str(data['prefixes_v6']).split(",") + self.__update_policy(deployment_id, community_value, prefixes_v4, prefixes_v6) + return True + + def __set_handler_validate(self, key, data): + """ + Validate parameters of a "Set" message + :param key: ket of the 'SET' message + :param data: data of the 'SET' message + :return: True if parameters are valid, False if parameters are invalid + """ + if data is None: + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message without data") + return False + if not self.key_re.match(key): + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid key: '%s'" % key) + return False + prefixes_v4 = [] + prefixes_v6 = [] + if "prefixes_v4" in data: + prefixes_v4 = str(data["prefixes_v4"]).split(",") + if not all(TemplateFabric.is_ipv4(prefix) for prefix in prefixes_v4): + arguments = "prefixes_v4", str(data["prefixes_v4"]) + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) + return False + if "prefixes_v6" in data: + prefixes_v6 = str(data["prefixes_v6"]).split(",") + if not all(TemplateFabric.is_ipv6(prefix) for prefix in prefixes_v6): + arguments = "prefixes_v6", str(data["prefixes_v6"]) + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'" % arguments) + return False + if not prefixes_v4 and not prefixes_v6: + log_err("BGPAllowListMgr::Received BGP ALLOWED 'SET' message with no prefixes specified: %s" % str(data)) + return False + return True + + def del_handler(self, key): + """ + Manager method which runs on "DEL" message + :param key: a key of "DEL" message + """ + if not self.enabled: + log_warn("BGPAllowListMgr::Received 'DEL' command, but this feature is disabled in constants") + return + if not self.__del_handler_validate(key): + return + key = key.replace('DEPLOYMENT_ID|', '') + deployment_id, community = key.split('|', 1) if '|' in key else (key, BGPAllowListMgr.EMPTY_COMMUNITY) + deployment_id = int(deployment_id) + self.__remove_policy(deployment_id, community) + + def __del_handler_validate(self, key): + """ + Validate "DEL" method parameters + :param key: a key of "DEL" message + :return: True if parameters are valid, False if parameters are invalid + """ + if not self.key_re.match(key): + log_err("BGPAllowListMgr::Received BGP ALLOWED 'DEL' message with invalid key: '$s'" % key) + return False + return True + + def __update_policy(self, deployment_id, community_value, prefixes_v4, prefixes_v6): + """ + Update "allow list" policy with parameters + :param deployment_id: deployment id which policy will be changed + :param community_value: community value to match for the updated policy + :param prefixes_v4: a list of v4 prefixes for the updated policy + :param prefixes_v6: a list of v6 prefixes for the updated policy + """ + # update all related entries with the information + info = deployment_id, community_value, str(prefixes_v4), str(prefixes_v6) + msg = "BGPAllowListMgr::Updating 'Allow list' policy." + msg += " deployment_id '%s'. community: '%s'" + msg += " prefix_v4 '%s'. prefix_v6: '%s'" + log_info(msg % info) + names = self.__generate_names(deployment_id, community_value) + self.cfg_mgr.update() + cmds = [] + cmds += self.__update_prefix_list(self.V4, names['pl_v4'], prefixes_v4) + cmds += self.__update_prefix_list(self.V6, names['pl_v6'], prefixes_v6) + cmds += self.__update_community(names['community'], community_value) + cmds += self.__update_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) + cmds += self.__update_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) + if cmds: + rc = self.cfg_mgr.push_list(cmds) + rc = rc and self.__restart_peers(deployment_id) + log_debug("BGPAllowListMgr::__update_policy. The peers were updated: rc=%s" % rc) + else: + log_debug("BGPAllowListMgr::__update_policy. Nothing to update") + log_info("BGPAllowListMgr::Done") + + def __remove_policy(self, deployment_id, community_value): + """ + Remove "allow list" policy for given deployment_id and community_value + :param deployment_id: deployment id which policy will be removed + :param community_value: community value to match for the removed policy + """ + # remove all related entries from the configuration + # put default rule to the route-map + info = deployment_id, community_value + msg = "BGPAllowListMgr::Removing 'Allow list' policy." + msg += " deployment_id '%s'. community: '%s'" + log_info(msg % info) + + names = self.__generate_names(deployment_id, community_value) + self.cfg_mgr.update() + cmds = [] + cmds += self.__remove_allow_route_map_entry(self.V4, names['pl_v4'], names['community'], names['rm_v4']) + cmds += self.__remove_allow_route_map_entry(self.V6, names['pl_v6'], names['community'], names['rm_v6']) + cmds += self.__remove_prefix_list(self.V4, names['pl_v4']) + cmds += self.__remove_prefix_list(self.V6, names['pl_v6']) + cmds += self.__remove_community(names['community']) + if cmds: + rc = self.cfg_mgr.push_list(cmds) + rc = rc and self.__restart_peers(deployment_id) + log_debug("BGPAllowListMgr::__remove_policy. 'Allow list' policy was removed. rc:%s" % rc) + else: + log_debug("BGPAllowListMgr::__remove_policy. Nothing to remove") + log_info('BGPAllowListMgr::Done') + + @staticmethod + def __generate_names(deployment_id, community_value): + """ + Generate prefix-list names for a given peer_ip and community value + :param deployment_id: deployment_id for which we're going to filter prefixes + :param community_value: community, which we want to use to filter prefixes + :return: a dictionary with names + """ + if community_value == BGPAllowListMgr.EMPTY_COMMUNITY: + community_name = BGPAllowListMgr.EMPTY_COMMUNITY + else: + community_name = BGPAllowListMgr.COMMUNITY_NAME_TMPL % (deployment_id, community_value) + names = { + "pl_v4": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '4'), + "pl_v6": BGPAllowListMgr.PL_NAME_TMPL % (deployment_id, community_value, '6'), + "rm_v4": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '4'), + "rm_v6": BGPAllowListMgr.RM_NAME_TMPL % (deployment_id, '6'), + "community": community_name, + } + arguments = deployment_id, community_value, str(names) + log_debug("BGPAllowListMgr::__generate_names. deployment_id: %d, community: %s. names: %s" % arguments) + return names + + def __update_prefix_list(self, af, pl_name, allow_list): + """ + Create or update a prefix-list with name pl_name. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :param pl_name: prefix-list name + :param allow_list: prefix-list entries + :return: True if updating was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + constant_list = self.__get_constant_list(af) + allow_list = self.__to_prefix_list(allow_list) + log_debug("BGPAllowListMgr::__update_prefix_list. af='%s' prefix-list name=%s" % (af, pl_name)) + exist, correct = self.__is_prefix_list_valid(af, pl_name, allow_list, constant_list) + if correct: + log_debug("BGPAllowListMgr::__update_prefix_list. the prefix-list '%s' exists and correct" % pl_name) + return [] + family = self.__af_to_family(af) + cmds = [] + seq_no = 10 + if exist: + cmds.append('no %s prefix-list %s' % (family, pl_name)) + for entry in constant_list + allow_list: + cmds.append('%s prefix-list %s seq %d %s' % (family, pl_name, seq_no, entry)) + seq_no += 10 + return cmds + + def __remove_prefix_list(self, af, pl_name): + """ + Remove prefix-list in the address-family af. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :param pl_name: list of prefix-list names + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + log_debug("BGPAllowListMgr::__remove_prefix_lists. af='%s' pl_names='%s'" % (af, pl_name)) + exist, _ = self.__is_prefix_list_valid(af, pl_name, [], []) + if not exist: + log_debug("BGPAllowListMgr::__remove_prefix_lists: prefix_list '%s' not found" % pl_name) + return [] + family = self.__af_to_family(af) + return ["no %s prefix-list %s" % (family, pl_name)] + + def __is_prefix_list_valid(self, af, pl_name, allow_list, constant_list): + """ + Check that a prefix list exists and it has valid entries + :param af: address family of the checked prefix-list + :param pl_name: prefix-list name + :param allow_list: a prefix-list which must be a part of the valid prefix list + :param constant_list: a constant list which must be on top of each "allow" prefix list on the device + :return: a tuple. The first element of the tuple has True if the prefix-list exists, False otherwise, + The second element of the tuple has True if the prefix-list contains correct entries, False if not + """ + assert af == self.V4 or af == self.V6 + family = self.__af_to_family(af) + match_string = '%s prefix-list %s seq ' % (family, pl_name) + conf = self.cfg_mgr.get_text() + if not any(line.strip().startswith(match_string) for line in conf): + return False, False # if the prefix list is not exists, it is not correct + constant_set = set(constant_list) + allow_set = set(allow_list) + for line in conf: + if line.startswith(match_string): + found = line[len(match_string):].strip().split(' ') + rule = " ".join(found[1:]) + if rule in constant_set: + constant_set.discard(rule) + elif rule in allow_set: + if constant_set: + return True, False # Not everything from constant set is presented + else: + allow_set.discard(rule) + return True, len(allow_set) == 0 # allow_set should be presented all + + def __update_community(self, community_name, community_value): + """ + Update community for a peer + :param community_name: name of the community to update + :param community_value: community value for the peer + :return: True if operation was successful, False otherwise + """ + log_debug("BGPAllowListMgr::__update_community. community_name='%s' community='%s'" % (community_name, community_value)) + if community_value == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community + log_debug("BGPAllowListMgr::__update_community. Empty community. exiting") + return [] + cmds = [] + exists, found_community_value = self.__is_community_presented(community_name) + if exists: + if community_value == found_community_value: + log_debug("BGPAllowListMgr::__update_community. community '%s' is already presented" % community_name) + return [] + else: + msg = "BGPAllowListMgr::__update_community. " + msg += "community '%s' is already presented, but community value should be updated" % community_name + log_debug(msg) + cmds.append("no bgp community-list standard %s" % community_name) + cmds.append('bgp community-list standard %s permit %s' % (community_name, community_value)) + return cmds + + def __remove_community(self, community_name): + """ + Remove community for a peer + :param community_name: community value for the peer + :return: True if operation was successful, False otherwise + """ + log_debug("BGPAllowListMgr::__remove_community. community='%s'" % community_name) + if community_name == self.EMPTY_COMMUNITY: # we don't need to do anything for EMPTY community + log_debug("BGPAllowListMgr::__remove_community. There is nothing to remove in empty community") + return [] + exists, _ = self.__is_community_presented(community_name) + if not exists: + log_debug("BGPAllowListMgr::__remove_community. Community is already removed.") + return [] + return ['no bgp community-list standard %s' % community_name] + + def __is_community_presented(self, community_name): + """ + Return True if community for the peer_ip exists + :param community_name: community value for the peer + :return: A tuple. First element: True if operation was successful, False otherwise + Second element: community value if the first element is True no value otherwise + """ + log_debug("BGPAllowListMgr::__is_community_presented. community='%s'" % community_name) + match_string = 'bgp community-list standard %s permit ' % community_name + conf = self.cfg_mgr.get_text() + found = [line.strip() for line in conf if line.strip().startswith(match_string)] + if not found: + return False, None + community_value = found[0].replace(match_string, '') + return True, community_value + + def __update_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): + """ + Add or update a "Allow address" route-map entry with the parameters + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + info = af, route_map_name, allow_address_pl_name, community_name + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) + entries = self.__parse_allow_route_map_entries(af, route_map_name) + found, _ = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) + if found: + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. route-map='%s' is already found" % route_map_name) + return [] + seq_number = self.__find_next_seq_number(entries.keys(), community_name != self.EMPTY_COMMUNITY, route_map_name) + info = af, seq_number, allow_address_pl_name, community_name + out = "af='%s' seqno='%d' Allow pl='%s' cl='%s'" % info + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. %s" % out) + ip_version = "" if af == self.V4 else "v6" + cmds = [ + 'route-map %s permit %d' % (route_map_name, seq_number), + ' match ip%s address prefix-list %s' % (ip_version, allow_address_pl_name) + ] + if not community_name.endswith(self.EMPTY_COMMUNITY): + cmds.append(" match community %s" % community_name) + return cmds + + def __remove_allow_route_map_entry(self, af, allow_address_pl_name, community_name, route_map_name): + """ + Add or update a "Allow address" route-map entry with the parameters + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: True if operation was successful, False otherwise + """ + assert af == self.V4 or af == self.V6 + info = af, route_map_name, allow_address_pl_name, community_name + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. af='%s' Allow rm='%s' pl='%s' cl='%s'" % info) + entries = self.__parse_allow_route_map_entries(af, route_map_name) + found, seq_number = self.__find_route_map_entry(entries, allow_address_pl_name, community_name) + if not found: + log_debug("BGPAllowListMgr::__update_allow_route_map_entry. Not found route-map '%s' entry" % allow_address_pl_name) + return [] + return ['no route-map %s permit %d' % (route_map_name, seq_number)] + + @staticmethod + def __find_route_map_entry(entries, allow_address_pl_name, community_name): + """ + Find route-map entry with given allow_address prefix list name and community name in the parsed route-map. + :param entries: entries of parsed route-map + :param allow_address_pl_name: name of the "allow address" prefix-list + :param community_name: name of the "allow address" community name + :return: a tuple. The first element of the tuple is True, if the route-map entry was found, False otherwise. + The second element of the tuple has a sequence number of the entry. + """ + for sequence_number, values in entries.items(): + if sequence_number == 65535: + continue + allow_list_presented = values['pl_allow_list'] == allow_address_pl_name + community_presented = values['community'] == community_name + if allow_list_presented and community_presented: + log_debug("BGPAllowListMgr::__find_route_map_entry. found route-map '%s' entry" % allow_address_pl_name) + return True, sequence_number + return False, None + + def __parse_allow_route_map_entries(self, af, route_map_name): + """ + Parse "Allow list" route-map entries. + :param af: "v4" to create ipv4 prefix-list, "v6" to create ipv6 prefix-list + :return: A tuple, First element: True if operation was successful, False otherwise + Second element: list of object with parsed route-map entries + """ + assert af == self.V4 or af == self.V6 + log_debug("BGPAllowListMgr::__parse_allow_route_map_entries. af='%s', rm='%s'" % (af, route_map_name)) + match_string = 'route-map %s permit ' % route_map_name + entries = {} + inside_route_map = False + route_map_seq_number = None + pl_allow_list_name = None + community_name = self.EMPTY_COMMUNITY + if af == self.V4: + match_pl_allow_list = 'match ip address prefix-list ' + else: # self.V6 + match_pl_allow_list = 'match ipv6 address prefix-list ' + match_community = 'match community ' + conf = self.cfg_mgr.get_text() + for line in conf + [""]: + if inside_route_map: + if line.strip().startswith(match_pl_allow_list): + pl_allow_list_name = line.strip()[len(match_pl_allow_list):] + continue + elif line.strip().startswith(match_community): + community_name = line.strip()[len(match_community):] + continue + else: + if pl_allow_list_name is not None: + entries[route_map_seq_number] = { + 'pl_allow_list': pl_allow_list_name, + 'community': community_name, + } + else: + if route_map_seq_number != 65535: + log_warn("BGPAllowListMgr::Found incomplete route-map '%s' entry. seq_no=%d" % (route_map_name, route_map_seq_number)) + inside_route_map = False + pl_allow_list_name = None + community_name = self.EMPTY_COMMUNITY + route_map_seq_number = None + if line.startswith(match_string): + found = line[len(match_string):] + assert found.isdigit() + route_map_seq_number = int(found) + inside_route_map = True + return entries + + @staticmethod + def __find_next_seq_number(seq_numbers, has_community, route_map_name): + """ + Find a next available "Allow list" route-map entry number + :param seq_numbers: a list of already used sequence numbers + :param has_community: True, if the route-map entry has community + :return: next available route-map sequence number + """ + used_sequence_numbers = set(seq_numbers) + sequence_number = None + if has_community: # put entries without communities after 29999 + start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_START + end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITH_COMMUNITY_END + else: + start_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_START + end_seq = BGPAllowListMgr.ROUTE_MAP_ENTRY_WITHOUT_COMMUNITY_END + for i in range(start_seq, end_seq, 10): + if i not in used_sequence_numbers: + sequence_number = i + break + if sequence_number is None: + raise RuntimeError("No free sequence numbers for '%s'" % route_map_name) + info = sequence_number, "yes" if has_community else "no" + log_debug("BGPAllowListMgr::__find_next_seq_number '%d' has_community='%s'" % info) + return sequence_number + + def __extract_peer_group_names(self): + """ + Extract names of all peer-groups defined in the config + :return: list of peer-group names + """ + # Find all peer-groups entries + re_peer_group = re.compile(r'^\s*neighbor (\S+) peer-group$') + peer_groups = [] + for line in self.cfg_mgr.get_text(): + result = re_peer_group.match(line) + if result: + peer_groups.append(result.group(1)) + return peer_groups + + def __get_peer_group_to_route_map(self, peer_groups): + """ + Extract names of route-maps which is connected to peer-groups defines as peer_groups + :peer_groups: a list of peer-group names + :return: dictionary where key is a peer-group, value is a route-map name which is defined as route-map in + for the peer_group. + """ + pg_2_rm = {} + for pg in peer_groups: + re_peer_group_rm = re.compile(r'^\s*neighbor %s route-map (\S+) in$' % pg) + for line in self.cfg_mgr.get_text(): + result = re_peer_group_rm.match(line) + if result: + pg_2_rm[pg] = result.group(1) + break + return pg_2_rm + + def __get_route_map_calls(self, rms): + """ + Find mapping between route-maps and route-map call names, defined for the route-maps + :rms: a set with route-map names + :return: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map + """ + rm_2_call = {} + re_rm = re.compile(r'^route-map (\S+) permit \d+$') + re_call = re.compile(r'^\s*call (\S+)$') + inside_name = None + for line in self.cfg_mgr.get_text(): + if inside_name: + inside_result = re_call.match(line) + if inside_result: + rm_2_call[inside_name] = inside_result.group(1) + inside_name = None + continue + result = re_rm.match(line) + if not result: + continue + inside_name = None + if result.group(1) not in rms: + continue + inside_name = result.group(1) + return rm_2_call + + def __get_peer_group_to_restart(self, deployment_id, pg_2_rm, rm_2_call): + """ + Get peer_groups which are assigned to deployment_id + :deployment_id: deployment_id number + :pg_2_rm: a dictionary where key is a peer-group, value is a route-map name which is defined as route-map in + for the peer_group. + :rm_2_call: a dictionary: key - name of a route-map, value - name of a route-map call defined for the route-map + """ + ret = set() + target_allow_list_prefix = 'ALLOW_LIST_DEPLOYMENT_ID_%d_V' % deployment_id + for peer_group, route_map in pg_2_rm.items(): + if route_map in rm_2_call: + if rm_2_call[route_map].startswith(target_allow_list_prefix): + ret.add(peer_group) + return list(ret) + + def __find_peer_group_by_deployment_id(self, deployment_id): + """ + Deduce peer-group names which are connected to devices with requested deployment_id + :param deployment_id: deployment_id number + :return: a list of peer-groups which a used by devices with requested deployment_id number + """ + self.cfg_mgr.update() + peer_groups = self.__extract_peer_group_names() + pg_2_rm = self.__get_peer_group_to_route_map(peer_groups) + rm_2_call = self.__get_route_map_calls(set(pg_2_rm.values())) + ret = self.__get_peer_group_to_restart(deployment_id, pg_2_rm, rm_2_call) + return list(ret) + + def __restart_peers(self, deployment_id): + """ + Restart peer-groups with requested deployment_id + :param deployment_id: deployment_id number + """ + log_info("BGPAllowListMgr::Restart peers with deployment_id=%d" % deployment_id) + peer_groups = self.__find_peer_group_by_deployment_id(deployment_id) + rv = True + if peer_groups: + for peer_group in peer_groups: + no_error, _, _ = run_command(["vtysh", "-c", "clear bgp peer-group %s soft in" % peer_group]) + rv = no_error == 0 and rv + else: + no_error, _, _ = run_command(["vtysh", "-c", "clear bgp * soft in"]) + rv = no_error == 0 + return rv + + def __get_enabled(self): + """ + Load enable/disabled property from constants + :return: True if enabled, False otherwise + """ + return 'bgp' in self.constants \ + and 'allow_list' in self.constants["bgp"] \ + and "enabled" in self.constants["bgp"]["allow_list"] \ + and self.constants["bgp"]["allow_list"]["enabled"] + + def __load_constant_lists(self): + """ + Load default prefix-list entries from constants.yml file + """ + if 'bgp' in self.constants and 'allow_list' in self.constants["bgp"] \ + and "default_pl_rules" in self.constants["bgp"]["allow_list"]: + obj = self.constants["bgp"]["allow_list"]["default_pl_rules"] + if "v4" in obj: + self.constants_v4 = obj["v4"] + else: + self.constants_v4 = [] + if "v6" in obj: + self.constants_v6 = obj["v6"] + else: + self.constants_v6 = [] + + def __get_constant_list(self, af): + """ + Return loaded default prefix-list entries bases on address family + :param af: address family + :return: default prefix-list entries + """ + if af == self.V4: + return self.constants_v4 + else: + return self.constants_v6 + + @staticmethod + def __to_prefix_list(allow_list): + """ + Convert "allow list" prefix list, to a prefix-list rules + :param allow_list: "allow list" prefix list + :return: prefix-list rules + """ + return ["permit %s ge %d" % (prefix, int(prefix.split("/")[1])+1) for prefix in allow_list] + + def __af_to_family(self, af): + """ + Convert address family into prefix list family + :param af: address family + :return: prefix list ip family + """ + return 'ip' if af == self.V4 else 'ipv6' diff --git a/src/sonic-bgpcfgd/app/config.py b/src/sonic-bgpcfgd/app/config.py index 26639fe75e89..a0c1329f832e 100644 --- a/src/sonic-bgpcfgd/app/config.py +++ b/src/sonic-bgpcfgd/app/config.py @@ -10,19 +10,33 @@ class ConfigMgr(object): """ The class represents frr configuration """ def __init__(self): self.current_config = None + self.current_config_raw = None def reset(self): """ Reset stored config """ self.current_config = None + self.current_config_raw = None def update(self): """ Read current config from FRR """ self.current_config = None + self.current_config_raw = None ret_code, out, err = run_command(["vtysh", "-c", "show running-config"]) if ret_code != 0: + # FIXME: should we throw exception here? 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) + text = [] + for line in out.split('\n'): + if line.lstrip().startswith('!'): + continue + text.append(line) + text += [" "] # Add empty line to have something to work on, if there is no text + self.current_config_raw = text + self.current_config = self.to_canonical(out) # FIXME: use test as an input + + def push_list(self, cmdlist): + return self.push("\n".join(cmdlist)) def push(self, cmd): """ @@ -51,8 +65,12 @@ def write(self, cmd): 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 + self.current_config_raw = None return ret_code == 0 + def get_text(self): + return self.current_config_raw + @staticmethod def to_canonical(raw_config): """ diff --git a/src/sonic-bgpcfgd/app/directory.py b/src/sonic-bgpcfgd/app/directory.py new file mode 100644 index 000000000000..d27ec64256e3 --- /dev/null +++ b/src/sonic-bgpcfgd/app/directory.py @@ -0,0 +1,159 @@ +from collections import defaultdict + +from app.log import log_err + + +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) # 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 == '': + return True, self.data[slot] + d = self.data[slot] + for p in path.split("/"): + if p not in d: + return False, None + d = d[p] + return True, d + + 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, 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, 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(db, table, path): + for handler in self.notify[slot][path]: + handler() + + 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 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: + log_err("Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) + else: + log_err("Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) + + 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: + log_err("Directory: Can't remove slot '%s'. The slot doesn't exist" % 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 db, table, path in deps: + res = res and self.path_exist(db, table, path) + return res + + def subscribe(self, deps, handler): + """ + 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) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/manager.py b/src/sonic-bgpcfgd/app/manager.py new file mode 100644 index 000000000000..ba45029b5120 --- /dev/null +++ b/src/sonic-bgpcfgd/app/manager.py @@ -0,0 +1,71 @@ +from swsscommon import swsscommon + +from app.log import log_debug, log_err + + +class Manager(object): + """ 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 = [] + 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): # all required dependencies are set in the Directory? + res = self.set_handler(key, data) + 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: + 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 = [] + for key, data in self.set_queue: + res = self.set_handler(key, data) + if not res: + new_queue.append((key, data)) + self.set_queue = new_queue + + def set_handler(self, key, data): + """ Placeholder for 'SET' command """ + log_err("set_handler() wasn't implemented for %s" % self.__class__.__name__) + + def del_handler(self, key): + """ Placeholder for 'DEL' command """ + log_err("del_handler wasn't implemented for %s" % self.__class__.__name__) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/vars.py b/src/sonic-bgpcfgd/app/vars.py index 11377fc87f93..18bee5578e25 100644 --- a/src/sonic-bgpcfgd/app/vars.py +++ b/src/sonic-bgpcfgd/app/vars.py @@ -1 +1 @@ -g_debug = False +g_debug = True # FIXME: read from env variable, or from constants diff --git a/src/sonic-bgpcfgd/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd index 6f52ac1626e6..419fd41fb4be 100755 --- a/src/sonic-bgpcfgd/bgpcfgd +++ b/src/sonic-bgpcfgd/bgpcfgd @@ -15,10 +15,13 @@ import jinja2 import netaddr from swsscommon import swsscommon +from app.directory import Directory +from app.manager import Manager from app.vars import g_debug from app.log import log_debug, log_notice, log_info, log_warn, log_err, log_crit from app.template import TemplateFabric from app.config import ConfigMgr +from app.allow_list import BGPAllowListMgr from app.util import run_command g_run = True @@ -846,7 +849,7 @@ def wait_for_daemons(daemons, 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) + content = yaml.load(fp) # FIXME: , Loader=yaml.FullLoader) 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") @@ -878,6 +881,8 @@ def main(): BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", False), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), + # AllowList Managers + BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), ] runner = Runner() for mgr in managers: diff --git a/src/sonic-bgpcfgd/pytest.ini b/src/sonic-bgpcfgd/pytest.ini new file mode 100644 index 000000000000..639ceb636af9 --- /dev/null +++ b/src/sonic-bgpcfgd/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +addopts = --cov=app --cov-report term diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index 29d441e09a66..fc0839dff7fc 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -16,5 +16,6 @@ ] }, install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], - setup_requires=['pytest-runner', 'pytest'], + setup_requires=['pytest-runner'], + test_requires=['pytest', 'pytest-cov'], ) diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json index 148456fe960f..08f1eef63267 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all.json @@ -4,5 +4,14 @@ "sub_role": "BackEnd" } }, - "loopback0_ipv4": "10.10.10.10/32" -} \ No newline at end of file + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": true, + "default_action": "permit", + "drop_community": "12345:12345" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json index 53bf5572eff3..958c9b0fbd4b 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_base.json @@ -4,5 +4,12 @@ "sub_role": "NotBackEnd" } }, - "loopback0_ipv4": "10.10.10.10/32" -} \ No newline at end of file + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": false + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json new file mode 100644 index 000000000000..669810960c92 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_deny.json @@ -0,0 +1,17 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "sub_role": "BackEnd" + } + }, + "loopback0_ipv4": "10.10.10.10/32", + "constants": { + "bgp": { + "allow_list": { + "enabled": true, + "default_action": "deny", + "drop_community": "12345:12345" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf index 1e3288b9a7da..9e6c32b17ead 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all.conf @@ -1,6 +1,20 @@ ! ! template: bgpd/templates/general/policies.conf.j2 ! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community 12345:12345 additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community 12345:12345 additive +! +route-map FROM_BGP_PEER_V4 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf new file mode 100644 index 000000000000..6e0389fc1886 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_deny.conf @@ -0,0 +1,39 @@ +! +! template: bgpd/templates/general/policies.conf.j2 +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 + set community no-export additive +! +route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535 + set community no-export additive +! +route-map FROM_BGP_PEER_V4 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V4 + on-match next +! +route-map FROM_BGP_PEER_V6 permit 2 + call ALLOW_LIST_DEPLOYMENT_ID_0_V6 + on-match next +! +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 +! +route-map FROM_BGP_PEER_V4_INT permit 2 + set originator-id 10.10.10.10 +! +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 10.10.10.10 +! +! end of template: bgpd/templates/general/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/test_allow_list.py b/src/sonic-bgpcfgd/tests/test_allow_list.py new file mode 100644 index 000000000000..f3cf2f534aaa --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_allow_list.py @@ -0,0 +1,482 @@ +from app.directory import Directory +from app.template import TemplateFabric +import app +from mock import MagicMock, patch + +swsscommon_module_mock = MagicMock() + +global_constants = { + "bgp": { + "allow_list": { + "enabled": True, + "default_pl_rules": { + "v4": [ "deny 0.0.0.0/0 le 17" ], + "v6": [ + "deny 0::/0 le 59", + "deny 0::/0 ge 65" + ] + } + } + } +} + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def set_del_test(op, args, currect_config, expected_config): + from app.allow_list import BGPAllowListMgr + set_del_test.push_list_called = False + def push_list(args): + set_del_test.push_list_called = True + assert args == expected_config + return True + # + app.allow_list.run_command = lambda cmd: (0, "", "") + # + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.push_list = push_list + cfg_mgr.get_text.return_value = currect_config + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + if op == "SET": + mgr.set_handler(*args) + elif op == "DEL": + mgr.del_handler(*args) + else: + assert False, "Wrong operation" + if expected_config: + assert set_del_test.push_list_called, "cfg_mgr.push_list wasn't called" + else: + assert not set_del_test.push_list_called, "cfg_mgr.push_list was called" + +def test_set_handler_with_community(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64", + }), + [], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + ] + ) + +def test_set_handler_no_community(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }), + [], + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + ] + ) + +def test_del_handler_with_community(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + "" + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'no bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + ] + ) + +def test_del_handler_no_community(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5",), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + " " + ], + [ + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + 'no route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + ] + ) + +def test_set_handler_with_community_data_is_already_presented(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + "" + ], + [] + ) + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test_set_handler_no_community_data_is_already_presented(): + from app.allow_list import BGPAllowListMgr + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.get_text.return_value = [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + "" + ] + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + mgr.set_handler("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }) + assert not cfg_mgr.push_list.called, "cfg_mgr.push_list was called, but it shouldn't have been" + +def test_del_handler_with_community_no_data(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5|1010:2020",), + [""], + [] + ) + +def test_del_handler_no_community_no_data(): + set_del_test( + "DEL", + ("DEPLOYMENT_ID|5",), + [""], + [] + ) + +def test_set_handler_with_community_update_prefixes_add(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "10.20.30.0/24,30.50.0.0/16,80.90.0.0/16", + "prefixes_v6": "fc00:20::/64,fc00:30::/64,fc02::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'bgp community-list standard COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020 permit 1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 10', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 10', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020', + "" + ], + [ + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 20 permit 10.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 30 permit 30.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V4 seq 40 permit 80.90.0.0/16 ge 17', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 30 permit fc00:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 40 permit fc00:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_1010:2020_V6 seq 50 permit fc02::/64 ge 65', + ] + ) + +def test_set_handler_no_community_update_prefixes_add(): + set_del_test( + "SET", + ("DEPLOYMENT_ID|5", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16,80.90.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64,fc02::/64", + }), + [ + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + "" + ], + [ + 'no ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17', + 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 40 permit 80.90.0.0/16 ge 17', + 'no ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65', + 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 50 permit fc02::/64 ge 65', + ] + ) + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test___set_handler_validate(): + from app.allow_list import BGPAllowListMgr + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + data = { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + } + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", None) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID1|5|1010:2020", data) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|z|1010:2020", data) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", + "prefixes_v6": "20.20.30.0/24,40.50.0.0/16", + }) + assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { + "prefixes_v4": "fc01:20::/64,fc01:30::/64", + "prefixes_v6": "fc01:20::/64,fc01:30::/64", + }) + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test___find_peer_group_by_deployment_id(): + from app.allow_list import BGPAllowListMgr + cfg_mgr = MagicMock() + cfg_mgr.update.return_value = None + cfg_mgr.get_text.return_value = [ + 'router bgp 64601', + ' neighbor BGPSLBPassive peer-group', + ' neighbor BGPSLBPassive remote-as 65432', + ' neighbor BGPSLBPassive passive', + ' neighbor BGPSLBPassive ebgp-multihop 255', + ' neighbor BGPSLBPassive update-source 10.1.0.32', + ' neighbor PEER_V4 peer-group', + ' neighbor PEER_V4_INT peer-group', + ' neighbor PEER_V6 peer-group', + ' neighbor PEER_V6_INT peer-group', + ' neighbor 10.0.0.1 remote-as 64802', + ' neighbor 10.0.0.1 peer-group PEER_V4', + ' neighbor 10.0.0.1 description ARISTA01T1', + ' neighbor 10.0.0.1 timers 3 10', + ' neighbor fc00::2 remote-as 64802', + ' neighbor fc00::2 peer-group PEER_V6', + ' neighbor fc00::2 description ARISTA01T1', + ' neighbor fc00::2 timers 3 10', + ' address-family ipv4 unicast', + ' neighbor BGPSLBPassive activate', + ' neighbor BGPSLBPassive soft-reconfiguration inbound', + ' neighbor BGPSLBPassive route-map FROM_BGP_SPEAKER in', + ' neighbor BGPSLBPassive route-map TO_BGP_SPEAKER out', + ' neighbor PEER_V4 soft-reconfiguration inbound', + ' neighbor PEER_V4 allowas-in 1', + ' neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in', + ' neighbor PEER_V4 route-map TO_BGP_PEER_V4 out', + ' neighbor PEER_V4_INT soft-reconfiguration inbound', + ' neighbor PEER_V4_INT allowas-in 1', + ' neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in', + ' neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out', + ' neighbor 10.0.0.1 activate', + ' exit-address-family', + ' address-family ipv6 unicast', + ' neighbor BGPSLBPassive activate', + ' neighbor PEER_V6 soft-reconfiguration inbound', + ' neighbor PEER_V6 allowas-in 1', + ' neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in', + ' neighbor PEER_V6 route-map TO_BGP_PEER_V6 out', + ' neighbor PEER_V6_INT soft-reconfiguration inbound', + ' neighbor PEER_V6_INT allowas-in 1', + ' neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in', + ' neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out', + ' neighbor fc00::2 activate', + ' exit-address-family', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 10', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 30000', + ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V4', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535', + ' set community 5060:12345 additive', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 10', + ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 30000', + ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V6', + 'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535', + ' set community 5060:12345 additive', + 'route-map FROM_BGP_PEER_V4 permit 100', + 'route-map FROM_BGP_PEER_V4 permit 2', + ' call ALLOW_LIST_DEPLOYMENT_ID_0_V4', + ' on-match next', + 'route-map FROM_BGP_PEER_V6 permit 1', + ' set ipv6 next-hop prefer-global ', + 'route-map FROM_BGP_PEER_V6 permit 100', + 'route-map FROM_BGP_PEER_V6 permit 2', + ' call ALLOW_LIST_DEPLOYMENT_ID_0_V6', + ' on-match next', + 'route-map FROM_BGP_SPEAKER permit 10', + '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', + 'route-map TO_BGP_PEER_V4 permit 100', + 'route-map TO_BGP_PEER_V6 permit 100', + 'route-map TO_BGP_SPEAKER deny 1', + ] + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + values = mgr._BGPAllowListMgr__find_peer_group_by_deployment_id(0) + assert values == ['PEER_V4_INT', 'PEER_V6_INT', 'PEER_V6', 'PEER_V4'] + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test___restart_peers_found_deployment_id(): + from app.allow_list import BGPAllowListMgr + test___restart_peers_found_deployment_id.run_command_counter = 0 + def run_command(cmd): + output = [ + ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_1 soft in'], + ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_2 soft in'], + ] + desired_value = output[test___restart_peers_found_deployment_id.run_command_counter] + assert cmd == desired_value + test___restart_peers_found_deployment_id.run_command_counter += 1 + return 0, "", "" + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') + mocked.return_value = ["BGP_TEST_PEER_GROUP_1", "BGP_TEST_PEER_GROUP_2"] + mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked + app.allow_list.run_command = run_command + rc = mgr._BGPAllowListMgr__restart_peers(5) + assert rc + +@patch.dict("sys.modules", swsscommon=swsscommon_module_mock) +def test___restart_peers_not_found_deployment_id(): + from app.allow_list import BGPAllowListMgr + def run_command(cmd): + assert cmd == ['vtysh', '-c', 'clear bgp * soft in'] + return 0, "", "" + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(), + 'constants': global_constants, + } + mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") + mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') + mocked.return_value = [] + mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked + app.allow_list.run_command = run_command + rc = mgr._BGPAllowListMgr__restart_peers(5) + assert rc + +# FIXME: more testcases for coverage diff --git a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py index bc6d01cdb536..686b1ade65e1 100644 --- a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py +++ b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py @@ -77,21 +77,30 @@ def extract_rm_from_peer_group(path, peer_group_name): return list(rm_set) def check_routemap_in_file(filename, route_map_name): - route_map_re = re.compile(r'^route-map\s+%s\s+(\S+)' % route_map_name) + route_map_re = re.compile(r'^route-map\s+%s\s+permit\s+(\d+)' % route_map_name) set_re = re.compile(r'set ipv6 next-hop prefer-global') with open(filename) as fp: lines = [line.strip() for line in fp if not line.strip().startswith('!') and line.strip() != ''] - found_first_entry = False + found_entry = False + found_seq_no = None + route_map_entries = {} for line in lines: - err_msg = "route-map %s doesn't have mandatory 'set ipv6 next-hop prefer-global' entry as the first rule" % route_map_name - assert not (found_first_entry and line.startswith("route-map")), err_msg - if found_first_entry and set_re.match(line): - break # We're good + if found_entry: + route_map_entries[found_seq_no] = set_re.match(line) is not None + found_entry = False + found_seq_no = None if route_map_re.match(line): - err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name - assert route_map_re.match(line).group(1) == 'permit', err_msg - found_first_entry = True - return found_first_entry + found_seq_no = None + seq_n_txt = route_map_re.match(line).group(1) + assert seq_n_txt.isdigit(), "wrong sequence number for line '%s'" % line + found_seq_no = int(seq_n_txt) + assert found_seq_no not in route_map_entries, "Route-map has duplicate entries: %s - %d" % (route_map_name, found_seq_no) + found_entry = True + results = [route_map_entries[seq] for seq in sorted(route_map_entries.keys())] + if (len(results)): + err_msg = "route-map %s doesn't have mandatory permit entry for 'set ipv6 next-hop prefer-global" % route_map_name + assert results[0], err_msg + return len(results) > 0 def check_routemap(path, route_map_name): result_files = load_results(path, "policies.conf") diff --git a/src/sonic-bgpcfgd/tests/util.py b/src/sonic-bgpcfgd/tests/util.py index 0bc12b060aec..aa6c62a56b5f 100644 --- a/src/sonic-bgpcfgd/tests/util.py +++ b/src/sonic-bgpcfgd/tests/util.py @@ -5,7 +5,7 @@ def load_constants(): with open(CONSTANTS_PATH) as f: - data = yaml.load(f) + data = yaml.load(f) # FIXME" , Loader=yaml.FullLoader) result = {} assert "constants" in data, "'constants' key not found in constants.yml" assert "bgp" in data["constants"], "'bgp' key not found in constants.yml" @@ -13,4 +13,4 @@ def load_constants(): for name, value in data["constants"]["bgp"]["peers"].items(): assert "template_dir" in value, "'template_dir' key not found for peer '%s'" % name result[name] = value["template_dir"] - return result \ No newline at end of file + return result From 689487457e649448bc7d77173d679b8ce56a7f90 Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Sat, 3 Oct 2020 03:14:03 -0700 Subject: [PATCH 57/78] [Telemetry] remove unused mount from telemetry docker make file (#5536) --- rules/docker-telemetry.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index c42e15e24430..15f90c74c810 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -27,7 +27,6 @@ $(DOCKER_TELEMETRY)_CONTAINER_NAME = telemetry $(DOCKER_TELEMETRY)_RUN_OPT += --privileged -t $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TELEMETRY)_RUN_OPT += -v /var/run/dbus:/var/run/dbus:rw -$(DOCKER_TELEMETRY)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" $(DOCKER_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_TELEMETRY)_BASE_IMAGE_FILES += monit_telemetry:/etc/monit/conf.d From 32a517f583320e7c404d0f739470d025298dc015 Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Sat, 3 Oct 2020 09:47:51 -0700 Subject: [PATCH 58/78] [sonic-swss] Update sonic-swss submodule (#5533) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index be51ebc533cb..e4dfb3756e43 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit be51ebc533cbe92a885c584b4611ffc92d10ea36 +Subproject commit e4dfb3756e4332f90faed3ee0f82c9ad05ba38ce From 40623681bb5e4244f53f44af1568703e1c8e7077 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sun, 4 Oct 2020 01:17:13 +0800 Subject: [PATCH 59/78] [Mellanox] Fix truncated manufacture date returned from platform API (#5473) The manufacture date returned from platform API was truncated, time is not included. Revise the regular expression used for matching. --- platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py index 413388d20385..7673c9130f48 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py @@ -109,7 +109,7 @@ def _load_eeprom(self): for line in lines: try: - match = re.search('(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line) + match = re.search('(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+[\s]*[\S]*)', line) if match is not None: idx = match.group(1) value = match.group(3).rstrip('\0') From e92061cde9846ad36cc65d43f3efd3305d646673 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Sun, 4 Oct 2020 01:28:44 +0800 Subject: [PATCH 60/78] [Mellanox] Update dynamic minimum table for 4700, 3420 and 4600C (#5388) Update dynamic minimum fan speed table according to data provided by thermal team. --- .../mlnx-platform-api/sonic_platform/device_data.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 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 fd3c7ad50e23..7b86f7db9dfc 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py @@ -170,8 +170,8 @@ 'x86_64-mlnx_msn4700-r0': { 'thermal': { 'minimum_table': { - "unk_trust": {"-127:120":16}, - "unk_untrust": {"-127:120":16}, + "unk_trust": {"-127:35":14, "36:120":15}, + "unk_untrust": {"-127:35":14, "36:120":15}, } }, 'fans': { @@ -191,8 +191,8 @@ 'x86_64-mlnx_msn3420-r0': { 'thermal': { 'minimum_table': { - "unk_trust": {"-127:120":16}, - "unk_untrust": {"-127:120":16}, + "unk_trust": {"-127:120":12}, + "unk_untrust": {"-127:25":12, "26:35":13, "36:40":14, "41:120":16}, } }, 'fans': { @@ -212,8 +212,8 @@ 'x86_64-mlnx_msn4600c-r0': { 'thermal': { 'minimum_table': { - "unk_trust": {"-127:120":16}, - "unk_untrust": {"-127:120":16}, + "unk_trust": {"-127:40":12, "41:120":13}, + "unk_untrust": {"-127:5":12, "6:20":13, "21:30":14, "31:35":15, "36:40":16, "41:120":17}, } }, 'fans': { From dbea3bbfd78a438a8bf88f05442d60e010e77373 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Sat, 3 Oct 2020 23:46:21 +0300 Subject: [PATCH 61/78] BFN platform API 2.0 support (#4766) Added barefoot platform api 2.0 support Signed-off-by: Volodymyr Boyko --- .../debian/rules | 21 +- .../setup.py | 31 + .../sonic_platform/__init__.py | 2 + .../sonic_platform/chassis.py | 126 + .../sonic_platform/eeprom.py | 151 + .../sonic_platform/logging.conf | 17 + .../sonic_platform/platform.py | 21 + .../sonic_platform/platform_thrift_client.py | 37 + .../sonic_platform/pltfm_mgr_rpc/__init__.py | 1 + .../pltfm_mgr_rpc/pltfm_mgr_rpc.py | 2924 +++++++++++++++++ .../sonic_platform/pltfm_mgr_rpc/ttypes.py | 1060 ++++++ .../sonic_platform/psu.py | 58 + .../sonic_platform/sfp.py | 250 ++ .../debian/rules | 11 + .../setup.py | 1 + .../sonic_platform | 1 + .../sonic-platform-modules-bfn/debian/rules | 13 + .../sonic-platform-modules-bfn/setup.py | 1 + .../sonic-platform-modules-bfn/sonic_platform | 1 + 19 files changed, 4722 insertions(+), 5 deletions(-) create mode 100755 platform/barefoot/sonic-platform-modules-bfn-montara/setup.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/logging.conf create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/__init__.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py create mode 120000 platform/barefoot/sonic-platform-modules-bfn-newport/setup.py create mode 120000 platform/barefoot/sonic-platform-modules-bfn-newport/sonic_platform create mode 120000 platform/barefoot/sonic-platform-modules-bfn/setup.py create mode 120000 platform/barefoot/sonic-platform-modules-bfn/sonic_platform diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules index 7b430e9bd284..bf5a4c9a50fe 100755 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules @@ -1,25 +1,36 @@ #!/usr/bin/make -f +PLATFORM = x86_64-accton_wedge100bf_32x-r0 PACKAGE_NAME := sonic-platform-modules-bfn-montara SCRIPT_SRC := $(shell pwd)/scripts CONFIGS_SRC := $(shell pwd)/configs +BUILD_DIR := $(shell pwd)/build +WHEEL_BUILD_DIR := $(BUILD_DIR)/wheel PLUGINS_DIR := $(shell pwd)/plugins %: dh $@ +override_dh_auto_build: + set -e + python2.7 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + python3 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + set +e + override_dh_auto_install: dh_installdirs -p$(PACKAGE_NAME) usr/local/bin cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ - dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/x86_64-accton_wedge100bf_32x-r0/plugins - cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/x86_64-accton_wedge100bf_32x-r0/plugins/ + dh_installdirs -p$(PACKAGE_NAME) /usr/share/sonic/device/${PLATFORM}/ + cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/${PLATFORM}/ + dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/${PLATFORM}/plugins + cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/${PLATFORM}/plugins/ override_dh_usrlocal: -override_dh_pysupport: - override_dh_clean: + rm -fr $(WHEEL_BUILD_DIR) + rm -fr *.egg-info + rm -fr $(BUILD) dh_clean - diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/setup.py b/platform/barefoot/sonic-platform-modules-bfn-montara/setup.py new file mode 100755 index 000000000000..fc14c94ac4a0 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/setup.py @@ -0,0 +1,31 @@ +from setuptools import setup + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation', + license='Apache 2.0', + author='SONiC Team', + author_email='', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Barefoot', + maintainer_email='', + packages=[ + 'sonic_platform', + 'sonic_platform/pltfm_mgr_rpc' + ], + package_data = {'sonic_platform':['logging.conf']}, + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py new file mode 100644 index 000000000000..ef4108ee54e5 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ['chassis', 'eeprom', 'platform', 'psu', 'sfp'] +import platform diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py new file mode 100644 index 000000000000..36a921d539f5 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python + +try: + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.psu import Psu + from eeprom import Eeprom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Chassis(ChassisBase): + """ + Platform-specific Chassis class + """ + def __init__(self): + ChassisBase.__init__(self) + SFP_PORT_END = Sfp.port_end() + PORTS_IN_BLOCK = (SFP_PORT_END + 1) + MAX_PSU = Psu.get_num_psus() + + self._eeprom = Eeprom() + + for index in range(0, PORTS_IN_BLOCK): + sfp_node = Sfp(index) + self._sfp_list.append(sfp_node) + + for i in range(MAX_PSU): + psu = Psu(i) + self._psu_list.append(psu) + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_str() + + 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, 0 for Ethernet0, 1 for Ethernet4 and so on. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list)-1)) + return sfp + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.system_eeprom_info() + + def get_change_event(self, timeout=0): + ready, event_sfp = Sfp.get_transceiver_change_event(timeout) + return ready, { 'sfp': event_sfp } if ready else {} diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py new file mode 100644 index 000000000000..a548e9364715 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py @@ -0,0 +1,151 @@ +#!/usr/bin/python + + +try: + import time + import os + import sys + import errno + import datetime + import logging + import logging.config + import yaml + + sys.path.append(os.path.dirname(__file__)) + + from cStringIO import StringIO + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + + from .platform_thrift_client import ThriftClient +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +eeprom_default_dict = { + "prod_name" : ("Product Name", "0x21", 12), + "odm_pcba_part_num" : ("Part Number", "0x22", 13), + "prod_ser_num" : ("Serial Number", "0x23", 12), + "ext_mac_addr" : ("Extended MAC Address Base", "0x24", 12), + "sys_mfg_date" : ("System Manufacturing Date", "0x25", 4), + "prod_ver" : ("Product Version", "0x26", 1), + "ext_mac_addr_size" : ("Extende MAC Address Size", "0x2A", 2), + "sys_mfger" : ("Manufacturer", "0x2B", 8) +} + +eeprom_dict = { "version" : ("Version", None, 0), + "pcb_mfger" : ("PCB Manufacturer", "0x01", 8), + "prod_ser_num" : ("Serial Number", "0x23", 12), + "bfn_pcba_part_num" : ("Switch PCBA Part Number", "0x02", 12), + "odm_pcba_part_num" : ("Part Number", "0x22", 13), + "bfn_pcbb_part_num" : ("Switch PCBB Part Number", "0x04", 12), + "sys_asm_part_num" : ("System Assembly Part Number", "0x05", 12), + "prod_state" : ("Product Production State", "0x06", 1), + "location" : ("EEPROM Location of Fabric", "0x07", 8), + "ext_mac_addr_size" : ("Extende MAC Address Size", "0x08", 2), + "sys_mfg_date" : ("System Manufacturing Date", "0x25", 4), + "prod_name" : ("Product Name", "0x21", 12), + "prod_ver" : ("Product Version", "0x26", 1), + "prod_part_num" : ("Product Part Number", "0x09", 8), + "sys_mfger" : ("Manufacturer", "0x2B", 8), + "assembled_at" : ("Assembled at", "0x08", 8), + "prod_ast_tag" : ("Product Asset Tag", "0x09", 12), + "loc_mac_addr" : ("Local MAC address", "0x0A", 12), + "odm_pcba_ser_num" : ("ODM PBCA Serial Number", "0x0B", 12), + "ext_mac_addr" : ("Extended MAC Address Base", "0x0C", 12), + "prod_sub_ver" : ("Product Sub Version", "0x0D", 1) + } + +product_dict = { "Montara" : "Wedge100BF-32X-O-AC-F-BF", + "Lower MAV" : "Wedge100BF-65X-O-AC-F-BF", + "Upper MAV" : "Wedge100BF-65X-O-AC-F-BF" + } + +EEPROM_SYMLINK = "/var/run/platform/eeprom/syseeprom" +EEPROM_STATUS = "/var/run/platform/eeprom/status" + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + RETRIES = 35 + + def __init__(self): + + with open(os.path.dirname(__file__) + "/logging.conf", 'r') as f: + config_dict = yaml.load(f, yaml.SafeLoader) + logging.config.dictConfig(config_dict) + + if not os.path.exists(os.path.dirname(EEPROM_SYMLINK)): + try: + os.makedirs(os.path.dirname(EEPROM_SYMLINK)) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + open(EEPROM_SYMLINK, 'a').close() + f = open(EEPROM_STATUS, 'w') + f.write("initializing..") + f.close() + + self.eeprom_path = EEPROM_SYMLINK + super(Eeprom, self).__init__(self.eeprom_path, 0, EEPROM_STATUS, True) + + for attempt in range(self.RETRIES): + if self.eeprom_init(): + break + if attempt + 1 == self.RETRIES: + raise RuntimeError("eeprom.py: Initialization failed") + time.sleep(1) + + def eeprom_init(self): + try: + with ThriftClient() as client: + self.eeprom = client.pltfm_mgr.pltfm_mgr_sys_eeprom_get() + except Exception: + return False + + f = open(EEPROM_STATUS, 'w') + f.write("ok") + f.close() + + eeprom_params = "" + for attr, val in self.eeprom.__dict__.iteritems(): + if val is None: + continue + + elem = eeprom_default_dict.get(attr) + if elem is None: + continue + + if isinstance(val, basestring): + value = val.replace('\0', '') + else: + value = str(val) + + if attr == "sys_mfg_date": + value = datetime.datetime.strptime(value, '%m-%d-%y').strftime('%m/%d/%Y 00:00:00') + + product = product_dict.get(value) + if product is not None: + value = product + if len(eeprom_params) > 0: + eeprom_params += "," + eeprom_params += "{0:s}={1:s}".format(elem[1], value) + + orig_stdout = sys.stdout + sys.stdout = StringIO() + new_e = eeprom_tlvinfo.TlvInfoDecoder.set_eeprom(self, "", [eeprom_params]) + sys.stdout = orig_stdout + eeprom_base.EepromDecoder.write_eeprom(self, new_e) + + return True + + def serial_number_str(self): + return self.eeprom.prod_ser_num + + def system_eeprom_info(self): + return self.eeprom.__dict__ + + def get_base_mac(self): + return self.eeprom.ext_mac_addr + + def part_number_str(self): + return self.eeprom.prod_part_num diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/logging.conf b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/logging.conf new file mode 100644 index 000000000000..d7fd84773404 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/logging.conf @@ -0,0 +1,17 @@ +version: 1 +disable_existing_loggers: False + +formatters: + simple: + format: '%(asctime)s %(name)-30s %(levelname)-7s %(message)s' + +handlers: + file: + class: logging.handlers.RotatingFileHandler + formatter: simple + filename: /var/log/platform.log + +root: + level: ERROR + handlers: + - file diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform.py new file mode 100644 index 000000000000..ebc68a895362 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py new file mode 100644 index 000000000000..06afe8e962ae --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +try: + import os + import sys + import importlib + + sys.path.append(os.path.dirname(__file__)) + + from thrift.transport import TSocket + from thrift.transport import TTransport + from thrift.protocol import TBinaryProtocol + from thrift.protocol import TMultiplexedProtocol +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +THRIFT_SERVER = 'localhost' + +class ThriftClient(object): + def open(self): + self.transport = TSocket.TSocket(THRIFT_SERVER, 9090) + + self.transport = TTransport.TBufferedTransport(self.transport) + bprotocol = TBinaryProtocol.TBinaryProtocol(self.transport) + + pltfm_mgr_client_module = importlib.import_module(".".join(["pltfm_mgr_rpc", "pltfm_mgr_rpc"])) + pltfm_mgr_protocol = TMultiplexedProtocol.TMultiplexedProtocol(bprotocol, "pltfm_mgr_rpc") + self.pltfm_mgr = pltfm_mgr_client_module.Client(pltfm_mgr_protocol) + + self.transport.open() + return self + def close(self): + self.transport.close() + def __enter__(self): + return self.open() + def __exit__(self, exc_type, exc_value, tb): + self.close() diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/__init__.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/__init__.py new file mode 100644 index 000000000000..414c3d6389c5 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/__init__.py @@ -0,0 +1 @@ +__all__ = ['ttypes', 'pltfm_mgr_rpc'] diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py new file mode 100644 index 000000000000..b256b6285fc3 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py @@ -0,0 +1,2924 @@ +# +# Autogenerated by Thrift Compiler (0.10.0) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# +# options string: py +# + +from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException +from thrift.protocol.TProtocol import TProtocolException +import sys +import logging +from .ttypes import * +from thrift.Thrift import TProcessor +from thrift.transport import TTransport + + +class Iface(object): + def pltfm_mgr_dummy(self, device): + """ + Parameters: + - device + """ + pass + + def pltfm_mgr_sys_tmp_get(self): + pass + + def pltfm_mgr_sys_eeprom_get(self): + pass + + def pltfm_mgr_pwr_supply_present_get(self, ps_num): + """ + Parameters: + - ps_num + """ + pass + + def pltfm_mgr_pwr_supply_info_get(self, ps_num): + """ + Parameters: + - ps_num + """ + pass + + def pltfm_mgr_pwr_rail_info_get(self, ps_num): + """ + Parameters: + - ps_num + """ + pass + + def pltfm_mgr_fan_speed_set(self, fan_num, percent): + """ + Parameters: + - fan_num + - percent + """ + pass + + def pltfm_mgr_fan_info_get(self, fan_num): + """ + Parameters: + - fan_num + """ + pass + + def pltfm_mgr_qsfp_presence_get(self, port_num): + """ + Parameters: + - port_num + """ + pass + + def pltfm_mgr_qsfp_info_get(self, port_num): + """ + Parameters: + - port_num + """ + pass + + def pltfm_mgr_qsfp_get_max_port(self): + pass + + def pltfm_mgr_qsfp_reset(self, port_num, reset): + """ + Parameters: + - port_num + - reset + """ + pass + + def pltfm_mgr_qsfp_lpmode_get(self, port_num): + """ + Parameters: + - port_num + """ + pass + + def pltfm_mgr_qsfp_lpmode_set(self, port_num, lpmode): + """ + Parameters: + - port_num + - lpmode + """ + pass + + def pltfm_mgr_sensor_info_get(self, options): + """ + Parameters: + - options + """ + pass + + +class Client(Iface): + def __init__(self, iprot, oprot=None): + self._iprot = self._oprot = iprot + if oprot is not None: + self._oprot = oprot + self._seqid = 0 + + def pltfm_mgr_dummy(self, device): + """ + Parameters: + - device + """ + self.send_pltfm_mgr_dummy(device) + return self.recv_pltfm_mgr_dummy() + + def send_pltfm_mgr_dummy(self, device): + self._oprot.writeMessageBegin('pltfm_mgr_dummy', TMessageType.CALL, self._seqid) + args = pltfm_mgr_dummy_args() + args.device = device + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_dummy(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_dummy_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_dummy failed: unknown result") + + def pltfm_mgr_sys_tmp_get(self): + self.send_pltfm_mgr_sys_tmp_get() + return self.recv_pltfm_mgr_sys_tmp_get() + + def send_pltfm_mgr_sys_tmp_get(self): + self._oprot.writeMessageBegin('pltfm_mgr_sys_tmp_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_sys_tmp_get_args() + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_sys_tmp_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_sys_tmp_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sys_tmp_get failed: unknown result") + + def pltfm_mgr_sys_eeprom_get(self): + self.send_pltfm_mgr_sys_eeprom_get() + return self.recv_pltfm_mgr_sys_eeprom_get() + + def send_pltfm_mgr_sys_eeprom_get(self): + self._oprot.writeMessageBegin('pltfm_mgr_sys_eeprom_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_sys_eeprom_get_args() + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_sys_eeprom_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_sys_eeprom_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sys_eeprom_get failed: unknown result") + + def pltfm_mgr_pwr_supply_present_get(self, ps_num): + """ + Parameters: + - ps_num + """ + self.send_pltfm_mgr_pwr_supply_present_get(ps_num) + return self.recv_pltfm_mgr_pwr_supply_present_get() + + def send_pltfm_mgr_pwr_supply_present_get(self, ps_num): + self._oprot.writeMessageBegin('pltfm_mgr_pwr_supply_present_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_pwr_supply_present_get_args() + args.ps_num = ps_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_pwr_supply_present_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_pwr_supply_present_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_pwr_supply_present_get failed: unknown result") + + def pltfm_mgr_pwr_supply_info_get(self, ps_num): + """ + Parameters: + - ps_num + """ + self.send_pltfm_mgr_pwr_supply_info_get(ps_num) + return self.recv_pltfm_mgr_pwr_supply_info_get() + + def send_pltfm_mgr_pwr_supply_info_get(self, ps_num): + self._oprot.writeMessageBegin('pltfm_mgr_pwr_supply_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_pwr_supply_info_get_args() + args.ps_num = ps_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_pwr_supply_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_pwr_supply_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_pwr_supply_info_get failed: unknown result") + + def pltfm_mgr_pwr_rail_info_get(self, ps_num): + """ + Parameters: + - ps_num + """ + self.send_pltfm_mgr_pwr_rail_info_get(ps_num) + return self.recv_pltfm_mgr_pwr_rail_info_get() + + def send_pltfm_mgr_pwr_rail_info_get(self, ps_num): + self._oprot.writeMessageBegin('pltfm_mgr_pwr_rail_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_pwr_rail_info_get_args() + args.ps_num = ps_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_pwr_rail_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_pwr_rail_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_pwr_rail_info_get failed: unknown result") + + def pltfm_mgr_fan_speed_set(self, fan_num, percent): + """ + Parameters: + - fan_num + - percent + """ + self.send_pltfm_mgr_fan_speed_set(fan_num, percent) + return self.recv_pltfm_mgr_fan_speed_set() + + def send_pltfm_mgr_fan_speed_set(self, fan_num, percent): + self._oprot.writeMessageBegin('pltfm_mgr_fan_speed_set', TMessageType.CALL, self._seqid) + args = pltfm_mgr_fan_speed_set_args() + args.fan_num = fan_num + args.percent = percent + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_fan_speed_set(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_fan_speed_set_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_fan_speed_set failed: unknown result") + + def pltfm_mgr_fan_info_get(self, fan_num): + """ + Parameters: + - fan_num + """ + self.send_pltfm_mgr_fan_info_get(fan_num) + return self.recv_pltfm_mgr_fan_info_get() + + def send_pltfm_mgr_fan_info_get(self, fan_num): + self._oprot.writeMessageBegin('pltfm_mgr_fan_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_fan_info_get_args() + args.fan_num = fan_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_fan_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_fan_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_fan_info_get failed: unknown result") + + def pltfm_mgr_qsfp_presence_get(self, port_num): + """ + Parameters: + - port_num + """ + self.send_pltfm_mgr_qsfp_presence_get(port_num) + return self.recv_pltfm_mgr_qsfp_presence_get() + + def send_pltfm_mgr_qsfp_presence_get(self, port_num): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_presence_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_presence_get_args() + args.port_num = port_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_presence_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_presence_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_presence_get failed: unknown result") + + def pltfm_mgr_qsfp_info_get(self, port_num): + """ + Parameters: + - port_num + """ + self.send_pltfm_mgr_qsfp_info_get(port_num) + return self.recv_pltfm_mgr_qsfp_info_get() + + def send_pltfm_mgr_qsfp_info_get(self, port_num): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_info_get_args() + args.port_num = port_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_info_get failed: unknown result") + + def pltfm_mgr_qsfp_get_max_port(self): + self.send_pltfm_mgr_qsfp_get_max_port() + return self.recv_pltfm_mgr_qsfp_get_max_port() + + def send_pltfm_mgr_qsfp_get_max_port(self): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_get_max_port', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_get_max_port_args() + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_get_max_port(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_get_max_port_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_get_max_port failed: unknown result") + + def pltfm_mgr_qsfp_reset(self, port_num, reset): + """ + Parameters: + - port_num + - reset + """ + self.send_pltfm_mgr_qsfp_reset(port_num, reset) + return self.recv_pltfm_mgr_qsfp_reset() + + def send_pltfm_mgr_qsfp_reset(self, port_num, reset): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_reset', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_reset_args() + args.port_num = port_num + args.reset = reset + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_reset(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_reset_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_reset failed: unknown result") + + def pltfm_mgr_qsfp_lpmode_get(self, port_num): + """ + Parameters: + - port_num + """ + self.send_pltfm_mgr_qsfp_lpmode_get(port_num) + return self.recv_pltfm_mgr_qsfp_lpmode_get() + + def send_pltfm_mgr_qsfp_lpmode_get(self, port_num): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_lpmode_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_lpmode_get_args() + args.port_num = port_num + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_lpmode_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_lpmode_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_lpmode_get failed: unknown result") + + def pltfm_mgr_qsfp_lpmode_set(self, port_num, lpmode): + """ + Parameters: + - port_num + - lpmode + """ + self.send_pltfm_mgr_qsfp_lpmode_set(port_num, lpmode) + return self.recv_pltfm_mgr_qsfp_lpmode_set() + + def send_pltfm_mgr_qsfp_lpmode_set(self, port_num, lpmode): + self._oprot.writeMessageBegin('pltfm_mgr_qsfp_lpmode_set', TMessageType.CALL, self._seqid) + args = pltfm_mgr_qsfp_lpmode_set_args() + args.port_num = port_num + args.lpmode = lpmode + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_qsfp_lpmode_set(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_qsfp_lpmode_set_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_qsfp_lpmode_set failed: unknown result") + + def pltfm_mgr_sensor_info_get(self, options): + """ + Parameters: + - options + """ + self.send_pltfm_mgr_sensor_info_get(options) + return self.recv_pltfm_mgr_sensor_info_get() + + def send_pltfm_mgr_sensor_info_get(self, options): + self._oprot.writeMessageBegin('pltfm_mgr_sensor_info_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_sensor_info_get_args() + args.options = options + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_sensor_info_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_sensor_info_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sensor_info_get failed: unknown result") + + +class Processor(Iface, TProcessor): + def __init__(self, handler): + self._handler = handler + self._processMap = {} + self._processMap["pltfm_mgr_dummy"] = Processor.process_pltfm_mgr_dummy + self._processMap["pltfm_mgr_sys_tmp_get"] = Processor.process_pltfm_mgr_sys_tmp_get + self._processMap["pltfm_mgr_sys_eeprom_get"] = Processor.process_pltfm_mgr_sys_eeprom_get + self._processMap["pltfm_mgr_pwr_supply_present_get"] = Processor.process_pltfm_mgr_pwr_supply_present_get + self._processMap["pltfm_mgr_pwr_supply_info_get"] = Processor.process_pltfm_mgr_pwr_supply_info_get + self._processMap["pltfm_mgr_pwr_rail_info_get"] = Processor.process_pltfm_mgr_pwr_rail_info_get + self._processMap["pltfm_mgr_fan_speed_set"] = Processor.process_pltfm_mgr_fan_speed_set + self._processMap["pltfm_mgr_fan_info_get"] = Processor.process_pltfm_mgr_fan_info_get + self._processMap["pltfm_mgr_qsfp_presence_get"] = Processor.process_pltfm_mgr_qsfp_presence_get + self._processMap["pltfm_mgr_qsfp_info_get"] = Processor.process_pltfm_mgr_qsfp_info_get + self._processMap["pltfm_mgr_qsfp_get_max_port"] = Processor.process_pltfm_mgr_qsfp_get_max_port + self._processMap["pltfm_mgr_qsfp_reset"] = Processor.process_pltfm_mgr_qsfp_reset + self._processMap["pltfm_mgr_qsfp_lpmode_get"] = Processor.process_pltfm_mgr_qsfp_lpmode_get + self._processMap["pltfm_mgr_qsfp_lpmode_set"] = Processor.process_pltfm_mgr_qsfp_lpmode_set + self._processMap["pltfm_mgr_sensor_info_get"] = Processor.process_pltfm_mgr_sensor_info_get + + def process(self, iprot, oprot): + (name, type, seqid) = iprot.readMessageBegin() + if name not in self._processMap: + iprot.skip(TType.STRUCT) + iprot.readMessageEnd() + x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name)) + oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid) + x.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + return + else: + self._processMap[name](self, seqid, iprot, oprot) + return True + + def process_pltfm_mgr_dummy(self, seqid, iprot, oprot): + args = pltfm_mgr_dummy_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_dummy_result() + try: + result.success = self._handler.pltfm_mgr_dummy(args.device) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_dummy", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_sys_tmp_get(self, seqid, iprot, oprot): + args = pltfm_mgr_sys_tmp_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_sys_tmp_get_result() + try: + result.success = self._handler.pltfm_mgr_sys_tmp_get() + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_sys_tmp_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_sys_eeprom_get(self, seqid, iprot, oprot): + args = pltfm_mgr_sys_eeprom_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_sys_eeprom_get_result() + try: + result.success = self._handler.pltfm_mgr_sys_eeprom_get() + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_sys_eeprom_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_pwr_supply_present_get(self, seqid, iprot, oprot): + args = pltfm_mgr_pwr_supply_present_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_pwr_supply_present_get_result() + try: + result.success = self._handler.pltfm_mgr_pwr_supply_present_get(args.ps_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_pwr_supply_present_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_pwr_supply_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_pwr_supply_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_pwr_supply_info_get_result() + try: + result.success = self._handler.pltfm_mgr_pwr_supply_info_get(args.ps_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_pwr_supply_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_pwr_rail_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_pwr_rail_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_pwr_rail_info_get_result() + try: + result.success = self._handler.pltfm_mgr_pwr_rail_info_get(args.ps_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_pwr_rail_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_fan_speed_set(self, seqid, iprot, oprot): + args = pltfm_mgr_fan_speed_set_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_fan_speed_set_result() + try: + result.success = self._handler.pltfm_mgr_fan_speed_set(args.fan_num, args.percent) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_fan_speed_set", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_fan_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_fan_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_fan_info_get_result() + try: + result.success = self._handler.pltfm_mgr_fan_info_get(args.fan_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_fan_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_presence_get(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_presence_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_presence_get_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_presence_get(args.port_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_presence_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_info_get_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_info_get(args.port_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_get_max_port(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_get_max_port_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_get_max_port_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_get_max_port() + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_get_max_port", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_reset(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_reset_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_reset_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_reset(args.port_num, args.reset) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_reset", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_lpmode_get(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_lpmode_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_lpmode_get_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_lpmode_get(args.port_num) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_lpmode_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_qsfp_lpmode_set(self, seqid, iprot, oprot): + args = pltfm_mgr_qsfp_lpmode_set_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_qsfp_lpmode_set_result() + try: + result.success = self._handler.pltfm_mgr_qsfp_lpmode_set(args.port_num, args.lpmode) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_qsfp_lpmode_set", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_pltfm_mgr_sensor_info_get(self, seqid, iprot, oprot): + args = pltfm_mgr_sensor_info_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_sensor_info_get_result() + try: + result.success = self._handler.pltfm_mgr_sensor_info_get(args.options) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_sensor_info_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + +# HELPER FUNCTIONS AND STRUCTURES + + +class pltfm_mgr_dummy_args(object): + """ + Attributes: + - device + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'device', None, None, ), # 1 + ) + + def __init__(self, device=None,): + self.device = device + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.device = iprot.readByte() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_dummy_args') + if self.device is not None: + oprot.writeFieldBegin('device', TType.BYTE, 1) + oprot.writeByte(self.device) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_dummy_result(object): + """ + Attributes: + - success + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + ) + + def __init__(self, success=None,): + self.success = success + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_dummy_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sys_tmp_get_args(object): + + thrift_spec = ( + ) + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_tmp_get_args') + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sys_tmp_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_sys_tmp_t, pltfm_mgr_sys_tmp_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_sys_tmp_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_tmp_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sys_eeprom_get_args(object): + + thrift_spec = ( + ) + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_eeprom_get_args') + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sys_eeprom_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_eeprom_t, pltfm_mgr_eeprom_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_eeprom_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_eeprom_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_present_get_args(object): + """ + Attributes: + - ps_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I16, 'ps_num', None, None, ), # 1 + ) + + def __init__(self, ps_num=None,): + self.ps_num = ps_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I16: + self.ps_num = iprot.readI16() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_present_get_args') + if self.ps_num is not None: + oprot.writeFieldBegin('ps_num', TType.I16, 1) + oprot.writeI16(self.ps_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_present_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.BOOL, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.BOOL: + self.success = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_present_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.BOOL, 0) + oprot.writeBool(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_info_get_args(object): + """ + Attributes: + - ps_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I16, 'ps_num', None, None, ), # 1 + ) + + def __init__(self, ps_num=None,): + self.ps_num = ps_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I16: + self.ps_num = iprot.readI16() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_info_get_args') + if self.ps_num is not None: + oprot.writeFieldBegin('ps_num', TType.I16, 1) + oprot.writeI16(self.ps_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_pwr_supply_info_t, pltfm_mgr_pwr_supply_info_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_pwr_supply_info_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_rail_info_get_args(object): + """ + Attributes: + - ps_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I16, 'ps_num', None, None, ), # 1 + ) + + def __init__(self, ps_num=None,): + self.ps_num = ps_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I16: + self.ps_num = iprot.readI16() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_rail_info_get_args') + if self.ps_num is not None: + oprot.writeFieldBegin('ps_num', TType.I16, 1) + oprot.writeI16(self.ps_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_rail_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_pwr_rail_info_t, pltfm_mgr_pwr_rail_info_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_pwr_rail_info_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_rail_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_speed_set_args(object): + """ + Attributes: + - fan_num + - percent + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'fan_num', None, None, ), # 1 + (2, TType.I32, 'percent', None, None, ), # 2 + ) + + def __init__(self, fan_num=None, percent=None,): + self.fan_num = fan_num + self.percent = percent + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.fan_num = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I32: + self.percent = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_speed_set_args') + if self.fan_num is not None: + oprot.writeFieldBegin('fan_num', TType.I32, 1) + oprot.writeI32(self.fan_num) + oprot.writeFieldEnd() + if self.percent is not None: + oprot.writeFieldBegin('percent', TType.I32, 2) + oprot.writeI32(self.percent) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_speed_set_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_speed_set_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_info_get_args(object): + """ + Attributes: + - fan_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'fan_num', None, None, ), # 1 + ) + + def __init__(self, fan_num=None,): + self.fan_num = fan_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.fan_num = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_info_get_args') + if self.fan_num is not None: + oprot.writeFieldBegin('fan_num', TType.I32, 1) + oprot.writeI32(self.fan_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (pltfm_mgr_fan_info_t, pltfm_mgr_fan_info_t.thrift_spec), None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_fan_info_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_presence_get_args(object): + """ + Attributes: + - port_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + ) + + def __init__(self, port_num=None,): + self.port_num = port_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_presence_get_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_presence_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.BOOL, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.BOOL: + self.success = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_presence_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.BOOL, 0) + oprot.writeBool(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_info_get_args(object): + """ + Attributes: + - port_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + ) + + def __init__(self, port_num=None,): + self.port_num = port_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_info_get_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRING, 'success', 'UTF8', None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRING: + self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRING, 0) + oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_get_max_port_args(object): + + thrift_spec = ( + ) + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_get_max_port_args') + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_get_max_port_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_get_max_port_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_reset_args(object): + """ + Attributes: + - port_num + - reset + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + (2, TType.BOOL, 'reset', None, None, ), # 2 + ) + + def __init__(self, port_num=None, reset=None,): + self.port_num = port_num + self.reset = reset + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.BOOL: + self.reset = iprot.readBool() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_reset_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + if self.reset is not None: + oprot.writeFieldBegin('reset', TType.BOOL, 2) + oprot.writeBool(self.reset) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_reset_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_reset_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_lpmode_get_args(object): + """ + Attributes: + - port_num + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + ) + + def __init__(self, port_num=None,): + self.port_num = port_num + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_lpmode_get_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_lpmode_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.BOOL, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.BOOL: + self.success = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_lpmode_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.BOOL, 0) + oprot.writeBool(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_lpmode_set_args(object): + """ + Attributes: + - port_num + - lpmode + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'port_num', None, None, ), # 1 + (2, TType.BOOL, 'lpmode', None, None, ), # 2 + ) + + def __init__(self, port_num=None, lpmode=None,): + self.port_num = port_num + self.lpmode = lpmode + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.port_num = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.BOOL: + self.lpmode = iprot.readBool() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_lpmode_set_args') + if self.port_num is not None: + oprot.writeFieldBegin('port_num', TType.I32, 1) + oprot.writeI32(self.port_num) + oprot.writeFieldEnd() + if self.lpmode is not None: + oprot.writeFieldBegin('lpmode', TType.BOOL, 2) + oprot.writeBool(self.lpmode) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_qsfp_lpmode_set_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.I32, 'success', None, None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.I32: + self.success = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_qsfp_lpmode_set_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.I32, 0) + oprot.writeI32(self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sensor_info_get_args(object): + """ + Attributes: + - options + """ + + thrift_spec = ( + None, # 0 + (1, TType.STRING, 'options', 'UTF8', None, ), # 1 + ) + + def __init__(self, options=None,): + self.options = options + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.STRING: + self.options = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sensor_info_get_args') + if self.options is not None: + oprot.writeFieldBegin('options', TType.STRING, 1) + oprot.writeString(self.options.encode('utf-8') if sys.version_info[0] == 2 else self.options) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_sensor_info_get_result(object): + """ + Attributes: + - success + - ouch + """ + + thrift_spec = ( + (0, TType.STRING, 'success', 'UTF8', None, ), # 0 + (1, TType.STRUCT, 'ouch', (InvalidPltfmMgrOperation, InvalidPltfmMgrOperation.thrift_spec), None, ), # 1 + ) + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRING: + self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation() + self.ouch.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sensor_info_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRING, 0) + oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py new file mode 100644 index 000000000000..ce03e14f8691 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py @@ -0,0 +1,1060 @@ +# +# Autogenerated by Thrift Compiler (0.10.0) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# +# options string: py +# + +from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException +from thrift.protocol.TProtocol import TProtocolException +import sys + +from thrift.transport import TTransport + + +class pltfm_mgr_sys_tmp_t(object): + """ + Attributes: + - tmp1 + - tmp2 + - tmp3 + - tmp4 + - tmp5 + - tmp6 + - tmp7 + - tmp8 + - tmp9 + - tmp10 + """ + + thrift_spec = ( + None, # 0 + (1, TType.DOUBLE, 'tmp1', None, None, ), # 1 + (2, TType.DOUBLE, 'tmp2', None, None, ), # 2 + (3, TType.DOUBLE, 'tmp3', None, None, ), # 3 + (4, TType.DOUBLE, 'tmp4', None, None, ), # 4 + (5, TType.DOUBLE, 'tmp5', None, None, ), # 5 + (6, TType.DOUBLE, 'tmp6', None, None, ), # 6 + (7, TType.DOUBLE, 'tmp7', None, None, ), # 7 + (8, TType.DOUBLE, 'tmp8', None, None, ), # 8 + (9, TType.DOUBLE, 'tmp9', None, None, ), # 9 + (10, TType.DOUBLE, 'tmp10', None, None, ), # 10 + ) + + def __init__(self, tmp1=None, tmp2=None, tmp3=None, tmp4=None, tmp5=None, tmp6=None, tmp7=None, tmp8=None, tmp9=None, tmp10=None,): + self.tmp1 = tmp1 + self.tmp2 = tmp2 + self.tmp3 = tmp3 + self.tmp4 = tmp4 + self.tmp5 = tmp5 + self.tmp6 = tmp6 + self.tmp7 = tmp7 + self.tmp8 = tmp8 + self.tmp9 = tmp9 + self.tmp10 = tmp10 + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.DOUBLE: + self.tmp1 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.DOUBLE: + self.tmp2 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.DOUBLE: + self.tmp3 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.DOUBLE: + self.tmp4 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.DOUBLE: + self.tmp5 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.DOUBLE: + self.tmp6 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 7: + if ftype == TType.DOUBLE: + self.tmp7 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 8: + if ftype == TType.DOUBLE: + self.tmp8 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 9: + if ftype == TType.DOUBLE: + self.tmp9 = iprot.readDouble() + else: + iprot.skip(ftype) + elif fid == 10: + if ftype == TType.DOUBLE: + self.tmp10 = iprot.readDouble() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_sys_tmp_t') + if self.tmp1 is not None: + oprot.writeFieldBegin('tmp1', TType.DOUBLE, 1) + oprot.writeDouble(self.tmp1) + oprot.writeFieldEnd() + if self.tmp2 is not None: + oprot.writeFieldBegin('tmp2', TType.DOUBLE, 2) + oprot.writeDouble(self.tmp2) + oprot.writeFieldEnd() + if self.tmp3 is not None: + oprot.writeFieldBegin('tmp3', TType.DOUBLE, 3) + oprot.writeDouble(self.tmp3) + oprot.writeFieldEnd() + if self.tmp4 is not None: + oprot.writeFieldBegin('tmp4', TType.DOUBLE, 4) + oprot.writeDouble(self.tmp4) + oprot.writeFieldEnd() + if self.tmp5 is not None: + oprot.writeFieldBegin('tmp5', TType.DOUBLE, 5) + oprot.writeDouble(self.tmp5) + oprot.writeFieldEnd() + if self.tmp6 is not None: + oprot.writeFieldBegin('tmp6', TType.DOUBLE, 6) + oprot.writeDouble(self.tmp6) + oprot.writeFieldEnd() + if self.tmp7 is not None: + oprot.writeFieldBegin('tmp7', TType.DOUBLE, 7) + oprot.writeDouble(self.tmp7) + oprot.writeFieldEnd() + if self.tmp8 is not None: + oprot.writeFieldBegin('tmp8', TType.DOUBLE, 8) + oprot.writeDouble(self.tmp8) + oprot.writeFieldEnd() + if self.tmp9 is not None: + oprot.writeFieldBegin('tmp9', TType.DOUBLE, 9) + oprot.writeDouble(self.tmp9) + oprot.writeFieldEnd() + if self.tmp10 is not None: + oprot.writeFieldBegin('tmp10', TType.DOUBLE, 10) + oprot.writeDouble(self.tmp10) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_eeprom_t(object): + """ + Attributes: + - version + - prod_name + - prod_part_num + - sys_asm_part_num + - bfn_pcba_part_num + - bfn_pcbb_part_num + - odm_pcba_part_num + - odm_pcba_ser_num + - prod_state + - prod_ver + - prod_sub_ver + - prod_ser_num + - prod_ast_tag + - sys_mfger + - sys_mfg_date + - pcb_mfger + - assembled_at + - loc_mac_addr + - ext_mac_addr + - ext_mac_addr_size + - location + - crc8 + """ + + thrift_spec = ( + None, # 0 + (1, TType.I16, 'version', None, None, ), # 1 + (2, TType.STRING, 'prod_name', 'UTF8', None, ), # 2 + (3, TType.STRING, 'prod_part_num', 'UTF8', None, ), # 3 + (4, TType.STRING, 'sys_asm_part_num', 'UTF8', None, ), # 4 + (5, TType.STRING, 'bfn_pcba_part_num', 'UTF8', None, ), # 5 + (6, TType.STRING, 'bfn_pcbb_part_num', 'UTF8', None, ), # 6 + (7, TType.STRING, 'odm_pcba_part_num', 'UTF8', None, ), # 7 + (8, TType.STRING, 'odm_pcba_ser_num', 'UTF8', None, ), # 8 + (9, TType.I16, 'prod_state', None, None, ), # 9 + (10, TType.I16, 'prod_ver', None, None, ), # 10 + (11, TType.I16, 'prod_sub_ver', None, None, ), # 11 + (12, TType.STRING, 'prod_ser_num', 'UTF8', None, ), # 12 + (13, TType.STRING, 'prod_ast_tag', 'UTF8', None, ), # 13 + (14, TType.STRING, 'sys_mfger', 'UTF8', None, ), # 14 + (15, TType.STRING, 'sys_mfg_date', 'UTF8', None, ), # 15 + (16, TType.STRING, 'pcb_mfger', 'UTF8', None, ), # 16 + (17, TType.STRING, 'assembled_at', 'UTF8', None, ), # 17 + (18, TType.STRING, 'loc_mac_addr', 'UTF8', None, ), # 18 + (19, TType.STRING, 'ext_mac_addr', 'UTF8', None, ), # 19 + (20, TType.I32, 'ext_mac_addr_size', None, None, ), # 20 + (21, TType.STRING, 'location', 'UTF8', None, ), # 21 + (22, TType.I16, 'crc8', None, None, ), # 22 + ) + + def __init__(self, version=None, prod_name=None, prod_part_num=None, sys_asm_part_num=None, bfn_pcba_part_num=None, bfn_pcbb_part_num=None, odm_pcba_part_num=None, odm_pcba_ser_num=None, prod_state=None, prod_ver=None, prod_sub_ver=None, prod_ser_num=None, prod_ast_tag=None, sys_mfger=None, sys_mfg_date=None, pcb_mfger=None, assembled_at=None, loc_mac_addr=None, ext_mac_addr=None, ext_mac_addr_size=None, location=None, crc8=None,): + self.version = version + self.prod_name = prod_name + self.prod_part_num = prod_part_num + self.sys_asm_part_num = sys_asm_part_num + self.bfn_pcba_part_num = bfn_pcba_part_num + self.bfn_pcbb_part_num = bfn_pcbb_part_num + self.odm_pcba_part_num = odm_pcba_part_num + self.odm_pcba_ser_num = odm_pcba_ser_num + self.prod_state = prod_state + self.prod_ver = prod_ver + self.prod_sub_ver = prod_sub_ver + self.prod_ser_num = prod_ser_num + self.prod_ast_tag = prod_ast_tag + self.sys_mfger = sys_mfger + self.sys_mfg_date = sys_mfg_date + self.pcb_mfger = pcb_mfger + self.assembled_at = assembled_at + self.loc_mac_addr = loc_mac_addr + self.ext_mac_addr = ext_mac_addr + self.ext_mac_addr_size = ext_mac_addr_size + self.location = location + self.crc8 = crc8 + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I16: + self.version = iprot.readI16() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.STRING: + self.prod_name = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.STRING: + self.prod_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.STRING: + self.sys_asm_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.STRING: + self.bfn_pcba_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.STRING: + self.bfn_pcbb_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 7: + if ftype == TType.STRING: + self.odm_pcba_part_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 8: + if ftype == TType.STRING: + self.odm_pcba_ser_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 9: + if ftype == TType.I16: + self.prod_state = iprot.readI16() + else: + iprot.skip(ftype) + elif fid == 10: + if ftype == TType.I16: + self.prod_ver = iprot.readI16() + else: + iprot.skip(ftype) + elif fid == 11: + if ftype == TType.I16: + self.prod_sub_ver = iprot.readI16() + else: + iprot.skip(ftype) + elif fid == 12: + if ftype == TType.STRING: + self.prod_ser_num = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 13: + if ftype == TType.STRING: + self.prod_ast_tag = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 14: + if ftype == TType.STRING: + self.sys_mfger = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 15: + if ftype == TType.STRING: + self.sys_mfg_date = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 16: + if ftype == TType.STRING: + self.pcb_mfger = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 17: + if ftype == TType.STRING: + self.assembled_at = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 18: + if ftype == TType.STRING: + self.loc_mac_addr = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 19: + if ftype == TType.STRING: + self.ext_mac_addr = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 20: + if ftype == TType.I32: + self.ext_mac_addr_size = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 21: + if ftype == TType.STRING: + self.location = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 22: + if ftype == TType.I16: + self.crc8 = iprot.readI16() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_eeprom_t') + if self.version is not None: + oprot.writeFieldBegin('version', TType.I16, 1) + oprot.writeI16(self.version) + oprot.writeFieldEnd() + if self.prod_name is not None: + oprot.writeFieldBegin('prod_name', TType.STRING, 2) + oprot.writeString(self.prod_name.encode('utf-8') if sys.version_info[0] == 2 else self.prod_name) + oprot.writeFieldEnd() + if self.prod_part_num is not None: + oprot.writeFieldBegin('prod_part_num', TType.STRING, 3) + oprot.writeString(self.prod_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.prod_part_num) + oprot.writeFieldEnd() + if self.sys_asm_part_num is not None: + oprot.writeFieldBegin('sys_asm_part_num', TType.STRING, 4) + oprot.writeString(self.sys_asm_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.sys_asm_part_num) + oprot.writeFieldEnd() + if self.bfn_pcba_part_num is not None: + oprot.writeFieldBegin('bfn_pcba_part_num', TType.STRING, 5) + oprot.writeString(self.bfn_pcba_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.bfn_pcba_part_num) + oprot.writeFieldEnd() + if self.bfn_pcbb_part_num is not None: + oprot.writeFieldBegin('bfn_pcbb_part_num', TType.STRING, 6) + oprot.writeString(self.bfn_pcbb_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.bfn_pcbb_part_num) + oprot.writeFieldEnd() + if self.odm_pcba_part_num is not None: + oprot.writeFieldBegin('odm_pcba_part_num', TType.STRING, 7) + oprot.writeString(self.odm_pcba_part_num.encode('utf-8') if sys.version_info[0] == 2 else self.odm_pcba_part_num) + oprot.writeFieldEnd() + if self.odm_pcba_ser_num is not None: + oprot.writeFieldBegin('odm_pcba_ser_num', TType.STRING, 8) + oprot.writeString(self.odm_pcba_ser_num.encode('utf-8') if sys.version_info[0] == 2 else self.odm_pcba_ser_num) + oprot.writeFieldEnd() + if self.prod_state is not None: + oprot.writeFieldBegin('prod_state', TType.I16, 9) + oprot.writeI16(self.prod_state) + oprot.writeFieldEnd() + if self.prod_ver is not None: + oprot.writeFieldBegin('prod_ver', TType.I16, 10) + oprot.writeI16(self.prod_ver) + oprot.writeFieldEnd() + if self.prod_sub_ver is not None: + oprot.writeFieldBegin('prod_sub_ver', TType.I16, 11) + oprot.writeI16(self.prod_sub_ver) + oprot.writeFieldEnd() + if self.prod_ser_num is not None: + oprot.writeFieldBegin('prod_ser_num', TType.STRING, 12) + oprot.writeString(self.prod_ser_num.encode('utf-8') if sys.version_info[0] == 2 else self.prod_ser_num) + oprot.writeFieldEnd() + if self.prod_ast_tag is not None: + oprot.writeFieldBegin('prod_ast_tag', TType.STRING, 13) + oprot.writeString(self.prod_ast_tag.encode('utf-8') if sys.version_info[0] == 2 else self.prod_ast_tag) + oprot.writeFieldEnd() + if self.sys_mfger is not None: + oprot.writeFieldBegin('sys_mfger', TType.STRING, 14) + oprot.writeString(self.sys_mfger.encode('utf-8') if sys.version_info[0] == 2 else self.sys_mfger) + oprot.writeFieldEnd() + if self.sys_mfg_date is not None: + oprot.writeFieldBegin('sys_mfg_date', TType.STRING, 15) + oprot.writeString(self.sys_mfg_date.encode('utf-8') if sys.version_info[0] == 2 else self.sys_mfg_date) + oprot.writeFieldEnd() + if self.pcb_mfger is not None: + oprot.writeFieldBegin('pcb_mfger', TType.STRING, 16) + oprot.writeString(self.pcb_mfger.encode('utf-8') if sys.version_info[0] == 2 else self.pcb_mfger) + oprot.writeFieldEnd() + if self.assembled_at is not None: + oprot.writeFieldBegin('assembled_at', TType.STRING, 17) + oprot.writeString(self.assembled_at.encode('utf-8') if sys.version_info[0] == 2 else self.assembled_at) + oprot.writeFieldEnd() + if self.loc_mac_addr is not None: + oprot.writeFieldBegin('loc_mac_addr', TType.STRING, 18) + oprot.writeString(self.loc_mac_addr.encode('utf-8') if sys.version_info[0] == 2 else self.loc_mac_addr) + oprot.writeFieldEnd() + if self.ext_mac_addr is not None: + oprot.writeFieldBegin('ext_mac_addr', TType.STRING, 19) + oprot.writeString(self.ext_mac_addr.encode('utf-8') if sys.version_info[0] == 2 else self.ext_mac_addr) + oprot.writeFieldEnd() + if self.ext_mac_addr_size is not None: + oprot.writeFieldBegin('ext_mac_addr_size', TType.I32, 20) + oprot.writeI32(self.ext_mac_addr_size) + oprot.writeFieldEnd() + if self.location is not None: + oprot.writeFieldBegin('location', TType.STRING, 21) + oprot.writeString(self.location.encode('utf-8') if sys.version_info[0] == 2 else self.location) + oprot.writeFieldEnd() + if self.crc8 is not None: + oprot.writeFieldBegin('crc8', TType.I16, 22) + oprot.writeI16(self.crc8) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_supply_info_t(object): + """ + Attributes: + - vin + - vout + - iout + - pwr_out + - fspeed + - ffault + - load_sharing + - model + - serial + - rev + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'vin', None, None, ), # 1 + (2, TType.I32, 'vout', None, None, ), # 2 + (3, TType.I32, 'iout', None, None, ), # 3 + (4, TType.I32, 'pwr_out', None, None, ), # 4 + (5, TType.I32, 'fspeed', None, None, ), # 5 + (6, TType.BOOL, 'ffault', None, None, ), # 6 + (7, TType.BOOL, 'load_sharing', None, None, ), # 7 + (8, TType.STRING, 'model', 'UTF8', None, ), # 8 + (9, TType.STRING, 'serial', 'UTF8', None, ), # 9 + (10, TType.STRING, 'rev', 'UTF8', None, ), # 10 + ) + + def __init__(self, vin=None, vout=None, iout=None, pwr_out=None, fspeed=None, ffault=None, load_sharing=None, model=None, serial=None, rev=None,): + self.vin = vin + self.vout = vout + self.iout = iout + self.pwr_out = pwr_out + self.fspeed = fspeed + self.ffault = ffault + self.load_sharing = load_sharing + self.model = model + self.serial = serial + self.rev = rev + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.vin = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I32: + self.vout = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I32: + self.iout = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.I32: + self.pwr_out = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.I32: + self.fspeed = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.BOOL: + self.ffault = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 7: + if ftype == TType.BOOL: + self.load_sharing = iprot.readBool() + else: + iprot.skip(ftype) + elif fid == 8: + if ftype == TType.STRING: + self.model = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 9: + if ftype == TType.STRING: + self.serial = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + elif fid == 10: + if ftype == TType.STRING: + self.rev = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_supply_info_t') + if self.vin is not None: + oprot.writeFieldBegin('vin', TType.I32, 1) + oprot.writeI32(self.vin) + oprot.writeFieldEnd() + if self.vout is not None: + oprot.writeFieldBegin('vout', TType.I32, 2) + oprot.writeI32(self.vout) + oprot.writeFieldEnd() + if self.iout is not None: + oprot.writeFieldBegin('iout', TType.I32, 3) + oprot.writeI32(self.iout) + oprot.writeFieldEnd() + if self.pwr_out is not None: + oprot.writeFieldBegin('pwr_out', TType.I32, 4) + oprot.writeI32(self.pwr_out) + oprot.writeFieldEnd() + if self.fspeed is not None: + oprot.writeFieldBegin('fspeed', TType.I32, 5) + oprot.writeI32(self.fspeed) + oprot.writeFieldEnd() + if self.ffault is not None: + oprot.writeFieldBegin('ffault', TType.BOOL, 6) + oprot.writeBool(self.ffault) + oprot.writeFieldEnd() + if self.load_sharing is not None: + oprot.writeFieldBegin('load_sharing', TType.BOOL, 7) + oprot.writeBool(self.load_sharing) + oprot.writeFieldEnd() + if self.model is not None: + oprot.writeFieldBegin('model', TType.STRING, 8) + oprot.writeString(self.model.encode('utf-8') if sys.version_info[0] == 2 else self.model) + oprot.writeFieldEnd() + if self.serial is not None: + oprot.writeFieldBegin('serial', TType.STRING, 9) + oprot.writeString(self.serial.encode('utf-8') if sys.version_info[0] == 2 else self.serial) + oprot.writeFieldEnd() + if self.rev is not None: + oprot.writeFieldBegin('rev', TType.STRING, 10) + oprot.writeString(self.rev.encode('utf-8') if sys.version_info[0] == 2 else self.rev) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_pwr_rail_info_t(object): + """ + Attributes: + - vrail1 + - vrail2 + - vrail3 + - vrail4 + - vrail5 + - vrail6 + - vrail7 + - vrail8 + - vrail9 + - vrail10 + - vrail11 + - vrail12 + - vrail13 + - vrail14 + - vrail15 + - vrail16 + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'vrail1', None, None, ), # 1 + (2, TType.I32, 'vrail2', None, None, ), # 2 + (3, TType.I32, 'vrail3', None, None, ), # 3 + (4, TType.I32, 'vrail4', None, None, ), # 4 + (5, TType.I32, 'vrail5', None, None, ), # 5 + (6, TType.I32, 'vrail6', None, None, ), # 6 + (7, TType.I32, 'vrail7', None, None, ), # 7 + (8, TType.I32, 'vrail8', None, None, ), # 8 + (9, TType.I32, 'vrail9', None, None, ), # 9 + (10, TType.I32, 'vrail10', None, None, ), # 10 + (11, TType.I32, 'vrail11', None, None, ), # 11 + (12, TType.I32, 'vrail12', None, None, ), # 12 + (13, TType.I32, 'vrail13', None, None, ), # 13 + (14, TType.I32, 'vrail14', None, None, ), # 14 + (15, TType.I32, 'vrail15', None, None, ), # 15 + (16, TType.I32, 'vrail16', None, None, ), # 16 + ) + + def __init__(self, vrail1=None, vrail2=None, vrail3=None, vrail4=None, vrail5=None, vrail6=None, vrail7=None, vrail8=None, vrail9=None, vrail10=None, vrail11=None, vrail12=None, vrail13=None, vrail14=None, vrail15=None, vrail16=None,): + self.vrail1 = vrail1 + self.vrail2 = vrail2 + self.vrail3 = vrail3 + self.vrail4 = vrail4 + self.vrail5 = vrail5 + self.vrail6 = vrail6 + self.vrail7 = vrail7 + self.vrail8 = vrail8 + self.vrail9 = vrail9 + self.vrail10 = vrail10 + self.vrail11 = vrail11 + self.vrail12 = vrail12 + self.vrail13 = vrail13 + self.vrail14 = vrail14 + self.vrail15 = vrail15 + self.vrail16 = vrail16 + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.vrail1 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I32: + self.vrail2 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I32: + self.vrail3 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.I32: + self.vrail4 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.I32: + self.vrail5 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.I32: + self.vrail6 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 7: + if ftype == TType.I32: + self.vrail7 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 8: + if ftype == TType.I32: + self.vrail8 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 9: + if ftype == TType.I32: + self.vrail9 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 10: + if ftype == TType.I32: + self.vrail10 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 11: + if ftype == TType.I32: + self.vrail11 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 12: + if ftype == TType.I32: + self.vrail12 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 13: + if ftype == TType.I32: + self.vrail13 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 14: + if ftype == TType.I32: + self.vrail14 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 15: + if ftype == TType.I32: + self.vrail15 = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 16: + if ftype == TType.I32: + self.vrail16 = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_pwr_rail_info_t') + if self.vrail1 is not None: + oprot.writeFieldBegin('vrail1', TType.I32, 1) + oprot.writeI32(self.vrail1) + oprot.writeFieldEnd() + if self.vrail2 is not None: + oprot.writeFieldBegin('vrail2', TType.I32, 2) + oprot.writeI32(self.vrail2) + oprot.writeFieldEnd() + if self.vrail3 is not None: + oprot.writeFieldBegin('vrail3', TType.I32, 3) + oprot.writeI32(self.vrail3) + oprot.writeFieldEnd() + if self.vrail4 is not None: + oprot.writeFieldBegin('vrail4', TType.I32, 4) + oprot.writeI32(self.vrail4) + oprot.writeFieldEnd() + if self.vrail5 is not None: + oprot.writeFieldBegin('vrail5', TType.I32, 5) + oprot.writeI32(self.vrail5) + oprot.writeFieldEnd() + if self.vrail6 is not None: + oprot.writeFieldBegin('vrail6', TType.I32, 6) + oprot.writeI32(self.vrail6) + oprot.writeFieldEnd() + if self.vrail7 is not None: + oprot.writeFieldBegin('vrail7', TType.I32, 7) + oprot.writeI32(self.vrail7) + oprot.writeFieldEnd() + if self.vrail8 is not None: + oprot.writeFieldBegin('vrail8', TType.I32, 8) + oprot.writeI32(self.vrail8) + oprot.writeFieldEnd() + if self.vrail9 is not None: + oprot.writeFieldBegin('vrail9', TType.I32, 9) + oprot.writeI32(self.vrail9) + oprot.writeFieldEnd() + if self.vrail10 is not None: + oprot.writeFieldBegin('vrail10', TType.I32, 10) + oprot.writeI32(self.vrail10) + oprot.writeFieldEnd() + if self.vrail11 is not None: + oprot.writeFieldBegin('vrail11', TType.I32, 11) + oprot.writeI32(self.vrail11) + oprot.writeFieldEnd() + if self.vrail12 is not None: + oprot.writeFieldBegin('vrail12', TType.I32, 12) + oprot.writeI32(self.vrail12) + oprot.writeFieldEnd() + if self.vrail13 is not None: + oprot.writeFieldBegin('vrail13', TType.I32, 13) + oprot.writeI32(self.vrail13) + oprot.writeFieldEnd() + if self.vrail14 is not None: + oprot.writeFieldBegin('vrail14', TType.I32, 14) + oprot.writeI32(self.vrail14) + oprot.writeFieldEnd() + if self.vrail15 is not None: + oprot.writeFieldBegin('vrail15', TType.I32, 15) + oprot.writeI32(self.vrail15) + oprot.writeFieldEnd() + if self.vrail16 is not None: + oprot.writeFieldBegin('vrail16', TType.I32, 16) + oprot.writeI32(self.vrail16) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class pltfm_mgr_fan_info_t(object): + """ + Attributes: + - fan_num + - front_rpm + - rear_rpm + - percent + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'fan_num', None, None, ), # 1 + (2, TType.I32, 'front_rpm', None, None, ), # 2 + (3, TType.I32, 'rear_rpm', None, None, ), # 3 + (4, TType.I32, 'percent', None, None, ), # 4 + ) + + def __init__(self, fan_num=None, front_rpm=None, rear_rpm=None, percent=None,): + self.fan_num = fan_num + self.front_rpm = front_rpm + self.rear_rpm = rear_rpm + self.percent = percent + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.fan_num = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I32: + self.front_rpm = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I32: + self.rear_rpm = iprot.readI32() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.I32: + self.percent = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('pltfm_mgr_fan_info_t') + if self.fan_num is not None: + oprot.writeFieldBegin('fan_num', TType.I32, 1) + oprot.writeI32(self.fan_num) + oprot.writeFieldEnd() + if self.front_rpm is not None: + oprot.writeFieldBegin('front_rpm', TType.I32, 2) + oprot.writeI32(self.front_rpm) + oprot.writeFieldEnd() + if self.rear_rpm is not None: + oprot.writeFieldBegin('rear_rpm', TType.I32, 3) + oprot.writeI32(self.rear_rpm) + oprot.writeFieldEnd() + if self.percent is not None: + oprot.writeFieldBegin('percent', TType.I32, 4) + oprot.writeI32(self.percent) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + +class InvalidPltfmMgrOperation(TException): + """ + Attributes: + - code + """ + + thrift_spec = ( + None, # 0 + (1, TType.I32, 'code', None, None, ), # 1 + ) + + def __init__(self, code=None,): + self.code = code + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.I32: + self.code = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('InvalidPltfmMgrOperation') + if self.code is not None: + oprot.writeFieldBegin('code', TType.I32, 1) + oprot.writeI32(self.code) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __str__(self): + return repr(self) + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py new file mode 100644 index 000000000000..33adad8c1ac6 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +try: + import os + import sys + + sys.path.append(os.path.dirname(__file__)) + + from .platform_thrift_client import ThriftClient + + from sonic_platform_base.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class Psu(PsuBase): + """Platform-specific PSU class""" + + def __init__(self, index): + PsuBase.__init__(self) + self.index = index + + @staticmethod + def get_num_psus(): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_powergood_status(self): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based self.index + :param self.index: An integer, 1-based self.index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + try: + with ThriftClient() as client: + psu_info = client.pltfm_mgr.pltfm_mgr_pwr_supply_info_get(self.index) + except Exception: + return False + + return (psu_info.ffault == False) + + def get_presence(self): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based self.index + :param self.index: An integer, 1-based self.index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + try: + with ThriftClient() as client: + status = client.pltfm_mgr.pltfm_mgr_pwr_supply_present_get(self.index) + except Exception: + return False + + return status diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py new file mode 100644 index 000000000000..1b63630d1a8f --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python + +try: + import os + import sys + import time + + sys.path.append(os.path.dirname(__file__)) + + from .platform_thrift_client import ThriftClient + + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +SFP_EEPROM_CACHE = "/var/run/platform/sfp/cache" + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 0 + PORTS_IN_BLOCK = 0 + QSFP_PORT_START = 1 + QSFP_PORT_END = 0 + EEPROM_OFFSET = 0 + QSFP_CHECK_INTERVAL = 4 + + @property + def port_start(self): + self.update_port_info() + return self.PORT_START + + @property + def port_end(self): + self.update_port_info() + return self.PORT_END + + @property + def qsfp_ports(self): + self.update_port_info() + return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + print "dependency on sysfs has been removed" + raise Exception() + + def __init__(self): + self.ready = False + self.phy_port_dict = {'-1': 'system_not_ready'} + self.phy_port_cur_state = {} + self.qsfp_interval = self.QSFP_CHECK_INTERVAL + + if not os.path.exists(os.path.dirname(SFP_EEPROM_CACHE)): + try: + os.makedirs(os.path.dirname(SFP_EEPROM_CACHE)) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + open(SFP_EEPROM_CACHE, 'ab').close() + + SfpUtilBase.__init__(self) + + def update_port_info(self): + if self.QSFP_PORT_END == 0: + with ThriftClient() as client: + self.QSFP_PORT_END = client.pltfm_mgr.pltfm_mgr_qsfp_get_max_port(); + self.PORT_END = self.QSFP_PORT_END + self.PORTS_IN_BLOCK = self.QSFP_PORT_END + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + presence = False + + try: + with ThriftClient() as client: + presence = client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port_num) + except Exception as e: + print e.__doc__ + print e.message + + return presence + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + with ThriftClient() as client: + lpmode = client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_get(port_num) + return lpmode + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + with ThriftClient() as client: + status = client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_set(port_num, lpmode) + return (status == 0) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + with ThriftClient() as client: + client.pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, True) + status = client.pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, False) + return status + + def check_transceiver_change(self): + if not self.ready: + return + + self.phy_port_dict = {} + + try: + client = ThriftClient().open() + except Exception: + return + + # Get presence of each SFP + for port in range(self.port_start, self.port_end + 1): + try: + sfp_resent = client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port) + except Exception: + sfp_resent = False + sfp_state = '1' if sfp_resent else '0' + + if port in self.phy_port_cur_state: + if self.phy_port_cur_state[port] != sfp_state: + self.phy_port_dict[port] = sfp_state + else: + self.phy_port_dict[port] = sfp_state + + # Update port current state + self.phy_port_cur_state[port] = sfp_state + + client.close() + + def get_transceiver_change_event(self, timeout=0): + forever = False + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print "get_transceiver_change_event:Invalid timeout value", timeout + return False, {} + + while forever or timeout > 0: + if not self.ready: + try: + with ThriftClient(): pass + except Exception: + pass + else: + self.ready = True + self.phy_port_dict = {} + break + elif self.qsfp_interval == 0: + self.qsfp_interval = self.QSFP_CHECK_INTERVAL + + # Process transceiver plug-in/out event + self.check_transceiver_change() + + # Break if tranceiver state has changed + if bool(self.phy_port_dict): + break + + if timeout: + timeout -= 1 + + if self.qsfp_interval: + self.qsfp_interval -= 1 + + time.sleep(1) + + return self.ready, self.phy_port_dict + + def _get_port_eeprom_path(self, port_num, devid): + eeprom_path = None + + with ThriftClient() as client: + presence = client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port_num) + if presence == True: + eeprom_cache = open(SFP_EEPROM_CACHE, 'wb') + eeprom_hex = client.pltfm_mgr.pltfm_mgr_qsfp_info_get(port_num) + eeprom_raw = bytearray.fromhex(eeprom_hex) + eeprom_cache.write(eeprom_raw) + eeprom_cache.close() + eeprom_path = SFP_EEPROM_CACHE + + return eeprom_path + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + sfputil = SfpUtil() + + @staticmethod + def port_start(): + return Sfp.sfputil.port_start + + @staticmethod + def port_end(): + return Sfp.sfputil.port_end + + @staticmethod + def qsfp_ports(): + return Sfp.sfputil.qsfp_ports() + + @staticmethod + def get_transceiver_change_event(timeout=0): + return Sfp.sfputil.get_transceiver_change_event() + + def __init__(self, port_num): + self.port_num = port_num + SfpBase.__init__(self) + + def get_presence(self): + return Sfp.sfputil.get_presence(self.port_num) + + def get_lpmode(self): + return Sfp.sfputil.get_low_power_mode(self.port_num) + + def set_lpmode(self, lpmode): + return Sfp.sfputil.set_low_power_mode(self.port_num, lpmode) + + def reset(self): + return Sfp.sfputil.reset(self.port_num) + + def get_transceiver_info(self): + return Sfp.sfputil.get_transceiver_info_dict(self.port_num) + + def get_transceiver_bulk_status(self): + return Sfp.sfputil.get_transceiver_dom_info_dict(self.port_num) + + def get_transceiver_threshold_info(self): + return Sfp.sfputil.get_transceiver_dom_threshold_info_dict(self.port_num) + + def get_change_event(self, timeout=0): + return Sfp.get_transceiver_change_event(timeout) diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules index 5bb10ed19350..962a1de8204e 100755 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules @@ -8,6 +8,8 @@ KERNEL_SRC := /lib/modules/$(KVERSION) MODULE_SRC := $(shell pwd)/modules SCRIPT_SRC := $(shell pwd)/scripts CONFIGS_SRC := $(shell pwd)/configs +BUILD_DIR := $(shell pwd)/build +WHEEL_BUILD_DIR := $(BUILD_DIR)/wheel PLUGINS_DIR := $(shell pwd)/plugins MODULE_NAMES := as9516 as9516bf @@ -16,6 +18,10 @@ MODULE_NAMES := as9516 as9516bf override_dh_auto_build: make -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + set -e + python2.7 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + python3 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + set +e override_dh_auto_install: (for mod in $(MODULE_NAMES); do \ @@ -25,6 +31,8 @@ override_dh_auto_install: cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin; \ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} etc/network/interfaces.d/; \ cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_PRE_NAME)-$${mod}/etc/network/interfaces.d/; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/; \ + cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/; \ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/plugins; \ cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/share/sonic/device/x86_64-accton_$${mod}_32d-r0/plugins/; \ done) @@ -35,6 +43,9 @@ override_dh_pysupport: override_dh_clean: dh_clean + rm -fr $(WHEEL_BUILD_DIR) + rm -fr *.egg-info + rm -fr $(BUILD) rm -f $(MODULE_SRC)/*.o $(MODULE_SRC)/*.ko $(MODULE_SRC)/*.mod.c $(MODULE_SRC)/.*.cmd rm -f $(MODULE_SRC)/Module.markers $(MODULE_SRC)/Module.symvers $(MODULE_SRC)/modules.order rm -rf $(MODULE_SRC)/.tmp_versions diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/setup.py b/platform/barefoot/sonic-platform-modules-bfn-newport/setup.py new file mode 120000 index 000000000000..a68e2eec6762 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/setup.py @@ -0,0 +1 @@ +../sonic-platform-modules-bfn-montara/setup.py \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/sonic_platform b/platform/barefoot/sonic-platform-modules-bfn-newport/sonic_platform new file mode 120000 index 000000000000..b2918418aad1 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/sonic_platform @@ -0,0 +1 @@ +../sonic-platform-modules-bfn-montara/sonic_platform \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/rules b/platform/barefoot/sonic-platform-modules-bfn/debian/rules index 83cdefe640ba..1bea5b4c67ef 100755 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/rules @@ -3,20 +3,33 @@ PACKAGE_NAME := sonic-platform-modules-bfn SCRIPT_SRC := $(shell pwd)/scripts CONFIGS_SRC := $(shell pwd)/configs +BUILD_DIR := $(shell pwd)/build +WHEEL_BUILD_DIR := $(BUILD_DIR)/wheel %: dh $@ +override_dh_auto_build: + set -e + python2.7 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + python3 setup.py bdist_wheel -d $(WHEEL_BUILD_DIR) + set +e + override_dh_auto_install: dh_installdirs -p$(PACKAGE_NAME) usr/local/bin cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ + dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/platform/ + cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/platform/ override_dh_usrlocal: override_dh_pysupport: override_dh_clean: + rm -fr $(WHEEL_BUILD_DIR) + rm -fr *.egg-info + rm -fr $(BUILD) dh_clean diff --git a/platform/barefoot/sonic-platform-modules-bfn/setup.py b/platform/barefoot/sonic-platform-modules-bfn/setup.py new file mode 120000 index 000000000000..a68e2eec6762 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/setup.py @@ -0,0 +1 @@ +../sonic-platform-modules-bfn-montara/setup.py \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-bfn/sonic_platform b/platform/barefoot/sonic-platform-modules-bfn/sonic_platform new file mode 120000 index 000000000000..b2918418aad1 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/sonic_platform @@ -0,0 +1 @@ +../sonic-platform-modules-bfn-montara/sonic_platform \ No newline at end of file From ec0153008a6e079da540839fe6d0573ee114190c Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Sat, 3 Oct 2020 23:00:39 -0700 Subject: [PATCH 62/78] [rc.local] separate configuration migration and grub installation logic (#5528) To address issue #5525 Explicitly control the grub installation requirement when it is needed. We have scenario where configuration migration happened but grub installation is not required. Signed-off-by: Ying Xie --- files/image_config/platform/rc.local | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index 2e242559094c..878345106c95 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -199,6 +199,7 @@ logger "SONiC version ${SONIC_VERSION} starting up..." # If the machine.conf is absent, it indicates that the unit booted # into SONiC from another NOS. Extract the machine.conf from ONIE. +grub_installation_needed="" if [ ! -e /host/machine.conf ]; then onie_dev=$(blkid | grep ONIE-BOOT | head -n 1 | awk '{print $1}' | sed -e 's/:.*$//') mkdir -p /mnt/onie-boot @@ -213,6 +214,7 @@ if [ ! -e /host/machine.conf ]; then eval val='$'onie_$var echo "onie_${var}=${val}" >> /host/machine.conf done + grub_installation_needed="TRUE" fi umount /mnt/onie-boot @@ -277,7 +279,7 @@ if [ -f $FIRST_BOOT_FILE ]; then # If the unit booted into SONiC from another NOS's grub, # we now install a grub for SONiC. - if [ -n "$onie_platform" ] && [ -n "$migration" ]; then + if [ -n "$onie_platform" ] && [ -n "$grub_installation_needed" ]; then grub_bin=$(ls /host/image-$SONIC_VERSION/platform/x86_64-grub/grub-pc-bin*.deb 2> /dev/null) if [ -z "$grub_bin" ]; then From 6b0690adbbfe4bb7f0e03651383bd9ee9cb34a9b Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Sat, 3 Oct 2020 23:03:13 -0700 Subject: [PATCH 63/78] [sonic-py-swsssdk] update submodule for using correct connect parameter number (#5524) * [MultiDB] fix wrong parameter number in interface.py (#88) Signed-off-by: Dong Zhang d.zhang@alibaba-inc.com --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 3ef02a1e357b..3461ae0578f4 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 3ef02a1e357b8ce7cbf58e39c775f1f75e69be04 +Subproject commit 3461ae0578f415753978a5c5b33ad43e0a9b0cc5 From 8c344095a8cba34637c5c4fbda81f24abd9df90c Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Mon, 5 Oct 2020 08:48:13 -0700 Subject: [PATCH 64/78] [docker-orchagent]: Add NDP Proxy Daemon (#5517) * Install ndppd during image build, and copy config files to image * Configure proxy settings based on config DB at container start * Pipe ndppd output to logger inside container to log output in syslog --- dockers/docker-orchagent/Dockerfile.j2 | 4 +- dockers/docker-orchagent/docker-init.sh | 4 +- dockers/docker-orchagent/ndppd.conf | 9 +++++ dockers/docker-orchagent/ndppd.conf.j2 | 37 +++++++++++++++++++ .../tests/data/ndppd/vlan_interfaces.json | 20 ++++++++++ src/sonic-config-engine/tests/ndppd.conf.j2 | 1 + .../tests/sample_output/py2/ndppd.conf | 25 +++++++++++++ .../tests/sample_output/py3/ndppd.conf | 25 +++++++++++++ src/sonic-config-engine/tests/test_j2files.py | 10 +++++ 9 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 dockers/docker-orchagent/ndppd.conf create mode 100644 dockers/docker-orchagent/ndppd.conf.j2 create mode 100644 src/sonic-config-engine/tests/data/ndppd/vlan_interfaces.json create mode 120000 src/sonic-config-engine/tests/ndppd.conf.j2 create mode 100644 src/sonic-config-engine/tests/sample_output/py2/ndppd.conf create mode 100644 src/sonic-config-engine/tests/sample_output/py3/ndppd.conf diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index 9190a5d89b8f..097a582f6337 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -17,7 +17,8 @@ RUN apt-get update && \ libelf1 \ libmnl0 \ bridge-utils \ - conntrack + conntrack \ + ndppd {% if ( CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" ) %} ## Fix for gcc/python not found in arm docker @@ -60,6 +61,7 @@ RUN apt-get clean -y && \ COPY ["files/arp_update", "/usr/bin"] COPY ["arp_update.conf", "files/arp_update_vars.j2", "/usr/share/sonic/templates/"] +COPY ["ndppd.conf", "/usr/share/sonic/templates/"] COPY ["enable_counters.py", "/usr/bin"] COPY ["docker-init.sh", "orchagent.sh", "swssconfig.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] diff --git a/dockers/docker-orchagent/docker-init.sh b/dockers/docker-orchagent/docker-init.sh index 70b9f2d871b5..41d815b4d7a9 100755 --- a/dockers/docker-orchagent/docker-init.sh +++ b/dockers/docker-orchagent/docker-init.sh @@ -10,6 +10,7 @@ CFGGEN_PARAMS=" \ -t /usr/share/sonic/templates/ports.json.j2,/etc/swss/config.d/ports.json \ -t /usr/share/sonic/templates/copp.json.j2,/etc/swss/config.d/00-copp.config.json \ -t /usr/share/sonic/templates/vlan_vars.j2 \ + -t /usr/share/sonic/templates/ndppd.conf.j2,/etc/ndppd.conf \ " VLAN=$(sonic-cfggen $CFGGEN_PARAMS) @@ -18,9 +19,10 @@ if [ -x /usr/share/sonic/hwsku/hwsku-init ]; then /usr/share/sonic/hwsku/hwsku-init fi -# Start arp_update when VLAN exists +# Start arp_update and NDP proxy daemon when VLAN exists if [ "$VLAN" != "" ]; then cp /usr/share/sonic/templates/arp_update.conf /etc/supervisor/conf.d/ + cp /usr/share/sonic/templates/ndppd.conf /etc/supervisor/conf.d/ fi exec /usr/bin/supervisord diff --git a/dockers/docker-orchagent/ndppd.conf b/dockers/docker-orchagent/ndppd.conf new file mode 100644 index 000000000000..1e97bf97e313 --- /dev/null +++ b/dockers/docker-orchagent/ndppd.conf @@ -0,0 +1,9 @@ +[program:ndppd] +command=bash -c "/usr/sbin/ndppd | /usr/bin/logger" +priority=7 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited \ No newline at end of file diff --git a/dockers/docker-orchagent/ndppd.conf.j2 b/dockers/docker-orchagent/ndppd.conf.j2 new file mode 100644 index 000000000000..bc375f3c4987 --- /dev/null +++ b/dockers/docker-orchagent/ndppd.conf.j2 @@ -0,0 +1,37 @@ +{% block banner %} +# =========== Managed by sonic-cfggen -- DO NOT edit manually! ==================== +# Generated by /usr/share/sonic/templates/ndppd.conf.j2 using config DB data +# File: /etc/ndppd.conf +# +{% endblock banner %} +# Config file for ndppd, the NDP Proxy Daemon +# See man page for ndppd.conf.5 for descriptions of all available options +{% if VLAN_INTERFACE and VLAN_INTERFACE|pfx_filter|length > 0%} +{# Get all VLAN interfaces that have proxy_arp enabled #} +{% set proxy_interfaces = {} %} +{% for intf in VLAN_INTERFACE %} +{% if "proxy_arp" in VLAN_INTERFACE[intf] and VLAN_INTERFACE[intf]["proxy_arp"] == "enabled" %} +{% set _x = proxy_interfaces.update({intf: []}) %} +{% endif %} +{% endfor -%} + +{# Add each IPv6 prefix from each proxy_arp interface #} +{% for (intf, prefix) in VLAN_INTERFACE|pfx_filter %} +{% if intf in proxy_interfaces and prefix | ipv6 %} +{% set _x = proxy_interfaces[intf].append(prefix) %} +{% endif %} +{% endfor -%} + +{% for intf, prefix_list in proxy_interfaces.items() %} +{% if prefix_list %} + +proxy {{ intf }} { +{% for prefix in prefix_list %} + rule {{ prefix | network }}/{{ prefix | prefixlen }} { + static + } +{% endfor %} +} +{% endif %} +{% endfor %} +{% endif %} \ No newline at end of file diff --git a/src/sonic-config-engine/tests/data/ndppd/vlan_interfaces.json b/src/sonic-config-engine/tests/data/ndppd/vlan_interfaces.json new file mode 100644 index 000000000000..d45214827642 --- /dev/null +++ b/src/sonic-config-engine/tests/data/ndppd/vlan_interfaces.json @@ -0,0 +1,20 @@ +{ + "VLAN_INTERFACE": { + "Vlan1000": { + "proxy_arp": "enabled" + }, + "Vlan1000|192.168.0.1/21": {}, + "Vlan1000|fc01:1000::1/64": {}, + "Vlan1000|fc02:1000::1/64": {}, + "Vlan1000|fc03:1000::1/64": {}, + "Vlan2000": { + "proxy_arp": "enabled" + }, + "Vlan2000|fc01:2000::1/64": {}, + "Vlan3000|fc01:3000::1/64": {}, + "Vlan4000": { + "proxy_arp": "disabled" + }, + "Vlan4000|fc01:4000::1/64": {} + } +} \ No newline at end of file diff --git a/src/sonic-config-engine/tests/ndppd.conf.j2 b/src/sonic-config-engine/tests/ndppd.conf.j2 new file mode 120000 index 000000000000..e6f2f543eee4 --- /dev/null +++ b/src/sonic-config-engine/tests/ndppd.conf.j2 @@ -0,0 +1 @@ +../../../dockers/docker-orchagent/ndppd.conf.j2 \ No newline at end of file diff --git a/src/sonic-config-engine/tests/sample_output/py2/ndppd.conf b/src/sonic-config-engine/tests/sample_output/py2/ndppd.conf new file mode 100644 index 000000000000..71ff1dfaf9ca --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/ndppd.conf @@ -0,0 +1,25 @@ +# =========== Managed by sonic-cfggen -- DO NOT edit manually! ==================== +# Generated by /usr/share/sonic/templates/ndppd.conf.j2 using config DB data +# File: /etc/ndppd.conf +# +# Config file for ndppd, the NDP Proxy Daemon +# See man page for ndppd.conf.5 for descriptions of all available options + +proxy Vlan1000 { + rule fc02:1000::/64 { + static + } + rule fc03:1000::/64 { + static + } + rule fc01:1000::/64 { + static + } +} + +proxy Vlan2000 { + rule fc01:2000::/64 { + static + } +} + diff --git a/src/sonic-config-engine/tests/sample_output/py3/ndppd.conf b/src/sonic-config-engine/tests/sample_output/py3/ndppd.conf new file mode 100644 index 000000000000..28a239006d24 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/ndppd.conf @@ -0,0 +1,25 @@ +# =========== Managed by sonic-cfggen -- DO NOT edit manually! ==================== +# Generated by /usr/share/sonic/templates/ndppd.conf.j2 using config DB data +# File: /etc/ndppd.conf +# +# Config file for ndppd, the NDP Proxy Daemon +# See man page for ndppd.conf.5 for descriptions of all available options + +proxy Vlan1000 { + rule fc01:1000::/64 { + static + } + rule fc02:1000::/64 { + static + } + rule fc03:1000::/64 { + static + } +} + +proxy Vlan2000 { + rule fc01:2000::/64 { + static + } +} + diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 98bb2437628d..ad06f61b84c5 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -171,6 +171,16 @@ def test_ipinip_multi_asic(self): sample_output_file = os.path.join(self.test_dir, 'multi_npu_data', utils.PYvX_DIR, 'ipinip.json') assert filecmp.cmp(sample_output_file, self.output_file) + def test_ndppd_conf(self): + conf_template = os.path.join(self.test_dir, "ndppd.conf.j2") + vlan_interfaces_json = os.path.join(self.test_dir, "data", "ndppd", "vlan_interfaces.json") + expected = os.path.join(self.test_dir, "sample_output", utils.PYvX_DIR, "ndppd.conf") + + argument = '-j {} -t {} > {}'.format(vlan_interfaces_json, conf_template, self.output_file) + self.run_script(argument) + assert filecmp.cmp(expected, self.output_file), self.run_diff(expected, self.output_file) + + def tearDown(self): try: os.remove(self.output_file) From f61ff95e26f631ef35028227da7b561c5681c2fa Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Mon, 5 Oct 2020 20:50:03 +0300 Subject: [PATCH 65/78] [barefoot] Platform API 2.0 fixups (#5539) Fixes for bfn platform api Signed-off-by: Volodymyr Boyko --- .../debian/rules | 10 ++-- .../sonic_platform/chassis.py | 2 +- .../sonic_platform/eeprom.py | 31 +++++----- .../sonic_platform/platform_thrift_client.py | 12 ++++ .../sonic_platform/psu.py | 14 +++-- .../sonic_platform/sfp.py | 57 ++++++++++++------- .../sonic-platform-modules-bfn/debian/rules | 2 - 7 files changed, 77 insertions(+), 51 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules index bf5a4c9a50fe..3377688e6097 100755 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules @@ -1,6 +1,6 @@ #!/usr/bin/make -f -PLATFORM = x86_64-accton_wedge100bf_32x-r0 +PLATFORM := x86_64-accton_wedge100bf_32x-r0 PACKAGE_NAME := sonic-platform-modules-bfn-montara SCRIPT_SRC := $(shell pwd)/scripts CONFIGS_SRC := $(shell pwd)/configs @@ -22,10 +22,10 @@ override_dh_auto_install: cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ - dh_installdirs -p$(PACKAGE_NAME) /usr/share/sonic/device/${PLATFORM}/ - cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/${PLATFORM}/ - dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/${PLATFORM}/plugins - cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/${PLATFORM}/plugins/ + dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/$(PLATFORM)/ + cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/$(PLATFORM)/ + dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/device/$(PLATFORM)/plugins + cp -r $(PLUGINS_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/device/$(PLATFORM)/plugins/ override_dh_usrlocal: diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py index 36a921d539f5..1ca885ff2a40 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py @@ -24,7 +24,7 @@ def __init__(self): sfp_node = Sfp(index) self._sfp_list.append(sfp_node) - for i in range(MAX_PSU): + for i in range(1, MAX_PSU + 1): psu = Psu(i) self._psu_list.append(psu) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py index a548e9364715..a1ebe5f224a9 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py @@ -2,7 +2,6 @@ try: - import time import os import sys import errno @@ -17,7 +16,7 @@ from sonic_eeprom import eeprom_base from sonic_eeprom import eeprom_tlvinfo - from .platform_thrift_client import ThriftClient + from .platform_thrift_client import thrift_try except ImportError, e: raise ImportError (str(e) + "- required module not found") @@ -65,8 +64,6 @@ EEPROM_STATUS = "/var/run/platform/eeprom/status" class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): - RETRIES = 35 - def __init__(self): with open(os.path.dirname(__file__) + "/logging.conf", 'r') as f: @@ -88,20 +85,16 @@ def __init__(self): self.eeprom_path = EEPROM_SYMLINK super(Eeprom, self).__init__(self.eeprom_path, 0, EEPROM_STATUS, True) - for attempt in range(self.RETRIES): - if self.eeprom_init(): - break - if attempt + 1 == self.RETRIES: - raise RuntimeError("eeprom.py: Initialization failed") - time.sleep(1) - - def eeprom_init(self): + def sys_eeprom_get(client): + return client.pltfm_mgr.pltfm_mgr_sys_eeprom_get() try: - with ThriftClient() as client: - self.eeprom = client.pltfm_mgr.pltfm_mgr_sys_eeprom_get() + self.eeprom = thrift_try(sys_eeprom_get) except Exception: - return False + raise RuntimeError("eeprom.py: Initialization failed") + + self.eeprom_parse() + def eeprom_parse(self): f = open(EEPROM_STATUS, 'w') f.write("ok") f.close() @@ -131,9 +124,13 @@ def eeprom_init(self): eeprom_params += "{0:s}={1:s}".format(elem[1], value) orig_stdout = sys.stdout + sys.stdout = StringIO() - new_e = eeprom_tlvinfo.TlvInfoDecoder.set_eeprom(self, "", [eeprom_params]) - sys.stdout = orig_stdout + try: + new_e = eeprom_tlvinfo.TlvInfoDecoder.set_eeprom(self, "", [eeprom_params]) + finally: + sys.stdout = orig_stdout + eeprom_base.EepromDecoder.write_eeprom(self, new_e) return True diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py index 06afe8e962ae..96c0e09ba1c0 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py @@ -3,6 +3,7 @@ try: import os import sys + import time import importlib sys.path.append(os.path.dirname(__file__)) @@ -11,6 +12,7 @@ from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol from thrift.protocol import TMultiplexedProtocol + from thrift.Thrift import TException except ImportError as e: raise ImportError (str(e) + "- required module not found") @@ -35,3 +37,13 @@ def __enter__(self): return self.open() def __exit__(self, exc_type, exc_value, tb): self.close() + +def thrift_try(func, attempts=35): + for attempt in range(attempts): + try: + with ThriftClient() as client: + return func(client) + except TException as e: + if attempt + 1 == attempts: + raise e + time.sleep(1) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py index 33adad8c1ac6..7e7e4403ad5c 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py @@ -6,7 +6,7 @@ sys.path.append(os.path.dirname(__file__)) - from .platform_thrift_client import ThriftClient + from .platform_thrift_client import thrift_try from sonic_platform_base.psu_base import PsuBase except ImportError as e: @@ -34,9 +34,11 @@ def get_powergood_status(self): :param self.index: An integer, 1-based self.index of the PSU of which to query status :return: Boolean, True if PSU is operating properly, False if PSU is faulty """ + def psu_info_get(client): + return client.pltfm_mgr.pltfm_mgr_pwr_supply_info_get(self.index) + try: - with ThriftClient() as client: - psu_info = client.pltfm_mgr.pltfm_mgr_pwr_supply_info_get(self.index) + psu_info = thrift_try(psu_info_get) except Exception: return False @@ -49,9 +51,11 @@ def get_presence(self): :param self.index: An integer, 1-based self.index of the PSU of which to query status :return: Boolean, True if PSU is plugged, False if not """ + def psu_present_get(client): + return client.pltfm_mgr.pltfm_mgr_pwr_supply_present_get(self.index) + try: - with ThriftClient() as client: - status = client.pltfm_mgr.pltfm_mgr_pwr_supply_present_get(self.index) + status = thrift_try(psu_present_get) except Exception: return False diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py index 1b63630d1a8f..12587c66f474 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py @@ -8,6 +8,7 @@ sys.path.append(os.path.dirname(__file__)) from .platform_thrift_client import ThriftClient + from .platform_thrift_client import thrift_try from sonic_platform_base.sfp_base import SfpBase from sonic_platform_base.sonic_sfp.sfputilbase import SfpUtilBase @@ -65,11 +66,13 @@ def __init__(self): SfpUtilBase.__init__(self) def update_port_info(self): + def qsfp_max_port_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_get_max_port(); + if self.QSFP_PORT_END == 0: - with ThriftClient() as client: - self.QSFP_PORT_END = client.pltfm_mgr.pltfm_mgr_qsfp_get_max_port(); - self.PORT_END = self.QSFP_PORT_END - self.PORTS_IN_BLOCK = self.QSFP_PORT_END + self.QSFP_PORT_END = thrift_try(qsfp_max_port_get) + self.PORT_END = self.QSFP_PORT_END + self.PORTS_IN_BLOCK = self.QSFP_PORT_END def get_presence(self, port_num): # Check for invalid port_num @@ -78,9 +81,11 @@ def get_presence(self, port_num): presence = False + def qsfp_presence_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port_num) + try: - with ThriftClient() as client: - presence = client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port_num) + presence = thrift_try(qsfp_presence_get) except Exception as e: print e.__doc__ print e.message @@ -92,8 +97,11 @@ def get_low_power_mode(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False - with ThriftClient() as client: - lpmode = client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_get(port_num) + def qsfp_lpmode_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_get(port_num) + + lpmode = thrift_try(qsfp_lpmode_get) + return lpmode def set_low_power_mode(self, port_num, lpmode): @@ -101,8 +109,11 @@ def set_low_power_mode(self, port_num, lpmode): if port_num < self.port_start or port_num > self.port_end: return False - with ThriftClient() as client: - status = client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_set(port_num, lpmode) + def qsfp_lpmode_set(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_lpmode_set(port_num, lpmode) + + status = thrift_try(qsfp_lpmode_set) + return (status == 0) def reset(self, port_num): @@ -110,9 +121,12 @@ def reset(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False - with ThriftClient() as client: + def qsfp_reset(client): client.pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, True) - status = client.pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, False) + return client.pltfm_mgr.pltfm_mgr_qsfp_reset(port_num, False) + + status = thrift_try(qsfp_reset) + return status def check_transceiver_change(self): @@ -188,15 +202,16 @@ def get_transceiver_change_event(self, timeout=0): def _get_port_eeprom_path(self, port_num, devid): eeprom_path = None - with ThriftClient() as client: - presence = client.pltfm_mgr.pltfm_mgr_qsfp_presence_get(port_num) - if presence == True: - eeprom_cache = open(SFP_EEPROM_CACHE, 'wb') - eeprom_hex = client.pltfm_mgr.pltfm_mgr_qsfp_info_get(port_num) - eeprom_raw = bytearray.fromhex(eeprom_hex) - eeprom_cache.write(eeprom_raw) - eeprom_cache.close() - eeprom_path = SFP_EEPROM_CACHE + def qsfp_info_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_info_get(port_num) + + if self.get_presence(port_num): + eeprom_hex = thrift_try(qsfp_info_get) + eeprom_cache = open(SFP_EEPROM_CACHE, 'wb') + eeprom_raw = bytearray.fromhex(eeprom_hex) + eeprom_cache.write(eeprom_raw) + eeprom_cache.close() + eeprom_path = SFP_EEPROM_CACHE return eeprom_path diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/rules b/platform/barefoot/sonic-platform-modules-bfn/debian/rules index 1bea5b4c67ef..37e264ad7ed8 100755 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/rules +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/rules @@ -20,8 +20,6 @@ override_dh_auto_install: cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ - dh_installdirs -p$(PACKAGE_NAME) usr/share/sonic/platform/ - cp -r $(WHEEL_BUILD_DIR)/* debian/$(PACKAGE_NAME)/usr/share/sonic/platform/ override_dh_usrlocal: From 90d84143e831acf85c6d3b39e8dfed3575072f14 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Mon, 5 Oct 2020 19:54:21 -0700 Subject: [PATCH 66/78] [submodule update] Update sonic-utilities submodule pointer (#5545) - [acl-loader] Revert fix for IP protocol == 0 (#1142) - Show sflow interface to display all interfaces enabled for sflow (#1143) - [sflow_test.py]: tests for config sflow commands. (#1112) - [config/console] Support add/del console port setting commands (#1136) - [cli][bgp]use vtysh in the show ip bgp summary command (#1137) - [README.md] Describe new package creation schema (#1131) - [consutil] Remove actual baud and refactor lib for future change (#1130) Signed-off-by: Danny Allen --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 2f79ac135018..31eb13b7f8db 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 2f79ac135018b62a2a04e031c5221799fcaa2dc4 +Subproject commit 31eb13b7f8db910fa5fd8f11e0d53d89aaf93f50 From 70528f7460f3a5dee723ed90ba4781aca461a107 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Mon, 5 Oct 2020 22:54:47 -0700 Subject: [PATCH 67/78] [Multi-asic] Fixed Default Route to be BGP (#5548) Learned and not docker default route for multi-asic platforms. Signed-off-by: Abhishek Dosi --- dockers/docker-fpm-frr/docker_init.sh | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/dockers/docker-fpm-frr/docker_init.sh b/dockers/docker-fpm-frr/docker_init.sh index 09489a6ae04a..25482866b495 100755 --- a/dockers/docker-fpm-frr/docker_init.sh +++ b/dockers/docker-fpm-frr/docker_init.sh @@ -17,17 +17,19 @@ CFGGEN_PARAMS=" \ " CONFIG_TYPE=$(sonic-cfggen $CFGGEN_PARAMS) -if [[ ! -z "$NAMESPACE_ID" ]]; then +update_default_gw() +{ + IP_VER=${1} # FRR is not running in host namespace so we need to delete # default gw kernel route added by docker network via eth0 and add it back # with higher administrative distance so that default route learnt # by FRR becomes best route if/when available - GATEWAY_IP=$(ip route show 0.0.0.0/0 dev eth0 | awk '{print $3}') + GATEWAY_IP=$(ip -${IP_VER} route show default dev eth0 | awk '{print $3}') #Check if docker default route is there if [[ ! -z "$GATEWAY_IP" ]]; then - ip route del 0.0.0.0/0 dev eth0 + ip -${IP_VER} route del default dev eth0 #Make sure route is deleted - CHECK_GATEWAY_IP=$(ip route show 0.0.0.0/0 dev eth0 | awk '{print $3}') + CHECK_GATEWAY_IP=$(ip -${IP_VER} route show default dev eth0 | awk '{print $3}') if [[ -z "$CHECK_GATEWAY_IP" ]]; then # Ref: http://docs.frrouting.org/en/latest/zebra.html#zebra-vrf # Zebra does treat Kernel routes as special case for the purposes of Admin Distance. \ @@ -35,9 +37,14 @@ if [[ ! -z "$NAMESPACE_ID" ]]; then # The top byte of the value is interpreted as the Administrative Distance and # the low three bytes are read in as the metric. # so here we are programming administrative distance of 210 (210 << 24) > 200 (for routes learnt via IBGP) - ip route add 0.0.0.0/0 via $GATEWAY_IP dev eth0 metric 3523215360 + ip -${IP_VER} route add default via $GATEWAY_IP dev eth0 metric 3523215360 fi fi +} + +if [[ ! -z "$NAMESPACE_ID" ]]; then + update_default_gw 4 + update_default_gw 6 fi if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "separated" ]; then From 48c089b9bb79e7fcac2c91474ceb59b014d9db21 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Tue, 6 Oct 2020 06:23:24 -0700 Subject: [PATCH 68/78] Add Python3-swss-common package to image. (#5547) Make Python3-swsscommon available in image. ``` admin@str-s6000-acs-13:~$ sudo apt-cache search swss libswsscommon - This package contains Switch State Service common library. python-swsscommon - This package contains Switch State Service common Python2 library. python3-swsscommon- This package contains Switch State Service common Python3 library. admin@str-s6000-acs-13:~$ ``` --- platform/p4/docker-sonic-p4.mk | 1 + platform/vs/docker-sonic-vs.mk | 1 + slave.mk | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/p4/docker-sonic-p4.mk b/platform/p4/docker-sonic-p4.mk index 14747ec476e0..b499a99aefe5 100644 --- a/platform/p4/docker-sonic-p4.mk +++ b/platform/p4/docker-sonic-p4.mk @@ -8,6 +8,7 @@ $(DOCKER_SONIC_P4)_DEPENDS += $(SWSS) \ $(REDIS_TOOLS) \ $(REDIS_SERVER) \ $(PYTHON_SWSSCOMMON) \ + $(PYTHON3_SWSSCOMMON) \ $(LIBTEAMDCTL) \ $(LIBTEAM_UTILS) \ $(SONIC_DEVICE_DATA) \ diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index d1d694756c59..2812c5b26dd5 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -5,6 +5,7 @@ $(DOCKER_SONIC_VS)_PATH = $(PLATFORM_PATH)/docker-sonic-vs $(DOCKER_SONIC_VS)_DEPENDS += $(SWSS) \ $(SYNCD_VS) \ $(PYTHON_SWSSCOMMON) \ + $(PYTHON3_SWSSCOMMON) \ $(LIBTEAMDCTL) \ $(LIBTEAM_UTILS) \ $(SONIC_DEVICE_DATA) \ diff --git a/slave.mk b/slave.mk index 8eb78494ce3d..9b0b10b3c0e7 100644 --- a/slave.mk +++ b/slave.mk @@ -803,6 +803,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(LIBNSS_TACPLUS) \ $(MONIT) \ $(PYTHON_SWSSCOMMON) \ + $(PYTHON3_SWSSCOMMON) \ $(SONIC_UTILITIES_DATA)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ @@ -862,7 +863,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export sonic_yang_mgmt_py_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY))" export multi_instance="false" export python_swss_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($(LIBSWSSCOMMON)_RDEPENDS))" - export python_swss_debs+=" $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(LIBSWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON_SWSSCOMMON))" + export python_swss_debs+=" $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(LIBSWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON_SWSSCOMMON)) $(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(PYTHON3_SWSSCOMMON))" export sonic_utilities_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_UTILITIES_PY2))" $(foreach docker, $($*_DOCKERS),\ From 49b34dc433065d5b2c69d9284629bb4b16745140 Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Tue, 6 Oct 2020 07:58:00 -0700 Subject: [PATCH 69/78] [BCMSAI] Update BCM SAI debian package to 4.2.1.3 (6.5.19 hsdk) (#5532) * [BCMSAI DEB] Update BCM SAI debian package to 4.2.1.3 (6.5.19 hsdk)(1.6.5 SAI) * [BCMSAI GPL] Update BCMSAI GPL to 6.5.19 --- platform/broadcom/sai-modules.mk | 3 +- platform/broadcom/sai.mk | 8 +- .../broadcom/saibcm-modules/debian/changelog | 12 +- .../debian/opennsl-modules.install | 1 + platform/broadcom/saibcm-modules/debian/rules | 31 +- .../broadcom/saibcm-modules/include/ibde.h | 6 + .../broadcom/saibcm-modules/include/kcom.h | 53 +- .../saibcm-modules/include/sal/types.h | 25 +- .../saibcm-modules/include/soc/devids.h | 140 +- .../broadcom/saibcm-modules/make/Make.linux | 4 +- .../saibcm-modules/make/Makefile.linux-gto | 15 + .../saibcm-modules/make/Makefile.linux-gts | 142 + .../saibcm-modules/make/Makefile.linux-iproc | 16 +- .../make/Makefile.linux-iproc-4_4 | 92 + .../make/Makefile.linux-iproc_64 | 106 + .../saibcm-modules/make/Makefile.linux-slk | 146 + .../Makefile.linux-x86-generic-common-2_6 | 1 + .../Makefile.linux-x86-smp_generic_64-2_6 | 26 +- .../saibcm-modules/make/Makefile.linux-xlr | 142 + .../systems/bde/linux/kernel/Makefile | 8 +- .../bde/linux/kernel/linux-kernel-bde.c | 315 ++- .../systems/bde/linux/kernel/linux_dma.c | 41 +- .../bde/linux/user/kernel/linux-user-bde.c | 209 +- .../systems/bde/shared/shbde_iproc.c | 27 +- .../systems/linux/kernel/modules/Makefile | 2 +- .../linux/kernel/modules/bcm-knet/Makefile | 3 - .../linux/kernel/modules/bcm-knet/bcm-knet.c | 2429 +++++++++-------- .../kernel/modules/bcm-ptp-clock/Makefile | 65 + .../modules/bcm-ptp-clock/bcm-ptp-clock.c | 1981 ++++++++++++++ .../linux/kernel/modules/include/bcm-knet.h | 21 +- .../linux/kernel/modules/include/lkm.h | 5 + .../linux/kernel/modules/knet-cb/Makefile | 1 + .../linux/kernel/modules/knet-cb/knet-cb.c | 122 +- .../linux/kernel/modules/knet-cb/psample-cb.c | 262 +- .../linux/kernel/modules/psample/psample.c | 4 +- .../systems/linux/user/common/Makefile | 53 +- .../systems/linux/user/gts/Makefile | 63 + .../systems/linux/user/iproc-4_4/Makefile | 59 + .../systems/linux/user/iproc_64/Makefile | 59 + .../systems/linux/user/slk/Makefile | 60 + .../systems/linux/user/xlr/Makefile | 63 + 41 files changed, 5364 insertions(+), 1457 deletions(-) create mode 100644 platform/broadcom/saibcm-modules/make/Makefile.linux-gts create mode 100644 platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-4_4 create mode 100644 platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 create mode 100644 platform/broadcom/saibcm-modules/make/Makefile.linux-slk create mode 100644 platform/broadcom/saibcm-modules/make/Makefile.linux-xlr create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/Makefile create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/bcm-ptp-clock.c create mode 100644 platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile create mode 100644 platform/broadcom/saibcm-modules/systems/linux/user/iproc-4_4/Makefile create mode 100644 platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile create mode 100644 platform/broadcom/saibcm-modules/systems/linux/user/slk/Makefile create mode 100644 platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile diff --git a/platform/broadcom/sai-modules.mk b/platform/broadcom/sai-modules.mk index 5f48efefa19a..84d97c09ac88 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -1,9 +1,8 @@ # Broadcom SAI modules -BRCM_OPENNSL_KERNEL_VERSION = 3.7.3.3-1 +BRCM_OPENNSL_KERNEL_VERSION = 4.2.1.3-1 BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb $(BRCM_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules $(BRCM_OPENNSL_KERNEL)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_DPKG_DEBS += $(BRCM_OPENNSL_KERNEL) - diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 00aaae57b4fa..98c61b798bd7 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,8 +1,8 @@ -BRCM_SAI = libsaibcm_3.7.5.1-3_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/master/libsaibcm_3.7.5.1-3_amd64.deb?sv=2015-04-05&sr=b&sig=hwGt%2Fw1fWhauEsCXBTBmC3vC8G90iJT4DEp%2Bznwh4WY%3D&se=2034-04-16T01%3A02%3A17Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.7.5.1-3_amd64.deb +BRCM_SAI = libsaibcm_4.2.1.3_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.2/master/libsaibcm_4.2.1.3_amd64.deb?sv=2015-04-05&sr=b&sig=aA0Ltk2jteFuJZdr1ldj%2F5e6o7R0U5S%2FqVWvutPC7k0%3D&se=2021-08-31T04%3A08%3A35Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_4.2.1.3_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/master/libsaibcm-dev_3.7.5.1-3_amd64.deb?sv=2015-04-05&sr=b&sig=nuyZOMB%2BnmDIROP60UAiDl9eG0YHAEj6u8ViTlEqjf0%3D&se=2034-04-16T01%3A01%3A51Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/4.2/master/libsaibcm-dev_4.2.1.3_amd64.deb?sv=2015-04-05&sr=b&sig=r%2FWgs1VEFo07sbfYK%2FDZmk83QKTzwSSe%2F3%2BN3k3uAcY%3D&se=2022-01-30T22%3A55%3A04Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) diff --git a/platform/broadcom/saibcm-modules/debian/changelog b/platform/broadcom/saibcm-modules/debian/changelog index 2be513ed0435..f2b0db31e662 100644 --- a/platform/broadcom/saibcm-modules/debian/changelog +++ b/platform/broadcom/saibcm-modules/debian/changelog @@ -1,19 +1,25 @@ +opennsl (4.2.1.3-1) unstable; urgency=medium + + * Update to Broadcom SAI 4.2.1.3 + + -- Mahesh Maddikayala Fri, 18 Sep 2029 10:57:47 +0000 + opennsl (3.7.3.3-1) unstable; urgency=medium - + * Port Broadcom SAI 3.7.3.3 * Cherry-pick change from master branch, 3.7.3.3-1 -- Judy Joseph Fri, 2 Dec 2019 15:32:47 +0000 opennsl (3.7.3.2-1) unstable; urgency=medium - + * Port Broadcom SAI 3.7.3.2 * Cherry-pick change from master branch, 3.7.3.2-1 -- Judy Joseph Fri, 12 Nov 2019 15:22:47 +0000 opennsl (3.7.3.1-1) unstable; urgency=medium - + * Port Broadcom SAI 3.7.3.1 * Cherry-pick change from master branch, 3.7.3.1-1 diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install index e536bae27494..0e8051fbbca7 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install @@ -3,4 +3,5 @@ systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.19.0 systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.19.0-9-2-amd64/extra systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.19.0-9-2-amd64/extra systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.19.0-9-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-ptp-clock.ko lib/modules/4.19.0-9-2-amd64/extra systemd/opennsl-modules.service lib/systemd/system diff --git a/platform/broadcom/saibcm-modules/debian/rules b/platform/broadcom/saibcm-modules/debian/rules index 5fee0cbf8f65..64cc9b6c07e0 100755 --- a/platform/broadcom/saibcm-modules/debian/rules +++ b/platform/broadcom/saibcm-modules/debian/rules @@ -35,6 +35,8 @@ PACKAGE=opennsl-modules # modifieable for experiments or debugging m-a MA_DIR ?= /usr/share/modass KVERSION ?= 4.19.0-9-2-amd64 +KERNVERSION ?= 4.19.0-9-2 + # load generic variable handling -include $(MA_DIR)/include/generic.make # load default rules, including kdist, kdist_image, ... @@ -62,8 +64,8 @@ kdist_clean: clean dh_testdir dh_clean SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ - KERNDIR=/usr/src/linux-headers-$(KVERSION) \ - KERNEL_SRC=/usr/src/linux-headers-$(KVERSION) \ + KERNDIR=/usr/src/linux-headers-$(KERNVERSION)-common \ + KERNEL_SRC=/usr/src/linux-headers-$(KERNVERSION)-amd64 \ $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean # rm -f driver/*.o driver/*.ko # @@ -78,13 +80,24 @@ configure-stamp: build-arch: configure-stamp build-arch-stamp -build-arch-stamp: +build-arch-stamp: dh_testdir + # create links + cd /; sudo mkdir -p /lib/modules/$(KERNVERSION)-amd64 + cd /; sudo rm /lib/modules/$(KERNVERSION)-amd64/build + cd /; sudo rm /lib/modules/$(KERNVERSION)-amd64/source + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-common/ /lib/modules/$(KERNVERSION)-amd64/source + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-amd64/ /lib/modules/$(KERNVERSION)-amd64/build + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-amd64/include/generated/ /usr/src/linux-headers-$(KERNVERSION)-common/include/generated + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-amd64/arch/x86/include/generated/ /usr/src/linux-headers-$(KERNVERSION)-common/arch/x86/include/generated + cd /; sudo ln -s /usr/src/linux-headers-$(KERNVERSION)-amd64/include/config/ /usr/src/linux-headers-$(KERNVERSION)-common/include/config + cd /; sudo cp /usr/src/linux-headers-$(KERNVERSION)-amd64/Module.symvers /usr/src/linux-headers-$(KERNVERSION)-common/Module.symvers + # Add here command to compile/build the package. SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ - KERNDIR=/usr/src/linux-headers-$(KVERSION) \ - KERNEL_SRC=/usr/src/linux-headers-$(KVERSION) \ + KERNDIR=/usr/src/linux-headers-$(KERNVERSION)-common \ + KERNEL_SRC=/usr/src/linux-headers-$(KERNVERSION)-amd64 \ $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 touch $@ @@ -92,7 +105,7 @@ build-arch-stamp: #k = $(shell echo $(KVERS) | grep -q ^2.6 && echo k) build-indep: configure-stamp build-indep-stamp -build-indep-stamp: +build-indep-stamp: dh_testdir # Add here command to compile/build the arch indep package. @@ -104,15 +117,15 @@ build-indep-stamp: build: build-arch -clean: +clean: dh_testdir #dh_testroot rm -f build-arch-stamp build-indep-stamp configure-stamp # Add here commands to clean up after the build process. SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 \ - KERNDIR=/usr/src/linux-headers-$(KVERSION) \ - KERNEL_SRC=/usr/src/linux-headers-$(KVERSION) \ + KERNDIR=/usr/src/linux-headers-$(KERNVERSION)-common \ + KERNEL_SRC=/usr/src/linux-headers-$(KERNVERSION)-amd64 \ $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean dh_clean diff --git a/platform/broadcom/saibcm-modules/include/ibde.h b/platform/broadcom/saibcm-modules/include/ibde.h index 45112eadcb4b..5f371b2667c3 100644 --- a/platform/broadcom/saibcm-modules/include/ibde.h +++ b/platform/broadcom/saibcm-modules/include/ibde.h @@ -34,6 +34,12 @@ typedef struct ibde_dev_s { sal_vaddr_t base_address; sal_vaddr_t base_address1; sal_vaddr_t base_address2; + /* a unique number representing the specific device. + * Must be different for different devices. + * May be used to identify specific devices in the system. + * May be implemented as a full PCIe address, a persistent configurable user value, ... + * Possible implementation value stores in QSPI flash memory of the device. */ + uint32 dev_unique_id; } ibde_dev_t; diff --git a/platform/broadcom/saibcm-modules/include/kcom.h b/platform/broadcom/saibcm-modules/include/kcom.h index 1e3cad0753bc..eb41e1a5aaf2 100644 --- a/platform/broadcom/saibcm-modules/include/kcom.h +++ b/platform/broadcom/saibcm-modules/include/kcom.h @@ -59,8 +59,9 @@ #define KCOM_M_DBGPKT_SET 41 /* Enbale debug packet function */ #define KCOM_M_DBGPKT_GET 42 /* Get debug packet function info */ #define KCOM_M_WB_CLEANUP 51 /* Clean up for warmbooting */ +#define KCOM_M_CLOCK_CMD 52 /* Clock Commands */ -#define KCOM_VERSION 10 /* Protocol version */ +#define KCOM_VERSION 12 /* Protocol version */ /* * Message status codes @@ -138,11 +139,10 @@ typedef struct kcom_netif_s { uint16 vlan; uint16 qnum; uint8 macaddr[6]; - uint8 ptch[2]; - uint8 itmh[4]; uint8 system_headers[KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX]; uint8 system_headers_size; char name[KCOM_NETIF_NAME_MAX]; + uint8 phys_port; } kcom_netif_t; /* @@ -225,13 +225,9 @@ typedef struct kcom_filter_s { uint8 b[KCOM_FILTER_BYTES_MAX]; uint32 w[KCOM_FILTER_WORDS_MAX]; } mask; - /** Information to parse Dune system headers */ - uint32 ftmh_lb_key_ext_size; - uint32 ftmh_stacking_ext_size; - uint32 pph_base_size; - uint32 pph_lif_ext_size[8]; - uint8 udh_enable; - uint32 udh_length_type[4]; + /** Mark to match source modid and modport */ + uint8 is_src_modport; + uint8 spa_unit; } kcom_filter_t; /* @@ -338,6 +334,19 @@ typedef struct kcom_msg_version_s { uint32 filter_max; } kcom_msg_version_t; +/* + * Request KCOM interface clock info. + */ +#define KSYNC_M_HW_INIT 0 +#define KSYNC_M_HW_DEINIT 1 +#define KSYNC_M_VERSION 2 +#define KSYNC_M_HW_TS_DISABLE 3 + +typedef struct kcom_clock_info_s { + uint8 cmd; + int32 data[8]; +} kcom_clock_info_t; + /* * Send literal string to/from kernel module. * Mainly for debugging purposes. @@ -386,6 +395,19 @@ typedef struct kcom_msg_hw_init_s { uint8 pkt_hdr_size; uint32 dma_hi; uint32 cdma_channels; + /* + * Information to parse Dune system headers + */ + uint32 ftmh_lb_key_ext_size; + uint32 ftmh_stacking_ext_size; + uint32 pph_base_size; + uint32 pph_lif_ext_size[8]; + uint32 udh_length_type[4]; + uint32 udh_size; + uint32 oamp_punted; + uint8 no_skip_udh_check; + uint8 system_headers_mode; + uint8 udh_enable; } kcom_msg_hw_init_t; /* @@ -445,6 +467,14 @@ typedef struct kcom_msg_netif_destroy_s { kcom_msg_hdr_t hdr; } kcom_msg_netif_destroy_t; +/* + * Destroy system network interface. + */ +typedef struct kcom_msg_clock_s{ + kcom_msg_hdr_t hdr; + kcom_clock_info_t clock_info; +} kcom_msg_clock_cmd_t; + /* * Get list of currently defined system network interfaces. */ @@ -486,7 +516,7 @@ typedef struct kcom_msg_filter_destroy_s { * Get list of currently defined packet filters. */ #ifndef KCOM_FILTER_MAX -#define KCOM_FILTER_MAX 128 +#define KCOM_FILTER_MAX 128 #endif typedef struct kcom_msg_filter_list_s { @@ -535,6 +565,7 @@ typedef union kcom_msg_s { kcom_msg_dbg_pkt_set_t dbg_pkt_set; kcom_msg_dbg_pkt_get_t dbg_pkt_get; kcom_msg_wb_cleanup_t wb_cleanup; + kcom_msg_clock_cmd_t clock_cmd; } kcom_msg_t; /* diff --git a/platform/broadcom/saibcm-modules/include/sal/types.h b/platform/broadcom/saibcm-modules/include/sal/types.h index b6b40f762939..7ed68f43e5e5 100644 --- a/platform/broadcom/saibcm-modules/include/sal/types.h +++ b/platform/broadcom/saibcm-modules/include/sal/types.h @@ -92,17 +92,25 @@ typedef signed int int32; /* 32-bit quantity */ #define COUNTOF(ary) ((int) (sizeof (ary) / sizeof ((ary)[0]))) -typedef uint32 sal_paddr_t; /* Physical address (PCI address) */ - #ifdef PTRS_ARE_64BITS -typedef uint64 sal_vaddr_t; /* Virtual address (Host address) */ -#define PTR_TO_INT(x) ((uint32)(((sal_vaddr_t)(x))&0xFFFFFFFF)) +typedef uint64 sal_vaddr_t; /* Virtual address (Host address) */ +typedef uint64 sal_paddr_t; /* Physical address (PCI address) */ +#define PTR_TO_INT(x) ((uint32)(((sal_vaddr_t)(x))&0xFFFFFFFF)) +#define PTR_HI_TO_INT(x) ((uint32)((((sal_vaddr_t)(x))>>32)&0xFFFFFFFF)) +#else +typedef uint32 sal_vaddr_t; /* Virtual address (Host address) */ +/* Physical address (PCI address) */ +#ifdef PHYS_ADDRS_ARE_64BITS +typedef uint64 sal_paddr_t; +#define PTR_HI_TO_INT(x) ((uint32)((((uint64)(x))>>32)&0xFFFFFFFF)) #else -typedef uint32 sal_vaddr_t; /* Virtual address (Host address) */ -#define PTR_TO_INT(x) ((uint32)(x)) +typedef uint32 sal_paddr_t; +#define PTR_HI_TO_INT(x) (0) +#endif +#define PTR_TO_INT(x) ((uint32)(x)) #endif -#define INT_TO_PTR(x) ((void *)((sal_vaddr_t)(x))) +#define INT_TO_PTR(x) ((void *)((sal_vaddr_t)(x))) #define PTR_TO_UINTPTR(x) ((sal_vaddr_t)(x)) #define UINTPTR_TO_PTR(x) ((void *)(x)) @@ -128,6 +136,7 @@ typedef union #define SAL_I2C_DEV_TYPE 0x00040 /* I2C device */ #define SAL_AXI_DEV_TYPE 0x00080 /* AXI device */ #define SAL_EMMI_DEV_TYPE 0x10000 /* EMMI device */ +#define SAL_COMPOSITE_DEV_TYPE 0x20000 /* Composite device, composed of sub-devices with buses */ #define SAL_DEV_BUS_TYPE_MASK 0xf00ff /* Odd for historical reasons */ /* Device types */ @@ -152,4 +161,4 @@ typedef union /* Special access addresses */ #define SAL_DEV_OP_EMMI_INIT 0x0fff1000 -#endif /* !_SAL_TYPES_H */ +#endif /* !_SAL_TYPES_H */ diff --git a/platform/broadcom/saibcm-modules/include/soc/devids.h b/platform/broadcom/saibcm-modules/include/soc/devids.h index 7546ef392298..bb91d90be03f 100644 --- a/platform/broadcom/saibcm-modules/include/soc/devids.h +++ b/platform/broadcom/saibcm-modules/include/soc/devids.h @@ -14,7 +14,7 @@ * version 2 (GPLv2) along with this source code. */ /* - * Copyright: (c) 2019 Broadcom. + * Copyright: (c) 2020 Broadcom. * All Rights Reserved. */ @@ -1211,11 +1211,13 @@ #define BCM56169_B0_REV_ID 0x11 #define BCM56169_B1_REV_ID 0x12 +#define BCM56980_DEVICE_ID_MASK 0xFFF0 #define BCM56980_DEVICE_ID 0xb980 #define BCM56980_A0_REV_ID 1 #define BCM56980_B0_REV_ID 0x11 #define BCM56981_DEVICE_ID 0xb981 #define BCM56981_A0_REV_ID 1 +#define BCM56981_B0_REV_ID 0x11 #define BCM56982_DEVICE_ID 0xb982 #define BCM56982_A0_REV_ID 1 #define BCM56982_B0_REV_ID 0x11 @@ -1248,6 +1250,30 @@ #define BCM56166_A0_REV_ID 1 #define BCM56166_B0_REV_ID 0x11 +#define BCM56273_DEVICE_ID 0xb273 +#define BCM56273_A0_REV_ID 1 +#define BCM56273_A1_REV_ID 2 + +#define BCM56274_DEVICE_ID 0xb274 +#define BCM56274_A0_REV_ID 1 +#define BCM56274_A1_REV_ID 2 + +#define BCM56275_DEVICE_ID 0xb275 +#define BCM56275_A0_REV_ID 1 +#define BCM56275_A1_REV_ID 2 + +#define BCM56276_DEVICE_ID 0xb276 +#define BCM56276_A0_REV_ID 1 +#define BCM56276_A1_REV_ID 2 + +#define BCM56277_DEVICE_ID 0xb277 +#define BCM56277_A0_REV_ID 1 +#define BCM56277_A1_REV_ID 2 + +#define BCM56278_DEVICE_ID 0xb278 +#define BCM56278_A0_REV_ID 1 +#define BCM56278_A1_REV_ID 2 + #define BCM53440_DEVICE_ID 0x8440 #define BCM53440_A0_REV_ID 1 #define BCM53440_B0_REV_ID 0x11 @@ -1277,18 +1303,23 @@ #define BCM56670_DEVICE_ID 0xb670 #define BCM56670_A0_REV_ID 1 #define BCM56670_B0_REV_ID 0x11 +#define BCM56670_C0_REV_ID 0x21 + #define BCM56671_DEVICE_ID 0xb671 #define BCM56671_A0_REV_ID 1 #define BCM56671_B0_REV_ID 0x11 +#define BCM56671_C0_REV_ID 0x21 #define BCM56672_DEVICE_ID 0xb672 #define BCM56672_A0_REV_ID 1 #define BCM56672_B0_REV_ID 0x11 +#define BCM56672_C0_REV_ID 0x21 #define BCM56675_DEVICE_ID 0xb675 #define BCM56675_A0_REV_ID 1 #define BCM56675_B0_REV_ID 0x11 +#define BCM56675_C0_REV_ID 0x21 #define BCM56565_DEVICE_ID 0xb565 @@ -1312,9 +1343,6 @@ #define BCM56760_A1_REV_ID 2 #define BCM56760_B0_REV_ID 0x11 -#define BCM56761_DEVICE_ID 0xb761 -#define BCM56761_A0_REV_ID 1 -#define BCM56761_B0_REV_ID 0x11 #define BCM56761_DEVICE_ID 0xb761 #define BCM56761_A0_REV_ID 1 @@ -1372,6 +1400,11 @@ #define BCM53575_A0_REV_ID 1 #define BCM53575_B0_REV_ID 0x11 +#define BCM56070_DEVICE_ID 0xb070 +#define BCM56070_A0_REV_ID 1 +#define BCM56071_DEVICE_ID 0xb071 +#define BCM56071_A0_REV_ID 1 + #define BCM56965_DEVICE_ID 0xb965 #define BCM56965_A0_REV_ID 1 @@ -1407,42 +1440,52 @@ #define BCM56370_DEVICE_ID 0xb370 #define BCM56370_A0_REV_ID 1 #define BCM56370_A1_REV_ID 0x02 +#define BCM56370_A2_REV_ID 0x03 #define BCM56371_DEVICE_ID 0xb371 #define BCM56371_A0_REV_ID 1 #define BCM56371_A1_REV_ID 0x02 +#define BCM56371_A2_REV_ID 0x03 #define BCM56372_DEVICE_ID 0xb372 #define BCM56372_A0_REV_ID 1 #define BCM56372_A1_REV_ID 0x02 +#define BCM56372_A2_REV_ID 0x03 #define BCM56374_DEVICE_ID 0xb374 #define BCM56374_A0_REV_ID 1 #define BCM56374_A1_REV_ID 0x02 +#define BCM56374_A2_REV_ID 0x03 #define BCM56375_DEVICE_ID 0xb375 #define BCM56375_A0_REV_ID 1 #define BCM56375_A1_REV_ID 0x02 +#define BCM56375_A2_REV_ID 0x03 #define BCM56376_DEVICE_ID 0xb376 #define BCM56376_A0_REV_ID 1 #define BCM56376_A1_REV_ID 0x02 +#define BCM56376_A2_REV_ID 0x03 #define BCM56377_DEVICE_ID 0xb377 #define BCM56377_A0_REV_ID 1 #define BCM56377_A1_REV_ID 0x02 +#define BCM56377_A2_REV_ID 0x03 #define BCM56577_DEVICE_ID 0xb577 #define BCM56577_A0_REV_ID 1 #define BCM56577_A1_REV_ID 0x02 +#define BCM56577_A2_REV_ID 0x03 #define BCM56578_DEVICE_ID 0xb578 #define BCM56578_A0_REV_ID 1 #define BCM56578_A1_REV_ID 0x02 +#define BCM56578_A2_REV_ID 0x03 #define BCM56579_DEVICE_ID 0xb579 #define BCM56579_A0_REV_ID 1 #define BCM56579_A1_REV_ID 0x02 +#define BCM56579_A2_REV_ID 0x03 #define BCM56770_DEVICE_ID 0xb770 #define BCM56770_A0_REV_ID 1 @@ -1450,6 +1493,14 @@ #define BCM56771_DEVICE_ID 0xb771 #define BCM56771_A0_REV_ID 1 +#define BCM56470_DEVICE_ID 0xb470 +#define BCM56470_A0_REV_ID 1 +#define BCM56471_DEVICE_ID 0xb471 +#define BCM56471_A0_REV_ID 1 +#define BCM56472_DEVICE_ID 0xb472 +#define BCM56472_A0_REV_ID 1 + + #define BCM53540_DEVICE_ID 0x8540 #define BCM53540_A0_REV_ID 1 #define BCM53547_DEVICE_ID 0x8547 @@ -1526,6 +1577,7 @@ #define DNXC_A1_REV_ID 0x0002 #define DNXC_B0_REV_ID 0x0011 #define DNXC_B1_REV_ID 0x0012 +#define DNXC_DEVID_FAMILY_MASK 0xfff0 #define BCM88790_DEVICE_ID 0x8790 #define BCM88790_A0_REV_ID DNXC_A0_REV_ID #define BCM88790_B0_REV_ID DNXC_B0_REV_ID @@ -1544,7 +1596,6 @@ #define BCM8879D_DEVICE_ID 0x879D #define BCM8879E_DEVICE_ID 0x879E #define BCM8879F_DEVICE_ID 0x879F -#define BCM_DNXF_DEVID_MASK 0xFFF0 #define ARADPLUS_DEVICE_ID 0x8660 #define ARADPLUS_A0_REV_ID 0x0001 #define BCM88660_DEVICE_ID ARADPLUS_DEVICE_ID @@ -1675,19 +1726,22 @@ #define BCM88685_DEVICE_ID 0x8685 #define BCM88685_A0_REV_ID JERICHO_PLUS_A0_REV_ID +#define BCM88687_DEVICE_ID 0x8687 +#define BCM88687_A0_REV_ID JERICHO_PLUS_A0_REV_ID + #define BCM88380_DEVICE_ID 0x8380 #define BCM88380_A0_REV_ID JERICHO_PLUS_A0_REV_ID #define BCM88381_DEVICE_ID 0x8381 #define BCM88381_A0_REV_ID JERICHO_PLUS_A0_REV_ID -#define JERICHO_2_DEVICE_ID 0x8690 -#define JERICHO_2_A0_REV_ID DNXC_A0_REV_ID -#define JERICHO_2_B0_REV_ID DNXC_B0_REV_ID -#define JERICHO_2_B1_REV_ID DNXC_B1_REV_ID -#define BCM88690_DEVICE_ID JERICHO_2_DEVICE_ID -#define BCM88690_A0_REV_ID JERICHO_2_A0_REV_ID -#define BCM88690_B0_REV_ID JERICHO_2_B0_REV_ID -#define BCM88690_B1_REV_ID JERICHO_2_B1_REV_ID +#define JERICHO2_DEVICE_ID 0x8690 +#define JERICHO2_A0_REV_ID DNXC_A0_REV_ID +#define JERICHO2_B0_REV_ID DNXC_B0_REV_ID +#define JERICHO2_B1_REV_ID DNXC_B1_REV_ID +#define BCM88690_DEVICE_ID JERICHO2_DEVICE_ID +#define BCM88690_A0_REV_ID JERICHO2_A0_REV_ID +#define BCM88690_B0_REV_ID JERICHO2_B0_REV_ID +#define BCM88690_B1_REV_ID JERICHO2_B1_REV_ID #define BCM88691_DEVICE_ID 0x8691 #define BCM88692_DEVICE_ID 0x8692 #define BCM88693_DEVICE_ID 0x8693 @@ -1703,12 +1757,56 @@ #define BCM8869D_DEVICE_ID 0x869D #define BCM8869E_DEVICE_ID 0x869E #define BCM8869F_DEVICE_ID 0x869F -#define BCM_JR2_DEVID_MASK 0xFFF0 -#define J2C_DEVICE_ID 0x8800 +#define J2C_DEVICE_ID 0x8800 +#define J2C_2ND_DEVICE_ID 0x8820 +#define J2C_DEVID_FAMILY_MASK 0xffd0 #define J2C_A0_REV_ID DNXC_A0_REV_ID +#define J2C_A1_REV_ID DNXC_A1_REV_ID #define BCM88800_DEVICE_ID J2C_DEVICE_ID +#define BCM88820_DEVICE_ID J2C_2ND_DEVICE_ID #define BCM88800_A0_REV_ID J2C_A0_REV_ID +#define BCM88800_A1_REV_ID J2C_A1_REV_ID +#define BCM88821_DEVICE_ID 0x8821 +#define BCM88826_DEVICE_ID 0x8826 +#define BCM88802_DEVICE_ID 0x8802 +#define BCM88803_DEVICE_ID 0x8803 +#define BCM88804_DEVICE_ID 0x8804 +#define BCM88805_DEVICE_ID 0x8805 +#define BCM88806_DEVICE_ID 0x8806 +#define BCM88822_DEVICE_ID 0x8822 +#define BCM88823_DEVICE_ID 0x8823 +#define BCM88824_DEVICE_ID 0x8824 +#define BCM88825_DEVICE_ID 0x8825 + +#define J2P_DEVICE_ID 0x8850 +#define J2P_A0_REV_ID DNXC_A0_REV_ID +#define BCM88850_DEVICE_ID J2P_DEVICE_ID +#define BCM88850_A0_REV_ID J2P_A0_REV_ID + +#define Q2A_DEVICE_ID 0x8480 +#define Q2A_A0_REV_ID DNXC_A0_REV_ID +#define Q2A_B0_REV_ID DNXC_B0_REV_ID +#define Q2A_B1_REV_ID DNXC_B1_REV_ID +#define BCM88480_DEVICE_ID Q2A_DEVICE_ID +#define BCM88480_A0_REV_ID Q2A_A0_REV_ID +#define BCM88480_B0_REV_ID Q2A_B0_REV_ID +#define BCM88480_B1_REV_ID Q2A_B1_REV_ID +#define BCM88481_DEVICE_ID 0x8481 +#define BCM88482_DEVICE_ID 0x8482 +#define BCM88483_DEVICE_ID 0x8483 +#define BCM88484_DEVICE_ID 0x8484 +#define BCM88485_DEVICE_ID 0x8485 +#define BCM88486_DEVICE_ID 0x8486 +#define BCM88487_DEVICE_ID 0x8487 +#define BCM88488_DEVICE_ID 0x8488 +#define BCM88489_DEVICE_ID 0x8489 +#define BCM8848A_DEVICE_ID 0x848A +#define BCM8848B_DEVICE_ID 0x848B +#define BCM8848C_DEVICE_ID 0x848C +#define BCM8848D_DEVICE_ID 0x848D +#define BCM8848E_DEVICE_ID 0x848E +#define BCM8848F_DEVICE_ID 0x848F #define QAX_DEVICE_ID 0x8470 #define QAX_A0_REV_ID 0x0001 @@ -1822,5 +1920,17 @@ #define PLX9056_DEVICE_ID 0x9056 +#ifdef BCM_LTSW_SUPPORT +#define BCM56880_DEVICE_ID 0xb880 +#define BCM56880_A0_REV_ID 0x0001 +#define BCM56880_B0_REV_ID 0x0011 +#define BCM56881_DEVICE_ID 0xb881 +#define BCM56881_A0_REV_ID 0x0001 +#define BCM56881_B0_REV_ID 0x0011 +#define BCM56883_DEVICE_ID 0xb883 +#define BCM56883_A0_REV_ID 0x0001 +#define BCM56883_B0_REV_ID 0x0011 + +#endif #endif diff --git a/platform/broadcom/saibcm-modules/make/Make.linux b/platform/broadcom/saibcm-modules/make/Make.linux index bd86ca351b6e..81e88daf16bc 100644 --- a/platform/broadcom/saibcm-modules/make/Make.linux +++ b/platform/broadcom/saibcm-modules/make/Make.linux @@ -85,7 +85,7 @@ endif build: $(MAKE) $(CMD) -DELIVER clean C_COMPILER CXX_COMPILER variable mod bcm user: +DELIVER clean C_COMPILER CXX_COMPILER variable mod bcm user issu: $(MAKE) $(CMD) $@ clean_d: clean @@ -93,5 +93,5 @@ clean_d: clean distclean: $(MAKE) $(CMD) $@ -.PHONY: build clean distclean clean_d DELIVER variable mod bcm user +.PHONY: build clean distclean clean_d DELIVER variable mod bcm user issu diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto index 786b4cc26bc3..4a20a99dac69 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto @@ -97,6 +97,21 @@ ifdef SHADOW_PLX CFLAGS += -DBCM_PLX9656_LOCAL_BUS -DBDE_LINUX_NON_INTERRUPTIBLE -DSHADOW_SVK endif +ifdef LTSW_CHIPS +# Default open source target build +OPENSRC_BUILD ?= uclibc_201402_ppc + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif + +export SYSTEM_INTERFACE +endif + ifeq (,$(KFLAGS)) KFLAGS := -D__KERNEL__ -m32 -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/uapi/linux/version.h -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/powerpc -I$(KERNDIR)/arch/powerpc/include -I$(KERNDIR)/include/asm-powerpc -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -msoft-float -pipe -ffixed-r2 -mmultiple -mno-altivec -funit-at-a-time -Wa,-me500 -fomit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-gts b/platform/broadcom/saibcm-modules/make/Makefile.linux-gts new file mode 100644 index 000000000000..ddc94afa13fe --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-gts @@ -0,0 +1,142 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# $Id: Makefile.linux-xlr-4_19,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# XLR system make file. +# +# Most of this was taken from target x86-smp_generic_64-2_6. +# + + +############################################################################# +# this segment is custom and not sourced from any existing makefile # +# (base thanks to http:confluence.broadcom.com/display/NTSWSW/X86+System) # +############################################################################# + +# set up a basic feature list. tcl, etc. # +#ifeq (,$(FEATURE_LIST)) +#FEATURE_LIST = TCL BFD PTP CINT L3 I2C MEM_SCAN EDITLINE BCM_SAL_PROFILE CUSTOMER TEST CHASSIS MSTP RCPU +#endif + +# some basic path variables for tools and kernel source, etc # +export XLR_TOOLS_BASE = /projects/ntsw-tools/linux/xlr-419 +TOOLCHAIN_DIR = $(XLR_TOOLS_BASE)/buildroot/host/usr +KERNDIR = $(XLR_TOOLS_BASE)/kernel/linux + +# set up cross compile prefix, tools dir variables. # +export CROSS_COMPILE := x86_64-broadcom-linux-gnu- +export TOOLS_DIR := $(TOOLCHAIN_DIR)/bin + +# architecture. # +ARCH = x86_64 +TARGET_ARCHITECTURE = x86_64-broadcom-linux-gnu + +# Noisy kernel build +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +# set up paths. # +export LIBRARY_PATH := $(TOOLCHAIN_DIR)/lib:$(TOOLCHAIN_DIR)/lib64:$(LIBRARY_PATH) +export PATH := $(TOOLCHAIN_DIR)/bin:$(KERNDIR):$(PATH) + +# set up SYSINC path # +export SYSINC := $(XLR_TOOLS_BASE)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/5.4.0/include + + +# CFLAGS/CFGFLAGS # +CFLAGS += -DUSE_LINUX_BDE_MMAP=1 +#CFLAGS += -DBDE_LINUX_USE_MSI_INTERRUPT +CFLAGS += -Wno-error=unused-value +CFLAGS += -Wno-error=unused-but-set-variable +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=cpp +CFLAGS += -Wno-error=aggressive-loop-optimizations +CFLAGS += -Wno-error=array-bounds +CFLAGS += -Wno-error=strict-overflow +CFLAGS += -L$(TOOLCHAIN_DIR)/lib +CFLAGS += -L$(TOOLCHAIN_DIR)/lib64 +#CFLAGS += -Wl,--rpath=/lib64 # may need to set rpath and dynamic-linker path here (and possibly in KLFAGS below) in the future, # +#CFLAGS += -Wl,--dynamic-linker=/lib64/ld-linux-x86-64.so.2 # if we want to build the target executable to be used with shared libs # + +#XLDK-568 fix inline references +CFGFLAGS += -fgnu89-inline + + +# set up KFLAGS appropriately. # +ifeq (,$(KFLAGS)) +KFLAGS := -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib64 -I$(KERNDIR) -lc -nostdinc -isystem $(SYSINC) -Iinclude -I$(KERNDIR)/arch/x86/include -I$(KERNDIR)/arch/x86/include/generated -I$(KERNDIR)/arch/x86/include/generated/uapi -I$(KERNDIR)/arch/x86/include/uapi -I$(KERNDIR)/include -I$(KERNDIR)/include/generated -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/include/uapi -include $(KERNDIR)/include/generated/autoconf.h -D__KERNEL__ -DNDEBUG -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -O2 -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -Wframe-larger-than=1024 -fno-omit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign -fno-dwarf2-cfi-asm -fconserve-stack +endif + + +###################################################################### +# this segment comes from make/Makefile.linux-x86-smp_generic_64-2_6 # +###################################################################### +CFGFLAGS += -DLONGS_ARE_64BITS +CFGFLAGS += -DPTRS_ARE_64BITS +CFGFLAGS += -DSAL_SPL_LOCK_ON_IRQ + + +############################################################## +# This segment comes from make/Makefile.linux-x86-common-2_6 # +############################################################## +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +CFGFLAGS += -D$(ENDIAN) +CFGFLAGS += -DBCM_PLATFORM_STRING=\"X86\" +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=32 + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ +-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +ifdef LTSW_CHIPS +# Ensure we do not use an out-of-date libelf.so +ELFUTILS_MIN = 158 +ELFUTILS_DIR ?= /projects/ntsw-tools/lib + +# Default open source target build +OPENSRC_BUILD ?= fed21-x86_64 + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif + +export SYSTEM_INTERFACE +endif + +ifneq ($(targetplat),user) +# By default we exclude -Werror from x86 kernel builds +BCM_CFLAGS = -Wall +include ${SDK}/make/Makefile.linux-kernel-2_6 +endif + + diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc index 092e474e2563..7d8adb98de38 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc @@ -27,11 +27,14 @@ endif # TARGET_ARCHITECTURE Compiler for target architecture # KERNDIR Kernel directory for iPROC-CMICd devices ifeq (BE,$(ENDIAN_MODE)) +#While BE mode is supported, it's use is very limited. We had a specific customer +#request for BE support but don't currently mainstream it. So a 5.1.0 version +#has not been built. Continue using 5.0.3 for any BE support TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50-be/XLDK32 TARGET_ARCHITECTURE:=armeb-broadcom-linux-uclibcgnueabi KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux else -TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50/XLDK32 +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk51/XLDK32 TARGET_ARCHITECTURE:= arm-broadcom-linux-uclibcgnueabi KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux endif @@ -44,9 +47,10 @@ endif TOOLCHAIN_BIN_DIR=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/bin override PATH:=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/$(TARGET_ARCHITECTURE)/bin:$(TOOLCHAIN_BIN_DIR):$(PATH) LD_LIBRARY_PATH=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib - export TOOLCHAIN_BIN_DIR LD_LIBRARY_PATH +CROSS_GCC_VER ?= $(shell $(TOOLCHAIN_BIN_DIR)/$(CROSS_COMPILE)gcc -dumpversion) + # Default Linux include directory ifeq (,$(LINUX_INCLUDE)) LINUX_INCLUDE := $(KERNDIR)/include @@ -61,6 +65,12 @@ ENDIAN = LE_HOST=1 endif CFLAGS += -fno-aggressive-loop-optimizations +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=array-bounds +CFLAGS += -fgnu89-inline +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 7)" "1" + CFLAGS += -Wno-error=bool-operation +endif CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\" @@ -82,7 +92,7 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") -KFLAG_INCLD ?= $(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.4/include +KFLAG_INCLD ?= $(LD_LIBRARY_PATH)/gcc/$(TARGET_ARCHITECTURE)/$(CROSS_GCC_VER)/include ifeq (,$(KFLAGS)) KFLAGS := -D__LINUX_ARM_ARCH__=7 -D__KERNEL__ -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm/include -I$(KERNDIR)/arch/arm/include/generated -I$(KERNDIR)/arch/arm/mach-iproc/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -marm -mabi=aapcs-linux -fno-pic -pipe -msoft-float -ffreestanding -march=armv7-a -mfpu=vfp -mfloat-abi=softfp -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mlong-calls diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-4_4 b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-4_4 new file mode 100644 index 000000000000..df31f84e9d8f --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc-4_4 @@ -0,0 +1,92 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# $Id: Makefile.linux-iproc Exp $ +# $Copyright: (c) 2007 Broadcom Corp. +# All Rights Reserved.$ +# Makefile for iproc-CMICd + +# User must select one platform from below.By default ARM_LINUX is selected. . +ifeq (,$(BUILD_PLATFORM)) +BUILD_PLATFORM=ARM_LINUX +endif + +# TOOLCHAIN_BASE_DIR Toolchain base directory for iPROC-CMICd devices +# TARGET_ARCHITECTURE Compiler for target architecture +# KERNDIR Kernel directory for iPROC-CMICd devices +ifeq (BE,$(ENDIAN_MODE)) +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk40-be/XLDK +TARGET_ARCHITECTURE:=armeb-broadcom-linux-uclibcgnueabi +KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux +else +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk40/XLDK +TARGET_ARCHITECTURE:= arm-broadcom-linux-uclibcgnueabi +KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux +endif + +ifeq (,$(CROSS_COMPILE)) +CROSS_COMPILE:= $(TARGET_ARCHITECTURE)- +endif + +# arm9tools +TOOLCHAIN_BIN_DIR=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/bin +override PATH:=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/$(TARGET_ARCHITECTURE)/bin:$(TOOLCHAIN_BIN_DIR):$(PATH) +LD_LIBRARY_PATH=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib + +export TOOLCHAIN_BIN_DIR LD_LIBRARY_PATH + +# Default Linux include directory +ifeq (,$(LINUX_INCLUDE)) +LINUX_INCLUDE := $(KERNDIR)/include +endif + +ifeq (BE,$(ENDIAN_MODE)) +CFGFLAGS += -DSYS_BE_PIO=1 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=1 +ENDIAN = BE_HOST=1 +else +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +endif + +CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD +CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\" + +ARCH = arm +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ + -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +KFLAG_INCLD ?= $(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.3/include + +ifeq (,$(KFLAGS)) +KFLAGS := -D__LINUX_ARM_ARCH__=7 -D__KERNEL__ -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm/include -I$(KERNDIR)/arch/arm/include/generated -I$(KERNDIR)/arch/arm/mach-iproc/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -marm -mabi=aapcs-linux -fno-pic -pipe -msoft-float -ffreestanding -march=armv7-a -mfpu=vfp -mfloat-abi=softfp -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mlong-calls +KFLAGS += -I$(LINUX_INCLUDE)/uapi -I$(LINUX_INCLUDE)/generated/uapi -I$(KERNDIR)/arch/arm/include/uapi -I$(KERNDIR)/arch/arm/include/generated/uapi +endif + +ifneq ($(targetplat),user) +include ${SDK}/make/Makefile.linux-kernel-3_6 +endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 new file mode 100644 index 000000000000..dbccd7e25734 --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 @@ -0,0 +1,106 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# $Id: Makefile.linux-iproc Exp $ +# $Copyright: (c) 2007 Broadcom Corp. +# All Rights Reserved.$ +# Makefile for iproc-CMICd + +# User must select one platform from below.By default ARM_LINUX is selected. . +ifeq (,$(BUILD_PLATFORM)) +BUILD_PLATFORM=ARM_LINUX +endif + +# TOOLCHAIN_BASE_DIR Toolchain base directory for iPROC-CMICd devices +# TARGET_ARCHITECTURE Compiler for target architecture +# KERNDIR Kernel directory for iPROC-CMICd devices +ifeq (BE,$(ENDIAN_MODE)) +#We've never actually built a 64 BE executable. Just here for any future +#customer requirements. +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk51-be/XLDK64 +TARGET_ARCHITECTURE ?= aarch64_be-broadcom-linux-uclibc +KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux +else +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk51/XLDK64 +TARGET_ARCHITECTURE ?= aarch64-broadcom-linux-uclibc +KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux +endif + +ifeq (,$(CROSS_COMPILE)) +CROSS_COMPILE:= $(TARGET_ARCHITECTURE)- +endif + +# A72 tools +TOOLCHAIN_BIN_DIR=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/bin +override PATH:=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/$(TARGET_ARCHITECTURE)/bin:$(TOOLCHAIN_BIN_DIR):$(PATH) +LD_LIBRARY_PATH=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib +export TOOLCHAIN_BIN_DIR LD_LIBRARY_PATH + +CROSS_GCC_VER ?= $(shell $(TOOLCHAIN_BIN_DIR)/$(CROSS_COMPILE)gcc -dumpversion) + +# Default Linux include directory +ifeq (,$(LINUX_INCLUDE)) +LINUX_INCLUDE := $(KERNDIR)/include +endif + +ifeq (BE,$(ENDIAN_MODE)) +CFGFLAGS += -DSYS_BE_PIO=1 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=1 +ENDIAN = BE_HOST=1 +else +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +endif + +CFLAGS += -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS +CFLAGS += -DPHYS_ADDRS_ARE_64BITS +CFLAGS += -fno-aggressive-loop-optimizations -fno-strict-overflow +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=array-bounds +CFLAGS += -fgnu89-inline +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 7)" "1" + CFLAGS += -Wno-error=bool-operation +endif + + +CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD +CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\" +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=16 + +ARCH = arm64 +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ + -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +KFLAG_INCLD ?= $(LD_LIBRARY_PATH)/gcc/$(TARGET_ARCHITECTURE)/$(CROSS_GCC_VER)/include + +ifeq (,$(KFLAGS)) +KFLAGS := -D__LINUX_ARM_ARCH__=8 -D__KERNEL__ -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm64/include -I$(KERNDIR)/arch/arm64/include/generated -I$(KERNDIR)/arch/arm64/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/generated/asm -I$(KERNDIR)/include/uapi -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/uapi -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -fno-pic -pipe -ffreestanding -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mcmodel=large +endif + +ifneq ($(targetplat),user) +include ${SDK}/make/Makefile.linux-kernel-3_6 +endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-slk b/platform/broadcom/saibcm-modules/make/Makefile.linux-slk new file mode 100644 index 000000000000..00131c2f2af9 --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-slk @@ -0,0 +1,146 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# $Id: Makefile.linux-slk-3_14,v 1.2 Broadcom SDK $ +# $Copyright: (c) 2013 Broadcom Corp. +# All Rights Reserved.$ +# Makefile for SLK(BCM957812) + +# User must select one platform from below.By default ARM_LINUX is selected. . +ifeq (,$(BUILD_PLATFORM)) +BUILD_PLATFORM=ARM_LINUX +endif + +# Toolchain base directory for NS2 XMC card +ifeq (BE,$(ENDIAN_MODE)) +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/toolchains/slk/linaro-be +TARGET_ARCHITECTURE:=aarch64_be-linux-gnu +KERNDIR ?= /projects/ntsw-tools/linux/iproc_ldks/slk-be/poky/brcm-released-source/git +else +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/toolchains/slk/linaro-le +# Compiler for target architecture +TARGET_ARCHITECTURE:= aarch64-linux-gnu +# Kernel directory +KERNDIR ?= /projects/ntsw-tools/linux/iproc_ldks/slk/poky/brcm-released-source/git +endif + +ifeq (,$(CROSS_COMPILE)) +CROSS_COMPILE:= $(TARGET_ARCHITECTURE)- +endif + +# armtools +TOOLCHAIN_BIN_DIR=$(TOOLCHAIN_BASE_DIR)/bin +override PATH:=$(TOOLCHAIN_BIN_DIR):$(PATH) +LD_LIBRARY_PATH=$(TOOLCHAIN_BASE_DIR)/lib + +export TOOLCHAIN_BIN_DIR LD_LIBRARY_PATH + +# Default Linux include directory +ifeq (,$(LINUX_INCLUDE)) +LINUX_INCLUDE := $(KERNDIR)/include +endif + +ifeq (BE,$(ENDIAN_MODE)) +CFGFLAGS += -DSYS_BE_PIO=1 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=1 +ENDIAN = BE_HOST=1 +else +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +endif + +CFGFLAGS += -D$(ENDIAN) -DBCM958525 +CFGFLAGS += -DBCM_PLATFORM_STRING=\"SLK_BCM957812\" +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=32 +ifeq (1,$(SLK_32BIT)) +CFGFLAGS += -DSAL_BDE_32BIT_USER_64BIT_KERNEL +else +CFGFLAGS += -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS +endif +CFGFLAGS += -DPHYS_ADDRS_ARE_64BITS + +CFLAGS += -Wno-unused-value -Wno-unused-but-set-variable -Wno-sizeof-pointer-memaccess -fno-aggressive-loop-optimizations + +ifdef DPP_CHIPS +CFLAGS += -DDUNE_BCM -D__DUNE_LINUX_BCM_CPU_PCP_DMA__ +CFGFLAGS += -DSOC_CM_FUNCTION +endif + +ifdef DFE_CHIPS +CFLAGS += -DDUNE_BCM +CFGFLAGS += -DSOC_CM_FUNCTION +endif + +ifdef SAND_CHIPS +CFLAGS += -D__DUNE_SLK_BCM_CPU__ -D__DUNE_LINUX_BCM_CPU_PCIE__ +endif + +# Enable cached DMA memory by default +ifeq (,$(SAL_BDE_USE_CACHED_DMA_MEM)) +SAL_BDE_USE_CACHED_DMA_MEM = 1 +endif +ifeq ($(SAL_BDE_USE_CACHED_DMA_MEM),1) +CFGFLAGS += -DSAL_BDE_CACHE_DMA_MEM +endif + +ifeq (1,$(SLK_32BIT)) +ARCH = arm +else +ARCH = arm64 +endif + +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ + -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +KFLAG_INCLD = $(TOOLCHAIN_BASE_DIR)/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.2/include + +ifeq (,$(KFLAGS)) +KFLAGS := -D__LINUX_ARM_ARCH__=8 -D__KERNEL__ -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm64/include -I$(KERNDIR)/arch/arm64/include/generated -I$(KERNDIR)/arch/arm64/include/generated/asm -I$(KERNDIR)/include/uapi -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/uapi -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -fno-pic -pipe -ffreestanding -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign +endif + +ifdef LTSW_CHIPS +# Default open source target build +ifeq (BE,$(ENDIAN_MODE)) +OPENSRC_BUILD ?= linaro_arm64_be +else +OPENSRC_BUILD ?= linaro_arm64_le +endif + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif + +export SYSTEM_INTERFACE +endif + +ifneq ($(targetplat),user) +include ${SDK}/make/Makefile.linux-kernel-3_6 +endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 index bf0ea85d578e..b443a3d4733d 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 @@ -48,4 +48,5 @@ AUTOCONF = $(KERNDIR)/include/linux/autoconf.h endif # gcc system include path +# SAI_FIXUP /* SDK-218654 */ SYSINC = $(shell $(CC) -print-search-dirs | grep install | cut -c 10-)include diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 index bc0230ec8226..8a97f3954301 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 @@ -29,17 +29,33 @@ KFLAGS := -nostdinc -isystem $(SYSINC) -I$(KERNDIR)/include -I$(KERNDIR)/arch/x8 endif ifeq ($(LINUX_MAKE_SHARED_LIB), 1) -KFLAGS += -fPIC -mcmodel=small + KFLAGS += -fPIC -mcmodel=small else -KFLAGS += -fno-pie -mcmodel=kernel + KFLAGS += -fno-pie -mcmodel=kernel endif LINUX_UAPI = $(LINUX_INCLUDE)/uapi +ifneq (,$(shell ls $(LINUX_UAPI) 2>/dev/null)) KFLAGS += -I$(LINUX_INCLUDE)/uapi -I$(LINUX_INCLUDE)/generated/uapi -I$(KERNDIR)/arch/x86/include/generated -I$(KERNDIR)/arch/x86/include/uapi -I$(KERNDIR)/arch/x86/include/generated/uapi +endif + +ifdef LTSW_CHIPS +# Ensure we do not use an out-of-date libelf.so +ELFUTILS_MIN = 158 +ELFUTILS_DIR ?= /projects/ntsw-tools/lib + +# Default open source target build +OPENSRC_BUILD ?= x86_64 + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif -ifeq (1,$(DEBIAN_LINUX_HEADER)) -KERNDIR_COMMON := $(subst amd64,common,$(KERNDIR)) -KFLAGS += -I$(KERNDIR_COMMON)/include -I$(KERNDIR_COMMON)/include/uapi -I$(KERNDIR_COMMON)/arch/x86/include -I$(KERNDIR_COMMON)/arch/x86/include/uapi +export SYSTEM_INTERFACE endif include ${SDK}/make/Makefile.linux-x86-common-2_6 diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-xlr b/platform/broadcom/saibcm-modules/make/Makefile.linux-xlr new file mode 100644 index 000000000000..ddc94afa13fe --- /dev/null +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-xlr @@ -0,0 +1,142 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# $Id: Makefile.linux-xlr-4_19,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# XLR system make file. +# +# Most of this was taken from target x86-smp_generic_64-2_6. +# + + +############################################################################# +# this segment is custom and not sourced from any existing makefile # +# (base thanks to http:confluence.broadcom.com/display/NTSWSW/X86+System) # +############################################################################# + +# set up a basic feature list. tcl, etc. # +#ifeq (,$(FEATURE_LIST)) +#FEATURE_LIST = TCL BFD PTP CINT L3 I2C MEM_SCAN EDITLINE BCM_SAL_PROFILE CUSTOMER TEST CHASSIS MSTP RCPU +#endif + +# some basic path variables for tools and kernel source, etc # +export XLR_TOOLS_BASE = /projects/ntsw-tools/linux/xlr-419 +TOOLCHAIN_DIR = $(XLR_TOOLS_BASE)/buildroot/host/usr +KERNDIR = $(XLR_TOOLS_BASE)/kernel/linux + +# set up cross compile prefix, tools dir variables. # +export CROSS_COMPILE := x86_64-broadcom-linux-gnu- +export TOOLS_DIR := $(TOOLCHAIN_DIR)/bin + +# architecture. # +ARCH = x86_64 +TARGET_ARCHITECTURE = x86_64-broadcom-linux-gnu + +# Noisy kernel build +KBUILD_VERBOSE = 1 + +export ARCH KBUILD_VERBOSE + +# set up paths. # +export LIBRARY_PATH := $(TOOLCHAIN_DIR)/lib:$(TOOLCHAIN_DIR)/lib64:$(LIBRARY_PATH) +export PATH := $(TOOLCHAIN_DIR)/bin:$(KERNDIR):$(PATH) + +# set up SYSINC path # +export SYSINC := $(XLR_TOOLS_BASE)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/5.4.0/include + + +# CFLAGS/CFGFLAGS # +CFLAGS += -DUSE_LINUX_BDE_MMAP=1 +#CFLAGS += -DBDE_LINUX_USE_MSI_INTERRUPT +CFLAGS += -Wno-error=unused-value +CFLAGS += -Wno-error=unused-but-set-variable +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=cpp +CFLAGS += -Wno-error=aggressive-loop-optimizations +CFLAGS += -Wno-error=array-bounds +CFLAGS += -Wno-error=strict-overflow +CFLAGS += -L$(TOOLCHAIN_DIR)/lib +CFLAGS += -L$(TOOLCHAIN_DIR)/lib64 +#CFLAGS += -Wl,--rpath=/lib64 # may need to set rpath and dynamic-linker path here (and possibly in KLFAGS below) in the future, # +#CFLAGS += -Wl,--dynamic-linker=/lib64/ld-linux-x86-64.so.2 # if we want to build the target executable to be used with shared libs # + +#XLDK-568 fix inline references +CFGFLAGS += -fgnu89-inline + + +# set up KFLAGS appropriately. # +ifeq (,$(KFLAGS)) +KFLAGS := -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib64 -I$(KERNDIR) -lc -nostdinc -isystem $(SYSINC) -Iinclude -I$(KERNDIR)/arch/x86/include -I$(KERNDIR)/arch/x86/include/generated -I$(KERNDIR)/arch/x86/include/generated/uapi -I$(KERNDIR)/arch/x86/include/uapi -I$(KERNDIR)/include -I$(KERNDIR)/include/generated -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/include/uapi -include $(KERNDIR)/include/generated/autoconf.h -D__KERNEL__ -DNDEBUG -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -O2 -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -Wframe-larger-than=1024 -fno-omit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign -fno-dwarf2-cfi-asm -fconserve-stack +endif + + +###################################################################### +# this segment comes from make/Makefile.linux-x86-smp_generic_64-2_6 # +###################################################################### +CFGFLAGS += -DLONGS_ARE_64BITS +CFGFLAGS += -DPTRS_ARE_64BITS +CFGFLAGS += -DSAL_SPL_LOCK_ON_IRQ + + +############################################################## +# This segment comes from make/Makefile.linux-x86-common-2_6 # +############################################################## +CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 +ENDIAN = LE_HOST=1 +CFGFLAGS += -D$(ENDIAN) +CFGFLAGS += -DBCM_PLATFORM_STRING=\"X86\" +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=32 + +# Extra variables. +EXTRA_CFLAGS = -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +comma = , +basetarget = $(basename $(notdir $@)) +modname = $(basetarget) + +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ +-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +ifdef LTSW_CHIPS +# Ensure we do not use an out-of-date libelf.so +ELFUTILS_MIN = 158 +ELFUTILS_DIR ?= /projects/ntsw-tools/lib + +# Default open source target build +OPENSRC_BUILD ?= fed21-x86_64 + +# Hardware interface (see $SDKLT/bcma/sys/probe directory) +SYSTEM_INTERFACE ?= ngbde + +# Turn on direct register access if running on real hardware. +ifeq (ngbde,$(SYSTEM_INTERFACE)) +LTSW_ADD_CPPFLAGS += -DBCMDRD_CONFIG_MEMMAP_DIRECT=1 +endif + +export SYSTEM_INTERFACE +endif + +ifneq ($(targetplat),user) +# By default we exclude -Werror from x86 kernel builds +BCM_CFLAGS = -Wall +include ${SDK}/make/Makefile.linux-kernel-2_6 +endif + + diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile index aedd487b1f11..cfd72d3a9216 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile @@ -55,14 +55,16 @@ THIS_MOD_NAME := linux-kernel-bde MODULE = $(LIBDIR)/$(THIS_MOD_NAME).o KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko -build: kernel_libs $(MODULE) $(KMODULE) +build: kernel_libs module $(KMODULE) else MODULE = $(LIBDIR)/linux-kernel-bde.o -build: kernel_libs $(MODULE) +build: kernel_libs module endif -$(MODULE): $(BLDDIR)/.tree kernel_libs $(BOBJS) +module: kernel_libs $(MODULE) + +$(MODULE): $(BLDDIR)/.tree $(BOBJS) mkdir -p $(@D) $(LD) $(MODULE_LDFLAGS) -r -d $(BOBJS) $(LIBS) -o $@ ifneq ($(kernel_version),2_4) diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c index 464a72bd3e41..3a60ac4dd54e 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c @@ -1,25 +1,21 @@ /* * Copyright 2017 Broadcom - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation (the "GPL"). - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 (GPLv2) for more details. - * + * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. */ + /* - * $Id: linux-kernel-bde.c,v 1.414 Broadcom SDK $ - * $Copyright: (c) 2005 Broadcom Corp. - * All Rights Reserved.$ - * * Linux Kernel BDE - * */ #include @@ -30,27 +26,32 @@ #include #include #include -#include #include #include "linux_shbde.h" +#define MEMCPY memcpy -#ifdef __GNUC__ -#if __GNUC__ == 8 +#ifdef CONFIG_X86_64 +#if (defined(__GNUC__) && (__GNUC__ == 8)) /* * Prevent gcc 8.1.10 using a compiler inline memcpy even if using -fno-builtin or * -fno-builtin-memcpy . * __inline_memcpy and __memcpy are kernel functions that may be used instead, * for either an inline or non-inline implementations of the function */ -#define MEMCPY __inline_memcpy -#else -#define MEMCPY memcpy -#endif /* __GNUC__ == 8 */ -#else /* ifdef __GNUC__ */ -#define MEMCPY memcpy -#endif /* ifdef __GNUC__ */ +#undef MEMCPY +#define MEMCPY __memcpy +#endif /* (defined(__GNUC__) && (__GNUC__ == 8)) */ +#endif /* CONFIG_X86_64 */ + + +#if defined(CMIC_SOFT_BYTE_SWAP) +#define CMIC_SWAP32(_x) ((((_x) & 0xff000000) >> 24) \ + | (((_x) & 0x00ff0000) >> 8) \ + | (((_x) & 0x0000ff00) << 8) \ + | (((_x) & 0x000000ff) << 24)) +#endif /* defined(CMIC_SOFT_BYTE_SWAP) */ #define PCI_USE_INT_NONE (-1) #define PCI_USE_INT_INTX (0) @@ -68,8 +69,15 @@ MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Kernel BDE"); MODULE_LICENSE("GPL"); -/* PCIe max payload */ -int maxpayload = 256; +/* + * PCIe max payload size in bytes. + * The default value if not specified to the kernel module by maxpayload is historically 256. + * The default value may be changed using the BDE_PCIE_MAXPAYLOAD_DEFAULT macro. + */ +#ifndef BDE_PCIE_MAXPAYLOAD_DEFAULT +#define BDE_PCIE_MAXPAYLOAD_DEFAULT 256 +#endif +int maxpayload = BDE_PCIE_MAXPAYLOAD_DEFAULT; LKM_MOD_PARAM(maxpayload, "i", int, 0); MODULE_PARM_DESC(maxpayload, "Limit maximum payload size and request size on PCIe devices"); @@ -256,6 +264,19 @@ struct bde_spi_device_id { uint32 spifreq; }; +/* Maximum number of I/O windows supported per device. */ +#define BDE_NUM_IOWIN_MAX 3 + +/* I/O memory window definition. */ +struct memwin_s { + + /* Physical address of I/O window. */ + resource_size_t addr; + + /* Size of I/O window (in bytes). */ + resource_size_t size; +}; + /* Control Data */ typedef struct bde_ctrl_s { struct list_head list; @@ -285,10 +306,7 @@ typedef struct bde_ctrl_s { struct device *dma_dev; #endif - /* Physical addresses */ - resource_size_t phys_address; - resource_size_t phys_address1; - resource_size_t phys_address2; + struct memwin_s iowin[BDE_NUM_IOWIN_MAX]; /* Secondary mapped base address */ sal_vaddr_t alt_base_addr; @@ -334,7 +352,7 @@ static int _cpu_ndevices = 0; #if defined(IPROC_CMICD) && defined(CONFIG_OF) #define ICFG_CHIP_ID_REG 0x10236000 -#define IHOST_CMICX_MAX_INTRS 128 +#define IHOST_CMICX_MAX_INTRS 129 static uint32 iproc_cmicx_irqs[IHOST_CMICX_MAX_INTRS]; #endif @@ -415,7 +433,7 @@ static void *cpu_address = NULL; /* PLX PCI-E Switch */ #define PLX_PEX8608_DEV_ID 0x8608 #define PLX_PEX8617_DEV_ID 0x8617 -#define PLX_PEX86XX_DEV_CTRL_REG 0x70 +#define PLX_PEX86XX_DEV_CTRL_REG 0x70 /* Broadcom BCM58525 */ #define BCM58525_PCI_VENDOR_ID 0x14E4 @@ -432,10 +450,11 @@ static void *cpu_address = NULL; #define IHOST_GICD_REG_ADDR_VALID(d, addr) \ (_devices[d].bde_dev.base_address1 && \ - (addr & 0xFFFFFF00) == _devices[d].phys_address1) + (addr & 0xFFFFFF00) == _devices[d].iowin[1].addr) #define IHOST_GICD_REG_ADDR_REMAP(d, addr) \ - (void *)(_devices[d].bde_dev.base_address1 + (addr - _devices[d].phys_address1)) + (void *)(_devices[d].bde_dev.base_address1 + \ + (addr - ((sal_vaddr_t)_devices[d].iowin[1].addr))) static uint32_t _read(int d, uint32_t addr); @@ -554,7 +573,8 @@ _eb_device_create(resource_size_t paddr, int irq, int rd_hw, int wr_hw) /* Map in the device */ ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(paddr, 0x10000); - ctrl->phys_address = paddr; + ctrl->iowin[0].addr = paddr; + ctrl->iowin[0].size = 0x10000; dev_rev_id = _read(dev_id, 0x178); /* CMIC_DEV_REV_ID */ @@ -590,7 +610,8 @@ sand_device_create(void) /* Map in the device */ /* FIX_ME: not realy map anything */ ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(0x40000000, 0x100000); - ctrl->phys_address = 0x40000000; + ctrl->iowin[0].addr = 0x40000000; + ctrl->iowin[0].size = 0x100000; ctrl->iLine = 0; ctrl->isr = NULL; @@ -695,7 +716,8 @@ iproc_cmicd_probe(struct platform_device *pldev) gprintk("Error mapping iProc CMIC registers"); return -1; } - ctrl->phys_address = memres->start; + ctrl->iowin[0].addr = memres->start; + ctrl->iowin[0].size = size; #ifdef CONFIG_OF if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { @@ -712,16 +734,18 @@ iproc_cmicd_probe(struct platform_device *pldev) memres = iproc_platform_get_resource(pldev, IORESOURCE_MEM, 1); if (memres) { ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(memres->start, memres->end - memres->start + 1); - ctrl->phys_address1 = memres->start; + ctrl->iowin[1].addr = memres->start; + ctrl->iowin[1].size = memres->end - memres->start + 1; } else { /* Use default address if not available in DTB */ ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(IHOST_GICD_REG_ADDR, IHOST_GICD_REG_REMAP_LEN); - ctrl->phys_address1 = IHOST_GICD_REG_ADDR; + ctrl->iowin[1].addr = IHOST_GICD_REG_ADDR; + ctrl->iowin[1].size = IHOST_GICD_REG_REMAP_LEN; } if (ctrl->bde_dev.base_address1) { if (debug >= 1) { gprintk("base_address1:0x%lx phys_address1:0x%lx\n", - (unsigned long)ctrl->bde_dev.base_address1, (unsigned long)ctrl->phys_address1); + (unsigned long)ctrl->bde_dev.base_address1, (unsigned long)ctrl->iowin[1].addr); } } else { gprintk("Error mapping ihost GICD registers\n"); @@ -753,9 +777,12 @@ iproc_cmicd_probe(struct platform_device *pldev) #ifdef CONFIG_OF if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { int i; + memset(iproc_cmicx_irqs, 0, IHOST_CMICX_MAX_INTRS*sizeof(uint32_t)); for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { irqres = iproc_platform_get_resource(pldev, IORESOURCE_IRQ, i); - iproc_cmicx_irqs[i] = irqres->start; + if (irqres) { + iproc_cmicx_irqs[i] = irqres->start; + } if (debug >= 1) { gprintk("iproc_cmicx_irqs[%d] = %d\n", i, iproc_cmicx_irqs[i]); } @@ -1019,7 +1046,8 @@ _ics_bde_create(void) /* Map in the device */ paddr = BCM_ICS_CMIC_BASE; ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(paddr, 0x10000); - ctrl->phys_address = paddr; + ctrl->iowin[0].addr = paddr; + ctrl->iowin[0].size = 0x10000; dev_rev_id = *((unsigned int *)(KSEG1ADDR(paddr + 0x178))); @@ -1399,6 +1427,8 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56174_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53570_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53575_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56070_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56071_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9656, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056, PCI_ANY_ID, PCI_ANY_ID }, { BCM53000_VENDOR_ID, BCM53000PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1463,6 +1493,7 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88683_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88684_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88685_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88687_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88380_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88381_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88202_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1493,8 +1524,38 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM8869B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM8869C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM8869D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8869E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM8869F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88800_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88821_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88826_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88802_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88803_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88804_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88805_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88806_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88820_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88822_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88823_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88824_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88825_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88480_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88481_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88482_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88483_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88484_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88485_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88486_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88487_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88488_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88489_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848A_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8848F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88850_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, #endif /* BCM_DNX_SUPPORT */ #ifdef BCM_DFE_SUPPORT { BROADCOM_VENDOR_ID, BCM88750_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1546,6 +1607,12 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56832_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56836_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56870_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56273_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56274_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56275_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56276_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56277_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56278_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56370_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56371_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56372_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1568,6 +1635,9 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM53547_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53548_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53549_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56470_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56471_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56472_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { 0, 0, 0, 0 } };; @@ -2180,7 +2250,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) resource_size_t paddr; uint16 cmd = 0; uint32 bar_len; - int cmic_bar; + int i, cmic_bar; int baroff = 0; int iproc = 0; int plx_dev = 0; @@ -2219,7 +2289,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) } } #endif /* IPROC_CMICD */ - + /* * Note that a few supported devices have a non-Broadcom PCI vendor ID, * but since none of their associated PCI device IDs collide with the @@ -2441,7 +2511,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) ((PCI_FIND_DEV(BCM58525_PCI_VENDOR_ID, BCM58522_PCI_DEVICE_ID, NULL)) != NULL) || ((PCI_FIND_DEV(BCM58712_PCI_VENDOR_ID, BCM58712_PCI_DEVICE_ID, NULL)) != NULL) ) { /* BCM58525/BCM58712 CPU boards support 128 Max payload size */ - if (maxpayload) { + if (maxpayload && maxpayload != 128) { maxpayload = 128; if (debug >= 1) gprintk("force max payload size to 128\n"); } @@ -2500,19 +2570,6 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) } #endif /* BCM_DFE_SUPPORT */ -#if defined(BCM_DNXF_SUPPORT) - /*All Ramon devices from 0x8790 to 0x879F*/ - if ((dev->device & BCM_DNXF_DEVID_MASK) == BCM88790_DEVICE_ID) { - /* - * For DMA transactions - set Max_Payload_Size and - * Max_Read_Request_Size to 128 bytes. - */ - pci_write_config_byte(dev, 0xb5, 0x0c); - pci_write_config_byte(dev, 0xb4, 0x0); - - } -#endif - /* Prevent compiler warning */ if (ctrl == NULL) { return 0; @@ -2523,6 +2580,15 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) ctrl->pci_device = dev; pci_set_drvdata(dev, ctrl); + /* + * Sample setting of unique ID, used the PCIe address of the device: + * domain, bus, slot, function in hex digits: DDDDBBSS (SS includes the slot/device and function. + * Tested with old kernels from 2.6 . + * Do not use the PCI_DEVID macro which old kernel versions don't have. */ + ctrl->bde_dev.dev_unique_id = dev->bus ? + (((uint32)pci_domain_nr(dev->bus)) << 16) ^ (((uint32)dev->bus->number) << 8) ^ dev->devfn : + dev->devfn; + /* Check for iProc device */ if (shbde_pci_is_iproc(shbde, dev, &cmic_bar)) { iproc = 1; @@ -2557,13 +2623,21 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) } ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(paddr, bar_len); - ctrl->phys_address = paddr; + ctrl->iowin[0].addr = paddr; + ctrl->iowin[0].size = bar_len; + if (debug >= 3) { gprintk("BAR %d: kernel addr:0x%lx phys addr:0x%lx length:%lx\n", baroff, (unsigned long)ctrl->bde_dev.base_address, (unsigned long)paddr, (unsigned long)bar_len); } /* Map secondary address spaces */ + for (i = 1; i < BDE_NUM_IOWIN_MAX; i++) { + ctrl->iowin[i].addr = 0; + ctrl->iowin[i].size = 0; + } + ctrl->bde_dev.base_address1 = 0; + if (iproc #ifdef DNX_TEST_BOARD || (dev->device == PLX9056_DEVICE_ID && baroff == 2) @@ -2572,7 +2646,8 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) paddr = pci_resource_start(dev, 0); bar_len = pci_resource_len(dev, 0); ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(paddr, bar_len); - ctrl->phys_address1 = paddr; + ctrl->iowin[1].addr = paddr; + ctrl->iowin[1].size = bar_len; if (debug >= 3) { gprintk("BAR 0: kernel addr:0x%lx phys addr:0x%lx length:%lx\n", (unsigned long)ctrl->bde_dev.base_address1, (unsigned long)paddr, (unsigned long)bar_len); @@ -2773,7 +2848,8 @@ map_local_bus(uint64_t addr, uint32_t size) /* Map in the device */ ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(addr, size); - ctrl->phys_address = addr; + ctrl->iowin[0].addr = addr; + ctrl->iowin[0].size = size; _bde_add_device(); return(ctrl); @@ -2817,7 +2893,8 @@ map_local_bus2(bde_ctrl_t *plx_ctrl, uint32_t dev_base, uint32_t size) /* Map in the device */ ctrl->bde_dev.base_address = plx_ctrl->bde_dev.base_address + dev_base; - ctrl->phys_address = plx_ctrl->phys_address + (resource_size_t)dev_base; + ctrl->iowin[0].addr = plx_ctrl->iowin[0].addr + (resource_size_t)dev_base; + ctrl->iowin[0].size = size; #if 1 addr = (uint8_t *)ctrl->bde_dev.base_address + PL0_REVISION_REG; @@ -2850,12 +2927,12 @@ probe_plx_local_bus(void) } addr_hi_str[0] = 0; #ifdef PHYS_ADDR_IS_64BIT - sprintf(addr_hi_str, "%08x", (uint32_t)(plx_ctrl.phys_address >> 32)); + sprintf(addr_hi_str, "%08x", (uint32_t)(plx_ctrl.iowin[0].addr >> 32)); #endif printk(KERN_ERR "Found PLX %04x:%04x vir: 0x%08x phy: 0x%s%08x\n", plx_ctrl.bde_dev.device, plx_ctrl.bde_dev.rev, plx_ctrl.bde_dev.base_address, addr_hi_str, - (uint32_t)(plx_ctrl.phys_address)); + (uint32_t)(plx_ctrl.iowin[0].addr)); addr = (uint8_t *)plx_ctrl.bde_dev.base_address + CPLD_OFFSET + CPLD_REVISION_REG; val = readl(addr); @@ -2947,9 +3024,9 @@ _init(void) } #else if (use_msi > PCI_USE_INT_INTX) { - /* Warn if invalid configuration */ - gprintk("MSI interrupts not supported by kernel\n"); - } + /* Warn if invalid configuration */ + gprintk("MSI interrupts not supported by kernel\n"); + } use_msi = PCI_USE_INT_INTX; #endif /* CONFIG_PCI_MSI */ @@ -3079,6 +3156,10 @@ _pprint(void) pprintf("Broadcom Device Enumerator (%s)\n", LINUX_KERNEL_BDE_NAME); + pprintf("Module parameters:\n"); + pprintf("\tmaxpayload=%d\n", maxpayload); + pprintf("\tusemsi=%d\n", usemsi); + _dma_pprint(); if (_ndevices == 0) { @@ -3134,7 +3215,7 @@ _pprint(void) pprintf("AXI Device 0x%x:0x%x:0x%.8lx:%d\n", ctrl->bde_dev.device, ctrl->bde_dev.rev, - (unsigned long)ctrl->phys_address, + (unsigned long)ctrl->iowin[0].addr, ctrl->iLine); } else if (ctrl->dev_type & BDE_EB_DEV_TYPE) { pprintf("EB Bus Device 0x%x:0x%x\n", @@ -3150,6 +3231,54 @@ _pprint(void) } return 0; } +/* + * Some kernels are configured to prevent mapping of kernel RAM memory + * into user space via the /dev/mem device. + * + * The function below provides a backdoor to map IO and DMA memory to + * user space via the BDE device file. + */ +static int +_bde_mmap(struct file *filp, struct vm_area_struct *vma) +{ + unsigned long paddr = vma->vm_pgoff << PAGE_SHIFT; + unsigned long size = vma->vm_end - vma->vm_start; + int i, j, pio_range_valid = 0; + + for(i = 0; i < _ndevices; i++) { + bde_ctrl_t *ctrl = _devices + i; + if (ctrl->dev_type & BDE_SWITCH_DEV_TYPE) { + for (j = 0; j < BDE_NUM_IOWIN_MAX; j++) { + if (paddr >= (unsigned long)ctrl->iowin[j].addr && + (paddr + size) <= (unsigned long)(ctrl->iowin[j].addr + ctrl->iowin[j].size)) { + pio_range_valid = 1; + break; + } + if ((ctrl->dev_type & BDE_AXI_DEV_TYPE) && (paddr == ctrl->iowin[j].addr)) { + pio_range_valid = 1; + break; + } + } + } + } + + if (pio_range_valid) { + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (remap_pfn_range(vma, + vma->vm_start, + vma->vm_pgoff, + size, + vma->vm_page_prot)) { + gprintk("Failed to mmap phys range 0x%lx-0x%lx to 0x%lx-0x%lx\n", + paddr, paddr + size, vma->vm_start,vma->vm_end); + return -EAGAIN; + } + return 0; + } + + return _dma_mmap(filp, vma); +} /* Workaround for broken Busybox/PPC insmod */ static char _modname[] = LINUX_KERNEL_BDE_NAME; @@ -3160,7 +3289,7 @@ static gmodule_t _gmodule = { init: _init, cleanup: _cleanup, pprint: _pprint, - mmap: _dma_mmap, + mmap: _bde_mmap, }; gmodule_t * @@ -3479,6 +3608,9 @@ _interrupt_connect(int d, if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { int i, j; for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { + if (!iproc_cmicx_irqs[i]) { + continue; + } if (unlikely(debug >= 1)) gprintk("%s(%d):device# = %d, request_irq(%d)\n", __func__, __LINE__, d, iproc_cmicx_irqs[i]); @@ -3491,6 +3623,9 @@ _interrupt_connect(int d, } if (ret < 0) { for (j = 0; j < i; j++) { + if (!iproc_cmicx_irqs[j]) { + continue; + } free_irq(iproc_cmicx_irqs[j], ctrl); } goto err_disable_msi; @@ -3519,10 +3654,10 @@ _interrupt_connect(int d, msi_exit: #endif gprintk("could not request IRQ\n"); - ctrl->isr = NULL; - ctrl->isr_data = NULL; - ctrl->isr2 = NULL; - ctrl->isr2_data = NULL; + ctrl->isr = NULL; + ctrl->isr_data = NULL; + ctrl->isr2 = NULL; + ctrl->isr2_data = NULL; return -1; } @@ -3600,6 +3735,9 @@ _interrupt_disconnect(int d) if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { int i; for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { + if (!iproc_cmicx_irqs[i]) { + continue; + } if (unlikely(debug > 1)) { gprintk("%s(%d):device# = %d, free_irq(%d)\n", __func__, __LINE__, d, iproc_cmicx_irqs[i]); @@ -3862,10 +4000,10 @@ lkbde_cpu_pci_register(int d) case BCM88683_DEVICE_ID: case BCM88684_DEVICE_ID: case BCM88685_DEVICE_ID: + case BCM88687_DEVICE_ID: case BCM88380_DEVICE_ID: case BCM88381_DEVICE_ID: case BCM88680_DEVICE_ID: - case BCM88800_DEVICE_ID: case BCM88470_DEVICE_ID: case BCM88470P_DEVICE_ID: case BCM88471_DEVICE_ID: @@ -3915,34 +4053,41 @@ lkbde_cpu_pci_register(int d) break; } + /* configure iproc >=14 devices by device family */ +#if defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) + switch (ctrl->bde_dev.device & DNXC_DEVID_FAMILY_MASK) { #ifdef BCM_DNX_SUPPORT - /*All Jericho 2 devices from 0x8690 to 0x869F*/ - if (SOC_IS_JERICHO_2_TYPE(ctrl->bde_dev.device)) { - /* Fix bar 0 address */ /* FIXME: write full phy address */ - pci_write_config_byte(ctrl->pci_device, 0x12, 0x10); - pci_write_config_byte(ctrl->pci_device, 0x13, 0x60); - + case JERICHO2_DEVICE_ID: + case J2C_DEVICE_ID: + case J2C_2ND_DEVICE_ID: + case Q2A_DEVICE_ID: + case J2P_DEVICE_ID: +#endif +#ifdef BCM_DNXF_SUPPORT + case BCM88790_DEVICE_ID: +#endif /* * For DMA transactions - set Max_Payload_Size and * Max_Read_Request_Size to 128 bytes. */ pci_write_config_byte(ctrl->pci_device, 0xb5, 0x0c); pci_write_config_byte(ctrl->pci_device, 0xb4, 0x0); + break; } -#endif +#endif /* defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) */ /* Redo ioremap */ if (ctrl->bde_dev.base_address) { iounmap((void *)ctrl->bde_dev.base_address); } - ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(ctrl->phys_address, 0x1000000); + ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(ctrl->iowin[0].addr, 0x1000000); if (debug >= 1) { gprintk("%s, %s(): info:\n", __FILE__, __FUNCTION__); gprintk("_ndevices=%d, _switch_ndevices=%d\n", _ndevices, _switch_ndevices); gprintk("ctrl->dev_type=0x%x, ctrl->phys_address=0x%lx\n", - ctrl->dev_type, (unsigned long)ctrl->phys_address); + ctrl->dev_type, (unsigned long)ctrl->iowin[0].addr); gprintk("ctrl->bde_dev.device=0x%x, ctrl->bde_dev.rev=0x%x, " "ctrl->bde_dev.base_address=0x%lx\n", ctrl->bde_dev.device, ctrl->bde_dev.rev, @@ -4089,7 +4234,7 @@ lkbde_get_dev_phys(int d) d, _devices[d].dev_type); return 0; } - return _devices[d].phys_address; + return _devices[d].iowin[0].addr; } uint32_t @@ -4105,7 +4250,7 @@ lkbde_get_dev_phys_hi(int d) return 0; } #ifdef PHYS_ADDR_IS_64BIT - return (uint32_t)(_devices[d].phys_address >> 32); + return (uint32_t)(_devices[d].iowin[0].addr >> 32); #else return 0; #endif @@ -4151,15 +4296,15 @@ lkbde_get_dev_resource(int d, int rsrc, uint32_t *flags, switch (rsrc) { case 0: - *phys_lo = (uint32_t)(_devices[d].phys_address); + *phys_lo = (uint32_t)(_devices[d].iowin[0].addr); #ifdef PHYS_ADDR_IS_64BIT - *phys_hi = (uint32_t)(_devices[d].phys_address >> 32); + *phys_hi = (uint32_t)(_devices[d].iowin[0].addr >> 32); #endif break; case 1: - *phys_lo = (uint32_t)(_devices[d].phys_address1); + *phys_lo = (uint32_t)(_devices[d].iowin[1].addr); #ifdef PHYS_ADDR_IS_64BIT - *phys_hi = (uint32_t)(_devices[d].phys_address1 >> 32); + *phys_hi = (uint32_t)(_devices[d].iowin[1].addr >> 32); #endif break; default: @@ -4286,7 +4431,7 @@ lkbde_irq_mask_set(int d, uint32_t addr, uint32_t mask, uint32_t fmask) if (iproc_reg) { _iproc_write(d, addr, ctrl->imask | ctrl->imask2); } else { - _write(d, addr, ctrl->imask | ctrl->imask2); + _write(d, addr, ctrl->imask | ctrl->imask2); } spin_unlock_irqrestore(&ctrl->lock, flags); @@ -4326,7 +4471,7 @@ lkbde_irq_mask_get(int d, uint32_t *mask, uint32_t *fmask) *fmask = ctrl->fmask; *mask = ctrl->imask | ctrl->imask2; - + return 0; } diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c index eb3dc0495195..4f9518e9f4a9 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c @@ -67,6 +67,10 @@ #include #include +#if defined(IPROC_CMICD) && defined(CONFIG_OF) +#include +#endif + #ifdef BCM_PLX9656_LOCAL_BUS #include #endif @@ -117,9 +121,9 @@ #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) -#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((d),(p)) +#define BDE_DMA_MAPPING_ERROR(d, p) dma_mapping_error((d),(p)) #else -#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((p)) +#define BDE_DMA_MAPPING_ERROR(d, p) dma_mapping_error((p)) #endif #ifndef KMALLOC_MAX_SIZE @@ -612,6 +616,15 @@ static void _alloc_mpool(size_t size) { unsigned long pbase = 0; + struct device *dev = DMA_DEV(DMA_DEV_INDEX); + int dma64_support = 0; + +#if defined(IPROC_CMICD) && defined(CONFIG_OF) + if (of_find_compatible_node(NULL, NULL, "brcm,iproc-cmicx")) { + dma64_support = 1; + } +#endif + #if defined(__arm__) && !defined(CONFIG_HIGHMEM) if (_use_himem) { gprintk("DMA in high memory requires CONFIG_HIGHMEM on ARM CPUs.\n"); @@ -647,8 +660,8 @@ _alloc_mpool(size_t size) /* get a memory allocation from the kernel */ { dma_addr_t dma_handle; - if (!(_dma_vbase = dma_alloc_coherent(DMA_DEV(DMA_DEV_INDEX), - alloc_size, &dma_handle, GFP_KERNEL)) || !dma_handle) { + _dma_vbase = dma_alloc_coherent(dev, alloc_size, &dma_handle, GFP_KERNEL); + if (!_dma_vbase || !dma_handle) { gprintk("Failed to allocate coherent memory pool of size 0x%lx\n", (unsigned long)alloc_size); return; } @@ -672,9 +685,9 @@ _alloc_mpool(size_t size) } _cpu_pbase = virt_to_bus(_dma_vbase); /* Use dma_map_single to obtain DMA bus address or IOVA if iommu is present. */ - if (DMA_DEV(DMA_DEV_INDEX)) { - pbase = dma_map_single(DMA_DEV(DMA_DEV_INDEX), _dma_vbase, size, DMA_BIDIRECTIONAL); - if (DMA_MAPPING_ERROR(DMA_DEV(DMA_DEV_INDEX), pbase)) { + if (dev) { + pbase = dma_map_single(dev, _dma_vbase, size, DMA_BIDIRECTIONAL); + if (BDE_DMA_MAPPING_ERROR(dev, pbase)) { gprintk("Failed to map memory at %p\n", _dma_vbase); _pgcleanup(); _dma_vbase = NULL; @@ -692,7 +705,9 @@ _alloc_mpool(size_t size) return; } - if (((pbase + (size - 1)) >> 16) > DMA_BIT_MASK(16)) { + _dma_pbase = pbase; + + if (!dma64_support && ((pbase + (size - 1)) >> 16) > DMA_BIT_MASK(16)) { gprintk("DMA memory allocated at 0x%lx size 0x%lx is beyond the 4GB limit and not supported.\n", pbase, (unsigned long)size); _pgcleanup(); _dma_vbase = NULL; @@ -700,14 +715,13 @@ _alloc_mpool(size_t size) return; } - _dma_pbase = pbase; #ifdef REMAP_DMA_NONCACHED _dma_vbase = IOREMAP(_dma_pbase, size); #endif if (dma_debug >= 1) { - gprintk("_use_dma_mapping:%d _dma_vbase:%p _dma_pbase:%lx _cpu_pbase:%lx allocated:%lx dmaalloc:%d\n", + gprintk("_use_dma_mapping:%d _dma_vbase:%p _dma_pbase:%lx _cpu_pbase:%lx allocated:%lx dmaalloc:%d, dma64_support:%d\n", _use_dma_mapping, _dma_vbase, (unsigned long)_dma_pbase, - (unsigned long)_cpu_pbase, (unsigned long)size, dmaalloc); + (unsigned long)_cpu_pbase, (unsigned long)size, dmaalloc, dma64_support); } } } @@ -749,7 +763,7 @@ void _dma_init(int dev_index) if (dev_index > DMA_DEV_INDEX) { if (_use_dma_mapping && DMA_DEV(dev_index) && _dma_vbase) { pbase = dma_map_single(DMA_DEV(dev_index), _dma_vbase, _dma_mem_size, DMA_BIDIRECTIONAL); - if (DMA_MAPPING_ERROR(DMA_DEV(dev_index), pbase)) { + if (BDE_DMA_MAPPING_ERROR(DMA_DEV(dev_index), pbase)) { gprintk("Failed to map memory for device %d at %p\n", dev_index, _dma_vbase); return; } @@ -992,6 +1006,9 @@ lkbde_get_dma_info(phys_addr_t* cpu_pbase, phys_addr_t* dma_pbase, ssize_t* size void _dma_pprint(void) { + pprintf("\tdmasize=%s\n", dmasize); + pprintf("\thimem=%s\n", himem); + pprintf("\thimemaddr=%s\n", himemaddr); pprintf("DMA Memory (%s): %d bytes, %d used, %d free%s\n", (_use_himem) ? "high" : "kernel", (_dma_vbase) ? _dma_mem_size : 0, diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c index 370f89e022c4..46f60c8a3ae9 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c @@ -1,23 +1,20 @@ /* * Copyright 2017 Broadcom - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation (the "GPL"). - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 (GPLv2) for more details. - * + * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. */ + /* - * $Id: linux-user-bde.c,v 1.80 Broadcom SDK $ - * $Copyright: (c) 2005 Broadcom Corp. - * All Rights Reserved.$ - * * Linux User BDE Helper Module */ #include @@ -81,6 +78,17 @@ The INTR base address values are changed for HX5, hence making new #defines so runtime decisions can be made. */ +#define PAXB_0_PAXB_IC_INTRCLR_0 (0x180123a0) +#define PAXB_0_PAXB_IC_INTRCLR_1 (0x180123a4) + +#define PAXB_0_PAXB_IC_INTRCLR_MODE_0 (0x180123a8) +#define PAXB_0_PAXB_IC_INTRCLR_MODE_1 (0x180123ac) + +#define HX5_PAXB_0_PAXB_IC_INTRCLR_0 (0x102303a0) +#define HX5_PAXB_0_PAXB_IC_INTRCLR_1 (0x102303a4) + +#define HX5_PAXB_0_PAXB_IC_INTRCLR_MODE_0 (0x102303a8) +#define HX5_PAXB_0_PAXB_IC_INTRCLR_MODE_1 (0x102303ac) #define INTC_INTR_ENABLE_REG0 (0x180130f0) #define INTC_INTR_STATUS_REG0 (0x18013190) @@ -104,12 +112,18 @@ be made. #define HX5_IHOST_GICD_ISENABLERN_1 (0x10781104) #define HX5_IHOST_GICD_ICENABLERN_1 (0x10781184) #define HX5_IHOST_GICD_ICENABLERN_8 (0x107811a0) +#define HX5_IHOST_GICD_ISPENDRN_8 (0x10781220) /* Offset between ISENABLERN_1 and ICENABLERN_1 in 4-bytes */ #define HX5_IHOST_IRQ_MASK_OFFSET 0x20 -#define HX5_IHOST_INTR_MAP_NUM (HX5_IHOST_GICD_ICENABLERN_8 - HX5_IHOST_GICD_ISENABLERN_0) +/* Offset between ISENABLERN_1 and ISPENDRN_1 in 4-bytes */ +#define HX5_IHOST_IRQ_PEND_OFFSET 0x40 +#define HX5_IHOST_INTR_MAP_NUM (HX5_IHOST_GICD_ISPENDRN_8 - HX5_IHOST_GICD_ISENABLERN_0) #define HX5_IHOST_INTR_STATUS_MAP_NUM (INTC_INTR_REG_NUM * (sizeof(uint32))) #define IRQ_BIT(intr) (intr % (sizeof(uint32)*8)) #define IRQ_MASK_INDEX(intr) (intr / (sizeof(uint32)*8)) +#define HX5_SW_PROG_INTR_PRIORITY 73 +#define INTR_SW_PROG_INTR_BITPOS (1 << IRQ_BIT(HX5_SW_PROG_INTR_PRIORITY)) +#define INTC_SW_PROG_INTR_REG_IND IRQ_MASK_INDEX(HX5_SW_PROG_INTR_PRIORITY) #define HX5_CHIP_INTR_LOW_PRIORITY 119 #define INTR_LOW_PRIORITY_BITPOS (1 << IRQ_BIT(HX5_CHIP_INTR_LOW_PRIORITY)) #define INTC_LOW_PRIORITY_INTR_REG_IND IRQ_MASK_INDEX(HX5_CHIP_INTR_LOW_PRIORITY) @@ -141,10 +155,25 @@ be made. static uint32 *ihost_intr_status_base = NULL; static uint32 *ihost_intr_enable_base = NULL; +/* Debug output */ +static int debug; +LKM_MOD_PARAM(debug, "i", int, (S_IRUGO | S_IWUSR)); +MODULE_PARM_DESC(debug, +"Set debug level (default 0)."); + static ibde_t *user_bde = NULL; typedef void (*isr_f)(void *); +typedef struct _intr_regs_s { + uint32 intc_intr_status_base; + uint32 intc_intr_enable_base; + uint32 intc_intr_clear_0; + uint32 intc_intr_clear_1; + uint32 intc_intr_clear_mode_0; + uint32 intc_intr_clear_mode_1; +} _intr_regs_t; + typedef struct bde_ctrl_s { uint32 dev_type; int irq; @@ -153,6 +182,7 @@ typedef struct bde_ctrl_s { isr_f isr; uint32 *ba; int inst; /* associate to _bde_inst_resource[] */ + _intr_regs_t intr_regs; } bde_ctrl_t; #define VALID_DEVICE(_n) (_n < LINUX_BDE_MAX_DEVICES) @@ -178,6 +208,10 @@ typedef struct { } bde_inst_resource_t; static bde_inst_resource_t _bde_inst_resource[LINUX_BDE_MAX_DEVICES]; +/* + * Lock used to protect changes to _bde_inst_resource + */ +static spinlock_t bde_resource_lock; typedef struct { phys_addr_t cpu_pbase; /* CPU physical base address of the DMA pool */ @@ -263,44 +297,33 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) int d, ind; uint32 stat, iena, mask, fmask; bde_inst_resource_t *res; - uint32 intc_intr_status_base = 0, intc_intr_enable_base = 0; d = (((uint8 *)ctrl - (uint8 *)_devices) / sizeof (bde_ctrl_t)); + + if (ctrl->dev_type & BDE_PCI_DEV_TYPE) { + /* Clear MSI interrupts immediately to prevent spurious interrupts */ + WRITE_INTC_INTR(d, ctrl->intr_regs.intc_intr_clear_0, 0xFFFFFFFF); + WRITE_INTC_INTR(d, ctrl->intr_regs.intc_intr_clear_1, 0xFFFFFFFF); + } + res = &_bde_inst_resource[ctrl->inst]; lkbde_irq_mask_get(d, &mask, &fmask); - if ((ctrl->dev_type & BDE_SWITCH_DEV_TYPE) && - ((user_bde->get_dev(d)->device == BCM56370_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56371_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56372_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56374_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56375_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56376_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56377_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56577_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56578_DEVICE_ID) || - (user_bde->get_dev(d)->device == BCM56579_DEVICE_ID))) { - intc_intr_status_base = HX5_INTC_INTR_STATUS_BASE; - intc_intr_enable_base = HX5_INTC_INTR_ENABLE_BASE; - } else { - intc_intr_status_base = INTC_INTR_STATUS_BASE; - intc_intr_enable_base = INTC_INTR_ENABLE_BASE; - } if (fmask) { if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { IHOST_READ_INTR(d, ihost_intr_status_base + INTC_PDMA_INTR_REG_IND, stat); IHOST_READ_INTR(d, ihost_intr_enable_base + INTC_PDMA_INTR_REG_IND, iena); } else { - READ_INTC_INTR(d, intc_intr_status_base + 4 * INTC_PDMA_INTR_REG_IND, stat); - READ_INTC_INTR(d, intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, iena); + READ_INTC_INTR(d, ctrl->intr_regs.intc_intr_status_base + 4 * INTC_PDMA_INTR_REG_IND, stat); + READ_INTC_INTR(d, ctrl->intr_regs.intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, iena); } if (stat & iena) { if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { IHOST_WRITE_INTR(d, ihost_intr_enable_base + INTC_PDMA_INTR_REG_IND + HX5_IHOST_IRQ_MASK_OFFSET, ~0); } else { - WRITE_INTC_INTR(d, intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, 0); + WRITE_INTC_INTR(d, ctrl->intr_regs.intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, 0); } for (ind = 0; ind < INTC_INTR_REG_NUM; ind++) { @@ -308,17 +331,21 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) continue; } if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { - if (ind < INTC_LOW_PRIORITY_INTR_REG_IND) { + if (ind < INTC_SW_PROG_INTR_REG_IND) { continue; } - IHOST_READ_INTR(d, ihost_intr_status_base + ind, stat); - IHOST_READ_INTR(d, ihost_intr_enable_base + ind, iena); - if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { - stat &= INTR_LOW_PRIORITY_BITPOS; + if (ind == INTC_SW_PROG_INTR_REG_IND) { + IHOST_READ_INTR(d, ihost_intr_enable_base + ind + HX5_IHOST_IRQ_PEND_OFFSET, stat); + stat &= INTR_SW_PROG_INTR_BITPOS; + } else { + IHOST_READ_INTR(d, ihost_intr_status_base + ind, stat); + if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { + stat &= INTR_LOW_PRIORITY_BITPOS; + } } } else { - READ_INTC_INTR(d, intc_intr_status_base + 4 * ind, stat); - READ_INTC_INTR(d, intc_intr_enable_base + 4 * ind, iena); + READ_INTC_INTR(d, ctrl->intr_regs.intc_intr_status_base + 4 * ind, stat); + READ_INTC_INTR(d, ctrl->intr_regs.intc_intr_enable_base + 4 * ind, iena); } if (stat & iena) { break; @@ -340,10 +367,13 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) continue; } if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { - if (ind < INTC_LOW_PRIORITY_INTR_REG_IND) { + if (ind < INTC_SW_PROG_INTR_REG_IND) { continue; } - if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { + if (ind == INTC_SW_PROG_INTR_REG_IND) { + IHOST_WRITE_INTR(d, ihost_intr_enable_base + INTC_SW_PROG_INTR_REG_IND + + HX5_IHOST_IRQ_MASK_OFFSET, INTR_SW_PROG_INTR_BITPOS); + } else if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { IHOST_WRITE_INTR(d, ihost_intr_enable_base + INTC_LOW_PRIORITY_INTR_REG_IND + HX5_IHOST_IRQ_MASK_OFFSET, INTR_LOW_PRIORITY_BITPOS); } else { @@ -351,7 +381,7 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) HX5_IHOST_IRQ_MASK_OFFSET, ~0); } } else { - WRITE_INTC_INTR(d, intc_intr_enable_base + 4*ind, 0); + WRITE_INTC_INTR(d, ctrl->intr_regs.intc_intr_enable_base + 4*ind, 0); } } @@ -567,6 +597,18 @@ _cmicd_interrupt(bde_ctrl_t *ctrl) if (stat & imask) { break; } + /** Check if there are interrupts other than PacketIO interrupts on CMC1 */ + stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT0_OFFSET(1)); + imask = mask & ~fmask; + if (stat & imask) { + break; + } + /** Check if there are interrupts other than PacketIO interrupts on CMC2 */ + stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT0_OFFSET(2)); + imask = mask & ~fmask; + if (stat & imask) { + break; + } stat = user_bde->read(d, CMIC_CMCx_IRQ_STAT1_OFFSET(cmc)); if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { mask = user_bde->read(d, CMIC_CMCx_UC0_IRQ_MASK1_OFFSET(cmc)); @@ -716,6 +758,26 @@ _intr_mode_str(void *isr) return NULL; } +static void +_intr_regs_init(bde_ctrl_t *ctrl, int hx5_intr) +{ + if (hx5_intr) { + ctrl->intr_regs.intc_intr_status_base = HX5_INTC_INTR_STATUS_BASE; + ctrl->intr_regs.intc_intr_enable_base = HX5_INTC_INTR_ENABLE_BASE; + ctrl->intr_regs.intc_intr_clear_0 = HX5_PAXB_0_PAXB_IC_INTRCLR_0; + ctrl->intr_regs.intc_intr_clear_1 = HX5_PAXB_0_PAXB_IC_INTRCLR_1; + ctrl->intr_regs.intc_intr_clear_mode_0 = HX5_PAXB_0_PAXB_IC_INTRCLR_MODE_0; + ctrl->intr_regs.intc_intr_clear_mode_1 = HX5_PAXB_0_PAXB_IC_INTRCLR_MODE_1; + } else { + ctrl->intr_regs.intc_intr_status_base = INTC_INTR_STATUS_BASE; + ctrl->intr_regs.intc_intr_enable_base = INTC_INTR_ENABLE_BASE; + ctrl->intr_regs.intc_intr_clear_0 = PAXB_0_PAXB_IC_INTRCLR_0; + ctrl->intr_regs.intc_intr_clear_1 = PAXB_0_PAXB_IC_INTRCLR_1; + ctrl->intr_regs.intc_intr_clear_mode_0 = PAXB_0_PAXB_IC_INTRCLR_MODE_0; + ctrl->intr_regs.intc_intr_clear_mode_1 = PAXB_0_PAXB_IC_INTRCLR_MODE_1; + } +} + static void _devices_init(int d) { @@ -753,6 +815,8 @@ _devices_init(int d) case BCM53547_DEVICE_ID: case BCM53548_DEVICE_ID: case BCM53549_DEVICE_ID: + ctrl->isr = (isr_f)_cmicd_cmc0_interrupt; + break; case BCM88670_DEVICE_ID: case BCM88671_DEVICE_ID: case BCM88671M_DEVICE_ID: @@ -780,10 +844,10 @@ _devices_init(int d) case BCM88683_DEVICE_ID: case BCM88684_DEVICE_ID: case BCM88685_DEVICE_ID: + case BCM88687_DEVICE_ID: case BCM88380_DEVICE_ID: case BCM88381_DEVICE_ID: case BCM88680_DEVICE_ID: - case BCM88800_DEVICE_ID: case BCM88770_DEVICE_ID: case BCM88773_DEVICE_ID: case BCM88774_DEVICE_ID: @@ -812,10 +876,7 @@ _devices_init(int d) case BCM88956_DEVICE_ID: case BCM88772_DEVICE_ID: case BCM88952_DEVICE_ID: - ctrl->isr = (isr_f)_cmicd_cmc0_interrupt; - break; - case BCM88790_DEVICE_ID: - ctrl->isr = (isr_f)_cmicx_interrupt; + ctrl->isr = (isr_f)_cmicd_interrupt; break; case BCM56370_DEVICE_ID: case BCM56371_DEVICE_ID: @@ -827,6 +888,12 @@ _devices_init(int d) case BCM56577_DEVICE_ID: case BCM56578_DEVICE_ID: case BCM56579_DEVICE_ID: + case BCM56273_DEVICE_ID: + case BCM56274_DEVICE_ID: + case BCM56275_DEVICE_ID: + case BCM56276_DEVICE_ID: + case BCM56277_DEVICE_ID: + case BCM56278_DEVICE_ID: ctrl->isr = (isr_f)_cmicx_interrupt; if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { if (!ihost_intr_enable_base) { @@ -838,6 +905,7 @@ _devices_init(int d) HX5_IHOST_INTR_STATUS_MAP_NUM); } } + _intr_regs_init(ctrl, 1); break; default: /* Get CMIC version */ @@ -853,7 +921,8 @@ _devices_init(int d) } /* check if version is CMICX */ else if (ver == 0x04) { - ctrl->isr = (isr_f)_cmicx_interrupt; + ctrl->isr = (isr_f)_cmicx_interrupt; + _intr_regs_init(ctrl, 0); } else { ctrl->isr = (isr_f)_cmic_interrupt; if ((ctrl->dev_type & BDE_256K_REG_SPACE) && @@ -867,17 +936,25 @@ _devices_init(int d) break; } + /* configure interrupts for DNX devices using iproc >=14 */ +#if defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) + switch (user_bde->get_dev(d)->device & DNXC_DEVID_FAMILY_MASK) { #ifdef BCM_DNX_SUPPORT - /*All Jericho 2 devices from 0x8690 to 0x869F*/ - if (SOC_IS_JERICHO_2_TYPE(user_bde->get_dev(d)->device)) { - ctrl->isr = (isr_f)_cmicx_interrupt; - } + case JERICHO2_DEVICE_ID: + case J2C_DEVICE_ID: + case J2C_2ND_DEVICE_ID: + case Q2A_DEVICE_ID: + case J2P_DEVICE_ID: +#endif +#ifdef BCM_DNXF_SUPPORT + case BCM88790_DEVICE_ID: #endif - - /*All Ramon devices from 0x8790 to 0x879F*/ - if ((user_bde->get_dev(d)->device & BCM88790_DEVICE_ID) == BCM88790_DEVICE_ID) { ctrl->isr = (isr_f)_cmicx_interrupt; + _intr_regs_init(ctrl, 0); + break; } +#endif /* defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) */ + if (_intr_mode_str(ctrl->isr) == NULL) { gprintk("Warning: Unknown interrupt mode\n"); } @@ -906,6 +983,7 @@ _init(void) if ((linux_bde_create(NULL, &user_bde) < 0) || user_bde == NULL) { return -ENODEV; } + spin_lock_init(&bde_resource_lock); init_waitqueue_head(&_ether_interrupt_wq); @@ -1121,15 +1199,27 @@ _instance_attach(unsigned int inst_id, unsigned int dma_size) /* Reprobe the system for hot-plugged device */ _device_reprobe(); + if (debug >= 2) { + gprintk("INFO: Request to attach to instance_id %d with dma size %d!\n", inst_id, dma_size); + } + + spin_lock(&bde_resource_lock); + /* Validate the resource with inst_id */ exist = _instance_validate(inst_id, dma_size); if (exist < 0) { + spin_unlock(&bde_resource_lock); return LUBDE_FAIL; } if (exist > 0) { + if (debug >= 2) { + gprintk("INFO: Already attached to instance_id %d with dma size %d!\n", inst_id, dma_size); + } + spin_unlock(&bde_resource_lock); return LUBDE_SUCCESS; } if (_dma_resource_alloc(dma_size, &dma_offset) < 0) { + spin_unlock(&bde_resource_lock); return LUBDE_FAIL; } for (i = 0; i < user_bde->num_devices(BDE_ALL_DEVICES); i++) { @@ -1157,6 +1247,10 @@ _instance_attach(unsigned int inst_id, unsigned int dma_size) } } } + spin_unlock(&bde_resource_lock); + if (debug >= 2) { + gprintk("INFO: Attached to instance_id %d with dma size %d! SUCCESS\n", inst_id, dma_size); + } return LUBDE_SUCCESS; } @@ -1204,6 +1298,7 @@ _ioctl(unsigned int cmd, unsigned long arg) if (bde_dev) { io.d0 = bde_dev->device; io.d1 = bde_dev->rev; + io.dx.dw[0] = bde_dev->dev_unique_id; if (BDE_DEV_MEM_MAPPED(_devices[io.dev].dev_type)) { /* Get physical address to map */ io.d2 = lkbde_get_dev_phys(io.dev); @@ -1258,8 +1353,10 @@ _ioctl(unsigned int cmd, unsigned long arg) io.dx.dw[0] = cpu_pbase; #ifdef PHYS_ADDRS_ARE_64BITS io.dx.dw[1] = cpu_pbase >> 32; + io.d3 = dma_pbase >> 32; #else io.dx.dw[1] = 0; + io.d3 = 0; #endif break; case LUBDE_ENABLE_INTERRUPTS: @@ -1268,6 +1365,14 @@ _ioctl(unsigned int cmd, unsigned long arg) } if (_devices[io.dev].dev_type & BDE_SWITCH_DEV_TYPE) { if (_devices[io.dev].isr && !_devices[io.dev].enabled) { + bde_ctrl_t *ctrl; + ctrl = &_devices[io.dev]; + if ((ctrl->isr == (isr_f)_cmicx_interrupt) && + (ctrl->dev_type & BDE_PCI_DEV_TYPE)) { + /* Set MSI mode to SW clear vs auto clear */ + WRITE_INTC_INTR(io.dev, ctrl->intr_regs.intc_intr_clear_mode_0, 0x0); + WRITE_INTC_INTR(io.dev, ctrl->intr_regs.intc_intr_clear_mode_1, 0x0); + } user_bde->interrupt_connect(io.dev, _devices[io.dev].isr, _devices+io.dev); diff --git a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c index 05253141b2ff..087720a20a8b 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c +++ b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c @@ -290,8 +290,9 @@ shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs, } } - /* Configure MSIX interrupt page, only need for iproc ver == 0x10 */ - if ((icfg->use_msi == 2) && (icfg->iproc_ver == 0x10)) { + /* Configure MSIX interrupt page, need for iproc ver 0x10 and 0x12 */ + if ((icfg->use_msi == 2) && + ((icfg->iproc_ver == 0x10) || (icfg->iproc_ver == 0x12))){ unsigned int mask = (0x1 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT) - 1; reg = ROFFS(iproc_regs, PAXB_0_FUNC0_IMAP1_3); data = iproc32_read(shbde, reg); @@ -341,19 +342,23 @@ shbde_iproc_pci_read(shbde_hal_t *shbde, void *iproc_regs, subwin_base = (addr & ~0xfff); if((icfg->cmic_ver >= 4) && + ((subwin_base == 0x10230000) || (subwin_base == 0x18012000))) { + /* Route the PAXB register through IMAP0_2 */ + reg = ROFFS(iproc_regs, 0x2000 + (addr & 0xfff)); + } else if((icfg->cmic_ver >= 4) && ((subwin_base == 0x10231000) || (subwin_base == 0x18013000))) { /* Route the INTC block access through IMAP0_6 */ reg = ROFFS(iproc_regs, 0x6000 + (addr & 0xfff)); } else { /* Update base address for sub-window 7 */ subwin_base |= 1; /* Valid bit */ - reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); - iproc32_write(shbde, reg, subwin_base); + reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); + iproc32_write(shbde, reg, subwin_base); /* Read it to make sure the write actually goes through */ subwin_base = iproc32_read(shbde, reg); - /* Read register through sub-window 7 */ - reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); + /* Read register through sub-window 7 */ + reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); } return iproc32_read(shbde, reg); @@ -388,19 +393,23 @@ shbde_iproc_pci_write(shbde_hal_t *shbde, void *iproc_regs, subwin_base = (addr & ~0xfff); if((icfg->cmic_ver >= 4) && + ((subwin_base == 0x10230000) || (subwin_base == 0x18012000))) { + /* Route the PAXB register through IMAP0_2 */ + reg = ROFFS(iproc_regs, 0x2000 + (addr & 0xfff)); + } else if((icfg->cmic_ver >= 4) && ((subwin_base == 0x10231000) || (subwin_base == 0x18013000))) { /* Route the INTC block access through IMAP0_6 */ reg = ROFFS(iproc_regs, 0x6000 + (addr & 0xfff)); } else { /* Update base address for sub-window 7 */ subwin_base |= 1; /* Valid bit */ - reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); - iproc32_write(shbde, reg, subwin_base); + reg = ROFFS(iproc_regs, BAR0_PAXB_IMAP0_7); + iproc32_write(shbde, reg, subwin_base); /* Read it to make sure the write actually goes through */ subwin_base = iproc32_read(shbde, reg); /* Read register through sub-window 7 */ - reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); + reg = ROFFS(iproc_regs, 0x7000 + (addr & 0xfff)); } iproc32_write(shbde, reg, data); diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/Makefile index 84c677758cac..448b4b9a9310 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/Makefile @@ -24,7 +24,7 @@ LOCALDIR = systems/linux/kernel/modules include ${SDK}/make/Make.config -subdirs=shared uk-proxy bcm-diag-full bcm-core bcm-net bcm-diag +subdirs= include ${SDK}/make/Make.subdirs diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/Makefile index ed1a5000e3ca..a3f430a6a903 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/Makefile @@ -37,9 +37,6 @@ build: $(MODULE) $(KMODULE) endif KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../../../../bde/linux/kernel/kernel_module/Module.symvers -ifeq (,$(findstring -DPROXY_SUPPORT=0,$(CFLAGS))) -KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../uk-proxy/kernel_module/Module.symvers -endif # BCM Network Device diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c index 077386e6dcbc..a9eda27ad4d5 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c @@ -1,23 +1,18 @@ /* * Copyright 2017 Broadcom - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation (the "GPL"). - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 (GPLv2) for more details. - * + * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. */ -/* - * $Id: bcm-knet.c,v 1.90 Broadcom SDK $ - * $Copyright: (c) 2005 Broadcom Corp. - * All Rights Reserved.$ - */ /* * This module implements a Linux network driver for Broadcom @@ -54,7 +49,7 @@ * * To support pci hot-plug in this module, the resource update * should be handled when the PCI device is re-plugged. - * NOTE: the KNET detach should be invoked befere removing the + * NOTE: the KNET detach should be invoked before removing the * device. * * For a list of supported module parameters, please see below. @@ -65,12 +60,17 @@ #include #include +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,16,0) +#include +#endif + #include #include #include #include #include #include +#include MODULE_AUTHOR("Broadcom Corporation"); @@ -167,6 +167,39 @@ LKM_MOD_PARAM(basedev_suspend, "i", int, 0); MODULE_PARM_DESC(basedev_suspend, "Pause traffic till base device is up (enabled by default in NAPI mode)"); +/* + * Force to add one layer of VLAN tag to untagged packets on Dune devices + */ +#if defined(SAI_FIXUP) && defined(BCM_DNX_SUPPORT) /* SONIC-16195 CS9129167 - Change the default to NOT add tag */ +static int force_tagged = 0; +#else +static int force_tagged = 1; +#endif +LKM_MOD_PARAM(force_tagged, "i", int, 0); +MODULE_PARM_DESC(force_tagged, +"Always tagged with VLAN tag with spceified VID or VSI(default 1)"); + +static int ft_tpid=0x8100; +LKM_MOD_PARAM(ft_tpid, "i", int, 0); +MODULE_PARM_DESC(ft_tpid, +"Tag Protocol Identifier (TPID) indicates the frame type (default 0x8100)"); + +static int ft_pri=0; +LKM_MOD_PARAM(ft_pri, "i", int, 0); +MODULE_PARM_DESC(ft_cfi, +"Priority (PRI) indicates the frame priority (default 0)"); + +static int ft_cfi=0; +LKM_MOD_PARAM(ft_cfi, "i", int, 0); +MODULE_PARM_DESC(ft_cfi, +"Canonical Format Indicator (CFI) indicates whether a MAC address is encapsulated in canonical format over different transmission media (default 0)"); + +static int ft_vid=0; +LKM_MOD_PARAM(ft_vid, "i", int, 0); +MODULE_PARM_DESC(ft_vid, +"VLAN ID (VID) indicates the VLAN to which a frame belongs (default 0)"); + + /* Debug levels */ #define DBG_LVL_VERB 0x1 #define DBG_LVL_DCB 0x2 @@ -267,40 +300,6 @@ static int napi_weight = 0; #endif -/* - * If proxy support is compiled in the module will attempt to use - * the user/kernel message service provided by the linux-uk-proxy - * kernel module, otherwise device IOCTL will be used. - */ -#ifndef PROXY_SUPPORT -#define PROXY_SUPPORT 0 -#endif - -#if PROXY_SUPPORT - -#include - -static int use_proxy = 1; -LKM_MOD_PARAM(use_proxy, "i", int, 0); -MODULE_PARM_DESC(use_proxy, -"Use Linux User/Kernel proxy (default 1)"); - -#define PROXY_SERVICE_CREATE(_s,_q,_f) linux_uk_proxy_service_create(_s,_q,_f) -#define PROXY_SERVICE_DESTROY(_s) linux_uk_proxy_service_destroy(_s); -#define PROXY_SEND(_s,_m,_l) linux_uk_proxy_send(_s,_m,_l) -#define PROXY_RECV(_s,_m,_l) linux_uk_proxy_recv(_s,_m,_l) - -#else - -static int use_proxy = 0; - -#define PROXY_SERVICE_CREATE(_s,_q,_f) -#define PROXY_SERVICE_DESTROY(_s) -#define PROXY_SEND(_s,_m,_l) -#define PROXY_RECV(_s,_m,_l) (-1) - -#endif - /* Compatibility */ #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)) @@ -394,6 +393,10 @@ static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) __vlan_hwaccel_put_tag(_skb, htons(_proto), _tci) #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) +#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */ +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) #define bkn_dma_mapping_error(d, a) \ dma_mapping_error(a) @@ -407,6 +410,11 @@ static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) +enum hwtstamp_tx_types { + HWTSTAMP_TX_OFF, + HWTSTAMP_TX_ON, + HWTSTAMP_TX_ONESTEP_SYNC +}; enum { SKBTX_HW_TSTAMP = 1 << 0, SKBTX_SW_TSTAMP = 1 << 1, @@ -441,6 +449,7 @@ static inline ktime_t ns_to_ktime(u64 ns) #endif #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) #include +#define HWTSTAMP_TX_ONESTEP_SYNC 2 enum { SKBTX_HW_TSTAMP = 1 << 0, SKBTX_SW_TSTAMP = 1 << 1, @@ -452,6 +461,11 @@ static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) } #else #include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) +#define HWTSTAMP_TX_ONESTEP_SYNC 2 +#endif + #define bkn_skb_tx_flags(_skb) skb_shinfo(_skb)->tx_flags static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) { @@ -459,26 +473,41 @@ static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) } #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +#define bkn_dev_net_set(dev, net) +#else +#define bkn_dev_net_set(dev, net) dev_net_set(dev, net) +#endif + #ifdef LINUX_BDE_DMA_DEVICE_SUPPORT -#define DMA_DEV device -#define DMA_FROMDEV DMA_FROM_DEVICE -#define DMA_TODEV DMA_TO_DEVICE -#define DMA_MAP_SINGLE(d,p,s,r) dma_map_single(d,p,s,r) -#define DMA_UNMAP_SINGLE(d,a,s,r) dma_unmap_single(d,a,s,r) -#define DMA_ALLOC_COHERENT(d,s,h) dma_alloc_coherent(d,s,h,GFP_ATOMIC|GFP_DMA32) -#define DMA_FREE_COHERENT(d,s,a,h) dma_free_coherent(d,s,a,h) -#define DMA_MAPPING_ERROR(d,a) bkn_dma_mapping_error(d,a) +#define BKN_DMA_DEV device +#define BKN_DMA_FROMDEV DMA_FROM_DEVICE +#define BKN_DMA_TODEV DMA_TO_DEVICE +#define BKN_DMA_MAP_SINGLE(d,p,s,r) dma_map_single(d,p,s,r) +#define BKN_DMA_UNMAP_SINGLE(d,a,s,r) dma_unmap_single(d,a,s,r) +#define BKN_DMA_ALLOC_COHERENT(d,s,h) dma_alloc_coherent(d,s,h,GFP_ATOMIC|GFP_DMA32) +#define BKN_DMA_FREE_COHERENT(d,s,a,h) dma_free_coherent(d,s,a,h) +#define BKN_DMA_MAPPING_ERROR(d,a) bkn_dma_mapping_error(d,a) #else -#define DMA_DEV pci_dev -#define DMA_FROMDEV PCI_DMA_FROMDEVICE -#define DMA_TODEV PCI_DMA_TODEVICE -#define DMA_MAP_SINGLE(d,p,s,r) pci_map_single(d,p,s,r) -#define DMA_UNMAP_SINGLE(d,a,s,r) pci_unmap_single(d,a,s,r) -#define DMA_ALLOC_COHERENT(d,s,h) pci_alloc_consistent(d,s,h) -#define DMA_FREE_COHERENT(d,s,a,h) pci_free_consistent(d,s,a,h) -#define DMA_MAPPING_ERROR(d,a) bkn_pci_dma_mapping_error(d,a) +#define BKN_DMA_DEV pci_dev +#define BKN_DMA_FROMDEV PCI_DMA_FROMDEVICE +#define BKN_DMA_TODEV PCI_DMA_TODEVICE +#define BKN_DMA_MAP_SINGLE(d,p,s,r) pci_map_single(d,p,s,r) +#define BKN_DMA_UNMAP_SINGLE(d,a,s,r) pci_unmap_single(d,a,s,r) +#define BKN_DMA_ALLOC_COHERENT(d,s,h) pci_alloc_consistent(d,s,h) +#define BKN_DMA_FREE_COHERENT(d,s,a,h) pci_free_consistent(d,s,a,h) +#define BKN_DMA_MAPPING_ERROR(d,a) bkn_pci_dma_mapping_error(d,a) #endif +/* + * Get a 16-bit value from packet offset + * _data Pointer to packet + * _offset Offset + */ +#define PKT_U16_GET(_data, _offset) \ + (uint16_t)(_data[_offset] << 8 | _data[_offset + 1]) + + /* RCPU operations */ #define RCPU_OPCODE_RX 0x10 #define RCPU_OPCODE_TX 0x20 @@ -536,7 +565,7 @@ typedef struct bkn_switch_info_s { int ndev_max; /* Size of indexed array */ struct list_head rxpf_list; /* Associated Rx packet filters */ volatile void *base_addr; /* Base address for PCI register access */ - struct DMA_DEV *dma_dev; /* Required for DMA memory control */ + struct BKN_DMA_DEV *dma_dev; /* Required for DMA memory control */ struct pci_dev *pdev; /* Required for DMA memory control */ struct net_device *dev; /* Base network device */ struct napi_struct napi; /* New NAPI */ @@ -558,8 +587,12 @@ typedef struct bkn_switch_info_s { uint32_t ftmh_stacking_ext_size; /* FTMH Stacking extension existence/size */ uint32_t pph_base_size; /* Size of PPH base */ uint32_t pph_lif_ext_size[8]; /* Size of PPH Lif extension header */ - uint8_t udh_enable; /* Indicates UDH existence */ uint32_t udh_length_type[4]; /* Size of UDH header per type */ + uint32_t udh_size; /* Size of UDH header on legacy devices */ + uint32_t oamp_punt; /* OAMP port if nonzero */ + uint8_t no_skip_udh_check; /* Indicates UDH won't be skipped */ + uint8_t system_headers_mode; /* Indicates system header mode */ + uint8_t udh_enable; /* Indicates UDH existence */ int rx_chans; /* Number of Rx channels */ uint32_t dma_hi; /* DMA higher address */ uint32_t cmic_type; /* CMIC type (CMICe or CMICm) */ @@ -579,8 +612,6 @@ typedef struct bkn_switch_info_s { uint32_t inst_id; /* Instance id of this device */ int evt_idx; /* Event queue index for this device*/ int basedev_suspended; /* Base device suspended */ - int tx_hwts; /* HW timestamp for Tx */ - int rx_hwts; /* HW timestamp for Rx */ struct sk_buff_head tx_ptp_queue; /* Tx PTP skb queue */ struct work_struct tx_ptp_work; /* Tx PTP work */ struct { @@ -641,6 +672,8 @@ typedef struct bkn_switch_info_s { } rx[NUM_RX_CHAN]; } bkn_switch_info_t; +/* 0x1 - Jericho 2 mode */ +#define BKN_DNX_JR2_MODE 1 /* PTCH_2 */ #define BKN_DNX_PTCH_2_SIZE 2 /* ITMH */ @@ -675,49 +708,49 @@ typedef struct bkn_switch_info_s { /* TSH */ #define BKN_DNX_TSH_SIZE 4 /* PPH */ -#define BKN_DNX_PPH_BASE_TYPE_9 9 -#define BKN_DNX_PPH_BASE_TYPE_10 10 -#define BKN_DNX_PPH_BASE_TYPE_12 12 -#define BKN_DNX_PPH_9_FORWARD_DOMAIN_MSB 5 -#define BKN_DNX_PPH_9_FORWARD_DOMAIN_NOF_BITS 16 -#define BKN_DNX_PPH_9_LEARN_EXT_PRESENT_MSB 53 -#define BKN_DNX_PPH_9_LEARN_EXT_PRESENT_NOF_BITS 1 -#define BKN_DNX_PPH_9_FHEI_SIZE_MSB 54 -#define BKN_DNX_PPH_9_FHEI_SIZE_NOF_BITS 2 -#define BKN_DNX_PPH_9_LIF_EXT_TYPE_MSB 56 -#define BKN_DNX_PPH_9_LIF_EXT_TYPE_NOF_BITS 3 -#define BKN_DNX_PPH_10_FORWARD_DOMAIN_MSB 9 -#define BKN_DNX_PPH_10_FORWARD_DOMAIN_NOF_BITS 16 -#define BKN_DNX_PPH_10_LEARN_EXT_PRESENT_MSB 61 -#define BKN_DNX_PPH_10_LEARN_EXT_PRESENT_NOF_BITS 1 -#define BKN_DNX_PPH_10_FHEI_SIZE_MSB 62 -#define BKN_DNX_PPH_10_FHEI_SIZE_NOF_BITS 2 -#define BKN_DNX_PPH_10_LIF_EXT_TYPE_MSB 64 -#define BKN_DNX_PPH_10_LIF_EXT_TYPE_NOF_BITS 3 -#define BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB 21 -#define BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS 18 -#define BKN_DNX_PPH_12_LEARN_EXT_PRESENT_MSB 77 -#define BKN_DNX_PPH_12_LEARN_EXT_PRESENT_NOF_BITS 1 -#define BKN_DNX_PPH_12_FHEI_SIZE_MSB 78 -#define BKN_DNX_PPH_12_FHEI_SIZE_NOF_BITS 2 -#define BKN_DNX_PPH_12_LIF_EXT_TYPE_MSB 80 -#define BKN_DNX_PPH_12_LIF_EXT_TYPE_NOF_BITS 3 +#define BKN_DNX_INTERNAL_BASE_TYPE_9 9 +#define BKN_DNX_INTERNAL_BASE_TYPE_10 10 +#define BKN_DNX_INTERNAL_BASE_TYPE_12 12 +#define BKN_DNX_INTERNAL_9_FORWARD_DOMAIN_MSB 5 +#define BKN_DNX_INTERNAL_9_FORWARD_DOMAIN_NOF_BITS 16 +#define BKN_DNX_INTERNAL_9_LEARN_EXT_PRESENT_MSB 53 +#define BKN_DNX_INTERNAL_9_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_INTERNAL_9_FHEI_SIZE_MSB 54 +#define BKN_DNX_INTERNAL_9_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_INTERNAL_9_LIF_EXT_TYPE_MSB 56 +#define BKN_DNX_INTERNAL_9_LIF_EXT_TYPE_NOF_BITS 3 +#define BKN_DNX_INTERNAL_10_FORWARD_DOMAIN_MSB 9 +#define BKN_DNX_INTERNAL_10_FORWARD_DOMAIN_NOF_BITS 16 +#define BKN_DNX_INTERNAL_10_LEARN_EXT_PRESENT_MSB 61 +#define BKN_DNX_INTERNAL_10_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_INTERNAL_10_FHEI_SIZE_MSB 62 +#define BKN_DNX_INTERNAL_10_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_INTERNAL_10_LIF_EXT_TYPE_MSB 64 +#define BKN_DNX_INTERNAL_10_LIF_EXT_TYPE_NOF_BITS 3 +#define BKN_DNX_INTERNAL_12_FORWARD_DOMAIN_MSB 21 +#define BKN_DNX_INTERNAL_12_FORWARD_DOMAIN_NOF_BITS 18 +#define BKN_DNX_INTERNAL_12_LEARN_EXT_PRESENT_MSB 77 +#define BKN_DNX_INTERNAL_12_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_INTERNAL_12_FHEI_SIZE_MSB 78 +#define BKN_DNX_INTERNAL_12_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_INTERNAL_12_LIF_EXT_TYPE_MSB 80 +#define BKN_DNX_INTERNAL_12_LIF_EXT_TYPE_NOF_BITS 3 /* PPH.FHEI_TYPE */ -#define BKN_DNX_PPH_FHEI_TYPE_SZ0 1 -#define BKN_DNX_PPH_FHEI_TYPE_SZ1 2 -#define BKN_DNX_PPH_FHEI_TYPE_SZ2 3 +#define BKN_DNX_INTERNAL_FHEI_TYPE_SZ0 1 +#define BKN_DNX_INTERNAL_FHEI_TYPE_SZ1 2 +#define BKN_DNX_INTERNAL_FHEI_TYPE_SZ2 3 /* FHEI */ -#define BKN_DNX_PPH_FHEI_SZ0_SIZE 3 -#define BKN_DNX_PPH_FHEI_SZ1_SIZE 5 -#define BKN_DNX_PPH_FHEI_SZ2_SIZE 8 -#define BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_MSB 0 -#define BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_NOF_BITS 27 -#define BKN_DNX_PPH_FHEI_TRAP_5B_CODE_MSB 27 -#define BKN_DNX_PPH_FHEI_TRAP_5B_CODE_NOF_BITS 9 -#define BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_MSB 36 -#define BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_NOF_BITS 4 +#define BKN_DNX_INTERNAL_FHEI_SZ0_SIZE 3 +#define BKN_DNX_INTERNAL_FHEI_SZ1_SIZE 5 +#define BKN_DNX_INTERNAL_FHEI_SZ2_SIZE 8 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_QUALIFIER_MSB 0 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_QUALIFIER_NOF_BITS 27 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_CODE_MSB 27 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_CODE_NOF_BITS 9 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_TYPE_MSB 36 +#define BKN_DNX_INTERNAL_FHEI_TRAP_5B_TYPE_NOF_BITS 4 /* PPH Extension */ -#define BKN_DNX_PPH_LEARN_EXT_SIZE 19 +#define BKN_DNX_INTERNAL_LEARN_EXT_SIZE 19 /* UDH */ #define BKN_DNX_UDH_DATA_TYPE_0_MSB 0 #define BKN_DNX_UDH_DATA_TYPE_0_NOF_BITS 2 @@ -758,29 +791,48 @@ typedef struct bkn_switch_info_s { #define BKN_DPP_FTMH_PPH_TYPE_MSB 45 #define BKN_DPP_FTMH_PPH_TYPE_NOF_BITS 2 +/* OTSH */ +#define BKN_DPP_OTSH_SIZE_BYTE 6 +#define BKN_DPP_OTSH_TYPE_MSB 0 +#define BKN_DPP_OTSH_TYPE_NOF_BITS 2 +#define BKN_DPP_OTSH_OAM_SUB_TYPE_MSB 2 +#define BKN_DPP_OTSH_OAM_SUB_TYPE_NOF_BITS 3 + +#define BKN_DPP_OTSH_TYPE_OAM 0 +#define BKN_DPP_OTSH_OAM_SUB_TYPE_DM_1588 2 +#define BKN_DPP_OTSH_OAM_SUB_TYPE_DM_NTP 3 + +#define BKN_DPP_OAM_DM_TOD_SIZE_BYTE 4 + /* PPH */ -#define BKN_DPP_PPH_SIZE_BYTE 7 -#define BKN_DPP_PPH_EEI_EXTENSION_PRESENT_MSB 0 -#define BKN_DPP_PPH_EEI_EXTENSION_PRESENT_NOF_BITS 1 -#define BKN_DPP_PPH_LEARN_EXENSION_PRESENT_MSB 1 -#define BKN_DPP_PPH_LEARN_EXENSION_PRESENT_NOF_BITS 1 -#define BKN_DPP_PPH_FHEI_SIZE_MSB 2 -#define BKN_DPP_PPH_FHEI_SIZE_NOF_BITS 2 -#define BKN_DPP_PPH_FORWARD_CODE_MSB 4 -#define BKN_DPP_PPH_FORWARD_CODE_NOF_BITS 4 -#define BKN_DPP_PPH_VSI_MSB 22 -#define BKN_DPP_PPH_VSI_NOF_BITS 16 +#define BKN_DPP_INTERNAL_SIZE_BYTE 7 +#define BKN_DPP_INTERNAL_EEI_EXTENSION_PRESENT_MSB 0 +#define BKN_DPP_INTERNAL_EEI_EXTENSION_PRESENT_NOF_BITS 1 +#define BKN_DPP_INTERNAL_LEARN_EXENSION_PRESENT_MSB 1 +#define BKN_DPP_INTERNAL_LEARN_EXENSION_PRESENT_NOF_BITS 1 +#define BKN_DPP_INTERNAL_FHEI_SIZE_MSB 2 +#define BKN_DPP_INTERNAL_FHEI_SIZE_NOF_BITS 2 +#define BKN_DPP_INTERNAL_FORWARD_CODE_MSB 4 +#define BKN_DPP_INTERNAL_FORWARD_CODE_NOF_BITS 4 +#define BKN_DPP_INTERNAL_FORWARD_CODE_CPU_TRAP 7 +#define BKN_DPP_INTERNAL_FORWARDING_HEADER_OFFSET_MSB 8 +#define BKN_DPP_INTERNAL_FORWARDING_HEADER_OFFSET_NOF_BITS 7 +#define BKN_DPP_INTERNAL_VSI_MSB 22 +#define BKN_DPP_INTERNAL_VSI_NOF_BITS 16 + /* FHEI TRAP/SNOOP 3B */ -#define BKN_DPP_PPH_FHEI_3B_SIZE_BYTE 3 -#define BKN_DPP_PPH_FHEI_5B_SIZE_BYTE 5 -#define BKN_DPP_PPH_FHEI_8B_SIZE_BYTE 8 -#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB 0 -#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS 16 -#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB 16 -#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS 8 +#define BKN_DPP_INTERNAL_FHEI_3B_SIZE_BYTE 3 +#define BKN_DPP_INTERNAL_FHEI_5B_SIZE_BYTE 5 +#define BKN_DPP_INTERNAL_FHEI_8B_SIZE_BYTE 8 +#define BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB 0 +#define BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS 16 +#define BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB 16 +#define BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS 8 /* PPH extension */ -#define BKN_DPP_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE 3 -#define BKN_DPP_PPH_LEARN_EXTENSION_SIZE_BYTE 5 +#define BKN_DPP_INTERNAL_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE 3 +#define BKN_DPP_INTERNAL_LEARN_EXTENSION_SIZE_BYTE 5 + +#define BKN_SAND_SCRATCH_DATA_SIZE 4 /* ftmh action type. */ typedef enum bkn_dpp_ftmh_action_type_e { @@ -792,31 +844,22 @@ typedef enum bkn_dpp_ftmh_action_type_e { /* ftmh dest extension. */ typedef struct bkn_dpp_ftmh_dest_extension_s { - uint8 valid; /* Set if the extension is present */ + uint8_t valid; /* Set if the extension is present */ uint32_t dst_sys_port; /* Destination System Port */ } bkn_dpp_ftmh_dest_extension_t; /* dnx packet */ typedef struct bkn_dune_system_header_info_s { - uint32_t ntwrk_header_ptr; + uint32_t system_header_size; struct { - uint32_t packet_size; /* Packet size in bytes */ uint32_t action_type; /* Indicates if the copy is one of the Forward Snoop or Mirror packet copies */ - uint32_t pph_type; - uint32_t prio; /* Traffic class */ - uint32_t src_sys_port; /* Source System port*/ + uint32_t source_sys_port_aggregate; /* Source System port*/ } ftmh; struct { - uint32_t vsi; - uint32_t trap_qualifier; /* RAW Data */ - uint32_t trap_id; /* RAW Data */ + uint32_t forward_domain; + uint32_t trap_qualifier; + uint32_t trap_id; } internal; - uint32_t system_header_size; - uint32_t ftmh_spa; /* FTMH: Source-System-Port-Aggregate*/ - uint32_t pph_forward_domain; /* PPH: Forward-Domain*/ - uint32_t fhei_qualifier; /* FHEI: Qualifier */ - uint32_t fhei_code; /* FHEI: Code */ - uint32_t fhei_type; /* FHEI: Type */ } bkn_dune_system_header_info_t; #define PREV_IDX(_cur, _max) (((_cur) == 0) ? (_max) - 1 : (_cur) - 1) @@ -874,13 +917,16 @@ typedef struct bkn_priv_s { int id; int type; int port; - uint8_t itmh[4]; int qnum; uint32_t vlan; uint32_t flags; uint32_t cb_user_data; uint8_t system_headers[27]; uint32_t system_headers_size; + int tx_hwts; /* HW timestamp for Tx */ + int rx_hwts; /* HW timestamp for Rx */ + int phys_port; + struct ethtool_link_settings link_settings; } bkn_priv_t; typedef struct bkn_filter_s { @@ -890,6 +936,13 @@ typedef struct bkn_filter_s { kcom_filter_t kf; } bkn_filter_t; +#ifdef SAI_FIXUP /* SDK-224448 */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) +#define BKN_NETDEV_TX_BUSY NETDEV_TX_BUSY +#else +#define BKN_NETDEV_TX_BUSY 1 +#endif +#endif /* SDK-224448 */ /* * Multiple instance support in KNET @@ -927,6 +980,7 @@ static knet_hw_tstamp_tx_time_get_cb_f knet_hw_tstamp_tx_time_get_cb = NULL; static knet_hw_tstamp_tx_meta_get_cb_f knet_hw_tstamp_tx_meta_get_cb = NULL; static knet_hw_tstamp_ptp_clock_index_cb_f knet_hw_tstamp_ptp_clock_index_cb = NULL; static knet_hw_tstamp_rx_time_upscale_cb_f knet_hw_tstamp_rx_time_upscale_cb = NULL; +static knet_hw_tstamp_ioctl_cmd_cb_f knet_hw_tstamp_ioctl_cmd_cb = NULL; static knet_netif_cb_f knet_netif_create_cb = NULL; static knet_netif_cb_f knet_netif_destroy_cb = NULL; @@ -935,69 +989,6 @@ static knet_netif_cb_f knet_netif_destroy_cb = NULL; */ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)) -/* - * Old style using kernel_thread() - */ -typedef struct { - const char * name; - volatile int pid; - volatile int run; - struct completion completion; - int state; -} bkn_thread_ctrl_t; - -static int -bkn_thread_start(bkn_thread_ctrl_t *tc, const char *name, - int (*threadfn)(void *)) -{ - if (name == NULL) { - return -1; - } - tc->name = name; - tc->pid = kernel_thread(threadfn, tc, 0); - if (tc->pid < 0) { - tc->pid = 0; - return -1; - } - tc->run = 1; - init_completion(&tc->completion); - return 0; -} - -static int -bkn_thread_stop(bkn_thread_ctrl_t *tc) -{ - if (tc->pid == 0) { - return 0; - } - tc->run = 0; - kill_proc(tc->pid, SIGTERM, 1); - wait_for_completion(&tc->completion); - return 0; -} - -static int -bkn_thread_should_stop(bkn_thread_ctrl_t *tc) -{ - if (tc->run) { - return 0; - } - tc->pid = 0; - return 1; -} - -static void -bkn_thread_boot(bkn_thread_ctrl_t *tc) -{ - siginitsetinv(¤t->blocked, sigmask(SIGTERM) | sigmask(SIGKILL)); -} - -static void -bkn_thread_exit(bkn_thread_ctrl_t *tc) -{ - complete_and_exit(&tc->completion, 0); -} - static void bkn_sleep(int clicks) { @@ -1007,60 +998,6 @@ bkn_sleep(int clicks) sleep_on_timeout(&wq, clicks); } #else -/* - * New style using kthread API - */ -#include -typedef struct { - const char * name; - struct task_struct *task; - int state; -} bkn_thread_ctrl_t; - -static int -bkn_thread_start(bkn_thread_ctrl_t *tc, const char *name, - int (*threadfn)(void *)) -{ - if (name == NULL) { - return -1; - } - tc->name = name; - tc->task = kthread_run(threadfn, tc, name); - if (IS_ERR(tc->task)) { - tc->task = NULL; - return -1; - } - return 0; -} - -static int -bkn_thread_stop(bkn_thread_ctrl_t *tc) -{ - if (tc->task == NULL) { - return 0; - } - send_sig(SIGTERM, tc->task, 0); - return kthread_stop(tc->task); -} - -static int -bkn_thread_should_stop(bkn_thread_ctrl_t *tc) -{ - return kthread_should_stop(); -} - -static void -bkn_thread_boot(bkn_thread_ctrl_t *tc) -{ - allow_signal(SIGTERM); - allow_signal(SIGKILL); -} - -static void -bkn_thread_exit(bkn_thread_ctrl_t *tc) -{ -} - static void bkn_sleep(int clicks) { @@ -1071,9 +1008,6 @@ bkn_sleep(int clicks) } #endif -static bkn_thread_ctrl_t bkn_cmd_ctrl; -static bkn_thread_ctrl_t bkn_evt_ctrl; - /* * On XGS devices bit 15 fo the Transferred Bytes field in * the DCBs is used to indicate that kernel processing is @@ -1399,7 +1333,7 @@ xgsm_cdma_halt_set(bkn_switch_info_t *sinfo, int chan) MEMORY_BARRIER; } -static int +static int xgsm_dma_chan_init(bkn_switch_info_t *sinfo, int chan, int dir) { uint32_t cdc; @@ -1872,7 +1806,7 @@ bkn_alloc_dcbs(bkn_switch_info_t *sinfo) rx_ring_size = dcb_size * (MAX_RX_DCBS + 1); sinfo->dcb_mem_size = tx_ring_size + rx_ring_size * sinfo->rx_chans; - sinfo->dcb_mem = DMA_ALLOC_COHERENT(sinfo->dma_dev, + sinfo->dcb_mem = BKN_DMA_ALLOC_COHERENT(sinfo->dma_dev, sinfo->dcb_mem_size, &dcb_dma); if (sinfo->dcb_mem == NULL) { @@ -1889,7 +1823,7 @@ static void bkn_free_dcbs(bkn_switch_info_t *sinfo) { if (sinfo->dcb_mem != NULL) { - DMA_FREE_COHERENT(sinfo->dma_dev, sinfo->dcb_mem_size, + BKN_DMA_FREE_COHERENT(sinfo->dma_dev, sinfo->dcb_mem_size, sinfo->dcb_mem, (dma_addr_t)sinfo->dcb_dma); sinfo->dcb_mem = NULL; } @@ -1907,9 +1841,9 @@ bkn_clean_tx_dcbs(bkn_switch_info_t *sinfo) if (desc->skb != NULL) { DBG_SKB(("Cleaning Tx SKB from DCB %d.\n", sinfo->tx.dirty)); - DMA_UNMAP_SINGLE(sinfo->dma_dev, + BKN_DMA_UNMAP_SINGLE(sinfo->dma_dev, desc->skb_dma, desc->dma_size, - DMA_TODEV); + BKN_DMA_TODEV); desc->skb_dma = 0; dev_kfree_skb_any(desc->skb); desc->skb = NULL; @@ -1936,9 +1870,9 @@ bkn_clean_rx_dcbs(bkn_switch_info_t *sinfo, int chan) if (desc->skb != NULL) { DBG_SKB(("Cleaning Rx%d SKB from DCB %d.\n", chan, sinfo->rx[chan].dirty)); - DMA_UNMAP_SINGLE(sinfo->dma_dev, + BKN_DMA_UNMAP_SINGLE(sinfo->dma_dev, desc->skb_dma, desc->dma_size, - DMA_FROMDEV); + BKN_DMA_FROMDEV); desc->skb_dma = 0; dev_kfree_skb_any(desc->skb); desc->skb = NULL; @@ -2327,10 +2261,10 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) desc->dma_size = 0; } #endif - desc->skb_dma = DMA_MAP_SINGLE(sinfo->dma_dev, + desc->skb_dma = BKN_DMA_MAP_SINGLE(sinfo->dma_dev, skb->data, desc->dma_size, - DMA_FROMDEV); - if (DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { + BKN_DMA_FROMDEV); + if (BKN_DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { dev_kfree_skb_any(skb); desc->skb = NULL; break; @@ -2532,8 +2466,7 @@ device_is_dnx(bkn_switch_info_t *sinfo) { int is_dnx = 0; - /* No EP_TO_CPU header for DNX(JR2) */ - is_dnx = ((sinfo->cmic_type == 'x') && (sinfo->pkt_hdr_size ==0)) ? 1 : 0; + is_dnx = (sinfo->dcb_type == 39) ? 1 : 0; return is_dnx; } @@ -2572,7 +2505,7 @@ bkn_match_rx_pkt(bkn_switch_info_t *sinfo, uint8_t *pkt, int pktlen, DBG_VERB(("Filter: size = %d (%d), data = 0x%08x, mask = 0x%08x\n", size, wsize, kf->data.w[0], kf->mask.w[0])); - if (device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { DBG_DUNE(("Filter: size = %d (wsize %d)\n", size, wsize)); for (idx = 0; idx < wsize; idx++) { @@ -2587,9 +2520,12 @@ bkn_match_rx_pkt(bkn_switch_info_t *sinfo, uint8_t *pkt, int pktlen, match = 1; if (match) { - if (device_is_sand(sinfo)) + if (device_is_dnx(sinfo)) { - /** priority 0 means no priority check */ + /* + * Mutliple RX channels are enabled on JR2 and above devices + * Bind between priority 0 and RX channel 0 is not checked, then all enabled RX channels can receive packets. + */ if (kf->priority && (kf->priority < (num_rx_prio * sinfo->rx_chans))) { if (kf->priority < (num_rx_prio * chan) || kf->priority >= (num_rx_prio * (chan + 1))) { @@ -2671,51 +2607,37 @@ bkn_netif_lookup(bkn_switch_info_t *sinfo, int id) } static int -bkn_hw_tstamp_rx_set(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32 *meta) +bkn_hw_tstamp_rx_set(bkn_switch_info_t *sinfo, int phys_port, struct sk_buff *skb, uint32 *meta) { struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); - uint32_t *md = meta; uint64_t ts = 0; - switch (sinfo->dcb_type) { - case 26: - case 32: - case 33: - ts = md[14]; - ts = ts << 32 | md[12]; - break; - case 36: - ts = md[10]; - break; - case 38: - ts = md[4] & 0xffff; - ts = ts << 32 | md[5]; - break; - default: - return -1; - } if (knet_hw_tstamp_rx_time_upscale_cb) { - if (knet_hw_tstamp_rx_time_upscale_cb(sinfo->dev_no, &ts) < 0) { + if (knet_hw_tstamp_rx_time_upscale_cb(sinfo->dev_no, phys_port, skb, meta, &ts) < 0) { return -1; } } memset(shhwtstamps, 0, sizeof(*shhwtstamps)); - shhwtstamps->hwtstamp = ns_to_ktime(be64_to_cpu(ts)); + shhwtstamps->hwtstamp = ns_to_ktime(ts); return 0; } static int -bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta) +bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta, int len) { int pktlen = skb->len; uint32_t *dmeta, *smeta, wsize, psize; int idx; /* Add and clear RCPU encapsulation */ - if (sinfo->cmic_type == 'x') { + if (device_is_sand(sinfo)) { + psize = RCPU_RX_ENCAP_SIZE; + skb_push(skb, psize); + memset(skb->data, 0, RCPU_RX_ENCAP_SIZE); + } else if (sinfo->cmic_type == 'x') { psize = RCPU_HDR_SIZE + sinfo->pkt_hdr_size; skb_push(skb, psize); memset(skb->data, 0, RCPU_HDR_SIZE); @@ -2747,12 +2669,20 @@ bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta) /* Meta data */ dmeta = (uint32_t *)&skb->data[RCPU_HDR_SIZE]; - smeta = sinfo->cmic_type == 'x' ? (uint32_t *)meta : (uint32_t *)meta + 2; - wsize = sinfo->cmic_type == 'x' ? sinfo->pkt_hdr_size / 4 : sinfo->dcb_wsize - 3; - for (idx = 0; idx < wsize; idx++) { - dmeta[idx] = htonl(smeta[idx]); + + if (device_is_sand(sinfo)) { + /* Copy at most 64 bytes system headers */ + len = len > RCPU_RX_META_SIZE ? RCPU_RX_META_SIZE : len; + memcpy(&skb->data[RCPU_HDR_SIZE], (uint8_t *)meta, len); + } else { + smeta = sinfo->cmic_type == 'x' ? (uint32_t *)meta : (uint32_t *)meta + 2; + wsize = sinfo->cmic_type == 'x' ? sinfo->pkt_hdr_size / 4 : sinfo->dcb_wsize - 3; + for (idx = 0; idx < wsize; idx++) { + dmeta[idx] = htonl(smeta[idx]); + } } + return 0; } @@ -2781,7 +2711,6 @@ packet_is_untagged(uint16_t tpid) { int is_untagged = 0; - /* Fixme SDK-111398 */ /* 0x8100 is used in 802.1Q */ /* 0x8848 is used in 802.11ad, the dtag tpid can be set to anything besides 0x8848, 0x9100 is a typical value, but couldn't cover all scenarios. */ is_untagged = ((tpid != 0x8100) && (tpid != 0x8848) && (tpid != 0x9100)); @@ -2866,615 +2795,707 @@ bkn_bitstream_get_field(uint8_t *input_buffer, uint32_t start_bit, uint32_t no } static void -bkn_dpp_packet_parse_ftmh(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dune_system_header_info_t *packet_info) -{ - uint32_t header_ptr = 0; - uint32_t dsp_ext_exist=0; +bkn_dpp_packet_parse_ftmh( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t *is_tsh_en, + uint8_t *is_inter_hdr_en) +{ + uint32_t pkt_offset = packet_info->system_header_size; + uint32_t dsp_ext_exist = 0; uint32_t fld_val; - header_ptr = packet_info->ntwrk_header_ptr; - - /* Packet-size */ - bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_FTMH_PKT_SIZE_MSB, - BKN_DPP_FTMH_PKT_SIZE_NOF_BITS, - &fld_val); - packet_info->ftmh.packet_size = fld_val; - /* Traffic-class */ - bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_FTMH_TC_MSB, - BKN_DPP_FTMH_TC_NOF_BITS, - &fld_val); - packet_info->ftmh.prio = fld_val; - /* Source-system-port-aggregate */ + /* FTMH: Source-system-port-aggregate */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], + &buf[pkt_offset], BKN_DPP_FTMH_SRC_SYS_PORT_MSB, BKN_DPP_FTMH_SRC_SYS_PORT_NOF_BITS, - &fld_val); - packet_info->ftmh.src_sys_port = fld_val; - /* TM-action-type */ + &packet_info->ftmh.source_sys_port_aggregate); + /* FTMH: TM-action-type */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], + &buf[pkt_offset], BKN_DPP_FTMH_ACTION_TYPE_MSB, BKN_DPP_FTMH_ACTION_TYPE_NOF_BITS, - &fld_val); - packet_info->ftmh.action_type = fld_val; - /* PPH-type */ + &packet_info->ftmh.action_type); + /* FTMH: Internal-type */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], + &buf[pkt_offset], BKN_DPP_FTMH_PPH_TYPE_MSB, BKN_DPP_FTMH_PPH_TYPE_NOF_BITS, &fld_val); - packet_info->ftmh.pph_type = fld_val; - - packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_SIZE_BYTE; - DBG_DUNE(("FTMH(%d) Packet-size %d Action-type %d PPH-type %d Source-system-port 0x%x Traffic-class %d\n", - packet_info->ntwrk_header_ptr, packet_info->ftmh.packet_size, packet_info->ftmh.action_type, - packet_info->ftmh.pph_type, packet_info->ftmh.src_sys_port, packet_info->ftmh.prio)); - /* LB-Key ext */ - if ((sinfo->pkt_hdr_size & BKN_DPP_FTMH_LB_EXT_EN) == BKN_DPP_FTMH_LB_EXT_EN) - { - packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_LB_EXT_SIZE_BYTE; - DBG_DUNE(("FTMH(%d) FTMH LB-Key Extension is present\n", packet_info->ntwrk_header_ptr)); - } - /* DSP ext*/ - fld_val = 0; + /* FTMH: DSP Extension */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], + &buf[pkt_offset], BKN_DPP_FTMH_EXT_DSP_EXIST_MSB, BKN_DPP_FTMH_EXT_DSP_EXIST_NOF_BITS, &dsp_ext_exist); + + if (fld_val & 0x1) + { + *is_inter_hdr_en = TRUE; + } + if (fld_val & 0x2) + { + *is_tsh_en = TRUE; + } + + pkt_offset += BKN_DPP_FTMH_SIZE_BYTE; + DBG_DUNE(("FTMH(9-%u): Action-type %d Source-system-port 0x%x\n", pkt_offset, + packet_info->ftmh.action_type, + packet_info->ftmh.source_sys_port_aggregate)); + + /* FTMH LB-Key Extension */ + if (sinfo->ftmh_lb_key_ext_size) + { + pkt_offset += sinfo->ftmh_lb_key_ext_size; + DBG_DUNE(("FTMH LB-Key Extension(1-%u) is present\n", pkt_offset)); + } + if (dsp_ext_exist) { - packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_DEST_EXT_SIZE_BYTE; - DBG_DUNE(("FTMH(%d) DSP-extension-present 1\n", packet_info->ntwrk_header_ptr)); + pkt_offset += BKN_DPP_FTMH_DEST_EXT_SIZE_BYTE; + DBG_DUNE(("FTMH DSP Extension(2-%u) is present\n", pkt_offset)); } - /* stacking ext */ - if ((sinfo->pkt_hdr_size & BKN_DPP_FTMH_STACKING_EXT_EN) == BKN_DPP_FTMH_STACKING_EXT_EN) + /* FTMH Stacking Extension */ + if (sinfo->ftmh_stacking_ext_size) { - packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_STACKING_SIZE_BYTE; - DBG_DUNE(("FTMH(%d) FTMH Stacking Extension is present\n", packet_info->ntwrk_header_ptr)); + pkt_offset += sinfo->ftmh_stacking_ext_size; + DBG_DUNE(("FTMH Stacking Extension(2-%u) is present\n", pkt_offset)); } + + packet_info->system_header_size = pkt_offset; return; } static void -bkn_dpp_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dune_system_header_info_t *packet_info) -{ - uint32_t header_ptr = 0; - uint32_t fld_val; +bkn_dpp_packet_parse_otsh( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t *is_oam_dm_tod_en, + uint8_t *is_skip_udh) +{ + uint32_t pkt_offset = packet_info->system_header_size; + uint32_t type = 0; + uint32_t oam_sub_type = 0; + + /* OTSH: TYPE */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DPP_OTSH_TYPE_MSB, + BKN_DPP_OTSH_TYPE_NOF_BITS, + &type); + if (type == BKN_DPP_OTSH_TYPE_OAM) { + /* OTSH: OAM_SUB_TYPE */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DPP_OTSH_OAM_SUB_TYPE_MSB, + BKN_DPP_OTSH_OAM_SUB_TYPE_NOF_BITS, + &oam_sub_type); + if ((oam_sub_type == BKN_DPP_OTSH_OAM_SUB_TYPE_DM_1588) || (oam_sub_type == BKN_DPP_OTSH_OAM_SUB_TYPE_DM_NTP)) { + *is_oam_dm_tod_en = TRUE; + /* Down MEP DM trapped packets will not have UDH present (even if configured), except for QAX when custom_feature_oam_dm_tod_msb_add_enable=0 */ + if (!sinfo->no_skip_udh_check) { + *is_skip_udh = TRUE; + } + } + } + packet_info->system_header_size += BKN_DPP_OTSH_SIZE_BYTE; + + DBG_DUNE(("OTSH(%d): Type 0x%x OAM-Sub-Type 0x%x\n", BKN_DPP_OTSH_SIZE_BYTE, type, oam_sub_type)); + return; +} + +static void +bkn_dpp_packet_parse_internal( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t is_oamp_punted, + uint8_t *is_trapped) +{ + uint32_t pkt_offset = packet_info->system_header_size; + uint32_t fld_val = 0; uint32_t eei_extension_present = 0; uint32_t learn_extension_present = 0; uint32_t fhei_size = 0; - uint32_t forward_code; - uint8_t is_trapped = 0; - - header_ptr = packet_info->ntwrk_header_ptr; + /* Internal: EEI EXT */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_EEI_EXTENSION_PRESENT_MSB, - BKN_DPP_PPH_EEI_EXTENSION_PRESENT_NOF_BITS, + &buf[pkt_offset], + BKN_DPP_INTERNAL_EEI_EXTENSION_PRESENT_MSB, + BKN_DPP_INTERNAL_EEI_EXTENSION_PRESENT_NOF_BITS, &eei_extension_present); + /* Internal: LERAN EXT */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_LEARN_EXENSION_PRESENT_MSB, - BKN_DPP_PPH_LEARN_EXENSION_PRESENT_NOF_BITS, + &buf[pkt_offset], + BKN_DPP_INTERNAL_LEARN_EXENSION_PRESENT_MSB, + BKN_DPP_INTERNAL_LEARN_EXENSION_PRESENT_NOF_BITS, &learn_extension_present); + /* Internal: FHEI EXT */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_FHEI_SIZE_MSB, - BKN_DPP_PPH_FHEI_SIZE_NOF_BITS, + &buf[pkt_offset], + BKN_DPP_INTERNAL_FHEI_SIZE_MSB, + BKN_DPP_INTERNAL_FHEI_SIZE_NOF_BITS, &fhei_size); + /* Internal: FORWARD_CODE */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_FORWARD_CODE_MSB, - BKN_DPP_PPH_FORWARD_CODE_NOF_BITS, - &forward_code); - /* 7: CPU-Trap */ - is_trapped = (uint8_t)(forward_code == 7); - + &buf[pkt_offset], + BKN_DPP_INTERNAL_FORWARD_CODE_MSB, + BKN_DPP_INTERNAL_FORWARD_CODE_NOF_BITS, + &fld_val); + *is_trapped = (uint8_t)(fld_val == BKN_DPP_INTERNAL_FORWARD_CODE_CPU_TRAP); + /* Internal: VSI */ bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_VSI_MSB, - BKN_DPP_PPH_VSI_NOF_BITS, + &buf[pkt_offset], + BKN_DPP_INTERNAL_VSI_MSB, + BKN_DPP_INTERNAL_VSI_NOF_BITS, &fld_val); - packet_info->internal.vsi = fld_val; + packet_info->internal.forward_domain = fld_val; - /* size of PPH base is 7 */ - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_SIZE_BYTE; - header_ptr = packet_info->ntwrk_header_ptr; + if (is_oamp_punted && *is_trapped) { + if(fhei_size == 3) { + /* Force to FHEI size 1 when packets are punted by OAMP */ + fhei_size = 1; + } + } - DBG_DUNE(("PPH(%d) Forward-Code %d EEI-Extension %d Learn-Extension %d VSI %d FHEI-size %d\n", packet_info->ntwrk_header_ptr, - forward_code, eei_extension_present, learn_extension_present, packet_info->internal.vsi, fhei_size)); + /* Move forward to end of Internal header */ + pkt_offset += BKN_DPP_INTERNAL_SIZE_BYTE; - /* PPH extension */ - if (is_trapped && (fhei_size == 1)) - { - /* CPU trap code qualifier */ - bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB, - BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS, - &fld_val); - packet_info->internal.trap_qualifier = fld_val; - /* CPU trap code */ - bkn_bitstream_get_field( - &hdr_buff[header_ptr], - BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB, - BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS, - &fld_val); - packet_info->internal.trap_id = fld_val; - } + DBG_DUNE(("PPH(7-%u): EEI-Extension %d Learn-Extension %d VSI %d FHEI-size %d\n", + pkt_offset, eei_extension_present,learn_extension_present, packet_info->internal.forward_domain, fhei_size)); + + /* Advance header according to FHEI Trap extension */ switch(fhei_size) { case 1: - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_3B_SIZE_BYTE; + /* 3B FHEI Extension: do nothing, header poniter is in the right location */ break; case 2: - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_5B_SIZE_BYTE; + /* 5B FHEI Extension: adavance header pointer in 2B */ + pkt_offset += 2; break; case 3: - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_8B_SIZE_BYTE; + /* 8B FHEI Extension: adavance header pointer in 5B */ + pkt_offset += 5; break; default: break; } + + /* Internal extension */ + if (*is_trapped && fhei_size) + { + /* CPU trap code qualifier */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB, + BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS, + &packet_info->internal.trap_qualifier); + /* CPU trap code */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB, + BKN_DPP_INTERNAL_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS, + &packet_info->internal.trap_id); + + DBG_DUNE(("FHEI: trap_qualifier 0x%x trap_id 0x%x\n", + packet_info->internal.trap_qualifier, + packet_info->internal.trap_id)); + } + + /* Move forward to end of FHEI Trap extension */ + if (fhei_size) { + pkt_offset += 3; + } + + /* EEI extension */ if (eei_extension_present) { - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE; + pkt_offset += BKN_DPP_INTERNAL_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE; } + /* Learn extension */ if (learn_extension_present) { - packet_info->ntwrk_header_ptr += BKN_DPP_PPH_LEARN_EXTENSION_SIZE_BYTE; + pkt_offset += BKN_DPP_INTERNAL_LEARN_EXTENSION_SIZE_BYTE; } - DBG_DUNE(("FHEI(%d) trap_qualifier 0x%x trap_id 0x%x\n", packet_info->ntwrk_header_ptr, packet_info->internal.trap_qualifier, packet_info->internal.trap_id)); + packet_info->system_header_size = pkt_offset; return; } static int -bkn_dpp_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buff, uint32_t buff_len, bkn_dune_system_header_info_t *packet_info) -{ - uint8_t hdr_buff[BKN_DPP_HDR_MAX_SIZE]; - uint32_t hdr_size; - uint8_t has_internal = 0; - - if ((buff == NULL) || (packet_info == NULL)) { +bkn_dpp_packet_header_parse( + bkn_switch_info_t *sinfo, + uint8_t *buff, + uint32_t buff_len, + bkn_dune_system_header_info_t *packet_info) +{ + uint8_t is_inter_hdr_en = FALSE; + uint8_t is_tsh_en = FALSE; + uint8_t is_oamp_punted = FALSE; + uint8_t is_trapped = FALSE; + uint8_t is_oam_dm_tod_en = FALSE; + uint8_t is_skip_udh = FALSE; + + if ((sinfo == NULL) || (buff == NULL) || (packet_info == NULL)) { return -1; } - hdr_size = buff_len < BKN_DPP_HDR_MAX_SIZE ? buff_len: BKN_DPP_HDR_MAX_SIZE; - memcpy(hdr_buff, buff, hdr_size); /* FTMH */ - bkn_dpp_packet_parse_ftmh(sinfo, hdr_buff, packet_info); - if (packet_info->ftmh.packet_size != (buff_len + 2)) { - DBG_DUNE(("FTMH packet size verfication failed, %d-%d\n", packet_info->ftmh.packet_size, buff_len)); - memset(packet_info, 0, sizeof(bkn_dune_system_header_info_t)); - return -1; + bkn_dpp_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + /* Check if packet is punted from OAMP */ + if (sinfo->oamp_punt && (packet_info->ftmh.source_sys_port_aggregate == sinfo->oamp_punt)) { + is_oamp_punted = TRUE; } - switch (packet_info->ftmh.pph_type) { - case 0: - has_internal = 0; - break; - case 1: - has_internal = 1; - break; - case 2: /* PPH OAM-TS only */ - case 3: /* PPH Base + OAM-TS */ - /* OTSH immediately follows the FTMH when present */ - packet_info->ntwrk_header_ptr += 6; - DBG_DUNE(("FTMH + OAM-TS(%d)\n", packet_info->ntwrk_header_ptr)); - has_internal = 1; - break; - default: - break; + /* OTSH */ + if (is_tsh_en == TRUE) + { + bkn_dpp_packet_parse_otsh(sinfo, buff, buff_len, packet_info, &is_oam_dm_tod_en, &is_skip_udh); + } + /* Internal header is forced to be present if packet was punted to CPU by OAMP */ + if (sinfo->oamp_punt && (packet_info->ftmh.source_sys_port_aggregate == sinfo->oamp_punt)) + { + is_inter_hdr_en = TRUE; + } + /* Internal */ + if (is_inter_hdr_en) + { + bkn_dpp_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); + } + /* Skip UDH for the outer layer when packet is punted by OAM for JR2 in JR1 mode */ + if (device_is_dnx(sinfo) && is_oamp_punted) { + is_skip_udh = TRUE; + } + /* UDH */ + if (sinfo->udh_size && !is_skip_udh) { + packet_info->system_header_size += sinfo->udh_size; + } + /* OAM DM TOD header */ + if(is_oam_dm_tod_en) { + packet_info->system_header_size += BKN_DPP_OAM_DM_TOD_SIZE_BYTE; } - if (has_internal) { - bkn_dpp_packet_parse_internal(sinfo, &hdr_buff[0], packet_info); + /* Additional layer of system headers */ + if (is_oamp_punted && is_trapped) + { + is_inter_hdr_en = FALSE; + is_tsh_en = FALSE; + is_oamp_punted = FALSE; + is_trapped = FALSE; + is_oam_dm_tod_en = FALSE; + is_skip_udh = FALSE; + + /* FTMH */ + bkn_dpp_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + /* OTSH */ + if (is_tsh_en == TRUE) + { + bkn_dpp_packet_parse_otsh(sinfo, buff, buff_len, packet_info, &is_oam_dm_tod_en, &is_skip_udh); + } + /* Internal */ + if (is_inter_hdr_en) + { + bkn_dpp_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); + } + /* OAMP Punted packets do not have UDH in the inner header for both JR1 and JR2 in JR1 mode */ + /* OAM DM TOD header */ + if(is_oam_dm_tod_en) { + packet_info->system_header_size += BKN_DPP_OAM_DM_TOD_SIZE_BYTE; + } } - /* FIXME: */ - /* ignore packets with a double set of FTMH,internals */ - /* ignore the user header size */ + DBG_DUNE(("Total length of headers is %u\n", packet_info->system_header_size)); + return 0; } + static int -bkn_dnx_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buf, uint32_t buf_len, bkn_dune_system_header_info_t *packet_info) +bkn_dnx_packet_parse_ftmh( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t *is_tsh_en, + uint8_t *is_inter_hdr_en) { uint32_t fld_val; - uint32_t hdr_size = 0; - uint32_t pkt_offset_ingress_untrapped =0; + uint32_t pkt_offset = packet_info->system_header_size; uint8_t tm_dst_ext_present = 0; uint8_t app_specific_ext_size = 0; uint8_t flow_id_ext_size = 0; uint8_t bier_bfr_ext_size = 0; - uint8_t is_pph_en = 0; - uint8_t is_tsh_en = 0; - if ((buf == NULL) || (packet_info == NULL)) { + if ((sinfo == NULL) || (buf == NULL) || (packet_info == NULL)) { return -1; } /* FTMH: Source-System-Port-Aggregate */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_MSB, BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_NOF_BITS, &fld_val); - packet_info->ftmh_spa = fld_val; + packet_info->ftmh.source_sys_port_aggregate = fld_val; + /* FTMH: Action-Type */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_FTMH_ACTION_TYPE_MSB, + BKN_DNX_FTMH_ACTION_TYPE_NOF_BITS, + &fld_val); + packet_info->ftmh.action_type = fld_val; /* FTMH: PPH-Type TSH */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_MSB, BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_NOF_BITS, &fld_val); - is_tsh_en = fld_val; + *is_tsh_en = fld_val; /* FTMH: PPH-Type PPH base */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_MSB, BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_NOF_BITS, &fld_val); - is_pph_en = fld_val; + *is_inter_hdr_en = fld_val; /* FTMH: TM-Destination-Extension-Present */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_TM_DST_EXT_PRESENT_MSB, BKN_DNX_FTMH_TM_DST_EXT_PRESENT_NOF_BITS, &fld_val); tm_dst_ext_present = fld_val; /* FTMH: Application-Specific-Extension-Size */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_MSB, BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_NOF_BITS, &fld_val); app_specific_ext_size = fld_val; /* FTMH: Flow-ID-Extension-Size */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_MSB, BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_NOF_BITS, &fld_val); flow_id_ext_size = fld_val; /* FTMH: BIER-BFR-Extension-Size */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_MSB, BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_NOF_BITS, &fld_val); bier_bfr_ext_size = fld_val; - hdr_size = BKN_DNX_FTMH_BASE_SIZE; - pkt_offset_ingress_untrapped = BKN_DNX_FTMH_BASE_SIZE; + pkt_offset += BKN_DNX_FTMH_BASE_SIZE; - DBG_DUNE(("FTMH(%d) source-system-port 0x%x is_tsh_en %d is_pph_en %d\n", - hdr_size, packet_info->ftmh_spa, is_tsh_en, is_pph_en)); + DBG_DUNE(("FTMH(10-%u): source-system-port 0x%x action_type %u is_tsh_en %u is_inter_hdr_en %u\n", + pkt_offset, packet_info->ftmh.source_sys_port_aggregate, + packet_info->ftmh.action_type, *is_tsh_en, *is_inter_hdr_en)); /* FTMH LB-Key Extension */ if (sinfo->ftmh_lb_key_ext_size > 0) { - hdr_size += sinfo->ftmh_lb_key_ext_size; - DBG_DUNE(("FTMH LB-Key Extension(%d) is present\n", sinfo->ftmh_lb_key_ext_size)); + pkt_offset += sinfo->ftmh_lb_key_ext_size; + DBG_DUNE(("FTMH LB-Key Extension(%u-%u) is present\n", sinfo->ftmh_lb_key_ext_size, pkt_offset)); } /* FTMH Stacking Extension */ if (sinfo->ftmh_stacking_ext_size > 0) { - hdr_size += sinfo->ftmh_stacking_ext_size; - DBG_DUNE(("FTMH Stacking Extension(%d) is present\n", sinfo->ftmh_stacking_ext_size)); + pkt_offset += sinfo->ftmh_stacking_ext_size; + DBG_DUNE(("FTMH Stacking Extension(%u-%u) is present\n", sinfo->ftmh_stacking_ext_size, pkt_offset)); } /* FTMH BIER BFR Extension */ if (bier_bfr_ext_size > 0) { - hdr_size += BKN_DNX_FTMH_BIER_BFR_EXT_SIZE; - DBG_DUNE(("FTMH BIER BFR Extension(2) is present\n")); + pkt_offset += BKN_DNX_FTMH_BIER_BFR_EXT_SIZE; + DBG_DUNE(("FTMH BIER BFR Extension(2-%u) is present\n", pkt_offset)); } /* FTMH TM Destination Extension */ if (tm_dst_ext_present > 0) { - hdr_size += BKN_DNX_FTMH_TM_DST_EXT_SIZE; - DBG_DUNE(("FTMH TM Destination Extension(3) is present\n")); + pkt_offset += BKN_DNX_FTMH_TM_DST_EXT_SIZE; + DBG_DUNE(("FTMH TM Destination Extension(3-%u) is present\n", pkt_offset)); } /* FTMH Application Specific Extension */ if (app_specific_ext_size > 0) { - hdr_size += BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE; - DBG_DUNE(("FTMH Application Specific Extension(6) is present\n")); + pkt_offset += BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE; + DBG_DUNE(("FTMH Application Specific Extension(6-%u) is present\n", pkt_offset)); } /* FTMH Flow-ID Extension */ if (flow_id_ext_size > 0) { - hdr_size += BKN_DNX_FTMH_FLOW_ID_EXT_SIZE; - DBG_DUNE(("FTMH Flow-ID Extension(3) is present\n")); + pkt_offset += BKN_DNX_FTMH_FLOW_ID_EXT_SIZE; + DBG_DUNE(("FTMH Flow-ID Extension(3-%u) is present\n", pkt_offset)); } - /* Given the packet is trapped to CPU */ + packet_info->system_header_size = pkt_offset; - /* Time-Stamp Header */ - if (is_tsh_en == TRUE) - { - hdr_size += BKN_DNX_TSH_SIZE; - DBG_DUNE(("Time-Stamp Header(4) is present\n")); - } + return 0; +} - /* Packet Processing Header */ - if (is_pph_en) - { - uint8_t learn_ext_present; - uint8_t fhei_size; - uint8_t lif_ext_type; - switch (sinfo->pph_base_size) - { - case BKN_DNX_PPH_BASE_TYPE_9: - /* FTMH: Forward-Domain */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_9_FORWARD_DOMAIN_MSB, - BKN_DNX_PPH_9_FORWARD_DOMAIN_NOF_BITS, - &fld_val); - packet_info->pph_forward_domain = fld_val; - /* FTMH: Learn-Extension-Present */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_9_LEARN_EXT_PRESENT_MSB, - BKN_DNX_PPH_9_LEARN_EXT_PRESENT_NOF_BITS, - &fld_val); - learn_ext_present = fld_val; - /* FTMH: FHEI-Size */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_9_FHEI_SIZE_MSB, - BKN_DNX_PPH_9_FHEI_SIZE_NOF_BITS, - &fld_val); - fhei_size = fld_val; - /* FTMH: LIF-Extension-Type */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_9_LIF_EXT_TYPE_MSB, - BKN_DNX_PPH_9_LIF_EXT_TYPE_NOF_BITS, - &fld_val); - lif_ext_type = fld_val; +static int +bkn_dnx_packet_parse_internal( + bkn_switch_info_t *sinfo, + uint8_t *buf, + uint32_t buf_len, + bkn_dune_system_header_info_t *packet_info, + uint8_t is_oamp_punted, + uint8_t *is_trapped) +{ + uint32_t fld_val; + uint32_t pkt_offset = packet_info->system_header_size; + uint8_t learn_ext_present; + uint8_t fhei_size; + uint8_t lif_ext_type; + uint8_t udh_en = sinfo->udh_enable; - hdr_size += BKN_DNX_PPH_BASE_TYPE_9; - DBG_DUNE(("PPH(10) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", - packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); - break; - case BKN_DNX_PPH_BASE_TYPE_10: - /* FTMH: Forward-Domain */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_10_FORWARD_DOMAIN_MSB, - BKN_DNX_PPH_10_FORWARD_DOMAIN_NOF_BITS, - &fld_val); - packet_info->pph_forward_domain = fld_val; - /* FTMH: Learn-Extension-Present */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_10_LEARN_EXT_PRESENT_MSB, - BKN_DNX_PPH_10_LEARN_EXT_PRESENT_NOF_BITS, - &fld_val); - learn_ext_present = fld_val; - /* FTMH: FHEI-Size */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_10_FHEI_SIZE_MSB, - BKN_DNX_PPH_10_FHEI_SIZE_NOF_BITS, - &fld_val); - fhei_size = fld_val; - /* FTMH: LIF-Extension-Type */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_10_LIF_EXT_TYPE_MSB, - BKN_DNX_PPH_10_LIF_EXT_TYPE_NOF_BITS, - &fld_val); - lif_ext_type = fld_val; + if ((sinfo == NULL) || (buf == NULL) || (packet_info == NULL)) { + return -1; + } + + /* Internal: Forward-Domain */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_12_FORWARD_DOMAIN_MSB, + BKN_DNX_INTERNAL_12_FORWARD_DOMAIN_NOF_BITS, + &fld_val); + packet_info->internal.forward_domain = fld_val; + /* Internal: Learn-Extension-Present */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_12_LEARN_EXT_PRESENT_MSB, + BKN_DNX_INTERNAL_12_LEARN_EXT_PRESENT_NOF_BITS, + &fld_val); + learn_ext_present = fld_val; + /* Internal: FHEI-Size */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_12_FHEI_SIZE_MSB, + BKN_DNX_INTERNAL_12_FHEI_SIZE_NOF_BITS, + &fld_val); + fhei_size = fld_val; + /* Internal: LIF-Extension-Type */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_12_LIF_EXT_TYPE_MSB, + BKN_DNX_INTERNAL_12_LIF_EXT_TYPE_NOF_BITS, + &fld_val); + lif_ext_type = fld_val; - hdr_size += BKN_DNX_PPH_BASE_TYPE_10; - DBG_DUNE(("PPH(10) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", - packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); + pkt_offset += BKN_DNX_INTERNAL_BASE_TYPE_12; + DBG_DUNE(("Internal(12-%u): FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", + pkt_offset, packet_info->internal.forward_domain, + learn_ext_present, fhei_size, lif_ext_type)); + + if (fhei_size) + { + switch (fhei_size) + { + case BKN_DNX_INTERNAL_FHEI_TYPE_SZ0: + pkt_offset += BKN_DNX_INTERNAL_FHEI_SZ0_SIZE; + DBG_DUNE(("FHEI(3-%u) is present\n", pkt_offset)); break; - case BKN_DNX_PPH_BASE_TYPE_12: - /* FTMH: Forward-Domain */ + case BKN_DNX_INTERNAL_FHEI_TYPE_SZ1: + /* FHEI: Type */ bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB, - BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS, + &buf[pkt_offset], + BKN_DNX_INTERNAL_FHEI_TRAP_5B_TYPE_MSB, + BKN_DNX_INTERNAL_FHEI_TRAP_5B_TYPE_NOF_BITS, &fld_val); - packet_info->pph_forward_domain = fld_val; - /* FTMH: Learn-Extension-Present */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_LEARN_EXT_PRESENT_MSB, - BKN_DNX_PPH_12_LEARN_EXT_PRESENT_NOF_BITS, - &fld_val); - learn_ext_present = fld_val; - /* FTMH: FHEI-Size */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_FHEI_SIZE_MSB, - BKN_DNX_PPH_12_FHEI_SIZE_NOF_BITS, - &fld_val); - fhei_size = fld_val; - /* FTMH: LIF-Extension-Type */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_LIF_EXT_TYPE_MSB, - BKN_DNX_PPH_12_LIF_EXT_TYPE_NOF_BITS, - &fld_val); - lif_ext_type = fld_val; - - hdr_size += BKN_DNX_PPH_BASE_TYPE_12; - DBG_DUNE(("PPH(12) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", - packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); - break; - default: - fhei_size = 0; - lif_ext_type = 0; - learn_ext_present = 0; - break; - } - if (fhei_size) - { - switch (fhei_size) - { - case BKN_DNX_PPH_FHEI_TYPE_SZ0: - hdr_size += BKN_DNX_PPH_FHEI_SZ0_SIZE; - DBG_DUNE(("FHEI(3) is present\n")); - break; - case BKN_DNX_PPH_FHEI_TYPE_SZ1: + /* FHEI-Size == 5B, FHEI-Type == Trap/Sniff */ + if (fld_val == 0x5) + { + *is_trapped = TRUE; + /* FHEI: Qualifier */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_INTERNAL_FHEI_TRAP_5B_QUALIFIER_MSB, + BKN_DNX_INTERNAL_FHEI_TRAP_5B_QUALIFIER_NOF_BITS, + &fld_val); + packet_info->internal.trap_qualifier = fld_val; /* FHEI: Code */ bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_MSB, - BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_NOF_BITS, + &buf[pkt_offset], + BKN_DNX_INTERNAL_FHEI_TRAP_5B_CODE_MSB, + BKN_DNX_INTERNAL_FHEI_TRAP_5B_CODE_NOF_BITS, &fld_val); - packet_info->fhei_type = fld_val; - /* FHEI-Size == 5B, FHEI-Type == Trap/Sniff */ - if (packet_info->fhei_type == 0x5) - { - /* FHEI: Qualifier */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_MSB, - BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_NOF_BITS, - &fld_val); - packet_info->fhei_qualifier = fld_val; - /* FHEI: Code */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_FHEI_TRAP_5B_CODE_MSB, - BKN_DNX_PPH_FHEI_TRAP_5B_CODE_NOF_BITS, - &fld_val); - packet_info->fhei_code = fld_val; - } - hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; - DBG_DUNE(("FHEI(5) is present code 0x%x qualifier 0x%x\n", packet_info->fhei_code, packet_info->fhei_qualifier)); - break; - case BKN_DNX_PPH_FHEI_TYPE_SZ2: - hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; - DBG_DUNE(("FHEI(8) is present\n")); - break; - } + packet_info->internal.trap_id= fld_val; + } + pkt_offset += BKN_DNX_INTERNAL_FHEI_SZ1_SIZE; + DBG_DUNE(("FHEI(5-%u): code 0x%x qualifier 0x%x\n", pkt_offset, packet_info->internal.trap_id, packet_info->internal.trap_qualifier)); + break; + case BKN_DNX_INTERNAL_FHEI_TYPE_SZ2: + pkt_offset += BKN_DNX_INTERNAL_FHEI_SZ1_SIZE; + DBG_DUNE(("FHEI(8-%u) is present\n", pkt_offset)); + break; } + } - /* PPH LIF Extension */ - if (lif_ext_type) - { - hdr_size += sinfo->pph_lif_ext_size[lif_ext_type]; - DBG_DUNE(("PPH LIF Extension(%d) is present\n", sinfo->pph_lif_ext_size[lif_ext_type])); - } + /* PPH LIF Extension */ + if (lif_ext_type) + { + pkt_offset += sinfo->pph_lif_ext_size[lif_ext_type]; + DBG_DUNE(("PPH LIF Extension(%d-%u) is present\n", sinfo->pph_lif_ext_size[lif_ext_type], pkt_offset)); + } - /* PPH Learn Extension */ - if (learn_ext_present) - { - hdr_size += BKN_DNX_PPH_LEARN_EXT_SIZE; - DBG_DUNE(("PPH Learn Extension(19) is present\n")); - } + /* PPH Learn Extension */ + if (learn_ext_present) + { + pkt_offset += BKN_DNX_INTERNAL_LEARN_EXT_SIZE; + DBG_DUNE(("PPH Learn Extension(19-%u) is present\n", pkt_offset)); + } + + /** Skip UDH If packet is punted to CPU by OAMP */ + if (is_oamp_punted) { + udh_en = FALSE; } /* UDH Header */ - if (sinfo->udh_enable) + if (udh_en) { - uint8 data_type_0; - uint8 data_type_1; - uint8 data_type_2; - uint8 data_type_3; - - DBG_DUNE(("UDH base(1) is present\n")); + uint8_t data_type_0; + uint8_t data_type_1; + uint8_t data_type_2; + uint8_t data_type_3; /* UDH: UDH-Data-Type[0] */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_UDH_DATA_TYPE_0_MSB, BKN_DNX_UDH_DATA_TYPE_0_NOF_BITS, &fld_val); data_type_0 = fld_val; - hdr_size += sinfo->udh_length_type[data_type_0]; /* UDH: UDH-Data-Type[1] */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_UDH_DATA_TYPE_1_MSB, BKN_DNX_UDH_DATA_TYPE_1_NOF_BITS, &fld_val); data_type_1 = fld_val; - hdr_size += sinfo->udh_length_type[data_type_1]; /* UDH: UDH-Data-Type[2] */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_UDH_DATA_TYPE_2_MSB, BKN_DNX_UDH_DATA_TYPE_2_NOF_BITS, &fld_val); data_type_2 = fld_val; - hdr_size += sinfo->udh_length_type[data_type_2]; /* UDH: UDH-Data-Type[3] */ bkn_bitstream_get_field( - &buf[hdr_size], + &buf[pkt_offset], BKN_DNX_UDH_DATA_TYPE_3_MSB, BKN_DNX_UDH_DATA_TYPE_3_NOF_BITS, &fld_val); data_type_3 = fld_val; - hdr_size += sinfo->udh_length_type[data_type_3]; - hdr_size += BKN_DNX_UDH_BASE_SIZE; + pkt_offset += BKN_DNX_UDH_BASE_SIZE; + pkt_offset += sinfo->udh_length_type[data_type_0]; + pkt_offset += sinfo->udh_length_type[data_type_1]; + pkt_offset += sinfo->udh_length_type[data_type_2]; + pkt_offset += sinfo->udh_length_type[data_type_3]; + DBG_DUNE(("UDH base(1-%u) is present\n", pkt_offset)); } - /* - * Check if fhei_type if of type trap - * There is a RISK that raw packet data is parsed and fhei_type is 0x5 by chance - */ - if (packet_info->fhei_type == 0x5) + packet_info->system_header_size = pkt_offset; + + return 0; +} + +static int +bkn_dnx_packet_header_parse( + bkn_switch_info_t *sinfo, + uint8_t *buff, + uint32_t buff_len, + bkn_dune_system_header_info_t *packet_info) +{ + uint8_t is_inter_hdr_en = FALSE; + uint8_t is_tsh_en = FALSE; + uint8_t is_oamp_punted = FALSE; + uint8_t is_trapped = FALSE; + + if ((sinfo == NULL) || (buff == NULL) || (packet_info == NULL)) { + return -1; + } + + /* FTMH */ + bkn_dnx_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + + /* Time-Stamp */ + if (is_tsh_en == TRUE) { - /* Done for ingress trapped packets */ - packet_info->system_header_size = hdr_size; - DBG_DUNE(("Total Size of Headers is %d\n", packet_info->system_header_size)); - return 0; + packet_info->system_header_size += BKN_DNX_TSH_SIZE; + DBG_DUNE(("Time-Stamp Header(4-%u) is present\n", packet_info->system_header_size)); } - else + + /* Check if packet was punted to CPU by OAMP */ + if ((packet_info->ftmh.source_sys_port_aggregate == 232) + || (packet_info->ftmh.source_sys_port_aggregate == 233)) { - /* New generated header will be FTMH(80b), TSH(32b), PPH(96b), FHEI(40b) */ + is_oamp_punted = TRUE; + } - /* Revert packet_info except info from FTHM base header */ - packet_info->fhei_qualifier = 0; - packet_info->fhei_code = 0; - packet_info->fhei_type = 0; - hdr_size = pkt_offset_ingress_untrapped; + /* Internal */ + if (is_inter_hdr_en) + { + bkn_dnx_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); + } - /* Time-Stamp Header */ - hdr_size += BKN_DNX_TSH_SIZE; - DBG_DUNE(("Time-Stamp Header(4) is present\n")); + if (is_oamp_punted) + { + is_inter_hdr_en = FALSE; + is_tsh_en = FALSE; + is_oamp_punted = FALSE; + is_trapped = FALSE; + + /* FTMH */ + bkn_dnx_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + /* Time-Stamp */ + if (is_tsh_en == TRUE) + { + packet_info->system_header_size += BKN_DNX_TSH_SIZE; + DBG_DUNE(("Time-Stamp Header(4-%u) is present\n", packet_info->system_header_size)); + } + /* Internal */ + if (is_inter_hdr_en) + { + bkn_dnx_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); + } + } - /** Packet Processing Header */ - bkn_bitstream_get_field( - &buf[hdr_size], - BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB, - BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS, - &fld_val); - packet_info->pph_forward_domain = fld_val; - hdr_size += BKN_DNX_PPH_BASE_TYPE_12; - DBG_DUNE(("PPH(12) is present\n")); + DBG_DUNE(("Total length of headers is %u\n", packet_info->system_header_size)); - /* - * FHEI(Trap,40) - * 5B-FHEI format for sys_hdr_generation_profile:J2-OAM - * 8b' 0 - * 19b'oam_id - * 9b' cpu_trap_code: INGRESS_TRAP_ID is always 0 here - * 4b' type(0x5): J2-Configuration FHEI Type for CPU trap - */ - hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; - DBG_DUNE(("FHEI(5) is present\n")); + return 0; +} + +static int +bkn_packet_header_parse(bkn_switch_info_t *sinfo, uint8_t *buf, uint32_t buf_len, bkn_dune_system_header_info_t *packet_info) +{ + if (device_is_dpp(sinfo)) + { + bkn_dpp_packet_header_parse(sinfo, buf, buf_len, packet_info); + } + else if (device_is_dnx(sinfo)) + { + if (sinfo->system_headers_mode == BKN_DNX_JR2_MODE) + { + /* Jericho 2 mode */ + bkn_dnx_packet_header_parse(sinfo, buf, buf_len, packet_info); + } + else + { + /* Jericho/QMX/QAX mode */ + bkn_dpp_packet_header_parse(sinfo, buf, buf_len, packet_info); + } } - packet_info->system_header_size = hdr_size; - DBG_DUNE(("Total Size of Headers is %d\n", packet_info->system_header_size)); return 0; } - static int bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) { @@ -3492,8 +3513,8 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) int pktlen; int idx; int dcbs_done = 0; - bkn_dune_system_header_info_t packet_info = {0}; - uint32_t dnx_meta_data[3] = {0}; + bkn_dune_system_header_info_t packet_info; + uint32_t sand_scratch_data[BKN_SAND_SCRATCH_DATA_SIZE] = {0}; dcb_chain = sinfo->rx[chan].api_dcb_chain; if (dcb_chain == NULL) { @@ -3536,84 +3557,76 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) pkt_dma = dcb[0]; } pkt = (uint8_t *)kernel_bde->p2l(sinfo->dev_no, (sal_paddr_t)pkt_dma); - if (sinfo->cmic_type == 'x') { - if (device_is_dnx(sinfo)){ - meta = &dnx_meta_data[0]; - /* get error bit from last DCB words */ - err_woff = 2; - meta[err_woff] = dcb[sinfo->dcb_wsize-1]; - } else { + + if (device_is_sand(sinfo)) { + err_woff = BKN_SAND_SCRATCH_DATA_SIZE - 1; + sand_scratch_data[err_woff] = dcb[sinfo->dcb_wsize-1]; + meta = (uint32_t *)pkt; + } else { + if (sinfo->cmic_type == 'x') { meta = (uint32_t *)pkt; err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } else { + meta = dcb; + err_woff = sinfo->dcb_wsize - 1; } - } else { - meta = dcb; - err_woff = sinfo->dcb_wsize - 1; } + pktlen = dcb[sinfo->dcb_wsize-1] & SOC_DCB_KNET_COUNT_MASK; bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); - if (device_is_dpp(sinfo)) { - uint16_t tpid = 0; - uint16_t vid = 0; - int res = -1; - + if (device_is_sand(sinfo)) { memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); - res = bkn_dpp_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - if (res == 0) { - if (packet_info.ftmh.action_type == 0x2) { - bkn_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); - } else if (packet_info.ftmh.action_type == 0x1) { - bkn_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); - } - bkn_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); - bkn_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); - bkn_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); - pkt += packet_info.ntwrk_header_ptr; - pktlen -= packet_info.ntwrk_header_ptr; - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); - /* check if vlan tag exists */ - tpid = (uint16_t)((pkt[12] << 8) | pkt[13]); - vid = (uint16_t)(packet_info.internal.vsi & 0xfff); + /* decode system headers and fill sratch data */ + bkn_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + bkn_bitstream_set_field(sand_scratch_data, 0, 16, packet_info.internal.trap_id); + bkn_bitstream_set_field(sand_scratch_data, 16, 16, packet_info.internal.trap_qualifier); + bkn_bitstream_set_field(sand_scratch_data, 32, 16, packet_info.ftmh.source_sys_port_aggregate); + bkn_bitstream_set_field(sand_scratch_data, 48, 16, packet_info.internal.forward_domain); + bkn_bitstream_set_field(sand_scratch_data, 64, 2, packet_info.ftmh.action_type); + + if (force_tagged) { + uint8_t *eth_hdr = pkt + packet_info.system_header_size; + uint16_t tpid = 0; + + tpid = PKT_U16_GET(eth_hdr, 12); if (packet_is_untagged(tpid)) { + int raw_packet_len = pktlen - packet_info.system_header_size; + uint32_t vid = 0; + if ((pktlen + 4) < rx_buffer_size) { - DBG_DUNE(("add vlan tag (%d) to untagged packets\n", vid)); - for (idx = (pktlen-1); idx >= 12; idx--) { - pkt[idx+4] = pkt[idx]; + for (idx = (raw_packet_len - 1); idx >= 12; idx--) { + eth_hdr[idx+4] = eth_hdr[idx]; + } + if (ft_vid) { + vid = ft_vid; + } + else if (packet_info.internal.forward_domain) { + vid = packet_info.internal.forward_domain & 0xfff; } - pkt[12] = 0x81; - pkt[13] = 0x00; - pkt[14] = (vid >> 8); - pkt[15] = (vid & 0xff); + else { + vid = 1; + } + DBG_DUNE(("add vlan tag (%d) to untagged packets\n", vid)); + + eth_hdr[12] = (ft_tpid >> 8) & 0xff; + eth_hdr[13] = ft_tpid & 0xff; + eth_hdr[14] = (((ft_pri & 0x7) << 5) | ((ft_cfi & 0x1) << 4) | ((vid >> 8) & 0xf)) & 0xff; + eth_hdr[15] = vid & 0xff; /* reset packet length in DCB */ pktlen += 4; + bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; - dcb[sinfo->dcb_wsize-1] |= ((pktlen + packet_info.ntwrk_header_ptr) & SOC_DCB_KNET_COUNT_MASK); - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); + dcb[sinfo->dcb_wsize-1] |= pktlen & SOC_DCB_KNET_COUNT_MASK; } } } } - else if (device_is_dnx(sinfo)) { - int res = -1; - res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - if (res == 0) { - bkn_bitstream_set_field(meta, 0, 16, packet_info.fhei_code); - bkn_bitstream_set_field(meta, 16, 16, packet_info.fhei_qualifier); - bkn_bitstream_set_field(meta, 32, 16, packet_info.ftmh_spa); - bkn_bitstream_set_field(meta, 48, 16, (packet_info.pph_forward_domain & 0xffff)); - - pkt += packet_info.system_header_size; - pktlen -= packet_info.system_header_size; - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); - } - } - if (device_is_dpp(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, pkt, pktlen, dcb, chan, &cbf); - } else if (device_is_dnx(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, pkt, pktlen, meta, chan, &cbf); + if (device_is_sand(sinfo)) { + filter = bkn_match_rx_pkt(sinfo, pkt + packet_info.system_header_size, + pktlen - packet_info.system_header_size, sand_scratch_data, chan, &cbf); } else { filter = bkn_match_rx_pkt(sinfo, pkt + sinfo->pkt_hdr_size, pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); @@ -3643,7 +3656,10 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) break; } - if (sinfo->cmic_type == 'x') { + if (device_is_sand(sinfo)) { + pkt += packet_info.system_header_size; + pktlen -= packet_info.system_header_size; + } else if (sinfo->cmic_type == 'x') { pkt += sinfo->pkt_hdr_size; pktlen -= sinfo->pkt_hdr_size; } @@ -3663,12 +3679,14 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) skb_reserve(skb, 2); /* 16 byte align the IP fields. */ /* Save for RCPU before stripping tag */ - ethertype = (pkt[16] << 8) | pkt[17]; + ethertype = PKT_U16_GET(pkt, 16); if ((priv->flags & KCOM_NETIF_F_KEEP_RX_TAG) == 0) { + uint16_t vlan_proto = PKT_U16_GET(pkt, 12); + if (filter->kf.flags & KCOM_FILTER_F_STRIP_TAG) { /* Strip the VLAN tag */ - uint16_t vlan_proto = (uint16_t)((pkt[12] << 8) | pkt[13]); - if (vlan_proto == 0x8100 || vlan_proto == 0x88a8) { + if (vlan_proto == ETH_P_8021Q || + vlan_proto == ETH_P_8021AD) { DBG_FLTR(("Strip VLAN tag\n")); for (idx = 11; idx >= 0; idx--) { pkt[idx+4] = pkt[idx]; @@ -3681,12 +3699,18 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) * Mark packet as VLAN-tagged, otherwise newer * kernels will strip the tag. */ - uint16_t tci = (pkt[14] << 8) | pkt[15]; + uint16_t tci = PKT_U16_GET(pkt, 14); + if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { bkn_vlan_hwaccel_put_tag(skb, ETH_P_8021Q, tci); } else { - bkn_vlan_hwaccel_put_tag(skb, - ((skb->data[12] << 8) | skb->data[13]), tci); + if (vlan_proto == ETH_P_8021AD) { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021AD, tci); + } else { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021Q, tci); + } } } } @@ -3702,11 +3726,16 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) priv->stats.rx_bytes += skb->len; /* Optional SKB updates */ + KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; if (knet_rx_cb != NULL) { KNET_SKB_CB(skb)->netif_user_data = priv->cb_user_data; KNET_SKB_CB(skb)->filter_user_data = filter->kf.cb_user_data; - KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; - skb = knet_rx_cb(skb, sinfo->dev_no, meta); + if (device_is_sand(sinfo)) { + skb = knet_rx_cb(skb, sinfo->dev_no, sand_scratch_data); + } + else { + skb = knet_rx_cb(skb, sinfo->dev_no, meta); + } if (skb == NULL) { /* Consumed by call-back */ sinfo->rx[chan].pkts_d_callback++; @@ -3715,12 +3744,12 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) } /* Do Rx timestamping */ - if (sinfo->rx_hwts) { - bkn_hw_tstamp_rx_set(sinfo, skb, meta); + if (priv->rx_hwts) { + bkn_hw_tstamp_rx_set(sinfo, priv->phys_port, skb, meta); } if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { - bkn_add_rcpu_encap(sinfo, skb, meta); + bkn_add_rcpu_encap(sinfo, skb, meta, packet_info.system_header_size); DBG_PDMP(("After add RCPU ENCAP\n")); bkn_dump_pkt(skb->data, pktlen + RCPU_RX_ENCAP_SIZE, XGS_DMA_RX_CHAN); } @@ -3792,7 +3821,9 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) int idx; int dcbs_done = 0; bkn_dune_system_header_info_t packet_info = {0}; - uint32_t dnx_meta_data[3] = {0}; + uint32_t sand_scratch_data[BKN_SAND_SCRATCH_DATA_SIZE] = {0}; + uint8_t sand_system_headers[RCPU_RX_META_SIZE] = {0}; + uint8_t *pkt = NULL; if (!sinfo->rx[chan].running) { /* Rx not ready */ @@ -3818,93 +3849,83 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) } sinfo->rx[chan].pkts++; skb = desc->skb; - if (sinfo->cmic_type == 'x') { - if (device_is_dnx(sinfo)){ - meta = &dnx_meta_data[0]; - /* get error bit from last DCB words */ - err_woff = 2; - meta[err_woff] = dcb[sinfo->dcb_wsize-1]; - } else { + + if (device_is_sand(sinfo)) { + err_woff = BKN_SAND_SCRATCH_DATA_SIZE - 1; + sand_scratch_data[err_woff] = dcb[sinfo->dcb_wsize-1]; + meta = (uint32_t *)skb->data; + pkt = skb->data; + } else { + if (sinfo->cmic_type == 'x') { meta = (uint32_t *)skb->data; err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } else { + meta = dcb; + err_woff = sinfo->dcb_wsize - 1; } - } else { - meta = dcb; - err_woff = sinfo->dcb_wsize - 1; } + pktlen = dcb[sinfo->dcb_wsize-1] & 0xffff; priv = netdev_priv(sinfo->dev); DBG_DCB_RX(("Rx%d SKB DMA done (%d).\n", chan, sinfo->rx[chan].dirty)); - DMA_UNMAP_SINGLE(sinfo->dma_dev, + BKN_DMA_UNMAP_SINGLE(sinfo->dma_dev, desc->skb_dma, desc->dma_size, - DMA_FROMDEV); + BKN_DMA_FROMDEV); desc->skb_dma = 0; bkn_dump_pkt(skb->data, pktlen, XGS_DMA_RX_CHAN); - if (device_is_dpp(sinfo)) { - uint16_t tpid = 0; - uint16_t vid = 0; - uint8_t *pkt = skb->data; - int res = 0; - + if (device_is_sand(sinfo)) { memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); - res = bkn_dpp_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - if (res == 0) { - if (packet_info.ftmh.action_type == 0x2) { - bkn_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); - } else if (packet_info.ftmh.action_type == 0x1) { - bkn_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); - } - bkn_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); - bkn_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); - bkn_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); - pkt = skb->data + packet_info.ntwrk_header_ptr; - /* check if vlan tag exists */ - tpid = (uint16_t)((pkt[12] << 8) | pkt[13]); - vid = (uint16_t)(packet_info.internal.vsi & 0xfff); + /* decode system headers and fill sratch data */ + bkn_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + bkn_bitstream_set_field(sand_scratch_data, 0, 16, packet_info.internal.trap_id); + bkn_bitstream_set_field(sand_scratch_data, 16, 16, packet_info.internal.trap_qualifier); + bkn_bitstream_set_field(sand_scratch_data, 32, 16, packet_info.ftmh.source_sys_port_aggregate); + bkn_bitstream_set_field(sand_scratch_data, 48, 16, packet_info.internal.forward_domain); + bkn_bitstream_set_field(sand_scratch_data, 64, 2, packet_info.ftmh.action_type); + memcpy(sand_system_headers, pkt, + ((packet_info.system_header_size > RCPU_RX_META_SIZE) ? RCPU_RX_META_SIZE : packet_info.system_header_size)); + meta = (uint32_t *)sand_system_headers; + if (force_tagged) { + uint8_t *eth_hdr = pkt + packet_info.system_header_size; + uint16_t tpid = 0; + + tpid = PKT_U16_GET(eth_hdr, 12); if (packet_is_untagged(tpid)) { + int raw_packet_len = pktlen - packet_info.system_header_size; + uint32_t vid = 0; + if ((pktlen + 4) < rx_buffer_size) { - DBG_DUNE(("add vlan tag to untagged packets\n")); - for (idx = (pktlen-packet_info.ntwrk_header_ptr-1); idx >= 12; idx--) { - pkt[idx+4] = pkt[idx]; - } - pkt[12] = 0x81; - pkt[13] = 0x00; - pkt[14] = (vid >> 8); - pkt[15] = (vid & 0xff); - pktlen += 4; - /* reset packet length in DCB */ - dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; - dcb[sinfo->dcb_wsize-1] |= (pktlen & SOC_DCB_KNET_COUNT_MASK); - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); + for (idx = (raw_packet_len - 1); idx >= 12; idx--) { + eth_hdr[idx+4] = eth_hdr[idx]; + } + if (ft_vid) { + vid = ft_vid; + } + else if (packet_info.internal.forward_domain) { + vid = packet_info.internal.forward_domain & 0xfff; + } + else { + vid = 1; + } + DBG_DUNE(("add vlan tag (%d) to untagged packets\n", vid)); + eth_hdr[12] = (ft_tpid >> 8) & 0xff; + eth_hdr[13] = ft_tpid & 0xff; + eth_hdr[14] = (((ft_pri & 0x7) << 5) | ((ft_cfi & 0x1) << 4) | ((vid >> 8) & 0xf)) & 0xff; + eth_hdr[15] = vid & 0xff; + /* reset packet length in DCB */ + pktlen += 4; + bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); + dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; + dcb[sinfo->dcb_wsize-1] |= pktlen & SOC_DCB_KNET_COUNT_MASK; } } } } - else if (device_is_dnx(sinfo)) { - uint8_t *pkt = skb->data; - int res = -1; - - res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - if (res == 0) { - bkn_bitstream_set_field(meta, 0, 16, packet_info.fhei_code); - bkn_bitstream_set_field(meta, 16, 16, packet_info.fhei_qualifier); - bkn_bitstream_set_field(meta, 32, 16, packet_info.ftmh_spa); - bkn_bitstream_set_field(meta, 48, 16, (packet_info.pph_forward_domain & 0xffff)); - - pkt += packet_info.system_header_size; - pktlen -= packet_info.ntwrk_header_ptr; - bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); - } - } - - if (device_is_dpp(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.ntwrk_header_ptr, - pktlen, dcb, chan, &cbf); - } else if (device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.system_header_size, - pktlen, meta, chan, &cbf); + pktlen - packet_info.system_header_size, sand_scratch_data, chan, &cbf); } else { filter = bkn_match_rx_pkt(sinfo, skb->data + sinfo->pkt_hdr_size, pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); @@ -3938,55 +3959,51 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) priv->id, priv->dev->name)); sinfo->rx[chan].pkts_f_netif++; - if (((filter->kf.mirror_type == KCOM_DEST_T_API) && - (!device_is_sand(sinfo))) || dbg_pkt_enable) { + if ((filter->kf.mirror_type == KCOM_DEST_T_API) || dbg_pkt_enable) { sinfo->rx[chan].pkts_m_api++; bkn_api_rx_copy_from_skb(sinfo, chan, desc); } - if (device_is_dpp(sinfo)) { - if (filter->kf.mirror_type == KCOM_DEST_T_API) { - sinfo->rx[chan].pkts_m_api++; - bkn_api_rx_copy_from_skb(sinfo, chan, desc); - } - /* Strip Dune headers */ - skb->data += packet_info.ntwrk_header_ptr; - pktlen -= packet_info.ntwrk_header_ptr; - bkn_dump_pkt(skb->data, 32, XGS_DMA_RX_CHAN); - /* CRC has been stripped on Dune*/ - skb_put(skb, pktlen); - } else if (device_is_dnx(sinfo)) { - if (filter->kf.mirror_type == KCOM_DEST_T_API) { - sinfo->rx[chan].pkts_m_api++; - bkn_api_rx_copy_from_skb(sinfo, chan, desc); - } - /* Strip Dune headers */ - skb->data += packet_info.system_header_size; - pktlen -= packet_info.system_header_size; - bkn_dump_pkt(skb->data, 32, XGS_DMA_RX_CHAN); + if (device_is_sand(sinfo)) { /* CRC has been stripped on Dune*/ skb_put(skb, pktlen); } else { skb_put(skb, pktlen - 4); /* Strip CRC */ } - if (sinfo->cmic_type == 'x' && !device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { + skb_pull(skb, packet_info.system_header_size); + } else if (sinfo->cmic_type == 'x') { skb_pull(skb, sinfo->pkt_hdr_size); } + /* Optional SKB updates */ + KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; + /* Do Rx timestamping */ + if (priv->rx_hwts) { + bkn_hw_tstamp_rx_set(sinfo, priv->phys_port, skb, meta); + } + /* Save for RCPU before stripping tag */ - ethertype = (skb->data[16] << 8) | skb->data[17]; + ethertype = PKT_U16_GET(skb->data, 16); if ((priv->flags & KCOM_NETIF_F_KEEP_RX_TAG) == 0) { + uint16_t vlan_proto; + + vlan_proto = PKT_U16_GET(skb->data, 12); if (filter->kf.flags & KCOM_FILTER_F_STRIP_TAG) { /* Strip VLAN tag */ - uint16_t vlan_proto = (uint16_t)((skb->data[12] << 8) | skb->data[13]); - if (vlan_proto == 0x8100 || vlan_proto == 0x88a8) { + if (vlan_proto == ETH_P_8021Q || + vlan_proto == ETH_P_8021AD) { DBG_FLTR(("Strip VLAN tag\n")); ((u32*)skb->data)[3] = ((u32*)skb->data)[2]; ((u32*)skb->data)[2] = ((u32*)skb->data)[1]; ((u32*)skb->data)[1] = ((u32*)skb->data)[0]; skb_pull(skb, 4); - if (sinfo->cmic_type == 'x' && !device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { + for (idx = packet_info.system_header_size; idx >= 4; idx--) { + pkt[idx] = pkt[idx - 4]; + } + } else if (sinfo->cmic_type == 'x') { for (idx = sinfo->pkt_hdr_size / sizeof(uint32_t); idx; idx--) { meta[idx] = meta[idx - 1]; } @@ -3998,25 +4015,35 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) * Mark packet as VLAN-tagged, otherwise newer * kernels will strip the tag. */ - uint16_t tci = (skb->data[14] << 8) | skb->data[15]; + uint16_t tci = PKT_U16_GET(skb->data, 14); + if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { bkn_vlan_hwaccel_put_tag(skb, ETH_P_8021Q, tci); } else { - bkn_vlan_hwaccel_put_tag(skb, - ((skb->data[12] << 8) | skb->data[13]), tci); + if (vlan_proto == ETH_P_8021AD) { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021AD, tci); + } else { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021Q, tci); + } } } } + priv->stats.rx_packets++; priv->stats.rx_bytes += skb->len; skb->dev = priv->dev; - /* Optional SKB updates */ if (knet_rx_cb != NULL) { KNET_SKB_CB(skb)->netif_user_data = priv->cb_user_data; KNET_SKB_CB(skb)->filter_user_data = filter->kf.cb_user_data; - KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; - skb = knet_rx_cb(skb, sinfo->dev_no, meta); + if (device_is_sand(sinfo)) { + skb = knet_rx_cb(skb, sinfo->dev_no, sand_scratch_data); + } + else { + skb = knet_rx_cb(skb, sinfo->dev_no, meta); + } if (skb == NULL) { /* Consumed by call-back */ sinfo->rx[chan].pkts_d_callback++; @@ -4026,13 +4053,8 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) } } - /* Do Rx timestamping */ - if (sinfo->rx_hwts) { - bkn_hw_tstamp_rx_set(sinfo, skb, meta); - } - if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { - bkn_add_rcpu_encap(sinfo, skb, meta); + bkn_add_rcpu_encap(sinfo, skb, meta, packet_info.system_header_size); DBG_PDMP(("After add RCPU ENCAP\n")); bkn_dump_pkt(skb->data, pktlen + RCPU_RX_ENCAP_SIZE, XGS_DMA_RX_CHAN); } @@ -4228,25 +4250,45 @@ bkn_resume_tx(bkn_switch_info_t *sinfo) } } +static void +bkn_skb_tstamp_copy(struct sk_buff *new_skb, struct sk_buff *skb) +{ + bkn_skb_tx_flags(new_skb) = bkn_skb_tx_flags(skb); + new_skb->sk = skb->sk; + + return; +} + static int bkn_hw_tstamp_tx_set(bkn_switch_info_t *sinfo, struct sk_buff *skb) { - struct skb_shared_hwtstamps shhwtstamps; + int hwts; + int port; uint64_t ts = 0; uint32_t hdrlen = sinfo->cmic_type == 'x' ? PKT_TX_HDR_SIZE : 0; - int port; + struct skb_shared_hwtstamps shhwtstamps; if (!knet_hw_tstamp_tx_time_get_cb) { return -1; } port = KNET_SKB_CB(skb)->port; - if (knet_hw_tstamp_tx_time_get_cb(sinfo->dev_no, port, skb->data + hdrlen, &ts) < 0) { - return -1; + hwts = KNET_SKB_CB(skb)->hwts; + ts = KNET_SKB_CB(skb)->ts; + + + if (hwts == HWTSTAMP_TX_ONESTEP_SYNC) { + if (ts == 0) { + return 1; + } + } else if (hwts == HWTSTAMP_TX_ON) { + if (knet_hw_tstamp_tx_time_get_cb(sinfo->dev_no, port, skb->data + hdrlen, &ts) < 0) { + return -1; + } } memset(&shhwtstamps, 0, sizeof(shhwtstamps)); - shhwtstamps.hwtstamp = ns_to_ktime(be64_to_cpu(ts)); + shhwtstamps.hwtstamp = ns_to_ktime(ts); skb_tstamp_tx(skb, &shhwtstamps); return 0; @@ -4290,9 +4332,19 @@ bkn_do_tx(bkn_switch_info_t *sinfo) } if (desc->skb) { DBG_DCB_TX(("Tx SKB DMA done (%d).\n", sinfo->tx.dirty)); - DMA_UNMAP_SINGLE(sinfo->dma_dev, + BKN_DMA_UNMAP_SINGLE(sinfo->dma_dev, desc->skb_dma, desc->dma_size, - DMA_TODEV); + BKN_DMA_TODEV); + + if ((KNET_SKB_CB(desc->skb)->hwts == HWTSTAMP_TX_ONESTEP_SYNC) && + (bkn_skb_tx_flags(desc->skb) & SKBTX_IN_PROGRESS)) { + + if (bkn_hw_tstamp_tx_set(sinfo, desc->skb) < 0) { + gprintk("Timestamp has not been taken for the current skb.\n"); + } + bkn_skb_tx_flags(desc->skb) &= ~SKBTX_IN_PROGRESS; + } + if (bkn_skb_tx_flags(desc->skb) & SKBTX_IN_PROGRESS) { skb_queue_tail(&sinfo->tx_ptp_queue, desc->skb); schedule_work(&sinfo->tx_ptp_work); @@ -4858,6 +4910,22 @@ xgsx_isr(bkn_switch_info_t *sinfo) /* Not ours */ return; } + + /* Bypass chain_done from Abort */ + if (device_is_dnx(sinfo)) { + uint32_t ctrl = 0; + int chan = 0; + for (chan = 0; chan < NUM_DMA_CHAN; chan++) { + if (irq_stat & CMICX_DS_CMC_CHAIN_DONE(chan)) { + DEV_READ32(sinfo, CMICX_DMA_CTRLr + 0x80 * chan, &ctrl); + if (ctrl & CMICX_DC_CMC_ABORT) { + DBG_IRQ(("chain %d: chain done for Abort\n", chan)); + return; + } + } + } + } + sinfo->interrupts++; DBG_IRQ(("Got interrupt on device %d (0x%08x)\n", @@ -5010,7 +5078,11 @@ bkn_open(struct net_device *dev) static int bkn_set_mac_address(struct net_device *dev, void *addr) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,18,12)) + if (!is_valid_ether_addr((const u8*)(((struct sockaddr *)addr)->sa_data))) { +#else if (!is_valid_ether_addr(((struct sockaddr *)addr)->sa_data)) { +#endif return -EINVAL; } memcpy(dev->dev_addr, ((struct sockaddr *)addr)->sa_data, dev->addr_len); @@ -5033,17 +5105,21 @@ bkn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (!knet_hw_tstamp_enable_cb || !knet_hw_tstamp_disable_cb || priv->type != KCOM_NETIF_T_PORT) { - return -ERANGE; + return -ENOSYS; } switch (config.tx_type) { case HWTSTAMP_TX_OFF: - knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->port); - sinfo->tx_hwts = 0; + knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->tx_hwts = (config.tx_type); break; case HWTSTAMP_TX_ON: - knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->port); - sinfo->tx_hwts = 1; + knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->tx_hwts = (config.tx_type); + break; + case HWTSTAMP_TX_ONESTEP_SYNC: + knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->tx_hwts = (config.tx_type); break; default: return -ERANGE; @@ -5051,15 +5127,15 @@ bkn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) switch (config.rx_filter) { case HWTSTAMP_FILTER_NONE: - if (sinfo->rx_hwts) { - knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->port); - sinfo->rx_hwts = 0; + if (priv->rx_hwts) { + knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->rx_hwts = 0; } break; default: - if (!sinfo->rx_hwts) { - knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->port); - sinfo->rx_hwts = 1; + if (!priv->rx_hwts) { + knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->phys_port, config.tx_type); + priv->rx_hwts = 1; } config.rx_filter = HWTSTAMP_FILTER_ALL; break; @@ -5071,8 +5147,8 @@ bkn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) if (cmd == SIOCGHWTSTAMP) { config.flags = 0; - config.tx_type = sinfo->tx_hwts ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; - config.rx_filter = sinfo->rx_hwts ? HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE; + config.tx_type = priv->tx_hwts; + config.rx_filter = priv->rx_hwts ? HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE; return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; } @@ -5208,7 +5284,9 @@ bkn_set_multicast_list(struct net_device *dev) } static int -bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32_t *meta) +bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, + int hwts, int hdrlen, + struct sk_buff *skb, u32 *meta) { uint32_t *md = NULL; @@ -5217,7 +5295,13 @@ bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32_t } KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; - knet_hw_tstamp_tx_meta_get_cb(sinfo->dev_no, skb, &md); + knet_hw_tstamp_tx_meta_get_cb(sinfo->dev_no, hwts, hdrlen, skb, + &(KNET_SKB_CB(skb)->ts), (meta ? &md : NULL)); + + if (!meta) { + return 0; + } + if (!md) { return -1; } @@ -5233,10 +5317,10 @@ bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32_t break; case 36: case 38: - meta[0] |= md[0]; - meta[1] |= md[1]; - meta[2] |= md[2]; - meta[3] |= md[3]; + meta[0] |= htonl(md[0]); + meta[1] |= htonl(md[1]); + meta[2] |= htonl(md[2]); + meta[3] |= htonl(md[3]); break; default: return -1; @@ -5257,8 +5341,9 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) uint16_t tpid; uint32_t *metadata; unsigned long flags; + uint32_t cpu_channel = 0; - DBG_VERB(("Netif Tx: Len=%d\n", skb->len)); + DBG_VERB(("Netif Tx: Len=%d priv->id=%d\n", skb->len, priv->id)); if (priv->id <= 0) { /* Do not transmit on base device */ @@ -5267,8 +5352,14 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) return 0; } + if (device_is_dnx(sinfo) && (skb->len == 0)) { + priv->stats.tx_dropped++; + dev_kfree_skb_any(skb); + return 0; + } + if (!netif_carrier_ok(dev)) { - DBG_WARN(("Tx drop: Invalid RCPU encapsulation\n")); + DBG_WARN(("Tx drop: Netif link is down.\n")); priv->stats.tx_dropped++; sinfo->tx.pkts_d_no_link++; dev_kfree_skb_any(skb); @@ -5283,7 +5374,13 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) pktdata = skb->data; pktlen = skb->len; - hdrlen = (sinfo->cmic_type == 'x' ) ? ((device_is_dnx(sinfo)) ? priv->system_headers_size: PKT_TX_HDR_SIZE) : 0; + + if (device_is_sand(sinfo)) { + hdrlen = priv->system_headers_size; + } + else { + hdrlen = (sinfo->cmic_type == 'x' ) ? PKT_TX_HDR_SIZE : 0; + } rcpulen = 0; sop = 0; @@ -5298,7 +5395,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) return 0; } if (check_rcpu_signature && - ((skb->data[18] << 8) | skb->data[19]) != sinfo->rcpu_sig) { + PKT_U16_GET(skb->data, 18) != sinfo->rcpu_sig) { DBG_WARN(("Tx drop: Invalid RCPU signature\n")); priv->stats.tx_dropped++; sinfo->tx.pkts_d_rcpu_sig++; @@ -5306,7 +5403,15 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&sinfo->lock, flags); return 0; } - if (skb->data[21] & RCPU_F_MODHDR) { + + if (device_is_sand(sinfo)) { + /* Dune devices don't use meta data */ + sop = 0; + /* Get CPU channel from rcpu_hdr_t.reserved */ + cpu_channel = (skb->data[28] << 24) | (skb->data[29] << 16) | (skb->data[30] << 8) | (skb->data[31]); + /* System headers are supposed to be set by users in RCPU mode. */ + hdrlen = 0; + } else if (skb->data[21] & RCPU_F_MODHDR) { sop = skb->data[RCPU_HDR_SIZE]; switch (sop) { case 0xff: @@ -5332,46 +5437,55 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) /* CPU packets require tag */ if (sop == 0) { - hdrlen = 0; - tpid = (pktdata[12] << 8) | pktdata[13]; - if (tpid != 0x8100) { - if (skb_header_cloned(skb)) { - /* Current SKB cannot be modified */ - DBG_SKB(("Realloc Tx SKB\n")); - new_skb = dev_alloc_skb(pktlen + TAG_SZ + FCS_SZ); - if (new_skb == NULL) { - DBG_WARN(("Tx drop: No SKB memory\n")); - priv->stats.tx_dropped++; - sinfo->tx.pkts_d_no_skb++; + if (device_is_sand(sinfo)) { + /* + * There should be Module Header + PTCH_2 + [ITMH] on JR2, + * PTCH_2 +[ITMH] on JR1 + */ + } else { + hdrlen = 0; + tpid = PKT_U16_GET(pktdata, 12); + if (tpid != 0x8100) { + if (skb_header_cloned(skb)) { + /* Current SKB cannot be modified */ + DBG_SKB(("Realloc Tx SKB\n")); + new_skb = dev_alloc_skb(pktlen + TAG_SZ + FCS_SZ); + if (new_skb == NULL) { + DBG_WARN(("Tx drop: No SKB memory\n")); + priv->stats.tx_dropped++; + sinfo->tx.pkts_d_no_skb++; + dev_kfree_skb_any(skb); + spin_unlock_irqrestore(&sinfo->lock, flags); + return 0; + } + memcpy(new_skb->data, pktdata, 12); + memcpy(&new_skb->data[16], &pktdata[12], pktlen - 12); + skb_put(new_skb, pktlen + TAG_SZ); + bkn_skb_tstamp_copy(new_skb, skb); dev_kfree_skb_any(skb); - spin_unlock_irqrestore(&sinfo->lock, flags); - return 0; - } - memcpy(new_skb->data, pktdata, 12); - memcpy(&new_skb->data[16], &pktdata[12], pktlen - 12); - skb_put(new_skb, pktlen + TAG_SZ); - dev_kfree_skb_any(skb); - skb = new_skb; - pktdata = skb->data; - rcpulen = 0; - } else { - /* Add tag to RCPU header space */ - DBG_SKB(("Expand into unused RCPU header\n")); - rcpulen -= TAG_SZ; - pktdata = &skb->data[rcpulen]; - for (idx = 0; idx < 12; idx++) { - pktdata[idx] = pktdata[idx + TAG_SZ]; + skb = new_skb; + pktdata = skb->data; + rcpulen = 0; + } else { + /* Add tag to RCPU header space */ + DBG_SKB(("Expand into unused RCPU header\n")); + rcpulen -= TAG_SZ; + pktdata = &skb->data[rcpulen]; + for (idx = 0; idx < 12; idx++) { + pktdata[idx] = pktdata[idx + TAG_SZ]; + } } + pktdata[12] = 0x81; + pktdata[13] = 0x00; + pktdata[14] = (priv->vlan >> 8) & 0xf; + pktdata[15] = priv->vlan & 0xff; + pktlen += TAG_SZ; } - pktdata[12] = 0x81; - pktdata[13] = 0x00; - pktdata[14] = (priv->vlan >> 8) & 0xf; - pktdata[15] = priv->vlan & 0xff; - pktlen += TAG_SZ; } } } else { - if (sinfo->cmic_type == 'x' && priv->port >= 0) { + if (((sinfo->cmic_type == 'x') && (priv->port >= 0)) + || device_is_sand(sinfo)) { if (skb_header_cloned(skb) || skb_headroom(skb) < hdrlen + 4) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB\n")); @@ -5384,12 +5498,13 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&sinfo->lock, flags); return 0; } - if (!device_is_dnx(sinfo)) + if (!device_is_sand(sinfo)) { skb_reserve(new_skb, 4); } memcpy(new_skb->data + hdrlen, skb->data, pktlen); skb_put(new_skb, pktlen + hdrlen); + bkn_skb_tstamp_copy(new_skb, skb); dev_kfree_skb_any(skb); skb = new_skb; } else { @@ -5406,7 +5521,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if (priv->port < 0 || (priv->flags & KCOM_NETIF_F_ADD_TAG)) { DBG_DUNE(("ADD VLAN TAG\n")); /* Need to add VLAN tag if packet is untagged */ - tpid = (skb->data[hdrlen + 12] << 8) | skb->data[hdrlen + 13]; + tpid = PKT_U16_GET(skb->data, hdrlen + 12); if (tpid != 0x8100) { if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { /* Current SKB cannot be modified */ @@ -5424,6 +5539,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) memcpy(&new_skb->data[hdrlen + 16], &skb->data[hdrlen + 12], pktlen - hdrlen - 12); skb_put(new_skb, pktlen + TAG_SZ); + bkn_skb_tstamp_copy(new_skb, skb); dev_kfree_skb_any(skb); skb = new_skb; } else { @@ -5446,7 +5562,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) /* Pad packet if needed */ taglen = 0; - tpid = (pktdata[hdrlen + 12] << 8) | pktdata[hdrlen + 13]; + tpid = PKT_U16_GET(pktdata, hdrlen + 12); if (tpid == 0x8100) { taglen = 4; } @@ -5478,8 +5594,19 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) meta = (sinfo->cmic_type == 'x') ? (uint32_t *)pktdata : dcb; memset(dcb, 0, sinfo->dcb_wsize * sizeof(uint32_t)); if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { - /* If module header SOP is non-zero, use RCPU meta data */ - if (sop != 0) { + if (device_is_sand(sinfo)) { + if (sinfo->cmic_type == 'x') { + dcb[2] |= 1 << 19; + /* Given Module Header exists and set first byte to be CPU channel */ + pktdata[0] = cpu_channel; + } else { + dcb[1] |= 1 << 19; + /* Set CPU channel */ + dcb[2] = (cpu_channel & 0xff) << 24; + } + + } else if (sop != 0) { + /* If module header SOP is non-zero, use RCPU meta data */ if (sinfo->cmic_type == 'x') { dcb[2] |= 1 << 19; } else { @@ -5521,67 +5648,15 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) dcb[4] |= (priv->qnum & 0xfff) << 14; break; case 28: - { - if (priv->type == KCOM_NETIF_T_PORT) { - /* add PTCH ITMH header */ - if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { - /* Current SKB cannot be modified */ - DBG_SKB(("Realloc Tx SKB for DNX ITMH header\n")); - new_skb = dev_alloc_skb(pktlen + 4 + 2 + FCS_SZ); - if (new_skb == NULL) { - DBG_WARN(("Tx drop: No SKB memory for DNX ITMH header\n")); - priv->stats.tx_dropped++; - sinfo->tx.pkts_d_no_skb++; - dev_kfree_skb_any(skb); - spin_unlock_irqrestore(&sinfo->lock, flags); - return 0; - } - memcpy(&new_skb->data[6], skb->data, pktlen); - skb_put(new_skb, pktlen + 6); - dev_kfree_skb_any(skb); - skb = new_skb; - } else { - /* Add tag to existing buffer */ - DBG_SKB(("Expand Tx SKB for DNX ITMH header\n")); - skb_push(skb, 6); - } - pktdata = skb->data; - pktdata[0] = 0x50; - pktdata[1] = 0x00; - memcpy(&pktdata[2], priv->itmh, 4); - pktlen += 6; - } - else if (priv->type == KCOM_NETIF_T_VLAN) { - /* add PTCH header */ - if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { - /* Current SKB cannot be modified */ - DBG_SKB(("Realloc Tx SKB for DNX header\n")); - new_skb = dev_alloc_skb(pktlen + 2 + FCS_SZ); - if (new_skb == NULL) { - DBG_WARN(("Tx drop: No SKB memory for DNX header\n")); - priv->stats.tx_dropped++; - sinfo->tx.pkts_d_no_skb++; - dev_kfree_skb_any(skb); - spin_unlock_irqrestore(&sinfo->lock, flags); - return 0; - } - memcpy(&new_skb->data[2], skb->data, pktlen); - skb_put(new_skb, pktlen + 2); - dev_kfree_skb_any(skb); - skb = new_skb; - } else { - /* Add tag to existing buffer */ - DBG_SKB(("Expand Tx SKB for DNX header\n")); - skb_push(skb, 2); - } - pktdata = skb->data; - pktdata[0] = 0xd0; - pktdata[1] = priv->port; - pktlen += 2; - } - dcb[1] = pktlen; - break; - } + /* + * If KCOM_NETIF_T_PORT, add PTCH+ITMH header + * If KCOM_NETIF_T_VLAN, add PTCH+header + */ + pktdata = skb->data; + memcpy(&pktdata[0], priv->system_headers, priv->system_headers_size); + /* Set CPU channel */ + dcb[2] = ((priv->qnum & 0xff) << 24); + break; case 29: dcb[2] = 0x81000000; dcb[3] = priv->port; @@ -5640,6 +5715,19 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) memcpy(&pktdata[0], priv->system_headers, priv->system_headers_size); } break; + case 40: + if (sinfo->cmic_type == 'x') { + meta[0] = htonl(0x81000000); + meta[1] = htonl(priv->port | (priv->qnum & 0xc00) << 20); + meta[2] = htonl(0x00040000 | (priv->qnum & 0x3ff) << 8); + } else { + dcb[2] = 0x81000000; + dcb[3] = priv->port; + dcb[3] |= (priv->qnum & 0xc00) << 20; + dcb[4] = 0x00040000; + dcb[4] |= (priv->qnum & 0x3ff) << 8; + } + break; default: dcb[2] = 0xff000000; dcb[3] = 0x00000100; @@ -5695,24 +5783,46 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } /* Do Tx timestamping */ - if (priv->port >= 0) { - if (bkn_skb_tx_flags(skb) & SKBTX_HW_TSTAMP && sinfo->tx_hwts) { - KNET_SKB_CB(skb)->port = priv->port; - bkn_hw_tstamp_tx_config(sinfo, skb, meta); + if (bkn_skb_tx_flags(skb) & SKBTX_HW_TSTAMP) { + KNET_SKB_CB(skb)->hwts = priv->tx_hwts; + if ((priv->port >= 0) && (priv->tx_hwts & HWTSTAMP_TX_ON)) { + /* TwoStep Processing of ptp-packets */ + KNET_SKB_CB(skb)->port = priv->phys_port; + bkn_hw_tstamp_tx_config(sinfo, priv->tx_hwts, PKT_TX_HDR_SIZE, skb, meta); + bkn_skb_tx_flags(skb) |= SKBTX_IN_PROGRESS; + bkn_skb_tx_timestamp(skb); + + } else if (priv->tx_hwts & HWTSTAMP_TX_ONESTEP_SYNC) { + + /* OneStep Processing of ptp-packets */ + KNET_SKB_CB(skb)->port = priv->phys_port; + KNET_SKB_CB(skb)->ts = 0; + bkn_hw_tstamp_tx_config(sinfo, priv->tx_hwts, PKT_TX_HDR_SIZE, skb, + ((priv->port >= 0) ? meta : NULL)); + + if (KNET_SKB_CB(skb)->ts != 0) { + bkn_skb_tx_flags(skb) |= SKBTX_IN_PROGRESS; + bkn_skb_tx_timestamp(skb); + } + } - bkn_skb_tx_timestamp(skb); } /* Prepare for DMA */ desc->skb = skb; - /* Add FCS bytes */ - pktlen = pktlen + FCS_SZ; + /* + * Add FCS bytes + * FCS bytes are always appended to packet by MAC on Dune devices + */ + if (!device_is_sand(sinfo)) { + pktlen = pktlen + FCS_SZ; + } desc->dma_size = pktlen; - desc->skb_dma = DMA_MAP_SINGLE(sinfo->dma_dev, + desc->skb_dma = BKN_DMA_MAP_SINGLE(sinfo->dma_dev, pktdata, desc->dma_size, - DMA_TODEV); - if (DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { + BKN_DMA_TODEV); + if (BKN_DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { priv->stats.tx_dropped++; dev_kfree_skb_any(skb); spin_unlock_irqrestore(&sinfo->lock, flags); @@ -5758,6 +5868,10 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) priv->stats.tx_bytes += pktlen; sinfo->tx.pkts++; } else { +#ifdef SAI_FIXUP /* SDK-224448 */ + DBG_VERB(("Tx busy: No DMA resources\n")); + sinfo->tx.pkts_d_dma_resrc++; +#else DBG_WARN(("Tx drop: No DMA resources\n")); priv->stats.tx_dropped++; sinfo->tx.pkts_d_dma_resrc++; @@ -5766,7 +5880,12 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) /* Check our Tx resources */ if (sinfo->tx.free <= 1) { +#endif /* SDK-224448 */ bkn_suspend_tx(sinfo); +#ifdef SAI_FIXUP /* SDK-224448 */ + spin_unlock_irqrestore(&sinfo->lock, flags); + return BKN_NETDEV_TX_BUSY; +#endif /* SDK-224448 */ } NETDEV_UPDATE_TRANS_START_TIME(dev); @@ -6079,6 +6198,7 @@ bkn_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) case 33: case 36: case 38: + case 40: info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_RX_HARDWARE | @@ -6105,11 +6225,43 @@ bkn_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) } #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) +static int bkn_get_link_ksettings(struct net_device *netdev, + struct ethtool_link_ksettings *cmd) +{ + bkn_priv_t *priv = netdev_priv(netdev); + + /* only speed info now, can enhance later */ + if (priv) { + cmd->base.speed = priv->link_settings.speed; + cmd->base.duplex = priv->link_settings.duplex; + } + return 0; +} + +static int bkn_set_link_ksettings(struct net_device *netdev, + const struct ethtool_link_ksettings *cmd) +{ + bkn_priv_t *priv = netdev_priv(netdev); + + /* only speed info now, can enhance later */ + if (priv) { + priv->link_settings.speed = cmd->base.speed; + priv->link_settings.duplex = cmd->base.speed? DUPLEX_FULL : 0; + } + return 0; +} +#endif + static const struct ethtool_ops bkn_ethtool_ops = { .get_drvinfo = bkn_get_drvinfo, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) .get_ts_info = bkn_get_ts_info, #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) + .get_link_ksettings = bkn_get_link_ksettings, + .set_link_ksettings = bkn_set_link_ksettings, +#endif }; static struct net_device * @@ -6165,8 +6317,8 @@ bkn_init_ndev(u8 *mac, char *name) strncpy(dev->name, name, IFNAMSIZ-1); } -#ifdef CONFIG_NET_NS - dev_net_set(dev, current->nsproxy->net_ns); +#if defined(CONFIG_NET_NS) + bkn_dev_net_set(dev, current->nsproxy->net_ns); #endif /* Register the kernel Ethernet device */ @@ -6739,9 +6891,11 @@ bkn_proc_debug_show(struct seq_file *m, void *v) seq_printf(m, " use_napi: %d\n", use_napi); seq_printf(m, " napi_weight: %d\n", napi_weight); seq_printf(m, " basedev_susp: %d\n", basedev_suspend); - seq_printf(m, "Thread states:\n"); - seq_printf(m, " Command thread: %d\n", bkn_cmd_ctrl.state); - seq_printf(m, " Event thread: %d\n", bkn_evt_ctrl.state); + seq_printf(m, " force_tagged: %d\n", force_tagged); + seq_printf(m, " ft_tpid: %d\n", ft_tpid); + seq_printf(m, " ft_pri: %d\n", ft_pri); + seq_printf(m, " ft_pri: %d\n", ft_cfi); + seq_printf(m, " ft_tpid: %d\n", ft_vid); seq_printf(m, "Active IOCTLs:\n"); seq_printf(m, " Command: %d\n", ioctl_cmd); seq_printf(m, " Event: %d\n", ioctl_evt); @@ -7510,6 +7664,27 @@ bkn_knet_hw_init(kcom_msg_hw_init_t *kmsg, int len) } } + if (device_is_sand(sinfo)) { + int idx = 0; + /* Information to parser Dune system headers */ + sinfo->ftmh_lb_key_ext_size = kmsg->ftmh_lb_key_ext_size; + sinfo->ftmh_stacking_ext_size = kmsg->ftmh_stacking_ext_size; + sinfo->pph_base_size = kmsg->pph_base_size; + for (idx = 0; idx < 8; idx++) + { + sinfo->pph_lif_ext_size[idx] = kmsg->pph_lif_ext_size[idx]; + } + for (idx = 0; idx < 4; idx++) + { + sinfo->udh_length_type[idx] = kmsg->udh_length_type[idx]; + } + sinfo->udh_size = kmsg->udh_size; + sinfo->oamp_punt = kmsg->oamp_punted; + sinfo->no_skip_udh_check = kmsg->no_skip_udh_check; + sinfo->system_headers_mode = kmsg->system_headers_mode; + sinfo->udh_enable = kmsg->udh_enable; + } + /* Ensure that we restart properly */ bkn_dma_abort(sinfo); bkn_clean_dcbs(sinfo); @@ -7552,13 +7727,13 @@ bkn_knet_detach(kcom_msg_detach_t *kmsg, int len) } spin_lock_irqsave(&sinfo->lock, flags); - - /* Create dummy event to unblock pending IOCTL */ - sinfo->dma_events |= KCOM_DMA_INFO_F_TX_DONE; - evt = &_bkn_evt[sinfo->evt_idx]; - evt->evt_wq_put++; - wake_up_interruptible(&evt->evt_wq); - + if (sinfo->evt_idx != -1) { + /* Create dummy event to unblock pending IOCTL */ + sinfo->dma_events |= KCOM_DMA_INFO_F_TX_DONE; + evt = &_bkn_evt[sinfo->evt_idx]; + evt->evt_wq_put++; + wake_up_interruptible(&evt->evt_wq); + } spin_unlock_irqrestore(&sinfo->lock, flags); /* Ensure that we return a valid unit number */ @@ -7591,7 +7766,7 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) bkn_priv_t *priv, *lpriv; unsigned long flags; int found, id; - uint8 *ma; + uint8_t *ma; kmsg->hdr.type = KCOM_MSG_TYPE_RSP; @@ -7623,26 +7798,26 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) priv->sinfo = sinfo; priv->type = kmsg->netif.type; priv->vlan = kmsg->netif.vlan; + /* System headers are prepared at BCM API for Dune headers */ + if (device_is_sand(sinfo)) { + int idx = 0; + for (idx = 0; idx < KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX; idx++) + { + priv->system_headers[idx] = kmsg->netif.system_headers[idx]; + } + priv->system_headers_size = kmsg->netif.system_headers_size; + } if (priv->type == KCOM_NETIF_T_PORT) { priv->port = kmsg->netif.port; - if (device_is_dpp(sinfo)) { - memcpy(priv->itmh, kmsg->netif.itmh, 4); - } else if (device_is_dnx(sinfo)) { - memcpy(priv->system_headers, kmsg->netif.system_headers, kmsg->netif.system_headers_size); - priv->system_headers_size = kmsg->netif.system_headers_size; - } + priv->phys_port = kmsg->netif.phys_port; priv->qnum = kmsg->netif.qnum; + memset(&(priv->link_settings), 0, sizeof(struct ethtool_link_settings));; } else { - if (device_is_sand(sinfo)) { - if (device_is_dpp(sinfo)) { - priv->port = kmsg->netif.port; - priv->qnum = kmsg->netif.qnum; - }else if (device_is_dnx(sinfo)) { - memcpy(priv->system_headers, kmsg->netif.system_headers, kmsg->netif.system_headers_size); - priv->system_headers_size = kmsg->netif.system_headers_size; - } - } - else { + if (device_is_sand(sinfo) && (priv->type == KCOM_NETIF_T_VLAN)) { + /* PTCH.SSPA */ + priv->port = kmsg->netif.port; + priv->qnum = kmsg->netif.qnum; + } else { priv->port = -1; } } @@ -7711,7 +7886,7 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) kmsg->netif.id = priv->id; memcpy(kmsg->netif.macaddr, dev->dev_addr, 6); memcpy(kmsg->netif.name, dev->name, KCOM_NETIF_NAME_MAX - 1); - + if (knet_netif_create_cb != NULL) { int retv = knet_netif_create_cb(kmsg->hdr.unit, &(kmsg->netif), dev); if (retv) { @@ -7721,7 +7896,7 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) spin_unlock_irqrestore(&sinfo->lock, flags); - if (device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { int idx = 0; for (idx = 0; idx < priv->system_headers_size; idx++) { DBG_DUNE(("System Header[%d]: 0x%02x\n", idx, priv->system_headers[idx])); @@ -7857,6 +8032,7 @@ bkn_knet_netif_get(kcom_msg_netif_get_t *kmsg, int len) kmsg->netif.type = priv->type; kmsg->netif.id = priv->id; kmsg->netif.flags = priv->flags; + kmsg->netif.cb_user_data = priv->cb_user_data; if (priv->port < 0) { kmsg->netif.port = 0; @@ -7918,7 +8094,6 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) kmsg->hdr.status = KCOM_E_RESOURCE; return sizeof(kcom_msg_hdr_t); } - filter = kmalloc(sizeof(*filter), GFP_ATOMIC); if (filter == NULL) { spin_unlock_irqrestore(&sinfo->lock, flags); @@ -7927,17 +8102,6 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) } memset(filter, 0, sizeof(*filter)); memcpy(&filter->kf, &kmsg->filter, sizeof(filter->kf)); - - if (device_is_dnx(sinfo)) { - /* Information to parser Dune system headers */ - sinfo->ftmh_lb_key_ext_size = kmsg->filter.ftmh_lb_key_ext_size; - sinfo->ftmh_stacking_ext_size = kmsg->filter.ftmh_stacking_ext_size; - sinfo->pph_base_size = kmsg->filter.pph_base_size; - memcpy(sinfo->pph_lif_ext_size, kmsg->filter.pph_lif_ext_size, sizeof(sinfo->pph_lif_ext_size)); - sinfo->udh_enable = kmsg->filter.udh_enable; - memcpy(sinfo->udh_length_type, kmsg->filter.udh_length_type, sizeof(sinfo->udh_length_type)); - } - filter->kf.id = id; /* Add according to priority */ @@ -7960,8 +8124,7 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) DBG_VERB(("Created filter ID %d (%s).\n", filter->kf.id, filter->kf.desc)); - - if (device_is_dnx(sinfo)) { + if (device_is_sand(sinfo)) { int idx, wsize; wsize = BYTES2WORDS(filter->kf.oob_data_size + filter->kf.pkt_data_size); DBG_DUNE(("Filter: oob_data_size = %d pkt_data_size=%d wsize %d\n", filter->kf.oob_data_size, filter->kf.pkt_data_size, wsize)); @@ -7974,7 +8137,6 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) sinfo->pph_lif_ext_size[1],sinfo->pph_lif_ext_size[2], sinfo->pph_lif_ext_size[3], sinfo->udh_enable, sinfo->udh_length_type[0], sinfo->udh_length_type[1], sinfo->udh_length_type[2], sinfo->udh_length_type[3])); } - return len; } @@ -8055,7 +8217,6 @@ bkn_knet_filter_list(kcom_msg_filter_list_t *kmsg, int len) kmsg->fcnt = idx; spin_unlock_irqrestore(&sinfo->lock, flags); - return sizeof(*kmsg) - sizeof(kmsg->id) + (idx * sizeof(kmsg->id[0])); } @@ -8254,6 +8415,24 @@ bkn_handle_cmd_req(kcom_msg_t *kmsg, int len) /* Clean up for warmbooting */ len = bkn_knet_wb_cleanup(&kmsg->wb_cleanup, len); break; + case KCOM_M_CLOCK_CMD: + /* PHC clock control*/ + if (knet_hw_tstamp_ioctl_cmd_cb) { + bkn_switch_info_t *sinfo; + sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); + if (sinfo == NULL) { + /* The device is not probed or initialized yet.*/ + return 0; + } + DBG_CMD(("KCOM_M_CLOCK_CMD\n")); + len = knet_hw_tstamp_ioctl_cmd_cb(&kmsg->clock_cmd, len, sinfo->dcb_type); + } else { + DBG_WARN(("Unsupported command (type=%d, opcode=%d)\n", + kmsg->hdr.type, kmsg->hdr.opcode)); + kmsg->hdr.opcode = 0; + len = sizeof(kcom_msg_hdr_t); + } + break; default: DBG_WARN(("Unsupported command (type=%d, opcode=%d)\n", kmsg->hdr.type, kmsg->hdr.opcode)); @@ -8264,39 +8443,6 @@ bkn_handle_cmd_req(kcom_msg_t *kmsg, int len) return len; } -static int -bkn_cmd_thread(void *context) -{ - bkn_thread_ctrl_t *tc = (bkn_thread_ctrl_t *)context; - kcom_msg_t kmsg; - unsigned int len, rlen; - - bkn_thread_boot(tc); - - DBG_VERB(("Command thread starting\n")); - tc->state = 1; - while (!bkn_thread_should_stop(tc)) { - len = sizeof(kmsg); - tc->state = 2; - if (PROXY_RECV(KCOM_CHAN_KNET, &kmsg, &len) >= 0) { - DBG_VERB(("Received %d bytes from KCOM_CHAN_CMD\n", len)); - tc->state = 3; - rlen = bkn_handle_cmd_req(&kmsg, len); - tc->state = 4; - if (rlen > 0) { - PROXY_SEND(KCOM_CHAN_KNET, &kmsg, rlen); - } - } else { - /* Thread interrupted */ - bkn_sleep(1); - } - } - DBG_VERB(("Command thread done\n")); - - bkn_thread_exit(tc); - return 0; -} - static int bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) { @@ -8370,38 +8516,6 @@ bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) return sizeof(*kmsg); } -static int -bkn_evt_thread(void *context) -{ - bkn_thread_ctrl_t *tc = (bkn_thread_ctrl_t *)context; - kcom_msg_dma_info_t kmsg; - int len; - - bkn_thread_boot(tc); - - memset(&kmsg, 0, sizeof(kmsg)); - kmsg.hdr.type = KCOM_MSG_TYPE_EVT; - kmsg.hdr.opcode = KCOM_M_DMA_INFO; - - DBG_VERB(("Event thread starting\n")); - tc->state = 1; - while (!bkn_thread_should_stop(tc)) { - tc->state = 2; - len = bkn_get_next_dma_event(&kmsg); - tc->state = 3; - if (len) { - PROXY_SEND(KCOM_CHAN_KNET, &kmsg, len); - } else { - /* Thread interrupted */ - bkn_sleep(1); - } - } - DBG_VERB(("Event thread done\n")); - - bkn_thread_exit(tc); - return 0; -} - static int _cleanup(void) { @@ -8415,15 +8529,6 @@ _cleanup(void) /* Inidicate that we are shutting down */ module_initialized = 0; - /* Shut down event thread */ - bkn_thread_stop(&bkn_evt_ctrl); - - /* Shut down command thread */ - bkn_thread_stop(&bkn_cmd_ctrl); - - /* Remove KCOM channel */ - PROXY_SERVICE_DESTROY(KCOM_CHAN_KNET); - bkn_proc_cleanup(); remove_proc_entry("bcm/knet", NULL); remove_proc_entry("bcm", NULL); @@ -8586,7 +8691,6 @@ bkn_knet_dev_init(int d) priv->sinfo = sinfo; priv->vlan = 1; priv->port = -1; - memset(priv->itmh, 0, sizeof(priv->itmh)); priv->id = -1; } @@ -8659,16 +8763,6 @@ _init(void) evt = &_bkn_evt[0]; init_waitqueue_head(&evt->evt_wq); - if (use_proxy) { - PROXY_SERVICE_CREATE(KCOM_CHAN_KNET, 1, 0); - - DBG_VERB(("Starting command thread\n")); - bkn_thread_start(&bkn_cmd_ctrl, "bkncmd", bkn_cmd_thread); - - DBG_VERB(("Starting event thread\n")); - bkn_thread_start(&bkn_evt_ctrl, "bknevt", bkn_evt_thread); - } - module_initialized = 1; return 0; @@ -8704,7 +8798,7 @@ _ioctl(unsigned int cmd, unsigned long arg) io.len = bkn_handle_cmd_req(&kmsg, io.len); ioctl_cmd--; } else { - memset(&kmsg, 0, sizeof(kcom_msg_dma_info_t)); + memset(&kmsg, 0, sizeof(kcom_msg_t)); /* * Retrive the kmsg.hdr.unit from user space. The dma event queue * selection is based the instance derived from unit. @@ -9018,6 +9112,27 @@ bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f return 0; } +int +bkn_hw_tstamp_ioctl_cmd_cb_register(knet_hw_tstamp_ioctl_cmd_cb_f hw_tstamp_ioctl_cmd_cb) +{ + if (knet_hw_tstamp_ioctl_cmd_cb != NULL) { + return -1; + } + knet_hw_tstamp_ioctl_cmd_cb = hw_tstamp_ioctl_cmd_cb; + return 0; +} + +int +bkn_hw_tstamp_ioctl_cmd_cb_unregister(knet_hw_tstamp_ioctl_cmd_cb_f hw_tstamp_ioctl_cmd_cb) +{ + if (knet_hw_tstamp_ioctl_cmd_cb == NULL || + knet_hw_tstamp_ioctl_cmd_cb != hw_tstamp_ioctl_cmd_cb) { + return -1; + } + knet_hw_tstamp_ioctl_cmd_cb = NULL; + return 0; +} + LKM_EXPORT_SYM(bkn_rx_skb_cb_register); LKM_EXPORT_SYM(bkn_rx_skb_cb_unregister); LKM_EXPORT_SYM(bkn_tx_skb_cb_register); @@ -9041,3 +9156,5 @@ LKM_EXPORT_SYM(bkn_netif_create_cb_register); LKM_EXPORT_SYM(bkn_netif_create_cb_unregister); LKM_EXPORT_SYM(bkn_netif_destroy_cb_register); LKM_EXPORT_SYM(bkn_netif_destroy_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_ioctl_cmd_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_ioctl_cmd_cb_unregister); diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/Makefile new file mode 100644 index 000000000000..1c9a3209e133 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/Makefile @@ -0,0 +1,65 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 1.3 Broadcom SDK $ +# $Copyright: (c) 2020 Broadcom. +# Broadcom Proprietary and Confidential. All rights reserved.$ +# +LOCALDIR = systems/linux/kernel/modules/bcm-ptp-clock + +include ${SDK}/make/Make.config + +LIBS = $(LIBDIR)/libkern.a + +ifeq ($(kernel_version),2_4) +MODULE = $(LIBDIR)/linux-bcm-ptp-clock.o +else +KERNEL_MODULE_DIR = kernel_module + +THIS_MOD_NAME := linux-bcm-ptp-clock +MODULE = $(LIBDIR)/$(THIS_MOD_NAME).o +KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko + +build: $(MODULE) $(KMODULE) +endif + +#KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../../../../bde/linux/kernel/kernel_module/Module.symvers +KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers + +# BCM PTP Clock Device + +$(MODULE): $(BLDDIR)/.tree $(BOBJS) $(LIBS) + $(LD) $(MODULE_LDFLAGS) -r -d $(BOBJS) $(LIBS) -o $@ +ifneq ($(kernel_version),2_4) +$(KMODULE): $(MODULE) + rm -fr $(BLDDIR)/$(KERNEL_MODULE_DIR) + mkdir $(BLDDIR)/$(KERNEL_MODULE_DIR) + cp ${SDK}/make/Makefile.linux-kmodule $(BLDDIR)/$(KERNEL_MODULE_DIR)/Makefile + cat ${KBUILD_EXTRA_SYMBOLS} > $(BLDDIR)/$(KERNEL_MODULE_DIR)/Module.symvers + MOD_NAME=$(THIS_MOD_NAME) $(MAKE) -C $(BLDDIR)/$(KERNEL_MODULE_DIR) $(THIS_MOD_NAME).ko +endif + +# Make.depend is before clean:: so that Make.depend's clean:: runs first. + +include ${SDK}/make/Make.depend + +clean:: + $(RM) $(BLDDIR)/version.c $(BLDDIR)/version.o + $(RM) $(BOBJS) $(MODULE) + +ifneq ($(kernel_version),2_4) +.PHONY: build +endif diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/bcm-ptp-clock.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/bcm-ptp-clock.c new file mode 100644 index 000000000000..5b0a6bde738d --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-ptp-clock/bcm-ptp-clock.c @@ -0,0 +1,1981 @@ +/* + * Copyright 2017 Broadcom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation (the "GPL"). + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 (GPLv2) for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 (GPLv2) along with this source code. + */ + +/* + * This module implements a Linux PTP Clock driver for Broadcom + * XGS switch devices. + * + * For a list of supported module parameters, please see below. + * debug: Debug level (default 0) + * network_transport : Transport Type (default 0 - Raw) + * base_dev_name: Base device name (default ptp0, ptp1, etc.) + * + * - All the data structures and functions work on the physical port. + * For array indexing purposes, we use (phy_port - 1). + */ + +#include /* Must be included first */ +/* Module Information */ +#define MODULE_MAJOR 125 +#define MODULE_NAME "linux-bcm-ptp-clock" + +MODULE_AUTHOR("Broadcom Corporation"); +MODULE_DESCRIPTION("PTP Clock Driver for Broadcom XGS Switch"); +MODULE_LICENSE("GPL"); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,17,0) +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Configuration Parameters */ +static int debug; +LKM_MOD_PARAM(debug, "i", int, 0); +MODULE_PARM_DESC(debug, + "Debug level (default 0)"); + +static int pci_cos; + +static int network_transport; +LKM_MOD_PARAM(network_transport, "i", int, 0); +MODULE_PARM_DESC(network_transport, + "Transport Type (default - Detect from packet)"); + +static char *base_dev_name = "ptp0"; +LKM_MOD_PARAM(base_dev_name, "s", charp, 0); +MODULE_PARM_DESC(base_dev_name, + "Base device name (default ptp0, ptp1, etc.)"); + +static int fw_core; +LKM_MOD_PARAM(fw_core, "i", int, 0); +MODULE_PARM_DESC(fw_core, + "Firmware core (default 0)"); + +/* Debug levels */ +#define DBG_LVL_VERB 0x1 +#define DBG_LVL_WARN 0x2 + +#define DBG_VERB(_s) do { if (debug & DBG_LVL_VERB) gprintk _s; } while (0) +#define DBG_WARN(_s) do { if (debug & DBG_LVL_WARN) gprintk _s; } while (0) +#define DBG_ERR(_s) do { if (1) gprintk _s; } while (0) + + +#ifdef LINUX_BDE_DMA_DEVICE_SUPPORT +#define DMA_DEV device +#define DMA_ALLOC_COHERENT(d,s,h) dma_alloc_coherent(d,s,h,GFP_ATOMIC|GFP_DMA32) +#define DMA_FREE_COHERENT(d,s,a,h) dma_free_coherent(d,s,a,h) +#else +#define DMA_DEV pci_dev +#define DMA_ALLOC_COHERENT(d,s,h) pci_alloc_consistent(d,s,h) +#define DMA_FREE_COHERENT(d,s,a,h) pci_free_consistent(d,s,a,h) +#endif + +/* Type length in bytes */ +#define BKSYNC_PACKLEN_U8 1 +#define BKSYNC_PACKLEN_U16 2 +#define BKSYNC_PACKLEN_U24 3 +#define BKSYNC_PACKLEN_U32 4 + +#define BKSYNC_UNPACK_U8(_buf, _var) \ + _var = *_buf++ + +#define BKSYNC_UNPACK_U16(_buf, _var) \ + do { \ + (_var) = (((_buf)[0] << 8) | \ + (_buf)[1]); \ + (_buf) += BKSYNC_PACKLEN_U16; \ + } while (0) + +#define BKSYNC_UNPACK_U24(_buf, _var) \ + do { \ + (_var) = (((_buf)[0] << 16) | \ + ((_buf)[1] << 8) | \ + (_buf)[2]); \ + (_buf) += BKSYNC_PACKLEN_U24; \ + } while (0) + +#define BKSYNC_UNPACK_U32(_buf, _var) \ + do { \ + (_var) = (((_buf)[0] << 24) | \ + ((_buf)[1] << 16) | \ + ((_buf)[2] << 8) | \ + (_buf)[3]); \ + (_buf) += BKSYNC_PACKLEN_U32; \ + } while (0) + + +#define CMICX_DEV_TYPE ((ptp_priv->dcb_type == 38) || \ + (ptp_priv->dcb_type == 36)) + +#define HOSTCMD_USE_REGS ((ptp_priv->dcb_type == 38) || \ + (ptp_priv->dcb_type == 36) || \ + (ptp_priv->dcb_type == 32)) + +/* CMIC MCS-0 SCHAN Messaging registers */ +/* Core0:CMC1 Core1:CMC2 */ +#define CMIC_CMC_BASE \ + (CMICX_DEV_TYPE ? (fw_core ? 0x10400 : 0x10300) : \ + (fw_core ? 0x33000 : 0x32000)) + +#define CMIC_CMC_SCHAN_MESSAGE_10r(BASE) (BASE + 0x00000034) +#define CMIC_CMC_SCHAN_MESSAGE_11r(BASE) (BASE + 0x00000038) +#define CMIC_CMC_SCHAN_MESSAGE_12r(BASE) (BASE + 0x0000003c) +#define CMIC_CMC_SCHAN_MESSAGE_13r(BASE) (BASE + 0x00000040) +#define CMIC_CMC_SCHAN_MESSAGE_14r(BASE) (BASE + 0x00000044) +#define CMIC_CMC_SCHAN_MESSAGE_15r(BASE) (BASE + 0x00000048) +#define CMIC_CMC_SCHAN_MESSAGE_16r(BASE) (BASE + 0x0000004c) +#define CMIC_CMC_SCHAN_MESSAGE_17r(BASE) (BASE + 0x00000050) +#define CMIC_CMC_SCHAN_MESSAGE_18r(BASE) (BASE + 0x00000054) +#define CMIC_CMC_SCHAN_MESSAGE_19r(BASE) (BASE + 0x00000058) +#define CMIC_CMC_SCHAN_MESSAGE_20r(BASE) (BASE + 0x0000005c) +#define CMIC_CMC_SCHAN_MESSAGE_21r(BASE) (BASE + 0x00000060) + +u32 hostcmd_regs[5] = { 0 }; + +/* TX Timestamp FIFO Access */ +#define BCM_NUM_PORTS 128 + +/* Service request commands to R5 */ +enum { + BCM_KSYNC_DONE = 0x0, + BCM_KSYNC_INIT = 0x1, + BCM_KSYNC_DEINIT = 0x2, + BCM_KSYNC_GETTIME = 0x3, + BCM_KSYNC_SETTIME = 0x4, + BCM_KSYNC_FREQCOR = 0x5, + BCM_KSYNC_PBM_UPDATE = 0x6, + BCM_KSYNC_ADJTIME = 0x7, + BCM_KSYNC_GET_TSTIME = 0x8, +}; + +/* Usage macros */ +#define ONE_BILLION (1000000000) + +#define SKB_U16_GET(_skb, _pkt_offset) \ + ((_skb->data[_pkt_offset] << 8) | _skb->data[_pkt_offset + 1]) + +#define BKSYNC_PTP_EVENT_MSG(_ptp_msg_type) \ + ((_ptp_msg_type == DELAY_REQ) || (_ptp_msg_type == SYNC)) + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) +#define HWTSTAMP_TX_ONESTEP_SYNC 2 +#else +#include +#endif + + +/* Values for the messageType field */ +#define SYNC 0x0 +#define DELAY_REQ 0x1 + +/* + * Hardware specific information. + * 4 words of information used from this data set. + * 0 - 3: 2-step untagged. + * 4 - 7: 2-step tagged. + * 8 - 11: 1-step untagged. + * 12 - 15: 1-step tagged. + * 16 - 19: 1-step untagged with ITS-set. + * 20 - 23: 1-step tagged with ITS-set. + */ +uint32_t sobmhrawpkts_dcb26[24] = {0x00000000, 0x00020E00, 0x00000000, 0x00000000, 0x00000000, 0x00021200, 0x00000000, 0x00000000, + 0x00000000, 0x00100E00, 0x00000000, 0x00000000, 0x00000000, 0x00101200, 0x00000000, 0x00000000, + 0x00000000, 0x00140E00, 0x00000000, 0x00000000, 0x00000000, 0x00141200, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv4_dcb26[24] = {0x00000000, 0x00022A00, 0x00000000, 0x00000000, 0x00000000, 0x00022E00, 0x00000000, 0x00000000, + 0x00000000, 0x00102A00, 0x00000000, 0x00000000, 0x00000000, 0x00102E00, 0x00000000, 0x00000000, + 0x00000000, 0x00142A00, 0x00000000, 0x00000000, 0x00000000, 0x00142E00, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv6_dcb26[24] = {0x00000000, 0x00023E00, 0x00000000, 0x00000000, 0x00000000, 0x00024200, 0x00000000, 0x00000000, + 0x00000000, 0x00103E00, 0x00000000, 0x00000000, 0x00000000, 0x00104200, 0x00000000, 0x00000000, + 0x00000000, 0x00143E00, 0x00000000, 0x00000000, 0x00000000, 0x00144200, 0x00000000, 0x00000000}; + +uint32_t sobmhrawpkts_dcb32[24] = {0x00000000, 0x00010E00, 0x00000000, 0x00000000, 0x00000000, 0x00011200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv4_dcb32[24] = {0x00000000, 0x00012A00, 0x00000000, 0x00000000, 0x00000000, 0x00012E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv6_dcb32[24] = {0x00000000, 0x00013E00, 0x00000000, 0x00000000, 0x00000000, 0x00014200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000}; + +uint32_t sobmhrawpkts_dcb36[24] = {0x00000000, 0x00010E00, 0x00000000, 0x00000000, 0x00000000, 0x00011200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv4_dcb36[24] = {0x00000000, 0x00012A00, 0x00000000, 0x00000000, 0x00000000, 0x00012E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv6_dcb36[24] = {0x00000000, 0x00013E00, 0x00000000, 0x00000000, 0x00000000, 0x00014200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000}; +/* th3: onestep only */ +uint32_t sobmhrawpkts_dcb38[24] = {0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000, + 0x00000000, 0x00080E00, 0x00000000, 0x00000000, 0x00000000, 0x00081200, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv4_dcb38[24] = {0x00000000, 0x00082A00, 0x00000000, 0x00000000, 0x00000000, 0x00082E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000, + 0x00000000, 0x000C2A00, 0x00000000, 0x00000000, 0x00000000, 0x000C2E00, 0x00000000, 0x00000000}; + +uint32_t sobmhudpipv6_dcb38[24] = {0x00000000, 0x00083E00, 0x00000000, 0x00000000, 0x00000000, 0x00084200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000, + 0x00000000, 0x000C3E00, 0x00000000, 0x00000000, 0x00000000, 0x000C4200, 0x00000000, 0x00000000}; + +/* Driver Proc Entry root */ +static struct proc_dir_entry *bksync_proc_root = NULL; + +/* Shared data structures with R5 */ +typedef struct _bksync_tx_ts_data_s +{ + u32 ts_valid; /* Timestamp valid indication */ + u32 port_id; /* Port number */ + u32 ts_seq_id; /* Sequency Id */ + u32 ts_cnt; + u64 timestamp; /* Timestamp */ +} bksync_tx_ts_data_t; + +typedef struct _bksync_uc_linux_ipc_s +{ + u32 ksyncinit; + u32 dev_id; + s64 freqcorr; + u64 portmap[BCM_NUM_PORTS/64]; + u64 ptptime; + u64 reftime; + s64 phase_offset; + bksync_tx_ts_data_t port_ts_data[BCM_NUM_PORTS]; +} bksync_uc_linux_ipc_t; + +typedef struct bksync_port_stats_s { + u32 pkt_rxctr; /* All ingress packets */ + u32 pkt_txctr; /* All egress packets */ + u32 tsts_match; /* 2-Step tstamp req match */ + u32 tsts_timeout; /* 2-Step tstamp req timeouts */ + u32 tsts_discard; /* 2-Step tstamp req discards */ + u32 osts_event_pkts; /* 1-step event packet counter */ + u32 osts_tstamp_reqs; /* 1-step events with tstamp request */ +} bksync_port_stats_t; + +/* Clock Private Data */ +struct bksync_ptp_priv { + struct device dev; + int dcb_type; + struct ptp_clock *ptp_clock; + struct ptp_clock_info ptp_caps; + struct mutex ptp_lock; + struct mutex ptp_pair_lock; + volatile void *base_addr; /* address for PCI register access */ + volatile bksync_uc_linux_ipc_t *shared_addr; /* address for shared memory access */ + uint64_t dma_mem; + int dma_mem_size; + int num_pports; + struct DMA_DEV *dma_dev; /* Required for DMA memory control */ + u32 pkt_rxctr[BCM_NUM_PORTS]; + u32 pkt_txctr[BCM_NUM_PORTS]; + u32 ts_match[BCM_NUM_PORTS]; + u32 ts_timeout[BCM_NUM_PORTS]; + u32 ts_discard[BCM_NUM_PORTS]; + int timekeep_status; + struct delayed_work time_keep; + bksync_port_stats_t *port_stats; +}; + +static struct bksync_ptp_priv *ptp_priv; +volatile bksync_uc_linux_ipc_t *linuxPTPMemory = (bksync_uc_linux_ipc_t*)(0); +static volatile int module_initialized; +static int retry_count = 10; /* Default retry for 10 jiffies */ + +static void bksync_ptp_time_keep_init(void); +static void bksync_ptp_time_keep_deinit(void); + +#if defined(CMIC_SOFT_BYTE_SWAP) + +#define CMIC_SWAP32(_x) ((((_x) & 0xff000000) >> 24) \ + | (((_x) & 0x00ff0000) >> 8) \ + | (((_x) & 0x0000ff00) << 8) \ + | (((_x) & 0x000000ff) << 24)) + +#define DEV_READ32(_d, _a, _p) \ + do { \ + uint32_t _data; \ + _data = (((volatile uint32_t *)(_d)->base_addr)[(_a)/4]); \ + *(_p) = CMIC_SWAP32(_data); \ + } while(0) + +#define DEV_WRITE32(_d, _a, _v) \ + do { \ + uint32_t _data = CMIC_SWAP32(_v); \ + ((volatile uint32_t *)(_d)->base_addr)[(_a)/4] = (_data); \ + } while(0) + +#else + +#define DEV_READ32(_d, _a, _p) \ + do { \ + *(_p) = (((volatile uint32_t *)(_d)->base_addr)[(_a)/4]); \ + } while(0) + +#define DEV_WRITE32(_d, _a, _v) \ + do { \ + ((volatile uint32_t *)(_d)->base_addr)[(_a)/4] = (_v); \ + } while(0) +#endif /* defined(CMIC_SOFT_BYTE_SWAP) */ + +static void +ptp_usleep(int usec) +{ + usleep_range(usec,usec+1); +} + +static void +ptp_sleep(int jiffies) +{ + wait_queue_head_t wq; + init_waitqueue_head(&wq); + + wait_event_timeout(wq, 0, jiffies); + +} + + +static int bksync_cmd_cmicm_go(u32 cmd, void *data0, void *data1) +{ + int ret = -1; + int retry_cnt = retry_count; + u32 cmd_status; + + mutex_lock(&ptp_priv->ptp_lock); + ptp_priv->shared_addr->ksyncinit = cmd; + switch (cmd) { + case BCM_KSYNC_INIT: + ptp_priv->shared_addr->phase_offset = 0; + ret = 0; + break; + case BCM_KSYNC_FREQCOR: + ptp_priv->shared_addr->freqcorr = *((s32 *)data0); + break; + case BCM_KSYNC_ADJTIME: + ptp_priv->shared_addr->phase_offset = *((s64 *)data0); + break; + case BCM_KSYNC_GETTIME: + break; + case BCM_KSYNC_SETTIME: + ptp_priv->shared_addr->ptptime = *((s64 *)data0); + ptp_priv->shared_addr->phase_offset = 0; + break; + default: + break; + } + + do { + cmd_status = ptp_priv->shared_addr->ksyncinit; + if (cmd_status == BCM_KSYNC_DONE) { + switch (cmd) { + case BCM_KSYNC_GETTIME: + *((s64 *)data0) = ptp_priv->shared_addr->ptptime; + *((s64 *)data1) = ptp_priv->shared_addr->reftime; /* ptp counter */ + break; + default: + break; + } + ret = 0; + break; + } + ptp_sleep(1); + retry_cnt--; + } while (retry_cnt); + mutex_unlock(&ptp_priv->ptp_lock); + + if (retry_cnt == 0) { + DBG_ERR(("Timeout on response from R5\n")); + } + + + return ret; +} + + + +static void bksync_hostcmd_data_op(int setget, u64 *d1, u64 *d2) +{ + u32 w0, w1; + u64 data; + + if (!d1) { + return; + } + + if (setget) { + data = *d1; + w0 = (data & 0xFFFFFFFF); + w1 = (data >> 32); + DEV_WRITE32(ptp_priv, hostcmd_regs[1], w0); + DEV_WRITE32(ptp_priv, hostcmd_regs[2], w1); + } else { + DEV_READ32(ptp_priv, hostcmd_regs[1], &w0); + DEV_READ32(ptp_priv, hostcmd_regs[2], &w1); + data = (((u64)w1 << 32) | (w0)); + *d1 = data; + + if (d2) { + DEV_READ32(ptp_priv, hostcmd_regs[3], &w0); + DEV_READ32(ptp_priv, hostcmd_regs[4], &w1); + data = (((u64)w1 << 32) | (w0)); + *d2 = data; + } + } +} + + +static int bksync_cmd_cmicx_go(u32 cmd, void *data0, void *data1) +{ + int ret = -1; + int retry_cnt = (retry_count * 100); + u32 cmd_status; + char cmd_str[20]; + + mutex_lock(&ptp_priv->ptp_lock); + ptp_priv->shared_addr->ksyncinit = cmd; + + /* init data */ + DEV_WRITE32(ptp_priv, hostcmd_regs[1], 0x0); + DEV_WRITE32(ptp_priv, hostcmd_regs[2], 0x0); + DEV_WRITE32(ptp_priv, hostcmd_regs[3], 0x0); + DEV_WRITE32(ptp_priv, hostcmd_regs[4], 0x0); + + switch (cmd) { + case BCM_KSYNC_INIT: + sprintf(cmd_str, "KSYNC_INIT"); + ptp_priv->shared_addr->phase_offset = 0; + bksync_hostcmd_data_op(1, (u64 *)&(ptp_priv->shared_addr->phase_offset), 0); + break; + case BCM_KSYNC_FREQCOR: + sprintf(cmd_str, "KSYNC_FREQCORR"); + ptp_priv->shared_addr->freqcorr = *((s32 *)data0); + bksync_hostcmd_data_op(1, (u64 *)&(ptp_priv->shared_addr->freqcorr), 0); + break; + case BCM_KSYNC_ADJTIME: + sprintf(cmd_str, "KSYNC_ADJTIME"); + ptp_priv->shared_addr->phase_offset = *((s64 *)data0); + bksync_hostcmd_data_op(1, (u64 *)&(ptp_priv->shared_addr->phase_offset), 0); + break; + case BCM_KSYNC_GETTIME: + sprintf(cmd_str, "KSYNC_GETTIME"); + break; + case BCM_KSYNC_GET_TSTIME: + retry_cnt = (retry_cnt * 2); + sprintf(cmd_str, "KSYNC_GET_TSTIME"); + bksync_hostcmd_data_op(1, data0, data1); + break; + case BCM_KSYNC_SETTIME: + sprintf(cmd_str, "KSYNC_SETTIME"); + ptp_priv->shared_addr->ptptime = *((s64 *)data0); + ptp_priv->shared_addr->phase_offset = 0; + bksync_hostcmd_data_op(1, (u64 *)&(ptp_priv->shared_addr->ptptime), (u64 *)&(ptp_priv->shared_addr->phase_offset)); + break; + case BCM_KSYNC_DEINIT: + sprintf(cmd_str, "KSYNC_DEINIT"); + break; + default: + sprintf(cmd_str, "KSYNC_XXX"); + break; + } + DEV_WRITE32(ptp_priv, hostcmd_regs[0], ptp_priv->shared_addr->ksyncinit); + + do { + DEV_READ32(ptp_priv, hostcmd_regs[0], &cmd_status); + ptp_priv->shared_addr->ksyncinit = cmd_status; + + if (cmd_status == BCM_KSYNC_DONE) { + ret = 0; + switch (cmd) { + case BCM_KSYNC_GET_TSTIME: + case BCM_KSYNC_GETTIME: + bksync_hostcmd_data_op(0, (u64 *)data0, (u64 *)data1); + break; + default: + break; + } + break; + } + ptp_usleep(100); + retry_cnt--; + } while (retry_cnt); + + mutex_unlock(&ptp_priv->ptp_lock); + + if (retry_cnt == 0) { + DBG_ERR(("Timeout on response from R5 to cmd %s\n", cmd_str)); + } + + + return ret; +} + + +static int bksync_cmd_go(u32 cmd, void *data0, void *data1) +{ + int ret = -1; + + if (ptp_priv == NULL || ptp_priv->shared_addr == NULL) { + return ret; + } + + switch (ptp_priv->dcb_type) { + case 26: + ret = bksync_cmd_cmicm_go(cmd, data0, data1); + break; + case 32: + case 36: + case 38: + ret = bksync_cmd_cmicx_go(cmd, data0, data1); + break; + default: + break; + } + + return ret; +} + + +/** + * bksync_ptp_adjfreq + * + * @ptp: pointer to ptp_clock_info structure + * @ppb: frequency correction value + * + * Description: this function will set the frequency correction + */ +static int bksync_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) +{ + int ret = -1; + u32 cmd_status = BCM_KSYNC_FREQCOR; + + ret = bksync_cmd_go(cmd_status, &ppb, NULL); + DBG_VERB(("applying freq correction: %x\n", ppb)); + + return ret; +} + +/** + * bksync_ptp_adjtime + * + * @ptp: pointer to ptp_clock_info structure + * @delta: desired change in nanoseconds + * + * Description: this function will shift/adjust the hardware clock time. + */ +static int bksync_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) +{ + u32 cmd_status = BCM_KSYNC_ADJTIME; + int ret = -1; + + ret = bksync_cmd_go(cmd_status, (void *)&delta, NULL); + DBG_VERB(("ptp adjtime: 0x%llx \n", delta)); + + return ret; +} + +/** + * bksync_ptp_gettime + * + * @ptp: pointer to ptp_clock_info structure + * @ts: pointer to hold time/result + * + * Description: this function will read the current time from the + * hardware clock and store it in @ts. + */ +static int bksync_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) +{ + int ret = -1; + u32 cmd_status = BCM_KSYNC_GETTIME; + s64 reftime = 0; + s64 refctr = 0; + + ret = bksync_cmd_go(cmd_status, (void *)&reftime, (void *)&refctr); + DBG_VERB(("ptp gettime: 0x%llx refctr:0x%llx\n", reftime, refctr)); + mutex_lock(&ptp_priv->ptp_pair_lock); + ptp_priv->shared_addr->ptptime = reftime; + ptp_priv->shared_addr->reftime = refctr; + mutex_unlock(&ptp_priv->ptp_pair_lock); + + *ts = ns_to_timespec64(reftime); + return ret; +} + + +/** + * bksync_ptp_settime + * + * @ptp: pointer to ptp_clock_info structure + * @ts: time value to set + * + * Description: this function will set the current time on the + * hardware clock. + */ +static int bksync_ptp_settime(struct ptp_clock_info *ptp, + const struct timespec64 *ts) +{ + s64 reftime, phaseadj; + int ret = -1; + u32 cmd_status = BCM_KSYNC_SETTIME; + + phaseadj = 0; + reftime = timespec64_to_ns(ts); + + ret = bksync_cmd_go(cmd_status, (void *)&reftime, (void *)&phaseadj); + DBG_VERB(("ptp settime: 0x%llx \n", reftime)); + + return ret; +} + +static int bksync_ptp_enable(struct ptp_clock_info *ptp, + struct ptp_clock_request *rq, int on) +{ + return 0; +} + +/* structure describing a PTP hardware clock */ +static struct ptp_clock_info bksync_ptp_caps = { + .owner = THIS_MODULE, + .name = "bksync_ptp_clock", + .max_adj = 200000, + .n_alarm = 0, + .n_ext_ts = 0, + .n_per_out = 0, /* will be overwritten in bksync_ptp_register */ + .n_pins = 0, + .pps = 0, + .adjfreq = bksync_ptp_adjfreq, + .adjtime = bksync_ptp_adjtime, + .gettime64 = bksync_ptp_gettime, + .settime64 = bksync_ptp_settime, + .enable = bksync_ptp_enable, +}; + +/** + * bksync_ptp_hw_tstamp_enable + * + * @dev_no: device number + * @port: port number + * + * Description: this is a callback function to enable the timestamping on + * a given port + */ +int bksync_ptp_hw_tstamp_enable(int dev_no, int port, int tx_type) +{ + uint64_t portmap = 0; + int map = 0; + int ret = 0; + + if (!module_initialized) { + ret = -1; + goto exit; + } + + if (tx_type == HWTSTAMP_TX_ONESTEP_SYNC) { + bksync_ptp_time_keep_init(); + goto exit; + } + + DBG_VERB(("Enable timestamp on a given port:%d\n", port)); + if (port <= 0) { + DBG_ERR(("Error enabling timestamp on port:%d\n", port)); + ret = -1; + goto exit; + } + + port -= 1; + map = port/64; port = port%64; + + /* Update the shared structure member */ + if (ptp_priv->shared_addr) { + portmap = ptp_priv->shared_addr->portmap[map]; + portmap |= (uint64_t)0x1 << port; + ptp_priv->shared_addr->portmap[map] = portmap; + /* Command to R5 for the update */ + ptp_priv->shared_addr->ksyncinit=BCM_KSYNC_PBM_UPDATE; + } + +exit: + return ret; +} + +/** + * bksync_ptp_hw_tstamp_disable + * + * @dev_no: device number + * @port: port number + * + * Description: this is a callback function to disable the timestamping on + * a given port + */ +int bksync_ptp_hw_tstamp_disable(int dev_no, int port, int tx_type) +{ + uint64_t portmap = 0; + int map = 0; + int ret = 0; + + if (!module_initialized) { + ret = -1; + goto exit; + } + + if (tx_type == HWTSTAMP_TX_ONESTEP_SYNC) { + goto exit; + } + + DBG_VERB(("Disable timestamp on a given port:%d\n", port)); + if (port <= 0) { + DBG_ERR(("Error disabling timestamp on port:%d\n", port)); + ret = -1; + goto exit; + } + + port -= 1; + map = port/64; port = port%64; + + /* Update the shared structure member */ + if (ptp_priv->shared_addr) { + portmap = ptp_priv->shared_addr->portmap[map]; + portmap &= ~((uint64_t)0x1 << port); + ptp_priv->shared_addr->portmap[map]= portmap; + + /* Command to R5 for the update */ + ptp_priv->shared_addr->ksyncinit = BCM_KSYNC_PBM_UPDATE; + } +exit: + return ret; +} + +int bksync_ptp_transport_get(uint8_t *pkt) +{ + int transport = 0; + uint16_t ethertype; + uint16_t tpid; + int tpid_offset, ethype_offset; + + /* Need to check VLAN tag if packet is tagged */ + tpid_offset = 12; + tpid = pkt[tpid_offset] << 8 | pkt[tpid_offset + 1]; + if (tpid == 0x8100) { + ethype_offset = tpid_offset + 4; + } else { + ethype_offset = tpid_offset; + } + + ethertype = pkt[ethype_offset] << 8 | pkt[ethype_offset+1]; + + switch (ethertype) { + case 0x88f7: /* ETHERTYPE_PTPV2 */ + transport = 2; + break; + + case 0x0800: /* ETHERTYPE_IPV4 */ + transport = 4; + break; + + case 0x86DD: /* ETHERTYPE_IPV6 */ + transport = 6; + break; + + default: + transport = 0; + } + + return transport; +} + +static int +bksync_txpkt_tsts_tsamp_get(int port, uint32_t pkt_seq_id, uint32_t *ts_valid, uint32_t *seq_id, uint64_t *timestamp) +{ + int ret = 0; + uint64_t tmp; + + tmp = (port & 0xFFFF) | (pkt_seq_id << 16); + + if (HOSTCMD_USE_REGS) { + ret = bksync_cmd_go(BCM_KSYNC_GET_TSTIME, &tmp, timestamp); + + if (ret >= 0) { + *seq_id = ((tmp >> 16) & 0xFFFF); + *ts_valid = (tmp & 0x1); + } +#if 0 + if (tmp & 0x1) gprintk("in_port: %d in_seq_id: %d out_port: %lld ts_valid: %lld seq_id: %lld ts: %llx\n", port, pkt_seq_id, ((tmp & 0xFFFF) >> 1), (tmp & 0x1), (tmp >> 16), *timestamp); +#endif + } else { + *ts_valid = ptp_priv->shared_addr->port_ts_data[port].ts_valid; + *seq_id = ptp_priv->shared_addr->port_ts_data[port].ts_seq_id; + *timestamp = ptp_priv->shared_addr->port_ts_data[port].timestamp; + } + + + return ret; +} + + +/** + * bksync_ptp_hw_tstamp_tx_time_get + * + * @dev_no: device number + * @port: port number + * @pkt: packet address + * @ts: timestamp to be retrieved + * + * Description: this is a callback function to retrieve the timestamp on + * a given port + */ +int bksync_ptp_hw_tstamp_tx_time_get(int dev_no, int port, uint8_t *pkt, uint64_t *ts) +{ + /* Get Timestamp from R5 or CLMAC */ + uint32_t ts_valid = 0; + uint32_t seq_id = 0; + uint32_t pktseq_id = 0; + uint64_t timestamp = 0; + uint16_t tpid = 0; + int retry_cnt = retry_count; + int seq_id_offset, tpid_offset; + int transport = network_transport; + + if (!ptp_priv || !pkt || !ts || port < 1 || port > 255 || ptp_priv->shared_addr == NULL) { + return -1; + } + + *ts = 0; + + tpid_offset = 12; + + /* Parse for nw transport */ + if (transport == 0) { + transport = bksync_ptp_transport_get(pkt); + } + + switch(transport) + { + case 2: + seq_id_offset = 0x2c; + break; + case 4: + seq_id_offset = 0x48; + break; + case 6: + seq_id_offset = 0x5c; + break; + default: + seq_id_offset = 0x2c; + break; + } + + /* Need to check VLAN tag if packet is tagged */ + tpid = pkt[tpid_offset] << 8 | pkt[tpid_offset + 1]; + if (tpid == 0x8100) { + seq_id_offset += 4; + } + + + pktseq_id = pkt[seq_id_offset] << 8 | pkt[seq_id_offset + 1]; + + port -= 1; + + /* Fetch the TX timestamp from shadow memory */ + do { + bksync_txpkt_tsts_tsamp_get(port, pktseq_id, &ts_valid, &seq_id, ×tamp); + if (ts_valid) { + + /* Clear the shadow memory to get next entry */ + ptp_priv->shared_addr->port_ts_data[port].timestamp = 0; + ptp_priv->shared_addr->port_ts_data[port].port_id = 0; + ptp_priv->shared_addr->port_ts_data[port].ts_seq_id = 0; + ptp_priv->shared_addr->port_ts_data[port].ts_valid = 0; + + if (seq_id == pktseq_id) { + *ts = timestamp; + if (HOSTCMD_USE_REGS) { + ptp_priv->port_stats[port].tsts_match += 1; + } else { + ptp_priv->ts_match[port] += 1; + } + + DBG_VERB(("Port: %d Skb_SeqID %d FW_SeqId %d and TS:%llx\n", + port, pktseq_id, seq_id, timestamp)); + + break; + } else { + DBG_ERR(("discard timestamp on port %d Skb_SeqID %d FW_SeqId %d\n", + port, pktseq_id, seq_id)); + + if (HOSTCMD_USE_REGS) { + ptp_priv->port_stats[port].tsts_discard += 1; + } else { + ptp_priv->ts_discard[port] += 1; + } + continue; + } + } + ptp_sleep(1); + retry_cnt--; + } while(retry_cnt); + + + if (HOSTCMD_USE_REGS) { + ptp_priv->port_stats[port].pkt_txctr += 1; + } else { + ptp_priv->pkt_txctr[port] += 1; + } + + if (retry_cnt == 0) { + if (HOSTCMD_USE_REGS) { + ptp_priv->port_stats[port].tsts_timeout += 1; + } else { + ptp_priv->ts_timeout[port] += 1; + } + DBG_ERR(("FW Response timeout: Tx TS on phy port:%d Skb_SeqID: %d\n", port, seq_id)); + } + + + return 0; +} + + +enum { + bxconCustomEncapVersionInvalid = 0, + bxconCustomEncapVersionOne = 1, + + bxconCustomEncapVersionCurrent = bxconCustomEncapVersionOne, + bxconCustomEncapVersionReserved = 255 /* last */ +} bxconCustomEncapVersion; + +enum { + bxconCustomEncapOpcodeInvalid = 0, + bxconCustomEncapOpcodePtpRx = 1, + bxconCustomEncapOpcodeReserved = 255 /* last */ +} bxconCustomEncapOpcode; + +enum { + bxconCustomEncapPtpRxTlvInvalid = 0, + bxconCustomEncapPtpRxTlvPtpRxTime = 1, + bxconCustomEncapPtpRxTlvReserved = 255 /* last */ +} bxconCustomEncapPtpRxTlvType; + +void +bksync_dump_pkt(uint8_t *data, int size) +{ + int idx; + char str[128]; + + for (idx = 0; idx < size; idx++) { + if ((idx & 0xf) == 0) { + sprintf(str, "%04x: ", idx); + } + sprintf(&str[strlen(str)], "%02x ", data[idx]); + if ((idx & 0xf) == 0xf) { + sprintf(&str[strlen(str)], "\n"); + gprintk(str); + } + } + if ((idx & 0xf) != 0) { + sprintf(&str[strlen(str)], "\n"); + gprintk(str); + } +} + + +static inline int +bksync_pkt_custom_encap_ptprx_get(uint8_t *pkt, uint64_t *ing_ptptime) +{ + uint8_t *custom_hdr; + uint8_t id[4]; + uint8_t ver, opc; + uint8_t nh_type, nh_rsvd; + uint16_t len, tot_len; + uint16_t nh_len; + uint32_t seq_id = 0; + uint32_t ptp_rx_time[2]; + uint64_t u64_ptp_rx_time = 0; + + custom_hdr = pkt; + + BKSYNC_UNPACK_U8(custom_hdr, id[0]); + BKSYNC_UNPACK_U8(custom_hdr, id[1]); + BKSYNC_UNPACK_U8(custom_hdr, id[2]); + BKSYNC_UNPACK_U8(custom_hdr, id[3]); + if (!((id[0] == 'B') && (id[1] == 'C') && (id[2] == 'M') && (id[3] == 'C'))) { + /* invalid signature */ + return -1; + } + + BKSYNC_UNPACK_U8(custom_hdr, ver); + switch (ver) { + case bxconCustomEncapVersionCurrent: + break; + default: + gprintk("invalid ver\n"); + return -1; + } + + BKSYNC_UNPACK_U8(custom_hdr, opc); + switch (opc) { + case bxconCustomEncapOpcodePtpRx: + break; + default: + gprintk("invalid opcode\n"); + return -1; + } + + + BKSYNC_UNPACK_U16(custom_hdr, len); + BKSYNC_UNPACK_U32(custom_hdr, seq_id); + tot_len = len; + + /* remaining length of custom encap */ + len = len - (custom_hdr - pkt); + + + /* process tlv */ + while (len > 0) { + BKSYNC_UNPACK_U8(custom_hdr, nh_type); + BKSYNC_UNPACK_U8(custom_hdr, nh_rsvd); + BKSYNC_UNPACK_U16(custom_hdr, nh_len); + len = len - (nh_len); + if (nh_rsvd != 0x0) { + continue; /* invalid tlv */ + } + + switch (nh_type) { + case bxconCustomEncapPtpRxTlvPtpRxTime: + BKSYNC_UNPACK_U32(custom_hdr, ptp_rx_time[0]); + BKSYNC_UNPACK_U32(custom_hdr, ptp_rx_time[1]); + u64_ptp_rx_time = ((uint64_t)ptp_rx_time[1] << 32) | (uint64_t)ptp_rx_time[0]; + *ing_ptptime = u64_ptp_rx_time; + break; + default: + custom_hdr += nh_len; + break; + } + } + +#if 0 +if (!(seq_id % 100)) { + gprintk("****** seq_id = %d ptp time = 0x%llx\n", seq_id, u64_ptp_rx_time); + bksync_dump_pkt(pkt, tot_len); +} +#endif + + DBG_VERB(("Custom encap header: ver=%d opcode=%d seq_id=0x%x\n", ver, opc, seq_id)); + + return (tot_len); +} + + + +/** + * bksync_ptp_hw_tstamp_rx_time_upscale + * + * @dev_no: device number + * @ts: timestamp to be retrieved + * + * Description: this is a callback function to retrieve 64b equivalent of + * rx timestamp + */ +int bksync_ptp_hw_tstamp_rx_time_upscale(int dev_no, int port, struct sk_buff *skb, uint32_t *meta, uint64_t *ts) +{ + int ret = 0; + int custom_encap_len = 0; + + switch (KNET_SKB_CB(skb)->dcb_type) { + case 26: + case 32: + if (pci_cos != (meta[4] & 0x3F)) { + return -1; + } + break; + case 38: + if (pci_cos != ((meta[12] >> 22) & 0x2F)) { + return -1; + } + break; + case 36: + if (pci_cos != ((meta[6] >> 22) & 0x2F)) { + return -1; + } + break; + default: + return -1; + } + + /* parse custom encap header in pkt for ptp rxtime */ + custom_encap_len = bksync_pkt_custom_encap_ptprx_get((skb->data), ts); + + /* Remove the custom encap header from pkt */ + if (custom_encap_len > 0) { + skb_pull(skb, custom_encap_len); + + DBG_VERB(("###### ptp message type: %d\n", skb->data[42])); + } + + if (port > 0){ + port -= 1; + if (HOSTCMD_USE_REGS) { + ptp_priv->port_stats[port].pkt_rxctr += 1; + } else { + ptp_priv->pkt_rxctr[port] += 1; + } + } + + return ret; +} + + +void bksync_hton64(u8 *buf, const uint64_t *data) +{ +#ifdef __LITTLE_ENDIAN + /* LITTLE ENDIAN */ + buf[0] = (*(((uint8_t*)(data)) + 7u)); + buf[1] = (*(((uint8_t*)(data)) + 6u)); + buf[2] = (*(((uint8_t*)(data)) + 5u)); + buf[3] = (*(((uint8_t*)(data)) + 4u)); + buf[4] = (*(((uint8_t*)(data)) + 3u)); + buf[5] = (*(((uint8_t*)(data)) + 2u)); + buf[6] = (*(((uint8_t*)(data)) + 1u)); + buf[7] = (*(((uint8_t*)(data)) + 0u)); +#else + memcpy(buf, data, 8); +#endif +} + + + +int bksync_ptp_hw_tstamp_tx_meta_get(int dev_no, + int hwts, int hdrlen, + struct sk_buff *skb, + uint64_t *tstamp, + u32 **md) +{ + uint16_t tpid = 0; + int md_offset = 0; + int pkt_offset = 0; + int ptp_hdr_offset = 0; + int transport = network_transport; + s64 ptptime = 0; + s64 ptpcounter = 0; + int64_t corrField; + int32_t negCurTS32; + int64_t negCurTS64; + + if(!ptp_priv || ptp_priv->shared_addr == NULL) { + return 0; + } + + mutex_lock(&ptp_priv->ptp_pair_lock); + ptptime = ptp_priv->shared_addr->ptptime; + ptpcounter = ptp_priv->shared_addr->reftime; + mutex_unlock(&ptp_priv->ptp_pair_lock); + + negCurTS32 = - (int32_t) ptpcounter; + negCurTS64 = - (int64_t)(ptpcounter); + + if (CMICX_DEV_TYPE) { + pkt_offset = ptp_hdr_offset = hdrlen; + } + + /* Need to check VLAN tag if packet is tagged */ + tpid = SKB_U16_GET(skb, (pkt_offset + 12)); + if (tpid == 0x8100) { + md_offset = 4; + ptp_hdr_offset += 4; + } + + /* One Step Meta Data */ + if (hwts == HWTSTAMP_TX_ONESTEP_SYNC) { + md_offset += 8; + if (KNET_SKB_CB(skb)->dcb_type == 26) { + corrField = (((int64_t)negCurTS32) << 16); + if (negCurTS32 >= 0) { + md_offset += 8; + } + } else { + corrField = (((int64_t)negCurTS64) << 16); + } + } + + + /* Parse for nw transport */ + if (transport == 0) { + transport = bksync_ptp_transport_get(skb->data + pkt_offset); + } + + switch(transport) + { + case 2: /* IEEE 802.3 */ + ptp_hdr_offset += 14; + if (KNET_SKB_CB(skb)->dcb_type == 32) { + if (md) *md = &sobmhrawpkts_dcb32[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 26) { + if (md) *md = &sobmhrawpkts_dcb26[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 36) { + if (md) *md = &sobmhrawpkts_dcb36[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 38) { + if (md) *md = &sobmhrawpkts_dcb38[md_offset]; + } + break; + case 4: /* UDP IPv4 */ + ptp_hdr_offset += 42; + if (KNET_SKB_CB(skb)->dcb_type == 32) { + if (md) *md = &sobmhudpipv4_dcb32[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 26) { + if (md) *md = &sobmhudpipv4_dcb26[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 36) { + if (md) *md = &sobmhudpipv4_dcb36[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 38) { + if (md) *md = &sobmhudpipv4_dcb38[md_offset]; + } + break; + case 6: /* UDP IPv6 */ + ptp_hdr_offset += 62; + if (KNET_SKB_CB(skb)->dcb_type == 32) { + if (md) *md = &sobmhudpipv6_dcb32[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 26) { + if (md) *md = &sobmhudpipv6_dcb26[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 36) { + if (md) *md = &sobmhudpipv6_dcb36[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 38) { + if (md) *md = &sobmhudpipv6_dcb38[md_offset]; + } + break; + default: + ptp_hdr_offset += 42; + if (KNET_SKB_CB(skb)->dcb_type == 32) { + if (md) *md = &sobmhudpipv4_dcb32[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 26) { + if (md) *md = &sobmhudpipv4_dcb26[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 36) { + if (md) *md = &sobmhudpipv4_dcb36[md_offset]; + } else if(KNET_SKB_CB(skb)->dcb_type == 38) { + if (md) *md = &sobmhudpipv4_dcb38[md_offset]; + } + break; + } + + + if ((hwts == HWTSTAMP_TX_ONESTEP_SYNC) && + BKSYNC_PTP_EVENT_MSG(skb->data[ptp_hdr_offset])) { + /* One Step Timestamp Field updation */ + int corr_offset = ptp_hdr_offset + 8; + int origin_ts_offset = ptp_hdr_offset + 34; + u32 tmp; + struct timespec64 ts; + int udp_csum_regen; + u32 udp_csum20; + u16 udp_csum; + + udp_csum = SKB_U16_GET(skb, (ptp_hdr_offset - 2)); + + switch (transport) { + case 2: + udp_csum_regen = 0; + break; + case 6: + udp_csum_regen = 1; + break; + default: + udp_csum_regen = (udp_csum != 0x0); + break; + } + + /* Fill the correction field */ + bksync_hton64(&(skb->data[corr_offset]), (const u64 *)&corrField); + + /* Fill the Origin Timestamp Field */ + ts = ns_to_timespec64(ptptime); + + tmp = (ts.tv_sec >> 32); + skb->data[origin_ts_offset + 0] = ((tmp >> 8) & 0xFF); + skb->data[origin_ts_offset + 1] = ((tmp ) & 0xFF); + + tmp = (ts.tv_sec & 0xFFFFFFFFLL); + skb->data[origin_ts_offset + 2] = ((tmp >> 24) & 0xFF); + skb->data[origin_ts_offset + 3] = ((tmp >> 16) & 0xFF); + skb->data[origin_ts_offset + 4] = ((tmp >> 8) & 0xFF); + skb->data[origin_ts_offset + 5] = ((tmp ) & 0xFF); + + tmp = (ts.tv_nsec & 0xFFFFFFFFLL); + skb->data[origin_ts_offset + 6] = ((tmp >> 24) & 0xFF); + skb->data[origin_ts_offset + 7] = ((tmp >> 16) & 0xFF); + skb->data[origin_ts_offset + 8] = ((tmp >> 8) & 0xFF); + skb->data[origin_ts_offset + 9] = ((tmp ) & 0xFF); + + if (udp_csum_regen) { + udp_csum20 = (~udp_csum) & 0xFFFF; + + udp_csum20 += SKB_U16_GET(skb, (corr_offset + 0)); + udp_csum20 += SKB_U16_GET(skb, (corr_offset + 2)); + udp_csum20 += SKB_U16_GET(skb, (corr_offset + 4)); + udp_csum20 += SKB_U16_GET(skb, (corr_offset + 6)); + + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 0)); + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 2)); + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 4)); + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 6)); + udp_csum20 += SKB_U16_GET(skb, (origin_ts_offset + 8)); + + /* Fold 20bit checksum into 16bit udp checksum */ + udp_csum20 = ((udp_csum20 & 0xFFFF) + (udp_csum20 >> 16)); + udp_csum = ((udp_csum20 & 0xFFFF) + (udp_csum20 >> 16)); + + /* invert again to get final checksum. */ + udp_csum = ~udp_csum; + if (udp_csum == 0) { + udp_csum = 0xFFFF; + } + + skb->data[ptp_hdr_offset - 2] = ((udp_csum >> 8) & 0xFF); + skb->data[ptp_hdr_offset - 1] = ((udp_csum ) & 0xFF); + } + + if (skb->data[ptp_hdr_offset] == DELAY_REQ) { + *tstamp = ptptime; + + DBG_VERB(("ptp delay req packet tstamp : 0x%llx corrField: 0x%llx\n", ptptime, corrField)); + } + + } + + return 0; +} + + +int bksync_ptp_hw_tstamp_ptp_clock_index_get(int dev_no) +{ + int phc_index = -1; + if (ptp_priv && ptp_priv->ptp_clock) + phc_index = ptp_clock_index(ptp_priv->ptp_clock); + return phc_index; +} + + +/** +* bcm_ptp_time_keep - call timecounter_read every second to avoid timer overrun +* because a 32bit counter, will timeout in 4s +*/ +static void bksync_ptp_time_keep(struct work_struct *work) +{ + struct delayed_work *dwork = to_delayed_work(work); + struct bksync_ptp_priv *priv = + container_of(dwork, struct bksync_ptp_priv, time_keep); + struct timespec64 ts; + + /* Call bcm_ptp_gettime function to keep the ref_time_64 and ref_counter_48 in sync */ + bksync_ptp_gettime(&(priv->ptp_caps), &ts); + schedule_delayed_work(&priv->time_keep, HZ); +} + +static void bksync_ptp_time_keep_init(void) +{ + if (!ptp_priv->timekeep_status) { + INIT_DELAYED_WORK(&(ptp_priv->time_keep), bksync_ptp_time_keep); + schedule_delayed_work(&ptp_priv->time_keep, HZ); + + ptp_priv->timekeep_status = 1; + } + + return; +} + +static void bksync_ptp_time_keep_deinit(void) +{ + if (ptp_priv->timekeep_status) { + /* Cancel delayed work */ + cancel_delayed_work_sync(&(ptp_priv->time_keep)); + + ptp_priv->timekeep_status = 0; + } + + return; +} + + + +static int bksync_ptp_init(struct ptp_clock_info *ptp) +{ + return bksync_cmd_go(BCM_KSYNC_INIT, NULL, NULL); +} + +static int bksync_ptp_deinit(struct ptp_clock_info *ptp) +{ + bksync_ptp_time_keep_deinit(); + + return bksync_cmd_go(BCM_KSYNC_DEINIT, NULL, NULL); +} + +/* + * Device Debug Statistics Proc Entry + */ +/** +* This function is called at the beginning of a sequence. +* ie, when: +* - the /proc/bcm/ksync/stats file is read (first time) +* - after the function stop (end of sequence) +* +*/ +static void *bksync_proc_seq_start(struct seq_file *s, loff_t *pos) +{ + /* beginning a new sequence ? */ + if ( (int)*pos == 0 && ptp_priv->shared_addr != NULL) + { + seq_printf(s, "Port Bitmap : %08llx%08llx\n", + (uint64_t)(ptp_priv->shared_addr->portmap[1]), + (uint64_t)(ptp_priv->shared_addr->portmap[0])); + seq_printf(s,"%4s| %9s| %9s| %9s| %9s| %9s| %9s|\n", + "Port", "RxCounter", "TxCounter", "TSTimeout", "TSRead", "TSMatch", "TSDiscard"); + } + + if (ptp_priv->shared_addr != NULL && (int)*pos < (ptp_priv->num_pports)) + return (void *)(unsigned long)(*pos + 1); + /* End of the sequence, return NULL */ + return NULL; +} + +/** +* This function is called after the beginning of a sequence. +* It's called untill the return is NULL (this ends the sequence). +* +*/ +static void *bksync_proc_seq_next(struct seq_file *s, void *v, loff_t *pos) +{ + (*pos)++; + return bksync_proc_seq_start(s, pos); +} +/** +* This function is called at the end of a sequence +* +*/ +static void bksync_proc_seq_stop(struct seq_file *s, void *v) +{ + /* nothing to do, we use a static value in bksync_proc_seq_start() */ +} + +/** +* This function is called for each "step" of a sequence +* +*/ +static int bksync_proc_seq_show(struct seq_file *s, void *v) +{ + unsigned long port = (unsigned long)v; + port = port - 1; + if (HOSTCMD_USE_REGS) { + if (ptp_priv->port_stats[port].pkt_rxctr || ptp_priv->port_stats[port].pkt_txctr || + ptp_priv->port_stats[port].tsts_discard || ptp_priv->port_stats[port].tsts_timeout || + ptp_priv->shared_addr->port_ts_data[port].ts_cnt || ptp_priv->port_stats[port].tsts_match) { + seq_printf(s, "%4lu | %9d| %9d| %9d| %9d| %9d| %9d| %s\n", (port + 1), + ptp_priv->port_stats[port].pkt_rxctr, + ptp_priv->port_stats[port].pkt_txctr, + ptp_priv->port_stats[port].tsts_timeout, + ptp_priv->shared_addr->port_ts_data[port].ts_cnt, + ptp_priv->port_stats[port].tsts_match, + ptp_priv->port_stats[port].tsts_discard, + ptp_priv->port_stats[port].pkt_txctr != ptp_priv->port_stats[port].tsts_match ? "***":""); + } + } else { + if (ptp_priv->pkt_rxctr[port] || ptp_priv->pkt_txctr[port] || + ptp_priv->ts_discard[port] || ptp_priv->ts_timeout[port] || + ptp_priv->shared_addr->port_ts_data[port].ts_cnt || ptp_priv->ts_match[port]) { + seq_printf(s, "%4lu | %9d| %9d| %9d| %9d| %9d| %9d| %s\n", (port + 1), + ptp_priv->pkt_rxctr[port], + ptp_priv->pkt_txctr[port], + ptp_priv->ts_timeout[port], + ptp_priv->shared_addr->port_ts_data[port].ts_cnt, + ptp_priv->ts_match[port], + ptp_priv->ts_discard[port], + ptp_priv->pkt_txctr[port] != ptp_priv->ts_match[port] ? "***":""); + } + } + return 0; +} + +/** +* seq_operations for bsync_proc_*** entries +* +*/ +static struct seq_operations bksync_proc_seq_ops = { + .start = bksync_proc_seq_start, + .next = bksync_proc_seq_next, + .stop = bksync_proc_seq_stop, + .show = bksync_proc_seq_show +}; +static int bksync_proc_txts_open(struct inode * inode, struct file * file) +{ + return seq_open(file, &bksync_proc_seq_ops); +} + +static ssize_t +bksync_proc_txts_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + char debug_str[40]; + char *ptr; + int port; + + if (copy_from_user(debug_str, buf, count)) { + return -EFAULT; + } + + if ((ptr = strstr(debug_str, "clear")) != NULL) { + for (port = 0; port < ptp_priv->num_pports; port++) { + if (HOSTCMD_USE_REGS) { + ptp_priv->port_stats[port].pkt_rxctr = 0; + ptp_priv->port_stats[port].pkt_txctr = 0; + ptp_priv->port_stats[port].tsts_discard = 0; + ptp_priv->port_stats[port].tsts_timeout = 0; + ptp_priv->port_stats[port].tsts_match = 0; + } else { + ptp_priv->pkt_rxctr[port] = 0; + ptp_priv->pkt_txctr[port] = 0; + ptp_priv->ts_discard[port] = 0; + ptp_priv->ts_timeout[port] = 0; + ptp_priv->ts_match[port] = 0; + } + if (ptp_priv->shared_addr) + ptp_priv->shared_addr->port_ts_data[port].ts_cnt = 0; + } + } else { + gprintk("Warning: unknown input\n"); + } + + return count; +} + +struct file_operations bksync_proc_txts_file_ops = { + owner: THIS_MODULE, + open: bksync_proc_txts_open, + read: seq_read, + llseek: seq_lseek, + write: bksync_proc_txts_write, + release: seq_release, +}; + +static int +bksync_proc_init(void) +{ + struct proc_dir_entry *entry; + + PROC_CREATE(entry, "stats", 0666, bksync_proc_root, &bksync_proc_txts_file_ops); + if (entry == NULL) { + return -1; + } + return 0; +} + +static int +bksync_proc_cleanup(void) +{ + remove_proc_entry("stats", bksync_proc_root); + return 0; +} + +static void bksync_ptp_cmicm_dma_init(int dcb_type) +{ + int endianess; + int num_pports = 128; + dma_addr_t dma_mem = 0; + + /* Initialize the Base address for CMIC and shared Memory access */ + ptp_priv->base_addr = lkbde_get_dev_virt(0); + ptp_priv->dma_dev = lkbde_get_dma_dev(0); + + ptp_priv->dma_mem_size = 16384;/*sizeof(bksync_uc_linux_ipc_t);*/ + + if (ptp_priv->shared_addr == NULL) { + DBG_ERR(("Allocate shared memory with R5\n")); + ptp_priv->shared_addr = DMA_ALLOC_COHERENT(ptp_priv->dma_dev, + ptp_priv->dma_mem_size, + &dma_mem); + ptp_priv->dma_mem = (uint64_t)dma_mem; + ptp_priv->num_pports = num_pports; + ptp_priv->port_stats = kzalloc((sizeof(bksync_port_stats_t) * num_pports), GFP_KERNEL); + } + + if (ptp_priv->shared_addr != NULL) { + /* Reset memory */ + memset((void *)ptp_priv->shared_addr, 0, ptp_priv->dma_mem_size); + + DBG_ERR(("Shared memory allocation (%d bytes) successful at 0x%016lx.\n", + ptp_priv->dma_mem_size, (long unsigned int)ptp_priv->dma_mem)); +#ifdef __LITTLE_ENDIAN + endianess = 0; +#else + endianess = 1; +#endif + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_12r(CMIC_CMC_BASE), ((pci_cos << 16) | endianess)); + + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_10r(CMIC_CMC_BASE), + (ptp_priv->dma_mem & 0xffffffff)); + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_11r(CMIC_CMC_BASE), + (ptp_priv->dma_mem >> 32) & 0xffffffff); + + ptp_priv->dcb_type = dcb_type; + } + + if (debug & DBG_LVL_VERB) { + printk(KERN_EMERG"%s %p:%p\n",__FUNCTION__, + ptp_priv->base_addr,(void *)ptp_priv->shared_addr); + } + + return; +} + +static void bksync_ptp_cmicx_dma_init(int dcb_type) +{ + int endianess; + int num_pports = 256; + + /* Initialize the Base address for CMIC and shared Memory access */ + ptp_priv->base_addr = lkbde_get_dev_virt(0); + ptp_priv->dma_dev = lkbde_get_dma_dev(0); + + ptp_priv->dcb_type = dcb_type; + ptp_priv->dma_mem_size = 16384;/*sizeof(bksync_uc_linux_ipc_t);*/ + + if (ptp_priv->shared_addr == NULL) { + ptp_priv->shared_addr = kzalloc(16384, GFP_KERNEL); + ptp_priv->num_pports = num_pports; + ptp_priv->port_stats = kzalloc((sizeof(bksync_port_stats_t) * num_pports), GFP_KERNEL); + } + + if (ptp_priv->shared_addr != NULL) { + /* Reset memory. */ + memset((void *)ptp_priv->shared_addr, 0, ptp_priv->dma_mem_size); + +#ifdef __LITTLE_ENDIAN + endianess = 0; +#else + endianess = 1; +#endif + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_12r(CMIC_CMC_BASE), ((pci_cos << 16) | endianess)); + + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_10r(CMIC_CMC_BASE), 1); + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_11r(CMIC_CMC_BASE), 1); + + } + + if (debug & DBG_LVL_VERB) { + printk(KERN_EMERG"%s %p:%p\n",__FUNCTION__, + ptp_priv->base_addr,(void *)ptp_priv->shared_addr); + } + + + hostcmd_regs[0] = CMIC_CMC_SCHAN_MESSAGE_21r(CMIC_CMC_BASE); + hostcmd_regs[1] = CMIC_CMC_SCHAN_MESSAGE_20r(CMIC_CMC_BASE); + hostcmd_regs[2] = CMIC_CMC_SCHAN_MESSAGE_19r(CMIC_CMC_BASE); + hostcmd_regs[3] = CMIC_CMC_SCHAN_MESSAGE_18r(CMIC_CMC_BASE); + hostcmd_regs[4] = CMIC_CMC_SCHAN_MESSAGE_17r(CMIC_CMC_BASE); + + return; +} + + +static void bksync_ptp_dma_init(int dcb_type) +{ + switch (dcb_type) { + case 26: + bksync_ptp_cmicm_dma_init(dcb_type); + ptp_priv->dcb_type = dcb_type; + break; + case 32: + case 36: + case 38: + bksync_ptp_cmicx_dma_init(dcb_type); + ptp_priv->dcb_type = dcb_type; + break; + default: + break; + } + + return; +} + + + +/** + * bksync_ioctl_cmd_handler + * @kmsg: kcom message - ptp clock ioctl command. + * Description: This function will handle ioctl commands + * from user mode. + */ +static int +bksync_ioctl_cmd_handler(kcom_msg_clock_cmd_t *kmsg, int len, int dcb_type) +{ + kmsg->hdr.type = KCOM_MSG_TYPE_RSP; + + if (!module_initialized && kmsg->clock_info.cmd != KSYNC_M_HW_INIT) { + kmsg->hdr.status = KCOM_E_NOT_FOUND; + return sizeof(kcom_msg_hdr_t); + } + + switch(kmsg->clock_info.cmd) { + case KSYNC_M_HW_INIT: + pci_cos = kmsg->clock_info.data[0]; + if (kmsg->clock_info.data[1] == 0 || kmsg->clock_info.data[1] == 1) { + fw_core = kmsg->clock_info.data[1]; + bksync_ptp_dma_init(dcb_type); + if (bksync_ptp_init(&(ptp_priv->ptp_caps)) >= 0) { + module_initialized = 1; + } + } + break; + case KSYNC_M_HW_DEINIT: + bksync_ptp_deinit(&(ptp_priv->ptp_caps)); + module_initialized = 0; + break; + case KSYNC_M_HW_TS_DISABLE: + bksync_ptp_hw_tstamp_disable(0, kmsg->clock_info.data[0], 0); + break; + case KSYNC_M_VERSION: + break; + default: + kmsg->hdr.status = KCOM_E_NOT_FOUND; + return sizeof(kcom_msg_hdr_t); + } + + return sizeof(*kmsg); +} + + + +/** + * bksync_ptp_register + * @priv: driver private structure + * Description: this function will register the ptp clock driver + * to kernel. It also does some house keeping work. + */ +static int bksync_ptp_register(void) +{ + int err = -ENODEV; + + /* Support on core-0 or core-1 */ + if (fw_core < 0 || fw_core > 1) { + goto exit; + } + + /* default transport is raw, ieee 802.3 */ + switch (network_transport) { + case 2: /* IEEE 802.3 */ + case 4: /* UDP IPv4 */ + case 6: /* UDP IPv6 */ + break; + default: + network_transport = 0; + } + + ptp_priv = kzalloc(sizeof(*ptp_priv), GFP_KERNEL); + if (!ptp_priv) { + err = -ENOMEM; + goto exit; + } + + /* Reset memory */ + memset(ptp_priv, 0, sizeof(*ptp_priv)); + + err = -ENODEV; + + ptp_priv->ptp_caps = bksync_ptp_caps; + + mutex_init(&(ptp_priv->ptp_lock)); + mutex_init(&(ptp_priv->ptp_pair_lock)); + + /* Register ptp clock driver with bksync_ptp_caps */ + ptp_priv->ptp_clock = ptp_clock_register(&ptp_priv->ptp_caps, NULL); + + if (IS_ERR(ptp_priv->ptp_clock)) { + ptp_priv->ptp_clock = NULL; + } else if (ptp_priv->ptp_clock) { + err = 0; + + /* Register BCM-KNET HW Timestamp Callback Functions */ + bkn_hw_tstamp_enable_cb_register(bksync_ptp_hw_tstamp_enable); + bkn_hw_tstamp_disable_cb_register(bksync_ptp_hw_tstamp_disable); + bkn_hw_tstamp_tx_time_get_cb_register(bksync_ptp_hw_tstamp_tx_time_get); + bkn_hw_tstamp_tx_meta_get_cb_register(bksync_ptp_hw_tstamp_tx_meta_get); + bkn_hw_tstamp_rx_time_upscale_cb_register(bksync_ptp_hw_tstamp_rx_time_upscale); + bkn_hw_tstamp_ptp_clock_index_cb_register(bksync_ptp_hw_tstamp_ptp_clock_index_get); + bkn_hw_tstamp_ioctl_cmd_cb_register(bksync_ioctl_cmd_handler); + + } + + /* Initialize proc files */ + bksync_proc_root = proc_mkdir("bcm/ksync", NULL); + bksync_proc_init(); + ptp_priv->shared_addr = NULL; + ptp_priv->port_stats = NULL; +exit: + return err; +} + +static int bksync_ptp_remove(void) +{ + if (!ptp_priv) + return 0; + + bksync_ptp_time_keep_deinit(); + + bksync_proc_cleanup(); + remove_proc_entry("bcm/ksync", NULL); + + /* UnRegister BCM-KNET HW Timestamp Callback Functions */ + bkn_hw_tstamp_enable_cb_unregister(bksync_ptp_hw_tstamp_enable); + bkn_hw_tstamp_disable_cb_unregister(bksync_ptp_hw_tstamp_disable); + bkn_hw_tstamp_tx_time_get_cb_unregister(bksync_ptp_hw_tstamp_tx_time_get); + bkn_hw_tstamp_tx_meta_get_cb_unregister(bksync_ptp_hw_tstamp_tx_meta_get); + bkn_hw_tstamp_rx_time_upscale_cb_unregister(bksync_ptp_hw_tstamp_rx_time_upscale); + bkn_hw_tstamp_ptp_clock_index_cb_unregister(bksync_ptp_hw_tstamp_ptp_clock_index_get); + bkn_hw_tstamp_ioctl_cmd_cb_unregister(bksync_ioctl_cmd_handler); + + if (module_initialized) { + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_10r(CMIC_CMC_BASE), 0); + DEV_WRITE32(ptp_priv, CMIC_CMC_SCHAN_MESSAGE_11r(CMIC_CMC_BASE), 0); + } + /* Deinitialize the PTP */ + bksync_ptp_deinit(&(ptp_priv->ptp_caps)); + module_initialized = 0; + + if (ptp_priv->port_stats != NULL) { + kfree((void *)ptp_priv->port_stats); + ptp_priv->port_stats = NULL; + } + if (ptp_priv->shared_addr != NULL) { + if (HOSTCMD_USE_REGS) { + kfree((void *)ptp_priv->shared_addr); + } else { + DMA_FREE_COHERENT(ptp_priv->dma_dev, ptp_priv->dma_mem_size, + (void *)ptp_priv->shared_addr, (dma_addr_t)ptp_priv->dma_mem); + } + ptp_priv->shared_addr = NULL; + DBG_ERR(("Free R5 memory\n")); + } + + /* Unregister the bcm ptp clock driver */ + ptp_clock_unregister(ptp_priv->ptp_clock); + + /* Free Memory */ + kfree(ptp_priv); + + return 0; +} +#endif + + +/* + * Generic module functions + */ + +/* + * Function: _pprint + * + * Purpose: + * Print proc filesystem information. + * Parameters: + * None + * Returns: + * Always 0 + */ + static int +_pprint(void) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,17,0) + /* put some goodies here */ + pprintf("Broadcom BCM PTP Hardware Clock Module\n"); +#else + pprintf("Broadcom BCM PTP Hardware Clock Module not supported\n"); +#endif + return 0; +} + +/* + * Function: _init + * + * Purpose: + * Module initialization. + * Attached SOC all devices and optionally initializes these. + * Parameters: + * None + * Returns: + * 0 on success, otherwise -1 + */ + static int +_init(void) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,17,0) + bksync_ptp_register(); + return 0; +#else + return -1; +#endif +} + +/* + * Function: _cleanup + * + * Purpose: + * Module cleanup function + * Parameters: + * None + * Returns: + * Always 0 + */ + static int +_cleanup(void) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,17,0) + mutex_destroy(&(ptp_priv->ptp_lock)); + mutex_destroy(&(ptp_priv->ptp_pair_lock)); + bksync_ptp_remove(); + return 0; +#else + return -1; +#endif +} + +static gmodule_t _gmodule = { +name: MODULE_NAME, + major: MODULE_MAJOR, + init: _init, + cleanup: _cleanup, + pprint: _pprint, + ioctl: NULL, + open: NULL, + close: NULL, +}; + + gmodule_t* +gmodule_get(void) +{ + EXPORT_NO_SYMBOLS; + return &_gmodule; +} diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h index 477c037a0c43..df8874fb1f70 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h @@ -47,6 +47,8 @@ typedef struct { uint32 filter_user_data; uint16 dcb_type; int port; + uint64_t ts; + uint32 hwts; } knet_skb_cb_t; #define KNET_SKB_CB(_skb) ((knet_skb_cb_t *)_skb->cb) @@ -59,19 +61,22 @@ typedef int int chan, kcom_filter_t *filter); typedef int -(*knet_hw_tstamp_enable_cb_f)(int dev_no, int port); +(*knet_hw_tstamp_enable_cb_f)(int dev_no, int phys_port, int tx_type); typedef int -(*knet_hw_tstamp_tx_time_get_cb_f)(int dev_no, int port, uint8_t *pkt, uint64_t *ts); +(*knet_hw_tstamp_tx_time_get_cb_f)(int dev_no, int phys_port, uint8_t *pkt, uint64_t *ts); typedef int -(*knet_hw_tstamp_tx_meta_get_cb_f)(int dev_no, struct sk_buff *skb, uint32_t **md); +(*knet_hw_tstamp_tx_meta_get_cb_f)(int dev_no, int hwts, int hdrlen, struct sk_buff *skb, uint64_t *ts, uint32_t **md); typedef int (*knet_hw_tstamp_ptp_clock_index_cb_f)(int dev_no); typedef int -(*knet_hw_tstamp_rx_time_upscale_cb_f)(int dev_no, uint64_t *ts); +(*knet_hw_tstamp_rx_time_upscale_cb_f)(int dev_no, int phys_port, struct sk_buff *skb, uint32_t *meta, uint64_t *ts); + +typedef int +(*knet_hw_tstamp_ioctl_cmd_cb_f)(kcom_msg_clock_cmd_t *kmsg, int len, int dcb_type); extern int bkn_rx_skb_cb_register(knet_skb_cb_f rx_cb); @@ -127,6 +132,12 @@ bkn_hw_tstamp_rx_time_upscale_cb_register(knet_hw_tstamp_rx_time_upscale_cb_f hw extern int bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb); +extern int +bkn_hw_tstamp_ioctl_cmd_cb_register(knet_hw_tstamp_ioctl_cmd_cb_f hw_tstamp_ioctl_cmd_cb); + +extern int +bkn_hw_tstamp_ioctl_cmd_cb_unregister(knet_hw_tstamp_ioctl_cmd_cb_f hw_tstamp_ioctl_cmd_cb); + typedef struct { uint8 cmic_type; uint8 dcb_type; @@ -153,6 +164,6 @@ bkn_netif_destroy_cb_register(knet_netif_cb_f netif_cb); extern int bkn_netif_destroy_cb_unregister(knet_netif_cb_f netif_cb); -#endif /* __KERNEL__ */ +#endif #endif /* __LINUX_BCM_KNET_H__ */ diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h index a48cb540adaf..56d641c9c87c 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h @@ -38,6 +38,11 @@ #include #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +#if defined(INCLUDE_KNET) && LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0) +#ifdef CONFIG_NF_CONNTRACK_MODULE +#include +#endif +#endif #include #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile index 2a167bb9e811..3de3e07080c4 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile @@ -36,6 +36,7 @@ KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko build: $(MODULE) $(KMODULE) endif +KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers ifeq ($(BUILD_PSAMPLE),1) KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../psample/kernel_module/Module.symvers endif diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c index 89d1087212c7..1626d33c1c5d 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c @@ -1,15 +1,15 @@ /* * Copyright 2017-2019 Broadcom - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation (the "GPL"). - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 (GPLv2) for more details. - * + * * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. */ @@ -59,6 +59,26 @@ LKM_MOD_PARAM(debug, "i", int, 0); MODULE_PARM_DESC(debug, "Debug level (default 0)"); +static int tpid=0x8100; +LKM_MOD_PARAM(tpid, "i", int, 0); +MODULE_PARM_DESC(debug, +"Tag Protocol Identifier (TPID) indicates the frame type (default 0x8100)"); + +static int pri=0; +LKM_MOD_PARAM(pri, "i", int, 0); +MODULE_PARM_DESC(pri, +"Priority (PRI) indicates the frame priority (default 0)"); + +static int cfi=0; +LKM_MOD_PARAM(cfi, "i", int, 0); +MODULE_PARM_DESC(cfi, +"Canonical Format Indicator (CFI) indicates whether a MAC address is encapsulated in canonical format over different transmission media (default 0)"); + +static int vid=0; +LKM_MOD_PARAM(vid, "i", int, 0); +MODULE_PARM_DESC(vid, +"VLAN ID (VID) indicates the VLAN to which a frame belongs (default 0)"); + /* Module Information */ #define MODULE_MAJOR 121 #define MODULE_NAME "linux-knet-cb" @@ -67,8 +87,8 @@ MODULE_PARM_DESC(debug, #define KNET_CB_DEBUG /* These below need to match incoming enum values */ -#define FILTER_TAG_STRIP 0 -#define FILTER_TAG_KEEP 1 +#define FILTER_TAG_STRIP 0 +#define FILTER_TAG_KEEP 1 #define FILTER_TAG_ORIGINAL 2 /* Maintain tag strip statistics */ @@ -105,6 +125,31 @@ strip_vlan_tag(struct sk_buff *skb) } } +/* Add VLAN tag to untagged packet */ +static void +add_vlan_tag(struct sk_buff *skb, u32 forward_domain) +{ + u32 vlan = 0; + uint16_t vlan_proto = (uint16_t) ((skb->data[12] << 8) | skb->data[13]); + + if ((vlan_proto != 0x8100) && (vlan_proto != 0x88a8) && (vlan_proto != 0x9100)) { + /* If vid is specified, use configued vid as VLAN ID, or, use forward_domain as vid */ + vlan = vid ? vid: forward_domain; + + skb_push(skb, 4); /* Add 4 bytes from start of buffer */ + /* Move first 12 bytes of packet forward by 4 */ + ((u32 *) skb->data)[0] = ((u32 *) skb->data)[1]; + ((u32 *) skb->data)[1] = ((u32 *) skb->data)[2]; + ((u32 *) skb->data)[2] = ((u32 *) skb->data)[3]; + + /* Set VLAN tag */ + skb->data[12] = (tpid >> 8) & 0xff; + skb->data[13] = tpid & 0xff; + skb->data[14] = (((pri & 0x7) << 5) | ((cfi & 0x1) << 4) | ((vlan >> 8) & 0xf)) & 0xff; + skb->data[15] = vlan & 0xff; + } +} + /* * Location of tagging status in select DCB types found below: * @@ -119,6 +164,7 @@ strip_vlan_tag(struct sk_buff *skb) * 1 = Single inner-tag * 2 = Single outer-tag * 3 = Double tagged. + * 4 = Dedicated for Dune device, packets are received with original tag status. * -1 = Unsupported DCB type */ static int @@ -159,6 +205,11 @@ get_tag_status(int dcb_type, void *meta) tag_status = tag_map[(dcb[9] >> 13) & 0x3]; } break; + case 28: + case 39: + tag_status = 4; + break; + break; default: tag_status = -1; break; @@ -188,12 +239,20 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) if (debug & 0x1) { gprintk("%s Enter; netif Flags: %08X filter_flags %08X \n", __func__, netif_flags, filter_flags); - } + } #endif + /* Get DCB type for this packet, passed by KNET driver */ + dcb_type = KNET_SKB_CB(skb)->dcb_type; /* KNET implements this already */ if (filter_flags == FILTER_TAG_KEEP) -{ + { + if (dcb_type ==28 || dcb_type == 39) + { + uint32 *meta_buffer = (uint32 *)meta; + uint32 forward_domain = meta_buffer[1] & 0xffff; + add_vlan_tag(skb, forward_domain); + } strip_stats.skipped++; return skb; } @@ -205,18 +264,16 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) { strip_tag = 1; } - /* Get DCB type for this packet, passed by KNET driver */ - dcb_type = KNET_SKB_CB(skb)->dcb_type; + + /* Get tag status from DCB */ tag_status = get_tag_status(dcb_type, meta); - #ifdef KNET_CB_DEBUG if (debug & 0x1) { gprintk("%s; DCB Type: %d; tag status: %d\n", __func__, dcb_type, tag_status); } #endif - if (tag_status < 0) { /* Unsupported DCB type */ return skb; @@ -231,12 +288,13 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) strip_tag = 1; } } + strip_stats.checked++; if (strip_tag) { #ifdef KNET_CB_DEBUG if (debug & 0x1) { - gprintk("%s; Stripping VLAN\n", __func__); + gprintk("%s; Stripping VLAN tag\n", __func__); } #endif strip_stats.stripped++; @@ -245,10 +303,11 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) #ifdef KNET_CB_DEBUG else { if (debug & 0x1) { - gprintk("%s; Preserve VLAN\n", __func__); + gprintk("%s; Keeping VLAN tag\n", __func__); } } #endif + return skb; } @@ -263,7 +322,7 @@ strip_tag_tx_cb(struct sk_buff *skb, int dev_no, void *meta) /* Filter callback not used */ static int strip_tag_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta, - int chan, kcom_filter_t *kf) + int chan, kcom_filter_t *kf) { /* Pass through for now */ return 0; @@ -287,7 +346,7 @@ knet_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev) { int retv = 0; #ifdef PSAMPLE_SUPPORT - retv = psample_netif_create_cb(unit, netif, dev); + retv = psample_netif_create_cb(unit, netif, dev); #endif return retv; } @@ -297,7 +356,7 @@ knet_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) { int retv = 0; #ifdef PSAMPLE_SUPPORT - retv = psample_netif_destroy_cb(unit, netif, dev); + retv = psample_netif_destroy_cb(unit, netif, dev); #endif return retv; } @@ -306,10 +365,9 @@ knet_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) * Get statistics. * % cat /proc/linux-knet-cb */ - static int _pprint(void) -{ +{ pprintf("Broadcom Linux KNET Call-Back: Untagged VLAN Stripper\n"); pprintf(" %lu stripped packets\n", strip_stats.stripped); pprintf(" %lu packets checked\n", strip_stats.checked); @@ -322,7 +380,9 @@ static int _cleanup(void) { bkn_rx_skb_cb_unregister(strip_tag_rx_cb); - /* strip_tag_tx_cb is currently a no-op, so no need to unregister */ + /* strip_tag_tx_cb is currently a noop, so + * no need to unregister. + */ if (0) { bkn_tx_skb_cb_unregister(strip_tag_tx_cb); @@ -336,14 +396,15 @@ _cleanup(void) psample_cleanup(); #endif return 0; -} +} static int _init(void) { - bkn_rx_skb_cb_register(strip_tag_rx_cb); - /* strip_tag_tx_cb is currently a no-op, so no need to register */ + /* strip_tag_tx_cb is currently a noop, so + * no need to register. + */ if (0) { bkn_tx_skb_cb_register(strip_tag_tx_cb); @@ -352,23 +413,24 @@ _init(void) #ifdef PSAMPLE_SUPPORT psample_init(); #endif - + bkn_filter_cb_register(knet_filter_cb); bkn_netif_create_cb_register(knet_netif_create_cb); bkn_netif_destroy_cb_register(knet_netif_destroy_cb); + return 0; } static gmodule_t _gmodule = { - name: MODULE_NAME, - major: MODULE_MAJOR, + name: MODULE_NAME, + major: MODULE_MAJOR, init: _init, - cleanup: _cleanup, - pprint: _pprint, + cleanup: _cleanup, + pprint: _pprint, ioctl: NULL, - open: NULL, - close: NULL, -}; + open: NULL, + close: NULL, +}; gmodule_t* gmodule_get(void) diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c index ef6fc102ce78..e1a6086a52ae 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c @@ -64,10 +64,24 @@ extern int debug; #define SOC_HIGIG_SRCPORT(x) ((x[1] >> 16) & 0x1f) #define SOC_HIGIG2_SOP (0xfb) //0xfc - TODO: how can we differentiate between Higig and higig2? #define SOC_HIGIG2_START(x) ((x[0] >> 24) & 0xff) +#define SOC_HIGIG2_IS_MC(x) ((x[0] >> 20) & 0x1) #define SOC_HIGIG2_DSTPORT(x) ((x[0] >> 0) & 0xff) #define SOC_HIGIG2_SRCPORT(x) ((x[1] >> 16) & 0xff) #define SOC_DCB32_HG_OFFSET (6) +/* sFlow v5 datagram dst ifindex field type + * dst ifindex encoding bits [31:30] + */ +#define DSTPORT_TYPE_DISCARD 1 +#define DSTPORT_TYPE_MC 2 + +#define DSTPORT_TYPE_OFFSET 30 +#define DSTPORT_TYPE_MASK 0x3 +#define DSTPORT_TYPE_CLR(_dst) (_dst &= ~(DSTPORT_TYPE_MASK << DSTPORT_TYPE_OFFSET)) +#define DSTPORT_TYPE_SET(_dst,_type) (_dst |= ((_type & DSTPORT_TYPE_MASK) << DSTPORT_TYPE_OFFSET)) +#define DSTPORT_TYPE_GET(_dst) ((_dst >> DSTPORT_TYPE_OFFSET) & DSTPORT_TYPE_MASK) +#define DSTPORT_GET(_dst) (_dst & ~(DSTPORT_TYPE_MASK << DSTPORT_TYPE_OFFSET)) + #define FCS_SZ 4 #define PSAMPLE_NLA_PADDING 4 @@ -78,17 +92,25 @@ LKM_MOD_PARAM(psample_size, "i", int, 0); MODULE_PARM_DESC(psample_size, "psample pkt size (default 128 bytes)"); +#define PSAMPLE_QLEN_DFLT 1024 +static int psample_qlen = PSAMPLE_QLEN_DFLT; +LKM_MOD_PARAM(psample_qlen, "i", int, 0); +MODULE_PARM_DESC(psample_qlen, +"psample queue length (default 1024 buffers)"); + /* driver proc entry root */ static struct proc_dir_entry *psample_proc_root = NULL; +static struct proc_dir_entry *knet_cb_proc_root = NULL; /* psample general info */ typedef struct { struct list_head netif_list; + int netif_count; knet_hw_info_t hw; struct net *netns; spinlock_t lock; } psample_info_t; -static psample_info_t g_psample_info = {{0}}; +static psample_info_t g_psample_info = {0}; /* Maintain sampled pkt statistics */ typedef struct psample_stats_s { @@ -96,9 +118,13 @@ typedef struct psample_stats_s { unsigned long pkts_f_psample_mod; unsigned long pkts_f_handled; unsigned long pkts_f_pass_through; + unsigned long pkts_f_dst_mc; + unsigned long pkts_c_qlen_cur; + unsigned long pkts_c_qlen_hi; + unsigned long pkts_d_qlen_max; + unsigned long pkts_d_no_mem; unsigned long pkts_d_no_group; unsigned long pkts_d_sampling_disabled; - unsigned long pkts_d_no_skb; unsigned long pkts_d_not_ready; unsigned long pkts_d_metadata; unsigned long pkts_d_meta_srcport; @@ -114,6 +140,19 @@ typedef struct psample_meta_s { int sample_rate; } psample_meta_t; +typedef struct psample_pkt_s { + struct list_head list; + struct psample_group *group; + psample_meta_t meta; + struct sk_buff *skb; +} psample_pkt_t; + +typedef struct psample_work_s { + struct list_head pkt_list; + struct work_struct wq; + spinlock_t lock; +} psample_work_t; +static psample_work_t g_psample_work = {0}; static psample_netif_t* psample_netif_lookup_by_port(int unit, int port) @@ -170,7 +209,6 @@ psample_meta_srcport_get(uint8_t *pkt, void *pkt_meta) case 26: /* TD2 */ case 23: /* HX4 */ metadata += SOC_DCB32_HG_OFFSET; - break; default: break; } @@ -205,16 +243,23 @@ psample_meta_dstport_get(uint8_t *pkt, void *pkt_meta) case 32: /* TH1/TH2 */ case 26: /* TD2 */ case 23: /* HX4 */ - metadata += SOC_DCB32_HG_OFFSET; - break; default: + metadata += SOC_DCB32_HG_OFFSET; break; } if (SOC_HIGIG2_START(metadata) == SOC_HIGIG2_SOP) { + if (SOC_HIGIG2_IS_MC(metadata)) + { + DSTPORT_TYPE_CLR(dstport); + DSTPORT_TYPE_SET(dstport, DSTPORT_TYPE_MC); + } + else + { dstport = SOC_HIGIG2_DSTPORT(metadata); } + } else if (SOC_HIGIG_START(metadata) == SOC_HIGIG_SOP) { dstport = SOC_HIGIG_DSTPORT(metadata); @@ -273,10 +318,10 @@ psample_meta_sample_reason(uint8_t *pkt, void *pkt_meta) static int psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_meta) { - int srcport, dstport; + int srcport, dstport, dstport_type; int src_ifindex = 0; int dst_ifindex = 0; - int sample_rate = PSAMPLE_RATE_DFLT; + int sample_rate = 1; int sample_size = PSAMPLE_SIZE_DFLT; psample_netif_t *psample_netif = NULL; @@ -313,8 +358,16 @@ psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_m } } - /* find dst port netif (no need to lookup CPU port) */ - if (dstport != 0) { + dstport_type = DSTPORT_TYPE_GET(dstport); + dstport = DSTPORT_GET(dstport); + + /* set sFlow dst type for MC pkts */ + if (dstport_type == DSTPORT_TYPE_MC) { + DSTPORT_TYPE_SET(dst_ifindex, DSTPORT_TYPE_MC); + g_psample_stats.pkts_f_dst_mc++; + + /* find dst port netif for UC pkts (no need to lookup CPU port) */ + } else if (dstport != 0) { if ((psample_netif = psample_netif_lookup_by_port(unit, dstport))) { dst_ifindex = psample_netif->dev->ifindex; } else { @@ -323,7 +376,7 @@ psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_m } } - PSAMPLE_CB_DBG_PRINT("%s: srcport %d, dstport %d, src_ifindex %d, dst_ifindex %d, trunc_size %d, sample_rate %d\n", + PSAMPLE_CB_DBG_PRINT("%s: srcport %d, dstport %d, src_ifindex 0x%x, dst_ifindex 0x%x, trunc_size %d, sample_rate %d\n", __func__, srcport, dstport, src_ifindex, dst_ifindex, sample_size, sample_rate); sflow_meta->src_ifindex = src_ifindex; @@ -334,13 +387,51 @@ psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_m return (0); } +static void +psample_task(struct work_struct *work) +{ + psample_work_t *psample_work = container_of(work, psample_work_t, wq); + unsigned long flags; + struct list_head *list_ptr, *list_next; + psample_pkt_t *pkt; + + spin_lock_irqsave(&psample_work->lock, flags); + list_for_each_safe(list_ptr, list_next, &psample_work->pkt_list) { + /* dequeue pkt from list */ + pkt = list_entry(list_ptr, psample_pkt_t, list); + list_del(list_ptr); + g_psample_stats.pkts_c_qlen_cur--; + spin_unlock_irqrestore(&psample_work->lock, flags); + + /* send to psample */ + if (pkt) { + PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx 0x%x, dst_ifdx 0x%x, sample_rate %d\n", + __func__, pkt->group->group_num, + pkt->meta.trunc_size, pkt->meta.src_ifindex, + pkt->meta.dst_ifindex, pkt->meta.sample_rate); + + psample_sample_packet(pkt->group, + pkt->skb, + pkt->meta.trunc_size, + pkt->meta.src_ifindex, + pkt->meta.dst_ifindex, + pkt->meta.sample_rate); + g_psample_stats.pkts_f_psample_mod++; + + dev_kfree_skb_any(pkt->skb); + kfree(pkt); + } + spin_lock_irqsave(&psample_work->lock, flags); + } + spin_unlock_irqrestore(&psample_work->lock, flags); +} + int psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta, int chan, kcom_filter_t *kf) { struct psample_group *group; psample_meta_t meta; - struct sk_buff skb; int rv = 0; static int info_get = 0; @@ -386,24 +477,51 @@ psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta, meta.trunc_size = size - PSAMPLE_NLA_PADDING; } - PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx %d, dst_ifdx %d, sample_rate %d\n", + PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx 0x%x, dst_ifdx 0x%x, sample_rate %d\n", __func__, group->group_num, meta.trunc_size, meta.src_ifindex, meta.dst_ifindex, meta.sample_rate); /* drop if configured sample rate is 0 */ if (meta.sample_rate > 0) { + unsigned long flags; + psample_pkt_t *psample_pkt; + struct sk_buff *skb; + + if (g_psample_stats.pkts_c_qlen_cur >= psample_qlen) { + gprintk("%s: tail drop due to max qlen %d reached\n", __func__, psample_qlen); + g_psample_stats.pkts_d_qlen_max++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + + if ((psample_pkt = kmalloc(sizeof(psample_pkt_t), GFP_ATOMIC)) == NULL) { + gprintk("%s: failed to alloc psample mem for pkt\n", __func__); + g_psample_stats.pkts_d_no_mem++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + memcpy(&psample_pkt->meta, &meta, sizeof(psample_meta_t)); + psample_pkt->group = group; + + if ((skb = dev_alloc_skb(meta.trunc_size)) == NULL) { + gprintk("%s: failed to alloc psample mem for pkt skb\n", __func__); + g_psample_stats.pkts_d_no_mem++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + /* setup skb to point to pkt */ - memset(&skb, 0, sizeof(struct sk_buff)); - skb.len = size; - skb.data = pkt; - - psample_sample_packet(group, - &skb, - meta.trunc_size, - meta.src_ifindex, - meta.dst_ifindex, - meta.sample_rate); - - g_psample_stats.pkts_f_psample_mod++; + memcpy(skb->data, pkt, meta.trunc_size); + skb_put(skb, meta.trunc_size); + skb->len = meta.trunc_size; + psample_pkt->skb = skb; + + spin_lock_irqsave(&g_psample_work.lock, flags); + list_add_tail(&psample_pkt->list, &g_psample_work.pkt_list); + + g_psample_stats.pkts_c_qlen_cur++; + if (g_psample_stats.pkts_c_qlen_cur > g_psample_stats.pkts_c_qlen_hi) { + g_psample_stats.pkts_c_qlen_hi = g_psample_stats.pkts_c_qlen_cur; + } + + schedule_work(&g_psample_work.wq); + spin_unlock_irqrestore(&g_psample_work.lock, flags); } else { g_psample_stats.pkts_d_sampling_disabled++; } @@ -427,7 +545,7 @@ psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev) psample_netif_t *psample_netif, *lpsample_netif; unsigned long flags; - if ((psample_netif = kmalloc(sizeof(psample_netif_t), GFP_KERNEL)) == NULL) { + if ((psample_netif = kmalloc(sizeof(psample_netif_t), GFP_ATOMIC)) == NULL) { gprintk("%s: failed to alloc psample mem for netif '%s'\n", __func__, dev->name); return (-1); @@ -449,6 +567,7 @@ psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev) lpsample_netif = (psample_netif_t*)list; if (netif->id < lpsample_netif->id) { found = 1; + g_psample_info.netif_count++; break; } } @@ -489,6 +608,7 @@ psample_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) list_del(&psample_netif->list); PSAMPLE_CB_DBG_PRINT("%s: removing psample netif '%s'\n", __func__, dev->name); kfree(psample_netif); + g_psample_info.netif_count--; break; } } @@ -702,6 +822,47 @@ struct file_operations psample_proc_size_file_ops = { release: single_release, }; +/* + * psample map Proc Read Entry + */ +static int +psample_proc_map_show(struct seq_file *m, void *v) +{ + struct list_head *list; + psample_netif_t *psample_netif; + unsigned long flags; + + seq_printf(m, " Interface logical port ifindex\n"); + seq_printf(m, "------------- ------------ -------\n"); + spin_lock_irqsave(&g_psample_info.lock, flags); + + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + seq_printf(m, " %-14s %-14d %d\n", + psample_netif->dev->name, + psample_netif->port, + psample_netif->dev->ifindex); + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return 0; +} + +static int +psample_proc_map_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_map_show, NULL); +} + +struct file_operations psample_proc_map_file_ops = { + owner: THIS_MODULE, + open: psample_proc_map_open, + read: seq_read, + llseek: seq_lseek, + write: NULL, + release: single_release, +}; + /* * psample debug Proc Read Entry */ @@ -715,6 +876,8 @@ psample_proc_debug_show(struct seq_file *m, void *v) seq_printf(m, " dcb_size: %d\n", g_psample_info.hw.dcb_size); seq_printf(m, " pkt_hdr_size: %d\n", g_psample_info.hw.pkt_hdr_size); seq_printf(m, " cdma_channels: %d\n", g_psample_info.hw.cdma_channels); + seq_printf(m, " netif_count: %d\n", g_psample_info.netif_count); + seq_printf(m, " queue length: %d\n", psample_qlen); return 0; } @@ -779,9 +942,13 @@ psample_proc_stats_show(struct seq_file *m, void *v) seq_printf(m, " pkts sent to psample module %10lu\n", g_psample_stats.pkts_f_psample_mod); seq_printf(m, " pkts handled by psample %10lu\n", g_psample_stats.pkts_f_handled); seq_printf(m, " pkts pass through %10lu\n", g_psample_stats.pkts_f_pass_through); + seq_printf(m, " pkts with mc destination %10lu\n", g_psample_stats.pkts_f_dst_mc); + seq_printf(m, " pkts current queue length %10lu\n", g_psample_stats.pkts_c_qlen_cur); + seq_printf(m, " pkts high queue length %10lu\n", g_psample_stats.pkts_c_qlen_hi); + seq_printf(m, " pkts drop max queue length %10lu\n", g_psample_stats.pkts_d_qlen_max); + seq_printf(m, " pkts drop no memory %10lu\n", g_psample_stats.pkts_d_no_mem); seq_printf(m, " pkts drop no psample group %10lu\n", g_psample_stats.pkts_d_no_group); seq_printf(m, " pkts drop sampling disabled %10lu\n", g_psample_stats.pkts_d_sampling_disabled); - seq_printf(m, " pkts drop no skb %10lu\n", g_psample_stats.pkts_d_no_skb); seq_printf(m, " pkts drop psample not ready %10lu\n", g_psample_stats.pkts_d_not_ready); seq_printf(m, " pkts drop metadata parse error %10lu\n", g_psample_stats.pkts_d_metadata); seq_printf(m, " pkts with invalid src port %10lu\n", g_psample_stats.pkts_d_meta_srcport); @@ -796,21 +963,46 @@ psample_proc_stats_open(struct inode * inode, struct file * file) return single_open(file, psample_proc_stats_show, NULL); } +/* + * psample stats Proc Write Entry + * + * Syntax: + * write any value to clear stats + */ +static ssize_t +psample_proc_stats_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + int qlen_cur = 0; + unsigned long flags; + + spin_lock_irqsave(&g_psample_work.lock, flags); + qlen_cur = g_psample_stats.pkts_c_qlen_cur; + memset(&g_psample_stats, 0, sizeof(psample_stats_t)); + g_psample_stats.pkts_c_qlen_cur = qlen_cur; + spin_unlock_irqrestore(&g_psample_work.lock, flags); + + return count; +} struct file_operations psample_proc_stats_file_ops = { owner: THIS_MODULE, open: psample_proc_stats_open, read: seq_read, llseek: seq_lseek, - write: NULL, + write: psample_proc_stats_write, release: single_release, }; int psample_cleanup(void) { + cancel_work_sync(&g_psample_work.wq); remove_proc_entry("stats", psample_proc_root); remove_proc_entry("rate", psample_proc_root); remove_proc_entry("size", psample_proc_root); remove_proc_entry("debug", psample_proc_root); + remove_proc_entry("map" , psample_proc_root); + remove_proc_entry("psample", knet_cb_proc_root); + remove_proc_entry("bcm/knet-cb", NULL); return 0; } @@ -822,7 +1014,7 @@ int psample_init(void) /* create procfs for psample */ snprintf(psample_procfs_path, PROCFS_MAX_PATH, "bcm/knet-cb"); - proc_mkdir(psample_procfs_path, NULL); + knet_cb_proc_root = proc_mkdir(psample_procfs_path, NULL); snprintf(psample_procfs_path, PROCFS_MAX_PATH, "%s/%s", psample_procfs_path, PSAMPLE_CB_NAME); psample_proc_root = proc_mkdir(psample_procfs_path, NULL); @@ -847,6 +1039,13 @@ int psample_init(void) return -1; } + /* create procfs for getting netdev mapping */ + PROC_CREATE(entry, "map", 0666, psample_proc_root, &psample_proc_map_file_ops); + if (entry == NULL) { + gprintk("%s: Unable to create procfs entry '/procfs/%s/map'\n", __func__, psample_procfs_path); + return -1; + } + /* create procfs for debug log */ PROC_CREATE(entry, "debug", 0666, psample_proc_root, &psample_proc_debug_file_ops); if (entry == NULL) { @@ -857,11 +1056,17 @@ int psample_init(void) /* clear data structs */ memset(&g_psample_stats, 0, sizeof(psample_stats_t)); memset(&g_psample_info, 0, sizeof(psample_info_t)); + memset(&g_psample_work, 0, sizeof(psample_work_t)); /* setup psample_info struct */ INIT_LIST_HEAD(&g_psample_info.netif_list); spin_lock_init(&g_psample_info.lock); + /* setup psample work queue */ + spin_lock_init(&g_psample_work.lock); + INIT_LIST_HEAD(&g_psample_work.pkt_list); + INIT_WORK(&g_psample_work.wq, psample_task); + /* get net namespace */ g_psample_info.netns = get_net_ns_by_pid(current->pid); if (!g_psample_info.netns) { @@ -871,5 +1076,6 @@ int psample_init(void) PSAMPLE_CB_DBG_PRINT("%s: current->pid %d, netns 0x%p, sample_size %d\n", __func__, current->pid, g_psample_info.netns, psample_size); + return 0; } diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c index e1d4e2353b09..1deccacc5edd 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c @@ -35,7 +35,7 @@ static const struct genl_multicast_group psample_nl_mcgrps[] = { [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME }, }; -static struct genl_family psample_nl_family __ro_after_init; +static struct genl_family psample_nl_family; static int psample_group_nl_fill(struct sk_buff *msg, struct psample_group *group, @@ -106,7 +106,7 @@ static const struct genl_ops psample_nl_ops[] = { } }; -static struct genl_family psample_nl_family __ro_after_init = { +static struct genl_family psample_nl_family = { .name = PSAMPLE_GENL_NAME, .version = PSAMPLE_GENL_VERSION, .maxattr = PSAMPLE_ATTR_MAX, diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile index 20d83735fcce..f95593a383ce 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile @@ -65,7 +65,7 @@ ifeq (,$(kernel_version)) kernel_version=2_4 endif -ifeq ($(kernel_version),2_6) +ifneq ($(kernel_version),2_4) KOBJ=ko else KOBJ=o @@ -94,6 +94,9 @@ BCM_KNET=$(DEST_DIR)/$(BCM_KNET_LOCAL) PSAMPLE_LOCAL := psample.$(KOBJ) PSAMPLE := $(DEST_DIR)/$(PSAMPLE_LOCAL) +BCM_LPTP_LOCAL :=linux-bcm-ptp-clock.$(KOBJ) +BCM_LPTP=$(DEST_DIR)/$(BCM_LPTP_LOCAL) + ifeq (,$(findstring DELIVER,$(MAKECMDGOALS))) .DEFAULT_GOAL := all all_targets := kernel_modules $(KERNEL_BDE) $(USER_BDE) @@ -110,6 +113,11 @@ endif ifndef BUILD_KNET BUILD_KNET = 1 endif +# Remove this when LinuxPTP support becomes optional. +ifndef BUILD_LPTP +BUILD_LPTP = 1 +BUILD_KNETSYNC = 1 +endif ifeq ($(BUILD_KNET),1) # Kernel network support @@ -132,19 +140,35 @@ endif ifdef BUILD_PSAMPLE all_targets += $(PSAMPLE) ADD_TO_CFLAGS += -DPSAMPLE_SUPPORT + + +# KnetSync support +ifdef BUILD_KNETSYNC + +KERNEL_TARGETS += $(BCM_PTP_CLOCK) +LOCAL_KERNEL_TARGETS += $(patsubst %,$(realpath ..)/$(platform)/%,$(BCM_PTP_CLOCK_LOCAL)) + +endif # BUILD_KNETSYNC + ifeq ($(NO_LOCAL_TARGETS),) LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(PSAMPLE_LOCAL)) all_targets +=$(LOCAL_TARGETS) endif endif +ifdef BUILD_LPTP +all_targets += $(BCM_LPTP) + +ifeq ($(NO_LOCAL_TARGETS),) +LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(BCM_LPTP_LOCAL)) +all_targets +=$(LOCAL_TARGETS) +endif +endif + ADD_TO_CFLAGS += -I$(SDK)/systems/linux/kernel/modules/include COND_KNET_LIBS = libuser.$(libext) endif -#SAI_FIXUP -.NOTPARALLEL: - all: $(BLDDIR)/.tree $(all_targets) ifeq ($(NO_LOCAL_TARGETS),) @@ -161,24 +185,33 @@ ADD_TO_CFLAGS += -I$(SDK)/systems/bde/linux/include ADD_TO_CFLAGS += -DPROXY_SUPPORT=0 CFLAGS += $(ADD_TO_CFLAGS) + #SAI_FIXUP CFLAGS:=$(filter-out -fPIC, $(CFLAGS)) +# KnetSync Support +ifdef BUILD_KNETSYNC +knetsync_subdirs = bcm-ptp-clock +endif # BUILD_KNETSYNC kernel_modules: $(MAKE) -C $(SDK)/systems/bde/linux/kernel kernel_version=$(kernel_version) $(MAKE) -C $(SDK)/systems/bde/linux/user/kernel kernel_version=$(kernel_version) ifeq ($(BUILD_KNET),1) - $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="shared bcm-knet" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" ifdef BUILD_PSAMPLE - $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="psample" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" endif ifdef BUILD_KNET_CB - $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="knet-cb" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" endif +ifdef BUILD_LPTP + $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + subdirs="bcm-ptp-clock" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" +endif endif $(KERNEL_BDE): $(KERN_BLDROOT)/linux-kernel-bde.$(KOBJ) @@ -197,6 +230,8 @@ $(KNET_CB): $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ) $(PSAMPLE): $(KERN_BLDROOT)/psample.$(KOBJ) $(OBJCOPY) --strip-debug $< $@ +$(BCM_LPTP): $(KERN_BLDROOT)/linux-bcm-ptp-clock.$(KOBJ) + $(OBJCOPY) --strip-debug $< $@ ifeq ($(NO_LOCAL_TARGETS),) $(foreach targ,$(LOCAL_TARGETS),$(eval $(call LOCAL_TARGET_DEF,$(targ)))) @@ -206,10 +241,10 @@ clean:: $(MAKE) -C $(SDK)/systems/bde/linux/kernel $@ $(MAKE) -C $(SDK)/systems/bde/linux/user/kernel $@ $(MAKE) -C $(SDK)/systems/linux/kernel/modules \ - subdirs="shared bcm-knet knet-cb" \ + subdirs="shared bcm-knet knet-cb psample bcm-ptp-clock" \ override-target=linux-$(platform) $@ $(RM) $(KERNEL_BDE) $(USER_BDE) - $(RM) $(BCM_KNET) $(KNET_CB) + $(RM) $(BCM_KNET) $(KNET_CB) $(PSAMPLE) $(BCM_LPTP) $(RM) $(KERN_BLDROOT)/linux-kernel-bde.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-user-bde.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ) diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile new file mode 100644 index 000000000000..466faf02a515 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile @@ -0,0 +1,63 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# +# Optionally the following environment variables can be set to +# override the default build server configuration: +# +# TOOLS_DIR - path to build tools (if not in PATH already) +# CROSS_COMPILE - cross compile tools prefix +# LINUX_INCLUDE - path to Linux kernel include directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=4_19 +platform=gts +LINUX_MAKE_USER=1 +export LINKER_RELAX = 1 +export ADD_TO_CFLAGS +export BR_NO_CCACHE + + +include ${SDK}/make/Make.linux + diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/iproc-4_4/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/iproc-4_4/Makefile new file mode 100644 index 000000000000..e8405f5c2a0c --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/iproc-4_4/Makefile @@ -0,0 +1,59 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 1.7 Broadcom SDK $ +# $Copyright: (c) 2005 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=4_4 +platform=iproc-$(kernel_version) + +IPROC_BUILD=1 +export IPROC_BUILD +export BUILD_PLATFORM +export ARM_LINUX_VERSION + +LINUX_MAKE_USER=1 +export ADD_TO_CFLAGS +export BR_NO_CCACHE + +include ${SDK}/make/Make.linux diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile new file mode 100644 index 000000000000..778c85a03bed --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile @@ -0,0 +1,59 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 1.7 Broadcom SDK $ +# $Copyright: (c) 2005 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=4_14 +platform=iproc_64 + +IPROC_BUILD=1 +export IPROC_BUILD +export BUILD_PLATFORM +export ARM_LINUX_VERSION + +LINUX_MAKE_USER=1 +export ADD_TO_CFLAGS +export BR_NO_CCACHE + +include ${SDK}/make/Make.linux diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/slk/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/slk/Makefile new file mode 100644 index 000000000000..99d49d285145 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/slk/Makefile @@ -0,0 +1,60 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# +# Optionally the following environment variables can be set to +# override the default build server configuration: +# +# TOOLS_DIR - path to build tools (if not in PATH already) +# CROSS_COMPILE - cross compile tools prefix +# LINUX_INCLUDE - path to Linux kernel include directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=3_14 +platform=slk +LINUX_MAKE_USER=1 +export LINKER_RELAX = 1 + +include ${SDK}/make/Make.linux + diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile new file mode 100644 index 000000000000..13246d09e78f --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile @@ -0,0 +1,63 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 0.1 Broadcom SDK $ +# $Copyright: (c) 2015 Broadcom Corp. +# All Rights Reserved.$ + +# +# This make job requires the following environment variables to be set: +# +# SDK - path to StrataXGS SDK root directory +# +# Optionally the following environment variables can be set to +# override the default build server configuration: +# +# TOOLS_DIR - path to build tools (if not in PATH already) +# CROSS_COMPILE - cross compile tools prefix +# LINUX_INCLUDE - path to Linux kernel include directory +# + +SDK :=$(shell if [ -n "$$SDK" ] ; then\ + echo $$SDK;\ + else\ + cd $(dir $(lastword $(MAKEFILE_LIST))); while /usr/bin/test ! -e RELEASE ; do \ + dir=`cd ../;pwd`; \ + if [ "$$dir" = "/" ] ; then \ + echo Cannot find SDK in $(lastword $(MAKEFILE_LIST)) 1>&2; \ + exit 1; \ + fi ; \ + cd $$dir; \ + done ; \ + pwd; \ + fi) + +ifeq ($(SDK),) +$(error Please run this in a tree) +endif + +export SDK + +override kernel_version=4_19 +platform=xlr +LINUX_MAKE_USER=1 +export LINKER_RELAX = 1 +export ADD_TO_CFLAGS +export BR_NO_CCACHE + + +include ${SDK}/make/Make.linux + From 63c1afbc683f50562a750c2e1855dfdfe6d8ab59 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Tue, 6 Oct 2020 08:37:49 -0700 Subject: [PATCH 70/78] [bgpcfgd]: Extract classes into their own files. Run bgpcfgd as a module (#5535) 1. Rename app module to bgpcfgd 2. Extract classes from one file to the module --- src/sonic-bgpcfgd/.gitignore | 2 +- src/sonic-bgpcfgd/app/util.py | 22 - src/sonic-bgpcfgd/bgpcfgd | 923 ------------------ .../{app => bgpcfgd}/__init__.py | 0 src/sonic-bgpcfgd/bgpcfgd/__main__.py | 4 + src/sonic-bgpcfgd/{app => bgpcfgd}/config.py | 2 +- .../{app => bgpcfgd}/directory.py | 2 +- src/sonic-bgpcfgd/{app => bgpcfgd}/log.py | 0 src/sonic-bgpcfgd/bgpcfgd/main.py | 81 ++ src/sonic-bgpcfgd/{app => bgpcfgd}/manager.py | 2 +- .../managers_allow_list.py} | 8 +- src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py | 391 ++++++++ src/sonic-bgpcfgd/bgpcfgd/managers_db.py | 28 + src/sonic-bgpcfgd/bgpcfgd/managers_intf.py | 56 ++ src/sonic-bgpcfgd/bgpcfgd/managers_setsrc.py | 69 ++ src/sonic-bgpcfgd/bgpcfgd/runner.py | 65 ++ .../{app => bgpcfgd}/template.py | 0 src/sonic-bgpcfgd/bgpcfgd/utils.py | 55 ++ src/sonic-bgpcfgd/{app => bgpcfgd}/vars.py | 0 src/sonic-bgpcfgd/pytest.ini | 2 +- src/sonic-bgpcfgd/setup.py | 4 +- src/sonic-bgpcfgd/tests/test_allow_list.py | 25 +- .../tests/test_ipv6_nexthop_global.py | 2 +- src/sonic-bgpcfgd/tests/test_pfx_filter.py | 2 +- src/sonic-bgpcfgd/tests/test_sonic-cfggen.py | 2 +- src/sonic-bgpcfgd/tests/test_templates.py | 4 +- 26 files changed, 778 insertions(+), 973 deletions(-) delete mode 100644 src/sonic-bgpcfgd/app/util.py delete mode 100755 src/sonic-bgpcfgd/bgpcfgd rename src/sonic-bgpcfgd/{app => bgpcfgd}/__init__.py (100%) create mode 100644 src/sonic-bgpcfgd/bgpcfgd/__main__.py rename src/sonic-bgpcfgd/{app => bgpcfgd}/config.py (99%) rename src/sonic-bgpcfgd/{app => bgpcfgd}/directory.py (99%) rename src/sonic-bgpcfgd/{app => bgpcfgd}/log.py (100%) create mode 100644 src/sonic-bgpcfgd/bgpcfgd/main.py rename src/sonic-bgpcfgd/{app => bgpcfgd}/manager.py (98%) rename src/sonic-bgpcfgd/{app/allow_list.py => bgpcfgd/managers_allow_list.py} (99%) create mode 100644 src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py create mode 100644 src/sonic-bgpcfgd/bgpcfgd/managers_db.py create mode 100644 src/sonic-bgpcfgd/bgpcfgd/managers_intf.py create mode 100644 src/sonic-bgpcfgd/bgpcfgd/managers_setsrc.py create mode 100644 src/sonic-bgpcfgd/bgpcfgd/runner.py rename src/sonic-bgpcfgd/{app => bgpcfgd}/template.py (100%) create mode 100644 src/sonic-bgpcfgd/bgpcfgd/utils.py rename src/sonic-bgpcfgd/{app => bgpcfgd}/vars.py (100%) diff --git a/src/sonic-bgpcfgd/.gitignore b/src/sonic-bgpcfgd/.gitignore index 920a1b3ae499..797140c05c8d 100644 --- a/src/sonic-bgpcfgd/.gitignore +++ b/src/sonic-bgpcfgd/.gitignore @@ -2,7 +2,7 @@ build/ dist/ *.egg-info/ -app/*.pyc +bgpcfgd/*.pyc tests/*.pyc tests/__pycache__/ .idea diff --git a/src/sonic-bgpcfgd/app/util.py b/src/sonic-bgpcfgd/app/util.py deleted file mode 100644 index b25e651f1ec6..000000000000 --- a/src/sonic-bgpcfgd/app/util.py +++ /dev/null @@ -1,22 +0,0 @@ -import subprocess - -from .log import log_debug, log_err - - -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: - 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 \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd b/src/sonic-bgpcfgd/bgpcfgd deleted file mode 100755 index 419fd41fb4be..000000000000 --- a/src/sonic-bgpcfgd/bgpcfgd +++ /dev/null @@ -1,923 +0,0 @@ -#!/usr/bin/env python - -import sys -import datetime -import time -import syslog -import signal -import traceback -import os -import json -from collections import defaultdict - -import yaml -import jinja2 -import netaddr -from swsscommon import swsscommon - -from app.directory import Directory -from app.manager import Manager -from app.vars import g_debug -from app.log import log_debug, log_notice, log_info, log_warn, log_err, log_crit -from app.template import TemplateFabric -from app.config import ConfigMgr -from app.allow_list import BGPAllowListMgr -from app.util import run_command - -g_run = True - - -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) # 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 == '': - return True, self.data[slot] - d = self.data[slot] - for p in path.split("/"): - if p not in d: - return False, None - d = d[p] - return True, d - - 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, 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, 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(db, table, path): - for handler in self.notify[slot][path]: - handler() - - 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 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: - log_err("Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) - else: - log_err("Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) - - 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: - log_err("Directory: Can't remove slot '%s'. The slot doesn't exist" % 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 db, table, path in deps: - res = res and self.path_exist(db, table, path) - return res - - def subscribe(self, deps, handler): - """ - 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): - """ 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 = [] - 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): # all required dependencies are set in the Directory? - res = self.set_handler(key, data) - 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: - 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 = [] - for key, data in self.set_queue: - res = self.set_handler(key, data) - if not res: - new_queue.append((key, data)) - self.set_queue = new_queue - - def set_handler(self, key, data): - """ Placeholder for 'SET' command """ - log_err("set_handler() wasn't implemented for %s" % self.__class__.__name__) - - def del_handler(self, key): - """ Placeholder for 'DEL' command """ - log_err("del_handler wasn't implemented for %s" % self.__class__.__name__) - - -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, - [], - db, - table, - ) - - def set_handler(self, 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): - """ Implementation of 'DEL' command for this class """ - self.directory.remove(self.db_name, self.table_name, key) - - -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, - [], - db, - table, - ) - - def set_handler(self, 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): - """ 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) - - -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") - - 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 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 - - return self.update_entity(policy, "Routing policy for peer '%s'" % name) - - 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 - - if kwargs['vrf'] == 'default': - cmd = ('router bgp %s\n' % kwargs['bgp_asn']) + pg - else: - cmd = ('router bgp %s vrf %s\n' % (kwargs['bgp_asn'], kwargs['vrf'])) + pg - - return self.update_entity(cmd, "Peer-group for peer '%s'" % name) - - 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 - - -class BGPPeerMgrBase(Manager): - """ Manager of BGP peers """ - def __init__(self, common_objs, db_name, table_name, peer_type, check_neig_meta): - """ - 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 - - 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", ""), - ] - - if check_neig_meta: - self.check_neig_meta = 'bgp' in self.constants \ - and 'use_neighbors_meta' in self.constants['bgp'] \ - and self.constants['bgp']['use_neighbors_meta'] - else: - self.check_neig_meta = False - - 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): - """ - 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) - peer_key = (vrf, nbr) - if peer_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. - data["local_addr"] = str(netaddr.IPNetwork(str(data["local_addr"])).ip) - 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 - 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: - 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): - """ - 'DEL' handler for the BGP PEER tables - :param key: key of the neighbor - """ - vrf, nbr = self.split_key(key) - peer_key = (vrf, nbr) - if peer_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(peer_key) - else: - log_err("Peer '(%s|%s)' hasn't been removed" % (vrf, nbr)) - - 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): - """ - 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 = 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 = 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"]] - else: - return None - - @staticmethod - def get_vnet(interface): - """ - 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"]: - return interface["vnet_name"] - 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)) - - @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))) - - return peers - - -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 prefix: '%s'" % ip_addr_w_mask) - return True - ip_addr = ip_addr_w_mask[:slash_pos] - try: - if TemplateFabric.is_ipv4(ip_addr): - if 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="") - else: - log_warn("Update command is not supported for set src templates. current ip='%s'. new ip='%s'" % (self.lo_ipv4, ip_addr)) - return True - elif TemplateFabric.is_ipv6(ip_addr): - if 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_warn("Update command is not supported for set src templates. current ip='%s'. new ip='%s'" % (self.lo_ipv6, ip_addr)) - return True - 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 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: - 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 - 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) # FIXME: , Loader=yaml.FullLoader) - 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 = [ - # 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", True), - BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", False), - BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), - # AllowList Managers - BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), - ] - runner = Runner() - for mgr in managers: - runner.add_manager(mgr) - runner.run() - - -def signal_handler(_, __): # signal_handler(signum, frame) - """ signal handler """ - global g_run - g_run = False - - -if __name__ == '__main__': - rc = 0 - try: - syslog.openlog('bgpcfgd') - signal.signal(signal.SIGTERM, signal_handler) - signal.signal(signal.SIGINT, signal_handler) - main() - except KeyboardInterrupt: - log_notice("Keyboard interrupt") - except RuntimeError as exc: - log_crit(str(exc)) - rc = -2 - 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: - sys.exit(rc) - except SystemExit: - os._exit(rc) diff --git a/src/sonic-bgpcfgd/app/__init__.py b/src/sonic-bgpcfgd/bgpcfgd/__init__.py similarity index 100% rename from src/sonic-bgpcfgd/app/__init__.py rename to src/sonic-bgpcfgd/bgpcfgd/__init__.py diff --git a/src/sonic-bgpcfgd/bgpcfgd/__main__.py b/src/sonic-bgpcfgd/bgpcfgd/__main__.py new file mode 100644 index 000000000000..413eeee346d0 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/__main__.py @@ -0,0 +1,4 @@ +from .main import main + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/config.py b/src/sonic-bgpcfgd/bgpcfgd/config.py similarity index 99% rename from src/sonic-bgpcfgd/app/config.py rename to src/sonic-bgpcfgd/bgpcfgd/config.py index a0c1329f832e..c642842a2c16 100644 --- a/src/sonic-bgpcfgd/app/config.py +++ b/src/sonic-bgpcfgd/bgpcfgd/config.py @@ -3,7 +3,7 @@ from .vars import g_debug from .log import log_crit, log_err -from .util import run_command +from .utils import run_command class ConfigMgr(object): diff --git a/src/sonic-bgpcfgd/app/directory.py b/src/sonic-bgpcfgd/bgpcfgd/directory.py similarity index 99% rename from src/sonic-bgpcfgd/app/directory.py rename to src/sonic-bgpcfgd/bgpcfgd/directory.py index d27ec64256e3..d2dfc915c037 100644 --- a/src/sonic-bgpcfgd/app/directory.py +++ b/src/sonic-bgpcfgd/bgpcfgd/directory.py @@ -1,6 +1,6 @@ from collections import defaultdict -from app.log import log_err +from .log import log_err class Directory(object): diff --git a/src/sonic-bgpcfgd/app/log.py b/src/sonic-bgpcfgd/bgpcfgd/log.py similarity index 100% rename from src/sonic-bgpcfgd/app/log.py rename to src/sonic-bgpcfgd/bgpcfgd/log.py diff --git a/src/sonic-bgpcfgd/bgpcfgd/main.py b/src/sonic-bgpcfgd/bgpcfgd/main.py new file mode 100644 index 000000000000..bef2f733ad57 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/main.py @@ -0,0 +1,81 @@ +import os +import signal +import sys +import syslog +import traceback + +from swsscommon import swsscommon + +from .config import ConfigMgr +from .directory import Directory +from .log import log_notice, log_crit +from .managers_allow_list import BGPAllowListMgr +from .managers_bgp import BGPPeerMgrBase +from .managers_db import BGPDataBaseMgr +from .managers_intf import InterfaceMgr +from .managers_setsrc import ZebraSetSrc +from .runner import Runner, signal_handler +from .template import TemplateFabric +from .utils import wait_for_daemons, read_constants +from .vars import g_debug + + +def do_work(): + """ Main function """ + wait_for_daemons(["bgpd", "zebra", "staticd"], seconds=20) + # + common_objs = { + 'directory': Directory(), + 'cfg_mgr': ConfigMgr(), + 'tf': TemplateFabric(), + 'constants': read_constants(), + } + managers = [ + # 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", True), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", False), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), + # AllowList Managers + BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), + ] + runner = Runner() + for mgr in managers: + runner.add_manager(mgr) + runner.run() + + +def main(): + rc = 0 + try: + syslog.openlog('bgpcfgd') + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGINT, signal_handler) + do_work() + except KeyboardInterrupt: + log_notice("Keyboard interrupt") + except RuntimeError as exc: + log_crit(str(exc)) + rc = -2 + 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: + sys.exit(rc) + except SystemExit: + os._exit(rc) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/manager.py b/src/sonic-bgpcfgd/bgpcfgd/manager.py similarity index 98% rename from src/sonic-bgpcfgd/app/manager.py rename to src/sonic-bgpcfgd/bgpcfgd/manager.py index ba45029b5120..6966a20f4b35 100644 --- a/src/sonic-bgpcfgd/app/manager.py +++ b/src/sonic-bgpcfgd/bgpcfgd/manager.py @@ -1,6 +1,6 @@ from swsscommon import swsscommon -from app.log import log_debug, log_err +from .log import log_debug, log_err class Manager(object): diff --git a/src/sonic-bgpcfgd/app/allow_list.py b/src/sonic-bgpcfgd/bgpcfgd/managers_allow_list.py similarity index 99% rename from src/sonic-bgpcfgd/app/allow_list.py rename to src/sonic-bgpcfgd/bgpcfgd/managers_allow_list.py index 2637d6999244..b8a784a2de5d 100644 --- a/src/sonic-bgpcfgd/app/allow_list.py +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_allow_list.py @@ -3,10 +3,10 @@ """ import re -from app.log import log_debug, log_info, log_err, log_warn -from app.template import TemplateFabric -from app.manager import Manager -from app.util import run_command +from .log import log_debug, log_info, log_err, log_warn +from .template import TemplateFabric +from .manager import Manager +from .utils import run_command class BGPAllowListMgr(Manager): """ This class initialize "AllowList" settings """ diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py b/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py new file mode 100644 index 000000000000..fc7e04f7e7b4 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py @@ -0,0 +1,391 @@ +import json +from swsscommon import swsscommon + +import jinja2 +import netaddr + +from .log import log_warn, log_err, log_info, log_debug, log_crit +from .manager import Manager +from .template import TemplateFabric +from .utils import run_command + + +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") + + 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 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 + + return self.update_entity(policy, "Routing policy for peer '%s'" % name) + + 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 + + if kwargs['vrf'] == 'default': + cmd = ('router bgp %s\n' % kwargs['bgp_asn']) + pg + else: + cmd = ('router bgp %s vrf %s\n' % (kwargs['bgp_asn'], kwargs['vrf'])) + pg + + return self.update_entity(cmd, "Peer-group for peer '%s'" % name) + + 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 + + +class BGPPeerMgrBase(Manager): + """ Manager of BGP peers """ + def __init__(self, common_objs, db_name, table_name, peer_type, check_neig_meta): + """ + 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 + + 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", ""), + ] + + if check_neig_meta: + self.check_neig_meta = 'bgp' in self.constants \ + and 'use_neighbors_meta' in self.constants['bgp'] \ + and self.constants['bgp']['use_neighbors_meta'] + else: + self.check_neig_meta = False + + 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): + """ + 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) + peer_key = (vrf, nbr) + if peer_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. + data["local_addr"] = str(netaddr.IPNetwork(str(data["local_addr"])).ip) + 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 + 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: + 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): + """ + 'DEL' handler for the BGP PEER tables + :param key: key of the neighbor + """ + vrf, nbr = self.split_key(key) + peer_key = (vrf, nbr) + if peer_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(peer_key) + else: + log_err("Peer '(%s|%s)' hasn't been removed" % (vrf, nbr)) + + 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): + """ + 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 = 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 = 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"]] + else: + return None + + @staticmethod + def get_vnet(interface): + """ + 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"]: + return interface["vnet_name"] + 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)) + + @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))) + + return peers \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_db.py b/src/sonic-bgpcfgd/bgpcfgd/managers_db.py new file mode 100644 index 000000000000..37d2eee99a8f --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_db.py @@ -0,0 +1,28 @@ +from .manager import Manager + + +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, + [], + db, + table, + ) + + def set_handler(self, 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): + """ Implementation of 'DEL' command for this class """ + self.directory.remove(self.db_name, self.table_name, key) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_intf.py b/src/sonic-bgpcfgd/bgpcfgd/managers_intf.py new file mode 100644 index 000000000000..ef4958ad9207 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_intf.py @@ -0,0 +1,56 @@ +import netaddr + +from .log import log_warn +from .manager import Manager + + +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, + [], + db, + table, + ) + + def set_handler(self, 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): + """ 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) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_setsrc.py b/src/sonic-bgpcfgd/bgpcfgd/managers_setsrc.py new file mode 100644 index 000000000000..19b589cf0446 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_setsrc.py @@ -0,0 +1,69 @@ +import jinja2 + +from .log import log_err, log_warn, log_info +from .manager import Manager +from .template import TemplateFabric + + +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 prefix: '%s'" % ip_addr_w_mask) + return True + ip_addr = ip_addr_w_mask[:slash_pos] + try: + if TemplateFabric.is_ipv4(ip_addr): + if 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="") + else: + log_warn("Update command is not supported for set src templates. current ip='%s'. new ip='%s'" % (self.lo_ipv4, ip_addr)) + return True + elif TemplateFabric.is_ipv6(ip_addr): + if 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_warn("Update command is not supported for set src templates. current ip='%s'. new ip='%s'" % (self.lo_ipv6, ip_addr)) + return True + 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 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") \ No newline at end of file diff --git a/src/sonic-bgpcfgd/bgpcfgd/runner.py b/src/sonic-bgpcfgd/bgpcfgd/runner.py new file mode 100644 index 000000000000..07799af5e7e4 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/runner.py @@ -0,0 +1,65 @@ +from collections import defaultdict +from swsscommon import swsscommon + +from .log import log_debug + + +g_run = True + + +def signal_handler(_, __): # signal_handler(signum, frame) + """ signal handler """ + global g_run + g_run = False + + +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)) \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/template.py b/src/sonic-bgpcfgd/bgpcfgd/template.py similarity index 100% rename from src/sonic-bgpcfgd/app/template.py rename to src/sonic-bgpcfgd/bgpcfgd/template.py diff --git a/src/sonic-bgpcfgd/bgpcfgd/utils.py b/src/sonic-bgpcfgd/bgpcfgd/utils.py new file mode 100644 index 000000000000..63d53512d04c --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/utils.py @@ -0,0 +1,55 @@ +import datetime +import subprocess +import time + +import yaml + +from .log import log_debug, log_err, log_info, log_warn, log_crit + + +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: + 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 + + +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: + 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 + 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) # FIXME: , Loader=yaml.FullLoader) + 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"] \ No newline at end of file diff --git a/src/sonic-bgpcfgd/app/vars.py b/src/sonic-bgpcfgd/bgpcfgd/vars.py similarity index 100% rename from src/sonic-bgpcfgd/app/vars.py rename to src/sonic-bgpcfgd/bgpcfgd/vars.py diff --git a/src/sonic-bgpcfgd/pytest.ini b/src/sonic-bgpcfgd/pytest.ini index 639ceb636af9..a49b58e45f0f 100644 --- a/src/sonic-bgpcfgd/pytest.ini +++ b/src/sonic-bgpcfgd/pytest.ini @@ -1,2 +1,2 @@ [pytest] -addopts = --cov=app --cov-report term +addopts = --cov=bgpcfgd --cov-report term diff --git a/src/sonic-bgpcfgd/setup.py b/src/sonic-bgpcfgd/setup.py index fc0839dff7fc..1e23802d98c1 100755 --- a/src/sonic-bgpcfgd/setup.py +++ b/src/sonic-bgpcfgd/setup.py @@ -9,13 +9,13 @@ author_email='pavelsh@microsoft.com', url='https://github.com/Azure/sonic-buildimage', packages=setuptools.find_packages(), - scripts=['bgpcfgd'], entry_points={ 'console_scripts': [ + 'bgpcfgd = bgpcfgd.main:main', 'bgpmon = bgpmon.bgpmon:main', ] }, install_requires=['jinja2>=2.10', 'netaddr', 'pyyaml'], setup_requires=['pytest-runner'], - test_requires=['pytest', 'pytest-cov'], + tests_require=['pytest', 'pytest-cov'], ) diff --git a/src/sonic-bgpcfgd/tests/test_allow_list.py b/src/sonic-bgpcfgd/tests/test_allow_list.py index f3cf2f534aaa..c906894eef47 100644 --- a/src/sonic-bgpcfgd/tests/test_allow_list.py +++ b/src/sonic-bgpcfgd/tests/test_allow_list.py @@ -1,8 +1,9 @@ -from app.directory import Directory -from app.template import TemplateFabric -import app +from bgpcfgd.directory import Directory +from bgpcfgd.template import TemplateFabric +import bgpcfgd from mock import MagicMock, patch + swsscommon_module_mock = MagicMock() global_constants = { @@ -22,14 +23,14 @@ @patch.dict("sys.modules", swsscommon=swsscommon_module_mock) def set_del_test(op, args, currect_config, expected_config): - from app.allow_list import BGPAllowListMgr + from bgpcfgd.managers_allow_list import BGPAllowListMgr set_del_test.push_list_called = False def push_list(args): set_del_test.push_list_called = True assert args == expected_config return True # - app.allow_list.run_command = lambda cmd: (0, "", "") + bgpcfgd.managers_allow_list.run_command = lambda cmd: (0, "", "") # cfg_mgr = MagicMock() cfg_mgr.update.return_value = None @@ -188,7 +189,7 @@ def test_set_handler_with_community_data_is_already_presented(): @patch.dict("sys.modules", swsscommon=swsscommon_module_mock) def test_set_handler_no_community_data_is_already_presented(): - from app.allow_list import BGPAllowListMgr + from bgpcfgd.managers_allow_list import BGPAllowListMgr cfg_mgr = MagicMock() cfg_mgr.update.return_value = None cfg_mgr.get_text.return_value = [ @@ -311,7 +312,7 @@ def test_set_handler_no_community_update_prefixes_add(): @patch.dict("sys.modules", swsscommon=swsscommon_module_mock) def test___set_handler_validate(): - from app.allow_list import BGPAllowListMgr + from bgpcfgd.managers_allow_list import BGPAllowListMgr cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), @@ -338,7 +339,7 @@ def test___set_handler_validate(): @patch.dict("sys.modules", swsscommon=swsscommon_module_mock) def test___find_peer_group_by_deployment_id(): - from app.allow_list import BGPAllowListMgr + from bgpcfgd.managers_allow_list import BGPAllowListMgr cfg_mgr = MagicMock() cfg_mgr.update.return_value = None cfg_mgr.get_text.return_value = [ @@ -432,7 +433,7 @@ def test___find_peer_group_by_deployment_id(): @patch.dict("sys.modules", swsscommon=swsscommon_module_mock) def test___restart_peers_found_deployment_id(): - from app.allow_list import BGPAllowListMgr + from bgpcfgd.managers_allow_list import BGPAllowListMgr test___restart_peers_found_deployment_id.run_command_counter = 0 def run_command(cmd): output = [ @@ -454,13 +455,13 @@ def run_command(cmd): mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') mocked.return_value = ["BGP_TEST_PEER_GROUP_1", "BGP_TEST_PEER_GROUP_2"] mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked - app.allow_list.run_command = run_command + bgpcfgd.managers_allow_list.run_command = run_command rc = mgr._BGPAllowListMgr__restart_peers(5) assert rc @patch.dict("sys.modules", swsscommon=swsscommon_module_mock) def test___restart_peers_not_found_deployment_id(): - from app.allow_list import BGPAllowListMgr + from bgpcfgd.managers_allow_list import BGPAllowListMgr def run_command(cmd): assert cmd == ['vtysh', '-c', 'clear bgp * soft in'] return 0, "", "" @@ -475,7 +476,7 @@ def run_command(cmd): mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') mocked.return_value = [] mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked - app.allow_list.run_command = run_command + bgpcfgd.managers_allow_list.run_command = run_command rc = mgr._BGPAllowListMgr__restart_peers(5) assert rc diff --git a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py index 686b1ade65e1..92b1e5dd8c2d 100644 --- a/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py +++ b/src/sonic-bgpcfgd/tests/test_ipv6_nexthop_global.py @@ -1,7 +1,7 @@ import os import re -from app.template import TemplateFabric +from bgpcfgd.template import TemplateFabric from .util import load_constants TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') diff --git a/src/sonic-bgpcfgd/tests/test_pfx_filter.py b/src/sonic-bgpcfgd/tests/test_pfx_filter.py index 3eebd3951f7b..684a95bf75f8 100644 --- a/src/sonic-bgpcfgd/tests/test_pfx_filter.py +++ b/src/sonic-bgpcfgd/tests/test_pfx_filter.py @@ -1,4 +1,4 @@ -from app.template import TemplateFabric +from bgpcfgd.template import TemplateFabric from collections import OrderedDict import pytest diff --git a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py index 065ecb815ccb..d10ec65d21dc 100644 --- a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py +++ b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py @@ -2,7 +2,7 @@ import subprocess -from app.config import ConfigMgr +from bgpcfgd.config import ConfigMgr from .test_templates import compress_comments, write_result diff --git a/src/sonic-bgpcfgd/tests/test_templates.py b/src/sonic-bgpcfgd/tests/test_templates.py index bd0bf9dbb484..f5f5f2155253 100644 --- a/src/sonic-bgpcfgd/tests/test_templates.py +++ b/src/sonic-bgpcfgd/tests/test_templates.py @@ -2,8 +2,8 @@ import json -from app.template import TemplateFabric -from app.config import ConfigMgr +from bgpcfgd.template import TemplateFabric +from bgpcfgd.config import ConfigMgr from .util import load_constants TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') From d03de95e811c9cc3917b0d0a2a6d4e66213815ac Mon Sep 17 00:00:00 2001 From: jon-nokia <63672455+jon-nokia@users.noreply.github.com> Date: Tue, 6 Oct 2020 18:47:50 -0400 Subject: [PATCH 71/78] [build]: fix pip installation for sonic utilities whl package (#5498) The problem was proxy was missing on "pip install". This is to fix the build behind the proxy. Signed-off-by: Jon Goldberg --- files/build_templates/sonic_debian_extension.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 0878c2801433..4dd49d8e3df8 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -190,7 +190,7 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/python-click*_all.deb || \ # Install SONiC Utilities Python 2 package SONIC_UTILITIES_PY2_WHEEL_NAME=$(basename {{sonic_utilities_py2_wheel_path}}) sudo cp {{sonic_utilities_py2_wheel_path}} $FILESYSTEM_ROOT/$SONIC_UTILITIES_PY2_WHEEL_NAME -sudo LANG=C chroot $FILESYSTEM_ROOT pip install $SONIC_UTILITIES_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SONIC_UTILITIES_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$SONIC_UTILITIES_PY2_WHEEL_NAME # Install sonic-utilities data files (and any dependencies via 'apt-get -y install -f') From 3da996bbf8a40a07ffe27fd6edc803ad35ee4d32 Mon Sep 17 00:00:00 2001 From: zzhiyuan Date: Tue, 6 Oct 2020 18:35:15 -0700 Subject: [PATCH 72/78] [arista]: Add disable_pcie_firmware_check soc property (#5543) This is to fix pcie firmware check assert in Broadcom SDK once the SAI changes merges. This will be in the future but adding the soc property in the broadcom config now. Co-authored-by: Zhi Yuan Carl Zhao --- .../Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm | 1 + .../Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm | 1 + src/sonic-device-data/tests/permitted_list | 1 + 3 files changed, 3 insertions(+) diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm index f4450ebac53f..af08293cf3a5 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-C64/th3-a7060px4-32-64x100G.config.bcm @@ -5,6 +5,7 @@ bcm_num_cos.0=8 bcm_stat_flags=1 bcm_stat_jumbo.0=9236 cdma_timeout_usec.0=15000000 +disable_pcie_firmware_check.0=1 dma_desc_timeout_usec.0=15000000 dpr_clock_frequency.0=1000 higig2_hdr_mode.0=1 diff --git a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm index cdbc4f4430b4..08712b5c8e4b 100644 --- a/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm +++ b/device/arista/x86_64-arista_7060px4_32/Arista-7060PX4-O32/th3-a7060px4-o32-32x400G.config.bcm @@ -5,6 +5,7 @@ bcm_num_cos.0=8 bcm_stat_flags=1 bcm_stat_jumbo.0=9236 cdma_timeout_usec.0=15000000 +disable_pcie_firmware_check.0=1 dma_desc_timeout_usec.0=15000000 dpr_clock_frequency.0=1000 higig2_hdr_mode.0=1 diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list index 9585c19301d4..8feb791875ef 100644 --- a/src/sonic-device-data/tests/permitted_list +++ b/src/sonic-device-data/tests/permitted_list @@ -15,6 +15,7 @@ cdma_timeout_usec core_clock_frequency ctr_evict_enable device_clock_frequency +disable_pcie_firmware_check dma_desc_timeout_usec dport_map_direct dport_map_enable From 895f4e0bf727bf25bb15d2612f65d68ce3744f5c Mon Sep 17 00:00:00 2001 From: Petro Bratash <68950226+bratashX@users.noreply.github.com> Date: Wed, 7 Oct 2020 21:32:38 +0300 Subject: [PATCH 73/78] [sonic-utilities] Submodule update (#5558) - Fix show queue watermark command fail Azure/sonic-utilities@6e58dff Signed-off-by: Petro Bratash --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 31eb13b7f8db..6e58dff4c9b5 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 31eb13b7f8db910fa5fd8f11e0d53d89aaf93f50 +Subproject commit 6e58dff4c9b590657e1f5e629a53ce4590d38382 From 744612d269dcb9161f84c0691d24bb6cd87fdbbb Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Thu, 8 Oct 2020 09:05:37 -0700 Subject: [PATCH 74/78] [ECMP][Multi-ASIC] Have different ECMP seed value on each ASIC (#5357) * Calculate ECMP hash seed based on ASIC ID on multi ASIC platform. Each ASIC will have a unique ECMP hash seed value. --- dockers/docker-orchagent/switch.json.j2 | 11 +++- src/sonic-config-engine/sonic-cfggen | 14 +++-- .../tests/sample_output/t0-switch-masic1.json | 10 +++ .../tests/sample_output/t0-switch-masic3.json | 10 +++ .../tests/sample_output/t0-switch.json | 10 +++ .../tests/sample_output/t1-switch.json | 10 +++ src/sonic-config-engine/tests/test_j2files.py | 63 ++++++++++++++++++- 7 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 src/sonic-config-engine/tests/sample_output/t0-switch-masic1.json create mode 100644 src/sonic-config-engine/tests/sample_output/t0-switch-masic3.json create mode 100644 src/sonic-config-engine/tests/sample_output/t0-switch.json create mode 100644 src/sonic-config-engine/tests/sample_output/t1-switch.json diff --git a/dockers/docker-orchagent/switch.json.j2 b/dockers/docker-orchagent/switch.json.j2 index f8beffbc9ad7..c359dd805219 100644 --- a/dockers/docker-orchagent/switch.json.j2 +++ b/dockers/docker-orchagent/switch.json.j2 @@ -1,20 +1,25 @@ {# the range of hash_seed is 0-15 #} {# set default hash seed to 0 #} {% set hash_seed = 0 %} +{% set hash_seed_offset = 0 %} {% if DEVICE_METADATA.localhost.type %} {% if DEVICE_METADATA.localhost.type == "ToRRouter" %} {% set hash_seed = 0 %} {% elif DEVICE_METADATA.localhost.type == "LeafRouter" %} {% set hash_seed = 10 %} {% elif DEVICE_METADATA.localhost.type == "SpineRouter" %} -{% set hash_seed = 15 %} +{% set hash_seed = 25 %} {% endif %} {% endif %} +{% if DEVICE_METADATA.localhost.namespace_id %} +{% set hash_seed_offset = DEVICE_METADATA.localhost.namespace_id | int %} +{% endif %} +{% set hash_seed_value = hash_seed_offset + hash_seed %} [ { "SWITCH_TABLE:switch": { - "ecmp_hash_seed": "{{ hash_seed }}", - "lag_hash_seed": "{{ hash_seed }}", + "ecmp_hash_seed": "{{ hash_seed_value }}", + "lag_hash_seed": "{{ hash_seed_value }}", "fdb_aging_time": "600" }, "OP": "SET" diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index de99d2523027..af638c2c2826 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -31,7 +31,7 @@ import contextlib import jinja2 import json import netaddr -import os.path +import os import sys import yaml @@ -61,7 +61,7 @@ def sort_by_port_index(value): if not value: return if isinstance(value, list): - # In multi-ASIC platforms backend ethernet ports are identified as + # In multi-ASIC platforms backend ethernet ports are identified as # 'Ethernet-BPxy'. Add 1024 to sort backend ports to the end. value.sort( key = lambda k: int(k[8:]) if "BP" not in k else int(k[11:]) + 1024 @@ -296,8 +296,14 @@ def main(): asic_id = None if asic_name is not None: asic_id = get_asic_id_from_name(asic_name) - - + # get the namespace ID + namespace_id = os.getenv("NAMESPACE_ID") + if namespace_id: + deep_update(data, { + 'DEVICE_METADATA': { + 'localhost': {'namespace_id': namespace_id} + } + }) # Load the database config for the namespace from global database json if args.namespace is not None: SonicDBConfig.load_sonic_global_db_config(namespace=args.namespace) diff --git a/src/sonic-config-engine/tests/sample_output/t0-switch-masic1.json b/src/sonic-config-engine/tests/sample_output/t0-switch-masic1.json new file mode 100644 index 000000000000..34fd946da361 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/t0-switch-masic1.json @@ -0,0 +1,10 @@ +[ + { + "SWITCH_TABLE:switch": { + "ecmp_hash_seed": "11", + "lag_hash_seed": "11", + "fdb_aging_time": "600" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/t0-switch-masic3.json b/src/sonic-config-engine/tests/sample_output/t0-switch-masic3.json new file mode 100644 index 000000000000..d9f929679cbc --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/t0-switch-masic3.json @@ -0,0 +1,10 @@ +[ + { + "SWITCH_TABLE:switch": { + "ecmp_hash_seed": "13", + "lag_hash_seed": "13", + "fdb_aging_time": "600" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/t0-switch.json b/src/sonic-config-engine/tests/sample_output/t0-switch.json new file mode 100644 index 000000000000..414e53b8a356 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/t0-switch.json @@ -0,0 +1,10 @@ +[ + { + "SWITCH_TABLE:switch": { + "ecmp_hash_seed": "0", + "lag_hash_seed": "0", + "fdb_aging_time": "600" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/sample_output/t1-switch.json b/src/sonic-config-engine/tests/sample_output/t1-switch.json new file mode 100644 index 000000000000..fdae474251f0 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/t1-switch.json @@ -0,0 +1,10 @@ +[ + { + "SWITCH_TABLE:switch": { + "ecmp_hash_seed": "10", + "lag_hash_seed": "10", + "fdb_aging_time": "600" + }, + "OP": "SET" + } +] diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index ad06f61b84c5..2dec13425e19 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -171,6 +171,68 @@ def test_ipinip_multi_asic(self): sample_output_file = os.path.join(self.test_dir, 'multi_npu_data', utils.PYvX_DIR, 'ipinip.json') assert filecmp.cmp(sample_output_file, self.output_file) + def test_swss_switch_render_template(self): + switch_template = os.path.join( + self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', + 'switch.json.j2' + ) + constants_yml = os.path.join( + self.test_dir, '..', '..', '..', 'files', 'image_config', + 'constants', 'constants.yml' + ) + test_list = { + "t1": { + "graph": self.t1_mlnx_minigraph, + "output": "t1-switch.json" + }, + "t0": { + "graph": self.t0_minigraph, + "output": "t0-switch.json" + }, + } + for _, v in test_list.items(): + argument = " -m {} -y {} -t {} > {}".format( + v["graph"], constants_yml, switch_template, self.output_file + ) + sample_output_file = os.path.join( + self.test_dir, 'sample_output', v["output"] + ) + self.run_script(argument) + assert filecmp.cmp(sample_output_file, self.output_file) + + def test_swss_switch_render_template_multi_asic(self): + # verify the ECMP hash seed changes per namespace + switch_template = os.path.join( + self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', + 'switch.json.j2' + ) + constants_yml = os.path.join( + self.test_dir, '..', '..', '..', 'files', 'image_config', + 'constants', 'constants.yml' + ) + test_list = { + "0": { + "namespace_id": "1", + "output": "t0-switch-masic1.json" + }, + "1": { + "namespace_id": "3", + "output": "t0-switch-masic3.json" + }, + } + for _, v in test_list.items(): + os.environ["NAMESPACE_ID"] = v["namespace_id"] + argument = " -m {} -y {} -t {} > {}".format( + self.t1_mlnx_minigraph, constants_yml, switch_template, + self.output_file + ) + sample_output_file = os.path.join( + self.test_dir, 'sample_output', v["output"] + ) + self.run_script(argument) + assert filecmp.cmp(sample_output_file, self.output_file) + os.environ["NAMESPACE_ID"] = "" + def test_ndppd_conf(self): conf_template = os.path.join(self.test_dir, "ndppd.conf.j2") vlan_interfaces_json = os.path.join(self.test_dir, "data", "ndppd", "vlan_interfaces.json") @@ -180,7 +242,6 @@ def test_ndppd_conf(self): self.run_script(argument) assert filecmp.cmp(expected, self.output_file), self.run_diff(expected, self.output_file) - def tearDown(self): try: os.remove(self.output_file) From 6edb5551cb805f041b387f8317b5a958fc617a99 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Thu, 8 Oct 2020 22:42:54 +0530 Subject: [PATCH 75/78] [Dell S6100] Properly release memory upon ICH driver deinit (#5561) During platform deinitialization, dell_ich is not removed properly and when we do initialize s6100 platform, ICH driver sysfs attributes are not attached. Because of this, get_transceiver_change_event returns error and this leads xcvrd to crash. --- platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c index cce36e9056fa..eb164e46fac5 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_ich.c @@ -926,7 +926,7 @@ static int dell_ich_remove(struct platform_device *pdev) // Unmap and release PMC regions if(ich_data->pmc_base) iounmap(ich_data->pmc_base); - if(ich_data->pmc_alloc) release_region(pmc_res.start, PMC_REG_LEN); + if(ich_data->pmc_alloc) release_mem_region(pmc_res.start, PMC_REG_LEN); ret = acpi_remove_sci_handler(dell_ich_sci_handler); if(ret) { From 01fceb6f799fac326552af810df1e4777c40e2cf Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Thu, 8 Oct 2020 11:31:09 -0700 Subject: [PATCH 76/78] Optimized caclmgrd Notification handling. Previously (#5560) any event happening on ACL Rule Table (eg DATAACL rules programmed) caused control plane default action to be triggered. Now Control Plance ACTION will be trigger only a) ACL Rule beloging to Control ACL Table Signed-off-by: Abhishek Dosi --- files/image_config/caclmgrd/caclmgrd | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index b2fa5efaea61..a199f4753ecb 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -533,9 +533,13 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): config_db_subscriber_table_map[namespace] = [] config_db_subscriber_table_map[namespace].append(subscribe_acl_table) config_db_subscriber_table_map[namespace].append(subscribe_acl_rule_table) - + + # Get the ACL rule table seprator + acl_rule_table_seprator = subscribe_acl_rule_table.getTableNameSeparator() + # Loop on select to see if any event happen on config db of any namespace while True: + ctrl_plane_acl_notification = False (state, selectableObj) = sel.select(SELECT_TIMEOUT_MS) # Continue if select is timeout or selectable object is not return if state != swsscommon.Select.OBJECT: @@ -546,9 +550,24 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): namespace = redisSelectObj.getDbConnector().getNamespace() # Pop data of both Subscriber Table object of namespace that got config db acl table event for table in config_db_subscriber_table_map[namespace]: - table.pop() - # Update the Control Plane ACL of the namespace that got config db acl table event - self.update_control_plane_acls(namespace) + (key, op, fvp) = table.pop() + # Pop of table that does not have data + if key == '': + continue + # ACL Table notification. We will take Control Plane ACTION for any ACL Table Event + # This can be optimize further but we should not have many acl table set/del events in normal + # scenario + elif acl_rule_table_seprator not in key: + ctrl_plane_acl_notification = True + # Check ACL Rule notification and make sure Rule point to ACL Table which is Controlplane + else: + acl_table = key.split(acl_rule_table_seprator)[0] + if self.config_db_map[namespace].get_table(self.ACL_TABLE)[acl_table]["type"] == self.ACL_TABLE_TYPE_CTRLPLANE: + ctrl_plane_acl_notification = True + + # Update the Control Plane ACL of the namespace that got config db acl table/rule event + if ctrl_plane_acl_notification: + self.update_control_plane_acls(namespace) # ============================= Functions ============================= From 9a1f68ba12d0fb5aa5dc028024fb7c7070f03c78 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Thu, 8 Oct 2020 23:23:51 +0300 Subject: [PATCH 77/78] [barefoot] Switch to Y profiles for Newport board (#5187) Signed-off-by: Volodymyr Boyko --- device/barefoot/x86_64-accton_as9516bf_32d-r0 | 1 - .../x86_64-accton_as9516bf_32d-r0/syncd.conf | 23 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) delete mode 120000 device/barefoot/x86_64-accton_as9516bf_32d-r0 create mode 100644 device/barefoot/x86_64-accton_as9516bf_32d-r0/syncd.conf diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0 b/device/barefoot/x86_64-accton_as9516bf_32d-r0 deleted file mode 120000 index 93f47d51b742..000000000000 --- a/device/barefoot/x86_64-accton_as9516bf_32d-r0 +++ /dev/null @@ -1 +0,0 @@ -x86_64-accton_as9516_32d-r0 \ No newline at end of file diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/syncd.conf b/device/barefoot/x86_64-accton_as9516bf_32d-r0/syncd.conf new file mode 100644 index 000000000000..6035b97b9834 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/syncd.conf @@ -0,0 +1,23 @@ +#!/bin/bash + + +y_profile_set() { + P4_PROFILE=$(sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["p4_profile"]') + if [[ -n "$P4_PROFILE" || ( ! -L /opt/bfn/install && -e /opt/bfn/install ) ]]; then + return + fi + + Y_PROFILE=$(ls -d /opt/bfn/install_y*_profile 2> /dev/null | head -1) + if [[ -z $Y_PROFILE ]]; then + echo "No P4 profile found for Newport" + return + fi + + ln -srfn $Y_PROFILE /opt/bfn/install +} + +( + unset PYTHONPATH + unset PYTHONHOME + y_profile_set +) From 42d9a44e05def705c2c391e2cb0b56d69983953a Mon Sep 17 00:00:00 2001 From: anish-n <44376847+anish-n@users.noreply.github.com> Date: Thu, 8 Oct 2020 15:45:21 -0700 Subject: [PATCH 78/78] Minigraph resource type changes (#5198) * Parse sub_role from minigraph into DEVICE_METADATA * Change minigraph sub_role to resource_type --- src/sonic-config-engine/minigraph.py | 12 ++++++++++-- .../tests/simple-sample-graph-metadata.xml | 5 +++++ src/sonic-config-engine/tests/test_cfggen.py | 5 +++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 7ab7c41cd2b1..62cb77600e47 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -547,6 +547,7 @@ def parse_meta(meta, hname): deployment_id = None region = None cloudtype = None + resource_type = 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(): @@ -573,7 +574,9 @@ def parse_meta(meta, hname): region = value elif name == "CloudType": cloudtype = value - return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype + elif name == "ResourceType": + resource_type = value + return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type def parse_linkmeta(meta, hname): @@ -820,6 +823,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw neighbors = None devices = None sub_role = None + resource_type = None docker_routing_config_mode = "separated" port_speeds_default = {} port_speed_png = {} @@ -871,7 +875,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw 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, cloudtype) = parse_meta(child, hostname) + (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type) = parse_meta(child, hostname) elif child.tag == str(QName(ns, "LinkMetadataDeclaration")): linkmetas = parse_linkmeta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): @@ -917,6 +921,10 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw current_device['sub_role'] = sub_role results['DEVICE_METADATA']['localhost']['sub_role'] = sub_role results['DEVICE_METADATA']['localhost']['asic_name'] = asic_name + + if resource_type is not None: + results['DEVICE_METADATA']['localhost']['resource_type'] = resource_type + results['BGP_NEIGHBOR'] = bgp_sessions results['BGP_MONITORS'] = bgp_monitors results['BGP_PEER_RANGE'] = bgp_peers_with_range 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 4bde42cdda3a..2b3368b7a9c7 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml @@ -253,6 +253,11 @@ 10.0.10.7;10.0.10.8 + + ResourceType + + resource_type_x + diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index ebaba3394f27..1fe1ad03849c 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -80,6 +80,11 @@ def test_minigraph_cloudtype(self): output = self.run_script(argument) self.assertEqual(output.strip(), 'Public') + def test_minigraph_resourcetype(self): + argument = '-v "DEVICE_METADATA[\'localhost\'][\'resource_type\']" -m "' + self.sample_graph_metadata + '"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'resource_type_x') + def test_print_data(self): argument = '-m "' + self.sample_graph + '" --print-data' output = self.run_script(argument)