Skip to content

Commit 9aa2291

Browse files
Npeca75PipoCanaja
andauthored
[cisco] Add vlans on trunk ports (librenms#18360)
* [cisco] Add vlans on trunk ports * Refactor VLAN processing logic in Cisco.php * Fix formatting in Cisco.php * Fix formatting issues in Cisco.php again ... * Fix tests * Fix existing logic * More fix * and tests * Update iosxe_c9800.json tests * better vlan mapping But still incomplete c9800 data I suppose, let's check * once more * test data --------- Co-authored-by: PipoCanaja <[email protected]>
1 parent 050e59d commit 9aa2291

File tree

2 files changed

+63
-7
lines changed

2 files changed

+63
-7
lines changed

LibreNMS/OS/Shared/Cisco.php

100755100644
Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
use LibreNMS\RRD\RrdDefinition;
6464
use LibreNMS\Util\IP;
6565
use LibreNMS\Util\Mac;
66+
use LibreNMS\Util\StringHelpers;
6667
use SnmpQuery;
6768

6869
class Cisco extends OS implements
@@ -996,17 +997,48 @@ public function discoverVlanPorts(Collection $vlans): Collection
996997
return $ports;
997998
}
998999

999-
// Only returns 'untagged' vlan for each port (either access ports, or native vlan of a trunk)
1000-
// stored for use in below loop
10011000
$native_vlans_raw = SnmpQuery::abortOnFailure()->walk([
1002-
'CISCO-VTP-MIB::vlanTrunkPortNativeVlan',
1001+
'CISCO-VTP-MIB::vlanTrunkPortTable',
10031002
'CISCO-VLAN-MEMBERSHIP-MIB::vmVlan',
10041003
])->table(1);
10051004

10061005
// Hash Table indexed by vlans and ifIndexes
10071006
foreach ($native_vlans_raw as $ifindex => $data) {
1007+
// Only returns 'untagged' vlan for each port (either access ports, or native vlan of a trunk)
1008+
// stored for use in below loop
10081009
$vlan_id = $data['CISCO-VLAN-MEMBERSHIP-MIB::vmVlan'] ?? $data['CISCO-VTP-MIB::vlanTrunkPortNativeVlan'] ?? 0;
1009-
$isNative[$vlan_id][$ifindex] = 1;
1010+
if ($vlan_id > 0) {
1011+
$isNative[$vlan_id][$ifindex] = 1;
1012+
}
1013+
if (isset($data['CISCO-VTP-MIB::vlanTrunkPortDynamicState']) && $data['CISCO-VTP-MIB::vlanTrunkPortDynamicState'] == 2) {
1014+
continue; // This port is not a trunk, so continue to next one
1015+
}
1016+
// Only returns 'tagged' vlan for each port
1017+
// stored for use in below loop
1018+
if (isset($data['CISCO-VTP-MIB::vlanTrunkPortVlansXmitJoined'])) {
1019+
$vlanIds = StringHelpers::bitsToIndices($data['CISCO-VTP-MIB::vlanTrunkPortVlansXmitJoined']);
1020+
foreach ($vlanIds as $vlan_id) {
1021+
$isNative[$vlan_id - 1][$ifindex] = $isNative[$vlan_id - 1][$ifindex] ?? 0;
1022+
}
1023+
}
1024+
if (isset($data['CISCO-VTP-MIB::vlanTrunkPortVlansXmitJoined2k'])) {
1025+
$vlanIds = StringHelpers::bitsToIndices($data['CISCO-VTP-MIB::vlanTrunkPortVlansXmitJoined2k']);
1026+
foreach ($vlanIds as $vlan_id) {
1027+
$isNative[$vlan_id + 1023][$ifindex] = $isNative[$vlan_id + 1023][$ifindex] ?? 0;
1028+
}
1029+
}
1030+
if (isset($data['CISCO-VTP-MIB::vlanTrunkPortVlansXmitJoined3k'])) {
1031+
$vlanIds = StringHelpers::bitsToIndices($data['CISCO-VTP-MIB::vlanTrunkPortVlansXmitJoined3k']);
1032+
foreach ($vlanIds as $vlan_id) {
1033+
$isNative[$vlan_id + 2047][$ifindex] = $isNative[$vlan_id + 2047][$ifindex] ?? 0;
1034+
}
1035+
}
1036+
if (isset($data['CISCO-VTP-MIB::vlanTrunkPortVlansXmitJoined4k'])) {
1037+
$vlanIds = StringHelpers::bitsToIndices($data['CISCO-VTP-MIB::vlanTrunkPortVlansXmitJoined4k']);
1038+
foreach ($vlanIds as $vlan_id) {
1039+
$isNative[$vlan_id + 3071][$ifindex] = $isNative[$vlan_id + 3071][$ifindex] ?? 0;
1040+
}
1041+
}
10101042
}
10111043

