4 # Part of NetDEF Topology Tests
6 # Copyright (c) 2018, LabN Consulting, L.L.C.
7 # Authored by Lou Berger <lberger@labn.net>
9 # Permission to use, copy, modify, and/or distribute this software
10 # for any purpose with or without fee is hereby granted, provided
11 # that the above copyright notice and this permission notice appear
14 # THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
15 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
17 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
18 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
20 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
31 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
32 sys
.path
.append(os
.path
.join(CWD
, "../"))
34 # pylint: disable=C0413
35 # Import topogen and topotest helpers
36 from lib
import topotest
37 from lib
.topogen
import Topogen
, TopoRouter
, get_topogen
38 from lib
.topolog
import logger
39 from lib
.common_config
import required_linux_kernel_version
40 from mininet
.topo
import Topo
53 +-(eth1)--(eth2)---(eth3)-+
57 +----------(eth0)---------+
64 +----------(eth0)--------------+
68 +-(eth1)-----(eth2)-----(eth3)-+
71 +------+ +------+ +------+
72 / 2001: \ / 2001: \ / 2001: \
73 \ 2::/64 / \ 4::/64 / \ 6::/64 /
74 +------+ +------+ +------+
80 def build(self
, *_args
, **_opts
):
81 tgen
= get_topogen(self
)
84 tgen
.add_router("ce1")
85 tgen
.add_router("ce2")
86 tgen
.add_router("ce3")
87 tgen
.add_router("ce4")
88 tgen
.add_router("ce5")
89 tgen
.add_router("ce6")
91 tgen
.add_link(tgen
.gears
["r1"], tgen
.gears
["r2"], "eth0", "eth0")
92 tgen
.add_link(tgen
.gears
["ce1"], tgen
.gears
["r1"], "eth0", "eth1")
93 tgen
.add_link(tgen
.gears
["ce2"], tgen
.gears
["r2"], "eth0", "eth1")
94 tgen
.add_link(tgen
.gears
["ce3"], tgen
.gears
["r1"], "eth0", "eth2")
95 tgen
.add_link(tgen
.gears
["ce4"], tgen
.gears
["r2"], "eth0", "eth2")
96 tgen
.add_link(tgen
.gears
["ce5"], tgen
.gears
["r1"], "eth0", "eth3")
97 tgen
.add_link(tgen
.gears
["ce6"], tgen
.gears
["r2"], "eth0", "eth3")
100 def setup_module(mod
):
101 result
= required_linux_kernel_version("4.15")
102 if result
is not True:
103 pytest
.skip("Kernel requirements are not met")
105 tgen
= Topogen(Topology
, mod
.__name
__)
106 tgen
.start_topology()
107 router_list
= tgen
.routers()
108 for rname
, router
in tgen
.routers().items():
109 router
.run("/bin/bash {}/{}/setup.sh".format(CWD
, rname
))
110 router
.load_config(TopoRouter
.RD_ZEBRA
,
111 os
.path
.join(CWD
, '{}/zebra.conf'.format(rname
)))
112 router
.load_config(TopoRouter
.RD_BGP
,
113 os
.path
.join(CWD
, '{}/bgpd.conf'.format(rname
)))
115 tgen
.gears
["r1"].run("ip link add vrf10 type vrf table 10")
116 tgen
.gears
["r1"].run("ip link set vrf10 up")
117 tgen
.gears
["r1"].run("ip link add vrf20 type vrf table 20")
118 tgen
.gears
["r1"].run("ip link set vrf20 up")
119 tgen
.gears
["r1"].run("ip link set eth1 master vrf10")
120 tgen
.gears
["r1"].run("ip link set eth2 master vrf10")
121 tgen
.gears
["r1"].run("ip link set eth3 master vrf20")
123 tgen
.gears
["r2"].run("ip link add vrf10 type vrf table 10")
124 tgen
.gears
["r2"].run("ip link set vrf10 up")
125 tgen
.gears
["r2"].run("ip link add vrf20 type vrf table 20")
126 tgen
.gears
["r2"].run("ip link set vrf20 up")
127 tgen
.gears
["r2"].run("ip link set eth1 master vrf10")
128 tgen
.gears
["r2"].run("ip link set eth2 master vrf20")
129 tgen
.gears
["r2"].run("ip link set eth3 master vrf20")
133 def teardown_module(mod
):
138 def open_json_file(filename
):
140 with
open(filename
, "r") as f
:
143 assert False, "Could not read file {}".format(filename
)
147 def _check(name
, cmd
, expected_file
):
148 logger
.info("polling")
150 router
= tgen
.gears
[name
]
151 output
= json
.loads(router
.vtysh_cmd(cmd
))
152 expected
= open_json_file("{}/{}".format(CWD
, expected_file
))
153 return topotest
.json_cmp(output
, expected
)
155 def check(name
, cmd
, expected_file
):
156 logger
.info("[+] check {} \"{}\" {}".format(name
, cmd
, expected_file
))
158 func
= functools
.partial(_check
, name
, cmd
, expected_file
)
159 success
, result
= topotest
.run_and_expect(func
, None, count
=10, wait
=0.5)
160 assert result
is None, 'Failed'
162 check("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib.json")
163 check("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib.json")
164 check("r1", "show ipv6 route vrf vrf10 json", "r1/vrf10_rib.json")
165 check("r1", "show ipv6 route vrf vrf20 json", "r1/vrf20_rib.json")
166 check("r2", "show ipv6 route vrf vrf10 json", "r2/vrf10_rib.json")
167 check("r2", "show ipv6 route vrf vrf20 json", "r2/vrf20_rib.json")
168 check("ce1", "show ipv6 route json", "ce1/ipv6_rib.json")
169 check("ce2", "show ipv6 route json", "ce2/ipv6_rib.json")
170 check("ce3", "show ipv6 route json", "ce3/ipv6_rib.json")
171 check("ce4", "show ipv6 route json", "ce4/ipv6_rib.json")
172 check("ce5", "show ipv6 route json", "ce5/ipv6_rib.json")
173 check("ce6", "show ipv6 route json", "ce6/ipv6_rib.json")
177 def _check(name
, dest_addr
, match
):
179 output
= tgen
.gears
[name
].run("ping6 {} -c 1 -w 1".format(dest_addr
))
181 assert match
in output
, "ping fail"
183 def check(name
, dest_addr
, match
):
184 logger
.info("[+] check {} {} {}".format(name
, dest_addr
, match
))
186 func
= functools
.partial(_check
, name
, dest_addr
, match
)
187 success
, result
= topotest
.run_and_expect(func
, None, count
=10, wait
=0.5)
188 assert result
is None, 'Failed'
190 check("ce1", "2001:2::2", " 0% packet loss")
191 check("ce1", "2001:3::2", " 0% packet loss")
192 check("ce1", "2001:4::2", " 100% packet loss")
193 check("ce1", "2001:5::2", " 100% packet loss")
194 check("ce1", "2001:6::2", " 100% packet loss")
195 check("ce4", "2001:1::2", " 100% packet loss")
196 check("ce4", "2001:2::2", " 100% packet loss")
197 check("ce4", "2001:3::2", " 100% packet loss")
198 check("ce4", "2001:5::2", " 0% packet loss")
199 check("ce4", "2001:6::2", " 0% packet loss")
202 if __name__
== "__main__":
203 args
= ["-s"] + sys
.argv
[1:]
204 sys
.exit(pytest
.main(args
))