Skip to content

Commit

Permalink
OVN: configure L2 address according to the used IP address
Browse files Browse the repository at this point in the history
Configure L2 dynamic address according to used IPv4 address.
This patch allows to define a deterministic relationship between
L2 and L3 addresses when dynamic IPAM is used.
This patch allows to fix a possible L2/L3 address mismatch than can
occur when pods are created and destroyed at high rate [1] since if
there is no relation between MAC and IP addresses ARP cache can be
poisoned with a wrong correspondence

[1] https://bugzilla.redhat.com/show_bug.cgi?id=1626217

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
  • Loading branch information
LorenzoBianconi authored and blp committed Nov 6, 2018
1 parent da6adac commit c814545
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 79 deletions.
45 changes: 21 additions & 24 deletions ovn/northd/ovn-northd.c
Expand Up @@ -1042,25 +1042,22 @@ ipam_add_port_addresses(struct ovn_datapath *od, struct ovn_port *op)
}

static uint64_t
ipam_get_unused_mac(void)
ipam_get_unused_mac(ovs_be32 ip)
{
/* Stores the suffix of the most recently ipam-allocated MAC address. */
static uint32_t last_mac;

uint64_t mac64;
uint32_t mac_addr_suffix, i, base_addr = ntohl(ip) & MAC_ADDR_SPACE;
struct eth_addr mac;
uint32_t mac_addr_suffix, i;
uint64_t mac64;

for (i = 0; i < MAC_ADDR_SPACE - 1; i++) {
/* The tentative MAC's suffix will be in the interval (1, 0xfffffe). */
mac_addr_suffix = ((last_mac + i) % (MAC_ADDR_SPACE - 1)) + 1;
mac_addr_suffix = ((base_addr + i) % (MAC_ADDR_SPACE - 1)) + 1;
if (!eth_addr_is_zero(mac_prefix)) {
mac64 = eth_addr_to_uint64(mac_prefix) | mac_addr_suffix;
} else {
mac64 = MAC_ADDR_PREFIX | mac_addr_suffix;
}
eth_addr_from_uint64(mac64, &mac);
if (!ipam_is_duplicate_mac(&mac, mac64, false)) {
last_mac = mac_addr_suffix;
if (!ipam_is_duplicate_mac(&mac, mac64, true)) {
break;
}
}
Expand Down Expand Up @@ -1296,21 +1293,6 @@ set_dynamic_updates(const char *addrspec,
static void
update_dynamic_addresses(struct dynamic_address_update *update)
{
struct eth_addr mac;
switch (update->mac) {
case NONE:
mac = update->current_addresses.ea;
break;
case REMOVE:
OVS_NOT_REACHED();
case STATIC:
mac = update->static_mac;
break;
case DYNAMIC:
eth_addr_from_uint64(ipam_get_unused_mac(), &mac);
break;
}

ovs_be32 ip4 = 0;
switch (update->ipv4) {
case NONE:
Expand All @@ -1326,6 +1308,21 @@ update_dynamic_addresses(struct dynamic_address_update *update)
ip4 = htonl(ipam_get_unused_ip(update->od));
}

struct eth_addr mac;
switch (update->mac) {
case NONE:
mac = update->current_addresses.ea;
break;
case REMOVE:
OVS_NOT_REACHED();
case STATIC:
mac = update->static_mac;
break;
case DYNAMIC:
eth_addr_from_uint64(ipam_get_unused_mac(ip4), &mac);
break;
}

struct in6_addr ip6 = in6addr_any;
switch (update->ipv6) {
case NONE:
Expand Down

0 comments on commit c814545

Please sign in to comment.