Skip to content

Commit 4dcfb61

Browse files
vivekrnvyxieca
authored andcommitted
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. #12{'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}]}}}}}#12 -- #012Traceback (most recent call last):#12 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')))})#12 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)#12 File "/usr/lib/python3.9/_strptime.py", line 562, in _strptime_time#012 tt = _strptime(data_string, format)[0]#12 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. #12{'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}]}}}}}#12 -- #012Traceback (most recent call last):#12 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')))})#12 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)#12 File "/usr/lib/python3.9/_strptime.py", line 562, in _strptime_time#012 tt = _strptime(data_string, format)[0]#12 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
1 parent df46ed4 commit 4dcfb61

File tree

2 files changed

+12
-7
lines changed

2 files changed

+12
-7
lines changed

src/lldp_syncd/daemon.py

+11-7
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,16 @@ def parse_time(time_str):
4444
}
4545
:return: parsed age in time ticks (or seconds)
4646
"""
47-
days, hour_min_secs = re.split(LLDPD_UPTIME_RE_SPLIT_PATTERN, time_str)
48-
struct_time = time.strptime(hour_min_secs, LLDPD_TIME_FORMAT)
49-
time_delta = datetime.timedelta(days=int(days), hours=struct_time.tm_hour,
50-
minutes=struct_time.tm_min,
51-
seconds=struct_time.tm_sec)
52-
return int(time_delta.total_seconds())
47+
try:
48+
days, hour_min_secs = re.split(LLDPD_UPTIME_RE_SPLIT_PATTERN, time_str)
49+
struct_time = time.strptime(hour_min_secs, LLDPD_TIME_FORMAT)
50+
time_delta = datetime.timedelta(days=int(days), hours=struct_time.tm_hour,
51+
minutes=struct_time.tm_min,
52+
seconds=struct_time.tm_sec)
53+
return int(time_delta.total_seconds())
54+
except ValueError:
55+
logger.exception("Failed to parse lldp age {} -- ".format(time_str))
56+
return 0
5357

5458

5559
class LldpSyncDaemon(SonicSyncDaemon):
@@ -264,7 +268,7 @@ def parse_update(self, lldp_json):
264268
parsed_interfaces[if_name].update({'lldp_rem_sys_cap_enabled':
265269
self.parse_sys_capabilities(
266270
capability_list, enabled=True)})
267-
if lldp_json['lldp_loc_chassis']:
271+
if lldp_json.get('lldp_loc_chassis'):
268272
loc_chassis_keys = ('lldp_loc_chassis_id_subtype',
269273
'lldp_loc_chassis_id',
270274
'lldp_loc_sys_name',

tests/test_lldpSyncDaemon.py

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ def test_sync_roundtrip(self):
9898
def test_timeparse(self):
9999
self.assertEqual(lldp_syncd.daemon.parse_time("0 day, 05:09:02"), make_seconds(0, 5, 9, 2))
100100
self.assertEqual(lldp_syncd.daemon.parse_time("2 days, 05:59:02"), make_seconds(2, 5, 59, 2))
101+
self.assertEqual(lldp_syncd.daemon.parse_time("-2 days, -23:-55:-02"), make_seconds(0, 0, 0, 0))
101102

102103
def parse_mgmt_ip(self, json_file):
103104
parsed_update = self.daemon.parse_update(json_file)

0 commit comments

Comments
 (0)