From patchwork Fri Nov 9 00:22:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 10675165 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7C07F1057 for ; Fri, 9 Nov 2018 00:22:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6952E2E91D for ; Fri, 9 Nov 2018 00:22:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5D6FA2E940; Fri, 9 Nov 2018 00:22:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BEFE12E91D for ; Fri, 9 Nov 2018 00:22:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727702AbeKIKAY (ORCPT ); Fri, 9 Nov 2018 05:00:24 -0500 Received: from mail-pg1-f196.google.com ([209.85.215.196]:42997 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727406AbeKIKAX (ORCPT ); Fri, 9 Nov 2018 05:00:23 -0500 Received: by mail-pg1-f196.google.com with SMTP id i4-v6so53264pgq.9 for ; Thu, 08 Nov 2018 16:22:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fomichev-me.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CXeDn/Okb5yBu53juKpA9Bi61hTkenwYsPdfGhG2e+A=; b=zN3BKhxPCziTMgCUoVEF9hX2ZzLBPChWJMiGfFwj0uWWWX3ymXkI6+1MM5cMap9azZ qk7ZiRGZeTabEAL0Z0H0ct4vnnPSQE+15DsAFG6mCwzi1MaY0EEs52O2nliKWD9R71pK iTZbj4hRfcds/bG9GReAFAGhOkSBoTR79l4MGh/LPJqtijvU48k3R4pgTMeqY89kpb14 +mjVlbGvVdUimc35ZA7+WlxiwBQksJs6HmRt3d4otQV95rM0K81x8oKW/19wjozXd0p9 x8m6d/xGJAogliSmM/5BSoy62BtyRbWwwySm/I3KfuRkBKkfKYEeqVQqSeOSB8GOgJmT XeLA== 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:mime-version:content-transfer-encoding; bh=CXeDn/Okb5yBu53juKpA9Bi61hTkenwYsPdfGhG2e+A=; b=eSg4tOtXCGMbcyW987x74wo50cR3I9x8FPxLgKUMS0yW46YGs8ANomYmU6k/9cwMqc Ixg3+kjX++qn7FbX5Z+AKYu7UsYp+3gRHDRnqhRG1ZuO79PWyh4MP4nb0dSXP6PpMtGD Ko1SNNJ8DBfUpuP2XdFveN54ogohGd4Pc+cx+89nzG8n8w8xvvtlAIbJHyGwwgXBlSLp upjW9sK/cQXS0jI3g22DGjeiWD7hNIPreKoxgkZpc+nHh5cbEnSotSQDXS2zwNx0ZqeE zcvJ0aBzBmMk8fVybGj0xWtuLSymK8gDUVWJcnhFI1rmqMunTEsdIG+ecPvj2Usv9O66 rcCQ== X-Gm-Message-State: AGRZ1gKMnwFYdGSJYx9SD3xg30kM2ri0a2WHDoTkDKKDfJWb02xeBjFm 4sN2shbQNRVub9GipZ0PqA539g== X-Google-Smtp-Source: AJdET5er10lMiOKz+zquMS87tcxYxnhtxBefPTeEoxOEm39e7AD46/CDRj6qtVzwVOg1gFxyN2vFHw== X-Received: by 2002:a63:e40c:: with SMTP id a12mr5650603pgi.28.1541722939488; Thu, 08 Nov 2018 16:22:19 -0800 (PST) Received: from mini-arch.hsd1.ca.comcast.net (c-98-210-199-22.hsd1.ca.comcast.net. [98.210.199.22]) by smtp.gmail.com with ESMTPSA id g21-v6sm4918955pgh.82.2018.11.08.16.22.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Nov 2018 16:22:18 -0800 (PST) From: Stanislav Fomichev X-Google-Original-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 Subject: [PATCH v4 bpf-next 1/7] selftests/bpf: rename flow dissector section to flow_dissector Date: Thu, 8 Nov 2018 16:22:07 -0800 Message-Id: <20181109002213.5914-2-s@fomichev.me> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181109002213.5914-1-s@fomichev.me> References: <20181109002213.5914-1-s@fomichev.me> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stanislav Fomichev 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 00:22:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 10675169 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7BCD213BF for ; Fri, 9 Nov 2018 00:22:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6914F2E94C for ; Fri, 9 Nov 2018 00:22:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 64BCE2E8FF; Fri, 9 Nov 2018 00:22:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 76ADE2E940 for ; Fri, 9 Nov 2018 00:22:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727722AbeKIKA1 (ORCPT ); Fri, 9 Nov 2018 05:00:27 -0500 Received: from mail-pf1-f196.google.com ([209.85.210.196]:42490 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727406AbeKIKAZ (ORCPT ); Fri, 9 Nov 2018 05:00:25 -0500 Received: by mail-pf1-f196.google.com with SMTP id u10-v6so58997pfn.9 for ; Thu, 08 Nov 2018 16:22:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fomichev-me.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=HJALDx151oxbCIHW7XGSqtqxh9vgP9Wc+Ltkz4aqgC4=; b=HONBsEdyQUxEKPGcLZSiwTAMeBQF5XOBUAzBi2+tp0XEMR1Q069Hyg2v1oL8xCP8B4 FhUOsUuslmUjPHeynpnafW/sovvd7TsiUHO0TFxMnXouI0VwOebkQ6uIb+qPj2OSWoTy cqTFbPZIy/jlcJpaeNltTdUNVuQ/8EssGhlfq/iPfcx4WBqg5bCHTIymBwC+ypVXWxkb t63ydWIpzZO4yquHDwwQMOvipC/0wVyaP6N1Sc/wOgWWNNLLJRmo/1iCqGtEalQ9H3HY FkazUc6E+UnnKwBqjYdsWZs7CQJA0o37wJc4xYVPily4sGzsi4Q9YNj0JKyahRl/Rby4 txsA== 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:mime-version:content-transfer-encoding; bh=HJALDx151oxbCIHW7XGSqtqxh9vgP9Wc+Ltkz4aqgC4=; b=buYxQOsAO+aVemAvaWOjgEVUOjurenFt4Rh4Ki6ft/AAITSZ2FTGCJwKPxbtS//FTL RATWObM6plPk6sTaWSYfk5Ro1cdYd5cRwCIiKi/LVx8jLc3yOD0ZVo+XI3E8N1TRPTwu E1/Cbpeodr3MKVwv14E9vocVLm4fePWvYMP00fPFDdjBAeDQxi1nAV9hqZYYugPviw6B X21pkIlwvP/qc3YujuPVH7efp/X4Wz7+qjO3l2sTatiBPN2YX1ByOrxPAAFdz+QroYWC nRLNl6PHkyUu8D/NbgGw7y+ofwp7ZKv4wtSN4N9rL5loZnzB2Gg1Cps++Dcyr3rP4LpG fang== X-Gm-Message-State: AGRZ1gLVHy0Liz4J+dRshM2W1K5ZMXWJTK09JqWFrsTdyfyq21FFfMd5 6bXQ2Zw0OxGWJZlqYZBV3OMGcg== X-Google-Smtp-Source: AJdET5eXkEzYRCDE5ZajRK02/D0scTpsBrwz+qqIs5NOGqOR+5RaOrp5KH0IvElkd3z1qFe30nS+7g== X-Received: by 2002:a63:dd58:: with SMTP id g24-v6mr5484142pgj.86.1541722941103; Thu, 08 Nov 2018 16:22:21 -0800 (PST) Received: from mini-arch.hsd1.ca.comcast.net (c-98-210-199-22.hsd1.ca.comcast.net. [98.210.199.22]) by smtp.gmail.com with ESMTPSA id g21-v6sm4918955pgh.82.2018.11.08.16.22.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Nov 2018 16:22:20 -0800 (PST) From: Stanislav Fomichev X-Google-Original-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 Subject: [PATCH v4 bpf-next 2/7] libbpf: cleanup after partial failure in bpf_object__pin Date: Thu, 8 Nov 2018 16:22:08 -0800 Message-Id: <20181109002213.5914-3-s@fomichev.me> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181109002213.5914-1-s@fomichev.me> References: <20181109002213.5914-1-s@fomichev.me> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stanislav Fomichev 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 --- tools/lib/bpf/libbpf.c | 328 ++++++++++++++++++++++++++++++++++++++--- tools/lib/bpf/libbpf.h | 18 +++ 2 files changed, 323 insertions(+), 23 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index d6e62e90e8d4..f8590490a9dd 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,55 @@ 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: + for (map = bpf_map__prev(map, obj); + map != NULL; + 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 +1968,80 @@ 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: + for (prog = bpf_program__prev(prog, obj); + prog != NULL; + 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 +2053,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 +2061,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 +2164,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 +2187,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 +2536,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 +2548,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 00:22:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 10675179 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 337A91057 for ; Fri, 9 Nov 2018 00:22:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 249CE2E8FF for ; Fri, 9 Nov 2018 00:22:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 226872E8E2; Fri, 9 Nov 2018 00:22:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BA7BB2E945 for ; Fri, 9 Nov 2018 00:22:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727529AbeKIKA1 (ORCPT ); Fri, 9 Nov 2018 05:00:27 -0500 Received: from mail-pl1-f194.google.com ([209.85.214.194]:37256 "EHLO mail-pl1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727715AbeKIKA0 (ORCPT ); Fri, 9 Nov 2018 05:00:26 -0500 Received: by mail-pl1-f194.google.com with SMTP id p6-v6so69363pll.4 for ; Thu, 08 Nov 2018 16:22:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fomichev-me.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=pWCaszsAdCBoBdg5GlrXFpzHo/aljxL3Lfvuxw9+2Oo=; b=Z6NWMNFO89U3Uo09eEv6GU+rKT/MNzLMpnbxREdb7K+exM/4B7KoakESTZjypHjQQV 8svPc9XZ+kFawHDED5PqlYMs5A+FKQsxjN9Ynjj4NX4opAPVRWqfZ1llrM8R0jMYi1q5 wwjDrN+KaGKDH1JJ/ZC1yO3MRUQZ2uc4gQr5qwxfv2Ls0SSh18UIzuY+Whth8VxXOGup omLlTArRScFq7693HjIARfP2jRywIdeMDVKkogwyScvrxVkNyBldpftN7RkjMskGsncK rYI/RdDX4C/2VILjJKhXgNl1veBISnfQ1CWWyVW28bBNy0XV/vwX/lfN5Wy1BA8nQfHY oIIA== 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:mime-version:content-transfer-encoding; bh=pWCaszsAdCBoBdg5GlrXFpzHo/aljxL3Lfvuxw9+2Oo=; b=plcs4pBlBNh7ZHZmyDCR11AnavaKcmMao98Uayezer6acsCIiKbRlJFb2Zx1bNLsvZ /U0FcM3FWkmyZP5KW4kbK3jARz4E9/YCJcPf6Asy7epZlt1pTX5YBpssUg8fbk+pbcoc MpK+K6RlXD798YAG9nK6+6VnIkPwPJo4tB7W29pyzzRpZ9uHYVBPF5tTl6o2hXCPJkUQ oykaOMDJ4rWGkv1YipeauVAKRLMC/rSO0uKeV9p3hytTiCjz4erQb1nGAsjPBsY8bF+X p6XVSjD2Kng69U7VRuGIrA0IjIR1n/VxpC49P0vJd6nLch5QWvXVVr6HznLF3APtHctd c0mQ== X-Gm-Message-State: AGRZ1gJeBWfm0v1Y+BpR6jVtsJvlzLiyTOWtweZhlOUkW3e31okKtgpi BkZwq3X4SMbK73Mj3BCLy4Y8qQ== X-Google-Smtp-Source: AJdET5e88cxDsRXn3NHtw5YytPISLtGuXEG9pRIa52IBe7QZZ6PiMEUf1/GdEBexGXLvBOS/eldL1w== X-Received: by 2002:a17:902:4324:: with SMTP id i33-v6mr6807177pld.253.1541722942621; Thu, 08 Nov 2018 16:22:22 -0800 (PST) Received: from mini-arch.hsd1.ca.comcast.net (c-98-210-199-22.hsd1.ca.comcast.net. [98.210.199.22]) by smtp.gmail.com with ESMTPSA id g21-v6sm4918955pgh.82.2018.11.08.16.22.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Nov 2018 16:22:21 -0800 (PST) From: Stanislav Fomichev X-Google-Original-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 Subject: [PATCH v4 bpf-next 3/7] libbpf: bpf_program__pin: add special case for instances.nr == 1 Date: Thu, 8 Nov 2018 16:22:09 -0800 Message-Id: <20181109002213.5914-4-s@fomichev.me> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181109002213.5914-1-s@fomichev.me> References: <20181109002213.5914-1-s@fomichev.me> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stanislav Fomichev 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 f8590490a9dd..cfa269c91e11 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 00:22:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 10675171 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0C9B31057 for ; Fri, 9 Nov 2018 00:22:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F209F2E936 for ; Fri, 9 Nov 2018 00:22:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E53642E950; Fri, 9 Nov 2018 00:22:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 78F142E91A for ; Fri, 9 Nov 2018 00:22:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727742AbeKIKA2 (ORCPT ); Fri, 9 Nov 2018 05:00:28 -0500 Received: from mail-pl1-f195.google.com ([209.85.214.195]:43291 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727718AbeKIKA2 (ORCPT ); Fri, 9 Nov 2018 05:00:28 -0500 Received: by mail-pl1-f195.google.com with SMTP id g59-v6so55895plb.10 for ; Thu, 08 Nov 2018 16:22:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fomichev-me.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YQgFM6EgajjoaTM392UrTbkvh275AydndcKVjYWUaAM=; b=MB45Jszh9IHvOZgzFmQzbQDjXzkUPei6XEjX7RexpCg4EAqOnQB4jEamOi2WDsB2uJ qtYjXO5CUuWBG178mBL5flQ0jzVMqZSQsMNsBa4jw4D80Wz/wrdi60RxgkrlOU8SuLrC sD4V83EipbisWK2cG40UHSqOE31ruEhNlUkXe+q6ydFNhHbLMC+RdhcB17kHkcJNcMo9 OJ15vzfZ66Qn+t8sxKia8tHQjSu3nst+7wvjXPoMbu9L8GJdZvHdjnCbBMA7TLu4dC7s n6ZAj+hc9G1/6e7BGk5VjSP+dVJuHerLEl9IPxTok6NCOeYgf40l7aVXdxhPwyP8OiAk 1cBA== 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:mime-version:content-transfer-encoding; bh=YQgFM6EgajjoaTM392UrTbkvh275AydndcKVjYWUaAM=; b=GCR6pZXhLH9AAIaJM4LhrX0tv4lqAeslEFhiowRCvC7Ddu9eKz2+0l0mBsuyfTeL8t Hi8JX142T9fF2d/k/P9K2roGnuHpjUNXIchYAlgfjOTdBfbBnhRxl/lgICbQhZLM9qGT TG47kN+iOtEBR3QYLVtiMGRgLBh5i2TQ/V8fVihoHk2Njaq85yi3xHF8h6MPm1XkKKFw oQmuNpQpp5rY34Vcxq12ZWUU1w7Lu9Y9BbybFieYK8VlHpYq4/VQ3OUnob5PnQWH2HhK kxgYXHYIym9GvhCYjMsWbHxhM3vy+CPAiNVB5l6F/8ZdNlSAkxIzEndYFu2GbhBbV2zA OiIw== X-Gm-Message-State: AGRZ1gJxTKbKRFr3RgSWGc/66ayI/FyQaDJRIsPoTali+G6M8ppeG+Lu m9XkYbd2waWW7vBDxfFcajJ4sg== X-Google-Smtp-Source: AJdET5ejSTbPEh4n/GtI4q3ISSwwaLzZRfBNtKHsB+Q93o/7tDbPVYC6y+DS+z9hPWjRklQcsXE+wg== X-Received: by 2002:a17:902:8f94:: with SMTP id z20-v6mr6571127plo.175.1541722944160; Thu, 08 Nov 2018 16:22:24 -0800 (PST) Received: from mini-arch.hsd1.ca.comcast.net (c-98-210-199-22.hsd1.ca.comcast.net. [98.210.199.22]) by smtp.gmail.com with ESMTPSA id g21-v6sm4918955pgh.82.2018.11.08.16.22.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Nov 2018 16:22:23 -0800 (PST) From: Stanislav Fomichev X-Google-Original-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 Subject: [PATCH v4 bpf-next 4/7] libbpf: add internal pin_name Date: Thu, 8 Nov 2018 16:22:10 -0800 Message-Id: <20181109002213.5914-5-s@fomichev.me> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181109002213.5914-1-s@fomichev.me> References: <20181109002213.5914-1-s@fomichev.me> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stanislav Fomichev 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 | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index cfa269c91e11..38dbeb113eeb 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,18 @@ static void bpf_program__exit(struct bpf_program *prog) prog->idx = -1; } +static char *__bpf_program__pin_name(struct bpf_program *prog) +{ + char *name; + + name = strdup(prog->section_name); + for (char *p = name; p && *p; p++) + if (*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 +296,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", @@ -2008,7 +2032,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; @@ -2032,7 +2056,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) @@ -2057,7 +2081,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 00:22:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 10675173 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4658C17D4 for ; Fri, 9 Nov 2018 00:22:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 32D8F2E936 for ; Fri, 9 Nov 2018 00:22:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 30A492E94E; Fri, 9 Nov 2018 00:22:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 435212E93C for ; Fri, 9 Nov 2018 00:22:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727748AbeKIKAa (ORCPT ); Fri, 9 Nov 2018 05:00:30 -0500 Received: from mail-pf1-f196.google.com ([209.85.210.196]:36913 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727326AbeKIKAa (ORCPT ); Fri, 9 Nov 2018 05:00:30 -0500 Received: by mail-pf1-f196.google.com with SMTP id u13-v6so69740pfm.4 for ; Thu, 08 Nov 2018 16:22:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fomichev-me.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RCz5nB0Ae6Wt+JjfYNZBGhdENbJTvVZQ+MjDx7YlpSA=; b=067B9hmqMcuLGEDCG2cymHDRMN5MIdTPQ1duyaQwuOZGJcHWIrdDe/Z+zIIiNi+f80 CY3DpMjJ+0JDdMrhB12i0Zqp0zzTQmpBmjC43lTqCZCgSHgvzlWqqr+6qD4Vb1SRqqs0 nek6jiTcnkgraNoSFUju74crDXk5ObKeZF4N+bU7q9rkxEL2QlQ9caUGodwBd/ZueKOT oUjCXUX3cGmVCMHzEsv+dNzM0OtdMXXAqzh81fZMSLwQ0ypR1NqpntbCqbod7Jj/pD+k HJUBqAJaade75UCfbb/gRMO4JbWmjfitb3Nv+WbV0zOcmyGaKy9Z9EN77NEzrHDy5d2f MDZA== 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:mime-version:content-transfer-encoding; bh=RCz5nB0Ae6Wt+JjfYNZBGhdENbJTvVZQ+MjDx7YlpSA=; b=iGC9ZGlBTJ//WITwmbjaqqsmN9wdS7UvQnTF5p9aXuARAvGItmFveoGEmy9efqjtKE vbJwCAkavdeCJziOF3PSnbuyqvG4ErKfPQBs8QtzEwx8gU9yuTPvz+EwkdkJ+0vPJkvJ XK25pmYwWZFm2rXVUPVSmCAp6poPoTI40PalT0xXQhdqc6VCSKLRp945oqN9Ztorvtmp 62aUHC50gUPa99vOC1nI7MpUlywjk+AGyGqgwxVdDMrGqUp6xMvQHo/YiMJYrhv/qmdT uCtwzSh9n5ZD116SB7P/a31czxiJZCDoxVYaEcrwTHg/0CKjmJY0qjFDI6e8sKHto1S8 YZog== X-Gm-Message-State: AGRZ1gJ6963BX1jrdScvNfCmtQfLsa5HtWoSzcTPpNQnk614Pg1qOfn4 Wpy0qc+Rs7gFawgrQrsdtiqgXA== X-Google-Smtp-Source: AJdET5dJgcIjRBQsyJ8ez/LTzG0b5udrr5Mtvhl+T0pCHA7O+fgpTqIMRmmHqGImtKvUm2SngooC5A== X-Received: by 2002:a63:b30f:: with SMTP id i15mr5636791pgf.240.1541722945729; Thu, 08 Nov 2018 16:22:25 -0800 (PST) Received: from mini-arch.hsd1.ca.comcast.net (c-98-210-199-22.hsd1.ca.comcast.net. [98.210.199.22]) by smtp.gmail.com with ESMTPSA id g21-v6sm4918955pgh.82.2018.11.08.16.22.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Nov 2018 16:22:25 -0800 (PST) From: Stanislav Fomichev X-Google-Original-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 Subject: [PATCH v4 bpf-next 5/7] bpftool: add loadall command Date: Thu, 8 Nov 2018 16:22:11 -0800 Message-Id: <20181109002213.5914-6-s@fomichev.me> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181109002213.5914-1-s@fomichev.me> References: <20181109002213.5914-1-s@fomichev.me> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stanislav Fomichev 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, 82 insertions(+), 42 deletions(-) diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index ac4e904b10fb..d943d9b67a1d 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* *FILE* [**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,13 @@ 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* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] + Load bpf program(s) from binary *OBJ* and pin as *FILE*. + Both **bpftool prog load** and **bpftool prog loadall** load + all maps and programs from the *OBJ* and differ only in + pinning. **load** pins only the first program from the *OBJ* + as *FILE*. **loadall** pins all programs from the *OBJ* + under *FILE* 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 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..751a90ccfdab 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 FILE \\\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 00:22:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 10675175 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E01E613BF for ; Fri, 9 Nov 2018 00:22:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D1F3F2E904 for ; Fri, 9 Nov 2018 00:22:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C602C2E94F; Fri, 9 Nov 2018 00:22:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9FF6C2E91D for ; Fri, 9 Nov 2018 00:22:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727758AbeKIKAc (ORCPT ); Fri, 9 Nov 2018 05:00:32 -0500 Received: from mail-pf1-f194.google.com ([209.85.210.194]:39550 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727751AbeKIKAb (ORCPT ); Fri, 9 Nov 2018 05:00:31 -0500 Received: by mail-pf1-f194.google.com with SMTP id n11-v6so65309pfb.6 for ; Thu, 08 Nov 2018 16:22:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fomichev-me.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KGu9IG6X9Z/NFbeZi3OX9Sg2BFdKzD9qqa8cgkVVrq4=; b=n9AC2+uah8COv5B0M1y4bHguij2SsThBVTRydeNgoQiqVL3axA6+UOdVyzJic/WE2W CO2M2Ox6tfL3e7FlQsZTI9EPWMlm1S2pKtAvW78mRTq0ZwGHa1wRwR/A4L/RM7GfwHQ6 X9fNA7ROhpo/qEBBE25SqBuvPvRoJJiVHEAVBpRtjMknHPqKgjj+YTI5ORb0zD0uvehr 5gHzNSs+b7Nvs3lfS/tNtfEtLWR1Yi4FNuE1/bcDj2au5fTrENdIHf8LynlJCsgCqSx1 KYq6VJ1S0zFI6SF1CKdq2i7bg1rCsv8Jd7P58vQSbUqHmqv/oSgq3++b2TH9orCrvAFe jmwA== 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:mime-version:content-transfer-encoding; bh=KGu9IG6X9Z/NFbeZi3OX9Sg2BFdKzD9qqa8cgkVVrq4=; b=fimDONxJcVOJ4gKQd0jWw/yiHw680eA34ylACxKBo73eH0N3RCC4LU9V0ZK72GKP1F jLu7B0GIThsAthgvsZVgsNv7QWG3AQLCrab10quVJGg/HjNsIRJGQM7c/bmc8796ap4Q sbOnlefFra4DMSClCAee6hy2kfLzUNbLRW+EDRzHqXwi2Ayej9fI6Ae5U++9vz+//Yt0 nWUFAO7JyA12gDOCnGAA5Y/rZDZig9EVmDOerlCX4uK2XXT9GRcYSWPA6FqJcbaeg8Ok jTY7xlNvaIAqIe7aD3/O/7TTEFHbqQszb4ngfbi0nFwAgl6tWTyjeestwFGz+zvjUUGJ KCnA== X-Gm-Message-State: AGRZ1gIJw9aNzPeO2yuOkF0gvbVp92Vb4+lad4WXIfuqg/jgT6ZnS4dS BaahaKzTC0vSvO7OdtOLnDzc1g== X-Google-Smtp-Source: AJdET5cpogEZ9aHdhcdrOhYBV6pdrQR5e3zy40EJpYa9u9zQfDukVOeCX3VUslYGW5wK11PDTICp4g== X-Received: by 2002:a62:1552:: with SMTP id 79-v6mr6656360pfv.120.1541722947213; Thu, 08 Nov 2018 16:22:27 -0800 (PST) Received: from mini-arch.hsd1.ca.comcast.net (c-98-210-199-22.hsd1.ca.comcast.net. [98.210.199.22]) by smtp.gmail.com with ESMTPSA id g21-v6sm4918955pgh.82.2018.11.08.16.22.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Nov 2018 16:22:26 -0800 (PST) From: Stanislav Fomichev X-Google-Original-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 Subject: [PATCH v4 bpf-next 6/7] bpftool: add pinmaps argument to the load/loadall Date: Thu, 8 Nov 2018 16:22:12 -0800 Message-Id: <20181109002213.5914-7-s@fomichev.me> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181109002213.5914-1-s@fomichev.me> References: <20181109002213.5914-1-s@fomichev.me> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stanislav Fomichev 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 d943d9b67a1d..b04c4a365739 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* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] + **bpftool prog { load | loadall }** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] [**pinmaps** *MAP_DIR*] Load bpf program(s) from binary *OBJ* and pin as *FILE*. Both **bpftool prog load** and **bpftool prog loadall** load all maps and programs from the *OBJ* and differ only in @@ -98,6 +98,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: *FILE* 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 751a90ccfdab..4654d9450cd9 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 FILE \\\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 00:22:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 10675177 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 664FD17D4 for ; Fri, 9 Nov 2018 00:22:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 531022E90D for ; Fri, 9 Nov 2018 00:22:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 510442E93C; Fri, 9 Nov 2018 00:22:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 756532E90D for ; Fri, 9 Nov 2018 00:22:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727775AbeKIKAd (ORCPT ); Fri, 9 Nov 2018 05:00:33 -0500 Received: from mail-pf1-f193.google.com ([209.85.210.193]:34657 "EHLO mail-pf1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727751AbeKIKAc (ORCPT ); Fri, 9 Nov 2018 05:00:32 -0500 Received: by mail-pf1-f193.google.com with SMTP id y18-v6so76358pfn.1 for ; Thu, 08 Nov 2018 16:22:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fomichev-me.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6pH1CIX4ClBDwCV0I4RFrXd+cIzi3ZcnjdEK0EKEJ+k=; b=ZgzK08tsnNaWYO0Mhck1QUx2rAcMJhB88/6NQq7+fY1rtc1ci9l2VogalM3TIRN60w MoW4ZJPzjiaPMQ2w012FOEc5V7z33d2/nI/8cG5vq7mkQxVWBcWM8zwu6aSQaBmkBeD4 /SGHsy4lNreOkl7ZgSQ+I/ROZaBCx96AG5ycvh7colGRAY2kH4mjPqQbpfMv8ZzBS1JT dSSS3D8kzb3sO+l3C0EDbP+F/xMeSZ84sOEo3/J1FSuAxQSYMM8M7aF5dhl32sT47w9O fifZd53D/p8In7PtgHGORh+j2iKXxffsR4ArW7P6h0FsRE6xpn4rpkSoAKYO0WAbAeus xp8Q== 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:mime-version:content-transfer-encoding; bh=6pH1CIX4ClBDwCV0I4RFrXd+cIzi3ZcnjdEK0EKEJ+k=; b=Ihp9Q/JRRuIesfCKeBRLjDiMDiThIR+OFK4YWmZ3vXFg81JyWfd3+PnncaBNCbTK8E wkOXT8jAQPekB8RXhHj8SDJRls813dBPsbWWcFrn2gyTdIm+9O8Whz/QpN2SIuE/o6ga D/4VDmWW+ePEWXdOL4cwG47a2YwZ/PN7yUUMolC6xfynNJpIOkhGBnEXJd/qHL5IAe7m ZvW/V4sSa3OmoIbqpIck8O/k7eiQYTELQ2z7p78c/bgR9xYwu5L0FUKJI3krQazl3zCb R0NcWqeztYQiGKHzj4jNde3qD8T2uq0hgkjKqW7Iwno2JsCwN2luFtA0AGPtghMdYZD8 Eyyg== X-Gm-Message-State: AGRZ1gLIaNtGy3pRC4G2t9vDafptunxwlGbIqlyGrVtOOHTkuxcolmFA 6pMvwXBAELyNVEJpWd7k4i5CuA== X-Google-Smtp-Source: AJdET5f2NIHhFm17Nka3zZ44IbUkh/nrTtwfUz0o9Ivv6F/fXB+9fRcs6mhQYyYLzW+3BIcflj4sqw== X-Received: by 2002:a63:160d:: with SMTP id w13mr5708064pgl.43.1541722948694; Thu, 08 Nov 2018 16:22:28 -0800 (PST) Received: from mini-arch.hsd1.ca.comcast.net (c-98-210-199-22.hsd1.ca.comcast.net. [98.210.199.22]) by smtp.gmail.com with ESMTPSA id g21-v6sm4918955pgh.82.2018.11.08.16.22.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Nov 2018 16:22:28 -0800 (PST) From: Stanislav Fomichev X-Google-Original-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 Subject: [PATCH v4 bpf-next 7/7] bpftool: support loading flow dissector Date: Thu, 8 Nov 2018 16:22:13 -0800 Message-Id: <20181109002213.5914-8-s@fomichev.me> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181109002213.5914-1-s@fomichev.me> References: <20181109002213.5914-1-s@fomichev.me> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stanislav Fomichev This commit adds support for loading/attaching/detaching flow dissector program. The structure of the flow dissector program is assumed to be the same as in the selftests: * flow_dissector section with the main entry point * a bunch of tail call progs * a jmp_table map that is populated with the tail call progs 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 | 87 +++++++++++-------- 3 files changed, 77 insertions(+), 50 deletions(-) diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index b04c4a365739..d77885176464 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* *FILE* [**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 @@ -105,13 +107,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 4654d9450cd9..b808a67d1d3e 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,53 @@ 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_atach_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)) { + p_err("too few parameters for attach/detach"); 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)) { + p_err("too few parameters for map attach/detach"); + return -EINVAL; + } - mapfd = map_parse_fd(&argc, &argv); - if (mapfd < 0) - return mapfd; + *mapfd = map_parse_fd(&argc, &argv); + if (*mapfd < 0) + return *mapfd; + + return 0; +} + +static int do_attach(int argc, char **argv) +{ + enum bpf_attach_type attach_type; + int err, progfd; + int mapfd; + + err = parse_atach_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 +784,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; - } + int err, progfd; + int mapfd; - 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"); - return -EINVAL; - } - NEXT_ARG(); - - mapfd = map_parse_fd(&argc, &argv); - if (mapfd < 0) - return mapfd; + err = parse_atach_detach_args(argc, argv, + &progfd, &attach_type, &mapfd); + if (err) + return err; err = bpf_prog_detach2(progfd, mapfd, attach_type); if (err) { @@ -1092,8 +1102,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 +1115,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],