bonding lacp: replace slave string with member
[vpp.git] / src / plugins / lacp / mux_machine.c
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #define _GNU_SOURCE
17
18 #include <vlib/vlib.h>
19 #include <vnet/bonding/node.h>
20 #include <lacp/node.h>
21
22 /*
23  *  LACP State = DETACHED
24  */
25 static lacp_fsm_state_t lacp_mux_state_detached[] = {
26   {LACP_ACTION_DETACHED, LACP_MUX_STATE_DETACHED},      // event 0 BEGIN
27   {LACP_ACTION_WAITING, LACP_MUX_STATE_WAITING},        // event 1 SELECTED
28   {LACP_ACTION_WAITING, LACP_MUX_STATE_WAITING},        // event 2 STANDBY
29   {LACP_ACTION_DETACHED, LACP_MUX_STATE_DETACHED},      // event 3 UNSELECTED
30   {LACP_ACTION_DETACHED, LACP_MUX_STATE_DETACHED},      // event 4 READY
31   {LACP_ACTION_DETACHED, LACP_MUX_STATE_DETACHED},      // event 5 SYNC
32 };
33
34 /*
35  *  LACP State = WAITING
36  */
37 static lacp_fsm_state_t lacp_mux_state_waiting[] = {
38   {LACP_ACTION_DETACHED, LACP_MUX_STATE_DETACHED},      // event 0 BEGIN
39   {LACP_ACTION_WAITING, LACP_MUX_STATE_WAITING},        // event 1 SELECTED
40   {LACP_ACTION_WAITING, LACP_MUX_STATE_WAITING},        // event 2 STANDBY
41   {LACP_ACTION_DETACHED, LACP_MUX_STATE_DETACHED},      // event 3 UNSELECTED
42   {LACP_ACTION_ATTACHED, LACP_MUX_STATE_ATTACHED},      // event 4 READY
43   {LACP_ACTION_WAITING, LACP_MUX_STATE_WAITING},        // event 5 SYNC
44 };
45
46 /*
47  *  LACP State = ATTACHED
48  */
49 static lacp_fsm_state_t lacp_mux_state_attached[] = {
50   {LACP_ACTION_DETACHED, LACP_MUX_STATE_DETACHED},      // event 0 BEGIN
51   {LACP_ACTION_ATTACHED, LACP_MUX_STATE_ATTACHED},      // event 1 SELECTED
52   {LACP_ACTION_DETACHED, LACP_MUX_STATE_DETACHED},      // event 2 STANDBY
53   {LACP_ACTION_DETACHED, LACP_MUX_STATE_DETACHED},      // event 3 UNSELECTED
54   {LACP_ACTION_ATTACHED, LACP_MUX_STATE_ATTACHED},      // event 4 READY
55   {LACP_ACTION_COLLECTING_DISTRIBUTING, LACP_MUX_STATE_COLLECTING_DISTRIBUTING},        // event 5_SYNC
56 };
57
58 /*
59  *  LACP State = COLLECTING_DISTRIBUTING
60  */
61 static lacp_fsm_state_t lacp_mux_state_collecting_distributing[] = {
62   {LACP_ACTION_DETACHED, LACP_MUX_STATE_DETACHED},      // event 0 BEGIN
63   {LACP_ACTION_COLLECTING_DISTRIBUTING, LACP_MUX_STATE_COLLECTING_DISTRIBUTING},        // event 1 SELECTED
64   {LACP_ACTION_COLLECTING_DISTRIBUTING, LACP_MUX_STATE_COLLECTING_DISTRIBUTING},        // event 2 STANDBY
65   {LACP_ACTION_ATTACHED, LACP_MUX_STATE_ATTACHED},      // event 3 UNSELECTED
66   {LACP_ACTION_COLLECTING_DISTRIBUTING, LACP_MUX_STATE_COLLECTING_DISTRIBUTING},        // event 4 READY
67   {LACP_ACTION_COLLECTING_DISTRIBUTING, LACP_MUX_STATE_COLLECTING_DISTRIBUTING},        // event 5 SYNC
68 };
69
70 static lacp_fsm_machine_t lacp_mux_fsm_table[] = {
71   {lacp_mux_state_detached},
72   {lacp_mux_state_waiting},
73   {lacp_mux_state_attached},
74   {lacp_mux_state_collecting_distributing},
75 };
76
77 lacp_machine_t lacp_mux_machine = {
78   lacp_mux_fsm_table,
79   lacp_mux_debug_func,
80 };
81
82 static void
83 lacp_detach_mux_from_aggregator (vlib_main_t * vm, member_if_t * mif)
84 {
85   mif->actor.state &= ~LACP_STATE_SYNCHRONIZATION;
86   mif->ready = 0;
87   mif->ready_n = 0;
88 }
89
90 static void
91 lacp_attach_mux_to_aggregator (vlib_main_t * vm, member_if_t * mif)
92 {
93   mif->actor.state |= LACP_STATE_SYNCHRONIZATION;
94 }
95
96 int
97 lacp_mux_action_detached (void *p1, void *p2)
98 {
99   vlib_main_t *vm = p1;
100   member_if_t *mif = p2;
101
102   lacp_detach_mux_from_aggregator (vm, mif);
103   mif->actor.state &= ~LACP_STATE_COLLECTING;
104   bond_disable_collecting_distributing (vm, mif);
105   mif->actor.state &= ~LACP_STATE_DISTRIBUTING;
106   mif->ntt = 1;
107   lacp_start_periodic_timer (vm, mif, 0);
108
109   if (mif->selected == LACP_PORT_SELECTED)
110     lacp_machine_dispatch (&lacp_mux_machine, vm, mif,
111                            LACP_MUX_EVENT_SELECTED, &mif->mux_state);
112
113   if (mif->selected == LACP_PORT_STANDBY)
114     lacp_machine_dispatch (&lacp_mux_machine, vm, mif, LACP_MUX_EVENT_STANDBY,
115                            &mif->mux_state);
116
117   return 0;
118 }
119
120 int
121 lacp_mux_action_attached (void *p1, void *p2)
122 {
123   vlib_main_t *vm = p1;
124   member_if_t *mif = p2;
125
126   lacp_attach_mux_to_aggregator (vm, mif);
127   mif->actor.state &= ~LACP_STATE_COLLECTING;
128   bond_disable_collecting_distributing (vm, mif);
129   mif->actor.state &= ~LACP_STATE_DISTRIBUTING;
130   mif->ntt = 1;
131   lacp_start_periodic_timer (vm, mif, 0);
132
133   if ((mif->selected == LACP_PORT_UNSELECTED) ||
134       (mif->selected == LACP_PORT_STANDBY))
135     lacp_machine_dispatch (&lacp_mux_machine, vm, mif,
136                            LACP_MUX_EVENT_UNSELECTED, &mif->mux_state);
137
138   if ((mif->selected == LACP_PORT_SELECTED) &&
139       (mif->partner.state & LACP_STATE_SYNCHRONIZATION))
140     lacp_machine_dispatch (&lacp_mux_machine, vm, mif, LACP_MUX_EVENT_SYNC,
141                            &mif->mux_state);
142   return 0;
143 }
144
145 int
146 lacp_mux_action_waiting (void *p1, void *p2)
147 {
148   vlib_main_t *vm = p1;
149   member_if_t *mif = p2;
150
151   if (!lacp_timer_is_running (mif->wait_while_timer))
152     lacp_start_wait_while_timer (vm, mif, LACP_AGGREGATE_WAIT_TIME);
153
154   if ((mif->selected == LACP_PORT_SELECTED) && mif->ready)
155     lacp_machine_dispatch (&lacp_mux_machine, vm, mif,
156                            LACP_MUX_EVENT_READY, &mif->mux_state);
157
158   if (mif->selected == LACP_PORT_UNSELECTED)
159     lacp_machine_dispatch (&lacp_mux_machine, vm, mif,
160                            LACP_MUX_EVENT_UNSELECTED, &mif->mux_state);
161
162   return 0;
163 }
164
165 int
166 lacp_mux_action_collecting_distributing (void *p1, void *p2)
167 {
168   vlib_main_t *vm = p1;
169   member_if_t *mif = p2;
170
171   mif->actor.state |= LACP_STATE_SYNCHRONIZATION | LACP_STATE_COLLECTING |
172     LACP_STATE_DISTRIBUTING;
173   bond_enable_collecting_distributing (vm, mif);
174   mif->ntt = 1;
175   lacp_start_periodic_timer (vm, mif, 0);
176   if ((mif->selected == LACP_PORT_UNSELECTED) ||
177       (mif->selected == LACP_PORT_STANDBY) ||
178       !(mif->partner.state & LACP_STATE_SYNCHRONIZATION))
179     lacp_machine_dispatch (&lacp_mux_machine, vm, mif,
180                            LACP_MUX_EVENT_UNSELECTED, &mif->mux_state);
181
182
183   return 0;
184 }
185
186 static u8 *
187 format_mux_event (u8 * s, va_list * args)
188 {
189   static lacp_event_struct lacp_mux_event_array[] = {
190 #define _(b, s, n) {.bit = b, .str = #s, },
191     foreach_lacp_mux_event
192 #undef _
193     {.str = NULL}
194   };
195   int e = va_arg (*args, int);
196   lacp_event_struct *event_entry = lacp_mux_event_array;
197
198   if (e >= (sizeof (lacp_mux_event_array) / sizeof (*event_entry)))
199     s = format (s, "Bad event %d", e);
200   else
201     s = format (s, "%s", event_entry[e].str);
202
203   return s;
204 }
205
206 void
207 lacp_mux_debug_func (member_if_t * mif, int event, int state,
208                      lacp_fsm_state_t * transition)
209 {
210   vlib_worker_thread_t *w = vlib_worker_threads + os_get_thread_index ();
211   /* *INDENT-OFF* */
212   ELOG_TYPE_DECLARE (e) =
213     {
214       .format = "%s",
215       .format_args = "T4",
216     };
217   /* *INDENT-ON* */
218   struct
219   {
220     u32 event;
221   } *ed = 0;
222
223   ed = ELOG_TRACK_DATA (&vlib_global_main.elog_main, e, w->elog_track);
224   ed->event =
225     elog_string (&vlib_global_main.elog_main, "%U-MUX: %U, %U->%U%c",
226                  format_vnet_sw_if_index_name, vnet_get_main (),
227                  mif->sw_if_index, format_mux_event, event,
228                  format_mux_sm_state, state, format_mux_sm_state,
229                  transition->next_state, 0);
230 }
231
232 void
233 lacp_init_mux_machine (vlib_main_t * vm, member_if_t * mif)
234 {
235   lacp_machine_dispatch (&lacp_mux_machine, vm, mif, LACP_MUX_EVENT_BEGIN,
236                          &mif->mux_state);
237 }
238
239 /*
240  * fd.io coding-style-patch-verification: ON
241  *
242  * Local Variables:
243  * eval: (c-set-style "gnu")
244  * End:
245  */