topotests: Add test for bgp update-delay configuration

Signed-off-by: Don Slice <dslice@nvidia.com>
This commit is contained in:
Don slice 2020-08-28 15:53:03 -04:00 committed by Don Slice
parent d70583f78d
commit 0922d2e56e
12 changed files with 411 additions and 0 deletions

View File

@ -0,0 +1,10 @@
! exit1
router bgp 65001
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65002
neighbor 192.168.255.1 timers connect 10
address-family ipv4 unicast
redistribute connected
exit-address-family
!
!

View File

@ -0,0 +1,9 @@
! exit1
interface lo
ip address 172.16.255.254/32
!
interface r1-eth0
ip address 192.168.255.2/30
!
ip forwarding
!

View File

@ -0,0 +1,18 @@
! spine
router bgp 65002
no bgp ebgp-requires-policy
timers bgp 3 9
neighbor 192.168.255.2 remote-as 65001
neighbor 192.168.254.2 remote-as 65003
neighbor 192.168.253.2 remote-as 65004
neighbor 192.168.255.2 timers connect 10
neighbor 192.168.254.2 timers connect 10
neighbor 192.168.253.2 timers connect 10
!
router bgp 65002 vrf vrf1
no bgp ebgp-requires-policy
timers bgp 3 9
neighbor 192.168.252.2 remote-as 65005
neighbor 192.168.252.2 timers connect 10
!
!

View File

@ -0,0 +1,20 @@
! spine
interface r2-eth0
ip address 192.168.255.1/30
!
interface r2-eth1
ip address 192.168.254.1/30
!
interface r2-eth2
ip address 192.168.253.1/30
!
interface r2-eth3
ip address 192.168.252.1/30
vrf vrf1
!
auto vrf1
iface vrf1
vrf-table auto
!
ip forwarding
!

View File

@ -0,0 +1,10 @@
! exit2
router bgp 65003
no bgp ebgp-requires-policy
timers bgp 3 9
neighbor 192.168.254.1 remote-as 65002
neighbor 192.168.254.1 timers connect 10
address-family ipv4 unicast
redistribute connected
!
!

View File

@ -0,0 +1,9 @@
! exit2
interface lo
ip address 172.16.254.254/32
!
interface r3-eth0
ip address 192.168.254.2/30
!
ip forwarding
!

View File

@ -0,0 +1,11 @@
! exit2
router bgp 65004
no bgp ebgp-requires-policy
timers bgp 3 9
neighbor 192.168.253.1 remote-as 65002
neighbor 192.168.253.1 timers connect 10
address-family ipv4 unicast
redistribute connected
exit-address-family
!
!

View File

@ -0,0 +1,9 @@
! exit2
interface lo
ip address 172.16.253.254/32
!
interface r4-eth0
ip address 192.168.253.2/30
!
ip forwarding
!

View File

@ -0,0 +1,11 @@
! exit1
router bgp 65005
no bgp ebgp-requires-policy
timers bgp 3 9
neighbor 192.168.252.1 remote-as 65002
neighbor 192.168.252.1 timers connect 10
address-family ipv4 unicast
redistribute connected
exit-address-family
!
!

View File

@ -0,0 +1,9 @@
! exit1
interface lo
ip address 172.16.252.254/32
!
interface r1-eth0
ip address 192.168.252.2/30
!
ip forwarding
!

View File

