You will need to add a commit message to this commit. You will need to add your Signed-off-by. You should also add yourself to the AUTHORS file.
Since ovs-vtep is already supposed to work for L2 related things, and has been tested well before, I suggest splitting the change for ovs-vtep into a separate patch with a proper description (in commit message) on what is the behavior that you are fixing. Looking at the code, I can't make out the reason for the changes. On 11 January 2016 at 17:52, Darrell Ball <dlu...@gmail.com> wrote: > --- > ovn/controller-vtep/vtep.c | 207 > ++++++++++++++++++++++++++++++++++++++++----- > tests/ovn.at | 6 +- > vtep/ovs-vtep | 18 +++- > 3 files changed, 204 insertions(+), 27 deletions(-) > > 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); > diff --git a/tests/ovn.at b/tests/ovn.at > index e00674d..a60ab56 100644 > --- a/tests/ovn.at > +++ b/tests/ovn.at > @@ -870,10 +870,8 @@ for s in 1 2 3; do > done > > # Broadcast and multicast. > - # xxx ovn-controller-vtep doesn't handle multicast traffic that is > - # xxx sourced from the gateway properly. > - #test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast > #2 > - #test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast > #2 > + test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast > #2 > + test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast > #2 > > test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown > #3 > done > diff --git a/vtep/ovs-vtep b/vtep/ovs-vtep > index 46a5692..a479a3a 100755 > --- a/vtep/ovs-vtep > +++ b/vtep/ovs-vtep > @@ -135,15 +135,31 @@ class Logical_Switch(object): > ovs_ofctl("add-flow %s > table=1,priority=1,in_port=%s,action=%s" > % (self.short_name, port_no, > ",".join(flood_ports))) > > + existing_flow = 0 > + appended_flood_port = 0 > + flows = ovs_ofctl("dump-flows %s table=1,cookie=0x4848/-1" > + % self.short_name).splitlines() > + for f in flows: > + if ("table" in f): > + existing_flow = 1 > + break > + > # Traffic coming from a VTEP physical port should only be flooded > to > # one 'unknown-dst' and to all other physical ports that belong > to that > # VTEP device and this logical switch. > for tunnel in self.unknown_dsts: > port_no = self.tunnels[tunnel][0] > flood_ports.append(port_no) > + appended_flood_port = 1 > break > > - ovs_ofctl("add-flow %s table=1,priority=0,action=%s" > + if ((existing_flow == 1) and (appended_flood_port == 1)): > + ovs_ofctl( > + "mod-flows %s > table=1,priority=0,cookie=0x4848/-1,action=%s" > + % (self.short_name, ",".join(flood_ports))) > + elif (existing_flow == 0): > + ovs_ofctl( > + "add-flow %s table=1,priority=0,cookie=0x4848,action=%s" > % (self.short_name, ",".join(flood_ports))) > > def add_lbinding(self, lbinding): > -- > 1.9.1 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev