From: Aaron Conole <aconole@redhat.com>
To: Adrian Moreno <amorenoz@redhat.com>
Cc: netdev@vger.kernel.org, echaudro@redhat.com, horms@kernel.org,
i.maximets@ovn.org, dev@openvswitch.org,
Pravin B Shelar <pshelar@ovn.org>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>, Shuah Khan <shuah@kernel.org>,
linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next v7 07/10] selftests: openvswitch: add psample action
Date: Mon, 01 Jul 2024 14:40:31 -0400 [thread overview]
Message-ID: <f7tbk3hvtuo.fsf@redhat.com> (raw)
In-Reply-To: <20240630195740.1469727-8-amorenoz@redhat.com> (Adrian Moreno's message of "Sun, 30 Jun 2024 21:57:28 +0200")
Adrian Moreno <amorenoz@redhat.com> writes:
> Add sample and psample action support to ovs-dpctl.py.
>
> Refactor common attribute parsing logic into an external function.
>
> Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
> ---
Reviewed-by: Aaron Conole <aconole@redhat.com>
> .../selftests/net/openvswitch/ovs-dpctl.py | 162 +++++++++++++++++-
> 1 file changed, 161 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> index 182a09975975..dcc400a21a22 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 socket
> @@ -60,6 +61,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])
> @@ -281,6 +283,75 @@ def parse_extract_field(
> return str_skipped, data
>
>
> +def parse_attrs(actstr, attr_desc):
> + """Parses the given action string and returns a list of netlink
> + attributes based on a list of attribute descriptions.
> +
> + Each element in the attribute description list is a tuple such as:
> + (name, attr_name, parse_func)
> + where:
> + name: is the string representing the attribute
> + attr_name: is the name of the attribute as defined in the uAPI.
> + parse_func: is a callable accepting a string and returning either
> + a single object (the parsed attribute value) or a tuple of
> + two values (the parsed attribute value and the remaining string)
> +
> + Returns a list of attributes and the remaining string.
> + """
> + def parse_attr(actstr, key, func):
> + actstr = actstr[len(key) :]
> +
> + if not func:
> + return None, actstr
> +
> + delim = actstr[0]
> + actstr = actstr[1:]
> +
> + if delim == "=":
> + pos = strcspn(actstr, ",)")
> + ret = func(actstr[:pos])
> + else:
> + ret = func(actstr)
> +
> + if isinstance(ret, tuple):
> + (datum, actstr) = ret
> + else:
> + datum = ret
> + actstr = actstr[strcspn(actstr, ",)"):]
> +
> + if delim == "(":
> + if not actstr or actstr[0] != ")":
> + raise ValueError("Action contains unbalanced parentheses")
> +
> + actstr = actstr[1:]
> +
> + actstr = actstr[strspn(actstr, ", ") :]
> +
> + return datum, actstr
> +
> + attrs = []
> + attr_desc = list(attr_desc)
> + while actstr and actstr[0] != ")" and attr_desc:
> + found = False
> + for i, (key, attr, func) in enumerate(attr_desc):
> + if actstr.startswith(key):
> + datum, actstr = parse_attr(actstr, key, func)
> + attrs.append([attr, datum])
> + found = True
> + del attr_desc[i]
> +
> + if not found:
> + raise ValueError("Unknown attribute: '%s'" % actstr)
> +
> + actstr = actstr[strspn(actstr, ", ") :]
> +
> + if actstr[0] != ")":
> + raise ValueError("Action string contains extra garbage or has "
> + "unbalanced parenthesis: '%s'" % 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
> @@ -299,7 +370,7 @@ class ovsactions(nla):
> ("OVS_ACTION_ATTR_SET", "ovskey"),
> ("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"),
> @@ -318,8 +389,85 @@ class ovsactions(nla):
> ("OVS_ACTION_ATTR_ADD_MPLS", "none"),
> ("OVS_ACTION_ATTR_DEC_TTL", "none"),
> ("OVS_ACTION_ATTR_DROP", "uint32"),
> + ("OVS_ACTION_ATTR_PSAMPLE", "psample"),
> )
>
> + class psample(nla):
> + nla_flags = NLA_F_NESTED
> +
> + nla_map = (
> + ("OVS_PSAMPLE_ATTR_UNSPEC", "none"),
> + ("OVS_PSAMPLE_ATTR_GROUP", "uint32"),
> + ("OVS_PSAMPLE_ATTR_COOKIE", "array(uint8)"),
> + )
> +
> + def dpstr(self, more=False):
> + args = "group=%d" % self.get_attr("OVS_PSAMPLE_ATTR_GROUP")
> +
> + cookie = self.get_attr("OVS_PSAMPLE_ATTR_COOKIE")
> + if cookie:
> + args += ",cookie(%s)" % \
> + "".join(format(x, "02x") for x in cookie)
> +
> + return "psample(%s)" % args
> +
> + def parse(self, actstr):
> + desc = (
> + ("group", "OVS_PSAMPLE_ATTR_GROUP", int),
> + ("cookie", "OVS_PSAMPLE_ATTR_COOKIE",
> + lambda x: list(bytearray.fromhex(x)))
> + )
> +
> + attrs, actstr = parse_attrs(actstr, desc)
> +
> + for attr in attrs:
> + self["attrs"].append(attr)
> +
> + return actstr
> +
> + 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"),
> + )
> +
> + def dpstr(self, more=False):
> + args = []
> +
> + args.append("sample={:.2f}%".format(
> + 100 * self.get_attr("OVS_SAMPLE_ATTR_PROBABILITY") /
> + UINT32_MAX))
> +
> + actions = self.get_attr("OVS_SAMPLE_ATTR_ACTIONS")
> + if actions:
> + args.append("actions(%s)" % actions.dpstr(more))
> +
> + return "sample(%s)" % ",".join(args)
> +
> + def parse(self, actstr):
> + def parse_nested_actions(actstr):
> + subacts = ovsactions()
> + parsed_len = subacts.parse(actstr)
> + return subacts, actstr[parsed_len :]
> +
> + def percent_to_rate(percent):
> + percent = float(percent.strip('%'))
> + return int(math.floor(UINT32_MAX * (percent / 100.0) + .5))
> +
> + desc = (
> + ("sample", "OVS_SAMPLE_ATTR_PROBABILITY", percent_to_rate),
> + ("actions", "OVS_SAMPLE_ATTR_ACTIONS", parse_nested_actions),
> + )
> + attrs, actstr = parse_attrs(actstr, desc)
> +
> + for attr in attrs:
> + self["attrs"].append(attr)
> +
> + return actstr
> +
> class ctact(nla):
> nla_flags = NLA_F_NESTED
>
> @@ -683,6 +831,18 @@ 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
> +
> + elif parse_starts_block(actstr, "psample(", False):
> + psampleact = self.psample()
> + actstr = psampleact.parse(actstr[len("psample(") : ])
> + self["attrs"].append(["OVS_ACTION_ATTR_PSAMPLE", psampleact])
> + parsed = True
> +
> actstr = actstr[strspn(actstr, ", ") :]
> while parencount > 0:
> parencount -= 1
next prev parent reply other threads:[~2024-07-01 18:40 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-30 19:57 [PATCH net-next v7 00/10] net: openvswitch: Add sample multicasting Adrian Moreno
2024-06-30 19:57 ` [PATCH net-next v7 01/10] net: psample: add user cookie Adrian Moreno
2024-07-01 11:20 ` Michal Kubiak
2024-07-01 18:05 ` Aaron Conole
2024-06-30 19:57 ` [PATCH net-next v7 02/10] net: sched: act_sample: add action cookie to sample Adrian Moreno
2024-07-01 18:06 ` Aaron Conole
2024-06-30 19:57 ` [PATCH net-next v7 03/10] net: psample: skip packet copy if no listeners Adrian Moreno
2024-07-01 18:07 ` Aaron Conole
2024-06-30 19:57 ` [PATCH net-next v7 04/10] net: psample: allow using rate as probability Adrian Moreno
2024-07-01 18:10 ` Aaron Conole
2024-06-30 19:57 ` [PATCH net-next v7 05/10] net: openvswitch: add psample action Adrian Moreno
2024-07-01 11:40 ` Michal Kubiak
2024-07-01 12:56 ` Adrián Moreno
2024-07-02 11:10 ` Michal Kubiak
2024-07-01 18:13 ` Ilya Maximets
2024-07-01 18:23 ` Aaron Conole
2024-07-02 7:05 ` Adrián Moreno
2024-07-02 7:29 ` Adrián Moreno
2024-07-02 9:37 ` Simon Horman
2024-07-02 9:52 ` Adrián Moreno
2024-07-02 9:53 ` Ilya Maximets
2024-07-02 12:33 ` [ovs-dev] " Simon Horman
2024-07-02 18:37 ` Adrián Moreno
2024-07-02 18:06 ` Jakub Kicinski
2024-07-02 18:16 ` Ilya Maximets
2024-07-02 18:24 ` Jakub Kicinski
2024-07-02 18:52 ` Ilya Maximets
2024-06-30 19:57 ` [PATCH net-next v7 06/10] net: openvswitch: store sampling probability in cb Adrian Moreno
2024-07-01 18:24 ` Aaron Conole
2024-06-30 19:57 ` [PATCH net-next v7 07/10] selftests: openvswitch: add psample action Adrian Moreno
2024-07-01 18:40 ` Aaron Conole [this message]
2024-06-30 19:57 ` [PATCH net-next v7 08/10] selftests: openvswitch: add userspace parsing Adrian Moreno
2024-06-30 19:57 ` [PATCH net-next v7 09/10] selftests: openvswitch: parse trunc action Adrian Moreno
2024-06-30 19:57 ` [PATCH net-next v7 10/10] selftests: openvswitch: add psample test Adrian Moreno
2024-07-01 18:34 ` Ilya Maximets
2024-07-01 18:38 ` Aaron Conole
2024-07-02 7:16 ` Adrián Moreno
2024-07-02 11:45 ` Aaron Conole
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f7tbk3hvtuo.fsf@redhat.com \
--to=aconole@redhat.com \
--cc=amorenoz@redhat.com \
--cc=davem@davemloft.net \
--cc=dev@openvswitch.org \
--cc=echaudro@redhat.com \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=i.maximets@ovn.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=pshelar@ovn.org \
--cc=shuah@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.