FD.io VPP  v19.08.3-2-gbabecb413
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 = p1;
100  slave_if_t *sif = 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 = p1;
125  slave_if_t *sif = 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 = p1;
151  slave_if_t *sif = 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 = p1;
173  slave_if_t *sif = 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 = lacp_mux_event_array;
202 
203  if (e >= (sizeof (lacp_mux_event_array) / sizeof (*event_entry)))
204  s = format (s, "Bad event %d", e);
205  else
206  s = format (s, "%s", event_entry[e].str);
207 
208  return s;
209 }
210 
211 void
212 lacp_mux_debug_func (slave_if_t * sif, int event, int state,
213  lacp_fsm_state_t * transition)
214 {
216  /* *INDENT-OFF* */
217  ELOG_TYPE_DECLARE (e) =
218  {
219  .format = "%s",
220  .format_args = "T4",
221  };
222  /* *INDENT-ON* */
223  struct
224  {
225  u32 event;
226  } *ed = 0;
227 
229  ed->event =
230  elog_string (&vlib_global_main.elog_main, "%U-MUX: %U, %U->%U%c",
232  sif->sw_if_index, format_mux_event, event,
234  transition->next_state, 0);
235 }
236 
237 void
239 {
240  lacp_machine_dispatch (&lacp_mux_machine, vm, sif, LACP_MUX_EVENT_BEGIN,
241  &sif->mux_state);
242 }
243 
244 /*
245  * fd.io coding-style-patch-verification: ON
246  *
247  * Local Variables:
248  * eval: (c-set-style "gnu")
249  * End:
250  */
void lacp_init_mux_machine(vlib_main_t *vm, slave_if_t *sif)
Definition: mux_machine.c:238
vlib_main_t * vlib_main
Definition: node.h:121
vlib_main_t vlib_global_main
Definition: main.c:1940
#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:271
#define LACP_ACTION_COLLECTING_DISTRIBUTING
Definition: mux_machine.h:62
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
elog_track_t elog_track
Definition: threads.h:100
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:424
void bond_enable_collecting_distributing(vlib_main_t *vm, slave_if_t *sif)
Definition: cli.c:105
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
u8 ntt
Definition: node.h:253
static u8 lacp_timer_is_running(f64 timer)
Definition: node.h:166
int lacp_mux_action_collecting_distributing(void *p1, void *p2)
Definition: mux_machine.c:170
lacp_port_info_t actor
Definition: node.h:246
vhost_vring_state_t state
Definition: vhost_user.h:146
int lacp_mux_action_waiting(void *p1, void *p2)
Definition: mux_machine.c:148
unsigned int u32
Definition: types.h:88
#define LACP_ACTION_DETACHED
Definition: mux_machine.h:59
#define LACP_ACTION_ATTACHED
Definition: mux_machine.h:60
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.c:37
u8 ready
Definition: node.h:268
u32 sw_if_index
Definition: node.h:212
vlib_main_t * vm
Definition: buffer.c:323
lacp_port_info_t partner
Definition: node.h:245
static u8 * format_mux_sm_state(u8 *s, va_list *args)
Definition: node.h:220
void bond_disable_collecting_distributing(vlib_main_t *vm, slave_if_t *sif)
Definition: cli.c:26
elog_main_t elog_main
Definition: main.h:193
lacp_main_t lacp_main
Definition: lacp.c:25
#define ELOG_TYPE_DECLARE(f)
Definition: elog.h:442
#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
#define ELOG_TRACK_DATA(em, f, track)
Definition: elog.h:478
u8 ready_n
Definition: node.h:265
u32 elog_string(elog_main_t *em, char *fmt,...)
add a string to the event-log string table
Definition: elog.c:562
int lacp_mux_action_attached(void *p1, void *p2)
Definition: mux_machine.c:122
static_always_inline uword os_get_thread_index(void)
Definition: os.h:62
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:212
f64 wait_while_timer
Definition: node.h:301
static lacp_fsm_machine_t lacp_mux_fsm_table[]
Definition: mux_machine.c:70
int mux_state
Definition: node.h:306
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:300
static u8 * format_mux_event(u8 *s, va_list *args)
Definition: mux_machine.c:192