[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