FD.io VPP  v18.01-8-g0eacf49
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 
23 #include <vnet/ipsec/ipsec.h>
24 
25 static clib_error_t *
27  unformat_input_t * input,
28  vlib_cli_command_t * cmd)
29 {
30  unformat_input_t _line_input, *line_input = &_line_input;
31  ipsec_main_t *im = &ipsec_main;
32  u32 sw_if_index = (u32) ~ 0;
33  u32 spd_id;
34  int is_add = 1;
35  clib_error_t *error = NULL;
36 
37  if (!unformat_user (input, unformat_line_input, line_input))
38  return 0;
39 
40  if (unformat
41  (line_input, "%U %u", unformat_vnet_sw_interface, im->vnet_main,
42  &sw_if_index, &spd_id))
43  ;
44  else if (unformat (line_input, "del"))
45  is_add = 0;
46  else
47  {
48  error = clib_error_return (0, "parse error: '%U'",
49  format_unformat_error, line_input);
50  goto done;
51  }
52 
53  ipsec_set_interface_spd (vm, sw_if_index, spd_id, is_add);
54 
55 done:
56  unformat_free (line_input);
57 
58  return error;
59 }
60 
61 /* *INDENT-OFF* */
62 VLIB_CLI_COMMAND (set_interface_spd_command, static) = {
63  .path = "set interface ipsec spd",
64  .short_help =
65  "set interface ipsec spd <int> <id>",
66  .function = set_interface_spd_command_fn,
67 };
68 /* *INDENT-ON* */
69 
70 static clib_error_t *
72  unformat_input_t * input,
73  vlib_cli_command_t * cmd)
74 {
75  ipsec_main_t *im = &ipsec_main;
76  unformat_input_t _line_input, *line_input = &_line_input;
77  ipsec_sa_t sa;
78  int is_add = ~0;
79  u8 *ck = 0, *ik = 0;
80  clib_error_t *error = NULL;
81 
82  memset (&sa, 0, sizeof (sa));
83 
84  if (!unformat_user (input, unformat_line_input, line_input))
85  return 0;
86 
87  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
88  {
89  if (unformat (line_input, "add %u", &sa.id))
90  is_add = 1;
91  else if (unformat (line_input, "del %u", &sa.id))
92  is_add = 0;
93  else if (unformat (line_input, "spi %u", &sa.spi))
94  ;
95  else if (unformat (line_input, "esp"))
97  else if (unformat (line_input, "ah"))
98  {
100  }
101  else
102  if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck))
103  sa.crypto_key_len = vec_len (ck);
104  else
105  if (unformat
106  (line_input, "crypto-alg %U", unformat_ipsec_crypto_alg,
107  &sa.crypto_alg))
108  {
109  if (sa.crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
111  {
112  error = clib_error_return (0, "unsupported crypto-alg: '%U'",
114  sa.crypto_alg);
115  goto done;
116  }
117  }
118  else
119  if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik))
120  sa.integ_key_len = vec_len (ik);
121  else if (unformat (line_input, "integ-alg %U", unformat_ipsec_integ_alg,
122  &sa.integ_alg))
123  {
124  if (sa.integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
126  {
127  error = clib_error_return (0, "unsupported integ-alg: '%U'",
129  sa.integ_alg);
130  goto done;
131  }
132  }
133  else if (unformat (line_input, "tunnel-src %U",
135  sa.is_tunnel = 1;
136  else if (unformat (line_input, "tunnel-dst %U",
138  sa.is_tunnel = 1;
139  else if (unformat (line_input, "tunnel-src %U",
141  {
142  sa.is_tunnel = 1;
143  sa.is_tunnel_ip6 = 1;
144  }
145  else if (unformat (line_input, "tunnel-dst %U",
147  {
148  sa.is_tunnel = 1;
149  sa.is_tunnel_ip6 = 1;
150  }
151  else
152  {
153  error = clib_error_return (0, "parse error: '%U'",
154  format_unformat_error, line_input);
155  goto done;
156  }
157  }
158 
159  if (sa.crypto_key_len > sizeof (sa.crypto_key))
160  sa.crypto_key_len = sizeof (sa.crypto_key);
161 
162  if (sa.integ_key_len > sizeof (sa.integ_key))
163  sa.integ_key_len = sizeof (sa.integ_key);
164 
165  if (ck)
166  strncpy ((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len);
167 
168  if (ik)
169  strncpy ((char *) sa.integ_key, (char *) ik, sa.integ_key_len);
170 
171  if (is_add)
172  {
173  ASSERT (im->cb.check_support_cb);
174  error = im->cb.check_support_cb (&sa);
175  if (error)
176  goto done;
177  }
178 
179  ipsec_add_del_sa (vm, &sa, is_add);
180 
181 done:
182  unformat_free (line_input);
183 
184  return error;
185 }
186 
187 /* *INDENT-OFF* */
188 VLIB_CLI_COMMAND (ipsec_sa_add_del_command, static) = {
189  .path = "ipsec sa",
190  .short_help =
191  "ipsec sa [add|del]",
192  .function = ipsec_sa_add_del_command_fn,
193 };
194 /* *INDENT-ON* */
195 
196 static clib_error_t *
198  unformat_input_t * input,
199  vlib_cli_command_t * cmd)
200 {
201  unformat_input_t _line_input, *line_input = &_line_input;
202  u32 spd_id = ~0;
203  int is_add = ~0;
204  clib_error_t *error = NULL;
205 
206  if (!unformat_user (input, unformat_line_input, line_input))
207  return 0;
208 
209  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
210  {
211  if (unformat (line_input, "add"))
212  is_add = 1;
213  else if (unformat (line_input, "del"))
214  is_add = 0;
215  else if (unformat (line_input, "%u", &spd_id))
216  ;
217  else
218  {
219  error = clib_error_return (0, "parse error: '%U'",
220  format_unformat_error, line_input);
221  goto done;
222  }
223  }
224 
225  if (spd_id == ~0)
226  {
227  error = clib_error_return (0, "please specify SPD ID");
228  goto done;
229  }
230 
231  ipsec_add_del_spd (vm, spd_id, is_add);
232 
233 done:
234  unformat_free (line_input);
235 
236  return error;
237 }
238 
239 /* *INDENT-OFF* */
240 VLIB_CLI_COMMAND (ipsec_spd_add_del_command, static) = {
241  .path = "ipsec spd",
242  .short_help =
243  "ipsec spd [add|del] <id>",
244  .function = ipsec_spd_add_del_command_fn,
245 };
246 /* *INDENT-ON* */
247 
248 
249 static clib_error_t *
251  unformat_input_t * input,
252  vlib_cli_command_t * cmd)
253 {
254  unformat_input_t _line_input, *line_input = &_line_input;
255  ipsec_policy_t p;
256  int is_add = 0;
257  int is_ip_any = 1;
258  u32 tmp, tmp2;
259  clib_error_t *error = NULL;
260 
261  memset (&p, 0, sizeof (p));
262  p.lport.stop = p.rport.stop = ~0;
263  p.laddr.stop.ip4.as_u32 = p.raddr.stop.ip4.as_u32 = (u32) ~ 0;
264  p.laddr.stop.ip6.as_u64[0] = p.laddr.stop.ip6.as_u64[1] = (u64) ~ 0;
265  p.raddr.stop.ip6.as_u64[0] = p.raddr.stop.ip6.as_u64[1] = (u64) ~ 0;
266 
267  if (!unformat_user (input, unformat_line_input, line_input))
268  return 0;
269 
270  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
271  {
272  if (unformat (line_input, "add"))
273  is_add = 1;
274  else if (unformat (line_input, "del"))
275  is_add = 0;
276  else if (unformat (line_input, "spd %u", &p.id))
277  ;
278  else if (unformat (line_input, "inbound"))
279  p.is_outbound = 0;
280  else if (unformat (line_input, "outbound"))
281  p.is_outbound = 1;
282  else if (unformat (line_input, "priority %d", &p.priority))
283  ;
284  else if (unformat (line_input, "protocol %u", &tmp))
285  p.protocol = (u8) tmp;
286  else
287  if (unformat
288  (line_input, "action %U", unformat_ipsec_policy_action,
289  &p.policy))
290  {
291  if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
292  {
293  error = clib_error_return (0, "unsupported action: 'resolve'");
294  goto done;
295  }
296  }
297  else if (unformat (line_input, "sa %u", &p.sa_id))
298  ;
299  else if (unformat (line_input, "local-ip-range %U - %U",
302  is_ip_any = 0;
303  else if (unformat (line_input, "remote-ip-range %U - %U",
306  is_ip_any = 0;
307  else if (unformat (line_input, "local-ip-range %U - %U",
310  {
311  p.is_ipv6 = 1;
312  is_ip_any = 0;
313  }
314  else if (unformat (line_input, "remote-ip-range %U - %U",
317  {
318  p.is_ipv6 = 1;
319  is_ip_any = 0;
320  }
321  else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2))
322  {
323  p.lport.start = tmp;
324  p.lport.stop = tmp2;
325  }
326  else
327  if (unformat (line_input, "remote-port-range %u - %u", &tmp, &tmp2))
328  {
329  p.rport.start = tmp;
330  p.rport.stop = tmp2;
331  }
332  else
333  {
334  error = clib_error_return (0, "parse error: '%U'",
335  format_unformat_error, line_input);
336  goto done;
337  }
338  }
339 
340  /* Check if SA is for IPv6/AH which is not supported. Return error if TRUE. */
341  if (p.sa_id)
342  {
343  uword *p1;
344  ipsec_main_t *im = &ipsec_main;
345  ipsec_sa_t *sa = 0;
346  p1 = hash_get (im->sa_index_by_sa_id, p.sa_id);
347  sa = pool_elt_at_index (im->sad, p1[0]);
348  if (sa && sa->protocol == IPSEC_PROTOCOL_AH && is_add && p.is_ipv6)
349  {
350  error = clib_error_return (0, "AH not supported for IPV6: '%U'",
351  format_unformat_error, line_input);
352  goto done;
353  }
354  }
355  ipsec_add_del_policy (vm, &p, is_add);
356  if (is_ip_any)
357  {
358  p.is_ipv6 = 1;
359  ipsec_add_del_policy (vm, &p, is_add);
360  }
361 
362 done:
363  unformat_free (line_input);
364 
365  return error;
366 }
367 
368 /* *INDENT-OFF* */
369 VLIB_CLI_COMMAND (ipsec_policy_add_del_command, static) = {
370  .path = "ipsec policy",
371  .short_help =
372  "ipsec policy [add|del] spd <id> priority <n> ",
374 };
375 /* *INDENT-ON* */
376 
377 static clib_error_t *
379  unformat_input_t * input,
380  vlib_cli_command_t * cmd)
381 {
382  unformat_input_t _line_input, *line_input = &_line_input;
383  ipsec_sa_t sa;
384  u8 *ck = 0, *ik = 0;
385  clib_error_t *error = NULL;
386 
387  memset (&sa, 0, sizeof (sa));
388 
389  if (!unformat_user (input, unformat_line_input, line_input))
390  return 0;
391 
392  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
393  {
394  if (unformat (line_input, "%u", &sa.id))
395  ;
396  else
397  if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck))
398  sa.crypto_key_len = vec_len (ck);
399  else
400  if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik))
401  sa.integ_key_len = vec_len (ik);
402  else
403  {
404  error = clib_error_return (0, "parse error: '%U'",
405  format_unformat_error, line_input);
406  goto done;
407  }
408  }
409 
410  if (sa.crypto_key_len > sizeof (sa.crypto_key))
411  sa.crypto_key_len = sizeof (sa.crypto_key);
412 
413  if (sa.integ_key_len > sizeof (sa.integ_key))
414  sa.integ_key_len = sizeof (sa.integ_key);
415 
416  if (ck)
417  strncpy ((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len);
418 
419  if (ik)
420  strncpy ((char *) sa.integ_key, (char *) ik, sa.integ_key_len);
421 
422  ipsec_set_sa_key (vm, &sa);
423 
424 done:
425  unformat_free (line_input);
426 
427  return error;
428 }
429 
430 /* *INDENT-OFF* */
431 VLIB_CLI_COMMAND (set_ipsec_sa_key_command, static) = {
432  .path = "set ipsec sa",
433  .short_help =
434  "set ipsec sa <id> crypto-key <key> integ-key <key>",
435  .function = set_ipsec_sa_key_command_fn,
436 };
437 /* *INDENT-ON* */
438 
439 static clib_error_t *
441  unformat_input_t * input, vlib_cli_command_t * cmd)
442 {
443  ipsec_spd_t *spd;
444  ipsec_sa_t *sa;
445  ipsec_policy_t *p;
446  ipsec_main_t *im = &ipsec_main;
447  u32 *i;
450 
451  /* *INDENT-OFF* */
452  pool_foreach (sa, im->sad, ({
453  if (sa->id) {
454  vlib_cli_output(vm, "sa %u spi %u mode %s protocol %s", sa->id, sa->spi,
455  sa->is_tunnel ? "tunnel" : "transport",
456  sa->protocol ? "esp" : "ah");
457  if (sa->protocol == IPSEC_PROTOCOL_ESP) {
458  vlib_cli_output(vm, " crypto alg %U%s%U integrity alg %U%s%U",
459  format_ipsec_crypto_alg, sa->crypto_alg,
460  sa->crypto_alg ? " key " : "",
461  format_hex_bytes, sa->crypto_key, sa->crypto_key_len,
462  format_ipsec_integ_alg, sa->integ_alg,
463  sa->integ_alg ? " key " : "",
464  format_hex_bytes, sa->integ_key, sa->integ_key_len);
465  }
466  if (sa->is_tunnel && sa->is_tunnel_ip6) {
467  vlib_cli_output(vm, " tunnel src %U dst %U",
468  format_ip6_address, &sa->tunnel_src_addr.ip6,
469  format_ip6_address, &sa->tunnel_dst_addr.ip6);
470  } else if (sa->is_tunnel) {
471  vlib_cli_output(vm, " tunnel src %U dst %U",
472  format_ip4_address, &sa->tunnel_src_addr.ip4,
473  format_ip4_address, &sa->tunnel_dst_addr.ip4);
474  }
475  }
476  }));
477  /* *INDENT-ON* */
478 
479  /* *INDENT-OFF* */
480  pool_foreach (spd, im->spds, ({
481  vlib_cli_output(vm, "spd %u", spd->id);
482 
483  vlib_cli_output(vm, " outbound policies");
484  vec_foreach(i, spd->ipv4_outbound_policies)
485  {
486  p = pool_elt_at_index(spd->policies, *i);
487  vlib_cli_output(vm, " priority %d action %U protocol %s%s",
488  p->priority,
489  format_ipsec_policy_action, p->policy,
490  p->protocol ?
491  format(0, "%U", format_ip_protocol, p->protocol) :
492  (u8 *) "any",
493  p->policy == IPSEC_POLICY_ACTION_PROTECT ?
494  format(0, " sa %u", p->sa_id) :
495  (u8 *) "");
496  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
497  format_ip4_address, &p->laddr.start.ip4,
498  format_ip4_address, &p->laddr.stop.ip4,
499  p->lport.start, p->lport.stop);
500  vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
501  format_ip4_address, &p->raddr.start.ip4,
502  format_ip4_address, &p->raddr.stop.ip4,
503  p->rport.start, p->rport.stop);
504  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
505  p->counter.bytes);
506  };
507  vec_foreach(i, spd->ipv6_outbound_policies)
508  {
509  p = pool_elt_at_index(spd->policies, *i);
510  vlib_cli_output(vm, " priority %d action %U protocol %s%s",
511  p->priority,
512  format_ipsec_policy_action, p->policy,
513  p->protocol ?
514  format(0, "%U", format_ip_protocol, p->protocol) :
515  (u8 *) "any",
516  p->policy == IPSEC_POLICY_ACTION_PROTECT ?
517  format(0, " sa %u", p->sa_id) :
518  (u8 *) "");
519  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
520  format_ip6_address, &p->laddr.start.ip6,
521  format_ip6_address, &p->laddr.stop.ip6,
522  p->lport.start, p->lport.stop);
523  vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
524  format_ip6_address, &p->raddr.start.ip6,
525  format_ip6_address, &p->raddr.stop.ip6,
526  p->rport.start, p->rport.stop);
527  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
528  p->counter.bytes);
529  };
530  vlib_cli_output(vm, " inbound policies");
531  vec_foreach(i, spd->ipv4_inbound_protect_policy_indices)
532  {
533  p = pool_elt_at_index(spd->policies, *i);
534  vlib_cli_output(vm, " priority %d action %U protocol %s%s",
535  p->priority,
536  format_ipsec_policy_action, p->policy,
537  p->protocol ?
538  format(0, "%U", format_ip_protocol, p->protocol) :
539  (u8 *) "any",
540  p->policy == IPSEC_POLICY_ACTION_PROTECT ?
541  format(0, " sa %u", p->sa_id) :
542  (u8 *) "");
543  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
544  format_ip4_address, &p->laddr.start.ip4,
545  format_ip4_address, &p->laddr.stop.ip4,
546  p->lport.start, p->lport.stop);
547  vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
548  format_ip4_address, &p->raddr.start.ip4,
549  format_ip4_address, &p->raddr.stop.ip4,
550  p->rport.start, p->rport.stop);
551  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
552  p->counter.bytes);
553  };
554  vec_foreach(i, spd->ipv4_inbound_policy_discard_and_bypass_indices)
555  {
556  p = pool_elt_at_index(spd->policies, *i);
557  vlib_cli_output(vm, " priority %d action %U protocol %s%s",
558  p->priority,
559  format_ipsec_policy_action, p->policy,
560  p->protocol ?
561  format(0, "%U", format_ip_protocol, p->protocol) :
562  (u8 *) "any",
563  p->policy == IPSEC_POLICY_ACTION_PROTECT ?
564  format(0, " sa %u", p->sa_id) :
565  (u8 *) "");
566  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
567  format_ip4_address, &p->laddr.start.ip4,
568  format_ip4_address, &p->laddr.stop.ip4,
569  p->lport.start, p->lport.stop);
570  vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
571  format_ip4_address, &p->raddr.start.ip4,
572  format_ip4_address, &p->raddr.stop.ip4,
573  p->rport.start, p->rport.stop);
574  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
575  p->counter.bytes);
576  };
577  vec_foreach(i, spd->ipv6_inbound_protect_policy_indices)
578  {
579  p = pool_elt_at_index(spd->policies, *i);
580  vlib_cli_output(vm, " priority %d action %U protocol %s%s",
581  p->priority,
582  format_ipsec_policy_action, p->policy,
583  p->protocol ?
584  format(0, "%U", format_ip_protocol, p->protocol) :
585  (u8 *) "any",
586  p->policy == IPSEC_POLICY_ACTION_PROTECT ?
587  format(0, " sa %u", p->sa_id) :
588  (u8 *) "");
589  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
590  format_ip6_address, &p->laddr.start.ip6,
591  format_ip6_address, &p->laddr.stop.ip6,
592  p->lport.start, p->lport.stop);
593  vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
594  format_ip6_address, &p->raddr.start.ip6,
595  format_ip6_address, &p->raddr.stop.ip6,
596  p->rport.start, p->rport.stop);
597  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
598  p->counter.bytes);
599  };
600  vec_foreach(i, spd->ipv6_inbound_policy_discard_and_bypass_indices)
601  {
602  p = pool_elt_at_index(spd->policies, *i);
603  vlib_cli_output(vm, " priority %d action %U protocol %s%s",
604  p->priority,
605  format_ipsec_policy_action, p->policy,
606  p->protocol ?
607  format(0, "%U", format_ip_protocol, p->protocol) :
608  (u8 *) "any",
609  p->policy == IPSEC_POLICY_ACTION_PROTECT ?
610  format(0, " sa %u", p->sa_id) :
611  (u8 *) "");
612  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
613  format_ip6_address, &p->laddr.start.ip6,
614  format_ip6_address, &p->laddr.stop.ip6,
615  p->lport.start, p->lport.stop);
616  vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
617  format_ip6_address, &p->raddr.start.ip6,
618  format_ip6_address, &p->raddr.stop.ip6,
619  p->rport.start, p->rport.stop);
620  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
621  p->counter.bytes);
622  };
623  }));
624  /* *INDENT-ON* */
625 
626  vlib_cli_output (vm, "tunnel interfaces");
627  /* *INDENT-OFF* */
628  pool_foreach (t, im->tunnel_interfaces, ({
629  if (t->hw_if_index == ~0)
630  continue;
631  hi = vnet_get_hw_interface (im->vnet_main, t->hw_if_index);
632  vlib_cli_output(vm, " %s seq", hi->name);
633  sa = pool_elt_at_index(im->sad, t->output_sa_index);
634  vlib_cli_output(vm, " seq %u seq-hi %u esn %u anti-replay %u",
635  sa->seq, sa->seq_hi, sa->use_esn, sa->use_anti_replay);
636  vlib_cli_output(vm, " local-spi %u local-ip %U", sa->spi,
637  format_ip4_address, &sa->tunnel_src_addr.ip4);
638  vlib_cli_output(vm, " local-crypto %U %U",
639  format_ipsec_crypto_alg, sa->crypto_alg,
640  format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
641  vlib_cli_output(vm, " local-integrity %U %U",
642  format_ipsec_integ_alg, sa->integ_alg,
643  format_hex_bytes, sa->integ_key, sa->integ_key_len);
644  sa = pool_elt_at_index(im->sad, t->input_sa_index);
645  vlib_cli_output(vm, " last-seq %u last-seq-hi %u esn %u anti-replay %u window %U",
646  sa->last_seq, sa->last_seq_hi, sa->use_esn,
647  sa->use_anti_replay,
648  format_ipsec_replay_window, sa->replay_window);
649  vlib_cli_output(vm, " remote-spi %u remote-ip %U", sa->spi,
650  format_ip4_address, &sa->tunnel_src_addr.ip4);
651  vlib_cli_output(vm, " remote-crypto %U %U",
652  format_ipsec_crypto_alg, sa->crypto_alg,
653  format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
654  vlib_cli_output(vm, " remote-integrity %U %U",
655  format_ipsec_integ_alg, sa->integ_alg,
656  format_hex_bytes, sa->integ_key, sa->integ_key_len);
657  }));
658  /* *INDENT-ON* */
659  return 0;
660 }
661 
662 /* *INDENT-OFF* */
664  .path = "show ipsec",
665  .short_help = "show ipsec",
666  .function = show_ipsec_command_fn,
667 };
668 /* *INDENT-ON* */
669 
670 static clib_error_t *
672  unformat_input_t * input,
673  vlib_cli_command_t * cmd)
674 {
675  ipsec_main_t *im = &ipsec_main;
676  ipsec_spd_t *spd;
677  ipsec_policy_t *p;
678 
679  /* *INDENT-OFF* */
680  pool_foreach (spd, im->spds, ({
681  pool_foreach(p, spd->policies, ({
682  p->counter.packets = p->counter.bytes = 0;
683  }));
684  }));
685  /* *INDENT-ON* */
686 
687  return 0;
688 }
689 
690 /* *INDENT-OFF* */
692  .path = "clear ipsec counters",
693  .short_help = "clear ipsec counters",
695 };
696 /* *INDENT-ON* */
697 
698 static clib_error_t *
700  unformat_input_t * input,
701  vlib_cli_command_t * cmd)
702 {
703  unformat_input_t _line_input, *line_input = &_line_input;
705  int rv;
706  u32 num_m_args = 0;
707  clib_error_t *error = NULL;
708 
709  memset (&a, 0, sizeof (a));
710  a.is_add = 1;
711 
712  /* Get a line of input. */
713  if (!unformat_user (input, unformat_line_input, line_input))
714  return 0;
715 
716  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
717  {
718  if (unformat
719  (line_input, "local-ip %U", unformat_ip4_address, &a.local_ip))
720  num_m_args++;
721  else
722  if (unformat
723  (line_input, "remote-ip %U", unformat_ip4_address, &a.remote_ip))
724  num_m_args++;
725  else if (unformat (line_input, "local-spi %u", &a.local_spi))
726  num_m_args++;
727  else if (unformat (line_input, "remote-spi %u", &a.remote_spi))
728  num_m_args++;
729  else if (unformat (line_input, "del"))
730  a.is_add = 0;
731  else
732  {
733  error = clib_error_return (0, "unknown input `%U'",
734  format_unformat_error, line_input);
735  goto done;
736  }
737  }
738 
739  if (num_m_args < 4)
740  {
741  error = clib_error_return (0, "mandatory argument(s) missing");
742  goto done;
743  }
744 
745  rv = ipsec_add_del_tunnel_if (&a);
746 
747  switch (rv)
748  {
749  case 0:
750  break;
751  case VNET_API_ERROR_INVALID_VALUE:
752  if (a.is_add)
753  error = clib_error_return (0,
754  "IPSec tunnel interface already exists...");
755  else
756  error = clib_error_return (0, "IPSec tunnel interface not exists...");
757  goto done;
758  default:
759  error = clib_error_return (0, "ipsec_register_interface returned %d",
760  rv);
761  goto done;
762  }
763 
764 done:
765  unformat_free (line_input);
766 
767  return error;
768 }
769 
770 /* *INDENT-OFF* */
772  .path = "create ipsec tunnel",
773  .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> remote-ip <addr> remote-spi <spi>",
774  .function = create_ipsec_tunnel_command_fn,
775 };
776 /* *INDENT-ON* */
777 
778 static clib_error_t *
780  unformat_input_t * input,
781  vlib_cli_command_t * cmd)
782 {
783  unformat_input_t _line_input, *line_input = &_line_input;
784  ipsec_main_t *im = &ipsec_main;
786  u32 hw_if_index = (u32) ~ 0;
787  u32 alg;
788  u8 *key = 0;
789  clib_error_t *error = NULL;
790 
791  if (!unformat_user (input, unformat_line_input, line_input))
792  return 0;
793 
794  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
795  {
796  if (unformat (line_input, "%U",
797  unformat_vnet_hw_interface, im->vnet_main, &hw_if_index))
798  ;
799  else
800  if (unformat
801  (line_input, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
803  else
804  if (unformat
805  (line_input, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
807  else
808  if (unformat
809  (line_input, "local integ %U", unformat_ipsec_integ_alg, &alg))
811  else
812  if (unformat
813  (line_input, "remote integ %U", unformat_ipsec_integ_alg, &alg))
815  else if (unformat (line_input, "%U", unformat_hex_string, &key))
816  ;
817  else
818  {
819  error = clib_error_return (0, "parse error: '%U'",
820  format_unformat_error, line_input);
821  goto done;
822  }
823  }
824 
825  if (type == IPSEC_IF_SET_KEY_TYPE_NONE)
826  {
827  error = clib_error_return (0, "unknown key type");
828  goto done;
829  }
830 
831  if (alg > 0 && vec_len (key) == 0)
832  {
833  error = clib_error_return (0, "key is not specified");
834  goto done;
835  }
836 
837  if (hw_if_index == (u32) ~ 0)
838  {
839  error = clib_error_return (0, "interface not specified");
840  goto done;
841  }
842 
843  ipsec_set_interface_key (im->vnet_main, hw_if_index, type, alg, key);
844 
845 done:
846  vec_free (key);
847  unformat_free (line_input);
848 
849  return error;
850 }
851 
852 /* *INDENT-OFF* */
854  .path = "set interface ipsec key",
855  .short_help =
856  "set interface ipsec key <int> <local|remote> <crypto|integ> <key type> <key>",
857  .function = set_interface_key_command_fn,
858 };
859 /* *INDENT-ON* */
860 
861 clib_error_t *
863 {
864  return 0;
865 }
866 
868 
869 
870 /*
871  * fd.io coding-style-patch-verification: ON
872  *
873  * Local Variables:
874  * eval: (c-set-style "gnu")
875  * End:
876  */
unformat_function_t unformat_vnet_hw_interface
ip46_address_t stop
Definition: ipsec.h:148
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:353
vmrglw vmrglh hi
format_function_t format_ip_protocol
Definition: format.h:45
ipsec_spd_t * spds
Definition: ipsec.h:257
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
u16 stop
Definition: ipsec.h:153
int ipsec_add_del_policy(vlib_main_t *vm, ipsec_policy_t *policy, int is_add)
Definition: ipsec.c:155
ip46_address_t tunnel_src_addr
Definition: ipsec.h:130
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:378
a
Definition: bitmap.h:516
u32 id
Definition: ipsec.h:113
i32 priority
Definition: ipsec.h:197
int ipsec_set_interface_spd(vlib_main_t *vm, u32 sw_if_index, u32 spd_id, int is_add)
Definition: ipsec.c:42
#define NULL
Definition: clib.h:55
unformat_function_t unformat_hex_string
Definition: format.h:287
ipsec_integ_alg_t integ_alg
Definition: ipsec.h:121
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:699
u8 is_tunnel
Definition: ipsec.h:128
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:983
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
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:779
unformat_function_t unformat_vnet_sw_interface
static vlib_cli_command_t set_interface_key_command
(constructor) VLIB_CLI_COMMAND (set_interface_key_command)
Definition: ipsec_cli.c:853
u8 crypto_key[128]
Definition: ipsec.h:119
int ipsec_add_del_spd(vlib_main_t *vm, u32 spd_id, int is_add)
Definition: ipsec.c:89
u32 spi
Definition: ipsec.h:114
port_range_t lport
Definition: ipsec.h:205
format_function_t format_ip4_address
Definition: format.h:79
u8 integ_key[128]
Definition: ipsec.h:123
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:438
unformat_function_t unformat_ip4_address
Definition: format.h:76
static vlib_cli_command_t show_ipsec_command
(constructor) VLIB_CLI_COMMAND (show_ipsec_command)
Definition: ipsec_cli.c:663
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
ipsec_main_t ipsec_main
Definition: ipsec.c:28
uword unformat_ipsec_integ_alg(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:108
ip4_address_t remote_ip
Definition: ipsec.h:161
u16 start
Definition: ipsec.h:153
#define clib_error_return(e, args...)
Definition: error.h:99
ipsec_main_callbacks_t cb
Definition: ipsec.h:294
unsigned long u64
Definition: types.h:89
u8 * format_ipsec_crypto_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:58
unformat_function_t unformat_line_input
Definition: format.h:281
#define hash_get(h, key)
Definition: hash.h:248
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:459
static vlib_cli_command_t create_ipsec_tunnel_command
(constructor) VLIB_CLI_COMMAND (create_ipsec_tunnel_command)
Definition: ipsec_cli.c:771
u8 is_tunnel_ip6
Definition: ipsec.h:129
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:250
clib_error_t *(* check_support_cb)(ipsec_sa_t *sa)
Definition: ipsec.h:251
vnet_main_t * vnet_main
Definition: ipsec.h:270
struct _unformat_input_t unformat_input_t
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:26
uword unformat_ipsec_crypto_alg(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:76
ip46_address_range_t laddr
Definition: ipsec.h:202
ip46_address_t tunnel_dst_addr
Definition: ipsec.h:131
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:671
unformat_function_t unformat_ip6_address
Definition: format.h:94
ipsec_if_set_key_type_t
Definition: ipsec.h:185
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
format_function_t format_ip6_address
Definition: format.h:95
vlib_main_t * vm
Definition: buffer.c:283
int ipsec_add_del_sa(vlib_main_t *vm, ipsec_sa_t *new_sa, int is_add)
Definition: ipsec.c:414
clib_error_t * ipsec_cli_init(vlib_main_t *vm)
Definition: ipsec_cli.c:862
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
ip46_address_t start
Definition: ipsec.h:148
uword * sa_index_by_sa_id
Definition: ipsec.h:278
int ipsec_set_sa_key(vlib_main_t *vm, ipsec_sa_t *sa_update)
Definition: ipsec.c:465
port_range_t rport
Definition: ipsec.h:206
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
ip46_address_range_t raddr
Definition: ipsec.h:203
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
ip4_address_t local_ip
Definition: ipsec.h:161
ipsec_sa_t * sad
Definition: ipsec.h:258
u8 integ_key_len
Definition: ipsec.h:122
ipsec_protocol_t protocol
Definition: ipsec.h:115
uword unformat_ipsec_policy_action(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:44
u64 uword
Definition: types.h:112
u8 * format_ipsec_integ_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:90
u8 crypto_key_len
Definition: ipsec.h:118
u8 * format_ipsec_policy_action(u8 *s, va_list *args)
Definition: ipsec_format.c:26
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
u8 is_outbound
Definition: ipsec.h:198
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
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:71
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
ipsec_crypto_alg_t crypto_alg
Definition: ipsec.h:117
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:440
#define vec_foreach(var, vec)
Vector iterator.
int ipsec_add_del_tunnel_if(ipsec_add_del_tunnel_args_t *args)
Definition: ipsec_if.c:143
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:197
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
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:169
static vlib_cli_command_t clear_ipsec_counters_command
(constructor) VLIB_CLI_COMMAND (clear_ipsec_counters_command)
Definition: ipsec_cli.c:691