From patchwork Wed Mar 17 12:54:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Machata X-Patchwork-Id: 403778 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 07F40C43381 for ; Wed, 17 Mar 2021 12:56:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BDA9664F73 for ; Wed, 17 Mar 2021 12:56:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230287AbhCQMzb (ORCPT ); Wed, 17 Mar 2021 08:55:31 -0400 Received: from mail-bn8nam11on2078.outbound.protection.outlook.com ([40.107.236.78]:64321 "EHLO NAM11-BN8-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S230154AbhCQMzK (ORCPT ); Wed, 17 Mar 2021 08:55:10 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TxGC9H3TJViSCkaxXk3MwYbJqJHnSXxnVMZ6e/aYXzH9is4dWPOHsXP1JT7Q0/vNn8cdKdZHI4VSYNO4LJAQj7+c8EVW0WdtLxClzBfUKVcGKt6E+pEhP0ngZKZS9LlaEEmjaZwXnEAwjGpN2pI7RnRdTbDgcebEZJbLKdYFszU2lGbEHNH97gOiqK/zywgDNZVMIWPcXsIXegMR9mZGfO0v8WsOWJz8GYdlWcuBaiuKAz0kI33MdfwyJqjdjSFPb69Iu4inR336o6x4X7g/+DeHj4/ZhHWCwrb7L3Oi1egnpJYhwbluOOn1ip77v3JFIF3tlIkkr+ctuC2JhIuaPg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qOLvHl37FTBu4aiyVABEztfa+PmHInU/IFkoTG2qzfE=; b=f/30519LtIE7GmqVNVxt+WfX1Z6DNPhDwzBYMC569UvWRR4n+FdZyv0BEAkGK90g+fVvi/XidUJvaWA6z7MNEWnWO4PNuU4VD2x5G4PW7l/Ye4AgNhgCFclwv4KC8keaI6ujpP8uaUOuUY1ZXUGWisHRqBr9ibavfgmQ01HD7xBa20VutuPFHeHKMIs+n5nCNUaCVGKNA6JzqeBZ4KUIPV0Kj+tZSB5dPTK1A8GaX9YOx0PzUfb3QffFoggrwP/3gW6o8LcSG2CPwgZg6+SQO6Q/3BWxnJfSW+g1UzMYfKSO4aXEzpCGukzeB8qJDUh4/tO3kFrK3wgLOsEhGkshug== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=networkplumber.org smtp.mailfrom=nvidia.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qOLvHl37FTBu4aiyVABEztfa+PmHInU/IFkoTG2qzfE=; b=nBPMEZFIi0MbVBi19gsIWOALl7WrbCPMIJWmEVBnG77TDaPcy+/yxFItflSGi3e+Q2JaUyIfxGviYm6JuvKzbrMWzWy2xsaR0McRfhITY5dd+OIuAxyGLFD2qr+tZktsG+L3QVWudBfR0pcvtj7rwwicYhQhNEEi4y3NFfITi3sOPNVA9l8e9JXMz8niXeaJAh9qLu2txT5F/hLKdM2aAP1dlnbH30QkWRkMAy1PyN53hKbo9hSDgAP7fvyCna5pruK+RM/6bXlHUkKQyhNEcc5XoyXyXPZqAM5YswtDUQPhuMbUe8NNWYY+/My/vHNXLHVSBZ6dTuPhdyVreRUsSg== Received: from DM3PR11CA0015.namprd11.prod.outlook.com (2603:10b6:0:54::25) by BYAPR12MB2725.namprd12.prod.outlook.com (2603:10b6:a03:6b::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3933.32; Wed, 17 Mar 2021 12:55:08 +0000 Received: from DM6NAM11FT057.eop-nam11.prod.protection.outlook.com (2603:10b6:0:54:cafe::21) by DM3PR11CA0015.outlook.office365.com (2603:10b6:0:54::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3955.18 via Frontend Transport; Wed, 17 Mar 2021 12:55:08 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; networkplumber.org; dkim=none (message not signed) header.d=none;networkplumber.org; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by DM6NAM11FT057.mail.protection.outlook.com (10.13.172.252) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.3955.18 via Frontend Transport; Wed, 17 Mar 2021 12:55:08 +0000 Received: from localhost.localdomain (172.20.145.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 17 Mar 2021 12:55:05 +0000 From: Petr Machata To: , , CC: Ido Schimmel , Petr Machata Subject: [PATCH iproute2-next v4 2/6] json_print: Add print_tv() Date: Wed, 17 Mar 2021 13:54:31 +0100 Message-ID: X-Mailer: git-send-email 2.26.2 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [172.20.145.6] X-ClientProxiedBy: HQMAIL101.nvidia.com (172.20.187.10) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 6cf376af-7b6b-4408-6dd1-08d8e943e4c0 X-MS-TrafficTypeDiagnostic: BYAPR12MB2725: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:3513; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: xerhwkekUdE6vEYnLQNfosROeLFtuZGyNzHVEoGfvdYU57Nb72D7D+jaT2TeX5jIq0WYHBnliVvx1cqa9Npmm/iiqexw5nY/EkUC9HYUXVhZg/xKJX0uJ4MsV8yJt5k4liclytAp1Cx0caBnhf0e6F3SzqSIvtegLUjxRTYGDALOBAopXmSAJVN39DWLwZhfffyDFWZmIj2Bhqz4hR5x6lN6ZvBSGOn4eyqfCBQqJIYZYW6SdHDI2lps/wgVdZe8e21El3ylO5kwhohTIYM9iLBkUbdPHHefyKlWtxH3sonELGORZmTqTtuOzjTEj7JLC8glYq6obYM8mcomLXjeATxvez2U+anBVtjWaQmsLQr209WrqGeTlokTlh0mM40hVX1qEBs4ClUtf5Kp884PXj4q2FyeZvqu/rP9mAVycGmLqQi6NS56WgibN6IsPoO/fTHZfXWazxbKJncGGQLu0Zm+4Ou+0kI2istUcmCwIWiA9KklD8bNu4RFCus93RPeq6i3sxBsnbxkYC5bH015vXShCNO3HTUOKhLkC8BFdtu6mvkZmONMUBpYXNlGcubU3DbrwTtARIFUO0pDqyKTL7tflSOqMl1OaYlYLFif8pBAJbDJvKxUWzgKRQnbya6D4W1Q+5Z5v/g2Y5gIdbd38+YQzlZ8sG8BtU5ji8tyJrQRZrd5Ejycl7KlCh18yp5O X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(136003)(376002)(39860400002)(346002)(396003)(46966006)(36840700001)(6666004)(356005)(70586007)(2906002)(70206006)(86362001)(82740400003)(47076005)(36860700001)(36756003)(5660300002)(34020700004)(7636003)(8936002)(2616005)(8676002)(16526019)(426003)(26005)(186003)(110136005)(4326008)(36906005)(478600001)(316002)(107886003)(54906003)(336012)(82310400003); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Mar 2021 12:55:08.1682 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6cf376af-7b6b-4408-6dd1-08d8e943e4c0 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: DM6NAM11FT057.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR12MB2725 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add a helper to dump a timeval. Print by first converting to double and then dispatching to print_color_float(). Signed-off-by: Petr Machata --- Notes: v4: - Make print_tv() take a const*. include/json_print.h | 1 + lib/json_print.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/json_print.h b/include/json_print.h index 6fcf9fd910ec..91b34571ceb0 100644 --- a/include/json_print.h +++ b/include/json_print.h @@ -81,6 +81,7 @@ _PRINT_FUNC(0xhex, unsigned long long) _PRINT_FUNC(luint, unsigned long) _PRINT_FUNC(lluint, unsigned long long) _PRINT_FUNC(float, double) +_PRINT_FUNC(tv, const struct timeval *) #undef _PRINT_FUNC #define _PRINT_NAME_VALUE_FUNC(type_name, type, format_char) \ diff --git a/lib/json_print.c b/lib/json_print.c index 994a2f8d6ae0..e3a88375fe7c 100644 --- a/lib/json_print.c +++ b/lib/json_print.c @@ -299,6 +299,19 @@ int print_color_null(enum output_type type, return ret; } +int print_color_tv(enum output_type type, + enum color_attr color, + const char *key, + const char *fmt, + const struct timeval *tv) +{ + double usecs = tv->tv_usec; + double secs = tv->tv_sec; + double time = secs + usecs / 1000000; + + return print_color_float(type, color, key, fmt, time); +} + /* Print line separator (if not in JSON mode) */ void print_nl(void) { From patchwork Wed Mar 17 12:54:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Machata X-Patchwork-Id: 403776 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ECD3FC43333 for ; Wed, 17 Mar 2021 12:56:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BB07664F70 for ; Wed, 17 Mar 2021 12:56:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230346AbhCQMzf (ORCPT ); Wed, 17 Mar 2021 08:55:35 -0400 Received: from mail-dm6nam12on2086.outbound.protection.outlook.com ([40.107.243.86]:53771 "EHLO NAM12-DM6-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S229964AbhCQMzX (ORCPT ); Wed, 17 Mar 2021 08:55:23 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=DLHOfaLTe7ecQpDCRnD3JhWRIZYF++jT3AfKuzDUqLQEsgocBJ0d8pbE+aKeOi1OnRX0ncJIcZf38RAOWTJcArSJgup8DQLzUjLav5qDU2oN9GXO9cDS+fP9f9MTdnxV9DZNymFuK4yTKgvhzxgrw6tXuXGkuH2bQqT7tEK+lYuiKrRFyjr6sWrXqIpIqdWm6w/JNo2yHKGPvXxlw344+cRSFnnpj0CdM8SVPi2OctTBK1nOeWffcCXr3Q/deQbMnheCmOKlvUFITzSKFB0bTVhfFk71UxitLOxcXLByUUG/5vT6DuA1JfkmpRHkBzYlUz86zkKc0Rwi1OmiynXJzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XumUI+ja+nEBsrt0qqJHPUnSTG9CpLjnoVMhB+IatzE=; b=oQThBnQIdpW/ICKRZLkjwnJNbVSm/GpuDWOL+Lt2IBYsh6rp32fQm/u7g6eQDKmyVxVcnm5TuXpAsjeglgfyVpiApPRcCMTKp3mLjPD4vS/K3UCZMuzQM62OJymKA8Fgucs2vY+VmIqwngi7Tg5xJoUqI8zC+8KLBqModac+JDc6PfI4wk3uv5vBr6MAg9GEPE8vJ5RZyayl1T7RmmN0CympIRwvfFxXTdt4IDUDirxT+VoWLiqiUSznTaU8yYwM4NpuFNUIgNMmGTzZWLamx1u0+IwibRpDchRMChFG3G2zchJsDBGhdZTeH46jOmgnlaVgnQ9iAWQYSJc1CQwatA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=networkplumber.org smtp.mailfrom=nvidia.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XumUI+ja+nEBsrt0qqJHPUnSTG9CpLjnoVMhB+IatzE=; b=iMJBVrFCQcl7hSxh6/GeGTTpgrLkAbm5+PH1wEMaAB1wI285OZDwuZbaPQewmP7GmnmZcFaJ9srsuYC4uGWrmMnV/0D1b+z2ybiyfL2l44WsH/w1Z27FiUtaXlqpq68lf0Ky3XR6g6Wr99n+k0kg6zt6VI9AxU912+lkYNZ2c5mS4z2JlHrkNwYb22tiCUGeY08eNQ2l0dkdc2f1EoAJjOXeCIAojMhx/Zbg3C7u/A/naA42mHkyFuRktbVNheGkuWCHkZh3RE/4t5HjbSVL3E666xMr/6cA/9lP8iVZLU93VIcaLf8uB+6DXpUfPj+dblvMK98N2oObo1Q97pp4Sw== Received: from DM6PR06CA0033.namprd06.prod.outlook.com (2603:10b6:5:120::46) by BL0PR12MB4754.namprd12.prod.outlook.com (2603:10b6:208:8e::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3933.31; Wed, 17 Mar 2021 12:55:19 +0000 Received: from DM6NAM11FT061.eop-nam11.prod.protection.outlook.com (2603:10b6:5:120:cafe::74) by DM6PR06CA0033.outlook.office365.com (2603:10b6:5:120::46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3955.18 via Frontend Transport; Wed, 17 Mar 2021 12:55:18 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; networkplumber.org; dkim=none (message not signed) header.d=none;networkplumber.org; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by DM6NAM11FT061.mail.protection.outlook.com (10.13.173.138) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.3955.18 via Frontend Transport; Wed, 17 Mar 2021 12:55:18 +0000 Received: from localhost.localdomain (172.20.145.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 17 Mar 2021 12:55:15 +0000 From: Petr Machata To: , , CC: Ido Schimmel , Petr Machata Subject: [PATCH iproute2-next v4 6/6] nexthop: Add support for nexthop buckets Date: Wed, 17 Mar 2021 13:54:35 +0100 Message-ID: X-Mailer: git-send-email 2.26.2 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [172.20.145.6] X-ClientProxiedBy: HQMAIL101.nvidia.com (172.20.187.10) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 7d264618-626e-49ae-a208-08d8e943eb0a X-MS-TrafficTypeDiagnostic: BL0PR12MB4754: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:549; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: mM7DQhla9U7P84+taob633zz2uIhuZRCkSZshdIlhuzBDztOLU/VMHYtPc1McdKdldyROPwNd71XgN1BXxav5IraXwi/vAf1DbbQgJvpPk6SPTtZCpK6hmLxlkV5ZfskDDft2+oJA23MSR/5/AARxIXxRTss8rjcD+25C75yttvI/4WRUZzuXLFUWb5UYtOPWDsNMoc2YVv6CPnT5pFaMG3D5bieyxkpOfYsrDXXNfOuv/vI3SGdyeDNqxdHWHuO4pswHGUGMeJTBGwYOq1idWsUSQA1M0VEiT9mT8s/ztv0hv0i4q3AVx8Gtk5r7hgVx6diliDVHZskLR9Oy2fE5X4jzTN0DvUVrq98rE1rVt19RwoM+u2hrYxrlbUzU68K+rwtV1ia6HtEznpf4io6yPW8JVBJJ12X6dzPAs6XVw1zfJL3b2erSTYD5M6xioOeZ01Gr66V78Ga0suKm4N79KBHQNbt8BfquBihJ12el/4gjYOBD8hgOtAxRJ35XxN9mxw5elTGED5OFF6PctyOsIs2TjR1H/tZVRmM7ru/HMM5/zw9lPCfRQNAcBTpUD7QaUH5ky5ykdRWk47PdvO2Z4yMgAAUWfdGgsrH30LBV7TLgjJOYNtR97DYHmSR6pCgMJgbDEDp9Hxw0IH2z2NHWU3nCkefblCkcvPnMLcez3PHEAlft2PyLjEfxAP1giSB X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(396003)(376002)(346002)(39860400002)(136003)(46966006)(36840700001)(82310400003)(70586007)(6666004)(70206006)(356005)(34020700004)(2906002)(47076005)(186003)(36860700001)(478600001)(7636003)(336012)(30864003)(16526019)(110136005)(316002)(26005)(82740400003)(8936002)(107886003)(36906005)(54906003)(86362001)(83380400001)(2616005)(8676002)(5660300002)(4326008)(36756003)(426003); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Mar 2021 12:55:18.6869 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 7d264618-626e-49ae-a208-08d8e943eb0a X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: DM6NAM11FT061.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL0PR12MB4754 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ido Schimmel Add ability to dump multiple nexthop buckets and get a specific one. Example: # ip nexthop add id 10 group 1/2 type resilient buckets 8 # ip nexthop id 1 via 192.0.2.2 dev dummy10 scope link id 2 via 192.0.2.19 dev dummy20 scope link id 10 group 1/2 type resilient buckets 8 idle_timer 120 unbalanced_timer 0 unbalanced_time 0 # ip nexthop bucket id 10 index 0 idle_time 28.1 nhid 2 id 10 index 1 idle_time 28.1 nhid 2 id 10 index 2 idle_time 28.1 nhid 2 id 10 index 3 idle_time 28.1 nhid 2 id 10 index 4 idle_time 28.1 nhid 1 id 10 index 5 idle_time 28.1 nhid 1 id 10 index 6 idle_time 28.1 nhid 1 id 10 index 7 idle_time 28.1 nhid 1 # ip nexthop bucket show nhid 1 id 10 index 4 idle_time 53.59 nhid 1 id 10 index 5 idle_time 53.59 nhid 1 id 10 index 6 idle_time 53.59 nhid 1 id 10 index 7 idle_time 53.59 nhid 1 # ip nexthop bucket get id 10 index 5 id 10 index 5 idle_time 81 nhid 1 # ip -j -p nexthop bucket get id 10 index 5 [ { "id": 10, "bucket": { "index": 5, "idle_time": 104.89, "nhid": 1 }, "flags": [ ] } ] Signed-off-by: Ido Schimmel Signed-off-by: Petr Machata --- include/libnetlink.h | 3 + ip/ip_common.h | 1 + ip/ipmonitor.c | 6 + ip/ipnexthop.c | 254 ++++++++++++++++++++++++++++++++++++++++++ lib/libnetlink.c | 26 +++++ man/man8/ip-nexthop.8 | 45 ++++++++ 6 files changed, 335 insertions(+) diff --git a/include/libnetlink.h b/include/libnetlink.h index b9073a6a13ad..e8ed5d7fb495 100644 --- a/include/libnetlink.h +++ b/include/libnetlink.h @@ -97,6 +97,9 @@ int rtnl_dump_request_n(struct rtnl_handle *rth, struct nlmsghdr *n) int rtnl_nexthopdump_req(struct rtnl_handle *rth, int family, req_filter_fn_t filter_fn) __attribute__((warn_unused_result)); +int rtnl_nexthop_bucket_dump_req(struct rtnl_handle *rth, int family, + req_filter_fn_t filter_fn) + __attribute__((warn_unused_result)); struct rtnl_ctrl_data { int nsid; diff --git a/ip/ip_common.h b/ip/ip_common.h index 9a31e837563f..55a5521c4275 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -53,6 +53,7 @@ int print_rule(struct nlmsghdr *n, void *arg); int print_netconf(struct rtnl_ctrl_data *ctrl, struct nlmsghdr *n, void *arg); int print_nexthop(struct nlmsghdr *n, void *arg); +int print_nexthop_bucket(struct nlmsghdr *n, void *arg); void netns_map_init(void); void netns_nsid_socket_init(void); int print_nsid(struct nlmsghdr *n, void *arg); diff --git a/ip/ipmonitor.c b/ip/ipmonitor.c index 99f5fda8ba1f..d7f31cf5d1b5 100644 --- a/ip/ipmonitor.c +++ b/ip/ipmonitor.c @@ -90,6 +90,12 @@ static int accept_msg(struct rtnl_ctrl_data *ctrl, print_nexthop(n, arg); return 0; + case RTM_NEWNEXTHOPBUCKET: + case RTM_DELNEXTHOPBUCKET: + print_headers(fp, "[NEXTHOPBUCKET]", ctrl); + print_nexthop_bucket(n, arg); + return 0; + case RTM_NEWLINK: case RTM_DELLINK: ll_remember_index(n, NULL); diff --git a/ip/ipnexthop.c b/ip/ipnexthop.c index 1d50bf7529c4..0263307c49df 100644 --- a/ip/ipnexthop.c +++ b/ip/ipnexthop.c @@ -21,6 +21,8 @@ static struct { unsigned int master; unsigned int proto; unsigned int fdb; + unsigned int id; + unsigned int nhid; } filter; enum { @@ -39,8 +41,11 @@ static void usage(void) "Usage: ip nexthop { list | flush } [ protocol ID ] SELECTOR\n" " ip nexthop { add | replace } id ID NH [ protocol ID ]\n" " ip nexthop { get | del } id ID\n" + " ip nexthop bucket list BUCKET_SELECTOR\n" + " ip nexthop bucket get id ID index INDEX\n" "SELECTOR := [ id ID ] [ dev DEV ] [ vrf NAME ] [ master DEV ]\n" " [ groups ] [ fdb ]\n" + "BUCKET_SELECTOR := SELECTOR | [ nhid ID ]\n" "NH := { blackhole | [ via ADDRESS ] [ dev DEV ] [ onlink ]\n" " [ encap ENCAPTYPE ENCAPHDR ] |\n" " group GROUP [ fdb ] [ type TYPE [ TYPE_ARGS ] ] }\n" @@ -85,6 +90,36 @@ static int nh_dump_filter(struct nlmsghdr *nlh, int reqlen) return 0; } +static int nh_dump_bucket_filter(struct nlmsghdr *nlh, int reqlen) +{ + struct rtattr *nest; + int err = 0; + + err = nh_dump_filter(nlh, reqlen); + if (err) + return err; + + if (filter.id) { + err = addattr32(nlh, reqlen, NHA_ID, filter.id); + if (err) + return err; + } + + if (filter.nhid) { + nest = addattr_nest(nlh, reqlen, NHA_RES_BUCKET); + nest->rta_type |= NLA_F_NESTED; + + err = addattr32(nlh, reqlen, NHA_RES_BUCKET_NH_ID, + filter.nhid); + if (err) + return err; + + addattr_nest_end(nlh, nest); + } + + return err; +} + static struct rtnl_handle rth_del = { .fd = -1 }; static int delete_nexthop(__u32 id) @@ -266,6 +301,33 @@ static void print_nh_res_group(FILE *fp, const struct rtattr *res_grp_attr) close_json_object(); } +static void print_nh_res_bucket(FILE *fp, const struct rtattr *res_bucket_attr) +{ + struct rtattr *tb[NHA_RES_BUCKET_MAX + 1]; + + parse_rtattr_nested(tb, NHA_RES_BUCKET_MAX, res_bucket_attr); + + open_json_object("bucket"); + + if (tb[NHA_RES_BUCKET_INDEX]) + print_uint(PRINT_ANY, "index", "index %u ", + rta_getattr_u16(tb[NHA_RES_BUCKET_INDEX])); + + if (tb[NHA_RES_BUCKET_IDLE_TIME]) { + struct rtattr *rta = tb[NHA_RES_BUCKET_IDLE_TIME]; + struct timeval tv; + + __jiffies_to_tv(&tv, rta_getattr_u64(rta)); + print_tv(PRINT_ANY, "idle_time", "idle_time %g ", &tv); + } + + if (tb[NHA_RES_BUCKET_NH_ID]) + print_uint(PRINT_ANY, "nhid", "nhid %u ", + rta_getattr_u32(tb[NHA_RES_BUCKET_NH_ID])); + + close_json_object(); +} + int print_nexthop(struct nlmsghdr *n, void *arg) { struct nhmsg *nhm = NLMSG_DATA(n); @@ -346,6 +408,50 @@ int print_nexthop(struct nlmsghdr *n, void *arg) return 0; } +int print_nexthop_bucket(struct nlmsghdr *n, void *arg) +{ + struct nhmsg *nhm = NLMSG_DATA(n); + struct rtattr *tb[NHA_MAX+1]; + FILE *fp = (FILE *)arg; + int len; + + if (n->nlmsg_type != RTM_DELNEXTHOPBUCKET && + n->nlmsg_type != RTM_NEWNEXTHOPBUCKET) { + fprintf(stderr, "Not a nexthop bucket: %08x %08x %08x\n", + n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); + return -1; + } + + len = n->nlmsg_len - NLMSG_SPACE(sizeof(*nhm)); + if (len < 0) { + close_json_object(); + fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); + return -1; + } + + parse_rtattr_flags(tb, NHA_MAX, RTM_NHA(nhm), len, NLA_F_NESTED); + + open_json_object(NULL); + + if (n->nlmsg_type == RTM_DELNEXTHOP) + print_bool(PRINT_ANY, "deleted", "Deleted ", true); + + if (tb[NHA_ID]) + print_uint(PRINT_ANY, "id", "id %u ", + rta_getattr_u32(tb[NHA_ID])); + + if (tb[NHA_RES_BUCKET]) + print_nh_res_bucket(fp, tb[NHA_RES_BUCKET]); + + print_rt_flags(fp, nhm->nh_flags); + + print_string(PRINT_FP, NULL, "%s", "\n"); + close_json_object(); + fflush(fp); + + return 0; +} + static int add_nh_group_attr(struct nlmsghdr *n, int maxlen, char *argv) { struct nexthop_grp *grps; @@ -721,6 +827,151 @@ static int ipnh_get(int argc, char **argv) return ipnh_get_id(id); } +static int ipnh_bucket_list(int argc, char **argv) +{ + while (argc > 0) { + if (!matches(*argv, "dev")) { + NEXT_ARG(); + filter.ifindex = ll_name_to_index(*argv); + if (!filter.ifindex) + invarg("Device does not exist\n", *argv); + } else if (!matches(*argv, "master")) { + NEXT_ARG(); + filter.master = ll_name_to_index(*argv); + if (!filter.master) + invarg("Device does not exist\n", *argv); + } else if (matches(*argv, "vrf") == 0) { + NEXT_ARG(); + if (!name_is_vrf(*argv)) + invarg("Invalid VRF\n", *argv); + filter.master = ll_name_to_index(*argv); + if (!filter.master) + invarg("VRF does not exist\n", *argv); + } else if (!strcmp(*argv, "id")) { + NEXT_ARG(); + filter.id = ipnh_parse_id(*argv); + } else if (!strcmp(*argv, "nhid")) { + NEXT_ARG(); + filter.nhid = ipnh_parse_id(*argv); + } else if (matches(*argv, "help") == 0) { + usage(); + } else { + invarg("", *argv); + } + argc--; argv++; + } + + if (rtnl_nexthop_bucket_dump_req(&rth, preferred_family, + nh_dump_bucket_filter) < 0) { + perror("Cannot send dump request"); + return -2; + } + + new_json_obj(json); + + if (rtnl_dump_filter(&rth, print_nexthop_bucket, stdout) < 0) { + fprintf(stderr, "Dump terminated\n"); + return -2; + } + + delete_json_obj(); + fflush(stdout); + + return 0; +} + +static int ipnh_bucket_get_id(__u32 id, __u16 bucket_index) +{ + struct { + struct nlmsghdr n; + struct nhmsg nhm; + char buf[1024]; + } req = { + .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct nhmsg)), + .n.nlmsg_flags = NLM_F_REQUEST, + .n.nlmsg_type = RTM_GETNEXTHOPBUCKET, + .nhm.nh_family = preferred_family, + }; + struct nlmsghdr *answer; + struct rtattr *nest; + + addattr32(&req.n, sizeof(req), NHA_ID, id); + + nest = addattr_nest(&req.n, sizeof(req), NHA_RES_BUCKET); + nest->rta_type |= NLA_F_NESTED; + + addattr16(&req.n, sizeof(req), NHA_RES_BUCKET_INDEX, bucket_index); + + addattr_nest_end(&req.n, nest); + + if (rtnl_talk(&rth, &req.n, &answer) < 0) + return -2; + + new_json_obj(json); + + if (print_nexthop_bucket(answer, (void *)stdout) < 0) { + free(answer); + return -1; + } + + delete_json_obj(); + fflush(stdout); + + free(answer); + + return 0; +} + +static int ipnh_bucket_get(int argc, char **argv) +{ + bool bucket_valid = false; + __u16 bucket_index; + __u32 id = 0; + + while (argc > 0) { + if (!strcmp(*argv, "id")) { + NEXT_ARG(); + id = ipnh_parse_id(*argv); + } else if (!strcmp(*argv, "index")) { + NEXT_ARG(); + if (get_u16(&bucket_index, *argv, 0)) + invarg("invalid bucket index value", *argv); + bucket_valid = true; + } else { + usage(); + } + argc--; argv++; + } + + if (!id || !bucket_valid) { + usage(); + return -1; + } + + return ipnh_bucket_get_id(id, bucket_index); +} + +static int do_ipnh_bucket(int argc, char **argv) +{ + if (argc < 1) + return ipnh_bucket_list(0, NULL); + + if (!matches(*argv, "list") || + !matches(*argv, "show") || + !matches(*argv, "lst")) + return ipnh_bucket_list(argc-1, argv+1); + + if (!matches(*argv, "get")) + return ipnh_bucket_get(argc-1, argv+1); + + if (!matches(*argv, "help")) + usage(); + + fprintf(stderr, + "Command \"%s\" is unknown, try \"ip nexthop help\".\n", *argv); + exit(-1); +} + int do_ipnh(int argc, char **argv) { if (argc < 1) @@ -746,6 +997,9 @@ int do_ipnh(int argc, char **argv) if (!matches(*argv, "flush")) return ipnh_list_flush(argc-1, argv+1, IPNH_FLUSH); + if (!matches(*argv, "bucket")) + return do_ipnh_bucket(argc-1, argv+1); + if (!matches(*argv, "help")) usage(); diff --git a/lib/libnetlink.c b/lib/libnetlink.c index c958aa57d0cd..6885087b34f9 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -282,6 +282,32 @@ int rtnl_nexthopdump_req(struct rtnl_handle *rth, int family, return send(rth->fd, &req, sizeof(req), 0); } +int rtnl_nexthop_bucket_dump_req(struct rtnl_handle *rth, int family, + req_filter_fn_t filter_fn) +{ + struct { + struct nlmsghdr nlh; + struct nhmsg nhm; + char buf[128]; + } req = { + .nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct nhmsg)), + .nlh.nlmsg_type = RTM_GETNEXTHOPBUCKET, + .nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST, + .nlh.nlmsg_seq = rth->dump = ++rth->seq, + .nhm.nh_family = family, + }; + + if (filter_fn) { + int err; + + err = filter_fn(&req.nlh, sizeof(req)); + if (err) + return err; + } + + return send(rth->fd, &req, sizeof(req), 0); +} + int rtnl_addrdump_req(struct rtnl_handle *rth, int family, req_filter_fn_t filter_fn) { diff --git a/man/man8/ip-nexthop.8 b/man/man8/ip-nexthop.8 index c1ac130c2a2f..f81a5910bf22 100644 --- a/man/man8/ip-nexthop.8 +++ b/man/man8/ip-nexthop.8 @@ -28,6 +28,14 @@ ip-nexthop \- nexthop object management .BR "ip nexthop" " { " get " | " del " } id " .I ID +.ti -8 +.BI "ip nexthop bucket list " BUCKET_SELECTOR + +.ti -8 +.BR "ip nexthop bucket get " id +.I ID +.RI "index " INDEX + .ti -8 .IR SELECTOR " := " .RB "[ " id @@ -41,6 +49,12 @@ ip-nexthop \- nexthop object management .BR groups " ] [ " .BR fdb " ]" +.ti -8 +.IR BUCKET_SELECTOR " := " +.IR SELECTOR +.RB " | [ " nhid +.IR ID " ]" + .ti -8 .IR NH " := { " .BR blackhole " | [ " @@ -230,6 +244,37 @@ as show. ip nexthop get id ID get a single nexthop by id +.TP +ip nexthop bucket show +show the contents of the nexthop bucket table or the nexthop buckets +selected by some criteria. +.RS +.TP +.BI id " ID " +.in +0 +show the nexthop buckets that belong to a nexthop group with a given id +.TP +.BI nhid " ID " +.in +0 +show the nexthop buckets that hold a nexthop with a given id +.TP +.BI dev " DEV " +.in +0 +show the nexthop buckets using the given device +.TP +.BI vrf " NAME " +.in +0 +show the nexthop buckets using devices associated with the vrf name +.TP +.BI master " DEV " +.in +0 +show the nexthop buckets using devices enslaved to given master device +.RE + +.TP +ip nexthop bucket get id ID index INDEX +get a single nexthop bucket by nexthop group id and bucket index + .SH EXAMPLES .PP ip nexthop ls