diff options
| -rw-r--r-- | tests/topotests/pbr-topo1/r1/pbr-interface.json | 15 | ||||
| -rw-r--r-- | tests/topotests/pbr-topo1/r1/pbr-map.json | 86 | ||||
| -rw-r--r-- | tests/topotests/pbr-topo1/r1/pbr-nexthop-groups.json | 47 | ||||
| -rw-r--r-- | tests/topotests/pbr-topo1/r1/pbrd.conf | 64 | ||||
| -rw-r--r-- | tests/topotests/pbr-topo1/r1/zebra.conf | 5 | ||||
| -rwxr-xr-x | tests/topotests/pbr-topo1/test_pbr_topo1.py | 75 |
6 files changed, 248 insertions, 44 deletions
diff --git a/tests/topotests/pbr-topo1/r1/pbr-interface.json b/tests/topotests/pbr-topo1/r1/pbr-interface.json index 452b24dcd7..e28d9fb149 100644 --- a/tests/topotests/pbr-topo1/r1/pbr-interface.json +++ b/tests/topotests/pbr-topo1/r1/pbr-interface.json @@ -8,5 +8,20 @@ "name":"r1-eth2", "policy":"DONNA", "valid":true + }, + { + "name":"r1-eth3", + "policy":"AKIHABARA", + "valid":true + }, + { + "name":"r1-eth4", + "policy":"ASAKUSA", + "valid":true + }, + { + "name":"r1-noexist", + "policy":"NOEXIST", + "valid":false } ] diff --git a/tests/topotests/pbr-topo1/r1/pbr-map.json b/tests/topotests/pbr-topo1/r1/pbr-map.json index 6b9eaa9ceb..f0738dc540 100644 --- a/tests/topotests/pbr-topo1/r1/pbr-map.json +++ b/tests/topotests/pbr-topo1/r1/pbr-map.json @@ -1,21 +1,92 @@ [ { - "name":"DONNA", - "valid":true, + "name":"AKIHABARA", + "valid":false, "policies":[ { - "id":3, "sequenceNumber":5, - "ruleNumber":304, "vrfUnchanged":false, "installed":true, "installedReason":"Valid", + "nexthopGroup": { + "name":"C", + "installed":true, + "installedInternally":1 + }, + "matchDst":"192.168.4.0\/24" + }, + { + "sequenceNumber":10, + "vrfUnchanged":false, + "installed":true, + "installedReason":"Invalid Src or Dst", "nexthopGroup":{ - "tableId":10002, "name":"C", "installed":true, "installedInternally":1 + } + }, + { + "sequenceNumber":15, + "vrfUnchanged":false, + "installed":false, + "installedReason":"No Nexthops" + } + ] + }, + { + "name":"ASAKUSA", + "valid":true, + "policies":[ + { + "sequenceNumber":5, + "vrfUnchanged":false, + "installed":true, + "installedReason":"Valid", + "matchDst":"c0ff:ee::\/64", + "nexthopGroup":{ + "name":"D", + "installed":true, + "installedInternally":1 + } + }, + { + "sequenceNumber":10, + "vrfUnchanged":false, + "installed":true, + "installedReason":"Valid", + "nexthopGroup":{ + "name":"ASAKUSA10", + "installed":true, + "installedInternally":1 }, + "matchDst":"dead:beef::\/64", + "matchMark":314159 + } + ] + }, + { + "name":"DONNA", + "valid":false, + "policies":[ + { + "sequenceNumber":5, + "vrfUnchanged":false, + "installed":false, + "installedReason":"Invalid NH-group", + "nexthopGroup":{ + "name":"B", + "installed":false, + "installedInternally":0 + }, + "matchSrc":"1.2.0.0\/16", + "matchDst":"3.4.5.0\/24" + }, + { + "sequenceNumber":10, + "vrfUnchanged":true, + "installed":false, + "installedReason":"Valid", "matchSrc":"1.2.0.0\/16", "matchDst":"3.4.5.0\/24" } @@ -26,14 +97,11 @@ "valid":true, "policies":[ { - "id":1, "sequenceNumber":5, - "ruleNumber":304, "vrfUnchanged":false, "installed":true, "installedReason":"Valid", "nexthopGroup":{ - "tableId":10003, "name":"EVA5", "installed":true, "installedInternally":1 @@ -41,14 +109,12 @@ "matchSrc":"4.5.6.7\/32" }, { - "id":2, "sequenceNumber":10, "ruleNumber":309, "vrfUnchanged":false, "installed":true, "installedReason":"Valid", "nexthopGroup":{ - "tableId":10000, "name":"A", "installed":true, "installedInternally":1 diff --git a/tests/topotests/pbr-topo1/r1/pbr-nexthop-groups.json b/tests/topotests/pbr-topo1/r1/pbr-nexthop-groups.json index ff85438ad5..540ea28158 100644 --- a/tests/topotests/pbr-topo1/r1/pbr-nexthop-groups.json +++ b/tests/topotests/pbr-topo1/r1/pbr-nexthop-groups.json @@ -1,6 +1,16 @@ [ { - "id":10000, + "name":"ASAKUSA10", + "valid":true, + "installed":true, + "nexthops":[ + { + "nexthop":"c0ff:ee::1", + "valid":true + } + ] + }, + { "name":"A", "valid":true, "installed":true, @@ -20,19 +30,47 @@ ] }, { - "id":10002, + "name":"D", + "valid":true, + "installed":true, + "nexthops":[ + { + "nexthop":"c0ff:ee::3", + "valid":true + }, + { + "nexthop":"c0ff:ee::2", + "valid":true + }, + { + "nexthop":"c0ff:ee::1", + "valid":true + } + ] + }, + { "name":"C", "valid":true, "installed":true, "nexthops":[ { - "nexthop":"192.168.1.44", + "nexthop":"192.168.4.3", + "targetVrf":"vrf-chiyoda", + "valid":true + }, + { + "nexthop":"192.168.4.2", + "targetVrf":"vrf-chiyoda", + "valid":true + }, + { + "nexthop":"192.168.4.1", + "targetVrf":"vrf-chiyoda", "valid":true } ] }, { - "id":10001, "name":"B", "valid":false, "installed":false, @@ -44,7 +82,6 @@ ] }, { - "id":10003, "name":"EVA5", "valid":true, "installed":true, diff --git a/tests/topotests/pbr-topo1/r1/pbrd.conf b/tests/topotests/pbr-topo1/r1/pbrd.conf index 234683f307..4a126151b0 100644 --- a/tests/topotests/pbr-topo1/r1/pbrd.conf +++ b/tests/topotests/pbr-topo1/r1/pbrd.conf @@ -1,8 +1,16 @@ +debug pbr +# Valid table range +pbr table range 10000 50000 +# Try to set invalid bounds +pbr table range 10000 10001 +pbr table range 50000 10000 +# Reset table range +no pbr table range +! nexthop-group A nexthop 192.168.1.2 nexthop 192.168.2.2 nexthop 192.168.3.2 - nexhtop 192.168.4.2 ! # This one is bogus and should # never work @@ -10,7 +18,14 @@ nexthop-group B nexthop 192.168.50.1 ! nexthop-group C - nexthop 192.168.1.44 + nexthop 192.168.4.1 nexthop-vrf vrf-chiyoda + nexthop 192.168.4.2 nexthop-vrf vrf-chiyoda + nexthop 192.168.4.3 nexthop-vrf vrf-chiyoda +! +nexthop-group D + nexthop c0ff:ee::1 + nexthop c0ff:ee::2 + nexthop c0ff:ee::3 ! pbr-map EVA seq 5 match src-ip 4.5.6.7/32 @@ -23,11 +38,50 @@ pbr-map EVA seq 10 pbr-map DONNA seq 5 match dst-ip 3.4.5.0/24 match src-ip 1.2.0.0/16 - set nexthop-group C -! - + set nexthop-group B +! +pbr-map DONNA seq 10 + match dst-ip 3.4.5.0/24 + match src-ip 1.2.0.0/16 + set vrf unchanged +! +pbr-map AKIHABARA seq 5 + no set vrf unchanged + match dst-ip 192.168.4.0/24 + set nexthop-group C +! +pbr-map AKIHABARA seq 10 + match dst-ip 192.168.4.0/24 + no match dst-ip 192.168.4.0/24 + set nexthop-group C +! +pbr-map AKIHABARA seq 15 + set vrf noexist-vrf + match dst-ip 192.168.4.0/24 + set nexthop-group C + no set nexthop-group C +! +pbr-map ASAKUSA seq 5 + match dst-ip c0ff:ee::/64 + set nexthop-group D +! +pbr-map ASAKUSA seq 10 + match dst-ip dead:beef::/64 + match mark 314159 + set nexthop c0ff:ee::1 +! +# Interface policies int r1-eth1 pbr-policy EVA ! int r1-eth2 pbr-policy DONNA +! +int r1-eth3 + pbr-policy AKIHABARA +! +int r1-eth4 + pbr-policy ASAKUSA +! +int r1-noexist + pbr-policy NOEXIST diff --git a/tests/topotests/pbr-topo1/r1/zebra.conf b/tests/topotests/pbr-topo1/r1/zebra.conf index f29b146a62..2ec947c275 100644 --- a/tests/topotests/pbr-topo1/r1/zebra.conf +++ b/tests/topotests/pbr-topo1/r1/zebra.conf @@ -7,5 +7,8 @@ int r1-eth1 int r1-eth2 ip address 192.168.3.1/24 -int r1-eth3 +int r1-eth3 vrf vrf-chiyoda ip address 192.168.4.1/24 + +int r1-eth4 + ipv6 address c0ff:ee::/64 diff --git a/tests/topotests/pbr-topo1/test_pbr_topo1.py b/tests/topotests/pbr-topo1/test_pbr_topo1.py index 2853165d45..aedc9ca3fc 100755 --- a/tests/topotests/pbr-topo1/test_pbr_topo1.py +++ b/tests/topotests/pbr-topo1/test_pbr_topo1.py @@ -42,6 +42,7 @@ sys.path.append(os.path.join(CWD, "../")) from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger +from lib.common_config import shutdown_bringup_interface # Required to instantiate the topology builder class. from mininet.topo import Topo @@ -61,26 +62,14 @@ class NetworkTopo(Topo): tgen = get_topogen(self) + # Populate routers for routern in range(1, 2): tgen.add_router("r{}".format(routern)) - # On main router - # First switch is for a dummy interface (for local network) - switch = tgen.add_switch("sw1") - switch.add_link(tgen.gears["r1"]) - - # Switches for PBR - # switch 2 switch is for connection to PBR router - switch = tgen.add_switch("sw2") - switch.add_link(tgen.gears["r1"]) - - # switch 4 is stub on remote PBR router - switch = tgen.add_switch("sw4") - switch.add_link(tgen.gears["r1"]) - - # switch 3 is between PBR routers - switch = tgen.add_switch("sw3") - switch.add_link(tgen.gears["r1"]) + # Populate switches + for switchn in range(1, 6): + switch = tgen.add_switch("sw{}".format(switchn)) + switch.add_link(tgen.gears["r1"]) ##################################################### @@ -95,9 +84,13 @@ def setup_module(module): tgen = Topogen(NetworkTopo, module.__name__) tgen.start_topology() - # This is a sample of configuration loading. router_list = tgen.routers() for rname, router in router_list.iteritems(): + # Install vrf into the kernel and slave eth3 + router.run("ip link add vrf-chiyoda type vrf table 1000") + router.run("ip link set dev {}-eth3 master vrf-chiyoda".format(rname)) + router.run("ip link set vrf-chiyoda up") + router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -106,7 +99,7 @@ def setup_module(module): ) tgen.start_router() - #gen.mininet_cli() + def teardown_module(_mod): "Teardown the pytest environment" @@ -141,19 +134,19 @@ def test_pbr_data(): router_list = tgen.routers().values() for router in router_list: intf_file = "{}/{}/pbr-interface.json".format(CWD, router.name) - logger.info(intf_file) + # Read expected result from file expected = json.loads(open(intf_file).read()) # Actual output from router actual = router.vtysh_cmd("show pbr interface json", isjson=True) - assertmsg = '"show pbr interface" mismatches on {}'.format(router.name) assert topotest.json_cmp(actual, expected) is None, assertmsg map_file = "{}/{}/pbr-map.json".format(CWD, router.name) logger.info(map_file) + # Read expected result from file expected = json.loads(open(map_file).read()) @@ -164,7 +157,8 @@ def test_pbr_data(): assert topotest.json_cmp(actual, expected) is None, assertmsg nexthop_file = "{}/{}/pbr-nexthop-groups.json".format(CWD, router.name) - + logger.info(nexthop_file) + # Read expected result from file expected = json.loads(open(nexthop_file).read()) @@ -174,7 +168,42 @@ def test_pbr_data(): assertmsg = '"show pbr nexthop-groups" mismatches on {}'.format(router.name) assert topotest.json_cmp(actual, expected) is None, assertmsg + +def test_pbr_flap(): + "Test PBR interface flapping" + + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Verify PBR Status + logger.info("Flapping PBR Interfaces") + + router_list = tgen.routers().values() + for router in router_list: + # Flap interface to see if route-map properties are intact + # Shutdown interface + + for i in range(5): + intf = "r1-eth{}".format(i) + + # Down and back again + shutdown_bringup_interface(tgen, router.name, intf, False) + shutdown_bringup_interface(tgen, router.name, intf, True) + + intf_file = "{}/{}/pbr-interface.json".format(CWD, router.name) + logger.info(intf_file) + + # Read expected result from file + expected = json.loads(open(intf_file).read()) + + # Actual output from router + actual = router.vtysh_cmd("show pbr interface json", isjson=True) + assertmsg = '"show pbr interface" mismatches on {}'.format(router.name) + assert topotest.json_cmp(actual, expected) is None, assertmsg + + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) - |
