]>
Commit | Line | Data |
---|---|---|
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 | ||
20 | extern int force; | |
21 | ||
a872b870 DB |
22 | struct xdp_req { |
23 | struct iplink_req *req; | |
24 | __u32 flags; | |
25 | }; | |
26 | ||
c7272ca7 DB |
27 | static 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 | ||
40 | static const struct bpf_cfg_ops bpf_cb_ops = { | |
41 | .ebpf_cb = xdp_ebpf_cb, | |
42 | }; | |
43 | ||
a872b870 | 44 | static int xdp_delete(struct xdp_req *xdp) |
c7272ca7 | 45 | { |
a872b870 | 46 | xdp_ebpf_cb(xdp, -1, NULL); |
c7272ca7 DB |
47 | return 0; |
48 | } | |
49 | ||
14683814 | 50 | int xdp_parse(int *argc, char ***argv, struct iplink_req *req, bool generic, |
1b5e8094 | 51 | bool drv, bool offload) |
c7272ca7 DB |
52 | { |
53 | struct bpf_cfg_in cfg = { | |
54 | .argc = *argc, | |
55 | .argv = *argv, | |
56 | }; | |
a872b870 DB |
57 | struct xdp_req xdp = { |
58 | .req = req, | |
59 | }; | |
60 | ||
61 | if (!force) | |
62 | xdp.flags |= XDP_FLAGS_UPDATE_IF_NOEXIST; | |
63 | if (generic) | |
64 | xdp.flags |= XDP_FLAGS_SKB_MODE; | |
14683814 JK |
65 | if (drv) |
66 | xdp.flags |= XDP_FLAGS_DRV_MODE; | |
1b5e8094 JK |
67 | if (offload) |
68 | xdp.flags |= XDP_FLAGS_HW_MODE; | |
c7272ca7 DB |
69 | |
70 | if (*argc == 1) { | |
71 | if (strcmp(**argv, "none") == 0 || | |
72 | strcmp(**argv, "off") == 0) | |
a872b870 | 73 | return xdp_delete(&xdp); |
c7272ca7 | 74 | } |
a872b870 DB |
75 | |
76 | if (bpf_parse_common(BPF_PROG_TYPE_XDP, &cfg, &bpf_cb_ops, &xdp)) | |
c7272ca7 DB |
77 | return -1; |
78 | ||
79 | *argc = cfg.argc; | |
80 | *argv = cfg.argv; | |
81 | return 0; | |
82 | } | |
83 | ||
a0b5b7cf | 84 | void xdp_dump(FILE *fp, struct rtattr *xdp, bool link, bool details) |
c7272ca7 DB |
85 | { |
86 | struct rtattr *tb[IFLA_XDP_MAX + 1]; | |
a0b5b7cf | 87 | __u32 prog_id = 0; |
077bb180 | 88 | __u8 mode; |
c7272ca7 DB |
89 | |
90 | parse_rtattr_nested(tb, IFLA_XDP_MAX, xdp); | |
a872b870 | 91 | |
077bb180 | 92 | if (!tb[IFLA_XDP_ATTACHED]) |
c7272ca7 DB |
93 | return; |
94 | ||
077bb180 DB |
95 | mode = rta_getattr_u8(tb[IFLA_XDP_ATTACHED]); |
96 | if (mode == XDP_ATTACHED_NONE) | |
97 | return; | |
a0b5b7cf DB |
98 | else if (details && link) |
99 | fprintf(fp, "%s prog/xdp", _SL_); | |
077bb180 | 100 | else if (mode == XDP_ATTACHED_DRV) |
0b4ea60b | 101 | fprintf(fp, "xdp"); |
077bb180 | 102 | else if (mode == XDP_ATTACHED_SKB) |
0b4ea60b | 103 | fprintf(fp, "xdpgeneric"); |
2de33797 JK |
104 | else if (mode == XDP_ATTACHED_HW) |
105 | fprintf(fp, "xdpoffload"); | |
077bb180 | 106 | else |
0b4ea60b MKL |
107 | fprintf(fp, "xdp[%u]", mode); |
108 | ||
109 | if (tb[IFLA_XDP_PROG_ID]) | |
a0b5b7cf DB |
110 | prog_id = rta_getattr_u32(tb[IFLA_XDP_PROG_ID]); |
111 | if (!details) { | |
112 | if (prog_id && !link) | |
113 | fprintf(fp, "/id:%u", prog_id); | |
114 | fprintf(fp, " "); | |
115 | return; | |
116 | } | |
0b4ea60b | 117 | |
a0b5b7cf DB |
118 | if (prog_id) { |
119 | fprintf(fp, " "); | |
120 | bpf_dump_prog_info(fp, prog_id); | |
121 | } | |
c7272ca7 | 122 | } |