From patchwork Mon Sep 19 16:19:11 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Richardson X-Patchwork-Id: 671837 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 3sdB0k2C9Lz9sCZ for ; Tue, 20 Sep 2016 02:19:17 +1000 (AEST) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id EE06710592; Mon, 19 Sep 2016 09:19:16 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx3v3.cudamail.com (mx3.cudamail.com [64.34.241.5]) by archives.nicira.com (Postfix) with ESMTPS id 95E01102B2 for ; Mon, 19 Sep 2016 09:19:15 -0700 (PDT) Received: from bar6.cudamail.com (localhost [127.0.0.1]) by mx3v3.cudamail.com (Postfix) with ESMTPS id 12DC716244E for ; Mon, 19 Sep 2016 10:19:15 -0600 (MDT) X-ASG-Debug-ID: 1474301953-0b32372260653480001-byXFYA Received: from mx3-pf3.cudamail.com ([192.168.14.3]) by bar6.cudamail.com with ESMTP id MWYXmj10ZPBm3ASg (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 19 Sep 2016 10:19:13 -0600 (MDT) X-Barracuda-Envelope-From: lrichard@redhat.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.14.3 Received: from unknown (HELO mx1.redhat.com) (209.132.183.28) by mx3-pf3.cudamail.com with ESMTPS (DHE-RSA-AES256-SHA encrypted); 19 Sep 2016 16:19:13 -0000 Received-SPF: pass (mx3-pf3.cudamail.com: SPF record at _spf1.redhat.com designates 209.132.183.28 as permitted sender) X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-Barracuda-RBL-IP: 209.132.183.28 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 69B5CC054902 for ; Mon, 19 Sep 2016 16:19:12 +0000 (UTC) Received: from thinkcentre.nc.rr.com (vpn-63-254.rdu2.redhat.com [10.10.63.254]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u8JGJBOZ028322 for ; Mon, 19 Sep 2016 12:19:12 -0400 X-CudaMail-Envelope-Sender: lrichard@redhat.com From: Lance Richardson To: dev@openvswitch.org X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-V3-918023675 X-CudaMail-DTE: 091916 X-CudaMail-Originating-IP: 209.132.183.28 Date: Mon, 19 Sep 2016 12:19:11 -0400 X-ASG-Orig-Subj: [##CM-V3-918023675##][RFC v2] ovn-northd: support IPAM with externally specified MAC Message-Id: <1474301951-32628-1-git-send-email-lrichard@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Mon, 19 Sep 2016 16:19:12 +0000 (UTC) X-Barracuda-Connect: UNKNOWN[192.168.14.3] X-Barracuda-Start-Time: 1474301953 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] [RFC v2] ovn-northd: support IPAM with externally specified MAC 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" The current IPAM implementation allocates both a MAC address and an IPv4 address when dynamic address allocation is requested. This patch adds the ability to specify a fixed MAC address for use with dynamic IPv4 address allocation. Example: ovn-nbctl lsp-set-addresses p1 "00:01:02:03:04:05 dynamic" Signed-off-by: Lance Richardson --- v2: Eliminated compilation warning, dropped usage of isspace(). ovn/lib/ovn-util.c | 38 ++++++++++++++++++++++++++++++++++++++ ovn/lib/ovn-util.h | 2 +- ovn/northd/ovn-northd.c | 30 +++++++++++++++++++----------- ovn/ovn-nb.xml | 35 ++++++++++++++++++++++++++++++++--- tests/ovn.at | 7 +++++++ 5 files changed, 97 insertions(+), 15 deletions(-) diff --git a/ovn/lib/ovn-util.c b/ovn/lib/ovn-util.c index 5dbc138..06f48c6 100644 --- a/ovn/lib/ovn-util.c +++ b/ovn/lib/ovn-util.c @@ -62,6 +62,44 @@ add_ipv6_netaddr(struct lport_addresses *laddrs, struct in6_addr addr, inet_ntop(AF_INET6, &na->network, na->network_s, sizeof na->network_s); } +/* Returns true if specified address specifies a dynamic address, + * supporting the following formats: + * + * "dynamic": + * Both MAC and IP are to be allocated dynamically. + * + * "xx:xx:xx:xx:xx:xx dynamic": + * Use specified MAC address, but allocate an IP address + * dynamically. + */ +bool +is_dynamic_lsp_address(const char *address) +{ + const char *buf = address; + struct eth_addr ea; + int buf_index = 0; + + if (!strcmp(address, "dynamic")) { + return true; + } + + if (!ovs_scan_len(buf, &buf_index, ETH_ADDR_SCAN_FMT, + ETH_ADDR_SCAN_ARGS(ea))) { + return false; + } + + buf += buf_index; + while (*buf == ' ') { + buf++; + } + + if (!strcmp(buf, "dynamic")) { + return true; + } + + return false; +} + /* Extracts the mac, IPv4 and IPv6 addresses from * '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 diff --git a/ovn/lib/ovn-util.h b/ovn/lib/ovn-util.h index 2329111..30b27b1 100644 --- a/ovn/lib/ovn-util.h +++ b/ovn/lib/ovn-util.h @@ -53,7 +53,7 @@ struct lport_addresses { struct ipv6_netaddr *ipv6_addrs; }; - +bool is_dynamic_lsp_address(const char *address); bool extract_lsp_addresses(const char *address, struct lport_addresses *); bool extract_lrp_networks(const struct nbrec_logical_router_port *, struct lport_addresses *); diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index a91e1f8..c30d70c 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -732,7 +732,7 @@ ipam_insert_lsp_addresses(struct ovn_datapath *od, struct ovn_port *op, char *address) { if (!od || !op || !address || !strcmp(address, "unknown") - || !strcmp(address, "dynamic")) { + || is_dynamic_lsp_address(address)) { return; } @@ -857,7 +857,7 @@ ipam_get_unused_ip(struct ovn_datapath *od, uint32_t subnet, uint32_t mask) static bool ipam_allocate_addresses(struct ovn_datapath *od, struct ovn_port *op, - ovs_be32 subnet, ovs_be32 mask) + const char *addrspec, ovs_be32 subnet, ovs_be32 mask) { if (!od || !op || !op->nbsp) { return false; @@ -869,16 +869,23 @@ ipam_allocate_addresses(struct ovn_datapath *od, struct ovn_port *op, } struct eth_addr mac; - uint64_t mac64 = ipam_get_unused_mac(); - if (!mac64) { - return false; + bool check_mac; + + if (eth_addr_from_string(addrspec, &mac)) { + check_mac = true; + } else { + uint64_t mac64 = ipam_get_unused_mac(); + if (!mac64) { + return false; + } + eth_addr_from_uint64(mac64, &mac); + check_mac = false; } - eth_addr_from_uint64(mac64, &mac); /* Add MAC/IP to MACAM/IPAM hmaps if both addresses were allocated * successfully. */ ipam_insert_ip(od, ip, false); - ipam_insert_mac(&mac, false); + ipam_insert_mac(&mac, check_mac); char *new_addr = xasprintf(ETH_ADDR_FMT" "IP_FMT, ETH_ADDR_ARGS(mac), IP_ARGS(htonl(ip))); @@ -935,9 +942,10 @@ build_ipam(struct hmap *datapaths, struct hmap *ports) } for (size_t j = 0; j < nbsp->n_addresses; j++) { - if (!strcmp(nbsp->addresses[j], "dynamic") + if (is_dynamic_lsp_address(nbsp->addresses[j]) && !nbsp->dynamic_addresses) { - if (!ipam_allocate_addresses(od, op, subnet, mask) + if (!ipam_allocate_addresses(od, op, + nbsp->addresses[j], subnet, mask) || !extract_lsp_addresses(nbsp->dynamic_addresses, &op->lsp_addrs[op->n_lsp_addrs])) { static struct vlog_rate_limit rl @@ -1104,7 +1112,7 @@ join_logical_ports(struct northd_context *ctx, if (!strcmp(nbsp->addresses[j], "unknown")) { continue; } - if (!strcmp(nbsp->addresses[j], "dynamic")) { + if (is_dynamic_lsp_address(nbsp->addresses[j])) { if (nbsp->dynamic_addresses) { if (!extract_lsp_addresses(nbsp->dynamic_addresses, &op->lsp_addrs[op->n_lsp_addrs])) { @@ -2906,7 +2914,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports, ovn_multicast_add(mcgroups, &mc_unknown, op); op->od->has_unknown = true; } - } else if (!strcmp(op->nbsp->addresses[i], "dynamic")) { + } else if (is_dynamic_lsp_address(op->nbsp->addresses[i])) { if (!op->nbsp->dynamic_addresses || !eth_addr_from_string(op->nbsp->dynamic_addresses, &mac)) { diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml index c45a444..78af2b3 100644 --- a/ovn/ovn-nb.xml +++ b/ovn/ovn-nb.xml @@ -474,6 +474,35 @@ column="other_config" key="subnet"/> in the port's . + +
Ethernet address followed by keyword "dynamic"
+
+ +

+ The keyword dynamic after the MAC address indicates + that ovn-northd should choose an unused IPv4 address + from the logical port's subnet and store it with the specified + MAC in the port's column. + ovn-northd will use the subnet specified in in + the port's table. +

+ +

+ Examples: +

+ +
+
80:fa:5b:06:72:b7 dynamic
+
+ This indicates that the logical port owns the specified + MAC address and ovn-northd should allocate an + unused IPv4 address for the logical port from the corresponding + logical switch subnet. +
+
+
+ @@ -482,9 +511,9 @@ Addresses assigned to the logical port by ovn-northd, if dynamic is specified in . Addresses will be of the same format as those that populate the column. Note that these addresses are - constructed and managed locally in ovn-northd, so they cannot be - reconstructed in the event that the database is lost. + column="addresses"/> column. Note that dynamically assigned + addresses are constructed and managed locally in ovn-northd, so they + cannot be reconstructed in the event that the database is lost.

diff --git a/tests/ovn.at b/tests/ovn.at index 3f15561..b266444 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -4672,6 +4672,13 @@ AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0], ["0a:00:00:00:00:20 192.168.1.17" ]) +# Test static MAC address with dynamically allocated IP +ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \ +"fe:dc:ba:98:76:54 dynamic" +AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0], + ["fe:dc:ba:98:76:54 192.168.1.18" +]) + as ovn-sb OVS_APP_EXIT_AND_WAIT([ovsdb-server])