@ -0,0 +1,295 @@
#!/usr/bin/env python
#
# test_bgp_update_delay.py
# Part of NetDEF Topology Tests
#
# Copyright (c) 2019 by
# Don Slice <dslice@nvidia.com>
#
# 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.
#
"""
Test the ability to define update-delay to delay bestpath, rib install
and advertisement to peers when frr is started, restarted or "clear ip
bgp *" is performed. Test both the vrf-specific and global configuration
and operation.
r1
|
r2----r3
| \
| \
r5 r4
r2 is UUT and peers with r1, r3, and r4 in default bgp instance.
r2 peers with r5 in vrf vrf1.
Check r2 initial convergence in default table
Define update-delay with max-delay in the default bgp instance on r2
Shutdown peering on r1 toward r2 so that delay timers can be exercised
Clear bgp neighbors on r2 and then check for the 'in progress' indicator
Check that r2 only installs route learned from r4 after the max-delay timer expires
Define update-delay with max-delay and estabish-wait and check json output showing set
Clear neighbors on r2 and check that r3 installs route from r4 after establish-wait time
Remove update-delay timer on r2 to verify that it goes back to normal behavior
Clear neighbors on r2 and check that route install time on r2 does not delay
Define global bgp update-delay with max-delay and establish-wait on r2
Check that r2 default instance and vrf1 have the max-delay and establish set
Clear neighbors on r2 and check route-install time is after the establish-wait timer
Note that the keepalive/hold times were changed to 3/9 and the connect retry timer
to 10 to improve the odds the convergence timing in this test case is useful in the
event of packet loss.
"""
import os
import sys
import json
import time
import pytest
import functools
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, 6):
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"])
switch = tgen.add_switch("s3")
switch.add_link(tgen.gears["r2"])
switch.add_link(tgen.gears["r4"])
switch = tgen.add_switch("s4")
switch.add_link(tgen.gears["r2"])
switch.add_link(tgen.gears["r5"])
def setup_module(mod):
tgen = Topogen(TemplateTopo, mod.__name__)
tgen.start_topology()
router_list = tgen.routers()
for i, (rname, router) in enumerate(router_list.iteritems(), 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_update_delay():
tgen = get_topogen()
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
router1 = tgen.gears["r1"]
router2 = tgen.gears["r2"]
router3 = tgen.gears["r3"]
# initial convergence without update-delay defined
def _bgp_converge(router):
output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.2 json"))
expected = {
"192.168.255.2": {
"bgpState": "Established",
"addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 2}},
}
}
return topotest.json_cmp(output, expected)
def _bgp_check_update_delay(router):
output = json.loads(router.vtysh_cmd("show ip bgp sum json"))
expected = {"ipv4Unicast": {"updateDelayLimit": 20}}
return topotest.json_cmp(output, expected)
def _bgp_check_update_delay_in_progress(router):
output = json.loads(router.vtysh_cmd("show ip bgp sum json"))
expected = {"ipv4Unicast": {"updateDelayInProgress":True}}
return topotest.json_cmp(output, expected)
def _bgp_check_route_install(router):
output = json.loads(router.vtysh_cmd("show ip route 172.16.253.254/32 json"))
expected = {"172.16.253.254/32": [ {"protocol": "bgp"}]}
return topotest.json_cmp(output, expected)
def _bgp_check_update_delay_and_wait(router):
output = json.loads(router.vtysh_cmd("show ip bgp sum json"))
expected = {
"ipv4Unicast": {
"updateDelayLimit": 20,
"updateDelayEstablishWait": 10}}
return topotest.json_cmp(output, expected)
def _bgp_check_update_delay(router):
output = json.loads(router.vtysh_cmd("show ip bgp sum json"))
expected = {"ipv4Unicast": {"updateDelayLimit": 20}}
return topotest.json_cmp(output, expected)
def _bgp_check_vrf_update_delay_and_wait(router):
output = json.loads(router.vtysh_cmd("show ip bgp vrf vrf1 sum json"))
expected = {
"ipv4Unicast": {
"updateDelayLimit": 20,
"updateDelayEstablishWait": 10}}
return topotest.json_cmp(output, expected)
# Check r2 initial convergence in default table
test_func = functools.partial(_bgp_converge, router2)
success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, 'Failed bgp convergence in "{}"'.format(router2)
# Define update-delay with max-delay in the default bgp instance on r2
router2.vtysh_cmd(
"""
configure terminal
router bgp 65002
update-delay 20
"""
)
# Shutdown peering on r1 toward r2 so that delay timers can be exercised
router1.vtysh_cmd(
"""
configure terminal
router bgp 65001
neighbor 192.168.255.1 shut
"""
)
# Clear bgp neighbors on r2 and then check for the 'in progress' indicator
router2.vtysh_cmd("""clear ip bgp *""")
test_func = functools.partial(_bgp_check_update_delay_in_progress, router2)
success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, 'Failed to set update-delay max-delay timer "{}"'.format(router2)
# Check that r2 only installs route learned from r4 after the max-delay timer expires
test_func = functools.partial(_bgp_check_route_install, router2)
success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, 'Failed to install route after update-delay "{}"'.format(router2)
# Define update-delay with max-delay and estabish-wait and check json output showing set
router2.vtysh_cmd(
"""
configure terminal
router bgp 65002
update-delay 20 10
"""
)
test_func = functools.partial(_bgp_check_update_delay_and_wait, router2)
success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, 'Failed to set max-delay and establish-weight timers in "{}"'.format(router2)
# Define update-delay with max-delay and estabish-wait and check json output showing set
router2.vtysh_cmd("""clear ip bgp *""")
test_func = functools.partial(_bgp_check_route_install, router3)
success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, 'Failed to installed advertised route after establish-wait timer espired "{}"'.format(router2)
# Remove update-delay timer on r2 to verify that it goes back to normal behavior
router2.vtysh_cmd(
"""
configure terminal
router bgp 65002
no update-delay
"""
)
# Clear neighbors on r2 and check that route install time on r2 does not delay
router2.vtysh_cmd("""clear ip bgp *""")
test_func = functools.partial(_bgp_check_route_install, router2)
success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, 'Failed to remove update-delay delay timing "{}"'.format(router2)
# Define global bgp update-delay with max-delay and establish-wait on r2
router2.vtysh_cmd(
"""
configure terminal
bgp update-delay 20 10
"""
)
# Check that r2 default instance and vrf1 have the max-delay and establish set
test_func = functools.partial(_bgp_check_update_delay_and_wait, router2)
success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, 'Failed to set update-delay in default instance "{}"'.format(router2)
test_func = functools.partial(_bgp_check_vrf_update_delay_and_wait, router2)
success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, 'Failed to set update-delay in vrf1 "{}"'.format(router2)
# Clear neighbors on r2 and check route-install time is after the establish-wait timer
router2.vtysh_cmd("""clear ip bgp *""")
test_func = functools.partial(_bgp_check_route_install, router3)
success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, 'Failed to installed advertised route after establish-wait timer espired "{}"'.format(router2)
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))