Line data Source code
1 : /*
2 : * Copyright (c) 2011-2016 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 : * @file
17 : * @brief BFD CLI implementation
18 : */
19 :
20 : #include <vlib/vlib.h>
21 : #include <vlib/cli.h>
22 : #include <vppinfra/format.h>
23 : #include <vppinfra/warnings.h>
24 : #include <vnet/api_errno.h>
25 : #include <vnet/ip/format.h>
26 : #include <vnet/bfd/bfd_api.h>
27 : #include <vnet/bfd/bfd_main.h>
28 :
29 : static u8 *
30 2 : format_bfd_session_cli (u8 * s, va_list * args)
31 : {
32 2 : vlib_main_t *vm = va_arg (*args, vlib_main_t *);
33 2 : bfd_session_t *bs = va_arg (*args, bfd_session_t *);
34 2 : switch (bs->transport)
35 : {
36 1 : case BFD_TRANSPORT_UDP4:
37 1 : s = format (s, "%=10u %-32s %20U %20U\n", bs->bs_idx, "IPv4 address",
38 1 : format_ip4_address, bs->udp.key.local_addr.ip4.as_u8,
39 1 : format_ip4_address, bs->udp.key.peer_addr.ip4.as_u8);
40 1 : break;
41 1 : case BFD_TRANSPORT_UDP6:
42 1 : s = format (s, "%=10u %-32s %20U %20U\n", bs->bs_idx, "IPv6 address",
43 : format_ip6_address, &bs->udp.key.local_addr.ip6,
44 : format_ip6_address, &bs->udp.key.peer_addr.ip6);
45 1 : break;
46 : }
47 2 : s = format (s, "%10s %-32s %20s %20s\n", "", "Session state",
48 : bfd_state_string (bs->local_state),
49 : bfd_state_string (bs->remote_state));
50 2 : s = format (s, "%10s %-32s %20s %20s\n", "", "Diagnostic code",
51 : bfd_diag_code_string (bs->local_diag),
52 : bfd_diag_code_string (bs->remote_diag));
53 2 : s = format (s, "%10s %-32s %20u %20u\n", "", "Detect multiplier",
54 2 : bs->local_detect_mult, bs->remote_detect_mult);
55 2 : s = format (s, "%10s %-32s %20u %20llu\n", "",
56 : "Required Min Rx Interval (usec)",
57 : bs->config_required_min_rx_usec, bs->remote_min_rx_usec);
58 2 : s = format (s, "%10s %-32s %20u %20u\n", "",
59 : "Desired Min Tx Interval (usec)",
60 : bs->config_desired_min_tx_usec,
61 : bfd_nsec_to_usec (bs->remote_desired_min_tx_nsec));
62 : s =
63 2 : format (s, "%10s %-32s %20u\n", "", "Transmit interval",
64 : bfd_nsec_to_usec (bs->transmit_interval_nsec));
65 2 : u64 now = clib_cpu_time_now ();
66 2 : u8 *tmp = NULL;
67 2 : if (bs->last_tx_nsec > 0)
68 : {
69 4 : tmp = format (tmp, "%.2fs ago", (now - bs->last_tx_nsec) *
70 2 : vm->clib_time.seconds_per_clock);
71 2 : s = format (s, "%10s %-32s %20v\n", "", "Last control frame tx", tmp);
72 2 : vec_reset_length (tmp);
73 : }
74 2 : if (bs->last_rx_nsec)
75 : {
76 0 : tmp = format (tmp, "%.2fs ago", (now - bs->last_rx_nsec) *
77 0 : vm->clib_time.seconds_per_clock);
78 0 : s = format (s, "%10s %-32s %20v\n", "", "Last control frame rx", tmp);
79 0 : vec_reset_length (tmp);
80 : }
81 : s =
82 2 : format (s, "%10s %-32s %20u %20llu\n", "", "Min Echo Rx Interval (usec)",
83 : 1, bs->remote_min_echo_rx_usec);
84 2 : if (bs->echo)
85 : {
86 : s =
87 0 : format (s, "%10s %-32s %20u\n", "", "Echo transmit interval",
88 : bfd_nsec_to_usec (bs->echo_transmit_interval_nsec));
89 0 : tmp =
90 0 : format (tmp, "%.2fs ago",
91 0 : (now -
92 0 : bs->echo_last_tx_nsec) * vm->clib_time.seconds_per_clock);
93 0 : s = format (s, "%10s %-32s %20v\n", "", "Last echo frame tx", tmp);
94 0 : vec_reset_length (tmp);
95 0 : tmp = format (tmp, "%.6fs",
96 0 : (bs->echo_last_rx_nsec - bs->echo_last_tx_nsec) *
97 0 : vm->clib_time.seconds_per_clock);
98 : s =
99 0 : format (s, "%10s %-32s %20v\n", "", "Last echo frame roundtrip time",
100 : tmp);
101 : }
102 2 : vec_free (tmp);
103 2 : tmp = NULL;
104 2 : s = format (s, "%10s %-32s %20s %20s\n", "", "Demand mode", "no",
105 2 : bs->remote_demand ? "yes" : "no");
106 2 : s = format (s, "%10s %-32s %20s\n", "", "Poll state",
107 : bfd_poll_state_string (bs->poll_state));
108 2 : if (bs->auth.curr_key)
109 : {
110 1 : s = format (s, "%10s %-32s %20u\n", "", "Authentication config key ID",
111 1 : bs->auth.curr_key->conf_key_id);
112 1 : s = format (s, "%10s %-32s %20u\n", "", "Authentication BFD key ID",
113 1 : bs->auth.curr_bfd_key_id);
114 1 : s = format (s, "%10s %-32s %20u %20u\n", "", "Sequence number",
115 : bs->auth.local_seq_number, bs->auth.remote_seq_number);
116 : }
117 2 : return s;
118 : }
119 :
120 : static clib_error_t *
121 8 : show_bfd (vlib_main_t * vm, unformat_input_t * input,
122 : CLIB_UNUSED (vlib_cli_command_t * lmd))
123 : {
124 8 : bfd_main_t *bm = &bfd_main;
125 8 : bfd_session_t *bs = NULL;
126 8 : unformat_input_t _line_input, *line_input = &_line_input;
127 :
128 : /* Get a line of input. */
129 8 : if (!unformat_user (input, unformat_line_input, line_input))
130 1 : return 0;
131 :
132 7 : if (unformat (line_input, "keys"))
133 : {
134 1 : bfd_auth_key_t *key = NULL;
135 1 : u8 *s = format (NULL, "%=10s %=25s %=10s\n", "Configuration Key ID",
136 : "Type", "Use Count");
137 : /* *INDENT-OFF* */
138 3 : pool_foreach (key, bm->auth_keys) {
139 2 : s = format (s, "%10u %-25s %10u\n", key->conf_key_id,
140 : bfd_auth_type_str (key->auth_type), key->use_count);
141 : }
142 : /* *INDENT-ON* */
143 1 : vlib_cli_output (vm, "%v\n", s);
144 1 : vec_free (s);
145 1 : vlib_cli_output (vm, "Number of configured BFD keys: %lu\n",
146 1 : (u64) pool_elts (bm->auth_keys));
147 : }
148 6 : else if (unformat (line_input, "sessions"))
149 : {
150 1 : u8 *s = format (NULL, "%=10s %=32s %=20s %=20s\n", "Index", "Property",
151 : "Local value", "Remote value");
152 : /* *INDENT-OFF* */
153 3 : pool_foreach (bs, bm->sessions) {
154 2 : s = format (s, "%U", format_bfd_session_cli, vm, bs);
155 : }
156 : /* *INDENT-ON* */
157 1 : vlib_cli_output (vm, "%v", s);
158 1 : vec_free (s);
159 1 : vlib_cli_output (vm, "Number of configured BFD sessions: %lu\n",
160 1 : (u64) pool_elts (bm->sessions));
161 : }
162 5 : else if (unformat (line_input, "echo-source"))
163 : {
164 : int is_set;
165 : u32 sw_if_index;
166 : int have_usable_ip4;
167 : ip4_address_t ip4;
168 : int have_usable_ip6;
169 : ip6_address_t ip6;
170 5 : bfd_udp_get_echo_source (&is_set, &sw_if_index, &have_usable_ip4, &ip4,
171 : &have_usable_ip6, &ip6);
172 5 : if (is_set)
173 : {
174 : vnet_sw_interface_t *sw_if =
175 3 : vnet_get_sw_interface_or_null (&vnet_main, sw_if_index);
176 : vnet_hw_interface_t *hw_if =
177 3 : vnet_get_hw_interface (&vnet_main, sw_if->hw_if_index);
178 3 : u8 *s = format (NULL, "UDP echo source is: %v\n", hw_if->name);
179 3 : s = format (s, "IPv4 address usable as echo source: ");
180 3 : if (have_usable_ip4)
181 : {
182 2 : s = format (s, "%U\n", format_ip4_address, &ip4);
183 : }
184 : else
185 : {
186 1 : s = format (s, "none\n");
187 : }
188 3 : s = format (s, "IPv6 address usable as echo source: ");
189 3 : if (have_usable_ip6)
190 : {
191 1 : s = format (s, "%U\n", format_ip6_address, &ip6);
192 : }
193 : else
194 : {
195 2 : s = format (s, "none\n");
196 : }
197 3 : vlib_cli_output (vm, "%v", s);
198 3 : vec_free (s);
199 : }
200 : else
201 : {
202 2 : vlib_cli_output (vm, "UDP echo source is not set.\n");
203 : }
204 : }
205 : else
206 : {
207 0 : vlib_cli_output (vm, "Number of configured BFD sessions: %lu\n",
208 0 : (u64) pool_elts (bm->sessions));
209 0 : vlib_cli_output (vm, "Number of configured BFD keys: %lu\n",
210 0 : (u64) pool_elts (bm->auth_keys));
211 : }
212 7 : return 0;
213 : }
214 :
215 : /* *INDENT-OFF* */
216 285289 : VLIB_CLI_COMMAND (show_bfd_command, static) = {
217 : .path = "show bfd",
218 : .short_help = "show bfd [keys|sessions|echo-source]",
219 : .function = show_bfd,
220 : };
221 : /* *INDENT-ON* */
222 :
223 : static clib_error_t *
224 4 : bfd_cli_key_add (vlib_main_t * vm, unformat_input_t * input,
225 : CLIB_UNUSED (vlib_cli_command_t * lmd))
226 : {
227 4 : clib_error_t *ret = NULL;
228 4 : int have_key_id = 0;
229 4 : u32 key_id = 0;
230 4 : u8 *vec_auth_type = NULL;
231 4 : bfd_auth_type_e auth_type = BFD_AUTH_TYPE_reserved;
232 4 : u8 *secret = NULL;
233 4 : unformat_input_t _line_input, *line_input = &_line_input;
234 : static const u8 keyed_sha1[] = "keyed-sha1";
235 : static const u8 meticulous_keyed_sha1[] = "meticulous-keyed-sha1";
236 :
237 : /* Get a line of input. */
238 4 : if (!unformat_user (input, unformat_line_input, line_input))
239 0 : return 0;
240 :
241 16 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
242 : {
243 12 : if (unformat (line_input, "conf-key-id %u", &key_id))
244 : {
245 4 : have_key_id = 1;
246 : }
247 8 : else if (unformat (line_input, "type %U", unformat_token, "a-zA-Z0-9-",
248 : &vec_auth_type))
249 : {
250 4 : if (vec_len (vec_auth_type) == sizeof (keyed_sha1) - 1 &&
251 3 : 0 == memcmp (vec_auth_type, keyed_sha1,
252 : sizeof (keyed_sha1) - 1))
253 : {
254 3 : auth_type = BFD_AUTH_TYPE_keyed_sha1;
255 : }
256 1 : else if (vec_len (vec_auth_type) ==
257 1 : sizeof (meticulous_keyed_sha1) - 1 &&
258 1 : 0 == memcmp (vec_auth_type, meticulous_keyed_sha1,
259 : sizeof (meticulous_keyed_sha1) - 1))
260 : {
261 1 : auth_type = BFD_AUTH_TYPE_meticulous_keyed_sha1;
262 : }
263 : else
264 : {
265 0 : ret = clib_error_return (0, "invalid type `%v'", vec_auth_type);
266 0 : goto out;
267 : }
268 : }
269 : else
270 4 : if (unformat (line_input, "secret %U", unformat_hex_string, &secret))
271 : {
272 : /* nothing to do here */
273 : }
274 : else
275 : {
276 0 : ret = clib_error_return (0, "Unknown input `%U'",
277 : format_unformat_error, line_input);
278 0 : goto out;
279 : }
280 : }
281 :
282 4 : if (!have_key_id)
283 : {
284 : ret =
285 0 : clib_error_return (0, "required parameter missing: `conf-key-id'");
286 0 : goto out;
287 : }
288 4 : if (!vec_auth_type)
289 : {
290 0 : ret = clib_error_return (0, "required parameter missing: `type'");
291 0 : goto out;
292 : }
293 4 : if (!secret)
294 : {
295 0 : ret = clib_error_return (0, "required parameter missing: `secret'");
296 0 : goto out;
297 : }
298 :
299 : vnet_api_error_t rv =
300 4 : bfd_auth_set_key (key_id, auth_type, vec_len (secret), secret);
301 4 : if (rv)
302 : {
303 : ret =
304 2 : clib_error_return (0, "`bfd_auth_set_key' API call failed, rv=%d:%U",
305 : (int) rv, format_vnet_api_errno, rv);
306 : }
307 :
308 2 : out:
309 4 : vec_free (vec_auth_type);
310 4 : return ret;
311 : }
312 :
313 : /* *INDENT-OFF* */
314 285289 : VLIB_CLI_COMMAND (bfd_cli_key_add_command, static) = {
315 : .path = "bfd key set",
316 : .short_help = "bfd key set"
317 : " conf-key-id <id>"
318 : " type <keyed-sha1|meticulous-keyed-sha1> "
319 : " secret <secret>",
320 : .function = bfd_cli_key_add,
321 : };
322 : /* *INDENT-ON* */
323 :
324 : static clib_error_t *
325 2 : bfd_cli_key_del (vlib_main_t * vm, unformat_input_t * input,
326 : CLIB_UNUSED (vlib_cli_command_t * lmd))
327 : {
328 2 : clib_error_t *ret = NULL;
329 2 : u32 key_id = 0;
330 2 : unformat_input_t _line_input, *line_input = &_line_input;
331 :
332 : /* Get a line of input. */
333 2 : if (!unformat_user (input, unformat_line_input, line_input))
334 0 : return 0;
335 :
336 4 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
337 : {
338 2 : if (!unformat (line_input, "conf-key-id %u", &key_id))
339 : {
340 0 : ret = clib_error_return (0, "Unknown input `%U'",
341 : format_unformat_error, line_input);
342 0 : goto out;
343 : }
344 : }
345 :
346 2 : vnet_api_error_t rv = bfd_auth_del_key (key_id);
347 2 : if (rv)
348 : {
349 : ret =
350 0 : clib_error_return (0, "`bfd_auth_del_key' API call failed, rv=%d:%U",
351 : (int) rv, format_vnet_api_errno, rv);
352 : }
353 :
354 2 : out:
355 2 : return ret;
356 : }
357 :
358 : /* *INDENT-OFF* */
359 285289 : VLIB_CLI_COMMAND (bfd_cli_key_del_command, static) = {
360 : .path = "bfd key del",
361 : .short_help = "bfd key del conf-key-id <id>",
362 : .function = bfd_cli_key_del,
363 : };
364 : /* *INDENT-ON* */
365 :
366 : #define INTERFACE_STR "interface"
367 : #define LOCAL_ADDR_STR "local-addr"
368 : #define PEER_ADDR_STR "peer-addr"
369 : #define CONF_KEY_ID_STR "conf-key-id"
370 : #define BFD_KEY_ID_STR "bfd-key-id"
371 : #define DESIRED_MIN_TX_STR "desired-min-tx"
372 : #define REQUIRED_MIN_RX_STR "required-min-rx"
373 : #define DETECT_MULT_STR "detect-mult"
374 : #define ADMIN_STR "admin"
375 : #define DELAYED_STR "delayed"
376 :
377 : static const unsigned mandatory = 1;
378 : static const unsigned optional = 0;
379 :
380 : #define DECLARE(t, n, s, r, ...) \
381 : int have_##n = 0; \
382 : t n;
383 :
384 : #define UNFORMAT(t, n, s, r, ...) \
385 : if (unformat (line_input, s " " __VA_ARGS__, &n)) \
386 : { \
387 : something_parsed = 1; \
388 : have_##n = 1; \
389 : }
390 :
391 : #define CHECK_MANDATORY(t, n, s, r, ...) \
392 : WARN_OFF(tautological-compare) \
393 : if (mandatory == r && !have_##n) \
394 : { \
395 : WARN_ON(tautological-compare) \
396 : ret = clib_error_return (0, "Required parameter `%s' missing.", s); \
397 : goto out; \
398 : }
399 :
400 : static uword
401 60 : bfd_cli_unformat_ip46_address (unformat_input_t *input, va_list *args)
402 : {
403 60 : ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
404 60 : return unformat_user (input, unformat_ip46_address, ip46, IP46_TYPE_ANY);
405 : }
406 :
407 : static clib_error_t *
408 8 : bfd_cli_udp_session_add (vlib_main_t * vm, unformat_input_t * input,
409 : CLIB_UNUSED (vlib_cli_command_t * lmd))
410 : {
411 8 : clib_error_t *ret = NULL;
412 8 : unformat_input_t _line_input, *line_input = &_line_input;
413 : #define foreach_bfd_cli_udp_session_add_cli_param(F) \
414 : F (u32, sw_if_index, INTERFACE_STR, mandatory, "%U", \
415 : unformat_vnet_sw_interface, &vnet_main) \
416 : F (ip46_address_t, local_addr, LOCAL_ADDR_STR, mandatory, "%U", \
417 : bfd_cli_unformat_ip46_address) \
418 : F (ip46_address_t, peer_addr, PEER_ADDR_STR, mandatory, "%U", \
419 : bfd_cli_unformat_ip46_address) \
420 : F (u32, desired_min_tx, DESIRED_MIN_TX_STR, mandatory, "%u") \
421 : F (u32, required_min_rx, REQUIRED_MIN_RX_STR, mandatory, "%u") \
422 : F (u32, detect_mult, DETECT_MULT_STR, mandatory, "%u") \
423 : F (u32, conf_key_id, CONF_KEY_ID_STR, optional, "%u") \
424 : F (u32, bfd_key_id, BFD_KEY_ID_STR, optional, "%u")
425 :
426 8 : foreach_bfd_cli_udp_session_add_cli_param (DECLARE);
427 :
428 : /* Get a line of input. */
429 8 : if (!unformat_user (input, unformat_line_input, line_input))
430 0 : return 0;
431 :
432 16 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
433 : {
434 8 : int something_parsed = 0;
435 8 : foreach_bfd_cli_udp_session_add_cli_param (UNFORMAT);
436 :
437 8 : if (!something_parsed)
438 : {
439 0 : ret = clib_error_return (0, "Unknown input `%U'",
440 : format_unformat_error, line_input);
441 0 : goto out;
442 : }
443 : }
444 :
445 8 : foreach_bfd_cli_udp_session_add_cli_param (CHECK_MANDATORY);
446 :
447 8 : if (1 == have_conf_key_id + have_bfd_key_id)
448 : {
449 0 : ret = clib_error_return (0, "Incompatible parameter combination, `%s' "
450 : "and `%s' must be either both specified or none",
451 : CONF_KEY_ID_STR, BFD_KEY_ID_STR);
452 0 : goto out;
453 : }
454 :
455 8 : if (detect_mult > 255)
456 : {
457 0 : ret = clib_error_return (0, "%s value `%u' out of range <1,255>",
458 : DETECT_MULT_STR, detect_mult);
459 0 : goto out;
460 : }
461 :
462 8 : if (have_bfd_key_id && bfd_key_id > 255)
463 : {
464 0 : ret = clib_error_return (0, "%s value `%u' out of range <1,255>",
465 : BFD_KEY_ID_STR, bfd_key_id);
466 0 : goto out;
467 : }
468 :
469 : vnet_api_error_t rv =
470 8 : bfd_udp_add_session (sw_if_index, &local_addr, &peer_addr, desired_min_tx,
471 : required_min_rx,
472 : detect_mult, have_conf_key_id, conf_key_id,
473 : bfd_key_id);
474 8 : if (rv)
475 : {
476 : ret =
477 4 : clib_error_return (0,
478 : "`bfd_add_add_session' API call failed, rv=%d:%U",
479 : (int) rv, format_vnet_api_errno, rv);
480 4 : goto out;
481 : }
482 :
483 4 : out:
484 8 : return ret;
485 : }
486 :
487 : /* *INDENT-OFF* */
488 285289 : VLIB_CLI_COMMAND (bfd_cli_udp_session_add_command, static) = {
489 : .path = "bfd udp session add",
490 : .short_help = "bfd udp session add"
491 : " interface <interface>"
492 : " local-addr <local-address>"
493 : " peer-addr <peer-address>"
494 : " desired-min-tx <desired min tx interval>"
495 : " required-min-rx <required min rx interval>"
496 : " detect-mult <detect multiplier> "
497 : "["
498 : " conf-key-id <config key ID>"
499 : " bfd-key-id <BFD key ID>"
500 : "]",
501 : .function = bfd_cli_udp_session_add,
502 : };
503 : /* *INDENT-ON* */
504 :
505 : static clib_error_t *
506 4 : bfd_cli_udp_session_mod (vlib_main_t * vm, unformat_input_t * input,
507 : CLIB_UNUSED (vlib_cli_command_t * lmd))
508 : {
509 4 : clib_error_t *ret = NULL;
510 4 : unformat_input_t _line_input, *line_input = &_line_input;
511 : #define foreach_bfd_cli_udp_session_mod_cli_param(F) \
512 : F (u32, sw_if_index, INTERFACE_STR, mandatory, "%U", \
513 : unformat_vnet_sw_interface, &vnet_main) \
514 : F (ip46_address_t, local_addr, LOCAL_ADDR_STR, mandatory, "%U", \
515 : bfd_cli_unformat_ip46_address) \
516 : F (ip46_address_t, peer_addr, PEER_ADDR_STR, mandatory, "%U", \
517 : bfd_cli_unformat_ip46_address) \
518 : F (u32, desired_min_tx, DESIRED_MIN_TX_STR, mandatory, "%u") \
519 : F (u32, required_min_rx, REQUIRED_MIN_RX_STR, mandatory, "%u") \
520 : F (u32, detect_mult, DETECT_MULT_STR, mandatory, "%u")
521 :
522 4 : foreach_bfd_cli_udp_session_mod_cli_param (DECLARE);
523 :
524 : /* Get a line of input. */
525 4 : if (!unformat_user (input, unformat_line_input, line_input))
526 0 : return 0;
527 :
528 8 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
529 : {
530 4 : int something_parsed = 0;
531 4 : foreach_bfd_cli_udp_session_mod_cli_param (UNFORMAT);
532 :
533 4 : if (!something_parsed)
534 : {
535 0 : ret = clib_error_return (0, "Unknown input `%U'",
536 : format_unformat_error, line_input);
537 0 : goto out;
538 : }
539 : }
540 :
541 4 : foreach_bfd_cli_udp_session_mod_cli_param (CHECK_MANDATORY);
542 :
543 4 : if (detect_mult > 255)
544 : {
545 0 : ret = clib_error_return (0, "%s value `%u' out of range <1,255>",
546 : DETECT_MULT_STR, detect_mult);
547 0 : goto out;
548 : }
549 :
550 : vnet_api_error_t rv =
551 4 : bfd_udp_mod_session (sw_if_index, &local_addr, &peer_addr,
552 : desired_min_tx, required_min_rx, detect_mult);
553 4 : if (rv)
554 : {
555 : ret =
556 0 : clib_error_return (0,
557 : "`bfd_udp_mod_session' API call failed, rv=%d:%U",
558 : (int) rv, format_vnet_api_errno, rv);
559 0 : goto out;
560 : }
561 :
562 4 : out:
563 4 : return ret;
564 : }
565 :
566 : /* *INDENT-OFF* */
567 285289 : VLIB_CLI_COMMAND (bfd_cli_udp_session_mod_command, static) = {
568 : .path = "bfd udp session mod",
569 : .short_help = "bfd udp session mod interface"
570 : " <interface> local-addr"
571 : " <local-address> peer-addr"
572 : " <peer-address> desired-min-tx"
573 : " <desired min tx interval> required-min-rx"
574 : " <required min rx interval> detect-mult"
575 : " <detect multiplier> ",
576 : .function = bfd_cli_udp_session_mod,
577 : };
578 : /* *INDENT-ON* */
579 :
580 : static clib_error_t *
581 8 : bfd_cli_udp_session_del (vlib_main_t * vm, unformat_input_t * input,
582 : CLIB_UNUSED (vlib_cli_command_t * lmd))
583 : {
584 8 : clib_error_t *ret = NULL;
585 8 : unformat_input_t _line_input, *line_input = &_line_input;
586 : #define foreach_bfd_cli_udp_session_del_cli_param(F) \
587 : F (u32, sw_if_index, INTERFACE_STR, mandatory, "%U", \
588 : unformat_vnet_sw_interface, &vnet_main) \
589 : F (ip46_address_t, local_addr, LOCAL_ADDR_STR, mandatory, "%U", \
590 : bfd_cli_unformat_ip46_address) \
591 : F (ip46_address_t, peer_addr, PEER_ADDR_STR, mandatory, "%U", \
592 : bfd_cli_unformat_ip46_address)
593 :
594 8 : foreach_bfd_cli_udp_session_del_cli_param (DECLARE);
595 :
596 : /* Get a line of input. */
597 8 : if (!unformat_user (input, unformat_line_input, line_input))
598 0 : return 0;
599 :
600 16 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
601 : {
602 8 : int something_parsed = 0;
603 8 : foreach_bfd_cli_udp_session_del_cli_param (UNFORMAT);
604 :
605 8 : if (!something_parsed)
606 : {
607 0 : ret = clib_error_return (0, "Unknown input `%U'",
608 : format_unformat_error, line_input);
609 0 : goto out;
610 : }
611 : }
612 :
613 8 : foreach_bfd_cli_udp_session_del_cli_param (CHECK_MANDATORY);
614 :
615 : vnet_api_error_t rv =
616 8 : bfd_udp_del_session (sw_if_index, &local_addr, &peer_addr);
617 8 : if (rv)
618 : {
619 : ret =
620 4 : clib_error_return (0,
621 : "`bfd_udp_del_session' API call failed, rv=%d:%U",
622 : (int) rv, format_vnet_api_errno, rv);
623 4 : goto out;
624 : }
625 :
626 4 : out:
627 8 : return ret;
628 : }
629 :
630 : /* *INDENT-OFF* */
631 285289 : VLIB_CLI_COMMAND (bfd_cli_udp_session_del_command, static) = {
632 : .path = "bfd udp session del",
633 : .short_help = "bfd udp session del interface"
634 : " <interface> local-addr"
635 : " <local-address> peer-addr"
636 : "<peer-address> ",
637 : .function = bfd_cli_udp_session_del,
638 : };
639 : /* *INDENT-ON* */
640 :
641 : static clib_error_t *
642 2 : bfd_cli_udp_session_set_flags (vlib_main_t * vm, unformat_input_t * input,
643 : CLIB_UNUSED (vlib_cli_command_t * lmd))
644 : {
645 2 : clib_error_t *ret = NULL;
646 2 : unformat_input_t _line_input, *line_input = &_line_input;
647 : #define foreach_bfd_cli_udp_session_set_flags_cli_param(F) \
648 : F (u32, sw_if_index, INTERFACE_STR, mandatory, "%U", \
649 : unformat_vnet_sw_interface, &vnet_main) \
650 : F (ip46_address_t, local_addr, LOCAL_ADDR_STR, mandatory, "%U", \
651 : bfd_cli_unformat_ip46_address) \
652 : F (ip46_address_t, peer_addr, PEER_ADDR_STR, mandatory, "%U", \
653 : bfd_cli_unformat_ip46_address) \
654 : F (u8 *, admin_up_down_token, ADMIN_STR, mandatory, "%v", \
655 : &admin_up_down_token)
656 :
657 2 : foreach_bfd_cli_udp_session_set_flags_cli_param (DECLARE);
658 :
659 : /* Get a line of input. */
660 2 : if (!unformat_user (input, unformat_line_input, line_input))
661 0 : return 0;
662 :
663 6 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
664 : {
665 4 : int something_parsed = 0;
666 4 : foreach_bfd_cli_udp_session_set_flags_cli_param (UNFORMAT);
667 :
668 4 : if (!something_parsed)
669 : {
670 0 : ret = clib_error_return (0, "Unknown input `%U'",
671 : format_unformat_error, line_input);
672 0 : goto out;
673 : }
674 : }
675 :
676 2 : foreach_bfd_cli_udp_session_set_flags_cli_param (CHECK_MANDATORY);
677 :
678 : u8 admin_up_down;
679 : static const char up[] = "up";
680 : static const char down[] = "down";
681 2 : if (!memcmp (admin_up_down_token, up, sizeof (up) - 1))
682 : {
683 1 : admin_up_down = 1;
684 : }
685 1 : else if (!memcmp (admin_up_down_token, down, sizeof (down) - 1))
686 : {
687 1 : admin_up_down = 0;
688 : }
689 : else
690 : {
691 : ret =
692 0 : clib_error_return (0, "Unrecognized value for `%s' parameter: `%v'",
693 : ADMIN_STR, admin_up_down_token);
694 0 : goto out;
695 : }
696 : vnet_api_error_t rv =
697 2 : bfd_udp_session_set_flags (vm, sw_if_index, &local_addr,
698 : &peer_addr, admin_up_down);
699 2 : if (rv)
700 : {
701 : ret =
702 0 : clib_error_return (0,
703 : "`bfd_udp_session_set_flags' API call failed, rv=%d:%U",
704 : (int) rv, format_vnet_api_errno, rv);
705 0 : goto out;
706 : }
707 :
708 2 : out:
709 2 : return ret;
710 : }
711 :
712 : /* *INDENT-OFF* */
713 285289 : VLIB_CLI_COMMAND (bfd_cli_udp_session_set_flags_command, static) = {
714 : .path = "bfd udp session set-flags",
715 : .short_help = "bfd udp session set-flags"
716 : " interface <interface>"
717 : " local-addr <local-address>"
718 : " peer-addr <peer-address>"
719 : " admin <up|down>",
720 : .function = bfd_cli_udp_session_set_flags,
721 : };
722 : /* *INDENT-ON* */
723 :
724 : static clib_error_t *
725 4 : bfd_cli_udp_session_auth_activate (vlib_main_t * vm,
726 : unformat_input_t * input,
727 : CLIB_UNUSED (vlib_cli_command_t * lmd))
728 : {
729 4 : clib_error_t *ret = NULL;
730 4 : unformat_input_t _line_input, *line_input = &_line_input;
731 : #define foreach_bfd_cli_udp_session_auth_activate_cli_param(F) \
732 : F (u32, sw_if_index, INTERFACE_STR, mandatory, "%U", \
733 : unformat_vnet_sw_interface, &vnet_main) \
734 : F (ip46_address_t, local_addr, LOCAL_ADDR_STR, mandatory, "%U", \
735 : bfd_cli_unformat_ip46_address) \
736 : F (ip46_address_t, peer_addr, PEER_ADDR_STR, mandatory, "%U", \
737 : bfd_cli_unformat_ip46_address) \
738 : F (u8 *, delayed_token, DELAYED_STR, optional, "%v") \
739 : F (u32, conf_key_id, CONF_KEY_ID_STR, mandatory, "%u") \
740 : F (u32, bfd_key_id, BFD_KEY_ID_STR, mandatory, "%u")
741 :
742 4 : foreach_bfd_cli_udp_session_auth_activate_cli_param (DECLARE);
743 :
744 : /* Get a line of input. */
745 4 : if (!unformat_user (input, unformat_line_input, line_input))
746 0 : return 0;
747 :
748 10 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
749 : {
750 6 : int something_parsed = 0;
751 6 : foreach_bfd_cli_udp_session_auth_activate_cli_param (UNFORMAT);
752 :
753 6 : if (!something_parsed)
754 : {
755 0 : ret = clib_error_return (0, "Unknown input `%U'",
756 : format_unformat_error, line_input);
757 0 : goto out;
758 : }
759 : }
760 :
761 4 : foreach_bfd_cli_udp_session_auth_activate_cli_param (CHECK_MANDATORY);
762 :
763 4 : u8 is_delayed = 0;
764 4 : if (have_delayed_token)
765 : {
766 : static const char yes[] = "yes";
767 : static const char no[] = "no";
768 2 : if (!memcmp (delayed_token, yes, sizeof (yes) - 1))
769 : {
770 2 : is_delayed = 1;
771 : }
772 0 : else if (!memcmp (delayed_token, no, sizeof (no) - 1))
773 : {
774 0 : is_delayed = 0;
775 : }
776 : else
777 : {
778 : ret =
779 0 : clib_error_return (0,
780 : "Unrecognized value for `%s' parameter: `%v'",
781 : DELAYED_STR, delayed_token);
782 0 : goto out;
783 : }
784 : }
785 :
786 4 : if (have_bfd_key_id && bfd_key_id > 255)
787 : {
788 0 : ret = clib_error_return (0, "%s value `%u' out of range <1,255>",
789 : BFD_KEY_ID_STR, bfd_key_id);
790 0 : goto out;
791 : }
792 :
793 : vnet_api_error_t rv =
794 4 : bfd_udp_auth_activate (sw_if_index, &local_addr, &peer_addr, conf_key_id,
795 : bfd_key_id, is_delayed);
796 4 : if (rv)
797 : {
798 : ret =
799 0 : clib_error_return (0,
800 : "`bfd_udp_auth_activate' API call failed, rv=%d:%U",
801 : (int) rv, format_vnet_api_errno, rv);
802 0 : goto out;
803 : }
804 :
805 4 : out:
806 4 : return ret;
807 : }
808 :
809 : /* *INDENT-OFF* */
810 285289 : VLIB_CLI_COMMAND (bfd_cli_udp_session_auth_activate_command, static) = {
811 : .path = "bfd udp session auth activate",
812 : .short_help = "bfd udp session auth activate"
813 : " interface <interface>"
814 : " local-addr <local-address>"
815 : " peer-addr <peer-address>"
816 : " conf-key-id <config key ID>"
817 : " bfd-key-id <BFD key ID>"
818 : " [ delayed <yes|no> ]",
819 : .function = bfd_cli_udp_session_auth_activate,
820 : };
821 :
822 : static clib_error_t *
823 4 : bfd_cli_udp_session_auth_deactivate (vlib_main_t *vm, unformat_input_t *input,
824 : CLIB_UNUSED (vlib_cli_command_t *lmd))
825 : {
826 4 : clib_error_t *ret = NULL;
827 4 : unformat_input_t _line_input, *line_input = &_line_input;
828 : #define foreach_bfd_cli_udp_session_auth_deactivate_cli_param(F) \
829 : F (u32, sw_if_index, INTERFACE_STR, mandatory, "%U", \
830 : unformat_vnet_sw_interface, &vnet_main) \
831 : F (ip46_address_t, local_addr, LOCAL_ADDR_STR, mandatory, "%U", \
832 : bfd_cli_unformat_ip46_address) \
833 : F (ip46_address_t, peer_addr, PEER_ADDR_STR, mandatory, "%U", \
834 : bfd_cli_unformat_ip46_address) \
835 : F (u8 *, delayed_token, DELAYED_STR, optional, "%v")
836 :
837 4 : foreach_bfd_cli_udp_session_auth_deactivate_cli_param (DECLARE);
838 :
839 : /* Get a line of input. */
840 4 : if (!unformat_user (input, unformat_line_input, line_input))
841 0 : return 0;
842 :
843 8 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
844 : {
845 4 : int something_parsed = 0;
846 4 : foreach_bfd_cli_udp_session_auth_deactivate_cli_param (UNFORMAT);
847 :
848 4 : if (!something_parsed)
849 : {
850 0 : ret = clib_error_return (0, "Unknown input `%U'",
851 : format_unformat_error, input);
852 0 : goto out;
853 : }
854 : }
855 :
856 4 : foreach_bfd_cli_udp_session_auth_deactivate_cli_param (CHECK_MANDATORY);
857 :
858 4 : u8 is_delayed = 0;
859 4 : if (have_delayed_token)
860 : {
861 : static const char yes[] = "yes";
862 : static const char no[] = "no";
863 2 : if (!memcmp (delayed_token, yes, sizeof (yes) - 1))
864 : {
865 2 : is_delayed = 1;
866 : }
867 0 : else if (!memcmp (delayed_token, no, sizeof (no) - 1))
868 : {
869 0 : is_delayed = 0;
870 : }
871 : else
872 : {
873 0 : ret = clib_error_return (
874 : 0, "Unrecognized value for `%s' parameter: `%v'", DELAYED_STR,
875 : delayed_token);
876 0 : goto out;
877 : }
878 : }
879 :
880 4 : vnet_api_error_t rv = bfd_udp_auth_deactivate (sw_if_index, &local_addr,
881 : &peer_addr, is_delayed);
882 4 : if (rv)
883 : {
884 0 : ret = clib_error_return (
885 : 0, "`bfd_udp_auth_deactivate' API call failed, rv=%d:%U", (int)rv,
886 : format_vnet_api_errno, rv);
887 0 : goto out;
888 : }
889 :
890 4 : out:
891 4 : return ret;
892 : }
893 :
894 : /* *INDENT-OFF* */
895 285289 : VLIB_CLI_COMMAND (bfd_cli_udp_session_auth_deactivate_command, static) = {
896 : .path = "bfd udp session auth deactivate",
897 : .short_help = "bfd udp session auth deactivate"
898 : " interface <interface>"
899 : " local-addr <local-address>"
900 : " peer-addr <peer-address>"
901 : "[ delayed <yes|no> ]",
902 : .function = bfd_cli_udp_session_auth_deactivate,
903 : };
904 : /* *INDENT-ON* */
905 :
906 : static clib_error_t *
907 1 : bfd_cli_udp_set_echo_source (vlib_main_t * vm, unformat_input_t * input,
908 : CLIB_UNUSED (vlib_cli_command_t * lmd))
909 : {
910 1 : clib_error_t *ret = NULL;
911 1 : unformat_input_t _line_input, *line_input = &_line_input;
912 : #define foreach_bfd_cli_udp_set_echo_source_cli_param(F) \
913 : F (u32, sw_if_index, INTERFACE_STR, mandatory, "%U", \
914 : unformat_vnet_sw_interface, &vnet_main)
915 :
916 1 : foreach_bfd_cli_udp_set_echo_source_cli_param (DECLARE);
917 :
918 : /* Get a line of input. */
919 1 : if (!unformat_user (input, unformat_line_input, line_input))
920 0 : return 0;
921 :
922 2 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
923 : {
924 1 : int something_parsed = 0;
925 1 : foreach_bfd_cli_udp_set_echo_source_cli_param (UNFORMAT);
926 :
927 1 : if (!something_parsed)
928 : {
929 0 : ret = clib_error_return (0, "Unknown input `%U'",
930 : format_unformat_error, line_input);
931 0 : goto out;
932 : }
933 : }
934 :
935 1 : foreach_bfd_cli_udp_set_echo_source_cli_param (CHECK_MANDATORY);
936 :
937 1 : vnet_api_error_t rv = bfd_udp_set_echo_source (sw_if_index);
938 1 : if (rv)
939 : {
940 : ret =
941 0 : clib_error_return (0,
942 : "`bfd_udp_set_echo_source' API call failed, rv=%d:%U",
943 : (int) rv, format_vnet_api_errno, rv);
944 0 : goto out;
945 : }
946 :
947 1 : out:
948 1 : return ret;
949 : }
950 :
951 : /* *INDENT-OFF* */
952 285289 : VLIB_CLI_COMMAND (bfd_cli_udp_set_echo_source_cmd, static) = {
953 : .path = "bfd udp echo-source set",
954 : .short_help = "bfd udp echo-source set interface <interface>",
955 : .function = bfd_cli_udp_set_echo_source,
956 : };
957 : /* *INDENT-ON* */
958 :
959 : static clib_error_t *
960 1 : bfd_cli_udp_del_echo_source (vlib_main_t * vm, unformat_input_t * input,
961 : CLIB_UNUSED (vlib_cli_command_t * lmd))
962 : {
963 1 : vnet_api_error_t rv = bfd_udp_del_echo_source ();
964 1 : if (rv)
965 : {
966 0 : return clib_error_return (0,
967 : "`bfd_udp_del_echo_source' API call failed, rv=%d:%U",
968 : (int) rv, format_vnet_api_errno, rv);
969 : }
970 :
971 1 : return 0;
972 : }
973 :
974 : /* *INDENT-OFF* */
975 285289 : VLIB_CLI_COMMAND (bfd_cli_udp_del_echo_source_cmd, static) = {
976 : .path = "bfd udp echo-source del",
977 : .short_help = "bfd udp echo-source del",
978 : .function = bfd_cli_udp_del_echo_source,
979 : };
980 : /* *INDENT-ON* */
981 :
982 : /*
983 : * fd.io coding-style-patch-verification: ON
984 : *
985 : * Local Variables:
986 : * eval: (c-set-style "gnu")
987 : * End:
988 : */
|