summaryrefslogtreecommitdiff
path: root/ovn
diff options
context:
space:
mode:
authorLance Richardson <lrichard@redhat.com>2016-10-06 15:58:51 -0400
committerBen Pfaff <blp@ovn.org>2016-10-06 13:47:22 -0700
commit6374d5185d877e29eb32edc8a1bb34099b1b2bbf (patch)
tree55fa77fe14c423ba4eb04c4e24d3d75aeb34a36b /ovn
parent13c0048ecb9239d69cb4fc5788493d0f970c44a9 (diff)
downloadopenvswitch-6374d5185d877e29eb32edc8a1bb34099b1b2bbf.tar.gz
ovn-northd: support IPAM with externally specified MAC
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" Acked-by: Ben Pfaff <blp@ovn.org> Acked-by: Russell Bryant <russell@ovn.org> Signed-off-by: Lance Richardson <lrichard@redhat.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ovn')
-rw-r--r--ovn/lib/ovn-util.c20
-rw-r--r--ovn/lib/ovn-util.h2
-rw-r--r--ovn/northd/ovn-northd.c33
-rw-r--r--ovn/ovn-nb.xml35
4 files changed, 75 insertions, 15 deletions
diff --git a/ovn/lib/ovn-util.c b/ovn/lib/ovn-util.c
index 5dbc138ca..99e4a0ed4 100644
--- a/ovn/lib/ovn-util.c
+++ b/ovn/lib/ovn-util.c
@@ -62,6 +62,26 @@ 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)
+{
+ struct eth_addr ea;
+ int n;
+ return (!strcmp(address, "dynamic")
+ || (ovs_scan(address, ETH_ADDR_SCAN_FMT" dynamic%n",
+ ETH_ADDR_SCAN_ARGS(ea), &n) && address[n] == '\0'));
+}
+
/* 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 2329111e6..30b27b110 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 4668d9e8a..149fcab29 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -815,7 +815,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;
}
@@ -940,7 +940,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;
@@ -952,16 +952,26 @@ 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;
+ int n = 0;
+
+ if (ovs_scan(addrspec, ETH_ADDR_SCAN_FMT" dynamic%n",
+ ETH_ADDR_SCAN_ARGS(mac), &n)
+ && addrspec[n] == '\0') {
+ 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)));
@@ -1018,9 +1028,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
@@ -1197,7 +1208,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])) {
@@ -3078,7 +3089,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
|| !ovs_scan(op->nbsp->dynamic_addresses,
ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(mac))) {
diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
index c2a1ebb3c..e1b31361b 100644
--- a/ovn/ovn-nb.xml
+++ b/ovn/ovn-nb.xml
@@ -479,6 +479,35 @@
column="other_config" key="subnet"/> in the port's <ref
table="Logical_Switch"/>.
</dd>
+
+ <dt><code>Ethernet address followed by keyword "dynamic"</code></dt>
+ <dd>
+
+ <p>
+ The keyword <code>dynamic</code> after the MAC address indicates
+ that <code>ovn-northd</code> should choose an unused IPv4 address
+ from the logical port's subnet and store it with the specified
+ MAC in the port's <ref column="dynamic_addresses"/> column.
+ <code>ovn-northd</code> will use the subnet specified in <ref
+ table="Logical_Switch" column="other_config" key="subnet"/> in
+ the port's <ref table="Logical_Switch"/> table.
+ </p>
+
+ <p>
+ Examples:
+ </p>
+
+ <dl>
+ <dt><code>80:fa:5b:06:72:b7 dynamic</code></dt>
+ <dd>
+ This indicates that the logical port owns the specified
+ MAC address and <code>ovn-northd</code> should allocate an
+ unused IPv4 address for the logical port from the corresponding
+ logical switch subnet.
+ </dd>
+ </dl>
+ </dd>
+
</dl>
</column>
@@ -487,9 +516,9 @@
Addresses assigned to the logical port by <code>ovn-northd</code>, if
<code>dynamic</code> is specified in <ref column="addresses"/>.
Addresses will be of the same format as those that populate the <ref
- column="addresses"/> 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.
</p>
</column>