From patchwork Fri Nov 9 16:21:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 995646 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=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="wS+u4NUH"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42s55H5J6rz9sC7 for ; Sat, 10 Nov 2018 03:21:55 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728485AbeKJCDJ (ORCPT ); Fri, 9 Nov 2018 21:03:09 -0500 Received: from mail-qk1-f201.google.com ([209.85.222.201]:49184 "EHLO mail-qk1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728475AbeKJCDJ (ORCPT ); Fri, 9 Nov 2018 21:03:09 -0500 Received: by mail-qk1-f201.google.com with SMTP id c7so3892224qkg.16 for ; Fri, 09 Nov 2018 08:21:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=ORL5j8b/m1OmB7Hasq8yWBseIa8g/+0VcfbWrTQqk8U=; b=wS+u4NUHQ9zdR0MzC2zq5mBzO4PEzamz4hqT28B+BK/b19xT7RFxtO+0ssMiDqu/aj GCL6LndQBoOqTOYXF35O4EIfSxReFm0THpQtV3bt5N/94TWfHZ9zsEmFaC9ra9ClagIO VyifckZkA0A3myNvTowW1XgJzLWpT4OUTxt/S5L7Uy2KKmZ4GYb3WB39JMP+TrNuMCLX nX3HEJVZMzVJln4IQz47snK996gOrIzO/KCUb736SFCSf5E+lUYhdOwCaukEJqkNuugM ROhffIIOxzhbnma1ZZLYj+xHCvT36vjt/kKopNK9I2beVjaGM/0ee3B25LnXiKcOE3Vl McGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ORL5j8b/m1OmB7Hasq8yWBseIa8g/+0VcfbWrTQqk8U=; b=hNcy5PeXhxzHm+kTiTpm7AmbhEpoeBOHkr80Yoig6XP0cEyx15f3x1pZCG0RD56uNk zbPnLxszA1xtx14Z4Sldd9BZl/IKIVYlv0b4YavYn/qdNdxd5rN44ul8zBHI187c9xoU eyUOvzH01ZTA+VZWzNZQ3QvpW/2imxDyr9Xrg96TtH3rcvfBKk3m50suSuMSem6Vev+T 5NuUAVuGxpKWtINYjGpTI9wuzcpETDCZU7ZAQWDhanLMaMo4PYmSA+GWrhdqISC5muhC /UEZAHDaK5USadlz9OKJEWRva8OM7G7QZFUnz4KCRCMO3q3VXzVSLP3ViPcVFYQXMdyG iUvQ== X-Gm-Message-State: AGRZ1gItV6kSqr8Sb25IzHwK2dMkQroD67eoM2DG3mkC67sePuT/l1Lv 52h26dEmYEEf3X6pBE3zSTrg9v+uarcuq8VG9gJgcvQuRrNZa8hPK/2daj33vZ/9dhVxNAlDSaI A/pAU9BDtmOfWn/yistd5H2n08GRE7pJXAQ5EEjS1UiVF8v30a5YDuQ== X-Google-Smtp-Source: AJdET5cD7V97O6WARSYY4LRcReAydT4qaVmPXa9WsV9DfCCSIwjM4oQSViiqUR0TVBhsr4yPHDp77bI= X-Received: by 2002:ac8:2288:: with SMTP id f8mr6115192qta.6.1541780512901; Fri, 09 Nov 2018 08:21:52 -0800 (PST) Date: Fri, 9 Nov 2018 08:21:40 -0800 In-Reply-To: <20181109162146.78019-1-sdf@google.com> Message-Id: <20181109162146.78019-2-sdf@google.com> Mime-Version: 1.0 References: <20181109162146.78019-1-sdf@google.com> X-Mailer: git-send-email 2.19.1.930.g4563a0d9d0-goog Subject: [PATCH v5 bpf-next 1/7] selftests/bpf: rename flow dissector section to flow_dissector From: Stanislav Fomichev To: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, shuah@kernel.org, jakub.kicinski@netronome.com, quentin.monnet@netronome.com Cc: guro@fb.com, jiong.wang@netronome.com, sdf@google.com, bhole_prashant_q7@lab.ntt.co.jp, john.fastabend@gmail.com, jbenc@redhat.com, treeze.taeung@gmail.com, yhs@fb.com, osk@fb.com, sandipan@linux.vnet.ibm.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Makes it compatible with the logic that derives program type from section name in libbpf_prog_type_by_name. Signed-off-by: Stanislav Fomichev --- tools/testing/selftests/bpf/bpf_flow.c | 2 +- tools/testing/selftests/bpf/test_flow_dissector.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/bpf/bpf_flow.c b/tools/testing/selftests/bpf/bpf_flow.c index 107350a7821d..b9798f558ca7 100644 --- a/tools/testing/selftests/bpf/bpf_flow.c +++ b/tools/testing/selftests/bpf/bpf_flow.c @@ -116,7 +116,7 @@ static __always_inline int parse_eth_proto(struct __sk_buff *skb, __be16 proto) return BPF_DROP; } -SEC("dissect") +SEC("flow_dissector") int _dissect(struct __sk_buff *skb) { if (!skb->vlan_present) diff --git a/tools/testing/selftests/bpf/test_flow_dissector.sh b/tools/testing/selftests/bpf/test_flow_dissector.sh index c0fb073b5eab..d23d4da66b83 100755 --- a/tools/testing/selftests/bpf/test_flow_dissector.sh +++ b/tools/testing/selftests/bpf/test_flow_dissector.sh @@ -59,7 +59,7 @@ else fi # Attach BPF program -./flow_dissector_load -p bpf_flow.o -s dissect +./flow_dissector_load -p bpf_flow.o -s flow_dissector # Setup tc qdisc add dev lo ingress From patchwork Fri Nov 9 16:21:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 995647 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=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="Acj42z5z"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42s55L02tpz9sC7 for ; Sat, 10 Nov 2018 03:21:58 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728501AbeKJCDL (ORCPT ); Fri, 9 Nov 2018 21:03:11 -0500 Received: from mail-pg1-f202.google.com ([209.85.215.202]:56483 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728489AbeKJCDL (ORCPT ); Fri, 9 Nov 2018 21:03:11 -0500 Received: by mail-pg1-f202.google.com with SMTP id s141-v6so1451529pgs.23 for ; Fri, 09 Nov 2018 08:21:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=+9HDmDzintyxt4YQ61JsuKbu1XcTRIbO4Y4axXT9GtE=; b=Acj42z5z58oqQ398dTFQ5qZNV5FIMQJuf2+dShPqwuhRwq+w2WOgV/yFywSSR6HVg3 LzHf1ZEMe+cMA04ErXKMoXF12BK3PkAOtzrj7doTFK6y67J/QrOpGhdeYdXH+wHPOgHg GB/7gvxjI1xkZJlQrwnUAFXrxepNvoTM2OhCCfw2Sl4nXBuUZrxsPlZQEXltwVLde7lR lzZmotaul5+wy/hQxSdzMilu+wFG28o9baMsMUcJpZSHBYXpxSQ/wgujR3RKTA6/VTYP zRWfrzEmpwhbdeCIKffvTDvcw26WujA4yS3f0Bad/3iJEiAv5ofYj1PHJUpt5Vt3Ljst VvbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=+9HDmDzintyxt4YQ61JsuKbu1XcTRIbO4Y4axXT9GtE=; b=JoYNyP1aRhJjvN8lF6ah4MfNj/49zAMRw5kimxiSjNSFQ6CKSpEALGVee6SBFweDbk vdJx80zwZCCJ/Wlk3E//p4gK39spl/hOrKNUN7RsS44n2zAtfyCn1n1gEn3O1GXj3lRB sP4YJmmX0BJ+Jpbvk18Ng0DtYUrm1QDVOT6gFR4F3oGncwi2BdsPUSzFXqwMeKy5Y+Qq uCSR+UZed3c9BqvRivY8D5AE6b8mHAlRgMpbZTg+9h08fT0TnLdc5fwxy1cW3xUGh8QX Y0ew9xM+iSWtD6KAZAS148+CVWDDiS+bSoHq1sMJQ+zXdqqvS6lCykdMkLj6dSLYE/nl x0rA== X-Gm-Message-State: AGRZ1gID5CeQjTV7t72zawyOm67otMyRRBnOwiwtz96FLwBYHqEbf/37 3VQUi/wLcykvUsx0zc91D+XhjrskF88qPPxmJ2HwkppM3XzrDKRuBM+ZSr+/Koo36Im4joEhVuy z0kk+LP6jgCx+binxWDWlcGbFtQqeGhbX0wDJU4Nb7iG0pzbINRRokQ== X-Google-Smtp-Source: AJdET5fcXQh7WcnDKwu5pYDlEfCKWPLdGVLGkVEcvw643xA+WASV2dCeXyTX8VcIAb1GBGqngGogAZo= X-Received: by 2002:a17:902:1ab:: with SMTP id b40-v6mr115356plb.148.1541780515006; Fri, 09 Nov 2018 08:21:55 -0800 (PST) Date: Fri, 9 Nov 2018 08:21:41 -0800 In-Reply-To: <20181109162146.78019-1-sdf@google.com> Message-Id: <20181109162146.78019-3-sdf@google.com> Mime-Version: 1.0 References: <20181109162146.78019-1-sdf@google.com> X-Mailer: git-send-email 2.19.1.930.g4563a0d9d0-goog Subject: [PATCH v5 bpf-next 2/7] libbpf: cleanup after partial failure in bpf_object__pin From: Stanislav Fomichev To: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, shuah@kernel.org, jakub.kicinski@netronome.com, quentin.monnet@netronome.com Cc: guro@fb.com, jiong.wang@netronome.com, sdf@google.com, bhole_prashant_q7@lab.ntt.co.jp, john.fastabend@gmail.com, jbenc@redhat.com, treeze.taeung@gmail.com, yhs@fb.com, osk@fb.com, sandipan@linux.vnet.ibm.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org bpftool will use bpf_object__pin in the next commits to pin all programs and maps from the file; in case of a partial failure, we need to get back to the clean state (undo previous program/map pins). As part of a cleanup, I've added and exported separate routines to pin all maps (bpf_object__pin_maps) and progs (bpf_object__pin_programs) of an object. Signed-off-by: Stanislav Fomichev Signed-off-by: Martin KaFai Lau --- tools/lib/bpf/libbpf.c | 324 ++++++++++++++++++++++++++++++++++++++--- tools/lib/bpf/libbpf.h | 18 +++ 2 files changed, 319 insertions(+), 23 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index d6e62e90e8d4..341008f47c8a 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -1699,6 +1699,34 @@ int bpf_program__pin_instance(struct bpf_program *prog, const char *path, return 0; } +int bpf_program__unpin_instance(struct bpf_program *prog, const char *path, + int instance) +{ + int err; + + err = check_path(path); + if (err) + return err; + + if (prog == NULL) { + pr_warning("invalid program pointer\n"); + return -EINVAL; + } + + if (instance < 0 || instance >= prog->instances.nr) { + pr_warning("invalid prog instance %d of prog %s (max %d)\n", + instance, prog->section_name, prog->instances.nr); + return -EINVAL; + } + + err = unlink(path); + if (err != 0) + return -errno; + pr_debug("unpinned program '%s'\n", path); + + return 0; +} + static int make_dir(const char *path) { char *cp, errmsg[STRERR_BUFSIZE]; @@ -1737,6 +1765,64 @@ int bpf_program__pin(struct bpf_program *prog, const char *path) if (err) return err; + for (i = 0; i < prog->instances.nr; i++) { + char buf[PATH_MAX]; + int len; + + len = snprintf(buf, PATH_MAX, "%s/%d", path, i); + if (len < 0) { + err = -EINVAL; + goto err_unpin; + } else if (len >= PATH_MAX) { + err = -ENAMETOOLONG; + goto err_unpin; + } + + err = bpf_program__pin_instance(prog, buf, i); + if (err) + goto err_unpin; + } + + return 0; + +err_unpin: + for (i = i - 1; i >= 0; i--) { + char buf[PATH_MAX]; + int len; + + len = snprintf(buf, PATH_MAX, "%s/%d", path, i); + if (len < 0) + continue; + else if (len >= PATH_MAX) + continue; + + bpf_program__unpin_instance(prog, buf, i); + } + + rmdir(path); + + return err; +} + +int bpf_program__unpin(struct bpf_program *prog, const char *path) +{ + int i, err; + + err = check_path(path); + if (err) + return err; + + if (prog == NULL) { + pr_warning("invalid program pointer\n"); + return -EINVAL; + } + + if (prog->instances.nr <= 0) { + pr_warning("no instances of prog %s to pin\n", + prog->section_name); + return -EINVAL; + } + for (i = 0; i < prog->instances.nr; i++) { char buf[PATH_MAX]; int len; @@ -1747,11 +1833,15 @@ int bpf_program__pin(struct bpf_program *prog, const char *path) else if (len >= PATH_MAX) return -ENAMETOOLONG; - err = bpf_program__pin_instance(prog, buf, i); + err = bpf_program__unpin_instance(prog, buf, i); if (err) return err; } + err = rmdir(path); + if (err) + return -errno; + return 0; } @@ -1776,12 +1866,33 @@ int bpf_map__pin(struct bpf_map *map, const char *path) } pr_debug("pinned map '%s'\n", path); + return 0; } -int bpf_object__pin(struct bpf_object *obj, const char *path) +int bpf_map__unpin(struct bpf_map *map, const char *path) +{ + int err; + + err = check_path(path); + if (err) + return err; + + if (map == NULL) { + pr_warning("invalid map pointer\n"); + return -EINVAL; + } + + err = unlink(path); + if (err != 0) + return -errno; + pr_debug("unpinned map '%s'\n", path); + + return 0; +} + +int bpf_object__pin_maps(struct bpf_object *obj, const char *path) { - struct bpf_program *prog; struct bpf_map *map; int err; @@ -1797,6 +1908,53 @@ int bpf_object__pin(struct bpf_object *obj, const char *path) if (err) return err; + bpf_map__for_each(map, obj) { + char buf[PATH_MAX]; + int len; + + len = snprintf(buf, PATH_MAX, "%s/%s", path, + bpf_map__name(map)); + if (len < 0) { + err = -EINVAL; + goto err_unpin_maps; + } else if (len >= PATH_MAX) { + err = -ENAMETOOLONG; + goto err_unpin_maps; + } + + err = bpf_map__pin(map, buf); + if (err) + goto err_unpin_maps; + } + + return 0; + +err_unpin_maps: + while ((map = bpf_map__prev(map, obj))) { + char buf[PATH_MAX]; + int len; + + len = snprintf(buf, PATH_MAX, "%s/%s", path, + bpf_map__name(map)); + if (len < 0) + continue; + else if (len >= PATH_MAX) + continue; + + bpf_map__unpin(map, buf); + } + + return err; +} + +int bpf_object__unpin_maps(struct bpf_object *obj, const char *path) +{ + struct bpf_map *map; + int err; + + if (!obj) + return -ENOENT; + bpf_map__for_each(map, obj) { char buf[PATH_MAX]; int len; @@ -1808,11 +1966,78 @@ int bpf_object__pin(struct bpf_object *obj, const char *path) else if (len >= PATH_MAX) return -ENAMETOOLONG; - err = bpf_map__pin(map, buf); + err = bpf_map__unpin(map, buf); if (err) return err; } + return 0; +} + +int bpf_object__pin_programs(struct bpf_object *obj, const char *path) +{ + struct bpf_program *prog; + int err; + + if (!obj) + return -ENOENT; + + if (!obj->loaded) { + pr_warning("object not yet loaded; load it first\n"); + return -ENOENT; + } + + err = make_dir(path); + if (err) + return err; + + bpf_object__for_each_program(prog, obj) { + char buf[PATH_MAX]; + int len; + + len = snprintf(buf, PATH_MAX, "%s/%s", path, + prog->section_name); + if (len < 0) { + err = -EINVAL; + goto err_unpin_programs; + } else if (len >= PATH_MAX) { + err = -ENAMETOOLONG; + goto err_unpin_programs; + } + + err = bpf_program__pin(prog, buf); + if (err) + goto err_unpin_programs; + } + + return 0; + +err_unpin_programs: + while ((prog = bpf_program__prev(prog, obj))) { + char buf[PATH_MAX]; + int len; + + len = snprintf(buf, PATH_MAX, "%s/%s", path, + prog->section_name); + if (len < 0) + continue; + else if (len >= PATH_MAX) + continue; + + bpf_program__unpin(prog, buf); + } + + return err; +} + +int bpf_object__unpin_programs(struct bpf_object *obj, const char *path) +{ + struct bpf_program *prog; + int err; + + if (!obj) + return -ENOENT; + bpf_object__for_each_program(prog, obj) { char buf[PATH_MAX]; int len; @@ -1824,7 +2049,7 @@ int bpf_object__pin(struct bpf_object *obj, const char *path) else if (len >= PATH_MAX) return -ENAMETOOLONG; - err = bpf_program__pin(prog, buf); + err = bpf_program__unpin(prog, buf); if (err) return err; } @@ -1832,6 +2057,23 @@ int bpf_object__pin(struct bpf_object *obj, const char *path) return 0; } +int bpf_object__pin(struct bpf_object *obj, const char *path) +{ + int err; + + err = bpf_object__pin_maps(obj, path); + if (err) + return err; + + err = bpf_object__pin_programs(obj, path); + if (err) { + bpf_object__unpin_maps(obj, path); + return err; + } + + return 0; +} + void bpf_object__close(struct bpf_object *obj) { size_t i; @@ -1918,23 +2160,20 @@ void *bpf_object__priv(struct bpf_object *obj) } static struct bpf_program * -__bpf_program__next(struct bpf_program *prev, struct bpf_object *obj) +__bpf_program__iter(struct bpf_program *p, struct bpf_object *obj, int i) { - size_t idx; + ssize_t idx; if (!obj->programs) return NULL; - /* First handler */ - if (prev == NULL) - return &obj->programs[0]; - if (prev->obj != obj) { + if (p->obj != obj) { pr_warning("error: program handler doesn't match object\n"); return NULL; } - idx = (prev - obj->programs) + 1; - if (idx >= obj->nr_programs) + idx = (p - obj->programs) + i; + if (idx >= obj->nr_programs || idx < 0) return NULL; return &obj->programs[idx]; } @@ -1944,8 +2183,29 @@ bpf_program__next(struct bpf_program *prev, struct bpf_object *obj) { struct bpf_program *prog = prev; + if (prev == NULL) + return obj->programs; + do { - prog = __bpf_program__next(prog, obj); + prog = __bpf_program__iter(prog, obj, 1); + } while (prog && bpf_program__is_function_storage(prog, obj)); + + return prog; +} + +struct bpf_program * +bpf_program__prev(struct bpf_program *next, struct bpf_object *obj) +{ + struct bpf_program *prog = next; + + if (next == NULL) { + if (!obj->nr_programs) + return NULL; + return obj->programs + obj->nr_programs - 1; + } + + do { + prog = __bpf_program__iter(prog, obj, -1); } while (prog && bpf_program__is_function_storage(prog, obj)); return prog; @@ -2272,10 +2532,10 @@ void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex) map->map_ifindex = ifindex; } -struct bpf_map * -bpf_map__next(struct bpf_map *prev, struct bpf_object *obj) +static struct bpf_map * +__bpf_map__iter(struct bpf_map *m, struct bpf_object *obj, int i) { - size_t idx; + ssize_t idx; struct bpf_map *s, *e; if (!obj || !obj->maps) @@ -2284,21 +2544,39 @@ bpf_map__next(struct bpf_map *prev, struct bpf_object *obj) s = obj->maps; e = obj->maps + obj->nr_maps; - if (prev == NULL) - return s; - - if ((prev < s) || (prev >= e)) { + if ((m < s) || (m >= e)) { pr_warning("error in %s: map handler doesn't belong to object\n", __func__); return NULL; } - idx = (prev - obj->maps) + 1; - if (idx >= obj->nr_maps) + idx = (m - obj->maps) + i; + if (idx >= obj->nr_maps || idx < 0) return NULL; return &obj->maps[idx]; } +struct bpf_map * +bpf_map__next(struct bpf_map *prev, struct bpf_object *obj) +{ + if (prev == NULL) + return obj->maps; + + return __bpf_map__iter(prev, obj, 1); +} + +struct bpf_map * +bpf_map__prev(struct bpf_map *next, struct bpf_object *obj) +{ + if (next == NULL) { + if (!obj->nr_maps) + return NULL; + return obj->maps + obj->nr_maps - 1; + } + + return __bpf_map__iter(next, obj, -1); +} + struct bpf_map * bpf_object__find_map_by_name(struct bpf_object *obj, const char *name) { diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 1f3468dad8b2..b1686a787102 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -71,6 +71,13 @@ struct bpf_object *__bpf_object__open_xattr(struct bpf_object_open_attr *attr, LIBBPF_API struct bpf_object *bpf_object__open_buffer(void *obj_buf, size_t obj_buf_sz, const char *name); +LIBBPF_API int bpf_object__pin_maps(struct bpf_object *obj, const char *path); +LIBBPF_API int bpf_object__unpin_maps(struct bpf_object *obj, + const char *path); +LIBBPF_API int bpf_object__pin_programs(struct bpf_object *obj, + const char *path); +LIBBPF_API int bpf_object__unpin_programs(struct bpf_object *obj, + const char *path); LIBBPF_API int bpf_object__pin(struct bpf_object *object, const char *path); LIBBPF_API void bpf_object__close(struct bpf_object *object); @@ -112,6 +119,9 @@ LIBBPF_API struct bpf_program *bpf_program__next(struct bpf_program *prog, (pos) != NULL; \ (pos) = bpf_program__next((pos), (obj))) +LIBBPF_API struct bpf_program *bpf_program__prev(struct bpf_program *prog, + struct bpf_object *obj); + typedef void (*bpf_program_clear_priv_t)(struct bpf_program *, void *); @@ -131,7 +141,11 @@ LIBBPF_API int bpf_program__fd(struct bpf_program *prog); LIBBPF_API int bpf_program__pin_instance(struct bpf_program *prog, const char *path, int instance); +LIBBPF_API int bpf_program__unpin_instance(struct bpf_program *prog, + const char *path, + int instance); LIBBPF_API int bpf_program__pin(struct bpf_program *prog, const char *path); +LIBBPF_API int bpf_program__unpin(struct bpf_program *prog, const char *path); LIBBPF_API void bpf_program__unload(struct bpf_program *prog); struct bpf_insn; @@ -260,6 +274,9 @@ bpf_map__next(struct bpf_map *map, struct bpf_object *obj); (pos) != NULL; \ (pos) = bpf_map__next((pos), (obj))) +LIBBPF_API struct bpf_map * +bpf_map__prev(struct bpf_map *map, struct bpf_object *obj); + LIBBPF_API int bpf_map__fd(struct bpf_map *map); LIBBPF_API const struct bpf_map_def *bpf_map__def(struct bpf_map *map); LIBBPF_API const char *bpf_map__name(struct bpf_map *map); @@ -274,6 +291,7 @@ LIBBPF_API int bpf_map__reuse_fd(struct bpf_map *map, int fd); LIBBPF_API bool bpf_map__is_offload_neutral(struct bpf_map *map); LIBBPF_API void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex); LIBBPF_API int bpf_map__pin(struct bpf_map *map, const char *path); +LIBBPF_API int bpf_map__unpin(struct bpf_map *map, const char *path); LIBBPF_API long libbpf_get_error(const void *ptr); From patchwork Fri Nov 9 16:21:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 995648 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=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="kzW9w7UU"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42s55N0MYbz9sBk for ; Sat, 10 Nov 2018 03:22:00 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728506AbeKJCDO (ORCPT ); Fri, 9 Nov 2018 21:03:14 -0500 Received: from mail-qk1-f201.google.com ([209.85.222.201]:43575 "EHLO mail-qk1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728393AbeKJCDN (ORCPT ); Fri, 9 Nov 2018 21:03:13 -0500 Received: by mail-qk1-f201.google.com with SMTP id z126so3880309qka.10 for ; Fri, 09 Nov 2018 08:21:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=XyjY0EaWfTZCnQr753PMBCujgbURQNPI0esE9bXMifQ=; b=kzW9w7UULbex46PYqFb7/u8iVxhzE+jfy7QG/vLtkShwAZgzIKqlpVyAo7gorubivf H9lma8FiKitVlp/aAvOQ+pxugjNk+/ezd9Amfj6BKxkzAhfLE/mEnEd9B01Su4Cgrbm+ adlECu9XugIvKm/rm109ghuv9mWv8gIvJq8FbQXzn+sDSIsX/WzujykL4MLBm5Ei9zzE er300RcbPOQPPylnlv19aPxUvmz3rBcAkr5FoGOSq79wMQQ6gBfRZvBohbuVIVL/4rIt vnPymZco9svorqRjwP4lVh4LW97duWWiGQmBVp/u8EQwNnxwKK4zsucy57YvvKpE3upn vJkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=XyjY0EaWfTZCnQr753PMBCujgbURQNPI0esE9bXMifQ=; b=k2aBbMEQGJvyrxL/rRnlFp+BoqligDbjphCUzyTRxwQy0VBHmqFg3BzHHpz0p+k7Yg dqHzXIPW6ThHBcaUzbyI7tugpoYQo2gbZGzhCfJTnfNsJAm4uK7da5Tu9Ie9kxlsYMWW 0yGlreV9/3c2H0/JHP59/rENkB4A6XOzVW0TpWZl6qbr4rTuxJlbKdB665D3PEedefMY Bbgd/ts3KGzEpMB68kxrxQBELHmvxVHcbvq4oeiV93pAvl98ywyxPmBPdYnCNaZHRYen NfRO2cSgaILVqnJ6jYrMm79XSc1Lhz2Z4BZH7ej5NgN2O2ASfq03i9zByAbaay7h6zOD +Ang== X-Gm-Message-State: AGRZ1gIhEt8/8AYp76nI6k/ekgOH7kWAJlAmPnQokbT6IvX83waqnNx8 aUqdP7I9JqWxJlKz37XKUNz/rm0LcIKzh5mYKmve3lcwKnoi3xfM5VovyCxJpXmQpJ6kUF+XHq3 pozqXF2cSeac8jMN/fR1c1pW3GOgWFzJXF01MvHiOJrNUpDjf6zVXdQ== X-Google-Smtp-Source: AJdET5eQ+QN6wp1HpsaD21GTZ+Sw8U0pYOMgRE4tyxNRgVGr4uUd317Sl/q9EnKW/yX5Iyzo5JsSpwE= X-Received: by 2002:a37:11c1:: with SMTP id 62mr1341933qkr.54.1541780517492; Fri, 09 Nov 2018 08:21:57 -0800 (PST) Date: Fri, 9 Nov 2018 08:21:42 -0800 In-Reply-To: <20181109162146.78019-1-sdf@google.com> Message-Id: <20181109162146.78019-4-sdf@google.com> Mime-Version: 1.0 References: <20181109162146.78019-1-sdf@google.com> X-Mailer: git-send-email 2.19.1.930.g4563a0d9d0-goog Subject: [PATCH v5 bpf-next 3/7] libbpf: bpf_program__pin: add special case for instances.nr == 1 From: Stanislav Fomichev To: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, shuah@kernel.org, jakub.kicinski@netronome.com, quentin.monnet@netronome.com Cc: guro@fb.com, jiong.wang@netronome.com, sdf@google.com, bhole_prashant_q7@lab.ntt.co.jp, john.fastabend@gmail.com, jbenc@redhat.com, treeze.taeung@gmail.com, yhs@fb.com, osk@fb.com, sandipan@linux.vnet.ibm.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When bpf_program has only one instance, don't create a subdirectory with per-instance pin files (/0). Instead, just create a single pin file for that single instance. This simplifies object pinning by not creating unnecessary subdirectories. This can potentially break existing users that depend on the case where '/0' is always created. However, I couldn't find any serious usage of bpf_program__pin inside the kernel tree and I suppose there should be none outside. Signed-off-by: Stanislav Fomichev --- tools/lib/bpf/libbpf.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 341008f47c8a..97ce9f214002 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -1761,6 +1761,11 @@ int bpf_program__pin(struct bpf_program *prog, const char *path) return -EINVAL; } + if (prog->instances.nr == 1) { + /* don't create subdirs when pinning single instance */ + return bpf_program__pin_instance(prog, path, 0); + } + err = make_dir(path); if (err) return err; @@ -1823,6 +1828,11 @@ int bpf_program__unpin(struct bpf_program *prog, const char *path) return -EINVAL; } + if (prog->instances.nr == 1) { + /* don't create subdirs when pinning single instance */ + return bpf_program__unpin_instance(prog, path, 0); + } + for (i = 0; i < prog->instances.nr; i++) { char buf[PATH_MAX]; int len; From patchwork Fri Nov 9 16:21:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 995649 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=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="XUUOTFGV"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42s55P6TTmz9sBk for ; Sat, 10 Nov 2018 03:22:01 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728519AbeKJCDQ (ORCPT ); Fri, 9 Nov 2018 21:03:16 -0500 Received: from mail-pg1-f202.google.com ([209.85.215.202]:50006 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728393AbeKJCDP (ORCPT ); Fri, 9 Nov 2018 21:03:15 -0500 Received: by mail-pg1-f202.google.com with SMTP id a18so1469068pga.16 for ; Fri, 09 Nov 2018 08:22:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=gddtQnFXho8NV4kgxCBew2hJsxrC9rWfQZi/NxObeqs=; b=XUUOTFGV0B7UHDJbsdWisfnBlirbRTvlRNMx0WqVf+qA+er2i/zbSecvHE/1wV8gVv spWlWtKCgJkN7RHhtPoQvgGC7Ww+vzkb6bWfmOT0YoAdtOss2lxb+Qo+/XAzaiLt7G4e YQK1y0s1QryMxX39JZXHstNYhigyMCqN/mLLx+Ml8L+xgtTKGVLKDcqx0nQ4UGgR2BfY zFjd0n0yVTrmqVJJTvIz0fZ66cCO6dJ+NBP8nSEQx57oApPoL/oqK0/tSjbRplo7Nz8w W9i6aPW88fUYovjHMMM9emrecH1lxcVeJQwdrR6h4E5+SPcEd105priCyTO5WxMEvhaF bAVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=gddtQnFXho8NV4kgxCBew2hJsxrC9rWfQZi/NxObeqs=; b=jFECxsXjR9hhdh6SqIIj0HZ5rykiztto8KUQxs36X/GAetlVFodeZrzeOvl9sPuu/r J/hU+7FAAEG5ujs2lwPykQ4XOEIlMCos9UB1Hvlr/fatNV2nYnzhT+ALY8ROS7J+4riE lhES0bDxeXL1alCsTkJCXpBjE3Vu5L/Jiprkx9J0dKv67yG/LMq7jp3j+o9iq6PL6CcZ O1rCUcrB4uZQecGApfzMKaVtBolIm0uoBEN2p9WLiI2AfVgoM4Fmbs1cytsPLyxCvTs7 10T4QLMYNNv2hE2ERJ0N3MFHoua9WWfD7Z93ssZ/HhRdq4TZZFN0sQpu1yk7915pV06d Yk4w== X-Gm-Message-State: AGRZ1gJj6qo7gHNQ3nl7wX4fj0pMKxIUt+BXZWpZ3DpX4TJQC3tIN00j a4nLx0KBl8fwnTeRD4V06P39oLZKuJcGE2s8s4bQw7uetgAFGrwPFDpSvu/nQqoPRRJlXaXkAUu IpypaoYFVzO+GHDilw8iUZmSEFvZeivEu+l0ymrYnW0v8b8iNSyqCow== X-Google-Smtp-Source: AJdET5dEl4m1jqWvAGoHFicrqmF4qvF3PVxNaQQyjPDcjyiL14UcZHNJO5waVjIkL9LB6yDNqoi+AFE= X-Received: by 2002:a62:830b:: with SMTP id h11-v6mr76734pfe.30.1541780519611; Fri, 09 Nov 2018 08:21:59 -0800 (PST) Date: Fri, 9 Nov 2018 08:21:43 -0800 In-Reply-To: <20181109162146.78019-1-sdf@google.com> Message-Id: <20181109162146.78019-5-sdf@google.com> Mime-Version: 1.0 References: <20181109162146.78019-1-sdf@google.com> X-Mailer: git-send-email 2.19.1.930.g4563a0d9d0-goog Subject: [PATCH v5 bpf-next 4/7] libbpf: add internal pin_name From: Stanislav Fomichev To: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, shuah@kernel.org, jakub.kicinski@netronome.com, quentin.monnet@netronome.com Cc: guro@fb.com, jiong.wang@netronome.com, sdf@google.com, bhole_prashant_q7@lab.ntt.co.jp, john.fastabend@gmail.com, jbenc@redhat.com, treeze.taeung@gmail.com, yhs@fb.com, osk@fb.com, sandipan@linux.vnet.ibm.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org pin_name is the same as section_name where '/' is replaced by '_'. bpf_object__pin_programs is converted to use pin_name to avoid the situation where section_name would require creating another subdirectory for a pin (as, for example, when calling bpf_object__pin_programs for programs in sections like "cgroup/connect6"). Signed-off-by: Stanislav Fomichev --- tools/lib/bpf/libbpf.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 97ce9f214002..e827542ffa3a 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -124,6 +124,10 @@ struct bpf_program { char *name; int prog_ifindex; char *section_name; + /* section_name with / replaced by _; makes recursive pinning + * in bpf_object__pin_programs easier + */ + char *pin_name; struct bpf_insn *insns; size_t insns_cnt, main_prog_cnt; enum bpf_prog_type type; @@ -253,6 +257,7 @@ static void bpf_program__exit(struct bpf_program *prog) bpf_program__unload(prog); zfree(&prog->name); zfree(&prog->section_name); + zfree(&prog->pin_name); zfree(&prog->insns); zfree(&prog->reloc_desc); @@ -261,6 +266,17 @@ static void bpf_program__exit(struct bpf_program *prog) prog->idx = -1; } +static char *__bpf_program__pin_name(struct bpf_program *prog) +{ + char *name, *p; + + name = p = strdup(prog->section_name); + while ((p = strchr(p, '/'))) + *p = '_'; + + return name; +} + static int bpf_program__init(void *data, size_t size, char *section_name, int idx, struct bpf_program *prog) @@ -279,6 +295,13 @@ bpf_program__init(void *data, size_t size, char *section_name, int idx, goto errout; } + prog->pin_name = __bpf_program__pin_name(prog); + if (!prog->pin_name) { + pr_warning("failed to alloc pin name for prog under section(%d) %s\n", + idx, section_name); + goto errout; + } + prog->insns = malloc(size); if (!prog->insns) { pr_warning("failed to alloc insns for prog under section %s\n", @@ -2006,7 +2029,7 @@ int bpf_object__pin_programs(struct bpf_object *obj, const char *path) int len; len = snprintf(buf, PATH_MAX, "%s/%s", path, - prog->section_name); + prog->pin_name); if (len < 0) { err = -EINVAL; goto err_unpin_programs; @@ -2028,7 +2051,7 @@ int bpf_object__pin_programs(struct bpf_object *obj, const char *path) int len; len = snprintf(buf, PATH_MAX, "%s/%s", path, - prog->section_name); + prog->pin_name); if (len < 0) continue; else if (len >= PATH_MAX) @@ -2053,7 +2076,7 @@ int bpf_object__unpin_programs(struct bpf_object *obj, const char *path) int len; len = snprintf(buf, PATH_MAX, "%s/%s", path, - prog->section_name); + prog->pin_name); if (len < 0) return -EINVAL; else if (len >= PATH_MAX) From patchwork Fri Nov 9 16:21:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 995650 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=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="c4z63kOk"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42s55S2gWjz9sB7 for ; Sat, 10 Nov 2018 03:22:04 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728530AbeKJCDS (ORCPT ); Fri, 9 Nov 2018 21:03:18 -0500 Received: from mail-pf1-f201.google.com ([209.85.210.201]:56286 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728393AbeKJCDR (ORCPT ); Fri, 9 Nov 2018 21:03:17 -0500 Received: by mail-pf1-f201.google.com with SMTP id x5-v6so1803690pfn.22 for ; Fri, 09 Nov 2018 08:22:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Eahx8uva81jd6Vx1ZCIdE/ob+oYFp5+d4jnXzOM5o4c=; b=c4z63kOkstirSAy5n9/m0EEQNQ1gNdFE7W116BgVeWhSKHG+nVZ/b+/T9FmeIWtFGY ccj0PvbQpx7QCTkh0NAKzCksyRPaaGIGoexLFJTpc51nhn9hHxd8SDfNBXyx/5Bn/rBq VWF1lLa2nUK+QLhs2pSJ475fT2pbZTt84IYDpYGyJ+7uvNWBJNILJusUpupNoBJ+JsXP srSf/6JahI6xtpw/JMu3b+0RPWzNGSe6O9EWcRfrL6uLnsZLkFg16oPguYtinwtxZeDx 0gCT+07EIE7jAZpKnsWb4CN12SW9hWF9mv515wVdxXbW7NcZ08+1RRoSKPNngHr3d0BR c4bQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Eahx8uva81jd6Vx1ZCIdE/ob+oYFp5+d4jnXzOM5o4c=; b=N1TKFIc734/90N8JufCRiDKSZddtzExvmW2Q7TGp+Z7wFjLJvKel+yACimyvS/sQ17 yMqq5tpf1eeakRqSus0uLIozIPAhjVSh7xapKeXEhD68Bmc/X1BMmPGfDmcCX00NhTvt 6TAmx69xdZpQ22VHocYwknSMdMVjs4vV3fAZntxn3vu0U4GseAjhecpgpoXDO8v7eRsR WZ7Nhk+5xkwR5h/RQzhQxgWOjdEeKJjbQBIbfGKL8tS7gudYiIqQt9T34osQi1DyXkUV tXTMryyaSmzBYheNeBNJQqPOgFyo7fkzuMehbSuXq+qN4Po7s7bjVbSUzv8QVV0/mrOH GUCg== X-Gm-Message-State: AGRZ1gKIKY3CCWrXVCERC8PBksSa94uhPZDMpnEjk8HJbZTUGIEBtH2Q GYccimCiMvStd5y7XjwvQI0uNCdwVkcB58CKJUgFawOz3XruL6irvmy4AFKWLIcY4mZU9B/na9w 8SR71peCGgQXVqzU0Bs28BT1Ct4u9vGKm0TX6HfQqJyFqgBhRwGWRzA== X-Google-Smtp-Source: AJdET5ecwz2H/8eeYBipMy+3iLKKH3IHA4JhZnjU2BzVdWPeult8ZvVGq4x2TR6iZ93Y/gU702oUAuc= X-Received: by 2002:aa7:8647:: with SMTP id a7-v6mr141793pfo.18.1541780521963; Fri, 09 Nov 2018 08:22:01 -0800 (PST) Date: Fri, 9 Nov 2018 08:21:44 -0800 In-Reply-To: <20181109162146.78019-1-sdf@google.com> Message-Id: <20181109162146.78019-6-sdf@google.com> Mime-Version: 1.0 References: <20181109162146.78019-1-sdf@google.com> X-Mailer: git-send-email 2.19.1.930.g4563a0d9d0-goog Subject: [PATCH v5 bpf-next 5/7] bpftool: add loadall command From: Stanislav Fomichev To: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, shuah@kernel.org, jakub.kicinski@netronome.com, quentin.monnet@netronome.com Cc: guro@fb.com, jiong.wang@netronome.com, sdf@google.com, bhole_prashant_q7@lab.ntt.co.jp, john.fastabend@gmail.com, jbenc@redhat.com, treeze.taeung@gmail.com, yhs@fb.com, osk@fb.com, sandipan@linux.vnet.ibm.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch adds new *loadall* command which slightly differs from the existing *load*. *load* command loads all programs from the obj file, but pins only the first programs. *loadall* pins all programs from the obj file under specified directory. The intended usecase is flow_dissector, where we want to load a bunch of progs, pin them all and after that construct a jump table. Signed-off-by: Stanislav Fomichev Acked-by: Jakub Kicinski --- .../bpftool/Documentation/bpftool-prog.rst | 14 ++-- tools/bpf/bpftool/bash-completion/bpftool | 4 +- tools/bpf/bpftool/common.c | 31 ++++---- tools/bpf/bpftool/main.h | 1 + tools/bpf/bpftool/prog.c | 74 ++++++++++++++----- 5 files changed, 81 insertions(+), 43 deletions(-) diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index ac4e904b10fb..984d125c507a 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst @@ -15,7 +15,8 @@ SYNOPSIS *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } *COMMANDS* := - { **show** | **list** | **dump xlated** | **dump jited** | **pin** | **load** | **help** } + { **show** | **list** | **dump xlated** | **dump jited** | **pin** | **load** + | **loadall** | **help** } MAP COMMANDS ============= @@ -24,7 +25,7 @@ MAP COMMANDS | **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes** | **visual**}] | **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}] | **bpftool** **prog pin** *PROG* *FILE* -| **bpftool** **prog load** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] +| **bpftool** **prog { load | loadall }** *OBJ* *PATH* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] | **bpftool** **prog attach** *PROG* *ATTACH_TYPE* *MAP* | **bpftool** **prog detach** *PROG* *ATTACH_TYPE* *MAP* | **bpftool** **prog help** @@ -79,8 +80,11 @@ DESCRIPTION contain a dot character ('.'), which is reserved for future extensions of *bpffs*. - **bpftool prog load** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] - Load bpf program from binary *OBJ* and pin as *FILE*. + **bpftool prog { load | loadall }** *OBJ* *PATH* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] + Load bpf program(s) from binary *OBJ* and pin as *PATH*. + **bpftool prog load** pins only the first program from the + *OBJ* as *PATH*. **bpftool prog loadall** pins all programs + from the *OBJ* under *PATH* directory. **type** is optional, if not specified program type will be inferred from section names. By default bpftool will create new maps as declared in the ELF @@ -93,7 +97,7 @@ DESCRIPTION If **dev** *NAME* is specified program will be loaded onto given networking device (offload). - Note: *FILE* must be located in *bpffs* mount. It must not + Note: *PATH* must be located in *bpffs* mount. It must not contain a dot character ('.'), which is reserved for future extensions of *bpffs*. diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool index 3f78e6404589..780ebafb756a 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool @@ -243,7 +243,7 @@ _bpftool() # Completion depends on object and command in use case $object in prog) - if [[ $command != "load" ]]; then + if [[ $command != "load" && $command != "loadall" ]]; then case $prev in id) _bpftool_get_prog_ids @@ -309,7 +309,7 @@ _bpftool() fi return 0 ;; - load) + load|loadall) local obj if [[ ${#words[@]} -lt 6 ]]; then diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index 25af85304ebe..21ce556c15e1 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c @@ -169,34 +169,23 @@ int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type) return fd; } -int do_pin_fd(int fd, const char *name) +int mount_bpffs_for_pin(const char *name) { char err_str[ERR_MAX_LEN]; char *file; char *dir; int err = 0; - err = bpf_obj_pin(fd, name); - if (!err) - goto out; - file = malloc(strlen(name) + 1); strcpy(file, name); dir = dirname(file); - if (errno != EPERM || is_bpffs(dir)) { - p_err("can't pin the object (%s): %s", name, strerror(errno)); + if (is_bpffs(dir)) + /* nothing to do if already mounted */ goto out_free; - } - /* Attempt to mount bpffs, then retry pinning. */ err = mnt_bpffs(dir, err_str, ERR_MAX_LEN); - if (!err) { - err = bpf_obj_pin(fd, name); - if (err) - p_err("can't pin the object (%s): %s", name, - strerror(errno)); - } else { + if (err) { err_str[ERR_MAX_LEN - 1] = '\0'; p_err("can't mount BPF file system to pin the object (%s): %s", name, err_str); @@ -204,10 +193,20 @@ int do_pin_fd(int fd, const char *name) out_free: free(file); -out: return err; } +int do_pin_fd(int fd, const char *name) +{ + int err; + + err = mount_bpffs_for_pin(name); + if (err) + return err; + + return bpf_obj_pin(fd, name); +} + int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) { unsigned int id; diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h index 28322ace2856..1383824c9baf 100644 --- a/tools/bpf/bpftool/main.h +++ b/tools/bpf/bpftool/main.h @@ -129,6 +129,7 @@ const char *get_fd_type_name(enum bpf_obj_type type); char *get_fdinfo(int fd, const char *key); int open_obj_pinned(char *path); int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type); +int mount_bpffs_for_pin(const char *name); int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)); int do_pin_fd(int fd, const char *name); diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 5302ee282409..3abfee5533e6 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -792,15 +792,16 @@ static int do_detach(int argc, char **argv) jsonw_null(json_wtr); return 0; } -static int do_load(int argc, char **argv) + +static int load_with_options(int argc, char **argv, bool first_prog_only) { enum bpf_attach_type expected_attach_type; struct bpf_object_open_attr attr = { .prog_type = BPF_PROG_TYPE_UNSPEC, }; struct map_replace *map_replace = NULL; + struct bpf_program *prog = NULL, *pos; unsigned int old_map_fds = 0; - struct bpf_program *prog; struct bpf_object *obj; struct bpf_map *map; const char *pinfile; @@ -918,26 +919,25 @@ static int do_load(int argc, char **argv) goto err_free_reuse_maps; } - prog = bpf_program__next(NULL, obj); - if (!prog) { - p_err("object file doesn't contain any bpf program"); - goto err_close_obj; - } + bpf_object__for_each_program(pos, obj) { + enum bpf_prog_type prog_type = attr.prog_type; - bpf_program__set_ifindex(prog, ifindex); - if (attr.prog_type == BPF_PROG_TYPE_UNSPEC) { - const char *sec_name = bpf_program__title(prog, false); + if (attr.prog_type == BPF_PROG_TYPE_UNSPEC) { + const char *sec_name = bpf_program__title(pos, false); - err = libbpf_prog_type_by_name(sec_name, &attr.prog_type, - &expected_attach_type); - if (err < 0) { - p_err("failed to guess program type based on section name %s\n", - sec_name); - goto err_close_obj; + err = libbpf_prog_type_by_name(sec_name, &prog_type, + &expected_attach_type); + if (err < 0) { + p_err("failed to guess program type based on section name %s\n", + sec_name); + goto err_close_obj; + } } + + bpf_program__set_ifindex(pos, ifindex); + bpf_program__set_type(pos, prog_type); + bpf_program__set_expected_attach_type(pos, expected_attach_type); } - bpf_program__set_type(prog, attr.prog_type); - bpf_program__set_expected_attach_type(prog, expected_attach_type); qsort(map_replace, old_map_fds, sizeof(*map_replace), map_replace_compar); @@ -1001,9 +1001,31 @@ static int do_load(int argc, char **argv) goto err_close_obj; } - if (do_pin_fd(bpf_program__fd(prog), pinfile)) + err = mount_bpffs_for_pin(pinfile); + if (err) goto err_close_obj; + if (first_prog_only) { + prog = bpf_program__next(NULL, obj); + if (!prog) { + p_err("object file doesn't contain any bpf program"); + goto err_close_obj; + } + + err = bpf_obj_pin(bpf_program__fd(prog), pinfile); + if (err) { + p_err("failed to pin program %s", + bpf_program__title(prog, false)); + goto err_close_obj; + } + } else { + err = bpf_object__pin_programs(obj, pinfile); + if (err) { + p_err("failed to pin all programs"); + goto err_close_obj; + } + } + if (json_output) jsonw_null(json_wtr); @@ -1023,6 +1045,16 @@ static int do_load(int argc, char **argv) return -1; } +static int do_load(int argc, char **argv) +{ + return load_with_options(argc, argv, true); +} + +static int do_loadall(int argc, char **argv) +{ + return load_with_options(argc, argv, false); +} + static int do_help(int argc, char **argv) { if (json_output) { @@ -1035,7 +1067,8 @@ static int do_help(int argc, char **argv) " %s %s dump xlated PROG [{ file FILE | opcodes | visual }]\n" " %s %s dump jited PROG [{ file FILE | opcodes }]\n" " %s %s pin PROG FILE\n" - " %s %s load OBJ FILE [type TYPE] [dev NAME] \\\n" + " %s %s { load | loadall } OBJ PATH \\\n" + " [type TYPE] [dev NAME] \\\n" " [map { idx IDX | name NAME } MAP]\n" " %s %s attach PROG ATTACH_TYPE MAP\n" " %s %s detach PROG ATTACH_TYPE MAP\n" @@ -1067,6 +1100,7 @@ static const struct cmd cmds[] = { { "dump", do_dump }, { "pin", do_pin }, { "load", do_load }, + { "loadall", do_loadall }, { "attach", do_attach }, { "detach", do_detach }, { 0 } From patchwork Fri Nov 9 16:21:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 995651 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=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="YypxGcPZ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42s55W12ycz9sC7 for ; Sat, 10 Nov 2018 03:22:07 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728539AbeKJCDU (ORCPT ); Fri, 9 Nov 2018 21:03:20 -0500 Received: from mail-io1-f74.google.com ([209.85.166.74]:54687 "EHLO mail-io1-f74.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728533AbeKJCDU (ORCPT ); Fri, 9 Nov 2018 21:03:20 -0500 Received: by mail-io1-f74.google.com with SMTP id q26-v6so2666895ioi.21 for ; Fri, 09 Nov 2018 08:22:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=omwxHf5jMMNd3V1X+Ctrwq7jQeeI7VFLwXOIdYMYMx0=; b=YypxGcPZDw7eVfAIjo0jh4S4Ts11AAboDNDkIbrDxm37G4GBu93fgYsYaDp/ZRkgOx VYeMtkv/MviBQMmFPtHSomdIApYN2sE1TjaVqr1rDeZsVci9GRxd70yypUw5s3RWijSW msDu4UheUyiLuz+5lNXOPD7SnW86girIyD5oM6fTVo785CqFT3XTxPQDh0qLqebFu49t pj/rSuQ/0VgYxIwzqd0foufSN/PlA+7XqBkLwQ4tECf1MNNiZHK0NMpopevWWyK/KuUJ 5NV6dtXWkzhWzCF831LGZPO3jHBkJQFjJc833fJB/afwxdghAlms5/Qft2tEKxCbA94K INrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=omwxHf5jMMNd3V1X+Ctrwq7jQeeI7VFLwXOIdYMYMx0=; b=gPkN4e3CvvqJWtPqmyu2ypSIh80h2RzY+uPV5NtPQo8xdUAsoDvCOatftrWuILrDB8 /CH/jTLs0YBaSQiC3BGQk5YrhqilNyRUFhAQrO5MHVIDuiMSzm/RuKJqc/73MIei+Qfi AkLK8QBtY2vxmoUAilm049ORUrI/HRw6rx7mrsVpwgNdVW8XaF58ez5c4pcaEdXoUKjP KSNKz6XbBZ83Ic2DnftAqIWElLNCXQq2JIjUWwHGrY+lmwBFxBHkr2vr3SPQwX/j+KCl 6GxfGkuqjUDYWs4qgYZXfHXi6/uSNfacKJE9pPnL/v7rFd71SPWg8KkWv7H3higWeEHz Jrag== X-Gm-Message-State: AGRZ1gIKI5qhxk7HO1hYkFtlh49auMlN+MpoAKLIhoZk0C3c5dDBovH0 Bu10yPFgyMr39HCMYjJJvGlzdBwRpmdxxo/iaCuwgx6DFEch0klpvhBLHjhvAb09lWTOJRrPpSO 4LVp4Mj/SCxSqemqNYQ9C9ejlZ+kCFxgY9g5wlLl4n+/w3cQpKMsbNQ== X-Google-Smtp-Source: AJdET5ebBoVayoI6GwJBBHT8oIEoar6zjR8N/iusSpzXUsyfz5ZXRcnL5tD7WPHVjIeqD6uHiR4++l0= X-Received: by 2002:a24:2c91:: with SMTP id i139-v6mr2535991iti.40.1541780524314; Fri, 09 Nov 2018 08:22:04 -0800 (PST) Date: Fri, 9 Nov 2018 08:21:45 -0800 In-Reply-To: <20181109162146.78019-1-sdf@google.com> Message-Id: <20181109162146.78019-7-sdf@google.com> Mime-Version: 1.0 References: <20181109162146.78019-1-sdf@google.com> X-Mailer: git-send-email 2.19.1.930.g4563a0d9d0-goog Subject: [PATCH v5 bpf-next 6/7] bpftool: add pinmaps argument to the load/loadall From: Stanislav Fomichev To: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, shuah@kernel.org, jakub.kicinski@netronome.com, quentin.monnet@netronome.com Cc: guro@fb.com, jiong.wang@netronome.com, sdf@google.com, bhole_prashant_q7@lab.ntt.co.jp, john.fastabend@gmail.com, jbenc@redhat.com, treeze.taeung@gmail.com, yhs@fb.com, osk@fb.com, sandipan@linux.vnet.ibm.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This new additional argument lets users pin all maps from the object at specified path. Signed-off-by: Stanislav Fomichev Acked-by: Jakub Kicinski --- .../bpftool/Documentation/bpftool-prog.rst | 4 +++- tools/bpf/bpftool/bash-completion/bpftool | 3 ++- tools/bpf/bpftool/prog.c | 24 ++++++++++++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index 984d125c507a..15e9172f7e55 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst @@ -80,7 +80,7 @@ DESCRIPTION contain a dot character ('.'), which is reserved for future extensions of *bpffs*. - **bpftool prog { load | loadall }** *OBJ* *PATH* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] + **bpftool prog { load | loadall }** *OBJ* *PATH* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] [**pinmaps** *MAP_DIR*] Load bpf program(s) from binary *OBJ* and pin as *PATH*. **bpftool prog load** pins only the first program from the *OBJ* as *PATH*. **bpftool prog loadall** pins all programs @@ -96,6 +96,8 @@ DESCRIPTION use, referring to it by **id** or through a **pinned** file. If **dev** *NAME* is specified program will be loaded onto given networking device (offload). + Optional **pinmaps** argument can be provided to pin all + maps under *MAP_DIR* directory. Note: *PATH* must be located in *bpffs* mount. It must not contain a dot character ('.'), which is reserved for future diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool index 780ebafb756a..a05d0071f39f 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool @@ -346,7 +346,7 @@ _bpftool() _bpftool_get_map_ids return 0 ;; - pinned) + pinned|pinmaps) _filedir return 0 ;; @@ -358,6 +358,7 @@ _bpftool() COMPREPLY=( $( compgen -W "map" -- "$cur" ) ) _bpftool_once_attr 'type' _bpftool_once_attr 'dev' + _bpftool_once_attr 'pinmaps' return 0 ;; esac diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 3abfee5533e6..4bd6ad19fc05 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -802,6 +802,7 @@ static int load_with_options(int argc, char **argv, bool first_prog_only) struct map_replace *map_replace = NULL; struct bpf_program *prog = NULL, *pos; unsigned int old_map_fds = 0; + const char *pinmaps = NULL; struct bpf_object *obj; struct bpf_map *map; const char *pinfile; @@ -906,6 +907,13 @@ static int load_with_options(int argc, char **argv, bool first_prog_only) goto err_free_reuse_maps; } NEXT_ARG(); + } else if (is_prefix(*argv, "pinmaps")) { + NEXT_ARG(); + + if (!REQ_ARGS(1)) + goto err_free_reuse_maps; + + pinmaps = GET_ARG(); } else { p_err("expected no more arguments, 'type', 'map' or 'dev', got: '%s'?", *argv); @@ -1026,6 +1034,14 @@ static int load_with_options(int argc, char **argv, bool first_prog_only) } } + if (pinmaps) { + err = bpf_object__pin_maps(obj, pinmaps); + if (err) { + p_err("failed to pin all maps"); + goto err_unpin; + } + } + if (json_output) jsonw_null(json_wtr); @@ -1036,6 +1052,11 @@ static int load_with_options(int argc, char **argv, bool first_prog_only) return 0; +err_unpin: + if (first_prog_only) + unlink(pinfile); + else + bpf_object__unpin_programs(obj, pinfile); err_close_obj: bpf_object__close(obj); err_free_reuse_maps: @@ -1069,7 +1090,8 @@ static int do_help(int argc, char **argv) " %s %s pin PROG FILE\n" " %s %s { load | loadall } OBJ PATH \\\n" " [type TYPE] [dev NAME] \\\n" - " [map { idx IDX | name NAME } MAP]\n" + " [map { idx IDX | name NAME } MAP]\\\n" + " [pinmaps MAP_DIR]\n" " %s %s attach PROG ATTACH_TYPE MAP\n" " %s %s detach PROG ATTACH_TYPE MAP\n" " %s %s help\n" From patchwork Fri Nov 9 16:21:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 995652 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=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="FxDjhk3e"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42s55Y5xPNz9sC7 for ; Sat, 10 Nov 2018 03:22:09 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728550AbeKJCDX (ORCPT ); Fri, 9 Nov 2018 21:03:23 -0500 Received: from mail-yw1-f73.google.com ([209.85.161.73]:56861 "EHLO mail-yw1-f73.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728533AbeKJCDX (ORCPT ); Fri, 9 Nov 2018 21:03:23 -0500 Received: by mail-yw1-f73.google.com with SMTP id p81-v6so2533172ywc.23 for ; Fri, 09 Nov 2018 08:22:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc:content-transfer-encoding; bh=MIUB/UGjK9omjDVZkc3TatjwdaHrc9j+wxoV1sKHcxE=; b=FxDjhk3exrdETorVqMTsGxfrZ910jIRojwzG2Nq1BiPClbRU3/xoxyi4Eu2hMEpwS6 E7UGEjW9thu6E3oJhTXGyQCgyM7c9buoD9i2zWfOa/3C6vXpf9kDKFTGBO4Qw0SXvQ8c nGrcJtV1DeB09i/4HhGRsBM2zmzdhb8EQGivKASUKIgw7Cz9svlMODxCGRrZo7+qFLlw D1GCRwZV/FztrdYFqsxTENegWcomcoFIRTxh0/LIE6ijNSOnM1PFKkc90AvSoHXCdamZ XbOGuUN64Xcm1ZckOUxl0S8uYPM9BRMRZLJLWVdJ42gjFWiD78UNZAMszX+fmjiWKYPq 1eKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc:content-transfer-encoding; bh=MIUB/UGjK9omjDVZkc3TatjwdaHrc9j+wxoV1sKHcxE=; b=mjdbjXRHBvqVqKnFJZwEuUUtOuk9e3EtPug/1UeVyqC3rojX3IY13g2bCbu1GjM8gF v3J1croADI6cpJTlrkgHPGvRd5vWLRaxRPcr8BS9D8tvPhN0Fd7CHSqeA7bMDGlIYCQS P0htIykUqnUxDvjkd33hxlbS+STXBZCd6/lqHvAp/RpmdjTbXXYnT1RmnY7CIaQ1/6IA AxSc88PINpni/TGhmqGG9HydZJv1iq7rcpbDxgwzxTHcUSsJsvXS7th6ZiE3ubpTPMgf QrxXXRcUE3JxmM5zx5qdMsi+Oj1byOGSc1by9yS6Du/pATsWKbqt2A5NZ4ir0TwssD/D XGvA== X-Gm-Message-State: AGRZ1gJ/AmLyCUVHjQEVMl3FCpXb/zky01VcgnQnw7efAApS8HxcG/7w g4s763uVmHRGiUU9VPfsUm+3VK1568vfjbGcK6j1iz4Fa47HXK76uMsWeQnmr8aJDeHUqTa0GzI cVAcfuQjFp7nQ9vcmH6+2pf4UoSMz0ATd+NSu0sKqIDjNRE5gJUCF6g== X-Google-Smtp-Source: AJdET5fdACOyYuWjIbdMHvq4vqQG3YPQzrpZZ/tbLvOKweyRIFzUjd03HPnzOj6gnkHRFKIx2qAJgls= X-Received: by 2002:a5b:305:: with SMTP id j5-v6mr4650820ybp.43.1541780526643; Fri, 09 Nov 2018 08:22:06 -0800 (PST) Date: Fri, 9 Nov 2018 08:21:46 -0800 In-Reply-To: <20181109162146.78019-1-sdf@google.com> Message-Id: <20181109162146.78019-8-sdf@google.com> Mime-Version: 1.0 References: <20181109162146.78019-1-sdf@google.com> X-Mailer: git-send-email 2.19.1.930.g4563a0d9d0-goog Subject: [PATCH v5 bpf-next 7/7] bpftool: support loading flow dissector From: Stanislav Fomichev To: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, shuah@kernel.org, jakub.kicinski@netronome.com, quentin.monnet@netronome.com Cc: guro@fb.com, jiong.wang@netronome.com, sdf@google.com, bhole_prashant_q7@lab.ntt.co.jp, john.fastabend@gmail.com, jbenc@redhat.com, treeze.taeung@gmail.com, yhs@fb.com, osk@fb.com, sandipan@linux.vnet.ibm.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This commit adds support for loading/attaching/detaching flow dissector program. When `bpftool loadall` is called with a flow_dissector prog (i.e. when the 'type flow_dissector' argument is passed), we load and pin all programs. User is responsible to construct the jump table for the tail calls. The last argument of `bpftool attach` is made optional for this use case. Example: bpftool prog load tools/testing/selftests/bpf/bpf_flow.o \ /sys/fs/bpf/flow type flow_dissector \ pinmaps /sys/fs/bpf/flow bpftool map update pinned /sys/fs/bpf/flow/jmp_table \ key 0 0 0 0 \ value pinned /sys/fs/bpf/flow/IP bpftool map update pinned /sys/fs/bpf/flow/jmp_table \ key 1 0 0 0 \ value pinned /sys/fs/bpf/flow/IPV6 bpftool map update pinned /sys/fs/bpf/flow/jmp_table \ key 2 0 0 0 \ value pinned /sys/fs/bpf/flow/IPV6OP bpftool map update pinned /sys/fs/bpf/flow/jmp_table \ key 3 0 0 0 \ value pinned /sys/fs/bpf/flow/IPV6FR bpftool map update pinned /sys/fs/bpf/flow/jmp_table \ key 4 0 0 0 \ value pinned /sys/fs/bpf/flow/MPLS bpftool map update pinned /sys/fs/bpf/flow/jmp_table \ key 5 0 0 0 \ value pinned /sys/fs/bpf/flow/VLAN bpftool prog attach pinned /sys/fs/bpf/flow/flow_dissector flow_dissector Tested by using the above lines to load the prog in the test_flow_dissector.sh selftest. Signed-off-by: Stanislav Fomichev Acked-by: Jakub Kicinski --- .../bpftool/Documentation/bpftool-prog.rst | 26 +++--- tools/bpf/bpftool/bash-completion/bpftool | 14 ++- tools/bpf/bpftool/prog.c | 85 ++++++++++--------- 3 files changed, 74 insertions(+), 51 deletions(-) diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index 15e9172f7e55..8db78ed82a71 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst @@ -26,8 +26,8 @@ MAP COMMANDS | **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}] | **bpftool** **prog pin** *PROG* *FILE* | **bpftool** **prog { load | loadall }** *OBJ* *PATH* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] -| **bpftool** **prog attach** *PROG* *ATTACH_TYPE* *MAP* -| **bpftool** **prog detach** *PROG* *ATTACH_TYPE* *MAP* +| **bpftool** **prog attach** *PROG* *ATTACH_TYPE* [*MAP*] +| **bpftool** **prog detach** *PROG* *ATTACH_TYPE* [*MAP*] | **bpftool** **prog help** | | *MAP* := { **id** *MAP_ID* | **pinned** *FILE* } @@ -40,7 +40,9 @@ MAP COMMANDS | **cgroup/bind4** | **cgroup/bind6** | **cgroup/post_bind4** | **cgroup/post_bind6** | | **cgroup/connect4** | **cgroup/connect6** | **cgroup/sendmsg4** | **cgroup/sendmsg6** | } -| *ATTACH_TYPE* := { **msg_verdict** | **skb_verdict** | **skb_parse** } +| *ATTACH_TYPE* := { +| **msg_verdict** | **skb_verdict** | **skb_parse** | **flow_dissector** +| } DESCRIPTION @@ -103,13 +105,17 @@ DESCRIPTION contain a dot character ('.'), which is reserved for future extensions of *bpffs*. - **bpftool prog attach** *PROG* *ATTACH_TYPE* *MAP* - Attach bpf program *PROG* (with type specified by *ATTACH_TYPE*) - to the map *MAP*. - - **bpftool prog detach** *PROG* *ATTACH_TYPE* *MAP* - Detach bpf program *PROG* (with type specified by *ATTACH_TYPE*) - from the map *MAP*. + **bpftool prog attach** *PROG* *ATTACH_TYPE* [*MAP*] + Attach bpf program *PROG* (with type specified by + *ATTACH_TYPE*). Most *ATTACH_TYPEs* require a *MAP* + parameter, with the exception of *flow_dissector* which is + attached to current networking name space. + + **bpftool prog detach** *PROG* *ATTACH_TYPE* [*MAP*] + Detach bpf program *PROG* (with type specified by + *ATTACH_TYPE*). Most *ATTACH_TYPEs* require a *MAP* + parameter, with the exception of *flow_dissector* which is + detached from the current networking name space. **bpftool prog help** Print short help message. diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool index a05d0071f39f..45c2db257d2b 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool @@ -299,7 +299,8 @@ _bpftool() fi if [[ ${#words[@]} == 6 ]]; then - COMPREPLY=( $( compgen -W "msg_verdict skb_verdict skb_parse" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "msg_verdict skb_verdict \ + skb_parse flow_dissector" -- "$cur" ) ) return 0 fi @@ -338,7 +339,16 @@ _bpftool() case $prev in type) - COMPREPLY=( $( compgen -W "socket kprobe kretprobe classifier action tracepoint raw_tracepoint xdp perf_event cgroup/skb cgroup/sock cgroup/dev lwt_in lwt_out lwt_xmit lwt_seg6local sockops sk_skb sk_msg lirc_mode2 cgroup/bind4 cgroup/bind6 cgroup/connect4 cgroup/connect6 cgroup/sendmsg4 cgroup/sendmsg6 cgroup/post_bind4 cgroup/post_bind6" -- \ + COMPREPLY=( $( compgen -W "socket kprobe \ + kretprobe classifier flow_dissector \ + action tracepoint raw_tracepoint \ + xdp perf_event cgroup/skb cgroup/sock \ + cgroup/dev lwt_in lwt_out lwt_xmit \ + lwt_seg6local sockops sk_skb sk_msg \ + lirc_mode2 cgroup/bind4 cgroup/bind6 \ + cgroup/connect4 cgroup/connect6 \ + cgroup/sendmsg4 cgroup/sendmsg6 \ + cgroup/post_bind4 cgroup/post_bind6" -- \ "$cur" ) ) return 0 ;; diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 4bd6ad19fc05..9adc56e0885c 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -81,6 +81,7 @@ static const char * const attach_type_strings[] = { [BPF_SK_SKB_STREAM_PARSER] = "stream_parser", [BPF_SK_SKB_STREAM_VERDICT] = "stream_verdict", [BPF_SK_MSG_VERDICT] = "msg_verdict", + [BPF_FLOW_DISSECTOR] = "flow_dissector", [__MAX_BPF_ATTACH_TYPE] = NULL, }; @@ -721,30 +722,49 @@ int map_replace_compar(const void *p1, const void *p2) return a->idx - b->idx; } -static int do_attach(int argc, char **argv) +static int parse_attach_detach_args(int argc, char **argv, int *progfd, + enum bpf_attach_type *attach_type, + int *mapfd) { - enum bpf_attach_type attach_type; - int err, mapfd, progfd; - - if (!REQ_ARGS(5)) { - p_err("too few parameters for map attach"); + if (!REQ_ARGS(3)) return -EINVAL; - } - progfd = prog_parse_fd(&argc, &argv); - if (progfd < 0) - return progfd; + *progfd = prog_parse_fd(&argc, &argv); + if (*progfd < 0) + return *progfd; - attach_type = parse_attach_type(*argv); - if (attach_type == __MAX_BPF_ATTACH_TYPE) { - p_err("invalid attach type"); + *attach_type = parse_attach_type(*argv); + if (*attach_type == __MAX_BPF_ATTACH_TYPE) { + p_err("invalid attach/detach type"); return -EINVAL; } + + if (*attach_type == BPF_FLOW_DISSECTOR) { + *mapfd = -1; + return 0; + } + NEXT_ARG(); + if (!REQ_ARGS(2)) + return -EINVAL; + + *mapfd = map_parse_fd(&argc, &argv); + if (*mapfd < 0) + return *mapfd; + + return 0; +} - mapfd = map_parse_fd(&argc, &argv); - if (mapfd < 0) - return mapfd; +static int do_attach(int argc, char **argv) +{ + enum bpf_attach_type attach_type; + int err, progfd; + int mapfd; + + err = parse_attach_detach_args(argc, argv, + &progfd, &attach_type, &mapfd); + if (err) + return err; err = bpf_prog_attach(progfd, mapfd, attach_type, 0); if (err) { @@ -760,27 +780,13 @@ static int do_attach(int argc, char **argv) static int do_detach(int argc, char **argv) { enum bpf_attach_type attach_type; - int err, mapfd, progfd; - - if (!REQ_ARGS(5)) { - p_err("too few parameters for map detach"); - return -EINVAL; - } - - progfd = prog_parse_fd(&argc, &argv); - if (progfd < 0) - return progfd; + int err, progfd; + int mapfd; - attach_type = parse_attach_type(*argv); - if (attach_type == __MAX_BPF_ATTACH_TYPE) { - p_err("invalid attach type"); - return -EINVAL; - } - NEXT_ARG(); - - mapfd = map_parse_fd(&argc, &argv); - if (mapfd < 0) - return mapfd; + err = parse_attach_detach_args(argc, argv, + &progfd, &attach_type, &mapfd); + if (err) + return err; err = bpf_prog_detach2(progfd, mapfd, attach_type); if (err) { @@ -1092,8 +1098,8 @@ static int do_help(int argc, char **argv) " [type TYPE] [dev NAME] \\\n" " [map { idx IDX | name NAME } MAP]\\\n" " [pinmaps MAP_DIR]\n" - " %s %s attach PROG ATTACH_TYPE MAP\n" - " %s %s detach PROG ATTACH_TYPE MAP\n" + " %s %s attach PROG ATTACH_TYPE [MAP]\n" + " %s %s detach PROG ATTACH_TYPE [MAP]\n" " %s %s help\n" "\n" " " HELP_SPEC_MAP "\n" @@ -1105,7 +1111,8 @@ static int do_help(int argc, char **argv) " cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n" " cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n" " cgroup/sendmsg4 | cgroup/sendmsg6 }\n" - " ATTACH_TYPE := { msg_verdict | skb_verdict | skb_parse }\n" + " ATTACH_TYPE := { msg_verdict | skb_verdict | skb_parse |\n" + " flow_dissector }\n" " " HELP_SPEC_OPTIONS "\n" "", bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],