From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753445AbdLMPUO (ORCPT ); Wed, 13 Dec 2017 10:20:14 -0500 Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:40924 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753262AbdLMPTq (ORCPT ); Wed, 13 Dec 2017 10:19:46 -0500 From: Roman Gushchin To: CC: , , , , , , , Quentin Monnet , David Ahern Subject: [PATCH v4 net-next 4/4] bpftool: implement cgroup bpf operations Date: Wed, 13 Dec 2017 15:18:54 +0000 Message-ID: <20171213151854.21960-5-guro@fb.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20171213151854.21960-1-guro@fb.com> References: <20171213151854.21960-1-guro@fb.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [2620:10d:c092:180::1:f726] X-ClientProxiedBy: DB6PR07CA0138.eurprd07.prod.outlook.com (2603:10a6:6:16::31) To BL2PR15MB1075.namprd15.prod.outlook.com (2603:10b6:201:17::9) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 70bcc275-9c03-45b1-cb3f-08d5423ce46c X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(4534020)(4602075)(4627115)(201703031133081)(201702281549075)(5600026)(4604075)(2017052603307);SRVR:BL2PR15MB1075; X-Microsoft-Exchange-Diagnostics: 1;BL2PR15MB1075;3:dxoZ1UISC0Dot8r1pPCJJkvzgKCkwYND5D9GFI0chi6kDVc43i3T3OMdw+LkPyCTHly0Yizqez9kcwVJKkx3UwpzM7Stfc3Sr3eScCE7BXUci941ta/JI95Anpb0EanfOr1Sr8MmnDDBLp6z2FIgwtYepFny/IjRFAqapHutI+dIskT8k/T/6npn9V9dGBn42SiweUiovBxq5DCNzK+oIIdYwayu2bn2apDEqOkItSKmSdvQAThmaexFoxR/CeQN;25:FGB49bg4vNDYay1GPxRRV7OmUsSA07si4b8f7GScLMatb4+Ci/afNQj3NdSYwkZ/CS6Hh/JK4FoxmEtwbLipjXNwdjzHbkYv+P//c3VRM3yI7X95mEV44AUhZNGrKhoHuxd4vVQ06XmUKTKLgq7H6R+cck6uCkpdLZMNXd8fz1whn6nvThJUHDPiqPiC19e7bln8V5xHX3FxyDb4qeeJ1dpMtl373O5EBOlLDfY7SiBXHsHbvaywCJ6QRnB0g2ZoF6j0La+DI/uvjhpPtIp/7AGP+KKy74XcxL5ltsVSXsYIBesb53W1odZ8EcJD18gpKlkU1ffN0ZseC1MLpEj2Iw==;31:kSFOiwZwV+h1N0DQuf4yTCsxrEWg9FPWDzu42B/6NuKLPMkLpnJnkZPg8HMr+dAMcz9IqTpKK0FeYb3O8mpfYYD6wMlD13ioXqNSo1ZVHvJvFRn92EdG2Wi86gygoSKFjCGTRvy1e4w6Zy0WaZW38JewGtsQ0rUHhMZAlNzR+0z1AXl9MxNWJaxdeInvWl7Sl7oO3/c2lSbp8tOJHZq7o/eiAjYh/9vB6wexS/WTR5c= X-MS-TrafficTypeDiagnostic: BL2PR15MB1075: X-Microsoft-Exchange-Diagnostics: 1;BL2PR15MB1075;20:v9vnl/boYR7IPI6m+0hoFBbmJgL8YzAv1TVKKOBmWbjq3w3CqdMFjQZfT9pCNqfav0v2TdB7Dp6IsFBGOwwVgriZCPazAR2UDudc+BJtel4aoRh6b7wZHuLcFojT8X6X6mW7yBydZnCFEGM1BYAL9xlVJklBvrnaOshNvTsYRoTInHVKqYq0k7LbcZtey42+/JyFBzXKUwaWsrBikCBtEiTYMlgc6jiCf31becVd0WFMkituYmmKi7iOYm7RiwT6xj1b5YKatNe4CQdWwGzec29P1t0FnNAN+m7woD9TikcjsDmBYSb9wYl3JvHAyql5T4DZxQgs6uKyxbCw5omdbO7Wce8HqDA1jm57NDgVoMq+QRc+kbuDewQ5MY+oDAx1wZnsmMPCrTiT+r/vs+L1y/jq0sCOUDpfaAd3mPtIH+ypbYMIzOOF7/PSv2vClBCYlPTD7eWaBb6DvAN3jdAAv1kq+IWp+tEfpae7fRshTV8o5jF46eEAH3RMufpANbuD;4:MEkHIGOjhMeiGXLe4wIHEKMgmmNu3VIykSx9JILhXjptTpyCEu6l5aPdfpEy3L4RqejUmVbRAItwEshzli0q693TBK6oG9d1ofdr1M29iS2mFEs7u1vo79rAtNy+U9zARHWKBR+QTQUb2MKtqY+l2RH3kesLU635yF1FMOj7pk0xJ1NvTdmpamRsv+Mz5TatgRzSfdDiDvLt3ugsnJzVBHKLNh6EIGjp1OHGAhCZ8C8Nmuo7ZwZIgpfcZ6iLGpICW4/8q+Bn6AQcg/6tbM+DlLzG7BssCXKK/0jCFbWnGxMSjPvV+ys2ZemyET26JTB8UVTnJSsKDaSgd0iiOHhk5fnaccZO9hTzShopHjehzK0= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(67672495146484)(81227570615382); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040450)(2401047)(5005006)(8121501046)(3002001)(10201501046)(3231023)(11241501184)(93006095)(93001095)(6041248)(20161123564025)(20161123555025)(20161123558100)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123560025)(20161123562025)(6072148)(201708071742011);SRVR:BL2PR15MB1075;BCL:0;PCL:0;RULEID:(100000803101)(100110400095);SRVR:BL2PR15MB1075; X-Forefront-PRVS: 052017CAF1 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(346002)(39860400002)(376002)(366004)(199004)(189003)(48376002)(7736002)(52116002)(6512007)(6116002)(1076002)(305945005)(5660300001)(53936002)(52396003)(68736007)(39060400002)(50226002)(4326008)(51416003)(8936002)(386003)(6506007)(8676002)(25786009)(81156014)(575784001)(478600001)(2950100002)(6916009)(2351001)(2361001)(316002)(59450400001)(81166006)(86362001)(6666003)(50466002)(54906003)(16586007)(69596002)(47776003)(97736004)(36756003)(76176011)(106356001)(6486002)(2906002)(53416004)(105586002)(5890100001)(42262002);DIR:OUT;SFP:1102;SCL:1;SRVR:BL2PR15MB1075;H:castle.thefacebook.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BL2PR15MB1075;23:rpWg1hqwfYxBjGhMbCCbxp+2JZZmp2FPSvFQZbg97?= =?us-ascii?Q?Oj4e1wpvY2tqtohTRxp5ZI+j+VZCJTAOz/6j2bOl77N0yJXEIE3lYNF8TrkR?= =?us-ascii?Q?Y5VvXJYm5CI3WOelWZs2wk7bIPjkadJ7MhpRcojPBEkBm6oC19EB5gLODP8m?= =?us-ascii?Q?z2A1p7LpAotvbgRgfIR+aOjaniupbCwwU1/KQlPflhjKM999CoveW70K3Vei?= =?us-ascii?Q?gHoFxRPB+gZty+E9s043HX8bCAoGA88PAMSbrYv4nn8eWolUYuxu9zRjA3Qu?= =?us-ascii?Q?6prM89WznJLGjgtFInSgin0WACBmooCTuisO4kpwe9YlY0fHQDWHFMBK4JVT?= =?us-ascii?Q?EQNCyS9lUp11esHVmDQdDB5UVOpLTsc3xKPoRbJFy+54gjSGuLOG45IxHinR?= =?us-ascii?Q?6SZh8/NPF7IoPvBrRxhLekkB7A2ZLx5Ux4CVetvlB8E1z0a8oPF5h29rQMRp?= =?us-ascii?Q?G9aX3G2LqeYb1eSNlgVeE2HARhxeho24unpwysIE7qF/QQJPBl7T0AJBC+zC?= =?us-ascii?Q?3sKuQTgAYGtQpc0m8ztbrX4tifSNl2EaZL7Z2As/B01oAzUPQdNFe0LtmJOO?= =?us-ascii?Q?feciBEIHOZk1wH9uULlOb2Ntcac5ZkWDZIBLN7w+3g6JppUFVQ5bOfm//pZO?= =?us-ascii?Q?k+2mXXM5t7mITp3+/xYjQv1HLHO4miBrh1pTobWAL8DfcGuD3ap+3XxbTVj3?= =?us-ascii?Q?gh4/KazU84pqSZ/PPsOrCfwOLwn7dDCwbzPx6jFG3uN6WshDFZiO220jqdd2?= =?us-ascii?Q?Km72T0bnb+TFBtEvLzczcgJJnSudjKNsxPdugpSkHaDe/gNnvMlJfDFxOVwF?= =?us-ascii?Q?3G92JkFM3tlInRE9XC29b/ZI6crVVUsctK0NEQPBJKAq3TofeK5J4jgdfGz4?= =?us-ascii?Q?REKrBEllPHmqGU2USxGsxTttGHGNe1Qgua5Alfg6lP0fK/93bErqZRdJeym5?= =?us-ascii?Q?/hxjVJtn2+esEZnEDNEQdjVr9hFXIlcDh+dcQL6jNdHNU9AEa+MoIhAT7Xdz?= =?us-ascii?Q?sgrcWvLEBMbJvew96TuJc7/ZIcvi6sPxT6QSDlm3405T5fixjP+/rY4rJUzn?= =?us-ascii?Q?7kdv5fxN3FnPQmEPO2m56b14P1agJr9xF7ktd0pFnJv1cYyc+nxeaxHcAFtd?= =?us-ascii?Q?lALDT88HRmuYDJj68sCNQgn8mOeZPssbt9ko932F8LzZ+72c+0aq4AhTs24A?= =?us-ascii?Q?Mp7zMEszwS+S9qV3INFUDFmHzYZ5ut4FxTu09EsKqFcidDJ1ylz5Rg93w=3D?= =?us-ascii?Q?=3D?= X-Microsoft-Exchange-Diagnostics: 1;BL2PR15MB1075;6:veH8yCxElQHfFGydgyvqWREVZ6qbSWn74uLeidYg46TO5m6aI13wPbPPg9n4+e3W3gkyV3b95FVBpIOoRoC0iqXdlQkMtsjqALGznQITJq3zNwO8vOzvU7S3gI221X02F60jLGddP+XQiMEbd8c3tcm69yUGo+RCEIPhUifJrZ8pR/AV2raawPlSdoiwkv8YNAhgXBfGsnVqWXq620m3Z+76DCAof2fbrFWQ5p73IMhmFv3eQFTPd0dUgzMelUjIZ8MDuP2/Z7IRHaJfr7gNzd2GJgFtWJ6YaM+aMaBuxUWAV5PrPWYAB95TaNywHn7tZmV9nYNK+j/Oru3iaKx3FIV/+uc8943/F5MIN+IN2EY=;5:dwuyjIWybl1DifjlbA+yIIE/90f8ZYQvJO1zajGUQo2VdGQLW4XA6TUT3Rm19zF3SwZDUaDPMMjW3jcCIUowQ7F6ltKaXvz7OOhaXgpsqIXQwmvHe6KDw3Zcs00lzPzMke9rgeIEAOmQLNFTaKaGTdc7WGZWLzh79LJF3imGC1k=;24:l8Ep4wcRqF4ldhuII8jTCtPweQN/pCdsqmnkU3R+uIO7k/vuVpgO3+fMyOI1D2tBjeOT9EmHT2XdwWRubu7X3l6xQnlAffJLCbUyE2/dqpI=;7:pF799kO9CHYP23nXlHl3t5uBK3+kyG9fOfqCbDqtbSTxMlal8OSr6hLgIc1qsu0usz4QSVOn+1ZerW+R8HlsLb0h9jFWkTFs8pNLxCEQiRy+WbIhM7sTYX13xIzkMMOaqODjMpgiaqznpcgT2q39k6pNHQiEM1AXA8JTiyE71BEfdR/sYNlhlPR2FjCVJoXc8leOPtaY4PG5/D9JPDV2Mmvj7a01ACElLYbnWQIi8LVg4QPcU/FokCJxgJSUqr/O SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;BL2PR15MB1075;20:T30+vtQl2vcd8wASFMFQh6vWmGe7cfUcXUGUU5Gl+4EukaOeaGIqzsexraHBOfWpdwwFXq4JQsOP3LgS56i7KFXzqQ7YhUf+mHyj/gj/BjTaJO/8v0rOJ220mS+HfzT6XDJufEkjgM8fR6gGsquqDkU+18QuQLH+8LCt23qO1Hc= X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Dec 2017 15:19:22.4505 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 70bcc275-9c03-45b1-cb3f-08d5423ce46c X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8ae927fe-1255-47a7-a2af-5f3a069daaa2 X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL2PR15MB1075 X-OriginatorOrg: fb.com X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-12-13_07:,, 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 This patch adds basic cgroup bpf operations to bpftool: cgroup list, attach and detach commands. Usage is described in the corresponding man pages, and examples are provided. Syntax: $ bpftool cgroup list CGROUP $ bpftool cgroup attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS] $ bpftool cgroup detach CGROUP ATTACH_TYPE PROG Signed-off-by: Roman Gushchin Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Jakub Kicinski Cc: Martin KaFai Lau Cc: Quentin Monnet Reviewed-by: David Ahern --- tools/bpf/bpftool/Documentation/bpftool-cgroup.rst | 118 ++++++++ tools/bpf/bpftool/Documentation/bpftool-map.rst | 2 +- tools/bpf/bpftool/Documentation/bpftool-prog.rst | 2 +- tools/bpf/bpftool/Documentation/bpftool.rst | 6 +- tools/bpf/bpftool/cgroup.c | 307 +++++++++++++++++++++ tools/bpf/bpftool/main.c | 3 +- tools/bpf/bpftool/main.h | 1 + 7 files changed, 434 insertions(+), 5 deletions(-) create mode 100644 tools/bpf/bpftool/Documentation/bpftool-cgroup.rst create mode 100644 tools/bpf/bpftool/cgroup.c diff --git a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst new file mode 100644 index 000000000000..45c71b1f682b --- /dev/null +++ b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst @@ -0,0 +1,118 @@ +================ +bpftool-cgroup +================ +------------------------------------------------------------------------------- +tool for inspection and simple manipulation of eBPF progs +------------------------------------------------------------------------------- + +:Manual section: 8 + +SYNOPSIS +======== + + **bpftool** [*OPTIONS*] **cgroup** *COMMAND* + + *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } + + *COMMANDS* := + { **list** | **attach** | **detach** | **help** } + +MAP COMMANDS +============= + +| **bpftool** **cgroup list** *CGROUP* +| **bpftool** **cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*] +| **bpftool** **cgroup detach** *CGROUP* *ATTACH_TYPE* *PROG* +| **bpftool** **cgroup help** +| +| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* } +| *ATTACH_TYPE* := { *ingress* | *egress* | *sock_create* | *sock_ops* | *device* } +| *ATTACH_FLAGS* := { *multi* | *override* } + +DESCRIPTION +=========== + **bpftool cgroup list** *CGROUP* + List all programs attached to the cgroup *CGROUP*. + + Output will start with program ID followed by attach type, + attach flags and program name. + + **bpftool cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*] + Attach program *PROG* to the cgroup *CGROUP* with attach type + *ATTACH_TYPE* and optional *ATTACH_FLAGS*. + + *ATTACH_FLAGS* can be one of: **override** if a sub-cgroup installs + some bpf program, the program in this cgroup yields to sub-cgroup + program; **multi** if a sub-cgroup installs some bpf program, + that cgroup program gets run in addition to the program in this + cgroup. + + Only one program is allowed to be attached to a cgroup with + no attach flags or the **override** flag. Attaching another + program will release old program and attach the new one. + + Multiple programs are allowed to be attached to a cgroup with + **multi**. They are executed in FIFO order (those that were + attached first, run first). + + Non-default *ATTACH_FLAGS* are supported by kernel version 4.14 + and later. + + *ATTACH_TYPE* can be on of: + **ingress** ingress path of the inet socket (since 4.10); + **egress** egress path of the inet socket (since 4.10); + **sock_create** opening of an inet socket (since 4.10); + **sock_ops** various socket operations (since 4.12); + **device** device access (since 4.15). + + **bpftool cgroup detach** *CGROUP* *ATTACH_TYPE* *PROG* + Detach *PROG* from the cgroup *CGROUP* and attach type + *ATTACH_TYPE*. + + **bpftool prog help** + Print short help message. + +OPTIONS +======= + -h, --help + Print short generic help message (similar to **bpftool help**). + + -v, --version + Print version number (similar to **bpftool version**). + + -j, --json + Generate JSON output. For commands that cannot produce JSON, this + option has no effect. + + -p, --pretty + Generate human-readable JSON output. Implies **-j**. + + -f, --bpffs + Show file names of pinned programs. + +EXAMPLES +======== +| +| **# mount -t bpf none /sys/fs/bpf/** +| **# mkdir /sys/fs/cgroup/test.slice** +| **# bpftool prog load ./device_cgroup.o /sys/fs/bpf/prog** +| **# bpftool cgroup attach /sys/fs/cgroup/test.slice/ device id 1 allow_multi** + +**# bpftool cgroup list /sys/fs/cgroup/test.slice/** + +:: + + ID AttachType AttachFlags Name + 1 device allow_multi bpf_prog1 + +| +| **# bpftool cgroup detach /sys/fs/cgroup/test.slice/ device id 1** +| **# bpftool cgroup list /sys/fs/cgroup/test.slice/** + +:: + + ID AttachType AttachFlags Name + +SEE ALSO +======== + **bpftool**\ (8), **bpftool-prog**\ (8), **bpftool-map**\ (8) diff --git a/tools/bpf/bpftool/Documentation/bpftool-map.rst b/tools/bpf/bpftool/Documentation/bpftool-map.rst index 9f51a268eb06..421cabc417e6 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-map.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-map.rst @@ -128,4 +128,4 @@ EXAMPLES SEE ALSO ======== - **bpftool**\ (8), **bpftool-prog**\ (8) + **bpftool**\ (8), **bpftool-prog**\ (8), **bpftool-cgroup**\ (8) diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index ffdb20e8280f..81c97c0e9b67 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst @@ -155,4 +155,4 @@ EXAMPLES SEE ALSO ======== - **bpftool**\ (8), **bpftool-map**\ (8) + **bpftool**\ (8), **bpftool-map**\ (8), **bpftool-cgroup**\ (8) diff --git a/tools/bpf/bpftool/Documentation/bpftool.rst b/tools/bpf/bpftool/Documentation/bpftool.rst index f547a0c0aa34..6732a5a617e4 100644 --- a/tools/bpf/bpftool/Documentation/bpftool.rst +++ b/tools/bpf/bpftool/Documentation/bpftool.rst @@ -16,7 +16,7 @@ SYNOPSIS **bpftool** **version** - *OBJECT* := { **map** | **program** } + *OBJECT* := { **map** | **program** | **cgroup** } *OPTIONS* := { { **-V** | **--version** } | { **-h** | **--help** } | { **-j** | **--json** } [{ **-p** | **--pretty** }] } @@ -28,6 +28,8 @@ SYNOPSIS *PROG-COMMANDS* := { **show** | **dump jited** | **dump xlated** | **pin** | **load** | **help** } + *CGROUP-COMMANDS* := { **list** | **attach** | **detach** | **help** } + DESCRIPTION =========== *bpftool* allows for inspection and simple modification of BPF objects @@ -53,4 +55,4 @@ OPTIONS SEE ALSO ======== - **bpftool-map**\ (8), **bpftool-prog**\ (8) + **bpftool-map**\ (8), **bpftool-prog**\ (8), **bpftool-cgroup**\ (8) diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c new file mode 100644 index 000000000000..34ca303d72bc --- /dev/null +++ b/tools/bpf/bpftool/cgroup.c @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (C) 2017 Facebook +// Author: Roman Gushchin + +#include +#include +#include +#include +#include +#include + +#include + +#include "main.h" + +#define HELP_SPEC_ATTACH_FLAGS \ + "ATTACH_FLAGS := { multi | override }" + +#define HELP_SPEC_ATTACH_TYPES \ + "ATTACH_TYPE := { ingress | egress | sock_create | sock_ops | device }" + +static const char * const attach_type_strings[] = { + [BPF_CGROUP_INET_INGRESS] = "ingress", + [BPF_CGROUP_INET_EGRESS] = "egress", + [BPF_CGROUP_INET_SOCK_CREATE] = "sock_create", + [BPF_CGROUP_SOCK_OPS] = "sock_ops", + [BPF_CGROUP_DEVICE] = "device", + [__MAX_BPF_ATTACH_TYPE] = NULL, +}; + +static enum bpf_attach_type parse_attach_type(const char *str) +{ + enum bpf_attach_type type; + + for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) { + if (attach_type_strings[type] && + is_prefix(str, attach_type_strings[type])) + return type; + } + + return __MAX_BPF_ATTACH_TYPE; +} + +static int list_bpf_prog(int id, const char *attach_type_str, + const char *attach_flags_str) +{ + struct bpf_prog_info info = {}; + __u32 info_len = sizeof(info); + int prog_fd; + + prog_fd = bpf_prog_get_fd_by_id(id); + if (prog_fd < 0) + return -1; + + if (bpf_obj_get_info_by_fd(prog_fd, &info, &info_len)) { + close(prog_fd); + return -1; + } + + if (json_output) { + jsonw_start_object(json_wtr); + jsonw_uint_field(json_wtr, "id", info.id); + jsonw_string_field(json_wtr, "attach_type", + attach_type_str); + jsonw_string_field(json_wtr, "attach_flags", + attach_flags_str); + jsonw_string_field(json_wtr, "name", info.name); + jsonw_end_object(json_wtr); + } else { + printf("%-8u %-15s %-15s %-15s\n", info.id, + attach_type_str, + attach_flags_str, + info.name); + } + + close(prog_fd); + return 0; +} + +static int list_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type) +{ + __u32 prog_ids[1024] = {0}; + char *attach_flags_str; + __u32 prog_cnt, iter; + __u32 attach_flags; + char buf[32]; + int ret; + + prog_cnt = ARRAY_SIZE(prog_ids); + ret = bpf_prog_query(cgroup_fd, type, 0, &attach_flags, prog_ids, + &prog_cnt); + if (ret) + return ret; + + if (prog_cnt == 0) + return 0; + + switch (attach_flags) { + case BPF_F_ALLOW_MULTI: + attach_flags_str = "multi"; + break; + case BPF_F_ALLOW_OVERRIDE: + attach_flags_str = "override"; + break; + case 0: + attach_flags_str = ""; + break; + default: + snprintf(buf, sizeof(buf), "unknown(%x)", attach_flags); + attach_flags_str = buf; + } + + for (iter = 0; iter < prog_cnt; iter++) + list_bpf_prog(prog_ids[iter], attach_type_strings[type], + attach_flags_str); + + return 0; +} + +static int do_list(int argc, char **argv) +{ + enum bpf_attach_type type; + int cgroup_fd; + int ret = -1; + + if (argc < 1) { + p_err("too few parameters for cgroup list\n"); + goto exit; + } else if (argc > 1) { + p_err("too many parameters for cgroup list\n"); + goto exit; + } + + cgroup_fd = open(argv[0], O_RDONLY); + if (cgroup_fd < 0) { + p_err("can't open cgroup %s\n", argv[1]); + goto exit; + } + + if (json_output) + jsonw_start_array(json_wtr); + else + printf("%-8s %-15s %-15s %-15s\n", "ID", "AttachType", + "AttachFlags", "Name"); + + for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) { + /* + * Not all attach types may be supported, so it's expected, + * that some requests will fail. + * If we were able to get the list for at least one + * attach type, let's return 0. + */ + if (list_attached_bpf_progs(cgroup_fd, type) == 0) + ret = 0; + } + + if (json_output) + jsonw_end_array(json_wtr); + + close(cgroup_fd); +exit: + return ret; +} + +static int do_attach(int argc, char **argv) +{ + enum bpf_attach_type attach_type; + int cgroup_fd, prog_fd; + int attach_flags = 0; + int ret = -1; + int i; + + if (argc < 4) { + p_err("too few parameters for cgroup attach\n"); + goto exit; + } + + cgroup_fd = open(argv[0], O_RDONLY); + if (cgroup_fd < 0) { + p_err("can't open cgroup %s\n", argv[1]); + goto exit; + } + + attach_type = parse_attach_type(argv[1]); + if (attach_type == __MAX_BPF_ATTACH_TYPE) { + p_err("invalid attach type\n"); + goto exit_cgroup; + } + + argc -= 2; + argv = &argv[2]; + prog_fd = prog_parse_fd(&argc, &argv); + if (prog_fd < 0) + goto exit_cgroup; + + for (i = 0; i < argc; i++) { + if (is_prefix(argv[i], "multi")) { + attach_flags |= BPF_F_ALLOW_MULTI; + } else if (is_prefix(argv[i], "override")) { + attach_flags |= BPF_F_ALLOW_OVERRIDE; + } else { + p_err("unknown option: %s\n", argv[i]); + goto exit_cgroup; + } + } + + if (bpf_prog_attach(prog_fd, cgroup_fd, attach_type, attach_flags)) { + p_err("failed to attach program"); + goto exit_prog; + } + + if (json_output) + jsonw_null(json_wtr); + + ret = 0; + +exit_prog: + close(prog_fd); +exit_cgroup: + close(cgroup_fd); +exit: + return ret; +} + +static int do_detach(int argc, char **argv) +{ + enum bpf_attach_type attach_type; + int prog_fd, cgroup_fd; + int ret = -1; + + if (argc < 4) { + p_err("too few parameters for cgroup detach\n"); + goto exit; + } + + cgroup_fd = open(argv[0], O_RDONLY); + if (cgroup_fd < 0) { + p_err("can't open cgroup %s\n", argv[1]); + goto exit; + } + + attach_type = parse_attach_type(argv[1]); + if (attach_type == __MAX_BPF_ATTACH_TYPE) { + p_err("invalid attach type"); + goto exit_cgroup; + } + + argc -= 2; + argv = &argv[2]; + prog_fd = prog_parse_fd(&argc, &argv); + if (prog_fd < 0) + goto exit_cgroup; + + if (bpf_prog_detach2(prog_fd, cgroup_fd, attach_type)) { + p_err("failed to detach program"); + goto exit_prog; + } + + if (json_output) + jsonw_null(json_wtr); + + ret = 0; + +exit_prog: + close(prog_fd); +exit_cgroup: + close(cgroup_fd); +exit: + return ret; +} + +static int do_help(int argc, char **argv) +{ + if (json_output) { + jsonw_null(json_wtr); + return 0; + } + + fprintf(stderr, + "Usage: %s %s list CGROUP\n" + " %s %s attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS]\n" + " %s %s detach CGROUP ATTACH_TYPE PROG\n" + " %s %s help\n" + "\n" + " " HELP_SPEC_ATTACH_TYPES "\n" + " " HELP_SPEC_ATTACH_FLAGS "\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]); + + return 0; +} + +static const struct cmd cmds[] = { + { "list", do_list }, + { "attach", do_attach }, + { "detach", do_detach }, + { "help", do_help }, + { 0 } +}; + +int do_cgroup(int argc, char **argv) +{ + return cmd_select(cmds, argc, argv, do_help); +} diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c index d294bc8168be..ecd53ccf1239 100644 --- a/tools/bpf/bpftool/main.c +++ b/tools/bpf/bpftool/main.c @@ -85,7 +85,7 @@ static int do_help(int argc, char **argv) " %s batch file FILE\n" " %s version\n" "\n" - " OBJECT := { prog | map }\n" + " OBJECT := { prog | map | cgroup }\n" " " HELP_SPEC_OPTIONS "\n" "", bin_name, bin_name, bin_name); @@ -173,6 +173,7 @@ static const struct cmd cmds[] = { { "batch", do_batch }, { "prog", do_prog }, { "map", do_map }, + { "cgroup", do_cgroup }, { "version", do_version }, { 0 } }; diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h index bec1ccbb49c7..8f6d3cac0347 100644 --- a/tools/bpf/bpftool/main.h +++ b/tools/bpf/bpftool/main.h @@ -115,6 +115,7 @@ int do_pin_fd(int fd, const char *name); int do_prog(int argc, char **arg); int do_map(int argc, char **arg); +int do_cgroup(int argc, char **arg); int prog_parse_fd(int *argc, char ***argv); -- 2.14.3