Skip to content

Commit

Permalink
tests: Check if we are not sending duplicate BGP UPDATEs
Browse files Browse the repository at this point in the history
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
  • Loading branch information
ton31337 committed Nov 13, 2020
1 parent 99ae289 commit 8e66578
Show file tree
Hide file tree
Showing 14 changed files with 335 additions and 0 deletions.
Empty file.
11 changes: 11 additions & 0 deletions tests/topotests/bgp_community_change_update/c1/bgpd.conf
@@ -0,0 +1,11 @@
!
debug bgp updates
!
router bgp 65001
no bgp ebgp-requires-policy
neighbor 10.0.1.2 remote-as external
neighbor 10.0.1.2 timers 3 10
address-family ipv4 unicast
redistribute connected
exit-address-family
!
6 changes: 6 additions & 0 deletions tests/topotests/bgp_community_change_update/c1/zebra.conf
@@ -0,0 +1,6 @@
!
interface c1-eth0
ip address 10.0.1.1/30
!
ip forwarding
!
@@ -0,0 +1,183 @@
#!/usr/bin/env python

# Copyright (c) 2020 by
# Donatas Abraitis <donatas.abraitis@gmail.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.
#

"""
Reference: https://www.cmand.org/communityexploration
--y2--
/ | \
c1 ---- x1 ---- y1 | z1
\ | /
--y3--
1. z1 announces 192.168.255.254/32 to y2, y3.
2. y2 and y3 tags this prefix at ingress with appropriate
communities 65004:2 (y2) and 65004:3 (y3).
3. x1 filters all communities at the egress to c1.
4. Shutdown the link between y1 and y2.
5. y1 will generate a BGP UPDATE message regarding the next-hop change.
6. x1 will generate a BGP UPDATE message regarding community change.
To avoid sending duplicate BGP UPDATE messages we should make sure
we send only actual route updates. In this example, x1 will skip
BGP UPDATE to c1 because the actual route is the same
(filtered communities - nothing changes).
"""

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)

tgen.add_router("z1")
tgen.add_router("y1")
tgen.add_router("y2")
tgen.add_router("y3")
tgen.add_router("x1")
tgen.add_router("c1")

# 10.0.1.0/30
switch = tgen.add_switch("s1")
switch.add_link(tgen.gears["c1"])
switch.add_link(tgen.gears["x1"])

# 10.0.2.0/30
switch = tgen.add_switch("s2")
switch.add_link(tgen.gears["x1"])
switch.add_link(tgen.gears["y1"])

# 10.0.3.0/30
switch = tgen.add_switch("s3")
switch.add_link(tgen.gears["y1"])
switch.add_link(tgen.gears["y2"])

# 10.0.4.0/30
switch = tgen.add_switch("s4")
switch.add_link(tgen.gears["y1"])
switch.add_link(tgen.gears["y3"])

# 10.0.5.0/30
switch = tgen.add_switch("s5")
switch.add_link(tgen.gears["y2"])
switch.add_link(tgen.gears["y3"])

# 10.0.6.0/30
switch = tgen.add_switch("s6")
switch.add_link(tgen.gears["y2"])
switch.add_link(tgen.gears["z1"])

# 10.0.7.0/30
switch = tgen.add_switch("s7")
switch.add_link(tgen.gears["y3"])
switch.add_link(tgen.gears["z1"])


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_community_update_path_change():
tgen = get_topogen()

if tgen.routers_have_failure():
pytest.skip(tgen.errors)

def _bgp_converge_initial():
output = json.loads(
tgen.gears["c1"].vtysh_cmd("show ip bgp neighbor 10.0.1.2 json")
)
expected = {
"10.0.1.2": {
"bgpState": "Established",
"addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 8}},
}
}
return topotest.json_cmp(output, expected)

test_func = functools.partial(_bgp_converge_initial)
success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result is None, "Failed to see bgp convergence in c1"

# Shutdown link between y1 and y2.
tgen.gears["y1"].run("ifconfig y1-eth1 down")

def _bgp_converge_after_changes():
output = json.loads(tgen.gears["y1"].vtysh_cmd("show ip bgp nei 10.0.3.2 json"))
expected = {"10.0.3.2": {"bgpState": "Active"}}
return topotest.json_cmp(output, expected)

test_func = functools.partial(_bgp_converge_after_changes)
success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result is None, "Failed to see bgp convergence in y1"

def _bgp_check_for_duplicate_updates():
if (
len(
tgen.gears["c1"].run(
'grep "10.0.1.2 rcvd 192.168.255.254/32 IPv4 unicast...duplicate ignored" bgpd.log'
)
)
> 0
):
return False
return True

assert (
_bgp_check_for_duplicate_updates() == True
), "Seen duplicate BGP UPDATE message in c1 from x1"


