blob: 667d9b2fd118a81c929f6b841f169dd557ce75a2 [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>
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010031
32#include <vnet/vnet_msg_enum.h>
33
Damjan Mariona9a951f2017-01-16 22:06:10 +010034#if WITH_LIBSSL > 0
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#endif /* IPSEC */
39
40#define vl_typedefs /* define message structures */
41#include <vnet/vnet_all_api_h.h>
42#undef vl_typedefs
43
44#define vl_endianfun /* define message structures */
45#include <vnet/vnet_all_api_h.h>
46#undef vl_endianfun
47
48/* instantiate all the print functions we know about */
49#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
50#define vl_printfun
51#include <vnet/vnet_all_api_h.h>
52#undef vl_printfun
53
54#include <vlibapi/api_helper_macros.h>
55
Klement Sekerab4d30532018-11-08 13:00:02 +010056#define foreach_vpe_api_msg \
57_(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \
58_(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \
Neale Ranns17dcec02019-01-09 21:22:20 -080059_(IPSEC_SPD_ENTRY_ADD_DEL, ipsec_spd_entry_add_del) \
60_(IPSEC_SAD_ENTRY_ADD_DEL, ipsec_sad_entry_add_del) \
Klement Sekerab4d30532018-11-08 13:00:02 +010061_(IPSEC_SA_DUMP, ipsec_sa_dump) \
62_(IPSEC_SPDS_DUMP, ipsec_spds_dump) \
63_(IPSEC_SPD_DUMP, ipsec_spd_dump) \
64_(IPSEC_SPD_INTERFACE_DUMP, ipsec_spd_interface_dump) \
Neale Rannsdd4ccf22020-06-30 07:47:14 +000065_(IPSEC_ITF_CREATE, ipsec_itf_create) \
66_(IPSEC_ITF_DELETE, ipsec_itf_delete) \
67_(IPSEC_ITF_DUMP, ipsec_itf_dump) \
Klement Sekerab4d30532018-11-08 13:00:02 +010068_(IPSEC_TUNNEL_IF_ADD_DEL, ipsec_tunnel_if_add_del) \
Klement Sekerab4d30532018-11-08 13:00:02 +010069_(IPSEC_TUNNEL_IF_SET_SA, ipsec_tunnel_if_set_sa) \
Klement Sekerab4d30532018-11-08 13:00:02 +010070_(IPSEC_SELECT_BACKEND, ipsec_select_backend) \
Neale Rannsc87b66c2019-02-07 07:26:12 -080071_(IPSEC_BACKEND_DUMP, ipsec_backend_dump) \
72_(IPSEC_TUNNEL_PROTECT_UPDATE, ipsec_tunnel_protect_update) \
73_(IPSEC_TUNNEL_PROTECT_DEL, ipsec_tunnel_protect_del) \
74_(IPSEC_TUNNEL_PROTECT_DUMP, ipsec_tunnel_protect_dump)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010075
Klement Sekerab4d30532018-11-08 13:00:02 +010076static void
77vl_api_ipsec_spd_add_del_t_handler (vl_api_ipsec_spd_add_del_t * mp)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010078{
Damjan Mariona9a951f2017-01-16 22:06:10 +010079#if WITH_LIBSSL == 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010080 clib_warning ("unimplemented");
81#else
82
83 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
84 vl_api_ipsec_spd_add_del_reply_t *rmp;
85 int rv;
86
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010087 rv = ipsec_add_del_spd (vm, ntohl (mp->spd_id), mp->is_add);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010088
89 REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_REPLY);
90#endif
91}
92
93static void vl_api_ipsec_interface_add_del_spd_t_handler
94 (vl_api_ipsec_interface_add_del_spd_t * mp)
95{
96 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
97 vl_api_ipsec_interface_add_del_spd_reply_t *rmp;
98 int rv;
99 u32 sw_if_index __attribute__ ((unused));
100 u32 spd_id __attribute__ ((unused));
101
102 sw_if_index = ntohl (mp->sw_if_index);
103 spd_id = ntohl (mp->spd_id);
104
105 VALIDATE_SW_IF_INDEX (mp);
106
Damjan Mariona9a951f2017-01-16 22:06:10 +0100107#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100108 rv = ipsec_set_interface_spd (vm, sw_if_index, spd_id, mp->is_add);
109#else
110 rv = VNET_API_ERROR_UNIMPLEMENTED;
111#endif
112
113 BAD_SW_IF_INDEX_LABEL;
114
115 REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY);
116}
117
Neale Rannsc87b66c2019-02-07 07:26:12 -0800118static void vl_api_ipsec_tunnel_protect_update_t_handler
119 (vl_api_ipsec_tunnel_protect_update_t * mp)
120{
121 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
122 vl_api_ipsec_tunnel_protect_update_reply_t *rmp;
123 u32 sw_if_index, ii, *sa_ins = NULL;
Neale Ranns28287212019-12-16 00:53:11 +0000124 ip_address_t nh;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800125 int rv;
126
127 sw_if_index = ntohl (mp->tunnel.sw_if_index);
128
129 VALIDATE_SW_IF_INDEX (&(mp->tunnel));
130
131#if WITH_LIBSSL > 0
132
133 for (ii = 0; ii < mp->tunnel.n_sa_in; ii++)
134 vec_add1 (sa_ins, ntohl (mp->tunnel.sa_in[ii]));
135
Neale Ranns28287212019-12-16 00:53:11 +0000136 ip_address_decode2 (&mp->tunnel.nh, &nh);
137
138 rv = ipsec_tun_protect_update (sw_if_index, &nh,
Neale Rannsc87b66c2019-02-07 07:26:12 -0800139 ntohl (mp->tunnel.sa_out), sa_ins);
140#else
141 rv = VNET_API_ERROR_UNIMPLEMENTED;
142#endif
143
144 BAD_SW_IF_INDEX_LABEL;
145
146 REPLY_MACRO (VL_API_IPSEC_TUNNEL_PROTECT_UPDATE_REPLY);
147}
148
149static void vl_api_ipsec_tunnel_protect_del_t_handler
150 (vl_api_ipsec_tunnel_protect_del_t * mp)
151{
152 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
153 vl_api_ipsec_tunnel_protect_del_reply_t *rmp;
Neale Ranns28287212019-12-16 00:53:11 +0000154 ip_address_t nh;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800155 u32 sw_if_index;
Neale Ranns28287212019-12-16 00:53:11 +0000156 int rv;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800157
158 sw_if_index = ntohl (mp->sw_if_index);
159
160 VALIDATE_SW_IF_INDEX (mp);
161
162#if WITH_LIBSSL > 0
Neale Ranns28287212019-12-16 00:53:11 +0000163 ip_address_decode2 (&mp->nh, &nh);
164 rv = ipsec_tun_protect_del (sw_if_index, &nh);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800165#else
166 rv = VNET_API_ERROR_UNIMPLEMENTED;
167#endif
168
169 BAD_SW_IF_INDEX_LABEL;
170
171 REPLY_MACRO (VL_API_IPSEC_TUNNEL_PROTECT_DEL_REPLY);
172}
173
Neale Ranns12989b52019-09-26 16:20:19 +0000174typedef struct ipsec_dump_walk_ctx_t_
Neale Rannsc87b66c2019-02-07 07:26:12 -0800175{
176 vl_api_registration_t *reg;
177 u32 context;
Neale Ranns12989b52019-09-26 16:20:19 +0000178} ipsec_dump_walk_ctx_t;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800179
180static walk_rc_t
181send_ipsec_tunnel_protect_details (index_t itpi, void *arg)
182{
Neale Ranns12989b52019-09-26 16:20:19 +0000183 ipsec_dump_walk_ctx_t *ctx = arg;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800184 vl_api_ipsec_tunnel_protect_details_t *mp;
185 ipsec_tun_protect_t *itp;
Matthew Smith5cee0bc2020-03-31 09:52:17 -0500186 u32 ii = 0;
187 ipsec_sa_t *sa;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800188
189 itp = ipsec_tun_protect_get (itpi);
190
Neale Rannsc87b66c2019-02-07 07:26:12 -0800191 mp = vl_msg_api_alloc (sizeof (*mp) + (sizeof (u32) * itp->itp_n_sa_in));
192 clib_memset (mp, 0, sizeof (*mp));
193 mp->_vl_msg_id = ntohs (VL_API_IPSEC_TUNNEL_PROTECT_DETAILS);
194 mp->context = ctx->context;
195
196 mp->tun.sw_if_index = htonl (itp->itp_sw_if_index);
Neale Ranns28287212019-12-16 00:53:11 +0000197 ip_address_encode2 (itp->itp_key, &mp->tun.nh);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800198
Matthew Smith5cee0bc2020-03-31 09:52:17 -0500199 sa = ipsec_sa_get (itp->itp_out_sa);
200 mp->tun.sa_out = htonl (sa->id);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800201 mp->tun.n_sa_in = itp->itp_n_sa_in;
202 /* *INDENT-OFF* */
Matthew Smith5cee0bc2020-03-31 09:52:17 -0500203 FOR_EACH_IPSEC_PROTECT_INPUT_SA(itp, sa,
Neale Rannsc87b66c2019-02-07 07:26:12 -0800204 ({
Matthew Smith5cee0bc2020-03-31 09:52:17 -0500205 mp->tun.sa_in[ii++] = htonl (sa->id);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800206 }));
207 /* *INDENT-ON* */
208
209 vl_api_send_msg (ctx->reg, (u8 *) mp);
210
211 return (WALK_CONTINUE);
212}
213
214static void
215vl_api_ipsec_tunnel_protect_dump_t_handler (vl_api_ipsec_tunnel_protect_dump_t
216 * mp)
217{
218 vl_api_registration_t *reg;
219 u32 sw_if_index;
220
221#if WITH_LIBSSL > 0
222 reg = vl_api_client_index_to_registration (mp->client_index);
223 if (!reg)
224 return;
225
Neale Ranns12989b52019-09-26 16:20:19 +0000226 ipsec_dump_walk_ctx_t ctx = {
Neale Rannsc87b66c2019-02-07 07:26:12 -0800227 .reg = reg,
228 .context = mp->context,
229 };
230
231 sw_if_index = ntohl (mp->sw_if_index);
232
233 if (~0 == sw_if_index)
234 {
235 ipsec_tun_protect_walk (send_ipsec_tunnel_protect_details, &ctx);
236 }
237 else
238 {
Neale Ranns28287212019-12-16 00:53:11 +0000239 ipsec_tun_protect_walk_itf (sw_if_index,
240 send_ipsec_tunnel_protect_details, &ctx);
Neale Rannsc87b66c2019-02-07 07:26:12 -0800241 }
242#else
243 clib_warning ("unimplemented");
244#endif
245}
246
Neale Ranns17dcec02019-01-09 21:22:20 -0800247static int
248ipsec_spd_action_decode (vl_api_ipsec_spd_action_t in,
249 ipsec_policy_action_t * out)
250{
251 in = clib_net_to_host_u32 (in);
252
253 switch (in)
254 {
255#define _(v,f,s) case IPSEC_API_SPD_ACTION_##f: \
256 *out = IPSEC_POLICY_ACTION_##f; \
257 return (0);
258 foreach_ipsec_policy_action
259#undef _
260 }
261 return (VNET_API_ERROR_UNIMPLEMENTED);
262}
263
264static void vl_api_ipsec_spd_entry_add_del_t_handler
265 (vl_api_ipsec_spd_entry_add_del_t * mp)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100266{
267 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
Neale Ranns17dcec02019-01-09 21:22:20 -0800268 vl_api_ipsec_spd_entry_add_del_reply_t *rmp;
269 ip46_type_t itype;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800270 u32 stat_index;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100271 int rv;
272
Neale Ranns8c2dd1b2019-02-19 08:27:34 -0800273 stat_index = ~0;
274
Damjan Mariona9a951f2017-01-16 22:06:10 +0100275#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100276 ipsec_policy_t p;
277
Dave Barachb7b92992018-10-17 10:38:51 -0400278 clib_memset (&p, 0, sizeof (p));
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100279
Neale Ranns17dcec02019-01-09 21:22:20 -0800280 p.id = ntohl (mp->entry.spd_id);
281 p.priority = ntohl (mp->entry.priority);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100282
Neale Ranns17dcec02019-01-09 21:22:20 -0800283 itype = ip_address_decode (&mp->entry.remote_address_start, &p.raddr.start);
284 ip_address_decode (&mp->entry.remote_address_stop, &p.raddr.stop);
285 ip_address_decode (&mp->entry.local_address_start, &p.laddr.start);
286 ip_address_decode (&mp->entry.local_address_stop, &p.laddr.stop);
287
288 p.is_ipv6 = (itype == IP46_TYPE_IP6);
289
290 p.protocol = mp->entry.protocol;
Neale Rannsa4d24312019-07-10 13:46:21 +0000291 p.rport.start = ntohs (mp->entry.remote_port_start);
292 p.rport.stop = ntohs (mp->entry.remote_port_stop);
293 p.lport.start = ntohs (mp->entry.local_port_start);
294 p.lport.stop = ntohs (mp->entry.local_port_stop);
Neale Ranns17dcec02019-01-09 21:22:20 -0800295
296 rv = ipsec_spd_action_decode (mp->entry.policy, &p.policy);
297
298 if (rv)
299 goto out;
300
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100301 /* policy action resolve unsupported */
Neale Ranns17dcec02019-01-09 21:22:20 -0800302 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100303 {
304 clib_warning ("unsupported action: 'resolve'");
305 rv = VNET_API_ERROR_UNIMPLEMENTED;
306 goto out;
307 }
Neale Ranns17dcec02019-01-09 21:22:20 -0800308 p.sa_id = ntohl (mp->entry.sa_id);
Neale Ranns9f231d42019-03-19 10:06:00 +0000309 rv =
310 ipsec_policy_mk_type (mp->entry.is_outbound, p.is_ipv6, p.policy,
311 &p.type);
312 if (rv)
313 goto out;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100314
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800315 rv = ipsec_add_del_policy (vm, &p, mp->is_add, &stat_index);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100316 if (rv)
317 goto out;
318
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100319#else
320 rv = VNET_API_ERROR_UNIMPLEMENTED;
321 goto out;
322#endif
323
324out:
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800325 /* *INDENT-OFF* */
326 REPLY_MACRO2 (VL_API_IPSEC_SPD_ENTRY_ADD_DEL_REPLY,
327 ({
328 rmp->stat_index = ntohl(stat_index);
329 }));
330 /* *INDENT-ON* */
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100331}
332
Neale Ranns17dcec02019-01-09 21:22:20 -0800333static void vl_api_ipsec_sad_entry_add_del_t_handler
334 (vl_api_ipsec_sad_entry_add_del_t * mp)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100335{
336 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
Neale Ranns17dcec02019-01-09 21:22:20 -0800337 vl_api_ipsec_sad_entry_add_del_reply_t *rmp;
Neale Ranns8d7c5022019-02-06 01:41:05 -0800338 ip46_address_t tun_src = { }, tun_dst =
339 {
340 };
341 ipsec_key_t crypto_key, integ_key;
342 ipsec_crypto_alg_t crypto_alg;
343 ipsec_integ_alg_t integ_alg;
344 ipsec_protocol_t proto;
345 ipsec_sa_flags_t flags;
Dave Baracha5160d72019-03-13 15:29:15 -0400346 u32 id, spi, sa_index = ~0;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100347 int rv;
Neale Ranns8d7c5022019-02-06 01:41:05 -0800348
Damjan Mariona9a951f2017-01-16 22:06:10 +0100349#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100350
Neale Ranns8d7c5022019-02-06 01:41:05 -0800351 id = ntohl (mp->entry.sad_id);
352 spi = ntohl (mp->entry.spi);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100353
Neale Ranns8d7c5022019-02-06 01:41:05 -0800354 rv = ipsec_proto_decode (mp->entry.protocol, &proto);
Neale Ranns17dcec02019-01-09 21:22:20 -0800355
356 if (rv)
357 goto out;
358
Neale Ranns8d7c5022019-02-06 01:41:05 -0800359 rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
Neale Ranns17dcec02019-01-09 21:22:20 -0800360
361 if (rv)
362 goto out;
363
Neale Ranns8d7c5022019-02-06 01:41:05 -0800364 rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
Neale Ranns17dcec02019-01-09 21:22:20 -0800365
366 if (rv)
367 goto out;
368
Neale Ranns8d7c5022019-02-06 01:41:05 -0800369 ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
370 ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
Neale Ranns17dcec02019-01-09 21:22:20 -0800371
Neale Ranns8d7c5022019-02-06 01:41:05 -0800372 flags = ipsec_sa_flags_decode (mp->entry.flags);
Neale Ranns17dcec02019-01-09 21:22:20 -0800373
Neale Ranns8d7c5022019-02-06 01:41:05 -0800374 ip_address_decode (&mp->entry.tunnel_src, &tun_src);
375 ip_address_decode (&mp->entry.tunnel_dst, &tun_dst);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100376
Neale Ranns8d7c5022019-02-06 01:41:05 -0800377 if (mp->is_add)
Neale Ranns495d7ff2019-07-12 09:15:26 +0000378 rv = ipsec_sa_add_and_lock (id, spi, proto,
379 crypto_alg, &crypto_key,
380 integ_alg, &integ_key, flags,
381 0, mp->entry.salt, &tun_src, &tun_dst,
Neale Rannsabc56602020-04-01 09:45:23 +0000382 &sa_index, htons (mp->entry.udp_src_port),
383 htons (mp->entry.udp_dst_port));
Neale Ranns8d7c5022019-02-06 01:41:05 -0800384 else
Neale Ranns495d7ff2019-07-12 09:15:26 +0000385 rv = ipsec_sa_unlock_id (id);
Neale Ranns8d7c5022019-02-06 01:41:05 -0800386
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100387#else
388 rv = VNET_API_ERROR_UNIMPLEMENTED;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100389#endif
390
391out:
Neale Rannseba31ec2019-02-17 18:04:27 +0000392 /* *INDENT-OFF* */
393 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_REPLY,
394 {
395 rmp->stat_index = htonl (sa_index);
396 });
397 /* *INDENT-ON* */
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100398}
399
400static void
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700401send_ipsec_spds_details (ipsec_spd_t * spd, vl_api_registration_t * reg,
402 u32 context)
403{
404 vl_api_ipsec_spds_details_t *mp;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800405 u32 n_policies = 0;
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700406
407 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400408 clib_memset (mp, 0, sizeof (*mp));
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700409 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPDS_DETAILS);
410 mp->context = context;
411
412 mp->spd_id = htonl (spd->id);
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800413#define _(s, n) n_policies += vec_len (spd->policies[IPSEC_SPD_POLICY_##s]);
414 foreach_ipsec_spd_policy_type
415#undef _
416 mp->npolicies = htonl (n_policies);
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700417
418 vl_api_send_msg (reg, (u8 *) mp);
419}
420
421static void
422vl_api_ipsec_spds_dump_t_handler (vl_api_ipsec_spds_dump_t * mp)
423{
424 vl_api_registration_t *reg;
425 ipsec_main_t *im = &ipsec_main;
426 ipsec_spd_t *spd;
427#if WITH_LIBSSL > 0
428 reg = vl_api_client_index_to_registration (mp->client_index);
429 if (!reg)
430 return;
431
432 /* *INDENT-OFF* */
433 pool_foreach (spd, im->spds, ({
434 send_ipsec_spds_details (spd, reg, mp->context);
435 }));
436 /* *INDENT-ON* */
437#else
438 clib_warning ("unimplemented");
439#endif
440}
441
Neale Ranns17dcec02019-01-09 21:22:20 -0800442vl_api_ipsec_spd_action_t
443ipsec_spd_action_encode (ipsec_policy_action_t in)
444{
445 vl_api_ipsec_spd_action_t out = IPSEC_API_SPD_ACTION_BYPASS;
446
447 switch (in)
448 {
449#define _(v,f,s) case IPSEC_POLICY_ACTION_##f: \
450 out = IPSEC_API_SPD_ACTION_##f; \
451 break;
452 foreach_ipsec_policy_action
453#undef _
454 }
455 return (clib_host_to_net_u32 (out));
456}
457
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700458static void
Florin Coras6c4dae22018-01-09 06:39:23 -0800459send_ipsec_spd_details (ipsec_policy_t * p, vl_api_registration_t * reg,
460 u32 context)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100461{
462 vl_api_ipsec_spd_details_t *mp;
463
464 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400465 clib_memset (mp, 0, sizeof (*mp));
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100466 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_DETAILS);
467 mp->context = context;
468
Neale Ranns17dcec02019-01-09 21:22:20 -0800469 mp->entry.spd_id = htonl (p->id);
470 mp->entry.priority = htonl (p->priority);
Neale Ranns9f231d42019-03-19 10:06:00 +0000471 mp->entry.is_outbound = ((p->type == IPSEC_SPD_POLICY_IP6_OUTBOUND) ||
472 (p->type == IPSEC_SPD_POLICY_IP4_OUTBOUND));
Neale Ranns17dcec02019-01-09 21:22:20 -0800473
474 ip_address_encode (&p->laddr.start, IP46_TYPE_ANY,
475 &mp->entry.local_address_start);
476 ip_address_encode (&p->laddr.stop, IP46_TYPE_ANY,
477 &mp->entry.local_address_stop);
478 ip_address_encode (&p->raddr.start, IP46_TYPE_ANY,
479 &mp->entry.remote_address_start);
480 ip_address_encode (&p->raddr.stop, IP46_TYPE_ANY,
481 &mp->entry.remote_address_stop);
Neale Rannsa4d24312019-07-10 13:46:21 +0000482 mp->entry.local_port_start = htons (p->lport.start);
483 mp->entry.local_port_stop = htons (p->lport.stop);
484 mp->entry.remote_port_start = htons (p->rport.start);
485 mp->entry.remote_port_stop = htons (p->rport.stop);
Neale Ranns17dcec02019-01-09 21:22:20 -0800486 mp->entry.protocol = p->protocol;
487 mp->entry.policy = ipsec_spd_action_encode (p->policy);
488 mp->entry.sa_id = htonl (p->sa_id);
489
Florin Coras6c4dae22018-01-09 06:39:23 -0800490 vl_api_send_msg (reg, (u8 *) mp);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100491}
492
493static void
494vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp)
495{
Florin Coras6c4dae22018-01-09 06:39:23 -0800496 vl_api_registration_t *reg;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100497 ipsec_main_t *im = &ipsec_main;
Neale Ranns9f231d42019-03-19 10:06:00 +0000498 ipsec_spd_policy_type_t ptype;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100499 ipsec_policy_t *policy;
500 ipsec_spd_t *spd;
501 uword *p;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800502 u32 spd_index, *ii;
Damjan Mariona9a951f2017-01-16 22:06:10 +0100503#if WITH_LIBSSL > 0
Florin Coras6c4dae22018-01-09 06:39:23 -0800504 reg = vl_api_client_index_to_registration (mp->client_index);
505 if (!reg)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100506 return;
507
508 p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id));
509 if (!p)
510 return;
511
512 spd_index = p[0];
513 spd = pool_elt_at_index (im->spds, spd_index);
514
515 /* *INDENT-OFF* */
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800516 FOR_EACH_IPSEC_SPD_POLICY_TYPE(ptype) {
517 vec_foreach(ii, spd->policies[ptype])
518 {
519 policy = pool_elt_at_index(im->policies, *ii);
520
521 if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id)
522 send_ipsec_spd_details (policy, reg, mp->context);
523 }
524 }
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100525 /* *INDENT-ON* */
526#else
527 clib_warning ("unimplemented");
528#endif
529}
530
531static void
Filip Varga871bca92018-11-02 13:51:44 +0100532send_ipsec_spd_interface_details (vl_api_registration_t * reg, u32 spd_index,
533 u32 sw_if_index, u32 context)
534{
535 vl_api_ipsec_spd_interface_details_t *mp;
536
537 mp = vl_msg_api_alloc (sizeof (*mp));
538 clib_memset (mp, 0, sizeof (*mp));
539 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_INTERFACE_DETAILS);
540 mp->context = context;
541
542 mp->spd_index = htonl (spd_index);
543 mp->sw_if_index = htonl (sw_if_index);
544
545 vl_api_send_msg (reg, (u8 *) mp);
546}
547
548static void
549vl_api_ipsec_spd_interface_dump_t_handler (vl_api_ipsec_spd_interface_dump_t *
550 mp)
551{
552 ipsec_main_t *im = &ipsec_main;
553 vl_api_registration_t *reg;
554 u32 k, v, spd_index;
555
556#if WITH_LIBSSL > 0
557 reg = vl_api_client_index_to_registration (mp->client_index);
558 if (!reg)
559 return;
560
561 if (mp->spd_index_valid)
562 {
563 spd_index = ntohl (mp->spd_index);
564 /* *INDENT-OFF* */
565 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
566 if (v == spd_index)
567 send_ipsec_spd_interface_details(reg, v, k, mp->context);
568 }));
569 /* *INDENT-ON* */
570 }
571 else
572 {
573 /* *INDENT-OFF* */
574 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
575 send_ipsec_spd_interface_details(reg, v, k, mp->context);
576 }));
577 /* *INDENT-ON* */
578 }
579
580#else
581 clib_warning ("unimplemented");
582#endif
583}
584
Neale Ranns12989b52019-09-26 16:20:19 +0000585static u32
586ipsec_tun_mk_input_sa_id (u32 ti)
587{
588 return (0x80000000 | ti);
589}
590
591static u32
592ipsec_tun_mk_output_sa_id (u32 ti)
593{
594 return (0xc0000000 | ti);
595}
596
Filip Varga871bca92018-11-02 13:51:44 +0100597static void
Matthew Smithb0972cb2017-05-02 16:20:41 -0500598vl_api_ipsec_tunnel_if_add_del_t_handler (vl_api_ipsec_tunnel_if_add_del_t *
599 mp)
600{
601 vl_api_ipsec_tunnel_if_add_del_reply_t *rmp;
Matthew Smithe04d09d2017-05-14 21:47:18 -0500602 u32 sw_if_index = ~0;
Matthew Smithb0972cb2017-05-02 16:20:41 -0500603 int rv;
604
605#if WITH_LIBSSL > 0
Neale Ranns12989b52019-09-26 16:20:19 +0000606 ip46_address_t local_ip = ip46_address_initializer;
607 ip46_address_t remote_ip = ip46_address_initializer;
608 ipsec_key_t crypto_key, integ_key;
609 ipsec_sa_flags_t flags;
610 ip46_type_t local_ip_type, remote_ip_type;
611 ipip_transport_t transport;
612 u32 fib_index;
Matthew Smithb0972cb2017-05-02 16:20:41 -0500613
Neale Ranns12989b52019-09-26 16:20:19 +0000614 local_ip_type = ip_address_decode (&mp->local_ip, &local_ip);
615 remote_ip_type = ip_address_decode (&mp->remote_ip, &remote_ip);
616 transport = (IP46_TYPE_IP6 == local_ip_type ?
617 IPIP_TRANSPORT_IP6 : IPIP_TRANSPORT_IP4);
Matthew Smithb0972cb2017-05-02 16:20:41 -0500618
Neale Ranns12989b52019-09-26 16:20:19 +0000619 if (local_ip_type != remote_ip_type)
620 {
621 rv = VNET_API_ERROR_INVALID_VALUE;
622 goto done;
623 }
Matthew Smithb0972cb2017-05-02 16:20:41 -0500624
Neale Ranns12989b52019-09-26 16:20:19 +0000625 flags = IPSEC_SA_FLAG_NONE;
626
627 if (mp->udp_encap)
628 flags |= IPSEC_SA_FLAG_UDP_ENCAP;
629 if (mp->esn)
630 flags |= IPSEC_SA_FLAG_USE_ESN;
631 if (mp->anti_replay)
632 flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;
633
634 ipsec_mk_key (&crypto_key, mp->remote_crypto_key,
635 mp->remote_crypto_key_len);
636 ipsec_mk_key (&integ_key, mp->remote_integ_key, mp->remote_integ_key_len);
637 ipsec_mk_key (&crypto_key, mp->local_crypto_key, mp->local_crypto_key_len);
638 ipsec_mk_key (&integ_key, mp->local_integ_key, mp->local_integ_key_len);
639
640 fib_index =
641 fib_table_find (fib_proto_from_ip46 (local_ip_type),
642 ntohl (mp->tx_table_id));
643
644 if (~0 == fib_index)
645 {
646 rv = VNET_API_ERROR_NO_SUCH_FIB;
647 goto done;
648 }
649
650 if (mp->is_add)
651 {
652 // remote = input, local = output
653 /* create an ip-ip tunnel, then the two SA, then bind them */
654 rv = ipip_add_tunnel (transport,
Neale Rannsa548d132019-11-20 08:34:58 +0000655 (mp->renumber ? ntohl (mp->show_instance) : ~0),
Neale Ranns12989b52019-09-26 16:20:19 +0000656 &local_ip,
Neale Ranns95346962019-11-25 13:04:44 +0000657 &remote_ip, fib_index,
Neale Ranns59ff9182019-12-29 23:55:18 +0000658 TUNNEL_ENCAP_DECAP_FLAG_NONE, IP_DSCP_CS0,
Neale Ranns14053c92019-12-29 23:55:18 +0000659 TUNNEL_MODE_P2P, &sw_if_index);
Neale Ranns12989b52019-09-26 16:20:19 +0000660
661 if (rv)
662 goto done;
663
664 rv = ipsec_sa_add_and_lock (ipsec_tun_mk_input_sa_id (sw_if_index),
665 ntohl (mp->remote_spi),
666 IPSEC_PROTOCOL_ESP,
667 mp->crypto_alg,
668 &crypto_key,
669 mp->integ_alg,
670 &integ_key,
671 (flags | IPSEC_SA_FLAG_IS_INBOUND),
672 ntohl (mp->tx_table_id),
Filip Tehlare5d34912020-03-02 15:17:37 +0000673 mp->salt, &remote_ip, &local_ip, NULL,
Neale Rannsabc56602020-04-01 09:45:23 +0000674 IPSEC_UDP_PORT_NONE, IPSEC_UDP_PORT_NONE);
Neale Ranns12989b52019-09-26 16:20:19 +0000675
676 if (rv)
677 goto done;
678
679 rv = ipsec_sa_add_and_lock (ipsec_tun_mk_output_sa_id (sw_if_index),
680 ntohl (mp->local_spi),
681 IPSEC_PROTOCOL_ESP,
682 mp->crypto_alg,
683 &crypto_key,
684 mp->integ_alg,
685 &integ_key,
686 flags,
687 ntohl (mp->tx_table_id),
Filip Tehlare5d34912020-03-02 15:17:37 +0000688 mp->salt, &local_ip, &remote_ip, NULL,
Neale Rannsabc56602020-04-01 09:45:23 +0000689 IPSEC_UDP_PORT_NONE, IPSEC_UDP_PORT_NONE);
Neale Ranns12989b52019-09-26 16:20:19 +0000690
691 if (rv)
692 goto done;
693
Neale Ranns28287212019-12-16 00:53:11 +0000694 rv = ipsec_tun_protect_update_one (sw_if_index, NULL,
Neale Ranns12989b52019-09-26 16:20:19 +0000695 ipsec_tun_mk_output_sa_id
696 (sw_if_index),
697 ipsec_tun_mk_input_sa_id
698 (sw_if_index));
699 if (rv)
700 goto done;
701
702 /* the SAs are locked as a result of being used for proection,
703 * they cannot be removed from the API, since they cannot be refered
704 * to by the API. unlock them now, so that if the tunnel is rekeyed
705 * they-ll disapper
706 */
707 ipsec_sa_unlock_id (ipsec_tun_mk_input_sa_id (sw_if_index));
708 ipsec_sa_unlock_id (ipsec_tun_mk_output_sa_id (sw_if_index));
709 }
710 else
711 {
Neale Rannsd14fccd2019-11-15 15:03:27 +0000712 /* *INDENT-OFF* */
Neale Ranns12989b52019-09-26 16:20:19 +0000713 ipip_tunnel_key_t key = {
714 .transport = transport,
715 .fib_index = fib_index,
716 .src = local_ip,
717 .dst = remote_ip
718 };
Neale Rannsd14fccd2019-11-15 15:03:27 +0000719 /* *INDENT-ON* */
720
Neale Ranns12989b52019-09-26 16:20:19 +0000721 ipip_tunnel_t *t = ipip_tunnel_db_find (&key);
722
Neale Rannsd14fccd2019-11-15 15:03:27 +0000723 if (NULL != t)
724 {
Neale Ranns28287212019-12-16 00:53:11 +0000725 rv = ipsec_tun_protect_del (t->sw_if_index, NULL);
Neale Rannsd14fccd2019-11-15 15:03:27 +0000726 ipip_del_tunnel (t->sw_if_index);
727 }
728 else
729 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
Neale Ranns12989b52019-09-26 16:20:19 +0000730 }
Matthew Smithb0972cb2017-05-02 16:20:41 -0500731
732#else
733 rv = VNET_API_ERROR_UNIMPLEMENTED;
734#endif
Neale Ranns12989b52019-09-26 16:20:19 +0000735done:
Neale Ranns8d7c5022019-02-06 01:41:05 -0800736 /* *INDENT-OFF* */
737 REPLY_MACRO2 (VL_API_IPSEC_TUNNEL_IF_ADD_DEL_REPLY,
738 ({
739 rmp->sw_if_index = htonl (sw_if_index);
740 }));
741 /* *INDENT-ON* */
Matthew Smithb0972cb2017-05-02 16:20:41 -0500742}
743
Neale Rannsdd4ccf22020-06-30 07:47:14 +0000744static void
745vl_api_ipsec_itf_create_t_handler (vl_api_ipsec_itf_create_t * mp)
746{
747 vl_api_ipsec_itf_create_reply_t *rmp;
748 tunnel_mode_t mode;
749 u32 sw_if_index = ~0;
750 int rv;
751
752 rv = tunnel_mode_decode (mp->itf.mode, &mode);
753
754 if (!rv)
755 rv = ipsec_itf_create (ntohl (mp->itf.user_instance), mode, &sw_if_index);
756
757 /* *INDENT-OFF* */
758 REPLY_MACRO2 (VL_API_IPSEC_ITF_CREATE_REPLY,
759 ({
760 rmp->sw_if_index = htonl (sw_if_index);
761 }));
762 /* *INDENT-ON* */
763}
764
765static void
766vl_api_ipsec_itf_delete_t_handler (vl_api_ipsec_itf_delete_t * mp)
767{
768 vl_api_ipsec_itf_delete_reply_t *rmp;
769 int rv;
770
771 rv = ipsec_itf_delete (ntohl (mp->sw_if_index));
772
773 REPLY_MACRO (VL_API_IPSEC_ITF_DELETE_REPLY);
774}
775
776static void
777vl_api_ipsec_itf_dump_t_handler (vl_api_ipsec_itf_dump_t * mp)
778{
779}
780
Neale Ranns12989b52019-09-26 16:20:19 +0000781typedef struct ipsec_sa_dump_match_ctx_t_
Matthew Smith28029532017-09-26 13:33:44 -0500782{
Neale Ranns12989b52019-09-26 16:20:19 +0000783 index_t sai;
784 u32 sw_if_index;
785} ipsec_sa_dump_match_ctx_t;
786
787static walk_rc_t
788ipsec_sa_dump_match_sa (index_t itpi, void *arg)
789{
790 ipsec_sa_dump_match_ctx_t *ctx = arg;
791 ipsec_tun_protect_t *itp;
792 index_t sai;
793
794 itp = ipsec_tun_protect_get (itpi);
795
796 if (itp->itp_out_sa == ctx->sai)
797 {
798 ctx->sw_if_index = itp->itp_sw_if_index;
799 return (WALK_STOP);
800 }
801 /* *INDENT-OFF* */
802 FOR_EACH_IPSEC_PROTECT_INPUT_SAI (itp, sai,
803 ({
804 if (sai == ctx->sai)
805 {
806 ctx->sw_if_index = itp->itp_sw_if_index;
807 return (WALK_STOP);
808 }
809 }));
810 /* *INDENT-OFF* */
811
812 return (WALK_CONTINUE);
813}
814
815static walk_rc_t
816send_ipsec_sa_details (ipsec_sa_t * sa, void *arg)
817{
818 ipsec_dump_walk_ctx_t *ctx = arg;
Matthew Smith28029532017-09-26 13:33:44 -0500819 vl_api_ipsec_sa_details_t *mp;
Neale Ranns12989b52019-09-26 16:20:19 +0000820 ipsec_main_t *im = &ipsec_main;
Matthew Smith28029532017-09-26 13:33:44 -0500821
822 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400823 clib_memset (mp, 0, sizeof (*mp));
Matthew Smith28029532017-09-26 13:33:44 -0500824 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_DETAILS);
Neale Ranns12989b52019-09-26 16:20:19 +0000825 mp->context = ctx->context;
Matthew Smith28029532017-09-26 13:33:44 -0500826
Neale Ranns8d7c5022019-02-06 01:41:05 -0800827 mp->entry.sad_id = htonl (sa->id);
828 mp->entry.spi = htonl (sa->spi);
829 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
830 mp->entry.tx_table_id =
831 htonl (fib_table_get_table_id (sa->tx_fib_index, FIB_PROTOCOL_IP4));
Matthew Smith28029532017-09-26 13:33:44 -0500832
Neale Ranns8d7c5022019-02-06 01:41:05 -0800833 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
834 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
Matthew Smith28029532017-09-26 13:33:44 -0500835
Neale Ranns8d7c5022019-02-06 01:41:05 -0800836 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
837 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
Matthew Smith28029532017-09-26 13:33:44 -0500838
Neale Ranns8d7c5022019-02-06 01:41:05 -0800839 mp->entry.flags = ipsec_sad_flags_encode (sa);
Neale Ranns12989b52019-09-26 16:20:19 +0000840 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
841
842 if (ipsec_sa_is_set_IS_PROTECT (sa))
843 {
844 ipsec_sa_dump_match_ctx_t ctx = {
845 .sai = sa - im->sad,
846 .sw_if_index = ~0,
847 };
848 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
849
850 mp->sw_if_index = htonl (ctx.sw_if_index);
851 }
852 else
853 mp->sw_if_index = ~0;
Matthew Smith28029532017-09-26 13:33:44 -0500854
Damjan Mariond709cbc2019-03-26 13:16:42 +0100855 if (ipsec_sa_is_set_IS_TUNNEL (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500856 {
Neale Ranns8d7c5022019-02-06 01:41:05 -0800857 ip_address_encode (&sa->tunnel_src_addr, IP46_TYPE_ANY,
858 &mp->entry.tunnel_src);
859 ip_address_encode (&sa->tunnel_dst_addr, IP46_TYPE_ANY,
860 &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -0500861 }
Neale Rannsabc56602020-04-01 09:45:23 +0000862 if (ipsec_sa_is_set_UDP_ENCAP (sa))
863 {
864 mp->entry.udp_src_port = sa->udp_hdr.src_port;
865 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
866 }
Matthew Smith28029532017-09-26 13:33:44 -0500867
Matthew Smith28029532017-09-26 13:33:44 -0500868 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
869 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
Damjan Marion1e3aa5e2019-03-28 10:58:59 +0100870 if (ipsec_sa_is_set_USE_ESN (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500871 {
872 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
873 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
874 }
Damjan Mariond709cbc2019-03-26 13:16:42 +0100875 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500876 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
Pierre Pfister4c422f92018-12-10 11:19:08 +0100877
Matthew Smith48d32b42020-04-02 07:45:49 -0500878 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
879
Neale Ranns12989b52019-09-26 16:20:19 +0000880 vl_api_send_msg (ctx->reg, (u8 *) mp);
Matthew Smith28029532017-09-26 13:33:44 -0500881
Neale Ranns12989b52019-09-26 16:20:19 +0000882 return (WALK_CONTINUE);
883}
Matthew Smith28029532017-09-26 13:33:44 -0500884
885static void
886vl_api_ipsec_sa_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
887{
Florin Coras6c4dae22018-01-09 06:39:23 -0800888 vl_api_registration_t *reg;
Matthew Smith28029532017-09-26 13:33:44 -0500889
890#if WITH_LIBSSL > 0
Florin Coras6c4dae22018-01-09 06:39:23 -0800891 reg = vl_api_client_index_to_registration (mp->client_index);
Neale Ranns12989b52019-09-26 16:20:19 +0000892 if (!reg)
Matthew Smith28029532017-09-26 13:33:44 -0500893 return;
894
Neale Ranns12989b52019-09-26 16:20:19 +0000895 ipsec_dump_walk_ctx_t ctx = {
896 .reg = reg,
897 .context = mp->context,
898 };
Matthew Smith28029532017-09-26 13:33:44 -0500899
Neale Ranns12989b52019-09-26 16:20:19 +0000900 ipsec_sa_walk (send_ipsec_sa_details, &ctx);
Matthew Smith28029532017-09-26 13:33:44 -0500901
Matthew Smith28029532017-09-26 13:33:44 -0500902#else
903 clib_warning ("unimplemented");
904#endif
905}
906
Matthew Smith75d85602017-10-05 19:03:05 -0500907static void
Matthew Smithca514fd2017-10-12 12:06:59 -0500908vl_api_ipsec_tunnel_if_set_sa_t_handler (vl_api_ipsec_tunnel_if_set_sa_t * mp)
909{
910 vl_api_ipsec_tunnel_if_set_sa_reply_t *rmp;
Matthew Smithca514fd2017-10-12 12:06:59 -0500911 int rv;
912
913#if WITH_LIBSSL > 0
Neale Ranns12989b52019-09-26 16:20:19 +0000914 VALIDATE_SW_IF_INDEX(mp);
Matthew Smithca514fd2017-10-12 12:06:59 -0500915
Neale Ranns12989b52019-09-26 16:20:19 +0000916 if (mp->is_outbound)
Neale Ranns28287212019-12-16 00:53:11 +0000917 rv = ipsec_tun_protect_update_out (ntohl (mp->sw_if_index), NULL,
Neale Ranns12989b52019-09-26 16:20:19 +0000918 ntohl (mp->sa_id));
919 else
Neale Ranns28287212019-12-16 00:53:11 +0000920 rv = ipsec_tun_protect_update_in (ntohl (mp->sw_if_index), NULL,
Neale Ranns12989b52019-09-26 16:20:19 +0000921 ntohl (mp->sa_id));
922
Matthew Smithca514fd2017-10-12 12:06:59 -0500923#else
924 clib_warning ("unimplemented");
925#endif
926
Neale Ranns12989b52019-09-26 16:20:19 +0000927 BAD_SW_IF_INDEX_LABEL;
928
Matthew Smithca514fd2017-10-12 12:06:59 -0500929 REPLY_MACRO (VL_API_IPSEC_TUNNEL_IF_SET_SA_REPLY);
930}
931
Klement Sekerab4d30532018-11-08 13:00:02 +0100932static void
933vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp)
934{
935 vl_api_registration_t *rp;
936 ipsec_main_t *im = &ipsec_main;
937 u32 context = mp->context;
938
939 rp = vl_api_client_index_to_registration (mp->client_index);
940
941 if (rp == 0)
942 {
943 clib_warning ("Client %d AWOL", mp->client_index);
944 return;
945 }
946
947 ipsec_ah_backend_t *ab;
948 ipsec_esp_backend_t *eb;
949 /* *INDENT-OFF* */
950 pool_foreach (ab, im->ah_backends, {
951 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
952 clib_memset (mp, 0, sizeof (*mp));
953 mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
954 mp->context = context;
955 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (ab->name),
956 ab->name);
Neale Ranns17dcec02019-01-09 21:22:20 -0800957 mp->protocol = ntohl (IPSEC_API_PROTO_AH);
Klement Sekerab4d30532018-11-08 13:00:02 +0100958 mp->index = ab - im->ah_backends;
959 mp->active = mp->index == im->ah_current_backend ? 1 : 0;
960 vl_api_send_msg (rp, (u8 *)mp);
961 });
962 pool_foreach (eb, im->esp_backends, {
963 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
964 clib_memset (mp, 0, sizeof (*mp));
965 mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
966 mp->context = context;
967 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (eb->name),
968 eb->name);
Neale Ranns17dcec02019-01-09 21:22:20 -0800969 mp->protocol = ntohl (IPSEC_API_PROTO_ESP);
Klement Sekerab4d30532018-11-08 13:00:02 +0100970 mp->index = eb - im->esp_backends;
971 mp->active = mp->index == im->esp_current_backend ? 1 : 0;
972 vl_api_send_msg (rp, (u8 *)mp);
973 });
974 /* *INDENT-ON* */
975}
976
977static void
978vl_api_ipsec_select_backend_t_handler (vl_api_ipsec_select_backend_t * mp)
979{
980 ipsec_main_t *im = &ipsec_main;
981 vl_api_ipsec_select_backend_reply_t *rmp;
Neale Ranns17dcec02019-01-09 21:22:20 -0800982 ipsec_protocol_t protocol;
Klement Sekerab4d30532018-11-08 13:00:02 +0100983 int rv = 0;
984 if (pool_elts (im->sad) > 0)
985 {
986 rv = VNET_API_ERROR_INSTANCE_IN_USE;
987 goto done;
988 }
Neale Ranns17dcec02019-01-09 21:22:20 -0800989
990 rv = ipsec_proto_decode (mp->protocol, &protocol);
991
992 if (rv)
993 goto done;
994
Klement Sekerab4d30532018-11-08 13:00:02 +0100995#if WITH_LIBSSL > 0
Neale Ranns17dcec02019-01-09 21:22:20 -0800996 switch (protocol)
Klement Sekerab4d30532018-11-08 13:00:02 +0100997 {
998 case IPSEC_PROTOCOL_ESP:
Neale Rannse8915fc2019-04-23 20:57:55 -0400999 rv = ipsec_select_esp_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001000 break;
1001 case IPSEC_PROTOCOL_AH:
Neale Rannse8915fc2019-04-23 20:57:55 -04001002 rv = ipsec_select_ah_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001003 break;
1004 default:
Neale Rannse8915fc2019-04-23 20:57:55 -04001005 rv = VNET_API_ERROR_INVALID_PROTOCOL;
Klement Sekerab4d30532018-11-08 13:00:02 +01001006 break;
1007 }
1008#else
1009 clib_warning ("unimplemented"); /* FIXME */
1010#endif
1011done:
1012 REPLY_MACRO (VL_API_IPSEC_SELECT_BACKEND_REPLY);
1013}
1014
Neale Ranns7c44d782019-02-25 10:28:29 +00001015/*
1016 * ipsec_api_hookup
1017 * Add vpe's API message handlers to the table.
1018 * vlib has already mapped shared memory and
1019 * added the client registration handlers.
1020 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
1021 */
1022#define vl_msg_name_crc_list
1023#include <vnet/vnet_all_api_h.h>
1024#undef vl_msg_name_crc_list
1025
1026static void
1027setup_message_id_table (api_main_t * am)
1028{
1029#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1030 foreach_vl_msg_name_crc_ipsec;
1031#undef _
1032}
1033
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001034static clib_error_t *
1035ipsec_api_hookup (vlib_main_t * vm)
1036{
Dave Barach39d69112019-11-27 11:42:13 -05001037 api_main_t *am = vlibapi_get_main ();
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001038
1039#define _(N,n) \
1040 vl_msg_api_set_handlers(VL_API_##N, #n, \
1041 vl_api_##n##_t_handler, \
1042 vl_noop_handler, \
1043 vl_api_##n##_t_endian, \
1044 vl_api_##n##_t_print, \
1045 sizeof(vl_api_##n##_t), 1);
1046 foreach_vpe_api_msg;
1047#undef _
1048
1049 /*
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001050 * Set up the (msg_name, crc, message-id) table
1051 */
1052 setup_message_id_table (am);
1053
1054 return 0;
1055}
1056
1057VLIB_API_INIT_FUNCTION (ipsec_api_hookup);
1058
1059/*
1060 * fd.io coding-style-patch-verification: ON
1061 *
1062 * Local Variables:
1063 * eval: (c-set-style "gnu")
1064 * End:
1065 */