blob: 4bc14372042590a6dfe0d5e4be900d222cbfde17 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
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>
Pierre Pfister4c422f92018-12-10 11:19:08 +010022#include <vnet/fib/fib.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070023
24#include <vnet/ipsec/ipsec.h>
25
26static clib_error_t *
27set_interface_spd_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070028 unformat_input_t * input,
29 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -070030{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070031 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -070032 ipsec_main_t *im = &ipsec_main;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070033 u32 sw_if_index = (u32) ~ 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -070034 u32 spd_id;
35 int is_add = 1;
Billy McFalla9a20e72017-02-15 11:39:12 -050036 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -070037
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070038 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -070039 return 0;
40
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070041 if (unformat
42 (line_input, "%U %u", unformat_vnet_sw_interface, im->vnet_main,
43 &sw_if_index, &spd_id))
Ed Warnickecb9cada2015-12-08 15:45:58 -070044 ;
45 else if (unformat (line_input, "del"))
46 is_add = 0;
47 else
Billy McFalla9a20e72017-02-15 11:39:12 -050048 {
49 error = clib_error_return (0, "parse error: '%U'",
50 format_unformat_error, line_input);
51 goto done;
52 }
Ed Warnickecb9cada2015-12-08 15:45:58 -070053
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070054 ipsec_set_interface_spd (vm, sw_if_index, spd_id, is_add);
Ed Warnickecb9cada2015-12-08 15:45:58 -070055
Billy McFalla9a20e72017-02-15 11:39:12 -050056done:
57 unformat_free (line_input);
58
59 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -070060}
61
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070062/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -070063VLIB_CLI_COMMAND (set_interface_spd_command, static) = {
64 .path = "set interface ipsec spd",
65 .short_help =
66 "set interface ipsec spd <int> <id>",
67 .function = set_interface_spd_command_fn,
68};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070069/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -070070
71static clib_error_t *
72ipsec_sa_add_del_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070073 unformat_input_t * input,
74 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -070075{
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +000076 ipsec_main_t *im = &ipsec_main;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070077 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -070078 ipsec_sa_t sa;
79 int is_add = ~0;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070080 u8 *ck = 0, *ik = 0;
Billy McFalla9a20e72017-02-15 11:39:12 -050081 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -070082
Dave Barachb7b92992018-10-17 10:38:51 -040083 clib_memset (&sa, 0, sizeof (sa));
Pierre Pfister4c422f92018-12-10 11:19:08 +010084 sa.tx_fib_index = ~((u32) 0); /* Only supported for ipsec interfaces */
Ed Warnickecb9cada2015-12-08 15:45:58 -070085
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070086 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -070087 return 0;
88
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070089 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
90 {
91 if (unformat (line_input, "add %u", &sa.id))
92 is_add = 1;
93 else if (unformat (line_input, "del %u", &sa.id))
94 is_add = 0;
95 else if (unformat (line_input, "spi %u", &sa.spi))
96 ;
97 else if (unformat (line_input, "esp"))
98 sa.protocol = IPSEC_PROTOCOL_ESP;
99 else if (unformat (line_input, "ah"))
Billy McFalla9a20e72017-02-15 11:39:12 -0500100 {
“mukeshyadav1984”430ac932017-11-23 02:39:33 -0800101 sa.protocol = IPSEC_PROTOCOL_AH;
Billy McFalla9a20e72017-02-15 11:39:12 -0500102 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700103 else
104 if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck))
105 sa.crypto_key_len = vec_len (ck);
106 else
107 if (unformat
108 (line_input, "crypto-alg %U", unformat_ipsec_crypto_alg,
109 &sa.crypto_alg))
110 {
Radu Nicolau89c27812018-05-04 12:51:53 +0100111 if (sa.crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
Radu Nicolau6929ea92016-11-29 11:00:30 +0000112 sa.crypto_alg >= IPSEC_CRYPTO_N_ALG)
Billy McFalla9a20e72017-02-15 11:39:12 -0500113 {
114 error = clib_error_return (0, "unsupported crypto-alg: '%U'",
115 format_ipsec_crypto_alg,
116 sa.crypto_alg);
117 goto done;
118 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700119 }
120 else
121 if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik))
122 sa.integ_key_len = vec_len (ik);
123 else if (unformat (line_input, "integ-alg %U", unformat_ipsec_integ_alg,
124 &sa.integ_alg))
125 {
Radu Nicolau89c27812018-05-04 12:51:53 +0100126 if (sa.integ_alg < IPSEC_INTEG_ALG_NONE ||
Radu Nicolau6929ea92016-11-29 11:00:30 +0000127 sa.integ_alg >= IPSEC_INTEG_N_ALG)
Billy McFalla9a20e72017-02-15 11:39:12 -0500128 {
129 error = clib_error_return (0, "unsupported integ-alg: '%U'",
130 format_ipsec_integ_alg,
131 sa.integ_alg);
132 goto done;
133 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700134 }
135 else if (unformat (line_input, "tunnel-src %U",
136 unformat_ip4_address, &sa.tunnel_src_addr.ip4))
137 sa.is_tunnel = 1;
138 else if (unformat (line_input, "tunnel-dst %U",
139 unformat_ip4_address, &sa.tunnel_dst_addr.ip4))
140 sa.is_tunnel = 1;
141 else if (unformat (line_input, "tunnel-src %U",
142 unformat_ip6_address, &sa.tunnel_src_addr.ip6))
143 {
144 sa.is_tunnel = 1;
145 sa.is_tunnel_ip6 = 1;
146 }
147 else if (unformat (line_input, "tunnel-dst %U",
148 unformat_ip6_address, &sa.tunnel_dst_addr.ip6))
149 {
150 sa.is_tunnel = 1;
151 sa.is_tunnel_ip6 = 1;
152 }
Radu Nicolau717de092018-08-03 10:37:24 +0100153 else if (unformat (line_input, "udp-encap"))
154 {
155 sa.udp_encap = 1;
156 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700157 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500158 {
159 error = clib_error_return (0, "parse error: '%U'",
160 format_unformat_error, line_input);
161 goto done;
162 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700163 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700164
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700165 if (sa.crypto_key_len > sizeof (sa.crypto_key))
166 sa.crypto_key_len = sizeof (sa.crypto_key);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700167
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700168 if (sa.integ_key_len > sizeof (sa.integ_key))
169 sa.integ_key_len = sizeof (sa.integ_key);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700170
171 if (ck)
Pierre Pfister62219272018-11-26 09:29:00 +0100172 memcpy (sa.crypto_key, ck, sa.crypto_key_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700173
174 if (ik)
Pierre Pfister62219272018-11-26 09:29:00 +0100175 memcpy (sa.integ_key, ik, sa.integ_key_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700176
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +0000177 if (is_add)
178 {
Klement Sekerab4d30532018-11-08 13:00:02 +0100179 error = ipsec_check_support_cb (im, &sa);
Billy McFalla9a20e72017-02-15 11:39:12 -0500180 if (error)
181 goto done;
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +0000182 }
183
Radu Nicolau717de092018-08-03 10:37:24 +0100184 ipsec_add_del_sa (vm, &sa, is_add);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700185
Billy McFalla9a20e72017-02-15 11:39:12 -0500186done:
187 unformat_free (line_input);
188
189 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700190}
191
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700192/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700193VLIB_CLI_COMMAND (ipsec_sa_add_del_command, static) = {
194 .path = "ipsec sa",
195 .short_help =
196 "ipsec sa [add|del]",
197 .function = ipsec_sa_add_del_command_fn,
198};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700199/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700200
201static clib_error_t *
202ipsec_spd_add_del_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700203 unformat_input_t * input,
204 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700205{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700206 unformat_input_t _line_input, *line_input = &_line_input;
Damjan Marion3f54b182016-08-16 11:27:02 +0200207 u32 spd_id = ~0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700208 int is_add = ~0;
Billy McFalla9a20e72017-02-15 11:39:12 -0500209 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700210
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700211 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700212 return 0;
213
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700214 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
215 {
216 if (unformat (line_input, "add"))
217 is_add = 1;
218 else if (unformat (line_input, "del"))
219 is_add = 0;
220 else if (unformat (line_input, "%u", &spd_id))
221 ;
222 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500223 {
224 error = clib_error_return (0, "parse error: '%U'",
225 format_unformat_error, line_input);
226 goto done;
227 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700228 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700229
Damjan Marion3f54b182016-08-16 11:27:02 +0200230 if (spd_id == ~0)
Billy McFalla9a20e72017-02-15 11:39:12 -0500231 {
232 error = clib_error_return (0, "please specify SPD ID");
233 goto done;
234 }
Damjan Marion3f54b182016-08-16 11:27:02 +0200235
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700236 ipsec_add_del_spd (vm, spd_id, is_add);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700237
Billy McFalla9a20e72017-02-15 11:39:12 -0500238done:
239 unformat_free (line_input);
240
241 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700242}
243
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700244/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700245VLIB_CLI_COMMAND (ipsec_spd_add_del_command, static) = {
246 .path = "ipsec spd",
247 .short_help =
248 "ipsec spd [add|del] <id>",
249 .function = ipsec_spd_add_del_command_fn,
250};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700251/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700252
253
254static clib_error_t *
255ipsec_policy_add_del_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700256 unformat_input_t * input,
257 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700258{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700259 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700260 ipsec_policy_t p;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800261 int rv, is_add = 0;
262 u32 tmp, tmp2, stat_index;
Billy McFalla9a20e72017-02-15 11:39:12 -0500263 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700264
Dave Barachb7b92992018-10-17 10:38:51 -0400265 clib_memset (&p, 0, sizeof (p));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700266 p.lport.stop = p.rport.stop = ~0;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700267 p.laddr.stop.ip4.as_u32 = p.raddr.stop.ip4.as_u32 = (u32) ~ 0;
268 p.laddr.stop.ip6.as_u64[0] = p.laddr.stop.ip6.as_u64[1] = (u64) ~ 0;
269 p.raddr.stop.ip6.as_u64[0] = p.raddr.stop.ip6.as_u64[1] = (u64) ~ 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700270
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700271 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700272 return 0;
273
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700274 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
275 {
276 if (unformat (line_input, "add"))
277 is_add = 1;
278 else if (unformat (line_input, "del"))
279 is_add = 0;
280 else if (unformat (line_input, "spd %u", &p.id))
281 ;
282 else if (unformat (line_input, "inbound"))
283 p.is_outbound = 0;
284 else if (unformat (line_input, "outbound"))
285 p.is_outbound = 1;
286 else if (unformat (line_input, "priority %d", &p.priority))
287 ;
288 else if (unformat (line_input, "protocol %u", &tmp))
289 p.protocol = (u8) tmp;
290 else
291 if (unformat
292 (line_input, "action %U", unformat_ipsec_policy_action,
293 &p.policy))
294 {
295 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
Billy McFalla9a20e72017-02-15 11:39:12 -0500296 {
297 error = clib_error_return (0, "unsupported action: 'resolve'");
298 goto done;
299 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700300 }
301 else if (unformat (line_input, "sa %u", &p.sa_id))
302 ;
303 else if (unformat (line_input, "local-ip-range %U - %U",
304 unformat_ip4_address, &p.laddr.start.ip4,
305 unformat_ip4_address, &p.laddr.stop.ip4))
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800306 ;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700307 else if (unformat (line_input, "remote-ip-range %U - %U",
308 unformat_ip4_address, &p.raddr.start.ip4,
309 unformat_ip4_address, &p.raddr.stop.ip4))
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800310 ;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700311 else if (unformat (line_input, "local-ip-range %U - %U",
312 unformat_ip6_address, &p.laddr.start.ip6,
313 unformat_ip6_address, &p.laddr.stop.ip6))
314 {
315 p.is_ipv6 = 1;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700316 }
317 else if (unformat (line_input, "remote-ip-range %U - %U",
318 unformat_ip6_address, &p.raddr.start.ip6,
319 unformat_ip6_address, &p.raddr.stop.ip6))
320 {
321 p.is_ipv6 = 1;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700322 }
323 else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2))
324 {
325 p.lport.start = tmp;
326 p.lport.stop = tmp2;
327 }
328 else
329 if (unformat (line_input, "remote-port-range %u - %u", &tmp, &tmp2))
330 {
331 p.rport.start = tmp;
332 p.rport.stop = tmp2;
333 }
334 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500335 {
336 error = clib_error_return (0, "parse error: '%U'",
337 format_unformat_error, line_input);
338 goto done;
339 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700340 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700341
“mukeshyadav1984”430ac932017-11-23 02:39:33 -0800342 /* Check if SA is for IPv6/AH which is not supported. Return error if TRUE. */
343 if (p.sa_id)
344 {
345 uword *p1;
346 ipsec_main_t *im = &ipsec_main;
347 ipsec_sa_t *sa = 0;
348 p1 = hash_get (im->sa_index_by_sa_id, p.sa_id);
Klement Sekerac2fc57e2018-06-28 14:20:12 +0200349 if (!p1)
350 {
351 error =
352 clib_error_return (0, "SA with index %u not found", p.sa_id);
353 goto done;
354 }
“mukeshyadav1984”430ac932017-11-23 02:39:33 -0800355 sa = pool_elt_at_index (im->sad, p1[0]);
356 if (sa && sa->protocol == IPSEC_PROTOCOL_AH && is_add && p.is_ipv6)
357 {
358 error = clib_error_return (0, "AH not supported for IPV6: '%U'",
359 format_unformat_error, line_input);
360 goto done;
361 }
362 }
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800363 rv = ipsec_add_del_policy (vm, &p, is_add, &stat_index);
364
365 if (!rv)
366 vlib_cli_output (vm, "policy-index:%d", stat_index);
367 else
368 vlib_cli_output (vm, "error:%d", rv);
Billy McFalla9a20e72017-02-15 11:39:12 -0500369
370done:
371 unformat_free (line_input);
372
373 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700374}
375
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700376/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700377VLIB_CLI_COMMAND (ipsec_policy_add_del_command, static) = {
378 .path = "ipsec policy",
379 .short_help =
380 "ipsec policy [add|del] spd <id> priority <n> ",
381 .function = ipsec_policy_add_del_command_fn,
382};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700383/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700384
385static clib_error_t *
386set_ipsec_sa_key_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700387 unformat_input_t * input,
388 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700389{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700390 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700391 ipsec_sa_t sa;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700392 u8 *ck = 0, *ik = 0;
Billy McFalla9a20e72017-02-15 11:39:12 -0500393 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700394
Dave Barachb7b92992018-10-17 10:38:51 -0400395 clib_memset (&sa, 0, sizeof (sa));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700396
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700397 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700398 return 0;
399
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700400 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
401 {
402 if (unformat (line_input, "%u", &sa.id))
403 ;
404 else
405 if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck))
406 sa.crypto_key_len = vec_len (ck);
407 else
408 if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik))
409 sa.integ_key_len = vec_len (ik);
410 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500411 {
412 error = clib_error_return (0, "parse error: '%U'",
413 format_unformat_error, line_input);
414 goto done;
415 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700416 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700417
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700418 if (sa.crypto_key_len > sizeof (sa.crypto_key))
419 sa.crypto_key_len = sizeof (sa.crypto_key);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700420
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700421 if (sa.integ_key_len > sizeof (sa.integ_key))
422 sa.integ_key_len = sizeof (sa.integ_key);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700423
424 if (ck)
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700425 strncpy ((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700426
427 if (ik)
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700428 strncpy ((char *) sa.integ_key, (char *) ik, sa.integ_key_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700429
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700430 ipsec_set_sa_key (vm, &sa);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700431
Billy McFalla9a20e72017-02-15 11:39:12 -0500432done:
433 unformat_free (line_input);
434
435 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700436}
437
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700438/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700439VLIB_CLI_COMMAND (set_ipsec_sa_key_command, static) = {
440 .path = "set ipsec sa",
441 .short_help =
442 "set ipsec sa <id> crypto-key <key> integ-key <key>",
443 .function = set_ipsec_sa_key_command_fn,
444};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700445/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700446
447static clib_error_t *
448show_ipsec_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700449 unformat_input_t * input, vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700450{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700451 ipsec_sa_t *sa;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700452 ipsec_main_t *im = &ipsec_main;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800453 u32 i;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700454 ipsec_tunnel_if_t *t;
455 vnet_hw_interface_t *hi;
Klement Sekeraea841302018-05-11 12:59:05 +0200456 u8 *protocol = NULL;
457 u8 *policy = NULL;
Neale Ranns311124e2019-01-24 04:52:25 -0800458 u32 tx_table_id, spd_id, sw_if_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700459
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700460 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700461 pool_foreach (sa, im->sad, ({
462 if (sa->id) {
Neale Rannsde847272018-11-28 01:38:34 -0800463 vlib_cli_output(vm, "sa %u spi %u mode %s protocol %s%s%s%s", sa->id, sa->spi,
Ed Warnickecb9cada2015-12-08 15:45:58 -0700464 sa->is_tunnel ? "tunnel" : "transport",
Klement Sekera4b089f22018-04-17 18:04:57 +0200465 sa->protocol ? "esp" : "ah",
Neale Rannsde847272018-11-28 01:38:34 -0800466 sa->udp_encap ? " udp-encap-enabled" : "",
467 sa->use_anti_replay ? " anti-replay" : "",
468 sa->use_esn ? " extended-sequence-number" : "");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700469 if (sa->protocol == IPSEC_PROTOCOL_ESP) {
470 vlib_cli_output(vm, " crypto alg %U%s%U integrity alg %U%s%U",
471 format_ipsec_crypto_alg, sa->crypto_alg,
472 sa->crypto_alg ? " key " : "",
473 format_hex_bytes, sa->crypto_key, sa->crypto_key_len,
474 format_ipsec_integ_alg, sa->integ_alg,
475 sa->integ_alg ? " key " : "",
476 format_hex_bytes, sa->integ_key, sa->integ_key_len);
477 }
478 if (sa->is_tunnel && sa->is_tunnel_ip6) {
479 vlib_cli_output(vm, " tunnel src %U dst %U",
480 format_ip6_address, &sa->tunnel_src_addr.ip6,
481 format_ip6_address, &sa->tunnel_dst_addr.ip6);
482 } else if (sa->is_tunnel) {
483 vlib_cli_output(vm, " tunnel src %U dst %U",
484 format_ip4_address, &sa->tunnel_src_addr.ip4,
485 format_ip4_address, &sa->tunnel_dst_addr.ip4);
486 }
487 }
488 }));
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700489 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700490
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700491 /* *INDENT-OFF* */
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800492 pool_foreach_index (i, im->spds, ({
493 vlib_cli_output(vm, "%U", format_ipsec_spd, i);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700494 }));
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700495 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700496
Neale Ranns311124e2019-01-24 04:52:25 -0800497 vlib_cli_output (vm, "SPD Bindings:");
498 /* *INDENT-OFF* */
499 hash_foreach(sw_if_index, spd_id, im->spd_index_by_sw_if_index, ({
500 vlib_cli_output (vm, " %d -> %U", spd_id,
501 format_vnet_sw_if_index_name, im->vnet_main,
502 sw_if_index);
503 }));
504 /* *INDENT-ON* */
505
506
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700507 vlib_cli_output (vm, "tunnel interfaces");
508 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700509 pool_foreach (t, im->tunnel_interfaces, ({
Matus Fabian694265d2016-08-10 01:55:36 -0700510 if (t->hw_if_index == ~0)
511 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700512 hi = vnet_get_hw_interface (im->vnet_main, t->hw_if_index);
513 vlib_cli_output(vm, " %s seq", hi->name);
514 sa = pool_elt_at_index(im->sad, t->output_sa_index);
Pierre Pfister4c422f92018-12-10 11:19:08 +0100515
516 tx_table_id = fib_table_get_table_id(sa->tx_fib_index, FIB_PROTOCOL_IP4);
517
518 vlib_cli_output(vm, " seq %u seq-hi %u esn %u anti-replay %u udp-encap %u tx-table %u",
519 sa->seq, sa->seq_hi, sa->use_esn, sa->use_anti_replay, sa->udp_encap, tx_table_id);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700520 vlib_cli_output(vm, " local-spi %u local-ip %U", sa->spi,
521 format_ip4_address, &sa->tunnel_src_addr.ip4);
522 vlib_cli_output(vm, " local-crypto %U %U",
523 format_ipsec_crypto_alg, sa->crypto_alg,
524 format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
525 vlib_cli_output(vm, " local-integrity %U %U",
526 format_ipsec_integ_alg, sa->integ_alg,
527 format_hex_bytes, sa->integ_key, sa->integ_key_len);
528 sa = pool_elt_at_index(im->sad, t->input_sa_index);
529 vlib_cli_output(vm, " last-seq %u last-seq-hi %u esn %u anti-replay %u window %U",
530 sa->last_seq, sa->last_seq_hi, sa->use_esn,
531 sa->use_anti_replay,
532 format_ipsec_replay_window, sa->replay_window);
533 vlib_cli_output(vm, " remote-spi %u remote-ip %U", sa->spi,
534 format_ip4_address, &sa->tunnel_src_addr.ip4);
535 vlib_cli_output(vm, " remote-crypto %U %U",
536 format_ipsec_crypto_alg, sa->crypto_alg,
537 format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
538 vlib_cli_output(vm, " remote-integrity %U %U",
539 format_ipsec_integ_alg, sa->integ_alg,
540 format_hex_bytes, sa->integ_key, sa->integ_key_len);
541 }));
Klement Sekeraea841302018-05-11 12:59:05 +0200542 vec_free(policy);
543 vec_free(protocol);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700544 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700545 return 0;
546}
547
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700548/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700549VLIB_CLI_COMMAND (show_ipsec_command, static) = {
550 .path = "show ipsec",
Klement Sekerab4d30532018-11-08 13:00:02 +0100551 .short_help = "show ipsec [backends]",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700552 .function = show_ipsec_command_fn,
553};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700554/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700555
556static clib_error_t *
Klement Sekerab4d30532018-11-08 13:00:02 +0100557ipsec_show_backends_command_fn (vlib_main_t * vm,
558 unformat_input_t * input,
559 vlib_cli_command_t * cmd)
560{
561 ipsec_main_t *im = &ipsec_main;
562 u32 verbose = 0;
563
564 (void) unformat (input, "verbose %u", &verbose);
565
566 vlib_cli_output (vm, "IPsec AH backends available:");
567 u8 *s = format (NULL, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
568 ipsec_ah_backend_t *ab;
569 /* *INDENT-OFF* */
570 pool_foreach (ab, im->ah_backends, {
571 s = format (s, "%=25s %=25u %=10s\n", ab->name, ab - im->ah_backends,
572 ab - im->ah_backends == im->ah_current_backend ? "yes" : "no");
573 if (verbose) {
574 vlib_node_t *n;
575 n = vlib_get_node (vm, ab->ah4_encrypt_node_index);
576 s = format (s, " enc4 %s (next %d)\n", n->name, ab->ah4_encrypt_next_index);
577 n = vlib_get_node (vm, ab->ah4_decrypt_node_index);
578 s = format (s, " dec4 %s (next %d)\n", n->name, ab->ah4_decrypt_next_index);
579 n = vlib_get_node (vm, ab->ah6_encrypt_node_index);
580 s = format (s, " enc6 %s (next %d)\n", n->name, ab->ah6_encrypt_next_index);
581 n = vlib_get_node (vm, ab->ah6_decrypt_node_index);
582 s = format (s, " dec6 %s (next %d)\n", n->name, ab->ah6_decrypt_next_index);
583 }
584 });
585 /* *INDENT-ON* */
586 vlib_cli_output (vm, "%v", s);
587 _vec_len (s) = 0;
588 vlib_cli_output (vm, "IPsec ESP backends available:");
589 s = format (s, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
590 ipsec_esp_backend_t *eb;
591 /* *INDENT-OFF* */
592 pool_foreach (eb, im->esp_backends, {
593 s = format (s, "%=25s %=25u %=10s\n", eb->name, eb - im->esp_backends,
594 eb - im->esp_backends == im->esp_current_backend ? "yes"
595 : "no");
596 if (verbose) {
597 vlib_node_t *n;
598 n = vlib_get_node (vm, eb->esp4_encrypt_node_index);
599 s = format (s, " enc4 %s (next %d)\n", n->name, eb->esp4_encrypt_next_index);
600 n = vlib_get_node (vm, eb->esp4_decrypt_node_index);
601 s = format (s, " dec4 %s (next %d)\n", n->name, eb->esp4_decrypt_next_index);
602 n = vlib_get_node (vm, eb->esp6_encrypt_node_index);
603 s = format (s, " enc6 %s (next %d)\n", n->name, eb->esp6_encrypt_next_index);
604 n = vlib_get_node (vm, eb->esp6_decrypt_node_index);
605 s = format (s, " dec6 %s (next %d)\n", n->name, eb->esp6_decrypt_next_index);
606 }
607 });
608 /* *INDENT-ON* */
609 vlib_cli_output (vm, "%v", s);
610
611 vec_free (s);
612 return 0;
613}
614
615/* *INDENT-OFF* */
616VLIB_CLI_COMMAND (ipsec_show_backends_command, static) = {
617 .path = "show ipsec backends",
618 .short_help = "show ipsec backends",
619 .function = ipsec_show_backends_command_fn,
620};
621/* *INDENT-ON* */
622
623static clib_error_t *
624ipsec_select_backend_command_fn (vlib_main_t * vm,
625 unformat_input_t * input,
626 vlib_cli_command_t * cmd)
627{
628 u32 backend_index;
629 ipsec_main_t *im = &ipsec_main;
630
631 if (pool_elts (im->sad) > 0)
632 {
633 return clib_error_return (0,
634 "Cannot change IPsec backend, while %u SA entries are configured",
635 pool_elts (im->sad));
636 }
637
638 unformat_input_t _line_input, *line_input = &_line_input;
639 /* Get a line of input. */
640 if (!unformat_user (input, unformat_line_input, line_input))
641 return 0;
642
643 if (unformat (line_input, "ah"))
644 {
645 if (unformat (line_input, "%u", &backend_index))
646 {
647 if (ipsec_select_ah_backend (im, backend_index) < 0)
648 {
649 return clib_error_return (0, "Invalid AH backend index `%u'",
650 backend_index);
651 }
652 }
653 else
654 {
655 return clib_error_return (0, "Invalid backend index `%U'",
656 format_unformat_error, line_input);
657 }
658 }
659 else if (unformat (line_input, "esp"))
660 {
661 if (unformat (line_input, "%u", &backend_index))
662 {
663 if (ipsec_select_esp_backend (im, backend_index) < 0)
664 {
665 return clib_error_return (0, "Invalid ESP backend index `%u'",
666 backend_index);
667 }
668 }
669 else
670 {
671 return clib_error_return (0, "Invalid backend index `%U'",
672 format_unformat_error, line_input);
673 }
674 }
675 else
676 {
677 return clib_error_return (0, "Unknown input `%U'",
678 format_unformat_error, line_input);
679 }
680
681 return 0;
682}
683
684/* *INDENT-OFF* */
685VLIB_CLI_COMMAND (ipsec_select_backend_command, static) = {
686 .path = "ipsec select backend",
687 .short_help = "ipsec select backend <ah|esp> <backend index>",
688 .function = ipsec_select_backend_command_fn,
689};
690
691/* *INDENT-ON* */
692
693static clib_error_t *
Ed Warnickecb9cada2015-12-08 15:45:58 -0700694clear_ipsec_counters_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700695 unformat_input_t * input,
696 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700697{
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800698 vlib_clear_combined_counters (&ipsec_spd_policy_counters);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700699
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800700 return (NULL);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700701}
702
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700703/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700704VLIB_CLI_COMMAND (clear_ipsec_counters_command, static) = {
705 .path = "clear ipsec counters",
706 .short_help = "clear ipsec counters",
707 .function = clear_ipsec_counters_command_fn,
708};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700709/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700710
711static clib_error_t *
712create_ipsec_tunnel_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700713 unformat_input_t * input,
714 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700715{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700716 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700717 ipsec_add_del_tunnel_args_t a;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700718 int rv;
719 u32 num_m_args = 0;
Billy McFalla9a20e72017-02-15 11:39:12 -0500720 clib_error_t *error = NULL;
Matthew Smith2838a232016-06-21 16:05:09 -0500721
Dave Barachb7b92992018-10-17 10:38:51 -0400722 clib_memset (&a, 0, sizeof (a));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700723 a.is_add = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700724
725 /* Get a line of input. */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700726 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700727 return 0;
728
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700729 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
730 {
731 if (unformat
732 (line_input, "local-ip %U", unformat_ip4_address, &a.local_ip))
733 num_m_args++;
734 else
735 if (unformat
736 (line_input, "remote-ip %U", unformat_ip4_address, &a.remote_ip))
737 num_m_args++;
738 else if (unformat (line_input, "local-spi %u", &a.local_spi))
739 num_m_args++;
740 else if (unformat (line_input, "remote-spi %u", &a.remote_spi))
741 num_m_args++;
Matthew Smith8e1039a2018-04-12 07:32:56 -0500742 else if (unformat (line_input, "instance %u", &a.show_instance))
743 a.renumber = 1;
Radu Nicolau717de092018-08-03 10:37:24 +0100744 else if (unformat (line_input, "udp-encap"))
745 a.udp_encap = 1;
Kingwel Xie2baf9422019-02-04 02:07:06 -0800746 else if (unformat (line_input, "use-esn"))
747 a.esn = 1;
748 else if (unformat (line_input, "use-anti-replay"))
749 a.anti_replay = 1;
Pierre Pfister4c422f92018-12-10 11:19:08 +0100750 else if (unformat (line_input, "tx-table %u", &a.tx_table_id))
751 ;
Kingwel Xie2baf9422019-02-04 02:07:06 -0800752 else if (unformat (line_input, "del"))
753 a.is_add = 0;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700754 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500755 {
756 error = clib_error_return (0, "unknown input `%U'",
757 format_unformat_error, line_input);
758 goto done;
759 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700760 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700761
762 if (num_m_args < 4)
Billy McFalla9a20e72017-02-15 11:39:12 -0500763 {
764 error = clib_error_return (0, "mandatory argument(s) missing");
765 goto done;
766 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700767
Matthew Smith2838a232016-06-21 16:05:09 -0500768 rv = ipsec_add_del_tunnel_if (&a);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700769
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700770 switch (rv)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700771 {
772 case 0:
773 break;
774 case VNET_API_ERROR_INVALID_VALUE:
775 if (a.is_add)
Billy McFalla9a20e72017-02-15 11:39:12 -0500776 error = clib_error_return (0,
777 "IPSec tunnel interface already exists...");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700778 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500779 error = clib_error_return (0, "IPSec tunnel interface not exists...");
780 goto done;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700781 default:
Billy McFalla9a20e72017-02-15 11:39:12 -0500782 error = clib_error_return (0, "ipsec_register_interface returned %d",
783 rv);
784 goto done;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700785 }
786
Billy McFalla9a20e72017-02-15 11:39:12 -0500787done:
788 unformat_free (line_input);
789
790 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700791}
792
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700793/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700794VLIB_CLI_COMMAND (create_ipsec_tunnel_command, static) = {
795 .path = "create ipsec tunnel",
Pierre Pfister4c422f92018-12-10 11:19:08 +0100796 .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> "
Kingwel Xie2baf9422019-02-04 02:07:06 -0800797 "remote-ip <addr> remote-spi <spi> [instance <inst_num>] [udp-encap] [use-esn] [use-anti-replay] "
Pierre Pfister4c422f92018-12-10 11:19:08 +0100798 "[tx-table <table-id>]",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700799 .function = create_ipsec_tunnel_command_fn,
800};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700801/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700802
803static clib_error_t *
804set_interface_key_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700805 unformat_input_t * input,
806 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700807{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700808 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700809 ipsec_main_t *im = &ipsec_main;
810 ipsec_if_set_key_type_t type = IPSEC_IF_SET_KEY_TYPE_NONE;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700811 u32 hw_if_index = (u32) ~ 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700812 u32 alg;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700813 u8 *key = 0;
Billy McFalla9a20e72017-02-15 11:39:12 -0500814 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700815
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700816 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700817 return 0;
818
819 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
820 {
821 if (unformat (line_input, "%U",
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700822 unformat_vnet_hw_interface, im->vnet_main, &hw_if_index))
823 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700824 else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700825 if (unformat
826 (line_input, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
827 type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
828 else
829 if (unformat
830 (line_input, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
831 type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
832 else
833 if (unformat
834 (line_input, "local integ %U", unformat_ipsec_integ_alg, &alg))
835 type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
836 else
837 if (unformat
838 (line_input, "remote integ %U", unformat_ipsec_integ_alg, &alg))
839 type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
840 else if (unformat (line_input, "%U", unformat_hex_string, &key))
841 ;
842 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500843 {
844 error = clib_error_return (0, "parse error: '%U'",
845 format_unformat_error, line_input);
846 goto done;
847 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700848 }
849
Ed Warnickecb9cada2015-12-08 15:45:58 -0700850 if (type == IPSEC_IF_SET_KEY_TYPE_NONE)
Billy McFalla9a20e72017-02-15 11:39:12 -0500851 {
852 error = clib_error_return (0, "unknown key type");
853 goto done;
854 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700855
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700856 if (alg > 0 && vec_len (key) == 0)
Billy McFalla9a20e72017-02-15 11:39:12 -0500857 {
858 error = clib_error_return (0, "key is not specified");
859 goto done;
860 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700861
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700862 if (hw_if_index == (u32) ~ 0)
Billy McFalla9a20e72017-02-15 11:39:12 -0500863 {
864 error = clib_error_return (0, "interface not specified");
865 goto done;
866 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700867
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700868 ipsec_set_interface_key (im->vnet_main, hw_if_index, type, alg, key);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700869
Billy McFalla9a20e72017-02-15 11:39:12 -0500870done:
871 vec_free (key);
872 unformat_free (line_input);
873
874 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700875}
876
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700877/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700878VLIB_CLI_COMMAND (set_interface_key_command, static) = {
879 .path = "set interface ipsec key",
880 .short_help =
881 "set interface ipsec key <int> <local|remote> <crypto|integ> <key type> <key>",
882 .function = set_interface_key_command_fn,
883};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700884/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700885
Ed Warnickecb9cada2015-12-08 15:45:58 -0700886clib_error_t *
887ipsec_cli_init (vlib_main_t * vm)
888{
889 return 0;
890}
891
892VLIB_INIT_FUNCTION (ipsec_cli_init);
893
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700894
895/*
896 * fd.io coding-style-patch-verification: ON
897 *
898 * Local Variables:
899 * eval: (c-set-style "gnu")
900 * End:
901 */