tests: Advertise FIB installed routes to bgp peers

Added test case for bgp suppress-fib-pending
Updated document

Signed-off-by: kssoman <somanks@gmail.com>
This commit is contained in:
Soman K S 2020-11-06 08:59:39 +05:30
parent a77e2f4bab
commit 1cc5593892
10 changed files with 252 additions and 0 deletions

View File

@ -3412,6 +3412,48 @@ starting the daemon and the configuration gets saved, the option will persist
unless removed from the configuration with the negating command prior to the
configuration write operation.
.. _bgp-suppress-fib:
Suppressing routes not installed in FIB
=======================================
The FRR implementation of BGP advertises prefixes learnt from a peer to other
peers even if the routes do not get installed in the FIB. There can be
scenarios where the hardware tables in some of the routers (along the path from
the source to destination) is full which will result in all routes not getting
installed in the FIB. If these routes are advertised to the downstream routers
then traffic will start flowing and will be dropped at the intermediate router.
The solution is to provide a configurable option to check for the FIB install
status of the prefixes and advertise to peers if the prefixes are successfully
installed in the FIB. The advertisement of the prefixes are suppressed if it is
not installed in FIB.
The following conditions apply will apply when checking for route installation
status in FIB:
1. The advertisement or suppression of routes based on FIB install status
applies only for newly learnt routes from peer (routes which are not in
BGP local RIB).
2. If the route received from peer already exists in BGP local RIB and route
attributes have changed (best path changed), the old path is deleted and
new path is installed in FIB. The FIB install status will not have any
effect. Therefore only when the route is received first time the checks
apply.
3. The feature will not apply for routes learnt through other means like
redistribution to bgp from other protocols. This is applicable only to
peer learnt routes.
4. If a route is installed in FIB and then gets deleted from the dataplane,
then routes will not be withdrawn from peers. This will be considered as
dataplane issue.
5. The feature will slightly increase the time required to advertise the routes
to peers since the route install status needs to be received from the FIB
6. If routes are received by the peer before the configuration is applied, then
the bgp sessions need to be reset for the configuration to take effect.
7. If the route which is already installed in dataplane is removed for some
reason, sending withdraw message to peers is not currently supported.
.. index:: [no] bgp suppress-fib-pending
.. clicmd:: [no] bgp suppress-fib-pending
.. _routing-policy:

View File

@ -0,0 +1,15 @@
! exit1
router bgp 1
no bgp ebgp-requires-policy
neighbor 10.0.0.2 remote-as 2
address-family ipv4 unicast
redistribute static
neighbor 10.0.0.2 route-map rmap out
exit-address-family
ip prefix-list plist seq 5 permit any
route-map rmap permit 1
match ip address prefix-list plist
!

View File

@ -0,0 +1,9 @@
! exit1
interface r1-eth0
ip address 10.0.0.1/30
!
ip forwarding
!
ip route 40.0.0.0/8 blackhole
ip route 50.0.0.0/8 blackhole
!

View File

@ -0,0 +1,6 @@
!
router bgp 2
no bgp ebgp-requires-policy
bgp suppress-fib-pending
neighbor 10.0.0.1 remote-as 1
neighbor 10.0.0.10 remote-as 3

View File

@ -0,0 +1,13 @@
!
interface r2-eth0
ip address 10.0.0.2/30
!
interface r2-eth1
ip address 10.0.0.9/30
access-list access seq 5 permit 40.0.0.0/8
route-map LIMIT permit 10
match ip address access
ip protocol bgp route-map LIMIT

View File

@ -0,0 +1,9 @@
!
router bgp 3
no bgp ebgp-requires-policy
neighbor 10.0.0.9 remote-as 2
route-map rmap permit 1
match ip address prefix-list plist
!
!

View File

@ -0,0 +1,29 @@
{
"40.0.0.0\/8":[
{
"prefix":"40.0.0.0\/8",
"protocol":"bgp",
"selected":true,
"destSelected":true,
"distance":20,
"metric":0,
"installed":true,
"table":254,
"internalStatus":16,
"internalFlags":8,
"internalNextHopNum":1,
"internalNextHopActiveNum":1,
"nexthops":[
{
"flags":3,
"fib":true,
"ip":"10.0.0.9",
"afi":"ipv4",
"interfaceIndex":2,
"interfaceName":"r3-eth0",
"active":true
}
]
}
]
}

View File

@ -0,0 +1,4 @@
{
"0.0.0.0\/0":[
]
}

View File

@ -0,0 +1,6 @@
!
interface r3-eth0
ip address 10.0.0.10/30
!
ip forwarding
!

View File

@ -0,0 +1,119 @@
#!/usr/bin/env python
#
# test_bgp_suppress_fib.py
#
# Copyright (c) 2019 by
#
# Permission to use, copy, modify, and/or distribute this software
# for any purpose with or without fee is hereby granted, provided
# that the above copyright notice and this permission notice appear
# in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
#
"""
"""
import os
import sys
import json
import time
import pytest
from functools import partial
from time import sleep
CWD = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(CWD, "../"))
# pylint: disable=C0413
from lib import topotest
from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.topolog import logger
from mininet.topo import Topo
class TemplateTopo(Topo):
def build(self, *_args, **_opts):
tgen = get_topogen(self)
for routern in range(1, 4):
tgen.add_router("r{}".format(routern))
switch = tgen.add_switch("s1")
switch.add_link(tgen.gears["r1"])
switch.add_link(tgen.gears["r2"])
switch = tgen.add_switch("s2")
switch.add_link(tgen.gears["r2"])
switch.add_link(tgen.gears["r3"])
def setup_module(mod):
tgen = Topogen(TemplateTopo, mod.__name__)
tgen.start_topology()
router_list = tgen.routers()
for i, (rname, router) in enumerate(router_list.items(), 1):
router.load_config(
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
)
router.load_config(
TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
)
tgen.start_router()
def teardown_module(mod):
tgen = get_topogen()
tgen.stop_topology()
def test_bgp_route():
tgen = get_topogen()
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
r3 = tgen.gears["r3"]
sleep(5)
json_file = "{}/r3/v4_route.json".format(CWD)
expected = json.loads(open(json_file).read())
test_func = partial(
topotest.router_json_cmp,
r3,
"show ip route 40.0.0.0 json",
expected,
)
_, result = topotest.run_and_expect(test_func, None, count=2, wait=0.5)
assertmsg = '"r3" JSON output mismatches'
assert result is None, assertmsg
json_file = "{}/r3/v4_route2.json".format(CWD)
expected = json.loads(open(json_file).read())
test_func = partial(
topotest.router_json_cmp,
r3,
"show ip route 50.0.0.0 json",
expected,
)
_, result = topotest.run_and_expect(test_func, None, count=3, wait=0.5)
assertmsg = '"r3" JSON output mismatches'
assert result is None, assertmsg
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))