FD.io VPP  v19.01.1-17-ge106252
Vector Packet Processing
mux_machine.c
Go to the documentation of this file.
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 = {
80 };
81 
82 static void
84 {
85  sif->actor.state &= ~LACP_STATE_SYNCHRONIZATION;
86  sif->ready = 0;
87  sif->ready_n = 0;
88 }
89 
90 static void
92 {
93  sif->actor.state |= LACP_STATE_SYNCHRONIZATION;
94 }
95 
96 int
97 lacp_mux_action_detached (void *p1, void *p2)
98 {
99  vlib_main_t *vm = (vlib_main_t *) p1;
100  slave_if_t *sif = (slave_if_t *) p2;
101  lacp_main_t *lm = &lacp_main;
102 
104  sif->actor.state &= ~LACP_STATE_COLLECTING;
106  sif->actor.state &= ~LACP_STATE_DISTRIBUTING;
107  sif->ntt = 1;
108  lacp_start_periodic_timer (lm->vlib_main, sif, 0);
109 
110  if (sif->selected == LACP_PORT_SELECTED)
111  lacp_machine_dispatch (&lacp_mux_machine, vm, sif,
112  LACP_MUX_EVENT_SELECTED, &sif->mux_state);
113 
114  if (sif->selected == LACP_PORT_STANDBY)
115  lacp_machine_dispatch (&lacp_mux_machine, vm, sif, LACP_MUX_EVENT_STANDBY,
116  &sif->mux_state);
117 
118  return 0;
119 }
120 
121 int
122 lacp_mux_action_attached (void *p1, void *p2)
123 {
124  vlib_main_t *vm = (vlib_main_t *) p1;
125  slave_if_t *sif = (slave_if_t *) p2;
126  lacp_main_t *lm = &lacp_main;
127 
129  sif->actor.state &= ~LACP_STATE_COLLECTING;
131  sif->actor.state &= ~LACP_STATE_DISTRIBUTING;
132  sif->ntt = 1;
133  lacp_start_periodic_timer (lm->vlib_main, sif, 0);
134 
135  if ((sif->selected == LACP_PORT_UNSELECTED) ||
136  (sif->selected == LACP_PORT_STANDBY))
137  lacp_machine_dispatch (&lacp_mux_machine, vm, sif,
138  LACP_MUX_EVENT_UNSELECTED, &sif->mux_state);
139 
140  if ((sif->selected == LACP_PORT_SELECTED) &&
141  (sif->partner.state & LACP_STATE_SYNCHRONIZATION))
142  lacp_machine_dispatch (&lacp_mux_machine, vm, sif, LACP_MUX_EVENT_SYNC,
143  &sif->mux_state);
144  return 0;
145 }
146 
147 int
148 lacp_mux_action_waiting (void *p1, void *p2)
149 {
150  vlib_main_t *vm = (vlib_main_t *) p1;
151  slave_if_t *sif = (slave_if_t *) p2;
152  lacp_main_t *lm = &lacp_main;
153 
157 
158  if ((sif->selected == LACP_PORT_SELECTED) && sif->ready)
159  lacp_machine_dispatch (&lacp_mux_machine, vm, sif,
160  LACP_MUX_EVENT_READY, &sif->mux_state);
161 
162  if (sif->selected == LACP_PORT_UNSELECTED)
163  lacp_machine_dispatch (&lacp_mux_machine, vm, sif,
164  LACP_MUX_EVENT_UNSELECTED, &sif->mux_state);
165 
166  return 0;
167 }
168 
169 int
171 {
172  vlib_main_t *vm = (vlib_main_t *) p1;
173  slave_if_t *sif = (slave_if_t *) p2;
174  lacp_main_t *lm = &lacp_main;
175 
176  sif->actor.state |= LACP_STATE_SYNCHRONIZATION | LACP_STATE_COLLECTING |
177  LACP_STATE_DISTRIBUTING;
179  sif->ntt = 1;
180  lacp_start_periodic_timer (lm->vlib_main, sif, 0);
181  if ((sif->selected == LACP_PORT_UNSELECTED) ||
182  (sif->selected == LACP_PORT_STANDBY) ||
183  !(sif->partner.state & LACP_STATE_SYNCHRONIZATION))
184  lacp_machine_dispatch (&lacp_mux_machine, vm, sif,
185  LACP_MUX_EVENT_UNSELECTED, &sif->mux_state);
186 
187 
188  return 0;
189 }
190 
191 static u8 *
192 format_mux_event (u8 * s, va_list * args)
193 {
194  static lacp_event_struct lacp_mux_event_array[] = {
195 #define _(b, s, n) {.bit = b, .str = #s, },
197 #undef _
198  {.str = NULL}
199  };
200  int e = va_arg (*args, int);
201  lacp_event_struct *event_entry =
202  (lacp_event_struct *) & lacp_mux_event_array;
203 
204  if (e >= (sizeof (lacp_mux_event_array) / sizeof (*event_entry)))
205  s = format (s, "Bad event %d", e);
206  else
207  s = format (s, "%s", event_entry[e].str);
208 
209  return s;
210 }
211 
212 void
213 lacp_mux_debug_func (slave_if_t * sif, int event, int state,
214  lacp_fsm_state_t * transition)
215 {
216  clib_warning ("%U-MUX: event %U, old state %U, new state %U",
220  transition->next_state);
221 }
222 
223 void
225 {
226  lacp_machine_dispatch (&lacp_mux_machine, vm, sif, LACP_MUX_EVENT_BEGIN,
227  &sif->mux_state);
228 }
229 
230 /*
231  * fd.io coding-style-patch-verification: ON
232  *
233  * Local Variables:
234  * eval: (c-set-style "gnu")
235  * End:
236  */
void lacp_init_mux_machine(vlib_main_t *vm, slave_if_t *sif)
Definition: mux_machine.c:224
vlib_main_t * vlib_main
Definition: node.h:119
#define LACP_AGGREGATE_WAIT_TIME
Definition: protocol.h:23
static void lacp_start_wait_while_timer(vlib_main_t *vm, slave_if_t *sif, u8 expiration)
Definition: mux_machine.h:66
int selected
Definition: node.h:257
#define LACP_ACTION_COLLECTING_DISTRIBUTING
Definition: mux_machine.h:62
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
#define NULL
Definition: clib.h:58
static void lacp_detach_mux_from_aggregator(vlib_main_t *vm, slave_if_t *sif)
Definition: mux_machine.c:83
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
void bond_enable_collecting_distributing(vlib_main_t *vm, slave_if_t *sif)
Definition: cli.c:59
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
u8 ntt
Definition: node.h:239
static u8 lacp_timer_is_running(f64 timer)
Definition: node.h:163
int lacp_mux_action_collecting_distributing(void *p1, void *p2)
Definition: mux_machine.c:170
lacp_port_info_t actor
Definition: node.h:232
vhost_vring_state_t state
Definition: vhost_user.h:120
int lacp_mux_action_waiting(void *p1, void *p2)
Definition: mux_machine.c:148
#define LACP_ACTION_DETACHED
Definition: mux_machine.h:59
#define LACP_ACTION_ATTACHED
Definition: mux_machine.h:60
u8 ready
Definition: node.h:254
u32 sw_if_index
Definition: node.h:198
vlib_main_t * vm
Definition: buffer.c:301
lacp_port_info_t partner
Definition: node.h:231
static u8 * format_mux_sm_state(u8 *s, va_list *args)
Definition: node.h:219
#define clib_warning(format, args...)
Definition: error.h:59
void bond_disable_collecting_distributing(vlib_main_t *vm, slave_if_t *sif)
Definition: cli.c:25
lacp_main_t lacp_main
Definition: lacp.c:25
#define LACP_ACTION_WAITING
Definition: mux_machine.h:61
static void lacp_attach_mux_to_aggregator(vlib_main_t *vm, slave_if_t *sif)
Definition: mux_machine.c:91
u8 ready_n
Definition: node.h:251
int lacp_mux_action_attached(void *p1, void *p2)
Definition: mux_machine.c:122
static void lacp_start_periodic_timer(vlib_main_t *vm, slave_if_t *sif, u8 expiration)
Definition: ptx_machine.h:67
void lacp_mux_debug_func(slave_if_t *sif, int event, int state, lacp_fsm_state_t *transition)
Definition: mux_machine.c:213
f64 wait_while_timer
Definition: node.h:278
static lacp_fsm_machine_t lacp_mux_fsm_table[]
Definition: mux_machine.c:70
int mux_state
Definition: node.h:283
int lacp_mux_action_detached(void *p1, void *p2)
Definition: mux_machine.c:97
int lacp_machine_dispatch(lacp_machine_t *machine, vlib_main_t *vm, slave_if_t *sif, int event, int *state)
Definition: lacp.c:286
static u8 * format_mux_event(u8 *s, va_list *args)
Definition: mux_machine.c:192