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, VppTestRunner
9 from vpp_ip_route import VppIpRoute, VppRoutePath, DpoProto
10 from socket import AF_INET, AF_INET6, inet_pton
12 """ Test6rd is a subclass of VPPTestCase classes.
19 class Test6RD(VppTestCase):
24 super(Test6RD, cls).setUpClass()
25 cls.create_pg_interfaces(range(2))
26 cls.interfaces = list(cls.pg_interfaces)
29 super(Test6RD, cls).setUp()
30 for i in cls.interfaces:
39 super(Test6RD, self).tearDown()
41 for i in self.pg_interfaces:
45 if type(self.tunnel_index) is list:
46 for sw_if_index in self.tunnel_index:
47 self.vapi.ipip_6rd_del_tunnel(sw_if_index)
49 self.vapi.ipip_6rd_del_tunnel(self.tunnel_index)
51 def validate_6in4(self, rx, expected):
57 self.assertEqual(rx[IP].src, expected[IP].src)
58 self.assertEqual(rx[IP].dst, expected[IP].dst)
59 self.assertEqual(rx[IP].proto, expected[IP].proto)
60 self.assertEqual(rx[IPv6].src, expected[IPv6].src)
61 self.assertEqual(rx[IPv6].dst, expected[IPv6].dst)
63 def validate_4in6(self, rx, expected):
69 self.assertTrue(rx[IPv6].src == expected[IPv6].src)
70 self.assertTrue(rx[IPv6].dst == expected[IPv6].dst)
71 self.assertTrue(rx[IPv6].nh == expected[IPv6].nh)
73 def payload(self, len):
76 def test_6rd_ip6_to_ip4(self):
77 """ ip6 -> ip4 (encap) 6rd test """
78 p_ether = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
79 p_ip6 = IPv6(src="1::1", dst="2002:AC10:0202::1", nh='UDP')
81 rv = self.vapi.ipip_6rd_add_tunnel(
82 0, inet_pton(AF_INET6, '2002::'), 16,
83 inet_pton(AF_INET, '0.0.0.0'), 0,
84 self.pg0.local_ip4n, True)
85 self.tunnel_index = rv.sw_if_index
87 self.vapi.cli("show ip6 fib")
88 p_payload = UDP(sport=1234, dport=1234)
89 p = (p_ether / p_ip6 / p_payload)
91 p_reply = (IP(src=self.pg0.local_ip4, dst=self.pg1.remote_ip4,
92 proto='ipv6') / p_ip6)
94 rx = self.send_and_expect(self.pg0, p*10, self.pg1)
96 self.validate_6in4(p, p_reply)
98 # MTU tests (default is 1480)
100 p_ip6 = IPv6(src="1::1", dst="2002:AC10:0202::1")
101 p_payload = UDP(sport=1234, dport=1234) / Raw(self.payload(plen))
102 p = (p_ether / p_ip6 / p_payload)
104 p_reply = (IP(src=self.pg0.local_ip4, dst=self.pg1.remote_ip4,
105 proto='ipv6') / p_ip6)
107 rx = self.send_and_assert_no_replies(self.pg0, p*10)
109 def test_6rd_ip4_to_ip6(self):
110 """ ip4 -> ip6 (decap) 6rd test """
112 rv = self.vapi.ipip_6rd_add_tunnel(
113 0, inet_pton(AF_INET6, '2002::'),
114 16, inet_pton(AF_INET, '0.0.0.0'),
115 0, self.pg0.local_ip4n, True)
116 self.tunnel_index = rv.sw_if_index
117 rv = self.vapi.ipip_6rd_del_tunnel(rv.sw_if_index)
118 rv = self.vapi.ipip_6rd_add_tunnel(
119 0, inet_pton(AF_INET6, '2002::'),
120 16, inet_pton(AF_INET, '0.0.0.0'),
121 0, self.pg0.local_ip4n, True)
122 self.tunnel_index = rv.sw_if_index
124 p_ip6 = (IPv6(src="2002:AC10:0202::1", dst=self.pg1.remote_ip6) /
125 UDP(sport=1234, dport=1234))
127 p = (Ether(src=self.pg0.remote_mac,
128 dst=self.pg0.local_mac) /
129 IP(src=self.pg1.remote_ip4, dst=self.pg0.local_ip4) /
134 rx = self.send_and_expect(self.pg0, p*10, self.pg1)
136 self.validate_4in6(p, p_reply)
138 def test_6rd_ip4_to_ip6_multiple(self):
139 """ ip4 -> ip6 (decap) 6rd test """
141 self.tunnel_index = []
142 rv = self.vapi.ipip_6rd_add_tunnel(
143 0, inet_pton(AF_INET6, '2002::'),
144 16, inet_pton(AF_INET, '0.0.0.0'),
145 0, self.pg0.local_ip4n, True)
146 self.tunnel_index.append(rv.sw_if_index)
148 rv = self.vapi.ipip_6rd_add_tunnel(
149 0, inet_pton(AF_INET6, '2003::'),
150 16, inet_pton(AF_INET, '0.0.0.0'),
151 0, self.pg1.local_ip4n, True)
152 self.tunnel_index.append(rv.sw_if_index)
154 self.vapi.cli("show ip6 fib")
155 p_ether = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
156 p_ip4 = IP(src=self.pg1.remote_ip4, dst=self.pg0.local_ip4)
157 p_ip6_1 = (IPv6(src="2002:AC10:0202::1", dst=self.pg1.remote_ip6) /
158 UDP(sport=1234, dport=1234))
159 p_ip6_2 = (IPv6(src="2003:AC10:0202::1", dst=self.pg1.remote_ip6) /
160 UDP(sport=1234, dport=1234))
162 p = (p_ether / p_ip4 / p_ip6_1)
163 rx = self.send_and_expect(self.pg0, p*10, self.pg1)
165 self.validate_4in6(p, p_ip6_1)
167 p = (p_ether / p_ip4 / p_ip6_2)
168 rx = self.send_and_expect(self.pg0, p*10, self.pg1)
170 self.validate_4in6(p, p_ip6_2)
172 def test_6rd_ip4_to_ip6_suffix(self):
173 """ ip4 -> ip6 (decap) 6rd test """
175 rv = self.vapi.ipip_6rd_add_tunnel(
176 0, inet_pton(AF_INET6, '2002::'), 16,
177 inet_pton(AF_INET, '172.0.0.0'), 8,
178 self.pg0.local_ip4n, True)
180 self.tunnel_index = rv.sw_if_index
182 self.vapi.cli("show ip6 fib")
183 p_ether = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
184 p_ip4 = IP(src=self.pg1.remote_ip4, dst=self.pg0.local_ip4)
185 p_ip6 = (IPv6(src="2002:1002:0200::1", dst=self.pg1.remote_ip6) /
186 UDP(sport=1234, dport=1234))
188 p = (p_ether / p_ip4 / p_ip6)
189 rx = self.send_and_expect(self.pg0, p*10, self.pg1)
191 self.validate_4in6(p, p_ip6)
193 def test_6rd_ip4_to_ip6_sec_check(self):
194 """ ip4 -> ip6 (decap) security check 6rd test """
196 rv = self.vapi.ipip_6rd_add_tunnel(
197 0, inet_pton(AF_INET6, '2002::'),
198 16, inet_pton(AF_INET, '0.0.0.0'),
199 0, self.pg0.local_ip4n, True)
200 self.tunnel_index = rv.sw_if_index
202 self.vapi.cli("show ip6 fib")
203 p_ip6 = (IPv6(src="2002:AC10:0202::1", dst=self.pg1.remote_ip6) /
204 UDP(sport=1234, dport=1234))
205 p_ip6_fail = (IPv6(src="2002:DEAD:0202::1", dst=self.pg1.remote_ip6) /
206 UDP(sport=1234, dport=1234))
208 p = (Ether(src=self.pg0.remote_mac,
209 dst=self.pg0.local_mac) /
210 IP(src=self.pg1.remote_ip4, dst=self.pg0.local_ip4) /
215 rx = self.send_and_expect(self.pg0, p*10, self.pg1)
217 self.validate_4in6(p, p_reply)
219 p = (Ether(src=self.pg0.remote_mac,
220 dst=self.pg0.local_mac) /
221 IP(src=self.pg1.remote_ip4, dst=self.pg0.local_ip4) /
223 rx = self.send_and_assert_no_replies(self.pg0, p*10)
225 def test_6rd_bgp_tunnel(self):
226 """ 6rd BGP tunnel """
228 rv = self.vapi.ipip_6rd_add_tunnel(
229 0, inet_pton(AF_INET6, '2002::'),
230 16, inet_pton(AF_INET, '0.0.0.0'),
231 0, self.pg0.local_ip4n, False)
232 self.tunnel_index = rv.sw_if_index
234 default_route = VppIpRoute(
235 self, "DEAD::", 16, [VppRoutePath("2002:0808:0808::",
237 proto=DpoProto.DPO_PROTO_IP6)],
239 default_route.add_vpp_config()
241 ip4_route = VppIpRoute(self, "8.0.0.0", 8,
242 [VppRoutePath(self.pg1.remote_ip4, 0xFFFFFFFF)])
243 ip4_route.add_vpp_config()
245 # Via recursive route 6 -> 4
246 p = (Ether(src=self.pg0.remote_mac,
247 dst=self.pg0.local_mac) /
248 IPv6(src="1::1", dst="DEAD:BEEF::1") /
249 UDP(sport=1234, dport=1234))
251 p_reply = (IP(src=self.pg0.local_ip4, dst="8.8.8.8",
253 IPv6(src='1::1', dst='DEAD:BEEF::1', nh='UDP'))
255 rx = self.send_and_expect(self.pg0, p*10, self.pg1)
257 self.validate_6in4(p, p_reply)
259 # Via recursive route 4 -> 6 (Security check must be disabled)
260 p_ip6 = (IPv6(src="DEAD:BEEF::1", dst=self.pg1.remote_ip6) /
261 UDP(sport=1234, dport=1234))
262 p = (Ether(src=self.pg0.remote_mac,
263 dst=self.pg0.local_mac) /
264 IP(src="8.8.8.8", dst=self.pg0.local_ip4) /
269 rx = self.send_and_expect(self.pg0, p*10, self.pg1)
271 self.validate_4in6(p, p_reply)
274 if __name__ == '__main__':
275 unittest.main(testRunner=VppTestRunner)