xsk.c (9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e) xsk.c (f540d44e05cf2f324697ba375235da2d7c92743c)
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>

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

13#include <string.h>
14#include <unistd.h>
15#include <arpa/inet.h>
16#include <asm/barrier.h>
17#include <linux/compiler.h>
18#include <linux/ethtool.h>
19#include <linux/filter.h>
20#include <linux/if_ether.h>
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>

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

13#include <string.h>
14#include <unistd.h>
15#include <arpa/inet.h>
16#include <asm/barrier.h>
17#include <linux/compiler.h>
18#include <linux/ethtool.h>
19#include <linux/filter.h>
20#include <linux/if_ether.h>
21#include <linux/if_link.h>
21#include <linux/if_packet.h>
22#include <linux/if_xdp.h>
23#include <linux/kernel.h>
24#include <linux/list.h>
22#include <linux/if_packet.h>
23#include <linux/if_xdp.h>
24#include <linux/kernel.h>
25#include <linux/list.h>
26#include <linux/netlink.h>
27#include <linux/rtnetlink.h>
25#include <linux/sockios.h>
26#include <net/if.h>
27#include <sys/ioctl.h>
28#include <sys/mman.h>
29#include <sys/socket.h>
30#include <sys/types.h>
28#include <linux/sockios.h>
29#include <net/if.h>
30#include <sys/ioctl.h>
31#include <sys/mman.h>
32#include <sys/socket.h>
33#include <sys/types.h>
31#include <linux/if_link.h>
32
33#include <bpf/bpf.h>
34#include <bpf/libbpf.h>
35#include "xsk.h"
36#include "bpf_util.h"
37
38#ifndef SOL_XDP
39 #define SOL_XDP 283

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

76struct xsk_socket {
77 struct xsk_ring_cons *rx;
78 struct xsk_ring_prod *tx;
79 struct xsk_ctx *ctx;
80 struct xsk_socket_config config;
81 int fd;
82};
83
34
35#include <bpf/bpf.h>
36#include <bpf/libbpf.h>
37#include "xsk.h"
38#include "bpf_util.h"
39
40#ifndef SOL_XDP
41 #define SOL_XDP 283

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

