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

Reply via email to