FD.io VPP  v20.09-64-g4f7b92f0a
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  mif->actor.state &= ~LACP_STATE_SYNCHRONIZATION;
86  mif->ready = 0;
87  mif->ready_n = 0;
88 }
89 
90 static void
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 
103  mif->actor.state &= ~LACP_STATE_COLLECTING;
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 
127  mif->actor.state &= ~LACP_STATE_COLLECTING;
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 
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
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;
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, },
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 {
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 
224  ed->event =
225  elog_string (&vlib_global_main.elog_main, "%U-MUX: %U, %U->%U%c",
227  mif->sw_if_index, format_mux_event, event,
229  transition->next_state, 0);
230 }
231 
232 void
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  */
vlib_main_t vlib_global_main
Definition: main.c:1983
#define LACP_AGGREGATE_WAIT_TIME
Definition: protocol.h:23
#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:101
vlib_main_t * vm
Definition: in2out_ed.c:1582
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
int selected
Definition: node.h:280
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
static u8 lacp_timer_is_running(f64 timer)
Definition: node.h:166
u8 ready_n
Definition: node.h:274
int lacp_mux_action_collecting_distributing(void *p1, void *p2)
Definition: mux_machine.c:166
int lacp_mux_action_waiting(void *p1, void *p2)
Definition: mux_machine.c:146
unsigned int u32
Definition: types.h:88
void lacp_init_mux_machine(vlib_main_t *vm, member_if_t *mif)
Definition: mux_machine.c:233
#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:34
u8 ntt
Definition: node.h:262
static void lacp_start_wait_while_timer(vlib_main_t *vm, member_if_t *mif, u8 expiration)
Definition: mux_machine.h:66
lacp_port_info_t partner
Definition: node.h:254
static void lacp_start_periodic_timer(vlib_main_t *vm, member_if_t *mif, u8 expiration)
Definition: ptx_machine.h:67
int mux_state
Definition: node.h:315
static void lacp_detach_mux_from_aggregator(vlib_main_t *vm, member_if_t *mif)
Definition: mux_machine.c:83
static u8 * format_mux_sm_state(u8 *s, va_list *args)
Definition: node.h:220
elog_main_t elog_main
Definition: main.h:224
#define ELOG_TYPE_DECLARE(f)
Definition: elog.h:442
void bond_disable_collecting_distributing(vlib_main_t *vm, member_if_t *mif)
Definition: cli.c:26
#define LACP_ACTION_WAITING
Definition: mux_machine.h:61
#define ELOG_TRACK_DATA(em, f, track)
Definition: elog.h:478
u8 ready
Definition: node.h:277
f64 wait_while_timer
Definition: node.h:310
u32 elog_string(elog_main_t *em, char *fmt,...)
add a string to the event-log string table
Definition: elog.c:571
int lacp_mux_action_attached(void *p1, void *p2)
Definition: mux_machine.c:121
static_always_inline uword os_get_thread_index(void)
Definition: os.h:63
int lacp_machine_dispatch(lacp_machine_t *machine, vlib_main_t *vm, member_if_t *mif, int event, int *state)
Definition: lacp.c:317
u32 sw_if_index
Definition: node.h:218
void lacp_mux_debug_func(member_if_t *mif, int event, int state, lacp_fsm_state_t *transition)
Definition: mux_machine.c:207
vl_api_dhcp_client_state_t state
Definition: dhcp.api:201
static void lacp_attach_mux_to_aggregator(vlib_main_t *vm, member_if_t *mif)
Definition: mux_machine.c:91
lacp_port_info_t actor
Definition: node.h:255
static lacp_fsm_machine_t lacp_mux_fsm_table[]
Definition: mux_machine.c:70
int lacp_mux_action_detached(void *p1, void *p2)
Definition: mux_machine.c:97
static u8 * format_mux_event(u8 *s, va_list *args)
Definition: mux_machine.c:187
void bond_enable_collecting_distributing(vlib_main_t *vm, member_if_t *mif)
Definition: cli.c:134