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
, __u32 ifindex
,
52 bool generic
, bool drv
, bool offload
)
54 struct bpf_cfg_in cfg
= {
55 .type
= BPF_PROG_TYPE_XDP
,
59 struct xdp_req xdp
= {
66 cfg
.ifindex
= ifindex
;
70 xdp
.flags
|= XDP_FLAGS_UPDATE_IF_NOEXIST
;
72 xdp
.flags
|= XDP_FLAGS_SKB_MODE
;
74 xdp
.flags
|= XDP_FLAGS_DRV_MODE
;
76 xdp
.flags
|= XDP_FLAGS_HW_MODE
;
79 if (strcmp(**argv
, "none") == 0 ||
80 strcmp(**argv
, "off") == 0)
81 return xdp_delete(&xdp
);
84 if (bpf_parse_and_load_common(&cfg
, &bpf_cb_ops
, &xdp
))
92 static void xdp_dump_json(struct rtattr
*tb
[IFLA_XDP_MAX
+ 1])
97 mode
= rta_getattr_u8(tb
[IFLA_XDP_ATTACHED
]);
98 if (tb
[IFLA_XDP_PROG_ID
])
99 prog_id
= rta_getattr_u32(tb
[IFLA_XDP_PROG_ID
]);
101 open_json_object("xdp");
102 print_uint(PRINT_JSON
, "mode", NULL
, mode
);
104 bpf_dump_prog_info(NULL
, prog_id
);
108 void xdp_dump(FILE *fp
, struct rtattr
*xdp
, bool link
, bool details
)
110 struct rtattr
*tb
[IFLA_XDP_MAX
+ 1];
114 parse_rtattr_nested(tb
, IFLA_XDP_MAX
, xdp
);
116 if (!tb
[IFLA_XDP_ATTACHED
])
119 mode
= rta_getattr_u8(tb
[IFLA_XDP_ATTACHED
]);
120 if (mode
== XDP_ATTACHED_NONE
)
122 else if (is_json_context())
123 return details
? (void)0 : xdp_dump_json(tb
);
124 else if (details
&& link
)
125 fprintf(fp
, "%s prog/xdp", _SL_
);
126 else if (mode
== XDP_ATTACHED_DRV
)
128 else if (mode
== XDP_ATTACHED_SKB
)
129 fprintf(fp
, "xdpgeneric");
130 else if (mode
== XDP_ATTACHED_HW
)
131 fprintf(fp
, "xdpoffload");
133 fprintf(fp
, "xdp[%u]", mode
);
135 if (tb
[IFLA_XDP_PROG_ID
])
136 prog_id
= rta_getattr_u32(tb
[IFLA_XDP_PROG_ID
]);
138 if (prog_id
&& !link
)
139 fprintf(fp
, "/id:%u", prog_id
);
146 bpf_dump_prog_info(fp
, prog_id
);