78struct xsk_socket {
79 struct xsk_ring_cons *rx;
80 struct xsk_ring_prod *tx;
81 struct xsk_ctx *ctx;
82 struct xsk_socket_config config;
83 int fd;
84};
85
86struct nl_mtu_req {
87 struct nlmsghdr nh;
88 struct ifinfomsg msg;
89 char buf[512];
90};
91
84int xsk_umem__fd(const struct xsk_umem *umem)
85{
86 return umem ? umem->fd : -EINVAL;
87}
88
89int xsk_socket__fd(const struct xsk_socket *xsk)
90{
91 return xsk ? xsk->fd : -EINVAL;

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

281 if (mode == XDP_FLAGS_DRV_MODE)
282 return opts.attach_mode == XDP_ATTACHED_DRV;
283 else if (mode == XDP_FLAGS_SKB_MODE)
284 return opts.attach_mode == XDP_ATTACHED_SKB;
285
286 return false;
287}
288
92int xsk_umem__fd(const struct xsk_umem *umem)
93{
94 return umem ? umem->fd : -EINVAL;
95}
96
97int xsk_socket__fd(const struct xsk_socket *xsk)
98{
99 return xsk ? xsk->fd : -EINVAL;

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

289 if (mode == XDP_FLAGS_DRV_MODE)
290 return opts.attach_mode == XDP_ATTACHED_DRV;
291 else if (mode == XDP_FLAGS_SKB_MODE)
292 return opts.attach_mode == XDP_ATTACHED_SKB;
293
294 return false;
295}
296
297/* Lifted from netlink.c in tools/lib/bpf */
298static int netlink_recvmsg(int sock, struct msghdr *mhdr, int flags)
299{
300 int len;
301
302 do {
303 len = recvmsg(sock, mhdr, flags);
304 } while (len < 0 && (errno == EINTR || errno == EAGAIN));
305
306 if (len < 0)
307 return -errno;
308 return len;
309}
310
311/* Lifted from netlink.c in tools/lib/bpf */
312static int alloc_iov(struct iovec *iov, int len)
313{
314 void *nbuf;
315
316 nbuf = realloc(iov->iov_base, len);
317 if (!nbuf)
318 return -ENOMEM;
319
320 iov->iov_base = nbuf;
321 iov->iov_len = len;
322 return 0;
323}
324
325/* Original version lifted from netlink.c in tools/lib/bpf */
326static int netlink_recv(int sock)
327{
328 struct iovec iov = {};
329 struct msghdr mhdr = {
330 .msg_iov = &iov,
331 .msg_iovlen = 1,
332 };
333 bool multipart = true;
334 struct nlmsgerr *err;
335 struct nlmsghdr *nh;
336 int len, ret;
337
338 ret = alloc_iov(&iov, 4096);
339 if (ret)
340 goto done;
341
342 while (multipart) {
343 multipart = false;
344 len = netlink_recvmsg(sock, &mhdr, MSG_PEEK | MSG_TRUNC);
345 if (len < 0) {
346 ret = len;
347 goto done;
348 }
349
350 if (len > iov.iov_len) {
351 ret = alloc_iov(&iov, len);
352 if (ret)
353 goto done;
354 }
355
356 len = netlink_recvmsg(sock, &mhdr, 0);
357 if (len < 0) {
358 ret = len;
359 goto done;
360 }
361
362 if (len == 0)
363 break;
364
365 for (nh = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(nh, len);
366 nh = NLMSG_NEXT(nh, len)) {
367 if (nh->nlmsg_flags & NLM_F_MULTI)
368 multipart = true;
369 switch (nh->nlmsg_type) {
370 case NLMSG_ERROR:
371 err = (struct nlmsgerr *)NLMSG_DATA(nh);
372 if (!err->error)
373 continue;
374 ret = err->error;
375 goto done;
376 case NLMSG_DONE:
377 ret = 0;
378 goto done;
379 default:
380 break;
381 }
382 }
383 }
384 ret = 0;
385done:
386 free(iov.iov_base);
387 return ret;
388}
389
390int xsk_set_mtu(int ifindex, int mtu)
391{
392 struct nl_mtu_req req;
393 struct rtattr *rta;
394 int fd, ret;
395
396 fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
397 if (fd < 0)
398 return fd;
399
400 memset(&req, 0, sizeof(req));
401 req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
402 req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
403 req.nh.nlmsg_type = RTM_NEWLINK;
404 req.msg.ifi_family = AF_UNSPEC;
405 req.msg.ifi_index = ifindex;
406 rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.nh.nlmsg_len));
407 rta->rta_type = IFLA_MTU;
408 rta->rta_len = RTA_LENGTH(sizeof(unsigned int));
409 req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + RTA_LENGTH(sizeof(mtu));
410 memcpy(RTA_DATA(rta), &mtu, sizeof(mtu));
411
412 ret = send(fd, &req, req.nh.nlmsg_len, 0);
413 if (ret < 0) {
414 close(fd);
415 return errno;
416 }
417
418 ret = netlink_recv(fd);
419 close(fd);
420 return ret;
421}
422
289int xsk_attach_xdp_program(struct bpf_program *prog, int ifindex, u32 xdp_flags)
290{
291 int prog_fd;
292
293 prog_fd = bpf_program__fd(prog);
294 return bpf_xdp_attach(ifindex, prog_fd, xdp_flags, NULL);
295}
296

--- 349 unchanged lines hidden ---
423int xsk_attach_xdp_program(struct bpf_program *prog, int ifindex, u32 xdp_flags)
424{
425 int prog_fd;
426
427 prog_fd = bpf_program__fd(prog);
428 return bpf_xdp_attach(ifindex, prog_fd, xdp_flags, NULL);
429}
430

--- 349 unchanged lines hidden ---