This patch moves miimon logic from the bond module to netdev-linux.
This greatly simplifies the bonding code while adding minimal
complexity to netdev-linux. The bonding code is so high level, it
really has no business worrying about how precisely slave status is
determined.
I know already that this breaks the statsfixes that were implemented by the
following commits:
827ab71c97 "ofproto: Datapath statistics accounted twice."
6f1435fc8f "ofproto: Resubmit statistics improperly account during..."
These were already broken in a previous merge. I will work on a fix.
The bonding code neglected to call netdev_monitor_poll() on its
monitor during bond_run(). Thus carrier changes would be
permanently queued in the monitor, preventing it from ever allowing
poll_loop to sleep.
The code was careless about updating the netdev_monitor. Newly added
slaves weren't added to the monitor until the next bond_reconfigure() call,
and netdevs were never removed from the monitor.
This patch converts stable bonds from modulo n based hashing to
Highest Random Weight based hashing. This hashing strategy only
redistributes 1/n_slaves traffic when a slave is enabled or
disabled. It also turns out to have a vastly simpler
implementation.
Stable bonds require all flows to be revalidated when anything
changes. Instead of giving each slave a tag, and ORing them
together. This commit creates one tag representing the entire
bond. This will cause less false positives when deciding which
flows to revalidate.
bond_stb_enable_slave() depended on bond->stb_slaves being
nonnull. However, bond_stb_enable_slave() is responsible for
initializing this parameter. Thus none of it's logic ever ran.
Before this patch, when a slave was registered for this first time
the following warning would display.
interface (null): enabled
This is because the slave was enabled before having its name
configured.
The bonding code only needs to know whether a given slave may be
enabled, and whether LACP has been negotiated on the bond. Instead
of passing in the LACP handle and letting the bond query this
information. This patch passes in the information directly.
For BM_STABLE bonds, instead of choosing the sort key in the
qsort() comparator, this patch makes it a configuration setting of
each slave. This will help wrest LACP out of the bonding code
further in future patches.
Before this patch, the bonding code had taken over responsibility
for running the LACP module. However, the bonding code only needs
the LACP module for some basic status queries. LACP and bonding
are actually logically parallel modules and do not really have a
parent child relationship. Furthermore, we need to be able to run
LACP on non-bonded interfaces which the existing approach
prevented. This patch gives control of the LACP module back to the
bridge.
The enabled flag in the LACP module was only used to set the
Collecting and Distributing flags in the LACP protocol. It was
intended to be set by the bonding code to mimic its enabled flag.
The spec is relatively vague on the precise meaning of these flags,
and most implementations do something completely different with
them. For these reasons, it seems acceptable to remove the enabled
flag for the sake of simplicity. A slave is now Collecting and
Distributing if it is attached, or LACP couldn't be negotiated.
Slave registration should go through the normal slave enabling
facilities instead of doing it by hand. Before this patch, newly
created slaves would have no tag associated with them.
Furthermore, any further changes to how slaves are enabled would
not be picked up by the registration code.
When all flows in a bond are revalidated, stale bond_entry's can
cause incorrect load balancing. These issues will naturally
resolve themselves overtime. However, it's better to deal with
them immediately.
If LACP causes the return of bond_is_tcp_hash to change for
whatever reason, all flows should be revalidated because they will
have a different hash result.
Changes in the bonding mode can cause drastic changes in flow
assignments to slaves. This commit causes all flows in a bridge
to be revalidated when bond_reconfigure() changes its bonding mode.
This approach is a bit aggressive, but bond reconfiguration
shouldn't happen often.
When the bonding library encounters a flow it hasn't seen before,
it assigns it to the active slave and waits for load balancing to
move it to a more appropriate place. This commit causes it to
first attempt a random slave.
This removes over 1000 lines of code from bridge.c and will make it
easier to moving the bonding implementation into ofproto as part of
future development.