[ovs-dev] [PATCH 1/3] VTEP Schema - Support mcast macs remote table updates

Darrell Ball dball at vmware.com
Thu Mar 3 19:06:54 UTC 2016


Resending, as patches are visible in the mailing list archive, but not actually received by all






On 2/12/16, 5:12 PM, "Darrell Ball" <dlu998 at gmail.com> wrote:

>Signed-off-by: Darrell Ball <dball at vmware.com>
>---
> AUTHORS                    |   1 +
> ovn/controller-vtep/vtep.c | 207 ++++++++++++++++++++++++++++++++++++++++-----
> 2 files changed, 186 insertions(+), 22 deletions(-)
>
>diff --git a/AUTHORS b/AUTHORS
>index 5c3643a..b709482 100644
>--- a/AUTHORS
>+++ b/AUTHORS
>@@ -417,6 +417,7 @@ rahim entezari          rahim.entezari at gmail.com
> 胡靖飞                  hujingfei914 at msn.com
> 张伟                     zhangwqh at 126.com
> 张强                    zhangqiang at meizu.com
>+darrell ball            dlu998 at gmail.com
> 
> Thanks to all Open vSwitch contributors.  If you are not listed above
> but believe that you should be, please write to dev at openvswitch.org.
>diff --git a/ovn/controller-vtep/vtep.c b/ovn/controller-vtep/vtep.c
>index 016c2e0..04251c4 100644
>--- a/ovn/controller-vtep/vtep.c
>+++ b/ovn/controller-vtep/vtep.c
>@@ -30,6 +30,16 @@
> 
> VLOG_DEFINE_THIS_MODULE(vtep);
> 
>+struct vtep_rec_physical_locator_list_entry{
>+    struct ovs_list locators_node;
>+    const struct vteprec_physical_locator *vteprec_ploc;
>+};
>+
>+struct mmr_hash_node_data {
>+    const struct vteprec_mcast_macs_remote *mmr;
>+    struct shash physical_locators;
>+};
>+
> /*
>  * Scans through the Binding table in ovnsb, and updates the vtep logical
>  * switch tunnel keys and the 'Ucast_Macs_Remote' table in the VTEP
>@@ -84,6 +94,98 @@ create_pl(struct ovsdb_idl_txn *vtep_idl_txn, const char *chassis_ip)
> }
> 
> ?
>+/* Creates a new 'Mcast_Macs_Remote'. entry */
>+static void
>+vtep_create_mmr(struct ovsdb_idl_txn *vtep_idl_txn,
>+           const char *mac,
>+           const struct vteprec_logical_switch *vtep_ls,
>+           const struct vteprec_physical_locator_set *ploc_set)
>+{
>+    struct vteprec_mcast_macs_remote *new_mmr =
>+       vteprec_mcast_macs_remote_insert(vtep_idl_txn);
>+
>+    vteprec_mcast_macs_remote_set_MAC(new_mmr, mac);
>+    vteprec_mcast_macs_remote_set_logical_switch(new_mmr, vtep_ls);
>+    vteprec_mcast_macs_remote_set_locator_set(new_mmr,ploc_set);
>+}
>+
>+/* Compares prev and new mmr locator sets and return true if they
>+ * differ; false otherwise; also preps new locator set
>+ * for database write */
>+static bool
>+vtep_process_pls(
>+           const struct ovs_list *locators_list,
>+           const struct mmr_hash_node_data *mmr_ext,
>+           struct vteprec_physical_locator **locators)
>+{
>+    int i;
>+    size_t n_locators_prev = 0;
>+    size_t n_locators_new = list_size(locators_list);
>+    struct vtep_rec_physical_locator_list_entry *ploc_entry;
>+    const struct vteprec_physical_locator *pl = NULL;
>+    bool prev_and_new_locator_lists_differ = false;
>+
>+    if(mmr_ext) {
>+        n_locators_prev = mmr_ext->mmr->locator_set->n_locators;
>+    }
>+    if(n_locators_prev != n_locators_new) {
>+        prev_and_new_locator_lists_differ = true;
>+    }
>+
>+    if(n_locators_new) {
>+        i = 0;
>+        LIST_FOR_EACH (ploc_entry, locators_node, locators_list) {
>+            locators[i] = (struct vteprec_physical_locator *)
>+                           ploc_entry->vteprec_ploc;
>+            if(mmr_ext) {
>+                pl = shash_find_data(&mmr_ext->physical_locators,
>+                                     locators[i]->dst_ip);
>+                if(!pl) {
>+                    prev_and_new_locator_lists_differ = true;
>+                }
>+            }
>+            i++;
>+        }
>+    }
>+
>+    return(prev_and_new_locator_lists_differ);
>+}
>+
>+/* Creates a new 'Mcast_Macs_Remote' entry if needed.
>+ * Also cleans prev remote mcast mac entries as needed */
>+static void
>+vtep_update_mmr(struct ovsdb_idl_txn *vtep_idl_txn,
>+                struct ovs_list *locators_list,
>+                const struct vteprec_logical_switch *vtep_ls,
>+                const struct mmr_hash_node_data *mmr_ext)
>+{
>+    struct vteprec_physical_locator **locators = NULL;
>+    size_t n_locators_new = list_size(locators_list);
>+    bool mmr_changed = false;
>+    const struct vteprec_physical_locator_set *ploc_set;
>+
>+    locators = xmalloc(n_locators_new * sizeof(*locators));
>+
>+    if(vtep_process_pls(locators_list, mmr_ext, locators)) {
>+        mmr_changed = true;
>+    }
>+
>+    if(mmr_ext && (!n_locators_new)) {
>+        vteprec_mcast_macs_remote_delete(mmr_ext->mmr);
>+    } else if ((mmr_ext && mmr_changed) ||
>+               ((!mmr_ext) && n_locators_new)) {
>+
>+        ploc_set = vteprec_physical_locator_set_insert(vtep_idl_txn);
>+
>+        vtep_create_mmr(vtep_idl_txn, "unknown-dst", vtep_ls, ploc_set);
>+
>+        vteprec_physical_locator_set_set_locators(ploc_set, locators,
>+                                                  n_locators_new);
>+
>+    }
>+    free(locators);
>+}
>+
> /* Updates the vtep Logical_Switch table entries' tunnel keys based
>  * on the port bindings. */
> static void
>@@ -153,12 +255,15 @@ vtep_lswitch_run(struct shash *vtep_pbs, struct sset *vtep_pswitches,
>  * bindings. */
> static void
> vtep_macs_run(struct ovsdb_idl_txn *vtep_idl_txn, struct shash *ucast_macs_rmts,
>-              struct shash *physical_locators, struct shash *vtep_lswitches,
>-              struct shash *non_vtep_pbs)
>+              struct shash *mcast_macs_rmts, struct shash *physical_locators,
>+              struct shash *vtep_lswitches, struct shash *non_vtep_pbs)
> {
>     struct shash_node *node;
>     struct hmap ls_map;
> 
>+    struct vtep_rec_physical_locator_list_entry *ploc_entry;
>+    const struct vteprec_physical_locator *pl;
>+
>     /* Maps from ovn logical datapath tunnel key (which is also the vtep
>      * logical switch tunnel key) to the corresponding vtep logical switch
>      * instance.  Also, the shash map 'added_macs' is used for checking
>@@ -168,6 +273,9 @@ vtep_macs_run(struct ovsdb_idl_txn *vtep_idl_txn, struct shash *ucast_macs_rmts,
> 
>         const struct vteprec_logical_switch *vtep_ls;
>         struct shash added_macs;
>+
>+        struct ovs_list locators_list;
>+        struct mmr_hash_node_data *mmr_ext;
>     };
> 
>     hmap_init(&ls_map);
>@@ -181,6 +289,8 @@ vtep_macs_run(struct ovsdb_idl_txn *vtep_idl_txn, struct shash *ucast_macs_rmts,
>         ls_node = xmalloc(sizeof *ls_node);
>         ls_node->vtep_ls = vtep_ls;
>         shash_init(&ls_node->added_macs);
>+        list_init(&ls_node->locators_list);
>+        ls_node->mmr_ext = NULL;
>         hmap_insert(&ls_map, &ls_node->hmap_node,
>                     hash_uint64((uint64_t) vtep_ls->tunnel_key[0]));
>     }
>@@ -222,18 +332,31 @@ vtep_macs_run(struct ovsdb_idl_txn *vtep_idl_txn, struct shash *ucast_macs_rmts,
>             continue;
>         }
> 
>+        pl = shash_find_data(physical_locators, chassis_ip);
>+        if(!pl){
>+            pl = create_pl(vtep_idl_txn, chassis_ip);
>+            shash_add(physical_locators, chassis_ip, pl);
>+        }
>+
>+        char *mac_tnlkey =
>+            xasprintf("%s_%"PRId64, "unknown-dst", tnl_key);
>+        ls_node->mmr_ext =
>+               shash_find_data(mcast_macs_rmts, mac_tnlkey);
>+        if(ls_node->mmr_ext &&
>+           ls_node->mmr_ext->mmr->logical_switch == ls_node->vtep_ls) {
>+                shash_find_and_delete(mcast_macs_rmts, mac_tnlkey);
>+        }
>+        free(mac_tnlkey);
>+        ploc_entry = xmalloc(sizeof *ploc_entry);
>+        ploc_entry->vteprec_ploc = pl;
>+        list_push_back(&ls_node->locators_list,
>+                       &ploc_entry->locators_node);
>+
>         for (i = 0; i < port_binding_rec->n_mac; i++) {
>             const struct vteprec_ucast_macs_remote *umr;
>-            const struct vteprec_physical_locator *pl;
>             const struct sbrec_port_binding *conflict;
>             char *mac = port_binding_rec->mac[i];
> 
>-            /* xxx Need to address this later when we support
>-             * update of 'Mcast_Macs_Remote' table in VTEP. */
>-            if (!strcmp(mac, "unknown")) {
>-                continue;
>-            }
>-
>             /* Checks for duplicate MAC in the same vtep logical switch. */
>             conflict = shash_find_data(&ls_node->added_macs, mac);
>             if (conflict) {
>@@ -257,19 +380,8 @@ vtep_macs_run(struct ovsdb_idl_txn *vtep_idl_txn, struct shash *ucast_macs_rmts,
>                 shash_find_and_delete(ucast_macs_rmts, mac_ip_tnlkey);
>             } else {
>                 const struct vteprec_ucast_macs_remote *new_umr;
>-
>                 new_umr = create_umr(vtep_idl_txn, mac, ls_node->vtep_ls);
>-                pl = shash_find_data(physical_locators, chassis_ip);
>-                if (pl) {
>-                    vteprec_ucast_macs_remote_set_locator(new_umr, pl);
>-                } else {
>-                    const struct vteprec_physical_locator *new_pl;
>-
>-                    new_pl = create_pl(vtep_idl_txn, chassis_ip);
>-                    vteprec_ucast_macs_remote_set_locator(new_umr, new_pl);
>-                    /* Updates the 'physical_locators'. */
>-                    shash_add(physical_locators, chassis_ip, new_pl);
>-                }
>+                vteprec_ucast_macs_remote_set_locator(new_umr, pl);
>             }
>             free(mac_ip_tnlkey);
>         }
>@@ -281,11 +393,25 @@ vtep_macs_run(struct ovsdb_idl_txn *vtep_idl_txn, struct shash *ucast_macs_rmts,
>     }
>     struct ls_hash_node *iter, *next;
>     HMAP_FOR_EACH_SAFE (iter, next, hmap_node, &ls_map) {
>+        vtep_update_mmr(vtep_idl_txn,&iter->locators_list,
>+                        iter->vtep_ls, iter->mmr_ext);
>+        LIST_FOR_EACH_POP(ploc_entry,locators_node,
>+                          &iter->locators_list) {
>+            free(ploc_entry);
>+        }
>         hmap_remove(&ls_map, &iter->hmap_node);
>         shash_destroy(&iter->added_macs);
>         free(iter);
>     }
>     hmap_destroy(&ls_map);
>+    /* Clean stale MMRs */
>+    struct mmr_hash_node_data *mmr_ext;
>+    SHASH_FOR_EACH (node, mcast_macs_rmts) {
>+        mmr_ext = node->data;
>+        shash_destroy(&mmr_ext->physical_locators);
>+        vteprec_mcast_macs_remote_delete(mmr_ext->mmr);
>+        free(mmr_ext);
>+    }
> }
> 
> /* Resets all logical switches' 'tunnel_key' to NULL */
>@@ -311,11 +437,16 @@ static bool
> vtep_macs_cleanup(struct ovsdb_idl *vtep_idl)
> {
>     const struct vteprec_ucast_macs_remote *umr;
>+    const struct vteprec_mcast_macs_remote *mmr;
> 
>     VTEPREC_UCAST_MACS_REMOTE_FOR_EACH (umr, vtep_idl) {
>         vteprec_ucast_macs_remote_delete(umr);
>         return false;
>     }
>+    VTEPREC_MCAST_MACS_REMOTE_FOR_EACH (mmr, vtep_idl) {
>+        vteprec_mcast_macs_remote_delete(mmr);
>+        return false;
>+    }
>     return true;
> }
> ?
>@@ -330,6 +461,7 @@ vtep_run(struct controller_vtep_ctx *ctx)
>     struct sset vtep_pswitches = SSET_INITIALIZER(&vtep_pswitches);
>     struct shash vtep_lswitches = SHASH_INITIALIZER(&vtep_lswitches);
>     struct shash ucast_macs_rmts = SHASH_INITIALIZER(&ucast_macs_rmts);
>+    struct shash mcast_macs_rmts = SHASH_INITIALIZER(&mcast_macs_rmts);
>     struct shash physical_locators = SHASH_INITIALIZER(&physical_locators);
>     struct shash vtep_pbs = SHASH_INITIALIZER(&vtep_pbs);
>     struct shash non_vtep_pbs = SHASH_INITIALIZER(&non_vtep_pbs);
>@@ -338,6 +470,12 @@ vtep_run(struct controller_vtep_ctx *ctx)
>     const struct vteprec_ucast_macs_remote *umr;
>     const struct vteprec_physical_locator *pl;
>     const struct sbrec_port_binding *port_binding_rec;
>+    const struct vteprec_mcast_macs_remote *mmr;
>+    struct mmr_hash_node_data *mmr_ext;
>+    const struct vteprec_physical_locator_set *locator_set;
>+    struct vteprec_physical_locator **locators_list;
>+    size_t n_locators;
>+    size_t i;
> 
>     /* Collects 'Physical_Switch's. */
>     VTEPREC_PHYSICAL_SWITCH_FOR_EACH (vtep_ps, ctx->vtep_idl) {
>@@ -360,6 +498,29 @@ vtep_run(struct controller_vtep_ctx *ctx)
>         shash_add(&ucast_macs_rmts, mac_ip_tnlkey, umr);
>         free(mac_ip_tnlkey);
>     }
>+    /* Collects 'Mcast_Macs_Remote's. */
>+    VTEPREC_MCAST_MACS_REMOTE_FOR_EACH (mmr, ctx->vtep_idl) {
>+        char *mac_tnlkey =
>+            xasprintf("%s_%"PRId64, mmr->MAC,
>+                      mmr->logical_switch && mmr->logical_switch->n_tunnel_key
>+                          ? mmr->logical_switch->tunnel_key[0] : INT64_MAX);
>+
>+        mmr_ext = xmalloc(sizeof *mmr_ext);
>+        shash_add(&mcast_macs_rmts, mac_tnlkey, mmr_ext);
>+        mmr_ext->mmr = mmr;
>+        locator_set = mmr_ext->mmr->locator_set;
>+        n_locators = locator_set->n_locators;
>+        locators_list = locator_set->locators;
>+
>+        shash_init(&mmr_ext->physical_locators);
>+        for(i = 0; i < n_locators; i++) {
>+            shash_add(&mmr_ext->physical_locators,
>+                      locators_list[i]->dst_ip,
>+                      locators_list[i]);
>+        }
>+
>+        free(mac_tnlkey);
>+    }
>     /* Collects 'Physical_Locator's. */
>     VTEPREC_PHYSICAL_LOCATOR_FOR_EACH (pl, ctx->vtep_idl) {
>         shash_add(&physical_locators, pl->dst_ip, pl);
>@@ -380,12 +541,14 @@ vtep_run(struct controller_vtep_ctx *ctx)
>                               "tunnel keys and 'ucast_macs_remote's");
> 
>     vtep_lswitch_run(&vtep_pbs, &vtep_pswitches, &vtep_lswitches);
>-    vtep_macs_run(ctx->vtep_idl_txn, &ucast_macs_rmts, &physical_locators,
>+    vtep_macs_run(ctx->vtep_idl_txn, &ucast_macs_rmts,
>+                  &mcast_macs_rmts, &physical_locators,
>                   &vtep_lswitches, &non_vtep_pbs);
> 
>     sset_destroy(&vtep_pswitches);
>     shash_destroy(&vtep_lswitches);
>     shash_destroy(&ucast_macs_rmts);
>+    shash_destroy(&mcast_macs_rmts);
>     shash_destroy(&physical_locators);
>     shash_destroy(&vtep_pbs);
>     shash_destroy(&non_vtep_pbs);
>-- 
>1.9.1
>


More information about the dev mailing list