Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e3228ed

Browse files
committed
New Bird BFD things
1 parent ad806ff commit e3228ed

12 files changed

Lines changed: 1278 additions & 16 deletions

File tree

app/Http/Controllers/Services/LookingGlass.php

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,33 @@ public function __construct( Request $request )
9999
$this->request = $request;
100100
}
101101

102+
/**
103+
* Safely decode a JSON response from the looking glass backend.
104+
*
105+
* Birdseye/birdwatcher can return garbage (HTML error pages, empty bodies,
106+
* control characters) when the daemon is restarting or hits an internal
107+
* error. Without this guard, json_decode throws and we 500 the user.
108+
*
109+
* Returns an object with an empty "routes" array as a safe default so the
110+
* template always has something iterable.
111+
*/
112+
private function safeJsonDecode( ?string $raw ): object
113+
{
114+
if ( $raw === null || $raw === '' ) {
115+
return (object)['routes' => []];
116+
}
117+
try {
118+
$decoded = json_decode( $raw, false, 512, JSON_THROW_ON_ERROR );
119+
return is_object( $decoded ) ? $decoded : (object)['routes' => []];
120+
} catch ( \Throwable $e ) {
121+
\Log::warning( '[LookingGlass] Invalid JSON from backend', [
122+
'error' => $e->getMessage(),
123+
'sample' => substr( (string)$raw, 0, 200 ),
124+
] );
125+
return (object)['routes' => []];
126+
}
127+
}
128+
102129
/**
103130
* Looking glass accessor
104131
*
@@ -142,7 +169,7 @@ private function addCommonParams( View $view ): View
142169
$cust = Auth::check() ? Customer::find( Auth::getUser()->custid ) : null;
143170
$user = Auth::check() ? User::find( Auth::id() ) : null;
144171

145-
$view->with( 'status', json_decode( $this->lg()->status(), false, 512, JSON_THROW_ON_ERROR));
172+
$view->with( 'status', $this->safeJsonDecode( $this->lg()->status() ));
146173
$view->with( 'lg', $this->lg() );
147174
$view->with( 'routers', RouterAggregator::forDropdown( $cust, $user ) );
148175
$view->with( 'tabRouters', RouterAggregator::forTab( $cust, $user ) );
@@ -212,7 +239,7 @@ public function bgpSummary(string $handle ): View
212239
{
213240
// get bgp protocol summary
214241
$view = view('services/lg/bgp-summary' )->with([
215-
'content' => json_decode( $this->lg()->bgpSummary(), false, 512, JSON_THROW_ON_ERROR),
242+
'content' => $this->safeJsonDecode( $this->lg()->bgpSummary() ),
216243
]);
217244

218245
return $this->addCommonParams( $view );
@@ -246,7 +273,7 @@ public function routesForTable( string $handle, string $table ): RedirectRespons
246273
}
247274

248275
$view = view('services/lg/routes' )->with([
249-
'content' => json_decode($routes, false, 512, JSON_THROW_ON_ERROR),
276+
'content' => $this->safeJsonDecode( $routes ),
250277
'source' => 'table', 'name' => $table,
251278
'peerName' => null,
252279
]);
@@ -265,7 +292,7 @@ public function routesForProtocol( string $handle, string $protocol ): RedirectR
265292
try{
266293
// get bgp protocol summary
267294
$view = view('services/lg/routes' )->with([
268-
'content' => json_decode( $this->lg()->routesForProtocol( $protocol ), false, 512, JSON_THROW_ON_ERROR),
295+
'content' => $this->safeJsonDecode( $this->lg()->routesForProtocol( $protocol ) ),
269296
'source' => 'protocol', 'name' => $protocol,
270297
'peerName' => $this->peerName( $protocol ),
271298
]);
@@ -288,7 +315,7 @@ public function routesForExport( string $handle, string $protocol ): View
288315
{
289316
// get bgp protocol summary
290317
$view = view('services/lg/routes' )->with([
291-
'content' => json_decode( $this->lg()->routesForExport( $protocol ), false, 512, JSON_THROW_ON_ERROR),
318+
'content' => $this->safeJsonDecode( $this->lg()->routesForExport( $protocol ) ),
292319
'source' => 'export to protocol',
293320
'name' => $protocol,
294321
'peerName' => $this->peerName( $protocol ),
@@ -308,11 +335,8 @@ public function routesForExport( string $handle, string $protocol ): View
308335
*/
309336
public function routeProtocol( string $handle, string $network, string $mask, string $protocol ): View
310337
{
311-
$raw = $this->lg()->protocolRoute($protocol, $network, (int) $mask);
312-
$content = json_decode($raw, false);
313-
314338
return view('services/lg/route' )->with([
315-
'content' => $content ?: (object)['routes' => []],
339+
'content' => $this->safeJsonDecode( $this->lg()->protocolRoute($protocol, $network, (int) $mask) ),
316340
'source' => 'protocol',
317341
'name' => $protocol,
318342
'lg' => $this->lg(),
@@ -332,11 +356,8 @@ public function routeProtocol( string $handle, string $network, string $mask, st
332356
*/
333357
public function routeTable( string $handle, string $network, string $mask, string $table ): View
334358
{
335-
$raw = $this->lg()->protocolTable( $table, $network, (int)$mask );
336-
$content = json_decode( $raw, false );
337-
338359
return view('services/lg/route')->with( [
339-
'content' => $content ?: (object)['routes' => []],
360+
'content' => $this->safeJsonDecode( $this->lg()->protocolTable( $table, $network, (int)$mask ) ),
340361
'source' => 'table',
341362
'name' => $table,
342363
'lg' => $this->lg(),
@@ -357,7 +378,7 @@ public function routeTable( string $handle, string $network, string $mask, strin
357378
public function routeExport( string $handle, string $network, string $mask, string $protocol ): View
358379
{
359380
return view('services/lg/route' )->with([
360-
'content' => json_decode( $this->lg()->exportRoute( $protocol, $network, (int)$mask ), false ),
381+
'content' => $this->safeJsonDecode( $this->lg()->exportRoute( $protocol, $network, (int)$mask ) ),
361382
'source' => 'export',
362383
'name' => $protocol,
363384
'lg' => $this->lg(),
@@ -503,7 +524,7 @@ public function routesFiltered( string $handle, string $protocol ): RedirectResp
503524
try {
504525
$routes = $this->getFilteredRoutes( $protocol );
505526
$view = view('services/lg/routes' )->with([
506-
'content' => json_decode( $routes, false, 512, JSON_THROW_ON_ERROR ),
527+
'content' => $this->safeJsonDecode( $routes ),
507528
'source' => 'filtered from protocol',
508529
'name' => $protocol,
509530
'peerName' => $this->peerName( $protocol ),
@@ -523,7 +544,7 @@ public function routesNotExported( string $handle, string $protocol ): RedirectR
523544
try {
524545
$routes = $this->getNotExportedRoutes( $protocol );
525546
$view = view('services/lg/routes' )->with([
526-
'content' => json_decode( $routes, false, 512, JSON_THROW_ON_ERROR ),
547+
'content' => $this->safeJsonDecode( $routes ),
527548
'source' => 'not exported to protocol',
528549
'name' => $protocol,
529550
'peerName' => $this->peerName( $protocol ),
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
/*
3+
* Bird Route Server Configuration Template
4+
*
5+
*
6+
* You should not need to edit these files - instead use your own custom skins. If
7+
* you can't effect the changes you need with skinning, consider posting to the mailing
8+
* list to see if it can be achieved / incorporated.
9+
*
10+
* Skinning: https://ixp-manager.readthedocs.io/en/latest/features/skinning.html
11+
*
12+
* Copyright (C) 2009 - 2019 Internet Neutral Exchange Association Company Limited By Guarantee.
13+
* All Rights Reserved.
14+
*
15+
* This file is part of IXP Manager.
16+
*
17+
* IXP Manager is free software: you can redistribute it and/or modify it
18+
* under the terms of the GNU General Public License as published by the Free
19+
* Software Foundation, version v2.0 of the License.
20+
*
21+
* IXP Manager is distributed in the hope that it will be useful, but WITHOUT
22+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
24+
* more details.
25+
*
26+
* You should have received a copy of the GNU General Public License v2.0
27+
* along with IXP Manager. If not, see:
28+
*
29+
* http://www.gnu.org/licenses/gpl-2.0.html
30+
*/
31+
?>
32+
33+
########################################################################################
34+
########################################################################################
35+
#
36+
# Standard IXP community filter
37+
#
38+
########################################################################################
39+
########################################################################################
40+
41+
42+
function ixp_community_filter(int peerasn) -> bool
43+
{
44+
if !(source = RTS_BGP) then
45+
return false;
46+
47+
<?php if( $t->router->bgp_lc ): ?>
48+
# AS path prepending
49+
if (routeserverasn, 103, peerasn) ~ bgp_large_community then {
50+
bgp_path.prepend( bgp_path.first );
51+
bgp_path.prepend( bgp_path.first );
52+
bgp_path.prepend( bgp_path.first );
53+
} else if (routeserverasn, 102, peerasn) ~ bgp_large_community then {
54+
bgp_path.prepend( bgp_path.first );
55+
bgp_path.prepend( bgp_path.first );
56+
} else if (routeserverasn, 101, peerasn) ~ bgp_large_community then {
57+
bgp_path.prepend( bgp_path.first );
58+
} else if (routeserverasn, 103, 0) ~ bgp_large_community then {
59+
bgp_path.prepend( bgp_path.first );
60+
bgp_path.prepend( bgp_path.first );
61+
bgp_path.prepend( bgp_path.first );
62+
} else if (routeserverasn, 102, 0) ~ bgp_large_community then {
63+
bgp_path.prepend( bgp_path.first );
64+
bgp_path.prepend( bgp_path.first );
65+
} else if (routeserverasn, 101, 0) ~ bgp_large_community then {
66+
bgp_path.prepend( bgp_path.first );
67+
}
68+
69+
70+
# support for BGP Large Communities
71+
if (routeserverasn, 0, peerasn) ~ bgp_large_community then
72+
return false;
73+
if (routeserverasn, 1, peerasn) ~ bgp_large_community then
74+
return true;
75+
if (routeserverasn, 0, 0) ~ bgp_large_community then
76+
return false;
77+
if (routeserverasn, 1, 0) ~ bgp_large_community then
78+
return true;
79+
80+
<?php endif; ?>
81+
# it's unwise to conduct a 32-bit check on a 16-bit value
82+
if routeserverasn > 65535 || peerasn > 65535 then
83+
return true;
84+
85+
<?php if( $t->router->asn <= 65535 ): ?>
86+
# Implement widely used community filtering schema.
87+
if (0, peerasn) ~ bgp_community then
88+
return false;
89+
if (routeserverasn, peerasn) ~ bgp_community then
90+
return true;
91+
if (0, routeserverasn) ~ bgp_community then
92+
return false;
93+
94+
<?php endif; ?>
95+
return true;
96+
}
97+
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
2+
########################################################################################
3+
########################################################################################
4+
#
5+
# Community filtering definitions for use with looking glasses
6+
#
7+
# Current implementation based on:
8+
#
9+
# https://github.com/euro-ix/rs-workshop-july-2017/wiki/Route-Server-BGP-Community-usage
10+
#
11+
########################################################################################
12+
########################################################################################
13+
14+
15+
16+
# These will all be filtered and not piped to the master table:
17+
18+
define IXP_LC_FILTERED_PREFIX_LEN_TOO_LONG = ( routeserverasn, 1101, 1 );
19+
define IXP_LC_FILTERED_PREFIX_LEN_TOO_SHORT = ( routeserverasn, 1101, 2 );
20+
define IXP_LC_FILTERED_BOGON = ( routeserverasn, 1101, 3 );
21+
define IXP_LC_FILTERED_BOGON_ASN = ( routeserverasn, 1101, 4 );
22+
define IXP_LC_FILTERED_AS_PATH_TOO_LONG = ( routeserverasn, 1101, 5 );
23+
define IXP_LC_FILTERED_AS_PATH_TOO_SHORT = ( routeserverasn, 1101, 6 );
24+
define IXP_LC_FILTERED_FIRST_AS_NOT_PEER_AS = ( routeserverasn, 1101, 7 );
25+
define IXP_LC_FILTERED_NEXT_HOP_NOT_PEER_IP = ( routeserverasn, 1101, 8 );
26+
define IXP_LC_FILTERED_IRRDB_PREFIX_FILTERED = ( routeserverasn, 1101, 9 );
27+
define IXP_LC_FILTERED_IRRDB_ORIGIN_AS_FILTERED = ( routeserverasn, 1101, 10 );
28+
define IXP_LC_FILTERED_PREFIX_NOT_IN_ORIGIN_AS = ( routeserverasn, 1101, 11 );
29+
30+
define IXP_LC_FILTERED_RPKI_UNKNOWN = ( routeserverasn, 1101, 12 );
31+
define IXP_LC_FILTERED_RPKI_INVALID = ( routeserverasn, 1101, 13 );
32+
define IXP_LC_FILTERED_TRANSIT_FREE_ASN = ( routeserverasn, 1101, 14 );
33+
define IXP_LC_FILTERED_TOO_MANY_COMMUNITIES = ( routeserverasn, 1101, 15 );
34+
35+
36+
37+
38+
# Informational prefixes
39+
40+
define IXP_LC_INFO_RPKI_VALID = ( routeserverasn, 1000, 1 );
41+
define IXP_LC_INFO_RPKI_UNKNOWN = ( routeserverasn, 1000, 2 );
42+
define IXP_LC_INFO_RPKI_NOT_CHECKED = ( routeserverasn, 1000, 3 );
43+
44+
define IXP_LC_INFO_IRRDB_VALID = ( routeserverasn, 1001, 1 );
45+
define IXP_LC_INFO_IRRDB_NOT_CHECKED = ( routeserverasn, 1001, 2 );
46+
define IXP_LC_INFO_IRRDB_MORE_SPECIFIC = ( routeserverasn, 1001, 3 );
47+
48+
define IXP_LC_INFO_IRRDB_FILTERED_LOOSE = ( routeserverasn, 1001, 1000 );
49+
define IXP_LC_INFO_IRRDB_FILTERED_STRICT = ( routeserverasn, 1001, 1001 );
50+
define IXP_LC_INFO_IRRDB_PREFIX_EMPTY = ( routeserverasn, 1001, 1002 );
51+
52+
define IXP_LC_INFO_SAME_AS_NEXT_HOP = ( routeserverasn, 1001, 1200 );
53+
54+
# ( routeserverasn, 1010, peerasn ) -> route learnt from peerasn via routeserverasn
55+
# ( routeserverasn, 1011, originasn ) -> route origin asn via routeserverasn
56+
57+
58+
# And the filter for examining routes in the peers import table being exported
59+
# to the master table
60+
61+
filter f_export_to_master
62+
{
63+
64+
if bgp_large_community ~ [( routeserverasn, 1101, * )] then reject;
65+
66+
accept;
67+
}
68+
69+
70+
71+

0 commit comments

Comments
 (0)