From patchwork Mon Apr 8 12:57:40 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: 13621124 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 58396762DA for ; Mon, 8 Apr 2024 12:58:27 +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=1712581108; cv=none; b=S8ulQzVPO15Q+vALy7VzuEIuUUIYpYsxjNA6PaH2toj966D4HNNK5FOJReg2Kjr5Xs95UqC8iIPZMvIRSRAzw33hD1D7+RZ63RYo5m3rT0i+vuOHvlo8YJBYJkwEvYb+K+nRpVgbnPERaBvMJfqi820chjKTZtvAOnuzWzT1Q+A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712581108; c=relaxed/simple; bh=3AyGycfT0WMau/4BHOkgdyQ3sS/qjOjS/YxEFf70SDM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=m7rsGI40WtI4c82EytbF1y0nS9LA/qmTvrxxJbAzmVlpJrePwpeiz1xsUMRT6P2m1JIROf9iSDGg2RvrWb26GxdyHLHrEVJz3v3HSSDIt1Du+9+TTEMz1wZRbxKuK/b6zxKO3Cq0Bo8h5sSckZjwz3pGubKqOhMNIvMO8gOzEcQ= 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=ZLE26bVk; 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="ZLE26bVk" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1712581106; 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=2q1CIE8IfTYGc+n0dUKKT+JjLmE8wbfXj7V+fytNap4=; b=ZLE26bVkH9ibvLvGw/n0EJX2Odqb9EdZ9An/7TtNUuxRxKVwMNQRs3mfBIHYc065sjaln7 lxxN1ceLpe0PZs1NDKChSP7pNd20HY5zd2SSRh73oFiORpwm8kfaMOnOD9Uz1Nhtt0bzFn /kA2axQ+Zy5x6bd2zw98711ZQdN/QE0= 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-122-NNqM-5KPOLCUDf7c-Zl0Rw-1; Mon, 08 Apr 2024 08:58:20 -0400 X-MC-Unique: NNqM-5KPOLCUDf7c-Zl0Rw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (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 558903806222; Mon, 8 Apr 2024 12:58:20 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.170]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5542547F; Mon, 8 Apr 2024 12:58:18 +0000 (UTC) From: Adrian Moreno To: netdev@vger.kernel.org Cc: Adrian Moreno , jiri@resnulli.us, xiyou.wangcong@gmail.com, cmi@nvidia.com, yotam.gi@gmail.com, i.maximets@ovn.org, aconole@redhat.com, echaudro@redhat.com, horms@kernel.org Subject: [RFC net-next v2 1/5] net: netlink: export genl private pointer getters Date: Mon, 8 Apr 2024 14:57:40 +0200 Message-ID: <20240408125753.470419-2-amorenoz@redhat.com> In-Reply-To: <20240408125753.470419-1-amorenoz@redhat.com> References: <20240408125753.470419-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.1 X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC 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. Signed-off-by: Adrian Moreno Reviewed-by: Jakub Kicinski --- 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 Mon Apr 8 12:57:41 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: 13621125 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 E3C6470CDA for ; Mon, 8 Apr 2024 12:58:27 +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=1712581109; cv=none; b=CMFhHC+ZpfPrnw4RRhHxVn+msbFyCqHPEJN7KkfJtSeis0p7SL3uH1Bjk/GMOMHWqEhiM85/mTpZA07KsD9lEaPhnAB0WvN4gyx+yOwLdTe2fLMVhcp16UMhS1zsD6GIsoUsWiDX+uyPsRiFQ242AhqqVU+9xX6LRyMgFDgYKGo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712581109; c=relaxed/simple; bh=PEVYbxeaDX3yxZvZ8EuaIuTFCCKeAPFoxiU/zE4/i4k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CFiNPTFpiXRRhbafjI+mSrx+5skSUaWCavm/LpiFHakl1AeoQfs+njXS3b8eBAzPJ8JQGf9h0VlLffNQMZd+jiuvVxW3BuMzncMYMNFgSvXKtx+nuEJ2rqvrZVMegMafojrRXSgwJcFYKCJApY//SSPyQMsTweIGmqj8m4CHv8Y= 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=Arg762VZ; 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="Arg762VZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1712581107; 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=V/aDzcVcLzeBPVZ5j9YK8Jwgxn6uUSBkSWCxCOExK2Q=; b=Arg762VZ3ypot97sOuuuTP/Fc6SXyfVEfEB/hklSNZUZHcYtM9qnkFSv7TkJtCrPUU1gnY AUOUfUP5qjhBKXJZkSK14hGxub+RlAyyW+KbhPE8KNEeIsnokMTE3t+ba0UCI/MUehayTH 5P4a/be1B33DaZ0k1CnSJkdldF5u/1Q= 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-202-H5KAer7NMIWtkt8A2pTaQg-1; Mon, 08 Apr 2024 08:58:23 -0400 X-MC-Unique: H5KAer7NMIWtkt8A2pTaQg-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (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 986ED380621A; Mon, 8 Apr 2024 12:58:22 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.170]) by smtp.corp.redhat.com (Postfix) with ESMTP id AC3BF47E; Mon, 8 Apr 2024 12:58:20 +0000 (UTC) From: Adrian Moreno To: netdev@vger.kernel.org Cc: Adrian Moreno , jiri@resnulli.us, xiyou.wangcong@gmail.com, cmi@nvidia.com, yotam.gi@gmail.com, i.maximets@ovn.org, aconole@redhat.com, echaudro@redhat.com, horms@kernel.org Subject: [RFC net-next v2 2/5] net: psample: add multicast filtering on group_id Date: Mon, 8 Apr 2024 14:57:41 +0200 Message-ID: <20240408125753.470419-3-amorenoz@redhat.com> In-Reply-To: <20240408125753.470419-1-amorenoz@redhat.com> References: <20240408125753.470419-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.1 X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC 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 SAMPLE_FILTER_SET 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 | 127 +++++++++++++++++++++++++++++++++-- 2 files changed, 122 insertions(+), 6 deletions(-) diff --git a/include/uapi/linux/psample.h b/include/uapi/linux/psample.h index e585db5bf2d2..5e0305b1520d 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_SAMPLE_FILTER_SET, }; enum psample_tunnel_key_attr { diff --git a/net/psample/psample.c b/net/psample/psample.c index a5d9b8446f77..a0cef63dfdec 100644 --- a/net/psample/psample.c +++ b/net/psample/psample.c @@ -98,13 +98,84 @@ 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; + bool group_num_valid; +}; + +struct psample_nl_sock_priv { + struct psample_obj_desc __rcu *flt; + spinlock_t flt_lock; /* Protects flt. */ +}; + +static void psample_nl_sock_priv_init(void *priv) +{ + struct psample_nl_sock_priv *sk_priv = priv; + + spin_lock_init(&sk_priv->flt_lock); +} + +static void psample_nl_sock_priv_destroy(void *priv) +{ + struct psample_nl_sock_priv *sk_priv = priv; + struct psample_obj_desc *flt; + + flt = rcu_dereference_protected(sk_priv->flt, true); + kfree_rcu(flt, rcu); +} + +static int psample_nl_sample_filter_set_doit(struct sk_buff *skb, + struct genl_info *info) +{ + struct psample_nl_sock_priv *sk_priv; + struct nlattr **attrs = info->attrs; + struct psample_obj_desc *flt; + + flt = kzalloc(sizeof(*flt), GFP_KERNEL); + + if (attrs[PSAMPLE_ATTR_SAMPLE_GROUP]) { + flt->group_num = nla_get_u32(attrs[PSAMPLE_ATTR_SAMPLE_GROUP]); + flt->group_num_valid = true; + } + + if (!flt->group_num_valid) { + kfree(flt); + flt = NULL; + } + + sk_priv = genl_sk_priv_get(&psample_nl_family, NETLINK_CB(skb).sk); + if (IS_ERR(sk_priv)) { + kfree(flt); + return PTR_ERR(sk_priv); + } + + spin_lock(&sk_priv->flt_lock); + flt = rcu_replace_pointer(sk_priv->flt, flt, + lockdep_is_held(&sk_priv->flt_lock)); + spin_unlock(&sk_priv->flt_lock); + kfree_rcu(flt, rcu); + return 0; +} + +static const struct nla_policy + psample_sample_filter_set_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_SAMPLE_FILTER_SET, + .doit = psample_nl_sample_filter_set_doit, + .policy = psample_sample_filter_set_policy, + .flags = 0, + }, }; static struct genl_family psample_nl_family __ro_after_init = { @@ -114,10 +185,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 +434,42 @@ 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; + desc->group_num_valid = true; +} + +static bool psample_obj_desc_match(struct psample_obj_desc *desc, + struct psample_obj_desc *flt) +{ + if (desc->group_num_valid && flt->group_num_valid && + desc->group_num != flt->group_num) + return false; + return true; +} + +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 *flt; + int ret = 0; + + rcu_read_lock(); + sk_priv = __genl_sk_priv_get(&psample_nl_family, dsk); + if (!IS_ERR_OR_NULL(sk_priv)) { + flt = rcu_dereference(sk_priv->flt); + if (flt) + ret = !psample_obj_desc_match(desc, flt); + } + 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 +480,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 +598,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 Mon Apr 8 12:57:42 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: 13621126 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 3CEEE7BAFD for ; Mon, 8 Apr 2024 12:58:28 +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=1712581110; cv=none; b=YhYzM6WvmTcWvsYWll1z3VluSvOYgmul0JdkvKwb86vX9PGGi1el2vacazUTCkxyfwmyDC0rvja95lsuK13aKB+33pr8qzbJJ/TDrL37ZDbEesd2vSqAQ2rfCD/QoSyojzPD+jvSCE+x9B8G25ckZ1GaUyoPOWkKJMWnhK6vamM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712581110; c=relaxed/simple; bh=kF/bqzz4mzoPphXhTN8LFNIEpCX5AhJnwNEDHHfmvuY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NUlpr+MaDZgSkx6x67ZkyIUoXV4dCxVOV3Q3wtIwIM/nc/e8+6wjZT2rW2FDaM/p2ANbj/VQ1HZcC0qnght44PSWxlBHLJ1c061R+irpq6eQx1rVoTFuDIsRNMj81f0lJgSxqr6kgVbobj5zEK+I2Ia5Sohtpk7mCQkfYd6/JVw= 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=aV/FuN8g; 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="aV/FuN8g" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1712581108; 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=RGVy8Azl62jFM3927f2h3RE43mNDEWmkRx8aXu39BnU=; b=aV/FuN8gF8vym005GJRUN0aUwhD2NPsda3GDIUTegL9Usy+sOzgluFCdATCiLiOplWSpNH sLoopOtv+bim+MuK9u9X85cmQrRDyL2oLkJGv3XPzdR65wUSU3+HG3ew52dxE2h2cmXs7v 0oRuxp+oVeZM2EWl1Fh4nF3akWLz/4E= 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-611-vN1kun-6MXiLjUWOPoi0XQ-1; Mon, 08 Apr 2024 08:58:25 -0400 X-MC-Unique: vN1kun-6MXiLjUWOPoi0XQ-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (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 9B5C9801FAF; Mon, 8 Apr 2024 12:58:24 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.170]) by smtp.corp.redhat.com (Postfix) with ESMTP id D66FC47E; Mon, 8 Apr 2024 12:58:22 +0000 (UTC) From: Adrian Moreno To: netdev@vger.kernel.org Cc: Adrian Moreno , jiri@resnulli.us, xiyou.wangcong@gmail.com, cmi@nvidia.com, yotam.gi@gmail.com, i.maximets@ovn.org, aconole@redhat.com, echaudro@redhat.com, horms@kernel.org Subject: [RFC net-next v2 3/5] net: psample: add user cookie Date: Mon, 8 Apr 2024 14:57:42 +0200 Message-ID: <20240408125753.470419-4-amorenoz@redhat.com> In-Reply-To: <20240408125753.470419-1-amorenoz@redhat.com> References: <20240408125753.470419-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.1 X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC 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..2503ab3c92a5 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; + 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 5e0305b1520d..1f61fd7ef7fd 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, __PSAMPLE_ATTR_MAX }; diff --git a/net/psample/psample.c b/net/psample/psample.c index a0cef63dfdec..9fdb88e01f21 100644 --- a/net/psample/psample.c +++ b/net/psample/psample.c @@ -497,7 +497,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); @@ -596,6 +597,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 Mon Apr 8 12:57:43 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: 13621127 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 69BA57BAFD for ; Mon, 8 Apr 2024 12:58:31 +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=1712581113; cv=none; b=kivSEXuwDjxno2n2Mf+azw8glCGXuv8sExtprMEFkFxCAFPoOqEAbMe79Cai5ce0ejVOecXpG878waH3MFPjNTsp/A/KfhtQwQdh/ltNGwogzM4DB/r6ibzWLx7V9rPtvyDlfkULNgaalYmxCXYUGwFHmsnRNBQJ450zYH0d2vo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712581113; c=relaxed/simple; bh=n+RkZRic6ie2G6KEet41avGQwCdtOj5Z3lDU2WqxhVM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ni6uV5WTPWrNwxE+CmdH10Cayw/el+v8riEnCi/0XnL6bc6xtt7XaNJVjDEY0iFFI5JsWNKqJoEgmjylWrVpXePwHliKCEuZFpBThvk8ZAxXBUM1tEz64iKbQYRWpsp0UrLOtmeIWuxI1mgFKnumVeMp3LSO4Sh/QKKjSj6FmFk= 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=FdzsYkEK; 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="FdzsYkEK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1712581110; 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=FdzsYkEK0hfQAJgZoPurXk3V+UOQS3dw8YS60f69XPWsEArApM6VVF8DFldRAzuMd8zPPN VqZQgeDKOEZj9jsIxX2KsPT6XwhSteUDvMebPkKcec7l6urhrXCkgjhpT0p9otUIGkm1Mn yBQatGaHXo4UI8IaSBDeZTpyB1W4k6k= 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-150-FvLOH6nXOeGOr91xDZIF-Q-1; Mon, 08 Apr 2024 08:58:27 -0400 X-MC-Unique: FvLOH6nXOeGOr91xDZIF-Q-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (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 ABBE980D0F7; Mon, 8 Apr 2024 12:58:26 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.170]) by smtp.corp.redhat.com (Postfix) with ESMTP id D988E47E; Mon, 8 Apr 2024 12:58:24 +0000 (UTC) From: Adrian Moreno To: netdev@vger.kernel.org Cc: Adrian Moreno , jiri@resnulli.us, xiyou.wangcong@gmail.com, cmi@nvidia.com, yotam.gi@gmail.com, i.maximets@ovn.org, aconole@redhat.com, echaudro@redhat.com, horms@kernel.org Subject: [RFC net-next v2 4/5] net:sched:act_sample: add action cookie to sample Date: Mon, 8 Apr 2024 14:57:43 +0200 Message-ID: <20240408125753.470419-5-amorenoz@redhat.com> In-Reply-To: <20240408125753.470419-1-amorenoz@redhat.com> References: <20240408125753.470419-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.1 X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC If the action has a user_cookie, pass it along to the sample so it can be easily identified. Signed-off-by: Adrian Moreno --- 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 Mon Apr 8 12:57:44 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: 13621128 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 2C1657D07E for ; Mon, 8 Apr 2024 12:58:33 +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=1712581115; cv=none; b=RpoI3TN30Kw3CdEF1dVa8/spXW1TSQ6NhaXXB/UwNpZRCcb6z5ByADkuoLhxNrBhekjl2EL8ng39J205/IW4OUYG1220Kr7u2hyLw+JHziUXJSTr/+LVOIT7zouiF9fpsTWJ7NnoiB17jqunA78p2VUfG8ip0YuL5p0VKRqa7Jw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712581115; c=relaxed/simple; bh=PgOqsuL4tEAPJroNBRupbZ1YKjqbo79/77afKYNEp+g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=e2klvbTG0U3E/8ut+eNzSmfZp7ZSGBbn9EmZVvcUajiYkh+S1kKAOxBLwVrpmMWsoq8QlcydA1PvLV6VTtMk2IzPE946JqvmSQ2qOzihcoIxwAW5ZEpHyWdXoHLa4aTZtAWy0ToJfUTljSdx/16mYjLEhgA//Qg7kXsYuzh+Qko= 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=Vvux4KFd; 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="Vvux4KFd" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1712581112; 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=mj1WV8+XKaBG1PQSqQkg/RHbaef+usLutQrMfSAuYKU=; b=Vvux4KFdkU36VOmUFi+EpV19gefkQn0HjQjG2K51b7jJT+NHWoi4zejKxj5I+mOg9MJMoF rKrbercSH7QXvE7yW8p8JC1+3UUNqHe0dlCpu9pgnf6v1IcPIWBwEcSt8SlBK7Vkws/6Ky KvrAxh4yNNM/SrHsgQoB6Jm+W8R2YuI= 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-312-NYVuCbYKOFO6BZpR8uZHgg-1; Mon, 08 Apr 2024 08:58:29 -0400 X-MC-Unique: NYVuCbYKOFO6BZpR8uZHgg-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (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 B167D806626; Mon, 8 Apr 2024 12:58:28 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.170]) by smtp.corp.redhat.com (Postfix) with ESMTP id E9D8747E; Mon, 8 Apr 2024 12:58:26 +0000 (UTC) From: Adrian Moreno To: netdev@vger.kernel.org Cc: Adrian Moreno , jiri@resnulli.us, xiyou.wangcong@gmail.com, cmi@nvidia.com, yotam.gi@gmail.com, i.maximets@ovn.org, aconole@redhat.com, echaudro@redhat.com, horms@kernel.org Subject: [RFC net-next v2 5/5] net:openvswitch: add psample support Date: Mon, 8 Apr 2024 14:57:44 +0200 Message-ID: <20240408125753.470419-6-amorenoz@redhat.com> In-Reply-To: <20240408125753.470419-1-amorenoz@redhat.com> References: <20240408125753.470419-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.1 X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC Add a new attribute to the sample action, called OVS_SAMPLE_ATTR_PSAMPLE to allow userspace to pass a group_id and a user-defined cookie. 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. When set, the sample action will use psample to multicast the sample. Signed-off-by: Adrian Moreno --- include/uapi/linux/openvswitch.h | 22 +++++++-- net/openvswitch/actions.c | 52 ++++++++++++++++++--- net/openvswitch/datapath.c | 2 +- net/openvswitch/flow_netlink.c | 78 +++++++++++++++++++++++++------- 4 files changed, 127 insertions(+), 27 deletions(-) diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h index efc82c318fa2..a5a32588f582 100644 --- a/include/uapi/linux/openvswitch.h +++ b/include/uapi/linux/openvswitch.h @@ -646,15 +646,24 @@ 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 + * is not set. + * @OVS_SAMPLE_ATTR_PSAMPLE: Arguments to be passed to psample. Optional if + * OVS_SAMPLE_ATTR_ACTIONS is not set. * - * Executes the specified actions with the given probability on a per-packet - * basis. + * Either OVS_SAMPLE_ATTR_USER_COOKIE or OVS_SAMPLE_ATTR_USER_COOKIE 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_PSAMPLE, /* struct ovs_psample followed + * by the user-provided cookie. + */ __OVS_SAMPLE_ATTR_MAX, #ifdef __KERNEL__ @@ -675,6 +684,13 @@ struct sample_arg { }; #endif +#define OVS_PSAMPLE_COOKIE_MAX_SIZE 16 +struct ovs_psample { + __u32 group_id; /* The group used for packet sampling. */ + __u32 user_cookie_len; /* The length of the user-provided cookie. */ + __u8 user_cookie[]; /* The user-provided cookie. */ +}; + /** * enum ovs_userspace_attr - Attributes for %OVS_ACTION_ATTR_USERSPACE action. * @OVS_USERSPACE_ATTR_PID: u32 Netlink PID to which the %OVS_PACKET_CMD_ACTION diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 6fcd7e2ca81f..45d2b325b76a 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,31 @@ 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, + struct ovs_psample *psample, struct sk_buff *skb, + u32 rate) +{ + struct psample_group psample_group = {}; + struct psample_metadata md = {}; + struct vport *input_vport; + + psample_group.group_num = psample->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 = psample->user_cookie; + md.user_cookie_len = psample->user_cookie_len; + md.trunc_size = skb->len; + + 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,16 +1059,17 @@ 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 *next; bool clone_flow_key; + int ret; /* The first action is always 'OVS_SAMPLE_ATTR_ARG'. */ sample_arg = nla_data(attr); arg = nla_data(sample_arg); - actions = nla_next(sample_arg, &rem); + next = nla_next(sample_arg, &rem); if ((arg->probability != U32_MAX) && (!arg->probability || get_random_u32() > arg->probability)) { @@ -1051,9 +1078,22 @@ 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 (next->nla_type == OVS_SAMPLE_ATTR_PSAMPLE) { + ret = ovs_psample_packet(dp, key, nla_data(next), skb, + arg->probability); + if (last) + ovs_kfree_skb_reason(skb, OVS_DROP_LAST_ACTION); + if (ret) + return ret; + next = nla_next(next, &rem); + } + + if (nla_ok(next, rem)) { + clone_flow_key = !arg->exec; + ret = clone_execute(dp, skb, key, 0, next, rem, last, + clone_flow_key); + } + return ret; } /* When 'last' is true, clone() should always consume the 'skb'. diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 99d72543abd3..b5b560c2e74b 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -976,7 +976,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info) struct sw_flow_match match; u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]); int error; - bool log = !a[OVS_FLOW_ATTR_PROBE]; + bool log = true; /* Must have key and actions. */ error = -EINVAL; diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index f224d9bcea5e..f540686271b7 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c @@ -2381,8 +2381,12 @@ static void ovs_nla_free_sample_action(const struct nlattr *action) switch (nla_type(a)) { case OVS_SAMPLE_ATTR_ARG: - /* The real list of actions follows this attribute. */ a = nla_next(a, &rem); + + /* OVS_SAMPLE_ATTR_PSAMPLE may be present. */ + if (nla_type(a) == OVS_SAMPLE_ATTR_PSAMPLE) + a = nla_next(a, &rem); + ovs_nla_free_nested_actions(a, rem); break; } @@ -2561,6 +2565,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 +2576,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, *psample; const struct nlattr *a; - int rem, start, err; struct sample_arg arg; + int rem, start, err; memset(attrs, 0, sizeof(attrs)); nla_for_each_nested(a, attr, rem) { @@ -2589,7 +2596,23 @@ 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; + + psample = attrs[OVS_SAMPLE_ATTR_PSAMPLE]; + if (psample) { + struct ovs_psample *ovs_ps; + + if (!nla_len(psample) || nla_len(psample) < sizeof(*ovs_ps)) + return -EINVAL; + + ovs_ps = nla_data(psample); + if (ovs_ps->user_cookie_len > OVS_PSAMPLE_COOKIE_MAX_SIZE || + nla_len(psample) != sizeof(*ovs_ps) + ovs_ps->user_cookie_len) + return -EINVAL; + } + + if (!psample && !actions) return -EINVAL; /* validation done, copy sample action. */ @@ -2608,7 +2631,9 @@ 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) + arg.exec = last || !actions_may_change_flow(actions); + arg.probability = nla_get_u32(probability); err = ovs_nla_add_action(sfa, OVS_SAMPLE_ATTR_ARG, &arg, sizeof(arg), @@ -2616,10 +2641,17 @@ 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 (psample) + err = ovs_nla_add_action(sfa, OVS_SAMPLE_ATTR_PSAMPLE, + nla_data(psample), nla_len(psample), + log); + 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; @@ -3538,7 +3570,7 @@ static int sample_action_to_attr(const struct nlattr *attr, struct nlattr *start, *ac_start = NULL, *sample_arg; int err = 0, rem = nla_len(attr); const struct sample_arg *arg; - struct nlattr *actions; + struct nlattr *next; start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_SAMPLE); if (!start) @@ -3546,27 +3578,39 @@ static int sample_action_to_attr(const struct nlattr *attr, sample_arg = nla_data(attr); arg = nla_data(sample_arg); - actions = nla_next(sample_arg, &rem); + next = nla_next(sample_arg, &rem); if (nla_put_u32(skb, OVS_SAMPLE_ATTR_PROBABILITY, arg->probability)) { err = -EMSGSIZE; goto out; } - ac_start = nla_nest_start_noflag(skb, OVS_SAMPLE_ATTR_ACTIONS); - if (!ac_start) { - err = -EMSGSIZE; - goto out; + if (nla_type(next) == OVS_SAMPLE_ATTR_PSAMPLE) { + if (nla_put(skb, OVS_SAMPLE_ATTR_PSAMPLE, nla_len(next), + nla_data(next))) { + err = -EMSGSIZE; + goto out; + } + next = nla_next(next, &rem); } - err = ovs_nla_put_actions(actions, rem, skb); + if (nla_ok(next, rem)) { + ac_start = nla_nest_start_noflag(skb, OVS_SAMPLE_ATTR_ACTIONS); + if (!ac_start) { + err = -EMSGSIZE; + goto out; + } + err = ovs_nla_put_actions(next, 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); }