if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))
20 changes: 20 additions & 0 deletions tests/topotests/bgp_community_change_update/x1/bgpd.conf
@@ -0,0 +1,20 @@
!
debug bgp updates
!
router bgp 65002
no bgp ebgp-requires-policy
neighbor 10.0.1.1 remote-as external
neighbor 10.0.1.1 timers 3 10
neighbor 10.0.2.2 remote-as external
neighbor 10.0.2.2 timers 3 10
address-family ipv4 unicast
redistribute connected
neighbor 10.0.1.1 route-map c1 out
exit-address-family
!
bgp community-list standard c1 seq 1 permit 65004:2
bgp community-list standard c1 seq 2 permit 65004:3
!
route-map c1 permit 10
set comm-list c1 delete
!
9 changes: 9 additions & 0 deletions tests/topotests/bgp_community_change_update/x1/zebra.conf
@@ -0,0 +1,9 @@
!
interface x1-eth0
ip address 10.0.1.2/30
!
interface x1-eth1
ip address 10.0.2.1/30
!
ip forwarding
!
12 changes: 12 additions & 0 deletions tests/topotests/bgp_community_change_update/y1/bgpd.conf
@@ -0,0 +1,12 @@
router bgp 65003
no bgp ebgp-requires-policy
neighbor 10.0.2.1 remote-as external
neighbor 10.0.2.1 timers 3 10
neighbor 10.0.3.2 remote-as internal
neighbor 10.0.3.2 timers 3 10
neighbor 10.0.4.2 remote-as internal
neighbor 10.0.4.2 timers 3 10
address-family ipv4 unicast
redistribute connected
exit-address-family
!
12 changes: 12 additions & 0 deletions tests/topotests/bgp_community_change_update/y1/zebra.conf
@@ -0,0 +1,12 @@
!
interface y1-eth0
ip address 10.0.2.2/30
!
interface y1-eth1
ip address 10.0.3.1/30
!
interface y1-eth2
ip address 10.0.4.1/30
!
ip forwarding
!
18 changes: 18 additions & 0 deletions tests/topotests/bgp_community_change_update/y2/bgpd.conf
@@ -0,0 +1,18 @@
router bgp 65003
no bgp ebgp-requires-policy
neighbor 10.0.3.1 remote-as internal
neighbor 10.0.3.1 timers 3 10
neighbor 10.0.5.2 remote-as internal
neighbor 10.0.5.2 timers 3 10
neighbor 10.0.6.2 remote-as external
neighbor 10.0.6.2 timers 3 10
address-family ipv4 unicast
redistribute connected
neighbor 10.0.3.1 route-reflector-client
neighbor 10.0.5.2 route-reflector-client
neighbor 10.0.6.2 route-map z1 in
exit-address-family
!
route-map z1 permit 10
set community 65004:2
!
12 changes: 12 additions & 0 deletions tests/topotests/bgp_community_change_update/y2/zebra.conf
@@ -0,0 +1,12 @@
!
interface y2-eth0
ip address 10.0.3.2/30
!
interface y2-eth1
ip address 10.0.5.1/30
!
interface y2-eth2
ip address 10.0.6.1/30
!
ip forwarding
!
18 changes: 18 additions & 0 deletions tests/topotests/bgp_community_change_update/y3/bgpd.conf
@@ -0,0 +1,18 @@
router bgp 65003
no bgp ebgp-requires-policy
neighbor 10.0.4.1 remote-as internal
neighbor 10.0.4.1 timers 3 10
neighbor 10.0.5.1 remote-as internal
neighbor 10.0.5.1 timers 3 10
neighbor 10.0.7.2 remote-as external
neighbor 10.0.7.2 timers 3 10
address-family ipv4 unicast
redistribute connected
neighbor 10.0.4.1 route-reflector-client
neighbor 10.0.5.1 route-reflector-client
neighbor 10.0.7.2 route-map z1 in
exit-address-family
!
route-map z1 permit 10
set community 65004:3
!
12 changes: 12 additions & 0 deletions tests/topotests/bgp_community_change_update/y3/zebra.conf
@@ -0,0 +1,12 @@
!
interface y3-eth0
ip address 10.0.4.2/30
!
interface y3-eth1
ip address 10.0.5.2/30
!
interface y3-eth2
ip address 10.0.7.1/30
!
ip forwarding
!
10 changes: 10 additions & 0 deletions tests/topotests/bgp_community_change_update/z1/bgpd.conf
@@ -0,0 +1,10 @@
router bgp 65004
no bgp ebgp-requires-policy
neighbor 10.0.6.1 remote-as external
neighbor 10.0.6.1 timers 3 10
neighbor 10.0.7.1 remote-as external
neighbor 10.0.7.1 timers 3 10
address-family ipv4 unicast
redistribute connected
exit-address-family
!
12 changes: 12 additions & 0 deletions tests/topotests/bgp_community_change_update/z1/zebra.conf
@@ -0,0 +1,12 @@
!
interface lo
ip address 192.168.255.254/32
!
interface z1-eth0
ip address 10.0.6.2/30
!
interface z1-eth1
ip address 10.0.7.2/30
!
ip forwarding
!

0 comments on commit 8e66578

Please sign in to comment.