6363use LibreNMS \RRD \RrdDefinition ;
6464use LibreNMS \Util \IP ;
6565use LibreNMS \Util \Mac ;
66+ use LibreNMS \Util \StringHelpers ;
6667use SnmpQuery ;
6768
6869class 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 ]));
0 commit comments