blob: 01d4b759d27151ad51e91c80d40e008ce3cd4c6d [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>
Neale Ranns12989b52019-09-26 16:20:19 +000023#include <vnet/ipip/ipip.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070024
25#include <vnet/ipsec/ipsec.h>
Neale Rannsc87b66c2019-02-07 07:26:12 -080026#include <vnet/ipsec/ipsec_tun.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070027
28static clib_error_t *
29set_interface_spd_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070030 unformat_input_t * input,
31 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -070032{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070033 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -070034 ipsec_main_t *im = &ipsec_main;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070035 u32 sw_if_index = (u32) ~ 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -070036 u32 spd_id;
37 int is_add = 1;
Billy McFalla9a20e72017-02-15 11:39:12 -050038 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -070039
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070040 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -070041 return 0;
42
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070043 if (unformat
44 (line_input, "%U %u", unformat_vnet_sw_interface, im->vnet_main,
45 &sw_if_index, &spd_id))
Ed Warnickecb9cada2015-12-08 15:45:58 -070046 ;
47 else if (unformat (line_input, "del"))
48 is_add = 0;
49 else
Billy McFalla9a20e72017-02-15 11:39:12 -050050 {
51 error = clib_error_return (0, "parse error: '%U'",
52 format_unformat_error, line_input);
53 goto done;
54 }
Ed Warnickecb9cada2015-12-08 15:45:58 -070055
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070056 ipsec_set_interface_spd (vm, sw_if_index, spd_id, is_add);
Ed Warnickecb9cada2015-12-08 15:45:58 -070057
Billy McFalla9a20e72017-02-15 11:39:12 -050058done:
59 unformat_free (line_input);
60
61 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -070062}
63
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070064/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -070065VLIB_CLI_COMMAND (set_interface_spd_command, static) = {
66 .path = "set interface ipsec spd",
67 .short_help =
68 "set interface ipsec spd <int> <id>",
69 .function = set_interface_spd_command_fn,
70};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070071/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -070072
73static clib_error_t *
74ipsec_sa_add_del_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070075 unformat_input_t * input,
76 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -070077{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070078 unformat_input_t _line_input, *line_input = &_line_input;
Neale Ranns8d7c5022019-02-06 01:41:05 -080079 ip46_address_t tun_src = { }, tun_dst =
80 {
81 };
82 ipsec_crypto_alg_t crypto_alg;
83 ipsec_integ_alg_t integ_alg;
84 ipsec_protocol_t proto;
85 ipsec_sa_flags_t flags;
86 clib_error_t *error;
Kingwel Xied3d12052019-03-07 06:34:30 -050087 ipsec_key_t ck = { 0 };
88 ipsec_key_t ik = { 0 };
Neale Rannsabc56602020-04-01 09:45:23 +000089 u32 id, spi, salt, sai;
90 u16 udp_src, udp_dst;
Neale Ranns8d7c5022019-02-06 01:41:05 -080091 int is_add, rv;
Benoît Gannebdd8b572020-07-28 15:56:15 +020092 u32 m_args = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -070093
Neale Ranns8dc75c02019-12-10 01:08:19 +000094 salt = 0;
Neale Ranns8d7c5022019-02-06 01:41:05 -080095 error = NULL;
96 is_add = 0;
97 flags = IPSEC_SA_FLAG_NONE;
98 proto = IPSEC_PROTOCOL_ESP;
Neale Rannse6be7022019-06-04 15:37:34 +000099 integ_alg = IPSEC_INTEG_ALG_NONE;
100 crypto_alg = IPSEC_CRYPTO_ALG_NONE;
Neale Rannsabc56602020-04-01 09:45:23 +0000101 udp_src = udp_dst = IPSEC_UDP_PORT_NONE;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700102
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700103 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700104 return 0;
105
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700106 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
107 {
Neale Ranns8d7c5022019-02-06 01:41:05 -0800108 if (unformat (line_input, "add %u", &id))
Benoît Gannebdd8b572020-07-28 15:56:15 +0200109 {
110 is_add = 1;
111 m_args |= 1 << 0;
112 }
Neale Ranns8d7c5022019-02-06 01:41:05 -0800113 else if (unformat (line_input, "del %u", &id))
Benoît Gannebdd8b572020-07-28 15:56:15 +0200114 {
115 is_add = 0;
116 m_args |= 1 << 0;
117 }
Neale Ranns8d7c5022019-02-06 01:41:05 -0800118 else if (unformat (line_input, "spi %u", &spi))
Benoît Gannebdd8b572020-07-28 15:56:15 +0200119 m_args |= 1 << 1;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800120 else if (unformat (line_input, "salt 0x%x", &salt))
Neale Ranns80f6fd52019-04-16 02:41:34 +0000121 ;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700122 else if (unformat (line_input, "esp"))
Neale Ranns8d7c5022019-02-06 01:41:05 -0800123 proto = IPSEC_PROTOCOL_ESP;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700124 else if (unformat (line_input, "ah"))
Neale Ranns8d7c5022019-02-06 01:41:05 -0800125 proto = IPSEC_PROTOCOL_AH;
126 else if (unformat (line_input, "crypto-key %U",
127 unformat_ipsec_key, &ck))
128 ;
129 else if (unformat (line_input, "crypto-alg %U",
130 unformat_ipsec_crypto_alg, &crypto_alg))
131 ;
132 else if (unformat (line_input, "integ-key %U", unformat_ipsec_key, &ik))
133 ;
134 else if (unformat (line_input, "integ-alg %U",
135 unformat_ipsec_integ_alg, &integ_alg))
136 ;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700137 else if (unformat (line_input, "tunnel-src %U",
Kingwel Xie72b3bce2019-02-12 06:45:08 -0500138 unformat_ip46_address, &tun_src, IP46_TYPE_ANY))
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700139 {
Neale Ranns8d7c5022019-02-06 01:41:05 -0800140 flags |= IPSEC_SA_FLAG_IS_TUNNEL;
141 if (!ip46_address_is_ip4 (&tun_src))
142 flags |= IPSEC_SA_FLAG_IS_TUNNEL_V6;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700143 }
144 else if (unformat (line_input, "tunnel-dst %U",
Kingwel Xie72b3bce2019-02-12 06:45:08 -0500145 unformat_ip46_address, &tun_dst, IP46_TYPE_ANY))
Neale Ranns8d7c5022019-02-06 01:41:05 -0800146 ;
Radu Nicolau717de092018-08-03 10:37:24 +0100147 else if (unformat (line_input, "udp-encap"))
Neale Ranns8d7c5022019-02-06 01:41:05 -0800148 flags |= IPSEC_SA_FLAG_UDP_ENCAP;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700149 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500150 {
151 error = clib_error_return (0, "parse error: '%U'",
152 format_unformat_error, line_input);
153 goto done;
154 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700155 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700156
Benoît Gannebdd8b572020-07-28 15:56:15 +0200157 if (!(m_args & 1))
158 {
159 error = clib_error_return (0, "missing id");
160 goto done;
161 }
162
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +0000163 if (is_add)
Benoît Gannebdd8b572020-07-28 15:56:15 +0200164 {
165 if (!(m_args & 2))
166 {
167 error = clib_error_return (0, "missing spi");
168 goto done;
169 }
170 rv = ipsec_sa_add_and_lock (id, spi, proto, crypto_alg,
171 &ck, integ_alg, &ik, flags,
172 0, clib_host_to_net_u32 (salt),
173 &tun_src, &tun_dst, &sai, udp_src, udp_dst);
174 }
Neale Ranns8d7c5022019-02-06 01:41:05 -0800175 else
Benoît Gannebdd8b572020-07-28 15:56:15 +0200176 {
177 rv = ipsec_sa_unlock_id (id);
178 }
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +0000179
Neale Ranns8d7c5022019-02-06 01:41:05 -0800180 if (rv)
Neale Rannse6be7022019-06-04 15:37:34 +0000181 error = clib_error_return (0, "failed");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700182
Billy McFalla9a20e72017-02-15 11:39:12 -0500183done:
184 unformat_free (line_input);
185
186 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700187}
188
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700189/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700190VLIB_CLI_COMMAND (ipsec_sa_add_del_command, static) = {
191 .path = "ipsec sa",
192 .short_help =
193 "ipsec sa [add|del]",
194 .function = ipsec_sa_add_del_command_fn,
195};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700196/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700197
198static clib_error_t *
199ipsec_spd_add_del_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700200 unformat_input_t * input,
201 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700202{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700203 unformat_input_t _line_input, *line_input = &_line_input;
Damjan Marion3f54b182016-08-16 11:27:02 +0200204 u32 spd_id = ~0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700205 int is_add = ~0;
Billy McFalla9a20e72017-02-15 11:39:12 -0500206 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700207
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700208 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700209 return 0;
210
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700211 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
212 {
213 if (unformat (line_input, "add"))
214 is_add = 1;
215 else if (unformat (line_input, "del"))
216 is_add = 0;
217 else if (unformat (line_input, "%u", &spd_id))
218 ;
219 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500220 {
221 error = clib_error_return (0, "parse error: '%U'",
222 format_unformat_error, line_input);
223 goto done;
224 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700225 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700226
Damjan Marion3f54b182016-08-16 11:27:02 +0200227 if (spd_id == ~0)
Billy McFalla9a20e72017-02-15 11:39:12 -0500228 {
229 error = clib_error_return (0, "please specify SPD ID");
230 goto done;
231 }
Damjan Marion3f54b182016-08-16 11:27:02 +0200232
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700233 ipsec_add_del_spd (vm, spd_id, is_add);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700234
Billy McFalla9a20e72017-02-15 11:39:12 -0500235done:
236 unformat_free (line_input);
237
238 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700239}
240
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700241/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700242VLIB_CLI_COMMAND (ipsec_spd_add_del_command, static) = {
243 .path = "ipsec spd",
244 .short_help =
245 "ipsec spd [add|del] <id>",
246 .function = ipsec_spd_add_del_command_fn,
247};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700248/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700249
250
251static clib_error_t *
252ipsec_policy_add_del_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700253 unformat_input_t * input,
254 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700255{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700256 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700257 ipsec_policy_t p;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800258 int rv, is_add = 0;
Neale Rannsb1fd80f2020-05-12 13:33:56 +0000259 u32 tmp, tmp2, stat_index, local_range_set, remote_range_set;
Billy McFalla9a20e72017-02-15 11:39:12 -0500260 clib_error_t *error = NULL;
Neale Ranns9f231d42019-03-19 10:06:00 +0000261 u32 is_outbound;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700262
Dave Barachb7b92992018-10-17 10:38:51 -0400263 clib_memset (&p, 0, sizeof (p));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700264 p.lport.stop = p.rport.stop = ~0;
Neale Rannsb1fd80f2020-05-12 13:33:56 +0000265 remote_range_set = local_range_set = is_outbound = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700266
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700267 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700268 return 0;
269
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700270 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
271 {
272 if (unformat (line_input, "add"))
273 is_add = 1;
274 else if (unformat (line_input, "del"))
275 is_add = 0;
Neale Rannsb1fd80f2020-05-12 13:33:56 +0000276 else if (unformat (line_input, "ip6"))
277 p.is_ipv6 = 1;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700278 else if (unformat (line_input, "spd %u", &p.id))
279 ;
280 else if (unformat (line_input, "inbound"))
Neale Ranns9f231d42019-03-19 10:06:00 +0000281 is_outbound = 0;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700282 else if (unformat (line_input, "outbound"))
Neale Ranns9f231d42019-03-19 10:06:00 +0000283 is_outbound = 1;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700284 else if (unformat (line_input, "priority %d", &p.priority))
285 ;
286 else if (unformat (line_input, "protocol %u", &tmp))
287 p.protocol = (u8) tmp;
288 else
289 if (unformat
290 (line_input, "action %U", unformat_ipsec_policy_action,
291 &p.policy))
292 {
293 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
Billy McFalla9a20e72017-02-15 11:39:12 -0500294 {
295 error = clib_error_return (0, "unsupported action: 'resolve'");
296 goto done;
297 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700298 }
299 else if (unformat (line_input, "sa %u", &p.sa_id))
300 ;
301 else if (unformat (line_input, "local-ip-range %U - %U",
302 unformat_ip4_address, &p.laddr.start.ip4,
303 unformat_ip4_address, &p.laddr.stop.ip4))
Neale Rannsb1fd80f2020-05-12 13:33:56 +0000304 local_range_set = 1;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700305 else if (unformat (line_input, "remote-ip-range %U - %U",
306 unformat_ip4_address, &p.raddr.start.ip4,
307 unformat_ip4_address, &p.raddr.stop.ip4))
Neale Rannsb1fd80f2020-05-12 13:33:56 +0000308 remote_range_set = 1;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700309 else if (unformat (line_input, "local-ip-range %U - %U",
310 unformat_ip6_address, &p.laddr.start.ip6,
311 unformat_ip6_address, &p.laddr.stop.ip6))
312 {
313 p.is_ipv6 = 1;
Neale Rannsb1fd80f2020-05-12 13:33:56 +0000314 local_range_set = 1;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700315 }
316 else if (unformat (line_input, "remote-ip-range %U - %U",
317 unformat_ip6_address, &p.raddr.start.ip6,
318 unformat_ip6_address, &p.raddr.stop.ip6))
319 {
320 p.is_ipv6 = 1;
Neale Rannsb1fd80f2020-05-12 13:33:56 +0000321 remote_range_set = 1;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700322 }
323 else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2))
324 {
325 p.lport.start = tmp;
326 p.lport.stop = tmp2;
327 }
328 else
329 if (unformat (line_input, "remote-port-range %u - %u", &tmp, &tmp2))
330 {
331 p.rport.start = tmp;
332 p.rport.stop = tmp2;
333 }
334 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500335 {
336 error = clib_error_return (0, "parse error: '%U'",
337 format_unformat_error, line_input);
338 goto done;
339 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700340 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700341
Neale Rannsb1fd80f2020-05-12 13:33:56 +0000342 if (!remote_range_set)
343 {
344 if (p.is_ipv6)
345 clib_memset (&p.raddr.stop.ip6, 0xff, 16);
346 else
347 clib_memset (&p.raddr.stop.ip4, 0xff, 4);
348 }
349 if (!local_range_set)
350 {
351 if (p.is_ipv6)
352 clib_memset (&p.laddr.stop.ip6, 0xff, 16);
353 else
354 clib_memset (&p.laddr.stop.ip4, 0xff, 4);
355 }
356
Neale Ranns9f231d42019-03-19 10:06:00 +0000357 rv = ipsec_policy_mk_type (is_outbound, p.is_ipv6, p.policy, &p.type);
358
359 if (rv)
360 {
361 error = clib_error_return (0, "unsupported policy type for:",
362 " outboud:%s %s action:%U",
363 (is_outbound ? "yes" : "no"),
364 (p.is_ipv6 ? "IPv4" : "IPv6"),
365 format_ipsec_policy_action, p.policy);
366 goto done;
367 }
368
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800369 rv = ipsec_add_del_policy (vm, &p, is_add, &stat_index);
370
371 if (!rv)
372 vlib_cli_output (vm, "policy-index:%d", stat_index);
373 else
374 vlib_cli_output (vm, "error:%d", rv);
Billy McFalla9a20e72017-02-15 11:39:12 -0500375
376done:
377 unformat_free (line_input);
378
379 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700380}
381
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700382/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700383VLIB_CLI_COMMAND (ipsec_policy_add_del_command, static) = {
384 .path = "ipsec policy",
385 .short_help =
386 "ipsec policy [add|del] spd <id> priority <n> ",
387 .function = ipsec_policy_add_del_command_fn,
388};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700389/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700390
Neale Rannsb294f102019-04-03 13:17:50 +0000391static void
Neale Ranns670027a2019-08-27 12:47:17 +0000392ipsec_sa_show_all (vlib_main_t * vm, ipsec_main_t * im, u8 detail)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700393{
Neale Rannsb294f102019-04-03 13:17:50 +0000394 u32 sai;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700395
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700396 /* *INDENT-OFF* */
Neale Ranns8d7c5022019-02-06 01:41:05 -0800397 pool_foreach_index (sai, im->sad, ({
Neale Ranns670027a2019-08-27 12:47:17 +0000398 vlib_cli_output(vm, "%U", format_ipsec_sa, sai,
399 (detail ? IPSEC_FORMAT_DETAIL : IPSEC_FORMAT_BRIEF));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700400 }));
Neale Rannsb294f102019-04-03 13:17:50 +0000401 /* *INDENT-ON* */
402}
403
404static void
405ipsec_spd_show_all (vlib_main_t * vm, ipsec_main_t * im)
406{
407 u32 spdi;
408
409 /* *INDENT-OFF* */
410 pool_foreach_index (spdi, im->spds, ({
411 vlib_cli_output(vm, "%U", format_ipsec_spd, spdi);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700412 }));
Neale Rannsb294f102019-04-03 13:17:50 +0000413 /* *INDENT-ON* */
414}
415
416static void
417ipsec_spd_bindings_show_all (vlib_main_t * vm, ipsec_main_t * im)
418{
419 u32 spd_id, sw_if_index;
Neale Rannsd83c4a82019-06-14 06:48:27 -0700420 ipsec_spd_t *spd;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700421
Neale Ranns311124e2019-01-24 04:52:25 -0800422 vlib_cli_output (vm, "SPD Bindings:");
Neale Ranns8d7c5022019-02-06 01:41:05 -0800423
Neale Rannsb294f102019-04-03 13:17:50 +0000424 /* *INDENT-OFF* */
Neale Ranns311124e2019-01-24 04:52:25 -0800425 hash_foreach(sw_if_index, spd_id, im->spd_index_by_sw_if_index, ({
Neale Rannsd83c4a82019-06-14 06:48:27 -0700426 spd = pool_elt_at_index (im->spds, spd_id);
427 vlib_cli_output (vm, " %d -> %U", spd->id,
Neale Ranns8d7c5022019-02-06 01:41:05 -0800428 format_vnet_sw_if_index_name, im->vnet_main,
429 sw_if_index);
Neale Ranns311124e2019-01-24 04:52:25 -0800430 }));
431 /* *INDENT-ON* */
Neale Rannsb294f102019-04-03 13:17:50 +0000432}
Neale Ranns311124e2019-01-24 04:52:25 -0800433
Neale Ranns12989b52019-09-26 16:20:19 +0000434static walk_rc_t
435ipsec_tun_protect_show_one (index_t itpi, void *ctx)
Neale Rannsb294f102019-04-03 13:17:50 +0000436{
Neale Ranns28287212019-12-16 00:53:11 +0000437 vlib_cli_output (ctx, "%U", format_ipsec_tun_protect_index, itpi);
Neale Rannsb294f102019-04-03 13:17:50 +0000438
Neale Ranns12989b52019-09-26 16:20:19 +0000439 return (WALK_CONTINUE);
440}
441
442static void
443ipsec_tunnel_show_all (vlib_main_t * vm)
444{
445 ipsec_tun_protect_walk (ipsec_tun_protect_show_one, vm);
Neale Rannsb294f102019-04-03 13:17:50 +0000446}
447
448static clib_error_t *
449show_ipsec_command_fn (vlib_main_t * vm,
450 unformat_input_t * input, vlib_cli_command_t * cmd)
451{
452 ipsec_main_t *im = &ipsec_main;
453
Neale Ranns670027a2019-08-27 12:47:17 +0000454 ipsec_sa_show_all (vm, im, 0);
Neale Rannsb294f102019-04-03 13:17:50 +0000455 ipsec_spd_show_all (vm, im);
456 ipsec_spd_bindings_show_all (vm, im);
Neale Ranns12989b52019-09-26 16:20:19 +0000457 ipsec_tun_protect_walk (ipsec_tun_protect_show_one, vm);
Neale Rannsb294f102019-04-03 13:17:50 +0000458
Fan Zhangf5395782020-04-29 14:00:03 +0100459 vlib_cli_output (vm, "IPSec async mode: %s",
460 (im->async_mode ? "on" : "off"));
461
Ed Warnickecb9cada2015-12-08 15:45:58 -0700462 return 0;
463}
464
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700465/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700466VLIB_CLI_COMMAND (show_ipsec_command, static) = {
Neale Rannsb294f102019-04-03 13:17:50 +0000467 .path = "show ipsec all",
468 .short_help = "show ipsec all",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700469 .function = show_ipsec_command_fn,
470};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700471/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700472
473static clib_error_t *
Neale Rannsb294f102019-04-03 13:17:50 +0000474show_ipsec_sa_command_fn (vlib_main_t * vm,
475 unformat_input_t * input, vlib_cli_command_t * cmd)
476{
477 ipsec_main_t *im = &ipsec_main;
478 u32 sai = ~0;
Neale Ranns670027a2019-08-27 12:47:17 +0000479 u8 detail = 0;
Neale Rannsb294f102019-04-03 13:17:50 +0000480
481 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
482 {
483 if (unformat (input, "%u", &sai))
484 ;
Neale Ranns670027a2019-08-27 12:47:17 +0000485 if (unformat (input, "detail"))
486 detail = 1;
Neale Rannsb294f102019-04-03 13:17:50 +0000487 else
488 break;
489 }
490
491 if (~0 == sai)
Neale Ranns670027a2019-08-27 12:47:17 +0000492 ipsec_sa_show_all (vm, im, detail);
Neale Rannsb294f102019-04-03 13:17:50 +0000493 else
Christian E. Hopps01d61e72019-09-27 14:43:22 -0400494 vlib_cli_output (vm, "%U", format_ipsec_sa, sai,
495 IPSEC_FORMAT_DETAIL | IPSEC_FORMAT_INSECURE);
Neale Rannsb294f102019-04-03 13:17:50 +0000496
497 return 0;
498}
499
Neale Rannsc87b66c2019-02-07 07:26:12 -0800500static clib_error_t *
501clear_ipsec_sa_command_fn (vlib_main_t * vm,
502 unformat_input_t * input, vlib_cli_command_t * cmd)
503{
504 ipsec_main_t *im = &ipsec_main;
505 u32 sai = ~0;
506
507 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
508 {
509 if (unformat (input, "%u", &sai))
510 ;
511 else
512 break;
513 }
514
515 if (~0 == sai)
516 {
517 /* *INDENT-OFF* */
518 pool_foreach_index (sai, im->sad, ({
519 ipsec_sa_clear(sai);
520 }));
521 /* *INDENT-ON* */
522 }
523 else
524 {
525 if (pool_is_free_index (im->sad, sai))
526 return clib_error_return (0, "unknown SA index: %d", sai);
527 else
528 ipsec_sa_clear (sai);
529 }
530
531 return 0;
532}
533
Neale Rannsb294f102019-04-03 13:17:50 +0000534/* *INDENT-OFF* */
535VLIB_CLI_COMMAND (show_ipsec_sa_command, static) = {
536 .path = "show ipsec sa",
537 .short_help = "show ipsec sa [index]",
538 .function = show_ipsec_sa_command_fn,
539};
Neale Rannsc87b66c2019-02-07 07:26:12 -0800540
541VLIB_CLI_COMMAND (clear_ipsec_sa_command, static) = {
542 .path = "clear ipsec sa",
543 .short_help = "clear ipsec sa [index]",
544 .function = clear_ipsec_sa_command_fn,
545};
Neale Rannsb294f102019-04-03 13:17:50 +0000546/* *INDENT-ON* */
547
548static clib_error_t *
549show_ipsec_spd_command_fn (vlib_main_t * vm,
550 unformat_input_t * input, vlib_cli_command_t * cmd)
551{
552 ipsec_main_t *im = &ipsec_main;
553 u8 show_bindings = 0;
554 u32 spdi = ~0;
555
556 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
557 {
558 if (unformat (input, "%u", &spdi))
559 ;
560 else if (unformat (input, "bindings"))
561 show_bindings = 1;
562 else
563 break;
564 }
565
566 if (show_bindings)
567 ipsec_spd_bindings_show_all (vm, im);
568 else if (~0 != spdi)
569 vlib_cli_output (vm, "%U", format_ipsec_spd, spdi);
570 else
571 ipsec_spd_show_all (vm, im);
572
573 return 0;
574}
575
576/* *INDENT-OFF* */
577VLIB_CLI_COMMAND (show_ipsec_spd_command, static) = {
578 .path = "show ipsec spd",
579 .short_help = "show ipsec spd [index]",
580 .function = show_ipsec_spd_command_fn,
581};
582/* *INDENT-ON* */
583
584static clib_error_t *
585show_ipsec_tunnel_command_fn (vlib_main_t * vm,
586 unformat_input_t * input,
587 vlib_cli_command_t * cmd)
588{
Neale Ranns12989b52019-09-26 16:20:19 +0000589 ipsec_tunnel_show_all (vm);
Neale Rannsb294f102019-04-03 13:17:50 +0000590
591 return 0;
592}
593
594/* *INDENT-OFF* */
595VLIB_CLI_COMMAND (show_ipsec_tunnel_command, static) = {
596 .path = "show ipsec tunnel",
Neale Ranns12989b52019-09-26 16:20:19 +0000597 .short_help = "show ipsec tunnel",
Neale Rannsb294f102019-04-03 13:17:50 +0000598 .function = show_ipsec_tunnel_command_fn,
599};
600/* *INDENT-ON* */
601
602static clib_error_t *
Klement Sekerab4d30532018-11-08 13:00:02 +0100603ipsec_show_backends_command_fn (vlib_main_t * vm,
604 unformat_input_t * input,
605 vlib_cli_command_t * cmd)
606{
607 ipsec_main_t *im = &ipsec_main;
608 u32 verbose = 0;
609
610 (void) unformat (input, "verbose %u", &verbose);
611
612 vlib_cli_output (vm, "IPsec AH backends available:");
613 u8 *s = format (NULL, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
614 ipsec_ah_backend_t *ab;
615 /* *INDENT-OFF* */
616 pool_foreach (ab, im->ah_backends, {
617 s = format (s, "%=25s %=25u %=10s\n", ab->name, ab - im->ah_backends,
618 ab - im->ah_backends == im->ah_current_backend ? "yes" : "no");
619 if (verbose) {
620 vlib_node_t *n;
621 n = vlib_get_node (vm, ab->ah4_encrypt_node_index);
622 s = format (s, " enc4 %s (next %d)\n", n->name, ab->ah4_encrypt_next_index);
623 n = vlib_get_node (vm, ab->ah4_decrypt_node_index);
624 s = format (s, " dec4 %s (next %d)\n", n->name, ab->ah4_decrypt_next_index);
625 n = vlib_get_node (vm, ab->ah6_encrypt_node_index);
626 s = format (s, " enc6 %s (next %d)\n", n->name, ab->ah6_encrypt_next_index);
627 n = vlib_get_node (vm, ab->ah6_decrypt_node_index);
628 s = format (s, " dec6 %s (next %d)\n", n->name, ab->ah6_decrypt_next_index);
629 }
630 });
631 /* *INDENT-ON* */
632 vlib_cli_output (vm, "%v", s);
633 _vec_len (s) = 0;
634 vlib_cli_output (vm, "IPsec ESP backends available:");
635 s = format (s, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
636 ipsec_esp_backend_t *eb;
637 /* *INDENT-OFF* */
638 pool_foreach (eb, im->esp_backends, {
639 s = format (s, "%=25s %=25u %=10s\n", eb->name, eb - im->esp_backends,
640 eb - im->esp_backends == im->esp_current_backend ? "yes"
641 : "no");
642 if (verbose) {
643 vlib_node_t *n;
644 n = vlib_get_node (vm, eb->esp4_encrypt_node_index);
645 s = format (s, " enc4 %s (next %d)\n", n->name, eb->esp4_encrypt_next_index);
646 n = vlib_get_node (vm, eb->esp4_decrypt_node_index);
647 s = format (s, " dec4 %s (next %d)\n", n->name, eb->esp4_decrypt_next_index);
648 n = vlib_get_node (vm, eb->esp6_encrypt_node_index);
649 s = format (s, " enc6 %s (next %d)\n", n->name, eb->esp6_encrypt_next_index);
650 n = vlib_get_node (vm, eb->esp6_decrypt_node_index);
651 s = format (s, " dec6 %s (next %d)\n", n->name, eb->esp6_decrypt_next_index);
652 }
653 });
654 /* *INDENT-ON* */
655 vlib_cli_output (vm, "%v", s);
656
657 vec_free (s);
658 return 0;
659}
660
661/* *INDENT-OFF* */
662VLIB_CLI_COMMAND (ipsec_show_backends_command, static) = {
663 .path = "show ipsec backends",
664 .short_help = "show ipsec backends",
665 .function = ipsec_show_backends_command_fn,
666};
667/* *INDENT-ON* */
668
669static clib_error_t *
670ipsec_select_backend_command_fn (vlib_main_t * vm,
671 unformat_input_t * input,
672 vlib_cli_command_t * cmd)
673{
Klement Sekerab4d30532018-11-08 13:00:02 +0100674 unformat_input_t _line_input, *line_input = &_line_input;
Neale Rannse8915fc2019-04-23 20:57:55 -0400675 ipsec_main_t *im = &ipsec_main;
676 clib_error_t *error;
677 u32 backend_index;
678
679 error = ipsec_rsc_in_use (im);
680
681 if (error)
682 return error;
683
Klement Sekerab4d30532018-11-08 13:00:02 +0100684 /* Get a line of input. */
685 if (!unformat_user (input, unformat_line_input, line_input))
686 return 0;
687
688 if (unformat (line_input, "ah"))
689 {
690 if (unformat (line_input, "%u", &backend_index))
691 {
692 if (ipsec_select_ah_backend (im, backend_index) < 0)
693 {
694 return clib_error_return (0, "Invalid AH backend index `%u'",
695 backend_index);
696 }
697 }
698 else
699 {
700 return clib_error_return (0, "Invalid backend index `%U'",
701 format_unformat_error, line_input);
702 }
703 }
704 else if (unformat (line_input, "esp"))
705 {
706 if (unformat (line_input, "%u", &backend_index))
707 {
708 if (ipsec_select_esp_backend (im, backend_index) < 0)
709 {
710 return clib_error_return (0, "Invalid ESP backend index `%u'",
711 backend_index);
712 }
713 }
714 else
715 {
716 return clib_error_return (0, "Invalid backend index `%U'",
717 format_unformat_error, line_input);
718 }
719 }
720 else
721 {
722 return clib_error_return (0, "Unknown input `%U'",
723 format_unformat_error, line_input);
724 }
725
726 return 0;
727}
728
729/* *INDENT-OFF* */
730VLIB_CLI_COMMAND (ipsec_select_backend_command, static) = {
731 .path = "ipsec select backend",
732 .short_help = "ipsec select backend <ah|esp> <backend index>",
733 .function = ipsec_select_backend_command_fn,
734};
735
736/* *INDENT-ON* */
737
738static clib_error_t *
Ed Warnickecb9cada2015-12-08 15:45:58 -0700739clear_ipsec_counters_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700740 unformat_input_t * input,
741 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700742{
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800743 vlib_clear_combined_counters (&ipsec_spd_policy_counters);
Neale Rannseba31ec2019-02-17 18:04:27 +0000744 vlib_clear_combined_counters (&ipsec_sa_counters);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700745
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800746 return (NULL);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700747}
748
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700749/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700750VLIB_CLI_COMMAND (clear_ipsec_counters_command, static) = {
751 .path = "clear ipsec counters",
752 .short_help = "clear ipsec counters",
753 .function = clear_ipsec_counters_command_fn,
754};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700755/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700756
Neale Ranns12989b52019-09-26 16:20:19 +0000757static u32
758ipsec_tun_mk_local_sa_id (u32 ti)
759{
760 return (0x80000000 | ti);
761}
762
763static u32
764ipsec_tun_mk_remote_sa_id (u32 ti)
765{
766 return (0xc0000000 | ti);
767}
768
Ed Warnickecb9cada2015-12-08 15:45:58 -0700769static clib_error_t *
770create_ipsec_tunnel_command_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700771 unformat_input_t * input,
772 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700773{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700774 unformat_input_t _line_input, *line_input = &_line_input;
Neale Ranns12989b52019-09-26 16:20:19 +0000775 ip46_address_t local_ip = ip46_address_initializer;
776 ip46_address_t remote_ip = ip46_address_initializer;
Neale Ranns28287212019-12-16 00:53:11 +0000777 ip_address_t nh = IP_ADDRESS_V4_ALL_0S;
Damjan Marion68449852020-03-16 17:53:38 +0100778 ipsec_crypto_alg_t crypto_alg = IPSEC_CRYPTO_ALG_NONE;
779 ipsec_integ_alg_t integ_alg = IPSEC_INTEG_ALG_NONE;
Neale Ranns12989b52019-09-26 16:20:19 +0000780 ipsec_sa_flags_t flags;
Benoît Gannebdd8b572020-07-28 15:56:15 +0200781 u32 local_spi, remote_spi, salt = 0, table_id, fib_index;
Neale Ranns12989b52019-09-26 16:20:19 +0000782 u32 instance = ~0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700783 int rv;
Benoît Gannebdd8b572020-07-28 15:56:15 +0200784 u32 m_args = 0;
Kingwel Xie72b3bce2019-02-12 06:45:08 -0500785 u8 ipv4_set = 0;
786 u8 ipv6_set = 0;
Neale Ranns12989b52019-09-26 16:20:19 +0000787 u8 is_add = 1;
Billy McFalla9a20e72017-02-15 11:39:12 -0500788 clib_error_t *error = NULL;
Kingwel Xied3d12052019-03-07 06:34:30 -0500789 ipsec_key_t rck = { 0 };
790 ipsec_key_t lck = { 0 };
791 ipsec_key_t lik = { 0 };
792 ipsec_key_t rik = { 0 };
Matthew Smith2838a232016-06-21 16:05:09 -0500793
Neale Ranns12989b52019-09-26 16:20:19 +0000794 table_id = 0;
795 flags = IPSEC_SA_FLAG_NONE;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700796
797 /* Get a line of input. */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700798 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700799 return 0;
800
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700801 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
802 {
803 if (unformat
Neale Ranns12989b52019-09-26 16:20:19 +0000804 (line_input, "local-ip %U", unformat_ip46_address, &local_ip,
Kingwel Xie72b3bce2019-02-12 06:45:08 -0500805 IP46_TYPE_ANY))
806 {
Neale Ranns12989b52019-09-26 16:20:19 +0000807 ip46_address_is_ip4 (&local_ip) ? (ipv4_set = 1) : (ipv6_set = 1);
Benoît Gannebdd8b572020-07-28 15:56:15 +0200808 m_args |= 1 << 0;
Kingwel Xie72b3bce2019-02-12 06:45:08 -0500809 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700810 else
811 if (unformat
Neale Ranns12989b52019-09-26 16:20:19 +0000812 (line_input, "remote-ip %U", unformat_ip46_address, &remote_ip,
Kingwel Xie72b3bce2019-02-12 06:45:08 -0500813 IP46_TYPE_ANY))
814 {
Neale Ranns12989b52019-09-26 16:20:19 +0000815 ip46_address_is_ip4 (&remote_ip) ? (ipv4_set = 1) : (ipv6_set = 1);
Benoît Gannebdd8b572020-07-28 15:56:15 +0200816 m_args |= 1 << 1;
Kingwel Xie72b3bce2019-02-12 06:45:08 -0500817 }
Neale Ranns12989b52019-09-26 16:20:19 +0000818 else if (unformat (line_input, "local-spi %u", &local_spi))
Benoît Gannebdd8b572020-07-28 15:56:15 +0200819 m_args |= 1 << 2;
Neale Ranns12989b52019-09-26 16:20:19 +0000820 else if (unformat (line_input, "remote-spi %u", &remote_spi))
Benoît Gannebdd8b572020-07-28 15:56:15 +0200821 m_args |= 1 << 3;
Neale Ranns12989b52019-09-26 16:20:19 +0000822 else if (unformat (line_input, "salt 0x%x", &salt))
Neale Ranns47feb112019-04-11 15:14:07 +0000823 ;
Radu Nicolau717de092018-08-03 10:37:24 +0100824 else if (unformat (line_input, "udp-encap"))
Neale Ranns12989b52019-09-26 16:20:19 +0000825 flags |= IPSEC_SA_FLAG_UDP_ENCAP;
Kingwel Xie2baf9422019-02-04 02:07:06 -0800826 else if (unformat (line_input, "use-esn"))
Neale Ranns12989b52019-09-26 16:20:19 +0000827 flags |= IPSEC_SA_FLAG_USE_ESN;
Kingwel Xie2baf9422019-02-04 02:07:06 -0800828 else if (unformat (line_input, "use-anti-replay"))
Neale Ranns12989b52019-09-26 16:20:19 +0000829 flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;
830 else if (unformat (line_input, "instance %u", &instance))
831 ;
832 else if (unformat (line_input, "tx-table %u", &table_id))
Pierre Pfister4c422f92018-12-10 11:19:08 +0100833 ;
Neale Rannsfd060842019-03-04 13:44:42 +0000834 else
835 if (unformat
836 (line_input, "local-crypto-key %U", unformat_ipsec_key, &lck))
837 ;
838 else
839 if (unformat
840 (line_input, "remote-crypto-key %U", unformat_ipsec_key, &rck))
841 ;
842 else if (unformat (line_input, "crypto-alg %U",
Neale Ranns12989b52019-09-26 16:20:19 +0000843 unformat_ipsec_crypto_alg, &crypto_alg))
Neale Rannsfd060842019-03-04 13:44:42 +0000844 ;
845 else
846 if (unformat
847 (line_input, "local-integ-key %U", unformat_ipsec_key, &lik))
848 ;
849 else
850 if (unformat
Simon Zhange8e950a2019-04-23 23:04:07 +0800851 (line_input, "remote-integ-key %U", unformat_ipsec_key, &rik))
Neale Rannsfd060842019-03-04 13:44:42 +0000852 ;
853 else if (unformat (line_input, "integ-alg %U",
Neale Ranns12989b52019-09-26 16:20:19 +0000854 unformat_ipsec_integ_alg, &integ_alg))
Neale Rannsfd060842019-03-04 13:44:42 +0000855 ;
Kingwel Xie2baf9422019-02-04 02:07:06 -0800856 else if (unformat (line_input, "del"))
Neale Ranns12989b52019-09-26 16:20:19 +0000857 is_add = 0;
Neale Ranns28287212019-12-16 00:53:11 +0000858 else if (unformat (line_input, "nh &U", unformat_ip_address, &nh))
859 ;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700860 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500861 {
862 error = clib_error_return (0, "unknown input `%U'",
863 format_unformat_error, line_input);
864 goto done;
865 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700866 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700867
Benoît Gannebdd8b572020-07-28 15:56:15 +0200868 if (0xf != m_args)
Billy McFalla9a20e72017-02-15 11:39:12 -0500869 {
870 error = clib_error_return (0, "mandatory argument(s) missing");
871 goto done;
872 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700873
Kingwel Xie72b3bce2019-02-12 06:45:08 -0500874 if (ipv4_set && ipv6_set)
875 return clib_error_return (0, "both IPv4 and IPv6 addresses specified");
876
Neale Ranns12989b52019-09-26 16:20:19 +0000877 fib_index = fib_table_find (fib_ip_proto (ipv6_set), table_id);
Kingwel Xie1ba5bc82019-03-20 07:21:58 -0400878
Neale Ranns12989b52019-09-26 16:20:19 +0000879 if (~0 == fib_index)
880 {
881 rv = VNET_API_ERROR_NO_SUCH_FIB;
882 goto done;
883 }
Neale Rannsfd060842019-03-04 13:44:42 +0000884
Neale Ranns12989b52019-09-26 16:20:19 +0000885 if (is_add)
886 {
887 // remote = input, local = output
888 u32 sw_if_index;
Neale Rannsfd060842019-03-04 13:44:42 +0000889
Neale Ranns12989b52019-09-26 16:20:19 +0000890 /* create an ip-ip tunnel, then the two SA, then bind them */
891 rv =
892 ipip_add_tunnel (ipv6_set ? IPIP_TRANSPORT_IP6 : IPIP_TRANSPORT_IP4,
Neale Ranns95346962019-11-25 13:04:44 +0000893 instance, &local_ip, &remote_ip, fib_index,
Neale Ranns59ff9182019-12-29 23:55:18 +0000894 TUNNEL_ENCAP_DECAP_FLAG_NONE, IP_DSCP_CS0,
Neale Ranns14053c92019-12-29 23:55:18 +0000895 TUNNEL_MODE_P2P, &sw_if_index);
Neale Ranns12989b52019-09-26 16:20:19 +0000896 rv |=
897 ipsec_sa_add_and_lock (ipsec_tun_mk_local_sa_id (sw_if_index),
898 local_spi, IPSEC_PROTOCOL_ESP, crypto_alg,
899 &lck, integ_alg, &lik, flags, table_id,
900 clib_host_to_net_u32 (salt), &local_ip,
Neale Rannsabc56602020-04-01 09:45:23 +0000901 &remote_ip, NULL, IPSEC_UDP_PORT_NONE,
902 IPSEC_UDP_PORT_NONE);
Neale Ranns12989b52019-09-26 16:20:19 +0000903 rv |=
904 ipsec_sa_add_and_lock (ipsec_tun_mk_remote_sa_id (sw_if_index),
905 remote_spi, IPSEC_PROTOCOL_ESP, crypto_alg,
906 &rck, integ_alg, &rik,
907 (flags | IPSEC_SA_FLAG_IS_INBOUND), table_id,
908 clib_host_to_net_u32 (salt), &remote_ip,
Neale Rannsabc56602020-04-01 09:45:23 +0000909 &local_ip, NULL, IPSEC_UDP_PORT_NONE,
910 IPSEC_UDP_PORT_NONE);
Neale Ranns12989b52019-09-26 16:20:19 +0000911 rv |=
Neale Ranns28287212019-12-16 00:53:11 +0000912 ipsec_tun_protect_update_one (sw_if_index, &nh,
Neale Ranns12989b52019-09-26 16:20:19 +0000913 ipsec_tun_mk_local_sa_id (sw_if_index),
914 ipsec_tun_mk_remote_sa_id
915 (sw_if_index));
916 }
917 else
918 rv = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700919
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700920 switch (rv)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700921 {
922 case 0:
923 break;
924 case VNET_API_ERROR_INVALID_VALUE:
Neale Rannsd14fccd2019-11-15 15:03:27 +0000925 error = clib_error_return (0,
926 "IPSec tunnel interface already exists...");
Billy McFalla9a20e72017-02-15 11:39:12 -0500927 goto done;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700928 default:
Billy McFalla9a20e72017-02-15 11:39:12 -0500929 error = clib_error_return (0, "ipsec_register_interface returned %d",
930 rv);
931 goto done;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700932 }
933
Billy McFalla9a20e72017-02-15 11:39:12 -0500934done:
935 unformat_free (line_input);
936
937 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700938}
939
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700940/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700941VLIB_CLI_COMMAND (create_ipsec_tunnel_command, static) = {
942 .path = "create ipsec tunnel",
Pierre Pfister4c422f92018-12-10 11:19:08 +0100943 .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> "
Kingwel Xie2baf9422019-02-04 02:07:06 -0800944 "remote-ip <addr> remote-spi <spi> [instance <inst_num>] [udp-encap] [use-esn] [use-anti-replay] "
Pierre Pfister4c422f92018-12-10 11:19:08 +0100945 "[tx-table <table-id>]",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700946 .function = create_ipsec_tunnel_command_fn,
947};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700948/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700949
Neale Rannsc87b66c2019-02-07 07:26:12 -0800950static clib_error_t *
951ipsec_tun_protect_cmd (vlib_main_t * vm,
952 unformat_input_t * input, vlib_cli_command_t * cmd)
953{
954 unformat_input_t _line_input, *line_input = &_line_input;
955 u32 sw_if_index, is_del, sa_in, sa_out, *sa_ins = NULL;
Neale Ranns28287212019-12-16 00:53:11 +0000956 ip_address_t peer = { };
Neale Rannsc87b66c2019-02-07 07:26:12 -0800957 vnet_main_t *vnm;
958
959 is_del = 0;
960 sw_if_index = ~0;
961 vnm = vnet_get_main ();
962
963 if (!unformat_user (input, unformat_line_input, line_input))
964 return 0;
965
966 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
967 {
968 if (unformat (line_input, "del"))
969 is_del = 1;
970 else if (unformat (line_input, "add"))
971 is_del = 0;
972 else if (unformat (line_input, "sa-in %d", &sa_in))
973 vec_add1 (sa_ins, sa_in);
974 else if (unformat (line_input, "sa-out %d", &sa_out))
975 ;
976 else if (unformat (line_input, "%U",
977 unformat_vnet_sw_interface, vnm, &sw_if_index))
978 ;
Neale Ranns28287212019-12-16 00:53:11 +0000979 else if (unformat (line_input, "%U", unformat_ip_address, &peer))
980 ;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800981 else
982 return (clib_error_return (0, "unknown input '%U'",
983 format_unformat_error, line_input));
984 }
985
986 if (!is_del)
Neale Ranns28287212019-12-16 00:53:11 +0000987 ipsec_tun_protect_update (sw_if_index, &peer, sa_out, sa_ins);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800988
989 unformat_free (line_input);
990 return NULL;
991}
992
993/**
994 * Protect tunnel with IPSEC
995 */
996/* *INDENT-OFF* */
997VLIB_CLI_COMMAND (ipsec_tun_protect_cmd_node, static) =
998{
999 .path = "ipsec tunnel protect",
1000 .function = ipsec_tun_protect_cmd,
1001 .short_help = "ipsec tunnel protect <interface> input-sa <SA> output-sa <SA>",
1002 // this is not MP safe
1003};
1004/* *INDENT-ON* */
1005
Neale Rannsc87b66c2019-02-07 07:26:12 -08001006
1007static clib_error_t *
1008ipsec_tun_protect_show (vlib_main_t * vm,
1009 unformat_input_t * input, vlib_cli_command_t * cmd)
1010{
1011 ipsec_tun_protect_walk (ipsec_tun_protect_show_one, vm);
1012
1013 return NULL;
1014}
1015
1016/**
1017 * show IPSEC tunnel protection
1018 */
1019/* *INDENT-OFF* */
1020VLIB_CLI_COMMAND (ipsec_tun_protect_show_node, static) =
1021{
1022 .path = "show ipsec protect",
1023 .function = ipsec_tun_protect_show,
1024 .short_help = "show ipsec protect",
1025};
1026/* *INDENT-ON* */
1027
Neale Ranns41afb332019-07-16 06:19:35 -07001028static clib_error_t *
1029ipsec_tun_protect_hash_show (vlib_main_t * vm,
1030 unformat_input_t * input,
1031 vlib_cli_command_t * cmd)
1032{
1033 ipsec_main_t *im = &ipsec_main;
1034
1035 {
1036 ipsec_tun_lkup_result_t value;
1037 ipsec4_tunnel_key_t key;
1038
1039 vlib_cli_output (vm, "IPv4:");
1040
1041 /* *INDENT-OFF* */
1042 hash_foreach(key.as_u64, value.as_u64, im->tun4_protect_by_key,
1043 ({
1044 vlib_cli_output (vm, " %U", format_ipsec4_tunnel_key, &key);
1045 vlib_cli_output (vm, " tun:%d sa:%d", value.tun_index, value.sa_index);
1046 }));
1047 /* *INDENT-ON* */
1048 }
1049
1050 {
1051 ipsec_tun_lkup_result_t value;
1052 ipsec6_tunnel_key_t *key;
1053
1054 vlib_cli_output (vm, "IPv6:");
1055
1056 /* *INDENT-OFF* */
1057 hash_foreach_mem(key, value.as_u64, im->tun6_protect_by_key,
1058 ({
1059 vlib_cli_output (vm, " %U", format_ipsec6_tunnel_key, key);
1060 vlib_cli_output (vm, " tun:%d sa:%d", value.tun_index, value.sa_index);
1061 }));
1062 /* *INDENT-ON* */
1063 }
1064
1065 return NULL;
1066}
1067
1068/**
1069 * show IPSEC tunnel protection hash tables
1070 */
1071/* *INDENT-OFF* */
1072VLIB_CLI_COMMAND (ipsec_tun_protect_hash_show_node, static) =
1073{
1074 .path = "show ipsec protect-hash",
1075 .function = ipsec_tun_protect_hash_show,
1076 .short_help = "show ipsec protect-hash",
1077};
1078/* *INDENT-ON* */
1079
Ed Warnickecb9cada2015-12-08 15:45:58 -07001080clib_error_t *
1081ipsec_cli_init (vlib_main_t * vm)
1082{
1083 return 0;
1084}
1085
1086VLIB_INIT_FUNCTION (ipsec_cli_init);
1087
Fan Zhangf5395782020-04-29 14:00:03 +01001088static clib_error_t *
1089set_async_mode_command_fn (vlib_main_t * vm, unformat_input_t * input,
1090 vlib_cli_command_t * cmd)
1091{
1092 unformat_input_t _line_input, *line_input = &_line_input;
1093 int async_enable = 0;
1094
1095 if (!unformat_user (input, unformat_line_input, line_input))
1096 return 0;
1097
1098 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1099 {
1100 if (unformat (line_input, "on"))
1101 async_enable = 1;
1102 else if (unformat (line_input, "off"))
1103 async_enable = 0;
1104 else
1105 return (clib_error_return (0, "unknown input '%U'",
1106 format_unformat_error, line_input));
1107 }
1108
1109 vnet_crypto_request_async_mode (async_enable);
1110 ipsec_set_async_mode (async_enable);
1111
1112 unformat_free (line_input);
1113 return (NULL);
1114}
1115
1116/* *INDENT-OFF* */
1117VLIB_CLI_COMMAND (set_async_mode_command, static) = {
1118 .path = "set ipsec async mode",
1119 .short_help = "set ipsec async mode on|off",
1120 .function = set_async_mode_command_fn,
1121};
1122/* *INDENT-ON* */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -07001123
1124/*
1125 * fd.io coding-style-patch-verification: ON
1126 *
1127 * Local Variables:
1128 * eval: (c-set-style "gnu")
1129 * End:
1130 */