diff options
Diffstat (limited to 'tests/topotests/bgp_vrf_netns')
-rw-r--r-- | tests/topotests/bgp_vrf_netns/__init__.py | 0 | ||||
-rw-r--r-- | tests/topotests/bgp_vrf_netns/bgp-vrf-netns-topo.dot | 50 | ||||
-rw-r--r-- | tests/topotests/bgp_vrf_netns/bgp-vrf-netns-topo.pdf | bin | 0 -> 13104 bytes | |||
-rw-r--r-- | tests/topotests/bgp_vrf_netns/exabgp.env | 54 | ||||
-rwxr-xr-x | tests/topotests/bgp_vrf_netns/peer1/exa-send.py | 28 | ||||
-rw-r--r-- | tests/topotests/bgp_vrf_netns/peer1/exabgp.cfg | 21 | ||||
-rw-r--r-- | tests/topotests/bgp_vrf_netns/r1/bgpd.conf | 10 | ||||
-rw-r--r-- | tests/topotests/bgp_vrf_netns/r1/summary.txt | 17 | ||||
-rw-r--r-- | tests/topotests/bgp_vrf_netns/r1/summary20.txt | 15 | ||||
-rw-r--r-- | tests/topotests/bgp_vrf_netns/r1/zebra.conf | 7 | ||||
-rw-r--r-- | tests/topotests/bgp_vrf_netns/test_bgp_vrf_netns_topo.py | 212 |
11 files changed, 414 insertions, 0 deletions
diff --git a/tests/topotests/bgp_vrf_netns/__init__.py b/tests/topotests/bgp_vrf_netns/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/__init__.py diff --git a/tests/topotests/bgp_vrf_netns/bgp-vrf-netns-topo.dot b/tests/topotests/bgp_vrf_netns/bgp-vrf-netns-topo.dot new file mode 100644 index 0000000..2b1f72b --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/bgp-vrf-netns-topo.dot @@ -0,0 +1,50 @@ +## Color coding: +######################### +## Main FRR: #f08080 red +## Switches: #d0e0d0 gray +## RIP: #19e3d9 Cyan +## RIPng: #fcb314 dark yellow +## OSPFv2: #32b835 Green +## OSPFv3: #19e3d9 Cyan +## ISIS IPv4 #fcb314 dark yellow +## ISIS IPv6 #9a81ec purple +## BGP IPv4 #eee3d3 beige +## BGP IPv6 #fdff00 yellow +##### Colors (see http://www.color-hex.com/) + +graph bgp_vrf_netns_eBGP_topo1 { + label="bgp vrf netns topo1 - eBGP with different AS numbers"; + labelloc="t"; + + # Routers + r1 [ + label="r1\nrtr-id 10.0.255.1/32", + shape=doubleoctagon, + fillcolor="#f08080", + style=filled, + ]; + + # 1 Switch for eBGP Peers + s1 [ + label="s1\n10.0.1.0/24", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + + # 1 ExaBGP Peers AS 101 + peer1 [ + label="eBGP peer1\nAS101\nrtr-id 10.0.1.101/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + + # Connections + r1 -- s1 [label="eth0\n.1"]; + + peer1 -- s1 [label="eth0\n.101"]; + + # Arrange network to make cleaner diagram + { rank=same peer1 } -- s1 -- { rank=same r1 } [style=invis] +} diff --git a/tests/topotests/bgp_vrf_netns/bgp-vrf-netns-topo.pdf b/tests/topotests/bgp_vrf_netns/bgp-vrf-netns-topo.pdf Binary files differnew file mode 100644 index 0000000..6da2288 --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/bgp-vrf-netns-topo.pdf diff --git a/tests/topotests/bgp_vrf_netns/exabgp.env b/tests/topotests/bgp_vrf_netns/exabgp.env new file mode 100644 index 0000000..a328e04 --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/exabgp.env @@ -0,0 +1,54 @@ + +[exabgp.api] +encoder = text +highres = false +respawn = false +socket = '' + +[exabgp.bgp] +openwait = 60 + +[exabgp.cache] +attributes = true +nexthops = true + +[exabgp.daemon] +daemonize = true +pid = '/var/run/exabgp/exabgp.pid' +user = 'exabgp' +##daemonize = false + +[exabgp.log] +all = false +configuration = true +daemon = true +destination = '/var/log/exabgp.log' +enable = true +level = INFO +message = false +network = true +packets = false +parser = false +processes = true +reactor = true +rib = false +routes = false +short = false +timers = false + +[exabgp.pdb] +enable = false + +[exabgp.profile] +enable = false +file = '' + +[exabgp.reactor] +speed = 1.0 + +[exabgp.tcp] +acl = false +bind = '' +delay = 0 +once = false +port = 179 diff --git a/tests/topotests/bgp_vrf_netns/peer1/exa-send.py b/tests/topotests/bgp_vrf_netns/peer1/exa-send.py new file mode 100755 index 0000000..ab0eb8c --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/peer1/exa-send.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python2 + +""" +exa-send.py: Send a few testroutes with ExaBGP +""" + +from sys import stdout, argv +from time import sleep + +sleep(5) + +# 1st arg is peer number +# 2nd arg is number of routes to send +peer = int(argv[1]) +numRoutes = int(argv[2]) +asnum = 99 + +# Announce numRoutes equal routes per PE - different neighbor AS +for i in range(0, numRoutes): + stdout.write( + "announce route 10.201.%s.0/24 med 100 community %i:1 next-hop 10.0.%i.%i\n" + % (i, i, (((peer - 1) / 5) + 1), peer + 100) + ) + stdout.flush() + +# Loop endlessly to allow ExaBGP to continue running +while True: + sleep(1) diff --git a/tests/topotests/bgp_vrf_netns/peer1/exabgp.cfg b/tests/topotests/bgp_vrf_netns/peer1/exabgp.cfg new file mode 100644 index 0000000..2d0ca89 --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/peer1/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "/etc/exabgp/exa-send.py 1 10"; + } + + process receive-routes { + run "/etc/exabgp/exa-receive.py 1"; + receive-routes; + encoder text; + } + + neighbor 10.0.1.1 { + router-id 10.0.1.101; + local-address 10.0.1.101; + local-as 99; + peer-as 100; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp_vrf_netns/r1/bgpd.conf b/tests/topotests/bgp_vrf_netns/r1/bgpd.conf new file mode 100644 index 0000000..572dce7 --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/r1/bgpd.conf @@ -0,0 +1,10 @@ +! +router bgp 100 vrf r1-bgp-cust1 + bgp router-id 10.0.1.1 + bgp bestpath as-path multipath-relax + no bgp ebgp-requires-policy + neighbor 10.0.1.101 remote-as 99 + neighbor 10.0.1.101 timers 3 10 + ! +! + diff --git a/tests/topotests/bgp_vrf_netns/r1/summary.txt b/tests/topotests/bgp_vrf_netns/r1/summary.txt new file mode 100644 index 0000000..819f261 --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/r1/summary.txt @@ -0,0 +1,17 @@ +{ +"ipv4Unicast":{ + "routerId":"10.0.1.1", + "as":100, + "vrfName":"r1-bgp-cust1", + "peerCount":1, + "peers":{ + "10.0.1.101":{ + "outq":0, + "inq":0, + "pfxRcd":10, + "state":"Established" + } + }, + "totalPeers":1 +} +} diff --git a/tests/topotests/bgp_vrf_netns/r1/summary20.txt b/tests/topotests/bgp_vrf_netns/r1/summary20.txt new file mode 100644 index 0000000..ea04a56 --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/r1/summary20.txt @@ -0,0 +1,15 @@ +{ + "routerId":"10.0.1.1", + "as":100, + "vrfName":"re1-bgp-cust1", + "peerCount":1, + "peers":{ + "10.0.1.101":{ + "outq":0, + "inq":0, + "pfxRcd":10, + "state":"Established" + } + }, + "totalPeers":1 +} diff --git a/tests/topotests/bgp_vrf_netns/r1/zebra.conf b/tests/topotests/bgp_vrf_netns/r1/zebra.conf new file mode 100644 index 0000000..ed4edfa --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/r1/zebra.conf @@ -0,0 +1,7 @@ +! +interface r1-eth0 vrf r1-bgp-cust1 + ip address 10.0.1.1/24 +! +line vty +! +! debug vrf diff --git a/tests/topotests/bgp_vrf_netns/test_bgp_vrf_netns_topo.py b/tests/topotests/bgp_vrf_netns/test_bgp_vrf_netns_topo.py new file mode 100644 index 0000000..8457b75 --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/test_bgp_vrf_netns_topo.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# test_bgp_vrf_netns_topo1.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2018 by 6WIND +# + +""" +test_bgp_vrf_netns_topo1.py: Test BGP topology with EBGP on NETNS VRF +""" + +import json +import os +import sys +import functools +import pytest + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +# Required to instantiate the topology builder class. + +pytestmark = [pytest.mark.bgpd] + + +total_ebgp_peers = 1 +CustomizeVrfWithNetns = True + +##################################################### +## +## Network Topology Definition +## +##################################################### + + +def build_topo(tgen): + tgen.add_router("r1") + + # Setup Switches + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + + # Add eBGP ExaBGP neighbors + peer_ip = "10.0.1.101" + peer_route = "via 10.0.1.1" + peer = tgen.add_exabgp_peer("peer1", ip=peer_ip, defaultRoute=peer_route) + switch = tgen.gears["s1"] + switch.add_link(peer) + + +##################################################### +## +## Tests starting +## +##################################################### + + +def setup_module(module): + tgen = Topogen(build_topo, module.__name__) + tgen.start_topology() + + # Get r1 reference + router = tgen.gears["r1"] + + # check for zebra capability + if CustomizeVrfWithNetns == True: + if router.check_capability(TopoRouter.RD_ZEBRA, "--vrfwnetns") == False: + return pytest.skip( + "Skipping BGP VRF NETNS Test. VRF NETNS backend not available on FRR" + ) + if os.system("ip netns list") != 0: + return pytest.skip( + "Skipping BGP VRF NETNS Test. NETNS not available on System" + ) + # retrieve VRF backend kind + if CustomizeVrfWithNetns == True: + logger.info("Testing with VRF Namespace support") + + # create VRF r1-bgp-cust1 + # move r1-eth0 to VRF r1-bgp-cust1 + + ns = "{}-bgp-cust1".format("r1") + router.net.add_netns(ns) + router.net.set_intf_netns("r1-eth0", ns, up=True) + + # run daemons + router.load_config( + TopoRouter.RD_ZEBRA, + os.path.join(CWD, "{}/zebra.conf".format("r1")), + "--vrfwnetns", + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format("r1")) + ) + + logger.info("Launching BGP and ZEBRA") + # BGP and ZEBRA start without underlying VRF + router.start() + # Starting Hosts and init ExaBGP on each of them + logger.info("starting exaBGP on peer1") + peer_list = tgen.exabgp_peers() + for pname, peer in peer_list.items(): + peer_dir = os.path.join(CWD, pname) + env_file = os.path.join(CWD, "exabgp.env") + logger.info("Running ExaBGP peer") + peer.start(peer_dir, env_file) + logger.info(pname) + + +def teardown_module(module): + tgen = get_topogen() + + # Move interfaces out of vrf namespace and delete the namespace + tgen.net["r1"].reset_intf_netns("r1-eth0") + tgen.net["r1"].delete_netns("r1-bgp-cust1") + + tgen.stop_topology() + + +def test_bgp_vrf_learn(): + "Test daemon learnt VRF context" + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Expected result + output = tgen.gears["r1"].vtysh_cmd("show vrf", isjson=False) + logger.info("output is: {}".format(output)) + + output = tgen.gears["r1"].vtysh_cmd("show bgp vrfs", isjson=False) + logger.info("output is: {}".format(output)) + + +def test_bgp_convergence(): + "Test for BGP topology convergence" + tgen = get_topogen() + + # uncomment if you want to troubleshoot + # tgen.mininet_cli() + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("waiting for bgp convergence") + + # Expected result + router = tgen.gears["r1"] + if router.has_version("<", "3.0"): + reffile = os.path.join(CWD, "r1/summary20.txt") + else: + reffile = os.path.join(CWD, "r1/summary.txt") + + expected = json.loads(open(reffile).read()) + + test_func = functools.partial( + topotest.router_json_cmp, + router, + "show bgp vrf r1-bgp-cust1 summary json", + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=90, wait=0.5) + assertmsg = "BGP router network did not converge" + assert res is None, assertmsg + + +def test_bgp_vrf_netns(): + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + expect = { + "routerId": "10.0.1.1", + "routes": {}, + } + + for subnet in range(0, 10): + netkey = "10.201.{}.0/24".format(subnet) + expect["routes"][netkey] = [] + peer = {"valid": True} + expect["routes"][netkey].append(peer) + + test_func = functools.partial( + topotest.router_json_cmp, + tgen.gears["r1"], + "show ip bgp vrf r1-bgp-cust1 ipv4 json", + expect, + ) + _, res = topotest.run_and_expect(test_func, None, count=12, wait=0.5) + assertmsg = 'expected routes in "show ip bgp vrf r1-bgp-cust1 ipv4" output' + assert res is None, assertmsg + + +if __name__ == "__main__": + + args = ["-s"] + sys.argv[1:] + ret = pytest.main(args) + + sys.exit(ret) |