396 lines
16 KiB
PHP
396 lines
16 KiB
PHP
<?php
|
|
/**
|
|
* Observium
|
|
*
|
|
* This file is part of Observium.
|
|
*
|
|
* @package observium
|
|
* @subpackage web
|
|
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Display bgp peers.
|
|
*
|
|
* Display pages with BGP Peers.
|
|
* Examples:
|
|
* print_bgp() - display all bgp peers from all devices
|
|
* print_bgp(array('pagesize' => 99)) - display 99 bgp peers from all device
|
|
* print_bgp(array('pagesize' => 10, 'pageno' => 3, 'pagination' => TRUE)) - display 10 bgp peers from page 3 with
|
|
* pagination header print_bgp(array('pagesize' => 10, 'device' = 4)) - display 10 bgp peers for device_id 4
|
|
*
|
|
* @param array $vars
|
|
*
|
|
* @return void
|
|
*
|
|
*/
|
|
function print_bgp_peer_table($vars) {
|
|
// Get bgp peers array
|
|
$entries = get_bgp_array($vars);
|
|
//r($entries);
|
|
|
|
if (!$entries['count']) {
|
|
// There have been no entries returned. Print the warning.
|
|
print_warning('<h4>No BGP peers found!</h4>');
|
|
return;
|
|
}
|
|
|
|
// Entries have been returned. Print the table.
|
|
$list = array('device' => FALSE);
|
|
if ($vars['page'] !== 'device') {
|
|
$list['device'] = TRUE;
|
|
}
|
|
|
|
switch ($vars['graph']) {
|
|
case 'prefixes_ipv4unicast':
|
|
case 'prefixes_ipv4multicast':
|
|
case 'prefixes_ipv4vpn':
|
|
case 'prefixes_ipv6unicast':
|
|
case 'prefixes_ipv6multicast':
|
|
case 'macaccounting_bits':
|
|
case 'macaccounting_pkts':
|
|
case 'updates':
|
|
$table_class = 'table-striped-two';
|
|
$list['graph'] = TRUE;
|
|
break;
|
|
default:
|
|
$table_class = 'table-striped';
|
|
$list['graph'] = FALSE;
|
|
}
|
|
|
|
$string = generate_box_open();
|
|
|
|
$string .= '<table class="table ' . $table_class . ' table-hover table-condensed ">' . PHP_EOL;
|
|
|
|
$cols = array(
|
|
array(NULL, 'class="state-marker"'),
|
|
array(NULL, 'style="width: 1px;"'),
|
|
'device' => array('Local address', 'style="width: 150px;"'),
|
|
'local_as' => [ 'Local AS / VRF', 'style="width: 110px;"' ],
|
|
array(NULL, 'style="width: 20px;"'),
|
|
'peer_ip' => array('Peer address', 'style="width: 150px;"'),
|
|
'peer_as' => [ 'Remote AS', 'style="width: 90px;"' ],
|
|
'type' => array('Type', 'style="width: 50px;"'),
|
|
array('Family', 'style="width: 50px;"'),
|
|
'state' => 'State',
|
|
'uptime' => 'Uptime / Updates',
|
|
);
|
|
//if (!$list['device']) { unset($cols['device']); }
|
|
$string .= get_table_header($cols, $vars);
|
|
|
|
$string .= ' <tbody>' . PHP_EOL;
|
|
|
|
foreach ($entries['entries'] as $peer)
|
|
{
|
|
$local_dev = device_by_id_cache($peer['device_id']);
|
|
$local_as = ($list['device'] ? ' (AS' . $peer['human_local_as'] . ')' : '');
|
|
$local_name = generate_device_link_short($local_dev, [ 'tab' => 'routing', 'proto' => 'bgp' ], 18);
|
|
$local_ip = generate_device_link($local_dev, $peer['human_localip'] . $local_as, array('tab' => 'routing', 'proto' => 'bgp'));
|
|
$peer_as = 'AS' . $peer['human_remote_as'];
|
|
if ($peer['peer_device_id']) {
|
|
$peer_dev = device_by_id_cache($peer['peer_device_id']);
|
|
$peer_name = generate_device_link_short($peer_dev, [ 'tab' => 'routing', 'proto' => 'bgp' ], 18);
|
|
} else {
|
|
$peer_name = $peer['reverse_dns'];
|
|
}
|
|
$peer_ip = generate_entity_link("bgp_peer", $peer, $peer['human_remoteip']);
|
|
$peer_afis = &$entries['afisafi'][$peer['device_id']][$peer['bgpPeer_id']];
|
|
$peer_afis_html = array();
|
|
|
|
// Generate AFI/SAFI labels
|
|
foreach ($peer_afis as $peer_afi)
|
|
{
|
|
// $peer_afi_html = '<span class="label-group">';
|
|
if (isset($GLOBALS['config']['routing_afis_name'][$peer_afi['afi']]))
|
|
{
|
|
$afi_num = $GLOBALS['config']['routing_afis_name'][$peer_afi['afi']];
|
|
$afi_class = $GLOBALS['config']['routing_afis'][$afi_num]['class'];
|
|
} else {
|
|
$afi_class = 'default';
|
|
}
|
|
|
|
if (isset($GLOBALS['config']['routing_safis_name'][$peer_afi['safi']]))
|
|
{
|
|
// Named SAFI
|
|
$safi_num = $GLOBALS['config']['routing_safis_name'][$peer_afi['safi']];
|
|
$safi_class = $GLOBALS['config']['routing_safis'][$safi_num]['class'];
|
|
}
|
|
else if (isset($GLOBALS['config']['routing_safis'][$peer_afi['safi']]))
|
|
{
|
|
// Numeric SAFI
|
|
$safi_num = $peer_afi['safi'];
|
|
$peer_afi['safi'] = $GLOBALS['config']['routing_safis'][$safi_num]['name'];
|
|
$safi_class = $GLOBALS['config']['routing_safis'][$safi_num]['class'];
|
|
} else {
|
|
$safi_class = 'default';
|
|
}
|
|
|
|
// $peer_afi_html .= '<span class="label label-' . $afi_class . '">' . $peer_afi['afi'] . '</span>';
|
|
// $peer_afi_html .= '<span class="label label-' . $safi_class . '">' . $peer_afi['safi'] . '</span>';
|
|
// $peer_afi_html .= '</span>';
|
|
|
|
$peer_afi_items = [
|
|
['event' => $afi_class, 'text' => $peer_afi['afi']],
|
|
['event' => $safi_class, 'text' => $peer_afi['safi']],
|
|
];
|
|
$peer_afi_html = get_label_group($peer_afi_items);
|
|
//r($peer_afi_html);
|
|
$peer_afis_html[] = $peer_afi_html;
|
|
}
|
|
|
|
$string .= ' <tr class="' . $peer['html_row_class'] . '">' . PHP_EOL;
|
|
$string .= ' <td class="state-marker"></td>' . PHP_EOL;
|
|
$string .= ' <td></td>' . PHP_EOL;
|
|
$string .= ' <td style="white-space: nowrap" class="entity">' . $local_ip . '<br />' . $local_name . '</td>' . PHP_EOL;
|
|
$string .= ' <td><strong><span class="label label-' . $peer['peer_local_class'] . '">AS' . $peer['human_local_as'] . '</span></strong>';
|
|
if (!safe_empty($peer['virtual_name'])) {
|
|
$vitual_type = isset($GLOBALS['config']['os'][$local_dev['os']]['snmp']['virtual_type']) ? nicecase($GLOBALS['config']['os'][$local_dev['os']]['snmp']['virtual_type']) : 'VRF';
|
|
$string .= '<br /><span class="label">'.$vitual_type.': '.$peer['virtual_name'].'</span>';
|
|
}
|
|
$string .= '</td>' . PHP_EOL;
|
|
$string .= ' <td><span class="text-success"><i class="glyphicon glyphicon-arrow-right"></i></span></td>' . PHP_EOL;
|
|
$string .= ' <td style="white-space: nowrap" class="entity">' . $peer_ip . '<br />' . $peer_name . '</td>' . PHP_EOL;
|
|
$string .= ' <td><strong>' . $peer_as . '</strong><br />' . $peer['astext'] . '</td>' . PHP_EOL;
|
|
$string .= ' <td><span class="label label-' . $peer['peer_type_class'] . '">' . $peer['peer_type'] . '</span></td>' . PHP_EOL;
|
|
$string .= ' <td>' . implode('<br />', $peer_afis_html) . '</td>' . PHP_EOL;
|
|
$string .= ' <td><strong><span class=" label label-' . $peer['admin_class'] . '">' . $peer['bgpPeerAdminStatus'] . '</span><br /><span class="label label-' . $peer['state_class'] . '">' . $peer['bgpPeerState'] . '</span></strong></td>' . PHP_EOL;
|
|
$string .= ' <td style="white-space: nowrap">' . format_uptime($peer['bgpPeerFsmEstablishedTime']) . '<br />
|
|
Updates: <i class="icon-circle-arrow-down text-success"></i> ' . format_si($peer['bgpPeerInUpdates']) . ' <i class="icon-circle-arrow-up text-primary"></i> ' . format_si($peer['bgpPeerOutUpdates']) . '</td>' . PHP_EOL;
|
|
$string .= ' </tr>' . PHP_EOL;
|
|
|
|
// Graphs
|
|
$peer_graph = FALSE;
|
|
switch ($vars['graph']) {
|
|
case 'prefixes_ipv4unicast':
|
|
case 'prefixes_ipv4multicast':
|
|
case 'prefixes_ipv4vpn':
|
|
case 'prefixes_ipv6unicast':
|
|
case 'prefixes_ipv6multicast':
|
|
$afisafi = preg_replace('/prefixes_(ipv[46])(\w+)/', '$1.$2', $vars['graph']); // prefixes_ipv6unicast ->> ipv6.unicast
|
|
if (isset($peer_afis[$afisafi]) && $peer['bgpPeer_id'])
|
|
{
|
|
$graph_array['type'] = 'bgp_' . $vars['graph'];
|
|
$graph_array['id'] = $peer['bgpPeer_id'];
|
|
$peer_graph = TRUE;
|
|
}
|
|
break;
|
|
case 'updates':
|
|
if ($peer['bgpPeer_id'])
|
|
{
|
|
$graph_array['type'] = 'bgp_updates';
|
|
$graph_array['id'] = $peer['bgpPeer_id'];
|
|
$peer_graph = TRUE;
|
|
}
|
|
break;
|
|
case 'macaccounting_bits':
|
|
case 'macaccounting_pkts':
|
|
//FIXME. I really still not know it works or not? -- mike
|
|
// This part copy-pasted from old code as is
|
|
$acc = dbFetchRow("SELECT * FROM `mac_accounting` AS M
|
|
LEFT JOIN `ip_mac` AS I ON M.mac = I.mac_address
|
|
LEFT JOIN `ports` AS P ON P.port_id = M.port_id
|
|
LEFT JOIN `devices` AS D ON D.device_id = P.device_id
|
|
WHERE I.ip_address = ?", array($peer['bgpPeerRemoteAddr']));
|
|
$database = get_rrd_path($device, "cip-" . $acc['ifIndex'] . "-" . $acc['mac'] . ".rrd");
|
|
if (is_array($acc) && is_file($database))
|
|
{
|
|
$peer_graph = TRUE;
|
|
$graph_array['id'] = $acc['ma_id'];
|
|
$graph_array['type'] = $vars['graph'];
|
|
}
|
|
break;
|
|
}
|
|
|
|
if ($peer_graph) {
|
|
$graph_array['to'] = get_time();
|
|
$string .= ' <tr class="' . $peer['html_row_class'] . '">' . PHP_EOL;
|
|
$string .= ' <td class="state-marker"></td><td colspan="10" style="white-space: nowrap">' . PHP_EOL;
|
|
|
|
$string .= generate_graph_row($graph_array);
|
|
|
|
$string .= ' </td>' . PHP_EOL . ' </tr>' . PHP_EOL;
|
|
}
|
|
elseif ($list['graph'])
|
|
{
|
|
// Empty row for correct view class table-striped-two
|
|
$string .= ' <tr class="' . $peer['html_row_class'] . '"><td class="state-marker"></td><td colspan="10"></td></tr>' . PHP_EOL;
|
|
}
|
|
}
|
|
|
|
$string .= ' </tbody>' . PHP_EOL;
|
|
$string .= '</table>';
|
|
|
|
$string .= generate_box_close();
|
|
|
|
// Print pagination header
|
|
if ($entries['pagination_html'])
|
|
{
|
|
$string = $entries['pagination_html'] . $string . $entries['pagination_html'];
|
|
}
|
|
|
|
// Print
|
|
echo $string;
|
|
|
|
}
|
|
|
|
/**
|
|
* Params:
|
|
*
|
|
* pagination, pageno, pagesize
|
|
* device, type, adminstatus, state
|
|
*/
|
|
function get_bgp_array($vars)
|
|
{
|
|
$array = [];
|
|
|
|
// With pagination? (display page numbers in header)
|
|
$array['pagination'] = (isset($vars['pagination']) && $vars['pagination']);
|
|
pagination($vars, 0, TRUE); // Get default pagesize/pageno
|
|
$array['pageno'] = $vars['pageno'];
|
|
$array['pagesize'] = $vars['pagesize'];
|
|
$start = $array['pagesize'] * $array['pageno'] - $array['pagesize'];
|
|
$pagesize = $array['pagesize'];
|
|
|
|
// Require cached IDs from html/includes/cache-data.inc.php
|
|
$cache_bgp = &$GLOBALS['cache']['bgp'];
|
|
|
|
// Begin query generate
|
|
$param = array();
|
|
$where = ' WHERE 1 ';
|
|
foreach ($vars as $var => $value) {
|
|
if ($value != '') {
|
|
switch ($var) {
|
|
case "group":
|
|
case "group_id":
|
|
$values = get_group_entities($value);
|
|
$where .= generate_query_values($values, 'bgpPeer_id');
|
|
break;
|
|
case 'device':
|
|
case 'device_id':
|
|
$where .= generate_query_values($value, 'device_id');
|
|
break;
|
|
case 'peer':
|
|
case 'peer_id':
|
|
$where .= generate_query_values($value, 'peer_device_id');
|
|
break;
|
|
case 'local_ip':
|
|
$where .= generate_query_values(ip_uncompress($value), 'bgpPeerLocalAddr');
|
|
break;
|
|
case 'peer_ip':
|
|
$where .= generate_query_values(ip_uncompress($value), 'bgpPeerRemoteAddr');
|
|
break;
|
|
case 'local_as':
|
|
$where .= generate_query_values(bgp_asdot_to_asplain($value), 'local_as');
|
|
break;
|
|
case 'peer_as':
|
|
$where .= generate_query_values(bgp_asdot_to_asplain($value), 'bgpPeerRemoteAs');
|
|
break;
|
|
case 'type':
|
|
if ($value === 'external' || $value === 'ebgp') {
|
|
$where .= generate_query_values($cache_bgp['external'], 'bgpPeer_id');
|
|
} elseif ($value === 'internal' || $value === 'ibgp') {
|
|
$where .= generate_query_values($cache_bgp['internal'], 'bgpPeer_id');
|
|
}
|
|
break;
|
|
case 'adminstatus':
|
|
if ($value === 'stop') {
|
|
$where .= generate_query_values($cache_bgp['start'], 'bgpPeer_id', '!='); // NOT IN
|
|
} elseif ($value === 'start') {
|
|
$where .= generate_query_values($cache_bgp['start'], 'bgpPeer_id');
|
|
}
|
|
break;
|
|
case 'state':
|
|
if ($value === 'down') {
|
|
$where .= generate_query_values($cache_bgp['up'], 'bgpPeer_id', '!='); // NOT IN
|
|
} elseif ($value === 'up') {
|
|
$where .= generate_query_values($cache_bgp['up'], 'bgpPeer_id');
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Show peers only for permitted devices
|
|
$query_permitted = generate_query_values($cache_bgp['permitted'], 'bgpPeer_id');
|
|
|
|
$query = 'FROM `bgpPeers`';
|
|
$query_count = 'SELECT COUNT(*) ' . $query . $where . $query_permitted; // Use only bgpPeer_id and device_id in query!
|
|
|
|
$query .= ' JOIN `devices` USING (`device_id`) ';
|
|
|
|
//$query .= ' LEFT JOIN `bgpPeers-state` AS S ON `bgpPeer_id` = S.`bgpPeer_id`';
|
|
//$query .= ' LEFT JOIN `devices` AS D ON `device_id` = D.`device_id`';
|
|
$query .= $where . $query_permitted;
|
|
|
|
$query = 'SELECT `hostname`, `bgpLocalAs`, bgpPeers.* ' . $query;
|
|
|
|
$sort_dir = $vars['sort_order'] === 'desc' ? ' DESC' : '';
|
|
|
|
switch($vars['sort']) {
|
|
case "device":
|
|
$sort = " ORDER BY `hostname`".$sort_dir;
|
|
break;
|
|
|
|
case "local_as":
|
|
$sort = " ORDER BY `local_as`$sort_dir, `virtual_name`$sort_dir";
|
|
break;
|
|
|
|
case "peer_ip":
|
|
$sort = " ORDER BY `bgpPeerRemoteAddr`".$sort_dir;
|
|
break;
|
|
|
|
case "peer_as":
|
|
$sort = " ORDER BY `bgpPeerRemoteAs`".$sort_dir;
|
|
break;
|
|
|
|
case 'state':
|
|
$sort = " ORDER BY `bgpPeerAdminStatus`".$sort_dir.", `bgpPeerState`".$sort_dir;
|
|
break;
|
|
|
|
case 'uptime':
|
|
$sort = " ORDER BY `bgpPeerFsmEstablishedTime`".$sort_dir;
|
|
break;
|
|
|
|
default:
|
|
$sort = " ORDER BY `hostname`".$sort_dir.", `bgpPeerRemoteAs`".$sort_dir.", `bgpPeerRemoteAddr`".$sort_dir;
|
|
}
|
|
|
|
$query .= $sort;
|
|
$query .= " LIMIT $start,$pagesize";
|
|
|
|
$peer_devices = array();
|
|
// Query BGP
|
|
foreach (dbFetchRows($query, $param) as $entry)
|
|
{
|
|
humanize_bgp($entry);
|
|
|
|
// Collect peer devices for AFI/SAFI
|
|
$peer_devices[$entry['device_id']] = 1;
|
|
|
|
$array['entries'][] = $entry;
|
|
}
|
|
|
|
// Query AFI/SAFI
|
|
if (count($peer_devices))
|
|
{
|
|
$query_afi = 'SELECT * FROM `bgpPeers_cbgp` WHERE 1' . generate_query_values(array_keys($peer_devices), 'device_id');
|
|
foreach (dbFetchRows($query_afi) as $entry)
|
|
{
|
|
$array['afisafi'][$entry['device_id']][$entry['bgpPeer_id']][$entry['afi'] . '.' . $entry['safi']] = array('afi' => $entry['afi'], 'safi' => $entry['safi']);
|
|
}
|
|
}
|
|
|
|
// Query BGP peers count
|
|
if ($array['pagination']) {
|
|
$array['count'] = dbFetchCell($query_count, $param);
|
|
$array['pagination_html'] = pagination($vars, $array['count']);
|
|
} else {
|
|
$array['count'] = safe_count($array['entries']);
|
|
}
|
|
|
|
return $array;
|
|
}
|
|
|
|
// EOF
|