Received: by 2002:a89:288:0:b0:1f7:eeee:6653 with SMTP id j8csp576813lqh; Tue, 7 May 2024 07:55:16 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVmqbAzR25c77WJrxVovg3a63tT9gkbSbpRgerSHaH6tbcfbrYfZMhg4uX8ccP8nFR/M4rYeFe54FyMg5GbWdQpCpbUH+q5iLaRIhw7gQ== X-Google-Smtp-Source: AGHT+IHD5bCiQzq2bDdz4fzEukprwrzCPp7oNOeAgrmRFG2OPyPptAAVAz9i8hSvLzWLtnczBTcR X-Received: by 2002:a05:6870:818f:b0:23d:49b4:6638 with SMTP id k15-20020a056870818f00b0023d49b46638mr16010752oae.17.1715093716037; Tue, 07 May 2024 07:55:16 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1715093716; cv=pass; d=google.com; s=arc-20160816; b=e/YVhrjTPl9FTh84eThGuCAu1G18DX1zZHBrdT0xHdrGRs37mltdtAGhTMuM/kFzMT slO4zK+SlKHyjf412NgD12ErLEPfj9xVwSklwLu4pfrV8yYvku3mbpXIcTU3bZaaPAs2 zpvzClZo3Egwg/L18nkjqjex+UisoyC9Xz9x84vT20vTiuTqKN3qPm9ACDbxl6CRrii1 wWrccgUVWa1dTQdv3Nb0yXobFQ3x9bHIkTq7lDd3fhPocSX1rFlNTGWK2UBmV7dHl7Ws 2illkyFjGQRMTh606xc3eWF92J03H1IzWeLxAgXaES/VGd7QKIae203aTmUJjntPod+o pSuw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:date:message-id:dkim-signature; bh=LcAsqHQw/OCz7FQ6iOt/s7wDjmqYvAKgLsN/DOzRL8E=; fh=92+IOUd2LZpWk3u/6eqOg5dGepIK3yK2Pt8Gd0jo5xc=; b=eWv7ywMOUhy8EVr0XbGH58620tMCezPSFLH9HbZ+giGguaBG1f5kwKF5aGdIMk0U9Q ZtSutEShmiqEhu7Kriv4I3xemLjd4YLA/cvHLq5214jLWNcT0iS5bWeck5wUE9IHkICQ tyxORpbcTWcb10clNboTqaN4tVtE7qzEF1wqyWejwxze3IlibiCJqGeUTK/vqMvyzWFN 2l0l8kvp2IM1F4EQm5ttZM/RQH/g/TeYHIGfD9Fw5D4XB1htkEk7AngofHLtftoV6tpD RFJiOby1QJHpTCf+wYQiWd0c/4d7V2Rof5GdvkxzsmsV/ouERcqHmhyk29KC2E27kiB3 HKFw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=CFTZWV3U; arc=pass (i=1 spf=pass spfdomain=redhat.com dkim=pass dkdomain=redhat.com dmarc=pass fromdomain=redhat.com); spf=pass (google.com: domain of linux-kernel+bounces-171557-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-171557-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id v188-20020a6261c5000000b006f4450ab8b9si7877427pfb.161.2024.05.07.07.55.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 May 2024 07:55:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-171557-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=CFTZWV3U; arc=pass (i=1 spf=pass spfdomain=redhat.com dkim=pass dkdomain=redhat.com dmarc=pass fromdomain=redhat.com); spf=pass (google.com: domain of linux-kernel+bounces-171557-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-171557-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id CB99AB257AD for ; Tue, 7 May 2024 14:22:42 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 296B915FCEB; Tue, 7 May 2024 14:18:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="CFTZWV3U" 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 5DC6315FCE7 for ; Tue, 7 May 2024 14:18:11 +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=1715091493; cv=none; b=EiuxSdm7Q4DWim38Jy8WTR/gMi/lPv1VR7PEcfyPOCM5K7OIS6a7JoT3fCsPxw4SPJQAs7zSDsmA4b04niZqL6vRibL8ELQMqPQMlvETi+d4OKQfQer+6WHmVIAsjXvXc+bn69Pa44oAmTYZlzSGJJszHGmAiOBrFSgFdOxl8Fo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715091493; c=relaxed/simple; bh=GEOUBCkdWdkVUanW3YXKSTvCsEN166531Bdu8wFoqAY=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=nLjRzyk326oQktYrzHqwQqBZ6JqKW38RKPyLB/G6cBp8K4aEJjImBq93rugATi8S3yqZwtcTp72d6+uOjpNqXzei9IR+rFjMNlIP+MIB6m0FAx0dpNKsdc9phMKCHPbFImM/YeW/FIGAq9/zNbu7iZYdKgban88yjVwb03N5QKk= 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=CFTZWV3U; 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715091490; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LcAsqHQw/OCz7FQ6iOt/s7wDjmqYvAKgLsN/DOzRL8E=; b=CFTZWV3UuiiGzZVivXHrJqOZ2J18dTb1npFXor6uFjKJOBdzVKA6CJsZ93z6Ho2hZ8Bw7F BgVuQE+QrkNU9ZU/DT2BaVOVQSXH/YNKXlERtmq5wLYcK69yPiupdmfkh/KTK2G3AaaIxm 4AggGOaUFbWfMLeGMakqwWZKtMWplq4= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-573-zbRAUGUROdulZwJ-AOMR8w-1; Tue, 07 May 2024 10:18:07 -0400 X-MC-Unique: zbRAUGUROdulZwJ-AOMR8w-1 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-34da03e19beso2441009f8f.1 for ; Tue, 07 May 2024 07:18:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715091486; x=1715696286; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=LcAsqHQw/OCz7FQ6iOt/s7wDjmqYvAKgLsN/DOzRL8E=; b=tZsNZT1qYgEAmeTPrutyFZdsTmewjF52GZZC5sra/NPiO6tPOVm29Wu2Gj4HSkmPht 9ChzpKKuaXMZXzvFRuu0ETkezqRBxudVWLxd/z+fVa33YB9QDKqTDWPGT0DRTAsrzuZM iloQCjOHaFR+EqQhQJJkhZ3aJXSaKYO8cWncKPMQ+GX2e7A86Bu0IylW9ZdfswkehsJP 3WKHEJznERXWf/jLJ317Us5BzvbZKluLpLfaJGSIMGpFmI6Nk9eJy2pvc0Qdf3iFjZEG zYo3PLAg2zLFFd9Mrvgy666hGxvS1U2bQihPBQFWh8XuQyOkA9dDEAh6BHyLmq8B93Kg jnNg== X-Forwarded-Encrypted: i=1; AJvYcCUq1L1B3v5mNsLlRRD7Miu84qko9UAGFB1CCuhczuD/vA7zBXF4e+LLx/yIjL0fFGYLgDpNJt2QKk/Xjj4Y8eXvIXMidn8EaI1dZLVP X-Gm-Message-State: AOJu0YzFZyQl5xz5Yw81ok8+cV2HJRiG7+uT804xRaRFU1FfHMMJh0k3 KBiCkNlsQR6pcTRgzfnUSl22RgQ3ROMauidseAXeBDfz4JMhRAPDaRiMY4683xWZKgJRm6zN8fr EPd/IHEd2Nu8rFQqicuV7voWIVUGgDD+EA8QyT5Xel2N5jhOA3zfxb94ctBZfUg== X-Received: by 2002:a5d:5708:0:b0:346:85a0:20a4 with SMTP id a8-20020a5d5708000000b0034685a020a4mr10414577wrv.34.1715091485724; Tue, 07 May 2024 07:18:05 -0700 (PDT) X-Received: by 2002:a5d:5708:0:b0:346:85a0:20a4 with SMTP id a8-20020a5d5708000000b0034685a020a4mr10414549wrv.34.1715091485170; Tue, 07 May 2024 07:18:05 -0700 (PDT) Received: from [192.168.1.137] ([193.177.210.114]) by smtp.gmail.com with ESMTPSA id c16-20020adffb10000000b0034f0633e322sm5973731wrr.38.2024.05.07.07.18.03 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 07 May 2024 07:18:04 -0700 (PDT) Message-ID: <5f516a72-d406-49bf-98a0-0f1ade8a0d50@redhat.com> Date: Tue, 7 May 2024 16:18:02 +0200 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH net-next 6/8] net:openvswitch: add psample support To: Eelco Chaudron Cc: netdev@vger.kernel.org, aconole@redhat.com, horms@kernel.org, i.maximets@ovn.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Pravin B Shelar , Donald Hunter , linux-kernel@vger.kernel.org, dev@openvswitch.org References: <20240424135109.3524355-1-amorenoz@redhat.com> <20240424135109.3524355-7-amorenoz@redhat.com> <72F692D6-621D-4E02-AAE2-AC63CC99FEBE@redhat.com> Content-Language: en-US From: Adrian Moreno In-Reply-To: <72F692D6-621D-4E02-AAE2-AC63CC99FEBE@redhat.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 5/3/24 11:43 AM, Eelco Chaudron wrote: > > > On 24 Apr 2024, at 15:50, Adrian Moreno wrote: > >> 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 > > This is not a full review yet. Just some comments, as I’m looking at the user-space patch first and added similar comments. > > I’ll do a proper review of this series once I’m done with user-space part. > > //Eelco > >> --- >> 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. > > As there is a limit of to the cookie should we mention it here? > I thought OVS_PSAMPLE_COOKIE_MAX_SIZE was expressive enough but sure, we can also mention it here. >> * >> - * 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_ > > Missing * after OVS_ACTION_ATTR_ As a matter of fact, adding an * makes checkpatch generate a warning IIRC. That's why I initially removed it. I can look at fixing checkpatch instead. > >> + * attributes. >> + */ >> + OVS_SAMPLE_ATTR_PSAMPLE_GROUP, /* u32 number */ >> + OVS_SAMPLE_ATTR_PSAMPLE_COOKIE, /* binary */ > > As these are general sample options, I would not add the PSAMPLE reference. Other data paths could use a different implementation. So I guess OVS_SAMPLE_ATTR_GROUP_ID and OVS_SAMPLE_ATTR_COOKIE would be enough. > OK. But isn't the API already psample-ish? I mean that the group_id is something specific to psample that might not be present in other datapath implementation. >> __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'. >> - */ > > > Not sure if you can actually do this, you are changing a structure that is part of the UAPI. This change breaks backwards compatibility. > Hmmm... this the internal argument structure protected by #ifdef __KERNEL__. It is used in several actions to optimize the internal action handling (i.e: using a compact struct instead of a list of netlink attributes). I guess the reason for having it in this file is because the attribute enum is being reused, but I wouldn't think of this struct as part of the uAPI. If the (#ifdef __KERNEL__) does not exclude this struct from the uAPI I think we should move it (all of them actually) to some internal file. > >> + 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. */ > > Would it make sense for the cookie also to be u8? > Yes, probably. >> }; >> #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); > > Does this mean now the ovs module, now is dependent on the presence of psample? I think we should only support sampling to psample if the module exists, else we should return an error. There might be distributions not including psample by default. Agree. I'll add some compile-time checks the same way we do with nf_nat. > >> + >> + 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); >> } >> >> -- >> 2.44.0 >