FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
ipsec_cli.c
Go to the documentation of this file.
1 /*
2  * decap.c : IPSec tunnel support
3  *
4  * Copyright (c) 2015 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vnet/vnet.h>
19 #include <vnet/api_errno.h>
20 #include <vnet/ip/ip.h>
21 #include <vnet/interface.h>
22 #include <vnet/fib/fib.h>
23 #include <vnet/ipip/ipip.h>
24 
25 #include <vnet/ipsec/ipsec.h>
26 #include <vnet/ipsec/ipsec_tun.h>
27 
28 static clib_error_t *
30  unformat_input_t * input,
31  vlib_cli_command_t * cmd)
32 {
33  unformat_input_t _line_input, *line_input = &_line_input;
34  ipsec_main_t *im = &ipsec_main;
35  u32 sw_if_index = (u32) ~ 0;
36  u32 spd_id;
37  int is_add = 1;
38  clib_error_t *error = NULL;
39  int err;
40 
41  if (!unformat_user (input, unformat_line_input, line_input))
42  return 0;
43 
44  if (unformat
45  (line_input, "%U %u", unformat_vnet_sw_interface, im->vnet_main,
46  &sw_if_index, &spd_id))
47  ;
48  else if (unformat (line_input, "del"))
49  is_add = 0;
50  else
51  {
52  error = clib_error_return (0, "parse error: '%U'",
53  format_unformat_error, line_input);
54  goto done;
55  }
56 
57  err = ipsec_set_interface_spd (vm, sw_if_index, spd_id, is_add);
58  switch (err)
59  {
60  case VNET_API_ERROR_SYSCALL_ERROR_1:
61  error = clib_error_return (0, "no such spd-id");
62  break;
63  case VNET_API_ERROR_SYSCALL_ERROR_2:
64  error = clib_error_return (0, "spd already assigned");
65  break;
66  }
67 
68 done:
69  unformat_free (line_input);
70 
71  return error;
72 }
73 
74 /* *INDENT-OFF* */
75 VLIB_CLI_COMMAND (set_interface_spd_command, static) = {
76  .path = "set interface ipsec spd",
77  .short_help =
78  "set interface ipsec spd <int> <id>",
79  .function = set_interface_spd_command_fn,
80 };
81 /* *INDENT-ON* */
82 
83 static clib_error_t *
85  unformat_input_t * input,
86  vlib_cli_command_t * cmd)
87 {
88  unformat_input_t _line_input, *line_input = &_line_input;
89  ip46_address_t tun_src = { }, tun_dst =
90  {
91  };
92  ipsec_crypto_alg_t crypto_alg;
96  clib_error_t *error;
97  ipsec_key_t ck = { 0 };
98  ipsec_key_t ik = { 0 };
99  u32 id, spi, salt, sai;
100  u16 udp_src, udp_dst;
101  int is_add, rv;
102  u32 m_args = 0;
104 
105  salt = 0;
106  error = NULL;
107  is_add = 0;
108  flags = IPSEC_SA_FLAG_NONE;
109  proto = IPSEC_PROTOCOL_ESP;
110  integ_alg = IPSEC_INTEG_ALG_NONE;
111  crypto_alg = IPSEC_CRYPTO_ALG_NONE;
112  udp_src = udp_dst = IPSEC_UDP_PORT_NONE;
113  tx_table_id = 0;
114 
115  if (!unformat_user (input, unformat_line_input, line_input))
116  return 0;
117 
118  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
119  {
120  if (unformat (line_input, "add %u", &id))
121  {
122  is_add = 1;
123  m_args |= 1 << 0;
124  }
125  else if (unformat (line_input, "del %u", &id))
126  {
127  is_add = 0;
128  m_args |= 1 << 0;
129  }
130  else if (unformat (line_input, "spi %u", &spi))
131  m_args |= 1 << 1;
132  else if (unformat (line_input, "salt 0x%x", &salt))
133  ;
134  else if (unformat (line_input, "esp"))
135  proto = IPSEC_PROTOCOL_ESP;
136  else if (unformat (line_input, "ah"))
137  proto = IPSEC_PROTOCOL_AH;
138  else if (unformat (line_input, "crypto-key %U",
139  unformat_ipsec_key, &ck))
140  ;
141  else if (unformat (line_input, "crypto-alg %U",
142  unformat_ipsec_crypto_alg, &crypto_alg))
143  ;
144  else if (unformat (line_input, "integ-key %U", unformat_ipsec_key, &ik))
145  ;
146  else if (unformat (line_input, "integ-alg %U",
147  unformat_ipsec_integ_alg, &integ_alg))
148  ;
149  else if (unformat (line_input, "tunnel-src %U",
151  {
152  flags |= IPSEC_SA_FLAG_IS_TUNNEL;
153  if (!ip46_address_is_ip4 (&tun_src))
154  flags |= IPSEC_SA_FLAG_IS_TUNNEL_V6;
155  }
156  else if (unformat (line_input, "tunnel-dst %U",
158  ;
159  else if (unformat (line_input, "tx-table-id %d", &tx_table_id))
160  ;
161  else if (unformat (line_input, "inbound"))
162  flags |= IPSEC_SA_FLAG_IS_INBOUND;
163  else if (unformat (line_input, "use-anti-replay"))
164  flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;
165  else if (unformat (line_input, "use-esn"))
166  flags |= IPSEC_SA_FLAG_USE_ESN;
167  else if (unformat (line_input, "udp-encap"))
168  flags |= IPSEC_SA_FLAG_UDP_ENCAP;
169  else
170  {
171  error = clib_error_return (0, "parse error: '%U'",
172  format_unformat_error, line_input);
173  goto done;
174  }
175  }
176  if ((flags & IPSEC_SA_FLAG_IS_INBOUND)
177  && !(flags & IPSEC_SA_FLAG_IS_TUNNEL))
178  {
179  error = clib_error_return (0, "inbound specified on non-tunnel SA");
180  goto done;
181  }
182 
183  if (!(m_args & 1))
184  {
185  error = clib_error_return (0, "missing id");
186  goto done;
187  }
188 
189  if (is_add)
190  {
191  if (!(m_args & 2))
192  {
193  error = clib_error_return (0, "missing spi");
194  goto done;
195  }
196  rv = ipsec_sa_add_and_lock (id, spi, proto, crypto_alg,
197  &ck, integ_alg, &ik, flags,
198  tx_table_id, clib_host_to_net_u32 (salt),
199  &tun_src, &tun_dst, &sai, udp_src, udp_dst);
200  }
201  else
202  {
203  rv = ipsec_sa_unlock_id (id);
204  }
205 
206  if (rv)
207  error = clib_error_return (0, "failed");
208 
209 done:
210  unformat_free (line_input);
211 
212  return error;
213 }
214 
215 /* *INDENT-OFF* */
216 VLIB_CLI_COMMAND (ipsec_sa_add_del_command, static) = {
217  .path = "ipsec sa",
218  .short_help =
219  "ipsec sa [add|del]",
220  .function = ipsec_sa_add_del_command_fn,
221 };
222 /* *INDENT-ON* */
223 
224 static clib_error_t *
226  unformat_input_t * input,
227  vlib_cli_command_t * cmd)
228 {
229  unformat_input_t _line_input, *line_input = &_line_input;
230  u32 spd_id = ~0;
231  int is_add = ~0;
232  clib_error_t *error = NULL;
233 
234  if (!unformat_user (input, unformat_line_input, line_input))
235  return 0;
236 
237  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
238  {
239  if (unformat (line_input, "add"))
240  is_add = 1;
241  else if (unformat (line_input, "del"))
242  is_add = 0;
243  else if (unformat (line_input, "%u", &spd_id))
244  ;
245  else
246  {
247  error = clib_error_return (0, "parse error: '%U'",
248  format_unformat_error, line_input);
249  goto done;
250  }
251  }
252 
253  if (spd_id == ~0)
254  {
255  error = clib_error_return (0, "please specify SPD ID");
256  goto done;
257  }
258 
259  ipsec_add_del_spd (vm, spd_id, is_add);
260 
261 done:
262  unformat_free (line_input);
263 
264  return error;
265 }
266 
267 /* *INDENT-OFF* */
268 VLIB_CLI_COMMAND (ipsec_spd_add_del_command, static) = {
269  .path = "ipsec spd",
270  .short_help =
271  "ipsec spd [add|del] <id>",
272  .function = ipsec_spd_add_del_command_fn,
273 };
274 /* *INDENT-ON* */
275 
276 
277 static clib_error_t *
279  unformat_input_t * input,
280  vlib_cli_command_t * cmd)
281 {
282  unformat_input_t _line_input, *line_input = &_line_input;
283  ipsec_policy_t p;
284  int rv, is_add = 0;
285  u32 tmp, tmp2, stat_index, local_range_set, remote_range_set;
286  clib_error_t *error = NULL;
288 
289  clib_memset (&p, 0, sizeof (p));
290  p.lport.stop = p.rport.stop = ~0;
291  remote_range_set = local_range_set = is_outbound = 0;
292 
293  if (!unformat_user (input, unformat_line_input, line_input))
294  return 0;
295 
296  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
297  {
298  if (unformat (line_input, "add"))
299  is_add = 1;
300  else if (unformat (line_input, "del"))
301  is_add = 0;
302  else if (unformat (line_input, "ip6"))
303  p.is_ipv6 = 1;
304  else if (unformat (line_input, "spd %u", &p.id))
305  ;
306  else if (unformat (line_input, "inbound"))
307  is_outbound = 0;
308  else if (unformat (line_input, "outbound"))
309  is_outbound = 1;
310  else if (unformat (line_input, "priority %d", &p.priority))
311  ;
312  else if (unformat (line_input, "protocol %u", &tmp))
313  p.protocol = (u8) tmp;
314  else
315  if (unformat
316  (line_input, "action %U", unformat_ipsec_policy_action,
317  &p.policy))
318  {
319  if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
320  {
321  error = clib_error_return (0, "unsupported action: 'resolve'");
322  goto done;
323  }
324  }
325  else if (unformat (line_input, "sa %u", &p.sa_id))
326  ;
327  else if (unformat (line_input, "local-ip-range %U - %U",
330  local_range_set = 1;
331  else if (unformat (line_input, "remote-ip-range %U - %U",
334  remote_range_set = 1;
335  else if (unformat (line_input, "local-ip-range %U - %U",
338  {
339  p.is_ipv6 = 1;
340  local_range_set = 1;
341  }
342  else if (unformat (line_input, "remote-ip-range %U - %U",
345  {
346  p.is_ipv6 = 1;
347  remote_range_set = 1;
348  }
349  else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2))
350  {
351  p.lport.start = tmp;
352  p.lport.stop = tmp2;
353  }
354  else
355  if (unformat (line_input, "remote-port-range %u - %u", &tmp, &tmp2))
356  {
357  p.rport.start = tmp;
358  p.rport.stop = tmp2;
359  }
360  else
361  {
362  error = clib_error_return (0, "parse error: '%U'",
363  format_unformat_error, line_input);
364  goto done;
365  }
366  }
367 
368  if (!remote_range_set)
369  {
370  if (p.is_ipv6)
371  clib_memset (&p.raddr.stop.ip6, 0xff, 16);
372  else
373  clib_memset (&p.raddr.stop.ip4, 0xff, 4);
374  }
375  if (!local_range_set)
376  {
377  if (p.is_ipv6)
378  clib_memset (&p.laddr.stop.ip6, 0xff, 16);
379  else
380  clib_memset (&p.laddr.stop.ip4, 0xff, 4);
381  }
382 
383  rv = ipsec_policy_mk_type (is_outbound, p.is_ipv6, p.policy, &p.type);
384 
385  if (rv)
386  {
387  error = clib_error_return (0, "unsupported policy type for:",
388  " outboud:%s %s action:%U",
389  (is_outbound ? "yes" : "no"),
390  (p.is_ipv6 ? "IPv4" : "IPv6"),
392  goto done;
393  }
394 
395  rv = ipsec_add_del_policy (vm, &p, is_add, &stat_index);
396 
397  if (!rv)
398  vlib_cli_output (vm, "policy-index:%d", stat_index);
399  else
400  vlib_cli_output (vm, "error:%d", rv);
401 
402 done:
403  unformat_free (line_input);
404 
405  return error;
406 }
407 
408 /* *INDENT-OFF* */
409 VLIB_CLI_COMMAND (ipsec_policy_add_del_command, static) = {
410  .path = "ipsec policy",
411  .short_help =
412  "ipsec policy [add|del] spd <id> priority <n> ",
414 };
415 /* *INDENT-ON* */
416 
417 static void
419 {
420  u32 sai;
421 
422  /* *INDENT-OFF* */
423  pool_foreach_index (sai, im->sad, ({
424  vlib_cli_output(vm, "%U", format_ipsec_sa, sai,
425  (detail ? IPSEC_FORMAT_DETAIL : IPSEC_FORMAT_BRIEF));
426  }));
427  /* *INDENT-ON* */
428 }
429 
430 static void
432 {
433  u32 spdi;
434 
435  /* *INDENT-OFF* */
436  pool_foreach_index (spdi, im->spds, ({
437  vlib_cli_output(vm, "%U", format_ipsec_spd, spdi);
438  }));
439  /* *INDENT-ON* */
440 }
441 
442 static void
444 {
445  u32 spd_id, sw_if_index;
446  ipsec_spd_t *spd;
447 
448  vlib_cli_output (vm, "SPD Bindings:");
449 
450  /* *INDENT-OFF* */
451  hash_foreach(sw_if_index, spd_id, im->spd_index_by_sw_if_index, ({
452  spd = pool_elt_at_index (im->spds, spd_id);
453  vlib_cli_output (vm, " %d -> %U", spd->id,
454  format_vnet_sw_if_index_name, im->vnet_main,
455  sw_if_index);
456  }));
457  /* *INDENT-ON* */
458 }
459 
460 static walk_rc_t
462 {
464 
465  return (WALK_CONTINUE);
466 }
467 
468 static void
470 {
472 }
473 
474 static clib_error_t *
476  unformat_input_t * input, vlib_cli_command_t * cmd)
477 {
478  ipsec_main_t *im = &ipsec_main;
479 
480  ipsec_sa_show_all (vm, im, 0);
481  ipsec_spd_show_all (vm, im);
484 
485  vlib_cli_output (vm, "IPSec async mode: %s",
486  (im->async_mode ? "on" : "off"));
487 
488  return 0;
489 }
490 
491 /* *INDENT-OFF* */
492 VLIB_CLI_COMMAND (show_ipsec_command, static) = {
493  .path = "show ipsec all",
494  .short_help = "show ipsec all",
495  .function = show_ipsec_command_fn,
496 };
497 /* *INDENT-ON* */
498 
499 static clib_error_t *
501  unformat_input_t * input, vlib_cli_command_t * cmd)
502 {
503  ipsec_main_t *im = &ipsec_main;
504  u32 sai = ~0;
505  u8 detail = 0;
506 
508  {
509  if (unformat (input, "%u", &sai))
510  ;
511  if (unformat (input, "detail"))
512  detail = 1;
513  else
514  break;
515  }
516 
517  if (~0 == sai)
518  ipsec_sa_show_all (vm, im, detail);
519  else
520  vlib_cli_output (vm, "%U", format_ipsec_sa, sai,
522 
523  return 0;
524 }
525 
526 static clib_error_t *
528  unformat_input_t * input, vlib_cli_command_t * cmd)
529 {
530  ipsec_main_t *im = &ipsec_main;
531  u32 sai = ~0;
532 
534  {
535  if (unformat (input, "%u", &sai))
536  ;
537  else
538  break;
539  }
540 
541  if (~0 == sai)
542  {
543  /* *INDENT-OFF* */
544  pool_foreach_index (sai, im->sad, ({
545  ipsec_sa_clear(sai);
546  }));
547  /* *INDENT-ON* */
548  }
549  else
550  {
551  if (pool_is_free_index (im->sad, sai))
552  return clib_error_return (0, "unknown SA index: %d", sai);
553  else
554  ipsec_sa_clear (sai);
555  }
556 
557  return 0;
558 }
559 
560 /* *INDENT-OFF* */
561 VLIB_CLI_COMMAND (show_ipsec_sa_command, static) = {
562  .path = "show ipsec sa",
563  .short_help = "show ipsec sa [index]",
564  .function = show_ipsec_sa_command_fn,
565 };
566 
567 VLIB_CLI_COMMAND (clear_ipsec_sa_command, static) = {
568  .path = "clear ipsec sa",
569  .short_help = "clear ipsec sa [index]",
570  .function = clear_ipsec_sa_command_fn,
571 };
572 /* *INDENT-ON* */
573 
574 static clib_error_t *
576  unformat_input_t * input, vlib_cli_command_t * cmd)
577 {
578  ipsec_main_t *im = &ipsec_main;
579  u8 show_bindings = 0;
580  u32 spdi = ~0;
581 
583  {
584  if (unformat (input, "%u", &spdi))
585  ;
586  else if (unformat (input, "bindings"))
587  show_bindings = 1;
588  else
589  break;
590  }
591 
592  if (show_bindings)
594  else if (~0 != spdi)
595  vlib_cli_output (vm, "%U", format_ipsec_spd, spdi);
596  else
597  ipsec_spd_show_all (vm, im);
598 
599  return 0;
600 }
601 
602 /* *INDENT-OFF* */
603 VLIB_CLI_COMMAND (show_ipsec_spd_command, static) = {
604  .path = "show ipsec spd",
605  .short_help = "show ipsec spd [index]",
606  .function = show_ipsec_spd_command_fn,
607 };
608 /* *INDENT-ON* */
609 
610 static clib_error_t *
612  unformat_input_t * input,
613  vlib_cli_command_t * cmd)
614 {
616 
617  return 0;
618 }
619 
620 /* *INDENT-OFF* */
621 VLIB_CLI_COMMAND (show_ipsec_tunnel_command, static) = {
622  .path = "show ipsec tunnel",
623  .short_help = "show ipsec tunnel",
624  .function = show_ipsec_tunnel_command_fn,
625 };
626 /* *INDENT-ON* */
627 
628 static clib_error_t *
630  unformat_input_t * input,
631  vlib_cli_command_t * cmd)
632 {
633  ipsec_main_t *im = &ipsec_main;
634  u32 verbose = 0;
635 
636  (void) unformat (input, "verbose %u", &verbose);
637 
638  vlib_cli_output (vm, "IPsec AH backends available:");
639  u8 *s = format (NULL, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
640  ipsec_ah_backend_t *ab;
641  /* *INDENT-OFF* */
642  pool_foreach (ab, im->ah_backends, {
643  s = format (s, "%=25s %=25u %=10s\n", ab->name, ab - im->ah_backends,
644  ab - im->ah_backends == im->ah_current_backend ? "yes" : "no");
645  if (verbose) {
646  vlib_node_t *n;
647  n = vlib_get_node (vm, ab->ah4_encrypt_node_index);
648  s = format (s, " enc4 %s (next %d)\n", n->name, ab->ah4_encrypt_next_index);
649  n = vlib_get_node (vm, ab->ah4_decrypt_node_index);
650  s = format (s, " dec4 %s (next %d)\n", n->name, ab->ah4_decrypt_next_index);
651  n = vlib_get_node (vm, ab->ah6_encrypt_node_index);
652  s = format (s, " enc6 %s (next %d)\n", n->name, ab->ah6_encrypt_next_index);
653  n = vlib_get_node (vm, ab->ah6_decrypt_node_index);
654  s = format (s, " dec6 %s (next %d)\n", n->name, ab->ah6_decrypt_next_index);
655  }
656  });
657  /* *INDENT-ON* */
658  vlib_cli_output (vm, "%v", s);
659  _vec_len (s) = 0;
660  vlib_cli_output (vm, "IPsec ESP backends available:");
661  s = format (s, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
663  /* *INDENT-OFF* */
664  pool_foreach (eb, im->esp_backends, {
665  s = format (s, "%=25s %=25u %=10s\n", eb->name, eb - im->esp_backends,
666  eb - im->esp_backends == im->esp_current_backend ? "yes"
667  : "no");
668  if (verbose) {
669  vlib_node_t *n;
670  n = vlib_get_node (vm, eb->esp4_encrypt_node_index);
671  s = format (s, " enc4 %s (next %d)\n", n->name, eb->esp4_encrypt_next_index);
672  n = vlib_get_node (vm, eb->esp4_decrypt_node_index);
673  s = format (s, " dec4 %s (next %d)\n", n->name, eb->esp4_decrypt_next_index);
674  n = vlib_get_node (vm, eb->esp6_encrypt_node_index);
675  s = format (s, " enc6 %s (next %d)\n", n->name, eb->esp6_encrypt_next_index);
676  n = vlib_get_node (vm, eb->esp6_decrypt_node_index);
677  s = format (s, " dec6 %s (next %d)\n", n->name, eb->esp6_decrypt_next_index);
678  }
679  });
680  /* *INDENT-ON* */
681  vlib_cli_output (vm, "%v", s);
682 
683  vec_free (s);
684  return 0;
685 }
686 
687 /* *INDENT-OFF* */
688 VLIB_CLI_COMMAND (ipsec_show_backends_command, static) = {
689  .path = "show ipsec backends",
690  .short_help = "show ipsec backends",
691  .function = ipsec_show_backends_command_fn,
692 };
693 /* *INDENT-ON* */
694 
695 static clib_error_t *
697  unformat_input_t * input,
698  vlib_cli_command_t * cmd)
699 {
700  unformat_input_t _line_input, *line_input = &_line_input;
701  ipsec_main_t *im = &ipsec_main;
702  clib_error_t *error;
703  u32 backend_index;
704 
705  error = ipsec_rsc_in_use (im);
706 
707  if (error)
708  return error;
709 
710  /* Get a line of input. */
711  if (!unformat_user (input, unformat_line_input, line_input))
712  return 0;
713 
714  if (unformat (line_input, "ah"))
715  {
716  if (unformat (line_input, "%u", &backend_index))
717  {
718  if (ipsec_select_ah_backend (im, backend_index) < 0)
719  {
720  return clib_error_return (0, "Invalid AH backend index `%u'",
721  backend_index);
722  }
723  }
724  else
725  {
726  return clib_error_return (0, "Invalid backend index `%U'",
727  format_unformat_error, line_input);
728  }
729  }
730  else if (unformat (line_input, "esp"))
731  {
732  if (unformat (line_input, "%u", &backend_index))
733  {
734  if (ipsec_select_esp_backend (im, backend_index) < 0)
735  {
736  return clib_error_return (0, "Invalid ESP backend index `%u'",
737  backend_index);
738  }
739  }
740  else
741  {
742  return clib_error_return (0, "Invalid backend index `%U'",
743  format_unformat_error, line_input);
744  }
745  }
746  else
747  {
748  return clib_error_return (0, "Unknown input `%U'",
749  format_unformat_error, line_input);
750  }
751 
752  return 0;
753 }
754 
755 /* *INDENT-OFF* */
756 VLIB_CLI_COMMAND (ipsec_select_backend_command, static) = {
757  .path = "ipsec select backend",
758  .short_help = "ipsec select backend <ah|esp> <backend index>",
760 };
761 
762 /* *INDENT-ON* */
763 
764 static clib_error_t *
766  unformat_input_t * input,
767  vlib_cli_command_t * cmd)
768 {
771 
772  return (NULL);
773 }
774 
775 /* *INDENT-OFF* */
776 VLIB_CLI_COMMAND (clear_ipsec_counters_command, static) = {
777  .path = "clear ipsec counters",
778  .short_help = "clear ipsec counters",
780 };
781 /* *INDENT-ON* */
782 
783 static u32
785 {
786  return (0x80000000 | ti);
787 }
788 
789 static u32
791 {
792  return (0xc0000000 | ti);
793 }
794 
795 static clib_error_t *
797  unformat_input_t * input,
798  vlib_cli_command_t * cmd)
799 {
800  unformat_input_t _line_input, *line_input = &_line_input;
801  ip46_address_t local_ip = ip46_address_initializer;
802  ip46_address_t remote_ip = ip46_address_initializer;
804  ipsec_crypto_alg_t crypto_alg = IPSEC_CRYPTO_ALG_NONE;
805  ipsec_integ_alg_t integ_alg = IPSEC_INTEG_ALG_NONE;
807  u32 local_spi, remote_spi, salt = 0, table_id, fib_index;
808  u32 instance = ~0;
809  int rv;
810  u32 m_args = 0;
811  u8 ipv4_set = 0;
812  u8 ipv6_set = 0;
813  u8 is_add = 1;
814  clib_error_t *error = NULL;
815  ipsec_key_t rck = { 0 };
816  ipsec_key_t lck = { 0 };
817  ipsec_key_t lik = { 0 };
818  ipsec_key_t rik = { 0 };
819 
820  table_id = 0;
821  flags = IPSEC_SA_FLAG_NONE;
822 
823  /* Get a line of input. */
824  if (!unformat_user (input, unformat_line_input, line_input))
825  return 0;
826 
827  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
828  {
829  if (unformat
830  (line_input, "local-ip %U", unformat_ip46_address, &local_ip,
831  IP46_TYPE_ANY))
832  {
833  ip46_address_is_ip4 (&local_ip) ? (ipv4_set = 1) : (ipv6_set = 1);
834  m_args |= 1 << 0;
835  }
836  else
837  if (unformat
838  (line_input, "remote-ip %U", unformat_ip46_address, &remote_ip,
839  IP46_TYPE_ANY))
840  {
841  ip46_address_is_ip4 (&remote_ip) ? (ipv4_set = 1) : (ipv6_set = 1);
842  m_args |= 1 << 1;
843  }
844  else if (unformat (line_input, "local-spi %u", &local_spi))
845  m_args |= 1 << 2;
846  else if (unformat (line_input, "remote-spi %u", &remote_spi))
847  m_args |= 1 << 3;
848  else if (unformat (line_input, "salt 0x%x", &salt))
849  ;
850  else if (unformat (line_input, "udp-encap"))
851  flags |= IPSEC_SA_FLAG_UDP_ENCAP;
852  else if (unformat (line_input, "use-esn"))
853  flags |= IPSEC_SA_FLAG_USE_ESN;
854  else if (unformat (line_input, "use-anti-replay"))
855  flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;
856  else if (unformat (line_input, "instance %u", &instance))
857  ;
858  else if (unformat (line_input, "tx-table %u", &table_id))
859  ;
860  else
861  if (unformat
862  (line_input, "local-crypto-key %U", unformat_ipsec_key, &lck))
863  ;
864  else
865  if (unformat
866  (line_input, "remote-crypto-key %U", unformat_ipsec_key, &rck))
867  ;
868  else if (unformat (line_input, "crypto-alg %U",
869  unformat_ipsec_crypto_alg, &crypto_alg))
870  ;
871  else
872  if (unformat
873  (line_input, "local-integ-key %U", unformat_ipsec_key, &lik))
874  ;
875  else
876  if (unformat
877  (line_input, "remote-integ-key %U", unformat_ipsec_key, &rik))
878  ;
879  else if (unformat (line_input, "integ-alg %U",
880  unformat_ipsec_integ_alg, &integ_alg))
881  ;
882  else if (unformat (line_input, "del"))
883  is_add = 0;
884  else if (unformat (line_input, "nh &U", unformat_ip_address, &nh))
885  ;
886  else
887  {
888  error = clib_error_return (0, "unknown input `%U'",
889  format_unformat_error, line_input);
890  goto done;
891  }
892  }
893 
894  if (0xf != m_args)
895  {
896  error = clib_error_return (0, "mandatory argument(s) missing");
897  goto done;
898  }
899 
900  if (ipv4_set && ipv6_set)
901  return clib_error_return (0, "both IPv4 and IPv6 addresses specified");
902 
903  fib_index = fib_table_find (fib_ip_proto (ipv6_set), table_id);
904 
905  if (~0 == fib_index)
906  {
907  rv = VNET_API_ERROR_NO_SUCH_FIB;
908  goto done;
909  }
910 
911  if (is_add)
912  {
913  // remote = input, local = output
915 
916  /* create an ip-ip tunnel, then the two SA, then bind them */
917  rv =
919  instance, &local_ip, &remote_ip, fib_index,
920  TUNNEL_ENCAP_DECAP_FLAG_NONE, IP_DSCP_CS0,
921  TUNNEL_MODE_P2P, &sw_if_index);
922  rv |=
924  local_spi, IPSEC_PROTOCOL_ESP, crypto_alg,
925  &lck, integ_alg, &lik, flags, table_id,
926  clib_host_to_net_u32 (salt), &local_ip,
927  &remote_ip, NULL, IPSEC_UDP_PORT_NONE,
929  rv |=
931  remote_spi, IPSEC_PROTOCOL_ESP, crypto_alg,
932  &rck, integ_alg, &rik,
933  (flags | IPSEC_SA_FLAG_IS_INBOUND), table_id,
934  clib_host_to_net_u32 (salt), &remote_ip,
935  &local_ip, NULL, IPSEC_UDP_PORT_NONE,
937  rv |=
938  ipsec_tun_protect_update_one (sw_if_index, &nh,
939  ipsec_tun_mk_local_sa_id (sw_if_index),
941  (sw_if_index));
942  }
943  else
944  rv = 0;
945 
946  switch (rv)
947  {
948  case 0:
949  break;
950  case VNET_API_ERROR_INVALID_VALUE:
951  error = clib_error_return (0,
952  "IPSec tunnel interface already exists...");
953  goto done;
954  default:
955  error = clib_error_return (0, "ipsec_register_interface returned %d",
956  rv);
957  goto done;
958  }
959 
960 done:
961  unformat_free (line_input);
962 
963  return error;
964 }
965 
966 /* *INDENT-OFF* */
967 VLIB_CLI_COMMAND (create_ipsec_tunnel_command, static) = {
968  .path = "create ipsec tunnel",
969  .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> "
970  "remote-ip <addr> remote-spi <spi> [instance <inst_num>] [udp-encap] [use-esn] [use-anti-replay] "
971  "[tx-table <table-id>]",
972  .function = create_ipsec_tunnel_command_fn,
973 };
974 /* *INDENT-ON* */
975 
976 static clib_error_t *
978  unformat_input_t * input, vlib_cli_command_t * cmd)
979 {
980  unformat_input_t _line_input, *line_input = &_line_input;
981  u32 sw_if_index, is_del, sa_in, sa_out, *sa_ins = NULL;
982  ip_address_t peer = { };
983  vnet_main_t *vnm;
984 
985  is_del = 0;
986  sw_if_index = ~0;
987  vnm = vnet_get_main ();
988 
989  if (!unformat_user (input, unformat_line_input, line_input))
990  return 0;
991 
992  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
993  {
994  if (unformat (line_input, "del"))
995  is_del = 1;
996  else if (unformat (line_input, "add"))
997  is_del = 0;
998  else if (unformat (line_input, "sa-in %d", &sa_in))
999  vec_add1 (sa_ins, sa_in);
1000  else if (unformat (line_input, "sa-out %d", &sa_out))
1001  ;
1002  else if (unformat (line_input, "%U",
1003  unformat_vnet_sw_interface, vnm, &sw_if_index))
1004  ;
1005  else if (unformat (line_input, "%U", unformat_ip_address, &peer))
1006  ;
1007  else
1008  return (clib_error_return (0, "unknown input '%U'",
1009  format_unformat_error, line_input));
1010  }
1011 
1012  if (!is_del)
1013  ipsec_tun_protect_update (sw_if_index, &peer, sa_out, sa_ins);
1014 
1015  unformat_free (line_input);
1016  return NULL;
1017 }
1018 
1019 /**
1020  * Protect tunnel with IPSEC
1021  */
1022 /* *INDENT-OFF* */
1023 VLIB_CLI_COMMAND (ipsec_tun_protect_cmd_node, static) =
1024 {
1025  .path = "ipsec tunnel protect",
1026  .function = ipsec_tun_protect_cmd,
1027  .short_help = "ipsec tunnel protect <interface> input-sa <SA> output-sa <SA>",
1028  // this is not MP safe
1029 };
1030 /* *INDENT-ON* */
1031 
1032 
1033 static clib_error_t *
1035  unformat_input_t * input, vlib_cli_command_t * cmd)
1036 {
1038 
1039  return NULL;
1040 }
1041 
1042 /**
1043  * show IPSEC tunnel protection
1044  */
1045 /* *INDENT-OFF* */
1046 VLIB_CLI_COMMAND (ipsec_tun_protect_show_node, static) =
1047 {
1048  .path = "show ipsec protect",
1049  .function = ipsec_tun_protect_show,
1050  .short_help = "show ipsec protect",
1051 };
1052 /* *INDENT-ON* */
1053 
1054 static clib_error_t *
1056  unformat_input_t * input,
1057  vlib_cli_command_t * cmd)
1058 {
1059  ipsec_main_t *im = &ipsec_main;
1060 
1061  {
1063  ipsec4_tunnel_key_t key;
1064 
1065  vlib_cli_output (vm, "IPv4:");
1066 
1067  /* *INDENT-OFF* */
1068  hash_foreach(key.as_u64, value.as_u64, im->tun4_protect_by_key,
1069  ({
1070  vlib_cli_output (vm, " %U", format_ipsec4_tunnel_key, &key);
1071  vlib_cli_output (vm, " tun:%d sa:%d", value.tun_index, value.sa_index);
1072  }));
1073  /* *INDENT-ON* */
1074  }
1075 
1076  {
1078  ipsec6_tunnel_key_t *key;
1079 
1080  vlib_cli_output (vm, "IPv6:");
1081 
1082  /* *INDENT-OFF* */
1084  ({
1085  vlib_cli_output (vm, " %U", format_ipsec6_tunnel_key, key);
1086  vlib_cli_output (vm, " tun:%d sa:%d", value.tun_index, value.sa_index);
1087  }));
1088  /* *INDENT-ON* */
1089  }
1090 
1091  return NULL;
1092 }
1093 
1094 /**
1095  * show IPSEC tunnel protection hash tables
1096  */
1097 /* *INDENT-OFF* */
1098 VLIB_CLI_COMMAND (ipsec_tun_protect_hash_show_node, static) =
1099 {
1100  .path = "show ipsec protect-hash",
1101  .function = ipsec_tun_protect_hash_show,
1102  .short_help = "show ipsec protect-hash",
1103 };
1104 /* *INDENT-ON* */
1105 
1106 clib_error_t *
1108 {
1109  return 0;
1110 }
1111 
1113 
1114 static clib_error_t *
1116  vlib_cli_command_t * cmd)
1117 {
1118  unformat_input_t _line_input, *line_input = &_line_input;
1119  int async_enable = 0;
1120 
1121  if (!unformat_user (input, unformat_line_input, line_input))
1122  return 0;
1123 
1124  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1125  {
1126  if (unformat (line_input, "on"))
1127  async_enable = 1;
1128  else if (unformat (line_input, "off"))
1129  async_enable = 0;
1130  else
1131  return (clib_error_return (0, "unknown input '%U'",
1132  format_unformat_error, line_input));
1133  }
1134 
1135  vnet_crypto_request_async_mode (async_enable);
1136  ipsec_set_async_mode (async_enable);
1137 
1138  unformat_free (line_input);
1139  return (NULL);
1140 }
1141 
1142 /* *INDENT-OFF* */
1143 VLIB_CLI_COMMAND (set_async_mode_command, static) = {
1144  .path = "set ipsec async mode",
1145  .short_help = "set ipsec async mode on|off",
1146  .function = set_async_mode_command_fn,
1147 };
1148 /* *INDENT-ON* */
1149 
1150 /*
1151  * fd.io coding-style-patch-verification: ON
1152  *
1153  * Local Variables:
1154  * eval: (c-set-style "gnu")
1155  * End:
1156  */
static clib_error_t * ipsec_select_backend_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:696
ipsec_spd_t * spds
Definition: ipsec.h:105
uword * tun6_protect_by_key
Definition: ipsec.h:129
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:103
static u32 ipsec_tun_mk_local_sa_id(u32 ti)
Definition: ipsec_cli.c:784
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
vl_api_fib_path_nh_t nh
Definition: fib_types.api:126
ipsec_integ_alg_t
Definition: ipsec_sa.h:59
ip46_address_range_t laddr
static clib_error_t * show_ipsec_spd_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:575
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
int ipsec_policy_mk_type(bool is_outbound, bool is_ipv6, ipsec_policy_action_t action, ipsec_spd_policy_type_t *type)
void vnet_crypto_request_async_mode(int is_enable)
Definition: crypto.c:559
static clib_error_t * create_ipsec_tunnel_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:796
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:592
ipsec_protocol_t
Definition: ipsec_sa.h:67
void ipsec_sa_clear(index_t sai)
Definition: ipsec_sa.c:444
u32 tx_table_id
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
vlib_main_t * vm
Definition: in2out_ed.c:1582
int ipsec_select_ah_backend(ipsec_main_t *im, u32 backend_idx)
Definition: ipsec.c:270
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
unformat_function_t unformat_vnet_sw_interface
A Secruity Policy Database.
Definition: ipsec_spd.h:46
int ipsec_sa_add_and_lock(u32 id, u32 spi, ipsec_protocol_t proto, ipsec_crypto_alg_t crypto_alg, const ipsec_key_t *ck, ipsec_integ_alg_t integ_alg, const ipsec_key_t *ik, ipsec_sa_flags_t flags, u32 tx_table_id, u32 salt, const ip46_address_t *tun_src, const ip46_address_t *tun_dst, u32 *sa_out_index, u16 src_port, u16 dst_port)
Definition: ipsec_sa.c:170
int ipip_add_tunnel(ipip_transport_t transport, u32 instance, ip46_address_t *src, ip46_address_t *dst, u32 fib_index, tunnel_encap_decap_flags_t flags, ip_dscp_t dscp, tunnel_mode_t tmode, u32 *sw_if_indexp)
Definition: ipip.c:653
static u8 ip46_address_is_ip4(const ip46_address_t *ip46)
Definition: ip46_address.h:55
void ipsec_tun_protect_walk(ipsec_tun_protect_walk_cb_t fn, void *ctx)
Definition: ipsec_tun.c:801
static void ipsec_tunnel_show_all(vlib_main_t *vm)
Definition: ipsec_cli.c:469
unsigned char u8
Definition: types.h:56
u8 id[64]
Definition: dhcp.api:160
u8 * format_ipsec_tun_protect_index(u8 *s, va_list *args)
Definition: ipsec_format.c:343
uword * spd_index_by_sw_if_index
Definition: ipsec.h:122
enum walk_rc_t_ walk_rc_t
Walk return code.
bool is_outbound
Definition: ipsec.api:96
void vlib_clear_combined_counters(vlib_combined_counter_main_t *cm)
Clear a collection of combined counters.
Definition: counter.c:61
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
unformat_function_t unformat_ip4_address
Definition: format.h:68
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
ipsec_main_t ipsec_main
Definition: ipsec.c:28
int ipsec_select_esp_backend(ipsec_main_t *im, u32 backend_idx)
Definition: ipsec.c:293
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:442
uword unformat_ipsec_crypto_alg(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:96
#define clib_error_return(e, args...)
Definition: error.h:99
int ipsec_sa_unlock_id(u32 id)
Definition: ipsec_sa.c:428
port_range_t rport
u8 * format_ipsec_sa(u8 *s, va_list *args)
Definition: ipsec_format.c:269
u32 salt
unsigned int u32
Definition: types.h:88
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1097
u32 sa_in[n_sa_in]
Definition: ipsec.api:253
static clib_error_t * ipsec_tun_protect_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:1034
unformat_function_t unformat_line_input
Definition: format.h:283
u32 sa_out
Definition: ipsec.api:251
vlib_combined_counter_main_t ipsec_spd_policy_counters
Policy packet & bytes counters.
u8 integ_alg
Definition: ikev2_types.api:59
u8 * format_ipsec_spd(u8 *s, va_list *args)
Definition: ipsec_format.c:203
vl_api_ip_proto_t proto
Definition: acl_types.api:50
static clib_error_t * ipsec_policy_add_del_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:278
long ctx[MAX_CONNS]
Definition: main.c:144
vnet_main_t * vnet_main
Definition: ipsec.h:118
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
int ipsec_add_del_policy(vlib_main_t *vm, ipsec_policy_t *policy, int is_add, u32 *stat_index)
Add/Delete a SPD.
static clib_error_t * set_interface_spd_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:29
static clib_error_t * set_async_mode_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:1115
clib_error_t * ipsec_rsc_in_use(ipsec_main_t *im)
Definition: ipsec.c:258
static clib_error_t * ipsec_show_backends_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:629
ipsec_spd_policy_type_t type
uword unformat_ip_address(unformat_input_t *input, va_list *args)
Definition: ip_types.c:41
#define hash_foreach_mem(key_var, value_var, h, body)
Definition: hash.h:461
vl_api_address_t peer
Definition: teib.api:28
#define IP_ADDRESS_V4_ALL_0S
Definition: ip_types.h:54
static void ipsec_spd_bindings_show_all(vlib_main_t *vm, ipsec_main_t *im)
Definition: ipsec_cli.c:443
static clib_error_t * clear_ipsec_counters_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:765
unformat_function_t unformat_ip6_address
Definition: format.h:89
int ipsec_tun_protect_update_one(u32 sw_if_index, const ip_address_t *nh, u32 sa_out, u32 sa_in)
Definition: ipsec_tun.c:495
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
static void ipsec_sa_show_all(vlib_main_t *vm, ipsec_main_t *im, u8 detail)
Definition: ipsec_cli.c:418
ipsec_ah_backend_t * ah_backends
Definition: ipsec.h:166
clib_error_t * ipsec_cli_init(vlib_main_t *vm)
Definition: ipsec_cli.c:1107
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
static clib_error_t * clear_ipsec_sa_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:527
ipsec_policy_action_t policy
ip46_address_t start
enum ipsec_sad_flags_t_ ipsec_sa_flags_t
u32 spi
Definition: flow_types.api:140
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:299
A Secruity Policy.
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
static void ipsec_spd_show_all(vlib_main_t *vm, ipsec_main_t *im)
Definition: ipsec_cli.c:431
vlib_combined_counter_main_t ipsec_sa_counters
SA packet & bytes counters.
Definition: ipsec_sa.c:27
u8 value
Definition: qos.api:54
void ipsec_set_async_mode(u32 is_enabled)
Definition: ipsec.c:339
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
ipsec_sa_t * sad
Definition: ipsec.h:107
static clib_error_t * show_ipsec_sa_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:500
uword unformat_ipsec_integ_alg(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:128
static clib_error_t * ipsec_tun_protect_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:977
u8 * format_ipsec_policy_action(u8 *s, va_list *args)
Definition: ipsec_format.c:28
uword unformat_ipsec_policy_action(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:64
unformat_function_t unformat_ip46_address
Definition: format.h:63
typedef key
Definition: ipsec_types.api:85
ip46_address_range_t raddr
u32 instance
Definition: gre.api:51
static fib_protocol_t fib_ip_proto(bool is_ip6)
Convert from boolean is_ip6 to FIB protocol.
Definition: fib_types.h:80
static u32 ipsec_tun_mk_remote_sa_id(u32 ti)
Definition: ipsec_cli.c:790
static clib_error_t * show_ipsec_tunnel_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:611
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
ipsec_crypto_alg_t
Definition: ipsec_sa.h:37
u32 table_id
Definition: wireguard.api:100
static clib_error_t * ipsec_sa_add_del_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:84
int ipsec_set_interface_spd(vlib_main_t *vm, u32 sw_if_index, u32 spd_id, int is_add)
Bind/attach a SPD to an interface.
Definition: ipsec_spd.c:63
static clib_error_t * ipsec_tun_protect_hash_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:1055
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
port_range_t lport
int ipsec_add_del_spd(vlib_main_t *vm, u32 spd_id, int is_add)
Add/Delete a SPD.
Definition: ipsec_spd.c:20
static clib_error_t * show_ipsec_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:475
static walk_rc_t ipsec_tun_protect_show_one(index_t itpi, void *ctx)
Definition: ipsec_cli.c:461
#define pool_foreach_index(i, v, body)
Iterate pool by index.
Definition: pool.h:558
static clib_error_t * ipsec_spd_add_del_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:225
u8 async_mode
Definition: ipsec.h:202
uword unformat_ipsec_key(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:242
#define IPSEC_UDP_PORT_NONE
Definition: ipsec_sa.h:277
#define ip46_address_initializer
Definition: ip46_address.h:52
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:33
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
uword * tun4_protect_by_key
Definition: ipsec.h:128
int ipsec_tun_protect_update(u32 sw_if_index, const ip_address_t *nh, u32 sa_out, u32 *sas_in)
Definition: ipsec_tun.c:616