1 /* $NetBSD: ieee8023ad_lacp_sm_mux.c,v 1.3 2005/12/11 12:24:54 christos Exp $ */
4 * Copyright (c)2005 YAMAMOTO Takashi,
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: ieee8023ad_lacp_sm_mux.c,v 1.3 2005/12/11 12:24:54 christos Exp $");
32 #include <sys/param.h>
33 #include <sys/callout.h>
35 #include <sys/systm.h>
38 #include <net/if_ether.h>
40 #include <net/agr/ieee8023_slowprotocols.h>
41 #include <net/agr/ieee8023_tlv.h>
42 #include <net/agr/ieee8023ad_lacp.h>
43 #include <net/agr/ieee8023ad_lacp_impl.h>
44 #include <net/agr/ieee8023ad_lacp_sm.h>
45 #include <net/agr/ieee8023ad_lacp_debug.h>
50 lacp_sm_mux(struct lacp_port
*lp
)
52 enum lacp_mux_state new_state
;
54 (lp
->lp_partner
.lip_state
& LACP_STATE_SYNC
) != 0;
56 (lp
->lp_partner
.lip_state
& LACP_STATE_COLLECTING
) != 0;
57 enum lacp_selected selected
= lp
->lp_selected
;
58 struct lacp_aggregator
*la
;
60 /* LACP_DPRINTF((lp, "%s: state %d\n", __func__, lp->lp_mux_state)); */
63 la
= lp
->lp_aggregator
;
64 KASSERT(lp
->lp_mux_state
== LACP_MUX_DETACHED
|| la
!= NULL
);
65 new_state
= lp
->lp_mux_state
;
66 switch (lp
->lp_mux_state
) {
67 case LACP_MUX_DETACHED
:
68 if (selected
!= LACP_UNSELECTED
) {
69 new_state
= LACP_MUX_WAITING
;
72 case LACP_MUX_WAITING
:
73 KASSERT(la
->la_pending
> 0 ||
74 !LACP_TIMER_ISARMED(lp
, LACP_TIMER_WAIT_WHILE
));
75 if (selected
== LACP_SELECTED
&& la
->la_pending
== 0) {
76 new_state
= LACP_MUX_ATTACHED
;
77 } else if (selected
== LACP_UNSELECTED
) {
78 new_state
= LACP_MUX_DETACHED
;
81 case LACP_MUX_ATTACHED
:
82 if (selected
== LACP_SELECTED
&& p_sync
) {
83 new_state
= LACP_MUX_COLLECTING
;
84 } else if (selected
!= LACP_SELECTED
) {
85 new_state
= LACP_MUX_DETACHED
;
88 case LACP_MUX_COLLECTING
:
89 if (selected
== LACP_SELECTED
&& p_sync
&& p_collecting
) {
90 new_state
= LACP_MUX_DISTRIBUTING
;
91 } else if (selected
!= LACP_SELECTED
|| !p_sync
) {
92 new_state
= LACP_MUX_ATTACHED
;
95 case LACP_MUX_DISTRIBUTING
:
96 if (selected
!= LACP_SELECTED
|| !p_sync
|| !p_collecting
) {
97 new_state
= LACP_MUX_COLLECTING
;
101 panic("%s: unknown state", __func__
);
104 if (lp
->lp_mux_state
== new_state
) {
109 case LACP_MUX_DETACHED
:
110 lp
->lp_state
&= ~LACP_STATE_SYNC
;
111 lacp_disable_distributing(lp
);
112 lacp_disable_collecting(lp
);
113 lacp_sm_assert_ntt(lp
);
115 if (LACP_TIMER_ISARMED(lp
, LACP_TIMER_WAIT_WHILE
)) {
116 KASSERT(la
->la_pending
> 0);
119 LACP_TIMER_DISARM(lp
, LACP_TIMER_WAIT_WHILE
);
122 case LACP_MUX_WAITING
:
123 LACP_TIMER_ARM(lp
, LACP_TIMER_WAIT_WHILE
,
124 LACP_AGGREGATE_WAIT_TIME
);
127 case LACP_MUX_ATTACHED
:
128 lp
->lp_state
|= LACP_STATE_SYNC
;
129 lacp_disable_collecting(lp
);
130 lacp_sm_assert_ntt(lp
);
132 case LACP_MUX_COLLECTING
:
133 lacp_enable_collecting(lp
);
134 lp
->lp_state
|= LACP_STATE_COLLECTING
;
135 lacp_disable_distributing(lp
);
136 lacp_sm_assert_ntt(lp
);
138 case LACP_MUX_DISTRIBUTING
:
139 lacp_enable_distributing(lp
);
142 panic("%s: unknown state", __func__
);
145 LACP_DPRINTF((lp
, "mux_state %d -> %d\n", lp
->lp_mux_state
, new_state
));
147 lp
->lp_mux_state
= new_state
;
152 lacp_sm_mux_timer(struct lacp_port
*lp
)
154 struct lacp_aggregator
*la
= lp
->lp_aggregator
;
155 #if defined(LACP_DEBUG)
156 char buf
[LACP_LAGIDSTR_MAX
+1];
160 KASSERT(la
->la_pending
> 0);
162 LACP_DPRINTF((lp
, "%s: aggregator %s, pending %d -> %d\n", __func__
,
163 lacp_format_lagid(&la
->la_actor
, &la
->la_partner
,
165 la
->la_pending
, la
->la_pending
- 1));