blob: b954a6eae9f609b70cbc1ecf4c70eb06f903d5c7 [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
33#include <vnet/vnet_msg_enum.h>
34
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010035#include <vnet/ipsec/ipsec.h>
Neale Rannsc87b66c2019-02-07 07:26:12 -080036#include <vnet/ipsec/ipsec_tun.h>
Neale Rannsdd4ccf22020-06-30 07:47:14 +000037#include <vnet/ipsec/ipsec_itf.h>
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010038
39#define vl_typedefs /* define message structures */
40#include <vnet/vnet_all_api_h.h>
41#undef vl_typedefs
42
43#define vl_endianfun /* define message structures */
44#include <vnet/vnet_all_api_h.h>
45#undef vl_endianfun
46
47/* instantiate all the print functions we know about */
48#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
49#define vl_printfun
50#include <vnet/vnet_all_api_h.h>
51#undef vl_printfun
52
53#include <vlibapi/api_helper_macros.h>
54
Neale Ranns9ec846c2021-02-09 14:04:02 +000055#define foreach_vpe_api_msg \
56 _ (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \
57 _ (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \
58 _ (IPSEC_SPD_ENTRY_ADD_DEL, ipsec_spd_entry_add_del) \
59 _ (IPSEC_SAD_ENTRY_ADD_DEL, ipsec_sad_entry_add_del) \
60 _ (IPSEC_SAD_ENTRY_ADD_DEL_V2, ipsec_sad_entry_add_del_v2) \
61 _ (IPSEC_SAD_ENTRY_ADD_DEL_V3, ipsec_sad_entry_add_del_v3) \
62 _ (IPSEC_SA_DUMP, ipsec_sa_dump) \
63 _ (IPSEC_SA_V2_DUMP, ipsec_sa_v2_dump) \
64 _ (IPSEC_SA_V3_DUMP, ipsec_sa_v3_dump) \
65 _ (IPSEC_SPDS_DUMP, ipsec_spds_dump) \
66 _ (IPSEC_SPD_DUMP, ipsec_spd_dump) \
67 _ (IPSEC_SPD_INTERFACE_DUMP, ipsec_spd_interface_dump) \
68 _ (IPSEC_ITF_CREATE, ipsec_itf_create) \
69 _ (IPSEC_ITF_DELETE, ipsec_itf_delete) \
70 _ (IPSEC_ITF_DUMP, ipsec_itf_dump) \
71 _ (IPSEC_SELECT_BACKEND, ipsec_select_backend) \
72 _ (IPSEC_BACKEND_DUMP, ipsec_backend_dump) \
73 _ (IPSEC_TUNNEL_PROTECT_UPDATE, ipsec_tunnel_protect_update) \
74 _ (IPSEC_TUNNEL_PROTECT_DEL, ipsec_tunnel_protect_del) \
75 _ (IPSEC_TUNNEL_PROTECT_DUMP, ipsec_tunnel_protect_dump) \
76 _ (IPSEC_SET_ASYNC_MODE, ipsec_set_async_mode)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010077
Klement Sekerab4d30532018-11-08 13:00:02 +010078static void
79vl_api_ipsec_spd_add_del_t_handler (vl_api_ipsec_spd_add_del_t * mp)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010080{
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010081 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
82 vl_api_ipsec_spd_add_del_reply_t *rmp;
83 int rv;
84
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010085 rv = ipsec_add_del_spd (vm, ntohl (mp->spd_id), mp->is_add);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010086
87 REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_REPLY);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010088}
89
90static void vl_api_ipsec_interface_add_del_spd_t_handler
91 (vl_api_ipsec_interface_add_del_spd_t * mp)
92{
93 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
94 vl_api_ipsec_interface_add_del_spd_reply_t *rmp;
95 int rv;
96 u32 sw_if_index __attribute__ ((unused));
97 u32 spd_id __attribute__ ((unused));
98
99 sw_if_index = ntohl (mp->sw_if_index);
100 spd_id = ntohl (mp->spd_id);
101
102 VALIDATE_SW_IF_INDEX (mp);
103
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100104 rv = ipsec_set_interface_spd (vm, sw_if_index, spd_id, mp->is_add);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100105
106 BAD_SW_IF_INDEX_LABEL;
107
108 REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY);
109}
110
Neale Rannsc87b66c2019-02-07 07:26:12 -0800111static void vl_api_ipsec_tunnel_protect_update_t_handler
112 (vl_api_ipsec_tunnel_protect_update_t * mp)
113{
114 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
115 vl_api_ipsec_tunnel_protect_update_reply_t *rmp;
116 u32 sw_if_index, ii, *sa_ins = NULL;
Neale Ranns28287212019-12-16 00:53:11 +0000117 ip_address_t nh;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800118 int rv;
119
120 sw_if_index = ntohl (mp->tunnel.sw_if_index);
121
122 VALIDATE_SW_IF_INDEX (&(mp->tunnel));
123
Neale Rannsc87b66c2019-02-07 07:26:12 -0800124 for (ii = 0; ii < mp->tunnel.n_sa_in; ii++)
125 vec_add1 (sa_ins, ntohl (mp->tunnel.sa_in[ii]));
126
Neale Ranns28287212019-12-16 00:53:11 +0000127 ip_address_decode2 (&mp->tunnel.nh, &nh);
128
129 rv = ipsec_tun_protect_update (sw_if_index, &nh,
Neale Rannsc87b66c2019-02-07 07:26:12 -0800130 ntohl (mp->tunnel.sa_out), sa_ins);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800131
132 BAD_SW_IF_INDEX_LABEL;
133
134 REPLY_MACRO (VL_API_IPSEC_TUNNEL_PROTECT_UPDATE_REPLY);
135}
136
137static void vl_api_ipsec_tunnel_protect_del_t_handler
138 (vl_api_ipsec_tunnel_protect_del_t * mp)
139{
140 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
141 vl_api_ipsec_tunnel_protect_del_reply_t *rmp;
Neale Ranns28287212019-12-16 00:53:11 +0000142 ip_address_t nh;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800143 u32 sw_if_index;
Neale Ranns28287212019-12-16 00:53:11 +0000144 int rv;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800145
146 sw_if_index = ntohl (mp->sw_if_index);
147
148 VALIDATE_SW_IF_INDEX (mp);
149
Neale Ranns28287212019-12-16 00:53:11 +0000150 ip_address_decode2 (&mp->nh, &nh);
151 rv = ipsec_tun_protect_del (sw_if_index, &nh);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800152
153 BAD_SW_IF_INDEX_LABEL;
154
155 REPLY_MACRO (VL_API_IPSEC_TUNNEL_PROTECT_DEL_REPLY);
156}
157
Neale Ranns12989b52019-09-26 16:20:19 +0000158typedef struct ipsec_dump_walk_ctx_t_
Neale Rannsc87b66c2019-02-07 07:26:12 -0800159{
160 vl_api_registration_t *reg;
161 u32 context;
Neale Ranns12989b52019-09-26 16:20:19 +0000162} ipsec_dump_walk_ctx_t;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800163
164static walk_rc_t
165send_ipsec_tunnel_protect_details (index_t itpi, void *arg)
166{
Neale Ranns12989b52019-09-26 16:20:19 +0000167 ipsec_dump_walk_ctx_t *ctx = arg;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800168 vl_api_ipsec_tunnel_protect_details_t *mp;
169 ipsec_tun_protect_t *itp;
Matthew Smith5cee0bc2020-03-31 09:52:17 -0500170 u32 ii = 0;
171 ipsec_sa_t *sa;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800172
173 itp = ipsec_tun_protect_get (itpi);
174
Neale Rannsc87b66c2019-02-07 07:26:12 -0800175 mp = vl_msg_api_alloc (sizeof (*mp) + (sizeof (u32) * itp->itp_n_sa_in));
176 clib_memset (mp, 0, sizeof (*mp));
177 mp->_vl_msg_id = ntohs (VL_API_IPSEC_TUNNEL_PROTECT_DETAILS);
178 mp->context = ctx->context;
179
180 mp->tun.sw_if_index = htonl (itp->itp_sw_if_index);
Neale Ranns28287212019-12-16 00:53:11 +0000181 ip_address_encode2 (itp->itp_key, &mp->tun.nh);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800182
Matthew Smith5cee0bc2020-03-31 09:52:17 -0500183 sa = ipsec_sa_get (itp->itp_out_sa);
184 mp->tun.sa_out = htonl (sa->id);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800185 mp->tun.n_sa_in = itp->itp_n_sa_in;
186 /* *INDENT-OFF* */
Matthew Smith5cee0bc2020-03-31 09:52:17 -0500187 FOR_EACH_IPSEC_PROTECT_INPUT_SA(itp, sa,
Neale Rannsc87b66c2019-02-07 07:26:12 -0800188 ({
Matthew Smith5cee0bc2020-03-31 09:52:17 -0500189 mp->tun.sa_in[ii++] = htonl (sa->id);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800190 }));
191 /* *INDENT-ON* */
192
193 vl_api_send_msg (ctx->reg, (u8 *) mp);
194
195 return (WALK_CONTINUE);
196}
197
198static void
199vl_api_ipsec_tunnel_protect_dump_t_handler (vl_api_ipsec_tunnel_protect_dump_t
200 * mp)
201{
202 vl_api_registration_t *reg;
203 u32 sw_if_index;
204
Neale Rannsc87b66c2019-02-07 07:26:12 -0800205 reg = vl_api_client_index_to_registration (mp->client_index);
206 if (!reg)
207 return;
208
Neale Ranns12989b52019-09-26 16:20:19 +0000209 ipsec_dump_walk_ctx_t ctx = {
Neale Rannsc87b66c2019-02-07 07:26:12 -0800210 .reg = reg,
211 .context = mp->context,
212 };
213
214 sw_if_index = ntohl (mp->sw_if_index);
215
216 if (~0 == sw_if_index)
217 {
218 ipsec_tun_protect_walk (send_ipsec_tunnel_protect_details, &ctx);
219 }
220 else
221 {
Neale Ranns28287212019-12-16 00:53:11 +0000222 ipsec_tun_protect_walk_itf (sw_if_index,
223 send_ipsec_tunnel_protect_details, &ctx);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800224 }
Neale Rannsc87b66c2019-02-07 07:26:12 -0800225}
226
Neale Ranns17dcec02019-01-09 21:22:20 -0800227static int
228ipsec_spd_action_decode (vl_api_ipsec_spd_action_t in,
229 ipsec_policy_action_t * out)
230{
231 in = clib_net_to_host_u32 (in);
232
233 switch (in)
234 {
235#define _(v,f,s) case IPSEC_API_SPD_ACTION_##f: \
236 *out = IPSEC_POLICY_ACTION_##f; \
237 return (0);
238 foreach_ipsec_policy_action
239#undef _
240 }
241 return (VNET_API_ERROR_UNIMPLEMENTED);
242}
243
244static void vl_api_ipsec_spd_entry_add_del_t_handler
245 (vl_api_ipsec_spd_entry_add_del_t * mp)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100246{
247 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
Neale Ranns17dcec02019-01-09 21:22:20 -0800248 vl_api_ipsec_spd_entry_add_del_reply_t *rmp;
249 ip46_type_t itype;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800250 u32 stat_index;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100251 int rv;
252
Neale Ranns8c2dd1b2019-02-19 08:27:34 -0800253 stat_index = ~0;
254
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100255 ipsec_policy_t p;
256
Dave Barachb7b92992018-10-17 10:38:51 -0400257 clib_memset (&p, 0, sizeof (p));
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100258
Neale Ranns17dcec02019-01-09 21:22:20 -0800259 p.id = ntohl (mp->entry.spd_id);
260 p.priority = ntohl (mp->entry.priority);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100261
Neale Ranns17dcec02019-01-09 21:22:20 -0800262 itype = ip_address_decode (&mp->entry.remote_address_start, &p.raddr.start);
263 ip_address_decode (&mp->entry.remote_address_stop, &p.raddr.stop);
264 ip_address_decode (&mp->entry.local_address_start, &p.laddr.start);
265 ip_address_decode (&mp->entry.local_address_stop, &p.laddr.stop);
266
267 p.is_ipv6 = (itype == IP46_TYPE_IP6);
268
269 p.protocol = mp->entry.protocol;
Neale Rannsa4d24312019-07-10 13:46:21 +0000270 p.rport.start = ntohs (mp->entry.remote_port_start);
271 p.rport.stop = ntohs (mp->entry.remote_port_stop);
272 p.lport.start = ntohs (mp->entry.local_port_start);
273 p.lport.stop = ntohs (mp->entry.local_port_stop);
Neale Ranns17dcec02019-01-09 21:22:20 -0800274
275 rv = ipsec_spd_action_decode (mp->entry.policy, &p.policy);
276
277 if (rv)
278 goto out;
279
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100280 /* policy action resolve unsupported */
Neale Ranns17dcec02019-01-09 21:22:20 -0800281 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100282 {
283 clib_warning ("unsupported action: 'resolve'");
284 rv = VNET_API_ERROR_UNIMPLEMENTED;
285 goto out;
286 }
Neale Ranns17dcec02019-01-09 21:22:20 -0800287 p.sa_id = ntohl (mp->entry.sa_id);
Neale Ranns9f231d42019-03-19 10:06:00 +0000288 rv =
289 ipsec_policy_mk_type (mp->entry.is_outbound, p.is_ipv6, p.policy,
290 &p.type);
291 if (rv)
292 goto out;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100293
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800294 rv = ipsec_add_del_policy (vm, &p, mp->is_add, &stat_index);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100295 if (rv)
296 goto out;
297
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100298out:
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800299 /* *INDENT-OFF* */
300 REPLY_MACRO2 (VL_API_IPSEC_SPD_ENTRY_ADD_DEL_REPLY,
301 ({
302 rmp->stat_index = ntohl(stat_index);
303 }));
304 /* *INDENT-ON* */
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100305}
306
Neale Ranns17dcec02019-01-09 21:22:20 -0800307static void vl_api_ipsec_sad_entry_add_del_t_handler
308 (vl_api_ipsec_sad_entry_add_del_t * mp)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100309{
Neale Ranns17dcec02019-01-09 21:22:20 -0800310 vl_api_ipsec_sad_entry_add_del_reply_t *rmp;
Neale Ranns8d7c5022019-02-06 01:41:05 -0800311 ipsec_key_t crypto_key, integ_key;
312 ipsec_crypto_alg_t crypto_alg;
313 ipsec_integ_alg_t integ_alg;
314 ipsec_protocol_t proto;
315 ipsec_sa_flags_t flags;
Dave Baracha5160d72019-03-13 15:29:15 -0400316 u32 id, spi, sa_index = ~0;
Neale Ranns9ec846c2021-02-09 14:04:02 +0000317 tunnel_t tun = {
318 .t_flags = TUNNEL_FLAG_NONE,
319 .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE,
320 .t_dscp = 0,
321 .t_mode = TUNNEL_MODE_P2P,
322 .t_table_id = 0,
323 .t_hop_limit = 255,
324 };
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100325 int rv;
Neale Ranns8d7c5022019-02-06 01:41:05 -0800326
Neale Ranns8d7c5022019-02-06 01:41:05 -0800327 id = ntohl (mp->entry.sad_id);
328 spi = ntohl (mp->entry.spi);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100329
Neale Ranns8d7c5022019-02-06 01:41:05 -0800330 rv = ipsec_proto_decode (mp->entry.protocol, &proto);
Neale Ranns17dcec02019-01-09 21:22:20 -0800331
332 if (rv)
333 goto out;
334
Neale Ranns8d7c5022019-02-06 01:41:05 -0800335 rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
Neale Ranns17dcec02019-01-09 21:22:20 -0800336
337 if (rv)
338 goto out;
339
Neale Ranns8d7c5022019-02-06 01:41:05 -0800340 rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
Neale Ranns17dcec02019-01-09 21:22:20 -0800341
342 if (rv)
343 goto out;
344
Neale Ranns8d7c5022019-02-06 01:41:05 -0800345 ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
346 ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
Neale Ranns17dcec02019-01-09 21:22:20 -0800347
Neale Ranns8d7c5022019-02-06 01:41:05 -0800348 flags = ipsec_sa_flags_decode (mp->entry.flags);
Neale Ranns17dcec02019-01-09 21:22:20 -0800349
Neale Ranns9ec846c2021-02-09 14:04:02 +0000350 ip_address_decode2 (&mp->entry.tunnel_src, &tun.t_src);
351 ip_address_decode2 (&mp->entry.tunnel_dst, &tun.t_dst);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100352
Neale Ranns8d7c5022019-02-06 01:41:05 -0800353 if (mp->is_add)
Neale Ranns9ec846c2021-02-09 14:04:02 +0000354 rv = ipsec_sa_add_and_lock (
355 id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
356 mp->entry.salt, htons (mp->entry.udp_src_port),
357 htons (mp->entry.udp_dst_port), &tun, &sa_index);
Neale Ranns8d7c5022019-02-06 01:41:05 -0800358 else
Neale Ranns495d7ff2019-07-12 09:15:26 +0000359 rv = ipsec_sa_unlock_id (id);
Neale Ranns8d7c5022019-02-06 01:41:05 -0800360
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100361out:
Neale Rannseba31ec2019-02-17 18:04:27 +0000362 /* *INDENT-OFF* */
363 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_REPLY,
364 {
365 rmp->stat_index = htonl (sa_index);
366 });
367 /* *INDENT-ON* */
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100368}
369
Neale Ranns041add72020-01-02 04:06:10 +0000370static void vl_api_ipsec_sad_entry_add_del_v2_t_handler
371 (vl_api_ipsec_sad_entry_add_del_v2_t * mp)
372{
373 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
374 vl_api_ipsec_sad_entry_add_del_v2_reply_t *rmp;
Neale Ranns041add72020-01-02 04:06:10 +0000375 ipsec_key_t crypto_key, integ_key;
376 ipsec_crypto_alg_t crypto_alg;
377 ipsec_integ_alg_t integ_alg;
378 ipsec_protocol_t proto;
379 ipsec_sa_flags_t flags;
380 u32 id, spi, sa_index = ~0;
381 int rv;
Neale Ranns9ec846c2021-02-09 14:04:02 +0000382 tunnel_t tun = {
383 .t_flags = TUNNEL_FLAG_NONE,
384 .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE,
385 .t_dscp = 0,
386 .t_mode = TUNNEL_MODE_P2P,
387 .t_table_id = htonl (mp->entry.tx_table_id),
388 .t_hop_limit = 255,
389 };
390
Neale Ranns9ec846c2021-02-09 14:04:02 +0000391 id = ntohl (mp->entry.sad_id);
392 spi = ntohl (mp->entry.spi);
393
394 rv = ipsec_proto_decode (mp->entry.protocol, &proto);
395
396 if (rv)
397 goto out;
398
399 rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
400
401 if (rv)
402 goto out;
403
404 rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
405
406 if (rv)
407 goto out;
408
409 rv = tunnel_encap_decap_flags_decode (mp->entry.tunnel_flags,
410 &tun.t_encap_decap_flags);
411
412 if (rv)
413 goto out;
414
415 ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
416 ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
417
418 flags = ipsec_sa_flags_decode (mp->entry.flags);
419 tun.t_dscp = ip_dscp_decode (mp->entry.dscp);
420
421 ip_address_decode2 (&mp->entry.tunnel_src, &tun.t_src);
422 ip_address_decode2 (&mp->entry.tunnel_dst, &tun.t_dst);
423
424 if (mp->is_add)
425 rv = ipsec_sa_add_and_lock (
426 id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
427 mp->entry.salt, htons (mp->entry.udp_src_port),
428 htons (mp->entry.udp_dst_port), &tun, &sa_index);
429 else
430 rv = ipsec_sa_unlock_id (id);
431
Neale Ranns9ec846c2021-02-09 14:04:02 +0000432out:
433 /* *INDENT-OFF* */
434 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_V2_REPLY,
435 {
436 rmp->stat_index = htonl (sa_index);
437 });
438 /* *INDENT-ON* */
439}
440
441static void
442vl_api_ipsec_sad_entry_add_del_v3_t_handler (
443 vl_api_ipsec_sad_entry_add_del_v3_t *mp)
444{
445 vl_api_ipsec_sad_entry_add_del_v3_reply_t *rmp;
446 ipsec_key_t crypto_key, integ_key;
447 ipsec_crypto_alg_t crypto_alg;
448 ipsec_integ_alg_t integ_alg;
449 ipsec_protocol_t proto;
450 ipsec_sa_flags_t flags;
451 u32 id, spi, sa_index = ~0;
452 tunnel_t tun;
453 int rv;
Neale Rannsc7eaa712021-02-04 11:09:33 +0000454
Neale Rannsc7eaa712021-02-04 11:09:33 +0000455 id = ntohl (mp->entry.sad_id);
456 spi = ntohl (mp->entry.spi);
457
458 rv = ipsec_proto_decode (mp->entry.protocol, &proto);
459
460 if (rv)
461 goto out;
462
463 rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
464
465 if (rv)
466 goto out;
467
468 rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
469
470 if (rv)
471 goto out;
472
Neale Ranns9ec846c2021-02-09 14:04:02 +0000473 flags = ipsec_sa_flags_decode (mp->entry.flags);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000474
Neale Ranns9ec846c2021-02-09 14:04:02 +0000475 if (flags & IPSEC_SA_FLAG_IS_TUNNEL)
476 {
477 rv = tunnel_decode (&mp->entry.tunnel, &tun);
478
479 if (rv)
480 goto out;
481 }
Neale Rannsc7eaa712021-02-04 11:09:33 +0000482
483 ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
484 ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
485
Neale Rannsc7eaa712021-02-04 11:09:33 +0000486 if (mp->is_add)
487 rv = ipsec_sa_add_and_lock (
488 id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
Neale Ranns9ec846c2021-02-09 14:04:02 +0000489 mp->entry.salt, htons (mp->entry.udp_src_port),
490 htons (mp->entry.udp_dst_port), &tun, &sa_index);
Neale Rannsc7eaa712021-02-04 11:09:33 +0000491 else
492 rv = ipsec_sa_unlock_id (id);
493
Neale Rannsc7eaa712021-02-04 11:09:33 +0000494out:
Neale Ranns9ec846c2021-02-09 14:04:02 +0000495 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_V3_REPLY,
496 { rmp->stat_index = htonl (sa_index); });
Neale Rannsc7eaa712021-02-04 11:09:33 +0000497}
498
499static void
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700500send_ipsec_spds_details (ipsec_spd_t * spd, vl_api_registration_t * reg,
501 u32 context)
502{
503 vl_api_ipsec_spds_details_t *mp;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800504 u32 n_policies = 0;
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700505
506 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400507 clib_memset (mp, 0, sizeof (*mp));
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700508 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPDS_DETAILS);
509 mp->context = context;
510
511 mp->spd_id = htonl (spd->id);
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800512#define _(s, n) n_policies += vec_len (spd->policies[IPSEC_SPD_POLICY_##s]);
513 foreach_ipsec_spd_policy_type
514#undef _
515 mp->npolicies = htonl (n_policies);
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700516
517 vl_api_send_msg (reg, (u8 *) mp);
518}
519
520static void
521vl_api_ipsec_spds_dump_t_handler (vl_api_ipsec_spds_dump_t * mp)
522{
523 vl_api_registration_t *reg;
524 ipsec_main_t *im = &ipsec_main;
525 ipsec_spd_t *spd;
Damjan Marion97898982021-04-19 18:15:31 +0200526
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700527 reg = vl_api_client_index_to_registration (mp->client_index);
528 if (!reg)
529 return;
530
Damjan Marionb2c31b62020-12-13 21:47:40 +0100531 pool_foreach (spd, im->spds) {
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700532 send_ipsec_spds_details (spd, reg, mp->context);
Damjan Marionb2c31b62020-12-13 21:47:40 +0100533 }
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700534}
535
Neale Ranns17dcec02019-01-09 21:22:20 -0800536vl_api_ipsec_spd_action_t
537ipsec_spd_action_encode (ipsec_policy_action_t in)
538{
539 vl_api_ipsec_spd_action_t out = IPSEC_API_SPD_ACTION_BYPASS;
540
541 switch (in)
542 {
543#define _(v,f,s) case IPSEC_POLICY_ACTION_##f: \
544 out = IPSEC_API_SPD_ACTION_##f; \
545 break;
546 foreach_ipsec_policy_action
547#undef _
548 }
549 return (clib_host_to_net_u32 (out));
550}
551
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700552static void
Florin Coras6c4dae22018-01-09 06:39:23 -0800553send_ipsec_spd_details (ipsec_policy_t * p, vl_api_registration_t * reg,
554 u32 context)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100555{
556 vl_api_ipsec_spd_details_t *mp;
557
558 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400559 clib_memset (mp, 0, sizeof (*mp));
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100560 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_DETAILS);
561 mp->context = context;
562
Neale Ranns17dcec02019-01-09 21:22:20 -0800563 mp->entry.spd_id = htonl (p->id);
564 mp->entry.priority = htonl (p->priority);
Neale Ranns9f231d42019-03-19 10:06:00 +0000565 mp->entry.is_outbound = ((p->type == IPSEC_SPD_POLICY_IP6_OUTBOUND) ||
566 (p->type == IPSEC_SPD_POLICY_IP4_OUTBOUND));
Neale Ranns17dcec02019-01-09 21:22:20 -0800567
568 ip_address_encode (&p->laddr.start, IP46_TYPE_ANY,
569 &mp->entry.local_address_start);
570 ip_address_encode (&p->laddr.stop, IP46_TYPE_ANY,
571 &mp->entry.local_address_stop);
572 ip_address_encode (&p->raddr.start, IP46_TYPE_ANY,
573 &mp->entry.remote_address_start);
574 ip_address_encode (&p->raddr.stop, IP46_TYPE_ANY,
575 &mp->entry.remote_address_stop);
Neale Rannsa4d24312019-07-10 13:46:21 +0000576 mp->entry.local_port_start = htons (p->lport.start);
577 mp->entry.local_port_stop = htons (p->lport.stop);
578 mp->entry.remote_port_start = htons (p->rport.start);
579 mp->entry.remote_port_stop = htons (p->rport.stop);
Neale Ranns17dcec02019-01-09 21:22:20 -0800580 mp->entry.protocol = p->protocol;
581 mp->entry.policy = ipsec_spd_action_encode (p->policy);
582 mp->entry.sa_id = htonl (p->sa_id);
583
Florin Coras6c4dae22018-01-09 06:39:23 -0800584 vl_api_send_msg (reg, (u8 *) mp);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100585}
586
587static void
588vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp)
589{
Florin Coras6c4dae22018-01-09 06:39:23 -0800590 vl_api_registration_t *reg;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100591 ipsec_main_t *im = &ipsec_main;
Neale Ranns9f231d42019-03-19 10:06:00 +0000592 ipsec_spd_policy_type_t ptype;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100593 ipsec_policy_t *policy;
594 ipsec_spd_t *spd;
595 uword *p;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800596 u32 spd_index, *ii;
Damjan Marion97898982021-04-19 18:15:31 +0200597
Florin Coras6c4dae22018-01-09 06:39:23 -0800598 reg = vl_api_client_index_to_registration (mp->client_index);
599 if (!reg)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100600 return;
601
602 p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id));
603 if (!p)
604 return;
605
606 spd_index = p[0];
607 spd = pool_elt_at_index (im->spds, spd_index);
608
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800609 FOR_EACH_IPSEC_SPD_POLICY_TYPE(ptype) {
610 vec_foreach(ii, spd->policies[ptype])
611 {
612 policy = pool_elt_at_index(im->policies, *ii);
613
614 if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id)
615 send_ipsec_spd_details (policy, reg, mp->context);
616 }
617 }
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100618}
619
620static void
Filip Varga871bca92018-11-02 13:51:44 +0100621send_ipsec_spd_interface_details (vl_api_registration_t * reg, u32 spd_index,
622 u32 sw_if_index, u32 context)
623{
624 vl_api_ipsec_spd_interface_details_t *mp;
625
626 mp = vl_msg_api_alloc (sizeof (*mp));
627 clib_memset (mp, 0, sizeof (*mp));
628 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_INTERFACE_DETAILS);
629 mp->context = context;
630
631 mp->spd_index = htonl (spd_index);
632 mp->sw_if_index = htonl (sw_if_index);
633
634 vl_api_send_msg (reg, (u8 *) mp);
635}
636
637static void
638vl_api_ipsec_spd_interface_dump_t_handler (vl_api_ipsec_spd_interface_dump_t *
639 mp)
640{
641 ipsec_main_t *im = &ipsec_main;
642 vl_api_registration_t *reg;
643 u32 k, v, spd_index;
644
Filip Varga871bca92018-11-02 13:51:44 +0100645 reg = vl_api_client_index_to_registration (mp->client_index);
646 if (!reg)
647 return;
648
649 if (mp->spd_index_valid)
650 {
651 spd_index = ntohl (mp->spd_index);
652 /* *INDENT-OFF* */
653 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
654 if (v == spd_index)
655 send_ipsec_spd_interface_details(reg, v, k, mp->context);
656 }));
657 /* *INDENT-ON* */
658 }
659 else
660 {
Filip Varga871bca92018-11-02 13:51:44 +0100661 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
662 send_ipsec_spd_interface_details(reg, v, k, mp->context);
663 }));
Filip Varga871bca92018-11-02 13:51:44 +0100664 }
Filip Varga871bca92018-11-02 13:51:44 +0100665}
666
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000667static void
668vl_api_ipsec_itf_create_t_handler (vl_api_ipsec_itf_create_t * mp)
669{
670 vl_api_ipsec_itf_create_reply_t *rmp;
671 tunnel_mode_t mode;
672 u32 sw_if_index = ~0;
673 int rv;
674
675 rv = tunnel_mode_decode (mp->itf.mode, &mode);
676
677 if (!rv)
678 rv = ipsec_itf_create (ntohl (mp->itf.user_instance), mode, &sw_if_index);
679
680 /* *INDENT-OFF* */
681 REPLY_MACRO2 (VL_API_IPSEC_ITF_CREATE_REPLY,
682 ({
683 rmp->sw_if_index = htonl (sw_if_index);
684 }));
685 /* *INDENT-ON* */
686}
687
688static void
689vl_api_ipsec_itf_delete_t_handler (vl_api_ipsec_itf_delete_t * mp)
690{
691 vl_api_ipsec_itf_delete_reply_t *rmp;
692 int rv;
693
694 rv = ipsec_itf_delete (ntohl (mp->sw_if_index));
695
696 REPLY_MACRO (VL_API_IPSEC_ITF_DELETE_REPLY);
697}
698
699static void
700vl_api_ipsec_itf_dump_t_handler (vl_api_ipsec_itf_dump_t * mp)
701{
702}
703
Neale Ranns12989b52019-09-26 16:20:19 +0000704typedef struct ipsec_sa_dump_match_ctx_t_
Matthew Smith28029532017-09-26 13:33:44 -0500705{
Neale Ranns12989b52019-09-26 16:20:19 +0000706 index_t sai;
707 u32 sw_if_index;
708} ipsec_sa_dump_match_ctx_t;
709
710static walk_rc_t
711ipsec_sa_dump_match_sa (index_t itpi, void *arg)
712{
713 ipsec_sa_dump_match_ctx_t *ctx = arg;
714 ipsec_tun_protect_t *itp;
715 index_t sai;
716
717 itp = ipsec_tun_protect_get (itpi);
718
719 if (itp->itp_out_sa == ctx->sai)
720 {
721 ctx->sw_if_index = itp->itp_sw_if_index;
722 return (WALK_STOP);
723 }
Damjan Marion97898982021-04-19 18:15:31 +0200724
Neale Ranns12989b52019-09-26 16:20:19 +0000725 FOR_EACH_IPSEC_PROTECT_INPUT_SAI (itp, sai,
726 ({
727 if (sai == ctx->sai)
728 {
729 ctx->sw_if_index = itp->itp_sw_if_index;
730 return (WALK_STOP);
731 }
732 }));
Neale Ranns12989b52019-09-26 16:20:19 +0000733
734 return (WALK_CONTINUE);
735}
736
737static walk_rc_t
738send_ipsec_sa_details (ipsec_sa_t * sa, void *arg)
739{
740 ipsec_dump_walk_ctx_t *ctx = arg;
Matthew Smith28029532017-09-26 13:33:44 -0500741 vl_api_ipsec_sa_details_t *mp;
742
743 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400744 clib_memset (mp, 0, sizeof (*mp));
Matthew Smith28029532017-09-26 13:33:44 -0500745 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_DETAILS);
Neale Ranns12989b52019-09-26 16:20:19 +0000746 mp->context = ctx->context;
Matthew Smith28029532017-09-26 13:33:44 -0500747
Neale Ranns8d7c5022019-02-06 01:41:05 -0800748 mp->entry.sad_id = htonl (sa->id);
749 mp->entry.spi = htonl (sa->spi);
750 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000751 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
Matthew Smith28029532017-09-26 13:33:44 -0500752
Neale Ranns8d7c5022019-02-06 01:41:05 -0800753 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
754 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
Matthew Smith28029532017-09-26 13:33:44 -0500755
Neale Ranns8d7c5022019-02-06 01:41:05 -0800756 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
757 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
Matthew Smith28029532017-09-26 13:33:44 -0500758
Neale Ranns8d7c5022019-02-06 01:41:05 -0800759 mp->entry.flags = ipsec_sad_flags_encode (sa);
Neale Ranns12989b52019-09-26 16:20:19 +0000760 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
761
762 if (ipsec_sa_is_set_IS_PROTECT (sa))
763 {
764 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000765 .sai = sa - ipsec_sa_pool,
766 .sw_if_index = ~0,
Neale Ranns12989b52019-09-26 16:20:19 +0000767 };
768 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
769
770 mp->sw_if_index = htonl (ctx.sw_if_index);
771 }
772 else
773 mp->sw_if_index = ~0;
Matthew Smith28029532017-09-26 13:33:44 -0500774
Damjan Mariond709cbc2019-03-26 13:16:42 +0100775 if (ipsec_sa_is_set_IS_TUNNEL (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500776 {
Neale Ranns9ec846c2021-02-09 14:04:02 +0000777 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
778 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -0500779 }
Neale Rannsabc56602020-04-01 09:45:23 +0000780 if (ipsec_sa_is_set_UDP_ENCAP (sa))
781 {
782 mp->entry.udp_src_port = sa->udp_hdr.src_port;
783 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
784 }
Matthew Smith28029532017-09-26 13:33:44 -0500785
Matthew Smith28029532017-09-26 13:33:44 -0500786 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
787 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
Damjan Marion1e3aa5e2019-03-28 10:58:59 +0100788 if (ipsec_sa_is_set_USE_ESN (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500789 {
790 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
791 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
792 }
Damjan Mariond709cbc2019-03-26 13:16:42 +0100793 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500794 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
Pierre Pfister4c422f92018-12-10 11:19:08 +0100795
Matthew Smith48d32b42020-04-02 07:45:49 -0500796 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
797
Neale Ranns12989b52019-09-26 16:20:19 +0000798 vl_api_send_msg (ctx->reg, (u8 *) mp);
Matthew Smith28029532017-09-26 13:33:44 -0500799
Neale Ranns12989b52019-09-26 16:20:19 +0000800 return (WALK_CONTINUE);
801}
Matthew Smith28029532017-09-26 13:33:44 -0500802
803static void
804vl_api_ipsec_sa_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
805{
Florin Coras6c4dae22018-01-09 06:39:23 -0800806 vl_api_registration_t *reg;
Matthew Smith28029532017-09-26 13:33:44 -0500807
Florin Coras6c4dae22018-01-09 06:39:23 -0800808 reg = vl_api_client_index_to_registration (mp->client_index);
Neale Ranns12989b52019-09-26 16:20:19 +0000809 if (!reg)
Matthew Smith28029532017-09-26 13:33:44 -0500810 return;
811
Neale Ranns12989b52019-09-26 16:20:19 +0000812 ipsec_dump_walk_ctx_t ctx = {
813 .reg = reg,
814 .context = mp->context,
815 };
Matthew Smith28029532017-09-26 13:33:44 -0500816
Neale Ranns12989b52019-09-26 16:20:19 +0000817 ipsec_sa_walk (send_ipsec_sa_details, &ctx);
Matthew Smith28029532017-09-26 13:33:44 -0500818}
819
Neale Ranns041add72020-01-02 04:06:10 +0000820static walk_rc_t
821send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg)
822{
823 ipsec_dump_walk_ctx_t *ctx = arg;
824 vl_api_ipsec_sa_v2_details_t *mp;
Neale Ranns041add72020-01-02 04:06:10 +0000825
826 mp = vl_msg_api_alloc (sizeof (*mp));
827 clib_memset (mp, 0, sizeof (*mp));
828 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_V2_DETAILS);
829 mp->context = ctx->context;
830
831 mp->entry.sad_id = htonl (sa->id);
832 mp->entry.spi = htonl (sa->spi);
833 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000834 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
Neale Ranns041add72020-01-02 04:06:10 +0000835
836 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
837 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
838
839 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
840 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
841
842 mp->entry.flags = ipsec_sad_flags_encode (sa);
843 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
844
845 if (ipsec_sa_is_set_IS_PROTECT (sa))
846 {
847 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000848 .sai = sa - ipsec_sa_pool,
849 .sw_if_index = ~0,
Neale Ranns041add72020-01-02 04:06:10 +0000850 };
851 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
852
853 mp->sw_if_index = htonl (ctx.sw_if_index);
854 }
855 else
856 mp->sw_if_index = ~0;
857
858 if (ipsec_sa_is_set_IS_TUNNEL (sa))
859 {
Neale Ranns9ec846c2021-02-09 14:04:02 +0000860 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
861 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
Neale Ranns041add72020-01-02 04:06:10 +0000862 }
863 if (ipsec_sa_is_set_UDP_ENCAP (sa))
864 {
865 mp->entry.udp_src_port = sa->udp_hdr.src_port;
866 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
867 }
868
Neale Ranns9ec846c2021-02-09 14:04:02 +0000869 mp->entry.tunnel_flags =
870 tunnel_encap_decap_flags_encode (sa->tunnel.t_encap_decap_flags);
871 mp->entry.dscp = ip_dscp_encode (sa->tunnel.t_dscp);
Neale Ranns041add72020-01-02 04:06:10 +0000872
873 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
874 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
875 if (ipsec_sa_is_set_USE_ESN (sa))
876 {
877 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
878 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
879 }
880 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
881 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
882
883 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
884
885 vl_api_send_msg (ctx->reg, (u8 *) mp);
886
887 return (WALK_CONTINUE);
888}
889
890static void
Neale Ranns9ec846c2021-02-09 14:04:02 +0000891vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_v2_dump_t *mp)
Neale Ranns041add72020-01-02 04:06:10 +0000892{
893 vl_api_registration_t *reg;
894
Neale Ranns041add72020-01-02 04:06:10 +0000895 reg = vl_api_client_index_to_registration (mp->client_index);
896 if (!reg)
897 return;
898
899 ipsec_dump_walk_ctx_t ctx = {
900 .reg = reg,
901 .context = mp->context,
902 };
903
904 ipsec_sa_walk (send_ipsec_sa_v2_details, &ctx);
Neale Ranns041add72020-01-02 04:06:10 +0000905}
906
Neale Ranns9ec846c2021-02-09 14:04:02 +0000907static walk_rc_t
908send_ipsec_sa_v3_details (ipsec_sa_t *sa, void *arg)
909{
910 ipsec_dump_walk_ctx_t *ctx = arg;
911 vl_api_ipsec_sa_v3_details_t *mp;
Neale Ranns9ec846c2021-02-09 14:04:02 +0000912
913 mp = vl_msg_api_alloc (sizeof (*mp));
914 clib_memset (mp, 0, sizeof (*mp));
915 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_V3_DETAILS);
916 mp->context = ctx->context;
917
918 mp->entry.sad_id = htonl (sa->id);
919 mp->entry.spi = htonl (sa->spi);
920 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
921
922 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
923 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
924
925 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
926 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
927
928 mp->entry.flags = ipsec_sad_flags_encode (sa);
929 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
930
931 if (ipsec_sa_is_set_IS_PROTECT (sa))
932 {
933 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000934 .sai = sa - ipsec_sa_pool,
Neale Ranns9ec846c2021-02-09 14:04:02 +0000935 .sw_if_index = ~0,
936 };
937 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
938
939 mp->sw_if_index = htonl (ctx.sw_if_index);
940 }
941 else
942 mp->sw_if_index = ~0;
943
944 if (ipsec_sa_is_set_IS_TUNNEL (sa))
945 tunnel_encode (&sa->tunnel, &mp->entry.tunnel);
946
947 if (ipsec_sa_is_set_UDP_ENCAP (sa))
948 {
949 mp->entry.udp_src_port = sa->udp_hdr.src_port;
950 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
951 }
952
953 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
954 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
955 if (ipsec_sa_is_set_USE_ESN (sa))
956 {
957 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
958 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
959 }
960 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
961 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
962
963 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
964
965 vl_api_send_msg (ctx->reg, (u8 *) mp);
966
967 return (WALK_CONTINUE);
968}
969
970static void
971vl_api_ipsec_sa_v3_dump_t_handler (vl_api_ipsec_sa_v3_dump_t *mp)
972{
973 vl_api_registration_t *reg;
974
Neale Ranns9ec846c2021-02-09 14:04:02 +0000975 reg = vl_api_client_index_to_registration (mp->client_index);
976 if (!reg)
977 return;
978
979 ipsec_dump_walk_ctx_t ctx = {
980 .reg = reg,
981 .context = mp->context,
982 };
983
984 ipsec_sa_walk (send_ipsec_sa_v3_details, &ctx);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000985}
986
Matthew Smith75d85602017-10-05 19:03:05 -0500987static void
Klement Sekerab4d30532018-11-08 13:00:02 +0100988vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp)
989{
990 vl_api_registration_t *rp;
991 ipsec_main_t *im = &ipsec_main;
992 u32 context = mp->context;
993
994 rp = vl_api_client_index_to_registration (mp->client_index);
995
996 if (rp == 0)
997 {
998 clib_warning ("Client %d AWOL", mp->client_index);
999 return;
1000 }
1001
1002 ipsec_ah_backend_t *ab;
1003 ipsec_esp_backend_t *eb;
1004 /* *INDENT-OFF* */
Damjan Marionb2c31b62020-12-13 21:47:40 +01001005 pool_foreach (ab, im->ah_backends) {
Klement Sekerab4d30532018-11-08 13:00:02 +01001006 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1007 clib_memset (mp, 0, sizeof (*mp));
1008 mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
1009 mp->context = context;
1010 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (ab->name),
1011 ab->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001012 mp->protocol = ntohl (IPSEC_API_PROTO_AH);
Klement Sekerab4d30532018-11-08 13:00:02 +01001013 mp->index = ab - im->ah_backends;
1014 mp->active = mp->index == im->ah_current_backend ? 1 : 0;
1015 vl_api_send_msg (rp, (u8 *)mp);
Damjan Marionb2c31b62020-12-13 21:47:40 +01001016 }
1017 pool_foreach (eb, im->esp_backends) {
Klement Sekerab4d30532018-11-08 13:00:02 +01001018 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1019 clib_memset (mp, 0, sizeof (*mp));
1020 mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
1021 mp->context = context;
1022 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (eb->name),
1023 eb->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001024 mp->protocol = ntohl (IPSEC_API_PROTO_ESP);
Klement Sekerab4d30532018-11-08 13:00:02 +01001025 mp->index = eb - im->esp_backends;
1026 mp->active = mp->index == im->esp_current_backend ? 1 : 0;
1027 vl_api_send_msg (rp, (u8 *)mp);
Damjan Marionb2c31b62020-12-13 21:47:40 +01001028 }
Klement Sekerab4d30532018-11-08 13:00:02 +01001029 /* *INDENT-ON* */
1030}
1031
1032static void
1033vl_api_ipsec_select_backend_t_handler (vl_api_ipsec_select_backend_t * mp)
1034{
1035 ipsec_main_t *im = &ipsec_main;
1036 vl_api_ipsec_select_backend_reply_t *rmp;
Neale Ranns17dcec02019-01-09 21:22:20 -08001037 ipsec_protocol_t protocol;
Klement Sekerab4d30532018-11-08 13:00:02 +01001038 int rv = 0;
Neale Rannsc5fe57d2021-02-25 16:01:28 +00001039 if (pool_elts (ipsec_sa_pool) > 0)
Klement Sekerab4d30532018-11-08 13:00:02 +01001040 {
1041 rv = VNET_API_ERROR_INSTANCE_IN_USE;
1042 goto done;
1043 }
Neale Ranns17dcec02019-01-09 21:22:20 -08001044
1045 rv = ipsec_proto_decode (mp->protocol, &protocol);
1046
1047 if (rv)
1048 goto done;
1049
Neale Ranns17dcec02019-01-09 21:22:20 -08001050 switch (protocol)
Klement Sekerab4d30532018-11-08 13:00:02 +01001051 {
1052 case IPSEC_PROTOCOL_ESP:
Neale Rannse8915fc2019-04-23 20:57:55 -04001053 rv = ipsec_select_esp_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001054 break;
1055 case IPSEC_PROTOCOL_AH:
Neale Rannse8915fc2019-04-23 20:57:55 -04001056 rv = ipsec_select_ah_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001057 break;
1058 default:
Neale Rannse8915fc2019-04-23 20:57:55 -04001059 rv = VNET_API_ERROR_INVALID_PROTOCOL;
Klement Sekerab4d30532018-11-08 13:00:02 +01001060 break;
1061 }
Klement Sekerab4d30532018-11-08 13:00:02 +01001062done:
1063 REPLY_MACRO (VL_API_IPSEC_SELECT_BACKEND_REPLY);
1064}
1065
Yulong Pei2e84d662020-08-14 18:21:08 +08001066static void
1067vl_api_ipsec_set_async_mode_t_handler (vl_api_ipsec_set_async_mode_t * mp)
1068{
1069 vl_api_ipsec_set_async_mode_reply_t *rmp;
1070 int rv = 0;
1071
Yulong Pei2e84d662020-08-14 18:21:08 +08001072 ipsec_set_async_mode (mp->async_enable);
1073
1074 REPLY_MACRO (VL_API_IPSEC_SET_ASYNC_MODE_REPLY);
1075}
1076
Neale Ranns7c44d782019-02-25 10:28:29 +00001077/*
1078 * ipsec_api_hookup
1079 * Add vpe's API message handlers to the table.
1080 * vlib has already mapped shared memory and
1081 * added the client registration handlers.
1082 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
1083 */
1084#define vl_msg_name_crc_list
1085#include <vnet/vnet_all_api_h.h>
1086#undef vl_msg_name_crc_list
1087
1088static void
1089setup_message_id_table (api_main_t * am)
1090{
1091#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1092 foreach_vl_msg_name_crc_ipsec;
1093#undef _
1094}
1095
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001096static clib_error_t *
1097ipsec_api_hookup (vlib_main_t * vm)
1098{
Dave Barach39d69112019-11-27 11:42:13 -05001099 api_main_t *am = vlibapi_get_main ();
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001100
1101#define _(N,n) \
1102 vl_msg_api_set_handlers(VL_API_##N, #n, \
1103 vl_api_##n##_t_handler, \
1104 vl_noop_handler, \
1105 vl_api_##n##_t_endian, \
1106 vl_api_##n##_t_print, \
1107 sizeof(vl_api_##n##_t), 1);
1108 foreach_vpe_api_msg;
1109#undef _
1110
1111 /*
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001112 * Set up the (msg_name, crc, message-id) table
1113 */
1114 setup_message_id_table (am);
1115
1116 return 0;
1117}
1118
1119VLIB_API_INIT_FUNCTION (ipsec_api_hookup);
1120
1121/*
1122 * fd.io coding-style-patch-verification: ON
1123 *
1124 * Local Variables:
1125 * eval: (c-set-style "gnu")
1126 * End:
1127 */