From patchwork Fri Feb 1 21:42:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maciej Fijalkowski X-Patchwork-Id: 1035219 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="vA3oKvq+"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43rrLx4ZJRz9sBZ for ; Sat, 2 Feb 2019 08:48:09 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726705AbfBAVsC (ORCPT ); Fri, 1 Feb 2019 16:48:02 -0500 Received: from mail-lj1-f194.google.com ([209.85.208.194]:43916 "EHLO mail-lj1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726696AbfBAVsB (ORCPT ); Fri, 1 Feb 2019 16:48:01 -0500 Received: by mail-lj1-f194.google.com with SMTP id q2-v6so7028389lji.10 for ; Fri, 01 Feb 2019 13:47:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=JnXm8bCbN5E4tU2utl1gLBZ2y0vvQ26MXJmNKL8u7OE=; b=vA3oKvq+EBzPDMj8MmVlqN5K3UBo1flJSEb1/9/EESCESwTQvert/lzfJS0VqVBVXc RC/zLHHLWzLdXO9pWYuicFve6E6IqeM5fHXkicz9qRt0GkavCq6IIETr1oBGQDVmrL4O tuj7HUMhwHyLX/myPyZ41UaGW/bIh8BWdndW3OEWtRtkS4AXZfSG24U+BOUe2yBSXZTh aSeXikrZ3dNo3efexiW+CS1Jdh+yTQ9eFUg3Nv00DONKUfCaEl09V4HcNOMczcwkOsCk KyQrOc2FIqhIXm2LT5zo+JAQwKGOS2OMgdclDSpfTC4VmQwg/OKXI0FT4hkbn557SZh6 JDYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=JnXm8bCbN5E4tU2utl1gLBZ2y0vvQ26MXJmNKL8u7OE=; b=WtJ4/exUJVDTE/zRNZlWCFIxIXVG29FRw4i3YOOhjFu5s0SXYv3vMef2hqjoSxWHOv K/R654xpCj3/UWm+SFgXW+A83Yk4H5dN8b/wQcNI0lZKNoPXW5IKys80nCaqz5Io3wQr 83vSfObvoC3/Nextkgu4whCCHJXqXcWnidPaPG675yGrj7Ka2ijLY4YF2IiBtHPS2S9D 6YNx6T8cFY9s646VkRqfSHaAEOsM7FuqtsO0vF7u95FHD6BQ6KxxkqzmMhE0e4JeI44f CeuXHoq07naTX6McJyxdfM0sryiFchBuAwA+7fv/x9yQdXVac0L9x9zXZnhTYFcw8xam tqAg== X-Gm-Message-State: AJcUukchBDYQGUgE2K2VejuPAB410OVQr+qoaZ500HJU07++EPuWF/pj xIZ7hWUfTjS8E3Pub8g+hJo= X-Google-Smtp-Source: ALg8bN5ePcy4kjhK5t1CykVNh6l52YwaOTJYFJXrbArjcMRrlVDMlEv8I6eyeehkQeDOiYSIckNvCg== X-Received: by 2002:a2e:6503:: with SMTP id z3-v6mr32875059ljb.153.1549057678446; Fri, 01 Feb 2019 13:47:58 -0800 (PST) Received: from localhost.localdomain (host-185-93-94-63.ip-point.pl. [185.93.94.63]) by smtp.gmail.com with ESMTPSA id d24-v6sm1456213ljg.2.2019.02.01.13.47.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 01 Feb 2019 13:47:57 -0800 (PST) From: Maciej Fijalkowski X-Google-Original-From: Maciej Fijalkowski To: daniel@iogearbox.net, ast@kernel.org Cc: netdev@vger.kernel.org, jakub.kicinski@netronome.com, brouer@redhat.com, john.fastabend@gmail.com Subject: [PATCH bpf-next v6 7/8] libbpf: Add a support for getting xdp prog id on ifindex Date: Fri, 1 Feb 2019 22:42:29 +0100 Message-Id: <20190201214230.1441-8-maciej.fijalkowski@intel.com> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20190201214230.1441-1-maciej.fijalkowski@intel.com> References: <20190201214230.1441-1-maciej.fijalkowski@intel.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 Reviewed-by: Jakub Kicinski --- tools/lib/bpf/libbpf.h | 1 + tools/lib/bpf/libbpf.map | 1 + tools/lib/bpf/netlink.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 931be6f3408c..43c77e98df6f 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -317,6 +317,7 @@ LIBBPF_API int bpf_prog_load(const char *file, enum bpf_prog_type type, struct bpf_object **pobj, int *prog_fd); LIBBPF_API int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags); +LIBBPF_API int bpf_get_link_xdp_id(int ifindex, __u32 *prog_id, __u32 flags); enum bpf_perf_event_ret { LIBBPF_PERF_EVENT_DONE = 0, diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index 43ba9bb8d24b..62c680fb13d1 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -132,4 +132,5 @@ LIBBPF_0.0.2 { bpf_probe_prog_type; bpf_map_lookup_elem_flags; bpf_object__find_map_fd_by_name; + bpf_get_link_xdp_id; } LIBBPF_0.0.1; 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 @@ typedef int (*__dump_nlmsg_t)(struct nlmsghdr *nlmsg, libbpf_dump_nlmsg_t, void *cookie); +struct xdp_id_md { + int ifindex; + __u32 flags; + __u32 id; +}; + int libbpf_netlink_open(__u32 *nl_pid) { struct sockaddr_nl sa; @@ -196,6 +202,85 @@ static int __dump_link_nlmsg(struct nlmsghdr *nlh, return dump_link_nlmsg(cookie, ifi, tb); } +static unsigned char get_xdp_id_attr(unsigned char mode, __u32 flags) +{ + if (mode != XDP_ATTACHED_MULTI) + return IFLA_XDP_PROG_ID; + if (flags & XDP_FLAGS_DRV_MODE) + return IFLA_XDP_DRV_PROG_ID; + if (flags & XDP_FLAGS_HW_MODE) + return IFLA_XDP_HW_PROG_ID; + if (flags & XDP_FLAGS_SKB_MODE) + return IFLA_XDP_SKB_PROG_ID; + + return IFLA_XDP_UNSPEC; +} + +static int get_xdp_id(void *cookie, void *msg, struct nlattr **tb) +{ + struct nlattr *xdp_tb[IFLA_XDP_MAX + 1]; + struct xdp_id_md *xdp_id = cookie; + struct ifinfomsg *ifinfo = msg; + unsigned char mode, xdp_attr; + int ret; + + if (xdp_id->ifindex && xdp_id->ifindex != ifinfo->ifi_index) + return 0; + + if (!tb[IFLA_XDP]) + return 0; + + ret = libbpf_nla_parse_nested(xdp_tb, IFLA_XDP_MAX, tb[IFLA_XDP], NULL); + if (ret) + return ret; + + if (!xdp_tb[IFLA_XDP_ATTACHED]) + return 0; + + mode = libbpf_nla_getattr_u8(xdp_tb[IFLA_XDP_ATTACHED]); + if (mode == XDP_ATTACHED_NONE) + return 0; + + xdp_attr = get_xdp_id_attr(mode, xdp_id->flags); + if (!xdp_attr || !xdp_tb[xdp_attr]) + return 0; + + xdp_id->id = libbpf_nla_getattr_u32(xdp_tb[xdp_attr]); + + return 0; +} + +int bpf_get_link_xdp_id(int ifindex, __u32 *prog_id, __u32 flags) +{ + struct xdp_id_md xdp_id = {}; + int sock, ret; + __u32 nl_pid; + __u32 mask; + + if (flags & ~XDP_FLAGS_MASK) + return -EINVAL; + + /* Check whether the single {HW,DRV,SKB} mode is set */ + flags &= (XDP_FLAGS_SKB_MODE | XDP_FLAGS_DRV_MODE | XDP_FLAGS_HW_MODE); + mask = flags - 1; + if (flags && flags & mask) + return -EINVAL; + + sock = libbpf_netlink_open(&nl_pid); + if (sock < 0) + return sock; + + xdp_id.ifindex = ifindex; + xdp_id.flags = flags; + + ret = libbpf_nl_get_link(sock, nl_pid, get_xdp_id, &xdp_id); + if (!ret) + *prog_id = xdp_id.id; + + close(sock); + return ret; +} + int libbpf_nl_get_link(int sock, unsigned int nl_pid, libbpf_dump_nlmsg_t dump_link_nlmsg, void *cookie) {