From f4dde980ffe681b1d663a792ecde34b8c4d663dd Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Tue, 16 Aug 2022 09:19:35 +0100 Subject: [PATCH] #914 change from silent_ports to macsuck_no_deviceport --- lib/App/Netdisco/Configuration.pm | 6 +- .../Worker/Plugin/Discover/Neighbors.pm | 18 ----- .../Netdisco/Worker/Plugin/Macsuck/Nodes.pm | 70 ++++++++++++++----- share/config.yml | 2 +- 4 files changed, 55 insertions(+), 41 deletions(-) diff --git a/lib/App/Netdisco/Configuration.pm b/lib/App/Netdisco/Configuration.pm index 04008392..404a005e 100644 --- a/lib/App/Netdisco/Configuration.pm +++ b/lib/App/Netdisco/Configuration.pm @@ -199,10 +199,10 @@ if (ref {} eq ref setting('device_identity')) { } else { config->{'device_identity'} ||= [] } -if (ref {} eq ref setting('silent_ports')) { - config->{'silent_ports'} = [ setting('silent_ports') ]; +if (ref {} eq ref setting('macsuck_no_deviceport')) { + config->{'macsuck_no_deviceport'} = [ setting('macsuck_no_deviceport') ]; } -else { config->{'silent_ports'} ||= [] } +else { config->{'macsuck_no_deviceport'} ||= [] } # copy devices_no and devices_only into others foreach my $name (qw/devices_no devices_only diff --git a/lib/App/Netdisco/Worker/Plugin/Discover/Neighbors.pm b/lib/App/Netdisco/Worker/Plugin/Discover/Neighbors.pm index d370eae2..19f3e9d5 100644 --- a/lib/App/Netdisco/Worker/Plugin/Discover/Neighbors.pm +++ b/lib/App/Netdisco/Worker/Plugin/Discover/Neighbors.pm @@ -166,24 +166,6 @@ sub store_neighbors { next NEIGHBOR; } - if (scalar @{ setting('silent_ports') }) { - my @silentmaps = @{ setting('silent_ports') }; - - foreach my $map (@silentmaps) { - next unless ref {} eq ref $map; - - foreach my $key (sort keys %$map) { - # lhs matches device, rhs matches port - next unless (check_acl_only($device, $key) - and check_acl_only($portrow, $map->{$key})); - - debug sprintf ' [%s] neigh - port %s requested to be silent - skipping', - $device->ip, $port; - next NEIGHBOR; - } - } - } - my $remote_ip = $c_ip->{$entry}; my $remote_port = undef; my $remote_type = Encode::decode('UTF-8', $c_platform->{$entry} || ''); diff --git a/lib/App/Netdisco/Worker/Plugin/Macsuck/Nodes.pm b/lib/App/Netdisco/Worker/Plugin/Macsuck/Nodes.pm index f55e3ed5..ea161559 100644 --- a/lib/App/Netdisco/Worker/Plugin/Macsuck/Nodes.pm +++ b/lib/App/Netdisco/Worker/Plugin/Macsuck/Nodes.pm @@ -292,6 +292,28 @@ sub walk_fwtable { my $skiplist = {}; # ports through which we can see another device my $cache = {}; + my $ignorelist = {}; # ports suppressed by macsuck_no_deviceport + if (scalar @{ setting('macsuck_no_deviceport') }) { + my @ignoremaps = @{ setting('macsuck_no_deviceport') }; + + foreach my $map (@ignoremaps) { + next unless ref {} eq ref $map; + + foreach my $key (sort keys %$map) { + # lhs matches device, rhs matches port + next unless check_acl_only($device, $key); + + foreach my $port (keys %$device_ports) { + next unless check_acl_only($device_ports->{$port}, $map->{$key}); + + ++$ignorelist->{$port}; + debug sprintf ' [%s] macsuck %s - port suppressed by macsuck_no_deviceport', + $device->ip, $port; + } + } + } + } + my $snmp = App::Netdisco::Transport::SNMP->reader_for($device) or return $cache; # already checked! @@ -307,24 +329,25 @@ sub walk_fwtable { # to map forwarding table port to device port we have # fw_port -> bp_index -> interfaces - while (my ($idx, $mac) = each %$fw_mac) { + MAC: while (my ($idx, $mac) = each %$fw_mac) { my $bp_id = $fw_port->{$idx}; - next unless check_mac($mac, $device); + next MAC unless check_mac($mac, $device); unless (defined $bp_id) { debug sprintf ' [%s] macsuck %s - %s has no fw_port mapping - skipping.', $device->ip, $mac, $idx; - next; + next MAC; } - my $iid = $bp_index->{$bp_id}; + my $iid = $bp_index->{$bp_id}; + my $vlan = $fw_vlan->{$idx} || $comm_vlan || '0'; unless (defined $iid) { debug sprintf ' [%s] macsuck %s - port %s has no bp_index mapping - skipping.', $device->ip, $mac, $bp_id; - next; + next MAC; } # WRT #475 this is SAFE because we check against known ports below @@ -335,29 +358,38 @@ sub walk_fwtable { debug sprintf ' [%s] macsuck %s - iid %s has no port mapping - skipping.', $device->ip, $mac, $iid; - next; + next MAC; + } + + # this uses the cached $ports resultset to limit hits on the db + my $device_port = $device_ports->{$port}; + + if (exists $ignorelist->{$port}) { + # stash in the skiplist so that node search works for neighbor + # (besides this, skiplist is not used for ignorelist ports) + $skiplist->{$port} = [ $vlan, $mac ] if exists $port_macs->{$mac}; + + debug sprintf + ' [%s] macsuck %s - port %s is suppressed by config - skipping.', + $device->ip, $mac, $port; + next MAC; } if (exists $skiplist->{$port}) { debug sprintf ' [%s] macsuck %s - seen another device thru port %s - skipping.', $device->ip, $mac, $port; - next; + next MAC; } - # this uses the cached $ports resultset to limit hits on the db - my $device_port = $device_ports->{$port}; - # WRT #475 ... see? :-) unless (defined $device_port) { debug sprintf ' [%s] macsuck %s - port %s is not in database - skipping.', $device->ip, $mac, $port; - next; + next MAC; } - my $vlan = $fw_vlan->{$idx} || $comm_vlan || '0'; - # check to see if the port is connected to another device # and if we have that device in the database. @@ -391,7 +423,7 @@ sub walk_fwtable { debug sprintf ' [%s] macsuck %s - port %s has neighbor %s - skipping.', $device->ip, $mac, $port, $neighbor->ip; - next; + next MAC; } elsif (my $remote = $device_port->remote_ip) { debug sprintf @@ -404,9 +436,9 @@ sub walk_fwtable { ' [%s] macsuck %s - port %s is detected uplink - skipping.', $device->ip, $mac, $port; - $skiplist->{$port} = [ $vlan, $mac ] # remember for later + $skiplist->{$port} = [ $vlan, $mac ] # remember neighbor port mac if exists $port_macs->{$mac}; - next; + next MAC; } } @@ -417,7 +449,7 @@ sub walk_fwtable { debug sprintf ' [%s] macsuck %s - port %s connects to self - skipping.', $device->ip, $mac, $port; - next; + next MAC; } debug sprintf ' [%s] macsuck %s - port %s is probably an uplink', @@ -427,7 +459,7 @@ sub walk_fwtable { # neighbor exists and Netdisco can speak to it, so we don't want # its MAC address. however don't add to skiplist as that would # clear all other MACs on the port. - next if $neigh_cannot_macsuck; + next MAC if $neigh_cannot_macsuck; # when there's no CDP/LLDP, we only want to gather macs at the # topology edge, hence skip ports with known device macs. @@ -436,7 +468,7 @@ sub walk_fwtable { $device->ip, $mac, $port; $skiplist->{$port} = [ $vlan, $mac ]; # remember for later - next; + next MAC; } } diff --git a/share/config.yml b/share/config.yml index d4793c40..c38a7f77 100644 --- a/share/config.yml +++ b/share/config.yml @@ -251,7 +251,6 @@ discover_waps: true discover_phones: false discover_routed_neighbors: true discover_min_age: 0 -silent_ports: [] macsuck_no: [] macsuck_only: [] macsuck_all_vlans: false @@ -266,6 +265,7 @@ macsuck_no_vlan: - 'SAM-vlan-appliance-management' - 'SAM-vlan-management' macsuck_no_devicevlan: [] +macsuck_no_deviceport: [] macsuck_unsupported: [] macsuck_unsupported_type: [] macsuck_bleed: false