2 """ 6RD RFC5969 functional tests """
5 from scapy.layers.inet import IP, UDP, Ether
6 from scapy.layers.inet6 import IPv6
7 from scapy.packet import Raw
8 from framework import VppTestCase
9 from asfframework import VppTestRunner
10 from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable
12 """ Test6rd is a subclass of VPPTestCase classes.
19 class Test6RD(VppTestCase):
24 super(Test6RD, cls).setUpClass()
25 cls.create_pg_interfaces(range(4))
26 cls.interfaces = list(cls.pg_interfaces)
29 def tearDownClass(cls):
30 super(Test6RD, cls).tearDownClass()
33 super(Test6RD, self).setUp()
34 t4 = VppIpTable(self, 10)
35 t6 = VppIpTable(self, 20, True)
41 i = self.pg_interfaces[n]
53 for i in self.pg_interfaces:
59 super(Test6RD, self).tearDown()
61 def validate_6in4(self, rx, expected):
67 self.assertEqual(rx[IP].src, expected[IP].src)
68 self.assertEqual(rx[IP].dst, expected[IP].dst)
69 self.assertEqual(rx[IP].proto, expected[IP].proto)
70 self.assertEqual(rx[IPv6].src, expected[IPv6].src)
71 self.assertEqual(rx[IPv6].dst, expected[IPv6].dst)
73 def validate_4in6(self, rx, expected):
79 self.assertEqual(rx[IPv6].src, expected[IPv6].src)
80 self.assertEqual(rx[IPv6].dst, expected[IPv6].dst)
81 self.assertEqual(rx[IPv6].nh, expected[IPv6].nh)
83 def payload(self, len):
86 def test_6rd_ip6_to_ip4(self):
87 """ip6 -> ip4 (encap) 6rd test"""
88 p_ether = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
89 p_ip6 = IPv6(src="1::1", dst="2002:AC10:0202::1", nh="UDP")
91 rv = self.vapi.ipip_6rd_add_tunnel(
94 ip6_prefix="2002::/16",
95 ip4_prefix="0.0.0.0/0",
96 ip4_src=self.pg0.local_ip4,
100 self.tunnel_index = rv.sw_if_index
102 self.vapi.cli("show ip6 fib")
103 p_payload = UDP(sport=1234, dport=1234)
104 p = p_ether / p_ip6 / p_payload
107 IP(src=self.pg0.local_ip4, dst=self.pg1.remote_ip4, proto="ipv6") / p_ip6
110 rx = self.send_and_expect(self.pg0, p * 10, self.pg1)
112 self.validate_6in4(p, p_reply)
114 # MTU tests (default is 1480)
116 p_ip6 = IPv6(src="1::1", dst="2002:AC10:0202::1")
117 p_payload = UDP(sport=1234, dport=1234) / Raw(self.payload(plen))
118 p = p_ether / p_ip6 / p_payload
121 IP(src=self.pg0.local_ip4, dst=self.pg1.remote_ip4, proto="ipv6") / p_ip6
124 rx = self.send_and_assert_no_replies(self.pg0, p * 10)
125 self.vapi.ipip_6rd_del_tunnel(self.tunnel_index)
127 def test_6rd_ip6_to_ip4_vrf(self):
128 """ip6 -> ip4 (encap) 6rd VRF test"""
129 p_ether = Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
130 p_ip6 = IPv6(src="1::1", dst="2002:AC10:0402::1", nh="UDP")
132 rv = self.vapi.ipip_6rd_add_tunnel(
135 ip6_prefix="2002::/16",
136 ip4_prefix="0.0.0.0/0",
137 ip4_src=self.pg2.local_ip4,
140 self.tunnel_index = rv.sw_if_index
142 self.vapi.cli("show ip6 fib")
143 p_payload = UDP(sport=1234, dport=1234)
144 p = p_ether / p_ip6 / p_payload
147 IP(src=self.pg2.local_ip4, dst=self.pg3.remote_ip4, proto="ipv6") / p_ip6
150 rx = self.send_and_expect(self.pg2, p * 10, self.pg3)
152 self.validate_6in4(p, p_reply)
154 # MTU tests (default is 1480)
156 p_ip6 = IPv6(src="1::1", dst="2002:AC10:0402::1")
157 p_payload = UDP(sport=1234, dport=1234) / Raw(self.payload(plen))
158 p = p_ether / p_ip6 / p_payload
161 IP(src=self.pg2.local_ip4, dst=self.pg3.remote_ip4, proto="ipv6") / p_ip6
164 rx = self.send_and_assert_no_replies(self.pg0, p * 10)
165 self.vapi.ipip_6rd_del_tunnel(self.tunnel_index)
167 def test_6rd_ip4_to_ip6(self):
168 """ip4 -> ip6 (decap) 6rd test"""
170 rv = self.vapi.ipip_6rd_add_tunnel(
173 ip6_prefix="2002::/16",
174 ip4_prefix="0.0.0.0/0",
175 ip4_src=self.pg0.local_ip4,
178 self.tunnel_index = rv.sw_if_index
179 rv = self.vapi.ipip_6rd_del_tunnel(rv.sw_if_index)
180 rv = self.vapi.ipip_6rd_add_tunnel(
183 ip6_prefix="2002::/16",
184 ip4_prefix="0.0.0.0/0",
185 ip4_src=self.pg0.local_ip4,
188 self.tunnel_index = rv.sw_if_index
190 p_ip6 = IPv6(src="2002:AC10:0202::1", dst=self.pg1.remote_ip6) / UDP(
191 sport=1234, dport=1234
195 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
196 / IP(src=self.pg1.remote_ip4, dst=self.pg0.local_ip4)
202 rx = self.send_and_expect(self.pg0, p * 10, self.pg1)
204 self.validate_4in6(p, p_reply)
205 self.vapi.ipip_6rd_del_tunnel(self.tunnel_index)
207 def test_6rd_ip4_to_ip6_vrf(self):
208 """ip4 -> ip6 (decap) 6rd VRF test"""
210 rv = self.vapi.ipip_6rd_add_tunnel(
213 ip6_prefix="2002::/16",
214 ip4_prefix="0.0.0.0/0",
215 ip4_src=self.pg2.local_ip4,
218 self.tunnel_index = rv.sw_if_index
219 rv = self.vapi.ipip_6rd_del_tunnel(rv.sw_if_index)
220 rv = self.vapi.ipip_6rd_add_tunnel(
223 ip6_prefix="2002::/16",
224 ip4_prefix="0.0.0.0/0",
225 ip4_src=self.pg2.local_ip4,
228 self.tunnel_index = rv.sw_if_index
229 self.vapi.sw_interface_set_table(self.tunnel_index, 1, 20)
231 p_ip6 = IPv6(src="2002:AC10:0402::1", dst=self.pg3.remote_ip6) / UDP(
232 sport=1234, dport=1234
236 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
237 / IP(src=self.pg3.remote_ip4, dst=self.pg2.local_ip4)
243 rx = self.send_and_expect(self.pg2, p * 10, self.pg3)
245 self.validate_4in6(p, p_reply)
246 self.vapi.sw_interface_set_table(self.tunnel_index, 1, 0)
247 self.vapi.ipip_6rd_del_tunnel(self.tunnel_index)
249 def test_6rd_ip4_to_ip6_multiple(self):
250 """ip4 -> ip6 (decap) 6rd test"""
252 self.tunnel_index = []
253 rv = self.vapi.ipip_6rd_add_tunnel(
256 ip6_prefix="2002::/16",
257 ip4_prefix="0.0.0.0/0",
258 ip4_src=self.pg0.local_ip4,
261 self.tunnel_index.append(rv.sw_if_index)
262 rv = self.vapi.ipip_6rd_add_tunnel(
265 ip6_prefix="2003::/16",
266 ip4_prefix="0.0.0.0/0",
267 ip4_src=self.pg1.local_ip4,
271 self.tunnel_index.append(rv.sw_if_index)
273 self.vapi.cli("show ip6 fib")
274 p_ether = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
275 p_ip4 = IP(src=self.pg1.remote_ip4, dst=self.pg0.local_ip4)
276 p_ip6_1 = IPv6(src="2002:AC10:0202::1", dst=self.pg1.remote_ip6) / UDP(
277 sport=1234, dport=1234
279 p_ip6_2 = IPv6(src="2003:AC10:0202::1", dst=self.pg1.remote_ip6) / UDP(
280 sport=1234, dport=1234
283 p = p_ether / p_ip4 / p_ip6_1
284 rx = self.send_and_expect(self.pg0, p * 10, self.pg1)
286 self.validate_4in6(p, p_ip6_1)
288 p = p_ether / p_ip4 / p_ip6_2
289 rx = self.send_and_expect(self.pg0, p * 10, self.pg1)
291 self.validate_4in6(p, p_ip6_2)
292 for i in self.tunnel_index:
293 self.vapi.ipip_6rd_del_tunnel(i)
295 def test_6rd_ip4_to_ip6_suffix(self):
296 """ip4 -> ip6 (decap) 6rd test"""
298 rv = self.vapi.ipip_6rd_add_tunnel(
301 ip6_prefix="2002::/16",
302 ip4_prefix="172.0.0.0/8",
303 ip4_src=self.pg0.local_ip4,
306 self.tunnel_index = rv.sw_if_index
308 self.vapi.cli("show ip6 fib")
309 p_ether = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
310 p_ip4 = IP(src=self.pg1.remote_ip4, dst=self.pg0.local_ip4)
311 p_ip6 = IPv6(src="2002:1002:0200::1", dst=self.pg1.remote_ip6) / UDP(
312 sport=1234, dport=1234
315 p = p_ether / p_ip4 / p_ip6
316 rx = self.send_and_expect(self.pg0, p * 10, self.pg1)
318 self.validate_4in6(p, p_ip6)
319 self.vapi.ipip_6rd_del_tunnel(self.tunnel_index)
321 def test_6rd_ip4_to_ip6_sec_check(self):
322 """ip4 -> ip6 (decap) security check 6rd test"""
324 rv = self.vapi.ipip_6rd_add_tunnel(
327 ip6_prefix="2002::/16",
328 ip4_prefix="0.0.0.0/0",
329 ip4_src=self.pg0.local_ip4,
332 self.tunnel_index = rv.sw_if_index
334 self.vapi.cli("show ip6 fib")
335 p_ip6 = IPv6(src="2002:AC10:0202::1", dst=self.pg1.remote_ip6) / UDP(
336 sport=1234, dport=1234
338 p_ip6_fail = IPv6(src="2002:DEAD:0202::1", dst=self.pg1.remote_ip6) / UDP(
339 sport=1234, dport=1234
343 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
344 / IP(src=self.pg1.remote_ip4, dst=self.pg0.local_ip4)
350 rx = self.send_and_expect(self.pg0, p * 10, self.pg1)
352 self.validate_4in6(p, p_reply)
355 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
356 / IP(src=self.pg1.remote_ip4, dst=self.pg0.local_ip4)
359 rx = self.send_and_assert_no_replies(self.pg0, p * 10)
360 self.vapi.ipip_6rd_del_tunnel(self.tunnel_index)
362 def test_6rd_bgp_tunnel(self):
365 rv = self.vapi.ipip_6rd_add_tunnel(
368 ip6_prefix="2002::/16",
369 ip4_prefix="0.0.0.0/0",
370 ip4_src=self.pg0.local_ip4,
371 security_check=False,
374 self.tunnel_index = rv.sw_if_index
376 default_route = VppIpRoute(
377 self, "DEAD::", 16, [VppRoutePath("2002:0808:0808::", self.tunnel_index)]
379 default_route.add_vpp_config()
381 ip4_route = VppIpRoute(
382 self, "8.0.0.0", 8, [VppRoutePath(self.pg1.remote_ip4, 0xFFFFFFFF)]
384 ip4_route.add_vpp_config()
386 # Via recursive route 6 -> 4
388 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
389 / IPv6(src="1::1", dst="DEAD:BEEF::1")
390 / UDP(sport=1234, dport=1234)
393 p_reply = IP(src=self.pg0.local_ip4, dst="8.8.8.8", proto="ipv6") / IPv6(
394 src="1::1", dst="DEAD:BEEF::1", nh="UDP"
397 rx = self.send_and_expect(self.pg0, p * 10, self.pg1)
399 self.validate_6in4(p, p_reply)
401 # Via recursive route 4 -> 6 (Security check must be disabled)
402 p_ip6 = IPv6(src="DEAD:BEEF::1", dst=self.pg1.remote_ip6) / UDP(
403 sport=1234, dport=1234
406 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
407 / IP(src="8.8.8.8", dst=self.pg0.local_ip4)
413 rx = self.send_and_expect(self.pg0, p * 10, self.pg1)
415 self.validate_4in6(p, p_reply)
416 ip4_route.remove_vpp_config()
417 default_route.remove_vpp_config()
418 self.vapi.ipip_6rd_del_tunnel(self.tunnel_index)
421 if __name__ == "__main__":
422 unittest.main(testRunner=VppTestRunner)