2 * decap.c : IPSec tunnel support
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <vnet/vnet.h>
19 #include <vnet/api_errno.h>
20 #include <vnet/ip/ip.h>
21 #include <vnet/interface.h>
23 #include <vnet/ipsec/ipsec.h>
26 set_interface_spd_command_fn (vlib_main_t * vm,
27 unformat_input_t * input,
28 vlib_cli_command_t * cmd)
30 unformat_input_t _line_input, *line_input = &_line_input;
31 ipsec_main_t *im = &ipsec_main;
32 u32 sw_if_index = (u32) ~ 0;
36 if (!unformat_user (input, unformat_line_input, line_input))
40 (line_input, "%U %u", unformat_vnet_sw_interface, im->vnet_main,
41 &sw_if_index, &spd_id))
43 else if (unformat (line_input, "del"))
46 return clib_error_return (0, "parse error: '%U'",
47 format_unformat_error, line_input);
49 unformat_free (line_input);
51 ipsec_set_interface_spd (vm, sw_if_index, spd_id, is_add);
57 VLIB_CLI_COMMAND (set_interface_spd_command, static) = {
58 .path = "set interface ipsec spd",
60 "set interface ipsec spd <int> <id>",
61 .function = set_interface_spd_command_fn,
66 ipsec_sa_add_del_command_fn (vlib_main_t * vm,
67 unformat_input_t * input,
68 vlib_cli_command_t * cmd)
70 unformat_input_t _line_input, *line_input = &_line_input;
75 memset (&sa, 0, sizeof (sa));
77 if (!unformat_user (input, unformat_line_input, line_input))
80 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
82 if (unformat (line_input, "add %u", &sa.id))
84 else if (unformat (line_input, "del %u", &sa.id))
86 else if (unformat (line_input, "spi %u", &sa.spi))
88 else if (unformat (line_input, "esp"))
89 sa.protocol = IPSEC_PROTOCOL_ESP;
90 else if (unformat (line_input, "ah"))
91 //sa.protocol = IPSEC_PROTOCOL_AH;
92 return clib_error_return (0, "unsupported security protocol 'AH'");
94 if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck))
95 sa.crypto_key_len = vec_len (ck);
98 (line_input, "crypto-alg %U", unformat_ipsec_crypto_alg,
101 if (sa.crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
102 sa.crypto_alg >= IPSEC_CRYPTO_N_ALG)
103 return clib_error_return (0, "unsupported crypto-alg: '%U'",
104 format_ipsec_crypto_alg, sa.crypto_alg);
107 if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik))
108 sa.integ_key_len = vec_len (ik);
109 else if (unformat (line_input, "integ-alg %U", unformat_ipsec_integ_alg,
113 if (sa.integ_alg < IPSEC_INTEG_ALG_NONE ||
115 if (sa.integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
117 sa.integ_alg >= IPSEC_INTEG_N_ALG)
118 return clib_error_return (0, "unsupported integ-alg: '%U'",
119 format_ipsec_integ_alg, sa.integ_alg);
121 else if (unformat (line_input, "tunnel-src %U",
122 unformat_ip4_address, &sa.tunnel_src_addr.ip4))
124 else if (unformat (line_input, "tunnel-dst %U",
125 unformat_ip4_address, &sa.tunnel_dst_addr.ip4))
127 else if (unformat (line_input, "tunnel-src %U",
128 unformat_ip6_address, &sa.tunnel_src_addr.ip6))
131 sa.is_tunnel_ip6 = 1;
133 else if (unformat (line_input, "tunnel-dst %U",
134 unformat_ip6_address, &sa.tunnel_dst_addr.ip6))
137 sa.is_tunnel_ip6 = 1;
140 return clib_error_return (0, "parse error: '%U'",
141 format_unformat_error, line_input);
145 /*Special cases, aes-gcm-128 encryption */
146 if (sa.crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
148 if (sa.integ_alg != IPSEC_INTEG_ALG_NONE
149 && sa.integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
150 return clib_error_return (0,
151 "unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
152 else /*set integ-alg internally to aes-gcm-128 */
153 sa.integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
155 else if (sa.integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
156 return clib_error_return (0, "unsupported integ-alg: aes-gcm-128");
157 else if (sa.integ_alg == IPSEC_INTEG_ALG_NONE)
158 return clib_error_return (0, "unsupported integ-alg: none");
161 unformat_free (line_input);
163 if (sa.crypto_key_len > sizeof (sa.crypto_key))
164 sa.crypto_key_len = sizeof (sa.crypto_key);
166 if (sa.integ_key_len > sizeof (sa.integ_key))
167 sa.integ_key_len = sizeof (sa.integ_key);
170 strncpy ((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len);
173 strncpy ((char *) sa.integ_key, (char *) ik, sa.integ_key_len);
175 ipsec_add_del_sa (vm, &sa, is_add);
181 VLIB_CLI_COMMAND (ipsec_sa_add_del_command, static) = {
184 "ipsec sa [add|del]",
185 .function = ipsec_sa_add_del_command_fn,
189 static clib_error_t *
190 ipsec_spd_add_del_command_fn (vlib_main_t * vm,
191 unformat_input_t * input,
192 vlib_cli_command_t * cmd)
194 unformat_input_t _line_input, *line_input = &_line_input;
198 if (!unformat_user (input, unformat_line_input, line_input))
201 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
203 if (unformat (line_input, "add"))
205 else if (unformat (line_input, "del"))
207 else if (unformat (line_input, "%u", &spd_id))
210 return clib_error_return (0, "parse error: '%U'",
211 format_unformat_error, line_input);
214 unformat_free (line_input);
217 return clib_error_return (0, "please specify SPD ID");
219 ipsec_add_del_spd (vm, spd_id, is_add);
225 VLIB_CLI_COMMAND (ipsec_spd_add_del_command, static) = {
228 "ipsec spd [add|del] <id>",
229 .function = ipsec_spd_add_del_command_fn,
234 static clib_error_t *
235 ipsec_policy_add_del_command_fn (vlib_main_t * vm,
236 unformat_input_t * input,
237 vlib_cli_command_t * cmd)
239 unformat_input_t _line_input, *line_input = &_line_input;
245 memset (&p, 0, sizeof (p));
246 p.lport.stop = p.rport.stop = ~0;
247 p.laddr.stop.ip4.as_u32 = p.raddr.stop.ip4.as_u32 = (u32) ~ 0;
248 p.laddr.stop.ip6.as_u64[0] = p.laddr.stop.ip6.as_u64[1] = (u64) ~ 0;
249 p.raddr.stop.ip6.as_u64[0] = p.raddr.stop.ip6.as_u64[1] = (u64) ~ 0;
251 if (!unformat_user (input, unformat_line_input, line_input))
254 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
256 if (unformat (line_input, "add"))
258 else if (unformat (line_input, "del"))
260 else if (unformat (line_input, "spd %u", &p.id))
262 else if (unformat (line_input, "inbound"))
264 else if (unformat (line_input, "outbound"))
266 else if (unformat (line_input, "priority %d", &p.priority))
268 else if (unformat (line_input, "protocol %u", &tmp))
269 p.protocol = (u8) tmp;
272 (line_input, "action %U", unformat_ipsec_policy_action,
275 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
276 return clib_error_return (0, "unsupported action: 'resolve'");
278 else if (unformat (line_input, "sa %u", &p.sa_id))
280 else if (unformat (line_input, "local-ip-range %U - %U",
281 unformat_ip4_address, &p.laddr.start.ip4,
282 unformat_ip4_address, &p.laddr.stop.ip4))
284 else if (unformat (line_input, "remote-ip-range %U - %U",
285 unformat_ip4_address, &p.raddr.start.ip4,
286 unformat_ip4_address, &p.raddr.stop.ip4))
288 else if (unformat (line_input, "local-ip-range %U - %U",
289 unformat_ip6_address, &p.laddr.start.ip6,
290 unformat_ip6_address, &p.laddr.stop.ip6))
295 else if (unformat (line_input, "remote-ip-range %U - %U",
296 unformat_ip6_address, &p.raddr.start.ip6,
297 unformat_ip6_address, &p.raddr.stop.ip6))
302 else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2))
308 if (unformat (line_input, "remote-port-range %u - %u", &tmp, &tmp2))
314 return clib_error_return (0, "parse error: '%U'",
315 format_unformat_error, line_input);
318 unformat_free (line_input);
320 ipsec_add_del_policy (vm, &p, is_add);
324 ipsec_add_del_policy (vm, &p, is_add);
330 VLIB_CLI_COMMAND (ipsec_policy_add_del_command, static) = {
331 .path = "ipsec policy",
333 "ipsec policy [add|del] spd <id> priority <n> ",
334 .function = ipsec_policy_add_del_command_fn,
338 static clib_error_t *
339 set_ipsec_sa_key_command_fn (vlib_main_t * vm,
340 unformat_input_t * input,
341 vlib_cli_command_t * cmd)
343 unformat_input_t _line_input, *line_input = &_line_input;
347 memset (&sa, 0, sizeof (sa));
349 if (!unformat_user (input, unformat_line_input, line_input))
352 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
354 if (unformat (line_input, "%u", &sa.id))
357 if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck))
358 sa.crypto_key_len = vec_len (ck);
360 if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik))
361 sa.integ_key_len = vec_len (ik);
363 return clib_error_return (0, "parse error: '%U'",
364 format_unformat_error, line_input);
367 unformat_free (line_input);
369 if (sa.crypto_key_len > sizeof (sa.crypto_key))
370 sa.crypto_key_len = sizeof (sa.crypto_key);
372 if (sa.integ_key_len > sizeof (sa.integ_key))
373 sa.integ_key_len = sizeof (sa.integ_key);
376 strncpy ((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len);
379 strncpy ((char *) sa.integ_key, (char *) ik, sa.integ_key_len);
381 ipsec_set_sa_key (vm, &sa);
387 VLIB_CLI_COMMAND (set_ipsec_sa_key_command, static) = {
388 .path = "set ipsec sa",
390 "set ipsec sa <id> crypto-key <key> integ-key <key>",
391 .function = set_ipsec_sa_key_command_fn,
395 static clib_error_t *
396 show_ipsec_command_fn (vlib_main_t * vm,
397 unformat_input_t * input, vlib_cli_command_t * cmd)
402 ipsec_main_t *im = &ipsec_main;
404 ipsec_tunnel_if_t *t;
405 vnet_hw_interface_t *hi;
408 pool_foreach (sa, im->sad, ({
410 vlib_cli_output(vm, "sa %u spi %u mode %s protocol %s", sa->id, sa->spi,
411 sa->is_tunnel ? "tunnel" : "transport",
412 sa->protocol ? "esp" : "ah");
413 if (sa->protocol == IPSEC_PROTOCOL_ESP) {
414 vlib_cli_output(vm, " crypto alg %U%s%U integrity alg %U%s%U",
415 format_ipsec_crypto_alg, sa->crypto_alg,
416 sa->crypto_alg ? " key " : "",
417 format_hex_bytes, sa->crypto_key, sa->crypto_key_len,
418 format_ipsec_integ_alg, sa->integ_alg,
419 sa->integ_alg ? " key " : "",
420 format_hex_bytes, sa->integ_key, sa->integ_key_len);
422 if (sa->is_tunnel && sa->is_tunnel_ip6) {
423 vlib_cli_output(vm, " tunnel src %U dst %U",
424 format_ip6_address, &sa->tunnel_src_addr.ip6,
425 format_ip6_address, &sa->tunnel_dst_addr.ip6);
426 } else if (sa->is_tunnel) {
427 vlib_cli_output(vm, " tunnel src %U dst %U",
428 format_ip4_address, &sa->tunnel_src_addr.ip4,
429 format_ip4_address, &sa->tunnel_dst_addr.ip4);
436 pool_foreach (spd, im->spds, ({
437 vlib_cli_output(vm, "spd %u", spd->id);
439 vlib_cli_output(vm, " outbound policies");
440 vec_foreach(i, spd->ipv4_outbound_policies)
442 p = pool_elt_at_index(spd->policies, *i);
443 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
445 format_ipsec_policy_action, p->policy,
447 format(0, "%U", format_ip_protocol, p->protocol) :
449 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
450 format(0, " sa %u", p->sa_id) :
452 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
453 format_ip4_address, &p->laddr.start.ip4,
454 format_ip4_address, &p->laddr.stop.ip4,
455 p->lport.start, p->lport.stop);
456 vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
457 format_ip4_address, &p->raddr.start.ip4,
458 format_ip4_address, &p->raddr.stop.ip4,
459 p->rport.start, p->rport.stop);
460 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
463 vec_foreach(i, spd->ipv6_outbound_policies)
465 p = pool_elt_at_index(spd->policies, *i);
466 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
468 format_ipsec_policy_action, p->policy,
470 format(0, "%U", format_ip_protocol, p->protocol) :
472 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
473 format(0, " sa %u", p->sa_id) :
475 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
476 format_ip6_address, &p->laddr.start.ip6,
477 format_ip6_address, &p->laddr.stop.ip6,
478 p->lport.start, p->lport.stop);
479 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
480 format_ip6_address, &p->raddr.start.ip6,
481 format_ip6_address, &p->raddr.stop.ip6,
482 p->rport.start, p->rport.stop);
483 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
486 vlib_cli_output(vm, " inbound policies");
487 vec_foreach(i, spd->ipv4_inbound_protect_policy_indices)
489 p = pool_elt_at_index(spd->policies, *i);
490 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
492 format_ipsec_policy_action, p->policy,
494 format(0, "%U", format_ip_protocol, p->protocol) :
496 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
497 format(0, " sa %u", p->sa_id) :
499 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
500 format_ip4_address, &p->laddr.start.ip4,
501 format_ip4_address, &p->laddr.stop.ip4,
502 p->lport.start, p->lport.stop);
503 vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
504 format_ip4_address, &p->raddr.start.ip4,
505 format_ip4_address, &p->raddr.stop.ip4,
506 p->rport.start, p->rport.stop);
507 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
510 vec_foreach(i, spd->ipv4_inbound_policy_discard_and_bypass_indices)
512 p = pool_elt_at_index(spd->policies, *i);
513 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
515 format_ipsec_policy_action, p->policy,
517 format(0, "%U", format_ip_protocol, p->protocol) :
519 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
520 format(0, " sa %u", p->sa_id) :
522 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
523 format_ip4_address, &p->laddr.start.ip4,
524 format_ip4_address, &p->laddr.stop.ip4,
525 p->lport.start, p->lport.stop);
526 vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
527 format_ip4_address, &p->raddr.start.ip4,
528 format_ip4_address, &p->raddr.stop.ip4,
529 p->rport.start, p->rport.stop);
530 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
533 vec_foreach(i, spd->ipv6_inbound_protect_policy_indices)
535 p = pool_elt_at_index(spd->policies, *i);
536 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
538 format_ipsec_policy_action, p->policy,
540 format(0, "%U", format_ip_protocol, p->protocol) :
542 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
543 format(0, " sa %u", p->sa_id) :
545 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
546 format_ip6_address, &p->laddr.start.ip6,
547 format_ip6_address, &p->laddr.stop.ip6,
548 p->lport.start, p->lport.stop);
549 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
550 format_ip6_address, &p->raddr.start.ip6,
551 format_ip6_address, &p->raddr.stop.ip6,
552 p->rport.start, p->rport.stop);
553 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
556 vec_foreach(i, spd->ipv6_inbound_policy_discard_and_bypass_indices)
558 p = pool_elt_at_index(spd->policies, *i);
559 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
561 format_ipsec_policy_action, p->policy,
563 format(0, "%U", format_ip_protocol, p->protocol) :
565 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
566 format(0, " sa %u", p->sa_id) :
568 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
569 format_ip6_address, &p->laddr.start.ip6,
570 format_ip6_address, &p->laddr.stop.ip6,
571 p->lport.start, p->lport.stop);
572 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
573 format_ip6_address, &p->raddr.start.ip6,
574 format_ip6_address, &p->raddr.stop.ip6,
575 p->rport.start, p->rport.stop);
576 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
582 vlib_cli_output (vm, "tunnel interfaces");
584 pool_foreach (t, im->tunnel_interfaces, ({
585 if (t->hw_if_index == ~0)
587 hi = vnet_get_hw_interface (im->vnet_main, t->hw_if_index);
588 vlib_cli_output(vm, " %s seq", hi->name);
589 sa = pool_elt_at_index(im->sad, t->output_sa_index);
590 vlib_cli_output(vm, " seq %u seq-hi %u esn %u anti-replay %u",
591 sa->seq, sa->seq_hi, sa->use_esn, sa->use_anti_replay);
592 vlib_cli_output(vm, " local-spi %u local-ip %U", sa->spi,
593 format_ip4_address, &sa->tunnel_src_addr.ip4);
594 vlib_cli_output(vm, " local-crypto %U %U",
595 format_ipsec_crypto_alg, sa->crypto_alg,
596 format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
597 vlib_cli_output(vm, " local-integrity %U %U",
598 format_ipsec_integ_alg, sa->integ_alg,
599 format_hex_bytes, sa->integ_key, sa->integ_key_len);
600 sa = pool_elt_at_index(im->sad, t->input_sa_index);
601 vlib_cli_output(vm, " last-seq %u last-seq-hi %u esn %u anti-replay %u window %U",
602 sa->last_seq, sa->last_seq_hi, sa->use_esn,
604 format_ipsec_replay_window, sa->replay_window);
605 vlib_cli_output(vm, " remote-spi %u remote-ip %U", sa->spi,
606 format_ip4_address, &sa->tunnel_src_addr.ip4);
607 vlib_cli_output(vm, " remote-crypto %U %U",
608 format_ipsec_crypto_alg, sa->crypto_alg,
609 format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
610 vlib_cli_output(vm, " remote-integrity %U %U",
611 format_ipsec_integ_alg, sa->integ_alg,
612 format_hex_bytes, sa->integ_key, sa->integ_key_len);
619 VLIB_CLI_COMMAND (show_ipsec_command, static) = {
620 .path = "show ipsec",
621 .short_help = "show ipsec",
622 .function = show_ipsec_command_fn,
626 static clib_error_t *
627 clear_ipsec_counters_command_fn (vlib_main_t * vm,
628 unformat_input_t * input,
629 vlib_cli_command_t * cmd)
631 ipsec_main_t *im = &ipsec_main;
636 pool_foreach (spd, im->spds, ({
637 pool_foreach(p, spd->policies, ({
638 p->counter.packets = p->counter.bytes = 0;
647 VLIB_CLI_COMMAND (clear_ipsec_counters_command, static) = {
648 .path = "clear ipsec counters",
649 .short_help = "clear ipsec counters",
650 .function = clear_ipsec_counters_command_fn,
654 static clib_error_t *
655 create_ipsec_tunnel_command_fn (vlib_main_t * vm,
656 unformat_input_t * input,
657 vlib_cli_command_t * cmd)
659 unformat_input_t _line_input, *line_input = &_line_input;
660 ipsec_add_del_tunnel_args_t a;
664 memset (&a, 0, sizeof (a));
667 /* Get a line of input. */
668 if (!unformat_user (input, unformat_line_input, line_input))
671 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
674 (line_input, "local-ip %U", unformat_ip4_address, &a.local_ip))
678 (line_input, "remote-ip %U", unformat_ip4_address, &a.remote_ip))
680 else if (unformat (line_input, "local-spi %u", &a.local_spi))
682 else if (unformat (line_input, "remote-spi %u", &a.remote_spi))
684 else if (unformat (line_input, "del"))
687 return clib_error_return (0, "unknown input `%U'",
688 format_unformat_error, input);
690 unformat_free (line_input);
693 return clib_error_return (0, "mandatory argument(s) missing");
695 rv = ipsec_add_del_tunnel_if (&a);
701 case VNET_API_ERROR_INVALID_VALUE:
703 return clib_error_return (0,
704 "IPSec tunnel interface already exists...");
706 return clib_error_return (0, "IPSec tunnel interface not exists...");
708 return clib_error_return (0, "ipsec_register_interface returned %d",
716 VLIB_CLI_COMMAND (create_ipsec_tunnel_command, static) = {
717 .path = "create ipsec tunnel",
718 .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> remote-ip <addr> remote-spi <spi>",
719 .function = create_ipsec_tunnel_command_fn,
723 static clib_error_t *
724 set_interface_key_command_fn (vlib_main_t * vm,
725 unformat_input_t * input,
726 vlib_cli_command_t * cmd)
728 unformat_input_t _line_input, *line_input = &_line_input;
729 ipsec_main_t *im = &ipsec_main;
730 ipsec_if_set_key_type_t type = IPSEC_IF_SET_KEY_TYPE_NONE;
731 u32 hw_if_index = (u32) ~ 0;
735 if (!unformat_user (input, unformat_line_input, line_input))
738 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
740 if (unformat (line_input, "%U",
741 unformat_vnet_hw_interface, im->vnet_main, &hw_if_index))
745 (line_input, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
746 type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
749 (line_input, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
750 type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
753 (line_input, "local integ %U", unformat_ipsec_integ_alg, &alg))
754 type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
757 (line_input, "remote integ %U", unformat_ipsec_integ_alg, &alg))
758 type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
759 else if (unformat (line_input, "%U", unformat_hex_string, &key))
762 return clib_error_return (0, "parse error: '%U'",
763 format_unformat_error, line_input);
766 unformat_free (line_input);
768 if (type == IPSEC_IF_SET_KEY_TYPE_NONE)
769 return clib_error_return (0, "unknown key type");
771 if (alg > 0 && vec_len (key) == 0)
772 return clib_error_return (0, "key is not specified");
774 if (hw_if_index == (u32) ~ 0)
775 return clib_error_return (0, "interface not specified");
777 ipsec_set_interface_key (im->vnet_main, hw_if_index, type, alg, key);
784 VLIB_CLI_COMMAND (set_interface_key_command, static) = {
785 .path = "set interface ipsec key",
787 "set interface ipsec key <int> <local|remote> <crypto|integ> <key type> <key>",
788 .function = set_interface_key_command_fn,
793 ipsec_cli_init (vlib_main_t * vm)
798 VLIB_INIT_FUNCTION (ipsec_cli_init);
802 * fd.io coding-style-patch-verification: ON
805 * eval: (c-set-style "gnu")