~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/prog_tests/test_xdp_veth.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 
  3 /* Create 3 namespaces with 3 veth peers, and forward packets in-between using
  4  * native XDP
  5  *
  6  *                      XDP_TX
  7  * NS1(veth11)        NS2(veth22)        NS3(veth33)
  8  *      |                  |                  |
  9  *      |                  |                  |
 10  *   (veth1,            (veth2,            (veth3,
 11  *   id:111)            id:122)            id:133)
 12  *     ^ |                ^ |                ^ |
 13  *     | |  XDP_REDIRECT  | |  XDP_REDIRECT  | |
 14  *     | ------------------ ------------------ |
 15  *     -----------------------------------------
 16  *                    XDP_REDIRECT
 17  */
 18 
 19 #define _GNU_SOURCE
 20 #include <net/if.h>
 21 #include "test_progs.h"
 22 #include "network_helpers.h"
 23 #include "xdp_dummy.skel.h"
 24 #include "xdp_redirect_map.skel.h"
 25 #include "xdp_tx.skel.h"
 26 
 27 #define VETH_PAIRS_COUNT        3
 28 #define NS_SUFFIX_LEN           6
 29 #define VETH_NAME_MAX_LEN       16
 30 #define IP_SRC                          "10.1.1.11"
 31 #define IP_DST                          "10.1.1.33"
 32 #define IP_CMD_MAX_LEN          128
 33 
 34 struct skeletons {
 35         struct xdp_dummy *xdp_dummy;
 36         struct xdp_tx *xdp_tx;
 37         struct xdp_redirect_map *xdp_redirect_maps;
 38 };
 39 
 40 struct veth_configuration {
 41         char local_veth[VETH_NAME_MAX_LEN]; /* Interface in main namespace */
 42         char remote_veth[VETH_NAME_MAX_LEN]; /* Peer interface in dedicated namespace*/
 43         const char *namespace; /* Namespace for the remote veth */
 44         char next_veth[VETH_NAME_MAX_LEN]; /* Local interface to redirect traffic to */
 45         char *remote_addr; /* IP address of the remote veth */
 46 };
 47 
 48 static struct veth_configuration config[VETH_PAIRS_COUNT] = {
 49         {
 50                 .local_veth = "veth1",
 51                 .remote_veth = "veth11",
 52                 .next_veth = "veth2",
 53                 .remote_addr = IP_SRC,
 54                 .namespace = "ns-veth11"
 55         },
 56         {
 57                 .local_veth = "veth2",
 58                 .remote_veth = "veth22",
 59                 .next_veth = "veth3",
 60                 .remote_addr = NULL,
 61                 .namespace = "ns-veth22"
 62         },
 63         {
 64                 .local_veth = "veth3",
 65                 .remote_veth = "veth33",
 66                 .next_veth = "veth1",
 67                 .remote_addr = IP_DST,
 68                 .namespace = "ns-veth33"
 69         }
 70 };
 71 
 72 static int attach_programs_to_veth_pair(struct skeletons *skeletons, int index)
 73 {
 74         struct bpf_program *local_prog, *remote_prog;
 75         struct bpf_link **local_link, **remote_link;
 76         struct nstoken *nstoken;
 77         struct bpf_link *link;
 78         int interface;
 79 
 80         switch (index) {
 81         case 0:
 82                 local_prog = skeletons->xdp_redirect_maps->progs.xdp_redirect_map_0;
 83                 local_link = &skeletons->xdp_redirect_maps->links.xdp_redirect_map_0;
 84                 remote_prog = skeletons->xdp_dummy->progs.xdp_dummy_prog;
 85                 remote_link = &skeletons->xdp_dummy->links.xdp_dummy_prog;
 86                 break;
 87         case 1:
 88                 local_prog = skeletons->xdp_redirect_maps->progs.xdp_redirect_map_1;
 89                 local_link = &skeletons->xdp_redirect_maps->links.xdp_redirect_map_1;
 90                 remote_prog = skeletons->xdp_tx->progs.xdp_tx;
 91                 remote_link = &skeletons->xdp_tx->links.xdp_tx;
 92                 break;
 93         case 2:
 94                 local_prog = skeletons->xdp_redirect_maps->progs.xdp_redirect_map_2;
 95                 local_link = &skeletons->xdp_redirect_maps->links.xdp_redirect_map_2;
 96                 remote_prog = skeletons->xdp_dummy->progs.xdp_dummy_prog;
 97                 remote_link = &skeletons->xdp_dummy->links.xdp_dummy_prog;
 98                 break;
 99         }
100         interface = if_nametoindex(config[index].local_veth);
101         if (!ASSERT_NEQ(interface, 0, "non zero interface index"))
102                 return -1;
103         link = bpf_program__attach_xdp(local_prog, interface);
104         if (!ASSERT_OK_PTR(link, "attach xdp program to local veth"))
105                 return -1;
106         *local_link = link;
107         nstoken = open_netns(config[index].namespace);
108         if (!ASSERT_OK_PTR(nstoken, "switch to remote veth namespace"))
109                 return -1;
110         interface = if_nametoindex(config[index].remote_veth);
111         if (!ASSERT_NEQ(interface, 0, "non zero interface index")) {
112                 close_netns(nstoken);
113                 return -1;
114         }
115         link = bpf_program__attach_xdp(remote_prog, interface);
116         *remote_link = link;
117         close_netns(nstoken);
118         if (!ASSERT_OK_PTR(link, "attach xdp program to remote veth"))
119                 return -1;
120 
121         return 0;
122 }
123 
124 static int configure_network(struct skeletons *skeletons)
125 {
126         int interface_id;
127         int map_fd;
128         int err;
129         int i = 0;
130 
131         /* First create and configure all interfaces */
132         for (i = 0; i < VETH_PAIRS_COUNT; i++) {
133                 SYS(fail, "ip netns add %s", config[i].namespace);
134                 SYS(fail, "ip link add %s type veth peer name %s netns %s",
135                     config[i].local_veth, config[i].remote_veth, config[i].namespace);
136                 SYS(fail, "ip link set dev %s up", config[i].local_veth);
137                 if (config[i].remote_addr)
138                         SYS(fail, "ip -n %s addr add %s/24 dev %s",     config[i].namespace,
139                             config[i].remote_addr, config[i].remote_veth);
140                 SYS(fail, "ip -n %s link set dev %s up", config[i].namespace,
141                     config[i].remote_veth);
142         }
143 
144         /* Then configure the redirect map and attach programs to interfaces */
145         map_fd = bpf_map__fd(skeletons->xdp_redirect_maps->maps.tx_port);
146         if (!ASSERT_GE(map_fd, 0, "open redirect map"))
147                 goto fail;
148         for (i = 0; i < VETH_PAIRS_COUNT; i++) {
149                 interface_id = if_nametoindex(config[i].next_veth);
150                 if (!ASSERT_NEQ(interface_id, 0, "non zero interface index"))
151                         goto fail;
152                 err = bpf_map_update_elem(map_fd, &i, &interface_id, BPF_ANY);
153                 if (!ASSERT_OK(err, "configure interface redirection through map"))
154                         goto fail;
155                 if (attach_programs_to_veth_pair(skeletons, i))
156                         goto fail;
157         }
158 
159         return 0;
160 
161 fail:
162         return -1;
163 }
164 
165 static void cleanup_network(void)
166 {
167         int i;
168 
169         /* Deleting namespaces is enough to automatically remove veth pairs as well
170          */
171         for (i = 0; i < VETH_PAIRS_COUNT; i++)
172                 SYS_NOFAIL("ip netns del %s", config[i].namespace);
173 }
174 
175 static int check_ping(struct skeletons *skeletons)
176 {
177         /* Test: if all interfaces are properly configured, we must be able to ping
178          * veth33 from veth11
179          */
180         return SYS_NOFAIL("ip netns exec %s ping -c 1 -W 1 %s > /dev/null",
181                                           config[0].namespace, IP_DST);
182 }
183 
184 void test_xdp_veth_redirect(void)
185 {
186         struct skeletons skeletons = {};
187 
188         skeletons.xdp_dummy = xdp_dummy__open_and_load();
189         if (!ASSERT_OK_PTR(skeletons.xdp_dummy, "xdp_dummy__open_and_load"))
190                 return;
191 
192         skeletons.xdp_tx = xdp_tx__open_and_load();
193         if (!ASSERT_OK_PTR(skeletons.xdp_tx, "xdp_tx__open_and_load"))
194                 goto destroy_xdp_dummy;
195 
196         skeletons.xdp_redirect_maps = xdp_redirect_map__open_and_load();
197         if (!ASSERT_OK_PTR(skeletons.xdp_redirect_maps, "xdp_redirect_map__open_and_load"))
198                 goto destroy_xdp_tx;
199 
200         if (configure_network(&skeletons))
201                 goto destroy_xdp_redirect_map;
202 
203         ASSERT_OK(check_ping(&skeletons), "ping");
204 
205 destroy_xdp_redirect_map:
206         xdp_redirect_map__destroy(skeletons.xdp_redirect_maps);
207 destroy_xdp_tx:
208         xdp_tx__destroy(skeletons.xdp_tx);
209 destroy_xdp_dummy:
210         xdp_dummy__destroy(skeletons.xdp_dummy);
211 
212         cleanup_network();
213 }
214 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php