1 /* $NetBSD: ieee8023ad_lacp.c,v 1.3 2005/12/11 12:24:54 christos Exp $ */
4 * Copyright (c)2005 YAMAMOTO Takashi,
5 * Copyright (c)2008 Andrew Thompson <thompsa@FreeBSD.org>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/callout.h>
35 #include <sys/eventhandler.h>
37 #include <sys/systm.h>
38 #include <sys/malloc.h>
39 #include <sys/kernel.h> /* hz */
40 #include <sys/socket.h> /* for net/if.h */
41 #include <sys/sockio.h>
42 #include <sys/sysctl.h>
43 #include <machine/stdarg.h>
45 #include <sys/rwlock.h>
46 #include <sys/taskqueue.h>
49 #include <net/if_var.h>
50 #include <net/if_dl.h>
51 #include <net/ethernet.h>
52 #include <net/if_media.h>
53 #include <net/if_types.h>
55 #include <net/if_lagg.h>
56 #include <net/ieee8023ad_lacp.h>
59 * actor system priority and port priority.
60 * XXX should be configurable.
63 #define LACP_SYSTEM_PRIO 0x8000
64 #define LACP_PORT_PRIO 0x8000
66 const uint8_t ethermulticastaddr_slowprotocols
[ETHER_ADDR_LEN
] =
67 { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x02 };
69 static const struct tlv_template lacp_info_tlv_template
[] = {
70 { LACP_TYPE_ACTORINFO
,
71 sizeof(struct tlvhdr
) + sizeof(struct lacp_peerinfo
) },
72 { LACP_TYPE_PARTNERINFO
,
73 sizeof(struct tlvhdr
) + sizeof(struct lacp_peerinfo
) },
74 { LACP_TYPE_COLLECTORINFO
,
75 sizeof(struct tlvhdr
) + sizeof(struct lacp_collectorinfo
) },
79 static const struct tlv_template marker_info_tlv_template
[] = {
81 sizeof(struct tlvhdr
) + sizeof(struct lacp_markerinfo
) },
85 static const struct tlv_template marker_response_tlv_template
[] = {
86 { MARKER_TYPE_RESPONSE
,
87 sizeof(struct tlvhdr
) + sizeof(struct lacp_markerinfo
) },
91 typedef void (*lacp_timer_func_t
)(struct lacp_port
*);
93 static void lacp_fill_actorinfo(struct lacp_port
*, struct lacp_peerinfo
*);
94 static void lacp_fill_markerinfo(struct lacp_port
*,
95 struct lacp_markerinfo
*);
97 static uint64_t lacp_aggregator_bandwidth(struct lacp_aggregator
*);
98 static void lacp_suppress_distributing(struct lacp_softc
*,
99 struct lacp_aggregator
*);
100 static void lacp_transit_expire(void *);
101 static void lacp_update_portmap(struct lacp_softc
*);
102 static void lacp_select_active_aggregator(struct lacp_softc
*);
103 static uint16_t lacp_compose_key(struct lacp_port
*);
104 static int tlv_check(const void *, size_t, const struct tlvhdr
*,
105 const struct tlv_template
*, boolean_t
);
106 static void lacp_tick(void *);
108 static void lacp_fill_aggregator_id(struct lacp_aggregator
*,
109 const struct lacp_port
*);
110 static void lacp_fill_aggregator_id_peer(struct lacp_peerinfo
*,
111 const struct lacp_peerinfo
*);
112 static int lacp_aggregator_is_compatible(const struct lacp_aggregator
*,
113 const struct lacp_port
*);
114 static int lacp_peerinfo_is_compatible(const struct lacp_peerinfo
*,
115 const struct lacp_peerinfo
*);
117 static struct lacp_aggregator
*lacp_aggregator_get(struct lacp_softc
*,
119 static void lacp_aggregator_addref(struct lacp_softc
*,
120 struct lacp_aggregator
*);
121 static void lacp_aggregator_delref(struct lacp_softc
*,
122 struct lacp_aggregator
*);
124 /* receive machine */
126 static int lacp_pdu_input(struct lacp_port
*, struct mbuf
*);
127 static int lacp_marker_input(struct lacp_port
*, struct mbuf
*);
128 static void lacp_sm_rx(struct lacp_port
*, const struct lacpdu
*);
129 static void lacp_sm_rx_timer(struct lacp_port
*);
130 static void lacp_sm_rx_set_expired(struct lacp_port
*);
131 static void lacp_sm_rx_update_ntt(struct lacp_port
*,
132 const struct lacpdu
*);
133 static void lacp_sm_rx_record_pdu(struct lacp_port
*,
134 const struct lacpdu
*);
135 static void lacp_sm_rx_update_selected(struct lacp_port
*,
136 const struct lacpdu
*);
137 static void lacp_sm_rx_record_default(struct lacp_port
*);
138 static void lacp_sm_rx_update_default_selected(struct lacp_port
*);
139 static void lacp_sm_rx_update_selected_from_peerinfo(struct lacp_port
*,
140 const struct lacp_peerinfo
*);
144 static void lacp_sm_mux(struct lacp_port
*);
145 static void lacp_set_mux(struct lacp_port
*, enum lacp_mux_state
);
146 static void lacp_sm_mux_timer(struct lacp_port
*);
148 /* periodic transmit machine */
150 static void lacp_sm_ptx_update_timeout(struct lacp_port
*, uint8_t);
151 static void lacp_sm_ptx_tx_schedule(struct lacp_port
*);
152 static void lacp_sm_ptx_timer(struct lacp_port
*);
154 /* transmit machine */
156 static void lacp_sm_tx(struct lacp_port
*);
157 static void lacp_sm_assert_ntt(struct lacp_port
*);
159 static void lacp_run_timers(struct lacp_port
*);
160 static int lacp_compare_peerinfo(const struct lacp_peerinfo
*,
161 const struct lacp_peerinfo
*);
162 static int lacp_compare_systemid(const struct lacp_systemid
*,
163 const struct lacp_systemid
*);
164 static void lacp_port_enable(struct lacp_port
*);
165 static void lacp_port_disable(struct lacp_port
*);
166 static void lacp_select(struct lacp_port
*);
167 static void lacp_unselect(struct lacp_port
*);
168 static void lacp_disable_collecting(struct lacp_port
*);
169 static void lacp_enable_collecting(struct lacp_port
*);
170 static void lacp_disable_distributing(struct lacp_port
*);
171 static void lacp_enable_distributing(struct lacp_port
*);
172 static int lacp_xmit_lacpdu(struct lacp_port
*);
173 static int lacp_xmit_marker(struct lacp_port
*);
177 static void lacp_dump_lacpdu(const struct lacpdu
*);
178 static const char *lacp_format_partner(const struct lacp_peerinfo
*, char *,
180 static const char *lacp_format_lagid(const struct lacp_peerinfo
*,
181 const struct lacp_peerinfo
*, char *, size_t);
182 static const char *lacp_format_lagid_aggregator(const struct lacp_aggregator
*,
184 static const char *lacp_format_state(uint8_t, char *, size_t);
185 static const char *lacp_format_mac(const uint8_t *, char *, size_t);
186 static const char *lacp_format_systemid(const struct lacp_systemid
*, char *,
188 static const char *lacp_format_portid(const struct lacp_portid
*, char *,
190 static void lacp_dprintf(const struct lacp_port
*, const char *, ...)
191 __attribute__((__format__(__printf__
, 2, 3)));
193 static VNET_DEFINE(int, lacp_debug
);
194 #define V_lacp_debug VNET(lacp_debug)
195 SYSCTL_NODE(_net_link_lagg
, OID_AUTO
, lacp
, CTLFLAG_RD
, 0, "ieee802.3ad");
196 SYSCTL_INT(_net_link_lagg_lacp
, OID_AUTO
, debug
, CTLFLAG_RWTUN
| CTLFLAG_VNET
,
197 &VNET_NAME(lacp_debug
), 0, "Enable LACP debug logging (1=debug, 2=trace)");
199 static VNET_DEFINE(int, lacp_default_strict_mode
) = 1;
200 SYSCTL_INT(_net_link_lagg_lacp
, OID_AUTO
, default_strict_mode
, CTLFLAG_RWTUN
,
201 &VNET_NAME(lacp_default_strict_mode
), 0,
202 "LACP strict protocol compliance default");
204 #define LACP_DPRINTF(a) if (V_lacp_debug & 0x01) { lacp_dprintf a ; }
205 #define LACP_TRACE(a) if (V_lacp_debug & 0x02) { lacp_dprintf(a,"%s\n",__func__); }
206 #define LACP_TPRINTF(a) if (V_lacp_debug & 0x04) { lacp_dprintf a ; }
209 * partner administration variables.
210 * XXX should be configurable.
213 static const struct lacp_peerinfo lacp_partner_admin_optimistic
= {
214 .lip_systemid
= { .lsi_prio
= 0xffff },
215 .lip_portid
= { .lpi_prio
= 0xffff },
216 .lip_state
= LACP_STATE_SYNC
| LACP_STATE_AGGREGATION
|
217 LACP_STATE_COLLECTING
| LACP_STATE_DISTRIBUTING
,
220 static const struct lacp_peerinfo lacp_partner_admin_strict
= {
221 .lip_systemid
= { .lsi_prio
= 0xffff },
222 .lip_portid
= { .lpi_prio
= 0xffff },
226 static const lacp_timer_func_t lacp_timer_funcs
[LACP_NTIMER
] = {
227 [LACP_TIMER_CURRENT_WHILE
] = lacp_sm_rx_timer
,
228 [LACP_TIMER_PERIODIC
] = lacp_sm_ptx_timer
,
229 [LACP_TIMER_WAIT_WHILE
] = lacp_sm_mux_timer
,
233 lacp_input(struct lagg_port
*lgp
, struct mbuf
*m
)
235 struct lacp_port
*lp
= LACP_PORT(lgp
);
238 if (m
->m_pkthdr
.len
< sizeof(struct ether_header
) + sizeof(subtype
)) {
243 m_copydata(m
, sizeof(struct ether_header
), sizeof(subtype
), &subtype
);
245 case SLOWPROTOCOLS_SUBTYPE_LACP
:
246 lacp_pdu_input(lp
, m
);
249 case SLOWPROTOCOLS_SUBTYPE_MARKER
:
250 lacp_marker_input(lp
, m
);
254 /* Not a subtype we are interested in */
259 * lacp_pdu_input: process lacpdu
262 lacp_pdu_input(struct lacp_port
*lp
, struct mbuf
*m
)
264 struct lacp_softc
*lsc
= lp
->lp_lsc
;
268 if (m
->m_pkthdr
.len
!= sizeof(*du
)) {
272 if ((m
->m_flags
& M_MCAST
) == 0) {
276 if (m
->m_len
< sizeof(*du
)) {
277 m
= m_pullup(m
, sizeof(*du
));
283 du
= mtod(m
, struct lacpdu
*);
285 if (memcmp(&du
->ldu_eh
.ether_dhost
,
286 ðermulticastaddr_slowprotocols
, ETHER_ADDR_LEN
)) {
291 * ignore the version for compatibility with
292 * the future protocol revisions.
295 if (du
->ldu_sph
.sph_version
!= 1) {
301 * ignore tlv types for compatibility with
302 * the future protocol revisions.
304 if (tlv_check(du
, sizeof(*du
), &du
->ldu_tlv_actor
,
305 lacp_info_tlv_template
, FALSE
)) {
309 if (V_lacp_debug
> 0) {
310 lacp_dprintf(lp
, "lacpdu receive\n");
311 lacp_dump_lacpdu(du
);
314 if ((1 << lp
->lp_ifp
->if_dunit
) & lp
->lp_lsc
->lsc_debug
.lsc_rx_test
) {
315 LACP_TPRINTF((lp
, "Dropping RX PDU\n"));
332 lacp_fill_actorinfo(struct lacp_port
*lp
, struct lacp_peerinfo
*info
)
334 struct lagg_port
*lgp
= lp
->lp_lagg
;
335 struct lagg_softc
*sc
= lgp
->lp_softc
;
337 info
->lip_systemid
.lsi_prio
= htons(LACP_SYSTEM_PRIO
);
338 memcpy(&info
->lip_systemid
.lsi_mac
,
339 IF_LLADDR(sc
->sc_ifp
), ETHER_ADDR_LEN
);
340 info
->lip_portid
.lpi_prio
= htons(LACP_PORT_PRIO
);
341 info
->lip_portid
.lpi_portno
= htons(lp
->lp_ifp
->if_index
);
342 info
->lip_state
= lp
->lp_state
;
346 lacp_fill_markerinfo(struct lacp_port
*lp
, struct lacp_markerinfo
*info
)
348 struct ifnet
*ifp
= lp
->lp_ifp
;
350 /* Fill in the port index and system id (encoded as the MAC) */
351 info
->mi_rq_port
= htons(ifp
->if_index
);
352 memcpy(&info
->mi_rq_system
, lp
->lp_systemid
.lsi_mac
, ETHER_ADDR_LEN
);
353 info
->mi_rq_xid
= htonl(0);
357 lacp_xmit_lacpdu(struct lacp_port
*lp
)
359 struct lagg_port
*lgp
= lp
->lp_lagg
;
364 LACP_LOCK_ASSERT(lp
->lp_lsc
);
366 m
= m_gethdr(M_NOWAIT
, MT_DATA
);
370 m
->m_len
= m
->m_pkthdr
.len
= sizeof(*du
);
372 du
= mtod(m
, struct lacpdu
*);
373 memset(du
, 0, sizeof(*du
));
375 memcpy(&du
->ldu_eh
.ether_dhost
, ethermulticastaddr_slowprotocols
,
377 memcpy(&du
->ldu_eh
.ether_shost
, lgp
->lp_lladdr
, ETHER_ADDR_LEN
);
378 du
->ldu_eh
.ether_type
= htons(ETHERTYPE_SLOW
);
380 du
->ldu_sph
.sph_subtype
= SLOWPROTOCOLS_SUBTYPE_LACP
;
381 du
->ldu_sph
.sph_version
= 1;
383 TLV_SET(&du
->ldu_tlv_actor
, LACP_TYPE_ACTORINFO
, sizeof(du
->ldu_actor
));
384 du
->ldu_actor
= lp
->lp_actor
;
386 TLV_SET(&du
->ldu_tlv_partner
, LACP_TYPE_PARTNERINFO
,
387 sizeof(du
->ldu_partner
));
388 du
->ldu_partner
= lp
->lp_partner
;
390 TLV_SET(&du
->ldu_tlv_collector
, LACP_TYPE_COLLECTORINFO
,
391 sizeof(du
->ldu_collector
));
392 du
->ldu_collector
.lci_maxdelay
= 0;
394 if (V_lacp_debug
> 0) {
395 lacp_dprintf(lp
, "lacpdu transmit\n");
396 lacp_dump_lacpdu(du
);
399 m
->m_flags
|= M_MCAST
;
402 * XXX should use higher priority queue.
403 * otherwise network congestion can break aggregation.
406 error
= lagg_enqueue(lp
->lp_ifp
, m
);
411 lacp_xmit_marker(struct lacp_port
*lp
)
413 struct lagg_port
*lgp
= lp
->lp_lagg
;
415 struct markerdu
*mdu
;
418 LACP_LOCK_ASSERT(lp
->lp_lsc
);
420 m
= m_gethdr(M_NOWAIT
, MT_DATA
);
424 m
->m_len
= m
->m_pkthdr
.len
= sizeof(*mdu
);
426 mdu
= mtod(m
, struct markerdu
*);
427 memset(mdu
, 0, sizeof(*mdu
));
429 memcpy(&mdu
->mdu_eh
.ether_dhost
, ethermulticastaddr_slowprotocols
,
431 memcpy(&mdu
->mdu_eh
.ether_shost
, lgp
->lp_lladdr
, ETHER_ADDR_LEN
);
432 mdu
->mdu_eh
.ether_type
= htons(ETHERTYPE_SLOW
);
434 mdu
->mdu_sph
.sph_subtype
= SLOWPROTOCOLS_SUBTYPE_MARKER
;
435 mdu
->mdu_sph
.sph_version
= 1;
437 /* Bump the transaction id and copy over the marker info */
438 lp
->lp_marker
.mi_rq_xid
= htonl(ntohl(lp
->lp_marker
.mi_rq_xid
) + 1);
439 TLV_SET(&mdu
->mdu_tlv
, MARKER_TYPE_INFO
, sizeof(mdu
->mdu_info
));
440 mdu
->mdu_info
= lp
->lp_marker
;
442 LACP_DPRINTF((lp
, "marker transmit, port=%u, sys=%6D, id=%u\n",
443 ntohs(mdu
->mdu_info
.mi_rq_port
), mdu
->mdu_info
.mi_rq_system
, ":",
444 ntohl(mdu
->mdu_info
.mi_rq_xid
)));
446 m
->m_flags
|= M_MCAST
;
447 error
= lagg_enqueue(lp
->lp_ifp
, m
);
452 lacp_linkstate(struct lagg_port
*lgp
)
454 struct lacp_port
*lp
= LACP_PORT(lgp
);
455 struct lacp_softc
*lsc
= lp
->lp_lsc
;
456 struct ifnet
*ifp
= lgp
->lp_ifp
;
457 struct ifmediareq ifmr
;
463 bzero((char *)&ifmr
, sizeof(ifmr
));
464 error
= (*ifp
->if_ioctl
)(ifp
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
);
469 media
= ifmr
.ifm_active
;
470 LACP_DPRINTF((lp
, "media changed 0x%x -> 0x%x, ether = %d, fdx = %d, "
471 "link = %d\n", lp
->lp_media
, media
, IFM_TYPE(media
) == IFM_ETHER
,
472 (media
& IFM_FDX
) != 0, ifp
->if_link_state
== LINK_STATE_UP
));
473 old_state
= lp
->lp_state
;
474 old_key
= lp
->lp_key
;
476 lp
->lp_media
= media
;
478 * If the port is not an active full duplex Ethernet link then it can
481 if (IFM_TYPE(media
) != IFM_ETHER
|| (media
& IFM_FDX
) == 0 ||
482 ifp
->if_link_state
!= LINK_STATE_UP
) {
483 lacp_port_disable(lp
);
485 lacp_port_enable(lp
);
487 lp
->lp_key
= lacp_compose_key(lp
);
489 if (old_state
!= lp
->lp_state
|| old_key
!= lp
->lp_key
) {
490 LACP_DPRINTF((lp
, "-> UNSELECTED\n"));
491 lp
->lp_selected
= LACP_UNSELECTED
;
499 struct lacp_softc
*lsc
= arg
;
500 struct lacp_port
*lp
;
502 LIST_FOREACH(lp
, &lsc
->lsc_ports
, lp_next
) {
503 if ((lp
->lp_state
& LACP_STATE_AGGREGATION
) == 0)
506 CURVNET_SET(lp
->lp_ifp
->if_vnet
);
512 lacp_sm_ptx_tx_schedule(lp
);
515 callout_reset(&lsc
->lsc_callout
, hz
, lacp_tick
, lsc
);
519 lacp_port_create(struct lagg_port
*lgp
)
521 struct lagg_softc
*sc
= lgp
->lp_softc
;
522 struct lacp_softc
*lsc
= LACP_SOFTC(sc
);
523 struct lacp_port
*lp
;
524 struct ifnet
*ifp
= lgp
->lp_ifp
;
525 struct sockaddr_dl sdl
;
526 struct ifmultiaddr
*rifma
= NULL
;
529 boolean_t active
= TRUE
; /* XXX should be configurable */
530 boolean_t fast
= FALSE
; /* Configurable via ioctl */
532 link_init_sdl(ifp
, (struct sockaddr
*)&sdl
, IFT_ETHER
);
533 sdl
.sdl_alen
= ETHER_ADDR_LEN
;
535 bcopy(ðermulticastaddr_slowprotocols
,
536 LLADDR(&sdl
), ETHER_ADDR_LEN
);
537 error
= if_addmulti(ifp
, (struct sockaddr
*)&sdl
, &rifma
);
539 printf("%s: ADDMULTI failed on %s\n", __func__
,
540 lgp
->lp_ifp
->if_xname
);
544 lp
= malloc(sizeof(struct lacp_port
),
545 M_DEVBUF
, M_NOWAIT
|M_ZERO
);
556 LIST_INSERT_HEAD(&lsc
->lsc_ports
, lp
, lp_next
);
558 lacp_fill_actorinfo(lp
, &lp
->lp_actor
);
559 lacp_fill_markerinfo(lp
, &lp
->lp_marker
);
561 (active
? LACP_STATE_ACTIVITY
: 0) |
562 (fast
? LACP_STATE_TIMEOUT
: 0);
563 lp
->lp_aggregator
= NULL
;
564 lacp_sm_rx_set_expired(lp
);
572 lacp_port_destroy(struct lagg_port
*lgp
)
574 struct lacp_port
*lp
= LACP_PORT(lgp
);
575 struct lacp_softc
*lsc
= lp
->lp_lsc
;
579 for (i
= 0; i
< LACP_NTIMER
; i
++) {
580 LACP_TIMER_DISARM(lp
, i
);
583 lacp_disable_collecting(lp
);
584 lacp_disable_distributing(lp
);
587 LIST_REMOVE(lp
, lp_next
);
590 /* The address may have already been removed by if_purgemaddrs() */
591 if (!lgp
->lp_detaching
)
592 if_delmulti_ifma(lp
->lp_ifma
);
598 lacp_req(struct lagg_softc
*sc
, void *data
)
600 struct lacp_opreq
*req
= (struct lacp_opreq
*)data
;
601 struct lacp_softc
*lsc
= LACP_SOFTC(sc
);
602 struct lacp_aggregator
*la
;
604 bzero(req
, sizeof(struct lacp_opreq
));
607 * If the LACP softc is NULL, return with the opreq structure full of
608 * zeros. It is normal for the softc to be NULL while the lagg is
614 la
= lsc
->lsc_active_aggregator
;
617 req
->actor_prio
= ntohs(la
->la_actor
.lip_systemid
.lsi_prio
);
618 memcpy(&req
->actor_mac
, &la
->la_actor
.lip_systemid
.lsi_mac
,
620 req
->actor_key
= ntohs(la
->la_actor
.lip_key
);
621 req
->actor_portprio
= ntohs(la
->la_actor
.lip_portid
.lpi_prio
);
622 req
->actor_portno
= ntohs(la
->la_actor
.lip_portid
.lpi_portno
);
623 req
->actor_state
= la
->la_actor
.lip_state
;
625 req
->partner_prio
= ntohs(la
->la_partner
.lip_systemid
.lsi_prio
);
626 memcpy(&req
->partner_mac
, &la
->la_partner
.lip_systemid
.lsi_mac
,
628 req
->partner_key
= ntohs(la
->la_partner
.lip_key
);
629 req
->partner_portprio
= ntohs(la
->la_partner
.lip_portid
.lpi_prio
);
630 req
->partner_portno
= ntohs(la
->la_partner
.lip_portid
.lpi_portno
);
631 req
->partner_state
= la
->la_partner
.lip_state
;
637 lacp_portreq(struct lagg_port
*lgp
, void *data
)
639 struct lacp_opreq
*req
= (struct lacp_opreq
*)data
;
640 struct lacp_port
*lp
= LACP_PORT(lgp
);
641 struct lacp_softc
*lsc
= lp
->lp_lsc
;
644 req
->actor_prio
= ntohs(lp
->lp_actor
.lip_systemid
.lsi_prio
);
645 memcpy(&req
->actor_mac
, &lp
->lp_actor
.lip_systemid
.lsi_mac
,
647 req
->actor_key
= ntohs(lp
->lp_actor
.lip_key
);
648 req
->actor_portprio
= ntohs(lp
->lp_actor
.lip_portid
.lpi_prio
);
649 req
->actor_portno
= ntohs(lp
->lp_actor
.lip_portid
.lpi_portno
);
650 req
->actor_state
= lp
->lp_actor
.lip_state
;
652 req
->partner_prio
= ntohs(lp
->lp_partner
.lip_systemid
.lsi_prio
);
653 memcpy(&req
->partner_mac
, &lp
->lp_partner
.lip_systemid
.lsi_mac
,
655 req
->partner_key
= ntohs(lp
->lp_partner
.lip_key
);
656 req
->partner_portprio
= ntohs(lp
->lp_partner
.lip_portid
.lpi_prio
);
657 req
->partner_portno
= ntohs(lp
->lp_partner
.lip_portid
.lpi_portno
);
658 req
->partner_state
= lp
->lp_partner
.lip_state
;
663 lacp_disable_collecting(struct lacp_port
*lp
)
665 LACP_DPRINTF((lp
, "collecting disabled\n"));
666 lp
->lp_state
&= ~LACP_STATE_COLLECTING
;
670 lacp_enable_collecting(struct lacp_port
*lp
)
672 LACP_DPRINTF((lp
, "collecting enabled\n"));
673 lp
->lp_state
|= LACP_STATE_COLLECTING
;
677 lacp_disable_distributing(struct lacp_port
*lp
)
679 struct lacp_aggregator
*la
= lp
->lp_aggregator
;
680 struct lacp_softc
*lsc
= lp
->lp_lsc
;
681 struct lagg_softc
*sc
= lsc
->lsc_softc
;
682 char buf
[LACP_LAGIDSTR_MAX
+1];
684 LACP_LOCK_ASSERT(lsc
);
686 if (la
== NULL
|| (lp
->lp_state
& LACP_STATE_DISTRIBUTING
) == 0) {
690 KASSERT(!TAILQ_EMPTY(&la
->la_ports
), ("no aggregator ports"));
691 KASSERT(la
->la_nports
> 0, ("nports invalid (%d)", la
->la_nports
));
692 KASSERT(la
->la_refcnt
>= la
->la_nports
, ("aggregator refcnt invalid"));
694 LACP_DPRINTF((lp
, "disable distributing on aggregator %s, "
696 lacp_format_lagid_aggregator(la
, buf
, sizeof(buf
)),
697 la
->la_nports
, la
->la_nports
- 1));
699 TAILQ_REMOVE(&la
->la_ports
, lp
, lp_dist_q
);
701 sc
->sc_active
= la
->la_nports
;
703 if (lsc
->lsc_active_aggregator
== la
) {
704 lacp_suppress_distributing(lsc
, la
);
705 lacp_select_active_aggregator(lsc
);
706 /* regenerate the port map, the active aggregator has changed */
707 lacp_update_portmap(lsc
);
710 lp
->lp_state
&= ~LACP_STATE_DISTRIBUTING
;
714 lacp_enable_distributing(struct lacp_port
*lp
)
716 struct lacp_aggregator
*la
= lp
->lp_aggregator
;
717 struct lacp_softc
*lsc
= lp
->lp_lsc
;
718 struct lagg_softc
*sc
= lsc
->lsc_softc
;
719 char buf
[LACP_LAGIDSTR_MAX
+1];
721 LACP_LOCK_ASSERT(lsc
);
723 if ((lp
->lp_state
& LACP_STATE_DISTRIBUTING
) != 0) {
727 LACP_DPRINTF((lp
, "enable distributing on aggregator %s, "
729 lacp_format_lagid_aggregator(la
, buf
, sizeof(buf
)),
730 la
->la_nports
, la
->la_nports
+ 1));
732 KASSERT(la
->la_refcnt
> la
->la_nports
, ("aggregator refcnt invalid"));
733 TAILQ_INSERT_HEAD(&la
->la_ports
, lp
, lp_dist_q
);
735 sc
->sc_active
= la
->la_nports
;
737 lp
->lp_state
|= LACP_STATE_DISTRIBUTING
;
739 if (lsc
->lsc_active_aggregator
== la
) {
740 lacp_suppress_distributing(lsc
, la
);
741 lacp_update_portmap(lsc
);
743 /* try to become the active aggregator */
744 lacp_select_active_aggregator(lsc
);
748 lacp_transit_expire(void *vp
)
750 struct lacp_softc
*lsc
= vp
;
752 LACP_LOCK_ASSERT(lsc
);
754 CURVNET_SET(lsc
->lsc_softc
->sc_ifp
->if_vnet
);
758 lsc
->lsc_suppress_distributing
= FALSE
;
762 lacp_attach(struct lagg_softc
*sc
)
764 struct lacp_softc
*lsc
;
766 lsc
= malloc(sizeof(struct lacp_softc
), M_DEVBUF
, M_WAITOK
| M_ZERO
);
771 lsc
->lsc_hashkey
= m_ether_tcpip_hash_init();
772 lsc
->lsc_active_aggregator
= NULL
;
773 lsc
->lsc_strict_mode
= VNET(lacp_default_strict_mode
);
775 TAILQ_INIT(&lsc
->lsc_aggregators
);
776 LIST_INIT(&lsc
->lsc_ports
);
778 callout_init_mtx(&lsc
->lsc_transit_callout
, &lsc
->lsc_mtx
, 0);
779 callout_init_mtx(&lsc
->lsc_callout
, &lsc
->lsc_mtx
, 0);
781 /* if the lagg is already up then do the same */
782 if (sc
->sc_ifp
->if_drv_flags
& IFF_DRV_RUNNING
)
787 lacp_detach(void *psc
)
789 struct lacp_softc
*lsc
= (struct lacp_softc
*)psc
;
791 KASSERT(TAILQ_EMPTY(&lsc
->lsc_aggregators
),
792 ("aggregators still active"));
793 KASSERT(lsc
->lsc_active_aggregator
== NULL
,
794 ("aggregator still attached"));
796 callout_drain(&lsc
->lsc_transit_callout
);
797 callout_drain(&lsc
->lsc_callout
);
799 LACP_LOCK_DESTROY(lsc
);
804 lacp_init(struct lagg_softc
*sc
)
806 struct lacp_softc
*lsc
= LACP_SOFTC(sc
);
809 callout_reset(&lsc
->lsc_callout
, hz
, lacp_tick
, lsc
);
814 lacp_stop(struct lagg_softc
*sc
)
816 struct lacp_softc
*lsc
= LACP_SOFTC(sc
);
819 callout_stop(&lsc
->lsc_transit_callout
);
820 callout_stop(&lsc
->lsc_callout
);
825 lacp_select_tx_port(struct lagg_softc
*sc
, struct mbuf
*m
)
827 struct lacp_softc
*lsc
= LACP_SOFTC(sc
);
828 struct lacp_portmap
*pm
;
829 struct lacp_port
*lp
;
832 if (__predict_false(lsc
->lsc_suppress_distributing
)) {
833 LACP_DPRINTF((NULL
, "%s: waiting transit\n", __func__
));
837 pm
= &lsc
->lsc_pmap
[lsc
->lsc_activemap
];
838 if (pm
->pm_count
== 0) {
839 LACP_DPRINTF((NULL
, "%s: no active aggregator\n", __func__
));
843 if ((sc
->sc_opts
& LAGG_OPT_USE_FLOWID
) &&
844 M_HASHTYPE_GET(m
) != M_HASHTYPE_NONE
)
845 hash
= m
->m_pkthdr
.flowid
>> sc
->flowid_shift
;
847 hash
= m_ether_tcpip_hash(sc
->sc_flags
, m
, lsc
->lsc_hashkey
);
848 hash
%= pm
->pm_count
;
849 lp
= pm
->pm_map
[hash
];
851 KASSERT((lp
->lp_state
& LACP_STATE_DISTRIBUTING
) != 0,
852 ("aggregated port is not distributing"));
854 return (lp
->lp_lagg
);
857 * lacp_suppress_distributing: drop transmit packets for a while
858 * to preserve packet ordering.
862 lacp_suppress_distributing(struct lacp_softc
*lsc
, struct lacp_aggregator
*la
)
864 struct lacp_port
*lp
;
866 if (lsc
->lsc_active_aggregator
!= la
) {
872 lsc
->lsc_suppress_distributing
= TRUE
;
874 /* send a marker frame down each port to verify the queues are empty */
875 LIST_FOREACH(lp
, &lsc
->lsc_ports
, lp_next
) {
876 lp
->lp_flags
|= LACP_PORT_MARK
;
877 lacp_xmit_marker(lp
);
880 /* set a timeout for the marker frames */
881 callout_reset(&lsc
->lsc_transit_callout
,
882 LACP_TRANSIT_DELAY
* hz
/ 1000, lacp_transit_expire
, lsc
);
886 lacp_compare_peerinfo(const struct lacp_peerinfo
*a
,
887 const struct lacp_peerinfo
*b
)
889 return (memcmp(a
, b
, offsetof(struct lacp_peerinfo
, lip_state
)));
893 lacp_compare_systemid(const struct lacp_systemid
*a
,
894 const struct lacp_systemid
*b
)
896 return (memcmp(a
, b
, sizeof(*a
)));
901 lacp_compare_portid(const struct lacp_portid
*a
,
902 const struct lacp_portid
*b
)
904 return (memcmp(a
, b
, sizeof(*a
)));
909 lacp_aggregator_bandwidth(struct lacp_aggregator
*la
)
911 struct lacp_port
*lp
;
914 lp
= TAILQ_FIRST(&la
->la_ports
);
919 speed
= ifmedia_baudrate(lp
->lp_media
);
920 speed
*= la
->la_nports
;
922 LACP_DPRINTF((lp
, "speed 0? media=0x%x nports=%d\n",
923 lp
->lp_media
, la
->la_nports
));
930 * lacp_select_active_aggregator: select an aggregator to be used to transmit
931 * packets from lagg(4) interface.
935 lacp_select_active_aggregator(struct lacp_softc
*lsc
)
937 struct lacp_aggregator
*la
;
938 struct lacp_aggregator
*best_la
= NULL
;
939 uint64_t best_speed
= 0;
940 char buf
[LACP_LAGIDSTR_MAX
+1];
944 TAILQ_FOREACH(la
, &lsc
->lsc_aggregators
, la_q
) {
947 if (la
->la_nports
== 0) {
951 speed
= lacp_aggregator_bandwidth(la
);
952 LACP_DPRINTF((NULL
, "%s, speed=%jd, nports=%d\n",
953 lacp_format_lagid_aggregator(la
, buf
, sizeof(buf
)),
954 speed
, la
->la_nports
));
957 * This aggregator is chosen if the partner has a better
958 * system priority or, the total aggregated speed is higher
959 * or, it is already the chosen aggregator
961 if ((best_la
!= NULL
&& LACP_SYS_PRI(la
->la_partner
) <
962 LACP_SYS_PRI(best_la
->la_partner
)) ||
963 speed
> best_speed
||
964 (speed
== best_speed
&&
965 la
== lsc
->lsc_active_aggregator
)) {
971 KASSERT(best_la
== NULL
|| best_la
->la_nports
> 0,
972 ("invalid aggregator refcnt"));
973 KASSERT(best_la
== NULL
|| !TAILQ_EMPTY(&best_la
->la_ports
),
974 ("invalid aggregator list"));
976 if (lsc
->lsc_active_aggregator
!= best_la
) {
977 LACP_DPRINTF((NULL
, "active aggregator changed\n"));
978 LACP_DPRINTF((NULL
, "old %s\n",
979 lacp_format_lagid_aggregator(lsc
->lsc_active_aggregator
,
982 LACP_DPRINTF((NULL
, "active aggregator not changed\n"));
984 LACP_DPRINTF((NULL
, "new %s\n",
985 lacp_format_lagid_aggregator(best_la
, buf
, sizeof(buf
))));
987 if (lsc
->lsc_active_aggregator
!= best_la
) {
988 lsc
->lsc_active_aggregator
= best_la
;
989 lacp_update_portmap(lsc
);
991 lacp_suppress_distributing(lsc
, best_la
);
997 * Updated the inactive portmap array with the new list of ports and
1001 lacp_update_portmap(struct lacp_softc
*lsc
)
1003 struct lagg_softc
*sc
= lsc
->lsc_softc
;
1004 struct lacp_aggregator
*la
;
1005 struct lacp_portmap
*p
;
1006 struct lacp_port
*lp
;
1011 newmap
= lsc
->lsc_activemap
== 0 ? 1 : 0;
1012 p
= &lsc
->lsc_pmap
[newmap
];
1013 la
= lsc
->lsc_active_aggregator
;
1015 bzero(p
, sizeof(struct lacp_portmap
));
1017 if (la
!= NULL
&& la
->la_nports
> 0) {
1018 p
->pm_count
= la
->la_nports
;
1020 TAILQ_FOREACH(lp
, &la
->la_ports
, lp_dist_q
)
1021 p
->pm_map
[i
++] = lp
;
1022 KASSERT(i
== p
->pm_count
, ("Invalid port count"));
1023 speed
= lacp_aggregator_bandwidth(la
);
1025 sc
->sc_ifp
->if_baudrate
= speed
;
1027 /* switch the active portmap over */
1028 atomic_store_rel_int(&lsc
->lsc_activemap
, newmap
);
1029 LACP_DPRINTF((NULL
, "Set table %d with %d ports\n",
1031 lsc
->lsc_pmap
[lsc
->lsc_activemap
].pm_count
));
1035 lacp_compose_key(struct lacp_port
*lp
)
1037 struct lagg_port
*lgp
= lp
->lp_lagg
;
1038 struct lagg_softc
*sc
= lgp
->lp_softc
;
1039 u_int media
= lp
->lp_media
;
1042 if ((lp
->lp_state
& LACP_STATE_AGGREGATION
) == 0) {
1045 * non-aggregatable links should have unique keys.
1047 * XXX this isn't really unique as if_index is 16 bit.
1050 /* bit 0..14: (some bits of) if_index of this port */
1051 key
= lp
->lp_ifp
->if_index
;
1055 u_int subtype
= IFM_SUBTYPE(media
);
1057 KASSERT(IFM_TYPE(media
) == IFM_ETHER
, ("invalid media type"));
1058 KASSERT((media
& IFM_FDX
) != 0, ("aggregating HDX interface"));
1060 /* bit 0..4: IFM_SUBTYPE modulo speed */
1082 case IFM_1000_SGMII
:
1083 case IFM_1000_CX_SGMII
:
1089 case IFM_10G_TWINAX
:
1090 case IFM_10G_TWINAX_LONG
:
1141 /* bit 5..14: (some bits of) if_index of lagg device */
1142 key
|= 0x7fe0 & ((sc
->sc_ifp
->if_index
) << 5);
1145 return (htons(key
));
1149 lacp_aggregator_addref(struct lacp_softc
*lsc
, struct lacp_aggregator
*la
)
1151 char buf
[LACP_LAGIDSTR_MAX
+1];
1153 LACP_DPRINTF((NULL
, "%s: lagid=%s, refcnt %d -> %d\n",
1155 lacp_format_lagid(&la
->la_actor
, &la
->la_partner
,
1157 la
->la_refcnt
, la
->la_refcnt
+ 1));
1159 KASSERT(la
->la_refcnt
> 0, ("refcount <= 0"));
1161 KASSERT(la
->la_refcnt
> la
->la_nports
, ("invalid refcount"));
1165 lacp_aggregator_delref(struct lacp_softc
*lsc
, struct lacp_aggregator
*la
)
1167 char buf
[LACP_LAGIDSTR_MAX
+1];
1169 LACP_DPRINTF((NULL
, "%s: lagid=%s, refcnt %d -> %d\n",
1171 lacp_format_lagid(&la
->la_actor
, &la
->la_partner
,
1173 la
->la_refcnt
, la
->la_refcnt
- 1));
1175 KASSERT(la
->la_refcnt
> la
->la_nports
, ("invalid refcnt"));
1177 if (la
->la_refcnt
> 0) {
1181 KASSERT(la
->la_refcnt
== 0, ("refcount not zero"));
1182 KASSERT(lsc
->lsc_active_aggregator
!= la
, ("aggregator active"));
1184 TAILQ_REMOVE(&lsc
->lsc_aggregators
, la
, la_q
);
1190 * lacp_aggregator_get: allocate an aggregator.
1193 static struct lacp_aggregator
*
1194 lacp_aggregator_get(struct lacp_softc
*lsc
, struct lacp_port
*lp
)
1196 struct lacp_aggregator
*la
;
1198 la
= malloc(sizeof(*la
), M_DEVBUF
, M_NOWAIT
);
1202 TAILQ_INIT(&la
->la_ports
);
1204 TAILQ_INSERT_TAIL(&lsc
->lsc_aggregators
, la
, la_q
);
1211 * lacp_fill_aggregator_id: setup a newly allocated aggregator from a port.
1215 lacp_fill_aggregator_id(struct lacp_aggregator
*la
, const struct lacp_port
*lp
)
1217 lacp_fill_aggregator_id_peer(&la
->la_partner
, &lp
->lp_partner
);
1218 lacp_fill_aggregator_id_peer(&la
->la_actor
, &lp
->lp_actor
);
1220 la
->la_actor
.lip_state
= lp
->lp_state
& LACP_STATE_AGGREGATION
;
1224 lacp_fill_aggregator_id_peer(struct lacp_peerinfo
*lpi_aggr
,
1225 const struct lacp_peerinfo
*lpi_port
)
1227 memset(lpi_aggr
, 0, sizeof(*lpi_aggr
));
1228 lpi_aggr
->lip_systemid
= lpi_port
->lip_systemid
;
1229 lpi_aggr
->lip_key
= lpi_port
->lip_key
;
1233 * lacp_aggregator_is_compatible: check if a port can join to an aggregator.
1237 lacp_aggregator_is_compatible(const struct lacp_aggregator
*la
,
1238 const struct lacp_port
*lp
)
1240 if (!(lp
->lp_state
& LACP_STATE_AGGREGATION
) ||
1241 !(lp
->lp_partner
.lip_state
& LACP_STATE_AGGREGATION
)) {
1245 if (!(la
->la_actor
.lip_state
& LACP_STATE_AGGREGATION
)) {
1249 if (!lacp_peerinfo_is_compatible(&la
->la_partner
, &lp
->lp_partner
)) {
1253 if (!lacp_peerinfo_is_compatible(&la
->la_actor
, &lp
->lp_actor
)) {
1261 lacp_peerinfo_is_compatible(const struct lacp_peerinfo
*a
,
1262 const struct lacp_peerinfo
*b
)
1264 if (memcmp(&a
->lip_systemid
, &b
->lip_systemid
,
1265 sizeof(a
->lip_systemid
))) {
1269 if (memcmp(&a
->lip_key
, &b
->lip_key
, sizeof(a
->lip_key
))) {
1277 lacp_port_enable(struct lacp_port
*lp
)
1279 lp
->lp_state
|= LACP_STATE_AGGREGATION
;
1283 lacp_port_disable(struct lacp_port
*lp
)
1285 lacp_set_mux(lp
, LACP_MUX_DETACHED
);
1287 lp
->lp_state
&= ~LACP_STATE_AGGREGATION
;
1288 lp
->lp_selected
= LACP_UNSELECTED
;
1289 lacp_sm_rx_record_default(lp
);
1290 lp
->lp_partner
.lip_state
&= ~LACP_STATE_AGGREGATION
;
1291 lp
->lp_state
&= ~LACP_STATE_EXPIRED
;
1295 * lacp_select: select an aggregator. create one if necessary.
1298 lacp_select(struct lacp_port
*lp
)
1300 struct lacp_softc
*lsc
= lp
->lp_lsc
;
1301 struct lacp_aggregator
*la
;
1302 char buf
[LACP_LAGIDSTR_MAX
+1];
1304 if (lp
->lp_aggregator
) {
1308 KASSERT(!LACP_TIMER_ISARMED(lp
, LACP_TIMER_WAIT_WHILE
),
1309 ("timer_wait_while still active"));
1311 LACP_DPRINTF((lp
, "port lagid=%s\n",
1312 lacp_format_lagid(&lp
->lp_actor
, &lp
->lp_partner
,
1313 buf
, sizeof(buf
))));
1315 TAILQ_FOREACH(la
, &lsc
->lsc_aggregators
, la_q
) {
1316 if (lacp_aggregator_is_compatible(la
, lp
)) {
1322 la
= lacp_aggregator_get(lsc
, lp
);
1324 LACP_DPRINTF((lp
, "aggregator creation failed\n"));
1327 * will retry on the next tick.
1332 lacp_fill_aggregator_id(la
, lp
);
1333 LACP_DPRINTF((lp
, "aggregator created\n"));
1335 LACP_DPRINTF((lp
, "compatible aggregator found\n"));
1336 if (la
->la_refcnt
== LACP_MAX_PORTS
)
1338 lacp_aggregator_addref(lsc
, la
);
1341 LACP_DPRINTF((lp
, "aggregator lagid=%s\n",
1342 lacp_format_lagid(&la
->la_actor
, &la
->la_partner
,
1343 buf
, sizeof(buf
))));
1345 lp
->lp_aggregator
= la
;
1346 lp
->lp_selected
= LACP_SELECTED
;
1350 * lacp_unselect: finish unselect/detach process.
1354 lacp_unselect(struct lacp_port
*lp
)
1356 struct lacp_softc
*lsc
= lp
->lp_lsc
;
1357 struct lacp_aggregator
*la
= lp
->lp_aggregator
;
1359 KASSERT(!LACP_TIMER_ISARMED(lp
, LACP_TIMER_WAIT_WHILE
),
1360 ("timer_wait_while still active"));
1366 lp
->lp_aggregator
= NULL
;
1367 lacp_aggregator_delref(lsc
, la
);
1373 lacp_sm_mux(struct lacp_port
*lp
)
1375 struct lagg_port
*lgp
= lp
->lp_lagg
;
1376 struct lagg_softc
*sc
= lgp
->lp_softc
;
1377 enum lacp_mux_state new_state
;
1379 (lp
->lp_partner
.lip_state
& LACP_STATE_SYNC
) != 0;
1380 boolean_t p_collecting
=
1381 (lp
->lp_partner
.lip_state
& LACP_STATE_COLLECTING
) != 0;
1382 enum lacp_selected selected
= lp
->lp_selected
;
1383 struct lacp_aggregator
*la
;
1385 if (V_lacp_debug
> 1)
1386 lacp_dprintf(lp
, "%s: state= 0x%x, selected= 0x%x, "
1387 "p_sync= 0x%x, p_collecting= 0x%x\n", __func__
,
1388 lp
->lp_mux_state
, selected
, p_sync
, p_collecting
);
1391 la
= lp
->lp_aggregator
;
1392 KASSERT(lp
->lp_mux_state
== LACP_MUX_DETACHED
|| la
!= NULL
,
1393 ("MUX not detached"));
1394 new_state
= lp
->lp_mux_state
;
1395 switch (lp
->lp_mux_state
) {
1396 case LACP_MUX_DETACHED
:
1397 if (selected
!= LACP_UNSELECTED
) {
1398 new_state
= LACP_MUX_WAITING
;
1401 case LACP_MUX_WAITING
:
1402 KASSERT(la
->la_pending
> 0 ||
1403 !LACP_TIMER_ISARMED(lp
, LACP_TIMER_WAIT_WHILE
),
1404 ("timer_wait_while still active"));
1405 if (selected
== LACP_SELECTED
&& la
->la_pending
== 0) {
1406 new_state
= LACP_MUX_ATTACHED
;
1407 } else if (selected
== LACP_UNSELECTED
) {
1408 new_state
= LACP_MUX_DETACHED
;
1411 case LACP_MUX_ATTACHED
:
1412 if (selected
== LACP_SELECTED
&& p_sync
) {
1413 new_state
= LACP_MUX_COLLECTING
;
1414 } else if (selected
!= LACP_SELECTED
) {
1415 new_state
= LACP_MUX_DETACHED
;
1418 case LACP_MUX_COLLECTING
:
1419 if (selected
== LACP_SELECTED
&& p_sync
&& p_collecting
) {
1420 new_state
= LACP_MUX_DISTRIBUTING
;
1421 } else if (selected
!= LACP_SELECTED
|| !p_sync
) {
1422 new_state
= LACP_MUX_ATTACHED
;
1425 case LACP_MUX_DISTRIBUTING
:
1426 if (selected
!= LACP_SELECTED
|| !p_sync
|| !p_collecting
) {
1427 new_state
= LACP_MUX_COLLECTING
;
1428 lacp_dprintf(lp
, "Interface stopped DISTRIBUTING, possible flapping\n");
1433 panic("%s: unknown state", __func__
);
1436 if (lp
->lp_mux_state
== new_state
) {
1440 lacp_set_mux(lp
, new_state
);
1445 lacp_set_mux(struct lacp_port
*lp
, enum lacp_mux_state new_state
)
1447 struct lacp_aggregator
*la
= lp
->lp_aggregator
;
1449 if (lp
->lp_mux_state
== new_state
) {
1453 switch (new_state
) {
1454 case LACP_MUX_DETACHED
:
1455 lp
->lp_state
&= ~LACP_STATE_SYNC
;
1456 lacp_disable_distributing(lp
);
1457 lacp_disable_collecting(lp
);
1458 lacp_sm_assert_ntt(lp
);
1460 if (LACP_TIMER_ISARMED(lp
, LACP_TIMER_WAIT_WHILE
)) {
1461 KASSERT(la
->la_pending
> 0,
1462 ("timer_wait_while not active"));
1465 LACP_TIMER_DISARM(lp
, LACP_TIMER_WAIT_WHILE
);
1468 case LACP_MUX_WAITING
:
1469 LACP_TIMER_ARM(lp
, LACP_TIMER_WAIT_WHILE
,
1470 LACP_AGGREGATE_WAIT_TIME
);
1473 case LACP_MUX_ATTACHED
:
1474 lp
->lp_state
|= LACP_STATE_SYNC
;
1475 lacp_disable_collecting(lp
);
1476 lacp_sm_assert_ntt(lp
);
1478 case LACP_MUX_COLLECTING
:
1479 lacp_enable_collecting(lp
);
1480 lacp_disable_distributing(lp
);
1481 lacp_sm_assert_ntt(lp
);
1483 case LACP_MUX_DISTRIBUTING
:
1484 lacp_enable_distributing(lp
);
1487 panic("%s: unknown state", __func__
);
1490 LACP_DPRINTF((lp
, "mux_state %d -> %d\n", lp
->lp_mux_state
, new_state
));
1492 lp
->lp_mux_state
= new_state
;
1496 lacp_sm_mux_timer(struct lacp_port
*lp
)
1498 struct lacp_aggregator
*la
= lp
->lp_aggregator
;
1499 char buf
[LACP_LAGIDSTR_MAX
+1];
1501 KASSERT(la
->la_pending
> 0, ("no pending event"));
1503 LACP_DPRINTF((lp
, "%s: aggregator %s, pending %d -> %d\n", __func__
,
1504 lacp_format_lagid(&la
->la_actor
, &la
->la_partner
,
1506 la
->la_pending
, la
->la_pending
- 1));
1511 /* periodic transmit machine */
1514 lacp_sm_ptx_update_timeout(struct lacp_port
*lp
, uint8_t oldpstate
)
1516 if (LACP_STATE_EQ(oldpstate
, lp
->lp_partner
.lip_state
,
1517 LACP_STATE_TIMEOUT
)) {
1521 LACP_DPRINTF((lp
, "partner timeout changed\n"));
1524 * FAST_PERIODIC -> SLOW_PERIODIC
1526 * SLOW_PERIODIC (-> PERIODIC_TX) -> FAST_PERIODIC
1528 * let lacp_sm_ptx_tx_schedule to update timeout.
1531 LACP_TIMER_DISARM(lp
, LACP_TIMER_PERIODIC
);
1534 * if timeout has been shortened, assert NTT.
1537 if ((lp
->lp_partner
.lip_state
& LACP_STATE_TIMEOUT
)) {
1538 lacp_sm_assert_ntt(lp
);
1543 lacp_sm_ptx_tx_schedule(struct lacp_port
*lp
)
1547 if (!(lp
->lp_state
& LACP_STATE_ACTIVITY
) &&
1548 !(lp
->lp_partner
.lip_state
& LACP_STATE_ACTIVITY
)) {
1554 LACP_TIMER_DISARM(lp
, LACP_TIMER_PERIODIC
);
1558 if (LACP_TIMER_ISARMED(lp
, LACP_TIMER_PERIODIC
)) {
1562 timeout
= (lp
->lp_partner
.lip_state
& LACP_STATE_TIMEOUT
) ?
1563 LACP_FAST_PERIODIC_TIME
: LACP_SLOW_PERIODIC_TIME
;
1565 LACP_TIMER_ARM(lp
, LACP_TIMER_PERIODIC
, timeout
);
1569 lacp_sm_ptx_timer(struct lacp_port
*lp
)
1571 lacp_sm_assert_ntt(lp
);
1575 lacp_sm_rx(struct lacp_port
*lp
, const struct lacpdu
*du
)
1580 * check LACP_DISABLED first
1583 if (!(lp
->lp_state
& LACP_STATE_AGGREGATION
)) {
1588 * check loopback condition.
1591 if (!lacp_compare_systemid(&du
->ldu_actor
.lip_systemid
,
1592 &lp
->lp_actor
.lip_systemid
)) {
1597 * EXPIRED, DEFAULTED, CURRENT -> CURRENT
1600 lacp_sm_rx_update_selected(lp
, du
);
1601 lacp_sm_rx_update_ntt(lp
, du
);
1602 lacp_sm_rx_record_pdu(lp
, du
);
1604 timeout
= (lp
->lp_state
& LACP_STATE_TIMEOUT
) ?
1605 LACP_SHORT_TIMEOUT_TIME
: LACP_LONG_TIMEOUT_TIME
;
1606 LACP_TIMER_ARM(lp
, LACP_TIMER_CURRENT_WHILE
, timeout
);
1608 lp
->lp_state
&= ~LACP_STATE_EXPIRED
;
1611 * kick transmit machine without waiting the next tick.
1618 lacp_sm_rx_set_expired(struct lacp_port
*lp
)
1620 lp
->lp_partner
.lip_state
&= ~LACP_STATE_SYNC
;
1621 lp
->lp_partner
.lip_state
|= LACP_STATE_TIMEOUT
;
1622 LACP_TIMER_ARM(lp
, LACP_TIMER_CURRENT_WHILE
, LACP_SHORT_TIMEOUT_TIME
);
1623 lp
->lp_state
|= LACP_STATE_EXPIRED
;
1627 lacp_sm_rx_timer(struct lacp_port
*lp
)
1629 if ((lp
->lp_state
& LACP_STATE_EXPIRED
) == 0) {
1630 /* CURRENT -> EXPIRED */
1631 LACP_DPRINTF((lp
, "%s: CURRENT -> EXPIRED\n", __func__
));
1632 lacp_sm_rx_set_expired(lp
);
1634 /* EXPIRED -> DEFAULTED */
1635 LACP_DPRINTF((lp
, "%s: EXPIRED -> DEFAULTED\n", __func__
));
1636 lacp_sm_rx_update_default_selected(lp
);
1637 lacp_sm_rx_record_default(lp
);
1638 lp
->lp_state
&= ~LACP_STATE_EXPIRED
;
1643 lacp_sm_rx_record_pdu(struct lacp_port
*lp
, const struct lacpdu
*du
)
1647 char buf
[LACP_STATESTR_MAX
+1];
1651 oldpstate
= lp
->lp_partner
.lip_state
;
1653 active
= (du
->ldu_actor
.lip_state
& LACP_STATE_ACTIVITY
)
1654 || ((lp
->lp_state
& LACP_STATE_ACTIVITY
) &&
1655 (du
->ldu_partner
.lip_state
& LACP_STATE_ACTIVITY
));
1657 lp
->lp_partner
= du
->ldu_actor
;
1659 ((LACP_STATE_EQ(lp
->lp_state
, du
->ldu_partner
.lip_state
,
1660 LACP_STATE_AGGREGATION
) &&
1661 !lacp_compare_peerinfo(&lp
->lp_actor
, &du
->ldu_partner
))
1662 || (du
->ldu_partner
.lip_state
& LACP_STATE_AGGREGATION
) == 0)) {
1665 lp
->lp_partner
.lip_state
&= ~LACP_STATE_SYNC
;
1668 lp
->lp_state
&= ~LACP_STATE_DEFAULTED
;
1670 if (oldpstate
!= lp
->lp_partner
.lip_state
) {
1671 LACP_DPRINTF((lp
, "old pstate %s\n",
1672 lacp_format_state(oldpstate
, buf
, sizeof(buf
))));
1673 LACP_DPRINTF((lp
, "new pstate %s\n",
1674 lacp_format_state(lp
->lp_partner
.lip_state
, buf
,
1678 /* XXX Hack, still need to implement 5.4.9 para 2,3,4 */
1679 if (lp
->lp_lsc
->lsc_strict_mode
)
1680 lp
->lp_partner
.lip_state
|= LACP_STATE_SYNC
;
1682 lacp_sm_ptx_update_timeout(lp
, oldpstate
);
1686 lacp_sm_rx_update_ntt(struct lacp_port
*lp
, const struct lacpdu
*du
)
1691 if (lacp_compare_peerinfo(&lp
->lp_actor
, &du
->ldu_partner
) ||
1692 !LACP_STATE_EQ(lp
->lp_state
, du
->ldu_partner
.lip_state
,
1693 LACP_STATE_ACTIVITY
| LACP_STATE_SYNC
| LACP_STATE_AGGREGATION
)) {
1694 LACP_DPRINTF((lp
, "%s: assert ntt\n", __func__
));
1695 lacp_sm_assert_ntt(lp
);
1700 lacp_sm_rx_record_default(struct lacp_port
*lp
)
1706 oldpstate
= lp
->lp_partner
.lip_state
;
1707 if (lp
->lp_lsc
->lsc_strict_mode
)
1708 lp
->lp_partner
= lacp_partner_admin_strict
;
1710 lp
->lp_partner
= lacp_partner_admin_optimistic
;
1711 lp
->lp_state
|= LACP_STATE_DEFAULTED
;
1712 lacp_sm_ptx_update_timeout(lp
, oldpstate
);
1716 lacp_sm_rx_update_selected_from_peerinfo(struct lacp_port
*lp
,
1717 const struct lacp_peerinfo
*info
)
1722 if (lacp_compare_peerinfo(&lp
->lp_partner
, info
) ||
1723 !LACP_STATE_EQ(lp
->lp_partner
.lip_state
, info
->lip_state
,
1724 LACP_STATE_AGGREGATION
)) {
1725 lp
->lp_selected
= LACP_UNSELECTED
;
1726 /* mux machine will clean up lp->lp_aggregator */
1731 lacp_sm_rx_update_selected(struct lacp_port
*lp
, const struct lacpdu
*du
)
1736 lacp_sm_rx_update_selected_from_peerinfo(lp
, &du
->ldu_actor
);
1740 lacp_sm_rx_update_default_selected(struct lacp_port
*lp
)
1745 if (lp
->lp_lsc
->lsc_strict_mode
)
1746 lacp_sm_rx_update_selected_from_peerinfo(lp
,
1747 &lacp_partner_admin_strict
);
1749 lacp_sm_rx_update_selected_from_peerinfo(lp
,
1750 &lacp_partner_admin_optimistic
);
1753 /* transmit machine */
1756 lacp_sm_tx(struct lacp_port
*lp
)
1760 if (!(lp
->lp_state
& LACP_STATE_AGGREGATION
)
1762 || (!(lp
->lp_state
& LACP_STATE_ACTIVITY
)
1763 && !(lp
->lp_partner
.lip_state
& LACP_STATE_ACTIVITY
))
1766 lp
->lp_flags
&= ~LACP_PORT_NTT
;
1769 if (!(lp
->lp_flags
& LACP_PORT_NTT
)) {
1773 /* Rate limit to 3 PDUs per LACP_FAST_PERIODIC_TIME */
1774 if (ppsratecheck(&lp
->lp_last_lacpdu
, &lp
->lp_lacpdu_sent
,
1775 (3 / LACP_FAST_PERIODIC_TIME
)) == 0) {
1776 LACP_DPRINTF((lp
, "rate limited pdu\n"));
1780 if (((1 << lp
->lp_ifp
->if_dunit
) & lp
->lp_lsc
->lsc_debug
.lsc_tx_test
) == 0) {
1781 error
= lacp_xmit_lacpdu(lp
);
1783 LACP_TPRINTF((lp
, "Dropping TX PDU\n"));
1787 lp
->lp_flags
&= ~LACP_PORT_NTT
;
1789 LACP_DPRINTF((lp
, "lacpdu transmit failure, error %d\n",
1795 lacp_sm_assert_ntt(struct lacp_port
*lp
)
1798 lp
->lp_flags
|= LACP_PORT_NTT
;
1802 lacp_run_timers(struct lacp_port
*lp
)
1806 for (i
= 0; i
< LACP_NTIMER
; i
++) {
1807 KASSERT(lp
->lp_timer
[i
] >= 0,
1808 ("invalid timer value %d", lp
->lp_timer
[i
]));
1809 if (lp
->lp_timer
[i
] == 0) {
1811 } else if (--lp
->lp_timer
[i
] <= 0) {
1812 if (lacp_timer_funcs
[i
]) {
1813 (*lacp_timer_funcs
[i
])(lp
);
1820 lacp_marker_input(struct lacp_port
*lp
, struct mbuf
*m
)
1822 struct lacp_softc
*lsc
= lp
->lp_lsc
;
1823 struct lagg_port
*lgp
= lp
->lp_lagg
;
1824 struct lacp_port
*lp2
;
1825 struct markerdu
*mdu
;
1829 if (m
->m_pkthdr
.len
!= sizeof(*mdu
)) {
1833 if ((m
->m_flags
& M_MCAST
) == 0) {
1837 if (m
->m_len
< sizeof(*mdu
)) {
1838 m
= m_pullup(m
, sizeof(*mdu
));
1844 mdu
= mtod(m
, struct markerdu
*);
1846 if (memcmp(&mdu
->mdu_eh
.ether_dhost
,
1847 ðermulticastaddr_slowprotocols
, ETHER_ADDR_LEN
)) {
1851 if (mdu
->mdu_sph
.sph_version
!= 1) {
1855 switch (mdu
->mdu_tlv
.tlv_type
) {
1856 case MARKER_TYPE_INFO
:
1857 if (tlv_check(mdu
, sizeof(*mdu
), &mdu
->mdu_tlv
,
1858 marker_info_tlv_template
, TRUE
)) {
1861 mdu
->mdu_tlv
.tlv_type
= MARKER_TYPE_RESPONSE
;
1862 memcpy(&mdu
->mdu_eh
.ether_dhost
,
1863 ðermulticastaddr_slowprotocols
, ETHER_ADDR_LEN
);
1864 memcpy(&mdu
->mdu_eh
.ether_shost
,
1865 lgp
->lp_lladdr
, ETHER_ADDR_LEN
);
1866 error
= lagg_enqueue(lp
->lp_ifp
, m
);
1869 case MARKER_TYPE_RESPONSE
:
1870 if (tlv_check(mdu
, sizeof(*mdu
), &mdu
->mdu_tlv
,
1871 marker_response_tlv_template
, TRUE
)) {
1874 LACP_DPRINTF((lp
, "marker response, port=%u, sys=%6D, id=%u\n",
1875 ntohs(mdu
->mdu_info
.mi_rq_port
), mdu
->mdu_info
.mi_rq_system
,
1876 ":", ntohl(mdu
->mdu_info
.mi_rq_xid
)));
1878 /* Verify that it is the last marker we sent out */
1879 if (memcmp(&mdu
->mdu_info
, &lp
->lp_marker
,
1880 sizeof(struct lacp_markerinfo
)))
1884 lp
->lp_flags
&= ~LACP_PORT_MARK
;
1886 if (lsc
->lsc_suppress_distributing
) {
1887 /* Check if any ports are waiting for a response */
1888 LIST_FOREACH(lp2
, &lsc
->lsc_ports
, lp_next
) {
1889 if (lp2
->lp_flags
& LACP_PORT_MARK
) {
1896 /* All interface queues are clear */
1897 LACP_DPRINTF((NULL
, "queue flush complete\n"));
1898 lsc
->lsc_suppress_distributing
= FALSE
;
1912 LACP_DPRINTF((lp
, "bad marker frame\n"));
1918 tlv_check(const void *p
, size_t size
, const struct tlvhdr
*tlv
,
1919 const struct tlv_template
*tmpl
, boolean_t check_type
)
1921 while (/* CONSTCOND */ 1) {
1922 if ((const char *)tlv
- (const char *)p
+ sizeof(*tlv
) > size
) {
1925 if ((check_type
&& tlv
->tlv_type
!= tmpl
->tmpl_type
) ||
1926 tlv
->tlv_length
!= tmpl
->tmpl_length
) {
1929 if (tmpl
->tmpl_type
== 0) {
1932 tlv
= (const struct tlvhdr
*)
1933 ((const char *)tlv
+ tlv
->tlv_length
);
1942 lacp_format_mac(const uint8_t *mac
, char *buf
, size_t buflen
)
1944 snprintf(buf
, buflen
, "%02X-%02X-%02X-%02X-%02X-%02X",
1956 lacp_format_systemid(const struct lacp_systemid
*sysid
,
1957 char *buf
, size_t buflen
)
1959 char macbuf
[LACP_MACSTR_MAX
+1];
1961 snprintf(buf
, buflen
, "%04X,%s",
1962 ntohs(sysid
->lsi_prio
),
1963 lacp_format_mac(sysid
->lsi_mac
, macbuf
, sizeof(macbuf
)));
1969 lacp_format_portid(const struct lacp_portid
*portid
, char *buf
, size_t buflen
)
1971 snprintf(buf
, buflen
, "%04X,%04X",
1972 ntohs(portid
->lpi_prio
),
1973 ntohs(portid
->lpi_portno
));
1979 lacp_format_partner(const struct lacp_peerinfo
*peer
, char *buf
, size_t buflen
)
1981 char sysid
[LACP_SYSTEMIDSTR_MAX
+1];
1982 char portid
[LACP_PORTIDSTR_MAX
+1];
1984 snprintf(buf
, buflen
, "(%s,%04X,%s)",
1985 lacp_format_systemid(&peer
->lip_systemid
, sysid
, sizeof(sysid
)),
1986 ntohs(peer
->lip_key
),
1987 lacp_format_portid(&peer
->lip_portid
, portid
, sizeof(portid
)));
1993 lacp_format_lagid(const struct lacp_peerinfo
*a
,
1994 const struct lacp_peerinfo
*b
, char *buf
, size_t buflen
)
1996 char astr
[LACP_PARTNERSTR_MAX
+1];
1997 char bstr
[LACP_PARTNERSTR_MAX
+1];
2001 * there's a convention to display small numbered peer
2005 if (lacp_compare_peerinfo(a
, b
) > 0) {
2006 const struct lacp_peerinfo
*t
;
2014 snprintf(buf
, buflen
, "[%s,%s]",
2015 lacp_format_partner(a
, astr
, sizeof(astr
)),
2016 lacp_format_partner(b
, bstr
, sizeof(bstr
)));
2022 lacp_format_lagid_aggregator(const struct lacp_aggregator
*la
,
2023 char *buf
, size_t buflen
)
2029 return (lacp_format_lagid(&la
->la_actor
, &la
->la_partner
, buf
, buflen
));
2033 lacp_format_state(uint8_t state
, char *buf
, size_t buflen
)
2035 snprintf(buf
, buflen
, "%b", state
, LACP_STATE_BITS
);
2040 lacp_dump_lacpdu(const struct lacpdu
*du
)
2042 char buf
[LACP_PARTNERSTR_MAX
+1];
2043 char buf2
[LACP_STATESTR_MAX
+1];
2045 printf("actor=%s\n",
2046 lacp_format_partner(&du
->ldu_actor
, buf
, sizeof(buf
)));
2047 printf("actor.state=%s\n",
2048 lacp_format_state(du
->ldu_actor
.lip_state
, buf2
, sizeof(buf2
)));
2049 printf("partner=%s\n",
2050 lacp_format_partner(&du
->ldu_partner
, buf
, sizeof(buf
)));
2051 printf("partner.state=%s\n",
2052 lacp_format_state(du
->ldu_partner
.lip_state
, buf2
, sizeof(buf2
)));
2054 printf("maxdelay=%d\n", ntohs(du
->ldu_collector
.lci_maxdelay
));
2058 lacp_dprintf(const struct lacp_port
*lp
, const char *fmt
, ...)
2063 printf("%s: ", lp
->lp_ifp
->if_xname
);