[ovs-dev] [ovn-ipv6 11/26] ovn-util: Add string representations to 'lport_addresses'.

Justin Pettit jpettit at ovn.org
Tue Jul 12 06:56:41 UTC 2016


A future commit will reduce the amount of conversions used by the
existing users of 'lport_addresses'.  This change will also make it
possible to use this structure for logical router port networks.

Signed-off-by: Justin Pettit <jpettit at ovn.org>
---
 ovn/controller/pinctrl.c |  2 +-
 ovn/lib/ovn-util.c       | 74 +++++++++++++++++++++++++++++++++++++-----------
 ovn/lib/ovn-util.h       | 32 ++++++++++++++-------
 ovn/northd/ovn-northd.c  | 13 ++++-----
 4 files changed, 86 insertions(+), 35 deletions(-)

diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c
index 0b5922c..5f0fd81 100644
--- a/ovn/controller/pinctrl.c
+++ b/ovn/controller/pinctrl.c
@@ -747,7 +747,7 @@ send_garp_update(const struct sbrec_port_binding *binding_rec,
         garp->ofport = ofport;
         shash_add(&send_garp_data, binding_rec->logical_port, garp);
 
-        free(laddrs.ipv4_addrs);
+        destroy_lport_addresses(&laddrs);
         break;
     }
 }
diff --git a/ovn/lib/ovn-util.c b/ovn/lib/ovn-util.c
index 6e94083..5499c45 100644
--- a/ovn/lib/ovn-util.c
+++ b/ovn/lib/ovn-util.c
@@ -23,11 +23,14 @@ VLOG_DEFINE_THIS_MODULE(ovn_util);
  * Extracts the mac, ipv4 and ipv6 addresses from the input param 'address'
  * which should be of the format 'MAC [IP1 IP2 ..]" where IPn should be
  * a valid IPv4 or IPv6 address and stores them in the 'ipv4_addrs' and
- * 'ipv6_addrs' fields of input param 'laddrs'.
- * The caller has to free the 'ipv4_addrs' and 'ipv6_addrs' fields.
- * If input param 'store_ipv6' is true only then extracted ipv6 addresses
- * are stored in 'ipv6_addrs' fields.
+ * 'ipv6_addrs' fields of input param 'laddrs'.  If input param
+ * 'store_ipv6' is true only then extracted ipv6 addresses are stored in
+ * 'ipv6_addrs' fields.
+ *
  * Return true if at least 'MAC' is found in 'address', false otherwise.
+ *
+ * The caller must call destroy_lport_addresses().
+ *
  * Eg 1.
  * If 'address' = '00:00:00:00:00:01 10.0.0.4 fe80::ea2a:eaff:fe28:3390/64
  *                 30.0.0.3/23' and 'store_ipv6' = true
