blob: 3994150d895a10d585363bc6e232fe2dfe93bc74 [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:
Vratko Polak520cde42022-11-25 17:10:10 +0100330 REPLY_MACRO2 (VL_API_IPSEC_SPD_ENTRY_ADD_DEL_V2_REPLY,
Piotr Bronowski815c6a42022-06-09 09:09:28 +0000331 ({ 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
Arthur de Kerhor4117b242022-08-31 19:13:03 +0200571vl_api_ipsec_sad_entry_update_t_handler (vl_api_ipsec_sad_entry_update_t *mp)
572{
573 vl_api_ipsec_sad_entry_update_reply_t *rmp;
574 u32 id;
575 tunnel_t tun = { 0 };
576 int rv;
577
578 id = ntohl (mp->sad_id);
579
580 if (mp->is_tun)
581 {
582 rv = tunnel_decode (&mp->tunnel, &tun);
583
584 if (rv)
585 goto out;
586 }
587
588 rv = ipsec_sa_update (id, htons (mp->udp_src_port), htons (mp->udp_dst_port),
589 &tun, mp->is_tun);
590
591out:
592 REPLY_MACRO (VL_API_IPSEC_SAD_ENTRY_UPDATE_REPLY);
593}
594
595static void
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700596send_ipsec_spds_details (ipsec_spd_t * spd, vl_api_registration_t * reg,
597 u32 context)
598{
599 vl_api_ipsec_spds_details_t *mp;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800600 u32 n_policies = 0;
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700601
602 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400603 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000604 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SPDS_DETAILS);
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700605 mp->context = context;
606
607 mp->spd_id = htonl (spd->id);
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800608#define _(s, n) n_policies += vec_len (spd->policies[IPSEC_SPD_POLICY_##s]);
609 foreach_ipsec_spd_policy_type
610#undef _
611 mp->npolicies = htonl (n_policies);
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700612
613 vl_api_send_msg (reg, (u8 *) mp);
614}
615
616static void
617vl_api_ipsec_spds_dump_t_handler (vl_api_ipsec_spds_dump_t * mp)
618{
619 vl_api_registration_t *reg;
620 ipsec_main_t *im = &ipsec_main;
621 ipsec_spd_t *spd;
Damjan Marion97898982021-04-19 18:15:31 +0200622
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700623 reg = vl_api_client_index_to_registration (mp->client_index);
624 if (!reg)
625 return;
626
Damjan Marionb2c31b62020-12-13 21:47:40 +0100627 pool_foreach (spd, im->spds) {
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700628 send_ipsec_spds_details (spd, reg, mp->context);
Damjan Marionb2c31b62020-12-13 21:47:40 +0100629 }
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700630}
631
Neale Ranns17dcec02019-01-09 21:22:20 -0800632vl_api_ipsec_spd_action_t
633ipsec_spd_action_encode (ipsec_policy_action_t in)
634{
635 vl_api_ipsec_spd_action_t out = IPSEC_API_SPD_ACTION_BYPASS;
636
637 switch (in)
638 {
639#define _(v,f,s) case IPSEC_POLICY_ACTION_##f: \
640 out = IPSEC_API_SPD_ACTION_##f; \
641 break;
642 foreach_ipsec_policy_action
643#undef _
644 }
645 return (clib_host_to_net_u32 (out));
646}
647
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700648static void
Florin Coras6c4dae22018-01-09 06:39:23 -0800649send_ipsec_spd_details (ipsec_policy_t * p, vl_api_registration_t * reg,
650 u32 context)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100651{
652 vl_api_ipsec_spd_details_t *mp;
653
654 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400655 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000656 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SPD_DETAILS);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100657 mp->context = context;
658
Neale Ranns17dcec02019-01-09 21:22:20 -0800659 mp->entry.spd_id = htonl (p->id);
660 mp->entry.priority = htonl (p->priority);
Neale Ranns9f231d42019-03-19 10:06:00 +0000661 mp->entry.is_outbound = ((p->type == IPSEC_SPD_POLICY_IP6_OUTBOUND) ||
662 (p->type == IPSEC_SPD_POLICY_IP4_OUTBOUND));
Neale Ranns17dcec02019-01-09 21:22:20 -0800663
664 ip_address_encode (&p->laddr.start, IP46_TYPE_ANY,
665 &mp->entry.local_address_start);
666 ip_address_encode (&p->laddr.stop, IP46_TYPE_ANY,
667 &mp->entry.local_address_stop);
668 ip_address_encode (&p->raddr.start, IP46_TYPE_ANY,
669 &mp->entry.remote_address_start);
670 ip_address_encode (&p->raddr.stop, IP46_TYPE_ANY,
671 &mp->entry.remote_address_stop);
Neale Rannsa4d24312019-07-10 13:46:21 +0000672 mp->entry.local_port_start = htons (p->lport.start);
673 mp->entry.local_port_stop = htons (p->lport.stop);
674 mp->entry.remote_port_start = htons (p->rport.start);
675 mp->entry.remote_port_stop = htons (p->rport.stop);
Neale Ranns17dcec02019-01-09 21:22:20 -0800676 mp->entry.protocol = p->protocol;
677 mp->entry.policy = ipsec_spd_action_encode (p->policy);
678 mp->entry.sa_id = htonl (p->sa_id);
679
Florin Coras6c4dae22018-01-09 06:39:23 -0800680 vl_api_send_msg (reg, (u8 *) mp);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100681}
682
683static void
684vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp)
685{
Florin Coras6c4dae22018-01-09 06:39:23 -0800686 vl_api_registration_t *reg;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100687 ipsec_main_t *im = &ipsec_main;
Neale Ranns9f231d42019-03-19 10:06:00 +0000688 ipsec_spd_policy_type_t ptype;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100689 ipsec_policy_t *policy;
690 ipsec_spd_t *spd;
691 uword *p;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800692 u32 spd_index, *ii;
Damjan Marion97898982021-04-19 18:15:31 +0200693
Florin Coras6c4dae22018-01-09 06:39:23 -0800694 reg = vl_api_client_index_to_registration (mp->client_index);
695 if (!reg)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100696 return;
697
698 p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id));
699 if (!p)
700 return;
701
702 spd_index = p[0];
703 spd = pool_elt_at_index (im->spds, spd_index);
704
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800705 FOR_EACH_IPSEC_SPD_POLICY_TYPE(ptype) {
706 vec_foreach(ii, spd->policies[ptype])
707 {
708 policy = pool_elt_at_index(im->policies, *ii);
709
710 if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id)
711 send_ipsec_spd_details (policy, reg, mp->context);
712 }
713 }
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100714}
715
716static void
Filip Varga871bca92018-11-02 13:51:44 +0100717send_ipsec_spd_interface_details (vl_api_registration_t * reg, u32 spd_index,
718 u32 sw_if_index, u32 context)
719{
720 vl_api_ipsec_spd_interface_details_t *mp;
721
722 mp = vl_msg_api_alloc (sizeof (*mp));
723 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000724 mp->_vl_msg_id =
725 ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SPD_INTERFACE_DETAILS);
Filip Varga871bca92018-11-02 13:51:44 +0100726 mp->context = context;
727
728 mp->spd_index = htonl (spd_index);
729 mp->sw_if_index = htonl (sw_if_index);
730
731 vl_api_send_msg (reg, (u8 *) mp);
732}
733
734static void
735vl_api_ipsec_spd_interface_dump_t_handler (vl_api_ipsec_spd_interface_dump_t *
736 mp)
737{
738 ipsec_main_t *im = &ipsec_main;
739 vl_api_registration_t *reg;
740 u32 k, v, spd_index;
741
Filip Varga871bca92018-11-02 13:51:44 +0100742 reg = vl_api_client_index_to_registration (mp->client_index);
743 if (!reg)
744 return;
745
746 if (mp->spd_index_valid)
747 {
748 spd_index = ntohl (mp->spd_index);
749 /* *INDENT-OFF* */
750 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
751 if (v == spd_index)
752 send_ipsec_spd_interface_details(reg, v, k, mp->context);
753 }));
754 /* *INDENT-ON* */
755 }
756 else
757 {
Filip Varga871bca92018-11-02 13:51:44 +0100758 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
759 send_ipsec_spd_interface_details(reg, v, k, mp->context);
760 }));
Filip Varga871bca92018-11-02 13:51:44 +0100761 }
Filip Varga871bca92018-11-02 13:51:44 +0100762}
763
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000764static void
765vl_api_ipsec_itf_create_t_handler (vl_api_ipsec_itf_create_t * mp)
766{
767 vl_api_ipsec_itf_create_reply_t *rmp;
768 tunnel_mode_t mode;
769 u32 sw_if_index = ~0;
770 int rv;
771
772 rv = tunnel_mode_decode (mp->itf.mode, &mode);
773
774 if (!rv)
775 rv = ipsec_itf_create (ntohl (mp->itf.user_instance), mode, &sw_if_index);
776
777 /* *INDENT-OFF* */
778 REPLY_MACRO2 (VL_API_IPSEC_ITF_CREATE_REPLY,
779 ({
780 rmp->sw_if_index = htonl (sw_if_index);
781 }));
782 /* *INDENT-ON* */
783}
784
785static void
786vl_api_ipsec_itf_delete_t_handler (vl_api_ipsec_itf_delete_t * mp)
787{
788 vl_api_ipsec_itf_delete_reply_t *rmp;
789 int rv;
790
791 rv = ipsec_itf_delete (ntohl (mp->sw_if_index));
792
793 REPLY_MACRO (VL_API_IPSEC_ITF_DELETE_REPLY);
794}
795
Neale Ranns89d939e2021-06-07 09:34:07 +0000796static walk_rc_t
797send_ipsec_itf_details (ipsec_itf_t *itf, void *arg)
798{
799 ipsec_dump_walk_ctx_t *ctx = arg;
800 vl_api_ipsec_itf_details_t *mp;
801
Neale Rannsbed9b722021-10-22 14:10:06 +0000802 if (~0 != ctx->sw_if_index && ctx->sw_if_index != itf->ii_sw_if_index)
803 return (WALK_CONTINUE);
804
Neale Ranns89d939e2021-06-07 09:34:07 +0000805 mp = vl_msg_api_alloc (sizeof (*mp));
806 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000807 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_ITF_DETAILS);
Neale Ranns89d939e2021-06-07 09:34:07 +0000808 mp->context = ctx->context;
809
810 mp->itf.mode = tunnel_mode_encode (itf->ii_mode);
811 mp->itf.user_instance = htonl (itf->ii_user_instance);
812 mp->itf.sw_if_index = htonl (itf->ii_sw_if_index);
813 vl_api_send_msg (ctx->reg, (u8 *) mp);
814
815 return (WALK_CONTINUE);
816}
817
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000818static void
819vl_api_ipsec_itf_dump_t_handler (vl_api_ipsec_itf_dump_t * mp)
820{
Neale Ranns89d939e2021-06-07 09:34:07 +0000821 vl_api_registration_t *reg;
822
823 reg = vl_api_client_index_to_registration (mp->client_index);
824 if (!reg)
825 return;
826
827 ipsec_dump_walk_ctx_t ctx = {
828 .reg = reg,
829 .context = mp->context,
Neale Rannsbed9b722021-10-22 14:10:06 +0000830 .sw_if_index = ntohl (mp->sw_if_index),
Neale Ranns89d939e2021-06-07 09:34:07 +0000831 };
832
833 ipsec_itf_walk (send_ipsec_itf_details, &ctx);
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000834}
835
Neale Ranns12989b52019-09-26 16:20:19 +0000836typedef struct ipsec_sa_dump_match_ctx_t_
Matthew Smith28029532017-09-26 13:33:44 -0500837{
Neale Ranns12989b52019-09-26 16:20:19 +0000838 index_t sai;
839 u32 sw_if_index;
840} ipsec_sa_dump_match_ctx_t;
841
842static walk_rc_t
843ipsec_sa_dump_match_sa (index_t itpi, void *arg)
844{
845 ipsec_sa_dump_match_ctx_t *ctx = arg;
846 ipsec_tun_protect_t *itp;
847 index_t sai;
848
849 itp = ipsec_tun_protect_get (itpi);
850
851 if (itp->itp_out_sa == ctx->sai)
852 {
853 ctx->sw_if_index = itp->itp_sw_if_index;
854 return (WALK_STOP);
855 }
Damjan Marion97898982021-04-19 18:15:31 +0200856
Neale Ranns12989b52019-09-26 16:20:19 +0000857 FOR_EACH_IPSEC_PROTECT_INPUT_SAI (itp, sai,
858 ({
859 if (sai == ctx->sai)
860 {
861 ctx->sw_if_index = itp->itp_sw_if_index;
862 return (WALK_STOP);
863 }
864 }));
Neale Ranns12989b52019-09-26 16:20:19 +0000865
866 return (WALK_CONTINUE);
867}
868
869static walk_rc_t
870send_ipsec_sa_details (ipsec_sa_t * sa, void *arg)
871{
872 ipsec_dump_walk_ctx_t *ctx = arg;
Matthew Smith28029532017-09-26 13:33:44 -0500873 vl_api_ipsec_sa_details_t *mp;
874
875 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400876 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000877 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_DETAILS);
Neale Ranns12989b52019-09-26 16:20:19 +0000878 mp->context = ctx->context;
Matthew Smith28029532017-09-26 13:33:44 -0500879
Neale Ranns8d7c5022019-02-06 01:41:05 -0800880 mp->entry.sad_id = htonl (sa->id);
881 mp->entry.spi = htonl (sa->spi);
882 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000883 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
Matthew Smith28029532017-09-26 13:33:44 -0500884
Neale Ranns8d7c5022019-02-06 01:41:05 -0800885 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
886 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
Matthew Smith28029532017-09-26 13:33:44 -0500887
Neale Ranns8d7c5022019-02-06 01:41:05 -0800888 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
889 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
Matthew Smith28029532017-09-26 13:33:44 -0500890
Neale Ranns8d7c5022019-02-06 01:41:05 -0800891 mp->entry.flags = ipsec_sad_flags_encode (sa);
Neale Ranns12989b52019-09-26 16:20:19 +0000892 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
893
894 if (ipsec_sa_is_set_IS_PROTECT (sa))
895 {
896 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000897 .sai = sa - ipsec_sa_pool,
898 .sw_if_index = ~0,
Neale Ranns12989b52019-09-26 16:20:19 +0000899 };
900 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
901
902 mp->sw_if_index = htonl (ctx.sw_if_index);
903 }
904 else
905 mp->sw_if_index = ~0;
Matthew Smith28029532017-09-26 13:33:44 -0500906
Damjan Mariond709cbc2019-03-26 13:16:42 +0100907 if (ipsec_sa_is_set_IS_TUNNEL (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500908 {
Neale Ranns9ec846c2021-02-09 14:04:02 +0000909 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
910 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -0500911 }
Neale Rannsabc56602020-04-01 09:45:23 +0000912 if (ipsec_sa_is_set_UDP_ENCAP (sa))
913 {
914 mp->entry.udp_src_port = sa->udp_hdr.src_port;
915 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
916 }
Matthew Smith28029532017-09-26 13:33:44 -0500917
Matthew Smith28029532017-09-26 13:33:44 -0500918 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns5b891102021-06-28 13:31:28 +0000919 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
Damjan Marion1e3aa5e2019-03-28 10:58:59 +0100920 if (ipsec_sa_is_set_USE_ESN (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500921 {
922 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns5b891102021-06-28 13:31:28 +0000923 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Matthew Smith28029532017-09-26 13:33:44 -0500924 }
Damjan Mariond709cbc2019-03-26 13:16:42 +0100925 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500926 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
Pierre Pfister4c422f92018-12-10 11:19:08 +0100927
Matthew Smith48d32b42020-04-02 07:45:49 -0500928 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
929
Neale Ranns12989b52019-09-26 16:20:19 +0000930 vl_api_send_msg (ctx->reg, (u8 *) mp);
Matthew Smith28029532017-09-26 13:33:44 -0500931
Neale Ranns12989b52019-09-26 16:20:19 +0000932 return (WALK_CONTINUE);
933}
Matthew Smith28029532017-09-26 13:33:44 -0500934
935static void
936vl_api_ipsec_sa_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
937{
Florin Coras6c4dae22018-01-09 06:39:23 -0800938 vl_api_registration_t *reg;
Matthew Smith28029532017-09-26 13:33:44 -0500939
Florin Coras6c4dae22018-01-09 06:39:23 -0800940 reg = vl_api_client_index_to_registration (mp->client_index);
Neale Ranns12989b52019-09-26 16:20:19 +0000941 if (!reg)
Matthew Smith28029532017-09-26 13:33:44 -0500942 return;
943
Neale Ranns12989b52019-09-26 16:20:19 +0000944 ipsec_dump_walk_ctx_t ctx = {
945 .reg = reg,
946 .context = mp->context,
947 };
Matthew Smith28029532017-09-26 13:33:44 -0500948
Neale Ranns12989b52019-09-26 16:20:19 +0000949 ipsec_sa_walk (send_ipsec_sa_details, &ctx);
Matthew Smith28029532017-09-26 13:33:44 -0500950}
951
Neale Ranns041add72020-01-02 04:06:10 +0000952static walk_rc_t
953send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg)
954{
955 ipsec_dump_walk_ctx_t *ctx = arg;
956 vl_api_ipsec_sa_v2_details_t *mp;
Neale Ranns041add72020-01-02 04:06:10 +0000957
958 mp = vl_msg_api_alloc (sizeof (*mp));
959 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000960 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_V2_DETAILS);
Neale Ranns041add72020-01-02 04:06:10 +0000961 mp->context = ctx->context;
962
963 mp->entry.sad_id = htonl (sa->id);
964 mp->entry.spi = htonl (sa->spi);
965 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000966 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
Neale Ranns041add72020-01-02 04:06:10 +0000967
968 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
969 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
970
971 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
972 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
973
974 mp->entry.flags = ipsec_sad_flags_encode (sa);
975 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
976
977 if (ipsec_sa_is_set_IS_PROTECT (sa))
978 {
979 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000980 .sai = sa - ipsec_sa_pool,
981 .sw_if_index = ~0,
Neale Ranns041add72020-01-02 04:06:10 +0000982 };
983 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
984
985 mp->sw_if_index = htonl (ctx.sw_if_index);
986 }
987 else
988 mp->sw_if_index = ~0;
989
990 if (ipsec_sa_is_set_IS_TUNNEL (sa))
991 {
Neale Ranns9ec846c2021-02-09 14:04:02 +0000992 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
993 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
Neale Ranns041add72020-01-02 04:06:10 +0000994 }
995 if (ipsec_sa_is_set_UDP_ENCAP (sa))
996 {
997 mp->entry.udp_src_port = sa->udp_hdr.src_port;
998 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
999 }
1000
Neale Ranns9ec846c2021-02-09 14:04:02 +00001001 mp->entry.tunnel_flags =
1002 tunnel_encap_decap_flags_encode (sa->tunnel.t_encap_decap_flags);
1003 mp->entry.dscp = ip_dscp_encode (sa->tunnel.t_dscp);
Neale Ranns041add72020-01-02 04:06:10 +00001004
1005 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns5b891102021-06-28 13:31:28 +00001006 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns041add72020-01-02 04:06:10 +00001007 if (ipsec_sa_is_set_USE_ESN (sa))
1008 {
1009 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns5b891102021-06-28 13:31:28 +00001010 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns041add72020-01-02 04:06:10 +00001011 }
1012 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
1013 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
1014
1015 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
1016
1017 vl_api_send_msg (ctx->reg, (u8 *) mp);
1018
1019 return (WALK_CONTINUE);
1020}
1021
1022static void
Neale Ranns9ec846c2021-02-09 14:04:02 +00001023vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_v2_dump_t *mp)
Neale Ranns041add72020-01-02 04:06:10 +00001024{
1025 vl_api_registration_t *reg;
1026
Neale Ranns041add72020-01-02 04:06:10 +00001027 reg = vl_api_client_index_to_registration (mp->client_index);
1028 if (!reg)
1029 return;
1030
1031 ipsec_dump_walk_ctx_t ctx = {
1032 .reg = reg,
1033 .context = mp->context,
1034 };
1035
1036 ipsec_sa_walk (send_ipsec_sa_v2_details, &ctx);
Neale Ranns041add72020-01-02 04:06:10 +00001037}
1038
Neale Ranns9ec846c2021-02-09 14:04:02 +00001039static walk_rc_t
1040send_ipsec_sa_v3_details (ipsec_sa_t *sa, void *arg)
1041{
1042 ipsec_dump_walk_ctx_t *ctx = arg;
1043 vl_api_ipsec_sa_v3_details_t *mp;
Neale Ranns9ec846c2021-02-09 14:04:02 +00001044
1045 mp = vl_msg_api_alloc (sizeof (*mp));
1046 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +00001047 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_V3_DETAILS);
Neale Ranns9ec846c2021-02-09 14:04:02 +00001048 mp->context = ctx->context;
1049
1050 mp->entry.sad_id = htonl (sa->id);
1051 mp->entry.spi = htonl (sa->spi);
1052 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
1053
1054 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
1055 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
1056
1057 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
1058 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
1059
1060 mp->entry.flags = ipsec_sad_flags_encode (sa);
1061 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
1062
1063 if (ipsec_sa_is_set_IS_PROTECT (sa))
1064 {
1065 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +00001066 .sai = sa - ipsec_sa_pool,
Neale Ranns9ec846c2021-02-09 14:04:02 +00001067 .sw_if_index = ~0,
1068 };
1069 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
1070
1071 mp->sw_if_index = htonl (ctx.sw_if_index);
1072 }
1073 else
1074 mp->sw_if_index = ~0;
1075
1076 if (ipsec_sa_is_set_IS_TUNNEL (sa))
1077 tunnel_encode (&sa->tunnel, &mp->entry.tunnel);
1078
1079 if (ipsec_sa_is_set_UDP_ENCAP (sa))
1080 {
1081 mp->entry.udp_src_port = sa->udp_hdr.src_port;
1082 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
1083 }
1084
1085 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns5b891102021-06-28 13:31:28 +00001086 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns9ec846c2021-02-09 14:04:02 +00001087 if (ipsec_sa_is_set_USE_ESN (sa))
1088 {
1089 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns5b891102021-06-28 13:31:28 +00001090 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns9ec846c2021-02-09 14:04:02 +00001091 }
1092 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
1093 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
1094
1095 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
1096
1097 vl_api_send_msg (ctx->reg, (u8 *) mp);
1098
1099 return (WALK_CONTINUE);
1100}
1101
1102static void
1103vl_api_ipsec_sa_v3_dump_t_handler (vl_api_ipsec_sa_v3_dump_t *mp)
1104{
1105 vl_api_registration_t *reg;
1106
Neale Ranns9ec846c2021-02-09 14:04:02 +00001107 reg = vl_api_client_index_to_registration (mp->client_index);
1108 if (!reg)
1109 return;
1110
1111 ipsec_dump_walk_ctx_t ctx = {
1112 .reg = reg,
1113 .context = mp->context,
1114 };
1115
1116 ipsec_sa_walk (send_ipsec_sa_v3_details, &ctx);
Neale Ranns9ec846c2021-02-09 14:04:02 +00001117}
1118
Matthew Smith75d85602017-10-05 19:03:05 -05001119static void
Klement Sekerab4d30532018-11-08 13:00:02 +01001120vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp)
1121{
1122 vl_api_registration_t *rp;
1123 ipsec_main_t *im = &ipsec_main;
1124 u32 context = mp->context;
1125
1126 rp = vl_api_client_index_to_registration (mp->client_index);
1127
1128 if (rp == 0)
1129 {
1130 clib_warning ("Client %d AWOL", mp->client_index);
1131 return;
1132 }
1133
1134 ipsec_ah_backend_t *ab;
1135 ipsec_esp_backend_t *eb;
1136 /* *INDENT-OFF* */
Damjan Marionb2c31b62020-12-13 21:47:40 +01001137 pool_foreach (ab, im->ah_backends) {
Klement Sekerab4d30532018-11-08 13:00:02 +01001138 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1139 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +00001140 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_BACKEND_DETAILS);
Klement Sekerab4d30532018-11-08 13:00:02 +01001141 mp->context = context;
1142 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (ab->name),
1143 ab->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001144 mp->protocol = ntohl (IPSEC_API_PROTO_AH);
Klement Sekerab4d30532018-11-08 13:00:02 +01001145 mp->index = ab - im->ah_backends;
1146 mp->active = mp->index == im->ah_current_backend ? 1 : 0;
1147 vl_api_send_msg (rp, (u8 *)mp);
Damjan Marionb2c31b62020-12-13 21:47:40 +01001148 }
1149 pool_foreach (eb, im->esp_backends) {
Klement Sekerab4d30532018-11-08 13:00:02 +01001150 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1151 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +00001152 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_BACKEND_DETAILS);
Klement Sekerab4d30532018-11-08 13:00:02 +01001153 mp->context = context;
1154 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (eb->name),
1155 eb->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001156 mp->protocol = ntohl (IPSEC_API_PROTO_ESP);
Klement Sekerab4d30532018-11-08 13:00:02 +01001157 mp->index = eb - im->esp_backends;
1158 mp->active = mp->index == im->esp_current_backend ? 1 : 0;
1159 vl_api_send_msg (rp, (u8 *)mp);
Damjan Marionb2c31b62020-12-13 21:47:40 +01001160 }
Klement Sekerab4d30532018-11-08 13:00:02 +01001161 /* *INDENT-ON* */
1162}
1163
1164static void
1165vl_api_ipsec_select_backend_t_handler (vl_api_ipsec_select_backend_t * mp)
1166{
1167 ipsec_main_t *im = &ipsec_main;
1168 vl_api_ipsec_select_backend_reply_t *rmp;
Neale Ranns17dcec02019-01-09 21:22:20 -08001169 ipsec_protocol_t protocol;
Klement Sekerab4d30532018-11-08 13:00:02 +01001170 int rv = 0;
Neale Rannsc5fe57d2021-02-25 16:01:28 +00001171 if (pool_elts (ipsec_sa_pool) > 0)
Klement Sekerab4d30532018-11-08 13:00:02 +01001172 {
1173 rv = VNET_API_ERROR_INSTANCE_IN_USE;
1174 goto done;
1175 }
Neale Ranns17dcec02019-01-09 21:22:20 -08001176
1177 rv = ipsec_proto_decode (mp->protocol, &protocol);
1178
1179 if (rv)
1180 goto done;
1181
Neale Ranns17dcec02019-01-09 21:22:20 -08001182 switch (protocol)
Klement Sekerab4d30532018-11-08 13:00:02 +01001183 {
1184 case IPSEC_PROTOCOL_ESP:
Neale Rannse8915fc2019-04-23 20:57:55 -04001185 rv = ipsec_select_esp_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001186 break;
1187 case IPSEC_PROTOCOL_AH:
Neale Rannse8915fc2019-04-23 20:57:55 -04001188 rv = ipsec_select_ah_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001189 break;
1190 default:
Neale Rannse8915fc2019-04-23 20:57:55 -04001191 rv = VNET_API_ERROR_INVALID_PROTOCOL;
Klement Sekerab4d30532018-11-08 13:00:02 +01001192 break;
1193 }
Klement Sekerab4d30532018-11-08 13:00:02 +01001194done:
1195 REPLY_MACRO (VL_API_IPSEC_SELECT_BACKEND_REPLY);
1196}
1197
Yulong Pei2e84d662020-08-14 18:21:08 +08001198static void
1199vl_api_ipsec_set_async_mode_t_handler (vl_api_ipsec_set_async_mode_t * mp)
1200{
1201 vl_api_ipsec_set_async_mode_reply_t *rmp;
1202 int rv = 0;
1203
Yulong Pei2e84d662020-08-14 18:21:08 +08001204 ipsec_set_async_mode (mp->async_enable);
1205
1206 REPLY_MACRO (VL_API_IPSEC_SET_ASYNC_MODE_REPLY);
1207}
1208
Filip Tehlarc73f3292021-06-22 08:21:31 +00001209#include <vnet/ipsec/ipsec.api.c>
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001210static clib_error_t *
1211ipsec_api_hookup (vlib_main_t * vm)
1212{
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001213 /*
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001214 * Set up the (msg_name, crc, message-id) table
1215 */
Filip Tehlarc73f3292021-06-22 08:21:31 +00001216 REPLY_MSG_ID_BASE = setup_message_id_table ();
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001217
1218 return 0;
1219}
1220
1221VLIB_API_INIT_FUNCTION (ipsec_api_hookup);
1222
1223/*
1224 * fd.io coding-style-patch-verification: ON
1225 *
1226 * Local Variables:
1227 * eval: (c-set-style "gnu")
1228 * End:
1229 */