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))
39 if (unformat (line_input, "%U %u", unformat_vnet_sw_interface, im->vnet_main,
40 &sw_if_index, &spd_id))
42 else if (unformat (line_input, "del"))
45 return clib_error_return (0, "parse error: '%U'",
46 format_unformat_error, line_input);
48 unformat_free (line_input);
50 ipsec_set_interface_spd(vm, sw_if_index, spd_id, is_add);
55 VLIB_CLI_COMMAND (set_interface_spd_command, static) = {
56 .path = "set interface ipsec spd",
58 "set interface ipsec spd <int> <id>",
59 .function = set_interface_spd_command_fn,
63 ipsec_sa_add_del_command_fn (vlib_main_t * vm,
64 unformat_input_t * input,
65 vlib_cli_command_t * cmd)
67 unformat_input_t _line_input, * line_input = &_line_input;
72 memset(&sa, 0, sizeof(sa));
74 if (! unformat_user (input, unformat_line_input, line_input))
77 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
78 if (unformat (line_input, "add %u", &sa.id))
80 else if (unformat (line_input, "del %u", &sa.id))
82 else if (unformat (line_input, "spi %u", &sa.spi))
84 else if (unformat (line_input, "esp"))
85 sa.protocol = IPSEC_PROTOCOL_ESP;
86 else if (unformat (line_input, "ah"))
87 //sa.protocol = IPSEC_PROTOCOL_AH;
88 return clib_error_return(0, "unsupported security protocol 'AH'");
89 else if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck))
90 sa.crypto_key_len = vec_len (ck);
91 else if (unformat (line_input, "crypto-alg %U", unformat_ipsec_crypto_alg,
94 if (sa.crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
95 sa.crypto_alg > IPSEC_CRYPTO_ALG_AES_CBC_256)
96 return clib_error_return(0, "unsupported crypto-alg: '%U'",
97 format_ipsec_crypto_alg, sa.crypto_alg);
99 else if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik))
100 sa.integ_key_len = vec_len (ik);
101 else if (unformat (line_input, "integ-alg %U", unformat_ipsec_integ_alg,
104 if (sa.integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
105 sa.integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
106 return clib_error_return(0, "unsupported integ-alg: '%U'",
107 format_ipsec_integ_alg, sa.integ_alg);
109 else if (unformat (line_input, "tunnel-src %U",
110 unformat_ip4_address, &sa.tunnel_src_addr.ip4))
112 else if (unformat (line_input, "tunnel-dst %U",
113 unformat_ip4_address, &sa.tunnel_dst_addr.ip4))
115 else if (unformat (line_input, "tunnel-src %U",
116 unformat_ip6_address, &sa.tunnel_src_addr.ip6))
117 { sa.is_tunnel = 1; sa.is_tunnel_ip6 = 1; }
118 else if (unformat (line_input, "tunnel-dst %U",
119 unformat_ip6_address, &sa.tunnel_dst_addr.ip6))
120 { sa.is_tunnel = 1; sa.is_tunnel_ip6 = 1; }
122 return clib_error_return (0, "parse error: '%U'",
123 format_unformat_error, line_input);
126 unformat_free (line_input);
128 if (sa.crypto_key_len > sizeof(sa.crypto_key))
129 sa.crypto_key_len = sizeof(sa.crypto_key);
131 if (sa.integ_key_len > sizeof(sa.integ_key))
132 sa.integ_key_len = sizeof(sa.integ_key);
135 strncpy((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len);
138 strncpy((char *) sa.integ_key, (char *) ik, sa.integ_key_len);
140 ipsec_add_del_sa(vm, &sa, is_add);
145 VLIB_CLI_COMMAND (ipsec_sa_add_del_command, static) = {
148 "ipsec sa [add|del]",
149 .function = ipsec_sa_add_del_command_fn,
152 static clib_error_t *
153 ipsec_spd_add_del_command_fn (vlib_main_t * vm,
154 unformat_input_t * input,
155 vlib_cli_command_t * cmd)
157 unformat_input_t _line_input, * line_input = &_line_input;
161 if (! unformat_user (input, unformat_line_input, line_input))
164 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
165 if (unformat (line_input, "add"))
167 else if (unformat (line_input, "del"))
169 else if (unformat (line_input, "%u", &spd_id))
172 return clib_error_return (0, "parse error: '%U'",
173 format_unformat_error, line_input);
176 unformat_free (line_input);
178 ipsec_add_del_spd(vm, spd_id, is_add);
183 VLIB_CLI_COMMAND (ipsec_spd_add_del_command, static) = {
186 "ipsec spd [add|del] <id>",
187 .function = ipsec_spd_add_del_command_fn,
191 static clib_error_t *
192 ipsec_policy_add_del_command_fn (vlib_main_t * vm,
193 unformat_input_t * input,
194 vlib_cli_command_t * cmd)
196 unformat_input_t _line_input, * line_input = &_line_input;
202 memset(&p, 0, sizeof(p));
203 p.lport.stop = p.rport.stop = ~0;
204 p.laddr.stop.ip4.as_u32 = p.raddr.stop.ip4.as_u32 = (u32) ~0;
205 p.laddr.stop.ip6.as_u64[0] = p.laddr.stop.ip6.as_u64[1] = (u64) ~0;
206 p.raddr.stop.ip6.as_u64[0] = p.raddr.stop.ip6.as_u64[1] = (u64) ~0;
208 if (! unformat_user (input, unformat_line_input, line_input))
211 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
212 if (unformat (line_input, "add"))
214 else if (unformat (line_input, "del"))
216 else if (unformat (line_input, "spd %u", &p.id))
218 else if (unformat (line_input, "inbound"))
220 else if (unformat (line_input, "outbound"))
222 else if (unformat (line_input, "priority %d", &p.priority))
224 else if (unformat (line_input, "protocol %u", &tmp))
225 p.protocol = (u8) tmp;
226 else if (unformat (line_input, "action %U", unformat_ipsec_policy_action,
229 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
230 return clib_error_return(0, "unsupported action: 'resolve'");
232 else if (unformat (line_input, "sa %u", &p.sa_id))
234 else if (unformat (line_input, "local-ip-range %U - %U",
235 unformat_ip4_address, &p.laddr.start.ip4,
236 unformat_ip4_address, &p.laddr.stop.ip4))
238 else if (unformat (line_input, "remote-ip-range %U - %U",
239 unformat_ip4_address, &p.raddr.start.ip4,
240 unformat_ip4_address, &p.raddr.stop.ip4))
242 else if (unformat (line_input, "local-ip-range %U - %U",
243 unformat_ip6_address, &p.laddr.start.ip6,
244 unformat_ip6_address, &p.laddr.stop.ip6))
249 else if (unformat (line_input, "remote-ip-range %U - %U",
250 unformat_ip6_address, &p.raddr.start.ip6,
251 unformat_ip6_address, &p.raddr.stop.ip6))
256 else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2))
257 { p.lport.start = tmp; p.lport.stop = tmp2; }
258 else if (unformat (line_input, "remote-port-range %u - %u", &tmp, &tmp2))
259 { p.rport.start = tmp; p.rport.stop = tmp2; }
261 return clib_error_return (0, "parse error: '%U'",
262 format_unformat_error, line_input);
265 unformat_free (line_input);
267 ipsec_add_del_policy(vm, &p, is_add);
271 ipsec_add_del_policy(vm, &p, is_add);
276 VLIB_CLI_COMMAND (ipsec_policy_add_del_command, static) = {
277 .path = "ipsec policy",
279 "ipsec policy [add|del] spd <id> priority <n> ",
280 .function = ipsec_policy_add_del_command_fn,
283 static clib_error_t *
284 set_ipsec_sa_key_command_fn (vlib_main_t * vm,
285 unformat_input_t * input,
286 vlib_cli_command_t * cmd)
288 unformat_input_t _line_input, * line_input = &_line_input;
292 memset(&sa, 0, sizeof(sa));
294 if (! unformat_user (input, unformat_line_input, line_input))
297 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
298 if (unformat (line_input, "%u", &sa.id))
300 else if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck))
301 sa.crypto_key_len = vec_len (ck);
302 else if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik))
303 sa.integ_key_len = vec_len (ik);
305 return clib_error_return (0, "parse error: '%U'", format_unformat_error,
309 unformat_free (line_input);
311 if (sa.crypto_key_len > sizeof(sa.crypto_key))
312 sa.crypto_key_len = sizeof(sa.crypto_key);
314 if (sa.integ_key_len > sizeof(sa.integ_key))
315 sa.integ_key_len = sizeof(sa.integ_key);
318 strncpy((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len);
321 strncpy((char *) sa.integ_key, (char *) ik, sa.integ_key_len);
323 ipsec_set_sa_key(vm, &sa);
328 VLIB_CLI_COMMAND (set_ipsec_sa_key_command, static) = {
329 .path = "set ipsec sa",
331 "set ipsec sa <id> crypto-key <key> integ-key <key>",
332 .function = set_ipsec_sa_key_command_fn,
335 static clib_error_t *
336 show_ipsec_command_fn (vlib_main_t * vm,
337 unformat_input_t * input,
338 vlib_cli_command_t * cmd)
343 ipsec_main_t * im = &ipsec_main;
345 ipsec_tunnel_if_t * t;
346 vnet_hw_interface_t * hi;
348 pool_foreach (sa, im->sad, ({
350 vlib_cli_output(vm, "sa %u spi %u mode %s protocol %s", sa->id, sa->spi,
351 sa->is_tunnel ? "tunnel" : "transport",
352 sa->protocol ? "esp" : "ah");
353 if (sa->protocol == IPSEC_PROTOCOL_ESP) {
354 vlib_cli_output(vm, " crypto alg %U%s%U integrity alg %U%s%U",
355 format_ipsec_crypto_alg, sa->crypto_alg,
356 sa->crypto_alg ? " key " : "",
357 format_hex_bytes, sa->crypto_key, sa->crypto_key_len,
358 format_ipsec_integ_alg, sa->integ_alg,
359 sa->integ_alg ? " key " : "",
360 format_hex_bytes, sa->integ_key, sa->integ_key_len);
362 if (sa->is_tunnel && sa->is_tunnel_ip6) {
363 vlib_cli_output(vm, " tunnel src %U dst %U",
364 format_ip6_address, &sa->tunnel_src_addr.ip6,
365 format_ip6_address, &sa->tunnel_dst_addr.ip6);
366 } else if (sa->is_tunnel) {
367 vlib_cli_output(vm, " tunnel src %U dst %U",
368 format_ip4_address, &sa->tunnel_src_addr.ip4,
369 format_ip4_address, &sa->tunnel_dst_addr.ip4);
374 pool_foreach (spd, im->spds, ({
375 vlib_cli_output(vm, "spd %u", spd->id);
377 vlib_cli_output(vm, " outbound policies");
378 vec_foreach(i, spd->ipv4_outbound_policies)
380 p = pool_elt_at_index(spd->policies, *i);
381 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
383 format_ipsec_policy_action, p->policy,
385 format(0, "%U", format_ip_protocol, p->protocol) :
387 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
388 format(0, " sa %u", p->sa_id) :
390 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
391 format_ip4_address, &p->laddr.start.ip4,
392 format_ip4_address, &p->laddr.stop.ip4,
393 p->lport.start, p->lport.stop);
394 vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
395 format_ip4_address, &p->raddr.start.ip4,
396 format_ip4_address, &p->raddr.stop.ip4,
397 p->rport.start, p->rport.stop);
398 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
401 vec_foreach(i, spd->ipv6_outbound_policies)
403 p = pool_elt_at_index(spd->policies, *i);
404 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
406 format_ipsec_policy_action, p->policy,
408 format(0, "%U", format_ip_protocol, p->protocol) :
410 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
411 format(0, " sa %u", p->sa_id) :
413 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
414 format_ip6_address, &p->laddr.start.ip6,
415 format_ip6_address, &p->laddr.stop.ip6,
416 p->lport.start, p->lport.stop);
417 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
418 format_ip6_address, &p->raddr.start.ip6,
419 format_ip6_address, &p->raddr.stop.ip6,
420 p->rport.start, p->rport.stop);
421 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
424 vlib_cli_output(vm, " inbound policies");
425 vec_foreach(i, spd->ipv4_inbound_protect_policy_indices)
427 p = pool_elt_at_index(spd->policies, *i);
428 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
430 format_ipsec_policy_action, p->policy,
432 format(0, "%U", format_ip_protocol, p->protocol) :
434 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
435 format(0, " sa %u", p->sa_id) :
437 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
438 format_ip4_address, &p->laddr.start.ip4,
439 format_ip4_address, &p->laddr.stop.ip4,
440 p->lport.start, p->lport.stop);
441 vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
442 format_ip4_address, &p->raddr.start.ip4,
443 format_ip4_address, &p->raddr.stop.ip4,
444 p->rport.start, p->rport.stop);
445 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
448 vec_foreach(i, spd->ipv4_inbound_policy_discard_and_bypass_indices)
450 p = pool_elt_at_index(spd->policies, *i);
451 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
453 format_ipsec_policy_action, p->policy,
455 format(0, "%U", format_ip_protocol, p->protocol) :
457 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
458 format(0, " sa %u", p->sa_id) :
460 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
461 format_ip4_address, &p->laddr.start.ip4,
462 format_ip4_address, &p->laddr.stop.ip4,
463 p->lport.start, p->lport.stop);
464 vlib_cli_output(vm, " remte addr range %U - %U port range %u - %u",
465 format_ip4_address, &p->raddr.start.ip4,
466 format_ip4_address, &p->raddr.stop.ip4,
467 p->rport.start, p->rport.stop);
468 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
471 vec_foreach(i, spd->ipv6_inbound_protect_policy_indices)
473 p = pool_elt_at_index(spd->policies, *i);
474 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
476 format_ipsec_policy_action, p->policy,
478 format(0, "%U", format_ip_protocol, p->protocol) :
480 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
481 format(0, " sa %u", p->sa_id) :
483 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
484 format_ip6_address, &p->laddr.start.ip6,
485 format_ip6_address, &p->laddr.stop.ip6,
486 p->lport.start, p->lport.stop);
487 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
488 format_ip6_address, &p->raddr.start.ip6,
489 format_ip6_address, &p->raddr.stop.ip6,
490 p->rport.start, p->rport.stop);
491 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
494 vec_foreach(i, spd->ipv6_inbound_policy_discard_and_bypass_indices)
496 p = pool_elt_at_index(spd->policies, *i);
497 vlib_cli_output(vm, " priority %d action %U protocol %s%s",
499 format_ipsec_policy_action, p->policy,
501 format(0, "%U", format_ip_protocol, p->protocol) :
503 p->policy == IPSEC_POLICY_ACTION_PROTECT ?
504 format(0, " sa %u", p->sa_id) :
506 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
507 format_ip6_address, &p->laddr.start.ip6,
508 format_ip6_address, &p->laddr.stop.ip6,
509 p->lport.start, p->lport.stop);
510 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
511 format_ip6_address, &p->raddr.start.ip6,
512 format_ip6_address, &p->raddr.stop.ip6,
513 p->rport.start, p->rport.stop);
514 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
519 vlib_cli_output(vm, "tunnel interfaces");
520 pool_foreach (t, im->tunnel_interfaces, ({
521 hi = vnet_get_hw_interface (im->vnet_main, t->hw_if_index);
522 vlib_cli_output(vm, " %s seq", hi->name);
523 sa = pool_elt_at_index(im->sad, t->output_sa_index);
524 vlib_cli_output(vm, " seq %u seq-hi %u esn %u anti-replay %u",
525 sa->seq, sa->seq_hi, sa->use_esn, sa->use_anti_replay);
526 vlib_cli_output(vm, " local-spi %u local-ip %U", sa->spi,
527 format_ip4_address, &sa->tunnel_src_addr.ip4);
528 vlib_cli_output(vm, " local-crypto %U %U",
529 format_ipsec_crypto_alg, sa->crypto_alg,
530 format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
531 vlib_cli_output(vm, " local-integrity %U %U",
532 format_ipsec_integ_alg, sa->integ_alg,
533 format_hex_bytes, sa->integ_key, sa->integ_key_len);
534 sa = pool_elt_at_index(im->sad, t->input_sa_index);
535 vlib_cli_output(vm, " last-seq %u last-seq-hi %u esn %u anti-replay %u window %U",
536 sa->last_seq, sa->last_seq_hi, sa->use_esn,
538 format_ipsec_replay_window, sa->replay_window);
539 vlib_cli_output(vm, " remote-spi %u remote-ip %U", sa->spi,
540 format_ip4_address, &sa->tunnel_src_addr.ip4);
541 vlib_cli_output(vm, " remote-crypto %U %U",
542 format_ipsec_crypto_alg, sa->crypto_alg,
543 format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
544 vlib_cli_output(vm, " remote-integrity %U %U",
545 format_ipsec_integ_alg, sa->integ_alg,
546 format_hex_bytes, sa->integ_key, sa->integ_key_len);
551 VLIB_CLI_COMMAND (show_ipsec_command, static) = {
552 .path = "show ipsec",
553 .short_help = "show ipsec",
554 .function = show_ipsec_command_fn,
557 static clib_error_t *
558 clear_ipsec_counters_command_fn (vlib_main_t * vm,
559 unformat_input_t * input,
560 vlib_cli_command_t * cmd)
562 ipsec_main_t * im = &ipsec_main;
566 pool_foreach (spd, im->spds, ({
567 pool_foreach(p, spd->policies, ({
568 p->counter.packets = p->counter.bytes = 0;
575 VLIB_CLI_COMMAND (clear_ipsec_counters_command, static) = {
576 .path = "clear ipsec counters",
577 .short_help = "clear ipsec counters",
578 .function = clear_ipsec_counters_command_fn,
581 static clib_error_t *
582 create_ipsec_tunnel_command_fn (vlib_main_t * vm,
583 unformat_input_t * input,
584 vlib_cli_command_t * cmd)
586 unformat_input_t _line_input, * line_input = &_line_input;
587 ipsec_add_del_tunnel_args_t a;
588 ipsec_main_t *im = &ipsec_main;
595 /* Get a line of input. */
596 if (! unformat_user (input, unformat_line_input, line_input))
599 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
600 if (unformat (line_input, "local-ip %U", unformat_ip4_address, &a.local_ip))
602 else if (unformat (line_input, "remote-ip %U", unformat_ip4_address, &a.remote_ip))
604 else if (unformat (line_input, "local-spi %u", &a.local_spi))
606 else if (unformat (line_input, "remote-spi %u", &a.remote_spi))
608 else if (unformat (line_input, "del"))
611 return clib_error_return (0, "unknown input `%U'",
612 format_unformat_error, input);
614 unformat_free (line_input);
617 return clib_error_return (0, "mandatory argument(s) missing");
619 rv = ipsec_add_del_tunnel_if (im->vnet_main, &a);
625 case VNET_API_ERROR_INVALID_VALUE:
627 return clib_error_return (0, "IPSec tunnel interface already exists...");
629 return clib_error_return (0, "IPSec tunnel interface not exists...");
631 return clib_error_return (0, "ipsec_register_interface returned %d", rv);
637 VLIB_CLI_COMMAND (create_ipsec_tunnel_command, static) = {
638 .path = "create ipsec tunnel",
639 .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> remote-ip <addr> remote-spi <spi>",
640 .function = create_ipsec_tunnel_command_fn,
643 static clib_error_t *
644 set_interface_key_command_fn (vlib_main_t * vm,
645 unformat_input_t * input,
646 vlib_cli_command_t * cmd)
648 unformat_input_t _line_input, * line_input = &_line_input;
649 ipsec_main_t *im = &ipsec_main;
650 ipsec_if_set_key_type_t type = IPSEC_IF_SET_KEY_TYPE_NONE;
651 u32 hw_if_index = (u32) ~0;
655 if (! unformat_user (input, unformat_line_input, line_input))
658 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
660 if (unformat (line_input, "%U",
661 unformat_vnet_hw_interface, im->vnet_main, &hw_if_index))
663 else if (unformat (line_input, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
664 type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
665 else if (unformat (line_input, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
666 type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
667 else if (unformat (line_input, "local integ %U", unformat_ipsec_integ_alg, &alg))
668 type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
669 else if (unformat (line_input, "remote integ %U", unformat_ipsec_integ_alg, &alg))
670 type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
671 else if (unformat (line_input, "%U", unformat_hex_string, &key))
674 return clib_error_return (0, "parse error: '%U'",
675 format_unformat_error, line_input);
678 unformat_free (line_input);
680 if (type == IPSEC_IF_SET_KEY_TYPE_NONE)
681 return clib_error_return (0, "unknown key type");
683 if (alg > 0 && vec_len(key)==0)
684 return clib_error_return (0, "key is not specified");
686 if (hw_if_index == (u32) ~0)
687 return clib_error_return (0, "interface not specified");
689 ipsec_set_interface_key(im->vnet_main, hw_if_index, type, alg, key);
695 VLIB_CLI_COMMAND (set_interface_key_command, static) = {
696 .path = "set interface ipsec key",
698 "set interface ipsec key <int> <local|remote> <crypto|integ> <key type> <key>",
699 .function = set_interface_key_command_fn,
704 ipsec_cli_init (vlib_main_t * vm)
709 VLIB_INIT_FUNCTION (ipsec_cli_init);