From patchwork Wed Apr 24 19:53:27 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: 1927344 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=WtB6Q2RC; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VPqS65hwRz1yP2 for ; Thu, 25 Apr 2024 05:53:58 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 4B85340449; Wed, 24 Apr 2024 19:53:56 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id xkVTsA7yN3IR; Wed, 24 Apr 2024 19:53:54 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org F2DEA4172D Authentication-Results: smtp2.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=WtB6Q2RC Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTPS id F2DEA4172D; Wed, 24 Apr 2024 19:53:53 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 777CDC0DD2; Wed, 24 Apr 2024 19:53:53 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 109AFC0037 for ; Wed, 24 Apr 2024 19:53:52 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id E68F8416F2 for ; Wed, 24 Apr 2024 19:53:51 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id LyVPuTohdTJS for ; Wed, 24 Apr 2024 19:53:51 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp2.osuosl.org A8AAD40449 Authentication-Results: smtp2.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org A8AAD40449 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp2.osuosl.org (Postfix) with ESMTPS id A8AAD40449 for ; Wed, 24 Apr 2024 19:53:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713988429; 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=bfoT8ZoPItN/xTOheYV79lIhvnwjkIXH/RnPhyNkK7g=; b=WtB6Q2RCSpAyPTYnDTwpS+jPimT0RYI2WeNokBUadM0dfRXSkmUSQs6Rayv1ws3UvSL9uM Bjs1NPGlJS4P3ceH2HwpTYWnzdZm2nVn4B+p3ik0veTyFDrGFbzOEeFrYZAm1wXExGa1gt DEy9OYfq7nMgQdIhB+EInCBBtgcKbvA= 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-645-r4O94X1dOc-FOjr1FGgf7A-1; Wed, 24 Apr 2024 15:53:46 -0400 X-MC-Unique: r4O94X1dOc-FOjr1FGgf7A-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (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 DFAC73C00096; Wed, 24 Apr 2024 19:53:45 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 77797200AE7F; Wed, 24 Apr 2024 19:53:44 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Wed, 24 Apr 2024 21:53:27 +0200 Message-ID: <20240424195337.3596657-2-amorenoz@redhat.com> In-Reply-To: <20240424195337.3596657-1-amorenoz@redhat.com> References: <20240424195337.3596657-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: dceara@redhat.com, i.maximets@ovn.org, horms@kernel.org Subject: [ovs-dev] [RFC 01/11] odp-util: Add support to new psample uAPI. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" The new odp sample attributes allow userspace to specify a group_id and user-defined cookie to be passed down to psample. Add support for parsing and formatting such action. Signed-off-by: Adrian Moreno --- include/linux/openvswitch.h | 49 +++++++++--- lib/odp-execute.c | 3 + lib/odp-util.c | 150 ++++++++++++++++++++++++++--------- ofproto/ofproto-dpif-ipfix.c | 2 + python/ovs/flow/odp.py | 2 + tests/odp.at | 5 ++ 6 files changed, 163 insertions(+), 48 deletions(-) diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h index d9fb991ef..3e748405c 100644 --- a/include/linux/openvswitch.h +++ b/include/linux/openvswitch.h @@ -696,6 +696,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 @@ -703,15 +704,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__ @@ -722,13 +735,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 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/lib/odp-execute.c b/lib/odp-execute.c index 081e4d432..d8ee93429 100644 --- a/lib/odp-execute.c +++ b/lib/odp-execute.c @@ -716,6 +716,9 @@ odp_execute_sample(void *dp, struct dp_packet *packet, bool steal, subactions = a; break; + /* Ignored in userspace datapath. */ + case OVS_SAMPLE_ATTR_PSAMPLE_GROUP: + case OVS_SAMPLE_ATTR_PSAMPLE_COOKIE: case OVS_SAMPLE_ATTR_UNSPEC: case __OVS_SAMPLE_ATTR_MAX: default: diff --git a/lib/odp-util.c b/lib/odp-util.c index 21f34d955..611b5229e 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -227,12 +227,16 @@ format_odp_sample_action(struct ds *ds, const struct nlattr *attr, { static const struct nl_policy ovs_sample_policy[] = { [OVS_SAMPLE_ATTR_PROBABILITY] = { .type = NL_A_U32 }, - [OVS_SAMPLE_ATTR_ACTIONS] = { .type = NL_A_NESTED } + [OVS_SAMPLE_ATTR_ACTIONS] = { .type = NL_A_NESTED, + .optional = true }, + [OVS_SAMPLE_ATTR_PSAMPLE_GROUP] = { .type = NL_A_U32, + .optional = true }, + [OVS_SAMPLE_ATTR_PSAMPLE_COOKIE] = { .type = NL_A_UNSPEC, + .optional = true } }; struct nlattr *a[ARRAY_SIZE(ovs_sample_policy)]; + const struct nlattr *nla; double percentage; - const struct nlattr *nla_acts; - int len; ds_put_cstr(ds, "sample"); @@ -244,13 +248,33 @@ format_odp_sample_action(struct ds *ds, const struct nlattr *attr, percentage = (100.0 * nl_attr_get_u32(a[OVS_SAMPLE_ATTR_PROBABILITY])) / UINT32_MAX; - ds_put_format(ds, "(sample=%.1f%%,", percentage); + ds_put_format(ds, "(sample=%.1f%%", percentage); - ds_put_cstr(ds, "actions("); - nla_acts = nl_attr_get(a[OVS_SAMPLE_ATTR_ACTIONS]); - len = nl_attr_get_size(a[OVS_SAMPLE_ATTR_ACTIONS]); - format_odp_actions(ds, nla_acts, len, portno_names); - ds_put_format(ds, "))"); + nla = a[OVS_SAMPLE_ATTR_PSAMPLE_GROUP]; + if (nla) { + ds_put_format(ds, ",group_id=%d", nl_attr_get_u32(nla)); + + nla = a[OVS_SAMPLE_ATTR_PSAMPLE_COOKIE]; + + if (nla) { + size_t i; + const uint8_t *c = nl_attr_get(nla); + ds_put_cstr(ds, ",cookie="); + for (i = 0; i < nl_attr_get_size(nla); i++) { + ds_put_format(ds, "%02x", c[i]); + } + } + } + + nla = a[OVS_SAMPLE_ATTR_ACTIONS]; + if (nla) { + ds_put_cstr(ds, ",actions("); + format_odp_actions(ds, nl_attr_get(nla), nl_attr_get_size(nla), + portno_names); + ds_put_format(ds, "))"); + } else { + ds_put_format(ds, ")"); + } } static void @@ -1348,6 +1372,84 @@ format_odp_actions(struct ds *ds, const struct nlattr *actions, } } +static int +parse_action_list(struct parse_odp_context *context, const char *s, + struct ofpbuf *actions); +static int +parse_odp_sample_action(const char *s, struct parse_odp_context *context, + struct ofpbuf *actions) +{ + double percentage; + uint32_t group_id; + size_t sample_ofs, actions_ofs; + double probability; + int parsed = 0; + int n; + + if (!ovs_scan(s, "sample(sample=%lf%%,%n", &percentage, &parsed)) { + return -EINVAL; + } + + probability = floor(UINT32_MAX * (percentage / 100.0) + .5); + sample_ofs = nl_msg_start_nested(actions, OVS_ACTION_ATTR_SAMPLE); + nl_msg_put_u32(actions, OVS_SAMPLE_ATTR_PROBABILITY, + (probability <= 0 ? 0 + : probability >= UINT32_MAX ? UINT32_MAX + : probability)); + + if (ovs_scan(s + parsed, "group_id=%"PRIu32"%n", &group_id, &n)) { + parsed += n; + + nl_msg_put_u32(actions, OVS_SAMPLE_ATTR_PSAMPLE_GROUP, group_id); + + if (ovs_scan(s + parsed, ",cookie=%n", &n)) { + struct ofpbuf buf; + size_t size; + char *end; + + parsed += n; + ofpbuf_init(&buf, OVS_PSAMPLE_COOKIE_MAX_SIZE); + + end = ofpbuf_put_hex(&buf, s + parsed, &size); + if (!end || + size > OVS_PSAMPLE_COOKIE_MAX_SIZE || + (end[0] != ')' && end[0] != ',')) { + ofpbuf_uninit(&buf); + return -EINVAL; + } + + nl_msg_put_unspec(actions, OVS_SAMPLE_ATTR_PSAMPLE_COOKIE, + buf.data, buf.size); + + ofpbuf_uninit(&buf); + parsed = end - s; + } + if (s[parsed] == ')') { + nl_msg_end_nested(actions, sample_ofs); + return parsed + 1; + } else if (s[parsed] == ',') { + parsed += 1; + } else { + return -EINVAL; + } + } + + if (ovs_scan(s + parsed, "actions(%n", &n)) { + parsed += n; + actions_ofs = nl_msg_start_nested(actions, OVS_SAMPLE_ATTR_ACTIONS); + int retval = parse_action_list(context, s + parsed, actions); + if (retval < 0) { + return retval; + } + parsed += retval; + nl_msg_end_nested(actions, actions_ofs); + nl_msg_end_nested(actions, sample_ofs); + return s[parsed + 1] == ')' ? parsed + 2 : -EINVAL; + } + + return -EINVAL; +} + /* Separate out parse_odp_userspace_action() function. */ static int parse_odp_userspace_action(const char *s, struct ofpbuf *actions) @@ -2561,34 +2663,8 @@ parse_odp_action__(struct parse_odp_context *context, const char *s, } { - double percentage; - int n = -1; - - if (ovs_scan(s, "sample(sample=%lf%%,actions(%n", &percentage, &n) - && percentage >= 0. && percentage <= 100.0) { - size_t sample_ofs, actions_ofs; - double probability; - - probability = floor(UINT32_MAX * (percentage / 100.0) + .5); - sample_ofs = nl_msg_start_nested(actions, OVS_ACTION_ATTR_SAMPLE); - nl_msg_put_u32(actions, OVS_SAMPLE_ATTR_PROBABILITY, - (probability <= 0 ? 0 - : probability >= UINT32_MAX ? UINT32_MAX - : probability)); - - actions_ofs = nl_msg_start_nested(actions, - OVS_SAMPLE_ATTR_ACTIONS); - int retval = parse_action_list(context, s + n, actions); - if (retval < 0) { - return retval; - } - - - n += retval; - nl_msg_end_nested(actions, actions_ofs); - nl_msg_end_nested(actions, sample_ofs); - - return s[n + 1] == ')' ? n + 2 : -EINVAL; + if (ovs_scan(s, "sample(")) { + return parse_odp_sample_action(s, context, actions); } } diff --git a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c index cd65dae7e..407b2b38a 100644 --- a/ofproto/ofproto-dpif-ipfix.c +++ b/ofproto/ofproto-dpif-ipfix.c @@ -3064,6 +3064,8 @@ dpif_ipfix_read_sample_actions(const struct flow *flow, &sample_actions); break; + case OVS_SAMPLE_ATTR_PSAMPLE_GROUP: + case OVS_SAMPLE_ATTR_PSAMPLE_COOKIE: case OVS_SAMPLE_ATTR_UNSPEC: case __OVS_SAMPLE_ATTR_MAX: default: diff --git a/python/ovs/flow/odp.py b/python/ovs/flow/odp.py index 7d9b165d4..bc0495eb4 100644 --- a/python/ovs/flow/odp.py +++ b/python/ovs/flow/odp.py @@ -349,6 +349,8 @@ class ODPFlow(Flow): KVDecoders( { "sample": (lambda x: float(x.strip("%"))), + "group_id": decode_int, + "cookie": decode_default, "actions": nested_kv_decoder( KVDecoders( decoders=_decoders, diff --git a/tests/odp.at b/tests/odp.at index ba20604e4..4a2435c97 100644 --- a/tests/odp.at +++ b/tests/odp.at @@ -327,6 +327,9 @@ push_vlan(tpid=0x9100,vid=13,pcp=5) push_vlan(tpid=0x9100,vid=13,pcp=5,cfi=0) pop_vlan sample(sample=9.7%,actions(1,2,3,push_vlan(vid=1,pcp=2))) +sample(sample=9.7%,group_id=25) +sample(sample=9.7%,group_id=12,cookie=0102) +sample(sample=9.7%,group_id=12,cookie=0102030405060708090a0b0c0d0e0f,actions(1,2,3,push_vlan(vid=1,pcp=2))) set(tunnel(tun_id=0xabcdef1234567890,src=1.1.1.1,dst=2.2.2.2,ttl=64,flags(df|csum|key))) set(tunnel(tun_id=0xabcdef1234567890,src=1.1.1.1,dst=2.2.2.2,ttl=64,flags(key))) tnl_pop(4) @@ -406,11 +409,13 @@ AT_DATA([actions.txt], [dnl encap_nsh@:{@ tnl_push(tnl_port(6),header(size=94,type=112,eth(dst=f8:bc:12:44:34:b6,src=f8:bc:12:46:58:e0,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::92,label=0,proto=43,tclass=0x0,hlimit=64),srv6(segments_left=2,segs(2001:cafe::90,2001:cafe::91))),out_port(1)) tnl_push(tnl_port(6),header(size=126,type=112,eth(dst=f8:bc:12:44:34:b6,src=f8:bc:12:46:58:e0,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::92,label=0,proto=43,tclass=0x0,hlimit=64),srv6(segments_left=2,segs(2001:cafe::90,2001:cafe::91,2001:cafe::92,2001:cafe::93))),out_port(1)) +sample(sample=9.7%,group_id=12,cookie=0102030405060708090a0b0c0d0e0f0f0f) ]) AT_CHECK_UNQUOTED([ovstest test-odp parse-actions < actions.txt], [0], [dnl odp_actions_from_string: error odp_actions_from_string: error odp_actions_from_string: error +odp_actions_from_string: error ]) AT_CLEANUP From patchwork Wed Apr 24 19:53:28 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: 1927345 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=AjPn5ukE; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VPqS84Rfxz1yP2 for ; Thu, 25 Apr 2024 05:54:00 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 913E860E3B; Wed, 24 Apr 2024 19:53:58 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id wVUsgV2csk7U; Wed, 24 Apr 2024 19:53:56 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org DEBA860E21 Authentication-Results: smtp3.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=AjPn5ukE Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp3.osuosl.org (Postfix) with ESMTPS id DEBA860E21; Wed, 24 Apr 2024 19:53:55 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id BA225C0077; Wed, 24 Apr 2024 19:53:55 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id C15F0C0DD7 for ; Wed, 24 Apr 2024 19:53:53 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 9E71B41713 for ; Wed, 24 Apr 2024 19:53:53 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id WzK92jiTVUT0 for ; Wed, 24 Apr 2024 19:53:53 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp2.osuosl.org B9B6F40449 Authentication-Results: smtp2.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org B9B6F40449 Authentication-Results: smtp2.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=AjPn5ukE Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp2.osuosl.org (Postfix) with ESMTPS id B9B6F40449 for ; Wed, 24 Apr 2024 19:53:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713988431; 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=A/ibDdHTTIGxt4w7rzM9rMlBYLFO9qQ6sXXkz8cdPis=; b=AjPn5ukE5hXGtRSySx8raDwaszN8TgckNQTqwvuy4PG2Z/0RMjCMXhf85UTK4HUw6iK6DU jpxVDdk2OK1gk5j6JS/5JbAklpm6VS7sDYIfLDMX/M+hJ/Cox5FnK+s2WP6A5DC6scLHtz E0YPZZyaJ9AXsWoC+TeEQAmfZMoMWjg= 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-617-UvtMSTe9Pp-zwtUxk1WI-A-1; Wed, 24 Apr 2024 15:53:47 -0400 X-MC-Unique: UvtMSTe9Pp-zwtUxk1WI-A-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (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 7B67218065AF; Wed, 24 Apr 2024 19:53:47 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 27CC1200AE7F; Wed, 24 Apr 2024 19:53:46 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Wed, 24 Apr 2024 21:53:28 +0200 Message-ID: <20240424195337.3596657-3-amorenoz@redhat.com> In-Reply-To: <20240424195337.3596657-1-amorenoz@redhat.com> References: <20240424195337.3596657-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: dceara@redhat.com, i.maximets@ovn.org, horms@kernel.org Subject: [ovs-dev] [RFC 02/11] ofproto_dpif: Check for psample support. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Only kernel datapath supports psample so check that the datapath is not userspace and that it accepts the new attributes. Signed-off-by: Adrian Moreno --- ofproto/ofproto-dpif.c | 59 ++++++++++++++++++++++++++++++++++++++++++ ofproto/ofproto-dpif.h | 6 ++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 32d037be6..3cee2795a 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -25,6 +25,7 @@ #include "coverage.h" #include "cfm.h" #include "ct-dpif.h" +#include "dpif-netdev.h" #include "fail-open.h" #include "guarded-list.h" #include "hmapx.h" @@ -873,6 +874,12 @@ ovs_lb_output_action_supported(struct ofproto_dpif *ofproto) return ofproto->backer->rt_support.lb_output_action; } +bool +ovs_psample_supported(struct ofproto_dpif *ofproto) +{ + return ofproto->backer->rt_support.psample; +} + /* Tests whether 'backer''s datapath supports recirculation. Only newer * datapaths support OVS_KEY_ATTR_RECIRC_ID in keys. We need to disable some * features on older datapaths that don't support this feature. @@ -1440,6 +1447,14 @@ dpif_supports_ct_zero_snat(struct dpif_backer *backer) return supported; } +static bool check_psample(struct dpif_backer *backer); + +static bool +dpif_supports_psample(struct dpif_backer *backer) +{ + return !dpif_is_netdev(backer->dpif) && check_psample(backer); +} + /* Tests whether 'backer''s datapath supports the * OVS_ACTION_ATTR_CHECK_PKT_LEN action. */ static bool @@ -1609,6 +1624,49 @@ check_add_mpls(struct dpif_backer *backer) return supported; } +/* Tests whether 'backer''s datapath supports the OVS_SAMPLE_ATTR_PSAMPLE + * attribute. */ +static bool +check_psample(struct dpif_backer *backer) +{ + uint8_t cookie[OVS_PSAMPLE_COOKIE_MAX_SIZE]; + struct odputil_keybuf keybuf; + struct ofpbuf actions; + struct ofpbuf key; + struct flow flow; + bool supported; + size_t offset; + + struct odp_flow_key_parms odp_parms = { + .flow = &flow, + .probe = true, + }; + + memset(&flow, 0, sizeof flow); + ofpbuf_use_stack(&key, &keybuf, sizeof keybuf); + odp_flow_key_from_flow(&odp_parms, &key); + ofpbuf_init(&actions, 64); + + /* Generate a random max-size cookie. */ + random_bytes(&cookie[0], sizeof(cookie)); + + offset = nl_msg_start_nested(&actions, OVS_ACTION_ATTR_SAMPLE); + nl_msg_put_u32(&actions, OVS_SAMPLE_ATTR_PROBABILITY, 1); + nl_msg_put_u32(&actions, OVS_SAMPLE_ATTR_PSAMPLE_GROUP, 10); + nl_msg_put_unspec(&actions, OVS_SAMPLE_ATTR_PSAMPLE_COOKIE, &cookie[0], + sizeof(cookie)); + nl_msg_end_nested(&actions, offset); + + supported = dpif_probe_feature(backer->dpif, "psample", &key, + &actions, NULL); + ofpbuf_uninit(&actions); + VLOG_INFO("%s: Datapath %s psample", + dpif_name(backer->dpif), + supported ? "supports" : "does not support"); + return supported; +} + + #define CHECK_FEATURE__(NAME, SUPPORT, FIELD, VALUE, ETHTYPE) \ static bool \ check_##NAME(struct dpif_backer *backer) \ @@ -1698,6 +1756,7 @@ check_support(struct dpif_backer *backer) dpif_supports_lb_output_action(backer->dpif); backer->rt_support.ct_zero_snat = dpif_supports_ct_zero_snat(backer); backer->rt_support.add_mpls = check_add_mpls(backer); + backer->rt_support.psample = dpif_supports_psample(backer); /* Flow fields. */ backer->rt_support.odp.ct_state = check_ct_state(backer); diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index d33f73df8..3db4263c7 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -213,7 +213,10 @@ struct group_dpif *group_dpif_lookup(struct ofproto_dpif *, DPIF_SUPPORT_FIELD(bool, ct_zero_snat, "Conntrack all-zero IP SNAT") \ \ /* True if the datapath supports add_mpls action. */ \ - DPIF_SUPPORT_FIELD(bool, add_mpls, "MPLS Label add") + DPIF_SUPPORT_FIELD(bool, add_mpls, "MPLS Label add") \ + \ + /* True if the datapath supports psample. */ \ + DPIF_SUPPORT_FIELD(bool, psample, "Psample") /* Stores the various features which the corresponding backer supports. */ @@ -411,5 +414,6 @@ bool ofproto_dpif_ct_zone_timeout_policy_get_name( uint8_t nw_proto, char **tp_name, bool *unwildcard); bool ovs_explicit_drop_action_supported(struct ofproto_dpif *); +bool ovs_psample_supported(struct ofproto_dpif *); #endif /* ofproto-dpif.h */ From patchwork Wed Apr 24 19:53:29 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: 1927346 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=efe1F4dW; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VPqSD5B3hz1yP2 for ; Thu, 25 Apr 2024 05:54:04 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 0E28A60E84; Wed, 24 Apr 2024 19:54:02 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id eCYAajHLg8uk; Wed, 24 Apr 2024 19:53:59 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org A546360E70 Authentication-Results: smtp3.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=efe1F4dW Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp3.osuosl.org (Postfix) with ESMTPS id A546360E70; Wed, 24 Apr 2024 19:53:58 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 60A06C0077; Wed, 24 Apr 2024 19:53:58 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id DBCE9C0077 for ; Wed, 24 Apr 2024 19:53:56 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id A6895820B4 for ; Wed, 24 Apr 2024 19:53:56 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id nsz4LlF_cv41 for ; Wed, 24 Apr 2024 19:53:54 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp1.osuosl.org 06EBF81330 Authentication-Results: smtp1.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 06EBF81330 Authentication-Results: smtp1.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=efe1F4dW Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp1.osuosl.org (Postfix) with ESMTPS id 06EBF81330 for ; Wed, 24 Apr 2024 19:53:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713988432; 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=T/CgFRWRgSngxWudp0PaIys/RIFD1TgifqKEWGTiOyE=; b=efe1F4dWZiOSIdCJFIGabZnb2t0PzwUWtsbZcvargvZBf0iKGLJJzATelJzC0KIX8aXInW 3g3+Z2+sQRVAXDMQR6R2ub9GI7ggYH0FxYklWcFEdS6HEBPq21VdhfPDZbSTZsl+ydEMVZ 1wYBF7zSTy/DZzyzXovFzFR39S6zWXI= 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-681--EdqqqjvO-mxi_i4S0wG7w-1; Wed, 24 Apr 2024 15:53:49 -0400 X-MC-Unique: -EdqqqjvO-mxi_i4S0wG7w-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (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 0A91980D6E1; Wed, 24 Apr 2024 19:53:49 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id B786D200AE7F; Wed, 24 Apr 2024 19:53:47 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Wed, 24 Apr 2024 21:53:29 +0200 Message-ID: <20240424195337.3596657-4-amorenoz@redhat.com> In-Reply-To: <20240424195337.3596657-1-amorenoz@redhat.com> References: <20240424195337.3596657-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: dceara@redhat.com, i.maximets@ovn.org, horms@kernel.org Subject: [ovs-dev] [RFC 03/11] ofproto: Add ofproto-dpif-psample. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Add a new resource in ofproto-dpif and the corresponding API in ofproto_provider.h to represent and change psample configuration. Signed-off-by: Adrian Moreno --- ofproto/automake.mk | 2 + ofproto/ofproto-dpif-psample.c | 167 +++++++++++++++++++++++++++++++++ ofproto/ofproto-dpif-psample.h | 31 ++++++ ofproto/ofproto-dpif.c | 33 +++++++ ofproto/ofproto-dpif.h | 1 + ofproto/ofproto-provider.h | 9 ++ ofproto/ofproto.c | 10 ++ ofproto/ofproto.h | 8 ++ 8 files changed, 261 insertions(+) create mode 100644 ofproto/ofproto-dpif-psample.c create mode 100644 ofproto/ofproto-dpif-psample.h diff --git a/ofproto/automake.mk b/ofproto/automake.mk index 7c08b563b..340003e12 100644 --- a/ofproto/automake.mk +++ b/ofproto/automake.mk @@ -34,6 +34,8 @@ ofproto_libofproto_la_SOURCES = \ ofproto/ofproto-dpif-mirror.h \ ofproto/ofproto-dpif-monitor.c \ ofproto/ofproto-dpif-monitor.h \ + ofproto/ofproto-dpif-psample.c \ + ofproto/ofproto-dpif-psample.h \ ofproto/ofproto-dpif-rid.c \ ofproto/ofproto-dpif-rid.h \ ofproto/ofproto-dpif-sflow.c \ diff --git a/ofproto/ofproto-dpif-psample.c b/ofproto/ofproto-dpif-psample.c new file mode 100644 index 000000000..a83530ed8 --- /dev/null +++ b/ofproto/ofproto-dpif-psample.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2024 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "ofproto-dpif-psample.h" + +#include "hash.h" +#include "ofproto.h" +#include "openvswitch/hmap.h" +#include "openvswitch/thread.h" +#include "openvswitch/vlog.h" + +VLOG_DEFINE_THIS_MODULE(psample); + +static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; + +struct psample_exporter { + uint32_t group_id; + uint32_t collector_set_id; +}; + +struct psample_exporter_map_node { + struct hmap_node node; + struct psample_exporter exporter; +}; + +struct dpif_psample { + struct hmap exporters_map; /* Contains psample_exporter_map_node. */ + + struct ovs_refcount ref_cnt; +}; + +/* Exporter handling */ +static void +dpif_psample_clear(struct dpif_psample *ps) OVS_REQUIRES(mutex) +{ + struct psample_exporter_map_node *node; + + HMAP_FOR_EACH_POP (node, node, &ps->exporters_map) { + free(node); + } +} + +static struct psample_exporter_map_node* +dpif_psample_new_exporter_node(struct dpif_psample *ps, + const struct ofproto_psample_options *options) + OVS_REQUIRES(mutex) +{ + struct psample_exporter_map_node *node; + node = xzalloc(sizeof *node); + node->exporter.collector_set_id = options->collector_set_id; + node->exporter.group_id = options->group_id; + hmap_insert(&ps->exporters_map, &node->node, + hash_int(options->collector_set_id, 0)); + return node; +} + +static struct psample_exporter_map_node* +dpif_psample_find_exporter_node(const struct dpif_psample *ps, + const uint32_t collector_set_id) + OVS_REQUIRES(mutex) +{ + struct psample_exporter_map_node *node; + HMAP_FOR_EACH_WITH_HASH (node, node, + hash_int(collector_set_id, 0), + &ps->exporters_map) { + if (node->exporter.collector_set_id == collector_set_id) { + return node; + } + } + return NULL; +} + +/* Configuration. */ + +/* Sets the psample configuration. + * Returns true if the configuration has changed. */ +bool +dpif_psample_set_options(struct dpif_psample *ps, + const struct ovs_list *options_list) +OVS_EXCLUDED(mutex) +{ + struct ofproto_psample_options *options; + struct psample_exporter_map_node *node; + bool changed = false; + + ovs_mutex_lock(&mutex); + + /* psample exporters do not hold any runtime memory so we do not need to + * be extra careful at detecting which exporter changed and which did + * not. As soon as we detect any change we can just recreate them all. */ + LIST_FOR_EACH(options, list_node, options_list) { + node = dpif_psample_find_exporter_node(ps, options->collector_set_id); + if (!node || + node->exporter.collector_set_id != options->collector_set_id || + node->exporter.group_id != options->group_id) { + changed = true; + break; + } + } + changed |= (hmap_count(&ps->exporters_map) != ovs_list_size(options_list)); + + if (changed) { + dpif_psample_clear(ps); + LIST_FOR_EACH(options, list_node, options_list) { + dpif_psample_new_exporter_node(ps, options); + } + } + + ovs_mutex_unlock(&mutex); + + return changed; +} + +/* Creation and destruction. */ +struct dpif_psample * +dpif_psample_create(void) +{ + struct dpif_psample *ps; + ps = xzalloc(sizeof *ps); + hmap_init(&ps->exporters_map); + ovs_refcount_init(&ps->ref_cnt); + return ps; +} + +static void +dpif_psample_destroy(struct dpif_psample *ps) OVS_EXCLUDED(mutex) +{ + if (ps) { + ovs_mutex_lock(&mutex); + dpif_psample_clear(ps); + free(ps); + ovs_mutex_unlock(&mutex); + } +} + +/* Reference counting. */ +struct dpif_psample* +dpif_psample_ref(const struct dpif_psample *ps_) +{ + struct dpif_psample *ps = CONST_CAST(struct dpif_psample*, ps_); + if (ps) { + ovs_refcount_ref(&ps->ref_cnt); + } + return ps; +} + +void +dpif_psample_unref(struct dpif_psample *ps) OVS_EXCLUDED(mutex) +{ + if (ps && ovs_refcount_unref_relaxed(&ps->ref_cnt) == 1) { + dpif_psample_destroy(ps); + } +} diff --git a/ofproto/ofproto-dpif-psample.h b/ofproto/ofproto-dpif-psample.h new file mode 100644 index 000000000..80ba44fb9 --- /dev/null +++ b/ofproto/ofproto-dpif-psample.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OFPROTO_DPIF_PSAMPLE_H +#define OFPROTO_DPIF_PSAMPLE_H 1 + +#include + +struct dpif_psample; +struct ovs_list; + +struct dpif_psample *dpif_psample_create(void); +void dpif_psample_unref(struct dpif_psample *); +struct dpif_psample* dpif_psample_ref(const struct dpif_psample *); + +bool dpif_psample_set_options(struct dpif_psample *, const struct ovs_list *); + +#endif // OFPROTO_DPIF_PSAMPLE_H diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 3cee2795a..fbb83a9ec 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -50,6 +50,7 @@ #include "ofproto-dpif-sflow.h" #include "ofproto-dpif-trace.h" #include "ofproto-dpif-upcall.h" +#include "ofproto-dpif-psample.h" #include "ofproto-dpif-xlate.h" #include "ofproto-dpif-xlate-cache.h" #include "openvswitch/ofp-actions.h" @@ -2529,6 +2530,37 @@ get_ipfix_stats(const struct ofproto *ofproto_, return dpif_ipfix_get_stats(di, bridge_ipfix, replies); } +static int +set_psample(struct ofproto *ofproto_, const struct ovs_list *pso) +{ + struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); + struct dpif_psample *ps = ofproto->psample; + bool changed = false; + bool has_options = pso && !ovs_list_is_empty(pso); + + if(!ofproto->backer->rt_support.psample) + return ENOTSUP; + + if (has_options && !ps) { + ps = ofproto->psample = dpif_psample_create(); + changed = true; + } + + if (ps) { + if (!has_options) { + dpif_psample_unref(ps); + ofproto->psample = NULL; + changed = true; + } else { + changed |= dpif_psample_set_options(ps, pso); + } + } + + if (changed) + ofproto->backer->need_revalidate = REV_RECONFIGURE; + return 0; +} + static int set_cfm(struct ofport *ofport_, const struct cfm_settings *s) { @@ -7099,6 +7131,7 @@ const struct ofproto_class ofproto_dpif_class = { get_netflow_ids, set_sflow, set_ipfix, + set_psample, get_ipfix_stats, set_cfm, cfm_status_changed, diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index 3db4263c7..97b2e78f1 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -331,6 +331,7 @@ struct ofproto_dpif { struct netflow *netflow; struct dpif_sflow *sflow; struct dpif_ipfix *ipfix; + struct dpif_psample *psample; struct hmap bundles; /* Contains "struct ofbundle"s. */ struct mac_learning *ml; struct mcast_snooping *ms; diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 83c509fcf..2ed7ebfbe 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -1479,6 +1479,15 @@ struct ofproto_class { const struct ofproto_ipfix_flow_exporter_options *flow_exporters_options, size_t n_flow_exporters_options); + /* Configures psample on 'ofproto' according to the options in + * 'options' or turns off psample if 'options' is NULL. + * + * 'options' contains 'struct ofproto_psample_options'. + * EOPNOTSUPP as a return value indicates that 'ofproto' does not support + * psample, as does a null pointer. */ + int (*set_psample)(struct ofproto *ofproto, + const struct ovs_list *options); + /* Gets IPFIX stats on 'ofproto' according to the exporter of birdge * IPFIX or flow-based IPFIX. * diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 21c6a1d82..22f584740 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1000,6 +1000,16 @@ ofproto_get_datapath_cap(const char *datapath_type, struct smap *dp_cap) } } +int ofproto_set_psample(struct ofproto *ofproto, + const struct ovs_list *pso) +{ + if (ofproto->ofproto_class->set_psample) { + return ofproto->ofproto_class->set_psample(ofproto, pso); + } else { + return (!pso || ovs_list_is_empty(pso)) ? 0: ENOTSUP; + } +} + /* Connection tracking configuration. */ void ofproto_ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h index 1c07df275..dc1c470dd 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -103,6 +103,12 @@ struct ofproto_ipfix_flow_exporter_options { char *virtual_obs_id; }; +struct ofproto_psample_options { + struct ovs_list list_node; + uint32_t collector_set_id; + uint32_t group_id; +}; + struct ofproto_rstp_status { bool enabled; /* If false, ignore other members. */ rstp_identifier root_id; @@ -390,6 +396,8 @@ void ofproto_ct_zone_limit_protection_update(const char *datapath_type, bool protected); void ofproto_get_datapath_cap(const char *datapath_type, struct smap *dp_cap); +int ofproto_set_psample(struct ofproto *, + const struct ovs_list *); /* Configuration of ports. */ void ofproto_port_unregister(struct ofproto *, ofp_port_t ofp_port); From patchwork Wed Apr 24 19:53:30 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: 1927348 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ipntopFw; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VPqSH62VKz1yP2 for ; Thu, 25 Apr 2024 05:54:07 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 37F32414CE; Wed, 24 Apr 2024 19:54:06 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id WTktGtPPgywZ; Wed, 24 Apr 2024 19:54:04 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org E3ACB4149D Authentication-Results: smtp4.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ipntopFw Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTPS id E3ACB4149D; Wed, 24 Apr 2024 19:54:03 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 59F60C0DD8; Wed, 24 Apr 2024 19:54:03 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 555C8C0037 for ; Wed, 24 Apr 2024 19:54:01 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id DB56B60E3F for ; Wed, 24 Apr 2024 19:53:59 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id OyUbkS6L1DyP for ; Wed, 24 Apr 2024 19:53:57 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp3.osuosl.org 98E3560E2C Authentication-Results: smtp3.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 98E3560E2C Authentication-Results: smtp3.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ipntopFw Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp3.osuosl.org (Postfix) with ESMTPS id 98E3560E2C for ; Wed, 24 Apr 2024 19:53:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713988434; 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=J10g9TpAVHazi4X37qI0125KYXHh5nDA0CO2BHKxvpM=; b=ipntopFwBpHsmWKClNhCL0TBkeQwYL7BEMYomDFDzJb4qD2nWpkjdGWD0DFh1T2ogTcmI/ 4dKosB1CsTrcARTXQn3I/sPXljS17eEN+g41vBnPb1KuixvdaKer/sxemmJNSwIGUnu6LP Osa3Z8rawgD2zLoX5oDMNdrkWS/pIrk= 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-271-l_DxGeONOPCnD9N9TQ8kAQ-1; Wed, 24 Apr 2024 15:53:51 -0400 X-MC-Unique: l_DxGeONOPCnD9N9TQ8kAQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (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 E173B1049C9B; Wed, 24 Apr 2024 19:53:50 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 47992200AE7F; Wed, 24 Apr 2024 19:53:49 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Wed, 24 Apr 2024 21:53:30 +0200 Message-ID: <20240424195337.3596657-5-amorenoz@redhat.com> In-Reply-To: <20240424195337.3596657-1-amorenoz@redhat.com> References: <20240424195337.3596657-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: dceara@redhat.com, i.maximets@ovn.org, horms@kernel.org Subject: [ovs-dev] [RFC 04/11] vswitchd: Add psample to schema and configure it. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Add a psample_group field to the Flow Sample Collector Set table and use it to configure the psample ofproto layer. Signed-off-by: Adrian Moreno --- vswitchd/bridge.c | 54 ++++++++++++++++++++++++++++++++++---- vswitchd/vswitch.ovsschema | 7 ++++- vswitchd/vswitch.xml | 32 +++++++++++++++++++--- 3 files changed, 83 insertions(+), 10 deletions(-) diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 95a65fcdc..474eb1650 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -288,6 +288,7 @@ static void bridge_configure_mac_table(struct bridge *); static void bridge_configure_mcast_snooping(struct bridge *); static void bridge_configure_sflow(struct bridge *, int *sflow_bridge_number); static void bridge_configure_ipfix(struct bridge *); +static void bridge_configure_psample(struct bridge *); static void bridge_configure_spanning_tree(struct bridge *); static void bridge_configure_tables(struct bridge *); static void bridge_configure_dp_desc(struct bridge *); @@ -989,6 +990,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) bridge_configure_netflow(br); bridge_configure_sflow(br, &sflow_bridge_number); bridge_configure_ipfix(br); + bridge_configure_psample(br); bridge_configure_spanning_tree(br); bridge_configure_tables(br); bridge_configure_dp_desc(br); @@ -1537,10 +1539,11 @@ ovsrec_ipfix_is_valid(const struct ovsrec_ipfix *ipfix) return ipfix && ipfix->n_targets > 0; } -/* Returns whether a Flow_Sample_Collector_Set row is valid. */ +/* Returns whether a Flow_Sample_Collector_Set row constains valid IPFIX + * configuration. */ static bool -ovsrec_fscs_is_valid(const struct ovsrec_flow_sample_collector_set *fscs, - const struct bridge *br) +ovsrec_fscs_is_valid_ipfix(const struct ovsrec_flow_sample_collector_set *fscs, + const struct bridge *br) { return ovsrec_ipfix_is_valid(fscs->ipfix) && fscs->bridge == br->cfg; } @@ -1558,7 +1561,7 @@ bridge_configure_ipfix(struct bridge *br) const char *virtual_obs_id; OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH(fe_cfg, idl) { - if (ovsrec_fscs_is_valid(fe_cfg, br)) { + if (ovsrec_fscs_is_valid_ipfix(fe_cfg, br)) { n_fe_opts++; } } @@ -1621,7 +1624,7 @@ bridge_configure_ipfix(struct bridge *br) fe_opts = xcalloc(n_fe_opts, sizeof *fe_opts); opts = fe_opts; OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH(fe_cfg, idl) { - if (ovsrec_fscs_is_valid(fe_cfg, br)) { + if (ovsrec_fscs_is_valid_ipfix(fe_cfg, br)) { opts->collector_set_id = fe_cfg->id; sset_init(&opts->targets); sset_add_array(&opts->targets, fe_cfg->ipfix->targets, @@ -1667,6 +1670,47 @@ bridge_configure_ipfix(struct bridge *br) } } +/* Set psample configuration on 'br'. */ +static void +bridge_configure_psample(struct bridge *br) +{ + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); + const struct ovsrec_flow_sample_collector_set *fscs; + struct ofproto_psample_options *ps_options; + struct ovs_list options_list; + int ret; + + ovs_list_init(&options_list); + + OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH(fscs, idl) { + if (!fscs->psample_group || fscs->n_psample_group != 1 + || fscs->bridge != br->cfg) + continue; + + ps_options = xzalloc(sizeof *ps_options); + ps_options->collector_set_id = fscs->id; + ps_options->group_id = *fscs->psample_group; + + ovs_list_insert(&options_list, &ps_options->list_node); + } + + ret = ofproto_set_psample(br->ofproto, &options_list); + + if (ret == ENOTSUP) { + if (!ovs_list_is_empty(&options_list)) { + VLOG_WARN_RL(&rl, "bridge %s: ignoring psample configuration: " + "not supported by this datapath", br->name); + } + } else if (ret) { + VLOG_ERR_RL(&rl, "bridge %s: error configuring psample: %s", + br->name, ovs_strerror(ret)); + } + + LIST_FOR_EACH_POP(ps_options, list_node, &options_list) { + free(ps_options); + } +} + static void port_configure_stp(const struct ofproto *ofproto, struct port *port, struct ofproto_port_stp_settings *port_s, diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema index e2d5e2e85..a7ad9bcaa 100644 --- a/vswitchd/vswitch.ovsschema +++ b/vswitchd/vswitch.ovsschema @@ -1,6 +1,6 @@ {"name": "Open_vSwitch", "version": "8.5.0", - "cksum": "4040946650 27557", + "cksum": "1366215760 27764", "tables": { "Open_vSwitch": { "columns": { @@ -562,6 +562,11 @@ "type": {"key": {"type": "uuid", "refTable": "IPFIX"}, "min": 0, "max": 1}}, + "psample_group": { + "type": {"key": {"type": "integer", + "minInteger": 0, + "maxInteger": 4294967295}, + "min": 0, "max": 1}}, "external_ids": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}}, diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 8a1b607d7..ab6e6f479 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -7008,10 +7008,30 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \

- A set of IPFIX collectors of packet samples generated by OpenFlow - sample actions. This table is used only for IPFIX - flow-based sampling, not for per-bridge sampling (see the table for a description of the two forms). + A set of IPFIX or Psample collectors of packet samples generated by + OpenFlow sample actions. +

+ +

+ If the column ipfix contains a reference to a + valid IPFIX entry, samples will be emitted via IPFIX. This mechanism + is known as flow-based IPFIX sampling, as opposed to bridge-based + sampling (see the table for a description of the + two forms). +

+ +

+ If the column psample_group contains an integer and the + running kernel supports it, samples will be sent to the psample group + specified by psample_group. + + External processes can read the raw samples by joining the psample netlink + multicast group. +

+ +

+ Note both psample_group and ipfix can be set + simultaneously.

@@ -7030,6 +7050,10 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \ record per sampled packet to. + + Configuration of the psample group where the sample will be multicasted. + + The overall purpose of these columns is described under Common Columns at the beginning of this document. From patchwork Wed Apr 24 19:53:31 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: 1927350 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=YP1cvPHI; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VPqSQ6xh1z23hs for ; Thu, 25 Apr 2024 05:54:14 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id EE3EA8237D; Wed, 24 Apr 2024 19:54:12 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id JAt5mHPhqpGR; Wed, 24 Apr 2024 19:54:08 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 9DEBD82122 Authentication-Results: smtp1.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=YP1cvPHI Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id 9DEBD82122; Wed, 24 Apr 2024 19:54:06 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id E0226C0DD8; Wed, 24 Apr 2024 19:54:05 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 04CDDC0077 for ; Wed, 24 Apr 2024 19:54:02 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 182A3410DF for ; Wed, 24 Apr 2024 19:53:59 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 2OPB5_azdpmD for ; Wed, 24 Apr 2024 19:53:57 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp4.osuosl.org 60AA0409F3 Authentication-Results: smtp4.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 60AA0409F3 Authentication-Results: smtp4.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=YP1cvPHI Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp4.osuosl.org (Postfix) with ESMTPS id 60AA0409F3 for ; Wed, 24 Apr 2024 19:53:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713988436; 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=TqejBajFj0CkDbyZJHHchnt7WeAd0Z/rgRobkQaTirg=; b=YP1cvPHIk98+aHbg0Bmg16YrPn9D4ftUXMKFG8eC03eClTF6XW6x5/4CONQdCZfEyGJ6HQ yFcKbkMnegjz5UfbQB6r8l67LQQvtSnw7p8U2mKS0k8o8K3OLSf53wtvRj7fdZIdBncfcd B3loUIwOtHutR0Bv18mr2nJxGU2ztcA= 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-495-0yuTCcwyODi2pCbCo5bC9g-1; Wed, 24 Apr 2024 15:53:52 -0400 X-MC-Unique: 0yuTCcwyODi2pCbCo5bC9g-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (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 737E0810B26; Wed, 24 Apr 2024 19:53:52 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 29CED200AE7F; Wed, 24 Apr 2024 19:53:51 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Wed, 24 Apr 2024 21:53:31 +0200 Message-ID: <20240424195337.3596657-6-amorenoz@redhat.com> In-Reply-To: <20240424195337.3596657-1-amorenoz@redhat.com> References: <20240424195337.3596657-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: dceara@redhat.com, i.maximets@ovn.org, horms@kernel.org Subject: [ovs-dev] [RFC 05/11] ofproto_dpif_xlate: Use psample for OFP samples. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" When a OFP_SAMPLE action is xlated and a dpif_psample object has been configured (via Flow_Sample_Collector_Set table) with the same collector_set_id, add psample information to the odp sample action. Signed-off-by: Adrian Moreno --- ofproto/ofproto-dpif-psample.c | 20 +++++ ofproto/ofproto-dpif-psample.h | 3 + ofproto/ofproto-dpif-xlate.c | 149 +++++++++++++++++++++++++-------- ofproto/ofproto-dpif-xlate.h | 3 +- ofproto/ofproto-dpif.c | 2 +- 5 files changed, 138 insertions(+), 39 deletions(-) diff --git a/ofproto/ofproto-dpif-psample.c b/ofproto/ofproto-dpif-psample.c index a83530ed8..1e4f4bf48 100644 --- a/ofproto/ofproto-dpif-psample.c +++ b/ofproto/ofproto-dpif-psample.c @@ -125,6 +125,26 @@ OVS_EXCLUDED(mutex) return changed; } +/* Returns the group_id of the exporter with the given collector_set_id, if it + * exists. */ +bool +dpif_psample_get_group_id(struct dpif_psample *ps, uint32_t collector_set_id, + uint32_t *group_id) OVS_EXCLUDED(mutex) +{ + + struct psample_exporter_map_node *node; + bool found = false; + + ovs_mutex_lock(&mutex); + node = dpif_psample_find_exporter_node(ps, collector_set_id); + if (node) { + found = true; + *group_id = node->exporter.group_id; + } + ovs_mutex_unlock(&mutex); + return found; +} + /* Creation and destruction. */ struct dpif_psample * dpif_psample_create(void) diff --git a/ofproto/ofproto-dpif-psample.h b/ofproto/ofproto-dpif-psample.h index 80ba44fb9..b9f2584af 100644 --- a/ofproto/ofproto-dpif-psample.h +++ b/ofproto/ofproto-dpif-psample.h @@ -18,6 +18,7 @@ #define OFPROTO_DPIF_PSAMPLE_H 1 #include +#include struct dpif_psample; struct ovs_list; @@ -28,4 +29,6 @@ struct dpif_psample* dpif_psample_ref(const struct dpif_psample *); bool dpif_psample_set_options(struct dpif_psample *, const struct ovs_list *); +bool dpif_psample_get_group_id(struct dpif_psample *, uint32_t, uint32_t *); + #endif // OFPROTO_DPIF_PSAMPLE_H diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 7c4950895..1dcf86856 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -47,6 +47,7 @@ #include "ofproto/ofproto-dpif-ipfix.h" #include "ofproto/ofproto-dpif-mirror.h" #include "ofproto/ofproto-dpif-monitor.h" +#include "ofproto/ofproto-dpif-psample.h" #include "ofproto/ofproto-dpif-sflow.h" #include "ofproto/ofproto-dpif-trace.h" #include "ofproto/ofproto-dpif-xlate-cache.h" @@ -117,6 +118,7 @@ struct xbridge { struct dpif_sflow *sflow; /* SFlow handle, or null. */ struct dpif_ipfix *ipfix; /* Ipfix handle, or null. */ struct netflow *netflow; /* Netflow handle, or null. */ + struct dpif_psample *psample; /* Psample handle, or null. */ struct stp *stp; /* STP or null if disabled. */ struct rstp *rstp; /* RSTP or null if disabled. */ @@ -687,6 +689,7 @@ static void xlate_xbridge_set(struct xbridge *, struct dpif *, const struct dpif_sflow *, const struct dpif_ipfix *, const struct netflow *, + const struct dpif_psample *, bool forward_bpdu, bool has_in_band, const struct dpif_backer_support *, const struct xbridge_addr *); @@ -1070,6 +1073,7 @@ xlate_xbridge_set(struct xbridge *xbridge, const struct dpif_sflow *sflow, const struct dpif_ipfix *ipfix, const struct netflow *netflow, + const struct dpif_psample *psample, bool forward_bpdu, bool has_in_band, const struct dpif_backer_support *support, const struct xbridge_addr *addr) @@ -1099,6 +1103,11 @@ xlate_xbridge_set(struct xbridge *xbridge, xbridge->ipfix = dpif_ipfix_ref(ipfix); } + if (xbridge->psample != psample) { + dpif_psample_unref(xbridge->psample); + xbridge->psample = dpif_psample_ref(psample); + } + if (xbridge->stp != stp) { stp_unref(xbridge->stp); xbridge->stp = stp_ref(stp); @@ -1214,8 +1223,9 @@ xlate_xbridge_copy(struct xbridge *xbridge) xbridge->dpif, xbridge->ml, xbridge->stp, xbridge->rstp, xbridge->ms, xbridge->mbridge, xbridge->sflow, xbridge->ipfix, xbridge->netflow, - xbridge->forward_bpdu, xbridge->has_in_band, - &xbridge->support, xbridge->addr); + xbridge->psample, xbridge->forward_bpdu, + xbridge->has_in_band, &xbridge->support, + xbridge->addr); LIST_FOR_EACH (xbundle, list_node, &xbridge->xbundles) { xlate_xbundle_copy(new_xbridge, xbundle); } @@ -1373,6 +1383,7 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name, const struct dpif_sflow *sflow, const struct dpif_ipfix *ipfix, const struct netflow *netflow, + const struct dpif_psample *psample, bool forward_bpdu, bool has_in_band, const struct dpif_backer_support *support) { @@ -1396,7 +1407,7 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name, old_addr = xbridge->addr; xlate_xbridge_set(xbridge, dpif, ml, stp, rstp, ms, mbridge, sflow, ipfix, - netflow, forward_bpdu, has_in_band, support, + netflow, psample, forward_bpdu, has_in_band, support, xbridge_addr); if (xbridge_addr != old_addr) { @@ -3357,6 +3368,11 @@ xlate_normal(struct xlate_ctx *ctx) } } +struct psample_args { + uint32_t group_id; + struct ofpbuf cookie; +}; + /* Appends a "sample" action for sFlow or IPFIX to 'ctx->odp_actions'. The * 'probability' is the number of packets out of UINT32_MAX to sample. The * 'cookie' is passed back in the callback for each sampled packet. @@ -3370,7 +3386,8 @@ xlate_normal(struct xlate_ctx *ctx) static size_t compose_sample_action(struct xlate_ctx *ctx, const uint32_t probability, - const struct user_action_cookie *cookie, + const struct user_action_cookie *upcall, + const struct psample_args *psample, const odp_port_t tunnel_out_port, bool include_actions) { @@ -3379,6 +3396,9 @@ compose_sample_action(struct xlate_ctx *ctx, return 0; } + /* Either upcall or psample data must be provided */ + ovs_assert(upcall || psample); + /* If the slow path meter is configured by the controller, * insert a meter action before the user space action. */ struct ofproto *ofproto = &ctx->xin->ofproto->up; @@ -3386,15 +3406,31 @@ compose_sample_action(struct xlate_ctx *ctx, /* When meter action is not required, avoid generate sample action * for 100% sampling rate. */ - bool is_sample = probability < UINT32_MAX || meter_id != UINT32_MAX; + bool is_sample = (probability < UINT32_MAX || meter_id != UINT32_MAX || + psample); size_t sample_offset = 0, actions_offset = 0; if (is_sample) { sample_offset = nl_msg_start_nested(ctx->odp_actions, OVS_ACTION_ATTR_SAMPLE); nl_msg_put_u32(ctx->odp_actions, OVS_SAMPLE_ATTR_PROBABILITY, probability); - actions_offset = nl_msg_start_nested(ctx->odp_actions, + if (psample) { + nl_msg_put_u32(ctx->odp_actions, OVS_SAMPLE_ATTR_PSAMPLE_GROUP, + psample->group_id); + if (psample->cookie.size) { + nl_msg_put_unspec(ctx->odp_actions, + OVS_SAMPLE_ATTR_PSAMPLE_COOKIE, + psample->cookie.data, + psample->cookie.size); + } + } + if (upcall) { + actions_offset = nl_msg_start_nested(ctx->odp_actions, OVS_SAMPLE_ATTR_ACTIONS); + } else { + nl_msg_end_nested(ctx->odp_actions, sample_offset); + return 0; + } } if (meter_id != UINT32_MAX) { @@ -3405,11 +3441,11 @@ compose_sample_action(struct xlate_ctx *ctx, ctx->xbridge, ctx->xin->flow.in_port.ofp_port); uint32_t pid = dpif_port_get_pid(ctx->xbridge->dpif, odp_port); size_t cookie_offset; - int res = odp_put_userspace_action(pid, cookie, sizeof *cookie, + int res = odp_put_userspace_action(pid, upcall, sizeof *upcall, tunnel_out_port, include_actions, ctx->odp_actions, &cookie_offset); ovs_assert(res == 0); - if (is_sample) { + if (actions_offset) { nl_msg_end_nested(ctx->odp_actions, actions_offset); nl_msg_end_nested(ctx->odp_actions, sample_offset); } @@ -3440,7 +3476,7 @@ compose_sflow_action(struct xlate_ctx *ctx) cookie.ofproto_uuid = ctx->xbridge->ofproto->uuid; return compose_sample_action(ctx, dpif_sflow_get_probability(sflow), - &cookie, ODPP_NONE, true); + &cookie, NULL, ODPP_NONE, true); } /* If flow IPFIX is enabled, make sure IPFIX flow sample action @@ -3490,7 +3526,7 @@ compose_ipfix_action(struct xlate_ctx *ctx, odp_port_t output_odp_port) compose_sample_action(ctx, dpif_ipfix_get_bridge_exporter_probability(ipfix), - &cookie, tunnel_out_port, false); + &cookie, NULL, tunnel_out_port, false); } /* Fix "sample" action according to data collected while composing ODP actions, @@ -5847,23 +5883,15 @@ xlate_fin_timeout(struct xlate_ctx *ctx, } static void -xlate_sample_action(struct xlate_ctx *ctx, - const struct ofpact_sample *os) +xlate_fill_ipfix_sample(struct xlate_ctx *ctx, + const struct ofpact_sample *os, + const struct dpif_ipfix *ipfix, + struct user_action_cookie *cookie, + odp_port_t *tunnel_out_port) { odp_port_t output_odp_port = ODPP_NONE; - odp_port_t tunnel_out_port = ODPP_NONE; - struct dpif_ipfix *ipfix = ctx->xbridge->ipfix; bool emit_set_tunnel = false; - if (!ipfix) { - return; - } - - /* Scale the probability from 16-bit to 32-bit while representing - * the same percentage. */ - uint32_t probability = - ((uint32_t) os->probability << 16) | os->probability; - /* If ofp_port in flow sample action is equel to ofp_port, * this sample action is a input port action. */ if (os->sampling_port != OFPP_NONE && @@ -5879,7 +5907,7 @@ xlate_sample_action(struct xlate_ctx *ctx, if (dpif_ipfix_get_flow_exporter_tunnel_sampling(ipfix, os->collector_set_id) && dpif_ipfix_is_tunnel_port(ipfix, output_odp_port)) { - tunnel_out_port = output_odp_port; + *tunnel_out_port = output_odp_port; emit_set_tunnel = true; } } @@ -5913,20 +5941,67 @@ xlate_sample_action(struct xlate_ctx *ctx, } } - struct user_action_cookie cookie; + cookie->type = USER_ACTION_COOKIE_FLOW_SAMPLE; + cookie->ofp_in_port = ctx->xin->flow.in_port.ofp_port; + cookie->ofproto_uuid = ctx->xbridge->ofproto->uuid; + cookie->flow_sample.probability = os->probability; + cookie->flow_sample.collector_set_id = os->collector_set_id; + cookie->flow_sample.obs_domain_id = os->obs_domain_id; + cookie->flow_sample.obs_point_id = os->obs_point_id; + cookie->flow_sample.output_odp_port = output_odp_port; + cookie->flow_sample.direction = os->direction; +} - memset(&cookie, 0, sizeof cookie); - cookie.type = USER_ACTION_COOKIE_FLOW_SAMPLE; - cookie.ofp_in_port = ctx->xin->flow.in_port.ofp_port; - cookie.ofproto_uuid = ctx->xbridge->ofproto->uuid; - cookie.flow_sample.probability = os->probability; - cookie.flow_sample.collector_set_id = os->collector_set_id; - cookie.flow_sample.obs_domain_id = os->obs_domain_id; - cookie.flow_sample.obs_point_id = os->obs_point_id; - cookie.flow_sample.output_odp_port = output_odp_port; - cookie.flow_sample.direction = os->direction; - - compose_sample_action(ctx, probability, &cookie, tunnel_out_port, false); +static void +xlate_sample_action(struct xlate_ctx *ctx, + const struct ofpact_sample *os) +{ + struct dpif_psample *psample = ctx->xbridge->psample; + struct dpif_ipfix *ipfix = ctx->xbridge->ipfix; + struct user_action_cookie *upcall_cookie = NULL; + struct psample_args *psample_args = NULL; + odp_port_t tunnel_out_port = ODPP_NONE; + uint32_t group_id; + + if (!ipfix && !psample) { + return; + } + + /* Scale the probability from 16-bit to 32-bit while representing + * the same percentage. */ + uint32_t probability = + ((uint32_t) os->probability << 16) | os->probability; + + if (ipfix) { + upcall_cookie = xzalloc(sizeof *upcall_cookie); + xlate_fill_ipfix_sample(ctx, os, ipfix, upcall_cookie, + &tunnel_out_port); + } + if (psample) { + if (dpif_psample_get_group_id(psample, + os->collector_set_id, + &group_id)) { + psample_args = xzalloc(sizeof *psample_args); + ofpbuf_init(&psample_args->cookie, OVS_PSAMPLE_COOKIE_MAX_SIZE); + + psample_args->group_id = group_id; + ofpbuf_put(&psample_args->cookie, &os->obs_domain_id, + sizeof(os->obs_domain_id)); + ofpbuf_put(&psample_args->cookie, &os->obs_point_id, + sizeof(os->obs_point_id)); + } + } + + compose_sample_action(ctx, probability, upcall_cookie, psample_args, + tunnel_out_port, false); + + if (upcall_cookie) { + free(upcall_cookie); + } + if (psample_args) { + ofpbuf_uninit(&psample_args->cookie); + free(psample_args); + } } /* Determine if an datapath action translated from the openflow action diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h index 05b46fb26..a2835082b 100644 --- a/ofproto/ofproto-dpif-xlate.h +++ b/ofproto/ofproto-dpif-xlate.h @@ -177,7 +177,8 @@ void xlate_ofproto_set(struct ofproto_dpif *, const char *name, struct dpif *, struct rstp *, const struct mcast_snooping *, const struct mbridge *, const struct dpif_sflow *, const struct dpif_ipfix *, const struct netflow *, - bool forward_bpdu, bool has_in_band, + const struct dpif_psample *, bool forward_bpdu, + bool has_in_band, const struct dpif_backer_support *support); void xlate_remove_ofproto(struct ofproto_dpif *); struct ofproto_dpif *xlate_ofproto_lookup(const struct uuid *uuid); diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index fbb83a9ec..64c06322e 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -486,7 +486,7 @@ type_run(const char *type) ofproto->backer->dpif, ofproto->ml, ofproto->stp, ofproto->rstp, ofproto->ms, ofproto->mbridge, ofproto->sflow, ofproto->ipfix, - ofproto->netflow, + ofproto->netflow, ofproto->psample, ofproto->up.forward_bpdu, connmgr_has_in_band(ofproto->up.connmgr), &ofproto->backer->rt_support); From patchwork Wed Apr 24 19:53:32 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: 1927349 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=B9R4x3qn; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VPqSQ0r1Lz1yP2 for ; Thu, 25 Apr 2024 05:54:14 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 7518960E66; Wed, 24 Apr 2024 19:54:12 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id R15WV1gPPBB8; Wed, 24 Apr 2024 19:54:08 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org C660560EAA Authentication-Results: smtp3.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=B9R4x3qn Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp3.osuosl.org (Postfix) with ESMTPS id C660560EAA; Wed, 24 Apr 2024 19:54:07 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id D9DD5C0DD3; Wed, 24 Apr 2024 19:54:06 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 13B9AC0DD9 for ; Wed, 24 Apr 2024 19:54:04 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 473558225A for ; Wed, 24 Apr 2024 19:54:01 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id OhWNtaAuEv7h for ; Wed, 24 Apr 2024 19:53:58 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp1.osuosl.org 91E2C821B6 Authentication-Results: smtp1.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 91E2C821B6 Authentication-Results: smtp1.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=B9R4x3qn Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp1.osuosl.org (Postfix) with ESMTPS id 91E2C821B6 for ; Wed, 24 Apr 2024 19:53:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713988436; 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=4KP682mt4zi1/aMnWP7CZoqH1Poxs3gxqZ+4Cff3KgU=; b=B9R4x3qnHCIZZ3G7xXha7wknzrTCyOq1KdH/0s1lChhfQI5NOT0Iuhy5Q/FE1UbMirzB8Z 30ie61DZyXkfYelhvfVj1nTgKWh4UwNuNRT7WPXQ91XcQQFCANQAz2oz3K5JyecPT6wNx4 m95XA5iXZqpVwzoN4yWSCv0UU1ahx0M= 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-251-CDKEN7V9OvK88WUgB6GMOw-1; Wed, 24 Apr 2024 15:53:54 -0400 X-MC-Unique: CDKEN7V9OvK88WUgB6GMOw-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (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 26792800CAC; Wed, 24 Apr 2024 19:53:54 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id B2D25200AE7F; Wed, 24 Apr 2024 19:53:52 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Wed, 24 Apr 2024 21:53:32 +0200 Message-ID: <20240424195337.3596657-7-amorenoz@redhat.com> In-Reply-To: <20240424195337.3596657-1-amorenoz@redhat.com> References: <20240424195337.3596657-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: dceara@redhat.com, i.maximets@ovn.org, horms@kernel.org Subject: [ovs-dev] [RFC 06/11] utilities: Add ovs-psample. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" This simple program reads from psample and prints the packets to stdout. It's useful for quickly collecting sampled packets. Signed-off-by: Adrian Moreno --- Documentation/automake.mk | 1 + Documentation/conf.py | 2 + Documentation/ref/index.rst | 1 + Documentation/ref/ovs-psample.8.rst | 47 ++++ include/linux/automake.mk | 1 + include/linux/psample.h | 64 ++++++ rhel/openvswitch-fedora.spec.in | 2 + rhel/openvswitch.spec.in | 1 + utilities/automake.mk | 9 + utilities/ovs-psample.c | 330 ++++++++++++++++++++++++++++ 10 files changed, 458 insertions(+) create mode 100644 Documentation/ref/ovs-psample.8.rst create mode 100644 include/linux/psample.h create mode 100644 utilities/ovs-psample.c diff --git a/Documentation/automake.mk b/Documentation/automake.mk index 47d2e336a..c22facfd6 100644 --- a/Documentation/automake.mk +++ b/Documentation/automake.mk @@ -165,6 +165,7 @@ RST_MANPAGES = \ ovs-l3ping.8.rst \ ovs-parse-backtrace.8.rst \ ovs-pki.8.rst \ + ovs-psample.8.rst \ ovs-tcpdump.8.rst \ ovs-tcpundump.1.rst \ ovs-test.8.rst \ diff --git a/Documentation/conf.py b/Documentation/conf.py index 15785605a..75efed2fc 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -134,6 +134,8 @@ _man_pages = [ u'convert "tcpdump -xx" output to hex strings'), ('ovs-test.8', u'Check Linux drivers for performance, vlan and L3 tunneling problems'), + ('ovs-psample.8', + u'Print packets sampled by psample'), ('ovs-vlan-test.8', u'Check Linux drivers for problems with vlan traffic'), ('ovsdb-server.7', diff --git a/Documentation/ref/index.rst b/Documentation/ref/index.rst index 03ada932f..d1076435a 100644 --- a/Documentation/ref/index.rst +++ b/Documentation/ref/index.rst @@ -46,6 +46,7 @@ time: ovs-pki.8 ovs-sim.1 ovs-parse-backtrace.8 + ovs-psample.8 ovs-tcpdump.8 ovs-tcpundump.1 ovs-test.8 diff --git a/Documentation/ref/ovs-psample.8.rst b/Documentation/ref/ovs-psample.8.rst new file mode 100644 index 000000000..c849c83d8 --- /dev/null +++ b/Documentation/ref/ovs-psample.8.rst @@ -0,0 +1,47 @@ +========== +ovs-sample +========== + +Synopsis +======== + +``ovs-sample`` +[``--group=`` | ``-g`` ] + +``ovs-sample --help`` + +``ovs-sample --version`` + +Description +=========== + +Open vSwitch per-flow sampling can be configured to emit the samples +through the ``psample`` netlink multicast group. + +Such sampled traffic contains, apart from the packet, some metadata that +gives further information about the packet sample. More specifically, OVS +inserts the ``observation_domain_id`` and the ``observation_point_id`` that +where provided in the sample action (see ``ovs-actions(7)``). + +the ``ovs-sample`` program provides a simple way of joining the psample +multicast group and printing the sampled packets. + + +Options +======= + +.. option:: ``-g`` or ``--group`` + + Tells ``ovs-sample`` to filter out samples that don't belong to that group. + + Different ``Flow_Sample_Collector_Set`` entries can be configured with + different ``group_id`` values (see ``ovs-vswitchd.conf.db(5)``). This option + helps focusing the output on the relevant samples. + +.. option:: -h, --help + + Prints a brief help message to the console. + +.. option:: -V, --version + + Prints version information to the console. diff --git a/include/linux/automake.mk b/include/linux/automake.mk index cdae5eedc..ac306b53c 100644 --- a/include/linux/automake.mk +++ b/include/linux/automake.mk @@ -3,6 +3,7 @@ noinst_HEADERS += \ include/linux/netfilter/nf_conntrack_sctp.h \ include/linux/openvswitch.h \ include/linux/pkt_cls.h \ + include/linux/psample.h \ include/linux/gen_stats.h \ include/linux/tc_act/tc_mpls.h \ include/linux/tc_act/tc_pedit.h \ diff --git a/include/linux/psample.h b/include/linux/psample.h new file mode 100644 index 000000000..eb642f875 --- /dev/null +++ b/include/linux/psample.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef __LINUX_PSAMPLE_H +#define __LINUX_PSAMPLE_H + +enum { + PSAMPLE_ATTR_IIFINDEX, + PSAMPLE_ATTR_OIFINDEX, + PSAMPLE_ATTR_ORIGSIZE, + PSAMPLE_ATTR_SAMPLE_GROUP, + PSAMPLE_ATTR_GROUP_SEQ, + PSAMPLE_ATTR_SAMPLE_RATE, + PSAMPLE_ATTR_DATA, + PSAMPLE_ATTR_GROUP_REFCOUNT, + PSAMPLE_ATTR_TUNNEL, + + PSAMPLE_ATTR_PAD, + PSAMPLE_ATTR_OUT_TC, /* u16 */ + PSAMPLE_ATTR_OUT_TC_OCC, /* u64, bytes */ + PSAMPLE_ATTR_LATENCY, /* u64, nanoseconds */ + PSAMPLE_ATTR_TIMESTAMP, /* u64, nanoseconds */ + PSAMPLE_ATTR_PROTO, /* u16 */ + PSAMPLE_ATTR_USER_COOKIE, + + __PSAMPLE_ATTR_MAX +}; + +enum psample_command { + PSAMPLE_CMD_SAMPLE, + PSAMPLE_CMD_GET_GROUP, + PSAMPLE_CMD_NEW_GROUP, + PSAMPLE_CMD_DEL_GROUP, + PSAMPLE_CMD_SAMPLE_FILTER_SET, +}; + +enum psample_tunnel_key_attr { + PSAMPLE_TUNNEL_KEY_ATTR_ID, /* be64 Tunnel ID */ + PSAMPLE_TUNNEL_KEY_ATTR_IPV4_SRC, /* be32 src IP address. */ + PSAMPLE_TUNNEL_KEY_ATTR_IPV4_DST, /* be32 dst IP address. */ + PSAMPLE_TUNNEL_KEY_ATTR_TOS, /* u8 Tunnel IP ToS. */ + PSAMPLE_TUNNEL_KEY_ATTR_TTL, /* u8 Tunnel IP TTL. */ + PSAMPLE_TUNNEL_KEY_ATTR_DONT_FRAGMENT, /* No argument, set DF. */ + PSAMPLE_TUNNEL_KEY_ATTR_CSUM, /* No argument. CSUM packet. */ + PSAMPLE_TUNNEL_KEY_ATTR_OAM, /* No argument. OAM frame. */ + PSAMPLE_TUNNEL_KEY_ATTR_GENEVE_OPTS, /* Array of Geneve options. */ + PSAMPLE_TUNNEL_KEY_ATTR_TP_SRC, /* be16 src Transport Port. */ + PSAMPLE_TUNNEL_KEY_ATTR_TP_DST, /* be16 dst Transport Port. */ + PSAMPLE_TUNNEL_KEY_ATTR_VXLAN_OPTS, /* Nested VXLAN opts* */ + PSAMPLE_TUNNEL_KEY_ATTR_IPV6_SRC, /* struct in6_addr src IPv6 address. */ + PSAMPLE_TUNNEL_KEY_ATTR_IPV6_DST, /* struct in6_addr dst IPv6 address. */ + PSAMPLE_TUNNEL_KEY_ATTR_PAD, + PSAMPLE_TUNNEL_KEY_ATTR_ERSPAN_OPTS, /* struct erspan_metadata */ + PSAMPLE_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE, /* No argument. IPV4_INFO_BRIDGE mode.*/ + __PSAMPLE_TUNNEL_KEY_ATTR_MAX +}; + +/* Can be overridden at runtime by module option */ +#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1) + +#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config" +#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets" +#define PSAMPLE_GENL_NAME "psample" +#define PSAMPLE_GENL_VERSION 1 + +#endif diff --git a/rhel/openvswitch-fedora.spec.in b/rhel/openvswitch-fedora.spec.in index 94b6d7431..9ee66180c 100644 --- a/rhel/openvswitch-fedora.spec.in +++ b/rhel/openvswitch-fedora.spec.in @@ -471,6 +471,7 @@ fi %{_bindir}/ovs-dpctl %{_bindir}/ovs-dpctl-top %{_bindir}/ovs-ofctl +%{_bindir}/ovs-psample %{_bindir}/ovs-vsctl %{_bindir}/ovsdb-client %{_bindir}/ovsdb-tool @@ -502,6 +503,7 @@ fi %{_mandir}/man8/ovs-kmod-ctl.8* %{_mandir}/man8/ovs-ofctl.8* %{_mandir}/man8/ovs-pki.8* +%{_mandir}/man8/ovs-psample.8* %{_mandir}/man8/ovs-vsctl.8* %{_mandir}/man8/ovs-vswitchd.8* %{_mandir}/man8/ovs-parse-backtrace.8* diff --git a/rhel/openvswitch.spec.in b/rhel/openvswitch.spec.in index 9903dd10a..06d79b921 100644 --- a/rhel/openvswitch.spec.in +++ b/rhel/openvswitch.spec.in @@ -195,6 +195,7 @@ exit 0 /usr/bin/ovs-pki /usr/bin/ovs-tcpdump /usr/bin/ovs-tcpundump +/usr/bin/ovs-sample /usr/bin/ovs-vlan-test /usr/bin/ovs-vsctl /usr/bin/ovsdb-client diff --git a/utilities/automake.mk b/utilities/automake.mk index 146b8c37f..0d07ff868 100644 --- a/utilities/automake.mk +++ b/utilities/automake.mk @@ -4,6 +4,7 @@ bin_PROGRAMS += \ utilities/ovs-dpctl \ utilities/ovs-ofctl \ utilities/ovs-vsctl + bin_SCRIPTS += utilities/ovs-docker \ utilities/ovs-pki \ utilities/ovs-pcap \ @@ -132,6 +133,14 @@ utilities_ovs_ofctl_LDADD = \ ofproto/libofproto.la \ lib/libopenvswitch.la +if LINUX +bin_PROGRAMS += utilities/ovs-psample +utilities_ovs_psample_SOURCES = utilities/ovs-psample.c +utilities_ovs_psample_LDADD = \ + ofproto/libofproto.la \ + lib/libopenvswitch.la +endif + utilities_ovs_vsctl_SOURCES = utilities/ovs-vsctl.c utilities_ovs_vsctl_LDADD = lib/libopenvswitch.la diff --git a/utilities/ovs-psample.c b/utilities/ovs-psample.c new file mode 100644 index 000000000..9127d065c --- /dev/null +++ b/utilities/ovs-psample.c @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2024 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "command-line.h" +#include "dp-packet.h" +#include "util.h" +#include "netlink.h" +#include "netlink-socket.h" +#include "openvswitch/ofp-actions.h" +#include "openvswitch/ofp-print.h" +#include "openvswitch/types.h" +#include "openvswitch/uuid.h" +#include "openvswitch/vlog.h" + +VLOG_DEFINE_THIS_MODULE(ovs_sample); + +/* -g, --group: Group id filter option */ +static uint32_t group_id = 0; +static bool has_filter; + +static int psample_family = 0; + +OVS_NO_RETURN static void usage(void) +{ + printf("%s: OpenvSwitch psample viewer\n" +"usage: %s [OPTIONS]\n" +"\nOptions:\n" +" -h, --help display this help message\n" +" -t, --group=GROUP only display events from GROUP group_id\n" +" -V, --version display %s version information\n", + program_name, program_name, program_name); + exit(EXIT_SUCCESS); +} + +struct sample; +static inline void sample_clear(struct sample *sample); +static int parse_psample(struct ofpbuf *, struct sample *sample); +static void psample_set_filter(struct nl_sock *sock); +static void parse_options(int argc, char *argv[]); +static int connect_psample_socket(struct nl_sock **sock); +static void run(struct nl_sock *sock); + +int +main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) +{ + struct nl_sock *sock; + int error; + + parse_options(argc, argv); + + error = connect_psample_socket(&sock); + if (error) { + return error; + } + + run(sock); +} + +static void parse_options(int argc, char *argv[]) +{ + static const struct option long_options[] = { + {"group", required_argument, NULL, 'g'}, + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'V'}, + {NULL, 0, NULL, 0}, + }; + + char *short_options_ = + ovs_cmdl_long_options_to_short_options(long_options); + char *short_options = xasprintf("+%s", short_options_); + + for (;;) { + int option; + + option = getopt_long(argc, argv, short_options, long_options, NULL); + if (option == -1) { + break; + } + switch (option) { + case 'g': + { + char *endptr; + + if (has_filter) { + ovs_fatal(0, "-g or --group may be specified only once"); + } + + group_id = strtol(optarg, &endptr, 10); + if (endptr - optarg != strlen(optarg)) { + ovs_fatal(0, "-g or --group expects a valid decimal" + " 32-bit number"); + } + + has_filter = true; + } + break; + case 'h': + usage(); + break; + + case 'V': + ovs_print_version(0, 0); + exit(EXIT_SUCCESS); + + case '?': + exit(EXIT_FAILURE); + + default: + OVS_NOT_REACHED(); + } + } + free(short_options_); + free(short_options); +} + +static int connect_psample_socket(struct nl_sock **sock) +{ + unsigned int psample_packet_mcgroup; + int error; + + error = nl_lookup_genl_family(PSAMPLE_GENL_NAME , &psample_family); + if (error) { + VLOG_ERR("PSAMPLE_GENL_NAME not found: %i", error); + } + + error = nl_lookup_genl_mcgroup(PSAMPLE_GENL_NAME, + PSAMPLE_NL_MCGRP_SAMPLE_NAME, + &psample_packet_mcgroup); + if (error) { + VLOG_ERR("psample packet multicast group not found: %i", error); + return error; + } + + error = nl_sock_create(NETLINK_GENERIC, sock); + if (error) { + VLOG_ERR("cannot create netlink socket: %i ", error); + return error; + } + + nl_sock_listen_all_nsid(*sock, true); + + psample_set_filter(*sock); + + error = nl_sock_join_mcgroup(*sock, psample_packet_mcgroup); + if (error) { + nl_sock_destroy(*sock); + *sock = NULL; + VLOG_ERR("cannot join psample multicast group: %i", error); + return error; + } + return 0; +} + +/* Internal representation of a sample. */ +struct sample { + struct dp_packet packet; + uint32_t group_id; + uint32_t obs_domain_id; + uint32_t obs_point_id; + bool has_cookie; +}; + +static inline void +sample_clear(struct sample *sample) { + sample->group_id = 0; + sample->obs_domain_id = 0; + sample->obs_point_id = 0; + sample->has_cookie = false; + dp_packet_clear(&sample->packet); +} + +static int +parse_psample(struct ofpbuf *buf, struct sample *sample) { + static const struct nl_policy psample_packet_policy[] = { + [PSAMPLE_ATTR_SAMPLE_GROUP] = { .type = NL_A_U32 }, + [PSAMPLE_ATTR_DATA] = { .type = NL_A_UNSPEC, + .optional = true, }, + [PSAMPLE_ATTR_USER_COOKIE] = { .type = NL_A_UNSPEC, + .optional = true }, + }; + + struct ofpbuf b = ofpbuf_const_initializer(buf->data, buf->size); + struct nlmsghdr *nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg); + struct genlmsghdr *genl = ofpbuf_try_pull(&b, sizeof *genl); + struct nlattr *attr; + const char *cookie; + + struct nlattr *a[ARRAY_SIZE(psample_packet_policy)]; + if (!nlmsg || !genl + || !nl_policy_parse(&b, 0, psample_packet_policy, a, + ARRAY_SIZE(psample_packet_policy))) { + return EINVAL; + } + + attr = a[PSAMPLE_ATTR_DATA]; + if (attr) { + dp_packet_push(&sample->packet, nl_attr_get(attr), + nl_attr_get_size(attr)); + } + + sample->group_id = nl_attr_get_u32(a[PSAMPLE_ATTR_SAMPLE_GROUP]); + + attr = a[PSAMPLE_ATTR_USER_COOKIE]; + if (attr && nl_attr_get_size(attr) == 8) { + cookie = nl_attr_get(attr); + sample->has_cookie = true; + sample->obs_domain_id = (uint32_t) *(&cookie[0]); + sample->obs_point_id = (uint32_t) *(&cookie[4]); + } + return 0; +} + +static int _psample_set_filter(struct nl_sock *sock, uint32_t group, + bool valid) +{ + uint64_t stub[512 / 8]; + struct ofpbuf buf; + int error; + + ofpbuf_use_stub(&buf, stub, sizeof stub); + + nl_msg_put_genlmsghdr(&buf, 0, psample_family, NLM_F_REQUEST, + PSAMPLE_CMD_SAMPLE_FILTER_SET, 1); + if (valid) { + nl_msg_put_u32(&buf, PSAMPLE_ATTR_SAMPLE_GROUP, group); + } + + error = nl_sock_send(sock, &buf, false); + if (error) { + return error; + } + + ofpbuf_clear(&buf); + error = nl_sock_recv(sock, &buf, NULL, false); + if (!error) { + struct nlmsghdr *h = ofpbuf_at(&buf, 0, NLMSG_HDRLEN); + if (h->nlmsg_type == NLMSG_ERROR) { + const struct nlmsgerr *e; + e = ofpbuf_at(&buf, NLMSG_HDRLEN, + NLMSG_ALIGN(sizeof(struct nlmsgerr))); + if (!e) + return EINVAL; + if (e && e->error < 0) + return -e->error; + } + } else if (error != EAGAIN) { + return error; + } + return 0; +} + +static void psample_set_filter(struct nl_sock *sock) +{ + int error; + if (has_filter) { + error = _psample_set_filter(sock, group_id, true); + if (error) { + VLOG_WARN("Failed to install in-kernel filter (%s). " + "Falling back to userspace filtering.", + ovs_strerror(error)); + } + } +} + +static void run(struct nl_sock *sock) +{ + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(10, 10); + int error; + + struct sample sample = {}; + dp_packet_init(&sample.packet, 1500); + + for (;;) { + uint64_t buf_stub[4096 / 8]; + struct ofpbuf buf; + + sample_clear(&sample); + + ofpbuf_use_stub(&buf, buf_stub, sizeof buf_stub); + error = nl_sock_recv(sock, &buf, NULL, true); + + if (error == ENOBUFS) { + fprintf(stderr, "[missed events]\n"); + continue; + } else if (error == EAGAIN) { + continue; + } else if (error) { + VLOG_ERR_RL(&rl, "error reading samples: %i", error); + } + + error = parse_psample(&buf, &sample); + if (error) + VLOG_ERR_RL(&rl, "error parsing samples: %i", error); + + if (!has_filter || sample.group_id == group_id) { + fprintf(stdout, "group_id=0x%"PRIx32" ", + sample.group_id); + if (sample.has_cookie) { + fprintf(stdout, + "obs_domain=0x%"PRIx32",obs_point=0x%"PRIx32" ", + sample.obs_domain_id, sample.obs_point_id); + } + ofp_print_dp_packet(stdout, &sample.packet); + } + } +} + From patchwork Wed Apr 24 19:53:33 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: 1927347 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=PhdX5hDw; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VPqSF4PRSz23hs for ; Thu, 25 Apr 2024 05:54:05 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 97869414C6; Wed, 24 Apr 2024 19:54:03 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id HZePnoMLZQrg; Wed, 24 Apr 2024 19:54:02 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 70FBD4148D Authentication-Results: smtp4.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=PhdX5hDw Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTPS id 70FBD4148D; Wed, 24 Apr 2024 19:54:02 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 40222C0037; Wed, 24 Apr 2024 19:54:02 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 06C34C0037 for ; Wed, 24 Apr 2024 19:54:01 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id C373A82122 for ; Wed, 24 Apr 2024 19:54:00 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id qLP-0quBVfYY for ; Wed, 24 Apr 2024 19:53:59 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp1.osuosl.org 00258821BF Authentication-Results: smtp1.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 00258821BF Authentication-Results: smtp1.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=PhdX5hDw Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp1.osuosl.org (Postfix) with ESMTPS id 00258821BF for ; Wed, 24 Apr 2024 19:53:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713988437; 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=Gzo++htnX3nnh3kV2oYOj4gGVn5GMKVB5BR8aPzbaF8=; b=PhdX5hDwuOZ/3cinNg0m4qpi4s/075ADI7Erm3fIJXRl6o9Tn1mTsZdRMAXhnrajHuFcce x41DO70bhxGPtGSMnbA+UFYWyxueV40WDYwb6W3jMbTGVH8233ci6mafXP8+Jw/TtOQozw 4s/6XzCtLco/v6dDBnCrPVmy8gKdgTo= 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-216--mO_6LwJOd2oAuKmHf7hvA-1; Wed, 24 Apr 2024 15:53:56 -0400 X-MC-Unique: -mO_6LwJOd2oAuKmHf7hvA-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (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 AD281830E76; Wed, 24 Apr 2024 19:53:55 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 62AB62033979; Wed, 24 Apr 2024 19:53:54 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Wed, 24 Apr 2024 21:53:33 +0200 Message-ID: <20240424195337.3596657-8-amorenoz@redhat.com> In-Reply-To: <20240424195337.3596657-1-amorenoz@redhat.com> References: <20240424195337.3596657-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: dceara@redhat.com, i.maximets@ovn.org, horms@kernel.org Subject: [ovs-dev] [RFC 07/11] netlink-offload-tc: Rename act_cookie->flow_cookie. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" In preparation to allowing certain actions to have a cookie that does not represent the entire flow, rename flower->act_cookie to flower->flow_cookie. This patch does not introduce any behavioral change, it's just a variable renaming. Signed-off-by: Adrian Moreno --- lib/netdev-offload-tc.c | 8 ++++---- lib/tc.c | 14 +++++++------- lib/tc.h | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 921d52317..36e814bee 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -1322,8 +1322,8 @@ netdev_tc_flow_dump_next(struct netdev_flow_dump *dump, continue; } - if (flower.act_cookie.len >= sizeof *ufid) { - *ufid = get_32aligned_u128(flower.act_cookie.data); + if (flower.flow_cookie.len >= sizeof *ufid) { + *ufid = get_32aligned_u128(flower.flow_cookie.data); } else if (!find_ufid(netdev, &id, ufid)) { continue; } @@ -2537,8 +2537,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, return ENOSPC; } - flower.act_cookie.data = ufid; - flower.act_cookie.len = sizeof *ufid; + flower.flow_cookie.data = ufid; + flower.flow_cookie.len = sizeof *ufid; block_id = get_block_id_from_netdev(netdev); id = tc_make_tcf_id_chain(ifindex, block_id, chain, prio, hook); diff --git a/lib/tc.c b/lib/tc.c index e9bcae4e4..7176991c3 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -2088,8 +2088,8 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, } if (act_cookie) { - flower->act_cookie.data = nl_attr_get(act_cookie); - flower->act_cookie.len = nl_attr_get_size(act_cookie); + flower->flow_cookie.data = nl_attr_get(act_cookie); + flower->flow_cookie.len = nl_attr_get_size(act_cookie); } return nl_parse_action_stats(action_attrs[TCA_ACT_STATS], @@ -3458,7 +3458,7 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) TCA_EGRESS_MIRROR); } } - nl_msg_put_act_cookie(request, &flower->act_cookie); + nl_msg_put_act_cookie(request, &flower->flow_cookie); nl_msg_put_act_flags(request); nl_msg_end_nested(request, act_offset); } @@ -3476,14 +3476,14 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) act_offset = nl_msg_start_nested(request, act_index++); nl_msg_put_act_gact(request, action->chain); - nl_msg_put_act_cookie(request, &flower->act_cookie); + nl_msg_put_act_cookie(request, &flower->flow_cookie); nl_msg_end_nested(request, act_offset); } break; case TC_ACT_CT: { act_offset = nl_msg_start_nested(request, act_index++); nl_msg_put_act_ct(request, action, action_pc); - nl_msg_put_act_cookie(request, &flower->act_cookie); + nl_msg_put_act_cookie(request, &flower->flow_cookie); nl_msg_end_nested(request, act_offset); } break; @@ -3501,7 +3501,7 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) released)) { return -EOPNOTSUPP; } - nl_msg_put_act_cookie(request, &flower->act_cookie); + nl_msg_put_act_cookie(request, &flower->flow_cookie); nl_msg_put_act_flags(request); nl_msg_end_nested(request, act_offset); } @@ -3515,7 +3515,7 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) if (!flower->action_count) { act_offset = nl_msg_start_nested(request, act_index++); nl_msg_put_act_gact(request, 0); - nl_msg_put_act_cookie(request, &flower->act_cookie); + nl_msg_put_act_cookie(request, &flower->flow_cookie); nl_msg_put_act_flags(request); nl_msg_end_nested(request, act_offset); } diff --git a/lib/tc.h b/lib/tc.h index fdbcf4b7c..40ea3d816 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -386,7 +386,7 @@ struct tc_flower { bool tunnel; - struct tc_cookie act_cookie; + struct tc_cookie flow_cookie; /* Cookie to help identify the flow. */ bool needs_full_ip_proto_mask; From patchwork Wed Apr 24 19:53:34 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: 1927353 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=b/39lbfR; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VPqSp34pVz1yP2 for ; Thu, 25 Apr 2024 05:54:34 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 8459282549; Wed, 24 Apr 2024 19:54:32 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id h0V1JKH1wbrb; Wed, 24 Apr 2024 19:54:28 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 6191D823F4 Authentication-Results: smtp1.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=b/39lbfR Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id 6191D823F4; Wed, 24 Apr 2024 19:54:17 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0076CC008E; Wed, 24 Apr 2024 19:54:17 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0ED5AC0DD9 for ; Wed, 24 Apr 2024 19:54:15 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 3C7F982307 for ; Wed, 24 Apr 2024 19:54:05 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id uiWpYUN0sFVD for ; Wed, 24 Apr 2024 19:54:02 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp1.osuosl.org 888F082073 Authentication-Results: smtp1.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 888F082073 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp1.osuosl.org (Postfix) with ESMTPS id 888F082073 for ; Wed, 24 Apr 2024 19:54:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713988441; 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=jjUY3Y0+zfA9jY205GArgEeOE3HuWnoiShm1fXTKBRc=; b=b/39lbfRvxQnc3JoSMwULPAJE0TodkSTKHShwiEBySSNZI+1FmVu9cavDXTQMUraM/5Hhr C3l2tmiS7onECxKB6WHU9O9o6jh25FoPnSSW7u7xVsk9S/WdBFM+tgV4yRxbixxAPALFdc ADIi7QOGe+IqZVFOYDCe5uH1a4x8NgU= 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-457-0l0QYSkFPUKjbNtwdlL5bw-1; Wed, 24 Apr 2024 15:53:57 -0400 X-MC-Unique: 0l0QYSkFPUKjbNtwdlL5bw-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (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 3E7013C025B4; Wed, 24 Apr 2024 19:53:57 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id E7F59200AE7F; Wed, 24 Apr 2024 19:53:55 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Wed, 24 Apr 2024 21:53:34 +0200 Message-ID: <20240424195337.3596657-9-amorenoz@redhat.com> In-Reply-To: <20240424195337.3596657-1-amorenoz@redhat.com> References: <20240424195337.3596657-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: dceara@redhat.com, i.maximets@ovn.org, horms@kernel.org Subject: [ovs-dev] [RFC 08/11] netdev-offload-tc: Add sample support. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Offload the sample action if it contains psample information by creating a tc "sample" action with the user cookie inside the action's cookie. Avoid using the "sample" action's cookie to store the ufid. Signed-off-by: Adrian Moreno --- include/linux/automake.mk | 5 +- include/linux/pkt_cls.h | 2 + include/linux/tc_act/tc_sample.h | 26 ++++++++++ lib/netdev-offload-tc.c | 67 +++++++++++++++++++++++++ lib/tc.c | 84 ++++++++++++++++++++++++++++++-- lib/tc.h | 7 +++ utilities/ovs-psample.c | 8 +-- 7 files changed, 190 insertions(+), 9 deletions(-) create mode 100644 include/linux/tc_act/tc_sample.h diff --git a/include/linux/automake.mk b/include/linux/automake.mk index ac306b53c..c2a270152 100644 --- a/include/linux/automake.mk +++ b/include/linux/automake.mk @@ -5,9 +5,10 @@ noinst_HEADERS += \ include/linux/pkt_cls.h \ include/linux/psample.h \ include/linux/gen_stats.h \ + include/linux/tc_act/tc_ct.h \ include/linux/tc_act/tc_mpls.h \ include/linux/tc_act/tc_pedit.h \ + include/linux/tc_act/tc_sample.h \ include/linux/tc_act/tc_skbedit.h \ include/linux/tc_act/tc_tunnel_key.h \ - include/linux/tc_act/tc_vlan.h \ - include/linux/tc_act/tc_ct.h + include/linux/tc_act/tc_vlan.h diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index fb4a7ecea..c566ac1b5 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -8,6 +8,8 @@ #include #include +#define TC_COOKIE_MAX_SIZE 16 + /* Action attributes */ enum { TCA_ACT_UNSPEC, diff --git a/include/linux/tc_act/tc_sample.h b/include/linux/tc_act/tc_sample.h new file mode 100644 index 000000000..398f32761 --- /dev/null +++ b/include/linux/tc_act/tc_sample.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef __LINUX_TC_SAMPLE_H +#define __LINUX_TC_SAMPLE_H + +#include +#include +#include + +struct tc_sample { + tc_gen; +}; + +enum { + TCA_SAMPLE_UNSPEC, + TCA_SAMPLE_TM, + TCA_SAMPLE_PARMS, + TCA_SAMPLE_RATE, + TCA_SAMPLE_TRUNC_SIZE, + TCA_SAMPLE_PSAMPLE_GROUP, + TCA_SAMPLE_PAD, + __TCA_SAMPLE_MAX +}; +#define TCA_SAMPLE_MAX (__TCA_SAMPLE_MAX - 1) + +#endif + diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 36e814bee..0e7273431 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -1038,6 +1038,21 @@ parse_tc_flower_to_actions__(struct tc_flower *flower, struct ofpbuf *buf, nl_msg_end_nested(buf, offset); } break; + case TC_ACT_SAMPLE: { + size_t offset; + + offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_SAMPLE); + nl_msg_put_u32(buf, OVS_SAMPLE_ATTR_PROBABILITY, + UINT32_MAX / action->sample.rate); + nl_msg_put_u32(buf, OVS_SAMPLE_ATTR_PSAMPLE_GROUP, + action->sample.group_id); + nl_msg_put_unspec(buf, OVS_SAMPLE_ATTR_PSAMPLE_COOKIE, + &action->sample.cookie[0], + action->sample.cookie_len); + + nl_msg_end_nested(buf, offset); + } + break; } if (action->jump_action && action->type != TC_ACT_POLICE_MTU) { @@ -2054,6 +2069,53 @@ parse_check_pkt_len_action(struct netdev *netdev, struct tc_flower *flower, return 0; } +static int +parse_sample_action(struct tc_flower *flower, const struct nlattr *nl_act, + struct tc_action *action) +{ + /* Only offloadable if it's psample only. Use the policy to enforce it by + * making psample arguments mandatory and omitting actions. */ + static const struct nl_policy ovs_sample_policy[] = { + [OVS_SAMPLE_ATTR_PROBABILITY] = { .type = NL_A_U32 }, + [OVS_SAMPLE_ATTR_PSAMPLE_GROUP] = { .type = NL_A_U32, }, + [OVS_SAMPLE_ATTR_PSAMPLE_COOKIE] = { .type = NL_A_UNSPEC, + .optional = true, + .max_len = TC_COOKIE_MAX_SIZE } + }; + struct nlattr *a[ARRAY_SIZE(ovs_sample_policy)]; + uint32_t probability; + + if (!nl_parse_nested(nl_act, ovs_sample_policy, a, ARRAY_SIZE(a))) { + return EOPNOTSUPP; + } + + action->type = TC_ACT_SAMPLE; + /* OVS probability and TC sampling rate have different semantics. + * The former represents the number of sampled packets out of UINT32_MAX + * while the other represents the ratio between observed and sampled + * packets. */ + probability = nl_attr_get_u32(a[OVS_SAMPLE_ATTR_PROBABILITY]); + if (!probability) { + return EINVAL; + } + action->sample.rate = UINT32_MAX / probability; + + action->sample.group_id = + nl_attr_get_u32(a[OVS_SAMPLE_ATTR_PSAMPLE_GROUP]); + + if (a[OVS_SAMPLE_ATTR_PSAMPLE_COOKIE]) { + action->sample.cookie_len = + nl_attr_get_size(a[OVS_SAMPLE_ATTR_PSAMPLE_COOKIE]); + + memcpy(&action->sample.cookie[0], + nl_attr_get(a[OVS_SAMPLE_ATTR_PSAMPLE_COOKIE]), + action->sample.cookie_len); + } + + flower->action_count++; + return 0; +} + static int netdev_tc_parse_nl_actions(struct netdev *netdev, struct tc_flower *flower, struct offload_info *info, @@ -2195,6 +2257,11 @@ netdev_tc_parse_nl_actions(struct netdev *netdev, struct tc_flower *flower, if (err) { return err; } + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_SAMPLE) { + err = parse_sample_action(flower, nla, action); + if (err) { + return err; + } } else { VLOG_DBG_RL(&rl, "unsupported put action type: %d", nl_attr_type(nla)); diff --git a/lib/tc.c b/lib/tc.c index 7176991c3..08d23064d 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -22,15 +22,16 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include -#include #include #include #include @@ -1563,6 +1564,42 @@ nl_parse_act_police(const struct nlattr *options, struct tc_flower *flower) return 0; } +static const struct nl_policy sample_policy[] = { + [TCA_SAMPLE_PARMS] = { .type = NL_A_UNSPEC, + .min_len = sizeof(struct tc_sample), + .optional = false, }, + [TCA_SAMPLE_PSAMPLE_GROUP] = { .type = NL_A_U32, + .optional = false, }, + [TCA_SAMPLE_RATE] = { .type = NL_A_U32, + .optional = false, }, +}; + +static int +nl_parse_act_sample(struct nlattr *options, const struct nlattr *cookie, + struct tc_flower *flower) +{ + struct nlattr *sample_attrs[ARRAY_SIZE(sample_policy)]; + struct tc_action *action; + + if (!nl_parse_nested(options, sample_policy, sample_attrs, + ARRAY_SIZE(sample_policy))) { + VLOG_ERR_RL(&error_rl, "Failed to parse sample action options"); + return EPROTO; + } + + action = &flower->actions[flower->action_count++]; + action->type = TC_ACT_SAMPLE; + action->sample.group_id = + nl_attr_get_u32(sample_attrs[TCA_SAMPLE_PSAMPLE_GROUP]); + action->sample.rate = + nl_attr_get_u32(sample_attrs[TCA_SAMPLE_RATE]); + action->sample.cookie_len = nl_attr_get_size(cookie); + memcpy(&action->sample.cookie[0], nl_attr_get(cookie), + MIN(action->sample.cookie_len, TC_COOKIE_MAX_SIZE)); + + return 0; +} + static const struct nl_policy mirred_policy[] = { [TCA_MIRRED_PARMS] = { .type = NL_A_UNSPEC, .min_len = sizeof(struct tc_mirred), @@ -2078,6 +2115,8 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, nl_parse_act_ct(act_options, flower); } else if (!strcmp(act_kind, "police")) { nl_parse_act_police(act_options, flower); + } else if (!strcmp(act_kind, "sample")) { + nl_parse_act_sample(act_options, act_cookie, flower); } else { VLOG_ERR_RL(&error_rl, "unknown tc action kind: %s", act_kind); err = EINVAL; @@ -2087,7 +2126,8 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, return err; } - if (act_cookie) { + /* TC_ACT_SAMPLE uses the cookie to store action-specific metadata. */ + if (act_cookie && strcmp(act_kind, "sample")) { flower->flow_cookie.data = nl_attr_get(act_cookie); flower->flow_cookie.len = nl_attr_get_size(act_cookie); } @@ -2901,6 +2941,29 @@ nl_msg_put_act_mirred(struct ofpbuf *request, int ifindex, int action, nl_msg_end_nested(request, offset); } +static void +nl_msg_put_act_sample(struct ofpbuf *request, struct tc_action *action, + uint32_t action_pc) +{ + size_t offset; + + nl_msg_put_string(request, TCA_ACT_KIND, "sample"); + offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS | NLA_F_NESTED); + { + struct tc_sample parm = { .action = action_pc }; + + nl_msg_put_unspec(request, TCA_SAMPLE_PARMS, &parm, sizeof parm); + nl_msg_put_u32(request, TCA_SAMPLE_RATE, action->sample.rate); + nl_msg_put_u32(request, TCA_SAMPLE_PSAMPLE_GROUP, + action->sample.group_id); + } + nl_msg_end_nested(request, offset); + if (action->sample.cookie_len) { + nl_msg_put_unspec(request, TCA_ACT_COOKIE, &action->sample.cookie[0], + action->sample.cookie_len); + } +} + static inline void nl_msg_put_act_cookie(struct ofpbuf *request, struct tc_cookie *ck) { if (ck->len) { @@ -3220,6 +3283,7 @@ get_action_index_for_tc_actions(struct tc_flower *flower, uint16_t act_index, case TC_ACT_MPLS_SET: case TC_ACT_GOTO: case TC_ACT_CT: + case TC_ACT_SAMPLE: /* Increase act_index by one if we are sure this type of action * will only add one tc action in the kernel. */ act_index++; @@ -3506,13 +3570,27 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) nl_msg_end_nested(request, act_offset); } break; + case TC_ACT_SAMPLE: { + act_offset = nl_msg_start_nested(request, act_index++); + /* TC_ACT_SAMPLE uses the action cookie so intentionally + * skipping flow action configuration. */ + nl_msg_put_act_sample(request, action, action_pc); + nl_msg_end_nested(request, act_offset); + break; + } } prev_action_pc = action_pc; } } - if (!flower->action_count) { + /* A flow with only a TC_ACT_SAMPLE action is possible. It is sampling the + * packet as it gets dropped. But given TC_ACT_SAMPLE uses the cookie to + * store action-specific data, add the explicit drop action to store the + * flow cookie. */ + if (!flower->action_count || + (flower->action_count == 1 && + flower->actions[0].type == TC_ACT_SAMPLE)) { act_offset = nl_msg_start_nested(request, act_index++); nl_msg_put_act_gact(request, 0); nl_msg_put_act_cookie(request, &flower->flow_cookie); diff --git a/lib/tc.h b/lib/tc.h index 40ea3d816..e6ad6950e 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -201,6 +201,7 @@ enum tc_action_type { TC_ACT_CT, TC_ACT_POLICE, TC_ACT_POLICE_MTU, + TC_ACT_SAMPLE, }; enum nat_type { @@ -296,6 +297,12 @@ struct tc_action { uint32_t result_jump; uint16_t mtu; } police; + struct { + uint32_t rate; + uint32_t group_id; + uint16_t cookie_len; + uint8_t cookie[TC_COOKIE_MAX_SIZE]; + } sample; }; enum tc_action_type type; diff --git a/utilities/ovs-psample.c b/utilities/ovs-psample.c index 9127d065c..51c72cc30 100644 --- a/utilities/ovs-psample.c +++ b/utilities/ovs-psample.c @@ -35,7 +35,7 @@ #include "openvswitch/uuid.h" #include "openvswitch/vlog.h" -VLOG_DEFINE_THIS_MODULE(ovs_sample); +VLOG_DEFINE_THIS_MODULE(ovs_psample); /* -g, --group: Group id filter option */ static uint32_t group_id = 0; @@ -206,7 +206,7 @@ parse_psample(struct ofpbuf *buf, struct sample *sample) { struct nlmsghdr *nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg); struct genlmsghdr *genl = ofpbuf_try_pull(&b, sizeof *genl); struct nlattr *attr; - const char *cookie; + const uint32_t *cookie; struct nlattr *a[ARRAY_SIZE(psample_packet_policy)]; if (!nlmsg || !genl @@ -227,8 +227,8 @@ parse_psample(struct ofpbuf *buf, struct sample *sample) { if (attr && nl_attr_get_size(attr) == 8) { cookie = nl_attr_get(attr); sample->has_cookie = true; - sample->obs_domain_id = (uint32_t) *(&cookie[0]); - sample->obs_point_id = (uint32_t) *(&cookie[4]); + sample->obs_domain_id = cookie[0]; + sample->obs_point_id = cookie[1]; } return 0; } From patchwork Wed Apr 24 19:53:35 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: 1927351 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=JnLt1qbK; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VPqSb6Lcxz1yP2 for ; Thu, 25 Apr 2024 05:54:23 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 3B78082309; Wed, 24 Apr 2024 19:54:22 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id DJPTh3iQekEW; Wed, 24 Apr 2024 19:54:19 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 0061D8237E Authentication-Results: smtp1.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=JnLt1qbK Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id 0061D8237E; Wed, 24 Apr 2024 19:54:12 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id B7096C0077; Wed, 24 Apr 2024 19:54:12 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 111DBC008E for ; Wed, 24 Apr 2024 19:54:11 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 0A0FB414BC for ; Wed, 24 Apr 2024 19:54:03 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id JnrIIAL22Ii6 for ; Wed, 24 Apr 2024 19:54:02 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp4.osuosl.org DADDD4149D Authentication-Results: smtp4.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org DADDD4149D Authentication-Results: smtp4.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=JnLt1qbK Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp4.osuosl.org (Postfix) with ESMTPS id DADDD4149D for ; Wed, 24 Apr 2024 19:54:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713988440; 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=PAy40QyL61RzIsvIeuTdECdoNPX66WnypXSh4wZWNVg=; b=JnLt1qbKCH9v/j7tuo8gy++jpZt+KrOLguu2g/8zXIcrwz3ZtUK4R3rCGCSBhKoLgQFk7W YRheYKxvtfT2r/ljOTHmEGppJyS8wbvUWq9xWsQt6+wejD33nNvoo4WDQVeBtGOsHGGek5 FckdHwKsLT+SRsIzHZcb54Os1AzTlUY= 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-248-DbdJeSblMTGZvI1aCYZXzw-1; Wed, 24 Apr 2024 15:53:59 -0400 X-MC-Unique: DbdJeSblMTGZvI1aCYZXzw-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (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 CC1C51049C97; Wed, 24 Apr 2024 19:53:58 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 81A15200AE7F; Wed, 24 Apr 2024 19:53:57 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Wed, 24 Apr 2024 21:53:35 +0200 Message-ID: <20240424195337.3596657-10-amorenoz@redhat.com> In-Reply-To: <20240424195337.3596657-1-amorenoz@redhat.com> References: <20240424195337.3596657-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: dceara@redhat.com, i.maximets@ovn.org, horms@kernel.org Subject: [ovs-dev] [RFC 09/11] ofproto-dpif-xlate-cache: Add psample to xcache. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Add a cache entry type for psample objects. Store both the dpif_psample reference and the collector_set_id so we can quickly find the particular exporter. Using that mechanism, account for packet and byte statistics. Signed-off-by: Adrian Moreno --- ofproto/ofproto-dpif-psample.c | 20 ++++++++++++++++++++ ofproto/ofproto-dpif-psample.h | 4 ++++ ofproto/ofproto-dpif-xlate-cache.c | 11 ++++++++++- ofproto/ofproto-dpif-xlate-cache.h | 6 ++++++ ofproto/ofproto-dpif-xlate.c | 9 +++++++++ ofproto/ofproto-dpif.c | 1 + 6 files changed, 50 insertions(+), 1 deletion(-) diff --git a/ofproto/ofproto-dpif-psample.c b/ofproto/ofproto-dpif-psample.c index 1e4f4bf48..ea4926eb2 100644 --- a/ofproto/ofproto-dpif-psample.c +++ b/ofproto/ofproto-dpif-psample.c @@ -17,6 +17,7 @@ #include #include "ofproto-dpif-psample.h" +#include "dpif.h" #include "hash.h" #include "ofproto.h" #include "openvswitch/hmap.h" @@ -30,6 +31,8 @@ static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; struct psample_exporter { uint32_t group_id; uint32_t collector_set_id; + uint64_t n_packets; + uint64_t n_bytes; }; struct psample_exporter_map_node { @@ -145,6 +148,23 @@ dpif_psample_get_group_id(struct dpif_psample *ps, uint32_t collector_set_id, return found; } +void +dpif_psample_credit_stats(struct dpif_psample *ps, uint32_t collector_set_id, + const struct dpif_flow_stats *stats) +OVS_EXCLUDED(mutex) +{ + struct psample_exporter_map_node *node; + + ovs_mutex_lock(&mutex); + node = dpif_psample_find_exporter_node(ps, collector_set_id); + if (node) { + node->exporter.n_packets += stats->n_packets; + node->exporter.n_bytes += stats->n_bytes; + } + ovs_mutex_unlock(&mutex); +} + + /* Creation and destruction. */ struct dpif_psample * dpif_psample_create(void) diff --git a/ofproto/ofproto-dpif-psample.h b/ofproto/ofproto-dpif-psample.h index b9f2584af..763fbd30b 100644 --- a/ofproto/ofproto-dpif-psample.h +++ b/ofproto/ofproto-dpif-psample.h @@ -20,6 +20,7 @@ #include #include +struct dpif_flow_stats; struct dpif_psample; struct ovs_list; @@ -31,4 +32,7 @@ bool dpif_psample_set_options(struct dpif_psample *, const struct ovs_list *); bool dpif_psample_get_group_id(struct dpif_psample *, uint32_t, uint32_t *); +void dpif_psample_credit_stats(struct dpif_psample *, uint32_t, + const struct dpif_flow_stats *); + #endif // OFPROTO_DPIF_PSAMPLE_H diff --git a/ofproto/ofproto-dpif-xlate-cache.c b/ofproto/ofproto-dpif-xlate-cache.c index 2e1fcb3a6..0fe76e5fa 100644 --- a/ofproto/ofproto-dpif-xlate-cache.c +++ b/ofproto/ofproto-dpif-xlate-cache.c @@ -35,9 +35,10 @@ #include "learn.h" #include "mac-learning.h" #include "netdev-vport.h" +#include "ofproto/ofproto-dpif.h" #include "ofproto/ofproto-dpif-mirror.h" +#include "ofproto/ofproto-dpif-psample.h" #include "ofproto/ofproto-dpif-xlate.h" -#include "ofproto/ofproto-dpif.h" #include "ofproto/ofproto-provider.h" #include "openvswitch/dynamic-string.h" #include "openvswitch/vlog.h" @@ -162,6 +163,11 @@ xlate_push_stats_entry(struct xc_entry *entry, } break; + case XC_PSAMPLE: + dpif_psample_credit_stats(entry->psample.psample, + entry->psample.collector_set_id, + stats); + break; default: OVS_NOT_REACHED(); } @@ -245,6 +251,9 @@ xlate_cache_clear_entry(struct xc_entry *entry) break; case XC_TUNNEL_HEADER: break; + case XC_PSAMPLE: + dpif_psample_unref(entry->psample.psample); + break; default: OVS_NOT_REACHED(); } diff --git a/ofproto/ofproto-dpif-xlate-cache.h b/ofproto/ofproto-dpif-xlate-cache.h index 0fc6d2ea6..fa707889d 100644 --- a/ofproto/ofproto-dpif-xlate-cache.h +++ b/ofproto/ofproto-dpif-xlate-cache.h @@ -29,6 +29,7 @@ struct bfd; struct bond; struct dpif_flow_stats; +struct dpif_psample; struct flow; struct group_dpif; struct mbridge; @@ -53,6 +54,7 @@ enum xc_type { XC_GROUP, XC_TNL_NEIGH, XC_TUNNEL_HEADER, + XC_PSAMPLE, }; /* xlate_cache entries hold enough information to perform the side effects of @@ -126,6 +128,10 @@ struct xc_entry { } operation; uint16_t hdr_size; } tunnel_hdr; + struct { + struct dpif_psample *psample; + uint32_t collector_set_id; + } psample; }; }; diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 1dcf86856..a9856e358 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -5989,6 +5989,15 @@ xlate_sample_action(struct xlate_ctx *ctx, sizeof(os->obs_domain_id)); ofpbuf_put(&psample_args->cookie, &os->obs_point_id, sizeof(os->obs_point_id)); + + if (ctx->xin->xcache) { + struct xc_entry *entry; + + entry = xlate_cache_add_entry(ctx->xin->xcache, XC_PSAMPLE); + entry->psample.psample = dpif_psample_ref(psample); + entry->psample.collector_set_id = os->collector_set_id; + } + } } diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 64c06322e..f1efdd482 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -5167,6 +5167,7 @@ ofproto_dpif_xcache_execute(struct ofproto_dpif *ofproto, case XC_GROUP: case XC_TNL_NEIGH: case XC_TUNNEL_HEADER: + case XC_PSAMPLE: xlate_push_stats_entry(entry, stats, false); break; default: From patchwork Wed Apr 24 19:53:36 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: 1927354 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=f5LnQNva; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VPqSy3BZMz1yP2 for ; Thu, 25 Apr 2024 05:54:42 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id B2F1A82660; Wed, 24 Apr 2024 19:54:40 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 0MVZCYjjPrST; Wed, 24 Apr 2024 19:54:38 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 654BA824A4 Authentication-Results: smtp1.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=f5LnQNva Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id 654BA824A4; Wed, 24 Apr 2024 19:54:25 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 019D6C0077; Wed, 24 Apr 2024 19:54:25 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0DA2AC0077 for ; Wed, 24 Apr 2024 19:54:23 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 2633F417B0 for ; Wed, 24 Apr 2024 19:54:08 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id RxOJmGm1IBb7 for ; Wed, 24 Apr 2024 19:54:06 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp2.osuosl.org 4ED974181C Authentication-Results: smtp2.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 4ED974181C Authentication-Results: smtp2.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=f5LnQNva Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp2.osuosl.org (Postfix) with ESMTPS id 4ED974181C for ; Wed, 24 Apr 2024 19:54:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713988444; 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=8r5ZipTVDR1826WALrLWImBLulhYf+f/tQ1YTO92eQI=; b=f5LnQNvatKrFHLK073sJdpwt78C0JtG7VNXyvyX47k6S7jgFlYyUrg4uRRPFQEKBoNMhZv UYrjvxTrTsvCiZNZUjEnmRroKVjgxqGcaVuJHz0YZrNT29/WIrI+j4Xv7rHhS3tPkyoUjE Bv+em+W1nrQ4+2dm0Ih6aNCRX0AQLGc= 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-472-syLQaQ3gPNKn92YFtDdOXw-1; Wed, 24 Apr 2024 15:54:00 -0400 X-MC-Unique: syLQaQ3gPNKn92YFtDdOXw-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (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 613BF29AA38F; Wed, 24 Apr 2024 19:54:00 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 13BEE2031A45; Wed, 24 Apr 2024 19:53:58 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Wed, 24 Apr 2024 21:53:36 +0200 Message-ID: <20240424195337.3596657-11-amorenoz@redhat.com> In-Reply-To: <20240424195337.3596657-1-amorenoz@redhat.com> References: <20240424195337.3596657-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: dceara@redhat.com, i.maximets@ovn.org, horms@kernel.org Subject: [ovs-dev] [RFC 10/11] ofproto-dpif-psample: Add command to show stats. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Adrian Moreno --- ofproto/ofproto-dpif-psample.c | 59 ++++++++++++++++++++++++++++++++++ ofproto/ofproto-dpif-psample.h | 1 + ofproto/ofproto-dpif.c | 1 + 3 files changed, 61 insertions(+) diff --git a/ofproto/ofproto-dpif-psample.c b/ofproto/ofproto-dpif-psample.c index ea4926eb2..2d73a4ded 100644 --- a/ofproto/ofproto-dpif-psample.c +++ b/ofproto/ofproto-dpif-psample.c @@ -20,9 +20,12 @@ #include "dpif.h" #include "hash.h" #include "ofproto.h" +#include "ofproto-dpif.h" +#include "openvswitch/dynamic-string.h" #include "openvswitch/hmap.h" #include "openvswitch/thread.h" #include "openvswitch/vlog.h" +#include "unixctl.h" VLOG_DEFINE_THIS_MODULE(psample); @@ -205,3 +208,59 @@ dpif_psample_unref(struct dpif_psample *ps) OVS_EXCLUDED(mutex) dpif_psample_destroy(ps); } } + +/* Unix commands. */ +static void +psample_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) +{ + struct psample_exporter_map_node *node; + struct ds ds = DS_EMPTY_INITIALIZER; + const struct ofproto_dpif *ofproto; + bool first = true; + + ofproto = ofproto_dpif_lookup_by_name(argv[1]); + if (!ofproto) { + unixctl_command_reply_error(conn, "no such bridge"); + return; + } + + if (!ofproto->psample) { + unixctl_command_reply_error(conn, "no psample exporters configured"); + return; + } + + ds_put_format(&ds, "Psample statistics for bridge \"%s\":\n", argv[1]); + + ovs_mutex_lock(&mutex); + HMAP_FOR_EACH (node, node, &ofproto->psample->exporters_map) { + if (!first) { + ds_put_cstr(&ds, "\n"); + } else { + first = false; + } + + ds_put_format(&ds, "- Collector Set ID: %"PRIu32"\n", + node->exporter.collector_set_id); + ds_put_format(&ds, " Psample Group ID: %"PRIu32"\n", + node->exporter.group_id); + ds_put_format(&ds, " Total number of bytes: %"PRIu64"\n", + node->exporter.n_bytes); + ds_put_format(&ds, " Total number of packets: %"PRIu64"\n", + node->exporter.n_packets); + } + ovs_mutex_unlock(&mutex); + + unixctl_command_reply(conn, ds_cstr(&ds)); + ds_destroy(&ds); +} + +void dpif_psample_init(void) +{ + static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; + if (ovsthread_once_start(&once)) { + unixctl_command_register("psample/show", "bridge", 1, 1, + psample_unixctl_show, NULL); + ovsthread_once_done(&once); + } +} diff --git a/ofproto/ofproto-dpif-psample.h b/ofproto/ofproto-dpif-psample.h index 763fbd30b..f264ad4c2 100644 --- a/ofproto/ofproto-dpif-psample.h +++ b/ofproto/ofproto-dpif-psample.h @@ -34,5 +34,6 @@ bool dpif_psample_get_group_id(struct dpif_psample *, uint32_t, uint32_t *); void dpif_psample_credit_stats(struct dpif_psample *, uint32_t, const struct dpif_flow_stats *); +void dpif_psample_init(void); #endif // OFPROTO_DPIF_PSAMPLE_H diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index f1efdd482..ebb399307 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -287,6 +287,7 @@ init(const struct shash *iface_hints) ofproto_unixctl_init(); ofproto_dpif_trace_init(); udpif_init(); + dpif_psample_init(); } static void From patchwork Wed Apr 24 19:53:37 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: 1927352 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=PxkGonXZ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VPqSm41HNz1yP2 for ; Thu, 25 Apr 2024 05:54:32 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id C2C254151D; Wed, 24 Apr 2024 19:54:30 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id jPc3czbEHtIK; Wed, 24 Apr 2024 19:54:25 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org D9D5B41581 Authentication-Results: smtp4.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=PxkGonXZ Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTPS id D9D5B41581; Wed, 24 Apr 2024 19:54:18 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 1422EC0DD7; Wed, 24 Apr 2024 19:54:18 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 362E0C008E for ; Wed, 24 Apr 2024 19:54:15 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 8646041825 for ; Wed, 24 Apr 2024 19:54:06 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id WlOXkL0XnZxd for ; Wed, 24 Apr 2024 19:54:05 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp2.osuosl.org 245DC41792 Authentication-Results: smtp2.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 245DC41792 Authentication-Results: smtp2.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=PxkGonXZ Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp2.osuosl.org (Postfix) with ESMTPS id 245DC41792 for ; Wed, 24 Apr 2024 19:54:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713988443; 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=6TpBzhp+7Cca2F10Ie4quz37iVG6VUotNLwTIXEUyk8=; b=PxkGonXZRgzzPV8+y/iT4mOnHtSjvf/xJuty3hR6nLMZwHFMn3bT0coHP/Bo+Y+Gb1myRv JxO7EZcFrJHgLundUCR1SgFAftWFnYGktTCmDxIVF/ZhYI0I6AO2IcmOSGIF65OocTbgpG MM6shEpQxfAZ/h82jcVkKRZ2LlNpZWc= 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-222-8Wa-OOFkPMaszp7OKe3nJA-1; Wed, 24 Apr 2024 15:54:02 -0400 X-MC-Unique: 8Wa-OOFkPMaszp7OKe3nJA-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (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 E5AAF3806703; Wed, 24 Apr 2024 19:54:01 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.193.98]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9D856200AE7F; Wed, 24 Apr 2024 19:54:00 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Wed, 24 Apr 2024 21:53:37 +0200 Message-ID: <20240424195337.3596657-12-amorenoz@redhat.com> In-Reply-To: <20240424195337.3596657-1-amorenoz@redhat.com> References: <20240424195337.3596657-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: dceara@redhat.com, i.maximets@ovn.org, horms@kernel.org Subject: [ovs-dev] [RFC 11/11] tests: Add test for sample offloading. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Adrian Moreno --- tests/system-common-macros.at | 4 +++ tests/system-offloads-traffic.at | 53 ++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/tests/system-common-macros.at b/tests/system-common-macros.at index 2a68cd664..860d6a8c9 100644 --- a/tests/system-common-macros.at +++ b/tests/system-common-macros.at @@ -378,3 +378,7 @@ m4_define([OVS_CHECK_GITHUB_ACTION], # OVS_CHECK_DROP_ACTION() m4_define([OVS_CHECK_DROP_ACTION], [AT_SKIP_IF([! grep -q "Datapath supports explicit drop action" ovs-vswitchd.log])]) + +# OVS_CHECK_PSAMPLE() +m4_define([OVS_CHECK_PSAMPLE], + [AT_SKIP_IF([! grep -q "Datapath supports psample" ovs-vswitchd.log])]) diff --git a/tests/system-offloads-traffic.at b/tests/system-offloads-traffic.at index d1da33d96..f4d0ccab5 100644 --- a/tests/system-offloads-traffic.at +++ b/tests/system-offloads-traffic.at @@ -933,3 +933,56 @@ OVS_WAIT_UNTIL([grep -q "Datapath does not support explicit drop action" ovs-vsw OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP + + +AT_SETUP([offloads - sample action]) +OVS_TRAFFIC_VSWITCHD_START([], [], [-- set Open_vSwitch . other_config:hw-offload=true]) +OVS_CHECK_PSAMPLE() + +ADD_NAMESPACES(at_ns0, at_ns1) + +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") + +# Choosing numbers whose hex representation is the same for big and little endian. +AT_DATA([flows.txt], [dnl +arp action=NORMAL +in_port=ovs-p0 actions=sample(probability=65535,collector_set_id=1,obs_domain_id=1431655765,obs_point_id=1717986918),NORMAL +in_port=ovs-p1 actions=sample(probability=65535,collector_set_id=2,obs_domain_id=2290649224,obs_point_id=2576980377),NORMAL +]) + +AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) + +AT_CHECK([ovs-vsctl --id=@br get Bridge br0 \ + -- create FLow_Sample_Collector_Set bridge=@br id=1 psample_group=10 \ + -- create FLow_Sample_Collector_Set bridge=@br id=2 psample_group=12], + [0], [ignore]) + +OVS_DAEMONIZE([ovs-psample > psample.out], [psample.pid]) +on_exit 'kill `cat psample.pid`' +sleep 1 + +NS_CHECK_EXEC([at_ns0], [ping -q -c 10 -i 0.1 -W 2 10.1.1.2 | FORMAT_PING], [0], [dnl +10 packets transmitted, 10 received, 0% packet loss, time 0ms +]) + +AT_CHECK([ovs-appctl dpctl/dump-flows | grep "eth_type(0x0800)" | DUMP_CLEAN_SORTED], [0], [dnl +in_port(2),eth(macs),eth_type(0x0800),ipv4(frag=no), packets:9, bytes:756, used:0.001s, actions:sample(sample=100.0%,group_id=10,cookie=5555555566666666),3 +in_port(3),eth(macs),eth_type(0x0800),ipv4(frag=no), packets:9, bytes:756, used:0.001s, actions:sample(sample=100.0%,group_id=12,cookie=8888888899999999),2 +]) + +AT_CHECK([ovs-appctl dpctl/dump-flows type=ovs | grep "eth_type(0x0800)" | DUMP_CLEAN_SORTED], [0], []) + +AT_CHECK([ovs-appctl dpctl/dump-flows type=tc,offloaded | grep "eth_type(0x0800)" | DUMP_CLEAN_SORTED], [0], [dnl +in_port(2),eth(macs),eth_type(0x0800),ipv4(frag=no), packets:9, bytes:756, used:0.001s, actions:sample(sample=100.0%,group_id=10,cookie=5555555566666666),3 +in_port(3),eth(macs),eth_type(0x0800),ipv4(frag=no), packets:9, bytes:756, used:0.001s, actions:sample(sample=100.0%,group_id=12,cookie=8888888899999999),2 +]) + +AT_CHECK([ovs-appctl upcall/show | grep -E "offloaded flows : [[1-9]]"], [0], [ignore]) + +AT_CHECK([grep -E "group_id=0xa obs_domain=0x55555555,obs_point=0x66666666 .*icmp.*nw_src=10.1.1.1,nw_dst=10.1.1.2" psample.out >/dev/null]) +AT_CHECK([grep -E "group_id=0xc obs_domain=0x88888888,obs_point=0x99999999 .*icmp.*nw_src=10.1.1.2,nw_dst=10.1.1.1" psample.out >/dev/null]) + +OVS_TRAFFIC_VSWITCHD_STOP +AT_CLEANUP +