Hi,

I have configured teamd witch the lacp runner. When a port has state disabled, all LACPDU frames are received in lacpdu_recv(), but when LACP has reached an agreement (state "current") the port will become enabled and LACPDU frames are no longer received by the port. After the LACP timeout the state will be changed to "expired" and the port will be disabled and LACPDUs can be received again.

In the kernel driver, team.c, the team_handle_frame() will return RX_HANDLER_EXACT when a port is disabled and RX_HANDLER_ANOTHER for an enabled LACP port. This means that the a enabled port will divert all traffic to the team device, which teamd (using lacp) isn't listening to.

I made a kernel patch which seems to work. Thoughts?

===================================================================
--- linux-3.13.3.orig/drivers/net/team/team_mode_loadbalance.c    2014-02-20 15:06:05.526217543 +0100
+++ linux-3.13.3/drivers/net/team/team_mode_loadbalance.c    2014-02-20 15:06:53.406215408 +0100
@@ -226,6 +226,17 @@
     return false;
 }
 
+static rx_handler_result_t lb_receive(struct team *team, struct team_port *port,
+                      struct sk_buff *skb)
+{
+    struct ethhdr *eth = eth_hdr(skb);
+
+    if (unlikely(ntohs(eth->h_proto) == ETH_P_SLOW))
+        return RX_HANDLER_EXACT;
+
+    return RX_HANDLER_ANOTHER;
+}
+
 static int lb_bpf_func_get(struct team *team, struct team_gsetter_ctx *ctx)
 {
     struct lb_priv *lb_priv = get_lb_priv(team);
@@ -649,6 +660,7 @@
     .port_leave        = lb_port_leave,
     .port_disabled        = lb_port_disabled,
     .transmit        = lb_transmit,
+    .receive        = lb_receive,
 };
 
 static const struct team_mode lb_mode = {
===================================================================

Jonas Johansson