blob: 0eb51b5727f0a4251a7c55047808258ad4b248a6 [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
Neale Ranns89d939e2021-06-07 09:34:07 +0000699static walk_rc_t
700send_ipsec_itf_details (ipsec_itf_t *itf, void *arg)
701{
702 ipsec_dump_walk_ctx_t *ctx = arg;
703 vl_api_ipsec_itf_details_t *mp;
704
705 mp = vl_msg_api_alloc (sizeof (*mp));
706 clib_memset (mp, 0, sizeof (*mp));
707 mp->_vl_msg_id = ntohs (VL_API_IPSEC_ITF_DETAILS);
708 mp->context = ctx->context;
709
710 mp->itf.mode = tunnel_mode_encode (itf->ii_mode);
711 mp->itf.user_instance = htonl (itf->ii_user_instance);
712 mp->itf.sw_if_index = htonl (itf->ii_sw_if_index);
713 vl_api_send_msg (ctx->reg, (u8 *) mp);
714
715 return (WALK_CONTINUE);
716}
717
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000718static void
719vl_api_ipsec_itf_dump_t_handler (vl_api_ipsec_itf_dump_t * mp)
720{
Neale Ranns89d939e2021-06-07 09:34:07 +0000721 vl_api_registration_t *reg;
722
723 reg = vl_api_client_index_to_registration (mp->client_index);
724 if (!reg)
725 return;
726
727 ipsec_dump_walk_ctx_t ctx = {
728 .reg = reg,
729 .context = mp->context,
730 };
731
732 ipsec_itf_walk (send_ipsec_itf_details, &ctx);
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000733}
734
Neale Ranns12989b52019-09-26 16:20:19 +0000735typedef struct ipsec_sa_dump_match_ctx_t_
Matthew Smith28029532017-09-26 13:33:44 -0500736{
Neale Ranns12989b52019-09-26 16:20:19 +0000737 index_t sai;
738 u32 sw_if_index;
739} ipsec_sa_dump_match_ctx_t;
740
741static walk_rc_t
742ipsec_sa_dump_match_sa (index_t itpi, void *arg)
743{
744 ipsec_sa_dump_match_ctx_t *ctx = arg;
745 ipsec_tun_protect_t *itp;
746 index_t sai;
747
748 itp = ipsec_tun_protect_get (itpi);
749
750 if (itp->itp_out_sa == ctx->sai)
751 {
752 ctx->sw_if_index = itp->itp_sw_if_index;
753 return (WALK_STOP);
754 }
Damjan Marion97898982021-04-19 18:15:31 +0200755
Neale Ranns12989b52019-09-26 16:20:19 +0000756 FOR_EACH_IPSEC_PROTECT_INPUT_SAI (itp, sai,
757 ({
758 if (sai == ctx->sai)
759 {
760 ctx->sw_if_index = itp->itp_sw_if_index;
761 return (WALK_STOP);
762 }
763 }));
Neale Ranns12989b52019-09-26 16:20:19 +0000764
765 return (WALK_CONTINUE);
766}
767
768static walk_rc_t
769send_ipsec_sa_details (ipsec_sa_t * sa, void *arg)
770{
771 ipsec_dump_walk_ctx_t *ctx = arg;
Matthew Smith28029532017-09-26 13:33:44 -0500772 vl_api_ipsec_sa_details_t *mp;
773
774 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400775 clib_memset (mp, 0, sizeof (*mp));
Matthew Smith28029532017-09-26 13:33:44 -0500776 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_DETAILS);
Neale Ranns12989b52019-09-26 16:20:19 +0000777 mp->context = ctx->context;
Matthew Smith28029532017-09-26 13:33:44 -0500778
Neale Ranns8d7c5022019-02-06 01:41:05 -0800779 mp->entry.sad_id = htonl (sa->id);
780 mp->entry.spi = htonl (sa->spi);
781 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000782 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
Matthew Smith28029532017-09-26 13:33:44 -0500783
Neale Ranns8d7c5022019-02-06 01:41:05 -0800784 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
785 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
Matthew Smith28029532017-09-26 13:33:44 -0500786
Neale Ranns8d7c5022019-02-06 01:41:05 -0800787 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
788 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
Matthew Smith28029532017-09-26 13:33:44 -0500789
Neale Ranns8d7c5022019-02-06 01:41:05 -0800790 mp->entry.flags = ipsec_sad_flags_encode (sa);
Neale Ranns12989b52019-09-26 16:20:19 +0000791 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
792
793 if (ipsec_sa_is_set_IS_PROTECT (sa))
794 {
795 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000796 .sai = sa - ipsec_sa_pool,
797 .sw_if_index = ~0,
Neale Ranns12989b52019-09-26 16:20:19 +0000798 };
799 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
800
801 mp->sw_if_index = htonl (ctx.sw_if_index);
802 }
803 else
804 mp->sw_if_index = ~0;
Matthew Smith28029532017-09-26 13:33:44 -0500805
Damjan Mariond709cbc2019-03-26 13:16:42 +0100806 if (ipsec_sa_is_set_IS_TUNNEL (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500807 {
Neale Ranns9ec846c2021-02-09 14:04:02 +0000808 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
809 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -0500810 }
Neale Rannsabc56602020-04-01 09:45:23 +0000811 if (ipsec_sa_is_set_UDP_ENCAP (sa))
812 {
813 mp->entry.udp_src_port = sa->udp_hdr.src_port;
814 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
815 }
Matthew Smith28029532017-09-26 13:33:44 -0500816
Matthew Smith28029532017-09-26 13:33:44 -0500817 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
818 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
Damjan Marion1e3aa5e2019-03-28 10:58:59 +0100819 if (ipsec_sa_is_set_USE_ESN (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500820 {
821 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
822 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
823 }
Damjan Mariond709cbc2019-03-26 13:16:42 +0100824 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500825 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
Pierre Pfister4c422f92018-12-10 11:19:08 +0100826
Matthew Smith48d32b42020-04-02 07:45:49 -0500827 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
828
Neale Ranns12989b52019-09-26 16:20:19 +0000829 vl_api_send_msg (ctx->reg, (u8 *) mp);
Matthew Smith28029532017-09-26 13:33:44 -0500830
Neale Ranns12989b52019-09-26 16:20:19 +0000831 return (WALK_CONTINUE);
832}
Matthew Smith28029532017-09-26 13:33:44 -0500833
834static void
835vl_api_ipsec_sa_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
836{
Florin Coras6c4dae22018-01-09 06:39:23 -0800837 vl_api_registration_t *reg;
Matthew Smith28029532017-09-26 13:33:44 -0500838
Florin Coras6c4dae22018-01-09 06:39:23 -0800839 reg = vl_api_client_index_to_registration (mp->client_index);
Neale Ranns12989b52019-09-26 16:20:19 +0000840 if (!reg)
Matthew Smith28029532017-09-26 13:33:44 -0500841 return;
842
Neale Ranns12989b52019-09-26 16:20:19 +0000843 ipsec_dump_walk_ctx_t ctx = {
844 .reg = reg,
845 .context = mp->context,
846 };
Matthew Smith28029532017-09-26 13:33:44 -0500847
Neale Ranns12989b52019-09-26 16:20:19 +0000848 ipsec_sa_walk (send_ipsec_sa_details, &ctx);
Matthew Smith28029532017-09-26 13:33:44 -0500849}
850
Neale Ranns041add72020-01-02 04:06:10 +0000851static walk_rc_t
852send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg)
853{
854 ipsec_dump_walk_ctx_t *ctx = arg;
855 vl_api_ipsec_sa_v2_details_t *mp;
Neale Ranns041add72020-01-02 04:06:10 +0000856
857 mp = vl_msg_api_alloc (sizeof (*mp));
858 clib_memset (mp, 0, sizeof (*mp));
859 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_V2_DETAILS);
860 mp->context = ctx->context;
861
862 mp->entry.sad_id = htonl (sa->id);
863 mp->entry.spi = htonl (sa->spi);
864 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
Neale Ranns9ec846c2021-02-09 14:04:02 +0000865 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
Neale Ranns041add72020-01-02 04:06:10 +0000866
867 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
868 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
869
870 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
871 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
872
873 mp->entry.flags = ipsec_sad_flags_encode (sa);
874 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
875
876 if (ipsec_sa_is_set_IS_PROTECT (sa))
877 {
878 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000879 .sai = sa - ipsec_sa_pool,
880 .sw_if_index = ~0,
Neale Ranns041add72020-01-02 04:06:10 +0000881 };
882 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
883
884 mp->sw_if_index = htonl (ctx.sw_if_index);
885 }
886 else
887 mp->sw_if_index = ~0;
888
889 if (ipsec_sa_is_set_IS_TUNNEL (sa))
890 {
Neale Ranns9ec846c2021-02-09 14:04:02 +0000891 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
892 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
Neale Ranns041add72020-01-02 04:06:10 +0000893 }
894 if (ipsec_sa_is_set_UDP_ENCAP (sa))
895 {
896 mp->entry.udp_src_port = sa->udp_hdr.src_port;
897 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
898 }
899
Neale Ranns9ec846c2021-02-09 14:04:02 +0000900 mp->entry.tunnel_flags =
901 tunnel_encap_decap_flags_encode (sa->tunnel.t_encap_decap_flags);
902 mp->entry.dscp = ip_dscp_encode (sa->tunnel.t_dscp);
Neale Ranns041add72020-01-02 04:06:10 +0000903
904 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
905 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
906 if (ipsec_sa_is_set_USE_ESN (sa))
907 {
908 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
909 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
910 }
911 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
912 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
913
914 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
915
916 vl_api_send_msg (ctx->reg, (u8 *) mp);
917
918 return (WALK_CONTINUE);
919}
920
921static void
Neale Ranns9ec846c2021-02-09 14:04:02 +0000922vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_v2_dump_t *mp)
Neale Ranns041add72020-01-02 04:06:10 +0000923{
924 vl_api_registration_t *reg;
925
Neale Ranns041add72020-01-02 04:06:10 +0000926 reg = vl_api_client_index_to_registration (mp->client_index);
927 if (!reg)
928 return;
929
930 ipsec_dump_walk_ctx_t ctx = {
931 .reg = reg,
932 .context = mp->context,
933 };
934
935 ipsec_sa_walk (send_ipsec_sa_v2_details, &ctx);
Neale Ranns041add72020-01-02 04:06:10 +0000936}
937
Neale Ranns9ec846c2021-02-09 14:04:02 +0000938static walk_rc_t
939send_ipsec_sa_v3_details (ipsec_sa_t *sa, void *arg)
940{
941 ipsec_dump_walk_ctx_t *ctx = arg;
942 vl_api_ipsec_sa_v3_details_t *mp;
Neale Ranns9ec846c2021-02-09 14:04:02 +0000943
944 mp = vl_msg_api_alloc (sizeof (*mp));
945 clib_memset (mp, 0, sizeof (*mp));
946 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_V3_DETAILS);
947 mp->context = ctx->context;
948
949 mp->entry.sad_id = htonl (sa->id);
950 mp->entry.spi = htonl (sa->spi);
951 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
952
953 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
954 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
955
956 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
957 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
958
959 mp->entry.flags = ipsec_sad_flags_encode (sa);
960 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
961
962 if (ipsec_sa_is_set_IS_PROTECT (sa))
963 {
964 ipsec_sa_dump_match_ctx_t ctx = {
Neale Rannsc5fe57d2021-02-25 16:01:28 +0000965 .sai = sa - ipsec_sa_pool,
Neale Ranns9ec846c2021-02-09 14:04:02 +0000966 .sw_if_index = ~0,
967 };
968 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
969
970 mp->sw_if_index = htonl (ctx.sw_if_index);
971 }
972 else
973 mp->sw_if_index = ~0;
974
975 if (ipsec_sa_is_set_IS_TUNNEL (sa))
976 tunnel_encode (&sa->tunnel, &mp->entry.tunnel);
977
978 if (ipsec_sa_is_set_UDP_ENCAP (sa))
979 {
980 mp->entry.udp_src_port = sa->udp_hdr.src_port;
981 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
982 }
983
984 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
985 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
986 if (ipsec_sa_is_set_USE_ESN (sa))
987 {
988 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
989 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
990 }
991 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
992 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
993
994 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
995
996 vl_api_send_msg (ctx->reg, (u8 *) mp);
997
998 return (WALK_CONTINUE);
999}
1000
1001static void
1002vl_api_ipsec_sa_v3_dump_t_handler (vl_api_ipsec_sa_v3_dump_t *mp)
1003{
1004 vl_api_registration_t *reg;
1005
Neale Ranns9ec846c2021-02-09 14:04:02 +00001006 reg = vl_api_client_index_to_registration (mp->client_index);
1007 if (!reg)
1008 return;
1009
1010 ipsec_dump_walk_ctx_t ctx = {
1011 .reg = reg,
1012 .context = mp->context,
1013 };
1014
1015 ipsec_sa_walk (send_ipsec_sa_v3_details, &ctx);
Neale Ranns9ec846c2021-02-09 14:04:02 +00001016}
1017
Matthew Smith75d85602017-10-05 19:03:05 -05001018static void
Klement Sekerab4d30532018-11-08 13:00:02 +01001019vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp)
1020{
1021 vl_api_registration_t *rp;
1022 ipsec_main_t *im = &ipsec_main;
1023 u32 context = mp->context;
1024
1025 rp = vl_api_client_index_to_registration (mp->client_index);
1026
1027 if (rp == 0)
1028 {
1029 clib_warning ("Client %d AWOL", mp->client_index);
1030 return;
1031 }
1032
1033 ipsec_ah_backend_t *ab;
1034 ipsec_esp_backend_t *eb;
1035 /* *INDENT-OFF* */
Damjan Marionb2c31b62020-12-13 21:47:40 +01001036 pool_foreach (ab, im->ah_backends) {
Klement Sekerab4d30532018-11-08 13:00:02 +01001037 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1038 clib_memset (mp, 0, sizeof (*mp));
1039 mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
1040 mp->context = context;
1041 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (ab->name),
1042 ab->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001043 mp->protocol = ntohl (IPSEC_API_PROTO_AH);
Klement Sekerab4d30532018-11-08 13:00:02 +01001044 mp->index = ab - im->ah_backends;
1045 mp->active = mp->index == im->ah_current_backend ? 1 : 0;
1046 vl_api_send_msg (rp, (u8 *)mp);
Damjan Marionb2c31b62020-12-13 21:47:40 +01001047 }
1048 pool_foreach (eb, im->esp_backends) {
Klement Sekerab4d30532018-11-08 13:00:02 +01001049 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1050 clib_memset (mp, 0, sizeof (*mp));
1051 mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
1052 mp->context = context;
1053 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (eb->name),
1054 eb->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001055 mp->protocol = ntohl (IPSEC_API_PROTO_ESP);
Klement Sekerab4d30532018-11-08 13:00:02 +01001056 mp->index = eb - im->esp_backends;
1057 mp->active = mp->index == im->esp_current_backend ? 1 : 0;
1058 vl_api_send_msg (rp, (u8 *)mp);
Damjan Marionb2c31b62020-12-13 21:47:40 +01001059 }
Klement Sekerab4d30532018-11-08 13:00:02 +01001060 /* *INDENT-ON* */
1061}
1062
1063static void
1064vl_api_ipsec_select_backend_t_handler (vl_api_ipsec_select_backend_t * mp)
1065{
1066 ipsec_main_t *im = &ipsec_main;
1067 vl_api_ipsec_select_backend_reply_t *rmp;
Neale Ranns17dcec02019-01-09 21:22:20 -08001068 ipsec_protocol_t protocol;
Klement Sekerab4d30532018-11-08 13:00:02 +01001069 int rv = 0;
Neale Rannsc5fe57d2021-02-25 16:01:28 +00001070 if (pool_elts (ipsec_sa_pool) > 0)
Klement Sekerab4d30532018-11-08 13:00:02 +01001071 {
1072 rv = VNET_API_ERROR_INSTANCE_IN_USE;
1073 goto done;
1074 }
Neale Ranns17dcec02019-01-09 21:22:20 -08001075
1076 rv = ipsec_proto_decode (mp->protocol, &protocol);
1077
1078 if (rv)
1079 goto done;
1080
Neale Ranns17dcec02019-01-09 21:22:20 -08001081 switch (protocol)
Klement Sekerab4d30532018-11-08 13:00:02 +01001082 {
1083 case IPSEC_PROTOCOL_ESP:
Neale Rannse8915fc2019-04-23 20:57:55 -04001084 rv = ipsec_select_esp_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001085 break;
1086 case IPSEC_PROTOCOL_AH:
Neale Rannse8915fc2019-04-23 20:57:55 -04001087 rv = ipsec_select_ah_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001088 break;
1089 default:
Neale Rannse8915fc2019-04-23 20:57:55 -04001090 rv = VNET_API_ERROR_INVALID_PROTOCOL;
Klement Sekerab4d30532018-11-08 13:00:02 +01001091 break;
1092 }
Klement Sekerab4d30532018-11-08 13:00:02 +01001093done:
1094 REPLY_MACRO (VL_API_IPSEC_SELECT_BACKEND_REPLY);
1095}
1096
Yulong Pei2e84d662020-08-14 18:21:08 +08001097static void
1098vl_api_ipsec_set_async_mode_t_handler (vl_api_ipsec_set_async_mode_t * mp)
1099{
1100 vl_api_ipsec_set_async_mode_reply_t *rmp;
1101 int rv = 0;
1102
Yulong Pei2e84d662020-08-14 18:21:08 +08001103 ipsec_set_async_mode (mp->async_enable);
1104
1105 REPLY_MACRO (VL_API_IPSEC_SET_ASYNC_MODE_REPLY);
1106}
1107
Neale Ranns7c44d782019-02-25 10:28:29 +00001108/*
1109 * ipsec_api_hookup
1110 * Add vpe's API message handlers to the table.
1111 * vlib has already mapped shared memory and
1112 * added the client registration handlers.
1113 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
1114 */
1115#define vl_msg_name_crc_list
1116#include <vnet/vnet_all_api_h.h>
1117#undef vl_msg_name_crc_list
1118
1119static void
1120setup_message_id_table (api_main_t * am)
1121{
1122#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1123 foreach_vl_msg_name_crc_ipsec;
1124#undef _
1125}
1126
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001127static clib_error_t *
1128ipsec_api_hookup (vlib_main_t * vm)
1129{
Dave Barach39d69112019-11-27 11:42:13 -05001130 api_main_t *am = vlibapi_get_main ();
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001131
1132#define _(N,n) \
1133 vl_msg_api_set_handlers(VL_API_##N, #n, \
1134 vl_api_##n##_t_handler, \
1135 vl_noop_handler, \
1136 vl_api_##n##_t_endian, \
1137 vl_api_##n##_t_print, \
1138 sizeof(vl_api_##n##_t), 1);
1139 foreach_vpe_api_msg;
1140#undef _
1141
1142 /*
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001143 * Set up the (msg_name, crc, message-id) table
1144 */
1145 setup_message_id_table (am);
1146
1147 return 0;
1148}
1149
1150VLIB_API_INIT_FUNCTION (ipsec_api_hookup);
1151
1152/*
1153 * fd.io coding-style-patch-verification: ON
1154 *
1155 * Local Variables:
1156 * eval: (c-set-style "gnu")
1157 * End:
1158 */