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_ALG_AES_CBC_256)
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,
112 if (sa.integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
113 sa.integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
114 return clib_error_return (0, "unsupported integ-alg: '%U'",
115 format_ipsec_integ_alg, sa.integ_alg);
117 else if (unformat (line_input, "tunnel-src %U",
118 unformat_ip4_address, &sa.tunnel_src_addr.ip4))
120 else if (unformat (line_input, "tunnel-dst %U",
121 unformat_ip4_address, &sa.tunnel_dst_addr.ip4))
123 else if (unformat (line_input, "tunnel-src %U",
124 unformat_ip6_address, &sa.tunnel_src_addr.ip6))
127 sa.is_tunnel_ip6 = 1;
129 else if (unformat (line_input, "tunnel-dst %U",
130 unformat_ip6_address, &sa.tunnel_dst_addr.ip6))
133 sa.is_tunnel_ip6 = 1;
136 return clib_error_return (0, "parse error: '%U'",
137 format_unformat_error, line_input);
140 unformat_free (line_input);
142 if (sa.crypto_key_len > sizeof (sa.crypto_key))
143 sa.crypto_key_len = sizeof (sa.crypto_key);
145 if (sa.integ_key_len > sizeof (sa.integ_key))
146 sa.integ_key_len = sizeof (sa.integ_key);
149 strncpy ((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len);
152 strncpy ((char *) sa.integ_key, (char *) ik, sa.integ_key_len);
154 ipsec_add_del_sa (vm, &sa, is_add);
160 VLIB_CLI_COMMAND (ipsec_sa_add_del_command, static) = {
163 "ipsec sa [add|del]",
164 .function = ipsec_sa_add_del_command_fn,
168 static clib_error_t *
169 ipsec_spd_add_del_command_fn (vlib_main_t * vm,
170 unformat_input_t * input,
171 vlib_cli_command_t * cmd)
173 unformat_input_t _line_input, *line_input = &_line_input;
177 if (!unformat_user (input, unformat_line_input, line_input))
180 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
182 if (unformat (line_input, "add"))
184 else if (unformat (line_input, "del"))
186 else if (unformat (line_input, "%u", &spd_id))
189 return clib_error_return (0, "parse error: '%U'",
190 format_unformat_error, line_input);
193 unformat_free (line_input);
196 return clib_error_return (0, "please specify SPD ID");
198 ipsec_add_del_spd (vm, spd_id, is_add);
204 VLIB_CLI_COMMAND (ipsec_spd_add_del_command, static) = {
207 "ipsec spd [add|del] <id>",
208 .function = ipsec_spd_add_del_command_fn,
213 static clib_error_t *
214 ipsec_policy_add_del_command_fn (vlib_main_t * vm,
215 unformat_input_t * input,
216 vlib_cli_command_t * cmd)
218 unformat_input_t _line_input, *line_input = &_line_input;
224 memset (&p, 0, sizeof (p));
225 p.lport.stop = p.rport.stop = ~0;
226 p.laddr.stop.ip4.as_u32 = p.raddr.stop.ip4.as_u32 = (u32) ~ 0;
227 p.laddr.stop.ip6.as_u64[0] = p.laddr.stop.ip6.as_u64[1] = (u64) ~ 0;
228 p.raddr.stop.ip6.as_u64[0] = p.raddr.stop.ip6.as_u64[1] = (u64) ~ 0;
230 if (!unformat_user (input, unformat_line_input, line_input))
233 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
235 if (unformat (line_input, "add"))
237 else if (unformat (line_input, "del"))
239 else if (unformat (line_input, "spd %u", &p.id))
241 else if (unformat (line_input, "inbound"))
243 else if (unformat (line_input, "outbound"))
245 else if (unformat (line_input, "priority %d", &p.priority))
247 else if (unformat (line_input, "protocol %u", &tmp))
248 p.protocol = (u8) tmp;
251 (line_input, "action %U", unformat_ipsec_policy_action,
254 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
255 return clib_error_return (0, "unsupported action: 'resolve'");
257 else if (unformat (line_input, "sa %u", &p.sa_id))
259 else if (unformat (line_input, "local-ip-range %U - %U",
260 unformat_ip4_address, &p.laddr.start.ip4,
261 unformat_ip4_address, &p.laddr.stop.ip4))
263 else if (unformat (line_input, "remote-ip-range %U - %U",
264 unformat_ip4_address, &p.raddr.start.ip4,
265 unformat_ip4_address, &p.raddr.stop.ip4))
267 else if (unformat (line_input, "local-ip-range %U - %U",
268 unformat_ip6_address, &p.laddr.start.ip6,
269 unformat_ip6_address, &p.laddr.stop.ip6))
274 else if (unformat (line_input, "remote-ip-range %U - %U",
275 unformat_ip6_address, &p.raddr.start.ip6,
276 unformat_ip6_address, &p.raddr.stop.ip6))
281 else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2))
287 if (unformat (line_input, "remote-port-range %u - %u", &tmp, &tmp2))
293 return clib_error_return (0, "parse error: '%U'",
294 format_unformat_error, line_input);
297 unformat_free (line_input);
299 ipsec_add_del_policy (vm, &p, is_add);
303 ipsec_add_del_policy (vm, &p, is_add);
309 VLIB_CLI_COMMAND (ipsec_policy_add_del_command, static) = {
310 .path = "ipsec policy",
312 "ipsec policy [add|del] spd <id> priority <n> ",
313 .function = ipsec_policy_add_del_command_fn,
317 static clib_error_t *
318 set_ipsec_sa_key_command_fn (vlib_main_t * vm,
319 unformat_input_t * input,
320 vlib_cli_command_t * cmd)
322 unformat_input_t _line_input, *line_input = &_line_input;
326 memset (&sa, 0, sizeof (sa));
328 if (!unformat_user (input, unformat_line_input, line_input))
331 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
333 if (unformat (line_input, "%u", &sa.id))
336 if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck))
337 sa.crypto_key_len = vec_len (ck);
339 if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik))
340 sa.integ_key_len = vec_len (ik);
342 return clib_error_return (0, "parse error: '%U'",
343 format_unformat_error, line_input);
346 unformat_free (line_input);
348 if (sa.crypto_key_len > sizeof (sa.crypto_key))
349 sa.crypto_key_len = sizeof (sa.crypto_key);
351 if (sa.integ_key_len > sizeof (sa.integ_key))
352 sa.integ_key_len = sizeof (sa.integ_key);
355 strncpy ((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len);
358 strncpy ((char *) sa.integ_key, (char *) ik, sa.integ_key_len);
360 ipsec_set_sa_key (vm, &sa);
366 VLIB_CLI_COMMAND (set_ipsec_sa_key_command, static) = {
367 .path = "set ipsec sa",
369 "set ipsec sa <id> crypto-key <key> integ-key <key>",
370 .function = set_ipsec_sa_key_command_fn,
374 static clib_error_t *
375 show_ipsec_command_fn (vlib_main_t * vm,
376 unformat_input_t * input, vlib_cli_command_t * cmd)
381 ipsec_main_t *im = &ipsec_main;
383 ipsec_tunnel_if_t *t;
384 vnet_hw_interface_t *hi;
387 pool_foreach (sa, im->sad, ({
389 vlib_cli_output(vm, "sa %u spi %u mode %s protocol %s", sa->id, sa->spi,
390 sa->is_tunnel ? "tunnel" : "transport",
391 sa->protocol ? "esp" : "ah");
392 if (sa->protocol == IPSEC_PROTOCOL_ESP) {
393 vlib_cli_output(vm, " crypto alg %U%s%U integrity alg %U%s%U",
394 format_ipsec_crypto_alg, sa->crypto_alg,
395 sa->crypto_alg ? " key " : "",
396 format_hex_bytes, sa->crypto_key, sa->crypto_key_len,
397 format_ipsec_integ_alg, sa->integ_alg,
398 sa->integ_alg ? " key " : "",
399 format_hex_bytes, sa->integ_key, sa->integ_key_len);
401 if (sa->is_tunnel && sa->is_tunnel_ip6) {
402 vlib_cli_output(vm, " tunnel src %U dst %U",
403 format_ip6_address, &sa->tunnel_src_addr.ip6,
404 format_ip6_address, &sa->tunnel_dst_addr.ip6);
405 } else if (sa->is_tunnel) {
406 vlib_cli_output(vm, " tunnel src %U dst %U",
407 format_ip4_address, &sa->tunnel_src_addr.ip4,
408 format_ip4_address, &sa->tunnel_dst_addr.ip4);
415 pool_foreach (spd, im->spds, ({
416 vlib_cli_output(vm, "spd %u", spd->id);
418 vlib_cli_output(vm, " outbound policies");
419 vec_foreach(i, spd->ipv4_outbound_policies)
421 p = pool_elt_at_index(spd->policies, *i);
422 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
424 format_ipsec_policy_action, p->policy,
426 format(0, "%U", format_ip_protocol, p->protocol) :
428 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
429 format(0, " sa %u", p->sa_id) :
431 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
432 format_ip4_address, &p->laddr.start.ip4,
433 format_ip4_address, &p->laddr.stop.ip4,
434 p->lport.start, p->lport.stop);
435 vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
436 format_ip4_address, &p->raddr.start.ip4,
437 format_ip4_address, &p->raddr.stop.ip4,
438 p->rport.start, p->rport.stop);
439 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
442 vec_foreach(i, spd->ipv6_outbound_policies)
444 p = pool_elt_at_index(spd->policies, *i);
445 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
447 format_ipsec_policy_action, p->policy,
449 format(0, "%U", format_ip_protocol, p->protocol) :
451 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
452 format(0, " sa %u", p->sa_id) :
454 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
455 format_ip6_address, &p->laddr.start.ip6,
456 format_ip6_address, &p->laddr.stop.ip6,
457 p->lport.start, p->lport.stop);
458 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
459 format_ip6_address, &p->raddr.start.ip6,
460 format_ip6_address, &p->raddr.stop.ip6,
461 p->rport.start, p->rport.stop);
462 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
465 vlib_cli_output(vm, " inbound policies");
466 vec_foreach(i, spd->ipv4_inbound_protect_policy_indices)
468 p = pool_elt_at_index(spd->policies, *i);
469 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
471 format_ipsec_policy_action, p->policy,
473 format(0, "%U", format_ip_protocol, p->protocol) :
475 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
476 format(0, " sa %u", p->sa_id) :
478 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
479 format_ip4_address, &p->laddr.start.ip4,
480 format_ip4_address, &p->laddr.stop.ip4,
481 p->lport.start, p->lport.stop);
482 vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
483 format_ip4_address, &p->raddr.start.ip4,
484 format_ip4_address, &p->raddr.stop.ip4,
485 p->rport.start, p->rport.stop);
486 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
489 vec_foreach(i, spd->ipv4_inbound_policy_discard_and_bypass_indices)
491 p = pool_elt_at_index(spd->policies, *i);
492 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
494 format_ipsec_policy_action, p->policy,
496 format(0, "%U", format_ip_protocol, p->protocol) :
498 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
499 format(0, " sa %u", p->sa_id) :
501 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
502 format_ip4_address, &p->laddr.start.ip4,
503 format_ip4_address, &p->laddr.stop.ip4,
504 p->lport.start, p->lport.stop);
505 vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
506 format_ip4_address, &p->raddr.start.ip4,
507 format_ip4_address, &p->raddr.stop.ip4,
508 p->rport.start, p->rport.stop);
509 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
512 vec_foreach(i, spd->ipv6_inbound_protect_policy_indices)
514 p = pool_elt_at_index(spd->policies, *i);
515 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
517 format_ipsec_policy_action, p->policy,
519 format(0, "%U", format_ip_protocol, p->protocol) :
521 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
522 format(0, " sa %u", p->sa_id) :
524 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
525 format_ip6_address, &p->laddr.start.ip6,
526 format_ip6_address, &p->laddr.stop.ip6,
527 p->lport.start, p->lport.stop);
528 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
529 format_ip6_address, &p->raddr.start.ip6,
530 format_ip6_address, &p->raddr.stop.ip6,
531 p->rport.start, p->rport.stop);
532 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
535 vec_foreach(i, spd->ipv6_inbound_policy_discard_and_bypass_indices)
537 p = pool_elt_at_index(spd->policies, *i);
538 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
540 format_ipsec_policy_action, p->policy,
542 format(0, "%U", format_ip_protocol, p->protocol) :
544 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
545 format(0, " sa %u", p->sa_id) :
547 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
548 format_ip6_address, &p->laddr.start.ip6,
549 format_ip6_address, &p->laddr.stop.ip6,
550 p->lport.start, p->lport.stop);
551 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
552 format_ip6_address, &p->raddr.start.ip6,
553 format_ip6_address, &p->raddr.stop.ip6,
554 p->rport.start, p->rport.stop);
555 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
561 vlib_cli_output (vm, "tunnel interfaces");
563 pool_foreach (t, im->tunnel_interfaces, ({
564 if (t->hw_if_index == ~0)
566 hi = vnet_get_hw_interface (im->vnet_main, t->hw_if_index);
567 vlib_cli_output(vm, " %s seq", hi->name);
568 sa = pool_elt_at_index(im->sad, t->output_sa_index);
569 vlib_cli_output(vm, " seq %u seq-hi %u esn %u anti-replay %u",
570 sa->seq, sa->seq_hi, sa->use_esn, sa->use_anti_replay);
571 vlib_cli_output(vm, " local-spi %u local-ip %U", sa->spi,
572 format_ip4_address, &sa->tunnel_src_addr.ip4);
573 vlib_cli_output(vm, " local-crypto %U %U",
574 format_ipsec_crypto_alg, sa->crypto_alg,
575 format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
576 vlib_cli_output(vm, " local-integrity %U %U",
577 format_ipsec_integ_alg, sa->integ_alg,
578 format_hex_bytes, sa->integ_key, sa->integ_key_len);
579 sa = pool_elt_at_index(im->sad, t->input_sa_index);
580 vlib_cli_output(vm, " last-seq %u last-seq-hi %u esn %u anti-replay %u window %U",
581 sa->last_seq, sa->last_seq_hi, sa->use_esn,
583 format_ipsec_replay_window, sa->replay_window);
584 vlib_cli_output(vm, " remote-spi %u remote-ip %U", sa->spi,
585 format_ip4_address, &sa->tunnel_src_addr.ip4);
586 vlib_cli_output(vm, " remote-crypto %U %U",
587 format_ipsec_crypto_alg, sa->crypto_alg,
588 format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
589 vlib_cli_output(vm, " remote-integrity %U %U",
590 format_ipsec_integ_alg, sa->integ_alg,
591 format_hex_bytes, sa->integ_key, sa->integ_key_len);
598 VLIB_CLI_COMMAND (show_ipsec_command, static) = {
599 .path = "show ipsec",
600 .short_help = "show ipsec",
601 .function = show_ipsec_command_fn,
605 static clib_error_t *
606 clear_ipsec_counters_command_fn (vlib_main_t * vm,
607 unformat_input_t * input,
608 vlib_cli_command_t * cmd)
610 ipsec_main_t *im = &ipsec_main;
615 pool_foreach (spd, im->spds, ({
616 pool_foreach(p, spd->policies, ({
617 p->counter.packets = p->counter.bytes = 0;
626 VLIB_CLI_COMMAND (clear_ipsec_counters_command, static) = {
627 .path = "clear ipsec counters",
628 .short_help = "clear ipsec counters",
629 .function = clear_ipsec_counters_command_fn,
633 static clib_error_t *
634 create_ipsec_tunnel_command_fn (vlib_main_t * vm,
635 unformat_input_t * input,
636 vlib_cli_command_t * cmd)
638 unformat_input_t _line_input, *line_input = &_line_input;
639 ipsec_add_del_tunnel_args_t a;
643 memset (&a, 0, sizeof (a));
646 /* Get a line of input. */
647 if (!unformat_user (input, unformat_line_input, line_input))
650 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
653 (line_input, "local-ip %U", unformat_ip4_address, &a.local_ip))
657 (line_input, "remote-ip %U", unformat_ip4_address, &a.remote_ip))
659 else if (unformat (line_input, "local-spi %u", &a.local_spi))
661 else if (unformat (line_input, "remote-spi %u", &a.remote_spi))
663 else if (unformat (line_input, "del"))
666 return clib_error_return (0, "unknown input `%U'",
667 format_unformat_error, input);
669 unformat_free (line_input);
672 return clib_error_return (0, "mandatory argument(s) missing");
674 rv = ipsec_add_del_tunnel_if (&a);
680 case VNET_API_ERROR_INVALID_VALUE:
682 return clib_error_return (0,
683 "IPSec tunnel interface already exists...");
685 return clib_error_return (0, "IPSec tunnel interface not exists...");
687 return clib_error_return (0, "ipsec_register_interface returned %d",
695 VLIB_CLI_COMMAND (create_ipsec_tunnel_command, static) = {
696 .path = "create ipsec tunnel",
697 .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> remote-ip <addr> remote-spi <spi>",
698 .function = create_ipsec_tunnel_command_fn,
702 static clib_error_t *
703 set_interface_key_command_fn (vlib_main_t * vm,
704 unformat_input_t * input,
705 vlib_cli_command_t * cmd)
707 unformat_input_t _line_input, *line_input = &_line_input;
708 ipsec_main_t *im = &ipsec_main;
709 ipsec_if_set_key_type_t type = IPSEC_IF_SET_KEY_TYPE_NONE;
710 u32 hw_if_index = (u32) ~ 0;
714 if (!unformat_user (input, unformat_line_input, line_input))
717 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
719 if (unformat (line_input, "%U",
720 unformat_vnet_hw_interface, im->vnet_main, &hw_if_index))
724 (line_input, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
725 type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
728 (line_input, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
729 type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
732 (line_input, "local integ %U", unformat_ipsec_integ_alg, &alg))
733 type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
736 (line_input, "remote integ %U", unformat_ipsec_integ_alg, &alg))
737 type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
738 else if (unformat (line_input, "%U", unformat_hex_string, &key))
741 return clib_error_return (0, "parse error: '%U'",
742 format_unformat_error, line_input);
745 unformat_free (line_input);
747 if (type == IPSEC_IF_SET_KEY_TYPE_NONE)
748 return clib_error_return (0, "unknown key type");
750 if (alg > 0 && vec_len (key) == 0)
751 return clib_error_return (0, "key is not specified");
753 if (hw_if_index == (u32) ~ 0)
754 return clib_error_return (0, "interface not specified");
756 ipsec_set_interface_key (im->vnet_main, hw_if_index, type, alg, key);
763 VLIB_CLI_COMMAND (set_interface_key_command, static) = {
764 .path = "set interface ipsec key",
766 "set interface ipsec key <int> <local|remote> <crypto|integ> <key type> <key>",
767 .function = set_interface_key_command_fn,
773 ipsec_cli_init (vlib_main_t * vm)
778 VLIB_INIT_FUNCTION (ipsec_cli_init);
782 * fd.io coding-style-patch-verification: ON
785 * eval: (c-set-style "gnu")