> > Why lose the ‘_WITH_HASH’? It seems pointless to iterate over all the > ports, when we just care of the port with the ‘port_number’?
With the _WITH_HASH a test on learned addresses shifting fails. It seems like it doesn't even enter the FOR_EACH cycle when the port_number is not 1, maybe there is a problem with the hash lookup? Can the bundles really be from different bridges, as they both are managed > by the same RSTP state machine? If both ofproto’s are the same, then this > function can be simplified. I guess they're from the same bridge. The shift is between two ports of the same bridge. Feel free to suggest any improvement on this. Daniele 2014-11-14 1:11 GMT+01:00 Jarno Rajahalme <jrajaha...@nicira.com>: > Daniele, > > See comments inline. > > Thanks! > > Jarno > > On Nov 6, 2014, at 7:31 AM, Daniele Venturino <daniele.ventur...@m3s.it> > wrote: > > > All MAC addresses previously learned on a Root Port can be moved to > an > > Alternate Port that becomes the new Root Port; i.e., Dynamic > Filtering > > Entries for those addresses may be modified to show the new Root > Port as > > their source, reducing the need to flood frames when recovering from > > some component failures. > > > > Indentation... > > > Signed-off-by: Daniele Venturino <daniele.ventur...@m3s.it> > > --- > > lib/rstp-common.h | 4 ++++ > > lib/rstp-state-machines.c | 21 +++++++++++++++++++ > > lib/rstp.c | 51 > ++++++++++++++++++++++++++++++++++++++--------- > > lib/rstp.h | 10 ++++++++++ > > ofproto/ofproto-dpif.c | 39 ++++++++++++++++++++++++++++++++++-- > > 5 files changed, 114 insertions(+), 11 deletions(-) > > > > diff --git a/lib/rstp-common.h b/lib/rstp-common.h > > index 6e56958..271db2a 100644 > > --- a/lib/rstp-common.h > > +++ b/lib/rstp-common.h > > @@ -868,6 +868,10 @@ struct rstp { > > /* Interface to client. */ > > void (*send_bpdu)(struct ofpbuf *bpdu, void *port_aux, void > *rstp_aux); > > void *aux; > > + > > + bool root_changed; > > + void *old_root_aux; > > + void *new_root_aux; > > }; > > > > #endif /* rstp-common.h */ > > diff --git a/lib/rstp-state-machines.c b/lib/rstp-state-machines.c > > index 516093f..40eeea5 100644 > > --- a/lib/rstp-state-machines.c > > +++ b/lib/rstp-state-machines.c > > @@ -287,7 +287,14 @@ updt_roles_tree__(struct rstp *r) > > struct rstp_port *p; > > int vsel; > > struct rstp_priority_vector best_vector, candidate_vector; > > + enum rstp_port_role new_root_old_role = ROLE_DESIGNATED; > > + uint16_t old_root_port_number = 0; > > + uint16_t new_root_port_number = 0; > > > > + old_root_port_number = r->root_port_id & 0x00ff; > > + if (old_root_port_number) { > > + r->old_root_aux = rstp_get_port_aux(r, old_root_port_number); > > + } > > vsel = -1; > > best_vector = r->bridge_priority; > > /* Letter c1) */ > > @@ -317,12 +324,26 @@ updt_roles_tree__(struct rstp *r) > > r->root_times = p->port_times; > > r->root_times.message_age++; > > vsel = p->port_number; > > + new_root_old_role = p->role; > > } > > } > > r->root_priority = best_vector; > > r->root_port_id = best_vector.bridge_port_id; > > VLOG_DBG("%s: new Root is "RSTP_ID_FMT, r->name, > > RSTP_ID_ARGS(r->root_priority.root_bridge_id)); > > + new_root_port_number = r->root_port_id & 0x00ff; > > + if (new_root_port_number) { > > + r->new_root_aux = rstp_get_port_aux(r, new_root_port_number); > > + } > > + /* Shift learned MAC addresses from an old Root Port to an existing > > + * Alternate Port. */ > > + if (!r->root_changed > > + && new_root_old_role == ROLE_ALTERNATE > > + && new_root_port_number > > + && old_root_port_number > > + && new_root_port_number != old_root_port_number) { > > Indentation above is wrong, the lines should line right after the opening > parenthesis above. > > > + r->root_changed = true; > > + } > > /* Letters d) e) */ > > HMAP_FOR_EACH (p, node, &r->ports) { > > p->designated_priority_vector.root_bridge_id = > > diff --git a/lib/rstp.c b/lib/rstp.c > > index fd42a7d..5256740 100644 > > --- a/lib/rstp.c > > +++ b/lib/rstp.c > > @@ -867,6 +867,42 @@ out: > > return aux; > > } > > > > +bool > > +rstp_shift_root_learned_address(struct rstp *rstp) { > > + bool ret = false; > > + ovs_mutex_lock(&rstp_mutex); > > + if (rstp->root_changed) { > > + ret = true; > > + } > > + ovs_mutex_unlock(&rstp_mutex); > > + return ret; > > +} > > + > > Format function definitions like this: > > bool > rstp_shift_root_learned_address(struct rstp *rstp) > { > bool ret; > > ovs_mutex_lock(&rstp_mutex); > ret = rstp->root_changed; > ovs_mutex_unlock(&rstp_mutex); > > return ret; > } > > > +void * > > +rstp_get_old_root_aux(struct rstp *rstp) { > > + void *aux = NULL; > > + ovs_mutex_lock(&rstp_mutex); > > + aux = rstp->old_root_aux; > > + ovs_mutex_unlock(&rstp_mutex); > > + return aux; > > +} > > + > > +void * > > +rstp_get_new_root_aux(struct rstp *rstp) { > > + void *aux = NULL; > > + ovs_mutex_lock(&rstp_mutex); > > + aux = rstp->new_root_aux; > > + ovs_mutex_unlock(&rstp_mutex); > > + return aux; > > +} > > + > > +void > > +rstp_reset_root_changed(struct rstp *rstp) { > > + ovs_mutex_lock(&rstp_mutex); > > + rstp->root_changed = false; > > + ovs_mutex_unlock(&rstp_mutex); > > +} > > + > > /* Returns the port in 'rstp' with number 'port_number'. > > * > > * XXX: May only be called while concurrent deletion of ports is > excluded. */ > > @@ -878,8 +914,7 @@ rstp_get_port__(struct rstp *rstp, uint16_t > port_number) > > > > ovs_assert(rstp && port_number > 0 && port_number <= RSTP_MAX_PORTS); > > > > - HMAP_FOR_EACH_WITH_HASH (port, node, hash_int(port_number, 0), > > - &rstp->ports) { > > + HMAP_FOR_EACH (port, node, &rstp->ports) { > > Why lose the ‘_WITH_HASH’? It seems pointless to iterate over all the > ports, when we just care of the port with the ‘port_number’? > > > if (port->port_number == port_number) { > > return port; > > } > > @@ -901,16 +936,14 @@ rstp_get_port(struct rstp *rstp, uint16_t > port_number) > > > > void * > > rstp_get_port_aux(struct rstp *rstp, uint16_t port_number) > > - OVS_EXCLUDED(rstp_mutex) > > + OVS_REQUIRES(rstp_mutex) > > { > > struct rstp_port *p; > > - void *aux; > > - > > - ovs_mutex_lock(&rstp_mutex); > > p = rstp_get_port__(rstp, port_number); > > - aux = p->aux; > > - ovs_mutex_unlock(&rstp_mutex); > > - return aux; > > + if (p) { > > + return p->aux; > > + } > > + return NULL; > > } > > > > /* Updates the port_enabled parameter. */ > > diff --git a/lib/rstp.h b/lib/rstp.h > > index b05cdf2..3b40a00 100644 > > --- a/lib/rstp.h > > +++ b/lib/rstp.h > > @@ -164,6 +164,16 @@ void *rstp_get_next_changed_port_aux(struct rstp *, > struct rstp_port **) > > void rstp_port_set_mac_operational(struct rstp_port *, > > bool new_mac_operational) > > OVS_EXCLUDED(rstp_mutex); > > +bool > > +rstp_shift_root_learned_address(struct rstp *rstp) > > + OVS_EXCLUDED(rstp_mutex); > > Function declarations should have the return type and the function name on > the same line. > > > +void *rstp_get_old_root_aux(struct rstp *) > > + OVS_EXCLUDED(rstp_mutex); > > +void *rstp_get_new_root_aux(struct rstp *) > > + OVS_EXCLUDED(rstp_mutex); > > +void > > +rstp_reset_root_changed(struct rstp *) > > + OVS_EXCLUDED(rstp_mutex); > > > > Here, too. > > > /* Bridge setters */ > > void rstp_set_bridge_address(struct rstp *, rstp_identifier > bridge_address) > > diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c > > index 2fd9896..2389a18 100644 > > --- a/ofproto/ofproto-dpif.c > > +++ b/ofproto/ofproto-dpif.c > > @@ -141,6 +141,7 @@ static void bundle_del_port(struct ofport_dpif *); > > static void bundle_run(struct ofbundle *); > > static void bundle_wait(struct ofbundle *); > > static void bundle_flush_macs(struct ofbundle *, bool); > > +static void bundle_move(struct ofbundle *, struct ofbundle *); > > > > static void stp_run(struct ofproto_dpif *ofproto); > > static void stp_wait(struct ofproto_dpif *ofproto); > > @@ -2096,11 +2097,15 @@ update_rstp_port_state(struct ofport_dpif > *ofport) > > netdev_get_name(ofport->up.netdev), > > rstp_state_name(ofport->rstp_state), > > rstp_state_name(state)); > > + > > if (rstp_learn_in_state(ofport->rstp_state) > > != rstp_learn_in_state(state)) { > > /* xxx Learning action flows should also be flushed. */ > > if (ofport->bundle) { > > - bundle_flush_macs(ofport->bundle, false); > > + if(!rstp_shift_root_learned_address(ofproto->rstp) > > + || ofport != rstp_get_old_root_aux(ofproto->rstp)) { > > + bundle_flush_macs(ofport->bundle, false); > > + } > > } > > } > > fwd_change = rstp_forward_in_state(ofport->rstp_state) > > @@ -2147,8 +2152,21 @@ rstp_run(struct ofproto_dpif *ofproto) > > * p->fdb_flush) and not periodically. > > */ > > while ((ofport = rstp_check_and_reset_fdb_flush(ofproto->rstp, > &rp))) { > > - bundle_flush_macs(ofport->bundle, false); > > + if (!rstp_shift_root_learned_address(ofproto->rstp) > > + || ofport != rstp_get_old_root_aux(ofproto->rstp)) { > > + bundle_flush_macs(ofport->bundle, false); > > + } > > + } > > + > > + struct ofport_dpif *old_root; > > + struct ofport_dpif *new_root; > > + if (rstp_shift_root_learned_address(ofproto->rstp)) { > > + old_root = rstp_get_old_root_aux(ofproto->rstp); > > + new_root = rstp_get_new_root_aux(ofproto->rstp); > > + bundle_move(old_root->bundle, new_root->bundle); > > + rstp_reset_root_changed(ofproto->rstp); > > } > > Better write the latter part as: > > if (rstp_shift_root_learned_address(ofproto->rstp)) { > bundle_move(rstp_get_old_root_aux(ofproto->rstp), > rstp_get_new_root_aux(ofproto->rstp)); > rstp_reset_root_changed(ofproto->rstp); > } > > > > + > > } > > } > > > > @@ -2495,6 +2513,23 @@ bundle_flush_macs(struct ofbundle *bundle, bool > all_ofprotos) > > ovs_rwlock_unlock(&ml->rwlock); > > } > > > > +static void bundle_move(struct ofbundle *old, struct ofbundle *new) { > > + struct ofproto_dpif *old_ofproto = old->ofproto; > > + struct ofproto_dpif *new_ofproto = new->ofproto; > > Can the bundles really be from different bridges, as they both are managed > by the same RSTP state machine? If both ofproto’s are the same, then this > function can be simplified. > > > + struct mac_learning *old_ml = old_ofproto->ml; > > + struct mac_entry *mac, *next_mac; > > + > > + old_ofproto->backer->need_revalidate = REV_RECONFIGURE; > > + new_ofproto->backer->need_revalidate = REV_RECONFIGURE; > > + ovs_rwlock_wrlock(&old_ml->rwlock); > > + LIST_FOR_EACH_SAFE (mac, next_mac, lru_node, &old_ml->lrus) { > > + if (mac->port.p == old) { > > + mac->port.p = new; > > + } > > + } > > + ovs_rwlock_unlock(&old_ml->rwlock); > > +} > > + > > static struct ofbundle * > > bundle_lookup(const struct ofproto_dpif *ofproto, void *aux) > > { > > -- > > 1.8.1.2 > > > > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev