From patchwork Tue Jul 12 06:56:41 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Justin Pettit X-Patchwork-Id: 647311 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3rpdJR3LLrz9s9N for ; Tue, 12 Jul 2016 20:20:23 +1000 (AEST) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 8914E1067C; Tue, 12 Jul 2016 03:20:22 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e4.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id 2D12810399 for ; Tue, 12 Jul 2016 03:20:21 -0700 (PDT) Received: from bar5.cudamail.com (unknown [192.168.21.12]) by mx1e4.cudamail.com (Postfix) with ESMTPS id B59E21E0644 for ; Tue, 12 Jul 2016 04:20:20 -0600 (MDT) X-ASG-Debug-ID: 1468318819-09eadd72150c260001-byXFYA Received: from mx3-pf2.cudamail.com ([192.168.14.1]) by bar5.cudamail.com with ESMTP id FUKfIQjRdfZA8Z8I (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 12 Jul 2016 04:20:20 -0600 (MDT) X-Barracuda-Envelope-From: jpettit@ovn.org X-Barracuda-RBL-Trusted-Forwarder: 192.168.14.1 Received: from unknown (HELO slow1-d.mail.gandi.net) (217.70.178.86) by mx3-pf2.cudamail.com with SMTP; 12 Jul 2016 10:20:19 -0000 Received-SPF: pass (mx3-pf2.cudamail.com: SPF record at ovn.org designates 217.70.178.86 as permitted sender) X-Barracuda-Apparent-Source-IP: 217.70.178.86 X-Barracuda-RBL-IP: 217.70.178.86 Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by slow1-d.mail.gandi.net (Postfix) with ESMTP id 8C4E84B65B0 for ; Tue, 12 Jul 2016 12:17:05 +0200 (CEST) X-Originating-IP: 98.234.50.139 Received: from localhost.localdomain (unknown [98.234.50.139]) (Authenticated sender: jpettit@ovn.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id EE8F6C5B67 for ; Tue, 12 Jul 2016 12:17:04 +0200 (CEST) X-CudaMail-Envelope-Sender: jpettit@ovn.org From: Justin Pettit To: dev@openvswitch.org X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-V2-711003379 X-CudaMail-DTE: 071216 X-CudaMail-Originating-IP: 217.70.178.86 Date: Mon, 11 Jul 2016 23:56:41 -0700 X-ASG-Orig-Subj: [##CM-V2-711003379##][ovn-ipv6 11/26] ovn-util: Add string representations to 'lport_addresses'. Message-Id: <1468306616-125783-12-git-send-email-jpettit@ovn.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1468306616-125783-1-git-send-email-jpettit@ovn.org> References: <1468306616-125783-1-git-send-email-jpettit@ovn.org> X-Barracuda-Connect: UNKNOWN[192.168.14.1] X-Barracuda-Start-Time: 1468318820 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-ASG-Whitelist: Header =?UTF-8?B?eFwtY3VkYW1haWxcLXdoaXRlbGlzdFwtdG8=?= X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 Subject: [ovs-dev] [ovn-ipv6 11/26] ovn-util: Add string representations to 'lport_addresses'. X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" 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 Acked-by: Ben Pfaff --- 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. */