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 --- |