@@ -45,24 +48,24 @@ bool
 extract_lsp_addresses(char *address, struct lport_addresses *laddrs,
                       bool store_ipv6)
 {
+    memset(laddrs, 0, sizeof *laddrs);
+
     char *buf = address;
     int buf_index = 0;
     char *buf_end = buf + strlen(address);
     if (!ovs_scan_len(buf, &buf_index, ETH_ADDR_SCAN_FMT,
                       ETH_ADDR_SCAN_ARGS(laddrs->ea))) {
+        laddrs->ea = eth_addr_zero;
         return false;
     }
 
+    laddrs->ea_s = xasprintf(ETH_ADDR_FMT, ETH_ADDR_ARGS(laddrs->ea));
+
     ovs_be32 ip4;
     struct in6_addr ip6;
     unsigned int plen;
     char *error;
 
-    laddrs->n_ipv4_addrs = 0;
-    laddrs->n_ipv6_addrs = 0;
-    laddrs->ipv4_addrs = NULL;
-    laddrs->ipv6_addrs = NULL;
-
     /* Loop through the buffer and extract the IPv4/IPv6 addresses
      * and store in the 'laddrs'. Break the loop if invalid data is found.
      */
@@ -72,11 +75,21 @@ extract_lsp_addresses(char *address, struct lport_addresses *laddrs,
         error = ip_parse_cidr_len(buf, &buf_index, &ip4, &plen);
         if (!error) {
             laddrs->n_ipv4_addrs++;
-            laddrs->ipv4_addrs = xrealloc(
-                laddrs->ipv4_addrs,
+            laddrs->ipv4_addrs = xrealloc(laddrs->ipv4_addrs,
                 sizeof (struct ipv4_netaddr) * laddrs->n_ipv4_addrs);
-            laddrs->ipv4_addrs[laddrs->n_ipv4_addrs - 1].addr = ip4;
-            laddrs->ipv4_addrs[laddrs->n_ipv4_addrs - 1].plen = plen;
+
+            struct ipv4_netaddr *na
+                = &laddrs->ipv4_addrs[laddrs->n_ipv4_addrs - 1];
+
+            na->addr = ip4;
+            na->mask = be32_prefix_mask(plen);
+            na->network = ip4 & na->mask;
+            na->plen = plen;
+
+            na->addr_s = xasprintf(IP_FMT, IP_ARGS(ip4));
+            na->network_s = xasprintf(IP_FMT, IP_ARGS(na->network));
+            na->bcast_s = xasprintf(IP_FMT, IP_ARGS(ip4 | ~na->mask));
+
             buf += buf_index;
             continue;
         }
@@ -87,9 +100,19 @@ extract_lsp_addresses(char *address, struct lport_addresses *laddrs,
             laddrs->ipv6_addrs = xrealloc(
                 laddrs->ipv6_addrs,
                 sizeof(struct ipv6_netaddr) * laddrs->n_ipv6_addrs);
-            memcpy(&laddrs->ipv6_addrs[laddrs->n_ipv6_addrs - 1].addr, &ip6,
-                   sizeof(struct in6_addr));
-            laddrs->ipv6_addrs[laddrs->n_ipv6_addrs - 1].plen = plen;
+
+            struct ipv6_netaddr *na
+                = &laddrs->ipv6_addrs[laddrs->n_ipv6_addrs - 1];
+
+            memcpy(&na->addr, &ip6, sizeof(struct in6_addr));
+            na->mask = ipv6_create_mask(plen);
+            na->network = ipv6_addr_bitand(&ip6, &na->mask);
+            na->plen = plen;
+
+            na->addr_s = xmalloc(INET6_ADDRSTRLEN);
+            inet_ntop(AF_INET6, &ip6, na->addr_s, INET6_ADDRSTRLEN);
+            na->network_s = xmalloc(INET6_ADDRSTRLEN);
+            inet_ntop(AF_INET6, &na->network, na->network_s, INET6_ADDRSTRLEN);
         }
 
         if (error) {
@@ -104,6 +127,25 @@ extract_lsp_addresses(char *address, struct lport_addresses *laddrs,
     return true;
 }
 
+void
+destroy_lport_addresses(struct lport_addresses *laddrs)
+{
+    free(laddrs->ea_s);
+
+    for (int i = 0; i < laddrs->n_ipv4_addrs; i++) {
+        free(laddrs->ipv4_addrs[i].addr_s);
+        free(laddrs->ipv4_addrs[i].network_s);
+        free(laddrs->ipv4_addrs[i].bcast_s);
+    }
+    free(laddrs->ipv4_addrs);
+
+    for (int i = 0; i < laddrs->n_ipv6_addrs; i++) {
+        free(laddrs->ipv6_addrs[i].addr_s);
+        free(laddrs->ipv6_addrs[i].network_s);
+    }
+    free(laddrs->ipv6_addrs);
+}
+
 /* Allocates a key for NAT conntrack zone allocation for a provided
  * 'key' record and a 'type'.
  *
diff --git a/ovn/lib/ovn-util.h b/ovn/lib/ovn-util.h
index 98b1426..318b082 100644
--- a/ovn/lib/ovn-util.h
+++ b/ovn/lib/ovn-util.h
@@ -18,19 +18,29 @@
 
 #include "lib/packets.h"
 
-struct sbrec_port_binding;
-
 struct ipv4_netaddr {
-    ovs_be32 addr;
-    unsigned int plen;
+    ovs_be32 addr;            /* 192.168.10.123 */
+    ovs_be32 mask;            /* 255.255.255.0 */
+    ovs_be32 network;         /* 192.168.10.0 */
+    unsigned int plen;        /* CIDR Prefix: 24. */
+
+    char *addr_s;             /* "192.168.10.123" */
+    char *network_s;          /* "192.168.10.0" */
+    char *bcast_s;            /* "192.168.10.255" */
 };
 
 struct ipv6_netaddr {
-    struct in6_addr addr;
-    unsigned int plen;
+    struct in6_addr addr;     /* fc00::1 */
+    struct in6_addr mask;     /* ffff:ffff:ffff:ffff:: */
+    struct in6_addr network;  /* fc00:: */
+    unsigned int plen;        /* CIDR Prefix: 64 */
+
+    char *addr_s;             /* "fc00::1" */
+    char *network_s;          /* "fc00::" */
 };
 
 struct lport_addresses {
+    char *ea_s;
     struct eth_addr ea;
     size_t n_ipv4_addrs;
     struct ipv4_netaddr *ipv4_addrs;
@@ -38,10 +48,10 @@ struct lport_addresses {
     struct ipv6_netaddr *ipv6_addrs;
 };
 
-bool
-extract_lsp_addresses(char *address, struct lport_addresses *laddrs,
-                      bool store_ipv6);
 
-char *
-alloc_nat_zone_key(const char *key, const char *type);
+bool extract_lsp_addresses(char *address, struct lport_addresses *laddrs,
+                           bool store_ipv6);
+void destroy_lport_addresses(struct lport_addresses *);
+
+char *alloc_nat_zone_key(const char *key, const char *type);
 #endif
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index 19b36ac..de88806 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -1155,8 +1155,7 @@ build_port_security_nd(struct ovn_port *op, struct hmap *lflows)
                           ds_cstr(&match), "next;");
             ds_destroy(&match);
         }
-        free(ps.ipv4_addrs);
-        free(ps.ipv6_addrs);
+        destroy_lport_addresses(&ps);
     }
 
     char *match = xasprintf("inport == %s && (arp || nd)", op->json_key);
@@ -1258,7 +1257,6 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op,
             ds_put_cstr(&match, "}");
             ovn_lflow_add(lflows, op->od, stage, 90, ds_cstr(&match), "next;");
             ds_destroy(&match);
-            free(ps.ipv4_addrs);
         }
 
         if (ps.n_ipv6_addrs) {
@@ -1286,9 +1284,10 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op,
             ovn_lflow_add(lflows, op->od, stage, 90,
                           ds_cstr(&match), "next;");
             ds_destroy(&match);
-            free(ps.ipv6_addrs);
         }
 
+        destroy_lport_addresses(&ps);
+
         char *match = xasprintf(
             "%s == %s && %s == "ETH_ADDR_FMT" && ip", port_direction,
             op->json_key, pipeline == P_IN ? "eth.src" : "eth.dst",
@@ -1296,6 +1295,7 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op,
         ovn_lflow_add(lflows, op->od, stage, 80, match, "drop;");
         free(match);
     }
+
 }
 
 static bool
@@ -1894,8 +1894,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
 
             }
 
-            free(laddrs.ipv4_addrs);
-            free(laddrs.ipv6_addrs);
+            destroy_lport_addresses(&laddrs);
         }
     }
 
@@ -2594,7 +2593,7 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
                     }
                 }
 
-                free(laddrs.ipv4_addrs);
+                destroy_lport_addresses(&laddrs);
             }
         } else if (!strcmp(op->nbs->type, "router")) {
             /* This is a logical switch port that connects to a router. */
-- 
1.9.1




More information about the dev mailing list