From patchwork Thu Oct 29 11:23:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Mi X-Patchwork-Id: 1390070 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CMNPJ4Rz9z9sSf for ; Thu, 29 Oct 2020 22:24:04 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 4ED8D86C11; Thu, 29 Oct 2020 11:24:02 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ecSouDc7hSsf; Thu, 29 Oct 2020 11:24:00 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 5FF9D86BA6; Thu, 29 Oct 2020 11:23:57 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 389A1C1AD9; Thu, 29 Oct 2020 11:23:57 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 1BA06C1AD8 for ; Thu, 29 Oct 2020 11:23:54 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id DE18087598 for ; Thu, 29 Oct 2020 11:23:53 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yMEf1vVH+tlI for ; Thu, 29 Oct 2020 11:23:52 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id 5044987586 for ; Thu, 29 Oct 2020 11:23:52 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from cmi@nvidia.com) with SMTP; 29 Oct 2020 13:23:46 +0200 Received: from dev-r630-04.mtbc.labs.mlnx (dev-r630-04.mtbc.labs.mlnx [10.75.205.14]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TBNg0c022472; Thu, 29 Oct 2020 13:23:45 +0200 From: Chris Mi To: dev@openvswitch.org Date: Thu, 29 Oct 2020 19:23:29 +0800 Message-Id: <20201029112340.14167-2-cmi@nvidia.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20201029112340.14167-1-cmi@nvidia.com> References: <20201029112340.14167-1-cmi@nvidia.com> MIME-Version: 1.0 Cc: elibr@nvidia.com, Chris Mi , roniba@nvidia.com, i.maximets@ovn.org Subject: [ovs-dev] [PATCH v5 01/12] compat: Add psample and tc sample action defines for older kernels X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Update kernel UAPI to support psample and the tc sample action. Signed-off-by: Chris Mi Reviewed-by: Eli Britstein --- include/linux/automake.mk | 4 ++- include/linux/psample.h | 58 ++++++++++++++++++++++++++++++++ include/linux/tc_act/tc_sample.h | 25 ++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 include/linux/psample.h create mode 100644 include/linux/tc_act/tc_sample.h diff --git a/include/linux/automake.mk b/include/linux/automake.mk index 8f063f482..c48d9699a 100644 --- a/include/linux/automake.mk +++ b/include/linux/automake.mk @@ -7,4 +7,6 @@ noinst_HEADERS += \ include/linux/tc_act/tc_skbedit.h \ include/linux/tc_act/tc_tunnel_key.h \ include/linux/tc_act/tc_vlan.h \ - include/linux/tc_act/tc_ct.h + include/linux/tc_act/tc_ct.h \ + include/linux/tc_act/tc_sample.h \ + include/linux/psample.h diff --git a/include/linux/psample.h b/include/linux/psample.h new file mode 100644 index 000000000..aea26ab14 --- /dev/null +++ b/include/linux/psample.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef __UAPI_PSAMPLE_H +#define __UAPI_PSAMPLE_H + +enum { + /* sampled packet metadata */ + PSAMPLE_ATTR_IIFINDEX, + PSAMPLE_ATTR_OIFINDEX, + PSAMPLE_ATTR_ORIGSIZE, + PSAMPLE_ATTR_SAMPLE_GROUP, + PSAMPLE_ATTR_GROUP_SEQ, + PSAMPLE_ATTR_SAMPLE_RATE, + PSAMPLE_ATTR_DATA, + PSAMPLE_ATTR_TUNNEL, + + /* commands attributes */ + PSAMPLE_ATTR_GROUP_REFCOUNT, + + __PSAMPLE_ATTR_MAX +}; + +enum psample_command { + PSAMPLE_CMD_SAMPLE, + PSAMPLE_CMD_GET_GROUP, + PSAMPLE_CMD_NEW_GROUP, + PSAMPLE_CMD_DEL_GROUP, +}; + +enum psample_tunnel_key_attr { + PSAMPLE_TUNNEL_KEY_ATTR_ID, /* be64 Tunnel ID */ + PSAMPLE_TUNNEL_KEY_ATTR_IPV4_SRC, /* be32 src IP address. */ + PSAMPLE_TUNNEL_KEY_ATTR_IPV4_DST, /* be32 dst IP address. */ + PSAMPLE_TUNNEL_KEY_ATTR_TOS, /* u8 Tunnel IP ToS. */ + PSAMPLE_TUNNEL_KEY_ATTR_TTL, /* u8 Tunnel IP TTL. */ + PSAMPLE_TUNNEL_KEY_ATTR_DONT_FRAGMENT, /* No argument, set DF. */ + PSAMPLE_TUNNEL_KEY_ATTR_CSUM, /* No argument. CSUM packet. */ + PSAMPLE_TUNNEL_KEY_ATTR_OAM, /* No argument. OAM frame. */ + PSAMPLE_TUNNEL_KEY_ATTR_GENEVE_OPTS, /* Array of Geneve options. */ + PSAMPLE_TUNNEL_KEY_ATTR_TP_SRC, /* be16 src Transport Port. */ + PSAMPLE_TUNNEL_KEY_ATTR_TP_DST, /* be16 dst Transport Port. */ + PSAMPLE_TUNNEL_KEY_ATTR_VXLAN_OPTS, /* Nested VXLAN opts* */ + PSAMPLE_TUNNEL_KEY_ATTR_IPV6_SRC, /* struct in6_addr src IPv6 address. */ + PSAMPLE_TUNNEL_KEY_ATTR_IPV6_DST, /* struct in6_addr dst IPv6 address. */ + PSAMPLE_TUNNEL_KEY_ATTR_PAD, + PSAMPLE_TUNNEL_KEY_ATTR_ERSPAN_OPTS, /* struct erspan_metadata */ + PSAMPLE_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE, /* No argument. IPV4_INFO_BRIDGE mode.*/ + __PSAMPLE_TUNNEL_KEY_ATTR_MAX +}; + +/* Can be overridden at runtime by module option */ +#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1) + +#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config" +#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets" +#define PSAMPLE_GENL_NAME "psample" +#define PSAMPLE_GENL_VERSION 1 + +#endif diff --git a/include/linux/tc_act/tc_sample.h b/include/linux/tc_act/tc_sample.h new file mode 100644 index 000000000..fee1bcc20 --- /dev/null +++ b/include/linux/tc_act/tc_sample.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef __LINUX_TC_SAMPLE_H +#define __LINUX_TC_SAMPLE_H + +#include +#include +#include + +struct tc_sample { + tc_gen; +}; + +enum { + TCA_SAMPLE_UNSPEC, + TCA_SAMPLE_TM, + TCA_SAMPLE_PARMS, + TCA_SAMPLE_RATE, + TCA_SAMPLE_TRUNC_SIZE, + TCA_SAMPLE_PSAMPLE_GROUP, + TCA_SAMPLE_PAD, + __TCA_SAMPLE_MAX +}; +#define TCA_SAMPLE_MAX (__TCA_SAMPLE_MAX - 1) + +#endif From patchwork Thu Oct 29 11:23:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Mi X-Patchwork-Id: 1390068 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CMNPC0N7Jz9sSf for ; Thu, 29 Oct 2020 22:23:59 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id E5B3D875A2; Thu, 29 Oct 2020 11:23:56 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id N3b+jUbxIQBV; Thu, 29 Oct 2020 11:23:56 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 3FB16875A4; Thu, 29 Oct 2020 11:23:56 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 1FD4FC1AD8; Thu, 29 Oct 2020 11:23:56 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0EBFCC088B for ; Thu, 29 Oct 2020 11:23:54 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id C024C87597 for ; Thu, 29 Oct 2020 11:23:53 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DT3mqT8Fg1Ah for ; Thu, 29 Oct 2020 11:23:53 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id 529D08758F for ; Thu, 29 Oct 2020 11:23:52 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from cmi@nvidia.com) with SMTP; 29 Oct 2020 13:23:48 +0200 Received: from dev-r630-04.mtbc.labs.mlnx (dev-r630-04.mtbc.labs.mlnx [10.75.205.14]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TBNg0d022472; Thu, 29 Oct 2020 13:23:46 +0200 From: Chris Mi To: dev@openvswitch.org Date: Thu, 29 Oct 2020 19:23:30 +0800 Message-Id: <20201029112340.14167-3-cmi@nvidia.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20201029112340.14167-1-cmi@nvidia.com> References: <20201029112340.14167-1-cmi@nvidia.com> MIME-Version: 1.0 Cc: elibr@nvidia.com, Chris Mi , roniba@nvidia.com, i.maximets@ovn.org Subject: [ovs-dev] [PATCH v5 02/12] ovs-kmod-ctl: Load kernel module psample X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Load kernel module psample to receive sampled packets from TC. Before removing kernel module psample, remove act_sample first. Signed-off-by: Chris Mi Reviewed-by: Eli Britstein --- utilities/ovs-kmod-ctl.in | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/utilities/ovs-kmod-ctl.in b/utilities/ovs-kmod-ctl.in index 19f100964..6fa945a83 100644 --- a/utilities/ovs-kmod-ctl.in +++ b/utilities/ovs-kmod-ctl.in @@ -28,6 +28,14 @@ for dir in "$sbindir" "$bindir" /sbin /bin /usr/sbin /usr/bin; do done insert_mods () { + # Try loading psample kernel module. + modinfo psample > /dev/null 2>&1 + if test $? = 0; then + action "Inserting psample module" modprobe psample + else + log_warning_msg "No psample module, can't offload sFlow action" + fi + # Try loading openvswitch kernel module. action "Inserting openvswitch module" modprobe openvswitch } @@ -95,6 +103,12 @@ remove_kmods() { if test -e /sys/module/vxlan; then action "Forcing removal of vxlan module" rmmod vxlan fi + if test -e /sys/module/act_sample; then + action "Forcing removal of act_sample module" rmmod act_sample + fi + if test -e /sys/module/psample; then + action "Forcing removal of psample module" rmmod psample + fi } usage () { From patchwork Thu Oct 29 11:23:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Mi X-Patchwork-Id: 1390067 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CMNPB08plz9sSP for ; Thu, 29 Oct 2020 22:23:58 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 162F0875A1; Thu, 29 Oct 2020 11:23:56 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id kabdZ5+JNYrt; Thu, 29 Oct 2020 11:23:55 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 507A78759B; Thu, 29 Oct 2020 11:23:55 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 35EA1C088B; Thu, 29 Oct 2020 11:23:55 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 17273C1AD7 for ; Thu, 29 Oct 2020 11:23:54 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id E10898759B for ; Thu, 29 Oct 2020 11:23:53 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id fujVqECkRDa8 for ; Thu, 29 Oct 2020 11:23:52 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id 545D787590 for ; Thu, 29 Oct 2020 11:23:52 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from cmi@nvidia.com) with SMTP; 29 Oct 2020 13:23:50 +0200 Received: from dev-r630-04.mtbc.labs.mlnx (dev-r630-04.mtbc.labs.mlnx [10.75.205.14]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TBNg0e022472; Thu, 29 Oct 2020 13:23:48 +0200 From: Chris Mi To: dev@openvswitch.org Date: Thu, 29 Oct 2020 19:23:31 +0800 Message-Id: <20201029112340.14167-4-cmi@nvidia.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20201029112340.14167-1-cmi@nvidia.com> References: <20201029112340.14167-1-cmi@nvidia.com> MIME-Version: 1.0 Cc: elibr@nvidia.com, Chris Mi , roniba@nvidia.com, i.maximets@ovn.org Subject: [ovs-dev] [PATCH v5 03/12] dpif: Introduce register sFlow upcall callback API X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" When offloading sample action to TC, psample sends the sampled packets to userspace by a netlink message. The thread polling psample socket will translate the psample netlink message to an sFlow format and call the sFlow upcall callback to send the sFlow packet to right monitoring host. Introduce register sFlow upcall callback API. Signed-off-by: Chris Mi Reviewed-by: Eli Britstein --- lib/dpif-netdev.c | 1 + lib/dpif-netlink.c | 1 + lib/dpif-provider.h | 10 ++++++++++ lib/dpif.c | 8 ++++++++ lib/dpif.h | 26 ++++++++++++++++++++++++++ 5 files changed, 46 insertions(+) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 300861ca5..f47a3fdab 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -8426,6 +8426,7 @@ const struct dpif_class dpif_netdev_class = { dpif_netdev_register_upcall_cb, dpif_netdev_enable_upcall, dpif_netdev_disable_upcall, + NULL, /* register_sflow_upcall_cb */ dpif_netdev_get_datapath_version, dpif_netdev_ct_dump_start, dpif_netdev_ct_dump_next, diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 2f881e4fa..3fb992def 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -3978,6 +3978,7 @@ const struct dpif_class dpif_netlink_class = { NULL, /* register_upcall_cb */ NULL, /* enable_upcall */ NULL, /* disable_upcall */ + NULL, /* register_sflow_upcall_cb */ dpif_netlink_get_datapath_version, /* get_datapath_version */ dpif_netlink_ct_dump_start, dpif_netlink_ct_dump_next, diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index b817fceac..589f11be4 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -427,6 +427,16 @@ struct dpif_class { /* Disables upcalls if 'dpif' directly executes upcall functions. */ void (*disable_upcall)(struct dpif *); + /* When offloading sample action, psample sends the sampled packets to + * userspace by a netlink message. The thread polling psample socket + * will translate the psample netlink message to an sFlow format and call + * the sFlow upcall callback to send the sFlow packet to right monitoring + * host. + * + * Registers an upcall callback to process sFlow packet. + */ + void (*register_sflow_upcall_cb)(struct dpif *, sflow_upcall_callback *); + /* Get datapath version. Caller is responsible for freeing the string * returned. */ char *(*get_datapath_version)(void); diff --git a/lib/dpif.c b/lib/dpif.c index ac2860764..6e72b2087 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -1520,6 +1520,14 @@ dpif_disable_upcall(struct dpif *dpif) } } +void +dpif_register_sflow_upcall_cb(struct dpif *dpif, sflow_upcall_callback *cb) +{ + if (dpif->dpif_class->register_sflow_upcall_cb) { + dpif->dpif_class->register_sflow_upcall_cb(dpif, cb); + } +} + void dpif_print_packet(struct dpif *dpif, struct dpif_upcall *upcall) { diff --git a/lib/dpif.h b/lib/dpif.h index cb047dbe2..ed4257210 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -869,6 +869,32 @@ typedef int upcall_callback(const struct dp_packet *packet, void dpif_register_upcall_cb(struct dpif *, upcall_callback *, void *aux); +/* When offloading sample action, userspace creates a unique ID to map + * sFlow action and tunnel info and passes this ID to datapath instead + * of the sFlow info. Datapath will send this ID and sampled packet to + * userspace. Using the ID, userspace can recover the sFlow info and send + * sampled packet to the right sFlow monitoring host. + */ +struct dpif_sflow_attr { + const struct nlattr *sflow; /* sFlow action */ + size_t sflow_len; /* Length of 'sflow' in bytes. */ + + void *userdata; /* struct user_action_cookie */ + size_t userdata_len; /* struct user_action_cookie length */ + + struct flow_tnl *tunnel; /* Tunnel info */ +}; + +/* A sampled packet passed up from datapath to userspace. */ +struct dpif_upcall_sflow { + struct dp_packet packet; /* packet data */ + uint32_t iifindex; /* input ifindex */ + const struct dpif_sflow_attr *sflow_attr; +}; + +typedef int sflow_upcall_callback(struct dpif_upcall_sflow *dupcall); +void dpif_register_sflow_upcall_cb(struct dpif *, sflow_upcall_callback *); + int dpif_recv_set(struct dpif *, bool enable); int dpif_handlers_set(struct dpif *, uint32_t n_handlers); int dpif_set_config(struct dpif *, const struct smap *cfg); From patchwork Thu Oct 29 11:23:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Mi X-Patchwork-Id: 1390071 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=whitealder.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CMNPN3p1bz9sSC for ; Thu, 29 Oct 2020 22:24:08 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id B176686C43; Thu, 29 Oct 2020 11:24:06 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id sFntKXF1OrZn; Thu, 29 Oct 2020 11:24:02 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by whitealder.osuosl.org (Postfix) with ESMTP id 678AE86C0E; Thu, 29 Oct 2020 11:24:02 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5C84CC0051; Thu, 29 Oct 2020 11:24:02 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id F31A5C0051 for ; Thu, 29 Oct 2020 11:23:59 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id DFE1286BF9 for ; Thu, 29 Oct 2020 11:23:59 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id pC8YU4Gu1fcJ for ; Thu, 29 Oct 2020 11:23:58 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by whitealder.osuosl.org (Postfix) with ESMTP id 7F09884F4F for ; Thu, 29 Oct 2020 11:23:57 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from cmi@nvidia.com) with SMTP; 29 Oct 2020 13:23:51 +0200 Received: from dev-r630-04.mtbc.labs.mlnx (dev-r630-04.mtbc.labs.mlnx [10.75.205.14]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TBNg0f022472; Thu, 29 Oct 2020 13:23:50 +0200 From: Chris Mi To: dev@openvswitch.org Date: Thu, 29 Oct 2020 19:23:32 +0800 Message-Id: <20201029112340.14167-5-cmi@nvidia.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20201029112340.14167-1-cmi@nvidia.com> References: <20201029112340.14167-1-cmi@nvidia.com> MIME-Version: 1.0 Cc: elibr@nvidia.com, Chris Mi , roniba@nvidia.com, i.maximets@ovn.org Subject: [ovs-dev] [PATCH v5 04/12] ofproto: Add upcall callback to process sFlow packet X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" When offloading sample action, dpif provider may receive packets for sFlow in a seperate channel. That means the sFlow packets will not be processed by usual upcall. Add an upcall callback, so the dpif thread polling the channel can call it to process the sFlow packet. Signed-off-by: Chris Mi Reviewed-by: Eli Britstein --- ofproto/ofproto-dpif-upcall.c | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index e022fde27..4b7a0292e 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -409,6 +409,7 @@ static int udpif_flow_unprogram(struct udpif *udpif, struct udpif_key *ukey, static upcall_callback upcall_cb; static dp_purge_callback dp_purge_cb; +static sflow_upcall_callback sflow_upcall_cb; static atomic_bool enable_megaflows = ATOMIC_VAR_INIT(true); static atomic_bool enable_ufid = ATOMIC_VAR_INIT(true); @@ -463,6 +464,7 @@ udpif_create(struct dpif_backer *backer, struct dpif *dpif) dpif_register_upcall_cb(dpif, upcall_cb, udpif); dpif_register_dp_purge_cb(dpif, dp_purge_cb, udpif); + dpif_register_sflow_upcall_cb(dpif, sflow_upcall_cb); return udpif; } @@ -1345,6 +1347,46 @@ out: return error; } +int +sflow_upcall_cb(struct dpif_upcall_sflow *dupcall) +{ + const struct dpif_sflow_attr *sflow_attr = dupcall->sflow_attr; + struct user_action_cookie *cookie; + struct ofproto_dpif *ofproto; + struct dpif_sflow *sflow; + uint32_t iifindex; + struct flow flow; + + if (!sflow_attr) { + VLOG_WARN_RL(&rl, "%s: sflow_attr is NULL", __func__); + return EINVAL; + } + + cookie = sflow_attr->userdata; + ofproto = ofproto_dpif_lookup_by_uuid(&cookie->ofproto_uuid); + if (!ofproto) { + VLOG_WARN_RL(&rl, "%s: could not find ofproto", __func__); + return ENODEV; + } + + sflow = ofproto->sflow; + if (!sflow) { + VLOG_WARN_RL(&rl, "%s: could not find sflow", __func__); + return ENODEV; + } + + memset(&flow, 0, sizeof flow); + if (sflow_attr->tunnel) { + memcpy(&flow.tunnel, sflow_attr->tunnel, sizeof flow.tunnel); + } + iifindex = dupcall->iifindex; + dpif_sflow_received(sflow, &dupcall->packet, &flow, + netdev_ifindex_to_odp_port(iifindex), + cookie, NULL); + + return 0; +} + static size_t dpif_get_actions(struct udpif *udpif, struct upcall *upcall, const struct nlattr **actions) From patchwork Thu Oct 29 11:23:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Mi X-Patchwork-Id: 1390069 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CMNPH5D2Sz9sSC for ; Thu, 29 Oct 2020 22:24:03 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 428EA875DD; Thu, 29 Oct 2020 11:24:02 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 89M51pXh3UMo; Thu, 29 Oct 2020 11:24:00 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 75F7B875C5; Thu, 29 Oct 2020 11:24:00 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 4903AC0051; Thu, 29 Oct 2020 11:24:00 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 81ECCC0051 for ; Thu, 29 Oct 2020 11:23:58 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 71C8F875BF for ; Thu, 29 Oct 2020 11:23:58 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id s6n35ks8HHAU for ; Thu, 29 Oct 2020 11:23:57 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id 53C37875AF for ; Thu, 29 Oct 2020 11:23:57 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from cmi@nvidia.com) with SMTP; 29 Oct 2020 13:23:53 +0200 Received: from dev-r630-04.mtbc.labs.mlnx (dev-r630-04.mtbc.labs.mlnx [10.75.205.14]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TBNg0g022472; Thu, 29 Oct 2020 13:23:52 +0200 From: Chris Mi To: dev@openvswitch.org Date: Thu, 29 Oct 2020 19:23:33 +0800 Message-Id: <20201029112340.14167-6-cmi@nvidia.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20201029112340.14167-1-cmi@nvidia.com> References: <20201029112340.14167-1-cmi@nvidia.com> MIME-Version: 1.0 Cc: elibr@nvidia.com, Chris Mi , roniba@nvidia.com, i.maximets@ovn.org Subject: [ovs-dev] [PATCH v5 05/12] netdev-offload: Introduce register sFlow upcall callback API X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Introduce register sFlow upcall callback API as a pre-step towards saving the upcall callback. Signed-off-by: Chris Mi Reviewed-by: Eli Britstein --- lib/dpif-netlink.h | 4 ++++ lib/netdev-offload-provider.h | 3 +++ lib/netdev-offload.c | 12 ++++++++++++ lib/netdev-offload.h | 3 +++ 4 files changed, 22 insertions(+) diff --git a/lib/dpif-netlink.h b/lib/dpif-netlink.h index 24294bc42..318a4c71f 100644 --- a/lib/dpif-netlink.h +++ b/lib/dpif-netlink.h @@ -21,6 +21,7 @@ #include #include +#include "dpif.h" #include "flow.h" struct ofpbuf; @@ -60,4 +61,7 @@ bool dpif_netlink_is_internal_device(const char *name); enum ovs_vport_type netdev_to_ovs_vport_type(const char *type); +typedef int dpif_netlink_sflow_upcall_callback(struct dpif_upcall_sflow + *dupcall); + #endif /* dpif-netlink.h */ diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-provider.h index 0bed7bf61..a199c9de1 100644 --- a/lib/netdev-offload-provider.h +++ b/lib/netdev-offload-provider.h @@ -83,6 +83,9 @@ struct netdev_flow_api { int (*flow_del)(struct netdev *, const ovs_u128 *ufid, struct dpif_flow_stats *); + /* Registers an upcall callback to process sFlow packet */ + void (*register_nl_sflow_upcall_cb)(dpif_netlink_sflow_upcall_callback *); + /* Initializies the netdev flow api. * Return 0 if successful, otherwise returns a positive errno value. */ int (*init_flow_api)(struct netdev *); diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c index 2da3bc701..f8d397d08 100644 --- a/lib/netdev-offload.c +++ b/lib/netdev-offload.c @@ -666,3 +666,15 @@ netdev_set_flow_api_enabled(const struct smap *ovs_other_config) } } } + +void +netdev_regsiter_nl_sflow_upcall_cb(struct netdev *netdev, + dpif_netlink_sflow_upcall_callback *cb) +{ + const struct netdev_flow_api *flow_api = + ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); + + if (flow_api && flow_api->register_nl_sflow_upcall_cb) { + flow_api->register_nl_sflow_upcall_cb(cb); + } +} diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h index 4c0ed2ae8..f74419dee 100644 --- a/lib/netdev-offload.h +++ b/lib/netdev-offload.h @@ -22,6 +22,7 @@ #include "openvswitch/types.h" #include "packets.h" #include "flow.h" +#include "dpif-netlink.h" #ifdef __cplusplus extern "C" { @@ -124,6 +125,8 @@ int netdev_ports_flow_get(const char *dpif_type, struct match *match, struct dpif_flow_stats *stats, struct dpif_flow_attrs *attrs, struct ofpbuf *buf); +void netdev_regsiter_nl_sflow_upcall_cb(struct netdev *netdev, + dpif_netlink_sflow_upcall_callback *cb); #ifdef __cplusplus } From patchwork Thu Oct 29 11:23:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Mi X-Patchwork-Id: 1390074 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=whitealder.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CMNPh1Y9Hz9sSG for ; Thu, 29 Oct 2020 22:24:24 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id C331286CE2; Thu, 29 Oct 2020 11:24:22 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EqchrOS9tyqs; Thu, 29 Oct 2020 11:24:20 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by whitealder.osuosl.org (Postfix) with ESMTP id 7EEB986BF9; Thu, 29 Oct 2020 11:24:11 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5BAD2C1D8C; Thu, 29 Oct 2020 11:24:11 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 64A37C1AD7 for ; Thu, 29 Oct 2020 11:24:06 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 2941E2E173 for ; Thu, 29 Oct 2020 11:24:06 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id k2AVudnX-iWk for ; Thu, 29 Oct 2020 11:24:01 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by silver.osuosl.org (Postfix) with ESMTP id 8664B2281C for ; Thu, 29 Oct 2020 11:23:57 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from cmi@nvidia.com) with SMTP; 29 Oct 2020 13:23:55 +0200 Received: from dev-r630-04.mtbc.labs.mlnx (dev-r630-04.mtbc.labs.mlnx [10.75.205.14]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TBNg0h022472; Thu, 29 Oct 2020 13:23:54 +0200 From: Chris Mi To: dev@openvswitch.org Date: Thu, 29 Oct 2020 19:23:34 +0800 Message-Id: <20201029112340.14167-7-cmi@nvidia.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20201029112340.14167-1-cmi@nvidia.com> References: <20201029112340.14167-1-cmi@nvidia.com> MIME-Version: 1.0 Cc: elibr@nvidia.com, Chris Mi , roniba@nvidia.com, i.maximets@ovn.org Subject: [ovs-dev] [PATCH v5 06/12] netdev-offload-tc: Implement register sFlow upcall callback API X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Save the upcall callback as a pre-step towards offloading sample action to TC. Signed-off-by: Chris Mi Reviewed-by: Eli Britstein --- lib/netdev-offload-tc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index e828a8683..8299e6a8a 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -49,6 +49,8 @@ static struct hmap tc_to_ufid = HMAP_INITIALIZER(&tc_to_ufid); static bool multi_mask_per_prio = false; static bool block_support = false; +static dpif_netlink_sflow_upcall_callback *upcall_cb; + struct netlink_field { int offset; int flower_offset; @@ -1985,6 +1987,12 @@ probe_tc_block_support(int ifindex) } } +static void +netdev_tc_register_sflow_upcall_cb(dpif_netlink_sflow_upcall_callback *cb) +{ + upcall_cb = cb; +} + static int netdev_tc_init_flow_api(struct netdev *netdev) { @@ -2048,5 +2056,6 @@ const struct netdev_flow_api netdev_offload_tc = { .flow_put = netdev_tc_flow_put, .flow_get = netdev_tc_flow_get, .flow_del = netdev_tc_flow_del, + .register_nl_sflow_upcall_cb = netdev_tc_register_sflow_upcall_cb, .init_flow_api = netdev_tc_init_flow_api, }; From patchwork Thu Oct 29 11:23:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Mi X-Patchwork-Id: 1390075 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CMNPl6gKZz9sSC for ; Thu, 29 Oct 2020 22:24:27 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 07E762E1AF; Thu, 29 Oct 2020 11:24:25 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Df8f2g9cNbNG; Thu, 29 Oct 2020 11:24:19 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id A013A2281C; Thu, 29 Oct 2020 11:24:06 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7F7A7C1AE1; Thu, 29 Oct 2020 11:24:06 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 8F1A9C1ADC for ; Thu, 29 Oct 2020 11:24:05 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 8A5AE86C4F for ; Thu, 29 Oct 2020 11:24:05 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id G9umO7VShhhz for ; Thu, 29 Oct 2020 11:24:03 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by fraxinus.osuosl.org (Postfix) with ESMTP id 6A8B486C20 for ; Thu, 29 Oct 2020 11:24:02 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from cmi@nvidia.com) with SMTP; 29 Oct 2020 13:23:57 +0200 Received: from dev-r630-04.mtbc.labs.mlnx (dev-r630-04.mtbc.labs.mlnx [10.75.205.14]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TBNg0i022472; Thu, 29 Oct 2020 13:23:55 +0200 From: Chris Mi To: dev@openvswitch.org Date: Thu, 29 Oct 2020 19:23:35 +0800 Message-Id: <20201029112340.14167-8-cmi@nvidia.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20201029112340.14167-1-cmi@nvidia.com> References: <20201029112340.14167-1-cmi@nvidia.com> MIME-Version: 1.0 Cc: elibr@nvidia.com, Chris Mi , roniba@nvidia.com, i.maximets@ovn.org Subject: [ovs-dev] [PATCH v5 07/12] dpif-netlink: Implement register sFlow upcall callback API X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Implement dpif netlink register sFlow upcall callback API. Signed-off-by: Chris Mi Reviewed-by: Eli Britstein --- lib/dpif-netlink.c | 28 +++++++++++++++++++++++++++- lib/netdev-offload.c | 18 ++++++++++++++++++ lib/netdev-offload.h | 1 + 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 3fb992def..380c1b129 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -236,6 +236,8 @@ static unsigned int ovs_vport_mcgroup; * to using the compat interface. */ static bool ovs_tunnels_out_of_tree = true; +static sflow_upcall_callback *sflow_upcall_cb; + static int dpif_netlink_init(void); static int open_dpif(const struct dpif_netlink_dp *, struct dpif **); static uint32_t dpif_netlink_port_get_pid(const struct dpif *, @@ -2820,6 +2822,30 @@ dpif_netlink_recv_purge(struct dpif *dpif_) fat_rwlock_unlock(&dpif->upcall_lock); } +static int +dpif_netlink_sflow_upcall_cb(struct dpif_upcall_sflow *dupcall) +{ + return sflow_upcall_cb(dupcall); +} + +static void +dpif_netlink_register_sflow_upcall_cb(struct dpif *dpif, + sflow_upcall_callback *cb) +{ + const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif)); + struct netdev *dev; + + sflow_upcall_cb = cb; + dev = netdev_get(dpif_type_str); + if (!dev) { + VLOG_ERR("%s: Can't find any netdev for dpif type: %s", __func__, + dpif_type_str); + return; + } + netdev_regsiter_nl_sflow_upcall_cb(dev, dpif_netlink_sflow_upcall_cb); + netdev_close(dev); +} + static char * dpif_netlink_get_datapath_version(void) { @@ -3978,7 +4004,7 @@ const struct dpif_class dpif_netlink_class = { NULL, /* register_upcall_cb */ NULL, /* enable_upcall */ NULL, /* disable_upcall */ - NULL, /* register_sflow_upcall_cb */ + dpif_netlink_register_sflow_upcall_cb, dpif_netlink_get_datapath_version, /* get_datapath_version */ dpif_netlink_ct_dump_start, dpif_netlink_ct_dump_next, diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c index f8d397d08..17f1592b5 100644 --- a/lib/netdev-offload.c +++ b/lib/netdev-offload.c @@ -581,6 +581,24 @@ netdev_ports_get(odp_port_t port_no, const char *dpif_type) return ret; } +struct netdev * +netdev_get(const char *dpif_type) +{ + struct port_to_netdev_data *data; + struct netdev *dev = NULL; + + ovs_rwlock_rdlock(&netdev_hmap_rwlock); + HMAP_FOR_EACH (data, portno_node, &port_to_netdev) { + if (netdev_get_dpif_type(data->netdev) == dpif_type) { + dev = netdev_ref(data->netdev); + break; + } + } + ovs_rwlock_unlock(&netdev_hmap_rwlock); + + return dev; +} + int netdev_ports_remove(odp_port_t port_no, const char *dpif_type) { diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h index f74419dee..dd465dd05 100644 --- a/lib/netdev-offload.h +++ b/lib/netdev-offload.h @@ -109,6 +109,7 @@ struct dpif_port; int netdev_ports_insert(struct netdev *, const char *dpif_type, struct dpif_port *); struct netdev *netdev_ports_get(odp_port_t port, const char *dpif_type); +struct netdev *netdev_get(const char *dpif_type); int netdev_ports_remove(odp_port_t port, const char *dpif_type); odp_port_t netdev_ifindex_to_odp_port(int ifindex); From patchwork Thu Oct 29 11:23:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Mi X-Patchwork-Id: 1390072 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CMNPX34zbz9sSC for ; Thu, 29 Oct 2020 22:24:16 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 09315875FC; Thu, 29 Oct 2020 11:24:15 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id oBOEA6-EeZXo; Thu, 29 Oct 2020 11:24:13 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 36EF8875E5; Thu, 29 Oct 2020 11:24:13 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 153B5C1DD7; Thu, 29 Oct 2020 11:24:13 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id C5CB6C1AD8 for ; Thu, 29 Oct 2020 11:24:07 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id A11C486C72 for ; Thu, 29 Oct 2020 11:24:07 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id tx2sccR6_B99 for ; Thu, 29 Oct 2020 11:24:04 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by fraxinus.osuosl.org (Postfix) with ESMTP id 6B28F86C22 for ; Thu, 29 Oct 2020 11:24:02 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from cmi@nvidia.com) with SMTP; 29 Oct 2020 13:23:59 +0200 Received: from dev-r630-04.mtbc.labs.mlnx (dev-r630-04.mtbc.labs.mlnx [10.75.205.14]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TBNg0j022472; Thu, 29 Oct 2020 13:23:57 +0200 From: Chris Mi To: dev@openvswitch.org Date: Thu, 29 Oct 2020 19:23:36 +0800 Message-Id: <20201029112340.14167-9-cmi@nvidia.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20201029112340.14167-1-cmi@nvidia.com> References: <20201029112340.14167-1-cmi@nvidia.com> MIME-Version: 1.0 Cc: elibr@nvidia.com, Chris Mi , roniba@nvidia.com, i.maximets@ovn.org Subject: [ovs-dev] [PATCH v5 08/12] netdev-offload-tc: Introduce group ID management API X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" When offloading sample action to TC, userspace creates a unique ID to map sFlow action and tunnel info and passes this ID to kernel instead of the sFlow info. psample will send this ID and sampled packet to userspace. Using the ID, userspace can recover the sFlow info and send sampled packet to the right sFlow monitoring host. Signed-off-by: Chris Mi Reviewed-by: Eli Britstein --- lib/netdev-offload-tc.c | 261 ++++++++++++++++++++++++++++++++++++++++ lib/tc.h | 1 + 2 files changed, 262 insertions(+) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 8299e6a8a..b475cc84e 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -39,6 +39,7 @@ #include "unaligned.h" #include "util.h" #include "dpif-provider.h" +#include "cmap.h" VLOG_DEFINE_THIS_MODULE(netdev_offload_tc); @@ -57,6 +58,256 @@ struct netlink_field { int size; }; +/* This maps a psample group ID to struct dpif_sflow_attr for sFlow */ +struct gid_node { + struct ovs_list exp_node OVS_GUARDED; + struct cmap_node metadata_node; + struct cmap_node id_node; + struct ovs_refcount refcount; + uint32_t hash; + uint32_t id; + const struct dpif_sflow_attr sflow; +}; + +static struct ovs_rwlock gid_rwlock = OVS_RWLOCK_INITIALIZER; + +static long long int gid_last_run OVS_GUARDED_BY(gid_rwlock); + +static struct cmap gid_map = CMAP_INITIALIZER; +static struct cmap gid_metadata_map = CMAP_INITIALIZER; + +static struct ovs_list gid_expiring OVS_GUARDED_BY(gid_rwlock) + = OVS_LIST_INITIALIZER(&gid_expiring); +static struct ovs_list gid_expired OVS_GUARDED_BY(gid_rwlock) + = OVS_LIST_INITIALIZER(&gid_expired); + +static uint32_t next_group_id OVS_GUARDED_BY(gid_rwlock) = 1; + +#define GID_RUN_INTERVAL 250 /* msec */ + +static void +gid_node_free(struct gid_node *node) +{ + if (node->sflow.tunnel) { + free(node->sflow.tunnel); + } + free(CONST_CAST(void *, node->sflow.sflow)); + free(node->sflow.userdata); + free(node); +} + +static void +gid_cleanup(void) +{ + long long int now = time_msec(); + struct gid_node *node; + + /* Do maintenance at most 4 times / sec. */ + ovs_rwlock_rdlock(&gid_rwlock); + if (now - gid_last_run < GID_RUN_INTERVAL) { + ovs_rwlock_unlock(&gid_rwlock); + return; + } + ovs_rwlock_unlock(&gid_rwlock); + + ovs_rwlock_wrlock(&gid_rwlock); + gid_last_run = now; + + LIST_FOR_EACH_POP (node, exp_node, &gid_expired) { + cmap_remove(&gid_map, &node->id_node, node->id); + ovsrcu_postpone(gid_node_free, node); + } + + if (!ovs_list_is_empty(&gid_expiring)) { + /* 'gid_expired' is now empty, move nodes in + * 'gid_expiring' to it. */ + ovs_list_splice(&gid_expired, + ovs_list_front(&gid_expiring), + &gid_expiring); + } + ovs_rwlock_unlock(&gid_rwlock); +} + +/* Lockless RCU protected lookup. If node is needed accross RCU quiescent + * state, caller should copy the contents. */ +static const struct gid_node * +gid_find(uint32_t id) +{ + const struct cmap_node *node = cmap_find(&gid_map, id); + + return node + ? CONTAINER_OF(node, const struct gid_node, id_node) + : NULL; +} + +static uint32_t +dpif_sflow_attr_hash(const struct dpif_sflow_attr *sflow) +{ + uint32_t hash1 = hash_bytes(sflow->sflow, sflow->sflow_len, 0); + uint32_t hash2; + + if (!sflow->tunnel) { + return hash1; + } + + hash2 = hash_bytes(sflow->tunnel, sizeof *sflow->tunnel, 0); + return hash_add(hash1, hash2); +} + +static bool +dpif_sflow_attr_equal(const struct dpif_sflow_attr *a, + const struct dpif_sflow_attr *b) +{ + if (a->sflow_len != b->sflow_len + || memcmp(a->sflow, b->sflow, a->sflow_len)) { + return false; + } + if (!a->tunnel && !b->tunnel) { + return true; + } + if (a->tunnel && b->tunnel) { + return !memcmp(a->tunnel, b->tunnel, sizeof *a->tunnel); + } + + return false; +} + +/* Lockless RCU protected lookup. If node is needed accross RCU quiescent + * state, caller should take a reference. */ +static struct gid_node * +gid_find_equal(const struct dpif_sflow_attr *target, uint32_t hash) +{ + struct gid_node *node; + + CMAP_FOR_EACH_WITH_HASH (node, metadata_node, hash, &gid_metadata_map) { + if (dpif_sflow_attr_equal(&node->sflow, target)) { + return node; + } + } + return NULL; +} + +static struct gid_node * +gid_ref_equal(const struct dpif_sflow_attr *target, uint32_t hash) +{ + struct gid_node *node; + + do { + node = gid_find_equal(target, hash); + /* Try again if the node was released before we get the reference. */ + } while (node && !ovs_refcount_try_ref_rcu(&node->refcount)); + + return node; +} + +static void +dpif_sflow_attr_clone(struct dpif_sflow_attr *new, + const struct dpif_sflow_attr *old) +{ + new->sflow_len = old->sflow_len; + new->sflow = xmalloc(new->sflow_len); + memcpy(CONST_CAST(void *, new->sflow), old->sflow, new->sflow_len); + + new->userdata_len = old->userdata_len; + new->userdata = xmalloc(new->userdata_len); + memcpy(new->userdata, old->userdata, new->userdata_len); + + if (old->tunnel) { + new->tunnel = xzalloc(sizeof *new->tunnel); + memcpy(new->tunnel, old->tunnel, sizeof *new->tunnel); + } else { + new->tunnel = NULL; + } +} + +/* We use the id as the hash value, which works due to cmap internal rehashing. + * We also only insert nodes with unique IDs, so all possible hash collisions + * remain internal to the cmap. */ +static struct gid_node * +gid_find__(uint32_t id) + OVS_REQUIRES(gid_rwlock) +{ + struct cmap_node *node = cmap_find_protected(&gid_map, id); + + return node ? CONTAINER_OF(node, struct gid_node, id_node) : NULL; +} + +/* Allocate a unique group id for the given set of flow metadata. + * The ID space is 2^^32, so there should never be a situation in which all + * the IDs are used up. We loop until we find a free one. */ +static struct gid_node * +gid_alloc__(const struct dpif_sflow_attr *sflow, uint32_t hash) +{ + struct gid_node *node = xzalloc(sizeof *node); + + node->hash = hash; + ovs_refcount_init(&node->refcount); + dpif_sflow_attr_clone(CONST_CAST(struct dpif_sflow_attr *, &node->sflow), + sflow); + + ovs_rwlock_wrlock(&gid_rwlock); + for (;;) { + node->id = next_group_id++; + if (OVS_UNLIKELY(!node->id)) { + next_group_id = 1; + node->id = next_group_id++; + } + /* Find if the id is free. */ + if (OVS_LIKELY(!gid_find__(node->id))) { + break; + } + } + cmap_insert(&gid_map, &node->id_node, node->id); + cmap_insert(&gid_metadata_map, &node->metadata_node, node->hash); + ovs_rwlock_unlock(&gid_rwlock); + return node; +} + +/* Allocate a unique group id for the given set of flow metadata and + optional actions. */ +static uint32_t +gid_alloc_ctx(const struct dpif_sflow_attr *sflow) +{ + uint32_t hash = dpif_sflow_attr_hash(sflow); + struct gid_node *node = gid_ref_equal(sflow, hash); + + if (!node) { + node = gid_alloc__(sflow, hash); + } + return node->id; +} + +static void +gid_node_unref(const struct gid_node *node_) + OVS_EXCLUDED(gid_rwlock) +{ + struct gid_node *node = CONST_CAST(struct gid_node *, node_); + + ovs_rwlock_wrlock(&gid_rwlock); + if (node && ovs_refcount_unref(&node->refcount) == 1) { + /* Prevent re-use of this node by removing the node from + * gid_metadata_map' */ + cmap_remove(&gid_metadata_map, &node->metadata_node, node->hash); + /* We keep the node in the 'gid_map' so that it can be found as + * long as it lingers, and add it to the 'gid_expiring' list. */ + ovs_list_insert(&gid_expiring, &node->exp_node); + } + ovs_rwlock_unlock(&gid_rwlock); +} + +static void +gid_free(uint32_t id) +{ + const struct gid_node *node; + + node = gid_find(id); + if (node) { + gid_node_unref(node); + } else { + VLOG_ERR("Freeing nonexistent group ID: %"PRIu32, id); + } +} + static bool is_internal_port(const char *type) { @@ -203,6 +454,9 @@ del_filter_and_ufid_mapping(struct tcf_id *id, const ovs_u128 *ufid) if (!err) { del_ufid_tc_mapping(ufid); } + if (id->sflow_group_id) { + gid_free(id->sflow_group_id); + } return err; } @@ -398,6 +652,8 @@ netdev_tc_flow_dump_create(struct netdev *netdev, *dump_out = dump; + gid_cleanup(); + return 0; } @@ -1797,6 +2053,11 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, action->type = TC_ACT_GOTO; action->chain = 0; /* 0 is reserved and not used by recirc. */ flower.action_count++; + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_SAMPLE) { + struct dpif_sflow_attr sflow_attr; + + memset(&sflow_attr, 0, sizeof sflow_attr); + gid_alloc_ctx(&sflow_attr); } else { VLOG_DBG_RL(&rl, "unsupported put action type: %d", nl_attr_type(nla)); diff --git a/lib/tc.h b/lib/tc.h index 281231c0d..cc2ad025d 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -273,6 +273,7 @@ struct tcf_id { uint32_t chain; uint16_t prio; uint32_t handle; + uint32_t sflow_group_id; }; static inline struct tcf_id From patchwork Thu Oct 29 11:23:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Mi X-Patchwork-Id: 1390073 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CMNPf4hqtz9sSC for ; Thu, 29 Oct 2020 22:24:22 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 1F053875D4; Thu, 29 Oct 2020 11:24:21 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id dMYIY7fl5JJC; Thu, 29 Oct 2020 11:24:17 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id C2885875FE; Thu, 29 Oct 2020 11:24:16 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id A1DD0C1D86; Thu, 29 Oct 2020 11:24:16 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id B8249C1AE2 for ; Thu, 29 Oct 2020 11:24:11 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id A23742E189 for ; Thu, 29 Oct 2020 11:24:11 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yNydEda0ZMxu for ; Thu, 29 Oct 2020 11:24:09 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by silver.osuosl.org (Postfix) with ESMTP id 742C8228DB for ; Thu, 29 Oct 2020 11:24:02 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from cmi@nvidia.com) with SMTP; 29 Oct 2020 13:24:00 +0200 Received: from dev-r630-04.mtbc.labs.mlnx (dev-r630-04.mtbc.labs.mlnx [10.75.205.14]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TBNg0k022472; Thu, 29 Oct 2020 13:23:59 +0200 From: Chris Mi To: dev@openvswitch.org Date: Thu, 29 Oct 2020 19:23:37 +0800 Message-Id: <20201029112340.14167-10-cmi@nvidia.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20201029112340.14167-1-cmi@nvidia.com> References: <20201029112340.14167-1-cmi@nvidia.com> MIME-Version: 1.0 Cc: elibr@nvidia.com, Chris Mi , roniba@nvidia.com, i.maximets@ovn.org Subject: [ovs-dev] [PATCH v5 09/12] netdev-offload-tc: Remove redundant ovsthread once X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Chris Mi Reviewed-by: Eli Britstein --- lib/netdev-offload-tc.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index b475cc84e..a81003a98 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -2257,8 +2257,7 @@ netdev_tc_register_sflow_upcall_cb(dpif_netlink_sflow_upcall_callback *cb) static int netdev_tc_init_flow_api(struct netdev *netdev) { - static struct ovsthread_once multi_mask_once = OVSTHREAD_ONCE_INITIALIZER; - static struct ovsthread_once block_once = OVSTHREAD_ONCE_INITIALIZER; + static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; enum tc_qdisc_hook hook = get_tc_qdisc_hook(netdev); uint32_t block_id = 0; struct tcf_id id; @@ -2283,16 +2282,13 @@ netdev_tc_init_flow_api(struct netdev *netdev) /* make sure there is no ingress/egress qdisc */ tc_add_del_qdisc(ifindex, false, 0, hook); - if (ovsthread_once_start(&block_once)) { + if (ovsthread_once_start(&once)) { probe_tc_block_support(ifindex); /* Need to re-fetch block id as it depends on feature availability. */ block_id = get_block_id_from_netdev(netdev); - ovsthread_once_done(&block_once); - } - if (ovsthread_once_start(&multi_mask_once)) { probe_multi_mask_per_prio(ifindex); - ovsthread_once_done(&multi_mask_once); + ovsthread_once_done(&once); } error = tc_add_del_qdisc(ifindex, true, block_id, hook); From patchwork Thu Oct 29 11:23:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Mi X-Patchwork-Id: 1390076 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CMNPs6gXwz9sSC for ; Thu, 29 Oct 2020 22:24:33 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 5097A875EA; Thu, 29 Oct 2020 11:24:32 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id s5+r90dwfZ9j; Thu, 29 Oct 2020 11:24:29 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 34A8787613; Thu, 29 Oct 2020 11:24:27 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 1072DC1AE2; Thu, 29 Oct 2020 11:24:27 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 984C4C1D8B for ; Thu, 29 Oct 2020 11:24:25 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 81AFC2281C for ; Thu, 29 Oct 2020 11:24:25 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Pi-VdUeoIJuZ for ; Thu, 29 Oct 2020 11:24:22 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by silver.osuosl.org (Postfix) with ESMTP id 7A8C72E17E for ; Thu, 29 Oct 2020 11:24:07 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from cmi@nvidia.com) with SMTP; 29 Oct 2020 13:24:02 +0200 Received: from dev-r630-04.mtbc.labs.mlnx (dev-r630-04.mtbc.labs.mlnx [10.75.205.14]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TBNg0l022472; Thu, 29 Oct 2020 13:24:01 +0200 From: Chris Mi To: dev@openvswitch.org Date: Thu, 29 Oct 2020 19:23:38 +0800 Message-Id: <20201029112340.14167-11-cmi@nvidia.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20201029112340.14167-1-cmi@nvidia.com> References: <20201029112340.14167-1-cmi@nvidia.com> MIME-Version: 1.0 Cc: elibr@nvidia.com, Chris Mi , roniba@nvidia.com, i.maximets@ovn.org Subject: [ovs-dev] [PATCH v5 10/12] netdev-offload-tc: Create psample netlink socket X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Create psample netlink socket as a pre-step towards receiving sampled packets. Signed-off-by: Chris Mi Reviewed-by: Eli Britstein --- lib/netdev-offload-tc.c | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index a81003a98..33485a0b5 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -18,6 +18,7 @@ #include #include +#include #include "dpif.h" #include "hash.h" @@ -51,6 +52,7 @@ static bool multi_mask_per_prio = false; static bool block_support = false; static dpif_netlink_sflow_upcall_callback *upcall_cb; +static int psample_family; struct netlink_field { int offset; @@ -2254,6 +2256,45 @@ netdev_tc_register_sflow_upcall_cb(dpif_netlink_sflow_upcall_callback *cb) upcall_cb = cb; } +static struct nl_sock * +netdev_tc_psample_init(void) +{ + unsigned int psample_mcgroup; + struct nl_sock *sock; + int error; + + if (nl_lookup_genl_family(PSAMPLE_GENL_NAME, &psample_family)) { + VLOG_INFO("%s: Generic Netlink family '%s' does not exist. " + "Please make sure the kernel module psample is loaded", + __func__, PSAMPLE_GENL_NAME); + return NULL; + } + + if (nl_lookup_genl_mcgroup(PSAMPLE_GENL_NAME, + PSAMPLE_NL_MCGRP_SAMPLE_NAME, + &psample_mcgroup)) { + VLOG_INFO("%s: Failed to join multicast group '%s' for Generic " + "Netlink family '%s'", __func__, PSAMPLE_NL_MCGRP_SAMPLE_NAME, + PSAMPLE_GENL_NAME); + return NULL; + } + + error = nl_sock_create(NETLINK_GENERIC, &sock); + if (error) { + VLOG_INFO("%s: Failed to create psample socket", __func__); + return NULL; + } + + error = nl_sock_join_mcgroup(sock, psample_mcgroup); + if (error) { + VLOG_INFO("%s: Failed to join psample mcgroup", __func__); + nl_sock_destroy(sock); + return NULL; + } + + return sock; +} + static int netdev_tc_init_flow_api(struct netdev *netdev) { @@ -2288,6 +2329,7 @@ netdev_tc_init_flow_api(struct netdev *netdev) block_id = get_block_id_from_netdev(netdev); probe_multi_mask_per_prio(ifindex); + netdev_tc_psample_init(); ovsthread_once_done(&once); } From patchwork Thu Oct 29 11:23:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Mi X-Patchwork-Id: 1390077 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CMNPt6xpGz9sSG for ; Thu, 29 Oct 2020 22:24:34 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 9102F86C20; Thu, 29 Oct 2020 11:24:33 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zZ-mPLHjY20w; Thu, 29 Oct 2020 11:24:30 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 07EF986C3E; Thu, 29 Oct 2020 11:24:29 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id CACBCC1DA0; Thu, 29 Oct 2020 11:24:28 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 68A5DC1ADB for ; Thu, 29 Oct 2020 11:24:26 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 43E492E1A5 for ; Thu, 29 Oct 2020 11:24:26 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Bdy1RA5jGDX2 for ; Thu, 29 Oct 2020 11:24:21 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by silver.osuosl.org (Postfix) with ESMTP id 78B062E17D for ; Thu, 29 Oct 2020 11:24:07 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from cmi@nvidia.com) with SMTP; 29 Oct 2020 13:24:04 +0200 Received: from dev-r630-04.mtbc.labs.mlnx (dev-r630-04.mtbc.labs.mlnx [10.75.205.14]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TBNg0m022472; Thu, 29 Oct 2020 13:24:03 +0200 From: Chris Mi To: dev@openvswitch.org Date: Thu, 29 Oct 2020 19:23:39 +0800 Message-Id: <20201029112340.14167-12-cmi@nvidia.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20201029112340.14167-1-cmi@nvidia.com> References: <20201029112340.14167-1-cmi@nvidia.com> MIME-Version: 1.0 Cc: elibr@nvidia.com, Chris Mi , roniba@nvidia.com, i.maximets@ovn.org Subject: [ovs-dev] [PATCH v5 11/12] netdev-offload-tc: Add psample receive handler X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Create a dedicated thread to poll psample netlink socket, receive sampled packet, parse it to sFlow format and send it to sFlow monitoring host. Signed-off-by: Chris Mi Reviewed-by: Eli Britstein --- lib/netdev-offload-tc.c | 127 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 33485a0b5..aef5312a9 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -19,12 +19,14 @@ #include #include #include +#include #include "dpif.h" #include "hash.h" #include "openvswitch/hmap.h" #include "openvswitch/match.h" #include "openvswitch/ofpbuf.h" +#include "openvswitch/poll-loop.h" #include "openvswitch/thread.h" #include "openvswitch/types.h" #include "openvswitch/util.h" @@ -2295,6 +2297,123 @@ netdev_tc_psample_init(void) return sock; } +struct netdev_tc_psample { + struct nlattr *packet; /* packet data */ + int dp_group_id; /* mapping id for sFlow offload */ + int iifindex; /* input ifindex */ + int group_seq; /* group sequence */ +}; + +static int +netdev_tc_psample_from_ofpbuf(struct netdev_tc_psample *psample, + const struct ofpbuf *buf) +{ + static const struct nl_policy ovs_psample_policy[] = { + [PSAMPLE_ATTR_IIFINDEX] = { .type = NL_A_U16 }, + [PSAMPLE_ATTR_SAMPLE_GROUP] = { .type = NL_A_U32 }, + [PSAMPLE_ATTR_GROUP_SEQ] = { .type = NL_A_U32 }, + [PSAMPLE_ATTR_DATA] = { .type = NL_A_UNSPEC }, + }; + struct nlattr *a[ARRAY_SIZE(ovs_psample_policy)]; + struct genlmsghdr *genl; + struct nlmsghdr *nlmsg; + struct ofpbuf b; + + b = ofpbuf_const_initializer(buf->data, buf->size); + nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg); + genl = ofpbuf_try_pull(&b, sizeof *genl); + if (!nlmsg || !genl || nlmsg->nlmsg_type != psample_family + || !nl_policy_parse(&b, 0, ovs_psample_policy, a, + ARRAY_SIZE(ovs_psample_policy))) { + return EINVAL; + } + + psample->iifindex = nl_attr_get_u16(a[PSAMPLE_ATTR_IIFINDEX]); + psample->dp_group_id = nl_attr_get_u32(a[PSAMPLE_ATTR_SAMPLE_GROUP]); + psample->group_seq = nl_attr_get_u16(a[PSAMPLE_ATTR_GROUP_SEQ]); + psample->packet = a[PSAMPLE_ATTR_DATA]; + + return 0; +} + +static int +netdev_tc_psample_parse_packet(struct netdev_tc_psample *psample, + struct dpif_upcall_sflow *dupcall) +{ + const struct gid_node *node; + + dp_packet_use_stub(&dupcall->packet, + CONST_CAST(struct nlattr *, + nl_attr_get(psample->packet)) - 1, + nl_attr_get_size(psample->packet) + + sizeof(struct nlattr)); + dp_packet_set_data(&dupcall->packet, + (char *)dp_packet_data(&dupcall->packet) + + sizeof(struct nlattr)); + dp_packet_set_size(&dupcall->packet, nl_attr_get_size(psample->packet)); + + node = gid_find(psample->dp_group_id); + dupcall->sflow_attr = &node->sflow; + dupcall->iifindex = psample->iifindex; + + return 0; +} + +static int +netdev_tc_psample_poll(struct dpif_upcall_sflow *dupcall, + struct nl_sock *sock) +{ + for (;;) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); + struct netdev_tc_psample psample; + uint64_t buf_stub[4096 / 8]; + struct ofpbuf buf; + int error; + + ofpbuf_use_stub(&buf, buf_stub, sizeof buf_stub); + error = nl_sock_recv(sock, &buf, NULL, false); + + if (!error) { + error = netdev_tc_psample_from_ofpbuf(&psample, &buf); + if (!error) { + ofpbuf_uninit(&buf); + error = netdev_tc_psample_parse_packet(&psample, dupcall); + return error; + } + } else if (error != EAGAIN) { + VLOG_WARN_RL(&rl, "%s: error reading or parsing netlink (%s)", + __func__, ovs_strerror(error)); + nl_sock_drain(sock); + error = ENOBUFS; + } + + ofpbuf_uninit(&buf); + if (error) { + return error; + } + } +} + +static void * +netdev_tc_psample_handler(void *arg) +{ + struct nl_sock *sock = CONST_CAST(struct nl_sock *, arg); + + struct dpif_upcall_sflow dupcall; + int err; + + while (true) { + err = netdev_tc_psample_poll(&dupcall, sock); + if (!err) { + upcall_cb(&dupcall); + } + nl_sock_wait(sock, POLLIN); + poll_block(); + } + + return NULL; +} + static int netdev_tc_init_flow_api(struct netdev *netdev) { @@ -2324,12 +2443,18 @@ netdev_tc_init_flow_api(struct netdev *netdev) tc_add_del_qdisc(ifindex, false, 0, hook); if (ovsthread_once_start(&once)) { + struct nl_sock *sock; + probe_tc_block_support(ifindex); /* Need to re-fetch block id as it depends on feature availability. */ block_id = get_block_id_from_netdev(netdev); probe_multi_mask_per_prio(ifindex); - netdev_tc_psample_init(); + sock = netdev_tc_psample_init(); + if (sock) { + ovs_thread_create("psample_handler", netdev_tc_psample_handler, + sock); + } ovsthread_once_done(&once); } From patchwork Thu Oct 29 11:23:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Mi X-Patchwork-Id: 1390078 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=whitealder.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CMNQs1TQCz9sSC for ; Thu, 29 Oct 2020 22:25:25 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id B590486BEC; Thu, 29 Oct 2020 11:25:23 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PlVFYMQjWrG6; Thu, 29 Oct 2020 11:25:17 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by whitealder.osuosl.org (Postfix) with ESMTP id AE1EC86CE7; Thu, 29 Oct 2020 11:24:46 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 9C6ADC1AD7; Thu, 29 Oct 2020 11:24:46 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 94CFCC0051 for ; Thu, 29 Oct 2020 11:24:45 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 679B7228AE for ; Thu, 29 Oct 2020 11:24:45 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Cos80AjBZfcH for ; Thu, 29 Oct 2020 11:24:38 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by silver.osuosl.org (Postfix) with ESMTP id 80DBE228A0 for ; Thu, 29 Oct 2020 11:24:12 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from cmi@nvidia.com) with SMTP; 29 Oct 2020 13:24:06 +0200 Received: from dev-r630-04.mtbc.labs.mlnx (dev-r630-04.mtbc.labs.mlnx [10.75.205.14]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TBNg0n022472; Thu, 29 Oct 2020 13:24:04 +0200 From: Chris Mi To: dev@openvswitch.org Date: Thu, 29 Oct 2020 19:23:40 +0800 Message-Id: <20201029112340.14167-13-cmi@nvidia.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20201029112340.14167-1-cmi@nvidia.com> References: <20201029112340.14167-1-cmi@nvidia.com> MIME-Version: 1.0 Cc: elibr@nvidia.com, Chris Mi , roniba@nvidia.com, i.maximets@ovn.org Subject: [ovs-dev] [PATCH v5 12/12] netdev-offload-tc: Add offload support for sFlow X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Create a unique group ID to map the sFlow info when offloading sFlow action to TC. When showing the offloaded datapath flows, translate the group ID from TC sample action to sFlow info using the mapping. Signed-off-by: Chris Mi Reviewed-by: Eli Britstein --- lib/netdev-offload-tc.c | 149 +++++++++++++++++++++++++++++++++++++--- lib/tc.c | 61 +++++++++++++++- lib/tc.h | 9 ++- 3 files changed, 207 insertions(+), 12 deletions(-) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index aef5312a9..36798acc6 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -989,6 +989,18 @@ parse_tc_flower_to_match(struct tc_flower *flower, action = flower->actions; for (i = 0; i < flower->action_count; i++, action++) { switch (action->type) { + case TC_ACT_SAMPLE: { + const struct gid_node *node; + + node = gid_find(action->sample.action_group_id); + if (!node) { + VLOG_ERR_RL(&error_rl, "gid node is NULL, gid: %d", + action->sample.action_group_id); + return ENOENT; + } + nl_msg_put(buf, node->sflow.sflow, node->sflow.sflow_len); + } + break; case TC_ACT_VLAN_POP: { nl_msg_put_flag(buf, OVS_ACTION_ATTR_POP_VLAN); } @@ -1668,6 +1680,78 @@ flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl, flower->mask.tunnel.metadata.present.len = tnl->metadata.present.len; } +static int +parse_userspace_userdata(const struct nlattr *actions, + struct dpif_sflow_attr *sflow_attr) +{ + const struct nlattr *nla; + unsigned int left; + + NL_NESTED_FOR_EACH_UNSAFE (nla, left, actions) { + if (nl_attr_type(nla) == OVS_USERSPACE_ATTR_USERDATA) { + struct user_action_cookie *cookie; + + cookie = CONST_CAST(struct user_action_cookie *, nl_attr_get(nla)); + if (cookie->type == USER_ACTION_COOKIE_SFLOW) { + sflow_attr->userdata = CONST_CAST(void *, nl_attr_get(nla)); + sflow_attr->userdata_len = nl_attr_get_size(nla); + return 0; + } + } + } + + VLOG_ERR_RL(&error_rl, "%s: no sFlow cookie", __func__); + return EINVAL; +} + +static int +parse_action_userspace(const struct nlattr *actions, + struct dpif_sflow_attr *sflow_attr) +{ + const struct nlattr *nla; + unsigned int left; + + NL_NESTED_FOR_EACH_UNSAFE (nla, left, actions) { + if (nl_attr_type(nla) == OVS_ACTION_ATTR_USERSPACE) { + return parse_userspace_userdata(nla, sflow_attr); + } + } + + VLOG_ERR_RL(&error_rl, "%s: no OVS_ACTION_ATTR_USERSPACE attribute", + __func__); + return EINVAL; +} + +static int +parse_sample_action(const struct nlattr *actions, + struct dpif_sflow_attr *sflow_attr, + struct tc_action *tc_action) +{ + const struct nlattr *nla; + unsigned int left; + int ret = EINVAL; + + sflow_attr->sflow = actions; + sflow_attr->sflow_len = actions->nla_len; + + NL_NESTED_FOR_EACH_UNSAFE (nla, left, actions) { + if (nl_attr_type(nla) == OVS_SAMPLE_ATTR_ACTIONS) { + ret = parse_action_userspace(nla, sflow_attr); + } else if (nl_attr_type(nla) == OVS_SAMPLE_ATTR_PROBABILITY) { + tc_action->type = TC_ACT_SAMPLE; + tc_action->sample.action_rate = UINT32_MAX / nl_attr_get_u32(nla); + } else { + return EINVAL; + } + } + + if (tc_action->sample.action_rate) { + return ret; + } + + return EINVAL; +} + static int netdev_tc_flow_put(struct netdev *netdev, struct match *match, struct nlattr *actions, size_t actions_len, @@ -1684,6 +1768,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, struct tc_action *action; bool recirc_act = false; uint32_t block_id = 0; + uint32_t group_id = 0; struct nlattr *nla; struct tcf_id id; uint32_t chain; @@ -1973,7 +2058,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, NL_ATTR_FOR_EACH(nla, left, actions, actions_len) { if (flower.action_count >= TCA_ACT_MAX_NUM) { VLOG_DBG_RL(&rl, "Can only support %d actions", TCA_ACT_MAX_NUM); - return EOPNOTSUPP; + err = EOPNOTSUPP; + goto out; } action = &flower.actions[flower.action_count]; if (nl_attr_type(nla) == OVS_ACTION_ATTR_OUTPUT) { @@ -1983,7 +2069,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, if (!outdev) { VLOG_DBG_RL(&rl, "Can't find netdev for output port %d", port); - return ENODEV; + err = ENODEV; + goto out; } action->out.ifindex_out = netdev_get_ifindex(outdev); action->out.ingress = is_internal_port(netdev_get_type(outdev)); @@ -2021,7 +2108,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, err = parse_put_flow_set_action(&flower, action, set, set_len); if (err) { - return err; + goto out; } if (action->type == TC_ACT_ENCAP) { action->encap.tp_dst = info->tp_dst_port; @@ -2034,7 +2121,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, err = parse_put_flow_set_masked_action(&flower, action, set, set_len, true); if (err) { - return err; + goto out; } } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_CT) { const struct nlattr *ct = nl_attr_get(nla); @@ -2042,7 +2129,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, err = parse_put_flow_ct_action(&flower, action, ct, ct_len); if (err) { - return err; + goto out; } } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_CT_CLEAR) { action->type = TC_ACT_CT; @@ -2061,17 +2148,49 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, struct dpif_sflow_attr sflow_attr; memset(&sflow_attr, 0, sizeof sflow_attr); - gid_alloc_ctx(&sflow_attr); + if (flower.tunnel) { + sflow_attr.tunnel = CONST_CAST(struct flow_tnl *, tnl); + } + err = parse_sample_action(nla, &sflow_attr, action); + if (err) { + goto out; + } + group_id = gid_alloc_ctx(&sflow_attr); + action->sample.action_group_id = group_id; + flower.action_count++; + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_USERSPACE) { + struct dpif_sflow_attr sflow_attr; + + /* If there is a sFlow cookie inside of a userspace attribute, + * but no sample attribute, that means sampling rate is 1. + */ + memset(&sflow_attr, 0, sizeof sflow_attr); + if (flower.tunnel) { + sflow_attr.tunnel = CONST_CAST(struct flow_tnl *, tnl); + } + err = parse_userspace_userdata(nla, &sflow_attr); + if (err) { + goto out; + } + sflow_attr.sflow = nla; + sflow_attr.sflow_len = nla->nla_len; + group_id = gid_alloc_ctx(&sflow_attr); + action->type = TC_ACT_SAMPLE; + action->sample.action_group_id = group_id; + action->sample.action_rate = 1; + flower.action_count++; } else { VLOG_DBG_RL(&rl, "unsupported put action type: %d", nl_attr_type(nla)); - return EOPNOTSUPP; + err = EOPNOTSUPP; + goto out; } } if ((chain || recirc_act) && !info->recirc_id_shared_with_tc) { VLOG_ERR_RL(&error_rl, "flow_put: recirc_id sharing not supported"); - return EOPNOTSUPP; + err = EOPNOTSUPP; + goto out; } if (get_ufid_tc_mapping(ufid, &id) == 0) { @@ -2083,20 +2202,30 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, prio = get_prio_for_tc_flower(&flower); if (prio == 0) { VLOG_ERR_RL(&rl, "couldn't get tc prio: %s", ovs_strerror(ENOSPC)); - return ENOSPC; + err = ENOSPC; + goto out; } flower.act_cookie.data = ufid; flower.act_cookie.len = sizeof *ufid; block_id = get_block_id_from_netdev(netdev); - id = tc_make_tcf_id_chain(ifindex, block_id, chain, prio, hook); + id = tc_make_tcf_id_chain(ifindex, block_id, chain, prio, hook, group_id); err = tc_replace_flower(&id, &flower); if (!err) { if (stats) { memset(stats, 0, sizeof *stats); } add_ufid_tc_mapping(netdev, ufid, &id); + } else { + goto out; + } + + return 0; + +out: + if (group_id) { + gid_free(group_id); } return err; diff --git a/lib/tc.c b/lib/tc.c index 8761304c9..2e31648fc 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -23,14 +23,15 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include -#include #include #include #include @@ -1289,6 +1290,38 @@ nl_parse_act_gact(struct nlattr *options, struct tc_flower *flower) return 0; } +static const struct nl_policy sample_policy[] = { + [TCA_SAMPLE_PARMS] = { .type = NL_A_UNSPEC, + .min_len = sizeof(struct tc_sample), + .optional = false, }, + [TCA_SAMPLE_PSAMPLE_GROUP] = { .type = NL_A_U32, + .optional = false, }, + [TCA_SAMPLE_RATE] = { .type = NL_A_U32, + .optional = false, }, +}; + +static int +nl_parse_act_sample(struct nlattr *options, struct tc_flower *flower) +{ + struct nlattr *sample_attrs[ARRAY_SIZE(sample_policy)]; + struct tc_action *action; + + if (!nl_parse_nested(options, sample_policy, sample_attrs, + ARRAY_SIZE(sample_policy))) { + VLOG_ERR_RL(&error_rl, "failed to parse sample action options"); + return EPROTO; + } + + action = &flower->actions[flower->action_count++]; + action->type = TC_ACT_SAMPLE; + action->sample.action_group_id = + nl_attr_get_u32(sample_attrs[TCA_SAMPLE_PSAMPLE_GROUP]); + action->sample.action_rate = + nl_attr_get_u32(sample_attrs[TCA_SAMPLE_RATE]); + + return 0; +} + static const struct nl_policy mirred_policy[] = { [TCA_MIRRED_PARMS] = { .type = NL_A_UNSPEC, .min_len = sizeof(struct tc_mirred), @@ -1697,6 +1730,8 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, /* Added for TC rule only (not in OvS rule) so ignore. */ } else if (!strcmp(act_kind, "ct")) { nl_parse_act_ct(act_options, flower); + } else if (!strcmp(act_kind, "sample")) { + nl_parse_act_sample(act_options, flower); } else { VLOG_ERR_RL(&error_rl, "unknown tc action kind: %s", act_kind); err = EINVAL; @@ -2292,6 +2327,23 @@ nl_msg_put_act_mirred(struct ofpbuf *request, int ifindex, int action, nl_msg_end_nested(request, offset); } +static void +nl_msg_put_act_sample(struct ofpbuf *request, uint32_t rate, uint32_t group_id) +{ + size_t offset; + + nl_msg_put_string(request, TCA_ACT_KIND, "sample"); + offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS | NLA_F_NESTED); + { + struct tc_sample parm = { .action = TC_ACT_PIPE }; + + nl_msg_put_unspec(request, TCA_SAMPLE_PARMS, &parm, sizeof parm); + nl_msg_put_u32(request, TCA_SAMPLE_RATE, rate); + nl_msg_put_u32(request, TCA_SAMPLE_PSAMPLE_GROUP, group_id); + } + nl_msg_end_nested(request, offset); +} + static inline void nl_msg_put_act_cookie(struct ofpbuf *request, struct tc_cookie *ck) { if (ck->len) { @@ -2551,6 +2603,13 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) nl_msg_end_nested(request, act_offset); } break; + case TC_ACT_SAMPLE: { + act_offset = nl_msg_start_nested(request, act_index++); + nl_msg_put_act_sample(request, action->sample.action_rate, + action->sample.action_group_id); + nl_msg_end_nested(request, act_offset); + } + break; case TC_ACT_OUTPUT: { if (!released && flower->tunnel) { act_offset = nl_msg_start_nested(request, act_index++); diff --git a/lib/tc.h b/lib/tc.h index cc2ad025d..143e225d1 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -171,6 +171,7 @@ enum tc_action_type { TC_ACT_MPLS_SET, TC_ACT_GOTO, TC_ACT_CT, + TC_ACT_SAMPLE, }; enum nat_type { @@ -253,6 +254,11 @@ struct tc_action { bool force; bool commit; } ct; + + struct { + uint32_t action_rate; + uint32_t action_group_id; + } sample; }; enum tc_action_type type; @@ -292,11 +298,12 @@ tc_make_tcf_id(int ifindex, uint32_t block_id, uint16_t prio, static inline struct tcf_id tc_make_tcf_id_chain(int ifindex, uint32_t block_id, uint32_t chain, - uint16_t prio, enum tc_qdisc_hook hook) + uint16_t prio, enum tc_qdisc_hook hook, uint32_t group_id) { struct tcf_id id = tc_make_tcf_id(ifindex, block_id, prio, hook); id.chain = chain; + id.sflow_group_id = group_id; return id; }