All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jay Vosburgh <jv@jvosburgh.net>
To: Hangbin Liu <liuhangbin@gmail.com>
Cc: netdev@vger.kernel.org, Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Nikolay Aleksandrov <razor@blackwall.org>,
	Simon Horman <horms@kernel.org>, Shuah Khan <shuah@kernel.org>,
	linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH net 1/2] bonding: update ntt to true in passive mode
Date: Wed, 16 Jul 2025 10:35:34 -0700	[thread overview]
Message-ID: <807057.1752687334@famine> (raw)
In-Reply-To: <aHd4ddc1YzeT1lN3@fedora>

Hangbin Liu <liuhangbin@gmail.com> wrote:

>On Tue, Jul 15, 2025 at 09:19:49PM -0700, Jay Vosburgh wrote:
>> Hangbin Liu <liuhangbin@gmail.com> wrote:
>> 
>> >When lacp_active is set to off, the bond operates in passive mode, meaning it
>> >will only "speak when spoken to." However, the current kernel implementation
>> >only sends an LACPDU in response when the partner's state changes.
>> >
>> >In this situation, once LACP negotiation succeeds, the actor stops sending
>> >LACPDUs until the partner times out and sends an "expired" LACPDU.
>> >This leads to endless LACP state flapping.
>> 
>> 	From the above, I suspect our implementation isn't compliant to
>> the standard.  Per IEEE 802.1AX-2014 6.4.1 LACP design elements:
>> 
>> c)	Active or passive participation in LACP is controlled by
>> 	LACP_Activity, an administrative control associated with each
>> 	Aggregation Port, that can take the value Active LACP or Passive
>> 	LACP. Passive LACP indicates the Aggregation Port’s preference
>> 	for not transmitting LACPDUs unless its Partner’s control value
>> 	is Active LACP (i.e., a preference not to speak unless spoken
>> 	to). Active LACP indicates the Aggregation Port’s preference to
>
>OK, so this means the passive side should start sending LACPDUs when receive
>passive actor's LACPDUs, with the slow/fast rate based on partner's rate?

	Did you mean "receive active actor's LACPDUs"?

	Regardless, the standard requires both sides to initiate
periodic LACPDU transmission if either or both enable LACP_Activity in
their LACPDUs.

	So, if a received LACPDU from the partner has LACP_Activity set,
then, yes, we would enable periodic LACPDU transmission, regardless of
our local setting of "lacp_active" / LACP_Activity.

>Hmm, then when we should stop sending LACPDUs? After
>port->sm_mux_state == AD_MUX_DETACHED ?

	We stop sending when the criteria for NO_PERIODIC in the
periodic state machine is met (IEEE 802.1AX-2014 6.4.13, Figure 6-19).

	Practically speaking, this happens when a BEGIN event occurs,
due to a port being reinitialized.  The ad_mux_machine() will set the
mux state to AD_MUX_DETACHED when BEGIN occurs, so I don't think we need
to test for DETACHED explicitly.

	The NO_PERIODIC check is the first "if" block in
ad_periodic_machine() that I referenced below.  The code currently tests
all of the criteria from Figure 6-19, but adds a test of "!lacp_active",
which is why I suspect that removing that bit and managing the
lacp_active option via the LACP_Activity in the actor port state would
do the right thing.

	-J

