blob: 741df31dfe48d11463c519a7f3865fd095b9c49f [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;
261 int is_add = 0;
262 int is_ip_any = 1;
263 u32 tmp, tmp2;
Billy McFalla9a20e72017-02-15 11:39:12 -0500264 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700265
Dave Barachb7b92992018-10-17 10:38:51 -0400266 clib_memset (&p, 0, sizeof (p));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700267 p.lport.stop = p.rport.stop = ~0;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700268 p.laddr.stop.ip4.as_u32 = p.raddr.stop.ip4.as_u32 = (u32) ~ 0;
269 p.laddr.stop.ip6.as_u64[0] = p.laddr.stop.ip6.as_u64[1] = (u64) ~ 0;
270 p.raddr.stop.ip6.as_u64[0] = p.raddr.stop.ip6.as_u64[1] = (u64) ~ 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700271
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700272 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700273 return 0;
274
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700275 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
276 {
277 if (unformat (line_input, "add"))
278 is_add = 1;
279 else if (unformat (line_input, "del"))
280 is_add = 0;
281 else if (unformat (line_input, "spd %u", &p.id))
282 ;
283 else if (unformat (line_input, "inbound"))
284 p.is_outbound = 0;
285 else if (unformat (line_input, "outbound"))
286 p.is_outbound = 1;
287 else if (unformat (line_input, "priority %d", &p.priority))
288 ;
289 else if (unformat (line_input, "protocol %u", &tmp))
290 p.protocol = (u8) tmp;
291 else
292 if (unformat
293 (line_input, "action %U", unformat_ipsec_policy_action,
294 &p.policy))
295 {
296 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
Billy McFalla9a20e72017-02-15 11:39:12 -0500297 {
298 error = clib_error_return (0, "unsupported action: 'resolve'");
299 goto done;
300 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700301 }
302 else if (unformat (line_input, "sa %u", &p.sa_id))
303 ;
304 else if (unformat (line_input, "local-ip-range %U - %U",
305 unformat_ip4_address, &p.laddr.start.ip4,
306 unformat_ip4_address, &p.laddr.stop.ip4))
307 is_ip_any = 0;
308 else if (unformat (line_input, "remote-ip-range %U - %U",
309 unformat_ip4_address, &p.raddr.start.ip4,
310 unformat_ip4_address, &p.raddr.stop.ip4))
311 is_ip_any = 0;
312 else if (unformat (line_input, "local-ip-range %U - %U",
313 unformat_ip6_address, &p.laddr.start.ip6,
314 unformat_ip6_address, &p.laddr.stop.ip6))
315 {
316 p.is_ipv6 = 1;
317 is_ip_any = 0;
318 }
319 else if (unformat (line_input, "remote-ip-range %U - %U",
320 unformat_ip6_address, &p.raddr.start.ip6,
321 unformat_ip6_address, &p.raddr.stop.ip6))
322 {
323 p.is_ipv6 = 1;
324 is_ip_any = 0;
325 }
326 else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2))
327 {
328 p.lport.start = tmp;
329 p.lport.stop = tmp2;
330 }
331 else
332 if (unformat (line_input, "remote-port-range %u - %u", &tmp, &tmp2))
333 {
334 p.rport.start = tmp;
335 p.rport.stop = tmp2;
336 }
337 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500338 {
339 error = clib_error_return (0, "parse error: '%U'",
340 format_unformat_error, line_input);
341 goto done;
342 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700343 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700344
“mukeshyadav1984”430ac932017-11-23 02:39:33 -0800345 /* Check if SA is for IPv6/AH which is not supported. Return error if TRUE. */
346 if (p.sa_id)
347 {
348 uword *p1;
349 ipsec_main_t *im = &ipsec_main;
350 ipsec_sa_t *sa = 0;
351 p1 = hash_get (im->sa_index_by_sa_id, p.sa_id);
Klement Sekerac2fc57e2018-06-28 14:20:12 +0200352 if (!p1)
353 {
354 error =
355 clib_error_return (0, "SA with index %u not found", p.sa_id);
356 goto done;
357 }
“mukeshyadav1984”430ac932017-11-23 02:39:33 -0800358 sa = pool_elt_at_index (im->sad, p1[0]);
359 if (sa && sa->protocol == IPSEC_PROTOCOL_AH && is_add && p.is_ipv6)
360 {
361 error = clib_error_return (0, "AH not supported for IPV6: '%U'",
362 format_unformat_error, line_input);
363 goto done;
364 }
365 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700366 ipsec_add_del_policy (vm, &p, is_add);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700367 if (is_ip_any)
368 {
369 p.is_ipv6 = 1;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700370 ipsec_add_del_policy (vm, &p, is_add);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700371 }
Billy McFalla9a20e72017-02-15 11:39:12 -0500372
373done:
374 unformat_free (line_input);
375
376 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700377}
378
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700379/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700380VLIB_CLI_COMMAND (ipsec_policy_add_del_command, static) = {
381 .path = "ipsec policy",
382 .short_help =
383 "ipsec policy [add|del] spd <id> priority <n> ",
384 .function = ipsec_policy_add_del_command_fn,
385};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700386/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700387
388static clib_error_t *
389set_ipsec_sa_key_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700390 unformat_input_t * input,
391 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700392{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700393 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700394 ipsec_sa_t sa;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700395 u8 *ck = 0, *ik = 0;
Billy McFalla9a20e72017-02-15 11:39:12 -0500396 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700397
Dave Barachb7b92992018-10-17 10:38:51 -0400398 clib_memset (&sa, 0, sizeof (sa));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700399
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700400 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700401 return 0;
402
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700403 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
404 {
405 if (unformat (line_input, "%u", &sa.id))
406 ;
407 else
408 if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck))
409 sa.crypto_key_len = vec_len (ck);
410 else
411 if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik))
412 sa.integ_key_len = vec_len (ik);
413 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500414 {
415 error = clib_error_return (0, "parse error: '%U'",
416 format_unformat_error, line_input);
417 goto done;
418 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700419 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700420
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700421 if (sa.crypto_key_len > sizeof (sa.crypto_key))
422 sa.crypto_key_len = sizeof (sa.crypto_key);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700423
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700424 if (sa.integ_key_len > sizeof (sa.integ_key))
425 sa.integ_key_len = sizeof (sa.integ_key);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700426
427 if (ck)
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700428 strncpy ((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700429
430 if (ik)
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700431 strncpy ((char *) sa.integ_key, (char *) ik, sa.integ_key_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700432
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700433 ipsec_set_sa_key (vm, &sa);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700434
Billy McFalla9a20e72017-02-15 11:39:12 -0500435done:
436 unformat_free (line_input);
437
438 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700439}
440
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700441/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700442VLIB_CLI_COMMAND (set_ipsec_sa_key_command, static) = {
443 .path = "set ipsec sa",
444 .short_help =
445 "set ipsec sa <id> crypto-key <key> integ-key <key>",
446 .function = set_ipsec_sa_key_command_fn,
447};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700448/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700449
450static clib_error_t *
451show_ipsec_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700452 unformat_input_t * input, vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700453{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700454 ipsec_spd_t *spd;
455 ipsec_sa_t *sa;
456 ipsec_policy_t *p;
457 ipsec_main_t *im = &ipsec_main;
458 u32 *i;
459 ipsec_tunnel_if_t *t;
460 vnet_hw_interface_t *hi;
Klement Sekeraea841302018-05-11 12:59:05 +0200461 u8 *protocol = NULL;
462 u8 *policy = NULL;
Neale Ranns311124e2019-01-24 04:52:25 -0800463 u32 tx_table_id, spd_id, sw_if_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700464
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700465 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700466 pool_foreach (sa, im->sad, ({
467 if (sa->id) {
Neale Rannsde847272018-11-28 01:38:34 -0800468 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 -0700469 sa->is_tunnel ? "tunnel" : "transport",
Klement Sekera4b089f22018-04-17 18:04:57 +0200470 sa->protocol ? "esp" : "ah",
Neale Rannsde847272018-11-28 01:38:34 -0800471 sa->udp_encap ? " udp-encap-enabled" : "",
472 sa->use_anti_replay ? " anti-replay" : "",
473 sa->use_esn ? " extended-sequence-number" : "");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700474 if (sa->protocol == IPSEC_PROTOCOL_ESP) {
475 vlib_cli_output(vm, " crypto alg %U%s%U integrity alg %U%s%U",
476 format_ipsec_crypto_alg, sa->crypto_alg,
477 sa->crypto_alg ? " key " : "",
478 format_hex_bytes, sa->crypto_key, sa->crypto_key_len,
479 format_ipsec_integ_alg, sa->integ_alg,
480 sa->integ_alg ? " key " : "",
481 format_hex_bytes, sa->integ_key, sa->integ_key_len);
482 }
483 if (sa->is_tunnel && sa->is_tunnel_ip6) {
484 vlib_cli_output(vm, " tunnel src %U dst %U",
485 format_ip6_address, &sa->tunnel_src_addr.ip6,
486 format_ip6_address, &sa->tunnel_dst_addr.ip6);
487 } else if (sa->is_tunnel) {
488 vlib_cli_output(vm, " tunnel src %U dst %U",
489 format_ip4_address, &sa->tunnel_src_addr.ip4,
490 format_ip4_address, &sa->tunnel_dst_addr.ip4);
491 }
492 }
493 }));
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700494 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700495
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700496 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700497 pool_foreach (spd, im->spds, ({
498 vlib_cli_output(vm, "spd %u", spd->id);
499
500 vlib_cli_output(vm, " outbound policies");
501 vec_foreach(i, spd->ipv4_outbound_policies)
502 {
503 p = pool_elt_at_index(spd->policies, *i);
Klement Sekeraea841302018-05-11 12:59:05 +0200504 vec_reset_length(protocol);
505 vec_reset_length(policy);
506 if (p->protocol) {
507 protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
508 } else {
509 protocol = format(protocol, "any");
510 }
511 if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
512 policy = format(policy, " sa %u", p->sa_id);
513 }
514
515 vlib_cli_output(vm, " priority %d action %U protocol %v%v",
516 p->priority, format_ipsec_policy_action, p->policy,
517 protocol, policy);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700518 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
519 format_ip4_address, &p->laddr.start.ip4,
520 format_ip4_address, &p->laddr.stop.ip4,
521 p->lport.start, p->lport.stop);
Paul Vinciguerrabdc0e6b2018-09-22 05:32:50 -0700522 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700523 format_ip4_address, &p->raddr.start.ip4,
524 format_ip4_address, &p->raddr.stop.ip4,
525 p->rport.start, p->rport.stop);
526 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
527 p->counter.bytes);
528 };
529 vec_foreach(i, spd->ipv6_outbound_policies)
530 {
531 p = pool_elt_at_index(spd->policies, *i);
Klement Sekeraea841302018-05-11 12:59:05 +0200532 vec_reset_length(protocol);
533 vec_reset_length(policy);
534 if (p->protocol) {
535 protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
536 } else {
537 protocol = format(protocol, "any");
538 }
539 if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
540 policy = format(policy, " sa %u", p->sa_id);
541 }
542 vlib_cli_output(vm, " priority %d action %U protocol %v%v",
543 p->priority, format_ipsec_policy_action, p->policy,
544 protocol, policy);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700545 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
546 format_ip6_address, &p->laddr.start.ip6,
547 format_ip6_address, &p->laddr.stop.ip6,
548 p->lport.start, p->lport.stop);
549 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
550 format_ip6_address, &p->raddr.start.ip6,
551 format_ip6_address, &p->raddr.stop.ip6,
552 p->rport.start, p->rport.stop);
553 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
554 p->counter.bytes);
555 };
556 vlib_cli_output(vm, " inbound policies");
557 vec_foreach(i, spd->ipv4_inbound_protect_policy_indices)
558 {
559 p = pool_elt_at_index(spd->policies, *i);
Klement Sekeraea841302018-05-11 12:59:05 +0200560 vec_reset_length(protocol);
561 vec_reset_length(policy);
562 if (p->protocol) {
563 protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
564 } else {
565 protocol = format(protocol, "any");
566 }
567 if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
568 policy = format(policy, " sa %u", p->sa_id);
569 }
570 vlib_cli_output(vm, " priority %d action %U protocol %v%v",
571 p->priority, format_ipsec_policy_action, p->policy,
572 protocol, policy);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700573 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
574 format_ip4_address, &p->laddr.start.ip4,
575 format_ip4_address, &p->laddr.stop.ip4,
576 p->lport.start, p->lport.stop);
Paul Vinciguerrabdc0e6b2018-09-22 05:32:50 -0700577 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700578 format_ip4_address, &p->raddr.start.ip4,
579 format_ip4_address, &p->raddr.stop.ip4,
580 p->rport.start, p->rport.stop);
581 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
582 p->counter.bytes);
583 };
584 vec_foreach(i, spd->ipv4_inbound_policy_discard_and_bypass_indices)
585 {
586 p = pool_elt_at_index(spd->policies, *i);
Klement Sekeraea841302018-05-11 12:59:05 +0200587 vec_reset_length(protocol);
588 vec_reset_length(policy);
589 if (p->protocol) {
590 protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
591 } else {
592 protocol = format(protocol, "any");
593 }
594 if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
595 policy = format(policy, " sa %u", p->sa_id);
596 }
597 vlib_cli_output(vm, " priority %d action %U protocol %v%v",
598 p->priority, format_ipsec_policy_action, p->policy,
599 protocol, policy);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700600 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
601 format_ip4_address, &p->laddr.start.ip4,
602 format_ip4_address, &p->laddr.stop.ip4,
603 p->lport.start, p->lport.stop);
Paul Vinciguerrabdc0e6b2018-09-22 05:32:50 -0700604 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700605 format_ip4_address, &p->raddr.start.ip4,
606 format_ip4_address, &p->raddr.stop.ip4,
607 p->rport.start, p->rport.stop);
608 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
609 p->counter.bytes);
610 };
611 vec_foreach(i, spd->ipv6_inbound_protect_policy_indices)
612 {
613 p = pool_elt_at_index(spd->policies, *i);
Klement Sekeraea841302018-05-11 12:59:05 +0200614 vec_reset_length(protocol);
615 vec_reset_length(policy);
616 if (p->protocol) {
617 protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
618 } else {
619 protocol = format(protocol, "any");
620 }
621 if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
622 policy = format(policy, " sa %u", p->sa_id);
623 }
624 vlib_cli_output(vm, " priority %d action %U protocol %v%v",
625 p->priority, format_ipsec_policy_action, p->policy,
626 protocol, policy);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700627 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
628 format_ip6_address, &p->laddr.start.ip6,
629 format_ip6_address, &p->laddr.stop.ip6,
630 p->lport.start, p->lport.stop);
631 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
632 format_ip6_address, &p->raddr.start.ip6,
633 format_ip6_address, &p->raddr.stop.ip6,
634 p->rport.start, p->rport.stop);
635 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
636 p->counter.bytes);
637 };
638 vec_foreach(i, spd->ipv6_inbound_policy_discard_and_bypass_indices)
639 {
640 p = pool_elt_at_index(spd->policies, *i);
Klement Sekeraea841302018-05-11 12:59:05 +0200641 vec_reset_length(protocol);
642 vec_reset_length(policy);
643 if (p->protocol) {
644 protocol = format(protocol, "%U", format_ip_protocol, p->protocol);
645 } else {
646 protocol = format(protocol, "any");
647 }
648 if (p->policy == IPSEC_POLICY_ACTION_PROTECT) {
649 policy = format(policy, " sa %u", p->sa_id);
650 }
651 vlib_cli_output(vm, " priority %d action %U protocol %v%v",
652 p->priority, format_ipsec_policy_action, p->policy,
653 protocol, policy);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700654 vlib_cli_output(vm, " local addr range %U - %U port range %u - %u",
655 format_ip6_address, &p->laddr.start.ip6,
656 format_ip6_address, &p->laddr.stop.ip6,
657 p->lport.start, p->lport.stop);
658 vlib_cli_output(vm, " remote addr range %U - %U port range %u - %u",
659 format_ip6_address, &p->raddr.start.ip6,
660 format_ip6_address, &p->raddr.stop.ip6,
661 p->rport.start, p->rport.stop);
662 vlib_cli_output(vm, " packets %u bytes %u", p->counter.packets,
663 p->counter.bytes);
664 };
665 }));
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700666 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700667
Neale Ranns311124e2019-01-24 04:52:25 -0800668 vlib_cli_output (vm, "SPD Bindings:");
669 /* *INDENT-OFF* */
670 hash_foreach(sw_if_index, spd_id, im->spd_index_by_sw_if_index, ({
671 vlib_cli_output (vm, " %d -> %U", spd_id,
672 format_vnet_sw_if_index_name, im->vnet_main,
673 sw_if_index);
674 }));
675 /* *INDENT-ON* */
676
677
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700678 vlib_cli_output (vm, "tunnel interfaces");
679 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700680 pool_foreach (t, im->tunnel_interfaces, ({
Matus Fabian694265d2016-08-10 01:55:36 -0700681 if (t->hw_if_index == ~0)
682 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700683 hi = vnet_get_hw_interface (im->vnet_main, t->hw_if_index);
684 vlib_cli_output(vm, " %s seq", hi->name);
685 sa = pool_elt_at_index(im->sad, t->output_sa_index);
Pierre Pfister4c422f92018-12-10 11:19:08 +0100686
687 tx_table_id = fib_table_get_table_id(sa->tx_fib_index, FIB_PROTOCOL_IP4);
688
689 vlib_cli_output(vm, " seq %u seq-hi %u esn %u anti-replay %u udp-encap %u tx-table %u",
690 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 -0700691 vlib_cli_output(vm, " local-spi %u local-ip %U", sa->spi,
692 format_ip4_address, &sa->tunnel_src_addr.ip4);
693 vlib_cli_output(vm, " local-crypto %U %U",
694 format_ipsec_crypto_alg, sa->crypto_alg,
695 format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
696 vlib_cli_output(vm, " local-integrity %U %U",
697 format_ipsec_integ_alg, sa->integ_alg,
698 format_hex_bytes, sa->integ_key, sa->integ_key_len);
699 sa = pool_elt_at_index(im->sad, t->input_sa_index);
700 vlib_cli_output(vm, " last-seq %u last-seq-hi %u esn %u anti-replay %u window %U",
701 sa->last_seq, sa->last_seq_hi, sa->use_esn,
702 sa->use_anti_replay,
703 format_ipsec_replay_window, sa->replay_window);
704 vlib_cli_output(vm, " remote-spi %u remote-ip %U", sa->spi,
705 format_ip4_address, &sa->tunnel_src_addr.ip4);
706 vlib_cli_output(vm, " remote-crypto %U %U",
707 format_ipsec_crypto_alg, sa->crypto_alg,
708 format_hex_bytes, sa->crypto_key, sa->crypto_key_len);
709 vlib_cli_output(vm, " remote-integrity %U %U",
710 format_ipsec_integ_alg, sa->integ_alg,
711 format_hex_bytes, sa->integ_key, sa->integ_key_len);
712 }));
Klement Sekeraea841302018-05-11 12:59:05 +0200713 vec_free(policy);
714 vec_free(protocol);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700715 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700716 return 0;
717}
718
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700719/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700720VLIB_CLI_COMMAND (show_ipsec_command, static) = {
721 .path = "show ipsec",
Klement Sekerab4d30532018-11-08 13:00:02 +0100722 .short_help = "show ipsec [backends]",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700723 .function = show_ipsec_command_fn,
724};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700725/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700726
727static clib_error_t *
Klement Sekerab4d30532018-11-08 13:00:02 +0100728ipsec_show_backends_command_fn (vlib_main_t * vm,
729 unformat_input_t * input,
730 vlib_cli_command_t * cmd)
731{
732 ipsec_main_t *im = &ipsec_main;
733 u32 verbose = 0;
734
735 (void) unformat (input, "verbose %u", &verbose);
736
737 vlib_cli_output (vm, "IPsec AH backends available:");
738 u8 *s = format (NULL, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
739 ipsec_ah_backend_t *ab;
740 /* *INDENT-OFF* */
741 pool_foreach (ab, im->ah_backends, {
742 s = format (s, "%=25s %=25u %=10s\n", ab->name, ab - im->ah_backends,
743 ab - im->ah_backends == im->ah_current_backend ? "yes" : "no");
744 if (verbose) {
745 vlib_node_t *n;
746 n = vlib_get_node (vm, ab->ah4_encrypt_node_index);
747 s = format (s, " enc4 %s (next %d)\n", n->name, ab->ah4_encrypt_next_index);
748 n = vlib_get_node (vm, ab->ah4_decrypt_node_index);
749 s = format (s, " dec4 %s (next %d)\n", n->name, ab->ah4_decrypt_next_index);
750 n = vlib_get_node (vm, ab->ah6_encrypt_node_index);
751 s = format (s, " enc6 %s (next %d)\n", n->name, ab->ah6_encrypt_next_index);
752 n = vlib_get_node (vm, ab->ah6_decrypt_node_index);
753 s = format (s, " dec6 %s (next %d)\n", n->name, ab->ah6_decrypt_next_index);
754 }
755 });
756 /* *INDENT-ON* */
757 vlib_cli_output (vm, "%v", s);
758 _vec_len (s) = 0;
759 vlib_cli_output (vm, "IPsec ESP backends available:");
760 s = format (s, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
761 ipsec_esp_backend_t *eb;
762 /* *INDENT-OFF* */
763 pool_foreach (eb, im->esp_backends, {
764 s = format (s, "%=25s %=25u %=10s\n", eb->name, eb - im->esp_backends,
765 eb - im->esp_backends == im->esp_current_backend ? "yes"
766 : "no");
767 if (verbose) {
768 vlib_node_t *n;
769 n = vlib_get_node (vm, eb->esp4_encrypt_node_index);
770 s = format (s, " enc4 %s (next %d)\n", n->name, eb->esp4_encrypt_next_index);
771 n = vlib_get_node (vm, eb->esp4_decrypt_node_index);
772 s = format (s, " dec4 %s (next %d)\n", n->name, eb->esp4_decrypt_next_index);
773 n = vlib_get_node (vm, eb->esp6_encrypt_node_index);
774 s = format (s, " enc6 %s (next %d)\n", n->name, eb->esp6_encrypt_next_index);
775 n = vlib_get_node (vm, eb->esp6_decrypt_node_index);
776 s = format (s, " dec6 %s (next %d)\n", n->name, eb->esp6_decrypt_next_index);
777 }
778 });
779 /* *INDENT-ON* */
780 vlib_cli_output (vm, "%v", s);
781
782 vec_free (s);
783 return 0;
784}
785
786/* *INDENT-OFF* */
787VLIB_CLI_COMMAND (ipsec_show_backends_command, static) = {
788 .path = "show ipsec backends",
789 .short_help = "show ipsec backends",
790 .function = ipsec_show_backends_command_fn,
791};
792/* *INDENT-ON* */
793
794static clib_error_t *
795ipsec_select_backend_command_fn (vlib_main_t * vm,
796 unformat_input_t * input,
797 vlib_cli_command_t * cmd)
798{
799 u32 backend_index;
800 ipsec_main_t *im = &ipsec_main;
801
802 if (pool_elts (im->sad) > 0)
803 {
804 return clib_error_return (0,
805 "Cannot change IPsec backend, while %u SA entries are configured",
806 pool_elts (im->sad));
807 }
808
809 unformat_input_t _line_input, *line_input = &_line_input;
810 /* Get a line of input. */
811 if (!unformat_user (input, unformat_line_input, line_input))
812 return 0;
813
814 if (unformat (line_input, "ah"))
815 {
816 if (unformat (line_input, "%u", &backend_index))
817 {
818 if (ipsec_select_ah_backend (im, backend_index) < 0)
819 {
820 return clib_error_return (0, "Invalid AH 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 if (unformat (line_input, "esp"))
831 {
832 if (unformat (line_input, "%u", &backend_index))
833 {
834 if (ipsec_select_esp_backend (im, backend_index) < 0)
835 {
836 return clib_error_return (0, "Invalid ESP backend index `%u'",
837 backend_index);
838 }
839 }
840 else
841 {
842 return clib_error_return (0, "Invalid backend index `%U'",
843 format_unformat_error, line_input);
844 }
845 }
846 else
847 {
848 return clib_error_return (0, "Unknown input `%U'",
849 format_unformat_error, line_input);
850 }
851
852 return 0;
853}
854
855/* *INDENT-OFF* */
856VLIB_CLI_COMMAND (ipsec_select_backend_command, static) = {
857 .path = "ipsec select backend",
858 .short_help = "ipsec select backend <ah|esp> <backend index>",
859 .function = ipsec_select_backend_command_fn,
860};
861
862/* *INDENT-ON* */
863
864static clib_error_t *
Ed Warnickecb9cada2015-12-08 15:45:58 -0700865clear_ipsec_counters_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700866 unformat_input_t * input,
867 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700868{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700869 ipsec_main_t *im = &ipsec_main;
870 ipsec_spd_t *spd;
871 ipsec_policy_t *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700872
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700873 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700874 pool_foreach (spd, im->spds, ({
875 pool_foreach(p, spd->policies, ({
876 p->counter.packets = p->counter.bytes = 0;
877 }));
878 }));
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700879 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700880
881 return 0;
882}
883
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700884/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700885VLIB_CLI_COMMAND (clear_ipsec_counters_command, static) = {
886 .path = "clear ipsec counters",
887 .short_help = "clear ipsec counters",
888 .function = clear_ipsec_counters_command_fn,
889};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700890/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700891
892static clib_error_t *
893create_ipsec_tunnel_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700894 unformat_input_t * input,
895 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700896{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700897 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700898 ipsec_add_del_tunnel_args_t a;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700899 int rv;
900 u32 num_m_args = 0;
Billy McFalla9a20e72017-02-15 11:39:12 -0500901 clib_error_t *error = NULL;
Matthew Smith2838a232016-06-21 16:05:09 -0500902
Dave Barachb7b92992018-10-17 10:38:51 -0400903 clib_memset (&a, 0, sizeof (a));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700904 a.is_add = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700905
906 /* Get a line of input. */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700907 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700908 return 0;
909
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700910 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
911 {
912 if (unformat
913 (line_input, "local-ip %U", unformat_ip4_address, &a.local_ip))
914 num_m_args++;
915 else
916 if (unformat
917 (line_input, "remote-ip %U", unformat_ip4_address, &a.remote_ip))
918 num_m_args++;
919 else if (unformat (line_input, "local-spi %u", &a.local_spi))
920 num_m_args++;
921 else if (unformat (line_input, "remote-spi %u", &a.remote_spi))
922 num_m_args++;
Matthew Smith8e1039a2018-04-12 07:32:56 -0500923 else if (unformat (line_input, "instance %u", &a.show_instance))
924 a.renumber = 1;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700925 else if (unformat (line_input, "del"))
926 a.is_add = 0;
Radu Nicolau717de092018-08-03 10:37:24 +0100927 else if (unformat (line_input, "udp-encap"))
928 a.udp_encap = 1;
Pierre Pfister4c422f92018-12-10 11:19:08 +0100929 else if (unformat (line_input, "tx-table %u", &a.tx_table_id))
930 ;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700931 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500932 {
933 error = clib_error_return (0, "unknown input `%U'",
934 format_unformat_error, line_input);
935 goto done;
936 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700937 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700938
939 if (num_m_args < 4)
Billy McFalla9a20e72017-02-15 11:39:12 -0500940 {
941 error = clib_error_return (0, "mandatory argument(s) missing");
942 goto done;
943 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700944
Matthew Smith2838a232016-06-21 16:05:09 -0500945 rv = ipsec_add_del_tunnel_if (&a);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700946
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700947 switch (rv)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700948 {
949 case 0:
950 break;
951 case VNET_API_ERROR_INVALID_VALUE:
952 if (a.is_add)
Billy McFalla9a20e72017-02-15 11:39:12 -0500953 error = clib_error_return (0,
954 "IPSec tunnel interface already exists...");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700955 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500956 error = clib_error_return (0, "IPSec tunnel interface not exists...");
957 goto done;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700958 default:
Billy McFalla9a20e72017-02-15 11:39:12 -0500959 error = clib_error_return (0, "ipsec_register_interface returned %d",
960 rv);
961 goto done;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700962 }
963
Billy McFalla9a20e72017-02-15 11:39:12 -0500964done:
965 unformat_free (line_input);
966
967 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700968}
969
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700970/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700971VLIB_CLI_COMMAND (create_ipsec_tunnel_command, static) = {
972 .path = "create ipsec tunnel",
Pierre Pfister4c422f92018-12-10 11:19:08 +0100973 .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> "
974 "remote-ip <addr> remote-spi <spi> [instance <inst_num>] [udp-encap] "
975 "[tx-table <table-id>]",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700976 .function = create_ipsec_tunnel_command_fn,
977};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700978/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700979
980static clib_error_t *
981set_interface_key_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700982 unformat_input_t * input,
983 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700984{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700985 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700986 ipsec_main_t *im = &ipsec_main;
987 ipsec_if_set_key_type_t type = IPSEC_IF_SET_KEY_TYPE_NONE;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700988 u32 hw_if_index = (u32) ~ 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700989 u32 alg;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700990 u8 *key = 0;
Billy McFalla9a20e72017-02-15 11:39:12 -0500991 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700992
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700993 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700994 return 0;
995
996 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
997 {
998 if (unformat (line_input, "%U",
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700999 unformat_vnet_hw_interface, im->vnet_main, &hw_if_index))
1000 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001001 else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001002 if (unformat
1003 (line_input, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
1004 type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
1005 else
1006 if (unformat
1007 (line_input, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
1008 type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
1009 else
1010 if (unformat
1011 (line_input, "local integ %U", unformat_ipsec_integ_alg, &alg))
1012 type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
1013 else
1014 if (unformat
1015 (line_input, "remote integ %U", unformat_ipsec_integ_alg, &alg))
1016 type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
1017 else if (unformat (line_input, "%U", unformat_hex_string, &key))
1018 ;
1019 else
Billy McFalla9a20e72017-02-15 11:39:12 -05001020 {
1021 error = clib_error_return (0, "parse error: '%U'",
1022 format_unformat_error, line_input);
1023 goto done;
1024 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07001025 }
1026
Ed Warnickecb9cada2015-12-08 15:45:58 -07001027 if (type == IPSEC_IF_SET_KEY_TYPE_NONE)
Billy McFalla9a20e72017-02-15 11:39:12 -05001028 {
1029 error = clib_error_return (0, "unknown key type");
1030 goto done;
1031 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07001032
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001033 if (alg > 0 && vec_len (key) == 0)
Billy McFalla9a20e72017-02-15 11:39:12 -05001034 {
1035 error = clib_error_return (0, "key is not specified");
1036 goto done;
1037 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07001038
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001039 if (hw_if_index == (u32) ~ 0)
Billy McFalla9a20e72017-02-15 11:39:12 -05001040 {
1041 error = clib_error_return (0, "interface not specified");
1042 goto done;
1043 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07001044
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001045 ipsec_set_interface_key (im->vnet_main, hw_if_index, type, alg, key);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001046
Billy McFalla9a20e72017-02-15 11:39:12 -05001047done:
1048 vec_free (key);
1049 unformat_free (line_input);
1050
1051 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001052}
1053
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001054/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -07001055VLIB_CLI_COMMAND (set_interface_key_command, static) = {
1056 .path = "set interface ipsec key",
1057 .short_help =
1058 "set interface ipsec key <int> <local|remote> <crypto|integ> <key type> <key>",
1059 .function = set_interface_key_command_fn,
1060};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001061/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -07001062
Ed Warnickecb9cada2015-12-08 15:45:58 -07001063clib_error_t *
1064ipsec_cli_init (vlib_main_t * vm)
1065{
1066 return 0;
1067}
1068
1069VLIB_INIT_FUNCTION (ipsec_cli_init);
1070
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001071
1072/*
1073 * fd.io coding-style-patch-verification: ON
1074 *
1075 * Local Variables:
1076 * eval: (c-set-style "gnu")
1077 * End:
1078 */