From 12919c4255bf9d87797a8cc972bf6ee1f6f0c262 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 31 Jan 2018 11:04:02 +0100 Subject: [PATCH] bgp_vrf_netns: add basic test to support netns backend with netns The test consist in starting a BGP router on a NETNS, and interacting with an exaBGP instance. The test automatically relies on VRF with netns backend but can be easily configured so as to perform basic BGP VRF testing with VRF with VRF-lite backend. Signed-off-by: Philippe Guibert --- tests/topotests/bgp_vrf_netns/__init__.py | 0 .../bgp_vrf_netns/bgp-vrf-netns-topo.dot | 50 ++++ .../bgp_vrf_netns/bgp-vrf-netns-topo.pdf | Bin 0 -> 13104 bytes tests/topotests/bgp_vrf_netns/exabgp.env | 54 +++++ .../bgp_vrf_netns/peer1/exa-receive.py | 38 +++ .../topotests/bgp_vrf_netns/peer1/exa-send.py | 26 ++ .../topotests/bgp_vrf_netns/peer1/exabgp.cfg | 21 ++ tests/topotests/bgp_vrf_netns/r1/bgpd.conf | 8 + tests/topotests/bgp_vrf_netns/r1/summary.txt | 17 ++ .../topotests/bgp_vrf_netns/r1/summary20.txt | 15 ++ tests/topotests/bgp_vrf_netns/r1/zebra.conf | 7 + .../bgp_vrf_netns/test_bgp_vrf_netns_topo.py | 225 ++++++++++++++++++ 12 files changed, 461 insertions(+) create mode 100644 tests/topotests/bgp_vrf_netns/__init__.py create mode 100644 tests/topotests/bgp_vrf_netns/bgp-vrf-netns-topo.dot create mode 100644 tests/topotests/bgp_vrf_netns/bgp-vrf-netns-topo.pdf create mode 100644 tests/topotests/bgp_vrf_netns/exabgp.env create mode 100755 tests/topotests/bgp_vrf_netns/peer1/exa-receive.py create mode 100755 tests/topotests/bgp_vrf_netns/peer1/exa-send.py create mode 100644 tests/topotests/bgp_vrf_netns/peer1/exabgp.cfg create mode 100644 tests/topotests/bgp_vrf_netns/r1/bgpd.conf create mode 100644 tests/topotests/bgp_vrf_netns/r1/summary.txt create mode 100644 tests/topotests/bgp_vrf_netns/r1/summary20.txt create mode 100644 tests/topotests/bgp_vrf_netns/r1/zebra.conf create mode 100755 tests/topotests/bgp_vrf_netns/test_bgp_vrf_netns_topo.py diff --git a/tests/topotests/bgp_vrf_netns/__init__.py b/tests/topotests/bgp_vrf_netns/__init__.py new file mode 100644 index 0000000000..e69de29bb2 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 0000000000..2b1f72b822 --- /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 new file mode 100644 index 0000000000000000000000000000000000000000..6da228898e36d8862e7cf9db1ffe865f247b6a08 GIT binary patch literal 13104 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 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() 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 0000000000..9a2a201c57 --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/peer1/exa-send.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python + +""" +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 0000000000..2d0ca89f0f --- /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 0000000000..e3f158d7b3 --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/r1/bgpd.conf @@ -0,0 +1,8 @@ +! +router bgp 100 vrf r1-cust1 + bgp router-id 10.0.1.1 + bgp bestpath as-path multipath-relax + neighbor 10.0.1.101 remote-as 99 + ! +! + 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 0000000000..7473fa2151 --- /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-cust1", + "peerCount":1, + "peers":{ + "10.0.1.101":{ + "outq":0, + "inq":0, + "prefixReceivedCount":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 0000000000..18318e07a8 --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/r1/summary20.txt @@ -0,0 +1,15 @@ +{ + "routerId":"10.0.1.1", + "as":100, + "vrfName":"re1-cust1", + "peerCount":1, + "peers":{ + "10.0.1.101":{ + "outq":0, + "inq":0, + "prefixReceivedCount":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 0000000000..817d9544d3 --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/r1/zebra.conf @@ -0,0 +1,7 @@ +! +interface r1-eth0 vrf r1-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 100755 index 0000000000..b63d68d5a2 --- /dev/null +++ b/tests/topotests/bgp_vrf_netns/test_bgp_vrf_netns_topo.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python + +# +# test_bgp_vrf_netns_topo1.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2018 by 6WIND +# +# 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_bgp_vrf_netns_topo1.py: Test BGP topology with EBGP on NETNS VRF +""" + +import json +import os +import sys +import pytest +import getopt + +# 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. +from mininet.topo import Topo + +total_ebgp_peers = 1 +CustomizeVrfWithNetns = True + +##################################################### +## +## Network Topology Definition +## +##################################################### + +class BGPVRFNETNSTopo1(Topo): + "BGP EBGP VRF NETNS Topology 1" + + def build(self, **_opts): + tgen = get_topogen(self) + + # Setup Routers + 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(BGPVRFNETNSTopo1, 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-cust1 + # move r1-eth0 to VRF r1-cust1 + cmds = ['ip netns add {0}-cust1', + 'ip link set dev {0}-eth0 netns {0}-cust1', + 'ip netns exec {0}-cust1 ifconfig {0}-eth0 up'] + for cmd in cmds: + router.run(cmd.format('r1')) + + #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 + topotest.sleep(10, 'starting BGP on peer') + peer_list = tgen.exabgp_peers() + for pname, peer in peer_list.iteritems(): + peer_dir = os.path.join(CWD, pname) + env_file = os.path.join(CWD, 'exabgp.env') + topotest.sleep(1, 'Running ExaBGP peer') + peer.start(peer_dir, env_file) + logger.info(pname) + +def teardown_module(module): + tgen = get_topogen() + # move back r1-eth0 to default VRF + # delete VRF r1-cust1 + cmds = ['ip netns delete {0}-cust1', + 'ip netns exec {0}-cust1 ip link set {0}-eth0 netns 1'] + for cmd in cmds: + tgen.net['r1'].cmd(cmd.format('r1')) + + 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) + + topotest.sleep(20, '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()) + + # Define test function and call it + def _convergence_test(): + output = router.vtysh_cmd('show bgp vrf r1-cust1 summary json', isjson=True) + return topotest.json_cmp(output, expected) + + _, res = topotest.run_and_expect(_convergence_test, None, count=10, wait=1) + 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) + + def _output_cmp(): + output = tgen.gears['r1'].vtysh_cmd('show ip bgp vrf r1-cust1 ipv4 json', isjson=True) + return topotest.json_cmp(output, expect) + + _, res = topotest.run_and_expect(_output_cmp, None, count=1, wait=3) + assertmsg = 'expected routes in "show ip bgp vrf r1-cust1 ipv4" output' + assert res is None, assertmsg + +if __name__ == '__main__': + + args = ["-s"] + sys.argv[1:] + ret = pytest.main(args) + + sys.exit(ret) -- 2.39.5