From patchwork Wed Aug 28 22:14:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1154905 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="U7qPUu5t"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Jg7L3dn2z9sNC for ; Thu, 29 Aug 2019 08:16:14 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 1BA973ACC; Wed, 28 Aug 2019 22:15:22 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 6A35A3A48 for ; Wed, 28 Aug 2019 22:15:05 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f196.google.com (mail-pf1-f196.google.com [209.85.210.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 77E6DEC for ; Wed, 28 Aug 2019 22:15:04 +0000 (UTC) Received: by mail-pf1-f196.google.com with SMTP id o70so661033pfg.5 for ; Wed, 28 Aug 2019 15:15:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TW7EF7qa5b9jzfs61Iz653ukwcnMwQca0v8QhQVNaJk=; b=U7qPUu5tn+HKvVi9iEjBLM/EChfdy0rpIWSZwu/1ZYNlEtftyfQp66bMj3pzFCP8lJ 3//L3liVKaqto0xP24eiP4gScvfx4Fa4unaWiLDUpgZXk3f2i9mmGBhmaxgn+/5Rbqwr KJwLPDyqUjE6v7ccQQKVp/bkAlF0xpapgZpjVxC9QFFPWQ54IseVpTR37hgIWlfoLSHq fsPASRAAs8LJDXibHj0gc7B7wozv1BKkgCPUT6E/Kvs9aIaM9MMv8VaIqT2aTCUt1FhC 9nxfxuo+wAgi472M9UgOkbYPazlzz90xQhwgqoHbhyNEaPbdwE+1RmJRnrLi2ou0mWMD 8zSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TW7EF7qa5b9jzfs61Iz653ukwcnMwQca0v8QhQVNaJk=; b=lKV2iVDygvdWd+iWtUL0763Xzjp1ktS4rULUHvEmEvKahA7VGnNBJWWNAVknyVvJ1f lafMjm/IeAmPZi3E2/Fl3pGNBNiSUwb2rxauYJWNJ/hLZQ9VBAaRU7QIixHHM8v/HSzQ h6vUxYY6jSeX8cvIltDXzEXM9S9FHUlEDDU3hb1UX2WAmOIcVZNyPUjQcWeTfQ+91VRX tYpj7Z6+kYJM1+vmT7mS6uNC+UDR9p3/v7R1EyP60+qHr6c1WqnEunZpZKrExfnt5iuo Ru2zE7V1QuYlEkNud16fgdfJr5Qahgsbfu2Lc8rg4lBZYYy+kFoZojg9Jixqv1tLydvV K2GA== X-Gm-Message-State: APjAAAXInYU/C5q5/JdL9THZqz+dV88DUqRWd/JbCeIJRhW/VSd4lsDA od6NXZ+HBrva3gM0hEEmxwqmX7LJ X-Google-Smtp-Source: APXvYqy/Wto3+z9JcgDf5cWtSuJ6YQtHHjrFB6gb6+qCkYLgvW1jiG+XiuuvNnrcSWMnXZJrp5JzYw== X-Received: by 2002:a62:1810:: with SMTP id 16mr7157577pfy.171.1567030502968; Wed, 28 Aug 2019 15:15:02 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id d128sm432493pfa.42.2019.08.28.15.15.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 28 Aug 2019 15:15:02 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org Date: Wed, 28 Aug 2019 15:14:22 -0700 Message-Id: <1567030469-120137-3-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1567030469-120137-1-git-send-email-yihung.wei@gmail.com> References: <1567030469-120137-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 2/9] ovs-vsctl: Add conntrack zone commands. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: William Tu The patch adds commands creating/deleting/listing conntrack zone timeout policies: $ ovs-vsctl {add,del,list}-zone-tp dp zone=zone_id ... Signed-off-by: William Tu --- tests/ovs-vsctl.at | 34 +++++++- utilities/ovs-vsctl.8.in | 26 ++++++ utilities/ovs-vsctl.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 256 insertions(+), 6 deletions(-) diff --git a/tests/ovs-vsctl.at b/tests/ovs-vsctl.at index 46fa3c5b1a33..df15fb6901a0 100644 --- a/tests/ovs-vsctl.at +++ b/tests/ovs-vsctl.at @@ -805,6 +805,20 @@ AT_CHECK( [RUN_OVS_VSCTL([--if-exists remove netflow x targets '"1.2.3.4:567"'])]) AT_CHECK( [RUN_OVS_VSCTL([--if-exists clear netflow x targets])]) + +AT_CHECK([RUN_OVS_VSCTL([-- --id=@m create Datapath datapath_version=0 -- set Open_vSwitch . datapaths:"netdev"=@m])], [0], [stdout]) +AT_CHECK([RUN_OVS_VSCTL([add-zone-tp netdev zone=1 icmp_first=1 icmp_reply=2])]) +AT_CHECK([RUN_OVS_VSCTL([--may-exist add-zone-tp netdev zone=1 icmp_first=1 icmp_reply=2])]) +AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:1, Timeout Policies: icmp_first=1 icmp_reply=2 +]) +AT_CHECK([RUN_OVS_VSCTL([add-zone-tp netdev zone=2 icmp_first=2 icmp_reply=3])]) +AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:1, Timeout Policies: icmp_first=1 icmp_reply=2 +Zone:2, Timeout Policies: icmp_first=2 icmp_reply=3 +]) +AT_CHECK([RUN_OVS_VSCTL([del-zone-tp netdev zone=1])]) +AT_CHECK([RUN_OVS_VSCTL([--if-exists del-zone-tp netdev zone=1])]) +AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:2, Timeout Policies: icmp_first=2 icmp_reply=3 +]) OVS_VSCTL_CLEANUP AT_CLEANUP @@ -890,10 +904,10 @@ AT_CHECK([RUN_OVS_VSCTL([set bridge br0 flood_vlans=-1])], AT_CHECK([RUN_OVS_VSCTL([set bridge br0 flood_vlans=4096])], [1], [], [ovs-vsctl: constraint violation: 4096 is not in the valid range 0 to 4095 (inclusive) ]) -AT_CHECK([RUN_OVS_VSCTL([set c br1 'connection-mode=xyz'])], +AT_CHECK([RUN_OVS_VSCTL([set controller br1 'connection-mode=xyz'])], [1], [], [[ovs-vsctl: constraint violation: xyz is not one of the allowed values ([in-band, out-of-band]) ]]) -AT_CHECK([RUN_OVS_VSCTL([set c br1 connection-mode:x=y])], +AT_CHECK([RUN_OVS_VSCTL([set controller br1 connection-mode:x=y])], [1], [], [ovs-vsctl: cannot specify key to set for non-map column connection_mode ]) AT_CHECK([RUN_OVS_VSCTL([add bridge br1 datapath_id x y])], @@ -929,6 +943,22 @@ AT_CHECK([RUN_OVS_VSCTL([remove bridge br1 flood-vlans true])], AT_CHECK([RUN_OVS_VSCTL([clear bridge br1 name])], [1], [], [ovs-vsctl: cannot modify read-only column name in table Bridge ]) + +AT_CHECK([RUN_OVS_VSCTL([-- --id=@m create Datapath datapath_version=0 -- set Open_vSwitch . datapaths:"netdev"=@m])], [0], [stdout]) +AT_CHECK([RUN_OVS_VSCTL([add-zone-tp netdevxx zone=1 icmp_first=1 icmp_reply=2])], + [1], [], [ovs-vsctl: datapath netdevxx does not exist +]) +AT_CHECK([RUN_OVS_VSCTL([add-zone-tp netdev zone=2 icmp_first=2 icmp_reply=3])]) +AT_CHECK([RUN_OVS_VSCTL([add-zone-tp netdev zone=2 icmp_first=2 icmp_reply=3])], + [1], [], [ovs-vsctl: zone id 2 already exists +]) +AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:2, Timeout Policies: icmp_first=2 icmp_reply=3 +]) +AT_CHECK([RUN_OVS_VSCTL([del-zone-tp netdev zone=11])], + [1], [], [ovs-vsctl: zone id 11 does not exist +]) +AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:2, Timeout Policies: icmp_first=2 icmp_reply=3 +]) OVS_VSCTL_CLEANUP AT_CLEANUP diff --git a/utilities/ovs-vsctl.8.in b/utilities/ovs-vsctl.8.in index 7c09df79bd29..5b9883ae1c3d 100644 --- a/utilities/ovs-vsctl.8.in +++ b/utilities/ovs-vsctl.8.in @@ -353,6 +353,32 @@ list. Prints the name of the bridge that contains \fIiface\fR on standard output. . +.SS "Conntrack Zone Commands" +These commands query and modify datapath CT zones and Timeout Policies. +. +.IP "[\fB\-\-may\-exist\fR] \fBadd\-zone\-tp \fIdatapath \fBzone=\fIzone_id \fIpolicies\fR" +Creates a conntrack zone timeout policy with \fIzone_id\fR in +\fIdatapath\fR. The \fIpolicies\fR consist of \fIkey\fB=\fIvalue\fR +pairs, separated by spaces. For example, \fBicmp_first=30 +icmp_reply=60\fR specifies a 30-second timeout policy for the first ICMP +packet and a 60-second policy for ICMP reply packet. See the +\fBCT_Timeout_Policy\fR table in \fBovs-vswitchd.conf.db\fR(5) for the +supported keys. +.IP +Without \fB\-\-may\-exist\fR, attempting to add a \fIzone_id\fR that +already exists is an error. With \fB\-\-may\-exist\fR, +this command does nothing if \fIzone_id\fR is already created\fR. +. +.IP "[\fB\-\-if\-exists\fR] \fBdel\-zone\-tp \fIdatapath \fBzone=\fIzone_id\fR" +Delete the timeout policy associated with \fIzone_id\fR from \fIdatapath\fR. +.IP +Without \fB\-\-if\-exists\fR, attempting to delete a zone that +does not exist is an error. With \fB\-\-if\-exists\fR, attempting to +delete a zone that does not exist has no effect. +. +.IP "\fBlist\-zone\-tp \fIdatapath\fR" +Prints the timeout policies of all zones in \fIdatapath\fR. +. .SS "OpenFlow Controller Connectivity" . \fBovs\-vswitchd\fR can perform all configured bridging and switching diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c index 4948137efe8c..76a708bd5069 100644 --- a/utilities/ovs-vsctl.c +++ b/utilities/ovs-vsctl.c @@ -32,14 +32,18 @@ #include "command-line.h" #include "compiler.h" #include "dirs.h" -#include "openvswitch/dynamic-string.h" #include "fatal-signal.h" #include "hash.h" +#include "openvswitch/dynamic-string.h" #include "openvswitch/json.h" +#include "openvswitch/ofp-parse.h" +#include "openvswitch/poll-loop.h" +#include "openvswitch/vconn.h" +#include "openvswitch/vlog.h" #include "ovsdb-data.h" #include "ovsdb-idl.h" -#include "openvswitch/poll-loop.h" #include "process.h" +#include "simap.h" #include "stream.h" #include "stream-ssl.h" #include "smap.h" @@ -49,8 +53,6 @@ #include "table.h" #include "timeval.h" #include "util.h" -#include "openvswitch/vconn.h" -#include "openvswitch/vlog.h" VLOG_DEFINE_THIS_MODULE(vsctl); @@ -1153,6 +1155,191 @@ cmd_emer_reset(struct ctl_context *ctx) vsctl_context_invalidate_cache(ctx); } +static struct ovsrec_datapath * +find_datapath(struct vsctl_context *vsctl_ctx, const char *dp_name) +{ + const struct ovsrec_open_vswitch *ovs = vsctl_ctx->ovs; + + for (int i = 0; i < ovs->n_datapaths; i++) { + if (!strcmp(ovs->key_datapaths[i], dp_name)) { + return ovs->value_datapaths[i]; + } + } + return NULL; +} + +static struct ovsrec_ct_zone * +find_ct_zone(struct ovsrec_datapath *dp, const int64_t zone_id) +{ + for (int i = 0; i < dp->n_ct_zones; i++) { + if (dp->key_ct_zones[i] == zone_id) { + return dp->value_ct_zones[i]; + } + } + return NULL; +} + +static struct ovsrec_ct_timeout_policy * +create_timeout_policy(struct ctl_context *ctx, char **argv, int n_tps) +{ + const struct ovsrec_ct_timeout_policy_table *tp_table; + const struct ovsrec_ct_timeout_policy *row; + struct ovsrec_ct_timeout_policy *tp = NULL; + struct simap new_tp = SIMAP_INITIALIZER(&new_tp); + + char **policies = xzalloc(sizeof *policies * n_tps); + const char **key_timeouts = xmalloc(sizeof *key_timeouts * n_tps); + int64_t *value_timeouts = xmalloc(sizeof *value_timeouts * n_tps); + + /* Parse timeout arguments. */ + for (int i = 0; i < n_tps; i++) { + policies[i] = xstrdup(argv[i]); + + char *key, *value; + char *policy = policies[i]; + if (!ofputil_parse_key_value(&policy, &key, &value)) { + goto done; + } + key_timeouts[i] = key; + value_timeouts[i] = atoi(value); + simap_put(&new_tp, key, (unsigned int)value_timeouts[i]); + } + +done: + tp_table = ovsrec_ct_timeout_policy_table_get(ctx->idl); + OVSREC_CT_TIMEOUT_POLICY_TABLE_FOR_EACH (row, tp_table) { + struct simap s = SIMAP_INITIALIZER(&s); + + /* Convert to simap. */ + for (int i = 0; i < row->n_timeouts; i++) { + simap_put(&s, row->key_timeouts[i], row->value_timeouts[i]); + } + + if (simap_equal(&s, &new_tp)) { + tp = CONST_CAST(struct ovsrec_ct_timeout_policy *, row); + simap_destroy(&s); + break; + } + simap_destroy(&s); + } + + if (!tp) { + tp = ovsrec_ct_timeout_policy_insert(ctx->txn); + ovsrec_ct_timeout_policy_set_timeouts(tp, key_timeouts, + (const int64_t *)value_timeouts, + n_tps); + } + + for (int i = 0; i < n_tps; i++) { + free(policies[i]); + } + free(policies); + simap_destroy(&new_tp); + free(key_timeouts); + free(value_timeouts); + return tp; +} + +static void +cmd_add_zone_tp(struct ctl_context *ctx) +{ + struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx); + struct ovsrec_ct_timeout_policy *tp; + int64_t zone_id; + + const char *dp_name = ctx->argv[1]; + ovs_scan(ctx->argv[2], "zone=%"SCNi64, &zone_id); + bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL; + + struct ovsrec_datapath *dp = find_datapath(vsctl_ctx, dp_name); + if (!dp) { + ctl_fatal("datapath %s does not exist", dp_name); + } + + int n_tps = ctx->argc - 3; + struct ovsrec_ct_zone *zone = find_ct_zone(dp, zone_id); + + if (n_tps <= 0) { + ctl_fatal("No timeout policy"); + } + + if (zone && !may_exist) { + ctl_fatal("zone id %"PRIu64" already exists", zone_id); + } + + tp = create_timeout_policy(ctx, &ctx->argv[3], n_tps); + if (zone) { + ovsrec_ct_zone_set_timeout_policy(zone, tp); + } else { + zone = ovsrec_ct_zone_insert(ctx->txn); + ovsrec_ct_zone_set_timeout_policy(zone, tp); + ovsrec_datapath_update_ct_zones_setkey(dp, zone_id, zone); + } +} + +static void +cmd_del_zone_tp(struct ctl_context *ctx) +{ + struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx); + int64_t zone_id; + + bool must_exist = !shash_find(&ctx->options, "--if-exists"); + const char *dp_name = ctx->argv[1]; + ovs_scan(ctx->argv[2], "zone=%"SCNi64, &zone_id); + + struct ovsrec_datapath *dp = find_datapath(vsctl_ctx, dp_name); + if (!dp) { + ctl_fatal("datapath %s does not exist", dp_name); + } + + struct ovsrec_ct_zone *zone = find_ct_zone(dp, zone_id); + if (must_exist && !zone) { + ctl_fatal("zone id %"PRIu64" does not exist", zone_id); + } + + if (zone) { + ovsrec_datapath_update_ct_zones_delkey(dp, zone_id); + } +} + +static void +cmd_list_zone_tp(struct ctl_context *ctx) +{ + struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx); + + struct ovsrec_datapath *dp = find_datapath(vsctl_ctx, ctx->argv[1]); + if (!dp) { + ctl_fatal("datapath: %s record not found", ctx->argv[1]); + } + + for (int i = 0; i < dp->n_ct_zones; i++) { + struct ovsrec_ct_zone *zone = dp->value_ct_zones[i]; + ds_put_format(&ctx->output, "Zone:%"PRIu64", Timeout Policies: ", + dp->key_ct_zones[i]); + + struct ovsrec_ct_timeout_policy *tp = zone->timeout_policy; + + for (int j = 0; j < tp->n_timeouts; j++) { + if (j == tp->n_timeouts - 1) { + ds_put_format(&ctx->output, "%s=%"PRIu64"\n", + tp->key_timeouts[j], tp->value_timeouts[j]); + } else { + ds_put_format(&ctx->output, "%s=%"PRIu64" ", + tp->key_timeouts[j], tp->value_timeouts[j]); + } + } + } +} + +static void +pre_get_zone(struct ctl_context *ctx) +{ + ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_datapaths); + ovsdb_idl_add_column(ctx->idl, &ovsrec_datapath_col_ct_zones); + ovsdb_idl_add_column(ctx->idl, &ovsrec_ct_zone_col_timeout_policy); + ovsdb_idl_add_column(ctx->idl, &ovsrec_ct_timeout_policy_col_timeouts); +} + static void cmd_add_br(struct ctl_context *ctx) { @@ -2896,6 +3083,13 @@ static const struct ctl_command_syntax vsctl_commands[] = { /* Switch commands. */ {"emer-reset", 0, 0, "", pre_cmd_emer_reset, cmd_emer_reset, NULL, "", RW}, + /* Zone and CT Timeout Policy commands. */ + {"add-zone-tp", 2, 18, "", pre_get_zone, cmd_add_zone_tp, NULL, + "--may-exist", RW}, + {"del-zone-tp", 2, 2, "", pre_get_zone, cmd_del_zone_tp, NULL, + "--if-exists", RW}, + {"list-zone-tp", 1, 1, "", pre_get_zone, cmd_list_zone_tp, NULL, "", RO}, + {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO}, };