mirror of
				https://github.com/librenms/librenms.git
				synced 2024-10-07 16:52:45 +00:00 
			
		
		
		
	STP fix, only try contexts on Cisco (#13767)
* STP fix, only try contexts on Cisco Only Cisco is known to support this type of polling * merge, not push. * Fix collection construction * Fixed the function signature in Interface def * fixed signature here as well * Lighter code to return a collection of Stp instances * Type enforced in signatures * missing implement for Cisco Class * style * Collection methods are immutable indeed 😠 * nullable vlan Co-authored-by: PipoCanaja <38363551+PipoCanaja@users.noreply.github.com>
This commit is contained in:
		@@ -32,7 +32,8 @@ interface StpInstanceDiscovery
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Discover STP instances on the device.
 | 
					     * Discover STP instances on the device.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  string  $vlan  Vlan ID of the instance to discover (or null for default)
 | 
				
			||||||
     * @return Collection<\App\Models\Stp>
 | 
					     * @return Collection<\App\Models\Stp>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function discoverStpInstances(): Collection;
 | 
					    public function discoverStpInstances(?string $vlan = null): Collection;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,11 +31,13 @@ use App\Models\Mempool;
 | 
				
			|||||||
use App\Models\PortsNac;
 | 
					use App\Models\PortsNac;
 | 
				
			||||||
use App\Models\Sla;
 | 
					use App\Models\Sla;
 | 
				
			||||||
use Illuminate\Support\Arr;
 | 
					use Illuminate\Support\Arr;
 | 
				
			||||||
 | 
					use Illuminate\Support\Collection;
 | 
				
			||||||
use LibreNMS\Device\Processor;
 | 
					use LibreNMS\Device\Processor;
 | 
				
			||||||
use LibreNMS\Interfaces\Discovery\MempoolsDiscovery;
 | 
					use LibreNMS\Interfaces\Discovery\MempoolsDiscovery;
 | 
				
			||||||
use LibreNMS\Interfaces\Discovery\OSDiscovery;
 | 
					use LibreNMS\Interfaces\Discovery\OSDiscovery;
 | 
				
			||||||
use LibreNMS\Interfaces\Discovery\ProcessorDiscovery;
 | 
					use LibreNMS\Interfaces\Discovery\ProcessorDiscovery;
 | 
				
			||||||
use LibreNMS\Interfaces\Discovery\SlaDiscovery;
 | 
					use LibreNMS\Interfaces\Discovery\SlaDiscovery;
 | 
				
			||||||
 | 
					use LibreNMS\Interfaces\Discovery\StpInstanceDiscovery;
 | 
				
			||||||
use LibreNMS\Interfaces\Polling\NacPolling;
 | 
					use LibreNMS\Interfaces\Polling\NacPolling;
 | 
				
			||||||
use LibreNMS\Interfaces\Polling\SlaPolling;
 | 
					use LibreNMS\Interfaces\Polling\SlaPolling;
 | 
				
			||||||
use LibreNMS\OS;
 | 
					use LibreNMS\OS;
 | 
				
			||||||
@@ -43,7 +45,14 @@ use LibreNMS\OS\Traits\YamlOSDiscovery;
 | 
				
			|||||||
use LibreNMS\RRD\RrdDefinition;
 | 
					use LibreNMS\RRD\RrdDefinition;
 | 
				
			||||||
use LibreNMS\Util\IP;
 | 
					use LibreNMS\Util\IP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Cisco extends OS implements OSDiscovery, SlaDiscovery, ProcessorDiscovery, MempoolsDiscovery, NacPolling, SlaPolling
 | 
					class Cisco extends OS implements
 | 
				
			||||||
 | 
					    OSDiscovery,
 | 
				
			||||||
 | 
					    SlaDiscovery,
 | 
				
			||||||
 | 
					    StpInstanceDiscovery,
 | 
				
			||||||
 | 
					    ProcessorDiscovery,
 | 
				
			||||||
 | 
					    MempoolsDiscovery,
 | 
				
			||||||
 | 
					    NacPolling,
 | 
				
			||||||
 | 
					    SlaPolling
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use YamlOSDiscovery {
 | 
					    use YamlOSDiscovery {
 | 
				
			||||||
        YamlOSDiscovery::discoverOS as discoverYamlOS;
 | 
					        YamlOSDiscovery::discoverOS as discoverYamlOS;
 | 
				
			||||||
@@ -520,6 +529,20 @@ class Cisco extends OS implements OSDiscovery, SlaDiscovery, ProcessorDiscovery,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function discoverStpInstances(?string $vlan = null): Collection
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $vlans = $this->getDevice()->vlans;
 | 
				
			||||||
 | 
					        $instances = new Collection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // attempt to discover context based vlan instances
 | 
				
			||||||
 | 
					        foreach ($vlans->isEmpty() ? [null] : $vlans as $vlan) {
 | 
				
			||||||
 | 
					            $vlan = (empty($vlan->vlan_vlan) || $vlan->vlan_vlan == '1') ? null : (string) $vlan->vlan_vlan;
 | 
				
			||||||
 | 
					            $instances = $instances->merge(parent::discoverStpInstances($vlan));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $instances;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected function getMainSerial()
 | 
					    protected function getMainSerial()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $serial_output = snmp_get_multi($this->getDeviceArray(), ['entPhysicalSerialNum.1', 'entPhysicalSerialNum.1001'], '-OQUs', 'ENTITY-MIB:OLD-CISCO-CHASSIS-MIB');
 | 
					        $serial_output = snmp_get_multi($this->getDeviceArray(), ['entPhysicalSerialNum.1', 'entPhysicalSerialNum.1001'], '-OQUs', 'ENTITY-MIB:OLD-CISCO-CHASSIS-MIB');
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,7 @@ use SnmpQuery;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
trait BridgeMib
 | 
					trait BridgeMib
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public function discoverStpInstances(): Collection
 | 
					    public function discoverStpInstances(?string $vlan = null): Collection
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $protocol = SnmpQuery::get('BRIDGE-MIB::dot1dStpProtocolSpecification.0')->value();
 | 
					        $protocol = SnmpQuery::get('BRIDGE-MIB::dot1dStpProtocolSpecification.0')->value();
 | 
				
			||||||
        // 1 = unknown (mstp?), 3 = ieee8021d
 | 
					        // 1 = unknown (mstp?), 3 = ieee8021d
 | 
				
			||||||
@@ -44,60 +44,53 @@ trait BridgeMib
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $timeFactor = $this->stpTimeFactor ?? 0.01;
 | 
					        $timeFactor = $this->stpTimeFactor ?? 0.01;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $vlans = $protocol == 1 ? $this->getDevice()->vlans : new Collection;
 | 
					        // fetch STP config and store it
 | 
				
			||||||
        $instances = new Collection;
 | 
					        $stp = SnmpQuery::context("$vlan", 'vlan-')->enumStrings()->get([
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dBaseBridgeAddress.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpProtocolSpecification.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpPriority.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpTimeSinceTopologyChange.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpTopChanges.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpDesignatedRoot.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpRootCost.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpRootPort.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpMaxAge.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpHelloTime.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpHoldTime.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpForwardDelay.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpBridgeMaxAge.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpBridgeHelloTime.0',
 | 
				
			||||||
 | 
					            'BRIDGE-MIB::dot1dStpBridgeForwardDelay.0',
 | 
				
			||||||
 | 
					        ])->values();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($vlans->isEmpty() ? [null] : $vlans as $vlan) {
 | 
					        if (empty($stp)) {
 | 
				
			||||||
            // fetch STP config and store it
 | 
					            return new Collection;
 | 
				
			||||||
            $vlan = (empty($vlan->vlan_vlan) || $vlan->vlan_vlan == '1') ? null : $vlan->vlan_vlan;
 | 
					 | 
				
			||||||
            $instance = SnmpQuery::context("$vlan", 'vlan-')->enumStrings()->get([
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dBaseBridgeAddress.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpProtocolSpecification.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpPriority.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpTimeSinceTopologyChange.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpTopChanges.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpDesignatedRoot.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpRootCost.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpRootPort.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpMaxAge.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpHelloTime.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpHoldTime.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpForwardDelay.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpBridgeMaxAge.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpBridgeHelloTime.0',
 | 
					 | 
				
			||||||
                'BRIDGE-MIB::dot1dStpBridgeForwardDelay.0',
 | 
					 | 
				
			||||||
            ]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $stp = $instance->values();
 | 
					 | 
				
			||||||
            if (empty($stp)) {
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            \Log::debug('VLAN: ' . ($vlan ?: 1) . " Bridge: {$stp['BRIDGE-MIB::dot1dBaseBridgeAddress.0']} DR: {$stp['BRIDGE-MIB::dot1dStpDesignatedRoot.0']}");
 | 
					 | 
				
			||||||
            $bridge = Rewrite::macToHex($stp['BRIDGE-MIB::dot1dBaseBridgeAddress.0'] ?? '');
 | 
					 | 
				
			||||||
            $drBridge = Rewrite::macToHex($stp['BRIDGE-MIB::dot1dStpDesignatedRoot.0'] ?? '');
 | 
					 | 
				
			||||||
            $instances->push(new \App\Models\Stp([
 | 
					 | 
				
			||||||
                'vlan' => $vlan,
 | 
					 | 
				
			||||||
                'rootBridge' => $bridge == $drBridge ? 1 : 0,
 | 
					 | 
				
			||||||
                'bridgeAddress' => $bridge,
 | 
					 | 
				
			||||||
                'protocolSpecification' => $stp['BRIDGE-MIB::dot1dStpProtocolSpecification.0'] ?? 'unknown',
 | 
					 | 
				
			||||||
                'priority' => $stp['BRIDGE-MIB::dot1dStpPriority.0'] ?? 0,
 | 
					 | 
				
			||||||
                'timeSinceTopologyChange' => substr($stp['BRIDGE-MIB::dot1dStpTimeSinceTopologyChange.0'] ?? '', 0, -2) ?: 0,
 | 
					 | 
				
			||||||
                'topChanges' => $stp['BRIDGE-MIB::dot1dStpTopChanges.0'] ?? 0,
 | 
					 | 
				
			||||||
                'designatedRoot' => $drBridge,
 | 
					 | 
				
			||||||
                'rootCost' => $stp['BRIDGE-MIB::dot1dStpRootCost.0'] ?? 0,
 | 
					 | 
				
			||||||
                'rootPort' => $stp['BRIDGE-MIB::dot1dStpRootPort.0'] ?? 0,
 | 
					 | 
				
			||||||
                'maxAge' => ($stp['BRIDGE-MIB::dot1dStpMaxAge.0'] ?? 0) * $timeFactor,
 | 
					 | 
				
			||||||
                'helloTime' => ($stp['BRIDGE-MIB::dot1dStpHelloTime.0'] ?? 0) * $timeFactor,
 | 
					 | 
				
			||||||
                'holdTime' => ($stp['BRIDGE-MIB::dot1dStpHoldTime.0'] ?? 0) * $timeFactor,
 | 
					 | 
				
			||||||
                'forwardDelay' => ($stp['BRIDGE-MIB::dot1dStpForwardDelay.0'] ?? 0) * $timeFactor,
 | 
					 | 
				
			||||||
                'bridgeMaxAge' => ($stp['BRIDGE-MIB::dot1dStpBridgeMaxAge.0'] ?? 0) * $timeFactor,
 | 
					 | 
				
			||||||
                'bridgeHelloTime' => ($stp['BRIDGE-MIB::dot1dStpBridgeHelloTime.0'] ?? 0) * $timeFactor,
 | 
					 | 
				
			||||||
                'bridgeForwardDelay' => ($stp['BRIDGE-MIB::dot1dStpBridgeForwardDelay.0'] ?? 0) * $timeFactor,
 | 
					 | 
				
			||||||
            ]));
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $instances;
 | 
					        \Log::debug('VLAN: ' . ($vlan ?: 1) . " Bridge: {$stp['BRIDGE-MIB::dot1dBaseBridgeAddress.0']} DR: {$stp['BRIDGE-MIB::dot1dStpDesignatedRoot.0']}");
 | 
				
			||||||
 | 
					        $bridge = Rewrite::macToHex($stp['BRIDGE-MIB::dot1dBaseBridgeAddress.0'] ?? '');
 | 
				
			||||||
 | 
					        $drBridge = Rewrite::macToHex($stp['BRIDGE-MIB::dot1dStpDesignatedRoot.0'] ?? '');
 | 
				
			||||||
 | 
					        $instance = new \App\Models\Stp([
 | 
				
			||||||
 | 
					            'vlan' => $vlan,
 | 
				
			||||||
 | 
					            'rootBridge' => $bridge == $drBridge ? 1 : 0,
 | 
				
			||||||
 | 
					            'bridgeAddress' => $bridge,
 | 
				
			||||||
 | 
					            'protocolSpecification' => $stp['BRIDGE-MIB::dot1dStpProtocolSpecification.0'] ?? 'unknown',
 | 
				
			||||||
 | 
					            'priority' => $stp['BRIDGE-MIB::dot1dStpPriority.0'] ?? 0,
 | 
				
			||||||
 | 
					            'timeSinceTopologyChange' => substr($stp['BRIDGE-MIB::dot1dStpTimeSinceTopologyChange.0'] ?? '', 0, -2) ?: 0,
 | 
				
			||||||
 | 
					            'topChanges' => $stp['BRIDGE-MIB::dot1dStpTopChanges.0'] ?? 0,
 | 
				
			||||||
 | 
					            'designatedRoot' => $drBridge,
 | 
				
			||||||
 | 
					            'rootCost' => $stp['BRIDGE-MIB::dot1dStpRootCost.0'] ?? 0,
 | 
				
			||||||
 | 
					            'rootPort' => $stp['BRIDGE-MIB::dot1dStpRootPort.0'] ?? 0,
 | 
				
			||||||
 | 
					            'maxAge' => ($stp['BRIDGE-MIB::dot1dStpMaxAge.0'] ?? 0) * $timeFactor,
 | 
				
			||||||
 | 
					            'helloTime' => ($stp['BRIDGE-MIB::dot1dStpHelloTime.0'] ?? 0) * $timeFactor,
 | 
				
			||||||
 | 
					            'holdTime' => ($stp['BRIDGE-MIB::dot1dStpHoldTime.0'] ?? 0) * $timeFactor,
 | 
				
			||||||
 | 
					            'forwardDelay' => ($stp['BRIDGE-MIB::dot1dStpForwardDelay.0'] ?? 0) * $timeFactor,
 | 
				
			||||||
 | 
					            'bridgeMaxAge' => ($stp['BRIDGE-MIB::dot1dStpBridgeMaxAge.0'] ?? 0) * $timeFactor,
 | 
				
			||||||
 | 
					            'bridgeHelloTime' => ($stp['BRIDGE-MIB::dot1dStpBridgeHelloTime.0'] ?? 0) * $timeFactor,
 | 
				
			||||||
 | 
					            'bridgeForwardDelay' => ($stp['BRIDGE-MIB::dot1dStpBridgeForwardDelay.0'] ?? 0) * $timeFactor,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return (new Collection())->push($instance);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function discoverStpPorts(Collection $stpInstances): Collection
 | 
					    public function discoverStpPorts(Collection $stpInstances): Collection
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user