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