205 lines
8.7 KiB
PHP

<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage discovery
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2022 Observium Limited
*
*/
/**
* @var array $config
* @var array $device
* @global array $valid
* @global string $module
*/
$discovery_vrf = [];
$vrf_contexts = [];
/* Start VRF discovery */
if (!$config['enable_vrfs']) {
print_debug("VRFs disabled globally.");
//return; // Do not exit for context discovery below
} else {
/*
There are 2 common MIBs for VPNs: MPLS-VPN-MIB (oldest) and MPLS-L3VPN-STD-MIB (newest)
Unfortunately, there is no simple way to find out which one to use, unless we reference
all the possible devices and check what they support.
Therefore we start testing the MPLS-L3VPN-STD-MIB that is preferred if available.
*/
$include_dir = 'includes/discovery/vrf';
//$include_order = 'default'; // Use MIBs from default os definitions by first!
include($config['install_dir']."/includes/include-dir-mib.inc.php");
print_debug_vars($discovery_vrf);
foreach ($discovery_vrf as $vrf_name => $entry) {
discover_vrf($device, $entry);
}
// Clean removed VRFs
print_debug_vars($valid['vrf']);
$where = '`device_id` = ?';
$where .= generate_query_values_and(array_keys((array)$valid['vrf']), 'vrf_name', '!=');
if ($count = dbFetchCell("SELECT COUNT(*) FROM `vrfs` WHERE $where", [ $device['device_id'] ])) {
$GLOBALS['module_stats'][$module]['deleted'] = $count;
dbDelete('vrfs', $where, [ $device['device_id'] ]);
}
// Clean Removed ports
print_debug_vars($valid['vrf-ports']);
$vrf_ports = [];
foreach ($valid['vrf-ports'] as $vrf_name => $entry) {
$vrf_ports = array_merge($vrf_ports, array_keys($entry));
}
print_debug_vars($vrf_ports);
$where = '`device_id` = ? AND `ifVrf` IS NOT NULL';
$where .= generate_query_values_and($vrf_ports, 'port_id', '!=');
if ($count = dbFetchCell("SELECT COUNT(*) FROM `ports` WHERE $where", [ $device['device_id'] ])) {
//$GLOBALS['module_stats'][$module]['deleted'] = $count;
dbUpdate([ 'ifVrf' => [ 'NULL' ] ], 'ports', $where, [ $device['device_id'] ]);
}
}
/* End VRF discovery */
// Currently only on Nexus and IOX-XR devices (probably some other Cisco), which not support common MPLS MIBs
/* Start detect SNMP contexts for VRFs */
if (safe_empty($device['snmp_context']) && // Device not already with context
isset($config['os'][$device['os']]['snmp']['virtual']) && $config['os'][$device['os']]['snmp']['virtual']) { // Context permitted for os
/* Types of Virtual Router tables:
VRF (Virtual Router Forwarder) - Cisco routers and many others
Context - Cisco ASA
VR (Virtual Routers) - JunOS
VDOM (Virtual Domain) - Fortigate
VSYS (Virtual Systems) - Palo Alto
NETNS (Network NameSpace) - Linux
*/
//$vrf_contexts = [];
$vrf_type = 'VRF';
if (is_device_mib($device, 'CISCO-CONTEXT-MAPPING-MIB')) {
// For enable context mapping on Nexus device:
// snmp-server context <context_name> vrf <vrf_name>
// CISCO-CONTEXT-MAPPING-MIB::cContextMappingVrfName."1" = STRING:
// CISCO-CONTEXT-MAPPING-MIB::cContextMappingVrfName."test" = STRING: management
// CISCO-CONTEXT-MAPPING-MIB::cContextMappingVrfName."vlan-1" = STRING:
// CISCO-CONTEXT-MAPPING-MIB::cContextMappingRowStatus."1" = INTEGER: active(1)
// CISCO-CONTEXT-MAPPING-MIB::cContextMappingRowStatus."test" = INTEGER: active(1)
// CISCO-CONTEXT-MAPPING-MIB::cContextMappingRowStatus."vlan-1" = INTEGER: active(1)
$vrf_snmp_contexts = snmpwalk_cache_oid($device, 'cContextMappingVrfName', [], 'CISCO-CONTEXT-MAPPING-MIB');
$vrf_snmp_contexts = snmpwalk_cache_oid($device, 'cContextMappingRowStatus', $vrf_snmp_contexts, 'CISCO-CONTEXT-MAPPING-MIB');
foreach ($vrf_snmp_contexts as $snmp_context => $entry) {
if (preg_match('/^(vlan\-)?(?<vlan>\d{1,4})$/', $snmp_context, $matches) &&
$matches['vlan'] > 0 && $matches['vlan'] < 4096) {
// Skip Vlan contexts
continue;
}
if ($entry['cContextMappingVrfName'] === '') {
// NX-OS can return empty cContextMappingVrfName
$entry['cContextMappingVrfName'] = $snmp_context;
}
if (snmp_virtual_exist($device, $snmp_context)) {
// prevent adding unnecessary vrfs
$vrf_contexts[$entry['cContextMappingVrfName']] = $snmp_context;
}
}
} elseif (is_device_mib($device, 'RBN-BIND-MIB')) {
// RBN-BIND-MIB::rbnBindContext[0:0:ffff-1400-1002] = STRING: local
// RBN-BIND-MIB::rbnBindContext[1:0:ffff-1800-1005] = STRING: iBGP
//$vrf_snmp_contexts = snmpwalk_cache_oid($device, 'rbnBindContext', [], 'RBN-BIND-MIB', NULL, OBS_SNMP_ALL_TABLE);
//$vrf_snmp_contexts = snmpwalk_cache_oid($device, 'rbnBindType', $vrf_snmp_contexts, 'RBN-BIND-MIB', NULL, OBS_SNMP_ALL_TABLE);
$vrf_snmp_contexts = snmpwalk_values($device, 'rbnBindContext', [], 'RBN-BIND-MIB');
foreach (array_unique($vrf_snmp_contexts) as $snmp_context) {
if ($snmp_context === '' || $snmp_context === 'local') { // local is just main table (without context)
print_debug("SNMP context '$snmp_context' skipped.");
continue;
}
if (snmp_virtual_exist($device, $snmp_context)) {
// Not really VRF, not know how there VRFs, need unique SNMP Contexts
$vrf_contexts[$snmp_context] = $snmp_context;
}
}
} elseif (is_device_mib($device, 'FORTINET-FORTIGATE-MIB') && snmp_get_oid($device, 'fgVdEnabled.0', 'FORTINET-FORTIGATE-MIB') === 'enabled') {
// FORTINET-FORTIGATE-MIB::fgVdNumber.0 = INTEGER: 2
// FORTINET-FORTIGATE-MIB::fgVdMaxVdoms.0 = INTEGER: 10
// FORTINET-FORTIGATE-MIB::fgVdEnabled.0 = INTEGER: enabled(2)
// FORTINET-FORTIGATE-MIB::fgVdEntIndex.1 = INTEGER: 1
// FORTINET-FORTIGATE-MIB::fgVdEntIndex.2 = INTEGER: 2
// FORTINET-FORTIGATE-MIB::fgVdEntName.1 = STRING: root
// FORTINET-FORTIGATE-MIB::fgVdEntName.2 = STRING: test
// FORTINET-FORTIGATE-MIB::fgVdEntOpMode.1 = INTEGER: nat(1)
// FORTINET-FORTIGATE-MIB::fgVdEntOpMode.2 = INTEGER: nat(1)
// FORTINET-FORTIGATE-MIB::fgVdEntHaState.1 = INTEGER: standalone(3)
// FORTINET-FORTIGATE-MIB::fgVdEntHaState.2 = INTEGER: standalone(3)
// FORTINET-FORTIGATE-MIB::fgVdEntCpuUsage.1 = Gauge32: 22
// FORTINET-FORTIGATE-MIB::fgVdEntCpuUsage.2 = Gauge32: 0
// FORTINET-FORTIGATE-MIB::fgVdEntMemUsage.1 = Gauge32: 58
// FORTINET-FORTIGATE-MIB::fgVdEntMemUsage.2 = Gauge32: 0
// FORTINET-FORTIGATE-MIB::fgVdEntSesCount.1 = Gauge32: 217
// FORTINET-FORTIGATE-MIB::fgVdEntSesCount.2 = Gauge32: 1
// FORTINET-FORTIGATE-MIB::fgVdEntSesRate.1 = Gauge32: 0 Sessions Per Second
// FORTINET-FORTIGATE-MIB::fgVdEntSesRate.2 = Gauge32: 0 Sessions Per Second
$vrf_type = 'VDOM';
$vrf_snmp_contexts = snmpwalk_values($device, 'fgVdEntName', [], 'FORTINET-FORTIGATE-MIB');
foreach ($vrf_snmp_contexts as $vdom) {
if ($vdom === '' || $vdom === 'root') { // root is just main table
print_debug("SNMP in VDOM '$vdom' skipped.");
continue;
}
if (snmp_virtual_exist($device, $vdom)) {
$vrf_contexts[$vdom] = $vdom;
}
}
}
print_debug_vars($vrf_snmp_contexts);
print_debug_vars($vrf_contexts);
$contexts_db = safe_json_decode(get_entity_attrib('device', $device, 'vrf_contexts'));
print_debug_vars($contexts_db);
$update_array = array_diff_assoc($vrf_contexts, (array)$contexts_db);
print_debug_vars($update_array);
$delete_array = array_diff_assoc((array)$contexts_db, $vrf_contexts);
print_debug_vars($delete_array);
if (safe_count($contexts_db) && safe_empty($vrf_contexts)) {
del_entity_attrib('device', $device, 'vrf_contexts');
log_event("SNMP in Virtual Routing removed.", $device, 'device', $device['device_id']);
} elseif (safe_count($update_array)) {
set_entity_attrib('device', $device, 'vrf_contexts', safe_json_encode($vrf_contexts));
$contexts_list = [];
foreach ($update_array as $vrf_name => $context) {
$contexts_list[] = "'$context' ($vrf_type $vrf_name)";
}
log_event("SNMP in Virtual Routing found: " . implode(", ", $contexts_list), $device, 'device', $device['device_id']);
} elseif (safe_count($delete_array)) {
set_entity_attrib('device', $device, 'vrf_contexts', safe_json_encode($vrf_contexts));
$contexts_list = [];
foreach ($delete_array as $vrf_name => $context) {
$contexts_list[] = "'$context' ($vrf_type $vrf_name)";
}
log_event("SNMP in Virtual Routing removed: " . implode(", ", $contexts_list), $device, 'device', $device['device_id']);
}
}
/* End detect SNMP contexts for VRFs */
unset($discovery_vrf, $vrf_ports, $where, $vrf_contexts);
// EOF