[ovs-dev,1/2] OVN: assign new addresses at the end of build_ipam routine
diff mbox series

Message ID ea73c9976df0207338b4d89d4a1a5cefefd09c5d.1540570936.git.lorenzo.bianconi@redhat.com
State Accepted
Headers show
Series
  • configure mac address according to IP address
Related show

Commit Message

Lorenzo Bianconi Oct. 26, 2018, 4:25 p.m. UTC
Visit all ovn datapaths before adding new dynamic addresses to the
system in order to avoid possible L2 address duplication when
the same MAC address is configured on different ovn logical switches.
Current implementation can miss the duplicated address since macam
is cleared at each ovn run and there is no guarantee on visit order
of ovn datapath hash table

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
 ovn/northd/ovn-northd.c | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)

Patch
diff mbox series

diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index 816c72311..33fc94f72 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -1093,6 +1093,7 @@  enum dynamic_update_type {
 struct dynamic_address_update {
     struct ovs_list node;       /* In build_ipam()'s list of updates. */
 
+    struct ovn_datapath *od;
     struct ovn_port *op;
 
     struct lport_addresses current_addresses;
@@ -1284,8 +1285,7 @@  set_dynamic_updates(const char *addrspec,
 }
 
 static void
-update_dynamic_addresses(struct ovn_datapath *od,
-                         struct dynamic_address_update *update)
+update_dynamic_addresses(struct dynamic_address_update *update)
 {
     struct eth_addr mac;
     switch (update->mac) {
@@ -1314,7 +1314,7 @@  update_dynamic_addresses(struct ovn_datapath *od,
     case STATIC:
         OVS_NOT_REACHED();
     case DYNAMIC:
-        ip4 = htonl(ipam_get_unused_ip(od));
+        ip4 = htonl(ipam_get_unused_ip(update->od));
     }
 
     struct in6_addr ip6 = in6addr_any;
@@ -1329,14 +1329,14 @@  update_dynamic_addresses(struct ovn_datapath *od,
     case STATIC:
         OVS_NOT_REACHED();
     case DYNAMIC:
-        in6_generate_eui64(mac, &od->ipam_info.ipv6_prefix, &ip6);
+        in6_generate_eui64(mac, &update->od->ipam_info.ipv6_prefix, &ip6);
         break;
     }
 
     struct ds new_addr = DS_EMPTY_INITIALIZER;
     ds_put_format(&new_addr, ETH_ADDR_FMT, ETH_ADDR_ARGS(mac));
     if (ip4) {
-        ipam_insert_ip(od, ntohl(ip4));
+        ipam_insert_ip(update->od, ntohl(ip4));
         ds_put_format(&new_addr, " "IP_FMT, IP_ARGS(ip4));
     }
     if (!IN6_ARE_ADDR_EQUAL(&ip6, &in6addr_any)) {
@@ -1362,13 +1362,14 @@  build_ipam(struct hmap *datapaths, struct hmap *ports)
     /* If the switch's other_config:subnet is set, allocate new addresses for
      * ports that have the "dynamic" keyword in their addresses column. */
     struct ovn_datapath *od;
+    struct ovs_list updates;
+
+    ovs_list_init(&updates);
     HMAP_FOR_EACH (od, key_node, datapaths) {
         if (!od->nbs) {
             continue;
         }
 
-        struct ovs_list updates;
-        ovs_list_init(&updates);
         for (size_t i = 0; i < od->nbs->n_ports; i++) {
             const struct nbrec_logical_switch_port *nbsp = od->nbs->ports[i];
 
@@ -1405,6 +1406,7 @@  build_ipam(struct hmap *datapaths, struct hmap *ports)
                 struct dynamic_address_update *update
                     = xzalloc(sizeof *update);
                 update->op = op;
+                update->od = od;
                 if (nbsp->dynamic_addresses) {
                     bool any_changed;
                     extract_lsp_addresses(nbsp->dynamic_addresses,
@@ -1431,15 +1433,16 @@  build_ipam(struct hmap *datapaths, struct hmap *ports)
             }
         }
 
-        /* After retaining all unchanged dynamic addresses, now assign
-         * new ones.
-         */
-        struct dynamic_address_update *update;
-        LIST_FOR_EACH_POP (update, node, &updates) {
-            update_dynamic_addresses(od, update);
-            destroy_lport_addresses(&update->current_addresses);
-            free(update);
-        }
+    }
+
+    /* After retaining all unchanged dynamic addresses, now assign
+     * new ones.
+     */
+    struct dynamic_address_update *update;
+    LIST_FOR_EACH_POP (update, node, &updates) {
+        update_dynamic_addresses(update);
+        destroy_lport_addresses(&update->current_addresses);
+        free(update);
     }
 }