blob: 6e7308ddf751caa554082bca845c9a7699a8d7bb [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
Maxime Peim0e2f1882022-12-22 11:26:57 +0000385 rv = ipsec_sa_add_and_lock (
386 id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
387 mp->entry.salt, htons (mp->entry.udp_src_port),
388 htons (mp->entry.udp_dst_port), 0, &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
Maxime Peim0e2f1882022-12-22 11:26:57 +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), 0, &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
Maxime Peim0e2f1882022-12-22 11:26:57 +0000517 return ipsec_sa_add_and_lock (
518 id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
519 entry->salt, htons (entry->udp_src_port), htons (entry->udp_dst_port), 0,
520 &tun, sa_index);
Neale Rannsff2e4132021-06-24 14:57:56 +0000521}
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
Maxime Peim0e2f1882022-12-22 11:26:57 +0000546static int
547ipsec_sad_entry_add_v4 (const vl_api_ipsec_sad_entry_v4_t *entry,
548 u32 *sa_index)
549{
550 ipsec_key_t crypto_key, integ_key;
551 ipsec_crypto_alg_t crypto_alg;
552 ipsec_integ_alg_t integ_alg;
553 ipsec_protocol_t proto;
554 ipsec_sa_flags_t flags;
555 u32 id, spi;
556 tunnel_t tun = { 0 };
557 int rv;
558
559 id = ntohl (entry->sad_id);
560 spi = ntohl (entry->spi);
561
562 rv = ipsec_proto_decode (entry->protocol, &proto);
563
564 if (rv)
565 return rv;
566
567 rv = ipsec_crypto_algo_decode (entry->crypto_algorithm, &crypto_alg);
568
569 if (rv)
570 return rv;
571
572 rv = ipsec_integ_algo_decode (entry->integrity_algorithm, &integ_alg);
573
574 if (rv)
575 return rv;
576
577 flags = ipsec_sa_flags_decode (entry->flags);
578
579 if (flags & IPSEC_SA_FLAG_IS_TUNNEL)
580 {
581 rv = tunnel_decode (&entry->tunnel, &tun);
582
583 if (rv)
584 return rv;
585 }
586
587 ipsec_key_decode (&entry->crypto_key, &crypto_key);
588 ipsec_key_decode (&entry->integrity_key, &integ_key);
589
590 return ipsec_sa_add_and_lock (
591 id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
592 entry->salt, htons (entry->udp_src_port), htons (entry->udp_dst_port),
593 ntohl (entry->anti_replay_window_size), &tun, sa_index);
594}
595
Neale Rannsc7eaa712021-02-04 11:09:33 +0000596static void
Neale Rannsff2e4132021-06-24 14:57:56 +0000597vl_api_ipsec_sad_entry_del_t_handler (vl_api_ipsec_sad_entry_del_t *mp)
598{
599 vl_api_ipsec_sad_entry_del_reply_t *rmp;
600 int rv;
601
602 rv = ipsec_sa_unlock_id (ntohl (mp->id));
603
604 REPLY_MACRO (VL_API_IPSEC_SAD_ENTRY_DEL_REPLY);
605}
606
607static void
608vl_api_ipsec_sad_entry_add_t_handler (vl_api_ipsec_sad_entry_add_t *mp)
609{
610 vl_api_ipsec_sad_entry_add_reply_t *rmp;
611 u32 sa_index = ~0;
612 int rv;
613
614 rv = ipsec_sad_entry_add_v3 (&mp->entry, &sa_index);
615
616 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_REPLY,
617 { rmp->stat_index = htonl (sa_index); });
618}
619
620static void
Maxime Peim0e2f1882022-12-22 11:26:57 +0000621vl_api_ipsec_sad_entry_add_v2_t_handler (vl_api_ipsec_sad_entry_add_v2_t *mp)
622{
623 vl_api_ipsec_sad_entry_add_reply_t *rmp;
624 u32 sa_index = ~0;
625 int rv;
626
627 rv = ipsec_sad_entry_add_v4 (&mp->entry, &sa_index);
628
629 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_V2_REPLY,
630 { rmp->stat_index = htonl (sa_index); });
631}
632
633static void
Arthur de Kerhor4117b242022-08-31 19:13:03 +0200634vl_api_ipsec_sad_entry_update_t_handler (vl_api_ipsec_sad_entry_update_t *mp)
635{
636 vl_api_ipsec_sad_entry_update_reply_t *rmp;
637 u32 id;
638 tunnel_t tun = { 0 };
639 int rv;
640
641 id = ntohl (mp->sad_id);
642
643 if (mp->is_tun)
644 {
645 rv = tunnel_decode (&mp->tunnel, &tun);
646
647 if (rv)
648 goto out;
649 }
650
651 rv = ipsec_sa_update (id, htons (mp->udp_src_port), htons (mp->udp_dst_port),
652 &tun, mp->is_tun);
653
654out:
655 REPLY_MACRO (VL_API_IPSEC_SAD_ENTRY_UPDATE_REPLY);
656}
657
658static void
Maxime Peim1271e3a2023-03-20 14:13:56 +0000659vl_api_ipsec_sad_bind_t_handler (vl_api_ipsec_sad_bind_t *mp)
660{
661 vl_api_ipsec_sad_bind_reply_t *rmp;
662 u32 sa_id;
663 u32 worker;
664 int rv;
665
666 sa_id = ntohl (mp->sa_id);
667 worker = ntohl (mp->worker);
668
669 rv = ipsec_sa_bind (sa_id, worker, true /* bind */);
670
671 REPLY_MACRO (VL_API_IPSEC_SAD_BIND_REPLY);
672}
673
674static void
675vl_api_ipsec_sad_unbind_t_handler (vl_api_ipsec_sad_unbind_t *mp)
676{
677 vl_api_ipsec_sad_unbind_reply_t *rmp;
678 u32 sa_id;
679 int rv;
680
681 sa_id = ntohl (mp->sa_id);
682
683 rv = ipsec_sa_bind (sa_id, ~0, false /* bind */);
684
685 REPLY_MACRO (VL_API_IPSEC_SAD_UNBIND_REPLY);
686}
687
688static void
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700689send_ipsec_spds_details (ipsec_spd_t * spd, vl_api_registration_t * reg,
690 u32 context)
691{
692 vl_api_ipsec_spds_details_t *mp;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800693 u32 n_policies = 0;
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700694
695 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400696 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000697 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SPDS_DETAILS);
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700698 mp->context = context;
699
700 mp->spd_id = htonl (spd->id);
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800701#define _(s, n) n_policies += vec_len (spd->policies[IPSEC_SPD_POLICY_##s]);
702 foreach_ipsec_spd_policy_type
703#undef _
704 mp->npolicies = htonl (n_policies);
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700705
706 vl_api_send_msg (reg, (u8 *) mp);
707}
708
709static void
710vl_api_ipsec_spds_dump_t_handler (vl_api_ipsec_spds_dump_t * mp)
711{
712 vl_api_registration_t *reg;
713 ipsec_main_t *im = &ipsec_main;
714 ipsec_spd_t *spd;
Damjan Marion97898982021-04-19 18:15:31 +0200715
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700716 reg = vl_api_client_index_to_registration (mp->client_index);
717 if (!reg)
718 return;
719
Damjan Marionb2c31b62020-12-13 21:47:40 +0100720 pool_foreach (spd, im->spds) {
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700721 send_ipsec_spds_details (spd, reg, mp->context);
Damjan Marionb2c31b62020-12-13 21:47:40 +0100722 }
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700723}
724
Neale Ranns17dcec02019-01-09 21:22:20 -0800725vl_api_ipsec_spd_action_t
726ipsec_spd_action_encode (ipsec_policy_action_t in)
727{
728 vl_api_ipsec_spd_action_t out = IPSEC_API_SPD_ACTION_BYPASS;
729
730 switch (in)
731 {
732#define _(v,f,s) case IPSEC_POLICY_ACTION_##f: \
733 out = IPSEC_API_SPD_ACTION_##f; \
734 break;
735 foreach_ipsec_policy_action
736#undef _
737 }
738 return (clib_host_to_net_u32 (out));
739}
740
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700741static void
Florin Coras6c4dae22018-01-09 06:39:23 -0800742send_ipsec_spd_details (ipsec_policy_t * p, vl_api_registration_t * reg,
743 u32 context)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100744{
745 vl_api_ipsec_spd_details_t *mp;
746
747 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400748 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000749 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SPD_DETAILS);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100750 mp->context = context;
751
Neale Ranns17dcec02019-01-09 21:22:20 -0800752 mp->entry.spd_id = htonl (p->id);
753 mp->entry.priority = htonl (p->priority);
Neale Ranns9f231d42019-03-19 10:06:00 +0000754 mp->entry.is_outbound = ((p->type == IPSEC_SPD_POLICY_IP6_OUTBOUND) ||
755 (p->type == IPSEC_SPD_POLICY_IP4_OUTBOUND));
Neale Ranns17dcec02019-01-09 21:22:20 -0800756
757 ip_address_encode (&p->laddr.start, IP46_TYPE_ANY,
758 &mp->entry.local_address_start);
759 ip_address_encode (&p->laddr.stop, IP46_TYPE_ANY,
760 &mp->entry.local_address_stop);
761 ip_address_encode (&p->raddr.start, IP46_TYPE_ANY,
762 &mp->entry.remote_address_start);
763 ip_address_encode (&p->raddr.stop, IP46_TYPE_ANY,
764 &mp->entry.remote_address_stop);
Neale Rannsa4d24312019-07-10 13:46:21 +0000765 mp->entry.local_port_start = htons (p->lport.start);
766 mp->entry.local_port_stop = htons (p->lport.stop);
767 mp->entry.remote_port_start = htons (p->rport.start);
768 mp->entry.remote_port_stop = htons (p->rport.stop);
Neale Ranns17dcec02019-01-09 21:22:20 -0800769 mp->entry.protocol = p->protocol;
770 mp->entry.policy = ipsec_spd_action_encode (p->policy);
771 mp->entry.sa_id = htonl (p->sa_id);
772
Florin Coras6c4dae22018-01-09 06:39:23 -0800773 vl_api_send_msg (reg, (u8 *) mp);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100774}
775
776static void
777vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp)
778{
Florin Coras6c4dae22018-01-09 06:39:23 -0800779 vl_api_registration_t *reg;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100780 ipsec_main_t *im = &ipsec_main;
Neale Ranns9f231d42019-03-19 10:06:00 +0000781 ipsec_spd_policy_type_t ptype;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100782 ipsec_policy_t *policy;
783 ipsec_spd_t *spd;
784 uword *p;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800785 u32 spd_index, *ii;
Damjan Marion97898982021-04-19 18:15:31 +0200786
Florin Coras6c4dae22018-01-09 06:39:23 -0800787 reg = vl_api_client_index_to_registration (mp->client_index);
788 if (!reg)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100789 return;
790
791 p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id));
792 if (!p)
793 return;
794
795 spd_index = p[0];
796 spd = pool_elt_at_index (im->spds, spd_index);
797
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800798 FOR_EACH_IPSEC_SPD_POLICY_TYPE(ptype) {
799 vec_foreach(ii, spd->policies[ptype])
800 {
801 policy = pool_elt_at_index(im->policies, *ii);
802
803 if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id)
804 send_ipsec_spd_details (policy, reg, mp->context);
805 }
806 }
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100807}
808
809static void
Filip Varga871bca92018-11-02 13:51:44 +0100810send_ipsec_spd_interface_details (vl_api_registration_t * reg, u32 spd_index,
811 u32 sw_if_index, u32 context)
812{
813 vl_api_ipsec_spd_interface_details_t *mp;
814
815 mp = vl_msg_api_alloc (sizeof (*mp));
816 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000817 mp->_vl_msg_id =
818 ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SPD_INTERFACE_DETAILS);
Filip Varga871bca92018-11-02 13:51:44 +0100819 mp->context = context;
820
821 mp->spd_index = htonl (spd_index);
822 mp->sw_if_index = htonl (sw_if_index);
823
824 vl_api_send_msg (reg, (u8 *) mp);
825}
826
827static void
828vl_api_ipsec_spd_interface_dump_t_handler (vl_api_ipsec_spd_interface_dump_t *
829 mp)
830{
831 ipsec_main_t *im = &ipsec_main;
832 vl_api_registration_t *reg;
833 u32 k, v, spd_index;
834
Filip Varga871bca92018-11-02 13:51:44 +0100835 reg = vl_api_client_index_to_registration (mp->client_index);
836 if (!reg)
837 return;
838
839 if (mp->spd_index_valid)
840 {
841 spd_index = ntohl (mp->spd_index);
842 /* *INDENT-OFF* */
843 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
844 if (v == spd_index)
845 send_ipsec_spd_interface_details(reg, v, k, mp->context);
846 }));
847 /* *INDENT-ON* */
848 }
849 else
850 {
Filip Varga871bca92018-11-02 13:51:44 +0100851 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
852 send_ipsec_spd_interface_details(reg, v, k, mp->context);
853 }));
Filip Varga871bca92018-11-02 13:51:44 +0100854 }
Filip Varga871bca92018-11-02 13:51:44 +0100855}
856
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000857static void
858vl_api_ipsec_itf_create_t_handler (vl_api_ipsec_itf_create_t * mp)
859{
860 vl_api_ipsec_itf_create_reply_t *rmp;
861 tunnel_mode_t mode;
862 u32 sw_if_index = ~0;
863 int rv;
864
865 rv = tunnel_mode_decode (mp->itf.mode, &mode);
866
867 if (!rv)
868 rv = ipsec_itf_create (ntohl (mp->itf.user_instance), mode, &sw_if_index);
869
870 /* *INDENT-OFF* */
871 REPLY_MACRO2 (VL_API_IPSEC_ITF_CREATE_REPLY,
872 ({
873 rmp->sw_if_index = htonl (sw_if_index);
874 }));
875 /* *INDENT-ON* */
876}
877
878static void
879vl_api_ipsec_itf_delete_t_handler (vl_api_ipsec_itf_delete_t * mp)
880{
881 vl_api_ipsec_itf_delete_reply_t *rmp;
882 int rv;
883
884 rv = ipsec_itf_delete (ntohl (mp->sw_if_index));
885
886 REPLY_MACRO (VL_API_IPSEC_ITF_DELETE_REPLY);
887}
888
Neale Ranns89d939e2021-06-07 09:34:07 +0000889static walk_rc_t
890send_ipsec_itf_details (ipsec_itf_t *itf, void *arg)
891{
892 ipsec_dump_walk_ctx_t *ctx = arg;
893 vl_api_ipsec_itf_details_t *mp;
894
Neale Rannsbed9b722021-10-22 14:10:06 +0000895 if (~0 != ctx->sw_if_index && ctx->sw_if_index != itf->ii_sw_if_index)
896 return (WALK_CONTINUE);
897
Neale Ranns89d939e2021-06-07 09:34:07 +0000898 mp = vl_msg_api_alloc (sizeof (*mp));
899 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000900 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_ITF_DETAILS);
Neale Ranns89d939e2021-06-07 09:34:07 +0000901 mp->context = ctx->context;
902
903 mp->itf.mode = tunnel_mode_encode (itf->ii_mode);
904 mp->itf.user_instance = htonl (itf->ii_user_instance);
905 mp->itf.sw_if_index = htonl (itf->ii_sw_if_index);
906 vl_api_send_msg (ctx->reg, (u8 *) mp);
907
908 return (WALK_CONTINUE);
909}
910
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000911static void
912vl_api_ipsec_itf_dump_t_handler (vl_api_ipsec_itf_dump_t * mp)
913{
Neale Ranns89d939e2021-06-07 09:34:07 +0000914 vl_api_registration_t *reg;
915
916 reg = vl_api_client_index_to_registration (mp->client_index);
917 if (!reg)
918 return;
919
920 ipsec_dump_walk_ctx_t ctx = {
921 .reg = reg,
922 .context = mp->context,
Neale Rannsbed9b722021-10-22 14:10:06 +0000923 .sw_if_index = ntohl (mp->sw_if_index),
Neale Ranns89d939e2021-06-07 09:34:07 +0000924 };
925
926 ipsec_itf_walk (send_ipsec_itf_details, &ctx);
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000927}
928
Neale Ranns12989b52019-09-26 16:20:19 +0000929typedef struct ipsec_sa_dump_match_ctx_t_
Matthew Smith28029532017-09-26 13:33:44 -0500930{
Neale Ranns12989b52019-09-26 16:20:19 +0000931 index_t sai;
932 u32 sw_if_index;
933} ipsec_sa_dump_match_ctx_t;
934
935static walk_rc_t
936ipsec_sa_dump_match_sa (index_t itpi, void *arg)
937{
938 ipsec_sa_dump_match_ctx_t *ctx = arg;
939 ipsec_tun_protect_t *itp;
940 index_t sai;
941
942 itp = ipsec_tun_protect_get (itpi);
943
944 if (itp->itp_out_sa == ctx->sai)
945 {
946 ctx->sw_if_index = itp->itp_sw_if_index;
947 return (WALK_STOP);
948 }
Damjan Marion97898982021-04-19 18:15:31 +0200949
Neale Ranns12989b52019-09-26 16:20:19 +0000950 FOR_EACH_IPSEC_PROTECT_INPUT_SAI (itp, sai,
951 ({
952 if (sai == ctx->sai)
953 {
954 ctx->sw_if_index = itp->itp_sw_if_index;
955 return (WALK_STOP);
956 }
957 }));
Neale Ranns12989b52019-09-26 16:20:19 +0000958
959 return (WALK_CONTINUE);
960}
961
962static walk_rc_t
963send_ipsec_sa_details (ipsec_sa_t * sa, void *arg)
964{
965 ipsec_dump_walk_ctx_t *ctx = arg;
Matthew Smith28029532017-09-26 13:33:44 -0500966 vl_api_ipsec_sa_details_t *mp;
967
968 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400969 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000970 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_DETAILS);
Neale Ranns12989b52019-09-26 16:20:19 +0000971 mp->context = ctx->context;
Matthew Smith28029532017-09-26 13:33:44 -0500972
Neale Ranns8d7c5022019-02-06 01:41:05 -0800973 mp->entry.sad_id = htonl (sa->id);
974 mp->entry.spi = htonl (sa->spi);
975 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000976 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
Matthew Smith28029532017-09-26 13:33:44 -0500977
Neale Ranns8d7c5022019-02-06 01:41:05 -0800978 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
979 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
Matthew Smith28029532017-09-26 13:33:44 -0500980
Neale Ranns8d7c5022019-02-06 01:41:05 -0800981 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
982 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
Matthew Smith28029532017-09-26 13:33:44 -0500983
Neale Ranns8d7c5022019-02-06 01:41:05 -0800984 mp->entry.flags = ipsec_sad_flags_encode (sa);
Neale Ranns12989b52019-09-26 16:20:19 +0000985 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
986
987 if (ipsec_sa_is_set_IS_PROTECT (sa))
988 {
989 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000990 .sai = sa - ipsec_sa_pool,
991 .sw_if_index = ~0,
Neale Ranns12989b52019-09-26 16:20:19 +0000992 };
993 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
994
995 mp->sw_if_index = htonl (ctx.sw_if_index);
996 }
997 else
998 mp->sw_if_index = ~0;
Matthew Smith28029532017-09-26 13:33:44 -0500999
Damjan Mariond709cbc2019-03-26 13:16:42 +01001000 if (ipsec_sa_is_set_IS_TUNNEL (sa))
Matthew Smith28029532017-09-26 13:33:44 -05001001 {
Neale Ranns9ec846c2021-02-09 14:04:02 +00001002 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
1003 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -05001004 }
Neale Rannsabc56602020-04-01 09:45:23 +00001005 if (ipsec_sa_is_set_UDP_ENCAP (sa))
1006 {
1007 mp->entry.udp_src_port = sa->udp_hdr.src_port;
1008 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
1009 }
Matthew Smith28029532017-09-26 13:33:44 -05001010
Matthew Smith28029532017-09-26 13:33:44 -05001011 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns5b891102021-06-28 13:31:28 +00001012 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
Damjan Marion1e3aa5e2019-03-28 10:58:59 +01001013 if (ipsec_sa_is_set_USE_ESN (sa))
Matthew Smith28029532017-09-26 13:33:44 -05001014 {
1015 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns5b891102021-06-28 13:31:28 +00001016 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Matthew Smith28029532017-09-26 13:33:44 -05001017 }
Damjan Mariond709cbc2019-03-26 13:16:42 +01001018 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
Maxime Peim0e2f1882022-12-22 11:26:57 +00001019 {
1020 mp->replay_window =
1021 clib_host_to_net_u64 (ipsec_sa_anti_replay_get_64b_window (sa));
1022 }
Pierre Pfister4c422f92018-12-10 11:19:08 +01001023
Matthew Smith48d32b42020-04-02 07:45:49 -05001024 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
1025
Neale Ranns12989b52019-09-26 16:20:19 +00001026 vl_api_send_msg (ctx->reg, (u8 *) mp);
Matthew Smith28029532017-09-26 13:33:44 -05001027
Neale Ranns12989b52019-09-26 16:20:19 +00001028 return (WALK_CONTINUE);
1029}
Matthew Smith28029532017-09-26 13:33:44 -05001030
1031static void
1032vl_api_ipsec_sa_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
1033{
Florin Coras6c4dae22018-01-09 06:39:23 -08001034 vl_api_registration_t *reg;
Matthew Smith28029532017-09-26 13:33:44 -05001035
Florin Coras6c4dae22018-01-09 06:39:23 -08001036 reg = vl_api_client_index_to_registration (mp->client_index);
Neale Ranns12989b52019-09-26 16:20:19 +00001037 if (!reg)
Matthew Smith28029532017-09-26 13:33:44 -05001038 return;
1039
Neale Ranns12989b52019-09-26 16:20:19 +00001040 ipsec_dump_walk_ctx_t ctx = {
1041 .reg = reg,
1042 .context = mp->context,
1043 };
Matthew Smith28029532017-09-26 13:33:44 -05001044
Neale Ranns12989b52019-09-26 16:20:19 +00001045 ipsec_sa_walk (send_ipsec_sa_details, &ctx);
Matthew Smith28029532017-09-26 13:33:44 -05001046}
1047
Neale Ranns041add72020-01-02 04:06:10 +00001048static walk_rc_t
1049send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg)
1050{
1051 ipsec_dump_walk_ctx_t *ctx = arg;
1052 vl_api_ipsec_sa_v2_details_t *mp;
Neale Ranns041add72020-01-02 04:06:10 +00001053
1054 mp = vl_msg_api_alloc (sizeof (*mp));
1055 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +00001056 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_V2_DETAILS);
Neale Ranns041add72020-01-02 04:06:10 +00001057 mp->context = ctx->context;
1058
1059 mp->entry.sad_id = htonl (sa->id);
1060 mp->entry.spi = htonl (sa->spi);
1061 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
Neale Ranns9ec846c2021-02-09 14:04:02 +00001062 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
Neale Ranns041add72020-01-02 04:06:10 +00001063
1064 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
1065 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
1066
1067 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
1068 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
1069
1070 mp->entry.flags = ipsec_sad_flags_encode (sa);
1071 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
1072
1073 if (ipsec_sa_is_set_IS_PROTECT (sa))
1074 {
1075 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +00001076 .sai = sa - ipsec_sa_pool,
1077 .sw_if_index = ~0,
Neale Ranns041add72020-01-02 04:06:10 +00001078 };
1079 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
1080
1081 mp->sw_if_index = htonl (ctx.sw_if_index);
1082 }
1083 else
1084 mp->sw_if_index = ~0;
1085
1086 if (ipsec_sa_is_set_IS_TUNNEL (sa))
1087 {
Neale Ranns9ec846c2021-02-09 14:04:02 +00001088 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
1089 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
Neale Ranns041add72020-01-02 04:06:10 +00001090 }
1091 if (ipsec_sa_is_set_UDP_ENCAP (sa))
1092 {
1093 mp->entry.udp_src_port = sa->udp_hdr.src_port;
1094 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
1095 }
1096
Neale Ranns9ec846c2021-02-09 14:04:02 +00001097 mp->entry.tunnel_flags =
1098 tunnel_encap_decap_flags_encode (sa->tunnel.t_encap_decap_flags);
1099 mp->entry.dscp = ip_dscp_encode (sa->tunnel.t_dscp);
Neale Ranns041add72020-01-02 04:06:10 +00001100
1101 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns5b891102021-06-28 13:31:28 +00001102 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns041add72020-01-02 04:06:10 +00001103 if (ipsec_sa_is_set_USE_ESN (sa))
1104 {
1105 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns5b891102021-06-28 13:31:28 +00001106 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns041add72020-01-02 04:06:10 +00001107 }
1108 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
Maxime Peim0e2f1882022-12-22 11:26:57 +00001109 {
1110 mp->replay_window =
1111 clib_host_to_net_u64 (ipsec_sa_anti_replay_get_64b_window (sa));
1112 }
Neale Ranns041add72020-01-02 04:06:10 +00001113
1114 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
1115
1116 vl_api_send_msg (ctx->reg, (u8 *) mp);
1117
1118 return (WALK_CONTINUE);
1119}
1120
1121static void
Neale Ranns9ec846c2021-02-09 14:04:02 +00001122vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_v2_dump_t *mp)
Neale Ranns041add72020-01-02 04:06:10 +00001123{
1124 vl_api_registration_t *reg;
1125
Neale Ranns041add72020-01-02 04:06:10 +00001126 reg = vl_api_client_index_to_registration (mp->client_index);
1127 if (!reg)
1128 return;
1129
1130 ipsec_dump_walk_ctx_t ctx = {
1131 .reg = reg,
1132 .context = mp->context,
1133 };
1134
1135 ipsec_sa_walk (send_ipsec_sa_v2_details, &ctx);
Neale Ranns041add72020-01-02 04:06:10 +00001136}
1137
Neale Ranns9ec846c2021-02-09 14:04:02 +00001138static walk_rc_t
1139send_ipsec_sa_v3_details (ipsec_sa_t *sa, void *arg)
1140{
1141 ipsec_dump_walk_ctx_t *ctx = arg;
1142 vl_api_ipsec_sa_v3_details_t *mp;
Neale Ranns9ec846c2021-02-09 14:04:02 +00001143
1144 mp = vl_msg_api_alloc (sizeof (*mp));
1145 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +00001146 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_V3_DETAILS);
Neale Ranns9ec846c2021-02-09 14:04:02 +00001147 mp->context = ctx->context;
1148
1149 mp->entry.sad_id = htonl (sa->id);
1150 mp->entry.spi = htonl (sa->spi);
1151 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
1152
1153 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
1154 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
1155
1156 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
1157 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
1158
1159 mp->entry.flags = ipsec_sad_flags_encode (sa);
1160 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
1161
1162 if (ipsec_sa_is_set_IS_PROTECT (sa))
1163 {
1164 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +00001165 .sai = sa - ipsec_sa_pool,
Neale Ranns9ec846c2021-02-09 14:04:02 +00001166 .sw_if_index = ~0,
1167 };
1168 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
1169
1170 mp->sw_if_index = htonl (ctx.sw_if_index);
1171 }
1172 else
1173 mp->sw_if_index = ~0;
1174
1175 if (ipsec_sa_is_set_IS_TUNNEL (sa))
1176 tunnel_encode (&sa->tunnel, &mp->entry.tunnel);
1177
1178 if (ipsec_sa_is_set_UDP_ENCAP (sa))
1179 {
1180 mp->entry.udp_src_port = sa->udp_hdr.src_port;
1181 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
1182 }
1183
1184 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns5b891102021-06-28 13:31:28 +00001185 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns9ec846c2021-02-09 14:04:02 +00001186 if (ipsec_sa_is_set_USE_ESN (sa))
1187 {
1188 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns5b891102021-06-28 13:31:28 +00001189 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns9ec846c2021-02-09 14:04:02 +00001190 }
1191 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
Maxime Peim0e2f1882022-12-22 11:26:57 +00001192 {
1193 mp->replay_window =
1194 clib_host_to_net_u64 (ipsec_sa_anti_replay_get_64b_window (sa));
1195 }
Neale Ranns9ec846c2021-02-09 14:04:02 +00001196
1197 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
1198
1199 vl_api_send_msg (ctx->reg, (u8 *) mp);
1200
1201 return (WALK_CONTINUE);
1202}
1203
1204static void
1205vl_api_ipsec_sa_v3_dump_t_handler (vl_api_ipsec_sa_v3_dump_t *mp)
1206{
1207 vl_api_registration_t *reg;
1208
Neale Ranns9ec846c2021-02-09 14:04:02 +00001209 reg = vl_api_client_index_to_registration (mp->client_index);
1210 if (!reg)
1211 return;
1212
1213 ipsec_dump_walk_ctx_t ctx = {
1214 .reg = reg,
1215 .context = mp->context,
1216 };
1217
1218 ipsec_sa_walk (send_ipsec_sa_v3_details, &ctx);
Neale Ranns9ec846c2021-02-09 14:04:02 +00001219}
1220
Maxime Peim1271e3a2023-03-20 14:13:56 +00001221static walk_rc_t
1222send_ipsec_sa_v4_details (ipsec_sa_t *sa, void *arg)
1223{
1224 ipsec_dump_walk_ctx_t *ctx = arg;
1225 vl_api_ipsec_sa_v4_details_t *mp;
1226
1227 mp = vl_msg_api_alloc (sizeof (*mp));
1228 clib_memset (mp, 0, sizeof (*mp));
1229 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_V4_DETAILS);
1230 mp->context = ctx->context;
1231
1232 mp->entry.sad_id = htonl (sa->id);
1233 mp->entry.spi = htonl (sa->spi);
1234 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
1235
1236 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
1237 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
1238
1239 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
1240 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
1241
1242 mp->entry.flags = ipsec_sad_flags_encode (sa);
1243 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
1244
1245 if (ipsec_sa_is_set_IS_PROTECT (sa))
1246 {
1247 ipsec_sa_dump_match_ctx_t ctx = {
1248 .sai = sa - ipsec_sa_pool,
1249 .sw_if_index = ~0,
1250 };
1251 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
1252
1253 mp->sw_if_index = htonl (ctx.sw_if_index);
1254 }
1255 else
1256 mp->sw_if_index = ~0;
1257
1258 if (ipsec_sa_is_set_IS_TUNNEL (sa))
1259 tunnel_encode (&sa->tunnel, &mp->entry.tunnel);
1260
1261 if (ipsec_sa_is_set_UDP_ENCAP (sa))
1262 {
1263 mp->entry.udp_src_port = sa->udp_hdr.src_port;
1264 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
1265 }
1266
1267 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
1268 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
1269 if (ipsec_sa_is_set_USE_ESN (sa))
1270 {
1271 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
1272 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
1273 }
1274 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
Maxime Peim0e2f1882022-12-22 11:26:57 +00001275 {
1276 mp->replay_window =
1277 clib_host_to_net_u64 (ipsec_sa_anti_replay_get_64b_window (sa));
1278 }
Maxime Peim1271e3a2023-03-20 14:13:56 +00001279
1280 mp->thread_index = clib_host_to_net_u32 (sa->thread_index);
1281 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
1282
1283 vl_api_send_msg (ctx->reg, (u8 *) mp);
1284
1285 return (WALK_CONTINUE);
1286}
1287
1288static void
1289vl_api_ipsec_sa_v4_dump_t_handler (vl_api_ipsec_sa_v4_dump_t *mp)
1290{
1291 vl_api_registration_t *reg;
1292
1293 reg = vl_api_client_index_to_registration (mp->client_index);
1294 if (!reg)
1295 return;
1296
1297 ipsec_dump_walk_ctx_t ctx = {
1298 .reg = reg,
1299 .context = mp->context,
1300 };
1301
1302 ipsec_sa_walk (send_ipsec_sa_v4_details, &ctx);
1303}
1304
Maxime Peim0e2f1882022-12-22 11:26:57 +00001305static walk_rc_t
1306send_ipsec_sa_v5_details (ipsec_sa_t *sa, void *arg)
1307{
1308 ipsec_dump_walk_ctx_t *ctx = arg;
1309 vl_api_ipsec_sa_v5_details_t *mp;
1310
1311 mp = vl_msg_api_alloc (sizeof (*mp));
1312 clib_memset (mp, 0, sizeof (*mp));
1313 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_V5_DETAILS);
1314 mp->context = ctx->context;
1315
1316 mp->entry.sad_id = htonl (sa->id);
1317 mp->entry.spi = htonl (sa->spi);
1318 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
1319
1320 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
1321 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
1322
1323 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
1324 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
1325
1326 mp->entry.flags = ipsec_sad_flags_encode (sa);
1327 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
1328
1329 if (ipsec_sa_is_set_IS_PROTECT (sa))
1330 {
1331 ipsec_sa_dump_match_ctx_t ctx = {
1332 .sai = sa - ipsec_sa_pool,
1333 .sw_if_index = ~0,
1334 };
1335 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
1336
1337 mp->sw_if_index = htonl (ctx.sw_if_index);
1338 }
1339 else
1340 mp->sw_if_index = ~0;
1341
1342 if (ipsec_sa_is_set_IS_TUNNEL (sa))
1343 tunnel_encode (&sa->tunnel, &mp->entry.tunnel);
1344
1345 if (ipsec_sa_is_set_UDP_ENCAP (sa))
1346 {
1347 mp->entry.udp_src_port = sa->udp_hdr.src_port;
1348 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
1349 }
1350
1351 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
1352 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
1353 if (ipsec_sa_is_set_USE_ESN (sa))
1354 {
1355 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
1356 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
1357 }
1358 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
1359 {
1360 mp->replay_window =
1361 clib_host_to_net_u64 (ipsec_sa_anti_replay_get_64b_window (sa));
1362
1363 mp->entry.anti_replay_window_size =
1364 clib_host_to_net_u32 (IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE (sa));
1365 }
1366
1367 mp->thread_index = clib_host_to_net_u32 (sa->thread_index);
1368 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
1369
1370 vl_api_send_msg (ctx->reg, (u8 *) mp);
1371
1372 return (WALK_CONTINUE);
1373}
1374
Matthew Smith75d85602017-10-05 19:03:05 -05001375static void
Maxime Peim0e2f1882022-12-22 11:26:57 +00001376vl_api_ipsec_sa_v5_dump_t_handler (vl_api_ipsec_sa_v5_dump_t *mp)
1377{
1378 vl_api_registration_t *reg;
1379
1380 reg = vl_api_client_index_to_registration (mp->client_index);
1381 if (!reg)
1382 return;
1383
1384 ipsec_dump_walk_ctx_t ctx = {
1385 .reg = reg,
1386 .context = mp->context,
1387 };
1388
1389 ipsec_sa_walk (send_ipsec_sa_v5_details, &ctx);
1390}
1391
1392static void
1393vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t *mp)
Klement Sekerab4d30532018-11-08 13:00:02 +01001394{
1395 vl_api_registration_t *rp;
1396 ipsec_main_t *im = &ipsec_main;
1397 u32 context = mp->context;
1398
1399 rp = vl_api_client_index_to_registration (mp->client_index);
1400
1401 if (rp == 0)
1402 {
1403 clib_warning ("Client %d AWOL", mp->client_index);
1404 return;
1405 }
1406
1407 ipsec_ah_backend_t *ab;
1408 ipsec_esp_backend_t *eb;
1409 /* *INDENT-OFF* */
Damjan Marionb2c31b62020-12-13 21:47:40 +01001410 pool_foreach (ab, im->ah_backends) {
Klement Sekerab4d30532018-11-08 13:00:02 +01001411 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1412 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +00001413 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_BACKEND_DETAILS);
Klement Sekerab4d30532018-11-08 13:00:02 +01001414 mp->context = context;
1415 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (ab->name),
1416 ab->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001417 mp->protocol = ntohl (IPSEC_API_PROTO_AH);
Klement Sekerab4d30532018-11-08 13:00:02 +01001418 mp->index = ab - im->ah_backends;
1419 mp->active = mp->index == im->ah_current_backend ? 1 : 0;
1420 vl_api_send_msg (rp, (u8 *)mp);
Damjan Marionb2c31b62020-12-13 21:47:40 +01001421 }
1422 pool_foreach (eb, im->esp_backends) {
Klement Sekerab4d30532018-11-08 13:00:02 +01001423 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1424 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +00001425 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_BACKEND_DETAILS);
Klement Sekerab4d30532018-11-08 13:00:02 +01001426 mp->context = context;
1427 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (eb->name),
1428 eb->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001429 mp->protocol = ntohl (IPSEC_API_PROTO_ESP);
Klement Sekerab4d30532018-11-08 13:00:02 +01001430 mp->index = eb - im->esp_backends;
1431 mp->active = mp->index == im->esp_current_backend ? 1 : 0;
1432 vl_api_send_msg (rp, (u8 *)mp);
Damjan Marionb2c31b62020-12-13 21:47:40 +01001433 }
Klement Sekerab4d30532018-11-08 13:00:02 +01001434 /* *INDENT-ON* */
1435}
1436
1437static void
1438vl_api_ipsec_select_backend_t_handler (vl_api_ipsec_select_backend_t * mp)
1439{
1440 ipsec_main_t *im = &ipsec_main;
1441 vl_api_ipsec_select_backend_reply_t *rmp;
Neale Ranns17dcec02019-01-09 21:22:20 -08001442 ipsec_protocol_t protocol;
Klement Sekerab4d30532018-11-08 13:00:02 +01001443 int rv = 0;
Neale Rannsc5fe57d2021-02-25 16:01:28 +00001444 if (pool_elts (ipsec_sa_pool) > 0)
Klement Sekerab4d30532018-11-08 13:00:02 +01001445 {
1446 rv = VNET_API_ERROR_INSTANCE_IN_USE;
1447 goto done;
1448 }
Neale Ranns17dcec02019-01-09 21:22:20 -08001449
1450 rv = ipsec_proto_decode (mp->protocol, &protocol);
1451
1452 if (rv)
1453 goto done;
1454
Neale Ranns17dcec02019-01-09 21:22:20 -08001455 switch (protocol)
Klement Sekerab4d30532018-11-08 13:00:02 +01001456 {
1457 case IPSEC_PROTOCOL_ESP:
Neale Rannse8915fc2019-04-23 20:57:55 -04001458 rv = ipsec_select_esp_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001459 break;
1460 case IPSEC_PROTOCOL_AH:
Neale Rannse8915fc2019-04-23 20:57:55 -04001461 rv = ipsec_select_ah_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001462 break;
1463 default:
Neale Rannse8915fc2019-04-23 20:57:55 -04001464 rv = VNET_API_ERROR_INVALID_PROTOCOL;
Klement Sekerab4d30532018-11-08 13:00:02 +01001465 break;
1466 }
Klement Sekerab4d30532018-11-08 13:00:02 +01001467done:
1468 REPLY_MACRO (VL_API_IPSEC_SELECT_BACKEND_REPLY);
1469}
1470
Yulong Pei2e84d662020-08-14 18:21:08 +08001471static void
1472vl_api_ipsec_set_async_mode_t_handler (vl_api_ipsec_set_async_mode_t * mp)
1473{
1474 vl_api_ipsec_set_async_mode_reply_t *rmp;
1475 int rv = 0;
1476
Yulong Pei2e84d662020-08-14 18:21:08 +08001477 ipsec_set_async_mode (mp->async_enable);
1478
1479 REPLY_MACRO (VL_API_IPSEC_SET_ASYNC_MODE_REPLY);
1480}
1481
Filip Tehlarc73f3292021-06-22 08:21:31 +00001482#include <vnet/ipsec/ipsec.api.c>
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001483static clib_error_t *
1484ipsec_api_hookup (vlib_main_t * vm)
1485{
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001486 /*
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001487 * Set up the (msg_name, crc, message-id) table
1488 */
Filip Tehlarc73f3292021-06-22 08:21:31 +00001489 REPLY_MSG_ID_BASE = setup_message_id_table ();
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001490
1491 return 0;
1492}
1493
1494VLIB_API_INIT_FUNCTION (ipsec_api_hookup);
1495
1496/*
1497 * fd.io coding-style-patch-verification: ON
1498 *
1499 * Local Variables:
1500 * eval: (c-set-style "gnu")
1501 * End:
1502 */