LLDP links not created due to not storing lldpLocPortId

I have been troubleshooting lldp links with my Nortel/Avaya/(Now Extreme) switches and have discovered that the way they denote lldpLocPortId and lldpRemPortId is with a MAC address that does not seem to exist anywhere else.

It looks like the lldpLocPortId is not stored in the ports table. I would think it would make it easier to link ports if it was stored as it is what lldp is telling the remote side what the id is.

Currently links are made by trying to matching based on ifDescr, ifName, and then ifAlias. As seen below that will never match on these switches. ifDescr has "Avaya Virtual Services Platform 7024XLS Module - " prepended so lldpRemPortDesc will not match ifDescr and it feels hacky to match on “%lldpRemPortDesc”.

So I was wondering if there was a reason lldpLocPortId is not stored in the ports tables. And if not do you accept database changes in pull requests.

I am proposing adding lldpLocPortId to the ports table and then try linking lldpLocPortId with lldpRemPortId first and then fall back to the current methods.

I do not know if this is a valid method for other lldp supported platforms, but it seems like it would as long as those platforms support the lldpLocPortId and lldpRemPortId.

The SNMP for the lldpLocPortId for this example port:

lldpLocPortId[23] = "A0 12 90 70 05 17 "

The Array from discovery for the link:

array (
‘lldpRemChassisIdSubtype’ => ‘4’,
‘lldpRemChassisId’ => ‘A0 12 90 6D E1 00’,
‘lldpRemPortIdSubtype’ => ‘3’,
‘lldpRemPortId’ => ‘A0 12 90 6D E1 17’,
‘lldpRemPortDesc’ => ‘Port 23’,
‘lldpRemSysName’ => ‘NOC-Core-7k’,
‘lldpRemSysDesc’ => ‘Virtual Services Platform 7024XLS HW:08 FW:10.3.1.5 SW:v10.3.3.000’,
‘lldpRemSysCapSupported’ => ‘28’,
‘lldpRemSysCapEnabled’ => ‘20’,
‘lldpRemManAddr’ => ‘10.0.5.51’,
),

The links table row for that link:

MariaDB [librenms]> select * from links where id = 69;
id 69
local_port_id 2602
local_device_id 43
remote_port_id NULL
active 1
protocol lldp
remote_hostname NOC-Core-7k
remote_device_id 45
remote_port A0 12 90 6D E1 17
remote_platform NULL
remote_version Virtual Services Platform 7024XLS HW:08 FW:10.3.1.5 SW:v10.3.3.00

The ports table entry for the port on the remote side:

MariaDB [librenms]> select port_id,ifDescr,ifName,portName,ifIndex,ifAlias,ifPhysAddress from ports where port_id =2378;
port_id 2378
ifDescr Avaya Virtual Services Platform 7024XLS Module - Port 23
ifName ifc23 (Slot: 1 Port: 23)
portName NULL
ifIndex 23
ifAlias IST to DF-7k-Core 1
ifPhysAddress a012906de100

Hi @sgocken
Do you have a way to predict the lldpPortId that will be transmitted by a port ? Looking at the data you attached, the ifPhysAddress of the remote side, matches the lldpRemChassisId of the discovery side. But I don’t see any way to match the port in the data.

Libre already grabs via SNMP what lldp calls a port, but doesn’t store it in the database.

The is the same string it gives out over LLDP for that port. So if a new column was added to the ports table and lldpLocPortId was stored, then on the link function of discovery lldpRemPortId would match with a previous stored lldpLocPortId. The string that is lldpLocPortId is the same string it advertises to other devices. At least on all my gear.

OK. Concerning the lldpLocPortId in the Ports table would probably make it possible to get the LLDP mapping but clearly does not make sense from a DB design perspective.

Could you check in the vendor specific MIB if there is a better way that this ?

I agree that making database changes should be avoided unless needed.
My argument for adding that as it seems to be universal to any device that supports the LLDP-MIB.

As an example this is what a cisco says:

lldpLocPortId[1] = “Fa0/1”
lldpLocPortId[2] = “Fa0/2”
lldpLocPortId[3] = “Fa0/3”
lldpLocPortId[4] = “Fa0/4”

Now I agree that you should be able to get the mapping with ifDescr or ifName, but this seems to be more universal and should be able to make the mapping process more straight forward.

As an example of someone else having the same problem:

I would think this method would fix their issue as well.

I have started my own fork to implement it.

It is not “avoid unless needed”, but really “avoid because not possible”. The real issue I see here is the fact that Port is populated by parsing IFMIB in the Ports module, and LLDP is parsed with the discovery-protocols module. You can disable one module and keep the other enabled, and that would forbid to add data from one module in the table of the other … discovery-protocols would have no way to create a port that does not already exist (missing mandatory data) etc etc.

May be creating a new table, that would link a LibreNMS-Port-ID (if available, and NULL if not) and lldpLocPortId could solve this.

Well I had not yet run into the not possible, so that is very useful info.
I like the idea of a new table. I think I will work in that direction.

Thanks

I would suggest you to open a draft PullRequest in github so we can discuss this with the code, which is usually easier.

I have the code working and just put in my PR.
I ended up not creating a new table as I would have to reinvent the wheel, so I just collected the lldpLocPortId in the ports.inc.php

Hi @sgocken
This is not possible to use the ports table for this IMHO. LibreNMS structure has a huge amount of port, only part of them probably have lldp in use. And LLDP data is not polled in the ports module (so you could run xdp_discovery and not ports, which would fail)
As LLDP is a protocol per se, you need a table that links the LLDP data (with it’s own id), the device_id (mandatory) and the port_id (nullable). That way you can keep all the LLDP data (and not only lldpLocPortId) and do the magic out of it to populate the links table.