aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/bpf/netlink.c
diff options
context:
space:
mode:
authorMaciej Fijalkowski <maciejromanfijalkowski@gmail.com>2019-02-01 16:42:29 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2019-02-01 17:37:51 -0500
commit50db9f0731889b9f3839cab5f44163733eb44f04 (patch)
treec258a5f0eed345e022e671195b27623161ab763f /tools/lib/bpf/netlink.c
parent743e568c15860d4061202f73214c106a5bb0890b (diff)
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>
Diffstat (limited to 'tools/lib/bpf/netlink.c')
-rw-r--r--tools/lib/bpf/netlink.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
index 0ce67aea8f3b..ce3ec81b71c0 100644
--- a/tools/lib/bpf/netlink.c
+++ b/tools/lib/bpf/netlink.c
@@ -21,6 +21,12 @@
21typedef int (*__dump_nlmsg_t)(struct nlmsghdr *nlmsg, libbpf_dump_nlmsg_t, 21typedef int (*__dump_nlmsg_t)(struct nlmsghdr *nlmsg, libbpf_dump_nlmsg_t,
22 void *cookie); 22 void *cookie);
23 23
24struct xdp_id_md {
25 int ifindex;
26 __u32 flags;
27 __u32 id;
28};
29
24int libbpf_netlink_open(__u32 *nl_pid) 30int libbpf_netlink_open(__u32 *nl_pid)
25{ 31{
26 struct sockaddr_nl sa; 32 struct sockaddr_nl sa;
@@ -196,6 +202,85 @@ static int __dump_link_nlmsg(struct nlmsghdr *nlh,
196 return dump_link_nlmsg(cookie, ifi, tb); 202 return dump_link_nlmsg(cookie, ifi, tb);
197} 203}
198 204
205static 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
219static 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
253int 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
199int libbpf_nl_get_link(int sock, unsigned int nl_pid, 284int libbpf_nl_get_link(int sock, unsigned int nl_pid,
200 libbpf_dump_nlmsg_t dump_link_nlmsg, void *cookie) 285 libbpf_dump_nlmsg_t dump_link_nlmsg, void *cookie)
201{ 286{