10121044
// process all the discovered vlans
@@ -1035,13 +1067,13 @@ public function discoverVlanPorts(Collection $vlans): Collection
10351067
'priority' => $data['BRIDGE-MIB::dot1dStpPortPriority'] ?? 0,
10361068
'state' => $data['BRIDGE-MIB::dot1dStpPortState'] ?? 'unknown',
10371069
'cost' => $data['BRIDGE-MIB::dot1dStpPortPathCost'] ?? 0,
1038-
'untagged' => isset($isNative[$vlan_id][$ifindex]),
1070+
'untagged' => isset($isNative[$vlan_id][$ifindex]) && $isNative[$vlan_id][$ifindex] > 0,
10391071
'port_id' => PortCache::getIdFromIfIndex($ifindex, $this->getDeviceId()) ?? 0, // ifIndex from device
10401072
]));
10411073
}
10421074
}
10431075

1044-
// Let's do the native/access that were not processed above
1076+
// Let's do the ones that were not processed above
10451077
// if we have isNative for this vlan, then we check which ifindexes are not yet processed and we add them.
10461078
if (isset($isNative[$vlan_id])) {
10471079
foreach ($isNative[$vlan_id] as $ifindex => $value) {
@@ -1051,7 +1083,7 @@ public function discoverVlanPorts(Collection $vlans): Collection
10511083
$ports->push(new PortVlan([
10521084
'vlan' => $vlan_id,
10531085
'baseport' => $this->bridgePortFromIfIndex($ifindex),
1054-
'untagged' => 1,
1086+
'untagged' => $value,
10551087
'state' => 'unknown',
10561088
'port_id' => PortCache::getIdFromIfIndex($ifindex, $this->getDeviceId()) ?? 0, // ifIndex from device,
10571089
]));

tests/data/iosxe_c9800.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5729,6 +5729,22 @@
57295729
"cost": 0,
57305730
"untagged": 1
57315731
},
5732+
{
5733+
"vlan": 1,
5734+
"baseport": 0,
5735+
"priority": 0,
5736+
"state": "unknown",
5737+
"cost": 0,
5738+
"untagged": 0
5739+
},
5740+
{
5741+
"vlan": 5,
5742+
"baseport": 0,
5743+
"priority": 0,
5744+
"state": "unknown",
5745+
"cost": 0,
5746+
"untagged": 0
5747+
},
57325748
{
57335749
"vlan": 52,
57345750
"baseport": 0,
@@ -5752,6 +5768,14 @@
57525768
"state": "unknown",
57535769
"cost": 0,
57545770
"untagged": 1
5771+
},
5772+
{
5773+
"vlan": 72,
5774+
"baseport": 0,
5775+
"priority": 0,
5776+
"state": "unknown",
5777+
"cost": 0,
5778+
"untagged": 0
57555779
}
57565780
]
57575781
}

0 commit comments

Comments
 (0)