From f4793ebf0b5c4db04075c30d332d82b8a9ccf002 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 21 Dec 2025 10:10:12 +0530 Subject: [PATCH 1/3] lldp-syncd: handle unsupported LLDP port and chassis subtypes Signed-off-by: unknown Signed-off-by: KeshavSM10 --- src/lldp_syncd/daemon.py | 58 ++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/src/lldp_syncd/daemon.py b/src/lldp_syncd/daemon.py index e949ad1..87096f1 100644 --- a/src/lldp_syncd/daemon.py +++ b/src/lldp_syncd/daemon.py @@ -296,25 +296,35 @@ def parse_update(self, lldp_json): logger.exception("Failed to parse LLDPd JSON. \n{}\n -- ".format(lldp_json)) def parse_chassis(self, chassis_attributes): + + chassis_id_subtype = chassis_id = sys_name = descr = mgmt_ip = '' + try: if 'id' in chassis_attributes and 'id' not in chassis_attributes['id']: - sys_name = '' attributes = chassis_attributes - id_attributes = chassis_attributes['id'] + id_attributes = chassis_attributes.get('id', {}) else: (sys_name, attributes) = list(chassis_attributes.items())[0] - id_attributes = attributes.get('id', '') + id_attributes = attributes.get('id', {}) + + id_type = id_attributes.get('type') + + if id_type not in self.ChassisIdSubtypeMap.__members__: + logger.error( + "Unsupported LLDP chassis ID subtype: %s", + id_type, + ) + else: + chassis_id_subtype = str(self.ChassisIdSubtypeMap[id_type].value) + chassis_id = id_attributes.get('value', '') - chassis_id_subtype = str(self.ChassisIdSubtypeMap[id_attributes['type']].value) - chassis_id = id_attributes.get('value', '') descr = attributes.get('descr', '') mgmt_ip = attributes.get('mgmt-ip', '') if isinstance(mgmt_ip, list): mgmt_ip = ','.join(mgmt_ip) - except (KeyError, ValueError): - logger.exception("Could not infer system information from: {}" - .format(chassis_attributes)) - chassis_id_subtype = chassis_id = sys_name = descr = mgmt_ip = '' + + except (KeyError, AttributeError, TypeError): + logger.error("Could not infer system information from: %s", chassis_attributes) return (chassis_id_subtype, chassis_id, @@ -324,19 +334,27 @@ def parse_chassis(self, chassis_attributes): ) def parse_port(self, port_attributes): - port_identifiers = port_attributes.get('id') - try: - subtype = str(self.PortIdSubtypeMap[port_identifiers['type']].value) - value = port_identifiers['value'] + port_identifiers = port_attributes.get('id', {}) - except ValueError: - logger.exception("Could not infer chassis subtype from: {}".format(port_attributes)) - subtype, value = None + subtype = None + value = None - return (subtype, - value, - port_attributes.get('descr', ''), - ) + id_type = port_identifiers.get('type') + + if id_type not in self.PortIdSubtypeMap.__members__: + logger.error( + "Unsupported LLDP port ID subtype: %s", + id_type, + ) + else: + subtype = str(self.PortIdSubtypeMap[id_type].value) + value = port_identifiers.get('value', '') + + return ( + subtype, + value, + port_attributes.get('descr', ''), + ) def cache_diff(self, cache, update): """ From 88793b72a773bdd63687c3e0aa830806c291e1c5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Feb 2026 16:54:45 +0530 Subject: [PATCH 2/3] lldp-syncd: handle unsupported LLDP subtypes without traceback Signed-off-by: KeshavSM10 --- src/lldp_syncd/daemon.py | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/lldp_syncd/daemon.py b/src/lldp_syncd/daemon.py index 87096f1..40be2b2 100644 --- a/src/lldp_syncd/daemon.py +++ b/src/lldp_syncd/daemon.py @@ -302,21 +302,22 @@ def parse_chassis(self, chassis_attributes): try: if 'id' in chassis_attributes and 'id' not in chassis_attributes['id']: attributes = chassis_attributes - id_attributes = chassis_attributes.get('id', {}) + id_attributes = chassis_attributes.get('id') or {} else: (sys_name, attributes) = list(chassis_attributes.items())[0] - id_attributes = attributes.get('id', {}) + id_attributes = attributes.get('id') or {} id_type = id_attributes.get('type') if id_type not in self.ChassisIdSubtypeMap.__members__: - logger.error( - "Unsupported LLDP chassis ID subtype: %s", - id_type, - ) + logger.warning( + "lldp-syncd: unsupported chassis id subtype: %s", + id_type, + ) else: - chassis_id_subtype = str(self.ChassisIdSubtypeMap[id_type].value) - chassis_id = id_attributes.get('value', '') + chassis_id_subtype = str(self.ChassisIdSubtypeMap[id_type].value) + chassis_id = id_attributes.get('value', '') + descr = attributes.get('descr', '') mgmt_ip = attributes.get('mgmt-ip', '') @@ -334,23 +335,23 @@ def parse_chassis(self, chassis_attributes): ) def parse_port(self, port_attributes): - port_identifiers = port_attributes.get('id', {}) + port_identifiers = port_attributes.get('id') or {} - subtype = None - value = None + subtype = None + value = None - id_type = port_identifiers.get('type') + id_type = port_identifiers.get('type') - if id_type not in self.PortIdSubtypeMap.__members__: - logger.error( - "Unsupported LLDP port ID subtype: %s", + if id_type not in self.PortIdSubtypeMap.__members__: + logger.warning( + "lldp-syncd: unsupported port id subtype: %s", id_type, ) - else: + else: subtype = str(self.PortIdSubtypeMap[id_type].value) value = port_identifiers.get('value', '') - return ( + return ( subtype, value, port_attributes.get('descr', ''), From 656b67ef52cb690e3c1f1b6e0df437263ea525b2 Mon Sep 17 00:00:00 2001 From: KeshavSM10 Date: Fri, 13 Feb 2026 17:32:33 +0530 Subject: [PATCH 3/3] test: cover unsupported LLDP subtype paths Signed-off-by: KeshavSM10 --- tests/test_lldpSyncDaemon.py | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/test_lldpSyncDaemon.py b/tests/test_lldpSyncDaemon.py index 8dd0df7..3a2ff5c 100644 --- a/tests/test_lldpSyncDaemon.py +++ b/tests/test_lldpSyncDaemon.py @@ -218,6 +218,62 @@ def test_invalid_chassis_name(self, mock_check_output): ''' result = self.daemon.source_update() self.assertIsNone(result) + + def test_unsupported_port_subtype(self): + bad_json = { + "lldp": { + "interface": [ + { + "Ethernet1": { + "via": "LLDP", + "rid": "1", + "age": "0 day, 00:00:10", + "chassis": { + "id": {"type": "mac", "value": "aa:bb:cc:dd:ee:ff"} + }, + "port": { + "id": {"type": "unhandled", "value": "garbage"}, + "ttl": "120" + } + } + } + ] + } + } + + parsed = self.daemon.parse_update(bad_json) + + self.assertIn("Ethernet1", parsed) + self.assertIsNone(parsed["Ethernet1"]["lldp_rem_port_id_subtype"]) + self.assertEqual(parsed["Ethernet1"]["lldp_rem_port_id"], None) + + def test_unsupported_chassis_subtype(self): + bad_json = { + "lldp": { + "interface": [ + { + "Ethernet2": { + "via": "LLDP", + "rid": "1", + "age": "0 day, 00:00:10", + "chassis": { + "id": {"type": "unhandled", "value": "garbage"} + }, + "port": { + "id": {"type": "ifname", "value": "Ethernet2"}, + "ttl": "120" + } + } + } + ] + } + } + + parsed = self.daemon.parse_update(bad_json) + + self.assertIn("Ethernet2", parsed) + self.assertEqual(parsed["Ethernet2"]["lldp_rem_chassis_id_subtype"], "") + self.assertEqual(parsed["Ethernet2"]["lldp_rem_chassis_id"], "") def test_changed_interface(self):