2009-09-07 11:07:59 +00:00
< ? php
2017-08-08 14:14:58 -05:00
2017-09-11 15:26:41 -05:00
use LibreNMS\Config ;
2017-11-20 18:46:15 -06:00
use LibreNMS\Exceptions\InvalidIpException ;
2017-08-08 14:14:58 -05:00
use LibreNMS\Util\IP ;
2017-09-11 15:26:41 -05:00
if ( Config :: get ( 'enable_bgp' )) {
2019-01-19 18:44:32 +01:00
if ( $device [ 'os' ] == 'timos' ) {
$bgpPeersCache = snmpwalk_cache_multi_oid ( $device , 'tBgpPeerNgTable' , [], 'TIMETRA-BGP-MIB' , 'nokia' );
foreach ( $bgpPeersCache as $key => $value ) {
$oid = explode ( " . " , $key );
$vrfInstance = $oid [ 0 ];
$address = str_replace ( $oid [ 0 ] . " . " . $oid [ 1 ] . " . " , '' , $key );
if ( strlen ( $address ) > 15 ) {
$address = IP :: fromHexString ( $address ) -> compressed ();
}
$bgpPeers [ $vrfInstance ][ $address ] = $value ;
}
unset ( $bgpPeersCache );
foreach ( $bgpPeers as $vrfOid => $vrf ) {
$vrfId = dbFetchCell ( 'SELECT vrf_id from `vrfs` WHERE vrf_oid = ?' , [ $vrfOid ]);
foreach ( $vrf as $address => $value ) {
$astext = get_astext ( $value [ 'tBgpPeerNgPeerAS4Byte' ]);
if ( dbFetchCell ( 'SELECT COUNT(*) from `bgpPeers` WHERE device_id = ? AND bgpPeerIdentifier = ? AND vrf_id = ?' , [ $device [ 'device_id' ], $address , $vrfId ]) < '1' ) {
$peers = [
'device_id' => $device [ 'device_id' ],
'vrf_id' => $vrfId ,
'bgpPeerIdentifier' => $address ,
'bgpPeerRemoteAs' => $value [ 'tBgpPeerNgPeerAS4Byte' ],
'bgpPeerState' => 'idle' ,
'bgpPeerAdminStatus' => 'stop' ,
'bgpLocalAddr' => '0.0.0.0' ,
'bgpPeerRemoteAddr' => '0.0.0.0' ,
'bgpPeerInUpdates' => 0 ,
'bgpPeerOutUpdates' => 0 ,
'bgpPeerInTotalMessages' => 0 ,
'bgpPeerOutTotalMessages' => 0 ,
'bgpPeerFsmEstablishedTime' => 0 ,
'bgpPeerInUpdateElapsedTime' => 0 ,
'astext' => $astext ,
];
dbInsert ( $peers , 'bgpPeers' );
if ( Config :: get ( 'autodiscovery.bgp' )) {
$name = gethostbyaddr ( $address );
discover_new_device ( $name , $device , 'BGP' );
}
echo '+' ;
} else {
dbUpdate ([ 'bgpPeerRemoteAs' => $value [ 'tBgpPeerNgPeerAS4Byte' ], 'astext' => $astext ], 'bgpPeers' , 'device_id = ? AND bgpPeerIdentifier = ? AND vrf_id = ?' , [ $device [ 'device_id' ], $address , $vrfId ]);
echo '.' ;
}
}
}
// clean up peers
$peers = dbFetchRows ( 'SELECT `B`.`vrf_id` AS `vrf_id`, `bgpPeerIdentifier`, `vrf_oid` FROM `bgpPeers` AS B LEFT JOIN `vrfs` AS V ON `B`.`vrf_id` = `V`.`vrf_id` WHERE `B`.`device_id` = ?' , [ $device [ 'device_id' ]]);
foreach ( $peers as $value ) {
$vrfId = $value [ 'vrf_id' ];
$vrfOid = $value [ 'vrf_oid' ];
$address = $value [ 'bgpPeerIdentifier' ];
if ( empty ( $bgpPeers [ $vrfOid ][ $address ])) {
$deleted = dbDelete ( 'bgpPeers' , 'device_id = ? AND bgpPeerIdentifier = ? AND vrf_id = ?' , [ $device [ 'device_id' ], $address , $vrfId ]);
echo str_repeat ( '-' , $deleted );
echo PHP_EOL ;
}
}
}
unset ( $bgpPeers );
2016-08-28 12:32:58 -05:00
if ( key_exists ( 'vrf_lite_cisco' , $device ) && ( count ( $device [ 'vrf_lite_cisco' ]) != 0 )) {
2016-04-12 16:21:43 +02:00
$vrfs_lite_cisco = $device [ 'vrf_lite_cisco' ];
2016-08-28 12:32:58 -05:00
} else {
2018-02-19 09:08:27 -06:00
$vrfs_lite_cisco = array ( array ( 'context_name' => '' ));
2016-04-12 16:21:43 +02:00
}
2016-02-02 12:21:45 +01:00
2018-01-18 14:54:38 -06:00
$bgpLocalAs = snmp_getnext ( $device , 'bgpLocalAs' , '-Oqvn' , 'BGP4-MIB' );
2016-02-20 17:41:56 +00:00
2016-04-12 16:21:43 +02:00
foreach ( $vrfs_lite_cisco as $vrf ) {
2017-03-11 23:16:49 +00:00
$device [ 'context_name' ] = $vrf [ 'context_name' ];
2016-08-28 12:32:58 -05:00
if ( is_numeric ( $bgpLocalAs )) {
echo " AS $bgpLocalAs " ;
if ( $bgpLocalAs != $device [ 'bgpLocalAs' ]) {
dbUpdate ( array ( 'bgpLocalAs' => $bgpLocalAs ), 'devices' , 'device_id=?' , array ( $device [ 'device_id' ]));
echo 'Updated AS ' ;
}
2016-02-02 12:21:45 +01:00
2017-03-11 23:16:49 +00:00
$peer2 = false ;
if ( $device [ 'os_group' ] === 'arista' ) {
$peers_data = snmp_walk ( $device , 'aristaBgp4V2PeerRemoteAs' , '-Oq' , 'ARISTA-BGP4V2-MIB' );
$peer2 = true ;
2016-08-28 12:32:58 -05:00
} elseif ( $device [ 'os' ] == 'junos' ) {
2017-03-11 23:16:49 +00:00
$peers_data = snmp_walk ( $device , 'jnxBgpM2PeerRemoteAs' , '-Onq' , 'BGP4-V2-MIB-JUNIPER' , 'junos' );
2018-01-18 14:54:38 -06:00
} elseif ( $device [ 'os_group' ] === 'cisco' ) {
$peers_data = snmp_walk ( $device , 'cbgpPeer2RemoteAs' , '-Oq' , 'CISCO-BGP4-MIB' );
$peer2 = ! empty ( $peers_data );
}
if ( empty ( $peers_data )) {
$bgp4_mib = true ;
$peers_data = snmp_walk ( $device , 'bgpPeerRemoteAs' , '-Oq' , 'BGP4-MIB' );
2010-11-23 14:33:02 +00:00
}
2016-08-28 12:32:58 -05:00
} else {
echo 'No BGP on host' ;
if ( $device [ 'bgpLocalAs' ]) {
2018-01-18 14:54:38 -06:00
dbUpdate ( array ( 'bgpLocalAs' => array ( 'NULL' )), 'devices' , 'device_id=?' , array ( $device [ 'device_id' ]));
2016-08-28 12:32:58 -05:00
echo ' (Removed ASN) ' ;
2011-03-08 17:28:24 +00:00
}
2016-08-28 12:32:58 -05:00
}
2017-03-11 23:16:49 +00:00
$peerlist = build_bgp_peers ( $device , $peers_data , $peer2 );
// Process discovered peers
2018-02-06 15:06:44 -06:00
if ( ! empty ( $peerlist )) {
$af_data = array ();
$af_list = array ();
2016-08-28 12:32:58 -05:00
foreach ( $peerlist as $peer ) {
2018-02-06 15:06:44 -06:00
$peer [ 'astext' ] = get_astext ( $peer [ 'as' ]);
2016-08-28 12:32:58 -05:00
2017-03-11 23:16:49 +00:00
add_bgp_peer ( $device , $peer );
2015-07-13 20:10:26 +02:00
2018-02-06 15:06:44 -06:00
if ( empty ( $af_data )) {
if ( $device [ 'os_group' ] == 'cisco' ) {
2016-08-28 12:32:58 -05:00
if ( $peer2 === true ) {
2018-01-18 14:54:38 -06:00
$af_data = snmpwalk_cache_oid ( $device , 'cbgpPeer2AddrFamilyEntry' , array (), 'CISCO-BGP4-MIB' );
2016-08-28 12:32:58 -05:00
}
2015-07-13 20:10:26 +02:00
2018-02-06 15:06:44 -06:00
if ( empty ( $af_data )) {
$af_data = snmpwalk_cache_oid ( $device , 'cbgpPeerAddrFamilyEntry' , array (), 'CISCO-BGP4-MIB' );
$peer2 = false ;
}
} elseif ( $device [ 'os_group' ] === 'arista' ) {
2017-03-11 23:16:49 +00:00
$af_data = snmpwalk_cache_oid ( $device , 'aristaBgp4V2PrefixInPrefixes' , $af_data , 'ARISTA-BGP4V2-MIB' );
}
}
2016-08-28 12:32:58 -05:00
2018-02-06 15:06:44 -06:00
// build the list
2017-03-11 23:16:49 +00:00
if ( ! empty ( $af_data )) {
$af_list = build_cbgp_peers ( $device , $peer , $af_data , $peer2 );
}
2019-04-09 14:44:48 +02:00
if ( $device [ 'os' ] == 'vrp' ) {
d_echo ( " VRP: " );
$af_data = snmpwalk_cache_oid ( $device , 'hwBgpPeers' , $af_data , 'HUAWEI-BGP-VPN-MIB' );
$af_list = build_cbgp_peers ( $device , $peer , $af_data , $peer2 );
}
2016-08-28 12:32:58 -05:00
2018-01-18 14:54:38 -06:00
if ( ! $bgp4_mib && $device [ 'os' ] == 'junos' ) {
2018-01-21 06:21:39 +03:00
$afis [ 'ipv4' ] = 'ipv4' ;
$afis [ 'ipv6' ] = 'ipv6' ;
$afis [ 25 ] = 'l2vpn' ;
$safis [ 1 ] = 'unicast' ;
$safis [ 2 ] = 'multicast' ;
$safis [ 3 ] = 'unicastAndMulticast' ;
$safis [ 4 ] = 'labeledUnicast' ;
$safis [ 5 ] = 'mvpn' ;
$safis [ 65 ] = 'vpls' ;
$safis [ 70 ] = 'evpn' ;
$safis [ 128 ] = 'vpn' ;
$safis [ 132 ] = 'rtfilter' ;
$safis [ 133 ] = 'flow' ;
2017-03-11 23:16:49 +00:00
if ( ! isset ( $j_peerIndexes )) {
$j_bgp = snmpwalk_cache_multi_oid ( $device , 'jnxBgpM2PeerEntry' , $jbgp , 'BGP4-V2-MIB-JUNIPER' , 'junos' );
d_echo ( $j_bgp );
foreach ( $j_bgp as $index => $entry ) {
2017-11-20 18:46:15 -06:00
$peer_index = $entry [ 'jnxBgpM2PeerIndex' ];
try {
$ip = IP :: fromHexString ( $entry [ 'jnxBgpM2PeerRemoteAddr' ]);
d_echo ( " peerindex for " . $ip -> getFamily () . " $ip is $peer_index\n " );
$j_peerIndexes [( string ) $ip ] = $peer_index ;
} catch ( InvalidIpException $e ) {
d_echo ( " Unable to parse IP for peer $peer_index : " . $entry [ 'jnxBgpM2PeerRemoteAddr' ] . PHP_EOL );
}
2016-08-28 12:32:58 -05:00
}
2017-03-11 23:16:49 +00:00
}
2016-04-12 16:21:43 +02:00
2017-03-11 23:16:49 +00:00
if ( ! isset ( $j_afisafi )) {
$j_prefixes = snmpwalk_cache_multi_oid ( $device , 'jnxBgpM2PrefixCountersTable' , $jbgp , 'BGP4-V2-MIB-JUNIPER' , 'junos' );
foreach ( array_keys ( $j_prefixes ) as $key ) {
list ( $index , $afisafi ) = explode ( '.' , $key , 2 );
$j_afisafi [ $index ][] = $afisafi ;
2016-08-28 12:32:58 -05:00
}
2017-03-11 23:16:49 +00:00
}
2015-07-13 20:10:26 +02:00
2017-03-11 23:16:49 +00:00
foreach ( $j_afisafi [ $j_peerIndexes [ $peer [ 'ip' ]]] as $afisafi ) {
list ( $afi , $safi ) = explode ( '.' , $afisafi );
2018-01-21 06:21:39 +03:00
$afi = $afis [ $afi ];
2017-03-11 23:16:49 +00:00
$safi = $safis [ $safi ];
$af_list [ $peer [ 'ip' ]][ $afi ][ $safi ] = 1 ;
add_cbgp_peer ( $device , $peer , $afi , $safi );
2016-08-28 12:32:58 -05:00
}
2017-03-11 23:16:49 +00:00
}
2015-07-13 20:10:26 +02:00
2018-02-19 09:08:27 -06:00
$af_query = " SELECT bgpPeerIdentifier, afi, safi FROM bgpPeers_cbgp WHERE `device_id`=? AND bgpPeerIdentifier=? AND context_name=? " ;
foreach ( dbFetchRows ( $af_query , [ $device [ 'device_id' ], $peer [ 'ip' ], $device [ 'context_name' ]]) as $entry ) {
2017-03-11 23:16:49 +00:00
$afi = $entry [ 'afi' ];
$safi = $entry [ 'safi' ];
if ( ! $af_list [ $entry [ 'bgpPeerIdentifier' ]][ $afi ][ $safi ]) {
2018-02-19 09:08:27 -06:00
dbDelete (
'bgpPeers_cbgp' ,
'`device_id`=? AND `bgpPeerIdentifier`=? AND context_name=? AND afi=? AND safi=?' ,
[ $device [ 'device_id' ], $peer [ 'ip' ], $device [ 'context_name' ], $afi , $safi ]
);
2015-07-13 20:10:26 +02:00
}
2016-02-20 17:41:56 +00:00
}
2011-03-08 17:28:24 +00:00
}
2016-08-28 12:32:58 -05:00
unset ( $j_afisafi );
unset ( $j_prefixes );
unset ( $j_bgp );
unset ( $j_peerIndexes );
}
2018-02-19 09:08:27 -06:00
// clean up peers
$params = [ $device [ 'device_id' ], $device [ 'context_name' ]];
$query = 'device_id=? AND context_name=?' ;
if ( ! empty ( $peerlist )) {
$query .= ' AND bgpPeerIdentifier NOT IN ' . dbGenPlaceholders ( count ( $peerlist ));
$params = array_merge ( $params , array_column ( $peerlist , 'ip' ));
}
2011-03-08 17:28:24 +00:00
2018-02-06 15:06:44 -06:00
$deleted = dbDelete ( 'bgpPeers' , $query , $params );
dbDelete ( 'bgpPeers_cbgp' , $query , $params );
2015-07-13 20:10:26 +02:00
2018-02-06 15:06:44 -06:00
echo str_repeat ( '-' , $deleted );
echo PHP_EOL ;
2016-08-28 12:32:58 -05:00
2017-03-11 23:16:49 +00:00
unset (
$device [ 'context_name' ],
2018-02-06 15:06:44 -06:00
$peerlist ,
$af_data
2017-03-11 23:16:49 +00:00
);
2016-01-20 15:13:53 +01:00
}
2018-02-19 09:08:27 -06:00
// delete unknown contexts
$contexts = dbFetchColumn (
'SELECT DISTINCT context_name FROM bgpPeers WHERE device_id=?' ,
[ $device [ 'device_id' ]]
);
$existing_contexts = array_column ( $vrfs_lite_cisco , 'context_name' );
foreach ( $contexts as $context ) {
if ( ! in_array ( $context , $existing_contexts )) {
dbDelete ( 'bgpPeers' , 'device_id=? and context_name=?' , [ $device [ 'device_id' ], $context ]);
dbDelete ( 'bgpPeers_cbgp' , 'device_id=? and context_name=?' , [ $device [ 'device_id' ], $context ]);
echo '-' ;
}
}
2017-03-11 23:16:49 +00:00
unset (
$device [ 'context_name' ],
2018-02-19 09:08:27 -06:00
$vrfs_lite_cisco ,
$peers_data ,
$af_data ,
$contexts ,
2017-03-11 23:16:49 +00:00
$vrfs_c
);
2010-07-27 20:49:31 +00:00
}