You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
7.4 KiB
219 lines
7.4 KiB
From b37f8c15ca6ee079541b0c02ee77ce9d392b18fc Mon Sep 17 00:00:00 2001
|
|
Message-Id: <b37f8c15ca6ee079541b0c02ee77ce9d392b18fc.1538494812.git.lorenzo.bianconi@redhat.com>
|
|
In-Reply-To: <cover.1538494812.git.lorenzo.bianconi@redhat.com>
|
|
References: <cover.1538494812.git.lorenzo.bianconi@redhat.com>
|
|
From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
|
|
Date: Thu, 20 Sep 2018 16:46:02 +0200
|
|
Subject: [PATCH] OVN: add CT_LB action to ovn-trace
|
|
|
|
Add CT_LB action to ovn-trace utility in order to fix the
|
|
following ovn-trace error if a load balancer rule is added to
|
|
OVN configuration
|
|
|
|
ct_next(ct_state=est|trk /* default (use --ct to customize) */) {
|
|
*** ct_lb action not implemented;
|
|
};
|
|
|
|
Add '--lb_dst' option in order to specify the ip address to use
|
|
in VIP pool. If --lb_dst is not provided the destination ip will be
|
|
randomly choosen
|
|
|
|
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
|
|
Signed-off-by: Ben Pfaff <blp@ovn.org>
|
|
---
|
|
ovn/utilities/ovn-trace.8.xml | 18 ++++++-
|
|
ovn/utilities/ovn-trace.c | 98 +++++++++++++++++++++++++++++++++--
|
|
2 files changed, 111 insertions(+), 5 deletions(-)
|
|
|
|
--- a/ovn/utilities/ovn-trace.8.xml
|
|
+++ b/ovn/utilities/ovn-trace.8.xml
|
|
@@ -253,9 +253,17 @@
|
|
<code>ct_snat</code>) action.
|
|
</dd>
|
|
|
|
- <dt><code>ct_lb</code></dt>
|
|
+ <dt><code>ct_lb;</code></dt>
|
|
+ <dt><code>ct_lb(<var>ip</var></code>[<code>:<var>port</var></code>]...<code>);</code></dt>
|
|
<dd>
|
|
- Not yet implemented; currently implemented as a no-op.
|
|
+ Forks the pipeline. In one fork, sets <code>ip4.dst</code> (or
|
|
+ <code>ip6.dst</code>) to one of the load-balancer addresses and the
|
|
+ destination port to its associated port, if any, and sets
|
|
+ <code>ct.dnat</code> to 1. With one or more arguments, gives preference
|
|
+ to the address specified on <code>--lb-dst</code>, if any; without
|
|
+ arguments, uses the address and port specified on <code>--lb-dst</code>.
|
|
+ In the other fork, the pipeline continues without change after the
|
|
+ <code>ct_lb</code> action.
|
|
</dd>
|
|
|
|
<dt><code>ct_commit</code></dt>
|
|
@@ -424,6 +432,12 @@
|
|
</p>
|
|
</dd>
|
|
|
|
+ <dt><code>--lb-dst=</code><var>ip</var>[<code>:<var>port</var></code>]</dt>
|
|
+ <dd>
|
|
+ Sets the IP from VIP pool to use as destination of the packet.
|
|
+ <code>--lb-dst</code> is not available in daemon mode.
|
|
+ </dd>
|
|
+
|
|
<dt><code>--friendly-names</code></dt>
|
|
<dt><code>--no-friendly-names</code></dt>
|
|
<dd>
|
|
--- a/ovn/utilities/ovn-trace.c
|
|
+++ b/ovn/utilities/ovn-trace.c
|
|
@@ -46,6 +46,7 @@
|
|
#include "stream.h"
|
|
#include "unixctl.h"
|
|
#include "util.h"
|
|
+#include "random.h"
|
|
|
|
VLOG_DEFINE_THIS_MODULE(ovntrace);
|
|
|
|
@@ -77,6 +78,9 @@ static uint32_t *ct_states;
|
|
static size_t n_ct_states;
|
|
static size_t ct_state_idx;
|
|
|
|
+/* --lb-dst: load balancer destination info. */
|
|
+static struct ovnact_ct_lb_dst lb_dst;
|
|
+
|
|
/* --friendly-names, --no-friendly-names: Whether to substitute human-friendly
|
|
* port and datapath names for the awkward UUIDs typically used in the actual
|
|
* logical flows. */
|
|
@@ -187,6 +191,24 @@ parse_ct_option(const char *state_s_)
|
|
}
|
|
|
|
static void
|
|
+parse_lb_option(const char *s)
|
|
+{
|
|
+ struct sockaddr_storage ss;
|
|
+ if (!inet_parse_active(s, 0, &ss)) {
|
|
+ ovs_fatal(0, "%s: bad address", s);
|
|
+ }
|
|
+
|
|
+ lb_dst.family = ss.ss_family;
|
|
+ struct in6_addr a = ss_get_address(&ss);
|
|
+ if (ss.ss_family == AF_INET) {
|
|
+ lb_dst.ipv4 = in6_addr_get_mapped_ipv4(&a);
|
|
+ } else {
|
|
+ lb_dst.ipv6 = a;
|
|
+ }
|
|
+ lb_dst.port = ss_get_port(&ss);
|
|
+}
|
|
+
|
|
+static void
|
|
parse_options(int argc, char *argv[])
|
|
{
|
|
enum {
|
|
@@ -202,7 +224,8 @@ parse_options(int argc, char *argv[])
|
|
OPT_NO_FRIENDLY_NAMES,
|
|
DAEMON_OPTION_ENUMS,
|
|
SSL_OPTION_ENUMS,
|
|
- VLOG_OPTION_ENUMS
|
|
+ VLOG_OPTION_ENUMS,
|
|
+ OPT_LB_DST
|
|
};
|
|
static const struct option long_options[] = {
|
|
{"db", required_argument, NULL, OPT_DB},
|
|
@@ -217,6 +240,7 @@ parse_options(int argc, char *argv[])
|
|
{"no-friendly-names", no_argument, NULL, OPT_NO_FRIENDLY_NAMES},
|
|
{"help", no_argument, NULL, 'h'},
|
|
{"version", no_argument, NULL, 'V'},
|
|
+ {"lb-dst", required_argument, NULL, OPT_LB_DST},
|
|
DAEMON_LONG_OPTIONS,
|
|
VLOG_LONG_OPTIONS,
|
|
STREAM_SSL_LONG_OPTIONS,
|
|
@@ -274,6 +298,10 @@ parse_options(int argc, char *argv[])
|
|
use_friendly_names = false;
|
|
break;
|
|
|
|
+ case OPT_LB_DST:
|
|
+ parse_lb_option(optarg);
|
|
+ break;
|
|
+
|
|
case 'h':
|
|
usage();
|
|
|
|
@@ -1823,6 +1851,71 @@ execute_ct_nat(const struct ovnact_ct_na
|
|
}
|
|
|
|
static void
|
|
+execute_ct_lb(const struct ovnact_ct_lb *ct_lb,
|
|
+ const struct ovntrace_datapath *dp, struct flow *uflow,
|
|
+ enum ovnact_pipeline pipeline, struct ovs_list *super)
|
|
+{
|
|
+ struct flow ct_lb_flow = *uflow;
|
|
+
|
|
+ int family = (ct_lb_flow.dl_type == htons(ETH_TYPE_IP) ? AF_INET
|
|
+ : ct_lb_flow.dl_type == htons(ETH_TYPE_IPV6) ? AF_INET6
|
|
+ : AF_UNSPEC);
|
|
+ if (family != AF_UNSPEC) {
|
|
+ const struct ovnact_ct_lb_dst *dst = NULL;
|
|
+ if (ct_lb->n_dsts) {
|
|
+ /* For ct_lb with addresses, choose one of the addresses. */
|
|
+ int n = 0;
|
|
+ for (int i = 0; i < ct_lb->n_dsts; i++) {
|
|
+ const struct ovnact_ct_lb_dst *d = &ct_lb->dsts[i];
|
|
+ if (d->family != family) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ /* Check for the destination specified by --lb-dst, if any. */
|
|
+ if (lb_dst.family == family
|
|
+ && (family == AF_INET
|
|
+ ? d->ipv4 == lb_dst.ipv4
|
|
+ : ipv6_addr_equals(&d->ipv6, &lb_dst.ipv6))) {
|
|
+ lb_dst.family = AF_UNSPEC;
|
|
+ dst = d;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* Select a random destination as a fallback. */
|
|
+ if (!random_range(++n)) {
|
|
+ dst = d;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!dst) {
|
|
+ ovntrace_node_append(super, OVNTRACE_NODE_ERROR,
|
|
+ "*** no load balancing destination "
|
|
+ "(use --lb-dst)");
|
|
+ }
|
|
+ } else if (lb_dst.family == family) {
|
|
+ /* For ct_lb without addresses, use user-specified address. */
|
|
+ dst = &lb_dst;
|
|
+ }
|
|
+
|
|
+ if (dst) {
|
|
+ if (family == AF_INET6) {
|
|
+ ct_lb_flow.ipv6_dst = dst->ipv6;
|
|
+ } else {
|
|
+ ct_lb_flow.nw_dst = dst->ipv4;
|
|
+ }
|
|
+ if (dst->port) {
|
|
+ ct_lb_flow.tp_dst = htons(dst->port);
|
|
+ }
|
|
+ ct_lb_flow.ct_state |= CS_DST_NAT;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ struct ovntrace_node *node = ovntrace_node_append(
|
|
+ super, OVNTRACE_NODE_TRANSFORMATION, "ct_lb");
|
|
+ trace__(dp, &ct_lb_flow, ct_lb->ltable, pipeline, &node->subs);
|
|
+}
|
|
+
|
|
+static void
|
|
execute_log(const struct ovnact_log *log, struct flow *uflow,
|
|
struct ovs_list *super)
|
|
{
|
|
@@ -1910,8 +2003,7 @@ trace_actions(const struct ovnact *ovnac
|
|
break;
|
|
|
|
case OVNACT_CT_LB:
|
|
- ovntrace_node_append(super, OVNTRACE_NODE_ERROR,
|
|
- "*** ct_lb action not implemented");
|
|
+ execute_ct_lb(ovnact_get_CT_LB(a), dp, uflow, pipeline, super);
|
|
break;
|
|
|
|
case OVNACT_CT_CLEAR:
|