blob: f96551429af4c31060aa85e02078e2997f5ac96f [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>
22
23#include <vnet/ipsec/ipsec.h>
24
25static clib_error_t *
26set_interface_spd_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070027 unformat_input_t * input,
28 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -070029{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070030 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -070031 ipsec_main_t *im = &ipsec_main;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070032 u32 sw_if_index = (u32) ~ 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -070033 u32 spd_id;
34 int is_add = 1;
Billy McFalla9a20e72017-02-15 11:39:12 -050035 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -070036
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070037 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -070038 return 0;
39
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070040 if (unformat
41 (line_input, "%U %u", unformat_vnet_sw_interface, im->vnet_main,
42 &sw_if_index, &spd_id))
Ed Warnickecb9cada2015-12-08 15:45:58 -070043 ;
44 else if (unformat (line_input, "del"))
45 is_add = 0;
46 else
Billy McFalla9a20e72017-02-15 11:39:12 -050047 {
48 error = clib_error_return (0, "parse error: '%U'",
49 format_unformat_error, line_input);
50 goto done;
51 }
Ed Warnickecb9cada2015-12-08 15:45:58 -070052
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070053 ipsec_set_interface_spd (vm, sw_if_index, spd_id, is_add);
Ed Warnickecb9cada2015-12-08 15:45:58 -070054
Billy McFalla9a20e72017-02-15 11:39:12 -050055done:
56 unformat_free (line_input);
57
58 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -070059}
60
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070061/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -070062VLIB_CLI_COMMAND (set_interface_spd_command, static) = {
63 .path = "set interface ipsec spd",
64 .short_help =
65 "set interface ipsec spd <int> <id>",
66 .function = set_interface_spd_command_fn,
67};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070068/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -070069
70static clib_error_t *
71ipsec_sa_add_del_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070072 unformat_input_t * input,
73 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -070074{
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +000075 ipsec_main_t *im = &ipsec_main;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070076 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -070077 ipsec_sa_t sa;
78 int is_add = ~0;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070079 u8 *ck = 0, *ik = 0;
Billy McFalla9a20e72017-02-15 11:39:12 -050080 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -070081
Dave Barachb7b92992018-10-17 10:38:51 -040082 clib_memset (&sa, 0, sizeof (sa));
Ed Warnickecb9cada2015-12-08 15:45:58 -070083
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070084 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -070085 return 0;
86
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070087 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
88 {
89 if (unformat (line_input, "add %u", &sa.id))
90 is_add = 1;
91 else if (unformat (line_input, "del %u", &sa.id))
92 is_add = 0;
93 else if (unformat (line_input, "spi %u", &sa.spi))
94 ;
95 else if (unformat (line_input, "esp"))
96 sa.protocol = IPSEC_PROTOCOL_ESP;
97 else if (unformat (line_input, "ah"))
Billy McFalla9a20e72017-02-15 11:39:12 -050098 {
“mukeshyadav1984”430ac932017-11-23 02:39:33 -080099 sa.protocol = IPSEC_PROTOCOL_AH;
Billy McFalla9a20e72017-02-15 11:39:12 -0500100 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700101 else
102 if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck))
103 sa.crypto_key_len = vec_len (ck);
104 else
105 if (unformat
106 (line_input, "crypto-alg %U", unformat_ipsec_crypto_alg,
107 &sa.crypto_alg))
108 {
Radu Nicolau89c27812018-05-04 12:51:53 +0100109 if (sa.crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
Radu Nicolau6929ea92016-11-29 11:00:30 +0000110 sa.crypto_alg >= IPSEC_CRYPTO_N_ALG)
Billy McFalla9a20e72017-02-15 11:39:12 -0500111 {
112 error = clib_error_return (0, "unsupported crypto-alg: '%U'",
113 format_ipsec_crypto_alg,
114 sa.crypto_alg);
115 goto done;
116 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700117 }
118 else
119 if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik))
120 sa.integ_key_len = vec_len (ik);
121 else if (unformat (line_input, "integ-alg %U", unformat_ipsec_integ_alg,
122 &sa.integ_alg))
123 {
Radu Nicolau89c27812018-05-04 12:51:53 +0100124 if (sa.integ_alg < IPSEC_INTEG_ALG_NONE ||
Radu Nicolau6929ea92016-11-29 11:00:30 +0000125 sa.integ_alg >= IPSEC_INTEG_N_ALG)
Billy McFalla9a20e72017-02-15 11:39:12 -0500126 {
127 error = clib_error_return (0, "unsupported integ-alg: '%U'",
128 format_ipsec_integ_alg,
129 sa.integ_alg);
130 goto done;
131 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700132 }
133 else if (unformat (line_input, "tunnel-src %U",
134 unformat_ip4_address, &sa.tunnel_src_addr.ip4))
135 sa.is_tunnel = 1;
136 else if (unformat (line_input, "tunnel-dst %U",
137 unformat_ip4_address, &sa.tunnel_dst_addr.ip4))
138 sa.is_tunnel = 1;
139 else if (unformat (line_input, "tunnel-src %U",
140 unformat_ip6_address, &sa.tunnel_src_addr.ip6))
141 {
142 sa.is_tunnel = 1;
143 sa.is_tunnel_ip6 = 1;
144 }
145 else if (unformat (line_input, "tunnel-dst %U",
146 unformat_ip6_address, &sa.tunnel_dst_addr.ip6))
147 {
148 sa.is_tunnel = 1;
149 sa.is_tunnel_ip6 = 1;
150 }
Radu Nicolau717de092018-08-03 10:37:24 +0100151 else if (unformat (line_input, "udp-encap"))
152 {
153 sa.udp_encap = 1;
154 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700155 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500156 {
157 error = clib_error_return (0, "parse error: '%U'",
158 format_unformat_error, line_input);
159 goto done;
160 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700161 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700162
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700163 if (sa.crypto_key_len > sizeof (sa.crypto_key))
164 sa.crypto_key_len = sizeof (sa.crypto_key);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700165
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700166 if (sa.integ_key_len > sizeof (sa.integ_key))
167 sa.integ_key_len = sizeof (sa.integ_key);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700168
169 if (ck)
Pierre Pfister62219272018-11-26 09:29:00 +0100170 memcpy (sa.crypto_key, ck, sa.crypto_key_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700171
172 if (ik)
Pierre Pfister62219272018-11-26 09:29:00 +0100173 memcpy (sa.integ_key, ik, sa.integ_key_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700174
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +0000175 if (is_add)
176 {
Klement Sekerab4d30532018-11-08 13:00:02 +0100177 error = ipsec_check_support_cb (im, &sa);
Billy McFalla9a20e72017-02-15 11:39:12 -0500178 if (error)
179 goto done;
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +0000180 }
181
Radu Nicolau717de092018-08-03 10:37:24 +0100182 ipsec_add_del_sa (vm, &sa, is_add);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700183
Billy McFalla9a20e72017-02-15 11:39:12 -0500184done:
185 unformat_free (line_input);
186
187 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700188}
189
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700190/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700191VLIB_CLI_COMMAND (ipsec_sa_add_del_command, static) = {
192 .path = "ipsec sa",
193 .short_help =
194 "ipsec sa [add|del]",
195 .function = ipsec_sa_add_del_command_fn,
196};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700197/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700198
199static clib_error_t *
200ipsec_spd_add_del_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700201 unformat_input_t * input,
202 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700203{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700204 unformat_input_t _line_input, *line_input = &_line_input;
Damjan Marion3f54b182016-08-16 11:27:02 +0200205 u32 spd_id = ~0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700206 int is_add = ~0;
Billy McFalla9a20e72017-02-15 11:39:12 -0500207 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700208
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700209 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700210 return 0;
211
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700212 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
213 {
214 if (unformat (line_input, "add"))
215 is_add = 1;
216 else if (unformat (line_input, "del"))
217 is_add = 0;
218 else if (unformat (line_input, "%u", &spd_id))
219 ;
220 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500221 {
222 error = clib_error_return (0, "parse error: '%U'",
223 format_unformat_error, line_input);
224 goto done;
225 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700226 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700227
Damjan Marion3f54b182016-08-16 11:27:02 +0200228 if (spd_id == ~0)
Billy McFalla9a20e72017-02-15 11:39:12 -0500229 {
230 error = clib_error_return (0, "please specify SPD ID");
231 goto done;
232 }
Damjan Marion3f54b182016-08-16 11:27:02 +0200233
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700234 ipsec_add_del_spd (vm, spd_id, is_add);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700235
Billy McFalla9a20e72017-02-15 11:39:12 -0500236done:
237 unformat_free (line_input);
238
239 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700240}
241
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700242/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700243VLIB_CLI_COMMAND (ipsec_spd_add_del_command, static) = {
244 .path = "ipsec spd",
245 .short_help =
246 "ipsec spd [add|del] <id>",
247 .function = ipsec_spd_add_del_command_fn,
248};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700249/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700250
251
252static clib_error_t *
253ipsec_policy_add_del_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700254 unformat_input_t * input,
255 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700256{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700257 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700258 ipsec_policy_t p;
259 int is_add = 0;
260 int is_ip_any = 1;
261 u32 tmp, tmp2;
Billy McFalla9a20e72017-02-15 11:39:12 -0500262 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700263
Dave Barachb7b92992018-10-17 10:38:51 -0400264 clib_memset (&p, 0, sizeof (p));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700265 p.lport.stop = p.rport.stop = ~0;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700266 p.laddr.stop.ip4.as_u32 = p.raddr.stop.ip4.as_u32 = (u32) ~ 0;
267 p.laddr.stop.ip6.as_u64[0] = p.laddr.stop.ip6.as_u64[1] = (u64) ~ 0;
268 p.raddr.stop.ip6.as_u64[0] = p.raddr.stop.ip6.as_u64[1] = (u64) ~ 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700269
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700270 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700271 return 0;
272
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700273 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
274 {
275 if (unformat (line_input, "add"))
276 is_add = 1;
277 else if (unformat (line_input, "del"))
278 is_add = 0;
279 else if (unformat (line_input, "spd %u", &p.id))
280 ;
281 else if (unformat (line_input, "inbound"))
282 p.is_outbound = 0;
283 else if (unformat (line_input, "outbound"))
284 p.is_outbound = 1;
285 else if (unformat (line_input, "priority %d", &p.priority))
286 ;
287 else if (unformat (line_input, "protocol %u", &tmp))
288 p.protocol = (u8) tmp;
289 else
290 if (unformat
291 (line_input, "action %U", unformat_ipsec_policy_action,
292 &p.policy))
293 {
294 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
Billy McFalla9a20e72017-02-15 11:39:12 -0500295 {
296 error = clib_error_return (0, "unsupported action: 'resolve'");
297 goto done;
298 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700299 }
300 else if (unformat (line_input, "sa %u", &p.sa_id))
301 ;
302 else if (unformat (line_input, "local-ip-range %U - %U",
303 unformat_ip4_address, &p.laddr.start.ip4,
304 unformat_ip4_address, &p.laddr.stop.ip4))
305 is_ip_any = 0;
306 else if (unformat (line_input, "remote-ip-range %U - %U",
307 unformat_ip4_address, &p.raddr.start.ip4,
308 unformat_ip4_address, &p.raddr.stop.ip4))
309 is_ip_any = 0;
310 else if (unformat (line_input, "local-ip-range %U - %U",
311 unformat_ip6_address, &p.laddr.start.ip6,
312 unformat_ip6_address, &p.laddr.stop.ip6))
313 {
314 p.is_ipv6 = 1;
315 is_ip_any = 0;
316 }
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;
322 is_ip_any = 0;
323 }
324 else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2))
325 {
326 p.lport.start = tmp;
327 p.lport.stop = tmp2;
328 }
329 else
330 if (unformat (line_input, "remote-port-range %u - %u", &tmp, &tmp2))
331 {
332 p.rport.start = tmp;
333 p.rport.stop = tmp2;
334 }
335 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500336 {
337 error = clib_error_return (0, "parse error: '%U'",
338 format_unformat_error, line_input);
339 goto done;
340 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700341 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700342
“mukeshyadav1984”430ac932017-11-23 02:39:33 -0800343 /* Check if SA is for IPv6/AH which is not supported. Return error if TRUE. */
344 if (p.sa_id)
345 {
346 uword *p1;
347 ipsec_main_t *im = &ipsec_main;
348 ipsec_sa_t *sa = 0;
349 p1 = hash_get (im->sa_index_by_sa_id, p.sa_id);
Klement Sekerac2fc57e2018-06-28 14:20:12 +0200350 if (!p1)
351 {
352 error =
353 clib_error_return (0, "SA with index %u not found", p.sa_id);
354 goto done;
355 }
“mukeshyadav1984”430ac932017-11-23 02:39:33 -0800356 sa = pool_elt_at_index (im->sad, p1[0]);
357 if (sa && sa->protocol == IPSEC_PROTOCOL_AH && is_add && p.is_ipv6)
358 {
359 error = clib_error_return (0, "AH not supported for IPV6: '%U'",
360 format_unformat_error, line_input);
361 goto done;
362 }
363 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700364 ipsec_add_del_policy (vm, &p, is_add);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700365 if (is_ip_any)
366 {
367 p.is_ipv6 = 1;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700368 ipsec_add_del_policy (vm, &p, is_add);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700369 }
Billy McFalla9a20e72017-02-15 11:39:12 -0500370
371done:
372 unformat_free (line_input);
373
374 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700375}
376
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700377/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700378VLIB_CLI_COMMAND (ipsec_policy_add_del_command, static) = {
379 .path = "ipsec policy",
380 .short_help =
381 "ipsec policy [add|del] spd <id> priority <n> ",
382 .function = ipsec_policy_add_del_command_fn,
383};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700384/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700385
386static clib_error_t *
387set_ipsec_sa_key_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700388 unformat_input_t * input,
389 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700390{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700391 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700392 ipsec_sa_t sa;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700393 u8 *ck = 0, *ik = 0;
Billy McFalla9a20e72017-02-15 11:39:12 -0500394 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700395
Dave Barachb7b92992018-10-17 10:38:51 -0400396 clib_memset (&sa, 0, sizeof (sa));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700397
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700398 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700399 return 0;
400
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700401 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
402 {
403 if (unformat (line_input, "%u", &sa.id))
404 ;
405 else
406 if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck))
407 sa.crypto_key_len = vec_len (ck);
408 else
409 if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik))
410 sa.integ_key_len = vec_len (ik);
411 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500412 {
413 error = clib_error_return (0, "parse error: '%U'",
414 format_unformat_error, line_input);
415 goto done;
416 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700417 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700418
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700419 if (sa.crypto_key_len > sizeof (sa.crypto_key))
420 sa.crypto_key_len = sizeof (sa.crypto_key);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700421
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700422 if (sa.integ_key_len > sizeof (sa.integ_key))
423 sa.integ_key_len = sizeof (sa.integ_key);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700424
425 if (ck)
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700426 strncpy ((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700427
428 if (ik)
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700429 strncpy ((char *) sa.integ_key, (char *) ik, sa.integ_key_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700430
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700431 ipsec_set_sa_key (vm, &sa);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700432
Billy McFalla9a20e72017-02-15 11:39:12 -0500433done:
434 unformat_free (line_input);
435
436 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700437}
438
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700439/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700440VLIB_CLI_COMMAND (set_ipsec_sa_key_command, static) = {
441 .path = "set ipsec sa",
442 .short_help =
443 "set ipsec sa <id> crypto-key <key> integ-key <key>",
444 .function = set_ipsec_sa_key_command_fn,
445};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700446/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700447
448static clib_error_t *
449show_ipsec_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700450 unformat_input_t * input, vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700451{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700452 ipsec_spd_t *spd;
453 ipsec_sa_t *sa;
454 ipsec_policy_t *p;
455 ipsec_main_t *im = &ipsec_main;
456 u32 *i;
457 ipsec_tunnel_if_t *t;
458 vnet_hw_interface_t *hi;
Klement Sekeraea841302018-05-11 12:59:05 +0200459 u8 *protocol = NULL;
460 u8 *policy = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700461
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700462 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700463 pool_foreach (sa, im->sad, ({
464 if (sa->id) {
Neale Rannsde847272018-11-28 01:38:34 -0800465 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 -0700466 sa->is_tunnel ? "tunnel" : "transport",
Klement Sekera4b089f22018-04-17 18:04:57 +0200467 sa->protocol ? "esp" : "ah",
Neale Rannsde847272018-11-28 01:38:34 -0800468 sa->udp_encap ? " udp-encap-enabled" : "",
469 sa->use_anti_replay ? " anti-replay" : "",
470 sa->use_esn ? " extended-sequence-number" : "");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700471 if (sa->protocol == IPSEC_PROTOCOL_ESP) {
472 vlib_cli_output(vm, " crypto alg %U%s%U integrity alg %U%s%U",
473 format_ipsec_crypto_alg, sa->crypto_alg,
474 sa->crypto_alg ? " key " : "",
475 format_hex_bytes, sa->crypto_key, sa->crypto_key_len,
476 format_ipsec_integ_alg, sa->integ_alg,
477 sa->integ_alg ? " key " : "",
478 format_hex_bytes, sa->integ_key, sa->integ_key_len);
479 }
480 if (sa->is_tunnel && sa->is_tunnel_ip6) {
481 vlib_cli_output(vm, " tunnel src %U dst %U",
482 format_ip6_address, &sa->tunnel_src_addr.ip6,
483 format_ip6_address, &sa->tunnel_dst_addr.ip6);
484 } else if (sa->is_tunnel) {
485 vlib_cli_output(vm, " tunnel src %U dst %U",
486 format_ip4_address, &sa->tunnel_src_addr.ip4,
487 format_ip4_address, &sa->tunnel_dst_addr.ip4);
488 }
489 }
490 }));
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700491 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700492
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700493 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700494 pool_foreach (spd, im->spds, ({
495 vlib_cli_output(vm, "spd %u", spd->id);
496
497 vlib_cli_output(vm, " outbound policies");
498 vec_foreach(i, spd->ipv4_outbound_policies)
499 {
500 p = pool_elt_at_index(spd->policies, *i);
Klement Sekeraea841302018-05-11 12:59:05 +0200501 vec_reset_length(protocol);
502 vec_reset_length(policy);
503 if (p->protocol) {
504 protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
505 } else {
506 protocol = format(protocol, "any");
507 }
508 if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
509 policy = format(policy, " sa %u", p->sa_id);
510 }
511
512 vlib_cli_output(vm, " priority %d action %U protocol %v%v",
513 p->priority, format_ipsec_policy_action, p->policy,
514 protocol, policy);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700515 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
516 format_ip4_address, &p->laddr.start.ip4,
517 format_ip4_address, &p->laddr.stop.ip4,
518 p->lport.start, p->lport.stop);
Paul Vinciguerrabdc0e6b2018-09-22 05:32:50 -0700519 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700520 format_ip4_address, &p->raddr.start.ip4,
521 format_ip4_address, &p->raddr.stop.ip4,
522 p->rport.start, p->rport.stop);
523 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
524 p->counter.bytes);
525 };
526 vec_foreach(i, spd->ipv6_outbound_policies)
527 {
528 p = pool_elt_at_index(spd->policies, *i);
Klement Sekeraea841302018-05-11 12:59:05 +0200529 vec_reset_length(protocol);
530 vec_reset_length(policy);
531 if (p->protocol) {
532 protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
533 } else {
534 protocol = format(protocol, "any");
535 }
536 if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
537 policy = format(policy, " sa %u", p->sa_id);
538 }
539 vlib_cli_output(vm, " priority %d action %U protocol %v%v",
540 p->priority, format_ipsec_policy_action, p->policy,
541 protocol, policy);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700542 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
543 format_ip6_address, &p->laddr.start.ip6,
544 format_ip6_address, &p->laddr.stop.ip6,
545 p->lport.start, p->lport.stop);
546 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
547 format_ip6_address, &p->raddr.start.ip6,
548 format_ip6_address, &p->raddr.stop.ip6,
549 p->rport.start, p->rport.stop);
550 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
551 p->counter.bytes);
552 };
553 vlib_cli_output(vm, " inbound policies");
554 vec_foreach(i, spd->ipv4_inbound_protect_policy_indices)
555 {
556 p = pool_elt_at_index(spd->policies, *i);
Klement Sekeraea841302018-05-11 12:59:05 +0200557 vec_reset_length(protocol);
558 vec_reset_length(policy);
559 if (p->protocol) {
560 protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
561 } else {
562 protocol = format(protocol, "any");
563 }
564 if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
565 policy = format(policy, " sa %u", p->sa_id);
566 }
567 vlib_cli_output(vm, " priority %d action %U protocol %v%v",
568 p->priority, format_ipsec_policy_action, p->policy,
569 protocol, policy);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700570 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
571 format_ip4_address, &p->laddr.start.ip4,
572 format_ip4_address, &p->laddr.stop.ip4,
573 p->lport.start, p->lport.stop);
Paul Vinciguerrabdc0e6b2018-09-22 05:32:50 -0700574 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700575 format_ip4_address, &p->raddr.start.ip4,
576 format_ip4_address, &p->raddr.stop.ip4,
577 p->rport.start, p->rport.stop);
578 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
579 p->counter.bytes);
580 };
581 vec_foreach(i, spd->ipv4_inbound_policy_discard_and_bypass_indices)
582 {
583 p = pool_elt_at_index(spd->policies, *i);
Klement Sekeraea841302018-05-11 12:59:05 +0200584 vec_reset_length(protocol);
585 vec_reset_length(policy);
586 if (p->protocol) {
587 protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
588 } else {
589 protocol = format(protocol, "any");
590 }
591 if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
592 policy = format(policy, " sa %u", p->sa_id);
593 }
594 vlib_cli_output(vm, " priority %d action %U protocol %v%v",
595 p->priority, format_ipsec_policy_action, p->policy,
596 protocol, policy);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700597 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
598 format_ip4_address, &p->laddr.start.ip4,
599 format_ip4_address, &p->laddr.stop.ip4,
600 p->lport.start, p->lport.stop);
Paul Vinciguerrabdc0e6b2018-09-22 05:32:50 -0700601 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700602 format_ip4_address, &p->raddr.start.ip4,
603 format_ip4_address, &p->raddr.stop.ip4,
604 p->rport.start, p->rport.stop);
605 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
606 p->counter.bytes);
607 };
608 vec_foreach(i, spd->ipv6_inbound_protect_policy_indices)
609 {
610 p = pool_elt_at_index(spd->policies, *i);
Klement Sekeraea841302018-05-11 12:59:05 +0200611 vec_reset_length(protocol);
612 vec_reset_length(policy);
613 if (p->protocol) {
614 protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
615 } else {
616 protocol = format(protocol, "any");
617 }
618 if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
619 policy = format(policy, " sa %u", p->sa_id);
620 }
621 vlib_cli_output(vm, " priority %d action %U protocol %v%v",
622 p->priority, format_ipsec_policy_action, p->policy,
623 protocol, policy);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700624 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
625 format_ip6_address, &p->laddr.start.ip6,
626 format_ip6_address, &p->laddr.stop.ip6,
627 p->lport.start, p->lport.stop);
628 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
629 format_ip6_address, &p->raddr.start.ip6,
630 format_ip6_address, &p->raddr.stop.ip6,
631 p->rport.start, p->rport.stop);
632 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
633 p->counter.bytes);
634 };
635 vec_foreach(i, spd->ipv6_inbound_policy_discard_and_bypass_indices)
636 {
637 p = pool_elt_at_index(spd->policies, *i);
Klement Sekeraea841302018-05-11 12:59:05 +0200638 vec_reset_length(protocol);
639 vec_reset_length(policy);
640 if (p->protocol) {
641 protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
642 } else {
643 protocol = format(protocol, "any");
644 }
645 if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
646 policy = format(policy, " sa %u", p->sa_id);
647 }
648 vlib_cli_output(vm, " priority %d action %U protocol %v%v",
649 p->priority, format_ipsec_policy_action, p->policy,
650 protocol, policy);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700651 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
652 format_ip6_address, &p->laddr.start.ip6,
653 format_ip6_address, &p->laddr.stop.ip6,
654 p->lport.start, p->lport.stop);
655 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
656 format_ip6_address, &p->raddr.start.ip6,
657 format_ip6_address, &p->raddr.stop.ip6,
658 p->rport.start, p->rport.stop);
659 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
660 p->counter.bytes);
661 };
662 }));
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700663 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700664
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700665 vlib_cli_output (vm, "tunnel interfaces");
666 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700667 pool_foreach (t, im->tunnel_interfaces, ({
Matus Fabian694265d2016-08-10 01:55:36 -0700668 if (t->hw_if_index == ~0)
669 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700670 hi = vnet_get_hw_interface (im->vnet_main, t->hw_if_index);
671 vlib_cli_output(vm, " %s seq", hi->name);
672 sa = pool_elt_at_index(im->sad, t->output_sa_index);
Radu Nicolau717de092018-08-03 10:37:24 +0100673 vlib_cli_output(vm, " seq %u seq-hi %u esn %u anti-replay %u udp-encap %u",
674 sa->seq, sa->seq_hi, sa->use_esn, sa->use_anti_replay, sa->udp_encap);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700675 vlib_cli_output(vm, " local-spi %u local-ip %U", sa->spi,
676 format_ip4_address, &sa->tunnel_src_addr.ip4);
677 vlib_cli_output(vm, " local-crypto %U %U",
678 format_ipsec_crypto_alg, sa->crypto_alg,
679 format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
680 vlib_cli_output(vm, " local-integrity %U %U",
681 format_ipsec_integ_alg, sa->integ_alg,
682 format_hex_bytes, sa->integ_key, sa->integ_key_len);
683 sa = pool_elt_at_index(im->sad, t->input_sa_index);
684 vlib_cli_output(vm, " last-seq %u last-seq-hi %u esn %u anti-replay %u window %U",
685 sa->last_seq, sa->last_seq_hi, sa->use_esn,
686 sa->use_anti_replay,
687 format_ipsec_replay_window, sa->replay_window);
688 vlib_cli_output(vm, " remote-spi %u remote-ip %U", sa->spi,
689 format_ip4_address, &sa->tunnel_src_addr.ip4);
690 vlib_cli_output(vm, " remote-crypto %U %U",
691 format_ipsec_crypto_alg, sa->crypto_alg,
692 format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
693 vlib_cli_output(vm, " remote-integrity %U %U",
694 format_ipsec_integ_alg, sa->integ_alg,
695 format_hex_bytes, sa->integ_key, sa->integ_key_len);
696 }));
Klement Sekeraea841302018-05-11 12:59:05 +0200697 vec_free(policy);
698 vec_free(protocol);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700699 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700700 return 0;
701}
702
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700703/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700704VLIB_CLI_COMMAND (show_ipsec_command, static) = {
705 .path = "show ipsec",
Klement Sekerab4d30532018-11-08 13:00:02 +0100706 .short_help = "show ipsec [backends]",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700707 .function = show_ipsec_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 *
Klement Sekerab4d30532018-11-08 13:00:02 +0100712ipsec_show_backends_command_fn (vlib_main_t * vm,
713 unformat_input_t * input,
714 vlib_cli_command_t * cmd)
715{
716 ipsec_main_t *im = &ipsec_main;
717 u32 verbose = 0;
718
719 (void) unformat (input, "verbose %u", &verbose);
720
721 vlib_cli_output (vm, "IPsec AH backends available:");
722 u8 *s = format (NULL, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
723 ipsec_ah_backend_t *ab;
724 /* *INDENT-OFF* */
725 pool_foreach (ab, im->ah_backends, {
726 s = format (s, "%=25s %=25u %=10s\n", ab->name, ab - im->ah_backends,
727 ab - im->ah_backends == im->ah_current_backend ? "yes" : "no");
728 if (verbose) {
729 vlib_node_t *n;
730 n = vlib_get_node (vm, ab->ah4_encrypt_node_index);
731 s = format (s, " enc4 %s (next %d)\n", n->name, ab->ah4_encrypt_next_index);
732 n = vlib_get_node (vm, ab->ah4_decrypt_node_index);
733 s = format (s, " dec4 %s (next %d)\n", n->name, ab->ah4_decrypt_next_index);
734 n = vlib_get_node (vm, ab->ah6_encrypt_node_index);
735 s = format (s, " enc6 %s (next %d)\n", n->name, ab->ah6_encrypt_next_index);
736 n = vlib_get_node (vm, ab->ah6_decrypt_node_index);
737 s = format (s, " dec6 %s (next %d)\n", n->name, ab->ah6_decrypt_next_index);
738 }
739 });
740 /* *INDENT-ON* */
741 vlib_cli_output (vm, "%v", s);
742 _vec_len (s) = 0;
743 vlib_cli_output (vm, "IPsec ESP backends available:");
744 s = format (s, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
745 ipsec_esp_backend_t *eb;
746 /* *INDENT-OFF* */
747 pool_foreach (eb, im->esp_backends, {
748 s = format (s, "%=25s %=25u %=10s\n", eb->name, eb - im->esp_backends,
749 eb - im->esp_backends == im->esp_current_backend ? "yes"
750 : "no");
751 if (verbose) {
752 vlib_node_t *n;
753 n = vlib_get_node (vm, eb->esp4_encrypt_node_index);
754 s = format (s, " enc4 %s (next %d)\n", n->name, eb->esp4_encrypt_next_index);
755 n = vlib_get_node (vm, eb->esp4_decrypt_node_index);
756 s = format (s, " dec4 %s (next %d)\n", n->name, eb->esp4_decrypt_next_index);
757 n = vlib_get_node (vm, eb->esp6_encrypt_node_index);
758 s = format (s, " enc6 %s (next %d)\n", n->name, eb->esp6_encrypt_next_index);
759 n = vlib_get_node (vm, eb->esp6_decrypt_node_index);
760 s = format (s, " dec6 %s (next %d)\n", n->name, eb->esp6_decrypt_next_index);
761 }
762 });
763 /* *INDENT-ON* */
764 vlib_cli_output (vm, "%v", s);
765
766 vec_free (s);
767 return 0;
768}
769
770/* *INDENT-OFF* */
771VLIB_CLI_COMMAND (ipsec_show_backends_command, static) = {
772 .path = "show ipsec backends",
773 .short_help = "show ipsec backends",
774 .function = ipsec_show_backends_command_fn,
775};
776/* *INDENT-ON* */
777
778static clib_error_t *
779ipsec_select_backend_command_fn (vlib_main_t * vm,
780 unformat_input_t * input,
781 vlib_cli_command_t * cmd)
782{
783 u32 backend_index;
784 ipsec_main_t *im = &ipsec_main;
785
786 if (pool_elts (im->sad) > 0)
787 {
788 return clib_error_return (0,
789 "Cannot change IPsec backend, while %u SA entries are configured",
790 pool_elts (im->sad));
791 }
792
793 unformat_input_t _line_input, *line_input = &_line_input;
794 /* Get a line of input. */
795 if (!unformat_user (input, unformat_line_input, line_input))
796 return 0;
797
798 if (unformat (line_input, "ah"))
799 {
800 if (unformat (line_input, "%u", &backend_index))
801 {
802 if (ipsec_select_ah_backend (im, backend_index) < 0)
803 {
804 return clib_error_return (0, "Invalid AH backend index `%u'",
805 backend_index);
806 }
807 }
808 else
809 {
810 return clib_error_return (0, "Invalid backend index `%U'",
811 format_unformat_error, line_input);
812 }
813 }
814 else if (unformat (line_input, "esp"))
815 {
816 if (unformat (line_input, "%u", &backend_index))
817 {
818 if (ipsec_select_esp_backend (im, backend_index) < 0)
819 {
820 return clib_error_return (0, "Invalid ESP backend index `%u'",
821 backend_index);
822 }
823 }
824 else
825 {
826 return clib_error_return (0, "Invalid backend index `%U'",
827 format_unformat_error, line_input);
828 }
829 }
830 else
831 {
832 return clib_error_return (0, "Unknown input `%U'",
833 format_unformat_error, line_input);
834 }
835
836 return 0;
837}
838
839/* *INDENT-OFF* */
840VLIB_CLI_COMMAND (ipsec_select_backend_command, static) = {
841 .path = "ipsec select backend",
842 .short_help = "ipsec select backend <ah|esp> <backend index>",
843 .function = ipsec_select_backend_command_fn,
844};
845
846/* *INDENT-ON* */
847
848static clib_error_t *
Ed Warnickecb9cada2015-12-08 15:45:58 -0700849clear_ipsec_counters_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700850 unformat_input_t * input,
851 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700852{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700853 ipsec_main_t *im = &ipsec_main;
854 ipsec_spd_t *spd;
855 ipsec_policy_t *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700856
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700857 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700858 pool_foreach (spd, im->spds, ({
859 pool_foreach(p, spd->policies, ({
860 p->counter.packets = p->counter.bytes = 0;
861 }));
862 }));
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700863 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700864
865 return 0;
866}
867
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700868/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700869VLIB_CLI_COMMAND (clear_ipsec_counters_command, static) = {
870 .path = "clear ipsec counters",
871 .short_help = "clear ipsec counters",
872 .function = clear_ipsec_counters_command_fn,
873};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700874/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700875
876static clib_error_t *
877create_ipsec_tunnel_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700878 unformat_input_t * input,
879 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700880{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700881 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700882 ipsec_add_del_tunnel_args_t a;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700883 int rv;
884 u32 num_m_args = 0;
Billy McFalla9a20e72017-02-15 11:39:12 -0500885 clib_error_t *error = NULL;
Matthew Smith2838a232016-06-21 16:05:09 -0500886
Dave Barachb7b92992018-10-17 10:38:51 -0400887 clib_memset (&a, 0, sizeof (a));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700888 a.is_add = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700889
890 /* Get a line of input. */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700891 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700892 return 0;
893
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700894 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
895 {
896 if (unformat
897 (line_input, "local-ip %U", unformat_ip4_address, &a.local_ip))
898 num_m_args++;
899 else
900 if (unformat
901 (line_input, "remote-ip %U", unformat_ip4_address, &a.remote_ip))
902 num_m_args++;
903 else if (unformat (line_input, "local-spi %u", &a.local_spi))
904 num_m_args++;
905 else if (unformat (line_input, "remote-spi %u", &a.remote_spi))
906 num_m_args++;
Matthew Smith8e1039a2018-04-12 07:32:56 -0500907 else if (unformat (line_input, "instance %u", &a.show_instance))
908 a.renumber = 1;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700909 else if (unformat (line_input, "del"))
910 a.is_add = 0;
Radu Nicolau717de092018-08-03 10:37:24 +0100911 else if (unformat (line_input, "udp-encap"))
912 a.udp_encap = 1;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700913 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500914 {
915 error = clib_error_return (0, "unknown input `%U'",
916 format_unformat_error, line_input);
917 goto done;
918 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700919 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700920
921 if (num_m_args < 4)
Billy McFalla9a20e72017-02-15 11:39:12 -0500922 {
923 error = clib_error_return (0, "mandatory argument(s) missing");
924 goto done;
925 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700926
Matthew Smith2838a232016-06-21 16:05:09 -0500927 rv = ipsec_add_del_tunnel_if (&a);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700928
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700929 switch (rv)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700930 {
931 case 0:
932 break;
933 case VNET_API_ERROR_INVALID_VALUE:
934 if (a.is_add)
Billy McFalla9a20e72017-02-15 11:39:12 -0500935 error = clib_error_return (0,
936 "IPSec tunnel interface already exists...");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700937 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500938 error = clib_error_return (0, "IPSec tunnel interface not exists...");
939 goto done;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700940 default:
Billy McFalla9a20e72017-02-15 11:39:12 -0500941 error = clib_error_return (0, "ipsec_register_interface returned %d",
942 rv);
943 goto done;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700944 }
945
Billy McFalla9a20e72017-02-15 11:39:12 -0500946done:
947 unformat_free (line_input);
948
949 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700950}
951
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700952/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700953VLIB_CLI_COMMAND (create_ipsec_tunnel_command, static) = {
954 .path = "create ipsec tunnel",
Radu Nicolau717de092018-08-03 10:37:24 +0100955 .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> remote-ip <addr> remote-spi <spi> [instance <inst_num>] [udp-encap]",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700956 .function = create_ipsec_tunnel_command_fn,
957};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700958/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700959
960static clib_error_t *
961set_interface_key_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700962 unformat_input_t * input,
963 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700964{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700965 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700966 ipsec_main_t *im = &ipsec_main;
967 ipsec_if_set_key_type_t type = IPSEC_IF_SET_KEY_TYPE_NONE;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700968 u32 hw_if_index = (u32) ~ 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700969 u32 alg;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700970 u8 *key = 0;
Billy McFalla9a20e72017-02-15 11:39:12 -0500971 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700972
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700973 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700974 return 0;
975
976 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
977 {
978 if (unformat (line_input, "%U",
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700979 unformat_vnet_hw_interface, im->vnet_main, &hw_if_index))
980 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700981 else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700982 if (unformat
983 (line_input, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
984 type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
985 else
986 if (unformat
987 (line_input, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
988 type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
989 else
990 if (unformat
991 (line_input, "local integ %U", unformat_ipsec_integ_alg, &alg))
992 type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
993 else
994 if (unformat
995 (line_input, "remote integ %U", unformat_ipsec_integ_alg, &alg))
996 type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
997 else if (unformat (line_input, "%U", unformat_hex_string, &key))
998 ;
999 else
Billy McFalla9a20e72017-02-15 11:39:12 -05001000 {
1001 error = clib_error_return (0, "parse error: '%U'",
1002 format_unformat_error, line_input);
1003 goto done;
1004 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07001005 }
1006
Ed Warnickecb9cada2015-12-08 15:45:58 -07001007 if (type == IPSEC_IF_SET_KEY_TYPE_NONE)
Billy McFalla9a20e72017-02-15 11:39:12 -05001008 {
1009 error = clib_error_return (0, "unknown key type");
1010 goto done;
1011 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07001012
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001013 if (alg > 0 && vec_len (key) == 0)
Billy McFalla9a20e72017-02-15 11:39:12 -05001014 {
1015 error = clib_error_return (0, "key is not specified");
1016 goto done;
1017 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07001018
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001019 if (hw_if_index == (u32) ~ 0)
Billy McFalla9a20e72017-02-15 11:39:12 -05001020 {
1021 error = clib_error_return (0, "interface not specified");
1022 goto done;
1023 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07001024
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001025 ipsec_set_interface_key (im->vnet_main, hw_if_index, type, alg, key);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001026
Billy McFalla9a20e72017-02-15 11:39:12 -05001027done:
1028 vec_free (key);
1029 unformat_free (line_input);
1030
1031 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001032}
1033
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001034/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -07001035VLIB_CLI_COMMAND (set_interface_key_command, static) = {
1036 .path = "set interface ipsec key",
1037 .short_help =
1038 "set interface ipsec key <int> <local|remote> <crypto|integ> <key type> <key>",
1039 .function = set_interface_key_command_fn,
1040};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001041/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -07001042
Ed Warnickecb9cada2015-12-08 15:45:58 -07001043clib_error_t *
1044ipsec_cli_init (vlib_main_t * vm)
1045{
1046 return 0;
1047}
1048
1049VLIB_INIT_FUNCTION (ipsec_cli_init);
1050
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001051
1052/*
1053 * fd.io coding-style-patch-verification: ON
1054 *
1055 * Local Variables:
1056 * eval: (c-set-style "gnu")
1057 * End:
1058 */