From 990f5b01b68cd5a85d7b6f7a9ea72bd3ab56318d Mon Sep 17 00:00:00 2001 From: Liu Shilong Date: Wed, 30 Nov 2022 18:01:34 +0800 Subject: [PATCH 1/7] Use github code scanning instead of LGTM (#55) --- .github/codeql/codeql-config.yml | 4 +++ .github/workflows/codeql-analysis.yml | 43 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 .github/codeql/codeql-config.yml create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml new file mode 100644 index 0000000..2c8b049 --- /dev/null +++ b/.github/codeql/codeql-config.yml @@ -0,0 +1,4 @@ +name: "CodeQL config" +queries: + - uses: security-and-quality + - uses: security-extended diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..6478fb9 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,43 @@ +# For more infomation, please visit: https://github.com/github/codeql-action + +name: "CodeQL" + +on: + push: + branches: + - 'master' + - '202[0-9][0-9][0-9]' + pull_request_target: + branches: + - 'master' + - '202[0-9][0-9][0-9]' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'python' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + config-file: ./.github/codeql/codeql-config.yml + languages: ${{ matrix.language }} + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" From fa8b709dc0df771341dad0ebc07c0e7f8fd1177c Mon Sep 17 00:00:00 2001 From: Vivek Date: Mon, 13 Mar 2023 09:39:49 -0700 Subject: [PATCH 2/7] Handled the error case of negative age (#57) #### Why I did lldpctl can sometimes return negative age i.e. Negative age is seen from lldpctl because of the hwclock of the system being forward in time and the system time is later reset to correct time by ntpd. But the lldp agent for eth0 can start before ntpd resets the system clock and thus the init time is forward in time. Thus for every 10 sec when the lldp_syncd polls the lldpd it returns negative age. ``` { "lldp": { "interface": { "eth0": { "via": "LLDP", "rid": "1", "age": "-2 day, -23:-59:-47", } } } ``` In those cases the lldp_syncd fails the parsing and throws error logs like these and also doesn't update APP_DB Table which is used by SNMP. ``` Jan 30 02:05:31.186000 r-r740-05-bf2-sonic-01 ERR lldp#lldp-syncd [lldp_syncd] ERROR: Failed to parse LLDPd JSON. #012{'lldp': {'interface': [{'eth0': {'via': 'LLDP', 'rid': '1', 'age': '-2 day, -23:-55:-15', 'chassis': {'MTR-F-1-S-LAB-R3-3-SW01': {'id': {'type': 'mac', 'value': 'e0:07:1b:38:37:c0'}, 'descr': 'HP J9775A 2530-48G Switch, revision YA.16.11.0003, ROM YA.15.20 (/ws/swbuildm/rel_beluru_qaoff/code/build/lakes(swbuildm_rel_beluru_qaoff_rel_beluru))', 'mgmt-ip': '10.210.100.142', 'capability': {'type': 'Bridge', 'enabled': True}}}, 'port': {'id': {'type': 'local', 'value': '14'}, 'descr': '14', 'ttl': '120', 'auto-negotiation': {'supported': True, 'enabled': True, 'advertised': [{'type': '10Base-T', 'hd': True, 'fd': True}, {'type': '100Base-TX', 'hd': True, 'fd': True}, {'type': '1000Base-T', 'hd': False, 'fd': True}], 'current': '1000BaseTFD - Four-pair Category 5 UTP, full duplex mode'}, 'power': {'supported': False, 'enabled': False, 'paircontrol': False, 'device-type': 'PSE', 'pairs': 'signal', 'class': 'class 0'}}, 'vlan': {'vlan-id': '23', 'pvid': True}, 'unknown-tlvs': {'unknown-tlv': {'oui': '00,16,B9', 'subtype': '2', 'len': '2', 'value': '00,01'}}}}, {'Ethernet0': {'via': 'LLDP', 'rid': '4', 'age': '0 day, 00:03:17', 'chassis': {'ARISTA01T0': {'id': {'type': 'mac', 'value': '22:25:8e:ab:b6:2e'}, 'descr': 'Arista Networks EOS version 4.27.0F-24308433.4270F (engineering build) running on an Arista cEOSLab', 'mgmt-ip': '10.215.11.41', 'capability': [{'type': 'Bridge', 'enabled': True}, {'type': 'Router', 'enabled': True}]}}, 'port': {'id': {'type': 'ifname', 'value': 'Ethernet1'}, 'ttl': '120', 'mfs': '9236'}}}, {'Ethernet4': {'via': 'LLDP', 'rid': '3', 'age': '0 day, 00:03:17', 'chassis': {'ARISTA02T0': {'id': {'type': 'mac', 'value': '0e:b9:12:65:d3:30'}, 'descr': 'Arista Networks EOS version 4.27.0F-24308433.4270F (engineering build) running on an Arista cEOSLab', 'mgmt-ip': '10.215.11.42', 'capability': [{'type': 'Bridge', 'enabled': True}, {'type': 'Router', 'enabled': True}]}}, 'port': {'id': {'type': 'ifname', 'value': 'Ethernet1'}, 'ttl': '120', 'mfs': '9236'}}}]}, 'lldp_loc_chassis': {'local-chassis': {'chassis': {'r-r740-05-bf2-sonic-01': {'id': {'type': 'mac', 'value': '08:c0:eb:7b:c0:ac'}, 'descr': 'SONiC Software Version: SONiC.bluefield.94-d9f9de047_Internal - HwSku: Nvidia-MBF2H536C - Distribution: Debian 11.6 - Kernel: 5.10.0-18-2-arm64', 'mgmt-ip': '10.215.11.59', 'capability': [{'type': 'Bridge', 'enabled': True}, {'type': 'Router', 'enabled': True}, {'type': 'Wlan', 'enabled': False}, {'type': 'Station', 'enabled': False}]}}}}}#012 -- #012Traceback (most recent call last):#012 File "/usr/local/lib/python3.9/dist-packages/lldp_syncd/daemon.py", line 254, in parse_update#012 str(parse_time(if_attributes.get('age')))})#012 File "/usr/local/lib/python3.9/dist-packages/lldp_syncd/daemon.py", line 48, in parse_time#012 struct_time = time.strptime(hour_min_secs, LLDPD_TIME_FORMAT)#012 File "/usr/lib/python3.9/_strptime.py", line 562, in _strptime_time#012 tt = _strptime(data_string, format)[0]#012 File "/usr/lib/python3.9/_strptime.py", line 349, in _strptime#012 raise ValueError("time data %r does not match format %r" %#012ValueError: time data '-23:-55:-15' does not match format '%H:%M:%S' Jan 30 02:05:41.297868 r-r740-05-bf2-sonic-01 ERR lldp#lldp-syncd [lldp_syncd] ERROR: Failed to parse LLDPd JSON. #012{'lldp': {'interface': [{'eth0': {'via': 'LLDP', 'rid': '1', 'age': '-2 day, -23:-55:-5', 'chassis': {'MTR-F-1-S-LAB-R3-3-SW01': {'id': {'type': 'mac', 'value': 'e0:07:1b:38:37:c0'}, 'descr': 'HP J9775A 2530-48G Switch, revision YA.16.11.0003, ROM YA.15.20 (/ws/swbuildm/rel_beluru_qaoff/code/build/lakes(swbuildm_rel_beluru_qaoff_rel_beluru))', 'mgmt-ip': '10.210.100.142', 'capability': {'type': 'Bridge', 'enabled': True}}}, 'port': {'id': {'type': 'local', 'value': '14'}, 'descr': '14', 'ttl': '120', 'auto-negotiation': {'supported': True, 'enabled': True, 'advertised': [{'type': '10Base-T', 'hd': True, 'fd': True}, {'type': '100Base-TX', 'hd': True, 'fd': True}, {'type': '1000Base-T', 'hd': False, 'fd': True}], 'current': '1000BaseTFD - Four-pair Category 5 UTP, full duplex mode'}, 'power': {'supported': False, 'enabled': False, 'paircontrol': False, 'device-type': 'PSE', 'pairs': 'signal', 'class': 'class 0'}}, 'vlan': {'vlan-id': '23', 'pvid': True}, 'unknown-tlvs': {'unknown-tlv': {'oui': '00,16,B9', 'subtype': '2', 'len': '2', 'value': '00,01'}}}}, {'Ethernet0': {'via': 'LLDP', 'rid': '4', 'age': '0 day, 00:03:27', 'chassis': {'ARISTA01T0': {'id': {'type': 'mac', 'value': '22:25:8e:ab:b6:2e'}, 'descr': 'Arista Networks EOS version 4.27.0F-24308433.4270F (engineering build) running on an Arista cEOSLab', 'mgmt-ip': '10.215.11.41', 'capability': [{'type': 'Bridge', 'enabled': True}, {'type': 'Router', 'enabled': True}]}}, 'port': {'id': {'type': 'ifname', 'value': 'Ethernet1'}, 'ttl': '120', 'mfs': '9236'}}}, {'Ethernet4': {'via': 'LLDP', 'rid': '3', 'age': '0 day, 00:03:27', 'chassis': {'ARISTA02T0': {'id': {'type': 'mac', 'value': '0e:b9:12:65:d3:30'}, 'descr': 'Arista Networks EOS version 4.27.0F-24308433.4270F (engineering build) running on an Arista cEOSLab', 'mgmt-ip': '10.215.11.42', 'capability': [{'type': 'Bridge', 'enabled': True}, {'type': 'Router', 'enabled': True}]}}, 'port': {'id': {'type': 'ifname', 'value': 'Ethernet1'}, 'ttl': '120', 'mfs': '9236'}}}]}, 'lldp_loc_chassis': {'local-chassis': {'chassis': {'r-r740-05-bf2-sonic-01': {'id': {'type': 'mac', 'value': '08:c0:eb:7b:c0:ac'}, 'descr': 'SONiC Software Version: SONiC.bluefield.94-d9f9de047_Internal - HwSku: Nvidia-MBF2H536C - Distribution: Debian 11.6 - Kernel: 5.10.0-18-2-arm64', 'mgmt-ip': '10.215.11.59', 'capability': [{'type': 'Bridge', 'enabled': True}, {'type': 'Router', 'enabled': True}, {'type': 'Wlan', 'enabled': False}, {'type': 'Station', 'enabled': False}]}}}}}#012 -- #012Traceback (most recent call last):#012 File "/usr/local/lib/python3.9/dist-packages/lldp_syncd/daemon.py", line 254, in parse_update#012 str(parse_time(if_attributes.get('age')))})#012 File "/usr/local/lib/python3.9/dist-packages/lldp_syncd/daemon.py", line 48, in parse_time#012 struct_time = time.strptime(hour_min_secs, LLDPD_TIME_FORMAT)#012 File "/usr/lib/python3.9/_strptime.py", line 562, in _strptime_time#012 tt = _strptime(data_string, format)[0]#012 File "/usr/lib/python3.9/_strptime.py", line 349, in _strptime#012 raise ValueError("time data %r does not match format %r" %#012ValueError: time data '-23:-55:-5' does not match format '%H:%M:%S' ``` #### What I did Don't fail updating the APP_DB with the contents of lldp json when there is error is age field. when the hwclock of the system is set forward in time and t --- src/lldp_syncd/daemon.py | 18 +++++++++++------- tests/test_lldpSyncDaemon.py | 1 + 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/lldp_syncd/daemon.py b/src/lldp_syncd/daemon.py index 442b678..a80edef 100644 --- a/src/lldp_syncd/daemon.py +++ b/src/lldp_syncd/daemon.py @@ -44,12 +44,16 @@ def parse_time(time_str): } :return: parsed age in time ticks (or seconds) """ - days, hour_min_secs = re.split(LLDPD_UPTIME_RE_SPLIT_PATTERN, time_str) - struct_time = time.strptime(hour_min_secs, LLDPD_TIME_FORMAT) - time_delta = datetime.timedelta(days=int(days), hours=struct_time.tm_hour, - minutes=struct_time.tm_min, - seconds=struct_time.tm_sec) - return int(time_delta.total_seconds()) + try: + days, hour_min_secs = re.split(LLDPD_UPTIME_RE_SPLIT_PATTERN, time_str) + struct_time = time.strptime(hour_min_secs, LLDPD_TIME_FORMAT) + time_delta = datetime.timedelta(days=int(days), hours=struct_time.tm_hour, + minutes=struct_time.tm_min, + seconds=struct_time.tm_sec) + return int(time_delta.total_seconds()) + except ValueError: + logger.exception("Failed to parse lldp age {} -- ".format(time_str)) + return 0 class LldpSyncDaemon(SonicSyncDaemon): @@ -264,7 +268,7 @@ def parse_update(self, lldp_json): parsed_interfaces[if_name].update({'lldp_rem_sys_cap_enabled': self.parse_sys_capabilities( capability_list, enabled=True)}) - if lldp_json['lldp_loc_chassis']: + if lldp_json.get('lldp_loc_chassis'): loc_chassis_keys = ('lldp_loc_chassis_id_subtype', 'lldp_loc_chassis_id', 'lldp_loc_sys_name', diff --git a/tests/test_lldpSyncDaemon.py b/tests/test_lldpSyncDaemon.py index b811fd2..bc50baf 100644 --- a/tests/test_lldpSyncDaemon.py +++ b/tests/test_lldpSyncDaemon.py @@ -98,6 +98,7 @@ def test_sync_roundtrip(self): def test_timeparse(self): self.assertEqual(lldp_syncd.daemon.parse_time("0 day, 05:09:02"), make_seconds(0, 5, 9, 2)) self.assertEqual(lldp_syncd.daemon.parse_time("2 days, 05:59:02"), make_seconds(2, 5, 59, 2)) + self.assertEqual(lldp_syncd.daemon.parse_time("-2 days, -23:-55:-02"), make_seconds(0, 0, 0, 0)) def parse_mgmt_ip(self, json_file): parsed_update = self.daemon.parse_update(json_file) From e4ac9068be56595c53b4f3d320d72bb7d10bd368 Mon Sep 17 00:00:00 2001 From: Mai Bui Date: Mon, 19 Jun 2023 16:29:42 -0400 Subject: [PATCH 3/7] [actions] Support Semgrep by Github Actions (#59) Why I did it Semgrep is a static analysis tool to find security vulnerabilities. When opening a PR or commtting to PR, Semgrep performs a diff-aware scanning, which scans changed files in PRs. When merging PR, Semgrep performs a full scan on master branch and report all findings. Ref: - Supported Language - Semgrep Rules How I did it Integrate Semgrep into this repository by committing a job configuration file --- .github/workflows/semgrep.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/semgrep.yml diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml new file mode 100644 index 0000000..975769a --- /dev/null +++ b/.github/workflows/semgrep.yml @@ -0,0 +1,22 @@ +name: Semgrep + +on: + pull_request: {} + push: + branches: + - master + - '201[7-9][0-1][0-9]' + - '202[0-9][0-1][0-9]' + +jobs: + semgrep: + if: github.repository_owner == 'sonic-net' + name: Semgrep + runs-on: ubuntu-latest + container: + image: returntocorp/semgrep + steps: + - uses: actions/checkout@v3 + - run: semgrep ci + env: + SEMGREP_RULES: p/default From e294eb0777cac48861cb39df275d419acbe73307 Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Thu, 16 Nov 2023 19:16:54 +0800 Subject: [PATCH 4/7] Update the code coverage rate to 80% (#63) Update the code coverage rate to 80% --- azure-pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 4cf5b0f..fffe920 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ trigger: - '*' variables: - DIFF_COVER_CHECK_THRESHOLD: 70 + DIFF_COVER_CHECK_THRESHOLD: 80 DIFF_COVER_ENABLE: 'true' DIFF_COVER_WORKING_DIRECTORY: $(System.DefaultWorkingDirectory) @@ -33,11 +33,11 @@ steps: - script: | set -xe sudo apt-get -y purge libhiredis-dev libnl-3-dev libnl-route-3-dev + sudo apt install -y libhiredis0.14 sudo dpkg -i libnl-3-200_*.deb sudo dpkg -i libnl-genl-3-200_*.deb sudo dpkg -i libnl-route-3-200_*.deb sudo dpkg -i libnl-nf-3-200_*.deb - sudo dpkg -i libhiredis0.14_*.deb sudo dpkg -i libyang_1.*.deb sudo dpkg -i libswsscommon_1.0.0_amd64.deb sudo dpkg -i python3-swsscommon_1.0.0_amd64.deb From 4d627eed8173ceab02bf9070cd5360c8ad0d42d7 Mon Sep 17 00:00:00 2001 From: Zhaohui Sun <94606222+ZhaohuiS@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:22:24 +0800 Subject: [PATCH 5/7] [lldp-syncd] Fix unexpected exception in snmp-subagent (#64) Separate deleted and changed scearios deleted interfaces, delete their table key changed interfaces if lldp_rem_time_mark is only changed key, just use hset its new value. Don't delete interface table key. If other keys are changed as well, delete interface key and use hmset to set the whole dict into DB, instead of using hset each item one by one. This will avoid interface exists but some of its keys are not added. Signed-off-by: Zhaohui Sun --- src/lldp_syncd/daemon.py | 48 +- tests/mock_tables/LLDP_ENTRY_TABLE.json | 716 ++++++++++++------------ tests/mock_tables/dbconnector.py | 67 ++- tests/test_lldpSyncDaemon.py | 44 +- 4 files changed, 499 insertions(+), 376 deletions(-) diff --git a/src/lldp_syncd/daemon.py b/src/lldp_syncd/daemon.py index a80edef..fde3002 100644 --- a/src/lldp_syncd/daemon.py +++ b/src/lldp_syncd/daemon.py @@ -349,6 +349,26 @@ def cache_diff(self, cache, update): return new_keys, changed_keys, deleted_keys + def is_only_time_mark_modified(self, cached_interface, updated_interface): + """ + Check if only lldp_rem_time_mark is modified in the update + :param cached_interface: Local cached interface dict + :param updated_interface: Updated interface dict + :return: True if only lldp_rem_time_mark is modified, False otherwise + """ + if len(cached_interface) != len(updated_interface): + return False + + changed_keys = 0 + + for key in cached_interface.keys(): + if 'lldp_rem_time_mark' == key and cached_interface[key] != updated_interface[key]: + changed_keys += 1 + elif key not in updated_interface or cached_interface[key] != updated_interface[key]: + return False + + return True if changed_keys == 1 else False + def sync(self, parsed_update): """ Sync LLDP information to redis DB. @@ -367,18 +387,32 @@ def sync(self, parsed_update): logger.debug("sync'd: {}".format(json.dumps(chassis_update, indent=3))) new, changed, deleted = self.cache_diff(self.interfaces_cache, parsed_update) + + # For changed elements, if only lldp_rem_time_mark changed, update its value, otherwise delete and repopulate + for interface in changed: + if re.match(SONIC_ETHERNET_RE_PATTERN, interface) is None: + logger.warning("Ignoring interface '{}'".format(interface)) + continue + table_key = ':'.join([LldpSyncDaemon.LLDP_ENTRY_TABLE, interface]) + if self.is_only_time_mark_modified(self.interfaces_cache[interface], parsed_update[interface]): + self.db_connector.set(self.db_connector.APPL_DB, table_key, 'lldp_rem_time_mark', parsed_update[interface]['lldp_rem_time_mark'], blocking=True) + logger.debug("Only sync'd interface {} lldp_rem_time_mark: {}".format(interface, parsed_update[interface]['lldp_rem_time_mark'])) + else: + self.db_connector.delete(self.db_connector.APPL_DB, table_key) + self.db_connector.hmset(self.db_connector.APPL_DB, table_key, parsed_update[interface]) + logger.debug("Sync'd changed interface {} : {}".format(interface, parsed_update[interface])) self.interfaces_cache = parsed_update - # Delete LLDP_ENTRIES which were modified or are missing - for interface in changed + deleted: + # Delete LLDP_ENTRIES which are missing + for interface in deleted: table_key = ':'.join([LldpSyncDaemon.LLDP_ENTRY_TABLE, interface]) self.db_connector.delete(self.db_connector.APPL_DB, table_key) - # Repopulate LLDP_ENTRY_TABLE by adding all changed elements - for interface in changed + new: + logger.debug("Delete table_key: {}".format(table_key)) + # Repopulate LLDP_ENTRY_TABLE by adding new elements + for interface in new: if re.match(SONIC_ETHERNET_RE_PATTERN, interface) is None: logger.warning("Ignoring interface '{}'".format(interface)) continue # port_table_key = LLDP_ENTRY_TABLE:INTERFACE_NAME; table_key = ':'.join([LldpSyncDaemon.LLDP_ENTRY_TABLE, interface]) - for k, v in parsed_update[interface].items(): - self.db_connector.set(self.db_connector.APPL_DB, table_key, k, v, blocking=True) - logger.debug("sync'd: \n{}".format(json.dumps(parsed_update[interface], indent=3))) + self.db_connector.hmset(self.db_connector.APPL_DB, table_key, parsed_update[interface]) + logger.debug("Add new interface {} : {}".format(interface, parsed_update[interface])) diff --git a/tests/mock_tables/LLDP_ENTRY_TABLE.json b/tests/mock_tables/LLDP_ENTRY_TABLE.json index 065ea41..73550f8 100644 --- a/tests/mock_tables/LLDP_ENTRY_TABLE.json +++ b/tests/mock_tables/LLDP_ENTRY_TABLE.json @@ -1,465 +1,465 @@ { - "LLDP_ENTRY_TABLE:Ethernet100": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "LLDP_ENTRY_TABLE:eth0": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "ge-0/0/17", + "lldp_rem_port_desc": "TPS report vending machine", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18544, - "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet26", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet4": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", + "lldp_rem_sys_name": "switch218ad08", + "lldp_rem_sys_desc": "I'm going to need you to come in on saturday", + "lldp_rem_man_addr": "", + "lldp_rem_time_mark": "18542", + "lldp_rem_index": "2", "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet0": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet1", + "lldp_rem_port_desc": "this is a port description", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", + "lldp_rem_sys_name": "switch13", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18543, + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18545", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet100": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet26", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet2", - "lldp_rem_man_addr": "10.3.147.196" + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18544", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" }, "LLDP_ENTRY_TABLE:Ethernet104": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18544, - "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "switch13", + "lldp_rem_port_id_subtype": "5", "lldp_rem_port_id": "Ethernet27", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet0": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_port_desc": "", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18545, - "lldp_rem_port_desc": "this is a port description", - "lldp_rem_chassis_id_subtype": 4, "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet1", - "lldp_rem_man_addr": "10.3.147.196" + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18544", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" }, "LLDP_ENTRY_TABLE:Ethernet108": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18544, - "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "switch13", + "lldp_rem_port_id_subtype": "5", "lldp_rem_port_id": "Ethernet28", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet8": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18543, "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet3", - "lldp_rem_man_addr": "10.3.147.196" + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18544", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" }, - "LLDP_ENTRY_TABLE:Ethernet96": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "", - "lldp_rem_sys_cap_supported": "", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "", - "lldp_rem_time_mark": 18543, + "LLDP_ENTRY_TABLE:Ethernet112": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet29", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "", - "lldp_rem_port_id": "Ethernet25", - "lldp_rem_man_addr": "" - }, - "LLDP_ENTRY_TABLE:Ethernet92": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 32, - "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet24", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet124": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "2103", + "lldp_rem_index": "1", "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet116": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet30", + "lldp_rem_port_desc": "", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", + "lldp_rem_sys_name": "switch13", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 4834, + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "1113", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet12": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet4", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet32", - "lldp_rem_man_addr": "10.3.147.196" + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18545", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" }, "LLDP_ENTRY_TABLE:Ethernet120": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet31", + "lldp_rem_port_desc": "", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", + "lldp_rem_sys_name": "switch13", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 3844, + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "3844", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet124": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet32", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet31", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet40": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "4834", + "lldp_rem_index": "1", "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet16": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet5", + "lldp_rem_port_desc": "", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", + "lldp_rem_sys_name": "switch13", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 572, + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18545", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet20": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet6", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet11", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet44": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18545", + "lldp_rem_index": "1", "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet24": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet7", + "lldp_rem_port_desc": "", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", + "lldp_rem_sys_name": "switch13", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 1202, + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "1775", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet28": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet8", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet12", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet48": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18513", + "lldp_rem_index": "1", "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet32": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet9", + "lldp_rem_port_desc": "", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", + "lldp_rem_sys_name": "switch13", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 1202, + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "1142", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet36": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet10", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet13", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet24": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "152", + "lldp_rem_index": "1", "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet4": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet2", + "lldp_rem_port_desc": "", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", + "lldp_rem_sys_name": "switch13", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 1775, + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18543", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet40": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet11", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet7", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet68": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "572", + "lldp_rem_index": "1", "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet44": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet12", + "lldp_rem_port_desc": "", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", + "lldp_rem_sys_name": "switch13", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18543, + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "1202", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet48": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet13", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet18", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:eth0": { - "lldp_rem_index": 2, - "lldp_rem_sys_cap_enabled": "28 00", + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "1202", + "lldp_rem_index": "1", "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm going to need you to come in on saturday", - "lldp_rem_time_mark": 18542, - "lldp_rem_port_desc": "TPS report vending machine", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "switch218ad08", - "lldp_rem_port_id": "ge-0/0/17", - "lldp_rem_man_addr": "" + "lldp_rem_sys_cap_enabled": "28 00" }, - "LLDP_ENTRY_TABLE:Ethernet20": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "LLDP_ENTRY_TABLE:Ethernet52": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet14", + "lldp_rem_port_desc": "", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", + "lldp_rem_sys_name": "switch13", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18545, + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18543", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet56": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet15", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet6", - "lldp_rem_man_addr": "10.3.147.196" + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18543", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" }, "LLDP_ENTRY_TABLE:Ethernet60": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18543, + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet16", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet16", - "lldp_rem_man_addr": "10.3.147.196" + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18543", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" }, "LLDP_ENTRY_TABLE:Ethernet64": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18543, - "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "switch13", + "lldp_rem_port_id_subtype": "5", "lldp_rem_port_id": "Ethernet17", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet112": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 2103, "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet29", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet116": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18543", + "lldp_rem_index": "1", "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet68": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet18", + "lldp_rem_port_desc": "", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", + "lldp_rem_sys_name": "switch13", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 1113, + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18543", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet72": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet19", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet30", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet84": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18543", + "lldp_rem_index": "1", "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet76": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet20", + "lldp_rem_port_desc": "", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", + "lldp_rem_sys_name": "switch13", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 362, + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18543", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet8": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet3", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet22", - "lldp_rem_man_addr": "10.3.147.196" + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "18543", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" }, "LLDP_ENTRY_TABLE:Ethernet80": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet21", + "lldp_rem_port_desc": "", + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", + "lldp_rem_sys_name": "switch13", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 362, + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "362", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" + }, + "LLDP_ENTRY_TABLE:Ethernet84": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet22", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet21", - "lldp_rem_man_addr": "10.3.147.196" + "lldp_rem_sys_desc": "I'm a little teapot.", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "362", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "28 00", + "lldp_rem_sys_cap_enabled": "28 00" }, "LLDP_ENTRY_TABLE:Ethernet88": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 92, - "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "switch13", + "lldp_rem_port_id_subtype": "5", "lldp_rem_port_id": "Ethernet23", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet52": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18543, "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet14", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet76": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18543, - "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet20", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet56": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18543, - "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet15", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet72": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "92", + "lldp_rem_index": "1", "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18543, - "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet19", - "lldp_rem_man_addr": "10.3.147.196" + "lldp_rem_sys_cap_enabled": "28 00" }, - "LLDP_ENTRY_TABLE:Ethernet32": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 1142, + "LLDP_ENTRY_TABLE:Ethernet92": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet24", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet9", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet28": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, + "lldp_rem_chassis_id_subtype": "4", "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18513, - "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet8", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet36": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 152, - "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet10", - "lldp_rem_man_addr": "10.3.147.196" - }, - "LLDP_ENTRY_TABLE:Ethernet16": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", + "lldp_rem_man_addr": "10.3.147.196", + "lldp_rem_time_mark": "32", + "lldp_rem_index": "1", "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18545, - "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet5", - "lldp_rem_man_addr": "10.3.147.196" + "lldp_rem_sys_cap_enabled": "28 00" }, - "LLDP_ENTRY_TABLE:Ethernet12": { - "lldp_rem_index": 1, - "lldp_rem_sys_cap_enabled": "28 00", - "lldp_rem_sys_cap_supported": "28 00", - "lldp_rem_port_id_subtype": 5, - "lldp_rem_chassis_id": "00:11:22:33:44:55", - "lldp_rem_sys_desc": "I'm a little teapot.", - "lldp_rem_time_mark": 18545, + "LLDP_ENTRY_TABLE:Ethernet96": { + "lldp_rem_port_id_subtype": "5", + "lldp_rem_port_id": "Ethernet25", "lldp_rem_port_desc": "", - "lldp_rem_chassis_id_subtype": 4, - "lldp_rem_sys_name": "switch13", - "lldp_rem_port_id": "Ethernet4", - "lldp_rem_man_addr": "10.3.147.196" + "lldp_rem_chassis_id_subtype": "4", + "lldp_rem_chassis_id": "00:11:22:33:44:55", + "lldp_rem_sys_name": "", + "lldp_rem_sys_desc": "", + "lldp_rem_man_addr": "", + "lldp_rem_time_mark": "18543", + "lldp_rem_index": "1", + "lldp_rem_sys_cap_supported": "", + "lldp_rem_sys_cap_enabled": "" }, "LLDP_LOC_CHASSIS": { "lldp_loc_chassis_id_subtype": "4", diff --git a/tests/mock_tables/dbconnector.py b/tests/mock_tables/dbconnector.py index ec44617..ca21263 100644 --- a/tests/mock_tables/dbconnector.py +++ b/tests/mock_tables/dbconnector.py @@ -5,7 +5,7 @@ import mockredis import redis -from swsssdk import SonicV2Connector +from swsscommon.swsscommon import SonicV2Connector from swsssdk import SonicDBConfig from swsssdk.interface import DBInterface from swsscommon import swsscommon @@ -16,13 +16,6 @@ xrange = range basestring = str -_old_connect_SonicV2Connector = SonicV2Connector.connect - -def connect_SonicV2Connector(self, db_name, retry_on=True): - self.dbintf.redis_kwargs['db_name'] = db_name - self.dbintf.redis_kwargs['decode_responses'] = True - _old_connect_SonicV2Connector(self, db_name, retry_on) - def _subscribe_keyspace_notification(self, db_name, client): pass @@ -107,9 +100,63 @@ def keys(self, pattern='*'): # Find every key that matches the pattern return [key for key in self.redis.keys() if regex.match(key)] +class MockConnector(object): + APPL_DB = 0 + CONFIG_DB = 4 + data = {} + + def __init__(self): + pass + + def connect(self, db_id): + if db_id == 0: + with open(INPUT_DIR + '/LLDP_ENTRY_TABLE.json') as f: + db = json.load(f) + for h, table in db.items(): + self.data[h] = {} + for k, v in table.items(): + self.data[h][k] = v + + elif db_id == 4: + with open(INPUT_DIR + '/CONFIG_DB.json') as f: + db = json.load(f) + for h, table in db.items(): + self.data[h] = {} + for k, v in table.items(): + self.data[h][k] = v + + + def get(self, db_id, key, field): + return MockConnector.data[key][field] + + def keys(self, db_id): + ret = [] + for key in MockConnector.data.keys(): + ret.append(key) + + return ret + + def get_all(self, db_id, key): + return MockConnector.data[key] + + def exists(self, db_id, key): + return key in MockConnector.data + + def set(self, db_id, key, field, value, blocking=False): + self.data[key] = {} + self.data[key][field] = value + + def hmset(self, db_id, key, fieldsvalues): + self.data[key] = {} + for field,value in fieldsvalues.items(): + self.data[key][field] = value + + def delete(self, db_id, key): + del self.data[key] + DBInterface._subscribe_keyspace_notification = _subscribe_keyspace_notification mockredis.MockRedis.config_set = config_set redis.StrictRedis = SwssSyncClient -SonicV2Connector.connect = connect_SonicV2Connector -swsscommon.SonicV2Connector = SonicV2Connector +SonicV2Connector.connect = MockConnector.connect +swsscommon.SonicV2Connector = MockConnector diff --git a/tests/test_lldpSyncDaemon.py b/tests/test_lldpSyncDaemon.py index bc50baf..28897bf 100644 --- a/tests/test_lldpSyncDaemon.py +++ b/tests/test_lldpSyncDaemon.py @@ -2,6 +2,7 @@ import sys # noinspection PyUnresolvedReferences import tests.mock_tables.dbconnector +import time modules_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -14,7 +15,7 @@ import lldp_syncd import lldp_syncd.conventions import lldp_syncd.daemon -from swsssdk import SonicV2Connector +from swsscommon.swsscommon import SonicV2Connector INPUT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'subproc_outputs') @@ -137,3 +138,44 @@ def test_remote_sys_capability_list(self): (if_name, if_attributes), = interface.items() capability_list = self.daemon.get_sys_capability_list(if_attributes, if_name, "fake_chassis_id") self.assertNotEqual(capability_list, []) + + def test_changed_deleted_interface(self): + parsed_update = self.daemon.parse_update(self._json) + self.daemon.sync(parsed_update) + db = create_dbconnector() + keys = db.keys(db.APPL_DB) + # Check if each lldp_rem_time_mark is changed + dump = {} + for k in keys: + if k != 'LLDP_LOC_CHASSIS': + if 'eth0' in k or 'Ethernet0' in k: + dump[k] = db.get(db.APPL_DB, k, 'lldp_rem_time_mark') + elif 'Ethernet100' in k: + dump[k] = db.get(db.APPL_DB, k, 'lldp_rem_port_desc') + + time.sleep(1) + # simulate lldp_rem_time_mark was changed or port description was changed or interface was removed + changed_json = self._json.copy() + changed_json['lldp']['interface'][0]['eth0']['age'] = '0 day, 05:09:12' + changed_json['lldp']['interface'][1]['Ethernet0']['age'] = '0 day, 05:09:15' + changed_json['lldp']['interface'][2]['Ethernet100']['port']['descr'] = "I'm a little teapot, too." + changed_json['lldp']['interface'].pop(3) # Remove interface Ethernet104 + + parsed_update = self.daemon.parse_update(changed_json) + self.daemon.sync(parsed_update) + keys = db.keys(db.APPL_DB) + + jo = {} + for k in keys: + if k != 'LLDP_LOC_CHASSIS': + if 'eth0' in k or 'Ethernet0' in k: + jo[k] = db.get(db.APPL_DB, k, 'lldp_rem_time_mark') + self.assertEqual(int(jo[k]), int(dump[k])+10) + elif 'Ethernet100' in k: + jo[k] = db.get(db.APPL_DB, k, 'lldp_rem_port_desc') + self.assertEqual(dump[k], "") + self.assertEqual(jo[k], "I'm a little teapot, too.") + else: + jo[k] = db.get_all(db.APPL_DB, k) + if 'LLDP_ENTRY_TABLE:Ethernet104' in jo: + self.fail("After removing Ethernet104, it is still found in APPL_DB!") \ No newline at end of file From bc6357191295d2682f44977f04522dc5bb7b69a3 Mon Sep 17 00:00:00 2001 From: Liu Shilong Date: Wed, 22 May 2024 09:44:04 +0800 Subject: [PATCH 6/7] Fix pipeline issue. (#66) * fix pipeline issue --- azure-pipelines.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index fffe920..46d1469 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -8,6 +8,10 @@ trigger: include: - '*' +parameters: +- name: dist + default: bullseye + variables: DIFF_COVER_CHECK_THRESHOLD: 80 DIFF_COVER_ENABLE: 'true' @@ -17,7 +21,7 @@ pool: vmImage: 'ubuntu-20.04' container: - image: sonicdev-microsoft.azurecr.io:443/sonic-slave-buster:latest + image: sonicdev-microsoft.azurecr.io:443/sonic-slave-bullseye:master steps: - task: DownloadPipelineArtifact@2 @@ -28,6 +32,9 @@ steps: artifact: sonic-buildimage.vs runVersion: 'latestFromBranch' runBranch: 'refs/heads/master' + patterns: | + target/debs/${{ parameters.dist }}/*.deb + target/python-wheels/${{ parameters.dist }}/*.whl displayName: "Download artifacts from latest sonic-buildimage build" - script: | @@ -41,21 +48,21 @@ steps: sudo dpkg -i libyang_1.*.deb sudo dpkg -i libswsscommon_1.0.0_amd64.deb sudo dpkg -i python3-swsscommon_1.0.0_amd64.deb - workingDirectory: $(Pipeline.Workspace)/target/debs/buster/ + workingDirectory: $(Pipeline.Workspace)/target/debs/${{ parameters.dist }}/ displayName: 'Install Debian dependencies' - script: | set -xe sudo pip3 install swsssdk-2.0.1-py3-none-any.whl sudo pip3 install sonic_py_common-1.0-py3-none-any.whl - workingDirectory: $(Pipeline.Workspace)/target/python-wheels/buster/ + workingDirectory: $(Pipeline.Workspace)/target/python-wheels/${{ parameters.dist }}/ displayName: 'Install Python dependencies' - script: | set -ex # Install .NET CORE curl -sSL https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - - sudo apt-add-repository https://packages.microsoft.com/debian/10/prod + sudo apt-add-repository https://packages.microsoft.com/debian/11/prod sudo apt-get update sudo apt-get install -y dotnet-sdk-5.0 displayName: "Install .NET CORE" From d5fa7937a4e38ce0356368977ab4ba89090b2209 Mon Sep 17 00:00:00 2001 From: Zhaohui Sun <94606222+ZhaohuiS@users.noreply.github.com> Date: Thu, 23 May 2024 08:33:32 +0800 Subject: [PATCH 7/7] Handle exception to avoid lldp_syncd crash (#65) * Handle exception smooth to avoid lldp_syncd crash Signed-off-by: Zhaohui Sun --- src/lldp_syncd/daemon.py | 2 ++ tests/test_lldpSyncDaemon.py | 41 +++++++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/lldp_syncd/daemon.py b/src/lldp_syncd/daemon.py index fde3002..73c9675 100644 --- a/src/lldp_syncd/daemon.py +++ b/src/lldp_syncd/daemon.py @@ -194,6 +194,8 @@ def source_update(self): logger.debug("Invoking lldpcli with: {}".format(cmd_local)) lldp_json = self._scrap_output(cmd) + if lldp_json is None: + return None lldp_json['lldp_loc_chassis'] = self._scrap_output(cmd_local) return lldp_json diff --git a/tests/test_lldpSyncDaemon.py b/tests/test_lldpSyncDaemon.py index 28897bf..727ace5 100644 --- a/tests/test_lldpSyncDaemon.py +++ b/tests/test_lldpSyncDaemon.py @@ -178,4 +178,43 @@ def test_changed_deleted_interface(self): else: jo[k] = db.get_all(db.APPL_DB, k) if 'LLDP_ENTRY_TABLE:Ethernet104' in jo: - self.fail("After removing Ethernet104, it is still found in APPL_DB!") \ No newline at end of file + self.fail("After removing Ethernet104, it is still found in APPL_DB!") + + @mock.patch('subprocess.check_output') + def test_invalid_chassis_name(self, mock_check_output): + # mock the invalid chassis name + mock_check_output.return_value = ''' + { + "local-chassis": { + "chassis": { + "chassis_name\1": { + "id": { + "type": "mac", + "value": "aa:bb:cc:dd:ee:ff" + }, + "descr": "SONiC Software Version: SONiC.20230531.22", + "capability": [ + { + "type": "Bridge", + "enabled": true + }, + { + "type": "Router", + "enabled": true + }, + { + "type": "Wlan", + "enabled": false + }, + { + "type": "Station", + "enabled": false + } + ] + } + } + } + } + ''' + result = self.daemon.source_update() + self.assertIsNone(result)