refactor: populate native vlans in the ports_vlan table for cisco devices too (#4805)

This commit is contained in:
Tony Murray
2016-10-19 16:44:49 -05:00
committed by Neil Lathwood
parent bfe59646bf
commit 4ff9e84f4e
4 changed files with 95 additions and 59 deletions

View File

@@ -19,17 +19,17 @@ foreach ($otherports as $otherport) {
if ($otherport['untagged']) {
$traverse_ifvlan = false;
}
$vlan_ports[$otherport[ifIndex]] = $otherport;
$vlan_ports[$otherport['ifIndex']] = $otherport;
}
if ($traverse_ifvlan) {
$otherports = dbFetchRows('SELECT * FROM ports WHERE `device_id` = ? AND `ifVlan` = ?', array($device['device_id'], $vlan['vlan_vlan']));
foreach ($otherports as $otherport) {
$vlan_ports[$otherport[ifIndex]] = array_merge($otherport, array('untagged' => '1'));
$vlan_ports[$otherport['ifIndex']] = array_merge($otherport, array('untagged' => '1'));
}
}
ksort($vlan_ports);
ksort($vlan_ports);
foreach ($vlan_ports as $port) {
$port = ifLabel($port, $device);

View File

@@ -8,7 +8,17 @@ foreach ($vlans_db_raw as $vlan_db) {
// Create an empty array to record what VLANs we discover this session.
$device['vlans'] = array();
$valid_vlan_port_ids = array();
$per_vlan_data = array(); // fill this with data for each vlan
$valid_vlan_port = array();
// get a map of base port to ifIndex and the inverse
$base_to_index = array();
$tmp_base_indexes = snmpwalk_cache_oid($device, 'dot1dBasePortIfIndex', array(), 'BRIDGE-MIB');
// flatten the array
foreach ($tmp_base_indexes as $index => $array) {
$base_to_index[$index] = $array['dot1dBasePortIfIndex'];
}
$index_to_base = array_flip($base_to_index);
require 'includes/discovery/vlans/q-bridge-mib.inc.php';
require 'includes/discovery/vlans/cisco-vtp.inc.php';
@@ -16,59 +26,49 @@ require 'includes/discovery/vlans/cisco-vtp.inc.php';
// Fetch switchport <> VLAN relationships. This is DIRTY.
foreach ($device['vlans'] as $domain_id => $vlans) {
foreach ($vlans as $vlan_id => $vlan) {
// FIXME - do this only when vlan type == ethernet?
if (is_numeric($vlan_id) && ($vlan_id < 1002 || $vlan_id > 1005)) {
// Ignore reserved VLAN IDs
if ($device['os_group'] == 'cisco' || $device['os'] == 'ios') {
// This shit only seems to work on IOS
// Probably does not work with snmpv3. I have no real idea about what this code is really doing
$vlan_device = array_merge($device, array('community' => $device['community'].'@'.$vlan_id));
$vlan_data = snmpwalk_cache_oid($vlan_device, 'dot1dStpPortEntry', array(), 'BRIDGE-MIB:Q-BRIDGE-MIB');
$vlan_data = snmpwalk_cache_oid($vlan_device, 'dot1dBasePortEntry', $vlan_data, 'BRIDGE-MIB:Q-BRIDGE-MIB');
} elseif (isset($qbridge_data)) {
$vlan_data = $qbridge_data[$vlan_id];
// grab the populated data for this vlan
$vlan_data = $per_vlan_data[$vlan_id];
echo "VLAN $vlan_id \n";
if ($vlan_data) {
echo str_pad('dot1d id', 10).str_pad('ifIndex', 10).str_pad('Port Name', 25).str_pad('Priority', 10).str_pad('State', 15).str_pad('Cost', 10)."\n";
}
foreach ($vlan_data as $ifIndex => $vlan_port) {
$port = get_port_by_index_cache($device, $ifIndex);
echo str_pad($vlan_port_id, 10).str_pad($ifIndex, 10).str_pad($port['ifDescr'], 25).str_pad($vlan_port['dot1dStpPortPriority'], 10).str_pad($vlan_port['dot1dStpPortState'], 15).str_pad($vlan_port['dot1dStpPortPathCost'], 10);
$db_w = array(
'device_id' => $device['device_id'],
'port_id' => $port['port_id'],
'vlan' => $vlan_id,
);
$db_a['baseport'] = $index_to_base[$ifIndex];
$db_a['priority'] = isset($vlan_port['dot1dStpPortPriority']) ? $vlan_port['dot1dStpPortPriority'] : 0;
$db_a['state'] = isset($vlan_port['dot1dStpPortState']) ? $vlan_port['dot1dStpPortState'] : 'unknown';
$db_a['cost'] = isset($vlan_port['dot1dStpPortPathCost']) ? $vlan_port['dot1dStpPortPathCost'] : 0;
$db_a['untagged'] = isset($vlan_port['untagged']) ? $vlan_port['untagged'] : 0;
$from_db = dbFetchRow('SELECT * FROM `ports_vlans` WHERE device_id = ? AND port_id = ? AND `vlan` = ?', array($device['device_id'], $port['port_id'], $vlan_id));
if ($from_db['port_vlan_id']) {
$db_id = $from_db['port_vlan_id'];
dbUpdate($db_a, 'ports_vlans', '`port_vlan_id` = ?', array($db_id));
echo 'Updated';
} else {
$db_id = dbInsert(array_merge($db_w, $db_a), 'ports_vlans');
echo 'Inserted';
}
$valid_vlan_port_ids[] = $db_id;
echo "VLAN $vlan_id \n";
if ($vlan_data) {
echo str_pad('dot1d id', 10).str_pad('ifIndex', 10).str_pad('Port Name', 25).str_pad('Priority', 10).str_pad('State', 15).str_pad('Cost', 10)."\n";
}
foreach ($vlan_data as $vlan_port_id => $vlan_port) {
$port = get_port_by_index_cache($device, $vlan_port['dot1dBasePortIfIndex']);
echo str_pad($vlan_port_id, 10).str_pad($vlan_port['dot1dBasePortIfIndex'], 10).str_pad($port['ifDescr'], 25).str_pad($vlan_port['dot1dStpPortPriority'], 10).str_pad($vlan_port['dot1dStpPortState'], 15).str_pad($vlan_port['dot1dStpPortPathCost'], 10);
$db_w = array(
'device_id' => $device['device_id'],
'port_id' => $port['port_id'],
'vlan' => $vlan_id,
);
$db_a['baseport'] = $vlan_port_id;
$db_a['priority'] = isset($vlan_port['dot1dStpPortPriority']) ? $vlan_port['dot1dStpPortPriority'] : 0;
$db_a['state'] = isset($vlan_port['dot1dStpPortState']) ? $vlan_port['dot1dStpPortState'] : 'unknown';
$db_a['cost'] = isset($vlan_port['dot1dStpPortPathCost']) ? $vlan_port['dot1dStpPortPathCost'] : 0;
$db_a['untagged'] = isset($vlan_port['untagged']) ? $vlan_port['untagged'] : 0;
$from_db = dbFetchRow('SELECT * FROM `ports_vlans` WHERE device_id = ? AND port_id = ? AND `vlan` = ?', array($device['device_id'], $port['port_id'], $vlan_id));
if ($from_db['port_vlan_id']) {
$db_id = $from_db['port_vlan_id'];
dbUpdate($db_a, 'ports_vlans', '`port_vlan_id` = ?', array($db_id));
echo 'Updated';
} else {
$db_id = dbInsert(array_merge($db_w, $db_a), 'ports_vlans');
echo 'Inserted';
}
$valid_vlan_port_ids[] = $db_id;
echo PHP_EOL;
}//end foreach
}//end if
echo PHP_EOL;
}//end foreach
}//end foreach
}//end foreach
// remove non-existent vlans
foreach ($vlans_db as $domain_id => $vlans) {
foreach ($vlans as $vlan_id => $vlan) {
if (empty($device['vlans'][$domain_id][$vlan_id])) {
@@ -82,3 +82,4 @@ $num = dbDelete('ports_vlans', '`device_id`=? AND `port_vlan_id` NOT IN ('.join(
d_echo("Deleted $num vlan mappings\n");
unset($device['vlans']);
unset($base_to_index, $tmp_base_indexes, $index_to_base, $per_vlan_data, $valid_vlan_port, $num);

View File

@@ -3,6 +3,9 @@
if ($device['os_group'] == 'cisco') {
echo "Cisco VLANs:\n";
$native_vlans = snmpwalk_cache_oid($device, 'vlanTrunkPortNativeVlan', array(), 'CISCO-VTP-MIB');
$native_vlans = snmpwalk_cache_oid($device, 'vmVlan', $native_vlans, 'CISCO-VLAN-MEMBERSHIP-MIB');
// Not sure why we check for VTP, but this data comes from that MIB, so...
$vtpversion = snmp_get($device, 'vtpVersion.0', '-OnvQ', 'CISCO-VTP-MIB');
if ($vtpversion == '1' || $vtpversion == '2' || $vtpversion == '3' || $vtpversion == 'one' || $vtpversion == 'two' || $vtpversion == 'three' || $vtpversion == 'none') {
@@ -21,8 +24,42 @@ if ($device['os_group'] == 'cisco') {
echo '+';
}
$device['vlans'][$vtpdomain_id][$vlan_id] = $vlan_id;
if (is_numeric($vlan_id) && ($vlan_id < 1002 || $vlan_id > 1005)) {
// Ignore reserved VLAN IDs
// get dot1dStpPortEntry within the vlan context
$vlan_device = array_merge($device, array('community' => $device['community'] . '@' . $vlan_id, 'context_name' => "vlan-$vlan_id"));
$tmp_vlan_data = snmpwalk_cache_oid($vlan_device, 'dot1dStpPortEntry', array(), 'BRIDGE-MIB');
// may need to fetch additional dot1dBasePortIfIndex mappings
$tmp_vlan_data = snmpwalk_cache_oid($vlan_device, 'dot1dBasePortIfIndex', $tmp_vlan_data, 'BRIDGE-MIB');
$vlan_data = array();
// flatten the array, use ifIndex instead of dot1dBasePortId
foreach ($tmp_vlan_data as $index => $array) {
if (isset($array['dot1dBasePortIfIndex'])) {
$base_to_index[$index] = $array['dot1dBasePortIfIndex'];
$index_to_base[$array['dot1dBasePortIfIndex']] = $index;
}
$vlan_data[$base_to_index[$index]] = $array;
}
$per_vlan_data[$vlan_id] = $vlan_data;
}
}
echo PHP_EOL;
// set all untagged vlans
foreach ($native_vlans as $ifIndex => $data) {
if (isset($data['vmVlan'])) {
$vlan_id = $data['vmVlan'];
} else {
$vlan_id = $data['vlanTrunkPortNativeVlan'];
}
$base = $index_to_base[$ifIndex];
echo "Vlan: $vlan_id tagged on $base (ifIndex $ifIndex)\n";
$per_vlan_data[$vlan_id][$ifIndex]['untagged'] = 1;
}
}
}
echo PHP_EOL;
}

View File

@@ -6,12 +6,10 @@ $vlanversion = snmp_get($device, 'dot1qVlanVersionNumber.0', '-Oqv', 'IEEE8021-Q
if ($vlanversion == 'version1' || $vlanversion == '2') {
echo "ver $vlanversion ";
$qbridge_data = array();
$vtpdomain_id = '1';
$vlans = snmpwalk_cache_oid($device, 'dot1qVlanStaticName', array(), 'Q-BRIDGE-MIB');
$tagoruntag = snmpwalk_cache_oid($device, 'dot1qVlanCurrentEgressPorts', array(), 'Q-BRIDGE-MIB', null, '-OQUs --hexOutputLength=0');
$untag = snmpwalk_cache_oid($device, 'dot1qVlanCurrentUntaggedPorts', array(), 'Q-BRIDGE-MIB', null, '-OQUs --hexOutputLength=0');
$base_indexes = snmpwalk_cache_oid($device, 'dot1dBasePortIfIndex', array(), 'BRIDGE-MIB');
foreach ($vlans as $vlan_id => $vlan) {
d_echo(" $vlan_id");
@@ -31,12 +29,12 @@ if ($vlanversion == 'version1' || $vlanversion == '2') {
$device['vlans'][$vtpdomain_id][$vlan_id] = $vlan_id;
$id = "0.$vlan_id";
$untagged_indexes = q_bridge_bits2indices($untag[$id]['dot1qVlanCurrentUntaggedPorts']);
$egress_indexes = q_bridge_bits2indices($tagoruntag[$id]['dot1qVlanCurrentEgressPorts']);
$untagged_ids = q_bridge_bits2indices($untag[$id]['dot1qVlanCurrentUntaggedPorts']);
$egress_ids = q_bridge_bits2indices($tagoruntag[$id]['dot1qVlanCurrentEgressPorts']);
foreach ($egress_indexes as $port_index) {
$qbridge_data[$vlan_id][$port_index] = $base_indexes[$port_index];
$qbridge_data[$vlan_id][$port_index]['untagged'] = (in_array($port_index, $untagged_indexes) ? 1 : 0);
foreach ($egress_ids as $port_id) {
$ifIndex = $base_to_index[$port_id];
$per_vlan_data[$vlan_id][$ifIndex]['untagged'] = (in_array($port_id, $untagged_ids) ? 1 : 0);
}
}
}