Skip to content

Commit 50db9f0

Browse files
Maciej Fijalkowskiborkmann
authored andcommitted
libbpf: Add a support for getting xdp prog id on ifindex
Since we have a dedicated netlink attributes for xdp setup on a particular interface, it is now possible to retrieve the program id that is currently attached to the interface. The use case is targeted for sample xdp programs, which will store the program id just after loading bpf program onto iface. On shutdown, the sample will make sure that it can unload the program by querying again the iface and verifying that both program id's matches. Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent 743e568 commit 50db9f0

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

tools/lib/bpf/libbpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ LIBBPF_API int bpf_prog_load(const char *file, enum bpf_prog_type type,
317317
struct bpf_object **pobj, int *prog_fd);
318318

319319
LIBBPF_API int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags);
320+
LIBBPF_API int bpf_get_link_xdp_id(int ifindex, __u32 *prog_id, __u32 flags);
320321

321322
enum bpf_perf_event_ret {
322323
LIBBPF_PERF_EVENT_DONE = 0,

tools/lib/bpf/libbpf.map

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,5 @@ LIBBPF_0.0.2 {
132132
bpf_probe_prog_type;
133133
bpf_map_lookup_elem_flags;
134134
bpf_object__find_map_fd_by_name;
135+
bpf_get_link_xdp_id;
135136
} LIBBPF_0.0.1;

tools/lib/bpf/netlink.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
typedef int (*__dump_nlmsg_t)(struct nlmsghdr *nlmsg, libbpf_dump_nlmsg_t,
2222
void *cookie);
2323

24+
struct xdp_id_md {
25+
int ifindex;
26+
__u32 flags;
27+
__u32 id;
28+
};
29+
2430
int libbpf_netlink_open(__u32 *nl_pid)
2531
{
2632
struct sockaddr_nl sa;
@@ -196,6 +202,85 @@ static int __dump_link_nlmsg(struct nlmsghdr *nlh,
196202
return dump_link_nlmsg(cookie, ifi, tb);
197203
}
198204

205+
static unsigned char get_xdp_id_attr(unsigned char mode, __u32 flags)
206+
{
207+
if (mode != XDP_ATTACHED_MULTI)
208+
return IFLA_XDP_PROG_ID;
209+
if (flags & XDP_FLAGS_DRV_MODE)
210+
return IFLA_XDP_DRV_PROG_ID;
211+
if (flags & XDP_FLAGS_HW_MODE)
212+
return IFLA_XDP_HW_PROG_ID;
213+
if (flags & XDP_FLAGS_SKB_MODE)
214+
return IFLA_XDP_SKB_PROG_ID;
215+
216+
return IFLA_XDP_UNSPEC;
217+
}
218+
219+
static int get_xdp_id(void *cookie, void *msg, struct nlattr **tb)
220+
{
221+
struct nlattr *xdp_tb[IFLA_XDP_MAX + 1];
222+
struct xdp_id_md *xdp_id = cookie;
223+
struct ifinfomsg *ifinfo = msg;
224+
unsigned char mode, xdp_attr;
225+
int ret;
226+
227+
if (xdp_id->ifindex && xdp_id->ifindex != ifinfo->ifi_index)
228+
return 0;
229+
230+
if (!tb[IFLA_XDP])
231+
return 0;
232+
233+
ret = libbpf_nla_parse_nested(xdp_tb, IFLA_XDP_MAX, tb[IFLA_XDP], NULL);
234+
if (ret)
235+
return ret;
236+
237+
if (!xdp_tb[IFLA_XDP_ATTACHED])
238+
return 0;
239+
240+
mode = libbpf_nla_getattr_u8(xdp_tb[IFLA_XDP_ATTACHED]);
241+
if (mode == XDP_ATTACHED_NONE)
242+
return 0;
243+
244+
xdp_attr = get_xdp_id_attr(mode, xdp_id->flags);
245+
if (!xdp_attr || !xdp_tb[xdp_attr])
246+
return 0;
247+
248+
xdp_id->id = libbpf_nla_getattr_u32(xdp_tb[xdp_attr]);
249+
250+
return 0;
251+
}
252+
253+
int bpf_get_link_xdp_id(int ifindex, __u32 *prog_id, __u32 flags)
254+
{
255+
struct xdp_id_md xdp_id = {};
256+
int sock, ret;
257+
__u32 nl_pid;
258+
__u32 mask;
259+
260+
if (flags & ~XDP_FLAGS_MASK)
261+
return -EINVAL;
262+
263+
/* Check whether the single {HW,DRV,SKB} mode is set */
264+
flags &= (XDP_FLAGS_SKB_MODE | XDP_FLAGS_DRV_MODE | XDP_FLAGS_HW_MODE);
265+
mask = flags - 1;
266+
if (flags && flags & mask)
267+
return -EINVAL;
268+
269+
sock = libbpf_netlink_open(&nl_pid);
270+
if (sock < 0)
271+
return sock;
272+
273+
xdp_id.ifindex = ifindex;
274+
xdp_id.flags = flags;
275+
276+
ret = libbpf_nl_get_link(sock, nl_pid, get_xdp_id, &xdp_id);
277+
if (!ret)
278+
*prog_id = xdp_id.id;
279+
280+
close(sock);
281+
return ret;
282+
}
283+
199284
int libbpf_nl_get_link(int sock, unsigned int nl_pid,
200285
libbpf_dump_nlmsg_t dump_link_nlmsg, void *cookie)
201286
{

0 commit comments

Comments
 (0)