Line data Source code
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 : #include <vnet/bonding/node.h>
18 : #include <lacp/node.h>
19 :
20 : int
21 4 : lacp_dump_ifs (lacp_interface_details_t ** out_lacpifs)
22 : {
23 4 : vnet_main_t *vnm = vnet_get_main ();
24 4 : bond_main_t *bm = &bond_main;
25 : member_if_t *mif;
26 : bond_if_t *bif;
27 : vnet_hw_interface_t *hi;
28 4 : lacp_interface_details_t *r_lacpifs = NULL;
29 4 : lacp_interface_details_t *lacpif = NULL;
30 :
31 : /* *INDENT-OFF* */
32 20 : pool_foreach (mif, bm->neighbors) {
33 16 : if (mif->lacp_enabled == 0)
34 0 : continue;
35 16 : vec_add2(r_lacpifs, lacpif, 1);
36 16 : clib_memset (lacpif, 0, sizeof (*lacpif));
37 16 : lacpif->sw_if_index = mif->sw_if_index;
38 16 : hi = vnet_get_hw_interface (vnm, mif->hw_if_index);
39 16 : clib_memcpy(lacpif->interface_name, hi->name,
40 : MIN (ARRAY_LEN (lacpif->interface_name) - 1,
41 : vec_len (hi->name)));
42 16 : bif = bond_get_bond_if_by_dev_instance (mif->bif_dev_instance);
43 16 : hi = vnet_get_hw_interface (vnm, bif->hw_if_index);
44 16 : clib_memcpy(lacpif->bond_interface_name, hi->name,
45 : MIN (ARRAY_LEN (lacpif->bond_interface_name) - 1,
46 : vec_len (hi->name)));
47 16 : clib_memcpy (lacpif->actor_system, mif->actor.system, 6);
48 16 : lacpif->actor_system_priority = mif->actor.system_priority;
49 16 : lacpif->actor_key = mif->actor.key;
50 16 : lacpif->actor_port_priority = mif->actor.port_priority;
51 16 : lacpif->actor_port_number = mif->actor.port_number;
52 16 : lacpif->actor_state = mif->actor.state;
53 16 : clib_memcpy (lacpif->partner_system, mif->partner.system, 6);
54 16 : lacpif->partner_system_priority = mif->partner.system_priority;
55 16 : lacpif->partner_key = mif->partner.key;
56 16 : lacpif->partner_port_priority = mif->partner.port_priority;
57 16 : lacpif->partner_port_number = mif->partner.port_number;
58 16 : lacpif->partner_state = mif->partner.state;
59 16 : lacpif->rx_state = mif->rx_state;
60 16 : lacpif->tx_state = mif->tx_state;
61 16 : lacpif->ptx_state = mif->ptx_state;
62 16 : lacpif->mux_state = mif->mux_state;
63 : }
64 : /* *INDENT-ON* */
65 :
66 4 : *out_lacpifs = r_lacpifs;
67 :
68 4 : return 0;
69 : }
70 :
71 : static void
72 1 : show_lacp (vlib_main_t * vm, u32 * sw_if_indices)
73 : {
74 : int i;
75 : member_if_t *mif;
76 : bond_if_t *bif;
77 :
78 1 : if (!sw_if_indices)
79 0 : return;
80 :
81 1 : vlib_cli_output (vm, "%-55s %-32s %-32s", " ", "actor state",
82 : "partner state");
83 1 : vlib_cli_output (vm, "%-25s %-12s %-16s %-31s %-31s", "interface name",
84 : "sw_if_index", "bond interface",
85 : "exp/def/dis/col/syn/agg/tim/act",
86 : "exp/def/dis/col/syn/agg/tim/act");
87 :
88 5 : for (i = 0; i < vec_len (sw_if_indices); i++)
89 : {
90 4 : mif = bond_get_member_by_sw_if_index (sw_if_indices[i]);
91 4 : if (!mif || (mif->lacp_enabled == 0))
92 0 : continue;
93 4 : bif = bond_get_bond_if_by_dev_instance (mif->bif_dev_instance);
94 4 : vlib_cli_output (vm,
95 : "%-25U %-12d %-16U %3x %3x %3x %3x %3x %3x %3x %3x "
96 : "%4x %3x %3x %3x %3x %3x %3x %3x",
97 : format_vnet_sw_if_index_name, vnet_get_main (),
98 : mif->sw_if_index, mif->sw_if_index,
99 : format_vnet_sw_if_index_name, vnet_get_main (),
100 4 : bif->sw_if_index, lacp_bit_test (mif->actor.state, 7),
101 4 : lacp_bit_test (mif->actor.state, 6),
102 4 : lacp_bit_test (mif->actor.state, 5),
103 4 : lacp_bit_test (mif->actor.state, 4),
104 4 : lacp_bit_test (mif->actor.state, 3),
105 4 : lacp_bit_test (mif->actor.state, 2),
106 4 : lacp_bit_test (mif->actor.state, 1),
107 4 : lacp_bit_test (mif->actor.state, 0),
108 4 : lacp_bit_test (mif->partner.state, 7),
109 4 : lacp_bit_test (mif->partner.state, 6),
110 4 : lacp_bit_test (mif->partner.state, 5),
111 4 : lacp_bit_test (mif->partner.state, 4),
112 4 : lacp_bit_test (mif->partner.state, 3),
113 4 : lacp_bit_test (mif->partner.state, 2),
114 4 : lacp_bit_test (mif->partner.state, 1),
115 4 : lacp_bit_test (mif->partner.state, 0));
116 4 : vlib_cli_output (vm,
117 : " LAG ID: "
118 : "[(%04x,%02x-%02x-%02x-%02x-%02x-%02x,%04x,%04x,%04x), "
119 : "(%04x,%02x-%02x-%02x-%02x-%02x-%02x,%04x,%04x,%04x)]",
120 4 : ntohs (mif->actor.system_priority),
121 4 : mif->actor.system[0], mif->actor.system[1],
122 4 : mif->actor.system[2], mif->actor.system[3],
123 4 : mif->actor.system[4], mif->actor.system[5],
124 4 : ntohs (mif->actor.key),
125 4 : ntohs (mif->actor.port_priority),
126 4 : ntohs (mif->actor.port_number),
127 4 : ntohs (mif->partner.system_priority),
128 4 : mif->partner.system[0], mif->partner.system[1],
129 4 : mif->partner.system[2], mif->partner.system[3],
130 4 : mif->partner.system[4], mif->partner.system[5],
131 4 : ntohs (mif->partner.key),
132 4 : ntohs (mif->partner.port_priority),
133 4 : ntohs (mif->partner.port_number));
134 4 : vlib_cli_output (vm,
135 : " RX-state: %U, TX-state: %U, "
136 : "MUX-state: %U, PTX-state: %U",
137 : format_rx_sm_state, mif->rx_state, format_tx_sm_state,
138 : mif->tx_state, format_mux_sm_state, mif->mux_state,
139 : format_ptx_sm_state, mif->ptx_state);
140 : }
141 : }
142 :
143 : static void
144 1 : show_lacp_details (vlib_main_t * vm, u32 * sw_if_indices)
145 : {
146 1 : lacp_main_t *lm = &lacp_main;
147 : member_if_t *mif;
148 : lacp_state_struct *state_entry;
149 : int i;
150 : f64 now;
151 :
152 1 : vlib_cli_output (vm, "Number of interfaces: %d", lm->lacp_int);
153 1 : if (!sw_if_indices)
154 0 : return;
155 :
156 1 : now = vlib_time_now (vm);
157 5 : for (i = 0; i < vec_len (sw_if_indices); i++)
158 : {
159 4 : mif = bond_get_member_by_sw_if_index (sw_if_indices[i]);
160 4 : if (!mif || (mif->lacp_enabled == 0))
161 0 : continue;
162 4 : vlib_cli_output (vm, " %U", format_vnet_sw_if_index_name,
163 : vnet_get_main (), mif->sw_if_index);
164 4 : vlib_cli_output (vm, " Good LACP PDUs received: %llu",
165 : mif->pdu_received);
166 4 : vlib_cli_output (vm, " Bad LACP PDUs received: %llu",
167 : mif->bad_pdu_received);
168 4 : vlib_cli_output (vm, " LACP PDUs sent: %llu", mif->pdu_sent);
169 4 : if (lacp_timer_is_running (mif->last_lacpdu_recd_time))
170 4 : vlib_cli_output (vm,
171 : " last LACP PDU received: %10.2f seconds ago",
172 4 : now - mif->last_lacpdu_recd_time);
173 4 : if (lacp_timer_is_running (mif->last_lacpdu_sent_time))
174 4 : vlib_cli_output (vm, " last LACP PDU sent: %10.2f seconds ago",
175 4 : now - mif->last_lacpdu_sent_time);
176 4 : vlib_cli_output (vm, " Good Marker PDUs received: %llu",
177 : mif->marker_pdu_received);
178 4 : vlib_cli_output (vm, " Bad Marker PDUs received: %llu",
179 : mif->marker_bad_pdu_received);
180 4 : if (lacp_timer_is_running (mif->last_marker_pdu_recd_time))
181 0 : vlib_cli_output (vm,
182 : " last Marker PDU received: %10.2f seconds ago",
183 0 : now - mif->last_marker_pdu_recd_time);
184 4 : if (lacp_timer_is_running (mif->last_marker_pdu_sent_time))
185 0 : vlib_cli_output (vm, " last Marker PDU sent: %10.2f seconds ago",
186 0 : now - mif->last_marker_pdu_sent_time);
187 4 : vlib_cli_output (vm, " debug: %d", mif->debug);
188 4 : vlib_cli_output (vm, " loopback port: %d", mif->loopback_port);
189 4 : vlib_cli_output (vm, " port_enabled: %d", mif->port_enabled);
190 4 : vlib_cli_output (vm, " port moved: %d", mif->port_moved);
191 4 : vlib_cli_output (vm, " ready_n: %d", mif->ready_n);
192 4 : vlib_cli_output (vm, " ready: %d", mif->ready);
193 4 : vlib_cli_output (vm, " Actor");
194 4 : vlib_cli_output (vm, " system: %U",
195 4 : format_ethernet_address, mif->actor.system);
196 4 : vlib_cli_output (vm, " system priority: %u",
197 4 : ntohs (mif->actor.system_priority));
198 4 : vlib_cli_output (vm, " key: %u", ntohs (mif->actor.key));
199 4 : vlib_cli_output (vm, " port priority: %u",
200 4 : ntohs (mif->actor.port_priority));
201 4 : vlib_cli_output (vm, " port number: %u",
202 4 : ntohs (mif->actor.port_number));
203 4 : vlib_cli_output (vm, " state: 0x%x", mif->actor.state);
204 :
205 4 : state_entry = (lacp_state_struct *) & lacp_state_array;
206 36 : while (state_entry->str)
207 : {
208 32 : if (mif->actor.state & (1 << state_entry->bit))
209 24 : vlib_cli_output (vm, " %s (%d)", state_entry->str,
210 24 : state_entry->bit);
211 32 : state_entry++;
212 : }
213 :
214 4 : vlib_cli_output (vm, " Partner");
215 4 : vlib_cli_output (vm, " system: %U",
216 4 : format_ethernet_address, mif->partner.system);
217 4 : vlib_cli_output (vm, " system priority: %u",
218 4 : ntohs (mif->partner.system_priority));
219 4 : vlib_cli_output (vm, " key: %u", ntohs (mif->partner.key));
220 4 : vlib_cli_output (vm, " port priority: %u",
221 4 : ntohs (mif->partner.port_priority));
222 4 : vlib_cli_output (vm, " port number: %u",
223 4 : ntohs (mif->partner.port_number));
224 4 : vlib_cli_output (vm, " state: 0x%x", mif->partner.state);
225 :
226 4 : state_entry = (lacp_state_struct *) & lacp_state_array;
227 36 : while (state_entry->str)
228 : {
229 32 : if (mif->partner.state & (1 << state_entry->bit))
230 24 : vlib_cli_output (vm, " %s (%d)", state_entry->str,
231 24 : state_entry->bit);
232 32 : state_entry++;
233 : }
234 :
235 4 : if (!lacp_timer_is_running (mif->wait_while_timer))
236 2 : vlib_cli_output (vm, " wait while timer: not running");
237 : else
238 2 : vlib_cli_output (vm, " wait while timer: %10.2f seconds",
239 2 : mif->wait_while_timer - now);
240 4 : if (!lacp_timer_is_running (mif->current_while_timer))
241 0 : vlib_cli_output (vm, " current while timer: not running");
242 : else
243 4 : vlib_cli_output (vm, " current while timer: %10.2f seconds",
244 4 : mif->current_while_timer - now);
245 4 : if (!lacp_timer_is_running (mif->periodic_timer))
246 0 : vlib_cli_output (vm, " periodic timer: not running");
247 : else
248 4 : vlib_cli_output (vm, " periodic timer: %10.2f seconds",
249 4 : mif->periodic_timer - now);
250 4 : vlib_cli_output (vm, " RX-state: %U", format_rx_sm_state,
251 : mif->rx_state);
252 4 : vlib_cli_output (vm, " TX-state: %U", format_tx_sm_state,
253 : mif->tx_state);
254 4 : vlib_cli_output (vm, " MUX-state: %U", format_mux_sm_state,
255 : mif->mux_state);
256 4 : vlib_cli_output (vm, " PTX-state: %U", format_ptx_sm_state,
257 : mif->ptx_state);
258 4 : vlib_cli_output (vm, "\n");
259 : }
260 : }
261 :
262 : static clib_error_t *
263 2 : show_lacp_fn (vlib_main_t * vm, unformat_input_t * input,
264 : vlib_cli_command_t * cmd)
265 : {
266 2 : bond_main_t *bm = &bond_main;
267 2 : vnet_main_t *vnm = &vnet_main;
268 : member_if_t *mif;
269 2 : clib_error_t *error = 0;
270 2 : u8 details = 0;
271 2 : u32 sw_if_index, *sw_if_indices = 0;
272 :
273 3 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
274 : {
275 1 : if (unformat
276 : (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
277 : {
278 0 : mif = bond_get_member_by_sw_if_index (sw_if_index);
279 0 : if (!mif)
280 : {
281 0 : error = clib_error_return (0, "interface is not a member");
282 0 : goto done;
283 : }
284 0 : vec_add1 (sw_if_indices, mif->sw_if_index);
285 : }
286 1 : else if (unformat (input, "details"))
287 1 : details = 1;
288 : else
289 : {
290 0 : error = clib_error_return (0, "unknown input `%U'",
291 : format_unformat_error, input);
292 0 : goto done;
293 : }
294 : }
295 :
296 2 : if (vec_len (sw_if_indices) == 0)
297 : {
298 10 : pool_foreach (mif, bm->neighbors)
299 8 : vec_add1 (sw_if_indices, mif->sw_if_index);
300 : }
301 :
302 2 : if (details)
303 1 : show_lacp_details (vm, sw_if_indices);
304 : else
305 1 : show_lacp (vm, sw_if_indices);
306 :
307 2 : done:
308 2 : vec_free (sw_if_indices);
309 2 : return error;
310 : }
311 :
312 : /* *INDENT-OFF* */
313 179305 : VLIB_CLI_COMMAND (show_lacp_command, static) = {
314 : .path = "show lacp",
315 : .short_help = "show lacp [<interface>] [details]",
316 : .function = show_lacp_fn,
317 : .is_mp_safe = 1,
318 : };
319 : /* *INDENT-ON* */
320 :
321 : static clib_error_t *
322 1 : debug_lacp_command_fn (vlib_main_t * vm, unformat_input_t * input,
323 : vlib_cli_command_t * cmd)
324 : {
325 1 : unformat_input_t _line_input, *line_input = &_line_input;
326 1 : clib_error_t *error = NULL;
327 1 : lacp_main_t *lm = &lacp_main;
328 1 : u8 onoff = 0;
329 1 : u8 input_found = 0;
330 1 : u32 sw_if_index = ~0;
331 : member_if_t *mif;
332 1 : vnet_main_t *vnm = vnet_get_main ();
333 :
334 : /* Get a line of input. */
335 1 : if (!unformat_user (input, unformat_line_input, line_input))
336 0 : return clib_error_return (0, "missing argument");
337 :
338 2 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
339 : {
340 1 : if (unformat (line_input, "%U",
341 : unformat_vnet_sw_interface, vnm, &sw_if_index))
342 : ;
343 1 : if (input_found)
344 : {
345 0 : error = clib_error_return (0, "unknown input `%U'",
346 : format_unformat_error, line_input);
347 0 : goto done;
348 : }
349 1 : else if (unformat (line_input, "on"))
350 : {
351 1 : input_found = 1;
352 1 : onoff = 1;
353 : }
354 0 : else if (unformat (line_input, "off"))
355 : {
356 0 : input_found = 1;
357 0 : onoff = 0;
358 : }
359 : else
360 : {
361 0 : error = clib_error_return (0, "unknown input `%U'",
362 : format_unformat_error, line_input);
363 0 : goto done;
364 : }
365 : }
366 :
367 1 : if (!input_found)
368 0 : return clib_error_return (0, "must specify on or off");
369 :
370 1 : if (sw_if_index != ~0)
371 : {
372 0 : mif = bond_get_member_by_sw_if_index (sw_if_index);
373 0 : if (!mif)
374 0 : return (clib_error_return
375 : (0, "Please add the member interface first"));
376 0 : mif->debug = onoff;
377 : }
378 : else
379 1 : lm->debug = onoff;
380 :
381 1 : done:
382 1 : unformat_free (line_input);
383 :
384 1 : return error;
385 : }
386 :
387 : /* *INDENT-OFF* */
388 179305 : VLIB_CLI_COMMAND (debug_lacp_command, static) = {
389 : .path = "debug lacp",
390 : .short_help = "debug lacp <interface> <on | off>",
391 : .function = debug_lacp_command_fn,
392 : };
393 : /* *INDENT-ON* */
394 :
395 : clib_error_t *
396 575 : lacp_cli_init (vlib_main_t * vm)
397 : {
398 575 : lacp_main_t *lm = &lacp_main;
399 :
400 575 : lm->vlib_main = vm;
401 575 : lm->vnet_main = vnet_get_main ();
402 :
403 575 : return 0;
404 : }
405 :
406 1151 : VLIB_INIT_FUNCTION (lacp_cli_init);
407 :
408 : /*
409 : * fd.io coding-style-patch-verification: ON
410 : *
411 : * Local Variables:
412 : * eval: (c-set-style "gnu")
413 : * End:
414 : */
|