Small nits below, otherwise: Acked-by: Jarno Rajahalme <jrajaha...@nicira.com>
On Nov 6, 2014, at 7:31 AM, Daniele Venturino <daniele.ventur...@m3s.it> wrote: > With this commit, RSTP is able to flush from the MAC learning table > entries pertaining to a single port. Before this commit the whole table > was flushed every time a port requested flushing actions. Indentation. > > Signed-off-by: Daniele Venturino <daniele.ventur...@m3s.it> > --- > lib/rstp.c | 52 +++++++++++++++++++++++++++++++++----------------- > lib/rstp.h | 2 +- > ofproto/ofproto-dpif.c | 18 ++++++++--------- > 3 files changed, 44 insertions(+), 28 deletions(-) > > diff --git a/lib/rstp.c b/lib/rstp.c > index 55c43c0..1ab4938 100644 > --- a/lib/rstp.c > +++ b/lib/rstp.c > @@ -775,31 +775,49 @@ rstp_get_root_path_cost(const struct rstp *rstp) > return cost; > } > > -/* Returns true if something has happened to 'rstp' which necessitates > - * flushing the client's MAC learning table. > +/* Finds a port which needs to flush its own MAC learning table. A NULL > pointer > + * is returned if no port needs to flush its MAC learning table. Mention that ‘*port’ needs to be NULL in the first call to start the iteration. > */ > -bool > -rstp_check_and_reset_fdb_flush(struct rstp *rstp) > +void * > +rstp_check_and_reset_fdb_flush(struct rstp *rstp, struct rstp_port **port) > OVS_EXCLUDED(rstp_mutex) > { > - bool needs_flush; > - struct rstp_port *p; > - > - needs_flush = false; > + void *aux = NULL; > > ovs_mutex_lock(&rstp_mutex); > - HMAP_FOR_EACH (p, node, &rstp->ports) { > - if (p->fdb_flush) { > - needs_flush = true; > - /* fdb_flush should be reset by the filtering database > - * once the entries are removed if rstp_version is TRUE, and > - * immediately if stp_version is TRUE.*/ > - p->fdb_flush = false; > + if (*port == NULL) { > + struct rstp_port *p; > + > + HMAP_FOR_EACH (p, node, &rstp->ports) { > + if (p->fdb_flush) { > + aux = p->aux; > + *port = p; > + goto out; > + } > } > + } else { /* continue */ > + struct rstp_port *p = *port; > + > + HMAP_FOR_EACH_CONTINUE (p, node, &rstp->ports) { > + if (p->fdb_flush) { > + aux = p->aux; > + *port = p; > + goto out; > + } > + } > + } > + /* No port needs flushing. */ > + *port = NULL; > +out: > + /* fdb_flush should be reset by the filtering database > + * once the entries are removed if rstp_version is TRUE, and > + * immediately if stp_version is TRUE.*/ > + if (*port != NULL) { > + (*port)->fdb_flush = false; > } > ovs_mutex_unlock(&rstp_mutex); > - return needs_flush; > -} > + return aux; > + } > > /* Finds a port whose state has changed, and returns the aux pointer set for > * the port. A NULL pointer is returned when no changed port is found. On > diff --git a/lib/rstp.h b/lib/rstp.h > index b429e35..b05cdf2 100644 > --- a/lib/rstp.h > +++ b/lib/rstp.h > @@ -157,7 +157,7 @@ void rstp_tick_timers(struct rstp *) > void rstp_port_received_bpdu(struct rstp_port *, const void *bpdu, > size_t bpdu_size) > OVS_EXCLUDED(rstp_mutex); > -bool rstp_check_and_reset_fdb_flush(struct rstp *) > +void *rstp_check_and_reset_fdb_flush(struct rstp *, struct rstp_port **) > OVS_EXCLUDED(rstp_mutex); > void *rstp_get_next_changed_port_aux(struct rstp *, struct rstp_port **) > OVS_EXCLUDED(rstp_mutex); > diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c > index dc0ecdf..2fd9896 100644 > --- a/ofproto/ofproto-dpif.c > +++ b/ofproto/ofproto-dpif.c > @@ -140,6 +140,7 @@ static void bundle_destroy(struct ofbundle *); > 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 stp_run(struct ofproto_dpif *ofproto); > static void stp_wait(struct ofproto_dpif *ofproto); > @@ -2098,9 +2099,9 @@ update_rstp_port_state(struct ofport_dpif *ofport) > if (rstp_learn_in_state(ofport->rstp_state) > != rstp_learn_in_state(state)) { > /* xxx Learning action flows should also be flushed. */ > - ovs_rwlock_wrlock(&ofproto->ml->rwlock); > - mac_learning_flush(ofproto->ml); > - ovs_rwlock_unlock(&ofproto->ml->rwlock); > + if (ofport->bundle) { > + bundle_flush_macs(ofport->bundle, false); > + } > } > fwd_change = rstp_forward_in_state(ofport->rstp_state) > != rstp_forward_in_state(state); > @@ -2140,16 +2141,13 @@ rstp_run(struct ofproto_dpif *ofproto) > while ((ofport = rstp_get_next_changed_port_aux(ofproto->rstp, &rp))) > { > update_rstp_port_state(ofport); > } > + rp = NULL; > + ofport = NULL; > /* FIXME: This check should be done on-event (i.e., when setting > * p->fdb_flush) and not periodically. > */ > - if (rstp_check_and_reset_fdb_flush(ofproto->rstp)) { > - ovs_rwlock_wrlock(&ofproto->ml->rwlock); > - /* FIXME: RSTP should be able to flush the entries pertaining to > a > - * single port, not the whole table. > - */ > - mac_learning_flush(ofproto->ml); > - ovs_rwlock_unlock(&ofproto->ml->rwlock); > + while ((ofport = rstp_check_and_reset_fdb_flush(ofproto->rstp, > &rp))) { > + bundle_flush_macs(ofport->bundle, false); > } > } > } > -- > 1.8.1.2 > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev