These need to eventually expand to either:
a. [<valid-IPv6-addr>]:port
or
b. <valid-IPv6-addr>

In order to achieve that, do some pre-processing in northd.  The LB
template test cases are also updated to cover this case.  The only
affected flows were those related to LB hairpin traffic.

Fixes: b45853fba816 ("lb: Support using templates.")
Signed-off-by: Dumitru Ceara <[email protected]>
---
 include/ovn/lex.h   |  2 ++
 lib/lb.c            | 48 +++++++++++++++++++++++++++++++++++++++++----
 lib/lb.h            |  5 +++++
 lib/lex.c           |  4 ++--
 northd/northd.c     |  2 +-
 tests/system-ovn.at |  6 ++++--
 6 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/include/ovn/lex.h b/include/ovn/lex.h
index 9159b7a263..64d33361f4 100644
--- a/include/ovn/lex.h
+++ b/include/ovn/lex.h
@@ -29,6 +29,8 @@
 
 struct ds;
 
+#define LEX_TEMPLATE_PREFIX '^'
+
 /* Token type. */
 enum lex_type {
     LEX_T_END,                  /* end of input */
diff --git a/lib/lb.c b/lib/lb.c
index e0e97572f7..d20bb990db 100644
--- a/lib/lb.c
+++ b/lib/lb.c
@@ -316,11 +316,10 @@ ovn_lb_vip_destroy(struct ovn_lb_vip *vip)
     free(vip->backends);
 }
 
-void
-ovn_lb_vip_format(const struct ovn_lb_vip *vip, struct ds *s, bool template)
+static void
+ovn_lb_vip_format__(const struct ovn_lb_vip *vip, struct ds *s,
+                    bool needs_brackets)
 {
-    bool needs_brackets = vip->address_family == AF_INET6 && vip->port_str
-                          && !template;
     if (needs_brackets) {
         ds_put_char(s, '[');
     }
@@ -333,6 +332,30 @@ ovn_lb_vip_format(const struct ovn_lb_vip *vip, struct ds 
*s, bool template)
     }
 }
 
+/* Formats the VIP in the way the ovn-controller expects it, that is,
+ * template IPv6 variables need to be between brackets too.
+ */
+static char *
+ovn_lb_vip6_template_format_internal(const struct ovn_lb_vip *vip)
+{
+    struct ds s = DS_EMPTY_INITIALIZER;
+
+    if (vip->vip_str && *vip->vip_str == LEX_TEMPLATE_PREFIX) {
+        ovn_lb_vip_format__(vip, &s, true);
+    } else {
+        ovn_lb_vip_format(vip, &s, !!vip->port_str);
+    }
+    return ds_steal_cstr(&s);
+}
+
+void
+ovn_lb_vip_format(const struct ovn_lb_vip *vip, struct ds *s, bool template)
+{
+    bool needs_brackets = vip->address_family == AF_INET6 && vip->port_str
+                          && !template;
+    ovn_lb_vip_format__(vip, s, needs_brackets);
+}
+
 void
 ovn_lb_vip_backends_format(const struct ovn_lb_vip *vip, struct ds *s,
                            bool template)
@@ -515,6 +538,7 @@ ovn_northd_lb_create(const struct nbrec_load_balancer 
*nbrec_lb,
     lb->n_vips = smap_count(&nbrec_lb->vips);
     lb->vips = xcalloc(lb->n_vips, sizeof *lb->vips);
     lb->vips_nb = xcalloc(lb->n_vips, sizeof *lb->vips_nb);
+    smap_init(&lb->template_vips);
     lb->controller_event = smap_get_bool(&nbrec_lb->options, "event", false);
 
     bool routable = smap_get_bool(&nbrec_lb->options, "add_route", false);
@@ -566,6 +590,12 @@ ovn_northd_lb_create(const struct nbrec_load_balancer 
*nbrec_lb,
         } else {
             sset_add(&lb->ips_v6, lb_vip->vip_str);
         }
+
+        if (lb->template && address_family == AF_INET6) {
+            smap_add_nocopy(&lb->template_vips,
+                            ovn_lb_vip6_template_format_internal(lb_vip),
+                            xstrdup(node->value));
+        }
         n_vips++;
     }
 
@@ -610,6 +640,15 @@ ovn_northd_lb_find(const struct hmap *lbs, const struct 
uuid *uuid)
     return NULL;
 }
 
+const struct smap *
+ovn_northd_lb_get_vips(const struct ovn_northd_lb *lb)
+{
+    if (!smap_is_empty(&lb->template_vips)) {
+        return &lb->template_vips;
+    }
+    return &lb->nlb->vips;
+}
+
 void
 ovn_northd_lb_add_lr(struct ovn_northd_lb *lb, size_t n,
                      struct ovn_datapath **ods)
@@ -637,6 +676,7 @@ ovn_northd_lb_destroy(struct ovn_northd_lb *lb)
     }
     free(lb->vips);
     free(lb->vips_nb);
+    smap_destroy(&lb->template_vips);
     sset_destroy(&lb->ips_v4);
     sset_destroy(&lb->ips_v6);
     free(lb->selection_fields);
diff --git a/lib/lb.h b/lib/lb.h
index 7594553d53..657a1c8da9 100644
--- a/lib/lb.h
+++ b/lib/lb.h
@@ -19,6 +19,7 @@
 
 #include <sys/types.h>
 #include <netinet/in.h>
+#include "lib/smap.h"
 #include "openvswitch/hmap.h"
 #include "ovn-util.h"
 #include "sset.h"
@@ -62,6 +63,9 @@ struct ovn_northd_lb {
     char *selection_fields;
     struct ovn_lb_vip *vips;
     struct ovn_northd_lb_vip *vips_nb;
+    struct smap template_vips; /* Slightly changed template VIPs, populated
+                                * if needed.  Until now it's only required
+                                * for IPv6 template load balancers. */
     size_t n_vips;
 
     enum lb_neighbor_responder_mode neigh_mode;
@@ -129,6 +133,7 @@ struct ovn_northd_lb *ovn_northd_lb_create(const struct 
nbrec_load_balancer *,
                                            size_t n_datapaths);
 struct ovn_northd_lb *ovn_northd_lb_find(const struct hmap *,
                                          const struct uuid *);
+const struct smap *ovn_northd_lb_get_vips(const struct ovn_northd_lb *);
 void ovn_northd_lb_destroy(struct ovn_northd_lb *);
 void ovn_northd_lb_add_lr(struct ovn_northd_lb *lb, size_t n,
                           struct ovn_datapath **ods);
diff --git a/lib/lex.c b/lib/lex.c
index 5251868b5a..a8b9812bbb 100644
--- a/lib/lex.c
+++ b/lib/lex.c
@@ -782,7 +782,7 @@ next:
         p = lex_parse_port_group(p, token);
         break;
 
-    case '^':
+    case LEX_TEMPLATE_PREFIX:
         p = lex_parse_template(p, token);
         break;
 
@@ -1061,7 +1061,7 @@ lexer_parse_template_string(const char *s, const struct 
smap *template_vars,
                             struct sset *template_vars_ref)
 {
     /* No '^' means no templates. */
-    if (!strchr(s, '^')) {
+    if (!strchr(s, LEX_TEMPLATE_PREFIX)) {
         return lex_str_use(s);
     }
 
diff --git a/northd/northd.c b/northd/northd.c
index 79f65e6e8d..345d80d373 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -4448,7 +4448,7 @@ sync_lbs(struct northd_input *input_data, struct 
ovsdb_idl_txn *ovnsb_txn,
 
         /* Update columns. */
         sbrec_load_balancer_set_name(lb->slb, lb->nlb->name);
-        sbrec_load_balancer_set_vips(lb->slb, &lb->nlb->vips);
+        sbrec_load_balancer_set_vips(lb->slb, ovn_northd_lb_get_vips(lb));
         sbrec_load_balancer_set_protocol(lb->slb, lb->nlb->protocol);
         sbrec_load_balancer_set_datapath_group(lb->slb, dpg->dp_group);
         sbrec_load_balancer_set_options(lb->slb, &options);
diff --git a/tests/system-ovn.at b/tests/system-ovn.at
index 2ece0f571b..cee1fd9218 100644
--- a/tests/system-ovn.at
+++ b/tests/system-ovn.at
@@ -9510,7 +9510,8 @@ name: 'vport' value: '666'
 # Start IPv4 TCP server on vm1.
 NETNS_DAEMONIZE([vm1], [nc -k -l 42.42.42.2 4242], [nc-vm1.pid])
 
-# Make sure connecting to the VIP works.
+# Make sure connecting to the VIP works (hairpin, via ls and via lr).
+NS_CHECK_EXEC([vm1], [nc 66.66.66.66 666 -z], [0], [ignore], [ignore])
 NS_CHECK_EXEC([vm2], [nc 66.66.66.66 666 -z], [0], [ignore], [ignore])
 NS_CHECK_EXEC([vm3], [nc 66.66.66.66 666 -z], [0], [ignore], [ignore])
 
@@ -9603,7 +9604,8 @@ name: 'vport' value: '666'
 # Start IPv6 TCP server on vm1.
 NETNS_DAEMONIZE([vm1], [nc -k -l 4242::2 4242], [nc-vm1.pid])
 
-# Make sure connecting to the VIP works.
+# Make sure connecting to the VIP works (hairpin, via ls and via lr).
+NS_CHECK_EXEC([vm1], [nc 6666::1 666 -z], [0], [ignore], [ignore])
 NS_CHECK_EXEC([vm2], [nc 6666::1 666 -z], [0], [ignore], [ignore])
 NS_CHECK_EXEC([vm3], [nc 6666::1 666 -z], [0], [ignore], [ignore])
 
-- 
2.31.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to