blob: 767dc82dca7060d20d7eec761adf4ee9c7c53182 [file] [log] [blame]
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001/*
2 *------------------------------------------------------------------
3 * ipsec_api.c - ipsec api
4 *
5 * Copyright (c) 2016 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
18 */
19
20#include <vnet/vnet.h>
21#include <vlibmemory/api.h>
22
23#include <vnet/interface.h>
24#include <vnet/api_errno.h>
25#include <vnet/ip/ip.h>
Neale Ranns17dcec02019-01-09 21:22:20 -080026#include <vnet/ip/ip_types_api.h>
Prashant Maheshwaridbf68c92019-11-14 12:42:59 +053027#include <vnet/ipsec/ipsec_types_api.h>
Neale Rannsdd4ccf22020-06-30 07:47:14 +000028#include <vnet/tunnel/tunnel_types_api.h>
Pierre Pfister4c422f92018-12-10 11:19:08 +010029#include <vnet/fib/fib.h>
Neale Ranns12989b52019-09-26 16:20:19 +000030#include <vnet/ipip/ipip.h>
Neale Ranns041add72020-01-02 04:06:10 +000031#include <vnet/tunnel/tunnel_types_api.h>
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010032#include <vnet/ipsec/ipsec.h>
Neale Rannsc87b66c2019-02-07 07:26:12 -080033#include <vnet/ipsec/ipsec_tun.h>
Neale Rannsdd4ccf22020-06-30 07:47:14 +000034#include <vnet/ipsec/ipsec_itf.h>
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010035
Filip Tehlarc73f3292021-06-22 08:21:31 +000036#include <vnet/format_fns.h>
37#include <vnet/ipsec/ipsec.api_enum.h>
38#include <vnet/ipsec/ipsec.api_types.h>
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010039
Filip Tehlarc73f3292021-06-22 08:21:31 +000040#define REPLY_MSG_ID_BASE ipsec_main.msg_id_base
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010041#include <vlibapi/api_helper_macros.h>
42
Klement Sekerab4d30532018-11-08 13:00:02 +010043static void
44vl_api_ipsec_spd_add_del_t_handler (vl_api_ipsec_spd_add_del_t * mp)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010045{
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010046 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
47 vl_api_ipsec_spd_add_del_reply_t *rmp;
48 int rv;
49
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010050 rv = ipsec_add_del_spd (vm, ntohl (mp->spd_id), mp->is_add);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010051
52 REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_REPLY);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010053}
54
55static void vl_api_ipsec_interface_add_del_spd_t_handler
56 (vl_api_ipsec_interface_add_del_spd_t * mp)
57{
58 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
59 vl_api_ipsec_interface_add_del_spd_reply_t *rmp;
60 int rv;
61 u32 sw_if_index __attribute__ ((unused));
62 u32 spd_id __attribute__ ((unused));
63
64 sw_if_index = ntohl (mp->sw_if_index);
65 spd_id = ntohl (mp->spd_id);
66
67 VALIDATE_SW_IF_INDEX (mp);
68
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010069 rv = ipsec_set_interface_spd (vm, sw_if_index, spd_id, mp->is_add);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010070
71 BAD_SW_IF_INDEX_LABEL;
72
73 REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY);
74}
75
Neale Rannsc87b66c2019-02-07 07:26:12 -080076static void vl_api_ipsec_tunnel_protect_update_t_handler
77 (vl_api_ipsec_tunnel_protect_update_t * mp)
78{
79 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
80 vl_api_ipsec_tunnel_protect_update_reply_t *rmp;
81 u32 sw_if_index, ii, *sa_ins = NULL;
Neale Ranns28287212019-12-16 00:53:11 +000082 ip_address_t nh;
Neale Rannsc87b66c2019-02-07 07:26:12 -080083 int rv;
84
85 sw_if_index = ntohl (mp->tunnel.sw_if_index);
86
87 VALIDATE_SW_IF_INDEX (&(mp->tunnel));
88
Neale Rannsc87b66c2019-02-07 07:26:12 -080089 for (ii = 0; ii < mp->tunnel.n_sa_in; ii++)
90 vec_add1 (sa_ins, ntohl (mp->tunnel.sa_in[ii]));
91
Neale Ranns28287212019-12-16 00:53:11 +000092 ip_address_decode2 (&mp->tunnel.nh, &nh);
93
94 rv = ipsec_tun_protect_update (sw_if_index, &nh,
Neale Rannsc87b66c2019-02-07 07:26:12 -080095 ntohl (mp->tunnel.sa_out), sa_ins);
Neale Rannsc87b66c2019-02-07 07:26:12 -080096
97 BAD_SW_IF_INDEX_LABEL;
98
99 REPLY_MACRO (VL_API_IPSEC_TUNNEL_PROTECT_UPDATE_REPLY);
100}
101
102static void vl_api_ipsec_tunnel_protect_del_t_handler
103 (vl_api_ipsec_tunnel_protect_del_t * mp)
104{
105 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
106 vl_api_ipsec_tunnel_protect_del_reply_t *rmp;
Neale Ranns28287212019-12-16 00:53:11 +0000107 ip_address_t nh;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800108 u32 sw_if_index;
Neale Ranns28287212019-12-16 00:53:11 +0000109 int rv;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800110
111 sw_if_index = ntohl (mp->sw_if_index);
112
113 VALIDATE_SW_IF_INDEX (mp);
114
Neale Ranns28287212019-12-16 00:53:11 +0000115 ip_address_decode2 (&mp->nh, &nh);
116 rv = ipsec_tun_protect_del (sw_if_index, &nh);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800117
118 BAD_SW_IF_INDEX_LABEL;
119
120 REPLY_MACRO (VL_API_IPSEC_TUNNEL_PROTECT_DEL_REPLY);
121}
122
Neale Ranns12989b52019-09-26 16:20:19 +0000123typedef struct ipsec_dump_walk_ctx_t_
Neale Rannsc87b66c2019-02-07 07:26:12 -0800124{
125 vl_api_registration_t *reg;
126 u32 context;
Neale Rannsbed9b722021-10-22 14:10:06 +0000127 u32 sw_if_index;
Neale Ranns12989b52019-09-26 16:20:19 +0000128} ipsec_dump_walk_ctx_t;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800129
130static walk_rc_t
131send_ipsec_tunnel_protect_details (index_t itpi, void *arg)
132{
Neale Ranns12989b52019-09-26 16:20:19 +0000133 ipsec_dump_walk_ctx_t *ctx = arg;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800134 vl_api_ipsec_tunnel_protect_details_t *mp;
135 ipsec_tun_protect_t *itp;
Matthew Smith5cee0bc2020-03-31 09:52:17 -0500136 u32 ii = 0;
137 ipsec_sa_t *sa;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800138
139 itp = ipsec_tun_protect_get (itpi);
140
Neale Rannsc87b66c2019-02-07 07:26:12 -0800141 mp = vl_msg_api_alloc (sizeof (*mp) + (sizeof (u32) * itp->itp_n_sa_in));
142 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000143 mp->_vl_msg_id =
144 ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_TUNNEL_PROTECT_DETAILS);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800145 mp->context = ctx->context;
146
147 mp->tun.sw_if_index = htonl (itp->itp_sw_if_index);
Neale Ranns28287212019-12-16 00:53:11 +0000148 ip_address_encode2 (itp->itp_key, &mp->tun.nh);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800149
Matthew Smith5cee0bc2020-03-31 09:52:17 -0500150 sa = ipsec_sa_get (itp->itp_out_sa);
151 mp->tun.sa_out = htonl (sa->id);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800152 mp->tun.n_sa_in = itp->itp_n_sa_in;
153 /* *INDENT-OFF* */
Matthew Smith5cee0bc2020-03-31 09:52:17 -0500154 FOR_EACH_IPSEC_PROTECT_INPUT_SA(itp, sa,
Neale Rannsc87b66c2019-02-07 07:26:12 -0800155 ({
Matthew Smith5cee0bc2020-03-31 09:52:17 -0500156 mp->tun.sa_in[ii++] = htonl (sa->id);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800157 }));
158 /* *INDENT-ON* */
159
160 vl_api_send_msg (ctx->reg, (u8 *) mp);
161
162 return (WALK_CONTINUE);
163}
164
165static void
166vl_api_ipsec_tunnel_protect_dump_t_handler (vl_api_ipsec_tunnel_protect_dump_t
167 * mp)
168{
169 vl_api_registration_t *reg;
170 u32 sw_if_index;
171
Neale Rannsc87b66c2019-02-07 07:26:12 -0800172 reg = vl_api_client_index_to_registration (mp->client_index);
173 if (!reg)
174 return;
175
Neale Ranns12989b52019-09-26 16:20:19 +0000176 ipsec_dump_walk_ctx_t ctx = {
Neale Rannsc87b66c2019-02-07 07:26:12 -0800177 .reg = reg,
178 .context = mp->context,
179 };
180
181 sw_if_index = ntohl (mp->sw_if_index);
182
183 if (~0 == sw_if_index)
184 {
185 ipsec_tun_protect_walk (send_ipsec_tunnel_protect_details, &ctx);
186 }
187 else
188 {
Neale Ranns28287212019-12-16 00:53:11 +0000189 ipsec_tun_protect_walk_itf (sw_if_index,
190 send_ipsec_tunnel_protect_details, &ctx);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800191 }
Neale Rannsc87b66c2019-02-07 07:26:12 -0800192}
193
Neale Ranns17dcec02019-01-09 21:22:20 -0800194static int
195ipsec_spd_action_decode (vl_api_ipsec_spd_action_t in,
196 ipsec_policy_action_t * out)
197{
198 in = clib_net_to_host_u32 (in);
199
200 switch (in)
201 {
202#define _(v,f,s) case IPSEC_API_SPD_ACTION_##f: \
203 *out = IPSEC_POLICY_ACTION_##f; \
204 return (0);
205 foreach_ipsec_policy_action
206#undef _
207 }
208 return (VNET_API_ERROR_UNIMPLEMENTED);
209}
210
211static void vl_api_ipsec_spd_entry_add_del_t_handler
212 (vl_api_ipsec_spd_entry_add_del_t * mp)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100213{
214 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
Neale Ranns17dcec02019-01-09 21:22:20 -0800215 vl_api_ipsec_spd_entry_add_del_reply_t *rmp;
216 ip46_type_t itype;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800217 u32 stat_index;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100218 int rv;
219
Neale Ranns8c2dd1b2019-02-19 08:27:34 -0800220 stat_index = ~0;
221
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100222 ipsec_policy_t p;
223
Dave Barachb7b92992018-10-17 10:38:51 -0400224 clib_memset (&p, 0, sizeof (p));
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100225
Neale Ranns17dcec02019-01-09 21:22:20 -0800226 p.id = ntohl (mp->entry.spd_id);
227 p.priority = ntohl (mp->entry.priority);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100228
Neale Ranns17dcec02019-01-09 21:22:20 -0800229 itype = ip_address_decode (&mp->entry.remote_address_start, &p.raddr.start);
230 ip_address_decode (&mp->entry.remote_address_stop, &p.raddr.stop);
231 ip_address_decode (&mp->entry.local_address_start, &p.laddr.start);
232 ip_address_decode (&mp->entry.local_address_stop, &p.laddr.stop);
233
234 p.is_ipv6 = (itype == IP46_TYPE_IP6);
235
Piotr Bronowski815c6a42022-06-09 09:09:28 +0000236 p.protocol =
237 mp->entry.protocol ? mp->entry.protocol : IPSEC_POLICY_PROTOCOL_ANY;
Neale Rannsa4d24312019-07-10 13:46:21 +0000238 p.rport.start = ntohs (mp->entry.remote_port_start);
239 p.rport.stop = ntohs (mp->entry.remote_port_stop);
240 p.lport.start = ntohs (mp->entry.local_port_start);
241 p.lport.stop = ntohs (mp->entry.local_port_stop);
Neale Ranns17dcec02019-01-09 21:22:20 -0800242
243 rv = ipsec_spd_action_decode (mp->entry.policy, &p.policy);
244
245 if (rv)
246 goto out;
247
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100248 /* policy action resolve unsupported */
Neale Ranns17dcec02019-01-09 21:22:20 -0800249 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100250 {
251 clib_warning ("unsupported action: 'resolve'");
252 rv = VNET_API_ERROR_UNIMPLEMENTED;
253 goto out;
254 }
Neale Ranns17dcec02019-01-09 21:22:20 -0800255 p.sa_id = ntohl (mp->entry.sa_id);
Neale Ranns9f231d42019-03-19 10:06:00 +0000256 rv =
257 ipsec_policy_mk_type (mp->entry.is_outbound, p.is_ipv6, p.policy,
258 &p.type);
259 if (rv)
260 goto out;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100261
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800262 rv = ipsec_add_del_policy (vm, &p, mp->is_add, &stat_index);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100263 if (rv)
264 goto out;
265
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100266out:
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800267 /* *INDENT-OFF* */
268 REPLY_MACRO2 (VL_API_IPSEC_SPD_ENTRY_ADD_DEL_REPLY,
269 ({
270 rmp->stat_index = ntohl(stat_index);
271 }));
272 /* *INDENT-ON* */
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100273}
274
Piotr Bronowski815c6a42022-06-09 09:09:28 +0000275static void
276vl_api_ipsec_spd_entry_add_del_v2_t_handler (
277 vl_api_ipsec_spd_entry_add_del_v2_t *mp)
278{
279 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
280 vl_api_ipsec_spd_entry_add_del_reply_t *rmp;
281 ip46_type_t itype;
282 u32 stat_index;
283 int rv;
284
285 stat_index = ~0;
286
287 ipsec_policy_t p;
288
289 clib_memset (&p, 0, sizeof (p));
290
291 p.id = ntohl (mp->entry.spd_id);
292 p.priority = ntohl (mp->entry.priority);
293
294 itype = ip_address_decode (&mp->entry.remote_address_start, &p.raddr.start);
295 ip_address_decode (&mp->entry.remote_address_stop, &p.raddr.stop);
296 ip_address_decode (&mp->entry.local_address_start, &p.laddr.start);
297 ip_address_decode (&mp->entry.local_address_stop, &p.laddr.stop);
298
299 p.is_ipv6 = (itype == IP46_TYPE_IP6);
300
301 p.protocol = mp->entry.protocol;
302 p.rport.start = ntohs (mp->entry.remote_port_start);
303 p.rport.stop = ntohs (mp->entry.remote_port_stop);
304 p.lport.start = ntohs (mp->entry.local_port_start);
305 p.lport.stop = ntohs (mp->entry.local_port_stop);
306
307 rv = ipsec_spd_action_decode (mp->entry.policy, &p.policy);
308
309 if (rv)
310 goto out;
311
312 /* policy action resolve unsupported */
313 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
314 {
315 clib_warning ("unsupported action: 'resolve'");
316 rv = VNET_API_ERROR_UNIMPLEMENTED;
317 goto out;
318 }
319 p.sa_id = ntohl (mp->entry.sa_id);
320 rv =
321 ipsec_policy_mk_type (mp->entry.is_outbound, p.is_ipv6, p.policy, &p.type);
322 if (rv)
323 goto out;
324
325 rv = ipsec_add_del_policy (vm, &p, mp->is_add, &stat_index);
326 if (rv)
327 goto out;
328
329out:
330 REPLY_MACRO2 (VL_API_IPSEC_SPD_ENTRY_ADD_DEL_REPLY,
331 ({ rmp->stat_index = ntohl (stat_index); }));
332}
333
Neale Ranns17dcec02019-01-09 21:22:20 -0800334static void vl_api_ipsec_sad_entry_add_del_t_handler
335 (vl_api_ipsec_sad_entry_add_del_t * mp)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100336{
Neale Ranns17dcec02019-01-09 21:22:20 -0800337 vl_api_ipsec_sad_entry_add_del_reply_t *rmp;
Neale Ranns8d7c5022019-02-06 01:41:05 -0800338 ipsec_key_t crypto_key, integ_key;
339 ipsec_crypto_alg_t crypto_alg;
340 ipsec_integ_alg_t integ_alg;
341 ipsec_protocol_t proto;
342 ipsec_sa_flags_t flags;
Dave Baracha5160d72019-03-13 15:29:15 -0400343 u32 id, spi, sa_index = ~0;
Neale Ranns9ec846c2021-02-09 14:04:02 +0000344 tunnel_t tun = {
345 .t_flags = TUNNEL_FLAG_NONE,
346 .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE,
347 .t_dscp = 0,
348 .t_mode = TUNNEL_MODE_P2P,
349 .t_table_id = 0,
350 .t_hop_limit = 255,
351 };
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100352 int rv;
Neale Ranns8d7c5022019-02-06 01:41:05 -0800353
Neale Ranns8d7c5022019-02-06 01:41:05 -0800354 id = ntohl (mp->entry.sad_id);
Neale Rannsff2e4132021-06-24 14:57:56 +0000355 if (!mp->is_add)
356 {
357 rv = ipsec_sa_unlock_id (id);
358 goto out;
359 }
Neale Ranns8d7c5022019-02-06 01:41:05 -0800360 spi = ntohl (mp->entry.spi);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100361
Neale Ranns8d7c5022019-02-06 01:41:05 -0800362 rv = ipsec_proto_decode (mp->entry.protocol, &proto);
Neale Ranns17dcec02019-01-09 21:22:20 -0800363
364 if (rv)
365 goto out;
366
Neale Ranns8d7c5022019-02-06 01:41:05 -0800367 rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
Neale Ranns17dcec02019-01-09 21:22:20 -0800368
369 if (rv)
370 goto out;
371
Neale Ranns8d7c5022019-02-06 01:41:05 -0800372 rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
Neale Ranns17dcec02019-01-09 21:22:20 -0800373
374 if (rv)
375 goto out;
376
Neale Ranns8d7c5022019-02-06 01:41:05 -0800377 ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
378 ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
Neale Ranns17dcec02019-01-09 21:22:20 -0800379
Neale Ranns8d7c5022019-02-06 01:41:05 -0800380 flags = ipsec_sa_flags_decode (mp->entry.flags);
Neale Ranns17dcec02019-01-09 21:22:20 -0800381
Neale Ranns9ec846c2021-02-09 14:04:02 +0000382 ip_address_decode2 (&mp->entry.tunnel_src, &tun.t_src);
383 ip_address_decode2 (&mp->entry.tunnel_dst, &tun.t_dst);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100384
Neale Rannsff2e4132021-06-24 14:57:56 +0000385 rv = ipsec_sa_add_and_lock (id, spi, proto, crypto_alg, &crypto_key,
386 integ_alg, &integ_key, flags, mp->entry.salt,
387 htons (mp->entry.udp_src_port),
388 htons (mp->entry.udp_dst_port), &tun, &sa_index);
Neale Ranns8d7c5022019-02-06 01:41:05 -0800389
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100390out:
Neale Rannseba31ec2019-02-17 18:04:27 +0000391 /* *INDENT-OFF* */
392 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_REPLY,
393 {
394 rmp->stat_index = htonl (sa_index);
395 });
396 /* *INDENT-ON* */
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100397}
398
Neale Ranns041add72020-01-02 04:06:10 +0000399static void vl_api_ipsec_sad_entry_add_del_v2_t_handler
400 (vl_api_ipsec_sad_entry_add_del_v2_t * mp)
401{
402 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
403 vl_api_ipsec_sad_entry_add_del_v2_reply_t *rmp;
Neale Ranns041add72020-01-02 04:06:10 +0000404 ipsec_key_t crypto_key, integ_key;
405 ipsec_crypto_alg_t crypto_alg;
406 ipsec_integ_alg_t integ_alg;
407 ipsec_protocol_t proto;
408 ipsec_sa_flags_t flags;
409 u32 id, spi, sa_index = ~0;
410 int rv;
Neale Ranns9ec846c2021-02-09 14:04:02 +0000411 tunnel_t tun = {
412 .t_flags = TUNNEL_FLAG_NONE,
413 .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE,
414 .t_dscp = 0,
415 .t_mode = TUNNEL_MODE_P2P,
416 .t_table_id = htonl (mp->entry.tx_table_id),
417 .t_hop_limit = 255,
418 };
419
Neale Ranns9ec846c2021-02-09 14:04:02 +0000420 id = ntohl (mp->entry.sad_id);
Neale Rannsff2e4132021-06-24 14:57:56 +0000421 if (!mp->is_add)
422 {
423 rv = ipsec_sa_unlock_id (id);
424 goto out;
425 }
426
Neale Ranns9ec846c2021-02-09 14:04:02 +0000427 spi = ntohl (mp->entry.spi);
428
429 rv = ipsec_proto_decode (mp->entry.protocol, &proto);
430
431 if (rv)
432 goto out;
433
434 rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
435
436 if (rv)
437 goto out;
438
439 rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
440
441 if (rv)
442 goto out;
443
444 rv = tunnel_encap_decap_flags_decode (mp->entry.tunnel_flags,
445 &tun.t_encap_decap_flags);
446
447 if (rv)
448 goto out;
449
450 ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
451 ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
452
453 flags = ipsec_sa_flags_decode (mp->entry.flags);
454 tun.t_dscp = ip_dscp_decode (mp->entry.dscp);
455
456 ip_address_decode2 (&mp->entry.tunnel_src, &tun.t_src);
457 ip_address_decode2 (&mp->entry.tunnel_dst, &tun.t_dst);
458
Neale Ranns9ec846c2021-02-09 14:04:02 +0000459 rv = ipsec_sa_add_and_lock (
460 id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
461 mp->entry.salt, htons (mp->entry.udp_src_port),
462 htons (mp->entry.udp_dst_port), &tun, &sa_index);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000463
Neale Ranns9ec846c2021-02-09 14:04:02 +0000464out:
465 /* *INDENT-OFF* */
466 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_V2_REPLY,
467 {
468 rmp->stat_index = htonl (sa_index);
469 });
470 /* *INDENT-ON* */
471}
472
Neale Rannsff2e4132021-06-24 14:57:56 +0000473static int
474ipsec_sad_entry_add_v3 (const vl_api_ipsec_sad_entry_v3_t *entry,
475 u32 *sa_index)
Neale Ranns9ec846c2021-02-09 14:04:02 +0000476{
Neale Ranns9ec846c2021-02-09 14:04:02 +0000477 ipsec_key_t crypto_key, integ_key;
478 ipsec_crypto_alg_t crypto_alg;
479 ipsec_integ_alg_t integ_alg;
480 ipsec_protocol_t proto;
481 ipsec_sa_flags_t flags;
Neale Rannsff2e4132021-06-24 14:57:56 +0000482 u32 id, spi;
Andrew Yourtchenko4b4aded2022-08-23 17:09:25 +0000483 tunnel_t tun = { 0 };
Neale Ranns9ec846c2021-02-09 14:04:02 +0000484 int rv;
Neale Rannsc7eaa712021-02-04 11:09:33 +0000485
Neale Rannsff2e4132021-06-24 14:57:56 +0000486 id = ntohl (entry->sad_id);
487 spi = ntohl (entry->spi);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000488
Neale Rannsff2e4132021-06-24 14:57:56 +0000489 rv = ipsec_proto_decode (entry->protocol, &proto);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000490
491 if (rv)
Neale Rannsff2e4132021-06-24 14:57:56 +0000492 return (rv);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000493
Neale Rannsff2e4132021-06-24 14:57:56 +0000494 rv = ipsec_crypto_algo_decode (entry->crypto_algorithm, &crypto_alg);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000495
496 if (rv)
Neale Rannsff2e4132021-06-24 14:57:56 +0000497 return (rv);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000498
Neale Rannsff2e4132021-06-24 14:57:56 +0000499 rv = ipsec_integ_algo_decode (entry->integrity_algorithm, &integ_alg);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000500
501 if (rv)
Neale Rannsff2e4132021-06-24 14:57:56 +0000502 return (rv);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000503
Neale Rannsff2e4132021-06-24 14:57:56 +0000504 flags = ipsec_sa_flags_decode (entry->flags);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000505
Neale Ranns9ec846c2021-02-09 14:04:02 +0000506 if (flags & IPSEC_SA_FLAG_IS_TUNNEL)
507 {
Neale Rannsff2e4132021-06-24 14:57:56 +0000508 rv = tunnel_decode (&entry->tunnel, &tun);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000509
510 if (rv)
Neale Rannsff2e4132021-06-24 14:57:56 +0000511 return (rv);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000512 }
Neale Rannsc7eaa712021-02-04 11:09:33 +0000513
Neale Rannsff2e4132021-06-24 14:57:56 +0000514 ipsec_key_decode (&entry->crypto_key, &crypto_key);
515 ipsec_key_decode (&entry->integrity_key, &integ_key);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000516
Neale Rannsff2e4132021-06-24 14:57:56 +0000517 return ipsec_sa_add_and_lock (id, spi, proto, crypto_alg, &crypto_key,
518 integ_alg, &integ_key, flags, entry->salt,
519 htons (entry->udp_src_port),
520 htons (entry->udp_dst_port), &tun, sa_index);
521}
522
523static void
524vl_api_ipsec_sad_entry_add_del_v3_t_handler (
525 vl_api_ipsec_sad_entry_add_del_v3_t *mp)
526{
527 vl_api_ipsec_sad_entry_add_del_v3_reply_t *rmp;
528 u32 id, sa_index = ~0;
529 int rv;
530
531 id = ntohl (mp->entry.sad_id);
532
533 if (!mp->is_add)
534 {
535 rv = ipsec_sa_unlock_id (id);
536 }
Neale Rannsc7eaa712021-02-04 11:09:33 +0000537 else
Neale Rannsff2e4132021-06-24 14:57:56 +0000538 {
539 rv = ipsec_sad_entry_add_v3 (&mp->entry, &sa_index);
540 }
Neale Rannsc7eaa712021-02-04 11:09:33 +0000541
Neale Ranns9ec846c2021-02-09 14:04:02 +0000542 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_V3_REPLY,
543 { rmp->stat_index = htonl (sa_index); });
Neale Rannsc7eaa712021-02-04 11:09:33 +0000544}
545
546static void
Neale Rannsff2e4132021-06-24 14:57:56 +0000547vl_api_ipsec_sad_entry_del_t_handler (vl_api_ipsec_sad_entry_del_t *mp)
548{
549 vl_api_ipsec_sad_entry_del_reply_t *rmp;
550 int rv;
551
552 rv = ipsec_sa_unlock_id (ntohl (mp->id));
553
554 REPLY_MACRO (VL_API_IPSEC_SAD_ENTRY_DEL_REPLY);
555}
556
557static void
558vl_api_ipsec_sad_entry_add_t_handler (vl_api_ipsec_sad_entry_add_t *mp)
559{
560 vl_api_ipsec_sad_entry_add_reply_t *rmp;
561 u32 sa_index = ~0;
562 int rv;
563
564 rv = ipsec_sad_entry_add_v3 (&mp->entry, &sa_index);
565
566 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_REPLY,
567 { rmp->stat_index = htonl (sa_index); });
568}
569
570static void
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700571send_ipsec_spds_details (ipsec_spd_t * spd, vl_api_registration_t * reg,
572 u32 context)
573{
574 vl_api_ipsec_spds_details_t *mp;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800575 u32 n_policies = 0;
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700576
577 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400578 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000579 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SPDS_DETAILS);
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700580 mp->context = context;
581
582 mp->spd_id = htonl (spd->id);
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800583#define _(s, n) n_policies += vec_len (spd->policies[IPSEC_SPD_POLICY_##s]);
584 foreach_ipsec_spd_policy_type
585#undef _
586 mp->npolicies = htonl (n_policies);
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700587
588 vl_api_send_msg (reg, (u8 *) mp);
589}
590
591static void
592vl_api_ipsec_spds_dump_t_handler (vl_api_ipsec_spds_dump_t * mp)
593{
594 vl_api_registration_t *reg;
595 ipsec_main_t *im = &ipsec_main;
596 ipsec_spd_t *spd;
Damjan Marion97898982021-04-19 18:15:31 +0200597
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700598 reg = vl_api_client_index_to_registration (mp->client_index);
599 if (!reg)
600 return;
601
Damjan Marionb2c31b62020-12-13 21:47:40 +0100602 pool_foreach (spd, im->spds) {
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700603 send_ipsec_spds_details (spd, reg, mp->context);
Damjan Marionb2c31b62020-12-13 21:47:40 +0100604 }
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700605}
606
Neale Ranns17dcec02019-01-09 21:22:20 -0800607vl_api_ipsec_spd_action_t
608ipsec_spd_action_encode (ipsec_policy_action_t in)
609{
610 vl_api_ipsec_spd_action_t out = IPSEC_API_SPD_ACTION_BYPASS;
611
612 switch (in)
613 {
614#define _(v,f,s) case IPSEC_POLICY_ACTION_##f: \
615 out = IPSEC_API_SPD_ACTION_##f; \
616 break;
617 foreach_ipsec_policy_action
618#undef _
619 }
620 return (clib_host_to_net_u32 (out));
621}
622
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700623static void
Florin Coras6c4dae22018-01-09 06:39:23 -0800624send_ipsec_spd_details (ipsec_policy_t * p, vl_api_registration_t * reg,
625 u32 context)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100626{
627 vl_api_ipsec_spd_details_t *mp;
628
629 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400630 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000631 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SPD_DETAILS);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100632 mp->context = context;
633
Neale Ranns17dcec02019-01-09 21:22:20 -0800634 mp->entry.spd_id = htonl (p->id);
635 mp->entry.priority = htonl (p->priority);
Neale Ranns9f231d42019-03-19 10:06:00 +0000636 mp->entry.is_outbound = ((p->type == IPSEC_SPD_POLICY_IP6_OUTBOUND) ||
637 (p->type == IPSEC_SPD_POLICY_IP4_OUTBOUND));
Neale Ranns17dcec02019-01-09 21:22:20 -0800638
639 ip_address_encode (&p->laddr.start, IP46_TYPE_ANY,
640 &mp->entry.local_address_start);
641 ip_address_encode (&p->laddr.stop, IP46_TYPE_ANY,
642 &mp->entry.local_address_stop);
643 ip_address_encode (&p->raddr.start, IP46_TYPE_ANY,
644 &mp->entry.remote_address_start);
645 ip_address_encode (&p->raddr.stop, IP46_TYPE_ANY,
646 &mp->entry.remote_address_stop);
Neale Rannsa4d24312019-07-10 13:46:21 +0000647 mp->entry.local_port_start = htons (p->lport.start);
648 mp->entry.local_port_stop = htons (p->lport.stop);
649 mp->entry.remote_port_start = htons (p->rport.start);
650 mp->entry.remote_port_stop = htons (p->rport.stop);
Neale Ranns17dcec02019-01-09 21:22:20 -0800651 mp->entry.protocol = p->protocol;
652 mp->entry.policy = ipsec_spd_action_encode (p->policy);
653 mp->entry.sa_id = htonl (p->sa_id);
654
Florin Coras6c4dae22018-01-09 06:39:23 -0800655 vl_api_send_msg (reg, (u8 *) mp);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100656}
657
658static void
659vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp)
660{
Florin Coras6c4dae22018-01-09 06:39:23 -0800661 vl_api_registration_t *reg;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100662 ipsec_main_t *im = &ipsec_main;
Neale Ranns9f231d42019-03-19 10:06:00 +0000663 ipsec_spd_policy_type_t ptype;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100664 ipsec_policy_t *policy;
665 ipsec_spd_t *spd;
666 uword *p;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800667 u32 spd_index, *ii;
Damjan Marion97898982021-04-19 18:15:31 +0200668
Florin Coras6c4dae22018-01-09 06:39:23 -0800669 reg = vl_api_client_index_to_registration (mp->client_index);
670 if (!reg)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100671 return;
672
673 p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id));
674 if (!p)
675 return;
676
677 spd_index = p[0];
678 spd = pool_elt_at_index (im->spds, spd_index);
679
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800680 FOR_EACH_IPSEC_SPD_POLICY_TYPE(ptype) {
681 vec_foreach(ii, spd->policies[ptype])
682 {
683 policy = pool_elt_at_index(im->policies, *ii);
684
685 if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id)
686 send_ipsec_spd_details (policy, reg, mp->context);
687 }
688 }
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100689}
690
691static void
Filip Varga871bca92018-11-02 13:51:44 +0100692send_ipsec_spd_interface_details (vl_api_registration_t * reg, u32 spd_index,
693 u32 sw_if_index, u32 context)
694{
695 vl_api_ipsec_spd_interface_details_t *mp;
696
697 mp = vl_msg_api_alloc (sizeof (*mp));
698 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000699 mp->_vl_msg_id =
700 ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SPD_INTERFACE_DETAILS);
Filip Varga871bca92018-11-02 13:51:44 +0100701 mp->context = context;
702
703 mp->spd_index = htonl (spd_index);
704 mp->sw_if_index = htonl (sw_if_index);
705
706 vl_api_send_msg (reg, (u8 *) mp);
707}
708
709static void
710vl_api_ipsec_spd_interface_dump_t_handler (vl_api_ipsec_spd_interface_dump_t *
711 mp)
712{
713 ipsec_main_t *im = &ipsec_main;
714 vl_api_registration_t *reg;
715 u32 k, v, spd_index;
716
Filip Varga871bca92018-11-02 13:51:44 +0100717 reg = vl_api_client_index_to_registration (mp->client_index);
718 if (!reg)
719 return;
720
721 if (mp->spd_index_valid)
722 {
723 spd_index = ntohl (mp->spd_index);
724 /* *INDENT-OFF* */
725 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
726 if (v == spd_index)
727 send_ipsec_spd_interface_details(reg, v, k, mp->context);
728 }));
729 /* *INDENT-ON* */
730 }
731 else
732 {
Filip Varga871bca92018-11-02 13:51:44 +0100733 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
734 send_ipsec_spd_interface_details(reg, v, k, mp->context);
735 }));
Filip Varga871bca92018-11-02 13:51:44 +0100736 }
Filip Varga871bca92018-11-02 13:51:44 +0100737}
738
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000739static void
740vl_api_ipsec_itf_create_t_handler (vl_api_ipsec_itf_create_t * mp)
741{
742 vl_api_ipsec_itf_create_reply_t *rmp;
743 tunnel_mode_t mode;
744 u32 sw_if_index = ~0;
745 int rv;
746
747 rv = tunnel_mode_decode (mp->itf.mode, &mode);
748
749 if (!rv)
750 rv = ipsec_itf_create (ntohl (mp->itf.user_instance), mode, &sw_if_index);
751
752 /* *INDENT-OFF* */
753 REPLY_MACRO2 (VL_API_IPSEC_ITF_CREATE_REPLY,
754 ({
755 rmp->sw_if_index = htonl (sw_if_index);
756 }));
757 /* *INDENT-ON* */
758}
759
760static void
761vl_api_ipsec_itf_delete_t_handler (vl_api_ipsec_itf_delete_t * mp)
762{
763 vl_api_ipsec_itf_delete_reply_t *rmp;
764 int rv;
765
766 rv = ipsec_itf_delete (ntohl (mp->sw_if_index));
767
768 REPLY_MACRO (VL_API_IPSEC_ITF_DELETE_REPLY);
769}
770
Neale Ranns89d939e2021-06-07 09:34:07 +0000771static walk_rc_t
772send_ipsec_itf_details (ipsec_itf_t *itf, void *arg)
773{
774 ipsec_dump_walk_ctx_t *ctx = arg;
775 vl_api_ipsec_itf_details_t *mp;
776
Neale Rannsbed9b722021-10-22 14:10:06 +0000777 if (~0 != ctx->sw_if_index && ctx->sw_if_index != itf->ii_sw_if_index)
778 return (WALK_CONTINUE);
779
Neale Ranns89d939e2021-06-07 09:34:07 +0000780 mp = vl_msg_api_alloc (sizeof (*mp));
781 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000782 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_ITF_DETAILS);
Neale Ranns89d939e2021-06-07 09:34:07 +0000783 mp->context = ctx->context;
784
785 mp->itf.mode = tunnel_mode_encode (itf->ii_mode);
786 mp->itf.user_instance = htonl (itf->ii_user_instance);
787 mp->itf.sw_if_index = htonl (itf->ii_sw_if_index);
788 vl_api_send_msg (ctx->reg, (u8 *) mp);
789
790 return (WALK_CONTINUE);
791}
792
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000793static void
794vl_api_ipsec_itf_dump_t_handler (vl_api_ipsec_itf_dump_t * mp)
795{
Neale Ranns89d939e2021-06-07 09:34:07 +0000796 vl_api_registration_t *reg;
797
798 reg = vl_api_client_index_to_registration (mp->client_index);
799 if (!reg)
800 return;
801
802 ipsec_dump_walk_ctx_t ctx = {
803 .reg = reg,
804 .context = mp->context,
Neale Rannsbed9b722021-10-22 14:10:06 +0000805 .sw_if_index = ntohl (mp->sw_if_index),
Neale Ranns89d939e2021-06-07 09:34:07 +0000806 };
807
808 ipsec_itf_walk (send_ipsec_itf_details, &ctx);
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000809}
810
Neale Ranns12989b52019-09-26 16:20:19 +0000811typedef struct ipsec_sa_dump_match_ctx_t_
Matthew Smith28029532017-09-26 13:33:44 -0500812{
Neale Ranns12989b52019-09-26 16:20:19 +0000813 index_t sai;
814 u32 sw_if_index;
815} ipsec_sa_dump_match_ctx_t;
816
817static walk_rc_t
818ipsec_sa_dump_match_sa (index_t itpi, void *arg)
819{
820 ipsec_sa_dump_match_ctx_t *ctx = arg;
821 ipsec_tun_protect_t *itp;
822 index_t sai;
823
824 itp = ipsec_tun_protect_get (itpi);
825
826 if (itp->itp_out_sa == ctx->sai)
827 {
828 ctx->sw_if_index = itp->itp_sw_if_index;
829 return (WALK_STOP);
830 }
Damjan Marion97898982021-04-19 18:15:31 +0200831
Neale Ranns12989b52019-09-26 16:20:19 +0000832 FOR_EACH_IPSEC_PROTECT_INPUT_SAI (itp, sai,
833 ({
834 if (sai == ctx->sai)
835 {
836 ctx->sw_if_index = itp->itp_sw_if_index;
837 return (WALK_STOP);
838 }
839 }));
Neale Ranns12989b52019-09-26 16:20:19 +0000840
841 return (WALK_CONTINUE);
842}
843
844static walk_rc_t
845send_ipsec_sa_details (ipsec_sa_t * sa, void *arg)
846{
847 ipsec_dump_walk_ctx_t *ctx = arg;
Matthew Smith28029532017-09-26 13:33:44 -0500848 vl_api_ipsec_sa_details_t *mp;
849
850 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400851 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000852 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_DETAILS);
Neale Ranns12989b52019-09-26 16:20:19 +0000853 mp->context = ctx->context;
Matthew Smith28029532017-09-26 13:33:44 -0500854
Neale Ranns8d7c5022019-02-06 01:41:05 -0800855 mp->entry.sad_id = htonl (sa->id);
856 mp->entry.spi = htonl (sa->spi);
857 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000858 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
Matthew Smith28029532017-09-26 13:33:44 -0500859
Neale Ranns8d7c5022019-02-06 01:41:05 -0800860 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
861 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
Matthew Smith28029532017-09-26 13:33:44 -0500862
Neale Ranns8d7c5022019-02-06 01:41:05 -0800863 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
864 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
Matthew Smith28029532017-09-26 13:33:44 -0500865
Neale Ranns8d7c5022019-02-06 01:41:05 -0800866 mp->entry.flags = ipsec_sad_flags_encode (sa);
Neale Ranns12989b52019-09-26 16:20:19 +0000867 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
868
869 if (ipsec_sa_is_set_IS_PROTECT (sa))
870 {
871 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000872 .sai = sa - ipsec_sa_pool,
873 .sw_if_index = ~0,
Neale Ranns12989b52019-09-26 16:20:19 +0000874 };
875 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
876
877 mp->sw_if_index = htonl (ctx.sw_if_index);
878 }
879 else
880 mp->sw_if_index = ~0;
Matthew Smith28029532017-09-26 13:33:44 -0500881
Damjan Mariond709cbc2019-03-26 13:16:42 +0100882 if (ipsec_sa_is_set_IS_TUNNEL (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500883 {
Neale Ranns9ec846c2021-02-09 14:04:02 +0000884 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
885 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -0500886 }
Neale Rannsabc56602020-04-01 09:45:23 +0000887 if (ipsec_sa_is_set_UDP_ENCAP (sa))
888 {
889 mp->entry.udp_src_port = sa->udp_hdr.src_port;
890 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
891 }
Matthew Smith28029532017-09-26 13:33:44 -0500892
Matthew Smith28029532017-09-26 13:33:44 -0500893 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns5b891102021-06-28 13:31:28 +0000894 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
Damjan Marion1e3aa5e2019-03-28 10:58:59 +0100895 if (ipsec_sa_is_set_USE_ESN (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500896 {
897 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns5b891102021-06-28 13:31:28 +0000898 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Matthew Smith28029532017-09-26 13:33:44 -0500899 }
Damjan Mariond709cbc2019-03-26 13:16:42 +0100900 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500901 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
Pierre Pfister4c422f92018-12-10 11:19:08 +0100902
Matthew Smith48d32b42020-04-02 07:45:49 -0500903 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
904
Neale Ranns12989b52019-09-26 16:20:19 +0000905 vl_api_send_msg (ctx->reg, (u8 *) mp);
Matthew Smith28029532017-09-26 13:33:44 -0500906
Neale Ranns12989b52019-09-26 16:20:19 +0000907 return (WALK_CONTINUE);
908}
Matthew Smith28029532017-09-26 13:33:44 -0500909
910static void
911vl_api_ipsec_sa_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
912{
Florin Coras6c4dae22018-01-09 06:39:23 -0800913 vl_api_registration_t *reg;
Matthew Smith28029532017-09-26 13:33:44 -0500914
Florin Coras6c4dae22018-01-09 06:39:23 -0800915 reg = vl_api_client_index_to_registration (mp->client_index);
Neale Ranns12989b52019-09-26 16:20:19 +0000916 if (!reg)
Matthew Smith28029532017-09-26 13:33:44 -0500917 return;
918
Neale Ranns12989b52019-09-26 16:20:19 +0000919 ipsec_dump_walk_ctx_t ctx = {
920 .reg = reg,
921 .context = mp->context,
922 };
Matthew Smith28029532017-09-26 13:33:44 -0500923
Neale Ranns12989b52019-09-26 16:20:19 +0000924 ipsec_sa_walk (send_ipsec_sa_details, &ctx);
Matthew Smith28029532017-09-26 13:33:44 -0500925}
926
Neale Ranns041add72020-01-02 04:06:10 +0000927static walk_rc_t
928send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg)
929{
930 ipsec_dump_walk_ctx_t *ctx = arg;
931 vl_api_ipsec_sa_v2_details_t *mp;
Neale Ranns041add72020-01-02 04:06:10 +0000932
933 mp = vl_msg_api_alloc (sizeof (*mp));
934 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000935 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_V2_DETAILS);
Neale Ranns041add72020-01-02 04:06:10 +0000936 mp->context = ctx->context;
937
938 mp->entry.sad_id = htonl (sa->id);
939 mp->entry.spi = htonl (sa->spi);
940 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000941 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
Neale Ranns041add72020-01-02 04:06:10 +0000942
943 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
944 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
945
946 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
947 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
948
949 mp->entry.flags = ipsec_sad_flags_encode (sa);
950 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
951
952 if (ipsec_sa_is_set_IS_PROTECT (sa))
953 {
954 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000955 .sai = sa - ipsec_sa_pool,
956 .sw_if_index = ~0,
Neale Ranns041add72020-01-02 04:06:10 +0000957 };
958 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
959
960 mp->sw_if_index = htonl (ctx.sw_if_index);
961 }
962 else
963 mp->sw_if_index = ~0;
964
965 if (ipsec_sa_is_set_IS_TUNNEL (sa))
966 {
Neale Ranns9ec846c2021-02-09 14:04:02 +0000967 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
968 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
Neale Ranns041add72020-01-02 04:06:10 +0000969 }
970 if (ipsec_sa_is_set_UDP_ENCAP (sa))
971 {
972 mp->entry.udp_src_port = sa->udp_hdr.src_port;
973 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
974 }
975
Neale Ranns9ec846c2021-02-09 14:04:02 +0000976 mp->entry.tunnel_flags =
977 tunnel_encap_decap_flags_encode (sa->tunnel.t_encap_decap_flags);
978 mp->entry.dscp = ip_dscp_encode (sa->tunnel.t_dscp);
Neale Ranns041add72020-01-02 04:06:10 +0000979
980 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns5b891102021-06-28 13:31:28 +0000981 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns041add72020-01-02 04:06:10 +0000982 if (ipsec_sa_is_set_USE_ESN (sa))
983 {
984 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns5b891102021-06-28 13:31:28 +0000985 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns041add72020-01-02 04:06:10 +0000986 }
987 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
988 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
989
990 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
991
992 vl_api_send_msg (ctx->reg, (u8 *) mp);
993
994 return (WALK_CONTINUE);
995}
996
997static void
Neale Ranns9ec846c2021-02-09 14:04:02 +0000998vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_v2_dump_t *mp)
Neale Ranns041add72020-01-02 04:06:10 +0000999{
1000 vl_api_registration_t *reg;
1001
Neale Ranns041add72020-01-02 04:06:10 +00001002 reg = vl_api_client_index_to_registration (mp->client_index);
1003 if (!reg)
1004 return;
1005
1006 ipsec_dump_walk_ctx_t ctx = {
1007 .reg = reg,
1008 .context = mp->context,
1009 };
1010
1011 ipsec_sa_walk (send_ipsec_sa_v2_details, &ctx);
Neale Ranns041add72020-01-02 04:06:10 +00001012}
1013
Neale Ranns9ec846c2021-02-09 14:04:02 +00001014static walk_rc_t
1015send_ipsec_sa_v3_details (ipsec_sa_t *sa, void *arg)
1016{
1017 ipsec_dump_walk_ctx_t *ctx = arg;
1018 vl_api_ipsec_sa_v3_details_t *mp;
Neale Ranns9ec846c2021-02-09 14:04:02 +00001019
1020 mp = vl_msg_api_alloc (sizeof (*mp));
1021 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +00001022 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_V3_DETAILS);
Neale Ranns9ec846c2021-02-09 14:04:02 +00001023 mp->context = ctx->context;
1024
1025 mp->entry.sad_id = htonl (sa->id);
1026 mp->entry.spi = htonl (sa->spi);
1027 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
1028
1029 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
1030 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
1031
1032 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
1033 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
1034
1035 mp->entry.flags = ipsec_sad_flags_encode (sa);
1036 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
1037
1038 if (ipsec_sa_is_set_IS_PROTECT (sa))
1039 {
1040 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +00001041 .sai = sa - ipsec_sa_pool,
Neale Ranns9ec846c2021-02-09 14:04:02 +00001042 .sw_if_index = ~0,
1043 };
1044 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
1045
1046 mp->sw_if_index = htonl (ctx.sw_if_index);
1047 }
1048 else
1049 mp->sw_if_index = ~0;
1050
1051 if (ipsec_sa_is_set_IS_TUNNEL (sa))
1052 tunnel_encode (&sa->tunnel, &mp->entry.tunnel);
1053
1054 if (ipsec_sa_is_set_UDP_ENCAP (sa))
1055 {
1056 mp->entry.udp_src_port = sa->udp_hdr.src_port;
1057 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
1058 }
1059
1060 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns5b891102021-06-28 13:31:28 +00001061 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns9ec846c2021-02-09 14:04:02 +00001062 if (ipsec_sa_is_set_USE_ESN (sa))
1063 {
1064 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns5b891102021-06-28 13:31:28 +00001065 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns9ec846c2021-02-09 14:04:02 +00001066 }
1067 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
1068 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
1069
1070 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
1071
1072 vl_api_send_msg (ctx->reg, (u8 *) mp);
1073
1074 return (WALK_CONTINUE);
1075}
1076
1077static void
1078vl_api_ipsec_sa_v3_dump_t_handler (vl_api_ipsec_sa_v3_dump_t *mp)
1079{
1080 vl_api_registration_t *reg;
1081
Neale Ranns9ec846c2021-02-09 14:04:02 +00001082 reg = vl_api_client_index_to_registration (mp->client_index);
1083 if (!reg)
1084 return;
1085
1086 ipsec_dump_walk_ctx_t ctx = {
1087 .reg = reg,
1088 .context = mp->context,
1089 };
1090
1091 ipsec_sa_walk (send_ipsec_sa_v3_details, &ctx);
Neale Ranns9ec846c2021-02-09 14:04:02 +00001092}
1093
Matthew Smith75d85602017-10-05 19:03:05 -05001094static void
Klement Sekerab4d30532018-11-08 13:00:02 +01001095vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp)
1096{
1097 vl_api_registration_t *rp;
1098 ipsec_main_t *im = &ipsec_main;
1099 u32 context = mp->context;
1100
1101 rp = vl_api_client_index_to_registration (mp->client_index);
1102
1103 if (rp == 0)
1104 {
1105 clib_warning ("Client %d AWOL", mp->client_index);
1106 return;
1107 }
1108
1109 ipsec_ah_backend_t *ab;
1110 ipsec_esp_backend_t *eb;
1111 /* *INDENT-OFF* */
Damjan Marionb2c31b62020-12-13 21:47:40 +01001112 pool_foreach (ab, im->ah_backends) {
Klement Sekerab4d30532018-11-08 13:00:02 +01001113 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1114 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +00001115 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_BACKEND_DETAILS);
Klement Sekerab4d30532018-11-08 13:00:02 +01001116 mp->context = context;
1117 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (ab->name),
1118 ab->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001119 mp->protocol = ntohl (IPSEC_API_PROTO_AH);
Klement Sekerab4d30532018-11-08 13:00:02 +01001120 mp->index = ab - im->ah_backends;
1121 mp->active = mp->index == im->ah_current_backend ? 1 : 0;
1122 vl_api_send_msg (rp, (u8 *)mp);
Damjan Marionb2c31b62020-12-13 21:47:40 +01001123 }
1124 pool_foreach (eb, im->esp_backends) {
Klement Sekerab4d30532018-11-08 13:00:02 +01001125 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1126 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +00001127 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_BACKEND_DETAILS);
Klement Sekerab4d30532018-11-08 13:00:02 +01001128 mp->context = context;
1129 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (eb->name),
1130 eb->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001131 mp->protocol = ntohl (IPSEC_API_PROTO_ESP);
Klement Sekerab4d30532018-11-08 13:00:02 +01001132 mp->index = eb - im->esp_backends;
1133 mp->active = mp->index == im->esp_current_backend ? 1 : 0;
1134 vl_api_send_msg (rp, (u8 *)mp);
Damjan Marionb2c31b62020-12-13 21:47:40 +01001135 }
Klement Sekerab4d30532018-11-08 13:00:02 +01001136 /* *INDENT-ON* */
1137}
1138
1139static void
1140vl_api_ipsec_select_backend_t_handler (vl_api_ipsec_select_backend_t * mp)
1141{
1142 ipsec_main_t *im = &ipsec_main;
1143 vl_api_ipsec_select_backend_reply_t *rmp;
Neale Ranns17dcec02019-01-09 21:22:20 -08001144 ipsec_protocol_t protocol;
Klement Sekerab4d30532018-11-08 13:00:02 +01001145 int rv = 0;
Neale Rannsc5fe57d2021-02-25 16:01:28 +00001146 if (pool_elts (ipsec_sa_pool) > 0)
Klement Sekerab4d30532018-11-08 13:00:02 +01001147 {
1148 rv = VNET_API_ERROR_INSTANCE_IN_USE;
1149 goto done;
1150 }
Neale Ranns17dcec02019-01-09 21:22:20 -08001151
1152 rv = ipsec_proto_decode (mp->protocol, &protocol);
1153
1154 if (rv)
1155 goto done;
1156
Neale Ranns17dcec02019-01-09 21:22:20 -08001157 switch (protocol)
Klement Sekerab4d30532018-11-08 13:00:02 +01001158 {
1159 case IPSEC_PROTOCOL_ESP:
Neale Rannse8915fc2019-04-23 20:57:55 -04001160 rv = ipsec_select_esp_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001161 break;
1162 case IPSEC_PROTOCOL_AH:
Neale Rannse8915fc2019-04-23 20:57:55 -04001163 rv = ipsec_select_ah_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001164 break;
1165 default:
Neale Rannse8915fc2019-04-23 20:57:55 -04001166 rv = VNET_API_ERROR_INVALID_PROTOCOL;
Klement Sekerab4d30532018-11-08 13:00:02 +01001167 break;
1168 }
Klement Sekerab4d30532018-11-08 13:00:02 +01001169done:
1170 REPLY_MACRO (VL_API_IPSEC_SELECT_BACKEND_REPLY);
1171}
1172
Yulong Pei2e84d662020-08-14 18:21:08 +08001173static void
1174vl_api_ipsec_set_async_mode_t_handler (vl_api_ipsec_set_async_mode_t * mp)
1175{
1176 vl_api_ipsec_set_async_mode_reply_t *rmp;
1177 int rv = 0;
1178
Yulong Pei2e84d662020-08-14 18:21:08 +08001179 ipsec_set_async_mode (mp->async_enable);
1180
1181 REPLY_MACRO (VL_API_IPSEC_SET_ASYNC_MODE_REPLY);
1182}
1183
Filip Tehlarc73f3292021-06-22 08:21:31 +00001184#include <vnet/ipsec/ipsec.api.c>
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001185static clib_error_t *
1186ipsec_api_hookup (vlib_main_t * vm)
1187{
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001188 /*
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001189 * Set up the (msg_name, crc, message-id) table
1190 */
Filip Tehlarc73f3292021-06-22 08:21:31 +00001191 REPLY_MSG_ID_BASE = setup_message_id_table ();
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001192
1193 return 0;
1194}
1195
1196VLIB_API_INIT_FUNCTION (ipsec_api_hookup);
1197
1198/*
1199 * fd.io coding-style-patch-verification: ON
1200 *
1201 * Local Variables:
1202 * eval: (c-set-style "gnu")
1203 * End:
1204 */