From patchwork Thu Oct 15 08:54:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Justin Pettit X-Patchwork-Id: 530564 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (li376-54.members.linode.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id EDA401402B6 for ; Thu, 15 Oct 2015 19:55:24 +1100 (AEDT) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 842A210A03; Thu, 15 Oct 2015 01:55:11 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e3.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id 6D7441099A for ; Thu, 15 Oct 2015 01:55:09 -0700 (PDT) Received: from bar5.cudamail.com (localhost [127.0.0.1]) by mx1e3.cudamail.com (Postfix) with ESMTPS id E82C34200C4 for ; Thu, 15 Oct 2015 02:55:08 -0600 (MDT) X-ASG-Debug-ID: 1444899308-09eadd28bf22020001-byXFYA Received: from mx1-pf1.cudamail.com ([192.168.24.1]) by bar5.cudamail.com with ESMTP id zf21IbBwla98MK6Y (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 15 Oct 2015 02:55:08 -0600 (MDT) X-Barracuda-Envelope-From: jpettit@nicira.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.1 Received: from unknown (HELO mail-pa0-f50.google.com) (209.85.220.50) by mx1-pf1.cudamail.com with ESMTPS (RC4-SHA encrypted); 15 Oct 2015 08:55:08 -0000 Received-SPF: unknown (mx1-pf1.cudamail.com: Multiple SPF records returned) X-Barracuda-Apparent-Source-IP: 209.85.220.50 X-Barracuda-RBL-IP: 209.85.220.50 Received: by payp3 with SMTP id p3so33963090pay.1 for ; Thu, 15 Oct 2015 01:55:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=F1KbNNkwzKi+hY77xPYJoKW9acoWS/MsVfCOG2cFHTw=; b=aljef3zU0O0UUh8+A76qynU3Y9EAlUaZRZmInSkSS16wwMUoVg6PWckPv+hFqhRaqw A0jUD3dhRxzQafZnAxGMElAjsOSQLT9sco2YhZIwrcIFN8pyfNuN65/xh8QNcNyE9Jmw RXaEDqdTa9549IO7np/Tt/4SPfSsWQa0cJg4bi13LHn0cmS+e9VHSHG9EDtUK6h7A9Eb EGT2MkvKGx67SNchiU+INS4Z19oqKxieaBpBQmy0urlrWHF1oXeOp5ZKGjFh9qPY3pem IFPnxoDs5e+nkCNRhNwPONBQFIIMyZaHkW3AcDkaI5YG7xcZ3YbFwYkO8qIUaaArNxLI Vwvg== X-Gm-Message-State: ALoCoQkNIKRtVAPcE3ZqY45fTq5e58zuD2nz6UH+ctLyucRjQvCWmhv2Jy6t8vW+g/Y8WZj8/I8J X-Received: by 10.66.254.101 with SMTP id ah5mr8889298pad.10.1444899307587; Thu, 15 Oct 2015 01:55:07 -0700 (PDT) Received: from localhost.localdomain (c-67-161-8-206.hsd1.ca.comcast.net. [67.161.8.206]) by smtp.gmail.com with ESMTPSA id ci2sm14015113pbc.66.2015.10.15.01.55.06 for (version=TLSv1/SSLv3 cipher=OTHER); Thu, 15 Oct 2015 01:55:06 -0700 (PDT) X-CudaMail-Envelope-Sender: jpettit@nicira.com From: Justin Pettit To: dev@openvswitch.org X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-E1-1014015809 X-CudaMail-DTE: 101515 X-CudaMail-Originating-IP: 209.85.220.50 Date: Thu, 15 Oct 2015 01:54:59 -0700 X-ASG-Orig-Subj: [##CM-E1-1014015809##][PATCH 4/5] ovn-controller: Support multiple encaps simultaneously. Message-Id: <1444899300-37713-4-git-send-email-jpettit@nicira.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1444899300-37713-1-git-send-email-jpettit@nicira.com> References: <1444899300-37713-1-git-send-email-jpettit@nicira.com> X-Barracuda-Connect: UNKNOWN[192.168.24.1] X-Barracuda-Start-Time: 1444899308 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-ASG-Whitelist: Header =?UTF-8?B?eFwtY3VkYW1haWxcLXdoaXRlbGlzdFwtdG8=?= X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 Subject: [ovs-dev] [PATCH 4/5] ovn-controller: Support multiple encaps simultaneously. X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Justin Pettit --- ovn/controller/chassis.c | 88 ++++++++++++++++++++++++++--------- ovn/controller/encaps.c | 20 ++++---- ovn/controller/ovn-controller.8.xml | 10 +++- ovn/controller/ovn-controller.c | 14 ++++++ ovn/controller/ovn-controller.h | 11 ++++ ovn/controller/physical.c | 2 +- 6 files changed, 109 insertions(+), 36 deletions(-) diff --git a/ovn/controller/chassis.c b/ovn/controller/chassis.c index 9d6a77a..894000d 100644 --- a/ovn/controller/chassis.c +++ b/ovn/controller/chassis.c @@ -16,6 +16,7 @@ #include #include "chassis.h" +#include "lib/dynamic-string.h" #include "lib/vswitch-idl.h" #include "openvswitch/vlog.h" #include "ovn/lib/ovn-sb-idl.h" @@ -30,6 +31,23 @@ chassis_register_ovs_idl(struct ovsdb_idl *ovs_idl) ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_external_ids); } +static const char * +pop_tunnel_name(uint32_t *type) +{ + if (*type & GENEVE) { + *type &= ~GENEVE; + return "geneve"; + } else if (*type & STT) { + *type &= ~STT; + return "stt"; + } else if (*type & VXLAN) { + *type &= ~VXLAN; + return "vxlan"; + } + + OVS_NOT_REACHED(); +} + void chassis_run(struct controller_ctx *ctx, const char *chassis_id) { @@ -40,13 +58,10 @@ chassis_run(struct controller_ctx *ctx, const char *chassis_id) const struct sbrec_chassis *chassis_rec; const struct ovsrec_open_vswitch *cfg; const char *encap_type, *encap_ip; - struct sbrec_encap *encap_rec; static bool inited = false; chassis_rec = get_chassis_by_name(ctx->ovnsb_idl, chassis_id); - /* xxx Need to support more than one encap. Also need to support - * xxx encap options. */ cfg = ovsrec_open_vswitch_first(ctx->ovs_idl); if (!cfg) { VLOG_INFO("No Open_vSwitch row defined."); @@ -60,23 +75,45 @@ chassis_run(struct controller_ctx *ctx, const char *chassis_id) return; } + char *tokstr = xstrdup(encap_type); + char *save_ptr = NULL; + char *token; + uint32_t req_tunnels = 0; + for (token = strtok_r(tokstr, ",", &save_ptr); token != NULL; + token = strtok_r(NULL, ",", &save_ptr)) { + uint32_t type = get_tunnel_type(token); + if (!type) { + VLOG_INFO("Unknown tunnel type: %s", token); + } + req_tunnels |= type; + } + free(tokstr); + if (chassis_rec) { - int i; - - for (i = 0; i < chassis_rec->n_encaps; i++) { - if (!strcmp(chassis_rec->encaps[i]->type, encap_type) - && !strcmp(chassis_rec->encaps[i]->ip, encap_ip)) { - /* Nothing changed. */ - inited = true; - return; - } else if (!inited) { - VLOG_WARN("Chassis config changing on startup, make sure " - "multiple chassis are not configured : %s/%s->%s/%s", - chassis_rec->encaps[i]->type, - chassis_rec->encaps[i]->ip, - encap_type, encap_ip); - } + uint32_t cur_tunnels = 0; + for (int i = 0; i < chassis_rec->n_encaps; i++) { + cur_tunnels |= get_tunnel_type(chassis_rec->encaps[i]->type); + } + if (req_tunnels == cur_tunnels + && !strcmp(chassis_rec->encaps[0]->ip, encap_ip)) { + /* Nothing changed. */ + inited = true; + return; + } else if (!inited) { + struct ds cur_encaps = DS_EMPTY_INITIALIZER; + for (int i = 0; i < chassis_rec->n_encaps; i++) { + ds_put_format(&cur_encaps, "%s,", + chassis_rec->encaps[i]->type); + } + ds_chomp(&cur_encaps, ','); + + VLOG_WARN("Chassis config changing on startup, make sure " + "multiple chassis are not configured : %s/%s->%s/%s", + ds_cstr(&cur_encaps), + chassis_rec->encaps[0]->ip, + encap_type, encap_ip); + ds_destroy(&cur_encaps); } } @@ -89,12 +126,19 @@ chassis_run(struct controller_ctx *ctx, const char *chassis_id) sbrec_chassis_set_name(chassis_rec, chassis_id); } - encap_rec = sbrec_encap_insert(ctx->ovnsb_idl_txn); + int n_encaps = count_1bits(req_tunnels); + struct sbrec_encap **encaps = xmalloc(n_encaps * sizeof *encaps); + for (int i = 0; i < n_encaps; i++) { + const char *type = pop_tunnel_name(&req_tunnels); + + encaps[i] = sbrec_encap_insert(ctx->ovnsb_idl_txn); - sbrec_encap_set_type(encap_rec, encap_type); - sbrec_encap_set_ip(encap_rec, encap_ip); + sbrec_encap_set_type(encaps[i], type); + sbrec_encap_set_ip(encaps[i], encap_ip); + } - sbrec_chassis_set_encaps(chassis_rec, &encap_rec, 1); + sbrec_chassis_set_encaps(chassis_rec, encaps, n_encaps); + free(encaps); inited = true; } diff --git a/ovn/controller/encaps.c b/ovn/controller/encaps.c index de1aef3..dfb11c0 100644 --- a/ovn/controller/encaps.c +++ b/ovn/controller/encaps.c @@ -210,20 +210,18 @@ bridge_delete_port(const struct ovsrec_bridge *br, static struct sbrec_encap * preferred_encap(const struct sbrec_chassis *chassis_rec) { - size_t i; - - /* For hypervisors, we only support Geneve and STT encapsulations. - * Sets are returned alphabetically, so "geneve" will be preferred - * over "stt". For gateways, we only support VXLAN encapsulation. */ - for (i = 0; i < chassis_rec->n_encaps; i++) { - if (!strcmp(chassis_rec->encaps[i]->type, "geneve") - || !strcmp(chassis_rec->encaps[i]->type, "stt") - || !strcmp(chassis_rec->encaps[i]->type, "vxlan")) { - return chassis_rec->encaps[i]; + struct sbrec_encap *best_encap = NULL; + uint32_t best_type = 0; + + for (int i = 0; i < chassis_rec->n_encaps; i++) { + uint32_t tun_type = get_tunnel_type(chassis_rec->encaps[i]->type); + if (tun_type > best_type) { + best_type = tun_type; + best_encap = chassis_rec->encaps[i]; } } - return NULL; + return best_encap; } void diff --git a/ovn/controller/ovn-controller.8.xml b/ovn/controller/ovn-controller.8.xml index b0aee10..24d34ef 100644 --- a/ovn/controller/ovn-controller.8.xml +++ b/ovn/controller/ovn-controller.8.xml @@ -104,7 +104,13 @@

The encapsulation type that a chassis should use to connect to - this node. Supported tunnel types for connecting hypervisors + this node. Multiple encapsulation types may be specified with + a comma-separated list. Each listed encapsulation type will + be paired with ovn-encap-ip. +

+ +

+ Supported tunnel types for connecting hypervisors are geneve and stt. Gateways may use geneve, vxlan, or stt. @@ -120,7 +126,7 @@

external_ids:ovn-encap-ip
The IP address that a chassis should use to connect to this node - using encapsulation type specified by + using encapsulation types specified by external_ids:ovn-encap-type.
diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index f1bc524..eca32b3 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -57,6 +57,20 @@ OVS_NO_RETURN static void usage(void); static char *ovs_remote; +uint32_t +get_tunnel_type(const char *name) +{ + if (!strcmp(name, "geneve")) { + return GENEVE; + } else if (!strcmp(name, "stt")) { + return STT; + } else if (!strcmp(name, "vxlan")) { + return VXLAN; + } + + return 0; +} + static const struct ovsrec_bridge * get_bridge(struct ovsdb_idl *ovs_idl, const char *br_name) { diff --git a/ovn/controller/ovn-controller.h b/ovn/controller/ovn-controller.h index be89b5f..8b10675 100644 --- a/ovn/controller/ovn-controller.h +++ b/ovn/controller/ovn-controller.h @@ -41,4 +41,15 @@ get_chassis_by_name(struct ovsdb_idl *ovnsb_idl, const char *chassis_id) return chassis_rec; } +/* Must be a bit-field ordered from most-preferred (higher number) to + * least-preferred (lower number). */ +enum chassis_tunnel_type { + GENEVE = 1 << 2, + STT = 1 << 1, + VXLAN = 1 << 0 +}; + +uint32_t get_tunnel_type(const char *name); + + #endif /* ovn/ovn-controller.h */ diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index b26db63..ca495c0 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -54,7 +54,7 @@ struct chassis_tunnel { struct hmap_node hmap_node; const char *chassis_id; ofp_port_t ofport; - enum chassis_tunnel_type { GENEVE, STT, VXLAN } type; + enum chassis_tunnel_type type; }; static struct chassis_tunnel *