From patchwork Wed Apr 24 13:50:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 13641897 X-Patchwork-Delegate: kuba@kernel.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A52815E1E7 for ; Wed, 24 Apr 2024 13:54:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966878; cv=none; b=Ue8vPUspBCUH9ViE1XD62JJm7+v3dWMQ9aH3iR6iLo+WrbvSRSMfuGN288MGa/otjegtaRbE6C6vde5JthRNck1DZXtd6jWZoRKHsgVer+RZUjAWORsNWMCxVgrXdBKxRgZ++f2D6SDeh/exhbkZAELkfZYLkpra7lel3NYrukc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966878; c=relaxed/simple; bh=aaAS8vV4wb9QvjU6bclPinSt2ufTufAeAaQH7gzZLTM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=O2vGnqXRKM1A60QnrunAZ4cyQ+DWHc0mYw/d56fRSbqKT5ES2bSGRLVeP75ZxYzbcPt5d8s7VoSChDV5k0e8rV7q65yqcSCBCX5VS9a8XvQ3M42lbCzOxo/hxioZ907j/RHembHur7VAQemxd1R9d9g0Ka3ebbySksYzyJZVcT0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=PtFH6AJ/; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="PtFH6AJ/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713966876; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rmUaRXIMcsJ+dXovFl57XFZEcsYZXt5cyjvVIml/sc4=; b=PtFH6AJ/f6c6RSnBZ0ZxWLh2y+ElHbYC9CeKwROKX5qo532060+gxEnpWOuyFl4sLb0zD3 0/DXPgYctlWzyeo/Jx77MrjZrZv/ZSQpcuBeupdxTbt33oh3jqka7QnZAStSgZenPSdQgX x84sciqXq9ffgfYWGD/HygCwqnojBoU= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-208-HJzfv7WJMfWcK7JLXcIesg-1; Wed, 24 Apr 2024 09:54:33 -0400 X-MC-Unique: HJzfv7WJMfWcK7JLXcIesg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A4DDD299E740; Wed, 24 Apr 2024 13:54:32 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 218A91C0654B; Wed, 24 Apr 2024 13:54:29 +0000 (UTC) From: Adrian Moreno To: netdev@vger.kernel.org Cc: aconole@redhat.com, echaudro@redhat.com, horms@kernel.org, i.maximets@ovn.org, Adrian Moreno , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Jiri Pirko , Jacob Keller , Johannes Berg , Ido Schimmel , Stanislaw Gruszka , linux-kernel@vger.kernel.org Subject: [PATCH net-next 1/8] net: netlink: export genl private pointer getters Date: Wed, 24 Apr 2024 15:50:48 +0200 Message-ID: <20240424135109.3524355-2-amorenoz@redhat.com> In-Reply-To: <20240424135109.3524355-1-amorenoz@redhat.com> References: <20240424135109.3524355-1-amorenoz@redhat.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Patchwork-Delegate: kuba@kernel.org Both "__genl_sk_priv_get" and "genl_sk_priv_get" are useful functions to handle private pointers attached to genetlink sockets. Export them so they can be used in modules. Reviewed-by: Jakub Kicinski Signed-off-by: Adrian Moreno --- net/netlink/genetlink.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index feb54c63a116..beafa415a9f5 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -726,6 +726,7 @@ void *__genl_sk_priv_get(struct genl_family *family, struct sock *sk) return ERR_PTR(-EINVAL); return xa_load(family->sock_privs, (unsigned long) sk); } +EXPORT_SYMBOL(__genl_sk_priv_get); /** * genl_sk_priv_get - Get family private pointer for socket @@ -764,6 +765,7 @@ void *genl_sk_priv_get(struct genl_family *family, struct sock *sk) } return priv; } +EXPORT_SYMBOL(genl_sk_priv_get); /** * genl_register_family - register a generic netlink family From patchwork Wed Apr 24 13:50:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 13641898 X-Patchwork-Delegate: kuba@kernel.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 229AE15E5D2 for ; Wed, 24 Apr 2024 13:54:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966881; cv=none; b=t9JfSZ1WRwPcocoHrQ49io9PaZxugpQ+ul0QlAtqcnT0Ao6SLMO7PfxZj2uj2KzYXhoNw4w/MywOCskIFEwFNLtxsv6Ct5dERwIW8HhqM3Oib9zmJDutTV/JHwbEZho3knZMwGYByA6kiiW41Y4dP40HZvszmOXP2mJxDUW+o5E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966881; c=relaxed/simple; bh=gxTGezLHWXY8b7sIhgnJbShbHkUHWXR6geF6I6OEDao=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=D0wIrubYLyKhEKsDwh9BLLYnHxmzy22E64czn2Fp2XQVoQzSsmqvN7S+Q0smqRyq2B8kj2KdOi0G3mhxEJ2TGomNyI/ZTkr0US7f6tQio0Ab0NZ1JBGwWRRl0MqSWR22uKmzqQITudTUiq7SUKV2q7H8R1Z1aihuI4wwUwFHWx0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=ewNrK89r; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="ewNrK89r" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713966879; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mvfMKL+8UkJyc+6NdO80ILmMaNmzG0sr9rlaAL4MQIg=; b=ewNrK89ru5RnG26gWR04oyqxPVGy94fUwE35Cad/DUDUZhAHB1LrN3dNzH209oi+nTik+w CberLWcXT9pi0ug6GqBvzL909n09jO9rbOjohnaxRioYasxnbv+VkeT1mUy5lKY393b0sH sGG6RmQVh8djrfjqGG8RAws8dpESAyQ= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-651-tSYvXOl7N2OL-BBPH0PrrQ-1; Wed, 24 Apr 2024 09:54:35 -0400 X-MC-Unique: tSYvXOl7N2OL-BBPH0PrrQ-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 148D73C0252B; Wed, 24 Apr 2024 13:54:35 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3B8881C0F120; Wed, 24 Apr 2024 13:54:33 +0000 (UTC) From: Adrian Moreno To: netdev@vger.kernel.org Cc: aconole@redhat.com, echaudro@redhat.com, horms@kernel.org, i.maximets@ovn.org, Adrian Moreno , Yotam Gigi , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-kernel@vger.kernel.org Subject: [PATCH net-next 2/8] net: psample: add multicast filtering on group_id Date: Wed, 24 Apr 2024 15:50:49 +0200 Message-ID: <20240424135109.3524355-3-amorenoz@redhat.com> In-Reply-To: <20240424135109.3524355-1-amorenoz@redhat.com> References: <20240424135109.3524355-1-amorenoz@redhat.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Patchwork-Delegate: kuba@kernel.org Packet samples can come from several places (e.g: different tc sample actions), typically using the sample group (PSAMPLE_ATTR_SAMPLE_GROUP) to differentiate them. Likewise, sample consumers that listen on the multicast group may only be interested on a single group. However, they are currently forced to receive all samples and discard the ones that are not relevant, causing unnecessary overhead. Allow users to filter on the desired group_id by adding a new command PSAMPLE_SET_FILTER that can be used to pass the desired group id. Store this filter on the per-socket private pointer and use it for filtering multicasted samples. Signed-off-by: Adrian Moreno --- include/uapi/linux/psample.h | 1 + net/psample/psample.c | 110 +++++++++++++++++++++++++++++++++-- 2 files changed, 105 insertions(+), 6 deletions(-) diff --git a/include/uapi/linux/psample.h b/include/uapi/linux/psample.h index e585db5bf2d2..9d62983af0a4 100644 --- a/include/uapi/linux/psample.h +++ b/include/uapi/linux/psample.h @@ -28,6 +28,7 @@ enum psample_command { PSAMPLE_CMD_GET_GROUP, PSAMPLE_CMD_NEW_GROUP, PSAMPLE_CMD_DEL_GROUP, + PSAMPLE_CMD_SET_FILTER, }; enum psample_tunnel_key_attr { diff --git a/net/psample/psample.c b/net/psample/psample.c index a5d9b8446f77..f5f77515b969 100644 --- a/net/psample/psample.c +++ b/net/psample/psample.c @@ -98,13 +98,77 @@ static int psample_nl_cmd_get_group_dumpit(struct sk_buff *msg, return msg->len; } -static const struct genl_small_ops psample_nl_ops[] = { +struct psample_obj_desc { + struct rcu_head rcu; + u32 group_num; +}; + +struct psample_nl_sock_priv { + struct psample_obj_desc __rcu *filter; + spinlock_t filter_lock; /* Protects filter. */ +}; + +static void psample_nl_sock_priv_init(void *priv) +{ + struct psample_nl_sock_priv *sk_priv = priv; + + spin_lock_init(&sk_priv->filter_lock); +} + +static void psample_nl_sock_priv_destroy(void *priv) +{ + struct psample_nl_sock_priv *sk_priv = priv; + struct psample_obj_desc *filter; + + filter = rcu_dereference_protected(sk_priv->filter, true); + kfree_rcu(filter, rcu); +} + +static int psample_nl_set_filter_doit(struct sk_buff *skb, + struct genl_info *info) +{ + struct psample_obj_desc *filter = NULL; + struct psample_nl_sock_priv *sk_priv; + struct nlattr **attrs = info->attrs; + + if (attrs[PSAMPLE_ATTR_SAMPLE_GROUP]) { + filter = kzalloc(sizeof(*filter), GFP_KERNEL); + filter->group_num = + nla_get_u32(attrs[PSAMPLE_ATTR_SAMPLE_GROUP]); + } + + sk_priv = genl_sk_priv_get(&psample_nl_family, NETLINK_CB(skb).sk); + if (IS_ERR(sk_priv)) { + kfree(filter); + return PTR_ERR(sk_priv); + } + + spin_lock(&sk_priv->filter_lock); + filter = rcu_replace_pointer(sk_priv->filter, filter, + lockdep_is_held(&sk_priv->filter_lock)); + spin_unlock(&sk_priv->filter_lock); + kfree_rcu(filter, rcu); + return 0; +} + +static const struct nla_policy +psample_set_filter_policy[PSAMPLE_ATTR_SAMPLE_GROUP + 1] = { + [PSAMPLE_ATTR_SAMPLE_GROUP] = { .type = NLA_U32, }, +}; + +static const struct genl_ops psample_nl_ops[] = { { .cmd = PSAMPLE_CMD_GET_GROUP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .dumpit = psample_nl_cmd_get_group_dumpit, /* can be retrieved by unprivileged users */ - } + }, + { + .cmd = PSAMPLE_CMD_SET_FILTER, + .doit = psample_nl_set_filter_doit, + .policy = psample_set_filter_policy, + .flags = 0, + }, }; static struct genl_family psample_nl_family __ro_after_init = { @@ -114,10 +178,13 @@ static struct genl_family psample_nl_family __ro_after_init = { .netnsok = true, .module = THIS_MODULE, .mcgrps = psample_nl_mcgrps, - .small_ops = psample_nl_ops, - .n_small_ops = ARRAY_SIZE(psample_nl_ops), + .ops = psample_nl_ops, + .n_ops = ARRAY_SIZE(psample_nl_ops), .resv_start_op = PSAMPLE_CMD_GET_GROUP + 1, .n_mcgrps = ARRAY_SIZE(psample_nl_mcgrps), + .sock_priv_size = sizeof(struct psample_nl_sock_priv), + .sock_priv_init = psample_nl_sock_priv_init, + .sock_priv_destroy = psample_nl_sock_priv_destroy, }; static void psample_group_notify(struct psample_group *group, @@ -360,6 +427,32 @@ static int psample_tunnel_meta_len(struct ip_tunnel_info *tun_info) } #endif +static inline void psample_nl_obj_desc_init(struct psample_obj_desc *desc, + u32 group_num) +{ + memset(desc, 0, sizeof(*desc)); + desc->group_num = group_num; +} + +static int psample_nl_sample_filter(struct sock *dsk, struct sk_buff *skb, + void *data) +{ + struct psample_obj_desc *desc = data; + struct psample_nl_sock_priv *sk_priv; + struct psample_obj_desc *filter; + int ret = 0; + + rcu_read_lock(); + sk_priv = __genl_sk_priv_get(&psample_nl_family, dsk); + if (!IS_ERR_OR_NULL(sk_priv)) { + filter = rcu_dereference(sk_priv->filter); + if (filter && desc) + ret = (filter->group_num != desc->group_num); + } + rcu_read_unlock(); + return ret; +} + void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, u32 sample_rate, const struct psample_metadata *md) { @@ -370,6 +463,7 @@ void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, #ifdef CONFIG_INET struct ip_tunnel_info *tun_info; #endif + struct psample_obj_desc desc; struct sk_buff *nl_skb; int data_len; int meta_len; @@ -487,8 +581,12 @@ void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, #endif genlmsg_end(nl_skb, data); - genlmsg_multicast_netns(&psample_nl_family, group->net, nl_skb, 0, - PSAMPLE_NL_MCGRP_SAMPLE, GFP_ATOMIC); + psample_nl_obj_desc_init(&desc, group->group_num); + genlmsg_multicast_netns_filtered(&psample_nl_family, + group->net, nl_skb, 0, + PSAMPLE_NL_MCGRP_SAMPLE, + GFP_ATOMIC, psample_nl_sample_filter, + &desc); return; error: From patchwork Wed Apr 24 13:50:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 13641899 X-Patchwork-Delegate: kuba@kernel.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 35A0E15ECDD for ; Wed, 24 Apr 2024 13:54:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966884; cv=none; b=CqIjcdgaaPGzzIpLsIb/D1Ym+Xiem3nD8LUyLelGCcSnlDLVNelMJ9oa4AD1yZzeMElBeI++JwsjuXzFvk2Wb1QDjgJXhtxM9da6kysNdIioPWjGkdVjgTCLRbW08ub98h8z5/7mL251qHX4MD3kdvFk+G8kkIXuAmoujVTNML4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966884; c=relaxed/simple; bh=UOWkQ6MFWCBRbY+FwMYzxJ5JdvgUYAvrEWMlto0lo14=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gWFlRLrWWYxCPOf2R645Pv4AXwV/2SiT5qfL9RvrxB1WN1Rxg/rFYsKfOJKOYSq8V4ua6+3alwwTbzHYqu9aUXvPvIEybdxYpzO3T+l5ZIO3Jr9Jp6xe9dkuObtdmG4cYu8rfMAHbwAE9ihFdtybFmAJsRQDf5S0cpaz8MNqtfw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=RxpcS+fR; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="RxpcS+fR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713966882; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vikpMJxJ9Ds+2aUp1Td8HwJZsh9X5P4rCQC4urDpxnw=; b=RxpcS+fRlkzv+XRJqNqB2T/X0M/31J3VLFCBpRifJ6C/1WqY3+iqiKmMUNLnntZIqHiWDQ dlmuthCworXKni1NBAE1D3OpHHr9+OF6GWaT6WhWeTHG+HPWUa9Uq1guF5aOQh4BcfJ0h+ jQ5y90OP9v95f3ElJyZk1GXShazEl6c= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-516-gdQN8hpGOlq2BtCoLX2ZrA-1; Wed, 24 Apr 2024 09:54:38 -0400 X-MC-Unique: gdQN8hpGOlq2BtCoLX2ZrA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 837FB834FEE; Wed, 24 Apr 2024 13:54:37 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id A82F71C060D0; Wed, 24 Apr 2024 13:54:35 +0000 (UTC) From: Adrian Moreno To: netdev@vger.kernel.org Cc: aconole@redhat.com, echaudro@redhat.com, horms@kernel.org, i.maximets@ovn.org, Adrian Moreno , Yotam Gigi , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-kernel@vger.kernel.org Subject: [PATCH net-next 3/8] net: psample: add user cookie Date: Wed, 24 Apr 2024 15:50:50 +0200 Message-ID: <20240424135109.3524355-4-amorenoz@redhat.com> In-Reply-To: <20240424135109.3524355-1-amorenoz@redhat.com> References: <20240424135109.3524355-1-amorenoz@redhat.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Patchwork-Delegate: kuba@kernel.org Add a user cookie to the sample metadata so that sample emitters can provide more contextual information to samples. If present, send the user cookie in a new attribute: PSAMPLE_ATTR_USER_COOKIE. Signed-off-by: Adrian Moreno --- include/net/psample.h | 2 ++ include/uapi/linux/psample.h | 1 + net/psample/psample.c | 12 +++++++++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/net/psample.h b/include/net/psample.h index 0509d2d6be67..2ac71260a546 100644 --- a/include/net/psample.h +++ b/include/net/psample.h @@ -25,6 +25,8 @@ struct psample_metadata { out_tc_occ_valid:1, latency_valid:1, unused:5; + const u8 *user_cookie; + u32 user_cookie_len; }; struct psample_group *psample_group_get(struct net *net, u32 group_num); diff --git a/include/uapi/linux/psample.h b/include/uapi/linux/psample.h index 9d62983af0a4..83dc919c4023 100644 --- a/include/uapi/linux/psample.h +++ b/include/uapi/linux/psample.h @@ -19,6 +19,7 @@ enum { PSAMPLE_ATTR_LATENCY, /* u64, nanoseconds */ PSAMPLE_ATTR_TIMESTAMP, /* u64, nanoseconds */ PSAMPLE_ATTR_PROTO, /* u16 */ + PSAMPLE_ATTR_USER_COOKIE, /* binary, user provided data */ __PSAMPLE_ATTR_MAX }; diff --git a/net/psample/psample.c b/net/psample/psample.c index f5f77515b969..476aaad7a885 100644 --- a/net/psample/psample.c +++ b/net/psample/psample.c @@ -480,7 +480,8 @@ void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, nla_total_size(sizeof(u32)) + /* group_num */ nla_total_size(sizeof(u32)) + /* seq */ nla_total_size_64bit(sizeof(u64)) + /* timestamp */ - nla_total_size(sizeof(u16)); /* protocol */ + nla_total_size(sizeof(u16)) + /* protocol */ + nla_total_size(md->user_cookie_len); /* user_cookie */ #ifdef CONFIG_INET tun_info = skb_tunnel_info(skb); @@ -579,6 +580,15 @@ void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, goto error; } #endif + if (md->user_cookie && md->user_cookie_len) { + int nla_len = nla_total_size(md->user_cookie_len); + struct nlattr *nla; + + nla = skb_put(nl_skb, nla_len); + nla->nla_type = PSAMPLE_ATTR_USER_COOKIE; + nla->nla_len = nla_attr_size(md->user_cookie_len); + memcpy(nla_data(nla), md->user_cookie, md->user_cookie_len); + } genlmsg_end(nl_skb, data); psample_nl_obj_desc_init(&desc, group->group_num); From patchwork Wed Apr 24 13:50:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 13641900 X-Patchwork-Delegate: kuba@kernel.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E778515DBB3 for ; Wed, 24 Apr 2024 13:54:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966886; cv=none; b=co+k8TgOzAqikWPHMYf4ohWXs9uVeHZPEuOfKYKMPluZx3hOFZuKVhal4Ya54clqg7Zk/qoixTS/E61ro44fAZg5LBdLctxCjx2Whu6AnM6+MPB/n4Ek7alIb0LtaQV8dTAVLbbKu0mMrVDU/edVPWV+hCkGzvee0U+DW1wiSrY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966886; c=relaxed/simple; bh=psco6awsRgaMV9T/niM4W2JCE6T6vm6u5bIdA5YcY4o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uxmbvSzfSCgBAWj9shS29fmlujPcci+drShK9ohhqE4CI2+l8CGz9ofQCqy0t56pPpdB+fYSAXdQB1GVTK4Q4jbZSipJvr4IbtqLNEbFR0V9tzVUJxHn8vXLGoQz8fyb7ZnCivIH9xOADYh3ppdXL/+OP4KomUUkDfdeBfYvYVE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Fgt3v+Wx; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Fgt3v+Wx" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713966884; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=80uJMF+CJMwXdgnnjS23JUC2Vtnpylf1OILSwz1dwGo=; b=Fgt3v+WxVA0VaKK+dchL1S0IvsuasM0xWPGlRr8Ruz0uUo/PWV+hWrpbx/6DV/whiXsiuz udaVBIE4UgCc/jm6fHLk7AO+FQeUax6bGu9wUc/I2K4KZ0b36Fr8RpZAbzdrhnI/SaUVF9 j6HS8A0MTvL2wHYFY07urigXnFNDU54= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-528-T36Ifq7pMmir5GN6AExaSw-1; Wed, 24 Apr 2024 09:54:41 -0400 X-MC-Unique: T36Ifq7pMmir5GN6AExaSw-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 222911839FA0; Wed, 24 Apr 2024 13:54:41 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4CCB21C060D0; Wed, 24 Apr 2024 13:54:39 +0000 (UTC) From: Adrian Moreno To: netdev@vger.kernel.org Cc: aconole@redhat.com, echaudro@redhat.com, horms@kernel.org, i.maximets@ovn.org, Adrian Moreno , Yotam Gigi , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-kernel@vger.kernel.org Subject: [PATCH net-next 4/8] net: psample: add tracepoint Date: Wed, 24 Apr 2024 15:50:51 +0200 Message-ID: <20240424135109.3524355-5-amorenoz@redhat.com> In-Reply-To: <20240424135109.3524355-1-amorenoz@redhat.com> References: <20240424135109.3524355-1-amorenoz@redhat.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Patchwork-Delegate: kuba@kernel.org Currently there are no widely-available tools to dump the metadata and group information when a packet is sampled, making it difficult to troubleshoot related issues. This makes psample use the event tracing framework to log the sampling of a packet so that it's easier to quickly identify the source (i.e: group) and context (i.e: metadata) of a packet being sampled. This patch creates some checkpatch splats, but the style of the tracepoint definition mimics that of other modules so it seems acceptable. Signed-off-by: Adrian Moreno --- net/psample/psample.c | 9 +++++++ net/psample/trace.h | 62 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 net/psample/trace.h diff --git a/net/psample/psample.c b/net/psample/psample.c index 476aaad7a885..92db8ffa2ba2 100644 --- a/net/psample/psample.c +++ b/net/psample/psample.c @@ -18,6 +18,12 @@ #include #include +#ifndef __CHECKER__ +#define CREATE_TRACE_POINTS +#endif + +#include "trace.h" + #define PSAMPLE_MAX_PACKET_SIZE 0xffff static LIST_HEAD(psample_groups_list); @@ -470,6 +476,9 @@ void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, void *data; int ret; + if (trace_psample_sample_packet_enabled()) + trace_psample_sample_packet(group, skb, sample_rate, md); + meta_len = (in_ifindex ? nla_total_size(sizeof(u16)) : 0) + (out_ifindex ? nla_total_size(sizeof(u16)) : 0) + (md->out_tc_valid ? nla_total_size(sizeof(u16)) : 0) + diff --git a/net/psample/trace.h b/net/psample/trace.h new file mode 100644 index 000000000000..2d32a846989b --- /dev/null +++ b/net/psample/trace.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM psample + +#if !defined(_TRACE_PSAMPLE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_PSAMPLE__H + +#include +#include +#include + +TRACE_EVENT(psample_sample_packet, + + TP_PROTO(struct psample_group *group, struct sk_buff *skb, + u32 sample_rate, const struct psample_metadata *md), + + TP_ARGS(group, skb, sample_rate, md), + + TP_STRUCT__entry( + __field(u32, group_num) + __field(u32, refcount) + __field(u32, seq) + __field(void *, skbaddr) + __field(unsigned int, len) + __field(unsigned int, data_len) + __field(u32, sample_rate) + __field(int, in_ifindex) + __field(int, out_ifindex) + __field(const void *, user_cookie) + __field(u32, user_cookie_len) + ), + + TP_fast_assign( + __entry->group_num = group->group_num; + __entry->refcount = group->refcount; + __entry->seq = group->seq; + __entry->skbaddr = skb; + __entry->len = skb->len; + __entry->data_len = skb->data_len; + __entry->sample_rate = sample_rate; + __entry->in_ifindex = md->in_ifindex; + __entry->out_ifindex = md->out_ifindex; + __entry->user_cookie = &md->user_cookie[0]; + __entry->user_cookie_len = md->user_cookie_len; + ), + + TP_printk("group_num=%u refcount=%u seq=%u skbaddr=%p len=%u data_len=%u sample_rate=%u in_ifindex=%d out_ifindex=%d user_cookie=%p user_cookie_len=%u", + __entry->group_num, __entry->refcount, __entry->seq, + __entry->skbaddr, __entry->len, __entry->data_len, + __entry->sample_rate, __entry->in_ifindex, + __entry->out_ifindex, __entry->user_cookie, + __entry->user_cookie_len) +); + +#endif /* _TRACE_PSAMPLE_H */ + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH ../../net/psample +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE trace +#include From patchwork Wed Apr 24 13:50:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 13641901 X-Patchwork-Delegate: kuba@kernel.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B27EB15EFC6 for ; Wed, 24 Apr 2024 13:54:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966890; cv=none; b=sFDvcR783hRbQs8PZ/arix6r5WbbtfYGELVAnJJVfsYUwrxkucRaWulcJXlMq/rczDQ+0+Di2fTGKQwdHXhiqAT1XjmbZd7ZIJPWGF/UQ8u+RtH8YjGj/OYRgDqSX44qlcg2lHciiOfHs8qEIA0zDO/BWrDPaN6xb1jBIztHDzk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966890; c=relaxed/simple; bh=n+RkZRic6ie2G6KEet41avGQwCdtOj5Z3lDU2WqxhVM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PeOs8Pq3ZLA6eTrXXF1iKywF7PruoJ53vdDz+iQ+Rtz3RZ7V+rMrj9aUCcWHcHpLAtUEbV41v1bs7BaETGiQBkDxg1yxSBWUNtsTqdrk1W99iPfZQXUXB71n8DPCkeRtRtFIF7SrTitPvu4MRlOQX9b/Vvk00mQUSX4A0CDH3Ys= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Q/gpswZ2; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Q/gpswZ2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713966887; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LGEwg3DBg8RjmiswLmLzz0YVtT2CJ7TbhBWyCbgcMoQ=; b=Q/gpswZ2Hi26RIQK7BUY0cBciyxt04i7Pje/YxEi3Pw5sMQJlkosBlFZyVSG5/APVTIdcz FjL7NZPFqempxVBZG88bY0zmrz9nB5VVFmxd2z6O8EHagDn2ss7W84yKAsoYyOl10ZvOO9 Jd46lw+2HxUjSYbEPHskvvHuPV/uPrY= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-656-Vzx_EQ-XMa24eb4s9v5pQA-1; Wed, 24 Apr 2024 09:54:44 -0400 X-MC-Unique: Vzx_EQ-XMa24eb4s9v5pQA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id EC52A104D537; Wed, 24 Apr 2024 13:54:43 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 902EC1C060D0; Wed, 24 Apr 2024 13:54:41 +0000 (UTC) From: Adrian Moreno To: netdev@vger.kernel.org Cc: aconole@redhat.com, echaudro@redhat.com, horms@kernel.org, i.maximets@ovn.org, Adrian Moreno , Jamal Hadi Salim , Cong Wang , Jiri Pirko , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-kernel@vger.kernel.org Subject: [PATCH net-next 5/8] net: sched: act_sample: add action cookie to sample Date: Wed, 24 Apr 2024 15:50:52 +0200 Message-ID: <20240424135109.3524355-6-amorenoz@redhat.com> In-Reply-To: <20240424135109.3524355-1-amorenoz@redhat.com> References: <20240424135109.3524355-1-amorenoz@redhat.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Patchwork-Delegate: kuba@kernel.org If the action has a user_cookie, pass it along to the sample so it can be easily identified. Signed-off-by: Adrian Moreno Reviewed-by: Ido Schimmel Reviewed-by: Jamal Hadi Salim --- net/sched/act_sample.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c index a69b53d54039..5c3f86ec964a 100644 --- a/net/sched/act_sample.c +++ b/net/sched/act_sample.c @@ -165,9 +165,11 @@ TC_INDIRECT_SCOPE int tcf_sample_act(struct sk_buff *skb, const struct tc_action *a, struct tcf_result *res) { + u8 cookie_data[TC_COOKIE_MAX_SIZE] = {}; struct tcf_sample *s = to_sample(a); struct psample_group *psample_group; struct psample_metadata md = {}; + struct tc_cookie *user_cookie; int retval; tcf_lastuse_update(&s->tcf_tm); @@ -189,6 +191,16 @@ TC_INDIRECT_SCOPE int tcf_sample_act(struct sk_buff *skb, if (skb_at_tc_ingress(skb) && tcf_sample_dev_ok_push(skb->dev)) skb_push(skb, skb->mac_len); + rcu_read_lock(); + user_cookie = rcu_dereference(a->user_cookie); + if (user_cookie) { + memcpy(cookie_data, user_cookie->data, + user_cookie->len); + md.user_cookie = cookie_data; + md.user_cookie_len = user_cookie->len; + } + rcu_read_unlock(); + md.trunc_size = s->truncate ? s->trunc_size : skb->len; psample_sample_packet(psample_group, skb, s->rate, &md); From patchwork Wed Apr 24 13:50:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 13641902 X-Patchwork-Delegate: kuba@kernel.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DEA4215E202 for ; Wed, 24 Apr 2024 13:54:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966897; cv=none; b=m31UEdeZxREs7qSaTsrHt5Hb3T54m+eF9v1c8aqCMcjnbRmYdDZdJ5x633Z1m1kDCi1V02+yn3bAWZj9v/GuydsP0Gtl/SlNnDhv4z0Upe4qIY6R6zumt51DPpjdFj46F4AuEuKeUQTqFahLVkrzpszu55QWPdus6gkY98NlAV4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966897; c=relaxed/simple; bh=4NcjaWSsSdX3L3qcZFJzNNlvPctHO6umf9/Defd/OAY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lh8viNKZp9svgvkd6AZSFt27cwJXfNL8mWTESGqA3JK3zG13RveAbrL3Sa9lsDYwGSo1EOA1Hk55DNHw41o8GU41/QdMHVU2aak9UpKU4BGaj2aPQqrnwrqT76kJ8yg3ai/f4AauRKDqHjDgS2FitBKIFF1H2YY4t4FD3DCQ33g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=NiZ/p5LM; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="NiZ/p5LM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713966895; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jIPqwhfGK1wcmX33k6tBJ0wJeSbk/ZBhsvCTykKHqkw=; b=NiZ/p5LMl5oc1Feji6su5aDoau1p4c3taNE4LHw3Aa/KtaFY7ipY5nGB6/w2gO1SPcsqqy wyeXwiHNhTSrWEKHPeAuf16qIYjGLYoX2j6b2HU8pWmY7Db6uq3Y93F/gFk8SFe8DksA4B V7Qx8QQMktA7fjcV48o8w6BUaNVuIaQ= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-70-_LhlJPW2PiOSXqOiu7ySag-1; Wed, 24 Apr 2024 09:54:51 -0400 X-MC-Unique: _LhlJPW2PiOSXqOiu7ySag-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 35ABB3C02B54; Wed, 24 Apr 2024 13:54:51 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1D8CE1C06798; Wed, 24 Apr 2024 13:54:48 +0000 (UTC) From: Adrian Moreno To: netdev@vger.kernel.org Cc: aconole@redhat.com, echaudro@redhat.com, horms@kernel.org, i.maximets@ovn.org, Adrian Moreno , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Pravin B Shelar , Donald Hunter , linux-kernel@vger.kernel.org, dev@openvswitch.org Subject: [PATCH net-next 6/8] net:openvswitch: add psample support Date: Wed, 24 Apr 2024 15:50:53 +0200 Message-ID: <20240424135109.3524355-7-amorenoz@redhat.com> In-Reply-To: <20240424135109.3524355-1-amorenoz@redhat.com> References: <20240424135109.3524355-1-amorenoz@redhat.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Patchwork-Delegate: kuba@kernel.org Add support for psample sampling via two new attributes to the OVS_ACTION_ATTR_SAMPLE action. OVS_SAMPLE_ATTR_PSAMPLE_GROUP used to pass an integer psample group_id. OVS_SAMPLE_ATTR_PSAMPLE_COOKIE used to pass a variable-length binary cookie that will be forwared to psample. The maximum length of the user-defined cookie is set to 16, same as tc_cookie, to discourage using cookies that will not be offloadable. In order to simplify the internal processing of the action and given the maximum size of the cookie is relatively small, add both fields to the internal-only struct sample_arg. The presence of a group_id mandates that the action shall called the psample module to multicast the packet with such group_id and the user-provided cookie if present. This behavior is orthonogal to also executing the nested actions if present. Signed-off-by: Adrian Moreno --- Documentation/netlink/specs/ovs_flow.yaml | 6 ++ include/uapi/linux/openvswitch.h | 49 ++++++++++---- net/openvswitch/actions.c | 51 +++++++++++++-- net/openvswitch/flow_netlink.c | 80 ++++++++++++++++++----- 4 files changed, 153 insertions(+), 33 deletions(-) diff --git a/Documentation/netlink/specs/ovs_flow.yaml b/Documentation/netlink/specs/ovs_flow.yaml index 4fdfc6b5cae9..5543c2937225 100644 --- a/Documentation/netlink/specs/ovs_flow.yaml +++ b/Documentation/netlink/specs/ovs_flow.yaml @@ -825,6 +825,12 @@ attribute-sets: name: actions type: nest nested-attributes: action-attrs + - + name: psample_group + type: u32 + - + name: psample_cookie + type: binary - name: userspace-attrs enum-name: ovs-userspace-attr diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h index efc82c318fa2..e9cd6f3a952d 100644 --- a/include/uapi/linux/openvswitch.h +++ b/include/uapi/linux/openvswitch.h @@ -639,6 +639,7 @@ enum ovs_flow_attr { #define OVS_UFID_F_OMIT_MASK (1 << 1) #define OVS_UFID_F_OMIT_ACTIONS (1 << 2) +#define OVS_PSAMPLE_COOKIE_MAX_SIZE 16 /** * enum ovs_sample_attr - Attributes for %OVS_ACTION_ATTR_SAMPLE action. * @OVS_SAMPLE_ATTR_PROBABILITY: 32-bit fraction of packets to sample with @@ -646,15 +647,27 @@ enum ovs_flow_attr { * %UINT32_MAX samples all packets and intermediate values sample intermediate * fractions of packets. * @OVS_SAMPLE_ATTR_ACTIONS: Set of actions to execute in sampling event. - * Actions are passed as nested attributes. + * Actions are passed as nested attributes. Optional if + * OVS_SAMPLE_ATTR_PSAMPLE_GROUP is set. + * @OVS_SAMPLE_ATTR_PSAMPLE_GROUP: A 32-bit number to be used as psample group. + * Optional if OVS_SAMPLE_ATTR_ACTIONS is set. + * @OVS_SAMPLE_ATTR_PSAMPLE_COOKIE: A variable-length binary cookie that, if + * provided, will be copied to the psample cookie. * - * Executes the specified actions with the given probability on a per-packet - * basis. + * Either OVS_SAMPLE_ATTR_PSAMPLE_GROUP or OVS_SAMPLE_ATTR_ACTIONS must be + * specified. + * + * Executes the specified actions and/or sends the packet to psample + * with the given probability on a per-packet basis. */ enum ovs_sample_attr { OVS_SAMPLE_ATTR_UNSPEC, - OVS_SAMPLE_ATTR_PROBABILITY, /* u32 number */ - OVS_SAMPLE_ATTR_ACTIONS, /* Nested OVS_ACTION_ATTR_* attributes. */ + OVS_SAMPLE_ATTR_PROBABILITY, /* u32 number */ + OVS_SAMPLE_ATTR_ACTIONS, /* Nested OVS_ACTION_ATTR_ + * attributes. + */ + OVS_SAMPLE_ATTR_PSAMPLE_GROUP, /* u32 number */ + OVS_SAMPLE_ATTR_PSAMPLE_COOKIE, /* binary */ __OVS_SAMPLE_ATTR_MAX, #ifdef __KERNEL__ @@ -665,13 +678,27 @@ enum ovs_sample_attr { #define OVS_SAMPLE_ATTR_MAX (__OVS_SAMPLE_ATTR_MAX - 1) #ifdef __KERNEL__ + +/* Definition for flags in struct sample_arg. */ +enum { + /* When set, actions in sample will not change the flows. */ + OVS_SAMPLE_ARG_FLAG_EXEC = 1 << 0, + /* When set, the packet will be sent to psample. */ + OVS_SAMPLE_ARG_FLAG_PSAMPLE = 1 << 1, +}; + struct sample_arg { - bool exec; /* When true, actions in sample will not - * change flow keys. False otherwise. - */ - u32 probability; /* Same value as - * 'OVS_SAMPLE_ATTR_PROBABILITY'. - */ + u16 flags; /* Flags that modify the behavior of the + * action. See SAMPLE_ARG_FLAG_*. + */ + u32 probability; /* Same value as + * 'OVS_SAMPLE_ATTR_PROBABILITY'. + */ + u32 group_id; /* Same value as + * 'OVS_SAMPLE_ATTR_PSAMPLE_GROUP'. + */ + u8 cookie_len; /* Length of psample cookie. */ + char cookie[OVS_PSAMPLE_COOKIE_MAX_SIZE]; /* psample cookie data. */ }; #endif diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 6fcd7e2ca81f..eb3166986fd2 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "datapath.h" @@ -1025,6 +1026,34 @@ static int dec_ttl_exception_handler(struct datapath *dp, struct sk_buff *skb, return 0; } +static int ovs_psample_packet(struct datapath *dp, struct sw_flow_key *key, + const struct sample_arg *arg, + struct sk_buff *skb) +{ + struct psample_group psample_group = {}; + struct psample_metadata md = {}; + struct vport *input_vport; + u32 rate; + + psample_group.group_num = arg->group_id; + psample_group.net = ovs_dp_get_net(dp); + + input_vport = ovs_vport_rcu(dp, key->phy.in_port); + if (!input_vport) + input_vport = ovs_vport_rcu(dp, OVSP_LOCAL); + + md.in_ifindex = input_vport->dev->ifindex; + md.user_cookie = arg->cookie_len ? &arg->cookie[0] : NULL; + md.user_cookie_len = arg->cookie_len; + md.trunc_size = skb->len; + + rate = arg->probability ? U32_MAX / arg->probability : 0; + + psample_sample_packet(&psample_group, skb, rate, &md); + + return 0; +} + /* When 'last' is true, sample() should always consume the 'skb'. * Otherwise, sample() should keep 'skb' intact regardless what * actions are executed within sample(). @@ -1033,11 +1062,12 @@ static int sample(struct datapath *dp, struct sk_buff *skb, struct sw_flow_key *key, const struct nlattr *attr, bool last) { - struct nlattr *actions; + const struct sample_arg *arg; struct nlattr *sample_arg; int rem = nla_len(attr); - const struct sample_arg *arg; + struct nlattr *actions; bool clone_flow_key; + int ret; /* The first action is always 'OVS_SAMPLE_ATTR_ARG'. */ sample_arg = nla_data(attr); @@ -1051,9 +1081,20 @@ static int sample(struct datapath *dp, struct sk_buff *skb, return 0; } - clone_flow_key = !arg->exec; - return clone_execute(dp, skb, key, 0, actions, rem, last, - clone_flow_key); + if (arg->flags & OVS_SAMPLE_ARG_FLAG_PSAMPLE) { + ret = ovs_psample_packet(dp, key, arg, skb); + if (ret) + return ret; + } + + if (nla_ok(actions, rem)) { + clone_flow_key = !(arg->flags & OVS_SAMPLE_ARG_FLAG_EXEC); + ret = clone_execute(dp, skb, key, 0, actions, rem, last, + clone_flow_key); + } else if (last) { + ovs_kfree_skb_reason(skb, OVS_DROP_LAST_ACTION); + } + return ret; } /* When 'last' is true, clone() should always consume the 'skb'. diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index f224d9bcea5e..1a348d3905fc 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c @@ -2561,6 +2561,9 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr, u32 mpls_label_count, bool log, u32 depth); +static int copy_action(const struct nlattr *from, + struct sw_flow_actions **sfa, bool log); + static int validate_and_copy_sample(struct net *net, const struct nlattr *attr, const struct sw_flow_key *key, struct sw_flow_actions **sfa, @@ -2569,10 +2572,10 @@ static int validate_and_copy_sample(struct net *net, const struct nlattr *attr, u32 depth) { const struct nlattr *attrs[OVS_SAMPLE_ATTR_MAX + 1]; - const struct nlattr *probability, *actions; + const struct nlattr *probability, *actions, *group, *cookie; + struct sample_arg arg = {}; const struct nlattr *a; int rem, start, err; - struct sample_arg arg; memset(attrs, 0, sizeof(attrs)); nla_for_each_nested(a, attr, rem) { @@ -2589,7 +2592,19 @@ static int validate_and_copy_sample(struct net *net, const struct nlattr *attr, return -EINVAL; actions = attrs[OVS_SAMPLE_ATTR_ACTIONS]; - if (!actions || (nla_len(actions) && nla_len(actions) < NLA_HDRLEN)) + if (actions && (!nla_len(actions) || nla_len(actions) < NLA_HDRLEN)) + return -EINVAL; + + group = attrs[OVS_SAMPLE_ATTR_PSAMPLE_GROUP]; + if (group && nla_len(group) != sizeof(u32)) + return -EINVAL; + + cookie = attrs[OVS_SAMPLE_ATTR_PSAMPLE_COOKIE]; + if (cookie && + (!group || nla_len(cookie) > OVS_PSAMPLE_COOKIE_MAX_SIZE)) + return -EINVAL; + + if (!group && !actions) return -EINVAL; /* validation done, copy sample action. */ @@ -2608,7 +2623,19 @@ static int validate_and_copy_sample(struct net *net, const struct nlattr *attr, * If the sample is the last action, it can always be excuted * rather than deferred. */ - arg.exec = last || !actions_may_change_flow(actions); + if (actions && (last || !actions_may_change_flow(actions))) + arg.flags |= OVS_SAMPLE_ARG_FLAG_EXEC; + + if (group) { + arg.flags |= OVS_SAMPLE_ARG_FLAG_PSAMPLE; + arg.group_id = nla_get_u32(group); + } + + if (cookie) { + memcpy(&arg.cookie[0], nla_data(cookie), nla_len(cookie)); + arg.cookie_len = nla_len(cookie); + } + arg.probability = nla_get_u32(probability); err = ovs_nla_add_action(sfa, OVS_SAMPLE_ATTR_ARG, &arg, sizeof(arg), @@ -2616,12 +2643,13 @@ static int validate_and_copy_sample(struct net *net, const struct nlattr *attr, if (err) return err; - err = __ovs_nla_copy_actions(net, actions, key, sfa, - eth_type, vlan_tci, mpls_label_count, log, - depth + 1); - - if (err) - return err; + if (actions) { + err = __ovs_nla_copy_actions(net, actions, key, sfa, + eth_type, vlan_tci, + mpls_label_count, log, depth + 1); + if (err) + return err; + } add_nested_action_end(*sfa, start); @@ -3553,20 +3581,38 @@ static int sample_action_to_attr(const struct nlattr *attr, goto out; } - ac_start = nla_nest_start_noflag(skb, OVS_SAMPLE_ATTR_ACTIONS); - if (!ac_start) { - err = -EMSGSIZE; - goto out; + if (arg->flags & OVS_SAMPLE_ARG_FLAG_PSAMPLE) { + if (nla_put_u32(skb, OVS_SAMPLE_ATTR_PSAMPLE_GROUP, + arg->group_id)) { + err = -EMSGSIZE; + goto out; + } + + if (arg->cookie_len && + nla_put(skb, OVS_SAMPLE_ATTR_PSAMPLE_COOKIE, + arg->cookie_len, &arg->cookie[0])) { + err = -EMSGSIZE; + goto out; + } } - err = ovs_nla_put_actions(actions, rem, skb); + if (nla_ok(actions, rem)) { + ac_start = nla_nest_start_noflag(skb, OVS_SAMPLE_ATTR_ACTIONS); + if (!ac_start) { + err = -EMSGSIZE; + goto out; + } + err = ovs_nla_put_actions(actions, rem, skb); + } out: if (err) { - nla_nest_cancel(skb, ac_start); + if (ac_start) + nla_nest_cancel(skb, ac_start); nla_nest_cancel(skb, start); } else { - nla_nest_end(skb, ac_start); + if (ac_start) + nla_nest_end(skb, ac_start); nla_nest_end(skb, start); } From patchwork Wed Apr 24 13:50:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 13641903 X-Patchwork-Delegate: kuba@kernel.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9468115F406 for ; Wed, 24 Apr 2024 13:54:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966900; cv=none; b=rNmvvB9ad4EK6uz1+YPhagmVzIxC0N0LH5Go2OwNrJHDFrhrNsLgMmB+LC76nHqsH2s0tGbGBN9fOx0Kn+Zoo8bdIL3V4hEkQallL20AgIB06QQg0ETo4k/dg+Lda3F2r9Dt+NinGkp678xayrz482O8A7HYKLDUiERoCBcbMcE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966900; c=relaxed/simple; bh=mCBdU1/Y+iR5BPM7dVWuIGMSVDs5uBgokHyUvZNcpYU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KWMW4G5nBGuTDQqyScYMUTkszKjz7j4uEdbDblELYRgEjd1+3bom4xZ8OoIzhLyumYO8HPNHT1dS4ucG4Ii8GFtk00HXK8iyTQLrVq4ajEUpPRGm+Bw6z/0jbkY/kp7rPO9IV1YnZz4lE1uGX2r5OOkH1H4XhpUYM3d/+KNT5L4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Je8uenkB; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Je8uenkB" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713966897; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=z8Yzpk3KTnFdMHRu4agPz/+OCowB+XjwxhNrbJUlANE=; b=Je8uenkBT/1lxDYl3GRx0Q82aXUMwiYo41v8StN2qNrpq7S8YFpmKFfUy0QNwhWcaPScuv eQo3bSgZir5GmhEB0B/+lnqe637AudijjYafODMLJ9xccix+jWJXkJGn+CikuUaURabssp 49QsQg1L0JoThWyUhAfMOgTkZpWltnc= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-436-gVewJ_sWPXmhNDPqLA0nCg-1; Wed, 24 Apr 2024 09:54:54 -0400 X-MC-Unique: gVewJ_sWPXmhNDPqLA0nCg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id DC6F43C02B49; Wed, 24 Apr 2024 13:54:53 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id ACE0E1C060D0; Wed, 24 Apr 2024 13:54:51 +0000 (UTC) From: Adrian Moreno To: netdev@vger.kernel.org Cc: aconole@redhat.com, echaudro@redhat.com, horms@kernel.org, i.maximets@ovn.org, Adrian Moreno , Pravin B Shelar , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Shuah Khan , dev@openvswitch.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next 7/8] selftests: openvswitch: add sample action. Date: Wed, 24 Apr 2024 15:50:54 +0200 Message-ID: <20240424135109.3524355-8-amorenoz@redhat.com> In-Reply-To: <20240424135109.3524355-1-amorenoz@redhat.com> References: <20240424135109.3524355-1-amorenoz@redhat.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Patchwork-Delegate: kuba@kernel.org Add sample action support to ovs-dpctl.py. Signed-off-by: Adrian Moreno --- .../selftests/net/openvswitch/ovs-dpctl.py | 96 ++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py index 1dd057afd3fb..3a2dddc57e42 100644 --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py @@ -8,6 +8,7 @@ import argparse import errno import ipaddress import logging +import math import multiprocessing import re import struct @@ -58,6 +59,7 @@ OVS_FLOW_CMD_DEL = 2 OVS_FLOW_CMD_GET = 3 OVS_FLOW_CMD_SET = 4 +UINT32_MAX = 0xFFFFFFFF def macstr(mac): outstr = ":".join(["%02X" % i for i in mac]) @@ -285,7 +287,7 @@ class ovsactions(nla): ("OVS_ACTION_ATTR_SET", "none"), ("OVS_ACTION_ATTR_PUSH_VLAN", "none"), ("OVS_ACTION_ATTR_POP_VLAN", "flag"), - ("OVS_ACTION_ATTR_SAMPLE", "none"), + ("OVS_ACTION_ATTR_SAMPLE", "sample"), ("OVS_ACTION_ATTR_RECIRC", "uint32"), ("OVS_ACTION_ATTR_HASH", "none"), ("OVS_ACTION_ATTR_PUSH_MPLS", "none"), @@ -306,6 +308,91 @@ class ovsactions(nla): ("OVS_ACTION_ATTR_DROP", "uint32"), ) + class sample(nla): + nla_flags = NLA_F_NESTED + + nla_map = ( + ("OVS_SAMPLE_ATTR_UNSPEC", "none"), + ("OVS_SAMPLE_ATTR_PROBABILITY", "uint32"), + ("OVS_SAMPLE_ATTR_ACTIONS", "ovsactions"), + ("OVS_SAMPLE_ATTR_PSAMPLE_GROUP", "uint32"), + ("OVS_SAMPLE_ATTR_PSAMPLE_COOKIE", "array(uint8)"), + ) + + def dpstr(self, more=False): + args = [] + + args.append("sample={:.2f}%".format( + 100 * self.get_attr("OVS_SAMPLE_ATTR_PROBABILITY") / + UINT32_MAX)) + + group = self.get_attr("OVS_SAMPLE_ATTR_PSAMPLE_GROUP") + cookie = self.get_attr("OVS_SAMPLE_ATTR_PSAMPLE_COOKIE") + actions = self.get_attr("OVS_SAMPLE_ATTR_ACTIONS") + + if group: + args.append("group_id=%d" % group) + if cookie: + args.append("cookie=%s" % + "".join(format(x, "02x") for x in cookie)) + if actions: + args.append("actions(%s)" % actions.dpstr(more)) + + return "sample(%s)" % ",".join(args) + + def parse(self, actstr): + """ Parses the input action string and populates the internal + attributes. The input string must start with "sample(" + + Returns the remaining action string. + Raises ValueError if the action string has invalid content. + """ + + def parse_nested_actions(actstr): + subacts = ovsactions() + parsed_len = subacts.parse(actstr) + return subacts, parsed_len + + def percent_to_rate(percent): + percent = float(percent.strip('%')) + return int(math.floor(UINT32_MAX * (percent / 100.0) + .5)) + + for (key, attr, func) in ( + ("sample", "OVS_SAMPLE_ATTR_PROBABILITY", percent_to_rate), + ("group_id", "OVS_SAMPLE_ATTR_PSAMPLE_GROUP", int), + ("cookie", "OVS_SAMPLE_ATTR_PSAMPLE_COOKIE", + lambda x: list(bytearray.fromhex(x))), + ("actions", "OVS_SAMPLE_ATTR_ACTIONS", parse_nested_actions), + ): + if not actstr.startswith(key): + continue + + actstr = actstr[len(key) :] + + if not func: + self["attrs"].append([attr, None]) + continue + + # The length of complex attributes cannot be determined + # beforehand and must be reported by the parsing func. + delim = actstr[0] + actstr = actstr[1:] + if delim == "=": + pos = strcspn(actstr, ",)") + datum = func(actstr[:pos]) + elif delim == "(": + datum, pos = func(actstr) + + self["attrs"].append([attr, datum]) + actstr = actstr[pos:] + actstr = actstr[strspn(actstr, ", ") :] + + if actstr[0] != ")": + raise ValueError("Action str: '%s' unbalanced" % actstr) + + return actstr[1:] + + class ctact(nla): nla_flags = NLA_F_NESTED @@ -637,6 +724,13 @@ class ovsactions(nla): self["attrs"].append(["OVS_ACTION_ATTR_CT", ctact]) parsed = True + elif parse_starts_block(actstr, "sample(", False): + sampleact = self.sample() + actstr = sampleact.parse(actstr[len("sample(") : ]) + self["attrs"].append(["OVS_ACTION_ATTR_SAMPLE", sampleact]) + parsed = True + + actstr = actstr[strspn(actstr, ", ") :] while parencount > 0: parencount -= 1 From patchwork Wed Apr 24 13:50:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 13641904 X-Patchwork-Delegate: kuba@kernel.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D912F15F413 for ; Wed, 24 Apr 2024 13:54:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966901; cv=none; b=Zo/kTawMvbFagh1fINKLLBXMDZq1ZrKqwHbFKXKpf8arkJoDqDkKdnnFATf0BRKKtoMKUPY3c5nY/ja/wVomg9FkRU+LjbfoLV8rwtDcPgvKmeUY7uY7x4eAJmpQpBJgFCTsN05c9FyLtOlPUF410eWfD1GZULPagDGCOE6Cz2w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713966901; c=relaxed/simple; bh=XeNqMhdDvrQ3e9k2Sc71pAHggkwcCI7HMO1vYqq4+y4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LNFWbTUTFG5EMHyWZT2AieqcWV2ibWjkIFqsg94fhoknOtjK/ez1n2Imjt7dEeN8zEF29SDT/YhQXWJgCQm26LNX7GxCuZOLRyBj4QuvNTm5dcMqAQgluxz6/5p1emKfqzPk1PHg6Ezs4IWkltDYgOR/x5VtsPDrsXDShpJG6MI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=FHJw1GO3; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="FHJw1GO3" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713966899; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NRfG44Ph4wnW5G/uRG2RMT/4P6AMh9CGQOP3sRR/P0s=; b=FHJw1GO3tC7uu3484bATFlR5zC7tNUxrRzGNYkBbg23gH/GqllaQNzGGW/vSk6IB1E6one t/M9Lgzat7+rjVA+9x3ctMOwjEcGTfQSFqY9XmBDra2i6Ly7BsynewsJkR18T69c0Rw4yD Z4YOaVAvf9/bCV3Pu/hYKUQio4GI1a4= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-411-aHlfTTb1N_y3PKS5ssXMKg-1; Wed, 24 Apr 2024 09:54:57 -0400 X-MC-Unique: aHlfTTb1N_y3PKS5ssXMKg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id BFC47823F1D; Wed, 24 Apr 2024 13:54:56 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8AB1C1C060D0; Wed, 24 Apr 2024 13:54:54 +0000 (UTC) From: Adrian Moreno To: netdev@vger.kernel.org Cc: aconole@redhat.com, echaudro@redhat.com, horms@kernel.org, i.maximets@ovn.org, Adrian Moreno , Pravin B Shelar , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Shuah Khan , dev@openvswitch.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next 8/8] selftests: openvswitch: add psample test Date: Wed, 24 Apr 2024 15:50:55 +0200 Message-ID: <20240424135109.3524355-9-amorenoz@redhat.com> In-Reply-To: <20240424135109.3524355-1-amorenoz@redhat.com> References: <20240424135109.3524355-1-amorenoz@redhat.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Patchwork-Delegate: kuba@kernel.org Add a test to verify sampling packets via psample works. In order to do that, create a subcommand in ovs-dpctl.py to listen to on the psample multicast group and print samples. In order to also test simultaneous sFlow and psample actions, add missing parsing support for "userspace" action (via refactoring the one in sample). Signed-off-by: Adrian Moreno --- .../selftests/net/openvswitch/openvswitch.sh | 97 +++++++++- .../selftests/net/openvswitch/ovs-dpctl.py | 167 ++++++++++++++---- 2 files changed, 231 insertions(+), 33 deletions(-) diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh b/tools/testing/selftests/net/openvswitch/openvswitch.sh index 5cae53543849..7a2307a384a9 100755 --- a/tools/testing/selftests/net/openvswitch/openvswitch.sh +++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh @@ -20,7 +20,8 @@ tests=" nat_related_v4 ip4-nat-related: ICMP related matches work with SNAT netlink_checks ovsnl: validate netlink attrs and settings upcall_interfaces ovs: test the upcall interfaces - drop_reason drop: test drop reasons are emitted" + drop_reason drop: test drop reasons are emitted + psample psample: Sampling packets with psample" info() { [ $VERBOSE = 0 ] || echo $* @@ -170,6 +171,19 @@ ovs_drop_reason_count() return `echo "$perf_output" | grep "$pattern" | wc -l` } +ovs_test_flow_fails () { + ERR_MSG="Flow actions may not be safe on all matching packets" + + PRE_TEST=$(dmesg | grep -c "${ERR_MSG}") + ovs_add_flow $@ &> /dev/null $@ && return 1 + POST_TEST=$(dmesg | grep -c "${ERR_MSG}") + + if [ "$PRE_TEST" == "$POST_TEST" ]; then + return 1 + fi + return 0 +} + usage() { echo echo "$0 [OPTIONS] [TEST]..." @@ -184,6 +198,87 @@ usage() { exit 1 } + +# psample test +# - samples packets with psample +test_psample() { + sbx_add "test_psample" || return $? + + # Add a datapath with per-vport dispatching. + ovs_add_dp "test_psample" psample -V 2:1 || return 1 + + info "create namespaces" + ovs_add_netns_and_veths "test_psample" "psample" \ + client c0 c1 172.31.110.10/24 -u || return 1 + ovs_add_netns_and_veths "test_psample" "psample" \ + server s0 s1 172.31.110.20/24 -u || return 1 + + # Check if psample actions can be configured. + ovs_add_flow "test_psample" psample \ + 'in_port(1),eth(),eth_type(0x0806),arp()' 'sample(sample=100%,group_id=1,cookie=0102)' + if [ $? == 1 ]; then + info "no support for psample - skipping" + ovs_exit_sig + return $ksft_skip + fi + + ovs_del_flows "test_psample" psample + + # Allow ARP + ovs_add_flow "test_psample" psample \ + 'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1 + ovs_add_flow "test_psample" psample \ + 'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1 + + # Test action verification. + OLDIFS=$IFS + IFS='*' + min_key='in_port(1),eth(),eth_type(0x800),ipv4()' + for testcase in \ + "cookie to large"*"sample(sample=100%,group_id=1,cookie=1615141312111009080706050403020100)" \ + "no group or action"*"sample(sample=100%)" \ + "no group or action with cookie"*"sample(sample=100%,cookie=deadbeef)"; + do + set -- $testcase; + ovs_test_flow_fails "test_psample" psample $min_key $2 + if [ $? == 1 ]; then + info "failed - $1" + return 1 + fi + done + IFS=$OLDIFS + + # Sample all traffic. In this case the sample action only has psample + # arguments. + ovs_add_flow "test_psample" psample \ + "in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10,proto=1),icmp()" "sample(sample=100%,group_id=1,cookie=c0ffee),2" + + # Sample all traffic. In this case the sample action has both psample + # arguments and an upcall emulating simultaneous psample and + # sFlow / IPFIX. + nlpid=$(grep -E "listening on upcall packet handler" $ovs_dir/s0.out | cut -d ":" -f 2 | tr -d ' ') + ovs_add_flow "test_psample" psample \ + "in_port(2),eth(),eth_type(0x0800),ipv4(src=172.31.110.20,proto=1),icmp()" "sample(sample=100%,group_id=2,cookie=eeff0c,actions(userspace(pid=${nlpid},userdata=eeff0c))),1" + + # Record psample data. + python3 $ovs_base/ovs-dpctl.py psample >$ovs_dir/psample.out 2>$ovs_dir/psample.err & + pid=$! + on_exit "ovs_sbx test_psample kill -TERM $pid 2>/dev/null" + + # Send a single ping. + sleep 1 + ovs_sbx "test_psample" ip netns exec client ping -I c1 172.31.110.20 -c 1 || return 1 + sleep 1 + + # We should have received one userspace action upcall and 2 psample packets. + grep -E "userspace action command" $ovs_dir/s0.out >/dev/null 2>&1 || return 1 + + grep -E "rate:1,group:1,cookie:c0ffee" $ovs_dir/psample.out >/dev/null 2>&1 || return 1 + grep -E "rate:1,group:2,cookie:eeff0c" $ovs_dir/psample.out >/dev/null 2>&1 || return 1 + + return 0 +} + # drop_reason test # - drop packets and verify the right drop reason is reported test_drop_reason() { diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py index 3a2dddc57e42..2fb5bcfe9c36 100644 --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py @@ -27,8 +27,10 @@ try: from pyroute2.netlink import genlmsg from pyroute2.netlink import nla from pyroute2.netlink import nlmsg_atoms - from pyroute2.netlink.exceptions import NetlinkError + from pyroute2.netlink.event import EventSocket from pyroute2.netlink.generic import GenericNetlinkSocket + from pyroute2.netlink.nlsocket import Marshal + from pyroute2.netlink.exceptions import NetlinkError import pyroute2 except ModuleNotFoundError: @@ -269,6 +271,47 @@ def parse_extract_field( return str_skipped, data +def parse_attributes(actstr, attributes): + """Parses actstr according to attribute description. attributes must be + a list of tuples (name, attribute, parse_func), e.g: + ("pid", OVS_USERSPACE_ATTR_PID, int) + + Returns a list of parsed attributes followed by the remaining string. + """ + attrs = [] + for (key, attr, func) in attributes: + if not actstr.startswith(key): + continue + + actstr = actstr[len(key) :] + + if not func: + attrs.append([attr]) + continue + + # The length of complex attributes cannot be determined + # beforehand and must be reported by the parsing func. + delim = actstr[0] + actstr = actstr[1:] + if delim == "=": + pos = strcspn(actstr, ",)") + datum = func(actstr[:pos]) + elif delim == "(": + datum, pos = func(actstr) + + attrs.append([attr, datum]) + actstr = actstr[pos:] + + if delim == "(": + actstr = actstr[1:] + + actstr = actstr[strspn(actstr, ", ") :] + + if actstr[0] != ")": + raise ValueError("Action str: '%s' unbalanced" % actstr) + + return attrs, actstr[1:] + class ovs_dp_msg(genlmsg): # include the OVS version # We need a custom header rather than just being able to rely on @@ -357,41 +400,19 @@ class ovsactions(nla): percent = float(percent.strip('%')) return int(math.floor(UINT32_MAX * (percent / 100.0) + .5)) - for (key, attr, func) in ( + attrs_desc = ( ("sample", "OVS_SAMPLE_ATTR_PROBABILITY", percent_to_rate), ("group_id", "OVS_SAMPLE_ATTR_PSAMPLE_GROUP", int), ("cookie", "OVS_SAMPLE_ATTR_PSAMPLE_COOKIE", lambda x: list(bytearray.fromhex(x))), ("actions", "OVS_SAMPLE_ATTR_ACTIONS", parse_nested_actions), - ): - if not actstr.startswith(key): - continue - - actstr = actstr[len(key) :] - - if not func: - self["attrs"].append([attr, None]) - continue - - # The length of complex attributes cannot be determined - # beforehand and must be reported by the parsing func. - delim = actstr[0] - actstr = actstr[1:] - if delim == "=": - pos = strcspn(actstr, ",)") - datum = func(actstr[:pos]) - elif delim == "(": - datum, pos = func(actstr) - - self["attrs"].append([attr, datum]) - actstr = actstr[pos:] - actstr = actstr[strspn(actstr, ", ") :] - - if actstr[0] != ")": - raise ValueError("Action str: '%s' unbalanced" % actstr) + ) - return actstr[1:] + attrs, actstr = parse_attributes(actstr, attrs_desc) + for attr in attrs: + self["attrs"].append(attr) + return actstr class ctact(nla): nla_flags = NLA_F_NESTED @@ -521,6 +542,18 @@ class ovsactions(nla): print_str += ")" return print_str + def parse(self, actstr): + attrs_desc = ( + ("pid", "OVS_USERSPACE_ATTR_PID", int), + ("userdata", "OVS_USERSPACE_ATTR_USERDATA", + lambda x: list(bytearray.fromhex(x))), + ("egress_tun_port", "OVS_USERSPACE_ATTR_EGRESS_TUN_PORT", int) + ) + attrs, actstr = parse_attributes(actstr, attrs_desc) + for attr in attrs: + self["attrs"].append(attr) + return actstr + def dpstr(self, more=False): print_str = "" @@ -730,6 +763,11 @@ class ovsactions(nla): self["attrs"].append(["OVS_ACTION_ATTR_SAMPLE", sampleact]) parsed = True + elif parse_starts_block(actstr, "userspace(", False): + uact = self.userspace() + actstr = uact.parse(actstr[len("userpsace(") : ]) + self["attrs"].append(["OVS_ACTION_ATTR_USERSPACE", uact]) + parsed = True actstr = actstr[strspn(actstr, ", ") :] while parencount > 0: @@ -2112,10 +2150,70 @@ class OvsFlow(GenericNetlinkSocket): print("MISS upcall[%d/%s]: %s" % (seq, pktpres, keystr), flush=True) def execute(self, packetmsg): - print("userspace execute command") + print("userspace execute command", flush=True) def action(self, packetmsg): - print("userspace action command") + print("userspace action command", flush=True) + + +class psample_sample(genlmsg): + nla_map = ( + ("PSAMPLE_ATTR_IIFINDEX", "none"), + ("PSAMPLE_ATTR_OIFINDEX", "none"), + ("PSAMPLE_ATTR_ORIGSIZE", "none"), + ("PSAMPLE_ATTR_SAMPLE_GROUP", "uint32"), + ("PSAMPLE_ATTR_GROUP_SEQ", "none"), + ("PSAMPLE_ATTR_SAMPLE_RATE", "uint32"), + ("PSAMPLE_ATTR_DATA", "array(uint8)"), + ("PSAMPLE_ATTR_GROUP_REFCOUNT", "none"), + ("PSAMPLE_ATTR_TUNNEL", "none"), + ("PSAMPLE_ATTR_PAD", "none"), + ("PSAMPLE_ATTR_OUT_TC", "none"), + ("PSAMPLE_ATTR_OUT_TC_OCC", "none"), + ("PSAMPLE_ATTR_LATENCY", "none"), + ("PSAMPLE_ATTR_TIMESTAMP", "none"), + ("PSAMPLE_ATTR_PROTO", "none"), + ("PSAMPLE_ATTR_USER_COOKIE", "array(uint8)"), + ) + + def dpstr(self): + fields = [] + data = "" + for (attr, value) in self["attrs"]: + if attr == "PSAMPLE_ATTR_SAMPLE_GROUP": + fields.append("group:%d" % value) + if attr == "PSAMPLE_ATTR_SAMPLE_RATE": + fields.append("rate:%d" % value) + if attr == "PSAMPLE_ATTR_USER_COOKIE": + value = "".join(format(x, "02x") for x in value) + fields.append("cookie:%s" % value) + if attr == "PSAMPLE_ATTR_DATA" and len(value) > 0: + data = "data:%s" % "".join(format(x, "02x") for x in value) + + return ("%s %s" % (",".join(fields), data)).strip() + + +class psample_msg(Marshal): + PSAMPLE_CMD_SAMPLE = 0 + PSAMPLE_CMD_GET_GROUP = 1 + PSAMPLE_CMD_NEW_GROUP = 2 + PSAMPLE_CMD_DEL_GROUP = 3 + PSAMPLE_CMD_SET_FILTER = 4 + msg_map = {PSAMPLE_CMD_SAMPLE: psample_sample} + + +class Psample(EventSocket): + genl_family = "psample" + mcast_groups = ["packets"] + marshal_class = psample_msg + + def read_samples(self): + while True: + try: + for msg in self.get(): + print(msg.dpstr(), flush=True) + except NetlinkError as ne: + raise ne def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB(), vpl=OvsVport()): @@ -2175,7 +2273,7 @@ def main(argv): help="Increment 'verbose' output counter.", default=0, ) - subparsers = parser.add_subparsers() + subparsers = parser.add_subparsers(dest="subcommand") showdpcmd = subparsers.add_parser("show") showdpcmd.add_argument( @@ -2232,6 +2330,8 @@ def main(argv): delfscmd = subparsers.add_parser("del-flows") delfscmd.add_argument("flsbr", help="Datapath name") + subparsers.add_parser("psample") + args = parser.parse_args() if args.verbose > 0: @@ -2246,6 +2346,9 @@ def main(argv): sys.setrecursionlimit(100000) + if args.subcommand == "psample": + Psample().read_samples() + if hasattr(args, "showdp"): found = False for iface in ndb.interfaces: