Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1555100/?format=api
{ "id": 1555100, "url": "http://patchwork.ozlabs.org/api/patches/1555100/?format=api", "web_url": "http://patchwork.ozlabs.org/project/openvswitch/patch/20211115025312.786953-5-cmi@nvidia.com/", "project": { "id": 47, "url": "http://patchwork.ozlabs.org/api/projects/47/?format=api", "name": "Open vSwitch", "link_name": "openvswitch", "list_id": "ovs-dev.openvswitch.org", "list_email": "ovs-dev@openvswitch.org", "web_url": "http://openvswitch.org/", "scm_url": "git@github.com:openvswitch/ovs.git", "webscm_url": "https://github.com/openvswitch/ovs", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20211115025312.786953-5-cmi@nvidia.com>", "list_archive_url": null, "date": "2021-11-15T02:53:08", "name": "[ovs-dev,v18,4/8] netdev-offload-tc: Introduce group ID management API", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "57c339dd412a75c6b0c0f23782124b2f7181b2c4", "submitter": { "id": 80086, "url": "http://patchwork.ozlabs.org/api/people/80086/?format=api", "name": "Chris Mi", "email": "cmi@nvidia.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/openvswitch/patch/20211115025312.786953-5-cmi@nvidia.com/mbox/", "series": [ { "id": 271987, "url": "http://patchwork.ozlabs.org/api/series/271987/?format=api", "web_url": "http://patchwork.ozlabs.org/project/openvswitch/list/?series=271987", "date": "2021-11-15T02:53:04", "name": "Add offload support for sFlow", "version": 18, "mbox": "http://patchwork.ozlabs.org/series/271987/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1555100/comments/", "check": "success", "checks": "http://patchwork.ozlabs.org/api/patches/1555100/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<ovs-dev-bounces@openvswitch.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "dev@openvswitch.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "ovs-dev@lists.linuxfoundation.org" ], "Authentication-Results": [ "bilbo.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=Nvidia.com header.i=@Nvidia.com header.a=rsa-sha256\n header.s=selector2 header.b=EP8h1VkC;\n\tdkim-atps=neutral", "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=140.211.166.136; helo=smtp3.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN>)" ], "Received": [ "from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n\t(No client certificate requested)\n\tby bilbo.ozlabs.org (Postfix) with ESMTPS id 4Hsv086dkzz9s5P\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 15 Nov 2021 13:53:44 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby smtp3.osuosl.org (Postfix) with ESMTP id 5582C60772;\n\tMon, 15 Nov 2021 02:53:42 +0000 (UTC)", "from smtp3.osuosl.org ([127.0.0.1])\n\tby localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id DTLfr76Zm_fW; Mon, 15 Nov 2021 02:53:39 +0000 (UTC)", "from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp3.osuosl.org (Postfix) with ESMTPS id B1E80607A2;\n\tMon, 15 Nov 2021 02:53:36 +0000 (UTC)", "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 715E8C002E;\n\tMon, 15 Nov 2021 02:53:36 +0000 (UTC)", "from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 05A77C002E\n for <dev@openvswitch.org>; Mon, 15 Nov 2021 02:53:35 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n by smtp3.osuosl.org (Postfix) with ESMTP id 8B31D60773\n for <dev@openvswitch.org>; Mon, 15 Nov 2021 02:53:31 +0000 (UTC)", "from smtp3.osuosl.org ([127.0.0.1])\n by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n with ESMTP id rTOZBt4PDY-v for <dev@openvswitch.org>;\n Mon, 15 Nov 2021 02:53:29 +0000 (UTC)", "from NAM12-BN8-obe.outbound.protection.outlook.com\n (mail-bn8nam12on2080.outbound.protection.outlook.com [40.107.237.80])\n by smtp3.osuosl.org (Postfix) with ESMTPS id 882B660752\n for <dev@openvswitch.org>; Mon, 15 Nov 2021 02:53:29 +0000 (UTC)", "from DM5PR17CA0056.namprd17.prod.outlook.com (2603:10b6:3:13f::18)\n by DM5PR12MB1306.namprd12.prod.outlook.com (2603:10b6:3:6c::13) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4690.26; Mon, 15 Nov\n 2021 02:53:26 +0000", "from DM6NAM11FT023.eop-nam11.prod.protection.outlook.com\n (2603:10b6:3:13f:cafe::73) by DM5PR17CA0056.outlook.office365.com\n (2603:10b6:3:13f::18) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4690.26 via Frontend\n Transport; Mon, 15 Nov 2021 02:53:26 +0000", "from mail.nvidia.com (216.228.112.34) by\n DM6NAM11FT023.mail.protection.outlook.com (10.13.173.96) with Microsoft SMTP\n Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id\n 15.20.4690.15 via Frontend Transport; Mon, 15 Nov 2021 02:53:25 +0000", "from HQMAIL101.nvidia.com (172.20.187.10) by HQMAIL107.nvidia.com\n (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Mon, 15 Nov\n 2021 02:53:24 +0000", "from dev-r630-03.lab.mtl.com (172.20.187.5) by mail.nvidia.com\n (172.20.187.10) with Microsoft SMTP Server id 15.0.1497.18 via Frontend\n Transport; Mon, 15 Nov 2021 02:53:22 +0000" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "whitelisted by SQLgrey-1.8.0", "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=iBq5xg79Et76IugPFbo26NTjdCzJ/XqR1uFiRQu1OBLrAfRNguvlnxFv8WQB1ESyy/m8Umj7z4srCT0kGGcyiR80dhOBoce7dMvqgYSpUakJ/25CSaZiLTkLaRWNZuUZ2LWqDLmTxG1DpMcT/VUBUjXcCZJ1SU6CdtOBhodQ15a+CPu3R4+pz9BA1koXcSA/bQ6DAtGJfC9uqQqvep5Gt3HxqJtWzE4K5VWdhsxmyffpnSC7RFNdlhjeQTEJ23mznpukCOntRP3FITR6tedaoSihHyNHC4E7mA3eRfz2d6mFva03rs31t9RRxY6EmdseuK8WO1e90MpTIhNyT4xDog==", "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector9901;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=g8n6Feqv5HwPb32oKc52iyN4mo5FZtudAFWE7fkj8sU=;\n b=UHuLm7s5hMHu+mh3CSPHuU8yIDxh8HJA5camu2/zYanD2VS9fRO/Rxe1ShcRZ0mN9Q79Pc6aWlMgVjcBEKVDYbKNBMgDL3t3wVij+sWdW5Glx6a2zQyb4EjERLzGjEVPNAP1TWqvs2RYrplCCw7SYZ8YFU2480FC47nnRYHKLoZR85nyuFMuM3hqVUz5ymCvbfgz9nmtA4+RfRrzYU8X8zeZ423UE1fvH3cCQd+b1bxp0Xu33MjitB0lZOh77THhfrqerlTVPxnjZy4XwYCmMnyAFmsXCcC2MkJUv7AMjyliPOc3M/aus9KoMSvYWbrwvIv4MMGIpHKHnLyztIrZfw==", "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 216.228.112.34) smtp.rcpttodomain=ovn.org smtp.mailfrom=nvidia.com;\n dmarc=pass (p=quarantine sp=quarantine pct=100) action=none\n header.from=nvidia.com; dkim=none (message not signed); arc=none", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com;\n s=selector2;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=g8n6Feqv5HwPb32oKc52iyN4mo5FZtudAFWE7fkj8sU=;\n b=EP8h1VkC9iBcIcq7R1pzjF22jFReGQM4z3aNDed8z+gVJ3tRUH31DssoiCvae3P1T0MqQPOFbmogxbe7NNBDpqRGwyYXb4nkrhb+W9AVI2Pek1I86bVKSKKG54otryRZsRFl2B/yn9KyZ7cZQa6ESbGjCgoBHq9xtmvGaiV9GrlIudvLkUgfuGS2+khOGoaUR/C2ZEJhPzihNTdxu7IY51Visk96M86wwraZiQxMgjwDmS/wGSCYNNyi46oSe+TJ3swoCtitNLVKIz1hDk/y1nj+cSM36rriwRY3yzRW+s1c0vKeWm4EBQm+HAK4ljoTySLRxIbfvchv9w2xsg9hcw==", "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 216.228.112.34)\n smtp.mailfrom=nvidia.com; dkim=none (message not signed)\n header.d=none;dmarc=pass action=none header.from=nvidia.com;", "Received-SPF": "Pass (protection.outlook.com: domain of nvidia.com designates\n 216.228.112.34 as permitted sender) receiver=protection.outlook.com;\n client-ip=216.228.112.34; helo=mail.nvidia.com;", "To": "<dev@openvswitch.org>", "Date": "Mon, 15 Nov 2021 10:53:08 +0800", "Message-ID": "<20211115025312.786953-5-cmi@nvidia.com>", "X-Mailer": "git-send-email 2.30.2", "In-Reply-To": "<20211115025312.786953-1-cmi@nvidia.com>", "References": "<20211115025312.786953-1-cmi@nvidia.com>", "MIME-Version": "1.0", "X-EOPAttributedMessage": "0", "X-MS-PublicTrafficType": "Email", "X-MS-Office365-Filtering-Correlation-Id": "fd3ec014-ab66-4e57-24e3-08d9a7e31821", "X-MS-TrafficTypeDiagnostic": "DM5PR12MB1306:", "X-Microsoft-Antispam-PRVS": "\n <DM5PR12MB13062D91E9A98D9E6B20BD7DCF989@DM5PR12MB1306.namprd12.prod.outlook.com>", "X-MS-Oob-TLC-OOBClassifiers": "OLM:7219;", "X-MS-Exchange-SenderADCheck": "1", "X-MS-Exchange-AntiSpam-Relay": "0", "X-Microsoft-Antispam": "BCL:0;", "X-Microsoft-Antispam-Message-Info": "\n 6MPHWCRXiUp3ndTfXjMUQOtQjKIXAwGmeTfRqhzrnylF9mAZqjLvzrXCPJbQRqj0jFDEkn4SaZTB+jmovsu0JWVkX30zBG8JkAZMJaRzyHdrr+EAxllFwURv3sh4cdA8BGmPzSwNG5jq96A644fPYLV4E56GvcDwlaUfCDadoQlRzlLpfj4fxlWrAioa/hDAes17WmIC/o4Df2w3RToc0rrrrLrsOntmewMSyODBRPOi7eYUh8W4BvWklZFSQOlHrRS9B7J4piDvtQ/qXyAKVQ3KxwjSAQ6q8SyEANBGnaIrNUIZW4aI9/yaimUaIzHVouyLavJsiRfjVPtL1F7lGrVvgUbQA+eViIJMQLXnLJNA/A9zYlc/oz8V3h2Ev79na/JmS9azuhEUn0idrFvwG+SKfFoyaKloRdAjKPPo5/+mmrk0EH3hGXo0CJ2FYaZM1WeBpVMQbV1EjyvFQz7PECW4/1R6jfLQqTjATHH1XpAy5s38KM6a4lw/vpYYSIcTuvOl3ubTDarAJ0DcvFATVPBGALv/m3ZS32Truy2w2uVl6tQHvyKHRon4eBywRt8jbGcGC/E2Rh4DCuxKz9dSOMgEKHNjxZKB2wkPjOTqIk71iPeOsW8yxptt/KtOEKt0l2tqqARgS5hvpSN4Kgs9ww5XDX+mZKeQ9W0o/2REiIvCCa5Q1cvFvlfERQTFL4+zxKZswKNVXUqp4C4LGIzeug==", "X-Forefront-Antispam-Report": "CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1;\n SRV:;\n IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE;\n SFS:(4636009)(36840700001)(46966006)(54906003)(4326008)(2906002)(36756003)(316002)(83380400001)(70586007)(5660300002)(1076003)(508600001)(70206006)(47076005)(86362001)(36906005)(107886003)(356005)(30864003)(26005)(6666004)(8676002)(426003)(336012)(6916009)(2616005)(82310400003)(36860700001)(8936002)(186003)(7636003);\n DIR:OUT; SFP:1101;", "X-OriginatorOrg": "Nvidia.com", "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "15 Nov 2021 02:53:25.2406 (UTC)", "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n fd3ec014-ab66-4e57-24e3-08d9a7e31821", "X-MS-Exchange-CrossTenant-Id": "43083d15-7273-40c1-b7db-39efd9ccc17a", "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34];\n Helo=[mail.nvidia.com]", "X-MS-Exchange-CrossTenant-AuthSource": "\n DM6NAM11FT023.eop-nam11.prod.protection.outlook.com", "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous", "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem", "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "DM5PR12MB1306", "Cc": "elibr@nvidia.com, simon.horman@netronome.com, roniba@nvidia.com,\n i.maximets@ovn.org", "Subject": "[ovs-dev] [PATCH v18 4/8] netdev-offload-tc: Introduce group ID\n\tmanagement API", "X-BeenThere": "ovs-dev@openvswitch.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "<ovs-dev.openvswitch.org>", "List-Unsubscribe": "<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>", "List-Archive": "<http://mail.openvswitch.org/pipermail/ovs-dev/>", "List-Post": "<mailto:ovs-dev@openvswitch.org>", "List-Help": "<mailto:ovs-dev-request@openvswitch.org?subject=help>", "List-Subscribe": "<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=subscribe>", "From": "Chris Mi via dev <ovs-dev@openvswitch.org>", "Reply-To": "Chris Mi <cmi@nvidia.com>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "ovs-dev-bounces@openvswitch.org", "Sender": "\"dev\" <ovs-dev-bounces@openvswitch.org>" }, "content": "When offloading sample action to TC, userspace creates a unique ID\nto map sFlow action and tunnel info and passes this ID to kernel instead\nof the sFlow info. psample will send this ID and sampled packet to\nuserspace. Using the ID, userspace can recover the sFlow info and send\nsampled packet to the right sFlow monitoring host.\n\nSigned-off-by: Chris Mi <cmi@nvidia.com>\nReviewed-by: Eli Britstein <elibr@nvidia.com>\nAcked-by: Eelco Chaudron <echaudro@redhat.com>\n---\n lib/dpif-offload-provider.h | 17 +++\n lib/netdev-offload-tc.c | 246 +++++++++++++++++++++++++++++++++++-\n lib/netdev-offload.h | 2 +\n lib/tc.h | 1 +\n 4 files changed, 260 insertions(+), 6 deletions(-)", "diff": "diff --git a/lib/dpif-offload-provider.h b/lib/dpif-offload-provider.h\nindex 3b94740df..af49eedb9 100644\n--- a/lib/dpif-offload-provider.h\n+++ b/lib/dpif-offload-provider.h\n@@ -17,9 +17,26 @@\n #ifndef DPIF_OFFLOAD_PROVIDER_H\n #define DPIF_OFFLOAD_PROVIDER_H\n \n+#include \"netlink-protocol.h\"\n+#include \"openvswitch/packets.h\"\n+#include \"openvswitch/types.h\"\n+\n struct dpif;\n struct dpif_offload_sflow;\n \n+/* When offloading sample action, userspace creates a unique ID to map\n+ * sFlow action and tunnel info and passes this ID to datapath instead\n+ * of the sFlow info. Datapath will send this ID and sampled packet to\n+ * userspace. Using the ID, userspace can recover the sFlow info and send\n+ * sampled packet to the right sFlow monitoring host.\n+ */\n+struct dpif_sflow_attr {\n+ const struct nlattr *action; /* SFlow action. */\n+ const struct nlattr *userdata; /* Struct user_action_cookie. */\n+ struct flow_tnl *tunnel; /* Tunnel info. */\n+ ovs_u128 ufid; /* Flow ufid. */\n+};\n+\n /* Datapath interface offload structure, to be defined by each implementation\n * of a datapath interface.\n */\ndiff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c\nindex 9845e8d3f..204d1c833 100644\n--- a/lib/netdev-offload-tc.c\n+++ b/lib/netdev-offload-tc.c\n@@ -40,6 +40,7 @@\n #include \"unaligned.h\"\n #include \"util.h\"\n #include \"dpif-provider.h\"\n+#include \"cmap.h\"\n \n VLOG_DEFINE_THIS_MODULE(netdev_offload_tc);\n \n@@ -62,6 +63,233 @@ struct chain_node {\n uint32_t chain;\n };\n \n+/* This maps a psample group ID to struct dpif_sflow_attr for sFlow */\n+struct sgid_node {\n+ struct ovs_list exp_node OVS_GUARDED;\n+ struct cmap_node metadata_node;\n+ struct cmap_node id_node;\n+ struct ovs_refcount refcount;\n+ uint32_t hash;\n+ uint32_t id;\n+ const struct dpif_sflow_attr sflow;\n+};\n+\n+static struct ovs_rwlock sgid_rwlock = OVS_RWLOCK_INITIALIZER;\n+static struct cmap sgid_map = CMAP_INITIALIZER;\n+static struct cmap sgid_metadata_map = CMAP_INITIALIZER;\n+static struct ovs_list sgid_expiring OVS_GUARDED_BY(sgid_rwlock)\n+ = OVS_LIST_INITIALIZER(&sgid_expiring);\n+static uint32_t next_sample_group_id OVS_GUARDED_BY(sgid_rwlock) = 1;\n+\n+static void\n+sgid_node_free(struct sgid_node *node)\n+{\n+ free(node->sflow.tunnel);\n+ free(CONST_CAST(void *, node->sflow.action));\n+ free(CONST_CAST(void *, node->sflow.userdata));\n+ free(node);\n+}\n+\n+/* Lockless RCU protected lookup. If node is needed accross RCU quiescent\n+ * state, caller should copy the contents. */\n+static const struct sgid_node *\n+sgid_find(uint32_t id)\n+{\n+ const struct cmap_node *node = cmap_find(&sgid_map, id);\n+\n+ return node ? CONTAINER_OF(node, const struct sgid_node, id_node) : NULL;\n+}\n+\n+const struct dpif_sflow_attr *\n+dpif_offload_sflow_attr_find(uint32_t id)\n+{\n+ const struct sgid_node *node;\n+\n+ node = sgid_find(id);\n+ if (!node) {\n+ return NULL;\n+ }\n+\n+ return &node->sflow;\n+}\n+\n+static uint32_t\n+dpif_sflow_attr_hash(const struct dpif_sflow_attr *sflow)\n+{\n+ return hash_bytes(&sflow->ufid, sizeof sflow->ufid, 0);\n+}\n+\n+static bool\n+dpif_sflow_attr_equal(const struct dpif_sflow_attr *a,\n+ const struct dpif_sflow_attr *b)\n+{\n+ if (!ovs_u128_equals(a->ufid, b->ufid)) {\n+ return false;\n+ }\n+ if (!a->action || !b->action) {\n+ return false;\n+ }\n+ if (a->action->nla_len != b->action->nla_len\n+ || memcmp(a->action, b->action, a->action->nla_len)) {\n+ return false;\n+ }\n+ if (!a->tunnel && !b->tunnel) {\n+ return true;\n+ }\n+ if (!a->tunnel || !b->tunnel) {\n+ return false;\n+ }\n+\n+ return !memcmp(a->tunnel, b->tunnel, sizeof *a->tunnel);\n+}\n+\n+/* Lockless RCU protected lookup. If node is needed accross RCU quiescent\n+ * state, caller should take a reference. */\n+static struct sgid_node *\n+sgid_find_equal(const struct dpif_sflow_attr *target, uint32_t hash)\n+{\n+ struct sgid_node *node;\n+\n+ CMAP_FOR_EACH_WITH_HASH (node, metadata_node, hash, &sgid_metadata_map) {\n+ if (dpif_sflow_attr_equal(&node->sflow, target)) {\n+ return node;\n+ }\n+ }\n+ return NULL;\n+}\n+\n+static struct sgid_node *\n+sgid_ref_equal(const struct dpif_sflow_attr *target, uint32_t hash)\n+{\n+ struct sgid_node *node;\n+\n+ do {\n+ node = sgid_find_equal(target, hash);\n+ /* Try again if the node was released before we get the reference. */\n+ } while (node && !ovs_refcount_try_ref_rcu(&node->refcount));\n+\n+ return node;\n+}\n+\n+static void\n+dpif_sflow_attr_clone(struct dpif_sflow_attr *new,\n+ const struct dpif_sflow_attr *old)\n+{\n+ new->action = xmemdup(old->action, old->action->nla_len);\n+ new->userdata = xmemdup(old->userdata, old->userdata->nla_len);\n+ new->tunnel = old->tunnel\n+ ? xmemdup(old->tunnel, sizeof *old->tunnel)\n+ : NULL;\n+ new->ufid = old->ufid;\n+}\n+\n+/* We use the id as the hash value, which works due to cmap internal rehashing.\n+ * We also only insert nodes with unique IDs, so all possible hash collisions\n+ * remain internal to the cmap. */\n+static struct sgid_node *\n+sgid_find__(uint32_t id)\n+ OVS_REQUIRES(sgid_rwlock)\n+{\n+ struct cmap_node *node = cmap_find_protected(&sgid_map, id);\n+\n+ return node ? CONTAINER_OF(node, struct sgid_node, id_node) : NULL;\n+}\n+\n+/* Allocate a unique group id for the given set of flow metadata. The id\n+ * space is 2^^32, but if looping too many times, we still can't find a\n+ * free one, that means something is wrong, return NULL.\n+ */\n+#define SGID_ALLOC_RETRY_MAX 8192\n+static struct sgid_node *\n+sgid_alloc__(const struct dpif_sflow_attr *sflow, uint32_t hash)\n+{\n+ struct sgid_node *node = xzalloc(sizeof *node);\n+ int i = 0;\n+\n+ node->hash = hash;\n+ ovs_refcount_init(&node->refcount);\n+ dpif_sflow_attr_clone(CONST_CAST(struct dpif_sflow_attr *,\n+ &node->sflow), sflow);\n+\n+ ovs_rwlock_wrlock(&sgid_rwlock);\n+ for (;;) {\n+ node->id = next_sample_group_id++;\n+ if (OVS_UNLIKELY(!node->id)) {\n+ next_sample_group_id = 1;\n+ node->id = next_sample_group_id++;\n+ }\n+ /* Find if the id is free. */\n+ if (OVS_LIKELY(!sgid_find__(node->id))) {\n+ break;\n+ }\n+ if (++i == SGID_ALLOC_RETRY_MAX) {\n+ VLOG_ERR(\"Can't find a free group ID after %d retries\", i);\n+ ovs_rwlock_unlock(&sgid_rwlock);\n+ sgid_node_free(node);\n+ return NULL;\n+ }\n+ }\n+ cmap_insert(&sgid_map, &node->id_node, node->id);\n+ cmap_insert(&sgid_metadata_map, &node->metadata_node, node->hash);\n+ ovs_rwlock_unlock(&sgid_rwlock);\n+ return node;\n+}\n+\n+/* Allocate a unique group id for the given set of flow metadata and\n+ optional actions. */\n+static uint32_t\n+sgid_alloc_ctx(const struct dpif_sflow_attr *sflow)\n+{\n+ uint32_t hash = dpif_sflow_attr_hash(sflow);\n+ struct sgid_node *node = sgid_ref_equal(sflow, hash);\n+\n+ if (!node) {\n+ node = sgid_alloc__(sflow, hash);\n+ }\n+\n+ return node ? node->id : 0;\n+}\n+\n+static void\n+sgid_node_unref(const struct sgid_node *node_)\n+ OVS_EXCLUDED(sgid_rwlock)\n+{\n+ struct sgid_node *node = CONST_CAST(struct sgid_node *, node_);\n+\n+ ovs_rwlock_wrlock(&sgid_rwlock);\n+ if (node && ovs_refcount_unref(&node->refcount) == 1) {\n+ cmap_remove(&sgid_metadata_map, &node->metadata_node, node->hash);\n+ cmap_remove(&sgid_map, &node->id_node, node->id);\n+ ovsrcu_postpone(sgid_node_free, node);\n+ }\n+ ovs_rwlock_unlock(&sgid_rwlock);\n+}\n+\n+static void\n+sgid_free(uint32_t id)\n+{\n+ const struct sgid_node *node;\n+\n+ if (!id) {\n+ return;\n+ }\n+\n+ node = sgid_find(id);\n+ if (node) {\n+ sgid_node_unref(node);\n+ } else {\n+ VLOG_ERR(\"Freeing nonexistent group ID: %\"PRIu32, id);\n+ }\n+}\n+\n+static int\n+del_filter_and_sgid(struct tcf_id *id)\n+{\n+ sgid_free(id->sample_group_id);\n+ id->sample_group_id = 0;\n+ return tc_del_filter(id);\n+}\n+\n static bool\n is_internal_port(const char *type)\n {\n@@ -198,13 +426,13 @@ del_ufid_tc_mapping(const ovs_u128 *ufid)\n ovs_mutex_unlock(&ufid_lock);\n }\n \n-/* Wrapper function to delete filter and ufid tc mapping */\n+/* Wrapper function to delete filter, sgid and ufid tc mapping */\n static int\n-del_filter_and_ufid_mapping(struct tcf_id *id, const ovs_u128 *ufid)\n+del_filter_sgid_ufid_mapping(struct tcf_id *id, const ovs_u128 *ufid)\n {\n int err;\n \n- err = tc_del_filter(id);\n+ err = del_filter_and_sgid(id);\n if (!err) {\n del_ufid_tc_mapping(ufid);\n }\n@@ -426,7 +654,7 @@ netdev_tc_flow_flush(struct netdev *netdev)\n continue;\n }\n \n- err = tc_del_filter(&data->id);\n+ err = del_filter_and_sgid(&data->id);\n if (!err) {\n del_ufid_tc_mapping_unlocked(&data->ufid);\n }\n@@ -1917,6 +2145,11 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,\n action->type = TC_ACT_GOTO;\n action->chain = 0; /* 0 is reserved and not used by recirc. */\n flower.action_count++;\n+ } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_SAMPLE) {\n+ struct dpif_sflow_attr sflow_attr;\n+\n+ memset(&sflow_attr, 0, sizeof sflow_attr);\n+ sgid_alloc_ctx(&sflow_attr);\n } else {\n VLOG_DBG_RL(&rl, \"unsupported put action type: %d\",\n nl_attr_type(nla));\n@@ -1932,7 +2165,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,\n if (get_ufid_tc_mapping(ufid, &id) == 0) {\n VLOG_DBG_RL(&rl, \"updating old handle: %d prio: %d\",\n id.handle, id.prio);\n- info->tc_modify_flow_deleted = !del_filter_and_ufid_mapping(&id, ufid);\n+ info->tc_modify_flow_deleted = !del_filter_sgid_ufid_mapping(&id,\n+ ufid);\n }\n \n prio = get_prio_for_tc_flower(&flower);\n@@ -2021,7 +2255,7 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED,\n }\n }\n \n- error = del_filter_and_ufid_mapping(&id, ufid);\n+ error = del_filter_sgid_ufid_mapping(&id, ufid);\n \n return error;\n }\ndiff --git a/lib/netdev-offload.h b/lib/netdev-offload.h\nindex e7fcedae9..c570b4e62 100644\n--- a/lib/netdev-offload.h\n+++ b/lib/netdev-offload.h\n@@ -138,6 +138,8 @@ int netdev_ports_flow_get(const char *dpif_type, struct match *match,\n int netdev_ports_get_n_flows(const char *dpif_type,\n odp_port_t port_no, uint64_t *n_flows);\n \n+const struct dpif_sflow_attr *dpif_offload_sflow_attr_find(uint32_t id);\n+\n #ifdef __cplusplus\n }\n #endif\ndiff --git a/lib/tc.h b/lib/tc.h\nindex a147ca461..2e4084f48 100644\n--- a/lib/tc.h\n+++ b/lib/tc.h\n@@ -276,6 +276,7 @@ struct tcf_id {\n uint32_t chain;\n uint16_t prio;\n uint32_t handle;\n+ uint32_t sample_group_id;\n };\n \n static inline struct tcf_id\n", "prefixes": [ "ovs-dev", "v18", "4/8" ] }