From patchwork Thu Nov 16 15:08:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ales Musil X-Patchwork-Id: 1864786 X-Patchwork-Delegate: i.maximets@samsung.com 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=Tqv8Fh5Q; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::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 4SWNjH2nLWz1yRV for ; Fri, 17 Nov 2023 02:09:07 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 4C94341A3B; Thu, 16 Nov 2023 15:09:05 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 4C94341A3B 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=Tqv8Fh5Q X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id bG2gHPfr-Mxh; Thu, 16 Nov 2023 15:09:03 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp2.osuosl.org (Postfix) with ESMTPS id C107D400E7; Thu, 16 Nov 2023 15:09:02 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org C107D400E7 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id A077DC0071; Thu, 16 Nov 2023 15:09: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 10520C0032 for ; Thu, 16 Nov 2023 15:09:01 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id D284382162 for ; Thu, 16 Nov 2023 15:09:00 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org D284382162 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=Tqv8Fh5Q X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id KGCc3_1rDWGM for ; Thu, 16 Nov 2023 15:09:00 +0000 (UTC) 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 F00F882158 for ; Thu, 16 Nov 2023 15:08:59 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org F00F882158 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1700147338; 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=HokqQmpObZruPQo8WDd/PTdrZ3VEriLqwXFLEHk0VNI=; b=Tqv8Fh5Q1cy+lqSAZCtDAfwM7Y88jE4QSkv5rdY9ZEZ/QVpW4mr3D3+c1MfjH7bdiylUZ0 S1yoDxHj9alg0h8DFGyF63U+HuNBCAYcKZAN/gHaTFiWuWQxt8iRiBEP7zDy42gagUmFyB 7kWNgzmqdgb6lDj/Wwo+Au5bnvIuVMQ= 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-383-Wt-41T6SM0y1arlIa7axFQ-1; Thu, 16 Nov 2023 10:08:54 -0500 X-MC-Unique: Wt-41T6SM0y1arlIa7axFQ-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 4628D857BDE; Thu, 16 Nov 2023 15:08:33 +0000 (UTC) Received: from amusil.redhat.com (unknown [10.45.224.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1ED9F2026D66; Thu, 16 Nov 2023 15:08:31 +0000 (UTC) From: Ales Musil To: dev@openvswitch.org Date: Thu, 16 Nov 2023 16:08:26 +0100 Message-ID: <20231116150828.115226-2-amusil@redhat.com> In-Reply-To: <20231116150828.115226-1-amusil@redhat.com> References: <20231116150828.115226-1-amusil@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: i.maximets@ovn.org, dceara@redhat.com Subject: [ovs-dev] [PATCH v4 1/3] ofp-prop: Add helper for parsing and storing of ovs_u128. 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 helper methods that allow us to store and parse the ovs_u128 type. Signed-off-by: Ales Musil --- v4: Rebase on top of current master. Use ofprop_put instead of manual ofpbuf_start/put/end. v3: Rebase on top of current master. v2: Add missing ofpprop_parse_be128() function. --- include/openvswitch/ofp-prop.h | 5 ++++ lib/ofp-prop.c | 42 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/openvswitch/ofp-prop.h b/include/openvswitch/ofp-prop.h index e676f8dc0..451f5dae2 100644 --- a/include/openvswitch/ofp-prop.h +++ b/include/openvswitch/ofp-prop.h @@ -84,10 +84,13 @@ enum ofperr ofpprop_pull(struct ofpbuf *msg, struct ofpbuf *property, enum ofperr ofpprop_parse_be16(const struct ofpbuf *, ovs_be16 *value); enum ofperr ofpprop_parse_be32(const struct ofpbuf *, ovs_be32 *value); enum ofperr ofpprop_parse_be64(const struct ofpbuf *, ovs_be64 *value); +enum ofperr ofpprop_parse_be128(const struct ofpbuf *property, + ovs_be128 *value); enum ofperr ofpprop_parse_u8(const struct ofpbuf *, uint8_t *value); enum ofperr ofpprop_parse_u16(const struct ofpbuf *, uint16_t *value); enum ofperr ofpprop_parse_u32(const struct ofpbuf *, uint32_t *value); enum ofperr ofpprop_parse_u64(const struct ofpbuf *, uint64_t *value); +enum ofperr ofpprop_parse_u128(const struct ofpbuf *, ovs_u128 *value); enum ofperr ofpprop_parse_uuid(const struct ofpbuf *, struct uuid *); enum ofperr ofpprop_parse_nested(const struct ofpbuf *, struct ofpbuf *); @@ -98,10 +101,12 @@ void *ofpprop_put_zeros(struct ofpbuf *, uint64_t type, size_t len); void ofpprop_put_be16(struct ofpbuf *, uint64_t type, ovs_be16 value); void ofpprop_put_be32(struct ofpbuf *, uint64_t type, ovs_be32 value); void ofpprop_put_be64(struct ofpbuf *, uint64_t type, ovs_be64 value); +void ofpprop_put_be128(struct ofpbuf *, uint64_t type, ovs_be128 value); void ofpprop_put_u8(struct ofpbuf *, uint64_t type, uint8_t value); void ofpprop_put_u16(struct ofpbuf *, uint64_t type, uint16_t value); void ofpprop_put_u32(struct ofpbuf *, uint64_t type, uint32_t value); void ofpprop_put_u64(struct ofpbuf *, uint64_t type, uint64_t value); +void ofpprop_put_u128(struct ofpbuf *, uint64_t type, ovs_u128 value); void ofpprop_put_bitmap(struct ofpbuf *, uint64_t type, uint64_t bitmap); void ofpprop_put_flag(struct ofpbuf *, uint64_t type); void ofpprop_put_uuid(struct ofpbuf *, uint64_t type, const struct uuid *); diff --git a/lib/ofp-prop.c b/lib/ofp-prop.c index 8b2d8a85a..2e323a08e 100644 --- a/lib/ofp-prop.c +++ b/lib/ofp-prop.c @@ -184,6 +184,20 @@ ofpprop_parse_be64(const struct ofpbuf *property, ovs_be64 *value) return 0; } +/* Attempts to parse 'property' as a property containing a 128-bit value. If + * successful, stores the value into '*value' and returns 0; otherwise returns + * an OpenFlow error. */ +enum ofperr +ofpprop_parse_be128(const struct ofpbuf *property, ovs_be128 *value) +{ + ovs_be128 *p = property->msg; + if (ofpbuf_msgsize(property) != sizeof *p) { + return OFPERR_OFPBPC_BAD_LEN; + } + *value = *p; + return 0; +} + /* Attempts to parse 'property' as a property containing a 8-bit value. If * successful, stores the value into '*value' and returns 0; otherwise returns * an OpenFlow error. */ @@ -250,6 +264,20 @@ ofpprop_parse_u64(const struct ofpbuf *property, uint64_t *value) return 0; } +/* Attempts to parse 'property' as a property containing a 128-bit value. If + * successful, stores the value into '*value' and returns 0; otherwise returns + * an OpenFlow error. */ +enum ofperr +ofpprop_parse_u128(const struct ofpbuf *property, ovs_u128 *value) +{ + ovs_be128 *p = property->msg; + if (ofpbuf_msgsize(property) != sizeof *p) { + return OFPERR_OFPBPC_BAD_LEN; + } + *value = ntoh128(*p); + return 0; +} + /* Attempts to parse 'property' as a property containing a UUID. If * successful, stores the value into '*uuid' and returns 0; otherwise returns * an OpenFlow error. */ @@ -351,6 +379,13 @@ ofpprop_put_be64(struct ofpbuf *msg, uint64_t type, ovs_be64 value) ofpprop_end(msg, start); } +/* Adds a property with the given 'type' and 128-bit 'value' to 'msg'. */ +void +ofpprop_put_be128(struct ofpbuf *msg, uint64_t type, ovs_be128 value) +{ + ofpprop_put(msg, type, &value, sizeof value); +} + /* Adds a property with the given 'type' and 8-bit 'value' to 'msg'. */ void ofpprop_put_u8(struct ofpbuf *msg, uint64_t type, uint8_t value) @@ -381,6 +416,13 @@ ofpprop_put_u64(struct ofpbuf *msg, uint64_t type, uint64_t value) ofpprop_put_be64(msg, type, htonll(value)); } +/* Adds a property with the given 'type' and 64-bit 'value' to 'msg'. */ +void +ofpprop_put_u128(struct ofpbuf *msg, uint64_t type, ovs_u128 value) +{ + ofpprop_put_be128(msg, type, hton128(value)); +} + /* Appends a property to 'msg' whose type is 'type' and whose contents is a * series of property headers, one for each 1-bit in 'bitmap'. */ void From patchwork Thu Nov 16 15:08:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ales Musil X-Patchwork-Id: 1864787 X-Patchwork-Delegate: i.maximets@samsung.com 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=COuzevwz; 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 4SWNjN1kXfz1yRV for ; Fri, 17 Nov 2023 02:09:12 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id BC2376FAB2; Thu, 16 Nov 2023 15:09:09 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org BC2376FAB2 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=COuzevwz X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NIJmaGKojSwQ; Thu, 16 Nov 2023 15:09:08 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTPS id 748266FABE; Thu, 16 Nov 2023 15:09:07 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 748266FABE Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 4D09AC0DD7; Thu, 16 Nov 2023 15:09:06 +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 D85F0C0071 for ; Thu, 16 Nov 2023 15:09:04 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id A6EFF6FAB1 for ; Thu, 16 Nov 2023 15:09:04 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org A6EFF6FAB1 X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id oaz4aXjV091L for ; Thu, 16 Nov 2023 15:09:03 +0000 (UTC) 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 A00CC6FAAB for ; Thu, 16 Nov 2023 15:09:03 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org A00CC6FAAB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1700147342; 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=SJKeAQObSH/w17/jC97sZ2jhMJik6aINOIqZC/3VHm8=; b=COuzevwzHs7yGA1ir1IQUXHMK7ZchhstoTLIcZiL/F879lvbSE44Jzj4VwkHC7BJHpWQht kq6mUBlqJaWEZ4ndTRDv1kagw77vczBsakb6RTv1wa9/RB0RkiUrjIBLzJC1mj7e4Jyr7u YYzFNBex4m6cU3ovgdZcnZi1clxtzqw= 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-GYaM-cjYOIWl0RtIEHOkiQ-1; Thu, 16 Nov 2023 10:08:59 -0500 X-MC-Unique: GYaM-cjYOIWl0RtIEHOkiQ-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 3AB6885268E; Thu, 16 Nov 2023 15:08:42 +0000 (UTC) Received: from amusil.redhat.com (unknown [10.45.224.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 89DBC2026D66; Thu, 16 Nov 2023 15:08:34 +0000 (UTC) From: Ales Musil To: dev@openvswitch.org Date: Thu, 16 Nov 2023 16:08:27 +0100 Message-ID: <20231116150828.115226-3-amusil@redhat.com> In-Reply-To: <20231116150828.115226-1-amusil@redhat.com> References: <20231116150828.115226-1-amusil@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: i.maximets@ovn.org, dceara@redhat.com Subject: [ovs-dev] [PATCH v4 2/3] dpctl, ovs-ofctl: Unify parsing of ct-flush arguments. 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 order to make the command extensible unify the arguments parsing into single function. This will be later on used for the mark and labels arguments. Signed-off-by: Ales Musil --- v4: Rebase on top of current master. v3: Rebase on top of current master. Fix the system-tests failure. --- include/openvswitch/ofp-ct.h | 5 ++-- lib/dpctl.c | 41 ++++--------------------------- lib/ofp-ct.c | 47 +++++++++++++++++++++++++++++++++++- tests/system-traffic.at | 2 +- utilities/ovs-ofctl.c | 37 ++++++---------------------- 5 files changed, 62 insertions(+), 70 deletions(-) diff --git a/include/openvswitch/ofp-ct.h b/include/openvswitch/ofp-ct.h index c8023c309..cd6192e6f 100644 --- a/include/openvswitch/ofp-ct.h +++ b/include/openvswitch/ofp-ct.h @@ -58,8 +58,9 @@ bool ofp_ct_tuple_is_zero(const struct ofp_ct_tuple *, uint8_t ip_proto); bool ofp_ct_tuple_is_five_tuple(const struct ofp_ct_tuple *, uint8_t ip_proto); void ofp_ct_match_format(struct ds *, const struct ofp_ct_match *); -bool ofp_ct_tuple_parse(struct ofp_ct_tuple *, const char *, - struct ds *, uint8_t *ip_proto, uint16_t *l3_type); +bool ofp_ct_match_parse(const char **, int argc, struct ds *, + struct ofp_ct_match *, bool *with_zone, + uint16_t *zone_id); enum ofperr ofp_ct_match_decode(struct ofp_ct_match *, bool *with_zone, uint16_t *zone_id, const struct ofp_header *); diff --git a/lib/dpctl.c b/lib/dpctl.c index cd12625a1..bbab5881e 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -1773,48 +1773,17 @@ dpctl_flush_conntrack(int argc, const char *argv[], struct dpif *dpif = NULL; struct ofp_ct_match match = {0}; struct ds ds = DS_EMPTY_INITIALIZER; - uint16_t zone, *pzone = NULL; + uint16_t zone; int error; int args = argc - 1; - int zone_pos = 1; + bool with_zone = false; if (dp_arg_exists(argc, argv)) { args--; - zone_pos = 2; - } - - /* Parse zone. */ - if (args && !strncmp(argv[zone_pos], "zone=", 5)) { - if (!ovs_scan(argv[zone_pos], "zone=%"SCNu16, &zone)) { - ds_put_cstr(&ds, "failed to parse zone"); - error = EINVAL; - goto error; - } - pzone = &zone; - args--; - } - - /* Parse ct tuples. */ - for (int i = 0; i < 2; i++) { - if (!args) { - break; - } - - struct ofp_ct_tuple *tuple = - i ? &match.tuple_reply : &match.tuple_orig; - const char *arg = argv[argc - args]; - - if (arg[0] && !ofp_ct_tuple_parse(tuple, arg, &ds, &match.ip_proto, - &match.l3_type)) { - error = EINVAL; - goto error; - } - args--; } - /* Report error if there is more than one unparsed argument. */ - if (args > 0) { - ds_put_cstr(&ds, "invalid arguments"); + if (args && !ofp_ct_match_parse(&argv[argc - args], args, &ds, &match, + &with_zone, &zone)) { error = EINVAL; goto error; } @@ -1825,7 +1794,7 @@ dpctl_flush_conntrack(int argc, const char *argv[], return error; } - error = ct_dpif_flush(dpif, pzone, &match); + error = ct_dpif_flush(dpif, with_zone ? &zone : NULL, &match); if (!error) { dpif_close(dpif); return 0; diff --git a/lib/ofp-ct.c b/lib/ofp-ct.c index 85a9d8bec..32aeb5455 100644 --- a/lib/ofp-ct.c +++ b/lib/ofp-ct.c @@ -98,7 +98,7 @@ ofp_ct_match_format(struct ds *ds, const struct ofp_ct_match *match) /* Parses a specification of a conntrack 5-tuple from 's' into 'tuple'. * Returns true on success. Otherwise, returns false and puts the error * message in 'ds'. */ -bool +static bool ofp_ct_tuple_parse(struct ofp_ct_tuple *tuple, const char *s, struct ds *ds, uint8_t *ip_proto, uint16_t *l3_type) { @@ -216,6 +216,51 @@ error: return false; } +/* Parses a specification of a conntrack match from 'argv' into 'match'. + * Returns true on success. Otherwise, returns false and puts the error + * message in 'ds'. */ +bool +ofp_ct_match_parse(const char **argv, int argc, struct ds *ds, + struct ofp_ct_match *match, bool *with_zone, + uint16_t *zone_id) +{ + int args = argc; + + /* Parse zone. */ + if (args && !strncmp(argv[argc - args], "zone=", 5)) { + if (!ovs_scan(argv[argc - args], "zone=%"SCNu16, zone_id)) { + ds_put_cstr(ds, "failed to parse zone"); + return false; + } + *with_zone = true; + args--; + } + + /* Parse ct tuples. */ + for (int i = 0; i < 2; i++) { + if (!args) { + break; + } + + struct ofp_ct_tuple *tuple = + i ? &match->tuple_reply : &match->tuple_orig; + const char *arg = argv[argc - args]; + + if (arg[0] && !ofp_ct_tuple_parse(tuple, arg, ds, &match->ip_proto, + &match->l3_type)) { + return false; + } + args--; + } + + if (args > 0) { + ds_put_cstr(ds, "invalid arguments"); + return false; + } + + return true; +} + static enum ofperr ofpprop_pull_ipv6(struct ofpbuf *property, struct in6_addr *addr, uint16_t *l3_type) diff --git a/tests/system-traffic.at b/tests/system-traffic.at index 7ea450202..33a5d600f 100644 --- a/tests/system-traffic.at +++ b/tests/system-traffic.at @@ -2737,7 +2737,7 @@ AT_CHECK([ovs-ofctl ct-flush br0 zone=1 'ct_nw_src=10.1.1.1' 'ct_nw_dst=10.1.1.1 AT_CHECK([grep -q "command takes at most 4 arguments" stderr]) AT_CHECK([ovs-ofctl ct-flush br0 'ct_nw_src=10.1.1.1' 'ct_nw_dst=10.1.1.1' invalid], [1], [ignore], [stderr]) -AT_CHECK([grep -q "Invalid arguments" stderr]) +AT_CHECK([grep -q "invalid arguments" stderr]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 24d0941cf..79d42dd0b 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -3060,42 +3060,19 @@ ofctl_ct_flush(struct ovs_cmdl_context *ctx) struct vconn *vconn; struct ofp_ct_match match = {0}; struct ds ds = DS_EMPTY_INITIALIZER; - uint16_t zone, *pzone = NULL; + uint16_t zone; int args = ctx->argc - 2; + bool with_zone = false; - /* Parse zone. */ - if (args && !strncmp(ctx->argv[2], "zone=", 5)) { - if (!ovs_scan(ctx->argv[2], "zone=%"SCNu16, &zone)) { - ovs_fatal(0, "Failed to parse zone"); - } - pzone = &zone; - args--; - } - - /* Parse ct tuples. */ - for (int i = 0; i < 2; i++) { - if (!args) { - break; - } - - struct ofp_ct_tuple *tuple = - i ? &match.tuple_reply : &match.tuple_orig; - const char *arg = ctx->argv[ctx->argc - args]; - - if (arg[0] && !ofp_ct_tuple_parse(tuple, arg, &ds, &match.ip_proto, - &match.l3_type)) { - ovs_fatal(0, "Failed to parse ct-tuple: %s", ds_cstr(&ds)); - } - args--; - } - - if (args > 0) { - ovs_fatal(0, "Invalid arguments"); + if (args && !ofp_ct_match_parse((const char **) &ctx->argv[2], + args, &ds, &match, &with_zone, &zone)) { + ovs_fatal(0, "Failed to parse CT match: %s", ds_cstr(&ds)); } open_vconn(ctx->argv[1], &vconn); enum ofp_version version = vconn_get_version(vconn); - struct ofpbuf *msg = ofp_ct_match_encode(&match, pzone, version); + struct ofpbuf *msg = + ofp_ct_match_encode(&match, with_zone ? &zone : NULL, version); ds_destroy(&ds); transact_noreply(vconn, msg); From patchwork Thu Nov 16 15:08:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ales Musil X-Patchwork-Id: 1864789 X-Patchwork-Delegate: i.maximets@samsung.com 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=YRkDVCIV; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.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 4SWNjV0Vc3z1yRV for ; Fri, 17 Nov 2023 02:09:18 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id B929F6FAE0; Thu, 16 Nov 2023 15:09:14 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org B929F6FAE0 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=YRkDVCIV X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DPcBAg315Zea; Thu, 16 Nov 2023 15:09:11 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTPS id 43F2E6FABE; Thu, 16 Nov 2023 15:09:10 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 43F2E6FABE Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0F1C5C0071; Thu, 16 Nov 2023 15:09:10 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 51172C0071 for ; Thu, 16 Nov 2023 15:09:08 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 297196FACA for ; Thu, 16 Nov 2023 15:09:08 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 297196FACA X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Y3nLZNuuaZTv for ; Thu, 16 Nov 2023 15:09:05 +0000 (UTC) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp3.osuosl.org (Postfix) with ESMTPS id 0C95B6FAB1 for ; Thu, 16 Nov 2023 15:09:04 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 0C95B6FAB1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1700147344; 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=I8eRQp1AZHv2Kb9CXzIKXavk1hfcFfoOttiaBXaeokE=; b=YRkDVCIV+zasPElwXpOd+Nb45NdeunmXF4AuAIuWFs273h+j2UT6YXWIrnP1J/7gX7DobC rZfzfwpPlhPzcSsZFOXsB2G2gyPWZqSV0AfFpRLKlF7GNXgoo4du1w25LYywUq2RfYDs70 +ODmlvFqey46bFbD7fsQHDF2lUdFd1k= 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-78-dif2B8xPNYqfxq1S6SLG1g-1; Thu, 16 Nov 2023 10:09:01 -0500 X-MC-Unique: dif2B8xPNYqfxq1S6SLG1g-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 D998783DE14; Thu, 16 Nov 2023 15:08:46 +0000 (UTC) Received: from amusil.redhat.com (unknown [10.45.224.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7227520268C8; Thu, 16 Nov 2023 15:08:45 +0000 (UTC) From: Ales Musil To: dev@openvswitch.org Date: Thu, 16 Nov 2023 16:08:28 +0100 Message-ID: <20231116150828.115226-4-amusil@redhat.com> In-Reply-To: <20231116150828.115226-1-amusil@redhat.com> References: <20231116150828.115226-1-amusil@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: i.maximets@ovn.org, dceara@redhat.com Subject: [ovs-dev] [PATCH v4 3/3] openflow: Allow CT flush to match on mark and labels. 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" Extend the current NX_CT_FLUSH with four additional fields, that allow to match on CT entry "mark" or "labels". This is encoded as separate TLV values which is backward compatible. Versions that do not support them will simply ignore it. Extend also the ovs-dpctl and ovs-ofctl command line tools with option to specify those two matching parameters for the "ct-flush" command. Reported-at: https://issues.redhat.com/browse/FDP-55 Signed-off-by: Ales Musil --- v4: Rebase on top of current master. Address comments from Ilya: - Add NEWs entry. - Adjust the flags to use unsigned int. - Make the encode function more user-friendly. - Adjust the tests. v3: Rebase on top of current master. v2: Make sure that the mask decoding matches the dpctl/ovs-ofctl interface. --- NEWS | 4 + include/openflow/nicira-ext.h | 4 + include/openvswitch/ofp-ct.h | 9 ++- lib/ct-dpif.c | 12 ++- lib/dpctl.c | 5 +- lib/ofp-ct.c | 135 +++++++++++++++++++++++++++++++++- tests/ofp-print.at | 85 +++++++++++++++++++++ tests/ovs-ofctl.at | 42 ++++++++++- tests/system-traffic.at | 112 ++++++++++++++++++---------- utilities/ovs-ofctl.8.in | 31 ++++---- utilities/ovs-ofctl.c | 12 +-- 11 files changed, 381 insertions(+), 70 deletions(-) diff --git a/NEWS b/NEWS index 43aea97b5..528c8b0a1 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ Post-v3.2.0 from older version is supported but it may trigger more leader elections during the process, and error logs complaining unrecognized fields may be observed on old nodes. +<<<<<<< HEAD - ovs-appctl: * Output of 'dpctl/show' command no longer shows interface configuration status, only values of the actual configuration options, a.k.a. @@ -13,6 +14,9 @@ Post-v3.2.0 a.k.a. 'configured' values, can be found in the 'status' column of the Interface table, i.e. with 'ovs-vsctl get interface <..> status'. Reported names adjusted accordingly. + - OpenFlow: + * Extended the NXT_CT_FLUSH to support matching on CT label and mark + fields. v3.2.0 - 17 Aug 2023 diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h index 768775898..959845ce6 100644 --- a/include/openflow/nicira-ext.h +++ b/include/openflow/nicira-ext.h @@ -1075,6 +1075,10 @@ enum nx_ct_flush_tlv_type { * by 'enum nx_ct_flush_tuple_tlv_type'*/ /* Primitive types. */ NXT_CT_ZONE_ID = 2, /* be16 zone id. */ + NXT_CT_MARK = 3, /* be32 mark. */ + NXT_CT_MARK_MASK = 4, /* be32 mark mask. */ + NXT_CT_LABELS = 5, /* be128 labels. */ + NXT_CT_LABELS_MASK = 6, /* be128 labels mask. */ }; /* CT flush nested TLVs. */ diff --git a/include/openvswitch/ofp-ct.h b/include/openvswitch/ofp-ct.h index cd6192e6f..d57b62678 100644 --- a/include/openvswitch/ofp-ct.h +++ b/include/openvswitch/ofp-ct.h @@ -51,11 +51,16 @@ struct ofp_ct_match { struct ofp_ct_tuple tuple_orig; struct ofp_ct_tuple tuple_reply; + + uint32_t mark; + uint32_t mark_mask; + + ovs_u128 labels; + ovs_u128 labels_mask; }; bool ofp_ct_match_is_zero(const struct ofp_ct_match *); -bool ofp_ct_tuple_is_zero(const struct ofp_ct_tuple *, uint8_t ip_proto); -bool ofp_ct_tuple_is_five_tuple(const struct ofp_ct_tuple *, uint8_t ip_proto); +bool ofp_ct_match_is_five_tuple(const struct ofp_ct_match *); void ofp_ct_match_format(struct ds *, const struct ofp_ct_match *); bool ofp_ct_match_parse(const char **, int argc, struct ds *, diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c index f59c6e560..0fd14b99f 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -269,6 +269,15 @@ ct_dpif_entry_cmp(const struct ct_dpif_entry *entry, return false; } + if ((match->mark & match->mark_mask) != (entry->mark & match->mark_mask)) { + return false; + } + + if (!ovs_u128_equals(ovs_u128_and(match->labels, match->labels_mask), + ovs_u128_and(entry->labels, match->labels_mask))) { + return false; + } + return true; } @@ -295,8 +304,7 @@ ct_dpif_flush_tuple(struct dpif *dpif, const uint16_t *zone, /* If we have full five tuple in original and empty reply tuple just * do the flush over original tuple directly. */ - if (ofp_ct_tuple_is_five_tuple(&match->tuple_orig, match->ip_proto) && - ofp_ct_tuple_is_zero(&match->tuple_reply, match->ip_proto)) { + if (ofp_ct_match_is_five_tuple(match)) { struct ct_dpif_tuple tuple; ct_dpif_tuple_from_ofp_ct_tuple(&match->tuple_orig, &tuple, diff --git a/lib/dpctl.c b/lib/dpctl.c index bbab5881e..9d28a91ba 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -2981,8 +2981,9 @@ static const struct dpctl_command all_commands[] = { 0, 4, dpctl_dump_conntrack, DP_RO }, { "dump-conntrack-exp", "[dp] [zone=N]", 0, 2, dpctl_dump_conntrack_exp, DP_RO }, - { "flush-conntrack", "[dp] [zone=N] [ct-orig-tuple] [ct-reply-tuple]", - 0, 4, dpctl_flush_conntrack, DP_RW }, + { "flush-conntrack", "[dp] [zone=N] [mark=X[/M]] [labels=Y[/N]] " + "[ct-orig-tuple [ct-reply-tuple]]", + 0, 6, dpctl_flush_conntrack, DP_RW }, { "cache-get-size", "[dp]", 0, 1, dpctl_cache_get_size, DP_RO }, { "cache-set-size", "dp cache ", 3, 3, dpctl_cache_set_size, DP_RW }, { "ct-stats-show", "[dp] [zone=N]", diff --git a/lib/ofp-ct.c b/lib/ofp-ct.c index 32aeb5455..f9fb5e91a 100644 --- a/lib/ofp-ct.c +++ b/lib/ofp-ct.c @@ -50,7 +50,7 @@ ofp_ct_tuple_format(struct ds *ds, const struct ofp_ct_tuple *tuple, } } -bool +static bool ofp_ct_tuple_is_zero(const struct ofp_ct_tuple *tuple, uint8_t ip_proto) { bool is_zero = ipv6_is_zero(&tuple->src) && ipv6_is_zero(&tuple->dst); @@ -62,7 +62,7 @@ ofp_ct_tuple_is_zero(const struct ofp_ct_tuple *tuple, uint8_t ip_proto) return is_zero; } -bool +static bool ofp_ct_tuple_is_five_tuple(const struct ofp_ct_tuple *tuple, uint8_t ip_proto) { /* First check if we have address. */ @@ -75,17 +75,48 @@ ofp_ct_tuple_is_five_tuple(const struct ofp_ct_tuple *tuple, uint8_t ip_proto) return five_tuple; } +bool +ofp_ct_match_is_five_tuple(const struct ofp_ct_match *match) +{ + return ofp_ct_tuple_is_five_tuple(&match->tuple_orig, match->ip_proto) && + ofp_ct_tuple_is_zero(&match->tuple_reply, match->ip_proto) && + !match->mark_mask && ovs_u128_is_zero(match->labels_mask); +} + bool ofp_ct_match_is_zero(const struct ofp_ct_match *match) { return !match->ip_proto && !match->l3_type && ofp_ct_tuple_is_zero(&match->tuple_orig, match->ip_proto) && - ofp_ct_tuple_is_zero(&match->tuple_reply, match->ip_proto); + ofp_ct_tuple_is_zero(&match->tuple_reply, match->ip_proto) && + !match->mark_mask && ovs_u128_is_zero(match->labels_mask); } void ofp_ct_match_format(struct ds *ds, const struct ofp_ct_match *match) { + if (match->mark_mask) { + ds_put_format(ds, "mark=%#"PRIx32, match->mark); + if (match->mark_mask != UINT32_MAX) { + ds_put_format(ds, "/%#"PRIx32, match->mark_mask); + } + ds_put_char(ds, ' '); + } + + if (!ovs_u128_is_zero(match->labels_mask)) { + ovs_be128 be_value = hton128(match->labels); + ovs_be128 be_mask = hton128(match->labels_mask); + + ds_put_cstr(ds, "labels="); + ds_put_hex(ds, &be_value, sizeof be_value); + + if (!ovs_u128_is_ones(match->labels_mask)) { + ds_put_char(ds, '/'); + ds_put_hex(ds, &be_mask, sizeof be_mask); + } + ds_put_char(ds, ' '); + } + ds_put_cstr(ds, "'"); ofp_ct_tuple_format(ds, &match->tuple_orig, match->ip_proto, match->l3_type); @@ -95,6 +126,23 @@ ofp_ct_match_format(struct ds *ds, const struct ofp_ct_match *match) ds_put_cstr(ds, "'"); } +static inline bool +ofp_ct_masked_parse(const char *s, uint8_t *val, size_t val_len, + uint8_t *mask, size_t mask_len) +{ + char *tail; + if (!parse_int_string(s, val, val_len, &tail)) { + if (*tail != '/' || parse_int_string(tail + 1, mask, + mask_len, &tail)) { + memset(mask, UINT8_MAX, mask_len); + } + + return true; + } + + return false; +} + /* Parses a specification of a conntrack 5-tuple from 's' into 'tuple'. * Returns true on success. Otherwise, returns false and puts the error * message in 'ds'. */ @@ -236,6 +284,40 @@ ofp_ct_match_parse(const char **argv, int argc, struct ds *ds, args--; } + /* Parse mark. */ + if (args && !strncmp(argv[argc - args], "mark=", 5)) { + const char *s = argv[argc - args] + 5; + ovs_be32 mark_be; + ovs_be32 mask_be; + + if (ofp_ct_masked_parse(s, (uint8_t *) &mark_be, sizeof mark_be, + (uint8_t *) &mask_be, sizeof mask_be)) { + match->mark = ntohl(mark_be); + match->mark_mask = ntohl(mask_be); + } else { + ds_put_cstr(ds, "failed to parse mark"); + return false; + } + args--; + } + + /* Parse labels. */ + if (args && !strncmp(argv[argc - args], "labels=", 7)) { + const char *s = argv[argc - args] + 7; + ovs_be128 labels_be; + ovs_be128 mask_be; + + if (ofp_ct_masked_parse(s, (uint8_t *) &labels_be, sizeof labels_be, + (uint8_t *) &mask_be, sizeof mask_be)) { + match->labels = ntoh128(labels_be); + match->labels_mask = ntoh128(mask_be); + } else { + ds_put_cstr(ds, "failed to parse labels"); + return false; + } + args--; + } + /* Parse ct tuples. */ for (int i = 0; i < 2; i++) { if (!args) { @@ -382,6 +464,7 @@ enum ofperr ofp_ct_match_decode(struct ofp_ct_match *match, bool *with_zone, uint16_t *zone_id, const struct ofp_header *oh) { + uint32_t tlv_flags = 0; struct ofpbuf msg = ofpbuf_const_initializer(oh, ntohs(oh->length)); ofpraw_pull_assert(&msg); @@ -422,11 +505,43 @@ ofp_ct_match_decode(struct ofp_ct_match *match, bool *with_zone, } error = ofpprop_parse_u16(&property, zone_id); break; + + case NXT_CT_MARK: + error = ofpprop_parse_u32(&property, &match->mark); + break; + + case NXT_CT_MARK_MASK: + error = ofpprop_parse_u32(&property, &match->mark_mask); + break; + + case NXT_CT_LABELS: + error = ofpprop_parse_u128(&property, &match->labels); + break; + + case NXT_CT_LABELS_MASK: + error = ofpprop_parse_u128(&property, &match->labels_mask); + break; } if (error) { return error; } + + if (type < (sizeof tlv_flags * CHAR_BIT)) { + tlv_flags |= (UINT32_C(1) << type); + } + } + + /* Consider the mask being all ones if it's not present but the value + * is specified. */ + if (tlv_flags & (UINT32_C(1) << NXT_CT_MARK) && + !(tlv_flags & (UINT32_C(1) << NXT_CT_MARK_MASK))) { + match->mark_mask = UINT32_MAX; + } + + if (tlv_flags & (UINT32_C(1) << NXT_CT_LABELS) && + !(tlv_flags & (UINT32_C(1) << NXT_CT_LABELS_MASK))) { + match->labels_mask = OVS_U128_MAX; } return 0; @@ -450,5 +565,19 @@ ofp_ct_match_encode(const struct ofp_ct_match *match, uint16_t *zone_id, ofpprop_put_u16(msg, NXT_CT_ZONE_ID, *zone_id); } + if (match->mark_mask) { + ofpprop_put_u32(msg, NXT_CT_MARK, match->mark); + if (match->mark_mask != UINT32_MAX) { + ofpprop_put_u32(msg, NXT_CT_MARK_MASK, match->mark_mask); + } + } + + if (!ovs_u128_is_zero(match->labels_mask)) { + ofpprop_put_u128(msg, NXT_CT_LABELS, match->labels); + if (!ovs_u128_is_ones(match->labels_mask)) { + ofpprop_put_u128(msg, NXT_CT_LABELS_MASK, match->labels_mask); + } + } + return msg; } diff --git a/tests/ofp-print.at b/tests/ofp-print.at index 14aa55416..bb4b0ca27 100644 --- a/tests/ofp-print.at +++ b/tests/ofp-print.at @@ -4093,6 +4093,84 @@ AT_CHECK([ovs-ofctl ofp-print "\ NXT_CT_FLUSH (xid=0x3): zone=13 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0,ct_nw_proto=6' 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0' ]) +AT_CHECK([ovs-ofctl ofp-print "\ +01 04 00 20 00 00 00 03 00 00 23 20 00 00 00 20 \ +06 \ +00 00 00 00 00 00 00 \ +00 03 00 08 00 00 00 ab \ +"], [0], [dnl +NXT_CT_FLUSH (xid=0x3): zone=0 mark=0xab 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0,ct_nw_proto=6' 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0' +]) + +AT_CHECK([ovs-ofctl ofp-print "\ +01 04 00 20 00 00 00 03 00 00 23 20 00 00 00 20 \ +06 \ +00 00 00 00 00 00 00 \ +00 04 00 08 00 00 00 cd \ +"], [0], [dnl +NXT_CT_FLUSH (xid=0x3): zone=0 mark=0/0xcd 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0,ct_nw_proto=6' 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0' +]) + +AT_CHECK([ovs-ofctl ofp-print "\ +01 04 00 28 00 00 00 03 00 00 23 20 00 00 00 20 \ +06 \ +00 00 00 00 00 00 00 \ +00 03 00 08 00 00 00 ab \ +00 04 00 08 00 00 00 cd \ +"], [0], [dnl +NXT_CT_FLUSH (xid=0x3): zone=0 mark=0xab/0xcd 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0,ct_nw_proto=6' 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0' +]) + +AT_CHECK([ovs-ofctl ofp-print "\ +01 04 00 30 00 00 00 03 00 00 23 20 00 00 00 20 \ +06 \ +00 00 00 00 00 00 00 \ +00 05 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ab 00 00 00 00 00 \ +"], [0], [dnl +NXT_CT_FLUSH (xid=0x3): zone=0 labels=0xffab00 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0,ct_nw_proto=6' 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0' +]) + +AT_CHECK([ovs-ofctl ofp-print "\ +01 04 00 30 00 00 00 03 00 00 23 20 00 00 00 20 \ +06 \ +00 00 00 00 00 00 00 \ +00 06 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 ff cd 00 00 00 00 00 \ +"], [0], [dnl +NXT_CT_FLUSH (xid=0x3): zone=0 labels=0/0xffcd00 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0,ct_nw_proto=6' 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0' +]) + +AT_CHECK([ovs-ofctl ofp-print "\ +01 04 00 48 00 00 00 03 00 00 23 20 00 00 00 20 \ +06 \ +00 00 00 00 00 00 00 \ +00 05 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ab 00 00 00 00 00 \ +00 06 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 ff cd 00 00 00 00 00 \ +"], [0], [dnl +NXT_CT_FLUSH (xid=0x3): zone=0 labels=0xffab00/0xffcd00 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0,ct_nw_proto=6' 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0' +]) + +AT_CHECK([ovs-ofctl ofp-print "\ +01 04 00 38 00 00 00 03 00 00 23 20 00 00 00 20 \ +06 \ +00 00 00 00 00 00 00 \ +00 03 00 08 00 00 00 ab \ +00 05 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ab 00 00 00 00 00 \ +"], [0], [dnl +NXT_CT_FLUSH (xid=0x3): zone=0 mark=0xab labels=0xffab00 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0,ct_nw_proto=6' 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0' +]) + +AT_CHECK([ovs-ofctl ofp-print "\ +01 04 00 58 00 00 00 03 00 00 23 20 00 00 00 20 \ +06 \ +00 00 00 00 00 00 00 \ +00 03 00 08 00 00 00 ab \ +00 04 00 08 00 00 00 cd \ +00 05 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ab 00 00 00 00 00 \ +00 06 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 ff cd 00 00 00 00 00 \ +"], [0], [dnl +NXT_CT_FLUSH (xid=0x3): zone=0 mark=0xab/0xcd labels=0xffab00/0xffcd00 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0,ct_nw_proto=6' 'ct_ipv6_src=::,ct_ipv6_dst=::,ct_tp_src=0,ct_tp_dst=0' +]) + AT_CHECK([ovs-ofctl ofp-print "\ 01 04 00 68 00 00 00 03 00 00 23 20 00 00 00 20 \ 06 \ @@ -4180,4 +4258,11 @@ AT_CHECK([ovs-ofctl ofp-print "\ 00 01 00 20 00 00 00 00 \ 00 00 00 14 00 00 00 00 00 00 00 00 00 00 ff ff 0a 0a 00 02 00 00 00 00 \ " | grep -q OFPBPC_BAD_VALUE], [0]) + +AT_CHECK([ovs-ofctl ofp-print "\ +01 04 00 30 00 00 00 03 00 00 23 20 00 00 00 20 \ +06 \ +00 00 00 00 00 00 00 \ +00 06 00 15 00 00 00 00 00 00 00 00 00 00 00 00 00 ff cd 00 00 00 00 00 \ +" | grep -q OFPBPC_BAD_LEN], [0]) AT_CLEANUP diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at index 8531b2e2e..6bd421021 100644 --- a/tests/ovs-ofctl.at +++ b/tests/ovs-ofctl.at @@ -545,8 +545,8 @@ ipv6,ipv6_label=0x12345 actions=2 ipv6,ipv6_src=2001:db8:3c4d:1:2:3:4:5 actions=3 ipv6,ipv6_src=2001:db8:3c4d:1:2:3:4:5/64 actions=4 ipv6,ipv6_dst=2001:db8:3c4d:1:2:3:4:5/127 actions=5 -tcp6,ipv6_src=2001:db8:3c4d:1::1,tp_dst=80 actions=drop -udp6,ipv6_src=2001:db8:3c4d:1::3,tp_dst=53 actions=drop +tcp6,ipv6_src=2001:db8:3c4d:1::1,tp_dst=80 actions=drop +udp6,ipv6_src=2001:db8:3c4d:1::3,tp_dst=53 actions=drop in_port=3 icmp6,ipv6_src=2001:db8:3c4d:1::1,icmp_type=134 actions=drop udp dl_vlan_pcp=7 idle_timeout=5 actions=strip_vlan output:0 tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1 @@ -1021,7 +1021,7 @@ nx_pull_match() returned error OFPBMC_BAD_WILDCARDS # eth type NXM_OF_ETH_TYPE(0800) -NXM_OF_IN_PORT(0012), NXM_OF_ETH_TYPE(0800) +NXM_OF_IN_PORT(0012), NXM_OF_ETH_TYPE(0800) # vlan tci NXM_OF_VLAN_TCI(f009) @@ -3307,5 +3307,41 @@ AT_CHECK([ovs-ofctl ct-flush br0]) OVS_WAIT_UNTIL([test $(grep -c "|ct_dpif|DBG|.*ct_flush" ovs-vswitchd.log) -eq 5]) AT_CHECK([grep -q "ct_dpif|DBG|.*ct_flush: " ovs-vswitchd.log]) +AT_CHECK([ovs-ofctl ct-flush br0 mark=0]) +OVS_WAIT_UNTIL([test $(grep -c "|ct_dpif|DBG|.*ct_flush" ovs-vswitchd.log) -eq 6]) +AT_CHECK([grep -q "ct_dpif|DBG|.*ct_flush: zone=0 mark=0" ovs-vswitchd.log]) + +AT_CHECK([ovs-ofctl ct-flush br0 mark=0/0x5]) +OVS_WAIT_UNTIL([test $(grep -c "|ct_dpif|DBG|.*ct_flush" ovs-vswitchd.log) -eq 7]) +AT_CHECK([grep -q "ct_dpif|DBG|.*ct_flush: zone=0 mark=0/0x5" ovs-vswitchd.log]) + +AT_CHECK([ovs-ofctl ct-flush br0 mark=0xabc/0xdef]) +OVS_WAIT_UNTIL([test $(grep -c "|ct_dpif|DBG|.*ct_flush" ovs-vswitchd.log) -eq 8]) +AT_CHECK([grep -q "ct_dpif|DBG|.*ct_flush: zone=0 mark=0xabc/0xdef" ovs-vswitchd.log]) + +AT_CHECK([ovs-ofctl ct-flush br0 labels=0]) +OVS_WAIT_UNTIL([test $(grep -c "|ct_dpif|DBG|.*ct_flush" ovs-vswitchd.log) -eq 9]) +AT_CHECK([grep -q "ct_dpif|DBG|.*ct_flush: zone=0 labels=0" ovs-vswitchd.log]) + +AT_CHECK([ovs-ofctl ct-flush br0 labels=0/0x5]) +OVS_WAIT_UNTIL([test $(grep -c "|ct_dpif|DBG|.*ct_flush" ovs-vswitchd.log) -eq 10]) +AT_CHECK([grep -q "ct_dpif|DBG|.*ct_flush: zone=0 labels=0/0x5" ovs-vswitchd.log]) + +AT_CHECK([ovs-ofctl ct-flush br0 labels=0xabc/0xdef]) +OVS_WAIT_UNTIL([test $(grep -c "|ct_dpif|DBG|.*ct_flush" ovs-vswitchd.log) -eq 11]) +AT_CHECK([grep -q "ct_dpif|DBG|.*ct_flush: zone=0 labels=0xabc/0xdef" ovs-vswitchd.log]) + +AT_CHECK([ovs-ofctl ct-flush br0 zone=5 mark=25 labels=25]) +OVS_WAIT_UNTIL([test $(grep -c "|ct_dpif|DBG|.*ct_flush" ovs-vswitchd.log) -eq 12]) +AT_CHECK([grep -q "ct_dpif|DBG|.*ct_flush: zone=5 mark=0x19 labels=0x19" ovs-vswitchd.log]) + +AT_CHECK([ovs-ofctl ct-flush br0 zone=5 mark=30/25 labels=30/25]) +OVS_WAIT_UNTIL([test $(grep -c "|ct_dpif|DBG|.*ct_flush" ovs-vswitchd.log) -eq 13]) +AT_CHECK([grep -q "ct_dpif|DBG|.*ct_flush: zone=5 mark=0x1e/0x19 labels=0x1e/0x19" ovs-vswitchd.log]) + +AT_CHECK([ovs-ofctl ct-flush br0 zone=6 mark=30/0 labels=30/0]) +OVS_WAIT_UNTIL([test $(grep -c "|ct_dpif|DBG|.*ct_flush" ovs-vswitchd.log) -eq 14]) +AT_CHECK([grep -q "ct_dpif|DBG|.*ct_flush: zone 6" ovs-vswitchd.log]) + OVS_VSWITCHD_STOP AT_CLEANUP diff --git a/tests/system-traffic.at b/tests/system-traffic.at index 33a5d600f..c8ad30582 100644 --- a/tests/system-traffic.at +++ b/tests/system-traffic.at @@ -2527,8 +2527,8 @@ ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal -priority=100,in_port=1,ip,action=ct(commit),2 -priority=100,in_port=2,ip,action=ct(zone=5,commit),1 +priority=100,in_port=1,ip,action=ct(commit,exec(set_field:0xaa->ct_mark)),2 +priority=100,in_port=2,ip,action=ct(zone=5,commit,exec(set_field:0xaa00000000->ct_label)),1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) @@ -2543,7 +2543,7 @@ dnl Test UDP from port 1 AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000 actions=resubmit(,0)"]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=10\.1\.1\.1,"], [], [dnl -udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1) +udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),mark=170 ]) AT_CHECK([FLUSH_CMD 'ct_nw_src=10.1.1.2,ct_nw_dst=10.1.1.1,ct_nw_proto=17,ct_tp_src=2,ct_tp_dst=1']) @@ -2555,7 +2555,7 @@ dnl Test UDP from port 2 AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=2 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101020a0101010002000100080000 actions=resubmit(,0)"]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=10\.1\.1\.2,"], [0], [dnl -udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD zone=5 'ct_nw_src=10.1.1.1,ct_nw_dst=10.1.1.2,ct_nw_proto=17,ct_tp_src=1,ct_tp_dst=2']) @@ -2569,7 +2569,7 @@ NS_CHECK_EXEC([at_ns1], [ping -q -c 3 -i 0.3 -W 2 10.1.1.1 | FORMAT_PING], [0], AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=10\.1\.1\.2,"], [0], [stdout]) AT_CHECK([cat stdout | FORMAT_CT(10.1.1.1)], [0],[dnl -icmp,orig=(src=10.1.1.2,dst=10.1.1.1,id=,type=8,code=0),reply=(src=10.1.1.1,dst=10.1.1.2,id=,type=0,code=0),zone=5 +icmp,orig=(src=10.1.1.2,dst=10.1.1.1,id=,type=8,code=0),reply=(src=10.1.1.1,dst=10.1.1.2,id=,type=0,code=0),zone=5,labels=0xaa00000000 ]) ICMP_ID=`cat stdout | cut -d ',' -f4 | cut -d '=' -f2` @@ -2585,14 +2585,14 @@ AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=2 packet=50540000000a5 AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1" | sort], [0], [dnl -udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1) -udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),mark=170 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD 'ct_nw_proto=17,ct_tp_src=1']) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1"], [0], [dnl -udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD 'ct_nw_proto=17,ct_tp_src=2']) @@ -2605,14 +2605,14 @@ AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=2 packet=50540000000a5 AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1" | sort], [0], [dnl -udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1) -udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),mark=170 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD 'ct_nw_proto=17,ct_tp_dst=2']) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1"], [0], [dnl -udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD 'ct_nw_proto=17,ct_tp_dst=1']) @@ -2625,14 +2625,14 @@ AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=2 packet=50540000000a5 AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1" | sort], [0], [dnl -udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1) -udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),mark=170 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD 'ct_nw_src=10.1.1.1']) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1"], [0], [dnl -udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD 'ct_nw_src=10.1.1.2']) @@ -2645,14 +2645,14 @@ AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=2 packet=50540000000a5 AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1" | sort], [0], [dnl -udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1) -udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),mark=170 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD 'ct_nw_dst=10.1.1.2']) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1"], [0], [dnl -udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD 'ct_nw_dst=10.1.1.1']) @@ -2665,14 +2665,14 @@ AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=2 packet=50540000000a5 AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1" | sort], [0], [dnl -udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1) -udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),mark=170 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD '' 'ct_nw_src=10.1.1.2']) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1"], [0], [dnl -udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD zone=5 '' 'ct_nw_src=10.1.1.1']) @@ -2685,8 +2685,8 @@ AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=2 packet=50540000000a5 AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1" | sort], [0], [dnl -udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1) -udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),mark=170 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD]) @@ -2698,46 +2698,80 @@ AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a5 AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=2 packet=50540000000950540000000a08004500003400010000408464410a0101020a010101000200010000000098f29e470100001470e18ccc00000000000a000a00000000 actions=resubmit(,0)"]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1" | sed "s/,protoinfo=.*$//" | sort], [0], [dnl -sctp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1) -sctp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +sctp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),mark=170 +sctp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD 'ct_nw_src=10.1.1.1,ct_nw_proto=132,ct_tp_src=1,ct_tp_dst=2']) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1" | sed "s/,protoinfo=.*$//" | sort], [0], [dnl -sctp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 +sctp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) AT_CHECK([FLUSH_CMD 'ct_nw_src=10.1.1.2,ct_nw_proto=132,ct_tp_src=2,ct_tp_dst=1']) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1"], [1]) + +dnl Test UDP from port 1 and 2, partial flush by mark and labels +AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000 actions=resubmit(,0)"]) +AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=2 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101020a0101010002000100080000 actions=resubmit(,0)"]) + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1" | sort], [0], [dnl +udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),mark=170 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 +]) + +AT_CHECK([FLUSH_CMD mark=0xaa]) + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1"], [0], [dnl +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 +]) + +AT_CHECK([FLUSH_CMD labels=0xaa00000000]) + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1"], [1]) + +AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000 actions=resubmit(,0)"]) +AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=2 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101020a0101010002000100080000 actions=resubmit(,0)"]) + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1" | sort], [0], [dnl +udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),mark=170 +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 +]) + +AT_CHECK([FLUSH_CMD mark=2/2]) + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1"], [0], [dnl +udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5,labels=0xaa00000000 ]) -dnl Test flush with invalid arguments +AT_CHECK([FLUSH_CMD labels=0x0200000000/0x0200000000]) + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "10\.1\.1\.1"], [1]) + +dnl Test flush with invalid arguments. -AT_CHECK([ovs-appctl dpctl/flush-conntrack zone=invalid 'ct_nw_src=10.1.1.1' 'ct_nw_dst=10.1.1.1'], [2], [ignore], [stderr]) +AT_CHECK([FLUSH_CMD zone=invalid 'ct_nw_src=10.1.1.1' 'ct_nw_dst=10.1.1.1'], [ignore], [ignore], [stderr]) AT_CHECK([grep -q "failed to parse zone" stderr]) -AT_CHECK([ovs-appctl dpctl/flush-conntrack zone=1 'ct_nw_src=10.1.1.1,invalid=invalid' 'ct_nw_dst=10.1.1.1'], [2], [ignore], [stderr]) +AT_CHECK([FLUSH_CMD zone=1 'ct_nw_src=10.1.1.1,invalid=invalid' 'ct_nw_dst=10.1.1.1'], [ignore], [ignore], [stderr]) AT_CHECK([grep -q "invalid conntrack tuple field: invalid" stderr]) -AT_CHECK([ovs-appctl dpctl/flush-conntrack zone=1 'ct_nw_src=invalid' 'ct_nw_dst=10.1.1.1'], [2], [ignore], [stderr]) +AT_CHECK([FLUSH_CMD zone=1 'ct_nw_src=invalid' 'ct_nw_dst=10.1.1.1'], [ignore], [ignore], [stderr]) AT_CHECK([grep -q "failed to parse field ct_nw_src" stderr]) -AT_CHECK([ovs-appctl dpctl/flush-conntrack zone=1 'ct_nw_src=10.1.1.1' 'ct_nw_dst=10.1.1.1' invalid], [2], [ignore], [stderr]) +AT_CHECK([FLUSH_CMD zone=1 'ct_nw_src=10.1.1.1' 'ct_nw_dst=10.1.1.1' invalid], [ignore], [ignore], [stderr]) AT_CHECK([grep -q "invalid arguments" stderr]) -AT_CHECK([ovs-appctl dpctl/flush-conntrack $dp zone=1 'ct_nw_src=10.1.1.1' 'ct_nw_dst=10.1.1.1' invalid], [2], [ignore], [stderr]) -AT_CHECK([grep -q "command takes at most 4 arguments" stderr]) +AT_CHECK([FLUSH_CMD zone=1 mark=1 labels=1 'ct_nw_src=10.1.1.1' 'ct_nw_dst=10.1.1.1' invalid invalid], [ignore], [ignore], [stderr]) +AT_CHECK([grep -q "command takes at most 6 arguments" stderr]) -AT_CHECK([ovs-appctl dpctl/flush-conntrack $dp 'ct_nw_src=10.1.1.1' 'ct_nw_dst=10.1.1.1' invalid], [2], [ignore], [stderr]) -AT_CHECK([grep -q "invalid arguments" stderr]) - -AT_CHECK([ovs-ofctl ct-flush br0 zone=1 'ct_nw_src=10.1.1.1' 'ct_nw_dst=10.1.1.1' invalid], [1], [ignore], [stderr]) -AT_CHECK([grep -q "command takes at most 4 arguments" stderr]) +AT_CHECK([FLUSH_CMD mark=invalid], [ignore], [ignore], [stderr]) +AT_CHECK([grep -q "failed to parse mark" stderr]) -AT_CHECK([ovs-ofctl ct-flush br0 'ct_nw_src=10.1.1.1' 'ct_nw_dst=10.1.1.1' invalid], [1], [ignore], [stderr]) -AT_CHECK([grep -q "invalid arguments" stderr]) +AT_CHECK([FLUSH_CMD labels=invalid], [ignore], [ignore], [stderr]) +AT_CHECK([grep -q "failed to parse labels" stderr]) +]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in index 0a611b2ee..e66ac74b2 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -118,7 +118,7 @@ Disables vacancy events. . .TP \fBdump\-ports \fIswitch\fR [\fInetdev\fR] -Prints to the console statistics for network devices associated with +Prints to the console statistics for network devices associated with \fIswitch\fR. If \fInetdev\fR is specified, only the statistics associated with that device will be printed. \fInetdev\fR can be an OpenFlow assigned port number or device name, e.g. \fBeth0\fR. @@ -242,7 +242,7 @@ formatting. See the descriptions of these options, under .TP \fBdump\-aggregate \fIswitch \fR[\fIflows\fR] Prints to the console aggregate statistics for flows in -\fIswitch\fR's tables that match \fIflows\fR. If \fIflows\fR is omitted, +\fIswitch\fR's tables that match \fIflows\fR. If \fIflows\fR is omitted, the statistics are aggregated across all flows in the switch's flow tables. See \fBFlow Syntax\fR, below, for the syntax of \fIflows\fR. The output format is described in \fBTable Entry Output\fR. @@ -296,17 +296,20 @@ Flushes the connection tracking entries in \fIzone\fR on \fIswitch\fR. This command uses an Open vSwitch extension that is only in Open vSwitch 2.6 and later. . -.IP "\fBct\-flush \fIswitch [zone=N] [ct-orig-tuple [ct-reply-tuple]]\fR -Flushes the connection entries on \fIswitch\fR based on \fIzone\fR and -connection tracking tuples \fIct-[orig|reply]-tuple\fR. +.IP "\fBct\-flush \fIswitch [zone=N] [mark=X[/M]] [labels=Y[/N]] [ct-orig-tuple [ct-reply-tuple]]\fR +Flushes the connection entries on \fIswitch\fR based on \fIzone\fR, +\fImark\fR, \fIlabels\fR and connection tracking tuples +\fIct-[orig|reply]-tuple\fR. .IP If \fIct-[orig|reply]-tuple\fR is not provided, flushes all the connection entries. If \fIzone\fR is specified, only flushes the connections in -\fIzone\fR. +\fIzone\fR. if \fImark\fR or \fIlabels\fR is provided, it will flush +only entries that are matching specific \fImark/labels\fR. .IP If \fIct-[orig|reply]-tuple\fR is provided, flushes the connection entry specified by \fIct-[orig|reply]-tuple\fR in \fIzone\fR. The zone defaults -to 0 if it is not provided. The userspace connection tracker requires flushing +to 0 if it is not provided. The \fImark\fR and \fIlabels\fR defaults to "0/0" +if it is not provided. The userspace connection tracker requires flushing with the original pre-NATed tuple and a warning log will be otherwise generated. The tuple can be partial and will remove all connections that are matching on the specified fields. In order to specify only @@ -866,10 +869,10 @@ allow priority to be specified. . .IP \fBpriority=\fIvalue\fR The priority at which a wildcarded entry will match in comparison to -others. \fIvalue\fR is a number between 0 and 65535, inclusive. A higher -\fIvalue\fR will match before a lower one. An exact-match entry will always -have priority over an entry containing wildcards, so it has an implicit -priority value of 65535. When adding a flow, if the field is not specified, +others. \fIvalue\fR is a number between 0 and 65535, inclusive. A higher +\fIvalue\fR will match before a lower one. An exact-match entry will always +have priority over an entry containing wildcards, so it has an implicit +priority value of 65535. When adding a flow, if the field is not specified, the flow's priority will default to 32768. .IP OpenFlow leaves behavior undefined when two or more flows with the @@ -941,7 +944,7 @@ Open vSwitch 1.10 added support for \fBno_packet_counts\fR and \fBno_byte_counts\fR. . .PP -The \fBdump\-flows\fR, \fBdump\-aggregate\fR, \fBdel\-flow\fR +The \fBdump\-flows\fR, \fBdump\-aggregate\fR, \fBdel\-flow\fR and \fBdel\-flows\fR commands support these additional optional fields: . .TP @@ -958,8 +961,8 @@ or later. . .SS "Table Entry Output" . -The \fBdump\-tables\fR and \fBdump\-aggregate\fR commands print information -about the entries in a datapath's tables. Each line of output is a +The \fBdump\-tables\fR and \fBdump\-aggregate\fR commands print information +about the entries in a datapath's tables. Each line of output is a flow entry as described in \fBFlow Syntax\fR, above, plus some additional fields: . diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 79d42dd0b..03c4cb38c 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -486,9 +486,10 @@ usage(void) " dump-ipfix-bridge SWITCH print ipfix stats of bridge\n" " dump-ipfix-flow SWITCH print flow ipfix of a bridge\n" " ct-flush-zone SWITCH ZONE flush conntrack entries in ZONE\n" - " ct-flush SWITCH [ZONE] [CT_ORIG_TUPLE [CT_REPLY_TUPLE]]\n" - " flush conntrack entries specified\n" - " by CT_ORIG/REPLY_TUPLE and ZONE\n" + " ct-flush SWITCH [ZONE] [mark=X[/M]] [labels=Y[/N]]" + " [CT_ORIG_TUPLE [CT_REPLY_TUPLE]]\n flush conntrack entries" + " specified by CT_ORIG/REPLY_TUPLE," + " ZONE, mark and labels\n" "\nFor OpenFlow switches and controllers:\n" " probe TARGET probe whether TARGET is up\n" " ping TARGET [N] latency of N-byte echos\n" @@ -5092,8 +5093,9 @@ static const struct ovs_cmdl_command all_commands[] = { { "ct-flush-zone", "switch zone", 2, 2, ofctl_ct_flush_zone, OVS_RO }, - { "ct-flush", "switch [zone=N] [ct-orig-tuple [ct-reply-tuple]]", - 1, 4, ofctl_ct_flush, OVS_RO }, + { "ct-flush", "switch [zone=N] [mark=X[/M]] [labels=Y[/N]] " + "[ct-orig-tuple [ct-reply-tuple]]", + 1, 6, ofctl_ct_flush, OVS_RO }, { "ofp-parse", "file", 1, 1, ofctl_ofp_parse, OVS_RW },