]> git.proxmox.com Git - mirror_iproute2.git/blame - ip/iplink_xdp.c
update kernel headers from net-next
[mirror_iproute2.git] / ip / iplink_xdp.c
CommitLineData
c7272ca7
DB
1/*
2 * iplink_xdp.c XDP program loader
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Daniel Borkmann <daniel@iogearbox.net>
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14
15#include <linux/bpf.h>
16
17#include "xdp.h"
18#include "bpf_util.h"
19
20extern int force;
21
a872b870
DB
22struct xdp_req {
23 struct iplink_req *req;
24 __u32 flags;
25};
26
c7272ca7
DB
27static void xdp_ebpf_cb(void *raw, int fd, const char *annotation)
28{
a872b870
DB
29 struct xdp_req *xdp = raw;
30 struct iplink_req *req = xdp->req;
31 struct rtattr *xdp_attr;
c7272ca7 32
a872b870 33 xdp_attr = addattr_nest(&req->n, sizeof(*req), IFLA_XDP);
c7272ca7 34 addattr32(&req->n, sizeof(*req), IFLA_XDP_FD, fd);
a872b870
DB
35 if (xdp->flags)
36 addattr32(&req->n, sizeof(*req), IFLA_XDP_FLAGS, xdp->flags);
37 addattr_nest_end(&req->n, xdp_attr);
c7272ca7
DB
38}
39
40static const struct bpf_cfg_ops bpf_cb_ops = {
41 .ebpf_cb = xdp_ebpf_cb,
42};
43
a872b870 44static int xdp_delete(struct xdp_req *xdp)
c7272ca7 45{
a872b870 46 xdp_ebpf_cb(xdp, -1, NULL);
c7272ca7
DB
47 return 0;
48}
49
a872b870 50int xdp_parse(int *argc, char ***argv, struct iplink_req *req, bool generic)
c7272ca7
DB
51{
52 struct bpf_cfg_in cfg = {
53 .argc = *argc,
54 .argv = *argv,
55 };
a872b870
DB
56 struct xdp_req xdp = {
57 .req = req,
58 };
59
60 if (!force)
61 xdp.flags |= XDP_FLAGS_UPDATE_IF_NOEXIST;
62 if (generic)
63 xdp.flags |= XDP_FLAGS_SKB_MODE;
c7272ca7
DB
64
65 if (*argc == 1) {
66 if (strcmp(**argv, "none") == 0 ||
67 strcmp(**argv, "off") == 0)
a872b870 68 return xdp_delete(&xdp);
c7272ca7 69 }
a872b870
DB
70
71 if (bpf_parse_common(BPF_PROG_TYPE_XDP, &cfg, &bpf_cb_ops, &xdp))
c7272ca7
DB
72 return -1;
73
74 *argc = cfg.argc;
75 *argv = cfg.argv;
76 return 0;
77}
78
79void xdp_dump(FILE *fp, struct rtattr *xdp)
80{
81 struct rtattr *tb[IFLA_XDP_MAX + 1];
077bb180 82 __u8 mode;
c7272ca7
DB
83
84 parse_rtattr_nested(tb, IFLA_XDP_MAX, xdp);
a872b870 85
077bb180 86 if (!tb[IFLA_XDP_ATTACHED])
c7272ca7
DB
87 return;
88
077bb180
DB
89 mode = rta_getattr_u8(tb[IFLA_XDP_ATTACHED]);
90 if (mode == XDP_ATTACHED_NONE)
91 return;
92 else if (mode == XDP_ATTACHED_DRV)
93 fprintf(fp, "xdp ");
94 else if (mode == XDP_ATTACHED_SKB)
95 fprintf(fp, "xdpgeneric ");
96 else
97 fprintf(fp, "xdp[%u] ", mode);
c7272ca7 98}