@@ -600,13 +600,15 @@
Creates a new load balancer named <var>lb</var> with the provided
<var>vip</var> and <var>ips</var> or adds the <var>vip</var> to
an existing <var>lb</var>. <var>vip</var> should be a
- virtual IPv4 address (or an IPv4 address and a port number with
+ virtual IP address (or an IP address and a port number with
<code>:</code> as a separator). Examples for <var>vip</var> are
- <code>192.168.1.4</code> and <code>192.168.1.5:8080</code>.
- <var>ips</var> should be comma separated IPv4 endpoints (or comma
- separated IPv4 addresses and port numbers with <code>:</code> as a
- separator). Examples for <var>ips</var> are <code>10.0.0.1,10.0.0.2
- </code>or <code>20.0.0.10:8800,20.0.0.11:8800</code>.
+ <code>192.168.1.4</code>, <code>fd0f::1</code>, and
+ <code>192.168.1.5:8080</code>. <var>ips</var> should be comma
+ separated IP endpoints (or comma separated IP addresses and port
+ numbers with <code>:</code> as a separator). <var>ips</var> must
+ be the same address family as <var>vip</var>. Examples for
+ <var>ips</var> are <code>10.0.0.1,10.0.0.2</code>or
+ <code>[fdef::1]:8800,[fdef::2]:8800</code>.
</p>
<p>
@@ -1548,40 +1548,76 @@ nbctl_lb_add(struct ctl_context *ctx)
}
}
- ovs_be32 ipv4 = 0;
- ovs_be16 port = 0;
- char *error = ip_parse_port(lb_vip, &ipv4, &port);
+ struct sockaddr_storage ss_vip;
+ char *error;
+ error = ipv46_parse(lb_vip, PORT_OPTIONAL, &ss_vip);
if (error) {
free(error);
- if (!ip_parse(lb_vip, &ipv4)) {
- ctl_fatal("%s: should be an IPv4 address (or an IPv4 address "
- "and a port number with : as a separator).", lb_vip);
+ ctl_fatal("%s: should be an IP address (or an IP address "
+ "and a port number with : as a separator).", lb_vip);
+ }
+
+ char lb_vip_normalized[INET6_ADDRSTRLEN + 8];
+ char normalized_ip[INET6_ADDRSTRLEN];
+ if (ss_vip.ss_family == AF_INET) {
+ struct sockaddr_in *sin = ALIGNED_CAST(struct sockaddr_in *, &ss_vip);
+ inet_ntop(AF_INET, &sin->sin_addr, normalized_ip,
+ sizeof normalized_ip);
+ if (sin->sin_port) {
+ is_vip_with_port = true;
+ snprintf(lb_vip_normalized, sizeof lb_vip_normalized, "%s:%d",
+ normalized_ip, ntohs(sin->sin_port));
+ } else {
+ is_vip_with_port = false;
+ ovs_strlcpy(lb_vip_normalized, normalized_ip,
+ sizeof lb_vip_normalized);
}
-
- if (is_update_proto) {
- ctl_fatal("Protocol is unnecessary when no port of vip "
- "is given.");
+ } else {
+ struct sockaddr_in6 *sin6 = ALIGNED_CAST(struct sockaddr_in6 *,
+ &ss_vip);
+ inet_ntop(AF_INET6, &sin6->sin6_addr, normalized_ip,
+ sizeof normalized_ip);
+ if (sin6->sin6_port) {
+ is_vip_with_port = true;
+ snprintf(lb_vip_normalized, sizeof lb_vip_normalized, "[%s]:%d",
+ normalized_ip, ntohs(sin6->sin6_port));
+ } else {
+ is_vip_with_port = false;
+ ovs_strlcpy(lb_vip_normalized, normalized_ip,
+ sizeof lb_vip_normalized);
}
- is_vip_with_port = false;
+ }
+
+ if (!is_vip_with_port && is_update_proto) {
+ ctl_fatal("Protocol is unnecessary when no port of vip "
+ "is given.");
}
char *token = NULL, *save_ptr = NULL;
struct ds lb_ips_new = DS_EMPTY_INITIALIZER;
for (token = strtok_r(lb_ips, ",", &save_ptr);
token != NULL; token = strtok_r(NULL, ",", &save_ptr)) {
- if (is_vip_with_port) {
- error = ip_parse_port(token, &ipv4, &port);
- if (error) {
- free(error);
- ds_destroy(&lb_ips_new);
- ctl_fatal("%s: should be an IPv4 address and a port "
+ struct sockaddr_storage ss_dst;
+
+ error = ipv46_parse(token, is_vip_with_port
+ ? PORT_REQUIRED
+ : PORT_FORBIDDEN,
+ &ss_dst);
+
+ if (error) {
+ free(error);
+ if (is_vip_with_port) {
+ ctl_fatal("%s: should be an IP address and a port "
"number with : as a separator.", token);
+ } else {
+ ctl_fatal("%s: should be an IP address.", token);
}
- } else {
- if (!ip_parse(token, &ipv4)) {
- ds_destroy(&lb_ips_new);
- ctl_fatal("%s: should be an IPv4 address.", token);
- }
+ }
+
+ if (ss_vip.ss_family != ss_dst.ss_family) {
+ ds_destroy(&lb_ips_new);
+ ctl_fatal("%s: IP address family is different from VIP %s.",
+ token, lb_vip_normalized);
}
ds_put_format(&lb_ips_new, "%s%s",
lb_ips_new.length ? "," : "", token);
@@ -1591,19 +1627,19 @@ nbctl_lb_add(struct ctl_context *ctx)
if (!add_duplicate) {
lb = lb_by_name_or_uuid(ctx, lb_name, false);
if (lb) {
- if (smap_get(&lb->vips, lb_vip)) {
+ if (smap_get(&lb->vips, lb_vip_normalized)) {
if (!may_exist) {
ds_destroy(&lb_ips_new);
ctl_fatal("%s: a load balancer with this vip (%s) "
- "already exists", lb_name, lb_vip);
+ "already exists", lb_name, lb_vip_normalized);
}
/* Update the vips. */
smap_replace(CONST_CAST(struct smap *, &lb->vips),
- lb_vip, ds_cstr(&lb_ips_new));
+ lb_vip_normalized, ds_cstr(&lb_ips_new));
} else {
/* Add the new vips. */
smap_add(CONST_CAST(struct smap *, &lb->vips),
- lb_vip, ds_cstr(&lb_ips_new));
+ lb_vip_normalized, ds_cstr(&lb_ips_new));
}
/* Update the load balancer. */
@@ -1623,7 +1659,7 @@ nbctl_lb_add(struct ctl_context *ctx)
nbrec_load_balancer_set_name(lb, lb_name);
nbrec_load_balancer_set_protocol(lb, lb_proto);
smap_add(CONST_CAST(struct smap *, &lb->vips),
- lb_vip, ds_cstr(&lb_ips_new));
+ lb_vip_normalized, ds_cstr(&lb_ips_new));
nbrec_load_balancer_set_vips(lb, &lb->vips);
ds_destroy(&lb_ips_new);
}
@@ -1665,32 +1701,49 @@ nbctl_lb_del(struct ctl_context *ctx)
static void
lb_info_add_smap(const struct nbrec_load_balancer *lb,
- struct smap *lbs)
+ struct smap *lbs, int vip_width)
{
struct ds key = DS_EMPTY_INITIALIZER;
struct ds val = DS_EMPTY_INITIALIZER;
char *error, *protocol;
- ovs_be32 ipv4 = 0;
- ovs_be16 port = 0;
const struct smap_node **nodes = smap_sort(&lb->vips);
if (nodes) {
for (int i = 0; i < smap_count(&lb->vips); i++) {
const struct smap_node *node = nodes[i];
protocol = lb->protocol;
- error = ip_parse_port(node->key, &ipv4, &port);
+
+ struct sockaddr_storage ss;
+ error = ipv46_parse(node->key, PORT_OPTIONAL, &ss);
if (error) {
+ VLOG_WARN("%s", error);
free(error);
- protocol = "tcp/udp";
+ continue;
+ }
+
+ if (ss.ss_family == AF_INET) {
+ struct sockaddr_in *sin = ALIGNED_CAST(struct sockaddr_in *,
+ &ss);
+ if (!sin->sin_port) {
+ protocol = "tcp/udp";
+ }
+ } else {
+ struct sockaddr_in6 *sin6 = ALIGNED_CAST(struct sockaddr_in6 *,
+ &ss);
+ if (!sin6->sin6_port) {
+ protocol = "tcp/udp";
+ }
}
i == 0 ? ds_put_format(&val,
- UUID_FMT " %-20.16s%-11.7s%-25.21s%s",
+ UUID_FMT " %-20.16s%-11.7s%-*.*s%s",
UUID_ARGS(&lb->header_.uuid),
lb->name, protocol,
+ vip_width + 4, vip_width,
node->key, node->value)
- : ds_put_format(&val, "\n%60s%-11.7s%-25.21s%s",
+ : ds_put_format(&val, "\n%60s%-11.7s%-*.*s%s",
"", protocol,
+ vip_width + 4, vip_width,
node->key, node->value);
}
@@ -1704,12 +1757,12 @@ lb_info_add_smap(const struct nbrec_load_balancer *lb,
}
static void
-lb_info_print(struct ctl_context *ctx, struct smap *lbs)
+lb_info_print(struct ctl_context *ctx, struct smap *lbs, int vip_width)
{
const struct smap_node **nodes = smap_sort(lbs);
if (nodes) {
- ds_put_format(&ctx->output, "%-40.36s%-20.16s%-11.7s%-25.21s%s\n",
- "UUID", "LB", "PROTO", "VIP", "IPs");
+ ds_put_format(&ctx->output, "%-40.36s%-20.16s%-11.7s%-*.*s%s\n",
+ "UUID", "LB", "PROTO", vip_width + 4, vip_width, "VIP", "IPs");
for (size_t i = 0; i < smap_count(lbs); i++) {
const struct smap_node *node = nodes[i];
ds_put_format(&ctx->output, "%s\n", node->value);
@@ -1719,21 +1772,45 @@ lb_info_print(struct ctl_context *ctx, struct smap *lbs)
}
}
+static int
+lb_get_max_vip_length(const struct nbrec_load_balancer *lb, int vip_width)
+{
+ const struct smap_node *node;
+ int max_length = vip_width;
+
+ SMAP_FOR_EACH (node, &lb->vips) {
+ size_t keylen = strlen(node->key);
+ if (max_length < keylen) {
+ max_length = keylen;
+ }
+ }
+
+ return max_length;
+}
+
static void
lb_info_list_all(struct ctl_context *ctx,
const char *lb_name, bool lb_check)
{
const struct nbrec_load_balancer *lb;
struct smap lbs = SMAP_INITIALIZER(&lbs);
+ int vip_width = 0;
+
+ NBREC_LOAD_BALANCER_FOR_EACH (lb, ctx->idl) {
+ if (lb_check && strcmp(lb->name, lb_name)) {
+ continue;
+ }
+ vip_width = lb_get_max_vip_length(lb, vip_width);
+ }
NBREC_LOAD_BALANCER_FOR_EACH(lb, ctx->idl) {
if (lb_check && strcmp(lb->name, lb_name)) {
continue;
}
- lb_info_add_smap(lb, &lbs);
+ lb_info_add_smap(lb, &lbs, vip_width);
}
- lb_info_print(ctx, &lbs);
+ lb_info_print(ctx, &lbs, vip_width);
smap_destroy(&lbs);
}
@@ -1832,15 +1909,21 @@ nbctl_lr_lb_list(struct ctl_context *ctx)
const char *lr_name = ctx->argv[1];
const struct nbrec_logical_router *lr;
struct smap lbs = SMAP_INITIALIZER(&lbs);
+ int vip_width = 0;
lr = lr_by_name_or_uuid(ctx, lr_name, true);
for (int i = 0; i < lr->n_load_balancer; i++) {
const struct nbrec_load_balancer *lb
= lr->load_balancer[i];
- lb_info_add_smap(lb, &lbs);
+ vip_width = lb_get_max_vip_length(lb, vip_width);
+ }
+ for (int i = 0; i < lr->n_load_balancer; i++) {
+ const struct nbrec_load_balancer *lb
+ = lr->load_balancer[i];
+ lb_info_add_smap(lb, &lbs, vip_width);
}
- lb_info_print(ctx, &lbs);
+ lb_info_print(ctx, &lbs, vip_width);
smap_destroy(&lbs);
}
@@ -1929,15 +2012,21 @@ nbctl_ls_lb_list(struct ctl_context *ctx)
const char *ls_name = ctx->argv[1];
const struct nbrec_logical_switch *ls;
struct smap lbs = SMAP_INITIALIZER(&lbs);
+ int vip_width = 0;
ls = ls_by_name_or_uuid(ctx, ls_name, true);
for (int i = 0; i < ls->n_load_balancer; i++) {
const struct nbrec_load_balancer *lb
= ls->load_balancer[i];
- lb_info_add_smap(lb, &lbs);
+ vip_width = lb_get_max_vip_length(lb, vip_width);
+ }
+ for (int i = 0; i < ls->n_load_balancer; i++) {
+ const struct nbrec_load_balancer *lb
+ = ls->load_balancer[i];
+ lb_info_add_smap(lb, &lbs, vip_width);
}
- lb_info_print(ctx, &lbs);
+ lb_info_print(ctx, &lbs, vip_width);
smap_destroy(&lbs);
}
@@ -399,47 +399,43 @@ OVN_NBCTL_TEST_START
dnl Add two LBs.
AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10:80a 192.168.10.10:80,192.168.10.20:80 tcp], [1], [],
-[ovn-nbctl: 30.0.0.10:80a: should be an IPv4 address (or an IPv4 address and a port number with : as a separator).
+[ovn-nbctl: 30.0.0.10:80a: should be an IP address (or an IP address and a port number with : as a separator).
])
AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10:a80 192.168.10.10:80,192.168.10.20:80 tcp], [1], [],
-[ovn-nbctl: 30.0.0.10:a80: should be an IPv4 address (or an IPv4 address and a port number with : as a separator).
+[ovn-nbctl: 30.0.0.10:a80: should be an IP address (or an IP address and a port number with : as a separator).
])
AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10: 192.168.10.10:80,192.168.10.20:80 tcp], [1], [],
-[ovn-nbctl: 30.0.0.10:: should be an IPv4 address (or an IPv4 address and a port number with : as a separator).
+[ovn-nbctl: 30.0.0.10:: should be an IP address (or an IP address and a port number with : as a separator).
])
AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10:80 192.168.10.10:80,192.168.10.20 tcp], [1], [],
-[ovn-nbctl: 192.168.10.20: should be an IPv4 address and a port number with : as a separator.
+[ovn-nbctl: 192.168.10.20: should be an IP address and a port number with : as a separator.
])
AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.1a 192.168.10.10:80,192.168.10.20:80], [1], [],
-[ovn-nbctl: 30.0.0.1a: should be an IPv4 address (or an IPv4 address and a port number with : as a separator).
+[ovn-nbctl: 30.0.0.1a: should be an IP address (or an IP address and a port number with : as a separator).
])
AT_CHECK([ovn-nbctl lb-add lb0 30.0.0 192.168.10.10:80,192.168.10.20:80], [1], [],
-[ovn-nbctl: 30.0.0: should be an IPv4 address (or an IPv4 address and a port number with : as a separator).
+[ovn-nbctl: 192.168.10.10:80: should be an IP address.
])
AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 192.168.10.10,192.168.10.20:80], [1], [],
-[ovn-nbctl: 192.168.10.20:80: should be an IPv4 address.
+[ovn-nbctl: 192.168.10.20:80: should be an IP address.
])
AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 192.168.10.10:a80], [1], [],
-[ovn-nbctl: 192.168.10.10:a80: should be an IPv4 address.
+[ovn-nbctl: 192.168.10.10:a80: should be an IP address.
])
AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 192.168.10.10:], [1], [],
-[ovn-nbctl: 192.168.10.10:: should be an IPv4 address.
+[ovn-nbctl: 192.168.10.10:: should be an IP address.
])
AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 192.168.10.1a], [1], [],
-[ovn-nbctl: 192.168.10.1a: should be an IPv4 address.
-])
-
-AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 192.168.10], [1], [],
-[ovn-nbctl: 192.168.10: should be an IPv4 address.
+[ovn-nbctl: 192.168.10.1a: should be an IP address.
])
AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 192.168.10.10 tcp], [1], [],
@@ -454,9 +450,9 @@ dnl Add ips to lb
AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10:80 ,,,192.168.10.10:80,,,,,])
AT_CHECK([ovn-nbctl lb-add lb1 30.0.0.10:80 ,,,192.168.10.10:80,,,,192.168.10.20:80,,,,])
AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
-UUID LB PROTO VIP IPs
-<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80
-<1> lb1 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+UUID LB PROTO VIP IPs
+<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80
+<1> lb1 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
])
AT_CHECK([ovn-nbctl lb-del lb0])
AT_CHECK([ovn-nbctl lb-del lb1])
@@ -464,51 +460,51 @@ AT_CHECK([ovn-nbctl lb-del lb1])
AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80])
AT_CHECK([ovn-nbctl lb-add lb1 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80 tcp])
AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
-UUID LB PROTO VIP IPs
-<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
-<1> lb1 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+UUID LB PROTO VIP IPs
+<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+<1> lb1 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
])
dnl Update the VIP of the lb1.
AT_CHECK([ovn-nbctl --may-exist lb-add lb1 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080])
AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
-UUID LB PROTO VIP IPs
-<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
-<1> lb1 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080
+UUID LB PROTO VIP IPs
+<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+<1> lb1 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080
])
AT_CHECK([ovn-nbctl --may-exist lb-add lb1 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080 udp])
AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
-UUID LB PROTO VIP IPs
-<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
-<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080
+UUID LB PROTO VIP IPs
+<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080
])
dnl Config lb1 with another VIP.
AT_CHECK([ovn-nbctl lb-add lb1 30.0.0.20:80 192.168.10.10:80 udp])
AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
-UUID LB PROTO VIP IPs
-<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
-<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080
- udp 30.0.0.20:80 192.168.10.10:80
+UUID LB PROTO VIP IPs
+<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080
+ udp 30.0.0.20:80 192.168.10.10:80
])
AT_CHECK([ovn-nbctl lb-del lb1 30.0.0.20:80])
AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
-UUID LB PROTO VIP IPs
-<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
-<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080
+UUID LB PROTO VIP IPs
+<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080
])
dnl Add LBs whose vip is just an IP address.
AT_CHECK([ovn-nbctl lb-add lb2 30.0.0.30 192.168.10.10])
AT_CHECK([ovn-nbctl lb-add lb3 30.0.0.30 192.168.10.10])
AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
-UUID LB PROTO VIP IPs
-<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
-<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080
-<2> lb2 tcp/udp 30.0.0.30 192.168.10.10
-<3> lb3 tcp/udp 30.0.0.30 192.168.10.10
+UUID LB PROTO VIP IPs
+<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080
+<2> lb2 tcp/udp 30.0.0.30 192.168.10.10
+<3> lb3 tcp/udp 30.0.0.30 192.168.10.10
])
AT_CHECK([ovn-nbctl lb-del lb2 30.0.0.30])
AT_CHECK([ovn-nbctl lb-del lb3 30.0.0.30])
@@ -516,11 +512,11 @@ AT_CHECK([ovn-nbctl lb-del lb3 30.0.0.30])
AT_CHECK([ovn-nbctl lb-add lb2 30.0.0.10:8080 192.168.10.10:80,192.168.10.20:80 tcp])
AT_CHECK([ovn-nbctl --add-duplicate lb-add lb2 30.0.0.10:8080 192.168.10.10:80,192.168.10.20:80 tcp])
AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
-UUID LB PROTO VIP IPs
-<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
-<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080
-<2> lb2 tcp 30.0.0.10:8080 192.168.10.10:80,192.168.10.20:80
-<3> lb2 tcp 30.0.0.10:8080 192.168.10.10:80,192.168.10.20:80
+UUID LB PROTO VIP IPs
+<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080
+<2> lb2 tcp 30.0.0.10:8080 192.168.10.10:80,192.168.10.20:80
+<3> lb2 tcp 30.0.0.10:8080 192.168.10.10:80,192.168.10.20:80
])
dnl If there are multiple load balancers with the same name, use a UUID to update/delete.
@@ -538,9 +534,9 @@ AT_CHECK([ovn-nbctl --may-exist lb-add lb1 30.0.0.10:9090 192.168.10.10:8080,192
AT_CHECK([ovn-nbctl lb-del lb0 30.0.0.10:80])
AT_CHECK([ovn-nbctl lb-del lb1])
AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
-UUID LB PROTO VIP IPs
-<0> lb2 tcp 30.0.0.10:8080 192.168.10.10:80,192.168.10.20:80
-<1> lb2 tcp 30.0.0.10:8080 192.168.10.10:80,192.168.10.20:80
+UUID LB PROTO VIP IPs
+<0> lb2 tcp 30.0.0.10:8080 192.168.10.10:80,192.168.10.20:80
+<1> lb2 tcp 30.0.0.10:8080 192.168.10.10:80,192.168.10.20:80
])
dnl Add load balancer to logical switch.
@@ -557,17 +553,17 @@ AT_CHECK([ovn-nbctl ls-lb-add ls0 lb2], [1], [],
AT_CHECK([ovn-nbctl ls-lb-add ls0 lb3])
AT_CHECK([ovn-nbctl ls-lb-list ls0 | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
-UUID LB PROTO VIP IPs
-<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
-<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
-<2> lb3 tcp/udp 30.0.0.10 192.168.10.10,192.168.10.20
+UUID LB PROTO VIP IPs
+<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+<2> lb3 tcp/udp 30.0.0.10 192.168.10.10,192.168.10.20
])
AT_CHECK([ovn-nbctl ls-lb-del ls0 lb0])
AT_CHECK([ovn-nbctl ls-lb-list ls0 | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
-UUID LB PROTO VIP IPs
-<0> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
-<1> lb3 tcp/udp 30.0.0.10 192.168.10.10,192.168.10.20
+UUID LB PROTO VIP IPs
+<0> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+<1> lb3 tcp/udp 30.0.0.10 192.168.10.10,192.168.10.20
])
AT_CHECK([ovn-nbctl ls-lb-del ls0 lb1])
@@ -593,17 +589,17 @@ AT_CHECK([ovn-nbctl lr-lb-add lr0 lb2], [1], [],
AT_CHECK([ovn-nbctl lr-lb-add lr0 lb3])
AT_CHECK([ovn-nbctl lr-lb-list lr0 | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
-UUID LB PROTO VIP IPs
-<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
-<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
-<2> lb3 tcp/udp 30.0.0.10 192.168.10.10,192.168.10.20
+UUID LB PROTO VIP IPs
+<0> lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+<1> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+<2> lb3 tcp/udp 30.0.0.10 192.168.10.10,192.168.10.20
])
AT_CHECK([ovn-nbctl lr-lb-del lr0 lb0])
AT_CHECK([ovn-nbctl lr-lb-list lr0 | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
-UUID LB PROTO VIP IPs
-<0> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
-<1> lb3 tcp/udp 30.0.0.10 192.168.10.10,192.168.10.20
+UUID LB PROTO VIP IPs
+<0> lb1 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
+<1> lb3 tcp/udp 30.0.0.10 192.168.10.10,192.168.10.20
])
AT_CHECK([ovn-nbctl lr-lb-del lr0 lb1])
@@ -620,7 +616,270 @@ AT_CHECK([ovn-nbctl lr-lb-list lr0 | ${PERL} $srcdir/uuidfilt.pl], [0], [])
OVN_NBCTL_TEST_STOP
AT_CLEANUP
+dnl
+dnl ---------------------------------------------------------------------
+
+AT_SETUP([ovn-nbctl - LBs IPv6])
+OVN_NBCTL_TEST_START
+
+dnl A bunch of commands that should fail
+AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:80a [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [],
+[ovn-nbctl: [[ae0f::10]]:80a: should be an IP address (or an IP address and a port number with : as a separator).
+])
+
+
+AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:a80 [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [],
+[ovn-nbctl: [[ae0f::10]]:a80: should be an IP address (or an IP address and a port number with : as a separator).
+])
+
+
+AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]: [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [],
+[ovn-nbctl: [[ae0f::10]]:: should be an IP address (or an IP address and a port number with : as a separator).
+])
+
+
+AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:80 [[fd0f::10]]:80,fd0f::20 tcp], [1], [],
+[ovn-nbctl: fd0f::20: should be an IP address and a port number with : as a separator.
+])
+
+
+AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10fff [[fd0f::10]]:80,fd0f::20 tcp], [1], [],
+[ovn-nbctl: ae0f::10fff: should be an IP address (or an IP address and a port number with : as a separator).
+])
+
+
+AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 [[fd0f::10]]:80,[[fd0f::20]]:80], [1], [],
+[ovn-nbctl: [[fd0f::10]]:80: should be an IP address.
+])
+
+
+AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 fd0f::10,[[fd0f::20]]:80], [1], [],
+[ovn-nbctl: [[fd0f::20]]:80: should be an IP address.
+])
+
+
+AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 [[fd0f::10]]:a80], [1], [],
+[ovn-nbctl: [[fd0f::10]]:a80: should be an IP address.
+])
+
+
+AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 [[fd0f::10]]:], [1], [],
+[ovn-nbctl: [[fd0f::10]]:: should be an IP address.
+])
+
+
+AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 fd0f::1001a], [1], [],
+[ovn-nbctl: fd0f::1001a: should be an IP address.
+])
+
+
+AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 fd0f::10 tcp], [1], [],
+[ovn-nbctl: Protocol is unnecessary when no port of vip is given.
+])
+
+
+AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 [[fd0f::10]]:900 tcp], [1], [],
+[ovn-nbctl: Protocol is unnecessary when no port of vip is given.
+])
+
+AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 192.168.10.10], [1], [],
+[ovn-nbctl: 192.168.10.10: IP address family is different from VIP ae0f::10.
+])
+
+AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 192.168.10.10], [1], [],
+[ovn-nbctl: 192.168.10.10: IP address family is different from VIP ae0f::10.
+])
+
+AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:80 192.168.10.10:80], [1], [],
+[ovn-nbctl: 192.168.10.10:80: IP address family is different from VIP [[ae0f::10]]:80.
+])
+
+AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 ae0f::10], [1], [],
+[ovn-nbctl: ae0f::10: IP address family is different from VIP 30.0.0.10.
+])
+
+AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10:80 [[ae0f::10]]:80], [1], [],
+[ovn-nbctl: [[ae0f::10]]:80: IP address family is different from VIP 30.0.0.10:80.
+])
+
+AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 fd0f::10])
+AT_CHECK([ovn-nbctl lb-add lb0 ae0f:0000:0000:0000:0000:0000:0000:0010 fd0f::20],
+[1], [], [ovn-nbctl: lb0: a load balancer with this vip (ae0f::10) already exists
+])
+
+AT_CHECK([ovn-nbctl lb-del lb0])
+
+dnl Add ips to lb
+AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:80 ,,,[[fd0f::10]]:80,,,,,])
+AT_CHECK([ovn-nbctl lb-add lb1 [[ae0f::10]]:80 ,,,[[fd0f::10]]:80,,,,[[fd0f::20]]:80,,,,])
+AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
+UUID LB PROTO VIP IPs
+<0> lb0 tcp [[ae0f::10]]:80 [[fd0f::10]]:80
+<1> lb1 tcp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+])
+AT_CHECK([ovn-nbctl lb-del lb0])
+AT_CHECK([ovn-nbctl lb-del lb1])
+
+
+AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80])
+AT_CHECK([ovn-nbctl lb-add lb1 [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80 tcp])
+AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
+UUID LB PROTO VIP IPs
+<0> lb0 tcp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+<1> lb1 tcp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+])
+
+dnl Update the VIP of the lb1.
+AT_CHECK([ovn-nbctl --may-exist lb-add lb1 [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:8080])
+AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
+UUID LB PROTO VIP IPs
+<0> lb0 tcp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+<1> lb1 tcp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:8080
+])
+
+AT_CHECK([ovn-nbctl --may-exist lb-add lb1 [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:8080 udp])
+AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
+UUID LB PROTO VIP IPs
+<0> lb0 tcp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+<1> lb1 udp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:8080
+])
+
+dnl Config lb1 with another VIP.
+AT_CHECK([ovn-nbctl lb-add lb1 [[ae0f::20]]:80 [[fd0f::10]]:80 udp])
+AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
+UUID LB PROTO VIP IPs
+<0> lb0 tcp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+<1> lb1 udp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:8080
+ udp [[ae0f::20]]:80 [[fd0f::10]]:80
+])
+
+AT_CHECK([ovn-nbctl lb-del lb1 [[ae0f::20]]:80])
+AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
+UUID LB PROTO VIP IPs
+<0> lb0 tcp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+<1> lb1 udp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:8080
+])
+dnl Add LBs whose vip is just an IP address.
+AT_CHECK([ovn-nbctl lb-add lb2 ae0f::30 fd0f::10])
+AT_CHECK([ovn-nbctl lb-add lb3 ae0f::30 fd0f::10])
+AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
+UUID LB PROTO VIP IPs
+<0> lb0 tcp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+<1> lb1 udp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:8080
+<2> lb2 tcp/udp ae0f::30 fd0f::10
+<3> lb3 tcp/udp ae0f::30 fd0f::10
+])
+AT_CHECK([ovn-nbctl lb-del lb2 ae0f::30])
+AT_CHECK([ovn-nbctl lb-del lb3 ae0f::30])
+
+AT_CHECK([ovn-nbctl lb-add lb2 [[ae0f::10]]:8080 [[fd0f::10]]:80,[[fd0f::20]]:80 tcp])
+AT_CHECK([ovn-nbctl --add-duplicate lb-add lb2 [[ae0f::10]]:8080 [[fd0f::10]]:80,[[fd0f::20]]:80 tcp])
+AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
+UUID LB PROTO VIP IPs
+<0> lb0 tcp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+<1> lb1 udp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:8080
+<2> lb2 tcp [[ae0f::10]]:8080 [[fd0f::10]]:80,[[fd0f::20]]:80
+<3> lb2 tcp [[ae0f::10]]:8080 [[fd0f::10]]:80,[[fd0f::20]]:80
+])
+
+dnl If there are multiple load balancers with the same name, use a UUID to update/delete.
+AT_CHECK([ovn-nbctl lb-add lb2 [[ae0f::10]]:8080 [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [],
+[ovn-nbctl: Multiple load balancers named 'lb2'. Use a UUID.
+])
+
+AT_CHECK([ovn-nbctl lb-del lb2], [1], [],
+[ovn-nbctl: Multiple load balancers named 'lb2'. Use a UUID.
+])
+
+AT_CHECK([ovn-nbctl --may-exist lb-add lb1 [[ae0f::10]]:80 [[fd0f::10]]:8080,[[fd0f::20]]:8080 udp])
+AT_CHECK([ovn-nbctl --may-exist lb-add lb1 [[ae0f::10]]:8080 [[fd0f::10]]:8080,[[fd0f::20]]:8080 udp])
+AT_CHECK([ovn-nbctl --may-exist lb-add lb1 [[ae0f::10]]:9090 [[fd0f::10]]:8080,[[fd0f::20]]:8080 udp])
+AT_CHECK([ovn-nbctl lb-del lb0 [[ae0f::10]]:80])
+AT_CHECK([ovn-nbctl lb-del lb1])
+AT_CHECK([ovn-nbctl lb-list | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
+UUID LB PROTO VIP IPs
+<0> lb2 tcp [[ae0f::10]]:8080 [[fd0f::10]]:80,[[fd0f::20]]:80
+<1> lb2 tcp [[ae0f::10]]:8080 [[fd0f::10]]:80,[[fd0f::20]]:80
+])
+
+dnl Add load balancer to logical switch.
+AT_CHECK([ovn-nbctl ls-add ls0])
+AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80])
+AT_CHECK([ovn-nbctl lb-add lb1 [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80 udp])
+AT_CHECK([ovn-nbctl lb-add lb3 ae0f::10 fd0f::10,fd0f::20])
+AT_CHECK([ovn-nbctl ls-lb-add ls0 lb0])
+AT_CHECK([ovn-nbctl ls-lb-add ls0 lb1])
+AT_CHECK([ovn-nbctl --may-exist ls-lb-add ls0 lb1])
+AT_CHECK([ovn-nbctl ls-lb-add ls0 lb2], [1], [],
+[ovn-nbctl: Multiple load balancers named 'lb2'. Use a UUID.
+])
+AT_CHECK([ovn-nbctl ls-lb-add ls0 lb3])
+
+AT_CHECK([ovn-nbctl ls-lb-list ls0 | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
+UUID LB PROTO VIP IPs
+<0> lb0 tcp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+<1> lb1 udp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+<2> lb3 tcp/udp ae0f::10 fd0f::10,fd0f::20
+])
+
+AT_CHECK([ovn-nbctl ls-lb-del ls0 lb0])
+AT_CHECK([ovn-nbctl ls-lb-list ls0 | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
+UUID LB PROTO VIP IPs
+<0> lb1 udp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+<1> lb3 tcp/udp ae0f::10 fd0f::10,fd0f::20
+])
+
+AT_CHECK([ovn-nbctl ls-lb-del ls0 lb1])
+AT_CHECK([ovn-nbctl ls-lb-del ls0 lb3])
+AT_CHECK([ovn-nbctl ls-lb-list ls0 | ${PERL} $srcdir/uuidfilt.pl], [0], [])
+AT_CHECK([ovn-nbctl --if-exists ls-lb-del ls0 lb1])
+
+dnl Remove all load balancers from logical switch.
+AT_CHECK([ovn-nbctl ls-lb-add ls0 lb0])
+AT_CHECK([ovn-nbctl ls-lb-add ls0 lb1])
+AT_CHECK([ovn-nbctl ls-lb-add ls0 lb3])
+AT_CHECK([ovn-nbctl ls-lb-del ls0])
+AT_CHECK([ovn-nbctl ls-lb-list ls0 | ${PERL} $srcdir/uuidfilt.pl], [0], [])
+
+dnl Add load balancer to logical router.
+AT_CHECK([ovn-nbctl lr-add lr0])
+AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
+AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
+AT_CHECK([ovn-nbctl --may-exist lr-lb-add lr0 lb1])
+AT_CHECK([ovn-nbctl lr-lb-add lr0 lb2], [1], [],
+[ovn-nbctl: Multiple load balancers named 'lb2'. Use a UUID.
+])
+AT_CHECK([ovn-nbctl lr-lb-add lr0 lb3])
+
+AT_CHECK([ovn-nbctl lr-lb-list lr0 | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
+UUID LB PROTO VIP IPs
+<0> lb0 tcp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+<1> lb1 udp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+<2> lb3 tcp/udp ae0f::10 fd0f::10,fd0f::20
+])
+
+AT_CHECK([ovn-nbctl lr-lb-del lr0 lb0])
+AT_CHECK([ovn-nbctl lr-lb-list lr0 | ${PERL} $srcdir/uuidfilt.pl], [0], [dnl
+UUID LB PROTO VIP IPs
+<0> lb1 udp [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80
+<1> lb3 tcp/udp ae0f::10 fd0f::10,fd0f::20
+])
+
+AT_CHECK([ovn-nbctl lr-lb-del lr0 lb1])
+AT_CHECK([ovn-nbctl lr-lb-del lr0 lb3])
+AT_CHECK([ovn-nbctl lr-lb-list lr0 | ${PERL} $srcdir/uuidfilt.pl], [0], [])
+AT_CHECK([ovn-nbctl --if-exists lr-lb-del lr0 lb1])
+
+dnl Remove all load balancers from logical router.
+AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
+AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
+AT_CHECK([ovn-nbctl lr-lb-add lr0 lb3])
+AT_CHECK([ovn-nbctl lr-lb-del lr0])
+AT_CHECK([ovn-nbctl lr-lb-list lr0 | ${PERL} $srcdir/uuidfilt.pl], [0], [])
+
+OVN_NBCTL_TEST_STOP
+AT_CLEANUP
dnl ---------------------------------------------------------------------
AT_SETUP([ovn-nbctl - basic logical router commands])
ovn-nbctl will now accept IPv6 addresses for load balancer VIPs and desetination addresses. In addition, the ovn-nbctl lb-list, lr-lb-list, and ls-lb-list have been modified to be able to fit IPv6 addresses on screen. Signed-off-by: Mark Michelson <mmichels@redhat.com> --- ovn/utilities/ovn-nbctl.8.xml | 14 +- ovn/utilities/ovn-nbctl.c | 175 ++++++++++++++----- tests/ovn-nbctl.at | 379 +++++++++++++++++++++++++++++++++++------- 3 files changed, 459 insertions(+), 109 deletions(-)