FD.io VPP  v18.07-rc0-415-g6c78436
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  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  u8 *protocol = NULL;
451  u8 *policy = NULL;
452 
453  /* *INDENT-OFF* */
454  pool_foreach (sa, im->sad, ({
455  if (sa->id) {
456  vlib_cli_output(vm, "sa %u spi %u mode %s protocol %s%s", sa->id, sa->spi,
457  sa->is_tunnel ? "tunnel" : "transport",
458  sa->protocol ? "esp" : "ah",
459  sa->udp_encap ? " udp-encap-enabled" : "");
460  if (sa->protocol == IPSEC_PROTOCOL_ESP) {
461  vlib_cli_output(vm, " crypto alg %U%s%U integrity alg %U%s%U",
462  format_ipsec_crypto_alg, sa->crypto_alg,
463  sa->crypto_alg ? " key " : "",
464  format_hex_bytes, sa->crypto_key, sa->crypto_key_len,
465  format_ipsec_integ_alg, sa->integ_alg,
466  sa->integ_alg ? " key " : "",
467  format_hex_bytes, sa->integ_key, sa->integ_key_len);
468  }
469  if (sa->is_tunnel && sa->is_tunnel_ip6) {
470  vlib_cli_output(vm, " tunnel src %U dst %U",
471  format_ip6_address, &sa->tunnel_src_addr.ip6,
472  format_ip6_address, &sa->tunnel_dst_addr.ip6);
473  } else if (sa->is_tunnel) {
474  vlib_cli_output(vm, " tunnel src %U dst %U",
475  format_ip4_address, &sa->tunnel_src_addr.ip4,
476  format_ip4_address, &sa->tunnel_dst_addr.ip4);
477  }
478  }
479  }));
480  /* *INDENT-ON* */
481 
482  /* *INDENT-OFF* */
483  pool_foreach (spd, im->spds, ({
484  vlib_cli_output(vm, "spd %u", spd->id);
485 
486  vlib_cli_output(vm, " outbound policies");
487  vec_foreach(i, spd->ipv4_outbound_policies)
488  {
489  p = pool_elt_at_index(spd->policies, *i);
490  vec_reset_length(protocol);
491  vec_reset_length(policy);
492  if (p->protocol) {
493  protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
494  } else {
495  protocol = format(protocol, "any");
496  }
497  if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
498  policy = format(policy, " sa %u", p->sa_id);
499  }
500 
501  vlib_cli_output(vm, " priority %d action %U protocol %v%v",
502  p->priority, format_ipsec_policy_action, p->policy,
503  protocol, policy);
504  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
505  format_ip4_address, &p->laddr.start.ip4,
506  format_ip4_address, &p->laddr.stop.ip4,
507  p->lport.start, p->lport.stop);
508  vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
509  format_ip4_address, &p->raddr.start.ip4,
510  format_ip4_address, &p->raddr.stop.ip4,
511  p->rport.start, p->rport.stop);
512  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
513  p->counter.bytes);
514  };
515  vec_foreach(i, spd->ipv6_outbound_policies)
516  {
517  p = pool_elt_at_index(spd->policies, *i);
518  vec_reset_length(protocol);
519  vec_reset_length(policy);
520  if (p->protocol) {
521  protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
522  } else {
523  protocol = format(protocol, "any");
524  }
525  if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
526  policy = format(policy, " sa %u", p->sa_id);
527  }
528  vlib_cli_output(vm, " priority %d action %U protocol %v%v",
529  p->priority, format_ipsec_policy_action, p->policy,
530  protocol, policy);
531  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
532  format_ip6_address, &p->laddr.start.ip6,
533  format_ip6_address, &p->laddr.stop.ip6,
534  p->lport.start, p->lport.stop);
535  vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
536  format_ip6_address, &p->raddr.start.ip6,
537  format_ip6_address, &p->raddr.stop.ip6,
538  p->rport.start, p->rport.stop);
539  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
540  p->counter.bytes);
541  };
542  vlib_cli_output(vm, " inbound policies");
543  vec_foreach(i, spd->ipv4_inbound_protect_policy_indices)
544  {
545  p = pool_elt_at_index(spd->policies, *i);
546  vec_reset_length(protocol);
547  vec_reset_length(policy);
548  if (p->protocol) {
549  protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
550  } else {
551  protocol = format(protocol, "any");
552  }
553  if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
554  policy = format(policy, " sa %u", p->sa_id);
555  }
556  vlib_cli_output(vm, " priority %d action %U protocol %v%v",
557  p->priority, format_ipsec_policy_action, p->policy,
558  protocol, policy);
559  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
560  format_ip4_address, &p->laddr.start.ip4,
561  format_ip4_address, &p->laddr.stop.ip4,
562  p->lport.start, p->lport.stop);
563  vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
564  format_ip4_address, &p->raddr.start.ip4,
565  format_ip4_address, &p->raddr.stop.ip4,
566  p->rport.start, p->rport.stop);
567  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
568  p->counter.bytes);
569  };
570  vec_foreach(i, spd->ipv4_inbound_policy_discard_and_bypass_indices)
571  {
572  p = pool_elt_at_index(spd->policies, *i);
573  vec_reset_length(protocol);
574  vec_reset_length(policy);
575  if (p->protocol) {
576  protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
577  } else {
578  protocol = format(protocol, "any");
579  }
580  if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
581  policy = format(policy, " sa %u", p->sa_id);
582  }
583  vlib_cli_output(vm, " priority %d action %U protocol %v%v",
584  p->priority, format_ipsec_policy_action, p->policy,
585  protocol, policy);
586  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
587  format_ip4_address, &p->laddr.start.ip4,
588  format_ip4_address, &p->laddr.stop.ip4,
589  p->lport.start, p->lport.stop);
590  vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
591  format_ip4_address, &p->raddr.start.ip4,
592  format_ip4_address, &p->raddr.stop.ip4,
593  p->rport.start, p->rport.stop);
594  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
595  p->counter.bytes);
596  };
597  vec_foreach(i, spd->ipv6_inbound_protect_policy_indices)
598  {
599  p = pool_elt_at_index(spd->policies, *i);
600  vec_reset_length(protocol);
601  vec_reset_length(policy);
602  if (p->protocol) {
603  protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
604  } else {
605  protocol = format(protocol, "any");
606  }
607  if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
608  policy = format(policy, " sa %u", p->sa_id);
609  }
610  vlib_cli_output(vm, " priority %d action %U protocol %v%v",
611  p->priority, format_ipsec_policy_action, p->policy,
612  protocol, policy);
613  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
614  format_ip6_address, &p->laddr.start.ip6,
615  format_ip6_address, &p->laddr.stop.ip6,
616  p->lport.start, p->lport.stop);
617  vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
618  format_ip6_address, &p->raddr.start.ip6,
619  format_ip6_address, &p->raddr.stop.ip6,
620  p->rport.start, p->rport.stop);
621  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
622  p->counter.bytes);
623  };
624  vec_foreach(i, spd->ipv6_inbound_policy_discard_and_bypass_indices)
625  {
626  p = pool_elt_at_index(spd->policies, *i);
627  vec_reset_length(protocol);
628  vec_reset_length(policy);
629  if (p->protocol) {
630  protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
631  } else {
632  protocol = format(protocol, "any");
633  }
634  if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
635  policy = format(policy, " sa %u", p->sa_id);
636  }
637  vlib_cli_output(vm, " priority %d action %U protocol %v%v",
638  p->priority, format_ipsec_policy_action, p->policy,
639  protocol, policy);
640  vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
641  format_ip6_address, &p->laddr.start.ip6,
642  format_ip6_address, &p->laddr.stop.ip6,
643  p->lport.start, p->lport.stop);
644  vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
645  format_ip6_address, &p->raddr.start.ip6,
646  format_ip6_address, &p->raddr.stop.ip6,
647  p->rport.start, p->rport.stop);
648  vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
649  p->counter.bytes);
650  };
651  }));
652  /* *INDENT-ON* */
653 
654  vlib_cli_output (vm, "tunnel interfaces");
655  /* *INDENT-OFF* */
656  pool_foreach (t, im->tunnel_interfaces, ({
657  if (t->hw_if_index == ~0)
658  continue;
659  hi = vnet_get_hw_interface (im->vnet_main, t->hw_if_index);
660  vlib_cli_output(vm, " %s seq", hi->name);
661  sa = pool_elt_at_index(im->sad, t->output_sa_index);
662  vlib_cli_output(vm, " seq %u seq-hi %u esn %u anti-replay %u",
663  sa->seq, sa->seq_hi, sa->use_esn, sa->use_anti_replay);
664  vlib_cli_output(vm, " local-spi %u local-ip %U", sa->spi,
665  format_ip4_address, &sa->tunnel_src_addr.ip4);
666  vlib_cli_output(vm, " local-crypto %U %U",
667  format_ipsec_crypto_alg, sa->crypto_alg,
668  format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
669  vlib_cli_output(vm, " local-integrity %U %U",
670  format_ipsec_integ_alg, sa->integ_alg,
671  format_hex_bytes, sa->integ_key, sa->integ_key_len);
672  sa = pool_elt_at_index(im->sad, t->input_sa_index);
673  vlib_cli_output(vm, " last-seq %u last-seq-hi %u esn %u anti-replay %u window %U",
674  sa->last_seq, sa->last_seq_hi, sa->use_esn,
675  sa->use_anti_replay,
676  format_ipsec_replay_window, sa->replay_window);
677  vlib_cli_output(vm, " remote-spi %u remote-ip %U", sa->spi,
678  format_ip4_address, &sa->tunnel_src_addr.ip4);
679  vlib_cli_output(vm, " remote-crypto %U %U",
680  format_ipsec_crypto_alg, sa->crypto_alg,
681  format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
682  vlib_cli_output(vm, " remote-integrity %U %U",
683  format_ipsec_integ_alg, sa->integ_alg,
684  format_hex_bytes, sa->integ_key, sa->integ_key_len);
685  }));
686  vec_free(policy);
687  vec_free(protocol);
688  /* *INDENT-ON* */
689  return 0;
690 }
691 
692 /* *INDENT-OFF* */
694  .path = "show ipsec",
695  .short_help = "show ipsec",
696  .function = show_ipsec_command_fn,
697 };
698 /* *INDENT-ON* */
699 
700 static clib_error_t *
702  unformat_input_t * input,
703  vlib_cli_command_t * cmd)
704 {
705  ipsec_main_t *im = &ipsec_main;
706  ipsec_spd_t *spd;
707  ipsec_policy_t *p;
708 
709  /* *INDENT-OFF* */
710  pool_foreach (spd, im->spds, ({
711  pool_foreach(p, spd->policies, ({
712  p->counter.packets = p->counter.bytes = 0;
713  }));
714  }));
715  /* *INDENT-ON* */
716 
717  return 0;
718 }
719 
720 /* *INDENT-OFF* */
722  .path = "clear ipsec counters",
723  .short_help = "clear ipsec counters",
725 };
726 /* *INDENT-ON* */
727 
728 static clib_error_t *
730  unformat_input_t * input,
731  vlib_cli_command_t * cmd)
732 {
733  unformat_input_t _line_input, *line_input = &_line_input;
735  int rv;
736  u32 num_m_args = 0;
737  clib_error_t *error = NULL;
738 
739  memset (&a, 0, sizeof (a));
740  a.is_add = 1;
741 
742  /* Get a line of input. */
743  if (!unformat_user (input, unformat_line_input, line_input))
744  return 0;
745 
746  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
747  {
748  if (unformat
749  (line_input, "local-ip %U", unformat_ip4_address, &a.local_ip))
750  num_m_args++;
751  else
752  if (unformat
753  (line_input, "remote-ip %U", unformat_ip4_address, &a.remote_ip))
754  num_m_args++;
755  else if (unformat (line_input, "local-spi %u", &a.local_spi))
756  num_m_args++;
757  else if (unformat (line_input, "remote-spi %u", &a.remote_spi))
758  num_m_args++;
759  else if (unformat (line_input, "instance %u", &a.show_instance))
760  a.renumber = 1;
761  else if (unformat (line_input, "del"))
762  a.is_add = 0;
763  else
764  {
765  error = clib_error_return (0, "unknown input `%U'",
766  format_unformat_error, line_input);
767  goto done;
768  }
769  }
770 
771  if (num_m_args < 4)
772  {
773  error = clib_error_return (0, "mandatory argument(s) missing");
774  goto done;
775  }
776 
777  rv = ipsec_add_del_tunnel_if (&a);
778 
779  switch (rv)
780  {
781  case 0:
782  break;
783  case VNET_API_ERROR_INVALID_VALUE:
784  if (a.is_add)
785  error = clib_error_return (0,
786  "IPSec tunnel interface already exists...");
787  else
788  error = clib_error_return (0, "IPSec tunnel interface not exists...");
789  goto done;
790  default:
791  error = clib_error_return (0, "ipsec_register_interface returned %d",
792  rv);
793  goto done;
794  }
795 
796 done:
797  unformat_free (line_input);
798 
799  return error;
800 }
801 
802 /* *INDENT-OFF* */
804  .path = "create ipsec tunnel",
805  .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> remote-ip <addr> remote-spi <spi> [instance <inst_num>]",
806  .function = create_ipsec_tunnel_command_fn,
807 };
808 /* *INDENT-ON* */
809 
810 static clib_error_t *
812  unformat_input_t * input,
813  vlib_cli_command_t * cmd)
814 {
815  unformat_input_t _line_input, *line_input = &_line_input;
816  ipsec_main_t *im = &ipsec_main;
818  u32 hw_if_index = (u32) ~ 0;
819  u32 alg;
820  u8 *key = 0;
821  clib_error_t *error = NULL;
822 
823  if (!unformat_user (input, unformat_line_input, line_input))
824  return 0;
825 
826  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
827  {
828  if (unformat (line_input, "%U",
829  unformat_vnet_hw_interface, im->vnet_main, &hw_if_index))
830  ;
831  else
832  if (unformat
833  (line_input, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
835  else
836  if (unformat
837  (line_input, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
839  else
840  if (unformat
841  (line_input, "local integ %U", unformat_ipsec_integ_alg, &alg))
843  else
844  if (unformat
845  (line_input, "remote integ %U", unformat_ipsec_integ_alg, &alg))
847  else if (unformat (line_input, "%U", unformat_hex_string, &key))
848  ;
849  else
850  {
851  error = clib_error_return (0, "parse error: '%U'",
852  format_unformat_error, line_input);
853  goto done;
854  }
855  }
856 
857  if (type == IPSEC_IF_SET_KEY_TYPE_NONE)
858  {
859  error = clib_error_return (0, "unknown key type");
860  goto done;
861  }
862 
863  if (alg > 0 && vec_len (key) == 0)
864  {
865  error = clib_error_return (0, "key is not specified");
866  goto done;
867  }
868 
869  if (hw_if_index == (u32) ~ 0)
870  {
871  error = clib_error_return (0, "interface not specified");
872  goto done;
873  }
874 
875  ipsec_set_interface_key (im->vnet_main, hw_if_index, type, alg, key);
876 
877 done:
878  vec_free (key);
879  unformat_free (line_input);
880 
881  return error;
882 }
883 
884 /* *INDENT-OFF* */
886  .path = "set interface ipsec key",
887  .short_help =
888  "set interface ipsec key <int> <local|remote> <crypto|integ> <key type> <key>",
889  .function = set_interface_key_command_fn,
890 };
891 /* *INDENT-ON* */
892 
893 clib_error_t *
895 {
896  return 0;
897 }
898 
900 
901 
902 /*
903  * fd.io coding-style-patch-verification: ON
904  *
905  * Local Variables:
906  * eval: (c-set-style "gnu")
907  * End:
908  */
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:378
a
Definition: bitmap.h:537
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: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:729
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:811
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:885
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:440
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:693
#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:281
#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:461
static vlib_cli_command_t create_ipsec_tunnel_command
(constructor) VLIB_CLI_COMMAND (create_ipsec_tunnel_command)
Definition: ipsec_cli.c:803
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:701
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:143
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:894
#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: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: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:169
static vlib_cli_command_t clear_ipsec_counters_command
(constructor) VLIB_CLI_COMMAND (clear_ipsec_counters_command)
Definition: ipsec_cli.c:721