Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754203AbdLHOyN (ORCPT ); Fri, 8 Dec 2017 09:54:13 -0500 Received: from mx0a-00082601.pphosted.com ([67.231.145.42]:48702 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754134AbdLHOxs (ORCPT ); Fri, 8 Dec 2017 09:53:48 -0500 From: Roman Gushchin To: CC: , , , , , , , Quentin Monnet , David Ahern Subject: [PATCH v3 net-next 3/4] bpftool: implement prog load command Date: Fri, 8 Dec 2017 14:52:35 +0000 Message-ID: <20171208145236.12635-4-guro@fb.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20171208145236.12635-1-guro@fb.com> References: <20171208145236.12635-1-guro@fb.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [2620:10d:c092:180::1:b43a] X-ClientProxiedBy: VI1PR0102CA0086.eurprd01.prod.exchangelabs.com (2603:10a6:803:15::27) To CO1PR15MB1078.namprd15.prod.outlook.com (2a01:111:e400:7b66::8) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d1dc887a-a044-49ce-b3ec-08d53e4b6b80 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(4534020)(4602075)(4627115)(201703031133081)(201702281549075)(5600026)(4604075)(2017052603307);SRVR:CO1PR15MB1078; X-Microsoft-Exchange-Diagnostics: 1;CO1PR15MB1078;3:0VWH3wXU26wbrhh+dSOgo6ZiwJVAuJVoChTnqQMePyrXYMMJlxZaSjO0f/h84HLsa8PpZp+IvRQWpYVBa91Pil8JHQRdMvJN3ZCc+3ZFv/yW4FjQSf+vTW3kBbVdkbtDFRIg5bs1/Q99FY+I5gQKXD1Fhy+AWBM53X+ARW7+yDbZARkbGKPTzYheKUfHjX6uVm8nG8vVvgsEOcQcAPNHulPI3ARlf+Q1urda9E0k7OUrMNHufQZRukXghYW3HGrO;25:LDxjEssc5nVEcno5s5XSMs+yRYEu9rreTk3NFlqIiKAm1eEvevyRfNusFz/PMnQiCAicLWt+CROm8v0c2DwElsKm6wOa7qe5MOOZ+tIm0pyojz/GLzzc2CLQ+HiqZyYliqNBdQpYjTIWTQzAvEdqXZmrEdLVZDKMDj9UIEH0mTZNBbDj+0xPsM+FNqRGsIC4tmuqVt97rGfkqkVwNRmx/lQgMiDuIVH+Q0C7xk8tCN31j8oFvheehopLd7zlVXeJEP0DkWDExS9fGi+HlfjcUy82GQPXp1GOzPIKXmIMIyb/IWrBXyl4JKmE/dNVhZVUJ7Q6ALYtveccVy0X9JLypg==;31:uyKsNerd+V3muJ1ndz+26njjdq6TwdLJgiYs3dq7dMbCxxBvMzckh9ZKH8AC2zZ6pN4yqRUFFfeUC4ydZ3BfsXN9sclE/S1ndjaQV+d3VEXBSfpjtXDFE7vzYU+9RaPXDMQqX3J3tAsj5hFgusBaBjdmLIVWq+cB35BErw210Io26vmxrMM2YADftphE8/cIwdguk8se+NnASb9jdcSl6qZJzlOkZkZebenVc9xD85w= X-MS-TrafficTypeDiagnostic: CO1PR15MB1078: X-Microsoft-Exchange-Diagnostics: 1;CO1PR15MB1078;20:+2osSkmIFcjUd39lPvhRpKTRdD53h5oCCp0ffkuwKcxnA3X2Jd2MOeVr7wS6By8fiJDcZjRhs4B8OLHybMEfKKgz7BEDm+vYO0rIuC7kJcymDPjpx0mekJAiwnOjbpOZ400XMXBcV+m9br36C/lqGOGh38n912MietE8DJGttBdsQN4XI4R5uzOE4lCF8g9FoHq73sdvU2XZ7/cPgG8lDoUXWufvi87kx86zXQQPBP7lYDC4in4RD12qiI5cva0h9V+hHt7okIU55/CHG1ioEKrMrmf85kOKPAAzrPU50LfMzV6cVkCmJlgwTanGotsUmC6kSscb7/saa3VZk05Ti3rpkJ0hUp2S4ufYdbilJWfIA0GywbxDyz/i13KTxGyQBmHQnc4jfRdsOO8oIgLqmBuAdp/KZrxiuonjsk9Ij4gFcyY81pOqkKvF8DD72th3oCi/undSnwQ/QQrH2mClMGhbzWMdN31w69lI3Qtir5Vu4dSJ9TPX6VPCbM1NuMzE;4:Ah7uu2OHnwSJKSVm1pPXgETupEop2rxjywG4H2ohJ2NefmQ9qyoJwRTAgW1iPimgxN8ENr4Aw/7uODH/IQvFAqk2U7DbR52hhSMIz1bafbgfVHT3abflfVJSM2csIRODJddT9cLnlXK3RBdmVxDAhVrW5MIaGEK5CI1qcFNyHoUHX3nu+s4DwKBEcRzmabhG20dQYZPApAdwJmAWt5nkr16BDl3Nfu4Qda+BTq2oJZpxxE2qR0H+/DRKgqZqSAoAqORmMnv5erkepmxxKD1mds+jTl2pSzCOn+UdhBnHxgtdlHlHToIax/iB2V6NCBt6 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(67672495146484); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(11241501159)(6040450)(2401047)(8121501046)(5005006)(93006095)(93001095)(3002001)(10201501046)(3231022)(6041248)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123562025)(20161123564025)(20161123558100)(20161123560025)(20161123555025)(6072148)(201708071742011);SRVR:CO1PR15MB1078;BCL:0;PCL:0;RULEID:(100000803101)(100110400095);SRVR:CO1PR15MB1078; X-Forefront-PRVS: 0515208626 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(366004)(376002)(346002)(189003)(199004)(7736002)(68736007)(6116002)(86362001)(575784001)(1076002)(105586002)(48376002)(106356001)(33646002)(2351001)(50226002)(2361001)(305945005)(2906002)(53416004)(2950100002)(6666003)(8936002)(81166006)(50466002)(8676002)(6916009)(81156014)(5660300001)(52116002)(51416003)(69596002)(6506006)(478600001)(53936002)(52396003)(16586007)(316002)(6486002)(39060400002)(4326008)(36756003)(6512007)(76176011)(25786009)(47776003)(97736004)(54906003)(42262002);DIR:OUT;SFP:1102;SCL:1;SRVR:CO1PR15MB1078;H:castle.thefacebook.com;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;CO1PR15MB1078;23:1RYwGbwylOQovlPBpRl2vkeJOyDiA6+FO4riKCrij?= =?us-ascii?Q?Tzg7id0PomppP9hfAKUmSIoRci9Cl7kDQaZHiNF2c2lOQDAiUoDEp/CWmSer?= =?us-ascii?Q?ya0xdqjzsBCYmzvqsQETe57wA2PiUS/fYZFz/Cm8N0CMR10TbEEDKwrluvje?= =?us-ascii?Q?6rZncank8b81ZJF62hOowRy56uV9YCv98MET4i8TO1e8PcAaEjedrkQtBrlB?= =?us-ascii?Q?JJFTC+MZ+Q2HWDnH2lCkGburEQizZIf2emLWH96KtoToAzOEECHHI2aSRLLz?= =?us-ascii?Q?Dw2VHPuwwFZfQrLMAcnqigrS0jbbIkXklC48pOSAo1xkhR/Xj5GOhqcokC+B?= =?us-ascii?Q?FAXE9cS4a6N6WYdDSovOwWM5EOQJavkUZq/b8Ty9ne23WLXmHf1ZZvB9mSs4?= =?us-ascii?Q?jLEtXueQrXgstcSHnCIjCYshpLml3+YCAicskgmB+hBUR/qKLWX/MWLPPF5f?= =?us-ascii?Q?q+7Gfq5oWkey5MOavIxPQixi2kXVWYUM6BlTzYfvrwXe4F+3rh7488X7MlIQ?= =?us-ascii?Q?RWkFdr2pxt0/FiTP7cHP9A6+KW1q+PRCmmW0rLhn+iox2JStrwWt3Xk6Rotj?= =?us-ascii?Q?+6zEtTJAuX7dZohI2gUjOdZznVamgiL3I056TDo6ZEWBnyJrQmvjrd0Cb7H3?= =?us-ascii?Q?6gbqUIvSBOFQXOkFe2qpNoOgAI2EnC4OQJGfO9+nam47Wq3s8qFAxkCiLq9F?= =?us-ascii?Q?gJFPKcGQ6WLLfq3vLwTvmVttYBs1Qk4lz4yFBifkc3HNs/kjsiBDhrQGEp/I?= =?us-ascii?Q?cilF/8ZO/mQU1uGfEXRbd2RhqY3xQXSiwCNbcA6jfMod31j7fhqGMO3+8uly?= =?us-ascii?Q?GVuBjz8LnUwSZSiY3vJFlq4EcDaeJUqo0eRn1WR7c8wDH5qomDsCvoJjC8Jv?= =?us-ascii?Q?koS0oYRNOJ+FJHd5P08+PlnwZZKrPmKtXSq8dYE0S2Gq7vC9EbLbtSUK7ng2?= =?us-ascii?Q?Mf6I+/oDjUva8OueQIR8QGwLmh50s++WPcoJjVbUclAHdQBO7ovy7Te/aOO5?= =?us-ascii?Q?6zYLsOa20IJk8lCBM4Kv+Qlz1vtd6g3CSn0RwwrVGtps9+Pdij766Z8nb6EG?= =?us-ascii?Q?VA5riZqU6+FYixdHNmk8qI+jCsGkFPcBYgF5LDDMwBEHo44aHZSR0OgBsdBw?= =?us-ascii?Q?33MSqZewVNJj0wdKpjFdeq2StW8BsJAUq3mxpGFQvjBiwqEUMwL7w=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;CO1PR15MB1078;6:pn8b+0CFNEJU1zhsJJ6ML5RlPmdnyiPR0EEEzMwztc3kLUp7qY/t6N5OHBYq6HR/87+ZGsd6lOX6k+sSlfAefbFgkcMhAkRqvG8OGSrWkPxXtiA8kanz0Tdv5NxJfRF62eVG4whmnCpA2pT/BGcIOphFMK67hlgLBdIRHfBNbIja6kZhSyAFsjbD58F5WGGz6yKb6tbjTJBm6NIgmSWUXE9fLcIRu3g9Y1cpeprdJwmsHEizQR25Ao58pmvh0PnC3Lk4SsUWqAyCZxohJj2KvO+za8O/b5o0lNkXSg2ENnUi1yoQP2/qcQueFuhtLoZFobFyn0MYtUti1kpYihUgCRs9KSTECX1fYKJNffLlCq4=;5:M+/QIsK9VD1H1Kblges+YzfDP/dqSTaCtfC5uyUaNPGolpEHvbp1zihL1O6tGG39LQ/uk+DWXOVai8QRIcMpWEZPbERQxP4AWBsxFyGRts9HoAvE/IIRHe08OwRzIFR9IRLnAEZ/HfTnPdHJHJcgWUPgD8uE+PDIYDYrdhKOcE4=;24:q1hsVncWExSFLydQQor0hKVly4/wdhuMrFAXt0dz6jBZesu3w1U+pZ31xf+DmjdM9krWmkIyaeqkE0r/6YJxWv5W9fM/sajV4ANRVFYJ+4w=;7:YgGS+nO1nxe2XCj/LVpdhQH5FapCBytO57m0mL+01HywLWes/keLJVhMRRzfA2dT1eWDLX5mPZ8/PfK7VxoB9uwuo0TfYf4clsQarIKhyZUuEkxZ6vJgBwRoa6E4RVHLpXFelTdT0yJ6bwYeKJ4TwVCEbGpwmKn1uA4zREOKF/Ex8W7VXYeInovGp4lnAwniNdUDlI1dbBEX5LzyNkjK0CJFuKISdfORoWYTdYlw3sFMhKdxJehD++HDmdQvzG5X SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;CO1PR15MB1078;20:XFCsAdwDrZiZQvXXSZdlflJdonzxHVDsvAwZLDV4HdVLfMm8QJXDkW/Hr+lDx+4Yn4MC8w7wioOQZvg7RWgqENiKd1TqtjKR2rV79aV/3xIvvl8VvsQlIKZ2i7Mnn7rMYLPph9dxfHNAj50cZlZQRsE/Japm0hQJu8dSfAaBkT4= X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Dec 2017 14:53:15.6733 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d1dc887a-a044-49ce-b3ec-08d53e4b6b80 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8ae927fe-1255-47a7-a2af-5f3a069daaa2 X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO1PR15MB1078 X-OriginatorOrg: fb.com X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-12-08_08:,, signatures=0 X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7290 Lines: 258 Add the prog load command to load a bpf program from a specified binary file and pin it to bpffs. Usage description and examples are given in the corresponding man page. Syntax: $ bpftool prog load OBJ FILE FILE is a non-existing file on bpffs. Signed-off-by: Roman Gushchin Cc: Alexei Starovoitov Cc: Daniel Borkmann Reviewed-by: Jakub Kicinski Cc: Martin KaFai Lau Cc: Quentin Monnet Cc: David Ahern --- tools/bpf/bpftool/Documentation/bpftool-prog.rst | 10 +++- tools/bpf/bpftool/Documentation/bpftool.rst | 2 +- tools/bpf/bpftool/common.c | 71 +++++++++++++----------- tools/bpf/bpftool/main.h | 1 + tools/bpf/bpftool/prog.c | 29 +++++++++- 5 files changed, 79 insertions(+), 34 deletions(-) diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index 36e8d1c3c40d..ffdb20e8280f 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst @@ -15,7 +15,7 @@ SYNOPSIS *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } *COMMANDS* := - { **show** | **dump xlated** | **dump jited** | **pin** | **help** } + { **show** | **dump xlated** | **dump jited** | **pin** | **load** | **help** } MAP COMMANDS ============= @@ -24,6 +24,7 @@ MAP COMMANDS | **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes**}] | **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}] | **bpftool** **prog pin** *PROG* *FILE* +| **bpftool** **prog load** *OBJ* *FILE* | **bpftool** **prog help** | | *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* } @@ -57,6 +58,11 @@ DESCRIPTION Note: *FILE* must be located in *bpffs* mount. + **bpftool prog load** *OBJ* *FILE* + Load bpf program from binary *OBJ* and pin as *FILE*. + + Note: *FILE* must be located in *bpffs* mount. + **bpftool prog help** Print short help message. @@ -126,8 +132,10 @@ EXAMPLES | | **# mount -t bpf none /sys/fs/bpf/** | **# bpftool prog pin id 10 /sys/fs/bpf/prog** +| **# bpftool prog load ./my_prog.o /sys/fs/bpf/prog2** | **# ls -l /sys/fs/bpf/** | -rw------- 1 root root 0 Jul 22 01:43 prog +| -rw------- 1 root root 0 Jul 22 01:44 prog2 **# bpftool prog dum jited pinned /sys/fs/bpf/prog opcodes** diff --git a/tools/bpf/bpftool/Documentation/bpftool.rst b/tools/bpf/bpftool/Documentation/bpftool.rst index 926c03d5a8da..f547a0c0aa34 100644 --- a/tools/bpf/bpftool/Documentation/bpftool.rst +++ b/tools/bpf/bpftool/Documentation/bpftool.rst @@ -26,7 +26,7 @@ SYNOPSIS | **pin** | **help** } *PROG-COMMANDS* := { **show** | **dump jited** | **dump xlated** | **pin** - | **help** } + | **load** | **help** } DESCRIPTION =========== diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index 2bd3b280e6dd..b62c94e3997a 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c @@ -163,13 +163,49 @@ int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type) return fd; } -int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) +int do_pin_fd(int fd, const char *name) { char err_str[ERR_MAX_LEN]; - unsigned int id; - char *endptr; 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)); + 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 { + err_str[ERR_MAX_LEN - 1] = '\0'; + p_err("can't mount BPF file system to pin the object (%s): %s", + name, err_str); + } + +out_free: + free(file); +out: + return err; +} + +int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) +{ + unsigned int id; + char *endptr; int err; int fd; @@ -195,35 +231,8 @@ int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) return -1; } - err = bpf_obj_pin(fd, *argv); - if (!err) - goto out_close; - - file = malloc(strlen(*argv) + 1); - strcpy(file, *argv); - dir = dirname(file); - - if (errno != EPERM || is_bpffs(dir)) { - p_err("can't pin the object (%s): %s", *argv, strerror(errno)); - goto out_free; - } + err = do_pin_fd(fd, *argv); - /* Attempt to mount bpffs, then retry pinning. */ - err = mnt_bpffs(dir, err_str, ERR_MAX_LEN); - if (!err) { - err = bpf_obj_pin(fd, *argv); - if (err) - p_err("can't pin the object (%s): %s", *argv, - strerror(errno)); - } else { - err_str[ERR_MAX_LEN - 1] = '\0'; - p_err("can't mount BPF file system to pin the object (%s): %s", - *argv, err_str); - } - -out_free: - free(file); -out_close: close(fd); return err; } diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h index bff330b49791..bec1ccbb49c7 100644 --- a/tools/bpf/bpftool/main.h +++ b/tools/bpf/bpftool/main.h @@ -111,6 +111,7 @@ 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 do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)); +int do_pin_fd(int fd, const char *name); int do_prog(int argc, char **arg); int do_map(int argc, char **arg); diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index ad619b96c276..037484ceaeaf 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -45,6 +45,7 @@ #include #include +#include #include "main.h" #include "disasm.h" @@ -635,6 +636,30 @@ static int do_pin(int argc, char **argv) return err; } +static int do_load(int argc, char **argv) +{ + struct bpf_object *obj; + int prog_fd; + + if (argc != 2) + usage(); + + if (bpf_prog_load(argv[0], BPF_PROG_TYPE_UNSPEC, &obj, &prog_fd)) { + p_err("failed to load program\n"); + return -1; + } + + if (do_pin_fd(prog_fd, argv[1])) { + p_err("failed to pin program\n"); + return -1; + } + + if (json_output) + jsonw_null(json_wtr); + + return 0; +} + static int do_help(int argc, char **argv) { if (json_output) { @@ -647,13 +672,14 @@ static int do_help(int argc, char **argv) " %s %s dump xlated PROG [{ file FILE | opcodes }]\n" " %s %s dump jited PROG [{ file FILE | opcodes }]\n" " %s %s pin PROG FILE\n" + " %s %s load OBJ FILE\n" " %s %s help\n" "\n" " " HELP_SPEC_PROGRAM "\n" " " HELP_SPEC_OPTIONS "\n" "", bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], - bin_name, argv[-2], bin_name, argv[-2]); + bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2]); return 0; } @@ -663,6 +689,7 @@ static const struct cmd cmds[] = { { "help", do_help }, { "dump", do_dump }, { "pin", do_pin }, + { "load", do_load }, { 0 } }; -- 2.14.3