FD.io VPP  v18.07.1-19-g511ce25
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
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, 0 /* enable nat traversal */ );
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  if (!p1)
348  {
349  error =
350  clib_error_return (0, "SA with index %u not found", p.sa_id);
351  goto done;
352  }
353  sa = pool_elt_at_index (im->sad, p1[0]);
354  if (sa && sa->protocol == IPSEC_PROTOCOL_AH && is_add && p.is_ipv6)
355  {
356  error = clib_error_return (0, "AH not supported for IPV6: '%U'",
357  format_unformat_error, line_input);
358  goto done;
359  }
360  }
361  ipsec_add_del_policy (vm, &p, is_add);
362  if (is_ip_any)
363  {
364  p.is_ipv6 = 1;
365  ipsec_add_del_policy (vm, &p, is_add);
366  }
367 
368 done:
369  unformat_free (line_input);
370 
371  return error;
372 }
373 
374 /* *INDENT-OFF* */
375 VLIB_CLI_COMMAND (ipsec_policy_add_del_command, static) = {
376  .path = "ipsec policy",
377  .short_help =
378  "ipsec policy [add|del] spd <id> priority <n> ",
380 };
381 /* *INDENT-ON* */
382 
383 static clib_error_t *
385  unformat_input_t * input,
386  vlib_cli_command_t * cmd)
387 {
388  unformat_input_t _line_input, *line_input = &_line_input;
389  ipsec_sa_t sa;
390  u8 *ck = 0, *ik = 0;
391  clib_error_t *error = NULL;
392 
393  memset (&sa, 0, sizeof (sa));
394 
395  if (!unformat_user (input, unformat_line_input, line_input))
396  return 0;
397 
398  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
399  {
400  if (unformat (line_input, "%u", &sa.id))
401  ;
402  else
403  if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck))
404  sa.crypto_key_len = vec_len (ck);
405  else
406  if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik))
407  sa.integ_key_len = vec_len (ik);
408  else
409  {
410  error = clib_error_return (0, "parse error: '%U'",
411  format_unformat_error, line_input);
412  goto done;
413  }
414  }
415 
416  if (sa.crypto_key_len > sizeof (sa.crypto_key))
417  sa.crypto_key_len = sizeof (sa.crypto_key);
418 
419  if (sa.integ_key_len > sizeof (sa.integ_key))
420  sa.integ_key_len = sizeof (sa.integ_key);
421 
422  if (ck)
423  strncpy ((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len);
424 
425  if (ik)
426  strncpy ((char *) sa.integ_key, (char *) ik, sa.integ_key_len);
427 
428  ipsec_set_sa_key (vm, &sa);
429 
430 done:
431  unformat_free (line_input);
432 
433  return error;
434 }
435 
436 /* *INDENT-OFF* */
437 VLIB_CLI_COMMAND (set_ipsec_sa_key_command, static) = {
438  .path = "set ipsec sa",
439  .short_help =
440  "set ipsec sa <id> crypto-key <key> integ-key <key>",
441  .function = set_ipsec_sa_key_command_fn,
442 };
443 /* *INDENT-ON* */
444 
445 static clib_error_t *
447  unformat_input_t * input, vlib_cli_command_t * cmd)
448 {
449  ipsec_spd_t *spd;
450  ipsec_sa_t *sa;
451  ipsec_policy_t *p;
452  ipsec_main_t *im = &ipsec_main;
453  u32 *i;
456  u8 *protocol = NULL;
457  u8 *policy = NULL;
458 
459  /* *INDENT-OFF* */
460  pool_foreach (sa, im->sad, ({
461  if (sa->id) {
462  vlib_cli_output(vm, "sa %u spi %u mode %s protocol %s%s", sa->id, sa->spi,
463  sa->is_tunnel ? "tunnel" : "transport",
464  sa->protocol ? "esp" : "ah",
465  sa->udp_encap ? " udp-encap-enabled" : "");
466  if (sa->protocol == IPSEC_PROTOCOL_ESP) {
467  vlib_cli_output(vm, " crypto alg %U%s%U integrity alg %U%s%U",
468  format_ipsec_crypto_alg, sa->crypto_alg,
469  sa->crypto_alg ? " key " : "",
470  format_hex_bytes, sa->crypto_key, sa->crypto_key_len,
471  format_ipsec_integ_alg, sa->integ_alg,
472  sa->integ_alg ? " key " : "",
473  format_hex_bytes, sa->integ_key, sa->integ_key_len);
474  }
475  if (sa->is_tunnel && sa->is_tunnel_ip6) {
476  vlib_cli_output(vm, " tunnel src %U dst %U",
477  format_ip6_address, &sa->tunnel_src_addr.ip6,
478  format_ip6_address, &sa->tunnel_dst_addr.ip6);
479  } else if (sa->is_tunnel) {
480  vlib_cli_output(vm, " tunnel src %U dst %U",
481  format_ip4_address, &sa->tunnel_src_addr.ip4,
482  format_ip4_address, &sa->tunnel_dst_addr.ip4);
483  }
484  }
485  }));
486  /* *INDENT-ON* */
487 
488  /* *INDENT-OFF* */
489  pool_foreach (spd, im->spds, ({
490  vlib_cli_output(vm, "spd %u", spd->id);
491 
492  vlib_cli_output(vm, " outbound policies");
493  vec_foreach(i, spd->ipv4_outbound_policies)
494  {
495  p = pool_elt_at_index(spd->policies, *i);
496  vec_reset_length(protocol);
497  vec_reset_length(policy);
498  if (p->protocol) {
499  protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
500  } else {
501  protocol = format(protocol, "any");
502  }
503  if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
504  policy = format(policy, " sa %u", p->sa_id);
505  }
506 
507  vlib_cli_output(vm, " priority %d action %U protocol %v%v",
508  p->priority, format_ipsec_policy_action, p->policy,
509  protocol, policy);
510  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
511  format_ip4_address, &p->laddr.start.ip4,
512  format_ip4_address, &p->laddr.stop.ip4,
513  p->lport.start, p->lport.stop);
514  vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
515  format_ip4_address, &p->raddr.start.ip4,
516  format_ip4_address, &p->raddr.stop.ip4,
517  p->rport.start, p->rport.stop);
518  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
519  p->counter.bytes);
520  };
521  vec_foreach(i, spd->ipv6_outbound_policies)
522  {
523  p = pool_elt_at_index(spd->policies, *i);
524  vec_reset_length(protocol);
525  vec_reset_length(policy);
526  if (p->protocol) {
527  protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
528  } else {
529  protocol = format(protocol, "any");
530  }
531  if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
532  policy = format(policy, " sa %u", p->sa_id);
533  }
534  vlib_cli_output(vm, " priority %d action %U protocol %v%v",
535  p->priority, format_ipsec_policy_action, p->policy,
536  protocol, policy);
537  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
538  format_ip6_address, &p->laddr.start.ip6,
539  format_ip6_address, &p->laddr.stop.ip6,
540  p->lport.start, p->lport.stop);
541  vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
542  format_ip6_address, &p->raddr.start.ip6,
543  format_ip6_address, &p->raddr.stop.ip6,
544  p->rport.start, p->rport.stop);
545  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
546  p->counter.bytes);
547  };
548  vlib_cli_output(vm, " inbound policies");
549  vec_foreach(i, spd->ipv4_inbound_protect_policy_indices)
550  {
551  p = pool_elt_at_index(spd->policies, *i);
552  vec_reset_length(protocol);
553  vec_reset_length(policy);
554  if (p->protocol) {
555  protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
556  } else {
557  protocol = format(protocol, "any");
558  }
559  if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
560  policy = format(policy, " sa %u", p->sa_id);
561  }
562  vlib_cli_output(vm, " priority %d action %U protocol %v%v",
563  p->priority, format_ipsec_policy_action, p->policy,
564  protocol, policy);
565  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
566  format_ip4_address, &p->laddr.start.ip4,
567  format_ip4_address, &p->laddr.stop.ip4,
568  p->lport.start, p->lport.stop);
569  vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
570  format_ip4_address, &p->raddr.start.ip4,
571  format_ip4_address, &p->raddr.stop.ip4,
572  p->rport.start, p->rport.stop);
573  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
574  p->counter.bytes);
575  };
576  vec_foreach(i, spd->ipv4_inbound_policy_discard_and_bypass_indices)
577  {
578  p = pool_elt_at_index(spd->policies, *i);
579  vec_reset_length(protocol);
580  vec_reset_length(policy);
581  if (p->protocol) {
582  protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
583  } else {
584  protocol = format(protocol, "any");
585  }
586  if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
587  policy = format(policy, " sa %u", p->sa_id);
588  }
589  vlib_cli_output(vm, " priority %d action %U protocol %v%v",
590  p->priority, format_ipsec_policy_action, p->policy,
591  protocol, policy);
592  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
593  format_ip4_address, &p->laddr.start.ip4,
594  format_ip4_address, &p->laddr.stop.ip4,
595  p->lport.start, p->lport.stop);
596  vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
597  format_ip4_address, &p->raddr.start.ip4,
598  format_ip4_address, &p->raddr.stop.ip4,
599  p->rport.start, p->rport.stop);
600  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
601  p->counter.bytes);
602  };
603  vec_foreach(i, spd->ipv6_inbound_protect_policy_indices)
604  {
605  p = pool_elt_at_index(spd->policies, *i);
606  vec_reset_length(protocol);
607  vec_reset_length(policy);
608  if (p->protocol) {
609  protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
610  } else {
611  protocol = format(protocol, "any");
612  }
613  if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
614  policy = format(policy, " sa %u", p->sa_id);
615  }
616  vlib_cli_output(vm, " priority %d action %U protocol %v%v",
617  p->priority, format_ipsec_policy_action, p->policy,
618  protocol, policy);
619  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
620  format_ip6_address, &p->laddr.start.ip6,
621  format_ip6_address, &p->laddr.stop.ip6,
622  p->lport.start, p->lport.stop);
623  vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
624  format_ip6_address, &p->raddr.start.ip6,
625  format_ip6_address, &p->raddr.stop.ip6,
626  p->rport.start, p->rport.stop);
627  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
628  p->counter.bytes);
629  };
630  vec_foreach(i, spd->ipv6_inbound_policy_discard_and_bypass_indices)
631  {
632  p = pool_elt_at_index(spd->policies, *i);
633  vec_reset_length(protocol);
634  vec_reset_length(policy);
635  if (p->protocol) {
636  protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
637  } else {
638  protocol = format(protocol, "any");
639  }
640  if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
641  policy = format(policy, " sa %u", p->sa_id);
642  }
643  vlib_cli_output(vm, " priority %d action %U protocol %v%v",
644  p->priority, format_ipsec_policy_action, p->policy,
645  protocol, policy);
646  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
647  format_ip6_address, &p->laddr.start.ip6,
648  format_ip6_address, &p->laddr.stop.ip6,
649  p->lport.start, p->lport.stop);
650  vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
651  format_ip6_address, &p->raddr.start.ip6,
652  format_ip6_address, &p->raddr.stop.ip6,
653  p->rport.start, p->rport.stop);
654  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
655  p->counter.bytes);
656  };
657  }));
658  /* *INDENT-ON* */
659 
660  vlib_cli_output (vm, "tunnel interfaces");
661  /* *INDENT-OFF* */
662  pool_foreach (t, im->tunnel_interfaces, ({
663  if (t->hw_if_index == ~0)
664  continue;
665  hi = vnet_get_hw_interface (im->vnet_main, t->hw_if_index);
666  vlib_cli_output(vm, " %s seq", hi->name);
667  sa = pool_elt_at_index(im->sad, t->output_sa_index);
668  vlib_cli_output(vm, " seq %u seq-hi %u esn %u anti-replay %u",
669  sa->seq, sa->seq_hi, sa->use_esn, sa->use_anti_replay);
670  vlib_cli_output(vm, " local-spi %u local-ip %U", sa->spi,
671  format_ip4_address, &sa->tunnel_src_addr.ip4);
672  vlib_cli_output(vm, " local-crypto %U %U",
673  format_ipsec_crypto_alg, sa->crypto_alg,
674  format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
675  vlib_cli_output(vm, " local-integrity %U %U",
676  format_ipsec_integ_alg, sa->integ_alg,
677  format_hex_bytes, sa->integ_key, sa->integ_key_len);
678  sa = pool_elt_at_index(im->sad, t->input_sa_index);
679  vlib_cli_output(vm, " last-seq %u last-seq-hi %u esn %u anti-replay %u window %U",
680  sa->last_seq, sa->last_seq_hi, sa->use_esn,
681  sa->use_anti_replay,
682  format_ipsec_replay_window, sa->replay_window);
683  vlib_cli_output(vm, " remote-spi %u remote-ip %U", sa->spi,
684  format_ip4_address, &sa->tunnel_src_addr.ip4);
685  vlib_cli_output(vm, " remote-crypto %U %U",
686  format_ipsec_crypto_alg, sa->crypto_alg,
687  format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
688  vlib_cli_output(vm, " remote-integrity %U %U",
689  format_ipsec_integ_alg, sa->integ_alg,
690  format_hex_bytes, sa->integ_key, sa->integ_key_len);
691  }));
692  vec_free(policy);
693  vec_free(protocol);
694  /* *INDENT-ON* */
695  return 0;
696 }
697 
698 /* *INDENT-OFF* */
700  .path = "show ipsec",
701  .short_help = "show ipsec",
702  .function = show_ipsec_command_fn,
703 };
704 /* *INDENT-ON* */
705 
706 static clib_error_t *
708  unformat_input_t * input,
709  vlib_cli_command_t * cmd)
710 {
711  ipsec_main_t *im = &ipsec_main;
712  ipsec_spd_t *spd;
713  ipsec_policy_t *p;
714 
715  /* *INDENT-OFF* */
716  pool_foreach (spd, im->spds, ({
717  pool_foreach(p, spd->policies, ({
718  p->counter.packets = p->counter.bytes = 0;
719  }));
720  }));
721  /* *INDENT-ON* */
722 
723  return 0;
724 }
725 
726 /* *INDENT-OFF* */
728  .path = "clear ipsec counters",
729  .short_help = "clear ipsec counters",
731 };
732 /* *INDENT-ON* */
733 
734 static clib_error_t *
736  unformat_input_t * input,
737  vlib_cli_command_t * cmd)
738 {
739  unformat_input_t _line_input, *line_input = &_line_input;
741  int rv;
742  u32 num_m_args = 0;
743  clib_error_t *error = NULL;
744 
745  memset (&a, 0, sizeof (a));
746  a.is_add = 1;
747 
748  /* Get a line of input. */
749  if (!unformat_user (input, unformat_line_input, line_input))
750  return 0;
751 
752  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
753  {
754  if (unformat
755  (line_input, "local-ip %U", unformat_ip4_address, &a.local_ip))
756  num_m_args++;
757  else
758  if (unformat
759  (line_input, "remote-ip %U", unformat_ip4_address, &a.remote_ip))
760  num_m_args++;
761  else if (unformat (line_input, "local-spi %u", &a.local_spi))
762  num_m_args++;
763  else if (unformat (line_input, "remote-spi %u", &a.remote_spi))
764  num_m_args++;
765  else if (unformat (line_input, "instance %u", &a.show_instance))
766  a.renumber = 1;
767  else if (unformat (line_input, "del"))
768  a.is_add = 0;
769  else
770  {
771  error = clib_error_return (0, "unknown input `%U'",
772  format_unformat_error, line_input);
773  goto done;
774  }
775  }
776 
777  if (num_m_args < 4)
778  {
779  error = clib_error_return (0, "mandatory argument(s) missing");
780  goto done;
781  }
782 
783  rv = ipsec_add_del_tunnel_if (&a);
784 
785  switch (rv)
786  {
787  case 0:
788  break;
789  case VNET_API_ERROR_INVALID_VALUE:
790  if (a.is_add)
791  error = clib_error_return (0,
792  "IPSec tunnel interface already exists...");
793  else
794  error = clib_error_return (0, "IPSec tunnel interface not exists...");
795  goto done;
796  default:
797  error = clib_error_return (0, "ipsec_register_interface returned %d",
798  rv);
799  goto done;
800  }
801 
802 done:
803  unformat_free (line_input);
804 
805  return error;
806 }
807 
808 /* *INDENT-OFF* */
810  .path = "create ipsec tunnel",
811  .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> remote-ip <addr> remote-spi <spi> [instance <inst_num>]",
812  .function = create_ipsec_tunnel_command_fn,
813 };
814 /* *INDENT-ON* */
815 
816 static clib_error_t *
818  unformat_input_t * input,
819  vlib_cli_command_t * cmd)
820 {
821  unformat_input_t _line_input, *line_input = &_line_input;
822  ipsec_main_t *im = &ipsec_main;
824  u32 hw_if_index = (u32) ~ 0;
825  u32 alg;
826  u8 *key = 0;
827  clib_error_t *error = NULL;
828 
829  if (!unformat_user (input, unformat_line_input, line_input))
830  return 0;
831 
832  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
833  {
834  if (unformat (line_input, "%U",
835  unformat_vnet_hw_interface, im->vnet_main, &hw_if_index))
836  ;
837  else
838  if (unformat
839  (line_input, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
841  else
842  if (unformat
843  (line_input, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
845  else
846  if (unformat
847  (line_input, "local integ %U", unformat_ipsec_integ_alg, &alg))
849  else
850  if (unformat
851  (line_input, "remote integ %U", unformat_ipsec_integ_alg, &alg))
853  else if (unformat (line_input, "%U", unformat_hex_string, &key))
854  ;
855  else
856  {
857  error = clib_error_return (0, "parse error: '%U'",
858  format_unformat_error, line_input);
859  goto done;
860  }
861  }
862 
863  if (type == IPSEC_IF_SET_KEY_TYPE_NONE)
864  {
865  error = clib_error_return (0, "unknown key type");
866  goto done;
867  }
868 
869  if (alg > 0 && vec_len (key) == 0)
870  {
871  error = clib_error_return (0, "key is not specified");
872  goto done;
873  }
874 
875  if (hw_if_index == (u32) ~ 0)
876  {
877  error = clib_error_return (0, "interface not specified");
878  goto done;
879  }
880 
881  ipsec_set_interface_key (im->vnet_main, hw_if_index, type, alg, key);
882 
883 done:
884  vec_free (key);
885  unformat_free (line_input);
886 
887  return error;
888 }
889 
890 /* *INDENT-OFF* */
892  .path = "set interface ipsec key",
893  .short_help =
894  "set interface ipsec key <int> <local|remote> <crypto|integ> <key type> <key>",
895  .function = set_interface_key_command_fn,
896 };
897 /* *INDENT-ON* */
898 
899 clib_error_t *
901 {
902  return 0;
903 }
904 
906 
907 
908 /*
909  * fd.io coding-style-patch-verification: ON
910  *
911  * Local Variables:
912  * eval: (c-set-style "gnu")
913  * End:
914  */
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:484
vmrglw vmrglh hi
format_function_t format_ip_protocol
Definition: format.h:45
ipsec_spd_t * spds
Definition: ipsec.h:263
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:152
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:384
a
Definition: bitmap.h:538
u32 id
Definition: ipsec.h:113
i32 priority
Definition: ipsec.h:200
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:55
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:735
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:817
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:891
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:91
u32 spi
Definition: ipsec.h:114
port_range_t lport
Definition: ipsec.h:208
format_function_t format_ip4_address
Definition: format.h:81
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:76
static vlib_cli_command_t show_ipsec_command
(constructor) VLIB_CLI_COMMAND (show_ipsec_command)
Definition: ipsec_cli.c:699
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:156
ipsec_main_t ipsec_main
Definition: ipsec.c:30
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:301
unsigned int u32
Definition: types.h:88
u8 * format_ipsec_crypto_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:58
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:809
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:257
vnet_main_t * vnet_main
Definition: ipsec.h:276
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:205
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:707
unformat_function_t unformat_ip6_address
Definition: format.h:97
ipsec_if_set_key_type_t
Definition: ipsec.h:188
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
format_function_t format_ip6_address
Definition: format.h:99
vlib_main_t * vm
Definition: buffer.c:294
clib_error_t * ipsec_cli_init(vlib_main_t *vm)
Definition: ipsec_cli.c:900
#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:284
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:209
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
ip46_address_range_t raddr
Definition: ipsec.h:206
#define ASSERT(truth)
ip4_address_t local_ip
Definition: ipsec.h:162
ipsec_sa_t * sad
Definition: ipsec.h:264
u8 integ_key_len
Definition: ipsec.h:122
int ipsec_add_del_sa(vlib_main_t *vm, ipsec_sa_t *new_sa, int is_add, u8 udp_encap)
Definition: ipsec.c:414
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:201
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:446
#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:197
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:681
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:727