>> 	participate in the protocol regardless of the Partner’s control
>> 	value (i.e., a preference to speak regardless).
>> 
>> d)	Periodic transmission of LACPDUs occurs if the LACP_Activity
>> 	control of either the Actor or the Partner is Active LACP. These
>> 	periodic transmissions will occur at either a slow or fast
>> 	transmission rate depending upon the expressed LACP_Timeout
>> 	preference (Long Timeout or Short Timeout) of the Partner
>> 	System.
>> 
>> 	Which, in summary, means that if either end (actor or partner)
>> has LACP_Activity set, both ends must send periodic LACPDUs at the rate
>> specified by their respective partner's LACP_Timeout rate.
>> 
>> >To avoid this, we need update ntt to true once received an LACPDU from the
>> >partner, ensuring an immediate reply. With this fix, the link becomes stable
>> >in most cases, except for one specific scenario:
>> >
>> >Actor: lacp_active=off, lacp_rate=slow
>> >Partner: lacp_active=on, lacp_rate=fast
>> >
>> >In this case, the partner expects frequent LACPDUs (every 1 second), but the
>> >actor only responds after receiving an LACPDU, which, in this setup, the
>> >partner sends every 30 seconds due to the actor's lacp_rate=slow. By the time
>> >the actor replies, the partner has already timed out and sent an "expired"
>> >LACPDU.
>> 
>> 	Presuming that I'm correct that we're not implementing 6.4.1 d),
>> above, correctly, then I don't think this is a proper fix, as it kind of
>> band-aids over the problem a bit.
>> 
>> 	Looking at the code, I suspect the problem revolves around the
>> "lacp_active" check in ad_periodic_machine():
>> 
>> static void ad_periodic_machine(struct port *port, struct bond_params *bond_params)
>> {
>> 	periodic_states_t last_state;
>> 
>> 	/* keep current state machine state to compare later if it was changed */
>> 	last_state = port->sm_periodic_state;
>> 
>> 	/* check if port was reinitialized */
>> 	if (((port->sm_vars & AD_PORT_BEGIN) || !(port->sm_vars & AD_PORT_LACP_ENABLED) || !port->is_enabled) ||
>> 	    (!(port->actor_oper_port_state & LACP_STATE_LACP_ACTIVITY) && !(port->partner_oper.port_state & LACP_STATE_LACP_ACTIVITY)) ||
>> 	    !bond_params->lacp_active) {
>> 		port->sm_periodic_state = AD_NO_PERIODIC;
>> 	}
>> 
>> 	In the above, because all the tests are chained with ||, the
>> lacp_active test overrides the two correct-looking
>> LACP_STATE_LACP_ACTIVITY tests.
>> 
>> 	It looks like ad_initialize_port() always sets
>> LACP_STATE_LACP_ACTIVITY in the port->actor_oper_port_state, and nothing
>> ever clears it.
>> 
>> 	Thinking out loud, perhaps this could be fixed by
>> 
>> 	a) remove the test of bond_params->lacp_active here, and,
>> 
>> 	b) The lacp_active option setting controls whether LACP_ACTIVITY
>> is set in port->actor_oper_port_state.
>> 
>> 	Thoughts?
>
>As the upper question. When should we stop sending the LACPDUs?
>
>Thanks
>Hangbin

---
	-Jay Vosburgh, jv@jvosburgh.net


  reply	other threads:[~2025-07-16 17:35 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-09  9:03 [PATCH net 0/2] bonding: fix LACP negotiation issues in passive mode Hangbin Liu
2025-07-09  9:03 ` [PATCH net 1/2] bonding: update ntt to true " Hangbin Liu
2025-07-16  4:19   ` Jay Vosburgh
2025-07-16 10:01     ` Hangbin Liu
2025-07-16 17:35       ` Jay Vosburgh [this message]
2025-07-23 10:27     ` Hangbin Liu
2025-07-24  9:57       ` Jay Vosburgh
2025-07-24 12:15         ` Hangbin Liu
2025-07-09  9:03 ` [PATCH net 2/2] selftests: bonding: add test for passive LACP mode Hangbin Liu
2025-07-15  9:37   ` Paolo Abeni
2025-07-16 11:23     ` Hangbin Liu
2025-07-24  4:05     ` Hangbin Liu
2025-07-24  4:12       ` Hangbin Liu
2025-07-25  8:27         ` Petr Machata
2025-07-25 12:53           ` Hangbin Liu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=807057.1752687334@famine \
    --to=jv@jvosburgh.net \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=liuhangbin@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=razor@blackwall.org \
    --cc=shuah@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.