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