xref: /linux/tools/testing/selftests/bpf/prog_tests/lwt_ip_encap.c (revision 4f9786035f9e519db41375818e1d0b5f20da2f10)
1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <netinet/in.h>
3 
4 #include "network_helpers.h"
5 #include "test_progs.h"
6 
7 #define BPF_FILE "test_lwt_ip_encap.bpf.o"
8 
9 #define NETNS_NAME_SIZE	32
10 #define NETNS_BASE	"ns-lwt-ip-encap"
11 
12 #define IP4_ADDR_1 "172.16.1.100"
13 #define IP4_ADDR_2 "172.16.2.100"
14 #define IP4_ADDR_3 "172.16.3.100"
15 #define IP4_ADDR_4 "172.16.4.100"
16 #define IP4_ADDR_5 "172.16.5.100"
17 #define IP4_ADDR_6 "172.16.6.100"
18 #define IP4_ADDR_7 "172.16.7.100"
19 #define IP4_ADDR_8 "172.16.8.100"
20 #define IP4_ADDR_GRE "172.16.16.100"
21 
22 #define IP4_ADDR_SRC IP4_ADDR_1
23 #define IP4_ADDR_DST IP4_ADDR_4
24 
25 #define IP6_ADDR_1 "fb01::1"
26 #define IP6_ADDR_2 "fb02::1"
27 #define IP6_ADDR_3 "fb03::1"
28 #define IP6_ADDR_4 "fb04::1"
29 #define IP6_ADDR_5 "fb05::1"
30 #define IP6_ADDR_6 "fb06::1"
31 #define IP6_ADDR_7 "fb07::1"
32 #define IP6_ADDR_8 "fb08::1"
33 #define IP6_ADDR_GRE "fb10::1"
34 
35 #define IP6_ADDR_SRC IP6_ADDR_1
36 #define IP6_ADDR_DST IP6_ADDR_4
37 
38 /* Setup/topology:
39  *
40  *    NS1             NS2             NS3
41  *   veth1 <---> veth2   veth3 <---> veth4 (the top route)
42  *   veth5 <---> veth6   veth7 <---> veth8 (the bottom route)
43  *
44  *   Each vethN gets IP[4|6]_ADDR_N address.
45  *
46  *   IP*_ADDR_SRC = IP*_ADDR_1
47  *   IP*_ADDR_DST = IP*_ADDR_4
48  *
49  *   All tests test pings from IP*_ADDR__SRC to IP*_ADDR_DST.
50  *
51  *   By default, routes are configured to allow packets to go
52  *   IP*_ADDR_1 <=> IP*_ADDR_2 <=> IP*_ADDR_3 <=> IP*_ADDR_4 (the top route).
53  *
54  *   A GRE device is installed in NS3 with IP*_ADDR_GRE, and
55  *   NS1/NS2 are configured to route packets to IP*_ADDR_GRE via IP*_ADDR_8
56  *   (the bottom route).
57  *
58  * Tests:
59  *
60  *   1. Routes NS2->IP*_ADDR_DST are brought down, so the only way a ping
61  *      from IP*_ADDR_SRC to IP*_ADDR_DST can work is via IP*_ADDR_GRE.
62  *
63  *   2a. In an egress test, a bpf LWT_XMIT program is installed on veth1
64  *       that encaps the packets with an IP/GRE header to route to IP*_ADDR_GRE.
65  *
66  *       ping: SRC->[encap at veth1:egress]->GRE:decap->DST
67  *       ping replies go DST->SRC directly
68  *
69  *   2b. In an ingress test, a bpf LWT_IN program is installed on veth2
70  *       that encaps the packets with an IP/GRE header to route to IP*_ADDR_GRE.
71  *
72  *       ping: SRC->[encap at veth2:ingress]->GRE:decap->DST
73  *       ping replies go DST->SRC directly
74  */
75 
76 static int create_ns(char *name, size_t name_sz)
77 {
78 	if (!name)
79 		goto fail;
80 
81 	if (!ASSERT_OK(append_tid(name, name_sz), "append TID"))
82 		goto fail;
83 
84 	SYS(fail, "ip netns add %s", name);
85 
86 	/* rp_filter gets confused by what these tests are doing, so disable it */
87 	SYS(fail, "ip netns exec %s sysctl -wq net.ipv4.conf.all.rp_filter=0", name);
88 	SYS(fail, "ip netns exec %s sysctl -wq net.ipv4.conf.default.rp_filter=0", name);
89 	/* Disable IPv6 DAD because it sometimes takes too long and fails tests */
90 	SYS(fail, "ip netns exec %s sysctl -wq net.ipv6.conf.all.accept_dad=0", name);
91 	SYS(fail, "ip netns exec %s sysctl -wq net.ipv6.conf.default.accept_dad=0", name);
92 
93 	return 0;
94 fail:
95 	return -1;
96 }
97 
98 static int set_top_addr(const char *ns1, const char *ns2, const char *ns3)
99 {
100 	SYS(fail, "ip -n %s    a add %s/24  dev veth1", ns1, IP4_ADDR_1);
101 	SYS(fail, "ip -n %s    a add %s/24  dev veth2", ns2, IP4_ADDR_2);
102 	SYS(fail, "ip -n %s    a add %s/24  dev veth3", ns2, IP4_ADDR_3);
103 	SYS(fail, "ip -n %s    a add %s/24  dev veth4", ns3, IP4_ADDR_4);
104 	SYS(fail, "ip -n %s -6 a add %s/128 dev veth1", ns1, IP6_ADDR_1);
105 	SYS(fail, "ip -n %s -6 a add %s/128 dev veth2", ns2, IP6_ADDR_2);
106 	SYS(fail, "ip -n %s -6 a add %s/128 dev veth3", ns2, IP6_ADDR_3);
107 	SYS(fail, "ip -n %s -6 a add %s/128 dev veth4", ns3, IP6_ADDR_4);
108 
109 	SYS(fail, "ip -n %s link set dev veth1 up", ns1);
110 	SYS(fail, "ip -n %s link set dev veth2 up", ns2);
111 	SYS(fail, "ip -n %s link set dev veth3 up", ns2);
112 	SYS(fail, "ip -n %s link set dev veth4 up", ns3);
113 
114 	return 0;
115 fail:
116 	return 1;
117 }
118 
119 static int set_bottom_addr(const char *ns1, const char *ns2, const char *ns3)
120 {
121 	SYS(fail, "ip -n %s    a add %s/24  dev veth5", ns1, IP4_ADDR_5);
122 	SYS(fail, "ip -n %s    a add %s/24  dev veth6", ns2, IP4_ADDR_6);
123 	SYS(fail, "ip -n %s    a add %s/24  dev veth7", ns2, IP4_ADDR_7);
124 	SYS(fail, "ip -n %s    a add %s/24  dev veth8", ns3, IP4_ADDR_8);
125 	SYS(fail, "ip -n %s -6 a add %s/128 dev veth5", ns1, IP6_ADDR_5);
126 	SYS(fail, "ip -n %s -6 a add %s/128 dev veth6", ns2, IP6_ADDR_6);
127 	SYS(fail, "ip -n %s -6 a add %s/128 dev veth7", ns2, IP6_ADDR_7);
128 	SYS(fail, "ip -n %s -6 a add %s/128 dev veth8", ns3, IP6_ADDR_8);
129 
130 	SYS(fail, "ip -n %s link set dev veth5 up", ns1);
131 	SYS(fail, "ip -n %s link set dev veth6 up", ns2);
132 	SYS(fail, "ip -n %s link set dev veth7 up", ns2);
133 	SYS(fail, "ip -n %s link set dev veth8 up", ns3);
134 
135 	return 0;
136 fail:
137 	return 1;
138 }
139 
140 static int configure_vrf(const char *ns1, const char *ns2)
141 {
142 	if (!ns1 || !ns2)
143 		goto fail;
144 
145 	SYS(fail, "ip -n %s link add red type vrf table 1001", ns1);
146 	SYS(fail, "ip -n %s link set red up", ns1);
147 	SYS(fail, "ip -n %s route add table 1001 unreachable default metric 8192", ns1);
148 	SYS(fail, "ip -n %s -6 route add table 1001 unreachable default metric 8192", ns1);
149 	SYS(fail, "ip -n %s link set veth1 vrf red", ns1);
150 	SYS(fail, "ip -n %s link set veth5 vrf red", ns1);
151 
152 	SYS(fail, "ip -n %s link add red type vrf table 1001", ns2);
153 	SYS(fail, "ip -n %s link set red up", ns2);
154 	SYS(fail, "ip -n %s route add table 1001 unreachable default metric 8192", ns2);
155 	SYS(fail, "ip -n %s -6 route add table 1001 unreachable default metric 8192", ns2);
156 	SYS(fail, "ip -n %s link set veth2 vrf red", ns2);
157 	SYS(fail, "ip -n %s link set veth3 vrf red", ns2);
158 	SYS(fail, "ip -n %s link set veth6 vrf red", ns2);
159 	SYS(fail, "ip -n %s link set veth7 vrf red", ns2);
160 
161 	return 0;
162 fail:
163 	return -1;
164 }
165 
166 static int configure_ns1(const char *ns1, const char *vrf)
167 {
168 	struct nstoken *nstoken = NULL;
169 
170 	if (!ns1 || !vrf)
171 		goto fail;
172 
173 	nstoken = open_netns(ns1);
174 	if (!ASSERT_OK_PTR(nstoken, "open ns1"))
175 		goto fail;
176 
177 	/* Top route */
178 	SYS(fail, "ip    route add %s/32  dev veth1 %s", IP4_ADDR_2, vrf);
179 	SYS(fail, "ip    route add default dev veth1 via %s %s", IP4_ADDR_2, vrf);
180 	SYS(fail, "ip -6 route add %s/128 dev veth1 %s", IP6_ADDR_2, vrf);
181 	SYS(fail, "ip -6 route add default dev veth1 via %s %s", IP6_ADDR_2, vrf);
182 	/* Bottom route */
183 	SYS(fail, "ip    route add %s/32  dev veth5 %s", IP4_ADDR_6, vrf);
184 	SYS(fail, "ip    route add %s/32  dev veth5 via  %s %s", IP4_ADDR_7, IP4_ADDR_6, vrf);
185 	SYS(fail, "ip    route add %s/32  dev veth5 via  %s %s", IP4_ADDR_8, IP4_ADDR_6, vrf);
186 	SYS(fail, "ip -6 route add %s/128 dev veth5 %s", IP6_ADDR_6, vrf);
187 	SYS(fail, "ip -6 route add %s/128 dev veth5 via  %s %s", IP6_ADDR_7, IP6_ADDR_6, vrf);
188 	SYS(fail, "ip -6 route add %s/128 dev veth5 via  %s %s", IP6_ADDR_8, IP6_ADDR_6, vrf);
189 
190 	close_netns(nstoken);
191 	return 0;
192 fail:
193 	close_netns(nstoken);
194 	return -1;
195 }
196 
197 static int configure_ns2(const char *ns2, const char *vrf)
198 {
199 	struct nstoken *nstoken = NULL;
200 
201 	if (!ns2 || !vrf)
202 		goto fail;
203 
204 	nstoken = open_netns(ns2);
205 	if (!ASSERT_OK_PTR(nstoken, "open ns2"))
206 		goto fail;
207 
208 	SYS(fail, "ip netns exec %s sysctl -wq net.ipv4.ip_forward=1", ns2);
209 	SYS(fail, "ip netns exec %s sysctl -wq net.ipv6.conf.all.forwarding=1", ns2);
210 
211 	/* Top route */
212 	SYS(fail, "ip    route add %s/32  dev veth2 %s", IP4_ADDR_1, vrf);
213 	SYS(fail, "ip    route add %s/32  dev veth3 %s", IP4_ADDR_4, vrf);
214 	SYS(fail, "ip -6 route add %s/128 dev veth2 %s", IP6_ADDR_1, vrf);
215 	SYS(fail, "ip -6 route add %s/128 dev veth3 %s", IP6_ADDR_4, vrf);
216 	/* Bottom route */
217 	SYS(fail, "ip    route add %s/32  dev veth6 %s", IP4_ADDR_5, vrf);
218 	SYS(fail, "ip    route add %s/32  dev veth7 %s", IP4_ADDR_8, vrf);
219 	SYS(fail, "ip -6 route add %s/128 dev veth6 %s", IP6_ADDR_5, vrf);
220 	SYS(fail, "ip -6 route add %s/128 dev veth7 %s", IP6_ADDR_8, vrf);
221 
222 	close_netns(nstoken);
223 	return 0;
224 fail:
225 	close_netns(nstoken);
226 	return -1;
227 }
228 
229 static int configure_ns3(const char *ns3)
230 {
231 	struct nstoken *nstoken = NULL;
232 
233 	if (!ns3)
234 		goto fail;
235 
236 	nstoken = open_netns(ns3);
237 	if (!ASSERT_OK_PTR(nstoken, "open ns3"))
238 		goto fail;
239 
240 	/* Top route */
241 	SYS(fail, "ip    route add %s/32  dev veth4", IP4_ADDR_3);
242 	SYS(fail, "ip    route add %s/32  dev veth4 via  %s", IP4_ADDR_1, IP4_ADDR_3);
243 	SYS(fail, "ip    route add %s/32  dev veth4 via  %s", IP4_ADDR_2, IP4_ADDR_3);
244 	SYS(fail, "ip -6 route add %s/128 dev veth4", IP6_ADDR_3);
245 	SYS(fail, "ip -6 route add %s/128 dev veth4 via  %s", IP6_ADDR_1, IP6_ADDR_3);
246 	SYS(fail, "ip -6 route add %s/128 dev veth4 via  %s", IP6_ADDR_2, IP6_ADDR_3);
247 	/* Bottom route */
248 	SYS(fail, "ip    route add %s/32  dev veth8", IP4_ADDR_7);
249 	SYS(fail, "ip    route add %s/32  dev veth8 via  %s", IP4_ADDR_5, IP4_ADDR_7);
250 	SYS(fail, "ip    route add %s/32  dev veth8 via  %s", IP4_ADDR_6, IP4_ADDR_7);
251 	SYS(fail, "ip -6 route add %s/128 dev veth8", IP6_ADDR_7);
252 	SYS(fail, "ip -6 route add %s/128 dev veth8 via  %s", IP6_ADDR_5, IP6_ADDR_7);
253 	SYS(fail, "ip -6 route add %s/128 dev veth8 via  %s", IP6_ADDR_6, IP6_ADDR_7);
254 
255 	/* Configure IPv4 GRE device */
256 	SYS(fail, "ip tunnel add gre_dev mode gre remote %s local %s ttl 255",
257 	    IP4_ADDR_1, IP4_ADDR_GRE);
258 	SYS(fail, "ip link set gre_dev up");
259 	SYS(fail, "ip a add %s dev gre_dev", IP4_ADDR_GRE);
260 
261 	/* Configure IPv6 GRE device */
262 	SYS(fail, "ip tunnel add gre6_dev mode ip6gre remote %s local %s ttl 255",
263 	    IP6_ADDR_1, IP6_ADDR_GRE);
264 	SYS(fail, "ip link set gre6_dev up");
265 	SYS(fail, "ip a add %s dev gre6_dev", IP6_ADDR_GRE);
266 
267 	close_netns(nstoken);
268 	return 0;
269 fail:
270 	close_netns(nstoken);
271 	return -1;
272 }
273 
274 static int setup_network(char *ns1, char *ns2, char *ns3, const char *vrf)
275 {
276 	if (!ns1 || !ns2 || !ns3 || !vrf)
277 		goto fail;
278 
279 	SYS(fail, "ip -n %s link add veth1 type veth peer name veth2 netns %s", ns1, ns2);
280 	SYS(fail, "ip -n %s link add veth3 type veth peer name veth4 netns %s", ns2, ns3);
281 	SYS(fail, "ip -n %s link add veth5 type veth peer name veth6 netns %s", ns1, ns2);
282 	SYS(fail, "ip -n %s link add veth7 type veth peer name veth8 netns %s", ns2, ns3);
283 
284 	if (vrf[0]) {
285 		if (!ASSERT_OK(configure_vrf(ns1, ns2), "configure vrf"))
286 			goto fail;
287 	}
288 	if (!ASSERT_OK(set_top_addr(ns1, ns2, ns3), "set top addresses"))
289 		goto fail;
290 
291 	if (!ASSERT_OK(set_bottom_addr(ns1, ns2, ns3), "set bottom addresses"))
292 		goto fail;
293 
294 	if (!ASSERT_OK(configure_ns1(ns1, vrf), "configure ns1 routes"))
295 		goto fail;
296 
297 	if (!ASSERT_OK(configure_ns2(ns2, vrf), "configure ns2 routes"))
298 		goto fail;
299 
300 	if (!ASSERT_OK(configure_ns3(ns3), "configure ns3 routes"))
301 		goto fail;
302 
303 	/* Link bottom route to the GRE tunnels */
304 	SYS(fail, "ip -n %s route add %s/32 dev veth5 via %s %s",
305 	    ns1, IP4_ADDR_GRE, IP4_ADDR_6, vrf);
306 	SYS(fail, "ip -n %s route add %s/32 dev veth7 via %s %s",
307 	    ns2, IP4_ADDR_GRE, IP4_ADDR_8, vrf);
308 	SYS(fail, "ip -n %s -6 route add %s/128 dev veth5 via %s %s",
309 	    ns1, IP6_ADDR_GRE, IP6_ADDR_6, vrf);
310 	SYS(fail, "ip -n %s -6 route add %s/128 dev veth7 via %s %s",
311 	    ns2, IP6_ADDR_GRE, IP6_ADDR_8, vrf);
312 
313 	return 0;
314 fail:
315 	return -1;
316 }
317 
318 static int remove_routes_to_gredev(const char *ns1, const char *ns2, const char *vrf)
319 {
320 	SYS(fail, "ip -n %s route del %s dev veth5 %s", ns1, IP4_ADDR_GRE, vrf);
321 	SYS(fail, "ip -n %s route del %s dev veth7 %s", ns2, IP4_ADDR_GRE, vrf);
322 	SYS(fail, "ip -n %s -6 route del %s/128 dev veth5 %s", ns1, IP6_ADDR_GRE, vrf);
323 	SYS(fail, "ip -n %s -6 route del %s/128 dev veth7 %s", ns2, IP6_ADDR_GRE, vrf);
324 
325 	return 0;
326 fail:
327 	return -1;
328 }
329 
330 static int add_unreachable_routes_to_gredev(const char *ns1, const char *ns2, const char *vrf)
331 {
332 	SYS(fail, "ip -n %s route add unreachable %s/32 %s", ns1, IP4_ADDR_GRE, vrf);
333 	SYS(fail, "ip -n %s route add unreachable %s/32 %s", ns2, IP4_ADDR_GRE, vrf);
334 	SYS(fail, "ip -n %s -6 route add unreachable %s/128 %s", ns1, IP6_ADDR_GRE, vrf);
335 	SYS(fail, "ip -n %s -6 route add unreachable %s/128 %s", ns2, IP6_ADDR_GRE, vrf);
336 
337 	return 0;
338 fail:
339 	return -1;
340 }
341 
342 #define GSO_SIZE 5000
343 #define GSO_TCP_PORT 9000
344 /* This tests the fix from commit ea0371f78799 ("net: fix GSO in bpf_lwt_push_ip_encap") */
345 static int test_gso_fix(const char *ns1, const char *ns3, int family)
346 {
347 	const char *ip_addr = family == AF_INET ? IP4_ADDR_DST : IP6_ADDR_DST;
348 	char gso_packet[GSO_SIZE] = {};
349 	struct nstoken *nstoken = NULL;
350 	int sfd, cfd, afd;
351 	ssize_t bytes;
352 	int ret = -1;
353 
354 	if (!ns1 || !ns3)
355 		return ret;
356 
357 	nstoken = open_netns(ns3);
358 	if (!ASSERT_OK_PTR(nstoken, "open ns3"))
359 		return ret;
360 
361 	sfd = start_server_str(family, SOCK_STREAM, ip_addr, GSO_TCP_PORT, NULL);
362 	if (!ASSERT_OK_FD(sfd, "start server"))
363 		goto close_netns;
364 
365 	close_netns(nstoken);
366 
367 	nstoken = open_netns(ns1);
368 	if (!ASSERT_OK_PTR(nstoken, "open ns1"))
369 		goto close_server;
370 
371 	cfd = connect_to_addr_str(family, SOCK_STREAM, ip_addr, GSO_TCP_PORT, NULL);
372 	if (!ASSERT_OK_FD(cfd, "connect to server"))
373 		goto close_server;
374 
375 	close_netns(nstoken);
376 	nstoken = NULL;
377 
378 	afd = accept(sfd, NULL, NULL);
379 	if (!ASSERT_OK_FD(afd, "accept"))
380 		goto close_client;
381 
382 	/* Send a packet larger than MTU */
383 	bytes = send(cfd, gso_packet, GSO_SIZE, 0);
384 	if (!ASSERT_EQ(bytes, GSO_SIZE, "send packet"))
385 		goto close_accept;
386 
387 	/* Verify we received all expected bytes */
388 	bytes = read(afd, gso_packet, GSO_SIZE);
389 	if (!ASSERT_EQ(bytes, GSO_SIZE, "receive packet"))
390 		goto close_accept;
391 
392 	ret = 0;
393 
394 close_accept:
395 	close(afd);
396 close_client:
397 	close(cfd);
398 close_server:
399 	close(sfd);
400 close_netns:
401 	close_netns(nstoken);
402 
403 	return ret;
404 }
405 
406 static int check_ping_ok(const char *ns1)
407 {
408 	SYS(fail, "ip netns exec %s ping -c 1 -W1 -I veth1 %s > /dev/null", ns1, IP4_ADDR_DST);
409 	SYS(fail, "ip netns exec %s ping6 -c 1 -W1 -I veth1 %s > /dev/null", ns1, IP6_ADDR_DST);
410 	return 0;
411 fail:
412 	return -1;
413 }
414 
415 static int check_ping_fails(const char *ns1)
416 {
417 	int ret;
418 
419 	ret = SYS_NOFAIL("ip netns exec %s ping -c 1 -W1 -I veth1 %s", ns1, IP4_ADDR_DST);
420 	if (!ret)
421 		return -1;
422 
423 	ret = SYS_NOFAIL("ip netns exec %s ping6 -c 1 -W1 -I veth1 %s", ns1, IP6_ADDR_DST);
424 	if (!ret)
425 		return -1;
426 
427 	return 0;
428 }
429 
430 #define EGRESS true
431 #define INGRESS false
432 #define IPV4_ENCAP true
433 #define IPV6_ENCAP false
434 static void lwt_ip_encap(bool ipv4_encap, bool egress, const char *vrf)
435 {
436 	char ns1[NETNS_NAME_SIZE] = NETNS_BASE "-1-";
437 	char ns2[NETNS_NAME_SIZE] = NETNS_BASE "-2-";
438 	char ns3[NETNS_NAME_SIZE] = NETNS_BASE "-3-";
439 	char *sec = ipv4_encap ?  "encap_gre" : "encap_gre6";
440 
441 	if (!vrf)
442 		return;
443 
444 	if (!ASSERT_OK(create_ns(ns1, NETNS_NAME_SIZE), "create ns1"))
445 		goto out;
446 	if (!ASSERT_OK(create_ns(ns2, NETNS_NAME_SIZE), "create ns2"))
447 		goto out;
448 	if (!ASSERT_OK(create_ns(ns3, NETNS_NAME_SIZE), "create ns3"))
449 		goto out;
450 
451 	if (!ASSERT_OK(setup_network(ns1, ns2, ns3, vrf), "setup network"))
452 		goto out;
453 
454 	/* By default, pings work */
455 	if (!ASSERT_OK(check_ping_ok(ns1), "ping OK"))
456 		goto out;
457 
458 	/* Remove NS2->DST routes, ping fails */
459 	SYS(out, "ip -n %s    route del %s/32  dev veth3 %s", ns2, IP4_ADDR_DST, vrf);
460 	SYS(out, "ip -n %s -6 route del %s/128 dev veth3 %s", ns2, IP6_ADDR_DST, vrf);
461 	if (!ASSERT_OK(check_ping_fails(ns1), "ping expected fail"))
462 		goto out;
463 
464 	/* Install replacement routes (LWT/eBPF), pings succeed */
465 	if (egress) {
466 		SYS(out, "ip -n %s route add %s encap bpf xmit obj %s sec %s dev veth1 %s",
467 		    ns1, IP4_ADDR_DST, BPF_FILE, sec, vrf);
468 		SYS(out, "ip -n %s -6 route add %s encap bpf xmit obj %s sec %s dev veth1 %s",
469 		    ns1, IP6_ADDR_DST, BPF_FILE, sec, vrf);
470 	} else {
471 		SYS(out, "ip -n %s route add %s encap bpf in obj %s sec %s dev veth2 %s",
472 		    ns2, IP4_ADDR_DST, BPF_FILE, sec, vrf);
473 		SYS(out, "ip -n %s -6 route add %s encap bpf in obj %s sec %s dev veth2 %s",
474 		    ns2, IP6_ADDR_DST, BPF_FILE, sec, vrf);
475 	}
476 
477 	if (!ASSERT_OK(check_ping_ok(ns1), "ping OK"))
478 		goto out;
479 
480 	/* Skip GSO tests with VRF: VRF routing needs properly assigned
481 	 * source IP/device, which is easy to do with ping but hard with TCP.
482 	 */
483 	if (egress && !vrf[0]) {
484 		if (!ASSERT_OK(test_gso_fix(ns1, ns3, AF_INET), "test GSO"))
485 			goto out;
486 	}
487 
488 	/* Negative test: remove routes to GRE devices: ping fails */
489 	if (!ASSERT_OK(remove_routes_to_gredev(ns1, ns2, vrf), "remove routes to gredev"))
490 		goto out;
491 	if (!ASSERT_OK(check_ping_fails(ns1), "ping expected fail"))
492 		goto out;
493 
494 	/* Another negative test */
495 	if (!ASSERT_OK(add_unreachable_routes_to_gredev(ns1, ns2, vrf),
496 		       "add unreachable routes"))
497 		goto out;
498 	ASSERT_OK(check_ping_fails(ns1), "ping expected fail");
499 
500 out:
501 	SYS_NOFAIL("ip netns del %s", ns1);
502 	SYS_NOFAIL("ip netns del %s", ns2);
503 	SYS_NOFAIL("ip netns del %s", ns3);
504 }
505 
506 void test_lwt_ip_encap_vrf_ipv6(void)
507 {
508 	if (test__start_subtest("egress"))
509 		lwt_ip_encap(IPV6_ENCAP, EGRESS, "vrf red");
510 
511 	if (test__start_subtest("ingress"))
512 		lwt_ip_encap(IPV6_ENCAP, INGRESS, "vrf red");
513 }
514 
515 void test_lwt_ip_encap_vrf_ipv4(void)
516 {
517 	if (test__start_subtest("egress"))
518 		lwt_ip_encap(IPV4_ENCAP, EGRESS, "vrf red");
519 
520 	if (test__start_subtest("ingress"))
521 		lwt_ip_encap(IPV4_ENCAP, INGRESS, "vrf red");
522 }
523 
524 void test_lwt_ip_encap_ipv6(void)
525 {
526 	if (test__start_subtest("egress"))
527 		lwt_ip_encap(IPV6_ENCAP, EGRESS, "");
528 
529 	if (test__start_subtest("ingress"))
530 		lwt_ip_encap(IPV6_ENCAP, INGRESS, "");
531 }
532 
533 void test_lwt_ip_encap_ipv4(void)
534 {
535 	if (test__start_subtest("egress"))
536 		lwt_ip_encap(IPV4_ENCAP, EGRESS, "");
537 
538 	if (test__start_subtest("ingress"))
539 		lwt_ip_encap(IPV4_ENCAP, INGRESS, "");
540 }
541