FD.io VPP  v19.04.2-12-g66b1689
Vector Packet Processing
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 
24 #include <vnet/ipsec/ipsec.h>
25 
26 static clib_error_t *
28  unformat_input_t * input,
29  vlib_cli_command_t * cmd)
30 {
31  unformat_input_t _line_input, *line_input = &_line_input;
32  ipsec_main_t *im = &ipsec_main;
33  u32 sw_if_index = (u32) ~ 0;
34  u32 spd_id;
35  int is_add = 1;
36  clib_error_t *error = NULL;
37 
38  if (!unformat_user (input, unformat_line_input, line_input))
39  return 0;
40 
41  if (unformat
42  (line_input, "%U %u", unformat_vnet_sw_interface, im->vnet_main,
43  &sw_if_index, &spd_id))
44  ;
45  else if (unformat (line_input, "del"))
46  is_add = 0;
47  else
48  {
49  error = clib_error_return (0, "parse error: '%U'",
50  format_unformat_error, line_input);
51  goto done;
52  }
53 
54  ipsec_set_interface_spd (vm, sw_if_index, spd_id, is_add);
55 
56 done:
57  unformat_free (line_input);
58 
59  return error;
60 }
61 
62 /* *INDENT-OFF* */
63 VLIB_CLI_COMMAND (set_interface_spd_command, static) = {
64  .path = "set interface ipsec spd",
65  .short_help =
66  "set interface ipsec spd <int> <id>",
67  .function = set_interface_spd_command_fn,
68 };
69 /* *INDENT-ON* */
70 
71 static clib_error_t *
73  unformat_input_t * input,
74  vlib_cli_command_t * cmd)
75 {
76  unformat_input_t _line_input, *line_input = &_line_input;
77  ip46_address_t tun_src = { }, tun_dst =
78  {
79  };
80  ipsec_crypto_alg_t crypto_alg;
81  ipsec_integ_alg_t integ_alg;
82  ipsec_protocol_t proto;
84  clib_error_t *error;
85  ipsec_key_t ck = { 0 };
86  ipsec_key_t ik = { 0 };
87  int is_add, rv;
88  u32 id, spi;
89 
90  error = NULL;
91  is_add = 0;
92  flags = IPSEC_SA_FLAG_NONE;
93  proto = IPSEC_PROTOCOL_ESP;
94 
95  if (!unformat_user (input, unformat_line_input, line_input))
96  return 0;
97 
98  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
99  {
100  if (unformat (line_input, "add %u", &id))
101  is_add = 1;
102  else if (unformat (line_input, "del %u", &id))
103  is_add = 0;
104  else if (unformat (line_input, "spi %u", &spi))
105  ;
106  else if (unformat (line_input, "esp"))
107  proto = IPSEC_PROTOCOL_ESP;
108  else if (unformat (line_input, "ah"))
109  proto = IPSEC_PROTOCOL_AH;
110  else if (unformat (line_input, "crypto-key %U",
111  unformat_ipsec_key, &ck))
112  ;
113  else if (unformat (line_input, "crypto-alg %U",
114  unformat_ipsec_crypto_alg, &crypto_alg))
115  ;
116  else if (unformat (line_input, "integ-key %U", unformat_ipsec_key, &ik))
117  ;
118  else if (unformat (line_input, "integ-alg %U",
119  unformat_ipsec_integ_alg, &integ_alg))
120  ;
121  else if (unformat (line_input, "tunnel-src %U",
123  {
124  flags |= IPSEC_SA_FLAG_IS_TUNNEL;
125  if (!ip46_address_is_ip4 (&tun_src))
126  flags |= IPSEC_SA_FLAG_IS_TUNNEL_V6;
127  }
128  else if (unformat (line_input, "tunnel-dst %U",
130  ;
131  else if (unformat (line_input, "udp-encap"))
132  flags |= IPSEC_SA_FLAG_UDP_ENCAP;
133  else
134  {
135  error = clib_error_return (0, "parse error: '%U'",
136  format_unformat_error, line_input);
137  goto done;
138  }
139  }
140 
141  if (is_add)
142  rv = ipsec_sa_add (id, spi, proto, crypto_alg,
143  &ck, integ_alg, &ik, flags,
144  0, 0, &tun_src, &tun_dst, NULL);
145  else
146  rv = ipsec_sa_del (id);
147 
148  if (rv)
149  clib_error_return (0, "failed");
150 
151 done:
152  unformat_free (line_input);
153 
154  return error;
155 }
156 
157 /* *INDENT-OFF* */
158 VLIB_CLI_COMMAND (ipsec_sa_add_del_command, static) = {
159  .path = "ipsec sa",
160  .short_help =
161  "ipsec sa [add|del]",
162  .function = ipsec_sa_add_del_command_fn,
163 };
164 /* *INDENT-ON* */
165 
166 static clib_error_t *
168  unformat_input_t * input,
169  vlib_cli_command_t * cmd)
170 {
171  unformat_input_t _line_input, *line_input = &_line_input;
172  u32 spd_id = ~0;
173  int is_add = ~0;
174  clib_error_t *error = NULL;
175 
176  if (!unformat_user (input, unformat_line_input, line_input))
177  return 0;
178 
179  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
180  {
181  if (unformat (line_input, "add"))
182  is_add = 1;
183  else if (unformat (line_input, "del"))
184  is_add = 0;
185  else if (unformat (line_input, "%u", &spd_id))
186  ;
187  else
188  {
189  error = clib_error_return (0, "parse error: '%U'",
190  format_unformat_error, line_input);
191  goto done;
192  }
193  }
194 
195  if (spd_id == ~0)
196  {
197  error = clib_error_return (0, "please specify SPD ID");
198  goto done;
199  }
200 
201  ipsec_add_del_spd (vm, spd_id, is_add);
202 
203 done:
204  unformat_free (line_input);
205 
206  return error;
207 }
208 
209 /* *INDENT-OFF* */
210 VLIB_CLI_COMMAND (ipsec_spd_add_del_command, static) = {
211  .path = "ipsec spd",
212  .short_help =
213  "ipsec spd [add|del] <id>",
214  .function = ipsec_spd_add_del_command_fn,
215 };
216 /* *INDENT-ON* */
217 
218 
219 static clib_error_t *
221  unformat_input_t * input,
222  vlib_cli_command_t * cmd)
223 {
224  unformat_input_t _line_input, *line_input = &_line_input;
225  ipsec_policy_t p;
226  int rv, is_add = 0;
227  u32 tmp, tmp2, stat_index;
228  clib_error_t *error = NULL;
230 
231  clib_memset (&p, 0, sizeof (p));
232  p.lport.stop = p.rport.stop = ~0;
233  p.laddr.stop.ip4.as_u32 = p.raddr.stop.ip4.as_u32 = (u32) ~ 0;
234  p.laddr.stop.ip6.as_u64[0] = p.laddr.stop.ip6.as_u64[1] = (u64) ~ 0;
235  p.raddr.stop.ip6.as_u64[0] = p.raddr.stop.ip6.as_u64[1] = (u64) ~ 0;
236  is_outbound = 0;
237 
238  if (!unformat_user (input, unformat_line_input, line_input))
239  return 0;
240 
241  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
242  {
243  if (unformat (line_input, "add"))
244  is_add = 1;
245  else if (unformat (line_input, "del"))
246  is_add = 0;
247  else if (unformat (line_input, "spd %u", &p.id))
248  ;
249  else if (unformat (line_input, "inbound"))
250  is_outbound = 0;
251  else if (unformat (line_input, "outbound"))
252  is_outbound = 1;
253  else if (unformat (line_input, "priority %d", &p.priority))
254  ;
255  else if (unformat (line_input, "protocol %u", &tmp))
256  p.protocol = (u8) tmp;
257  else
258  if (unformat
259  (line_input, "action %U", unformat_ipsec_policy_action,
260  &p.policy))
261  {
262  if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
263  {
264  error = clib_error_return (0, "unsupported action: 'resolve'");
265  goto done;
266  }
267  }
268  else if (unformat (line_input, "sa %u", &p.sa_id))
269  ;
270  else if (unformat (line_input, "local-ip-range %U - %U",
273  ;
274  else if (unformat (line_input, "remote-ip-range %U - %U",
277  ;
278  else if (unformat (line_input, "local-ip-range %U - %U",
281  {
282  p.is_ipv6 = 1;
283  }
284  else if (unformat (line_input, "remote-ip-range %U - %U",
287  {
288  p.is_ipv6 = 1;
289  }
290  else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2))
291  {
292  p.lport.start = tmp;
293  p.lport.stop = tmp2;
294  }
295  else
296  if (unformat (line_input, "remote-port-range %u - %u", &tmp, &tmp2))
297  {
298  p.rport.start = tmp;
299  p.rport.stop = tmp2;
300  }
301  else
302  {
303  error = clib_error_return (0, "parse error: '%U'",
304  format_unformat_error, line_input);
305  goto done;
306  }
307  }
308 
309  /* Check if SA is for IPv6/AH which is not supported. Return error if TRUE. */
310  if (p.sa_id)
311  {
312  uword *p1;
313  ipsec_main_t *im = &ipsec_main;
314  ipsec_sa_t *sa = 0;
315  p1 = hash_get (im->sa_index_by_sa_id, p.sa_id);
316  if (!p1)
317  {
318  error =
319  clib_error_return (0, "SA with index %u not found", p.sa_id);
320  goto done;
321  }
322  sa = pool_elt_at_index (im->sad, p1[0]);
323  if (sa && sa->protocol == IPSEC_PROTOCOL_AH && is_add && p.is_ipv6)
324  {
325  error = clib_error_return (0, "AH not supported for IPV6: '%U'",
326  format_unformat_error, line_input);
327  goto done;
328  }
329  }
330 
331  rv = ipsec_policy_mk_type (is_outbound, p.is_ipv6, p.policy, &p.type);
332 
333  if (rv)
334  {
335  error = clib_error_return (0, "unsupported policy type for:",
336  " outboud:%s %s action:%U",
337  (is_outbound ? "yes" : "no"),
338  (p.is_ipv6 ? "IPv4" : "IPv6"),
340  goto done;
341  }
342 
343  rv = ipsec_add_del_policy (vm, &p, is_add, &stat_index);
344 
345  if (!rv)
346  vlib_cli_output (vm, "policy-index:%d", stat_index);
347  else
348  vlib_cli_output (vm, "error:%d", rv);
349 
350 done:
351  unformat_free (line_input);
352 
353  return error;
354 }
355 
356 /* *INDENT-OFF* */
357 VLIB_CLI_COMMAND (ipsec_policy_add_del_command, static) = {
358  .path = "ipsec policy",
359  .short_help =
360  "ipsec policy [add|del] spd <id> priority <n> ",
362 };
363 /* *INDENT-ON* */
364 
365 static clib_error_t *
367  unformat_input_t * input,
368  vlib_cli_command_t * cmd)
369 {
370  unformat_input_t _line_input, *line_input = &_line_input;
371  clib_error_t *error = NULL;
372  ipsec_key_t ck, ik;
373  u32 id;
374 
375  if (!unformat_user (input, unformat_line_input, line_input))
376  return 0;
377 
378  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
379  {
380  if (unformat (line_input, "%u", &id))
381  ;
382  else
383  if (unformat (line_input, "crypto-key %U", unformat_ipsec_key, &ck))
384  ;
385  else if (unformat (line_input, "integ-key %U", unformat_ipsec_key, &ik))
386  ;
387  else
388  {
389  error = clib_error_return (0, "parse error: '%U'",
390  format_unformat_error, line_input);
391  goto done;
392  }
393  }
394 
395  ipsec_set_sa_key (id, &ck, &ik);
396 
397 done:
398  unformat_free (line_input);
399 
400  return error;
401 }
402 
403 /* *INDENT-OFF* */
404 VLIB_CLI_COMMAND (set_ipsec_sa_key_command, static) = {
405  .path = "set ipsec sa",
406  .short_help = "set ipsec sa <id> crypto-key <key> integ-key <key>",
407  .function = set_ipsec_sa_key_command_fn,
408 };
409 /* *INDENT-ON* */
410 
411 static void
413 {
414  u32 sai;
415 
416  /* *INDENT-OFF* */
417  pool_foreach_index (sai, im->sad, ({
418  vlib_cli_output(vm, "%U", format_ipsec_sa, sai, IPSEC_FORMAT_BRIEF);
419  }));
420  /* *INDENT-ON* */
421 }
422 
423 static void
425 {
426  u32 spdi;
427 
428  /* *INDENT-OFF* */
429  pool_foreach_index (spdi, im->spds, ({
430  vlib_cli_output(vm, "%U", format_ipsec_spd, spdi);
431  }));
432  /* *INDENT-ON* */
433 }
434 
435 static void
437 {
438  u32 spd_id, sw_if_index;
439 
440  vlib_cli_output (vm, "SPD Bindings:");
441 
442  /* *INDENT-OFF* */
443  hash_foreach(sw_if_index, spd_id, im->spd_index_by_sw_if_index, ({
444  vlib_cli_output (vm, " %d -> %U", spd_id,
445  format_vnet_sw_if_index_name, im->vnet_main,
446  sw_if_index);
447  }));
448  /* *INDENT-ON* */
449 }
450 
451 static void
453 {
454  u32 ti;
455 
456  vlib_cli_output (vm, "Tunnel interfaces");
457  /* *INDENT-OFF* */
459  vlib_cli_output(vm, " %U", format_ipsec_tunnel, ti);
460  }));
461  /* *INDENT-ON* */
462 }
463 
464 static clib_error_t *
466  unformat_input_t * input, vlib_cli_command_t * cmd)
467 {
468  ipsec_main_t *im = &ipsec_main;
469 
470  ipsec_sa_show_all (vm, im);
471  ipsec_spd_show_all (vm, im);
473  ipsec_tunnel_show_all (vm, im);
474 
475  return 0;
476 }
477 
478 /* *INDENT-OFF* */
479 VLIB_CLI_COMMAND (show_ipsec_command, static) = {
480  .path = "show ipsec all",
481  .short_help = "show ipsec all",
482  .function = show_ipsec_command_fn,
483 };
484 /* *INDENT-ON* */
485 
486 static clib_error_t *
488  unformat_input_t * input, vlib_cli_command_t * cmd)
489 {
490  ipsec_main_t *im = &ipsec_main;
491  u32 sai = ~0;
492 
494  {
495  if (unformat (input, "%u", &sai))
496  ;
497  else
498  break;
499  }
500 
501  if (~0 == sai)
502  ipsec_sa_show_all (vm, im);
503  else
505 
506  return 0;
507 }
508 
509 /* *INDENT-OFF* */
510 VLIB_CLI_COMMAND (show_ipsec_sa_command, static) = {
511  .path = "show ipsec sa",
512  .short_help = "show ipsec sa [index]",
513  .function = show_ipsec_sa_command_fn,
514 };
515 /* *INDENT-ON* */
516 
517 static clib_error_t *
519  unformat_input_t * input, vlib_cli_command_t * cmd)
520 {
521  ipsec_main_t *im = &ipsec_main;
522  u8 show_bindings = 0;
523  u32 spdi = ~0;
524 
526  {
527  if (unformat (input, "%u", &spdi))
528  ;
529  else if (unformat (input, "bindings"))
530  show_bindings = 1;
531  else
532  break;
533  }
534 
535  if (show_bindings)
537  else if (~0 != spdi)
538  vlib_cli_output (vm, "%U", format_ipsec_spd, spdi);
539  else
540  ipsec_spd_show_all (vm, im);
541 
542  return 0;
543 }
544 
545 /* *INDENT-OFF* */
546 VLIB_CLI_COMMAND (show_ipsec_spd_command, static) = {
547  .path = "show ipsec spd",
548  .short_help = "show ipsec spd [index]",
549  .function = show_ipsec_spd_command_fn,
550 };
551 /* *INDENT-ON* */
552 
553 static clib_error_t *
555  unformat_input_t * input,
556  vlib_cli_command_t * cmd)
557 {
558  ipsec_main_t *im = &ipsec_main;
559  u32 ti = ~0;
560 
562  {
563  if (unformat (input, "%u", &ti))
564  ;
565  else
566  break;
567  }
568 
569  if (~0 != ti)
570  vlib_cli_output (vm, "%U", format_ipsec_tunnel, ti);
571  else
572  ipsec_tunnel_show_all (vm, im);
573 
574  return 0;
575 }
576 
577 /* *INDENT-OFF* */
578 VLIB_CLI_COMMAND (show_ipsec_tunnel_command, static) = {
579  .path = "show ipsec tunnel",
580  .short_help = "show ipsec tunnel [index]",
581  .function = show_ipsec_tunnel_command_fn,
582 };
583 /* *INDENT-ON* */
584 
585 static clib_error_t *
587  unformat_input_t * input,
588  vlib_cli_command_t * cmd)
589 {
590  ipsec_main_t *im = &ipsec_main;
591  u32 verbose = 0;
592 
593  (void) unformat (input, "verbose %u", &verbose);
594 
595  vlib_cli_output (vm, "IPsec AH backends available:");
596  u8 *s = format (NULL, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
597  ipsec_ah_backend_t *ab;
598  /* *INDENT-OFF* */
599  pool_foreach (ab, im->ah_backends, {
600  s = format (s, "%=25s %=25u %=10s\n", ab->name, ab - im->ah_backends,
601  ab - im->ah_backends == im->ah_current_backend ? "yes" : "no");
602  if (verbose) {
603  vlib_node_t *n;
604  n = vlib_get_node (vm, ab->ah4_encrypt_node_index);
605  s = format (s, " enc4 %s (next %d)\n", n->name, ab->ah4_encrypt_next_index);
606  n = vlib_get_node (vm, ab->ah4_decrypt_node_index);
607  s = format (s, " dec4 %s (next %d)\n", n->name, ab->ah4_decrypt_next_index);
608  n = vlib_get_node (vm, ab->ah6_encrypt_node_index);
609  s = format (s, " enc6 %s (next %d)\n", n->name, ab->ah6_encrypt_next_index);
610  n = vlib_get_node (vm, ab->ah6_decrypt_node_index);
611  s = format (s, " dec6 %s (next %d)\n", n->name, ab->ah6_decrypt_next_index);
612  }
613  });
614  /* *INDENT-ON* */
615  vlib_cli_output (vm, "%v", s);
616  _vec_len (s) = 0;
617  vlib_cli_output (vm, "IPsec ESP backends available:");
618  s = format (s, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
620  /* *INDENT-OFF* */
621  pool_foreach (eb, im->esp_backends, {
622  s = format (s, "%=25s %=25u %=10s\n", eb->name, eb - im->esp_backends,
623  eb - im->esp_backends == im->esp_current_backend ? "yes"
624  : "no");
625  if (verbose) {
626  vlib_node_t *n;
627  n = vlib_get_node (vm, eb->esp4_encrypt_node_index);
628  s = format (s, " enc4 %s (next %d)\n", n->name, eb->esp4_encrypt_next_index);
629  n = vlib_get_node (vm, eb->esp4_decrypt_node_index);
630  s = format (s, " dec4 %s (next %d)\n", n->name, eb->esp4_decrypt_next_index);
631  n = vlib_get_node (vm, eb->esp6_encrypt_node_index);
632  s = format (s, " enc6 %s (next %d)\n", n->name, eb->esp6_encrypt_next_index);
633  n = vlib_get_node (vm, eb->esp6_decrypt_node_index);
634  s = format (s, " dec6 %s (next %d)\n", n->name, eb->esp6_decrypt_next_index);
635  }
636  });
637  /* *INDENT-ON* */
638  vlib_cli_output (vm, "%v", s);
639 
640  vec_free (s);
641  return 0;
642 }
643 
644 /* *INDENT-OFF* */
645 VLIB_CLI_COMMAND (ipsec_show_backends_command, static) = {
646  .path = "show ipsec backends",
647  .short_help = "show ipsec backends",
648  .function = ipsec_show_backends_command_fn,
649 };
650 /* *INDENT-ON* */
651 
652 static clib_error_t *
654  unformat_input_t * input,
655  vlib_cli_command_t * cmd)
656 {
657  unformat_input_t _line_input, *line_input = &_line_input;
658  ipsec_main_t *im = &ipsec_main;
659  clib_error_t *error;
660  u32 backend_index;
661 
662  error = ipsec_rsc_in_use (im);
663 
664  if (error)
665  return error;
666 
667  /* Get a line of input. */
668  if (!unformat_user (input, unformat_line_input, line_input))
669  return 0;
670 
671  if (unformat (line_input, "ah"))
672  {
673  if (unformat (line_input, "%u", &backend_index))
674  {
675  if (ipsec_select_ah_backend (im, backend_index) < 0)
676  {
677  return clib_error_return (0, "Invalid AH backend index `%u'",
678  backend_index);
679  }
680  }
681  else
682  {
683  return clib_error_return (0, "Invalid backend index `%U'",
684  format_unformat_error, line_input);
685  }
686  }
687  else if (unformat (line_input, "esp"))
688  {
689  if (unformat (line_input, "%u", &backend_index))
690  {
691  if (ipsec_select_esp_backend (im, backend_index) < 0)
692  {
693  return clib_error_return (0, "Invalid ESP backend index `%u'",
694  backend_index);
695  }
696  }
697  else
698  {
699  return clib_error_return (0, "Invalid backend index `%U'",
700  format_unformat_error, line_input);
701  }
702  }
703  else
704  {
705  return clib_error_return (0, "Unknown input `%U'",
706  format_unformat_error, line_input);
707  }
708 
709  return 0;
710 }
711 
712 /* *INDENT-OFF* */
713 VLIB_CLI_COMMAND (ipsec_select_backend_command, static) = {
714  .path = "ipsec select backend",
715  .short_help = "ipsec select backend <ah|esp> <backend index>",
717 };
718 
719 /* *INDENT-ON* */
720 
721 static clib_error_t *
723  unformat_input_t * input,
724  vlib_cli_command_t * cmd)
725 {
728 
729  return (NULL);
730 }
731 
732 /* *INDENT-OFF* */
733 VLIB_CLI_COMMAND (clear_ipsec_counters_command, static) = {
734  .path = "clear ipsec counters",
735  .short_help = "clear ipsec counters",
737 };
738 /* *INDENT-ON* */
739 
740 static clib_error_t *
742  unformat_input_t * input,
743  vlib_cli_command_t * cmd)
744 {
745  unformat_input_t _line_input, *line_input = &_line_input;
747  int rv;
748  u32 num_m_args = 0;
749  u8 ipv4_set = 0;
750  u8 ipv6_set = 0;
751  clib_error_t *error = NULL;
752  ipsec_key_t rck = { 0 };
753  ipsec_key_t lck = { 0 };
754  ipsec_key_t lik = { 0 };
755  ipsec_key_t rik = { 0 };
756 
757  clib_memset (&a, 0, sizeof (a));
758  a.is_add = 1;
759 
760  /* Get a line of input. */
761  if (!unformat_user (input, unformat_line_input, line_input))
762  return 0;
763 
764  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
765  {
766  if (unformat
767  (line_input, "local-ip %U", unformat_ip46_address, &a.local_ip,
768  IP46_TYPE_ANY))
769  {
770  ip46_address_is_ip4 (&a.local_ip) ? (ipv4_set = 1) : (ipv6_set = 1);
771  num_m_args++;
772  }
773  else
774  if (unformat
775  (line_input, "remote-ip %U", unformat_ip46_address, &a.remote_ip,
776  IP46_TYPE_ANY))
777  {
778  ip46_address_is_ip4 (&a.remote_ip) ? (ipv4_set = 1) : (ipv6_set =
779  1);
780  num_m_args++;
781  }
782  else if (unformat (line_input, "local-spi %u", &a.local_spi))
783  num_m_args++;
784  else if (unformat (line_input, "remote-spi %u", &a.remote_spi))
785  num_m_args++;
786  else if (unformat (line_input, "instance %u", &a.show_instance))
787  a.renumber = 1;
788  else if (unformat (line_input, "salt 0x%x", &a.salt))
789  ;
790  else if (unformat (line_input, "udp-encap"))
791  a.udp_encap = 1;
792  else if (unformat (line_input, "use-esn"))
793  a.esn = 1;
794  else if (unformat (line_input, "use-anti-replay"))
795  a.anti_replay = 1;
796  else if (unformat (line_input, "tx-table %u", &a.tx_table_id))
797  ;
798  else
799  if (unformat
800  (line_input, "local-crypto-key %U", unformat_ipsec_key, &lck))
801  ;
802  else
803  if (unformat
804  (line_input, "remote-crypto-key %U", unformat_ipsec_key, &rck))
805  ;
806  else if (unformat (line_input, "crypto-alg %U",
808  ;
809  else
810  if (unformat
811  (line_input, "local-integ-key %U", unformat_ipsec_key, &lik))
812  ;
813  else
814  if (unformat
815  (line_input, "rmote-integ-key %U", unformat_ipsec_key, &rik))
816  ;
817  else if (unformat (line_input, "integ-alg %U",
819  ;
820  else if (unformat (line_input, "del"))
821  a.is_add = 0;
822  else
823  {
824  error = clib_error_return (0, "unknown input `%U'",
825  format_unformat_error, line_input);
826  goto done;
827  }
828  }
829 
830  if (num_m_args < 4)
831  {
832  error = clib_error_return (0, "mandatory argument(s) missing");
833  goto done;
834  }
835 
836  if (ipv4_set && ipv6_set)
837  return clib_error_return (0, "both IPv4 and IPv6 addresses specified");
838 
839  a.is_ip6 = ipv6_set;
840 
841  clib_memcpy (a.local_crypto_key, lck.data, lck.len);
842  a.local_crypto_key_len = lck.len;
843  clib_memcpy (a.remote_crypto_key, rck.data, rck.len);
844  a.remote_crypto_key_len = rck.len;
845 
846  clib_memcpy (a.local_integ_key, lik.data, lik.len);
847  a.local_integ_key_len = lck.len;
848  clib_memcpy (a.remote_integ_key, rik.data, rik.len);
849  a.remote_integ_key_len = rck.len;
850 
851  rv = ipsec_add_del_tunnel_if (&a);
852 
853  switch (rv)
854  {
855  case 0:
856  break;
857  case VNET_API_ERROR_INVALID_VALUE:
858  if (a.is_add)
859  error = clib_error_return (0,
860  "IPSec tunnel interface already exists...");
861  else
862  error = clib_error_return (0, "IPSec tunnel interface not exists...");
863  goto done;
864  default:
865  error = clib_error_return (0, "ipsec_register_interface returned %d",
866  rv);
867  goto done;
868  }
869 
870 done:
871  unformat_free (line_input);
872 
873  return error;
874 }
875 
876 /* *INDENT-OFF* */
877 VLIB_CLI_COMMAND (create_ipsec_tunnel_command, static) = {
878  .path = "create ipsec tunnel",
879  .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> "
880  "remote-ip <addr> remote-spi <spi> [instance <inst_num>] [udp-encap] [use-esn] [use-anti-replay] "
881  "[tx-table <table-id>]",
882  .function = create_ipsec_tunnel_command_fn,
883 };
884 /* *INDENT-ON* */
885 
886 static clib_error_t *
888  unformat_input_t * input,
889  vlib_cli_command_t * cmd)
890 {
891  unformat_input_t _line_input, *line_input = &_line_input;
892  ipsec_main_t *im = &ipsec_main;
894  u32 hw_if_index = (u32) ~ 0;
895  u32 alg;
896  u8 *key = 0;
897  clib_error_t *error = NULL;
898 
899  if (!unformat_user (input, unformat_line_input, line_input))
900  return 0;
901 
902  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
903  {
904  if (unformat (line_input, "%U",
905  unformat_vnet_hw_interface, im->vnet_main, &hw_if_index))
906  ;
907  else
908  if (unformat
909  (line_input, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
911  else
912  if (unformat
913  (line_input, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
915  else
916  if (unformat
917  (line_input, "local integ %U", unformat_ipsec_integ_alg, &alg))
919  else
920  if (unformat
921  (line_input, "remote integ %U", unformat_ipsec_integ_alg, &alg))
923  else if (unformat (line_input, "%U", unformat_hex_string, &key))
924  ;
925  else
926  {
927  error = clib_error_return (0, "parse error: '%U'",
928  format_unformat_error, line_input);
929  goto done;
930  }
931  }
932 
933  if (type == IPSEC_IF_SET_KEY_TYPE_NONE)
934  {
935  error = clib_error_return (0, "unknown key type");
936  goto done;
937  }
938 
939  if (alg > 0 && vec_len (key) == 0)
940  {
941  error = clib_error_return (0, "key is not specified");
942  goto done;
943  }
944 
945  if (hw_if_index == (u32) ~ 0)
946  {
947  error = clib_error_return (0, "interface not specified");
948  goto done;
949  }
950 
951  ipsec_set_interface_key (im->vnet_main, hw_if_index, type, alg, key);
952 
953 done:
954  vec_free (key);
955  unformat_free (line_input);
956 
957  return error;
958 }
959 
960 /* *INDENT-OFF* */
961 VLIB_CLI_COMMAND (set_interface_key_command, static) = {
962  .path = "set interface ipsec key",
963  .short_help =
964  "set interface ipsec key <int> <local|remote> <crypto|integ> <key type> <key>",
965  .function = set_interface_key_command_fn,
966 };
967 /* *INDENT-ON* */
968 
969 clib_error_t *
971 {
972  return 0;
973 }
974 
976 
977 
978 /*
979  * fd.io coding-style-patch-verification: ON
980  *
981  * Local Variables:
982  * eval: (c-set-style "gnu")
983  * End:
984  */
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:653
unformat_function_t unformat_vnet_hw_interface
u32 sw_if_index
Definition: ipsec_gre.api:37
ipsec_spd_t * spds
Definition: ipsec.h:93
u32 flags
Definition: vhost_user.h:115
ipsec_tunnel_if_t * tunnel_interfaces
Definition: ipsec.h:100
u32 ipsec_sa_del(u32 id)
Definition: ipsec_sa.c:254
static clib_error_t * set_ipsec_sa_key_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:366
a
Definition: bitmap.h:538
ip46_address_t local_ip
Definition: ipsec_if.h:47
ipsec_integ_alg_t
Definition: ipsec_sa.h:60
unsigned long u64
Definition: types.h:89
ip46_address_range_t laddr
#define NULL
Definition: clib.h:58
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:518
unformat_function_t unformat_hex_string
Definition: format.h:288
int ipsec_policy_mk_type(bool is_outbound, bool is_ipv6, ipsec_policy_action_t action, ipsec_spd_policy_type_t *type)
int ipsec_set_sa_key(u32 id, const ipsec_key_t *ck, const ipsec_key_t *ik)
Definition: ipsec_sa.c:321
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:741
ipsec_protocol_t
Definition: ipsec_sa.h:68
int ipsec_add_del_tunnel_if(ipsec_add_del_tunnel_args_t *args)
Definition: ipsec_if.c:214
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:983
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
int ipsec_select_ah_backend(ipsec_main_t *im, u32 backend_idx)
Definition: ipsec.c:195
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
static clib_error_t * set_interface_key_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ipsec_cli.c:887
unformat_function_t unformat_vnet_sw_interface
unsigned char u8
Definition: types.h:56
uword * spd_index_by_sw_if_index
Definition: ipsec.h:110
#define clib_memcpy(d, s, n)
Definition: string.h:180
void vlib_clear_combined_counters(vlib_combined_counter_main_t *cm)
Clear a collection of combined counters.
Definition: counter.c:60
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:493
unformat_function_t unformat_ip4_address
Definition: format.h:70
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:163
ipsec_main_t ipsec_main
Definition: ipsec.c:28
int ipsec_select_esp_backend(ipsec_main_t *im, u32 backend_idx)
Definition: ipsec.c:218
#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:95
#define clib_error_return(e, args...)
Definition: error.h:99
port_range_t rport
u8 * format_ipsec_sa(u8 *s, va_list *args)
Definition: ipsec_format.c:270
int ipsec_set_interface_key(vnet_main_t *vnm, u32 hw_if_index, ipsec_if_set_key_type_t type, u8 alg, u8 *key)
Definition: ipsec_if.c:517
unsigned int u32
Definition: types.h:88
static void ipsec_tunnel_show_all(vlib_main_t *vm, ipsec_main_t *im)
Definition: ipsec_cli.c:452
unformat_function_t unformat_line_input
Definition: format.h:282
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:514
vlib_combined_counter_main_t ipsec_spd_policy_counters
Policy packet & bytes counters.
u8 * format_ipsec_spd(u8 *s, va_list *args)
Definition: ipsec_format.c:202
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:220
vnet_main_t * vnet_main
Definition: ipsec.h:106
struct _unformat_input_t unformat_input_t
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:27
ip46_address_t remote_ip
Definition: ipsec_if.h:47
u8 * format_ipsec_tunnel(u8 *s, va_list *args)
Definition: ipsec_format.c:336
clib_error_t * ipsec_rsc_in_use(ipsec_main_t *im)
Definition: ipsec.c:178
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:586
ipsec_spd_policy_type_t type
static void ipsec_spd_bindings_show_all(vlib_main_t *vm, ipsec_main_t *im)
Definition: ipsec_cli.c:436
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:722
#define ip46_address_is_ip4(ip46)
Definition: ip6_packet.h:88
unformat_function_t unformat_ip6_address
Definition: format.h:91
ipsec_crypto_alg_t crypto_alg
Definition: ipsec_if.h:50
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
vlib_main_t * vm
Definition: buffer.c:312
ipsec_ah_backend_t * ah_backends
Definition: ipsec.h:142
clib_error_t * ipsec_cli_init(vlib_main_t *vm)
Definition: ipsec_cli.c:970
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
ipsec_policy_action_t policy
ip46_address_t start
enum ipsec_sad_flags_t_ ipsec_sa_flags_t
uword * sa_index_by_sa_id
Definition: ipsec.h:111
u8 is_outbound
Definition: ipsec.api:92
A Secruity Policy.
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
static void ipsec_spd_show_all(vlib_main_t *vm, ipsec_main_t *im)
Definition: ipsec_cli.c:424
vlib_combined_counter_main_t ipsec_sa_counters
SA packet & bytes counters.
Definition: ipsec_sa.c:25
u32 spi
Definition: ipsec.api:270
u8 is_add
Definition: ipsec_gre.api:36
ipsec_integ_alg_t integ_alg
Definition: ipsec_if.h:55
ipsec_sa_t * sad
Definition: ipsec.h:95
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:487
uword unformat_ipsec_integ_alg(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:127
ipsec_protocol_t protocol
Definition: ipsec_sa.h:148
u8 * format_ipsec_policy_action(u8 *s, va_list *args)
Definition: ipsec_format.c:27
uword unformat_ipsec_policy_action(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:63
unformat_function_t unformat_ip46_address
Definition: format.h:65
int ipsec_sa_add(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)
Definition: ipsec_sa.c:123
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
ip46_address_range_t raddr
u64 uword
Definition: types.h:112
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:554
static void unformat_free(unformat_input_t *i)
Definition: format.h:162
ipsec_crypto_alg_t
Definition: ipsec_sa.h:38
typedef key
Definition: ipsec.api:244
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:72
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
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:465
ipsec_if_set_key_type_t
Definition: ipsec_if.h:20
u32 id
Definition: udp.api:45
#define pool_foreach_index(i, v, body)
Iterate pool by index.
Definition: pool.h:538
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:167
uword unformat_ipsec_key(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:241
static void ipsec_sa_show_all(vlib_main_t *vm, ipsec_main_t *im)
Definition: ipsec_cli.c:412
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:762
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170