blob: 72231f656fff18875118823778ef6916652e729b [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
236 p.protocol = mp->entry.protocol;
Neale Rannsa4d24312019-07-10 13:46:21 +0000237 p.rport.start = ntohs (mp->entry.remote_port_start);
238 p.rport.stop = ntohs (mp->entry.remote_port_stop);
239 p.lport.start = ntohs (mp->entry.local_port_start);
240 p.lport.stop = ntohs (mp->entry.local_port_stop);
Neale Ranns17dcec02019-01-09 21:22:20 -0800241
242 rv = ipsec_spd_action_decode (mp->entry.policy, &p.policy);
243
244 if (rv)
245 goto out;
246
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100247 /* policy action resolve unsupported */
Neale Ranns17dcec02019-01-09 21:22:20 -0800248 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100249 {
250 clib_warning ("unsupported action: 'resolve'");
251 rv = VNET_API_ERROR_UNIMPLEMENTED;
252 goto out;
253 }
Neale Ranns17dcec02019-01-09 21:22:20 -0800254 p.sa_id = ntohl (mp->entry.sa_id);
Neale Ranns9f231d42019-03-19 10:06:00 +0000255 rv =
256 ipsec_policy_mk_type (mp->entry.is_outbound, p.is_ipv6, p.policy,
257 &p.type);
258 if (rv)
259 goto out;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100260
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800261 rv = ipsec_add_del_policy (vm, &p, mp->is_add, &stat_index);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100262 if (rv)
263 goto out;
264
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100265out:
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800266 /* *INDENT-OFF* */
267 REPLY_MACRO2 (VL_API_IPSEC_SPD_ENTRY_ADD_DEL_REPLY,
268 ({
269 rmp->stat_index = ntohl(stat_index);
270 }));
271 /* *INDENT-ON* */
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100272}
273
Neale Ranns17dcec02019-01-09 21:22:20 -0800274static void vl_api_ipsec_sad_entry_add_del_t_handler
275 (vl_api_ipsec_sad_entry_add_del_t * mp)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100276{
Neale Ranns17dcec02019-01-09 21:22:20 -0800277 vl_api_ipsec_sad_entry_add_del_reply_t *rmp;
Neale Ranns8d7c5022019-02-06 01:41:05 -0800278 ipsec_key_t crypto_key, integ_key;
279 ipsec_crypto_alg_t crypto_alg;
280 ipsec_integ_alg_t integ_alg;
281 ipsec_protocol_t proto;
282 ipsec_sa_flags_t flags;
Dave Baracha5160d72019-03-13 15:29:15 -0400283 u32 id, spi, sa_index = ~0;
Neale Ranns9ec846c2021-02-09 14:04:02 +0000284 tunnel_t tun = {
285 .t_flags = TUNNEL_FLAG_NONE,
286 .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE,
287 .t_dscp = 0,
288 .t_mode = TUNNEL_MODE_P2P,
289 .t_table_id = 0,
290 .t_hop_limit = 255,
291 };
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100292 int rv;
Neale Ranns8d7c5022019-02-06 01:41:05 -0800293
Neale Ranns8d7c5022019-02-06 01:41:05 -0800294 id = ntohl (mp->entry.sad_id);
Neale Rannsff2e4132021-06-24 14:57:56 +0000295 if (!mp->is_add)
296 {
297 rv = ipsec_sa_unlock_id (id);
298 goto out;
299 }
Neale Ranns8d7c5022019-02-06 01:41:05 -0800300 spi = ntohl (mp->entry.spi);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100301
Neale Ranns8d7c5022019-02-06 01:41:05 -0800302 rv = ipsec_proto_decode (mp->entry.protocol, &proto);
Neale Ranns17dcec02019-01-09 21:22:20 -0800303
304 if (rv)
305 goto out;
306
Neale Ranns8d7c5022019-02-06 01:41:05 -0800307 rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
Neale Ranns17dcec02019-01-09 21:22:20 -0800308
309 if (rv)
310 goto out;
311
Neale Ranns8d7c5022019-02-06 01:41:05 -0800312 rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
Neale Ranns17dcec02019-01-09 21:22:20 -0800313
314 if (rv)
315 goto out;
316
Neale Ranns8d7c5022019-02-06 01:41:05 -0800317 ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
318 ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
Neale Ranns17dcec02019-01-09 21:22:20 -0800319
Neale Ranns8d7c5022019-02-06 01:41:05 -0800320 flags = ipsec_sa_flags_decode (mp->entry.flags);
Neale Ranns17dcec02019-01-09 21:22:20 -0800321
Neale Ranns9ec846c2021-02-09 14:04:02 +0000322 ip_address_decode2 (&mp->entry.tunnel_src, &tun.t_src);
323 ip_address_decode2 (&mp->entry.tunnel_dst, &tun.t_dst);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100324
Neale Rannsff2e4132021-06-24 14:57:56 +0000325 rv = ipsec_sa_add_and_lock (id, spi, proto, crypto_alg, &crypto_key,
326 integ_alg, &integ_key, flags, mp->entry.salt,
327 htons (mp->entry.udp_src_port),
328 htons (mp->entry.udp_dst_port), &tun, &sa_index);
Neale Ranns8d7c5022019-02-06 01:41:05 -0800329
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100330out:
Neale Rannseba31ec2019-02-17 18:04:27 +0000331 /* *INDENT-OFF* */
332 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_REPLY,
333 {
334 rmp->stat_index = htonl (sa_index);
335 });
336 /* *INDENT-ON* */
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100337}
338
Neale Ranns041add72020-01-02 04:06:10 +0000339static void vl_api_ipsec_sad_entry_add_del_v2_t_handler
340 (vl_api_ipsec_sad_entry_add_del_v2_t * mp)
341{
342 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
343 vl_api_ipsec_sad_entry_add_del_v2_reply_t *rmp;
Neale Ranns041add72020-01-02 04:06:10 +0000344 ipsec_key_t crypto_key, integ_key;
345 ipsec_crypto_alg_t crypto_alg;
346 ipsec_integ_alg_t integ_alg;
347 ipsec_protocol_t proto;
348 ipsec_sa_flags_t flags;
349 u32 id, spi, sa_index = ~0;
350 int rv;
Neale Ranns9ec846c2021-02-09 14:04:02 +0000351 tunnel_t tun = {
352 .t_flags = TUNNEL_FLAG_NONE,
353 .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE,
354 .t_dscp = 0,
355 .t_mode = TUNNEL_MODE_P2P,
356 .t_table_id = htonl (mp->entry.tx_table_id),
357 .t_hop_limit = 255,
358 };
359
Neale Ranns9ec846c2021-02-09 14:04:02 +0000360 id = ntohl (mp->entry.sad_id);
Neale Rannsff2e4132021-06-24 14:57:56 +0000361 if (!mp->is_add)
362 {
363 rv = ipsec_sa_unlock_id (id);
364 goto out;
365 }
366
Neale Ranns9ec846c2021-02-09 14:04:02 +0000367 spi = ntohl (mp->entry.spi);
368
369 rv = ipsec_proto_decode (mp->entry.protocol, &proto);
370
371 if (rv)
372 goto out;
373
374 rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
375
376 if (rv)
377 goto out;
378
379 rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
380
381 if (rv)
382 goto out;
383
384 rv = tunnel_encap_decap_flags_decode (mp->entry.tunnel_flags,
385 &tun.t_encap_decap_flags);
386
387 if (rv)
388 goto out;
389
390 ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
391 ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
392
393 flags = ipsec_sa_flags_decode (mp->entry.flags);
394 tun.t_dscp = ip_dscp_decode (mp->entry.dscp);
395
396 ip_address_decode2 (&mp->entry.tunnel_src, &tun.t_src);
397 ip_address_decode2 (&mp->entry.tunnel_dst, &tun.t_dst);
398
Neale Ranns9ec846c2021-02-09 14:04:02 +0000399 rv = ipsec_sa_add_and_lock (
400 id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
401 mp->entry.salt, htons (mp->entry.udp_src_port),
402 htons (mp->entry.udp_dst_port), &tun, &sa_index);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000403
Neale Ranns9ec846c2021-02-09 14:04:02 +0000404out:
405 /* *INDENT-OFF* */
406 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_V2_REPLY,
407 {
408 rmp->stat_index = htonl (sa_index);
409 });
410 /* *INDENT-ON* */
411}
412
Neale Rannsff2e4132021-06-24 14:57:56 +0000413static int
414ipsec_sad_entry_add_v3 (const vl_api_ipsec_sad_entry_v3_t *entry,
415 u32 *sa_index)
Neale Ranns9ec846c2021-02-09 14:04:02 +0000416{
Neale Ranns9ec846c2021-02-09 14:04:02 +0000417 ipsec_key_t crypto_key, integ_key;
418 ipsec_crypto_alg_t crypto_alg;
419 ipsec_integ_alg_t integ_alg;
420 ipsec_protocol_t proto;
421 ipsec_sa_flags_t flags;
Neale Rannsff2e4132021-06-24 14:57:56 +0000422 u32 id, spi;
Neale Ranns9ec846c2021-02-09 14:04:02 +0000423 tunnel_t tun;
424 int rv;
Neale Rannsc7eaa712021-02-04 11:09:33 +0000425
Neale Rannsff2e4132021-06-24 14:57:56 +0000426 id = ntohl (entry->sad_id);
427 spi = ntohl (entry->spi);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000428
Neale Rannsff2e4132021-06-24 14:57:56 +0000429 rv = ipsec_proto_decode (entry->protocol, &proto);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000430
431 if (rv)
Neale Rannsff2e4132021-06-24 14:57:56 +0000432 return (rv);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000433
Neale Rannsff2e4132021-06-24 14:57:56 +0000434 rv = ipsec_crypto_algo_decode (entry->crypto_algorithm, &crypto_alg);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000435
436 if (rv)
Neale Rannsff2e4132021-06-24 14:57:56 +0000437 return (rv);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000438
Neale Rannsff2e4132021-06-24 14:57:56 +0000439 rv = ipsec_integ_algo_decode (entry->integrity_algorithm, &integ_alg);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000440
441 if (rv)
Neale Rannsff2e4132021-06-24 14:57:56 +0000442 return (rv);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000443
Neale Rannsff2e4132021-06-24 14:57:56 +0000444 flags = ipsec_sa_flags_decode (entry->flags);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000445
Neale Ranns9ec846c2021-02-09 14:04:02 +0000446 if (flags & IPSEC_SA_FLAG_IS_TUNNEL)
447 {
Neale Rannsff2e4132021-06-24 14:57:56 +0000448 rv = tunnel_decode (&entry->tunnel, &tun);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000449
450 if (rv)
Neale Rannsff2e4132021-06-24 14:57:56 +0000451 return (rv);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000452 }
Neale Rannsc7eaa712021-02-04 11:09:33 +0000453
Neale Rannsff2e4132021-06-24 14:57:56 +0000454 ipsec_key_decode (&entry->crypto_key, &crypto_key);
455 ipsec_key_decode (&entry->integrity_key, &integ_key);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000456
Neale Rannsff2e4132021-06-24 14:57:56 +0000457 return ipsec_sa_add_and_lock (id, spi, proto, crypto_alg, &crypto_key,
458 integ_alg, &integ_key, flags, entry->salt,
459 htons (entry->udp_src_port),
460 htons (entry->udp_dst_port), &tun, sa_index);
461}
462
463static void
464vl_api_ipsec_sad_entry_add_del_v3_t_handler (
465 vl_api_ipsec_sad_entry_add_del_v3_t *mp)
466{
467 vl_api_ipsec_sad_entry_add_del_v3_reply_t *rmp;
468 u32 id, sa_index = ~0;
469 int rv;
470
471 id = ntohl (mp->entry.sad_id);
472
473 if (!mp->is_add)
474 {
475 rv = ipsec_sa_unlock_id (id);
476 }
Neale Rannsc7eaa712021-02-04 11:09:33 +0000477 else
Neale Rannsff2e4132021-06-24 14:57:56 +0000478 {
479 rv = ipsec_sad_entry_add_v3 (&mp->entry, &sa_index);
480 }
Neale Rannsc7eaa712021-02-04 11:09:33 +0000481
Neale Ranns9ec846c2021-02-09 14:04:02 +0000482 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_V3_REPLY,
483 { rmp->stat_index = htonl (sa_index); });
Neale Rannsc7eaa712021-02-04 11:09:33 +0000484}
485
486static void
Neale Rannsff2e4132021-06-24 14:57:56 +0000487vl_api_ipsec_sad_entry_del_t_handler (vl_api_ipsec_sad_entry_del_t *mp)
488{
489 vl_api_ipsec_sad_entry_del_reply_t *rmp;
490 int rv;
491
492 rv = ipsec_sa_unlock_id (ntohl (mp->id));
493
494 REPLY_MACRO (VL_API_IPSEC_SAD_ENTRY_DEL_REPLY);
495}
496
497static void
498vl_api_ipsec_sad_entry_add_t_handler (vl_api_ipsec_sad_entry_add_t *mp)
499{
500 vl_api_ipsec_sad_entry_add_reply_t *rmp;
501 u32 sa_index = ~0;
502 int rv;
503
504 rv = ipsec_sad_entry_add_v3 (&mp->entry, &sa_index);
505
506 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_REPLY,
507 { rmp->stat_index = htonl (sa_index); });
508}
509
510static void
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700511send_ipsec_spds_details (ipsec_spd_t * spd, vl_api_registration_t * reg,
512 u32 context)
513{
514 vl_api_ipsec_spds_details_t *mp;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800515 u32 n_policies = 0;
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700516
517 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400518 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000519 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SPDS_DETAILS);
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700520 mp->context = context;
521
522 mp->spd_id = htonl (spd->id);
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800523#define _(s, n) n_policies += vec_len (spd->policies[IPSEC_SPD_POLICY_##s]);
524 foreach_ipsec_spd_policy_type
525#undef _
526 mp->npolicies = htonl (n_policies);
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700527
528 vl_api_send_msg (reg, (u8 *) mp);
529}
530
531static void
532vl_api_ipsec_spds_dump_t_handler (vl_api_ipsec_spds_dump_t * mp)
533{
534 vl_api_registration_t *reg;
535 ipsec_main_t *im = &ipsec_main;
536 ipsec_spd_t *spd;
Damjan Marion97898982021-04-19 18:15:31 +0200537
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700538 reg = vl_api_client_index_to_registration (mp->client_index);
539 if (!reg)
540 return;
541
Damjan Marionb2c31b62020-12-13 21:47:40 +0100542 pool_foreach (spd, im->spds) {
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700543 send_ipsec_spds_details (spd, reg, mp->context);
Damjan Marionb2c31b62020-12-13 21:47:40 +0100544 }
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700545}
546
Neale Ranns17dcec02019-01-09 21:22:20 -0800547vl_api_ipsec_spd_action_t
548ipsec_spd_action_encode (ipsec_policy_action_t in)
549{
550 vl_api_ipsec_spd_action_t out = IPSEC_API_SPD_ACTION_BYPASS;
551
552 switch (in)
553 {
554#define _(v,f,s) case IPSEC_POLICY_ACTION_##f: \
555 out = IPSEC_API_SPD_ACTION_##f; \
556 break;
557 foreach_ipsec_policy_action
558#undef _
559 }
560 return (clib_host_to_net_u32 (out));
561}
562
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700563static void
Florin Coras6c4dae22018-01-09 06:39:23 -0800564send_ipsec_spd_details (ipsec_policy_t * p, vl_api_registration_t * reg,
565 u32 context)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100566{
567 vl_api_ipsec_spd_details_t *mp;
568
569 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400570 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000571 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SPD_DETAILS);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100572 mp->context = context;
573
Neale Ranns17dcec02019-01-09 21:22:20 -0800574 mp->entry.spd_id = htonl (p->id);
575 mp->entry.priority = htonl (p->priority);
Neale Ranns9f231d42019-03-19 10:06:00 +0000576 mp->entry.is_outbound = ((p->type == IPSEC_SPD_POLICY_IP6_OUTBOUND) ||
577 (p->type == IPSEC_SPD_POLICY_IP4_OUTBOUND));
Neale Ranns17dcec02019-01-09 21:22:20 -0800578
579 ip_address_encode (&p->laddr.start, IP46_TYPE_ANY,
580 &mp->entry.local_address_start);
581 ip_address_encode (&p->laddr.stop, IP46_TYPE_ANY,
582 &mp->entry.local_address_stop);
583 ip_address_encode (&p->raddr.start, IP46_TYPE_ANY,
584 &mp->entry.remote_address_start);
585 ip_address_encode (&p->raddr.stop, IP46_TYPE_ANY,
586 &mp->entry.remote_address_stop);
Neale Rannsa4d24312019-07-10 13:46:21 +0000587 mp->entry.local_port_start = htons (p->lport.start);
588 mp->entry.local_port_stop = htons (p->lport.stop);
589 mp->entry.remote_port_start = htons (p->rport.start);
590 mp->entry.remote_port_stop = htons (p->rport.stop);
Neale Ranns17dcec02019-01-09 21:22:20 -0800591 mp->entry.protocol = p->protocol;
592 mp->entry.policy = ipsec_spd_action_encode (p->policy);
593 mp->entry.sa_id = htonl (p->sa_id);
594
Florin Coras6c4dae22018-01-09 06:39:23 -0800595 vl_api_send_msg (reg, (u8 *) mp);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100596}
597
598static void
599vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp)
600{
Florin Coras6c4dae22018-01-09 06:39:23 -0800601 vl_api_registration_t *reg;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100602 ipsec_main_t *im = &ipsec_main;
Neale Ranns9f231d42019-03-19 10:06:00 +0000603 ipsec_spd_policy_type_t ptype;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100604 ipsec_policy_t *policy;
605 ipsec_spd_t *spd;
606 uword *p;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800607 u32 spd_index, *ii;
Damjan Marion97898982021-04-19 18:15:31 +0200608
Florin Coras6c4dae22018-01-09 06:39:23 -0800609 reg = vl_api_client_index_to_registration (mp->client_index);
610 if (!reg)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100611 return;
612
613 p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id));
614 if (!p)
615 return;
616
617 spd_index = p[0];
618 spd = pool_elt_at_index (im->spds, spd_index);
619
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800620 FOR_EACH_IPSEC_SPD_POLICY_TYPE(ptype) {
621 vec_foreach(ii, spd->policies[ptype])
622 {
623 policy = pool_elt_at_index(im->policies, *ii);
624
625 if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id)
626 send_ipsec_spd_details (policy, reg, mp->context);
627 }
628 }
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100629}
630
631static void
Filip Varga871bca92018-11-02 13:51:44 +0100632send_ipsec_spd_interface_details (vl_api_registration_t * reg, u32 spd_index,
633 u32 sw_if_index, u32 context)
634{
635 vl_api_ipsec_spd_interface_details_t *mp;
636
637 mp = vl_msg_api_alloc (sizeof (*mp));
638 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000639 mp->_vl_msg_id =
640 ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SPD_INTERFACE_DETAILS);
Filip Varga871bca92018-11-02 13:51:44 +0100641 mp->context = context;
642
643 mp->spd_index = htonl (spd_index);
644 mp->sw_if_index = htonl (sw_if_index);
645
646 vl_api_send_msg (reg, (u8 *) mp);
647}
648
649static void
650vl_api_ipsec_spd_interface_dump_t_handler (vl_api_ipsec_spd_interface_dump_t *
651 mp)
652{
653 ipsec_main_t *im = &ipsec_main;
654 vl_api_registration_t *reg;
655 u32 k, v, spd_index;
656
Filip Varga871bca92018-11-02 13:51:44 +0100657 reg = vl_api_client_index_to_registration (mp->client_index);
658 if (!reg)
659 return;
660
661 if (mp->spd_index_valid)
662 {
663 spd_index = ntohl (mp->spd_index);
664 /* *INDENT-OFF* */
665 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
666 if (v == spd_index)
667 send_ipsec_spd_interface_details(reg, v, k, mp->context);
668 }));
669 /* *INDENT-ON* */
670 }
671 else
672 {
Filip Varga871bca92018-11-02 13:51:44 +0100673 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
674 send_ipsec_spd_interface_details(reg, v, k, mp->context);
675 }));
Filip Varga871bca92018-11-02 13:51:44 +0100676 }
Filip Varga871bca92018-11-02 13:51:44 +0100677}
678
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000679static void
680vl_api_ipsec_itf_create_t_handler (vl_api_ipsec_itf_create_t * mp)
681{
682 vl_api_ipsec_itf_create_reply_t *rmp;
683 tunnel_mode_t mode;
684 u32 sw_if_index = ~0;
685 int rv;
686
687 rv = tunnel_mode_decode (mp->itf.mode, &mode);
688
689 if (!rv)
690 rv = ipsec_itf_create (ntohl (mp->itf.user_instance), mode, &sw_if_index);
691
692 /* *INDENT-OFF* */
693 REPLY_MACRO2 (VL_API_IPSEC_ITF_CREATE_REPLY,
694 ({
695 rmp->sw_if_index = htonl (sw_if_index);
696 }));
697 /* *INDENT-ON* */
698}
699
700static void
701vl_api_ipsec_itf_delete_t_handler (vl_api_ipsec_itf_delete_t * mp)
702{
703 vl_api_ipsec_itf_delete_reply_t *rmp;
704 int rv;
705
706 rv = ipsec_itf_delete (ntohl (mp->sw_if_index));
707
708 REPLY_MACRO (VL_API_IPSEC_ITF_DELETE_REPLY);
709}
710
Neale Ranns89d939e2021-06-07 09:34:07 +0000711static walk_rc_t
712send_ipsec_itf_details (ipsec_itf_t *itf, void *arg)
713{
714 ipsec_dump_walk_ctx_t *ctx = arg;
715 vl_api_ipsec_itf_details_t *mp;
716
Neale Rannsbed9b722021-10-22 14:10:06 +0000717 if (~0 != ctx->sw_if_index && ctx->sw_if_index != itf->ii_sw_if_index)
718 return (WALK_CONTINUE);
719
Neale Ranns89d939e2021-06-07 09:34:07 +0000720 mp = vl_msg_api_alloc (sizeof (*mp));
721 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000722 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_ITF_DETAILS);
Neale Ranns89d939e2021-06-07 09:34:07 +0000723 mp->context = ctx->context;
724
725 mp->itf.mode = tunnel_mode_encode (itf->ii_mode);
726 mp->itf.user_instance = htonl (itf->ii_user_instance);
727 mp->itf.sw_if_index = htonl (itf->ii_sw_if_index);
728 vl_api_send_msg (ctx->reg, (u8 *) mp);
729
730 return (WALK_CONTINUE);
731}
732
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000733static void
734vl_api_ipsec_itf_dump_t_handler (vl_api_ipsec_itf_dump_t * mp)
735{
Neale Ranns89d939e2021-06-07 09:34:07 +0000736 vl_api_registration_t *reg;
737
738 reg = vl_api_client_index_to_registration (mp->client_index);
739 if (!reg)
740 return;
741
742 ipsec_dump_walk_ctx_t ctx = {
743 .reg = reg,
744 .context = mp->context,
Neale Rannsbed9b722021-10-22 14:10:06 +0000745 .sw_if_index = ntohl (mp->sw_if_index),
Neale Ranns89d939e2021-06-07 09:34:07 +0000746 };
747
748 ipsec_itf_walk (send_ipsec_itf_details, &ctx);
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000749}
750
Neale Ranns12989b52019-09-26 16:20:19 +0000751typedef struct ipsec_sa_dump_match_ctx_t_
Matthew Smith28029532017-09-26 13:33:44 -0500752{
Neale Ranns12989b52019-09-26 16:20:19 +0000753 index_t sai;
754 u32 sw_if_index;
755} ipsec_sa_dump_match_ctx_t;
756
757static walk_rc_t
758ipsec_sa_dump_match_sa (index_t itpi, void *arg)
759{
760 ipsec_sa_dump_match_ctx_t *ctx = arg;
761 ipsec_tun_protect_t *itp;
762 index_t sai;
763
764 itp = ipsec_tun_protect_get (itpi);
765
766 if (itp->itp_out_sa == ctx->sai)
767 {
768 ctx->sw_if_index = itp->itp_sw_if_index;
769 return (WALK_STOP);
770 }
Damjan Marion97898982021-04-19 18:15:31 +0200771
Neale Ranns12989b52019-09-26 16:20:19 +0000772 FOR_EACH_IPSEC_PROTECT_INPUT_SAI (itp, sai,
773 ({
774 if (sai == ctx->sai)
775 {
776 ctx->sw_if_index = itp->itp_sw_if_index;
777 return (WALK_STOP);
778 }
779 }));
Neale Ranns12989b52019-09-26 16:20:19 +0000780
781 return (WALK_CONTINUE);
782}
783
784static walk_rc_t
785send_ipsec_sa_details (ipsec_sa_t * sa, void *arg)
786{
787 ipsec_dump_walk_ctx_t *ctx = arg;
Matthew Smith28029532017-09-26 13:33:44 -0500788 vl_api_ipsec_sa_details_t *mp;
789
790 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400791 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000792 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_DETAILS);
Neale Ranns12989b52019-09-26 16:20:19 +0000793 mp->context = ctx->context;
Matthew Smith28029532017-09-26 13:33:44 -0500794
Neale Ranns8d7c5022019-02-06 01:41:05 -0800795 mp->entry.sad_id = htonl (sa->id);
796 mp->entry.spi = htonl (sa->spi);
797 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000798 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
Matthew Smith28029532017-09-26 13:33:44 -0500799
Neale Ranns8d7c5022019-02-06 01:41:05 -0800800 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
801 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
Matthew Smith28029532017-09-26 13:33:44 -0500802
Neale Ranns8d7c5022019-02-06 01:41:05 -0800803 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
804 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
Matthew Smith28029532017-09-26 13:33:44 -0500805
Neale Ranns8d7c5022019-02-06 01:41:05 -0800806 mp->entry.flags = ipsec_sad_flags_encode (sa);
Neale Ranns12989b52019-09-26 16:20:19 +0000807 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
808
809 if (ipsec_sa_is_set_IS_PROTECT (sa))
810 {
811 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000812 .sai = sa - ipsec_sa_pool,
813 .sw_if_index = ~0,
Neale Ranns12989b52019-09-26 16:20:19 +0000814 };
815 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
816
817 mp->sw_if_index = htonl (ctx.sw_if_index);
818 }
819 else
820 mp->sw_if_index = ~0;
Matthew Smith28029532017-09-26 13:33:44 -0500821
Damjan Mariond709cbc2019-03-26 13:16:42 +0100822 if (ipsec_sa_is_set_IS_TUNNEL (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500823 {
Neale Ranns9ec846c2021-02-09 14:04:02 +0000824 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
825 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -0500826 }
Neale Rannsabc56602020-04-01 09:45:23 +0000827 if (ipsec_sa_is_set_UDP_ENCAP (sa))
828 {
829 mp->entry.udp_src_port = sa->udp_hdr.src_port;
830 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
831 }
Matthew Smith28029532017-09-26 13:33:44 -0500832
Matthew Smith28029532017-09-26 13:33:44 -0500833 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns5b891102021-06-28 13:31:28 +0000834 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
Damjan Marion1e3aa5e2019-03-28 10:58:59 +0100835 if (ipsec_sa_is_set_USE_ESN (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500836 {
837 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns5b891102021-06-28 13:31:28 +0000838 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Matthew Smith28029532017-09-26 13:33:44 -0500839 }
Damjan Mariond709cbc2019-03-26 13:16:42 +0100840 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500841 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
Pierre Pfister4c422f92018-12-10 11:19:08 +0100842
Matthew Smith48d32b42020-04-02 07:45:49 -0500843 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
844
Neale Ranns12989b52019-09-26 16:20:19 +0000845 vl_api_send_msg (ctx->reg, (u8 *) mp);
Matthew Smith28029532017-09-26 13:33:44 -0500846
Neale Ranns12989b52019-09-26 16:20:19 +0000847 return (WALK_CONTINUE);
848}
Matthew Smith28029532017-09-26 13:33:44 -0500849
850static void
851vl_api_ipsec_sa_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
852{
Florin Coras6c4dae22018-01-09 06:39:23 -0800853 vl_api_registration_t *reg;
Matthew Smith28029532017-09-26 13:33:44 -0500854
Florin Coras6c4dae22018-01-09 06:39:23 -0800855 reg = vl_api_client_index_to_registration (mp->client_index);
Neale Ranns12989b52019-09-26 16:20:19 +0000856 if (!reg)
Matthew Smith28029532017-09-26 13:33:44 -0500857 return;
858
Neale Ranns12989b52019-09-26 16:20:19 +0000859 ipsec_dump_walk_ctx_t ctx = {
860 .reg = reg,
861 .context = mp->context,
862 };
Matthew Smith28029532017-09-26 13:33:44 -0500863
Neale Ranns12989b52019-09-26 16:20:19 +0000864 ipsec_sa_walk (send_ipsec_sa_details, &ctx);
Matthew Smith28029532017-09-26 13:33:44 -0500865}
866
Neale Ranns041add72020-01-02 04:06:10 +0000867static walk_rc_t
868send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg)
869{
870 ipsec_dump_walk_ctx_t *ctx = arg;
871 vl_api_ipsec_sa_v2_details_t *mp;
Neale Ranns041add72020-01-02 04:06:10 +0000872
873 mp = vl_msg_api_alloc (sizeof (*mp));
874 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000875 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_V2_DETAILS);
Neale Ranns041add72020-01-02 04:06:10 +0000876 mp->context = ctx->context;
877
878 mp->entry.sad_id = htonl (sa->id);
879 mp->entry.spi = htonl (sa->spi);
880 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000881 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
Neale Ranns041add72020-01-02 04:06:10 +0000882
883 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
884 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
885
886 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
887 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
888
889 mp->entry.flags = ipsec_sad_flags_encode (sa);
890 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
891
892 if (ipsec_sa_is_set_IS_PROTECT (sa))
893 {
894 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000895 .sai = sa - ipsec_sa_pool,
896 .sw_if_index = ~0,
Neale Ranns041add72020-01-02 04:06:10 +0000897 };
898 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
899
900 mp->sw_if_index = htonl (ctx.sw_if_index);
901 }
902 else
903 mp->sw_if_index = ~0;
904
905 if (ipsec_sa_is_set_IS_TUNNEL (sa))
906 {
Neale Ranns9ec846c2021-02-09 14:04:02 +0000907 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
908 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
Neale Ranns041add72020-01-02 04:06:10 +0000909 }
910 if (ipsec_sa_is_set_UDP_ENCAP (sa))
911 {
912 mp->entry.udp_src_port = sa->udp_hdr.src_port;
913 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
914 }
915
Neale Ranns9ec846c2021-02-09 14:04:02 +0000916 mp->entry.tunnel_flags =
917 tunnel_encap_decap_flags_encode (sa->tunnel.t_encap_decap_flags);
918 mp->entry.dscp = ip_dscp_encode (sa->tunnel.t_dscp);
Neale Ranns041add72020-01-02 04:06:10 +0000919
920 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns5b891102021-06-28 13:31:28 +0000921 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns041add72020-01-02 04:06:10 +0000922 if (ipsec_sa_is_set_USE_ESN (sa))
923 {
924 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns5b891102021-06-28 13:31:28 +0000925 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns041add72020-01-02 04:06:10 +0000926 }
927 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
928 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
929
930 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
931
932 vl_api_send_msg (ctx->reg, (u8 *) mp);
933
934 return (WALK_CONTINUE);
935}
936
937static void
Neale Ranns9ec846c2021-02-09 14:04:02 +0000938vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_v2_dump_t *mp)
Neale Ranns041add72020-01-02 04:06:10 +0000939{
940 vl_api_registration_t *reg;
941
Neale Ranns041add72020-01-02 04:06:10 +0000942 reg = vl_api_client_index_to_registration (mp->client_index);
943 if (!reg)
944 return;
945
946 ipsec_dump_walk_ctx_t ctx = {
947 .reg = reg,
948 .context = mp->context,
949 };
950
951 ipsec_sa_walk (send_ipsec_sa_v2_details, &ctx);
Neale Ranns041add72020-01-02 04:06:10 +0000952}
953
Neale Ranns9ec846c2021-02-09 14:04:02 +0000954static walk_rc_t
955send_ipsec_sa_v3_details (ipsec_sa_t *sa, void *arg)
956{
957 ipsec_dump_walk_ctx_t *ctx = arg;
958 vl_api_ipsec_sa_v3_details_t *mp;
Neale Ranns9ec846c2021-02-09 14:04:02 +0000959
960 mp = vl_msg_api_alloc (sizeof (*mp));
961 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +0000962 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_SA_V3_DETAILS);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000963 mp->context = ctx->context;
964
965 mp->entry.sad_id = htonl (sa->id);
966 mp->entry.spi = htonl (sa->spi);
967 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
968
969 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
970 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
971
972 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
973 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
974
975 mp->entry.flags = ipsec_sad_flags_encode (sa);
976 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
977
978 if (ipsec_sa_is_set_IS_PROTECT (sa))
979 {
980 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000981 .sai = sa - ipsec_sa_pool,
Neale Ranns9ec846c2021-02-09 14:04:02 +0000982 .sw_if_index = ~0,
983 };
984 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
985
986 mp->sw_if_index = htonl (ctx.sw_if_index);
987 }
988 else
989 mp->sw_if_index = ~0;
990
991 if (ipsec_sa_is_set_IS_TUNNEL (sa))
992 tunnel_encode (&sa->tunnel, &mp->entry.tunnel);
993
994 if (ipsec_sa_is_set_UDP_ENCAP (sa))
995 {
996 mp->entry.udp_src_port = sa->udp_hdr.src_port;
997 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
998 }
999
1000 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns5b891102021-06-28 13:31:28 +00001001 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->seq));
Neale Ranns9ec846c2021-02-09 14:04:02 +00001002 if (ipsec_sa_is_set_USE_ESN (sa))
1003 {
1004 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns5b891102021-06-28 13:31:28 +00001005 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
Neale Ranns9ec846c2021-02-09 14:04:02 +00001006 }
1007 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
1008 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
1009
1010 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
1011
1012 vl_api_send_msg (ctx->reg, (u8 *) mp);
1013
1014 return (WALK_CONTINUE);
1015}
1016
1017static void
1018vl_api_ipsec_sa_v3_dump_t_handler (vl_api_ipsec_sa_v3_dump_t *mp)
1019{
1020 vl_api_registration_t *reg;
1021
Neale Ranns9ec846c2021-02-09 14:04:02 +00001022 reg = vl_api_client_index_to_registration (mp->client_index);
1023 if (!reg)
1024 return;
1025
1026 ipsec_dump_walk_ctx_t ctx = {
1027 .reg = reg,
1028 .context = mp->context,
1029 };
1030
1031 ipsec_sa_walk (send_ipsec_sa_v3_details, &ctx);
Neale Ranns9ec846c2021-02-09 14:04:02 +00001032}
1033
Matthew Smith75d85602017-10-05 19:03:05 -05001034static void
Klement Sekerab4d30532018-11-08 13:00:02 +01001035vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp)
1036{
1037 vl_api_registration_t *rp;
1038 ipsec_main_t *im = &ipsec_main;
1039 u32 context = mp->context;
1040
1041 rp = vl_api_client_index_to_registration (mp->client_index);
1042
1043 if (rp == 0)
1044 {
1045 clib_warning ("Client %d AWOL", mp->client_index);
1046 return;
1047 }
1048
1049 ipsec_ah_backend_t *ab;
1050 ipsec_esp_backend_t *eb;
1051 /* *INDENT-OFF* */
Damjan Marionb2c31b62020-12-13 21:47:40 +01001052 pool_foreach (ab, im->ah_backends) {
Klement Sekerab4d30532018-11-08 13:00:02 +01001053 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1054 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +00001055 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_BACKEND_DETAILS);
Klement Sekerab4d30532018-11-08 13:00:02 +01001056 mp->context = context;
1057 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (ab->name),
1058 ab->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001059 mp->protocol = ntohl (IPSEC_API_PROTO_AH);
Klement Sekerab4d30532018-11-08 13:00:02 +01001060 mp->index = ab - im->ah_backends;
1061 mp->active = mp->index == im->ah_current_backend ? 1 : 0;
1062 vl_api_send_msg (rp, (u8 *)mp);
Damjan Marionb2c31b62020-12-13 21:47:40 +01001063 }
1064 pool_foreach (eb, im->esp_backends) {
Klement Sekerab4d30532018-11-08 13:00:02 +01001065 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1066 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlarc73f3292021-06-22 08:21:31 +00001067 mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_IPSEC_BACKEND_DETAILS);
Klement Sekerab4d30532018-11-08 13:00:02 +01001068 mp->context = context;
1069 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (eb->name),
1070 eb->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001071 mp->protocol = ntohl (IPSEC_API_PROTO_ESP);
Klement Sekerab4d30532018-11-08 13:00:02 +01001072 mp->index = eb - im->esp_backends;
1073 mp->active = mp->index == im->esp_current_backend ? 1 : 0;
1074 vl_api_send_msg (rp, (u8 *)mp);
Damjan Marionb2c31b62020-12-13 21:47:40 +01001075 }
Klement Sekerab4d30532018-11-08 13:00:02 +01001076 /* *INDENT-ON* */
1077}
1078
1079static void
1080vl_api_ipsec_select_backend_t_handler (vl_api_ipsec_select_backend_t * mp)
1081{
1082 ipsec_main_t *im = &ipsec_main;
1083 vl_api_ipsec_select_backend_reply_t *rmp;
Neale Ranns17dcec02019-01-09 21:22:20 -08001084 ipsec_protocol_t protocol;
Klement Sekerab4d30532018-11-08 13:00:02 +01001085 int rv = 0;
Neale Rannsc5fe57d2021-02-25 16:01:28 +00001086 if (pool_elts (ipsec_sa_pool) > 0)
Klement Sekerab4d30532018-11-08 13:00:02 +01001087 {
1088 rv = VNET_API_ERROR_INSTANCE_IN_USE;
1089 goto done;
1090 }
Neale Ranns17dcec02019-01-09 21:22:20 -08001091
1092 rv = ipsec_proto_decode (mp->protocol, &protocol);
1093
1094 if (rv)
1095 goto done;
1096
Neale Ranns17dcec02019-01-09 21:22:20 -08001097 switch (protocol)
Klement Sekerab4d30532018-11-08 13:00:02 +01001098 {
1099 case IPSEC_PROTOCOL_ESP:
Neale Rannse8915fc2019-04-23 20:57:55 -04001100 rv = ipsec_select_esp_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001101 break;
1102 case IPSEC_PROTOCOL_AH:
Neale Rannse8915fc2019-04-23 20:57:55 -04001103 rv = ipsec_select_ah_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001104 break;
1105 default:
Neale Rannse8915fc2019-04-23 20:57:55 -04001106 rv = VNET_API_ERROR_INVALID_PROTOCOL;
Klement Sekerab4d30532018-11-08 13:00:02 +01001107 break;
1108 }
Klement Sekerab4d30532018-11-08 13:00:02 +01001109done:
1110 REPLY_MACRO (VL_API_IPSEC_SELECT_BACKEND_REPLY);
1111}
1112
Yulong Pei2e84d662020-08-14 18:21:08 +08001113static void
1114vl_api_ipsec_set_async_mode_t_handler (vl_api_ipsec_set_async_mode_t * mp)
1115{
1116 vl_api_ipsec_set_async_mode_reply_t *rmp;
1117 int rv = 0;
1118
Yulong Pei2e84d662020-08-14 18:21:08 +08001119 ipsec_set_async_mode (mp->async_enable);
1120
1121 REPLY_MACRO (VL_API_IPSEC_SET_ASYNC_MODE_REPLY);
1122}
1123
Filip Tehlarc73f3292021-06-22 08:21:31 +00001124#include <vnet/ipsec/ipsec.api.c>
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001125static clib_error_t *
1126ipsec_api_hookup (vlib_main_t * vm)
1127{
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001128 /*
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001129 * Set up the (msg_name, crc, message-id) table
1130 */
Filip Tehlarc73f3292021-06-22 08:21:31 +00001131 REPLY_MSG_ID_BASE = setup_message_id_table ();
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001132
1133 return 0;
1134}
1135
1136VLIB_API_INIT_FUNCTION (ipsec_api_hookup);
1137
1138/*
1139 * fd.io coding-style-patch-verification: ON
1140 *
1141 * Local Variables:
1142 * eval: (c-set-style "gnu")
1143 * End:
1144 */