>  static void
>  bond_choose_active_iface(struct port *port)
>  {
>     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
> +    struct iface *old_active_iface = port->active_iface;
>
>     port->active_iface = bond_choose_iface(port);
>     if (port->active_iface) {
> -        VLOG_INFO_RL(&rl, "port %s: active interface is now %s",
> -                     port->name, port->active_iface->name);
> -    } else {
> -        VLOG_WARN_RL(&rl, "port %s: all ports disabled, no active interface",
> -                     port->name);
> -    }
> -}
> -
> -static void
> -bond_enable_slave(struct iface *iface, bool enable)
> -{
> -    struct port *port = iface->port;
> -    struct bridge *br = port->bridge;
> -
> -    /* This acts as a recursion check.  If the act of disabling a slave
> -     * causes a different slave to be enabled, the flag will allow us to
> -     * skip redundant work when we reenter this function.  It must be
> -     * cleared on exit to keep things safe with multiple bonds. */
> -    static bool moving_active_iface = false;
> -
> -    iface->delay_expires = LLONG_MAX;
> -    if (enable == iface->enabled) {
> -        return;
> -    }
> +        if (port->active_iface->enabled) {
> +            VLOG_INFO_RL(&rl, "port %s: active interface is now %s",
> +                         port->name, port->active_iface->name);
> +        } else {
> +            VLOG_INFO_RL(&rl, "port %s: active interface is now %s, skipping 
> "
> +                         "remaining %lld ms updelay (since no interface was "
> +                         "enabled)", port->name, port->active_iface->name,
> +                         port->active_iface->delay_expires - time_msec());
> +            bond_enable_slave(port->active_iface, true);
> +        }
>
> -    iface->enabled = enable;
> -    if (!iface->enabled) {
> -        VLOG_WARN("interface %s: disabled", iface->name);
> -        ofproto_revalidate(br->ofproto, iface->tag);
> -        if (iface == port->active_iface) {
> -            /* Disabling a slave can lead to another slave being immediately
> -             * enabled if there will be no active slaves but one is waiting
> -             * on an updelay.  In this case we do not need to run most of the
> -             * code for the newly enabled slave since there was no period
> -             * without an active slave and it is redundant with the disabling
> -             * path. */
> -            moving_active_iface = true;
> -            bond_choose_active_iface(port);
> +        if (!old_active_iface) {
> +            ofproto_revalidate(port->bridge->ofproto, port->no_ifaces_tag);
>         }
>         bond_send_learning_packets(port);
>     } else {
> -        VLOG_WARN("interface %s: enabled", iface->name);
> -        if (!port->active_iface && !moving_active_iface) {
> -            ofproto_revalidate(br->ofproto, port->no_ifaces_tag);
> -            bond_choose_active_iface(port);
> -            bond_send_learning_packets(port);
> -        }
> -        iface->tag = tag_create_random();
> +        VLOG_WARN_RL(&rl, "port %s: all ports disabled, no active interface",
> +                     port->name);
>     }
> -
> -    moving_active_iface = false;
>  }

I don't have my mind completely wrapped around this.  But it seems
like it might be a good idea to ofproto_revalidate old_active_iface if
it exists.  Similarly we may want to revalidate the new active_iface.
This may be automatically done since active_iface will only be changed
during slave enabling and disabling.  It might be a defensive strategy
though.

Looks Good to me.
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to