xsk.c (6b3c0821caa49538c49262b041bae59bad523c7c) xsk.c (f0a249df1b071d6f7177cc615d688a3a5d48423a)
1// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2
3/*
4 * AF_XDP user-space access library.
5 *
6 * Copyright(c) 2018 - 2019 Intel Corporation.
7 *
8 * Author(s): Magnus Karlsson <magnus.karlsson@intel.com>

--- 253 unchanged lines hidden (view full) ---

262
263out_socket:
264 close(umem->fd);
265out_umem_alloc:
266 free(umem);
267 return err;
268}
269
1// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2
3/*
4 * AF_XDP user-space access library.
5 *
6 * Copyright(c) 2018 - 2019 Intel Corporation.
7 *
8 * Author(s): Magnus Karlsson <magnus.karlsson@intel.com>

--- 253 unchanged lines hidden (view full) ---

262
263out_socket:
264 close(umem->fd);
265out_umem_alloc:
266 free(umem);
267 return err;
268}
269
270static int __xsk_load_xdp_prog(int xsk_map_fd)
270int xsk_attach_xdp_program(struct bpf_program *prog, int ifindex, u32 xdp_flags)
271{
271{
272 static const int log_buf_size = 16 * 1024;
273 char log_buf[log_buf_size];
274 int prog_fd;
275
272 int prog_fd;
273
276 /* This is the post-5.3 kernel C-program:
277 * SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx)
278 * {
279 * return bpf_redirect_map(&xsks_map, ctx->rx_queue_index, XDP_PASS);
280 * }
281 */
282 struct bpf_insn prog[] = {
283 /* r2 = *(u32 *)(r1 + 16) */
284 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 16),
285 /* r1 = xskmap[] */
286 BPF_LD_MAP_FD(BPF_REG_1, xsk_map_fd),
287 /* r3 = XDP_PASS */
288 BPF_MOV64_IMM(BPF_REG_3, 2),
289 /* call bpf_redirect_map */
290 BPF_EMIT_CALL(BPF_FUNC_redirect_map),
291 BPF_EXIT_INSN(),
292 };
293 size_t insns_cnt = ARRAY_SIZE(prog);
294 LIBBPF_OPTS(bpf_prog_load_opts, opts,
295 .log_buf = log_buf,
296 .log_size = log_buf_size,
297 );
274 prog_fd = bpf_program__fd(prog);
275 return bpf_xdp_attach(ifindex, prog_fd, xdp_flags, NULL);
276}
298
277
299 prog_fd = bpf_prog_load(BPF_PROG_TYPE_XDP, NULL, "LGPL-2.1 or BSD-2-Clause",
300 prog, insns_cnt, &opts);
301 if (prog_fd < 0)
302 pr_warn("BPF log buffer:\n%s", log_buf);
303
304 return prog_fd;
278void xsk_detach_xdp_program(int ifindex, u32 xdp_flags)
279{
280 bpf_xdp_detach(ifindex, xdp_flags, NULL);
305}
306
281}
282
307int xsk_attach_xdp_program(int ifindex, int prog_fd, u32 xdp_flags)
283void xsk_clear_xskmap(struct bpf_map *map)
308{
284{
309 DECLARE_LIBBPF_OPTS(bpf_link_create_opts, opts);
310 __u32 prog_id = 0;
311 int link_fd;
312 int err;
285 u32 index = 0;
286 int map_fd;
313
287
314 err = bpf_xdp_query_id(ifindex, xdp_flags, &prog_id);
315 if (err) {
316 pr_warn("getting XDP prog id failed\n");
317 return err;
318 }
319
320 /* If there's a netlink-based XDP prog loaded on interface, bail out
321 * and ask user to do the removal by himself
322 */
323 if (prog_id) {
324 pr_warn("Netlink-based XDP prog detected, please unload it in order to launch AF_XDP prog\n");
325 return -EINVAL;
326 }
327
328 opts.flags = xdp_flags & ~(XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_REPLACE);
329
330 link_fd = bpf_link_create(prog_fd, ifindex, BPF_XDP, &opts);
331 if (link_fd < 0)
332 pr_warn("bpf_link_create failed: %s\n", strerror(errno));
333
334 return link_fd;
288 map_fd = bpf_map__fd(map);
289 bpf_map_delete_elem(map_fd, &index);
335}
336
290}
291
337int xsk_load_xdp_program(int *xsk_map_fd, int *prog_fd)
292int xsk_update_xskmap(struct bpf_map *map, struct xsk_socket *xsk)
338{
293{
339 *xsk_map_fd = bpf_map_create(BPF_MAP_TYPE_XSKMAP, "xsks_map", sizeof(int), sizeof(int),
340 XSKMAP_SIZE, NULL);
341 if (*xsk_map_fd < 0)
342 return *xsk_map_fd;
294 int map_fd, sock_fd;
295 u32 index = 0;
343
296
344 *prog_fd = __xsk_load_xdp_prog(*xsk_map_fd);
345 if (*prog_fd < 0) {
346 close(*xsk_map_fd);
347 return *prog_fd;
348 }
297 map_fd = bpf_map__fd(map);
298 sock_fd = xsk_socket__fd(xsk);
349
299
350 return 0;
300 return bpf_map_update_elem(map_fd, &index, &sock_fd, 0);
351}
352
353static struct xsk_ctx *xsk_get_ctx(struct xsk_umem *umem, int ifindex,
354 __u32 queue_id)
355{
356 struct xsk_ctx *ctx;
357
358 if (list_empty(&umem->ctx_list))

--- 318 unchanged lines hidden ---
301}
302
303static struct xsk_ctx *xsk_get_ctx(struct xsk_umem *umem, int ifindex,
304 __u32 queue_id)
305{
306 struct xsk_ctx *ctx;
307
308 if (list_empty(&umem->ctx_list))

--- 318 unchanged lines hidden ---