2 * iplink_xdp.c XDP program loader
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.
9 * Authors: Daniel Borkmann <daniel@iogearbox.net>
15 #include <linux/bpf.h>
19 #include "ip_common.h"
24 struct iplink_req
*req
;
28 static void xdp_ebpf_cb(void *raw
, int fd
, const char *annotation
)
30 struct xdp_req
*xdp
= raw
;
31 struct iplink_req
*req
= xdp
->req
;
32 struct rtattr
*xdp_attr
;
34 xdp_attr
= addattr_nest(&req
->n
, sizeof(*req
), IFLA_XDP
);
35 addattr32(&req
->n
, sizeof(*req
), IFLA_XDP_FD
, fd
);
37 addattr32(&req
->n
, sizeof(*req
), IFLA_XDP_FLAGS
, xdp
->flags
);
38 addattr_nest_end(&req
->n
, xdp_attr
);
41 static const struct bpf_cfg_ops bpf_cb_ops
= {
42 .ebpf_cb
= xdp_ebpf_cb
,
45 static int xdp_delete(struct xdp_req
*xdp
)
47 xdp_ebpf_cb(xdp
, -1, NULL
);
51 int xdp_parse(int *argc
, char ***argv
, struct iplink_req
*req
, bool generic
,
52 bool drv
, bool offload
)
54 struct bpf_cfg_in cfg
= {
58 struct xdp_req xdp
= {
63 xdp
.flags
|= XDP_FLAGS_UPDATE_IF_NOEXIST
;
65 xdp
.flags
|= XDP_FLAGS_SKB_MODE
;
67 xdp
.flags
|= XDP_FLAGS_DRV_MODE
;
69 xdp
.flags
|= XDP_FLAGS_HW_MODE
;
72 if (strcmp(**argv
, "none") == 0 ||
73 strcmp(**argv
, "off") == 0)
74 return xdp_delete(&xdp
);
77 if (bpf_parse_common(BPF_PROG_TYPE_XDP
, &cfg
, &bpf_cb_ops
, &xdp
))
85 void xdp_dump(FILE *fp
, struct rtattr
*xdp
)
87 struct rtattr
*tb
[IFLA_XDP_MAX
+ 1];
90 parse_rtattr_nested(tb
, IFLA_XDP_MAX
, xdp
);
92 if (!tb
[IFLA_XDP_ATTACHED
])
95 mode
= rta_getattr_u8(tb
[IFLA_XDP_ATTACHED
]);
96 if (is_json_context()) {
97 print_uint(PRINT_JSON
, "attached", NULL
, mode
);
99 if (mode
== XDP_ATTACHED_NONE
)
101 else if (mode
== XDP_ATTACHED_DRV
)
103 else if (mode
== XDP_ATTACHED_SKB
)
104 fprintf(fp
, "xdpgeneric");
105 else if (mode
== XDP_ATTACHED_HW
)
106 fprintf(fp
, "xdpoffload");
108 fprintf(fp
, "xdp[%u]", mode
);
111 if (tb
[IFLA_XDP_PROG_ID
])
112 print_uint(PRINT_ANY
, "prog_id", "/id:%u",
113 rta_getattr_u32(tb
[IFLA_XDP_PROG_ID
]));
115 print_string(PRINT_FP
, NULL
, "%c", " ");