blob: b1b6db7e29066957a2ec74d0af8653084d364c12 [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>
Pierre Pfister4c422f92018-12-10 11:19:08 +010027#include <vnet/fib/fib.h>
Neale Ranns12989b52019-09-26 16:20:19 +000028#include <vnet/ipip/ipip.h>
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010029
30#include <vnet/vnet_msg_enum.h>
31
Damjan Mariona9a951f2017-01-16 22:06:10 +010032#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010033#include <vnet/ipsec/ipsec.h>
Neale Rannsc87b66c2019-02-07 07:26:12 -080034#include <vnet/ipsec/ipsec_tun.h>
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010035#endif /* IPSEC */
36
37#define vl_typedefs /* define message structures */
38#include <vnet/vnet_all_api_h.h>
39#undef vl_typedefs
40
41#define vl_endianfun /* define message structures */
42#include <vnet/vnet_all_api_h.h>
43#undef vl_endianfun
44
45/* instantiate all the print functions we know about */
46#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
47#define vl_printfun
48#include <vnet/vnet_all_api_h.h>
49#undef vl_printfun
50
51#include <vlibapi/api_helper_macros.h>
52
Klement Sekerab4d30532018-11-08 13:00:02 +010053#define foreach_vpe_api_msg \
54_(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \
55_(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \
Neale Ranns17dcec02019-01-09 21:22:20 -080056_(IPSEC_SPD_ENTRY_ADD_DEL, ipsec_spd_entry_add_del) \
57_(IPSEC_SAD_ENTRY_ADD_DEL, ipsec_sad_entry_add_del) \
Klement Sekerab4d30532018-11-08 13:00:02 +010058_(IPSEC_SA_DUMP, ipsec_sa_dump) \
59_(IPSEC_SPDS_DUMP, ipsec_spds_dump) \
60_(IPSEC_SPD_DUMP, ipsec_spd_dump) \
61_(IPSEC_SPD_INTERFACE_DUMP, ipsec_spd_interface_dump) \
62_(IPSEC_TUNNEL_IF_ADD_DEL, ipsec_tunnel_if_add_del) \
Klement Sekerab4d30532018-11-08 13:00:02 +010063_(IPSEC_TUNNEL_IF_SET_SA, ipsec_tunnel_if_set_sa) \
Klement Sekerab4d30532018-11-08 13:00:02 +010064_(IPSEC_SELECT_BACKEND, ipsec_select_backend) \
Neale Rannsc87b66c2019-02-07 07:26:12 -080065_(IPSEC_BACKEND_DUMP, ipsec_backend_dump) \
66_(IPSEC_TUNNEL_PROTECT_UPDATE, ipsec_tunnel_protect_update) \
67_(IPSEC_TUNNEL_PROTECT_DEL, ipsec_tunnel_protect_del) \
68_(IPSEC_TUNNEL_PROTECT_DUMP, ipsec_tunnel_protect_dump)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010069
Klement Sekerab4d30532018-11-08 13:00:02 +010070static void
71vl_api_ipsec_spd_add_del_t_handler (vl_api_ipsec_spd_add_del_t * mp)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010072{
Damjan Mariona9a951f2017-01-16 22:06:10 +010073#if WITH_LIBSSL == 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010074 clib_warning ("unimplemented");
75#else
76
77 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
78 vl_api_ipsec_spd_add_del_reply_t *rmp;
79 int rv;
80
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010081 rv = ipsec_add_del_spd (vm, ntohl (mp->spd_id), mp->is_add);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010082
83 REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_REPLY);
84#endif
85}
86
87static void vl_api_ipsec_interface_add_del_spd_t_handler
88 (vl_api_ipsec_interface_add_del_spd_t * mp)
89{
90 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
91 vl_api_ipsec_interface_add_del_spd_reply_t *rmp;
92 int rv;
93 u32 sw_if_index __attribute__ ((unused));
94 u32 spd_id __attribute__ ((unused));
95
96 sw_if_index = ntohl (mp->sw_if_index);
97 spd_id = ntohl (mp->spd_id);
98
99 VALIDATE_SW_IF_INDEX (mp);
100
Damjan Mariona9a951f2017-01-16 22:06:10 +0100101#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100102 rv = ipsec_set_interface_spd (vm, sw_if_index, spd_id, mp->is_add);
103#else
104 rv = VNET_API_ERROR_UNIMPLEMENTED;
105#endif
106
107 BAD_SW_IF_INDEX_LABEL;
108
109 REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY);
110}
111
Neale Rannsc87b66c2019-02-07 07:26:12 -0800112static void vl_api_ipsec_tunnel_protect_update_t_handler
113 (vl_api_ipsec_tunnel_protect_update_t * mp)
114{
115 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
116 vl_api_ipsec_tunnel_protect_update_reply_t *rmp;
117 u32 sw_if_index, ii, *sa_ins = NULL;
118 int rv;
119
120 sw_if_index = ntohl (mp->tunnel.sw_if_index);
121
122 VALIDATE_SW_IF_INDEX (&(mp->tunnel));
123
124#if WITH_LIBSSL > 0
125
126 for (ii = 0; ii < mp->tunnel.n_sa_in; ii++)
127 vec_add1 (sa_ins, ntohl (mp->tunnel.sa_in[ii]));
128
129 rv = ipsec_tun_protect_update (sw_if_index,
130 ntohl (mp->tunnel.sa_out), sa_ins);
131#else
132 rv = VNET_API_ERROR_UNIMPLEMENTED;
133#endif
134
135 BAD_SW_IF_INDEX_LABEL;
136
137 REPLY_MACRO (VL_API_IPSEC_TUNNEL_PROTECT_UPDATE_REPLY);
138}
139
140static void vl_api_ipsec_tunnel_protect_del_t_handler
141 (vl_api_ipsec_tunnel_protect_del_t * mp)
142{
143 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
144 vl_api_ipsec_tunnel_protect_del_reply_t *rmp;
145 int rv;
146 u32 sw_if_index;
147
148 sw_if_index = ntohl (mp->sw_if_index);
149
150 VALIDATE_SW_IF_INDEX (mp);
151
152#if WITH_LIBSSL > 0
153 rv = ipsec_tun_protect_del (sw_if_index);
154#else
155 rv = VNET_API_ERROR_UNIMPLEMENTED;
156#endif
157
158 BAD_SW_IF_INDEX_LABEL;
159
160 REPLY_MACRO (VL_API_IPSEC_TUNNEL_PROTECT_DEL_REPLY);
161}
162
Neale Ranns12989b52019-09-26 16:20:19 +0000163typedef struct ipsec_dump_walk_ctx_t_
Neale Rannsc87b66c2019-02-07 07:26:12 -0800164{
165 vl_api_registration_t *reg;
166 u32 context;
Neale Ranns12989b52019-09-26 16:20:19 +0000167} ipsec_dump_walk_ctx_t;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800168
169static walk_rc_t
170send_ipsec_tunnel_protect_details (index_t itpi, void *arg)
171{
Neale Ranns12989b52019-09-26 16:20:19 +0000172 ipsec_dump_walk_ctx_t *ctx = arg;
Neale Rannsc87b66c2019-02-07 07:26:12 -0800173 vl_api_ipsec_tunnel_protect_details_t *mp;
174 ipsec_tun_protect_t *itp;
175 u32 sai, ii = 0;
176
177 itp = ipsec_tun_protect_get (itpi);
178
179
180 mp = vl_msg_api_alloc (sizeof (*mp) + (sizeof (u32) * itp->itp_n_sa_in));
181 clib_memset (mp, 0, sizeof (*mp));
182 mp->_vl_msg_id = ntohs (VL_API_IPSEC_TUNNEL_PROTECT_DETAILS);
183 mp->context = ctx->context;
184
185 mp->tun.sw_if_index = htonl (itp->itp_sw_if_index);
186
187 mp->tun.sa_out = htonl (itp->itp_out_sa);
188 mp->tun.n_sa_in = itp->itp_n_sa_in;
189 /* *INDENT-OFF* */
190 FOR_EACH_IPSEC_PROTECT_INPUT_SAI(itp, sai,
191 ({
192 mp->tun.sa_in[ii++] = htonl (sai);
193 }));
194 /* *INDENT-ON* */
195
196 vl_api_send_msg (ctx->reg, (u8 *) mp);
197
198 return (WALK_CONTINUE);
199}
200
201static void
202vl_api_ipsec_tunnel_protect_dump_t_handler (vl_api_ipsec_tunnel_protect_dump_t
203 * mp)
204{
205 vl_api_registration_t *reg;
206 u32 sw_if_index;
207
208#if WITH_LIBSSL > 0
209 reg = vl_api_client_index_to_registration (mp->client_index);
210 if (!reg)
211 return;
212
Neale Ranns12989b52019-09-26 16:20:19 +0000213 ipsec_dump_walk_ctx_t ctx = {
Neale Rannsc87b66c2019-02-07 07:26:12 -0800214 .reg = reg,
215 .context = mp->context,
216 };
217
218 sw_if_index = ntohl (mp->sw_if_index);
219
220 if (~0 == sw_if_index)
221 {
222 ipsec_tun_protect_walk (send_ipsec_tunnel_protect_details, &ctx);
223 }
224 else
225 {
226 index_t itpi;
227
228 itpi = ipsec_tun_protect_find (sw_if_index);
229
230 if (INDEX_INVALID != itpi)
231 send_ipsec_tunnel_protect_details (itpi, &ctx);
232 }
233#else
234 clib_warning ("unimplemented");
235#endif
236}
237
Neale Ranns17dcec02019-01-09 21:22:20 -0800238static int
239ipsec_spd_action_decode (vl_api_ipsec_spd_action_t in,
240 ipsec_policy_action_t * out)
241{
242 in = clib_net_to_host_u32 (in);
243
244 switch (in)
245 {
246#define _(v,f,s) case IPSEC_API_SPD_ACTION_##f: \
247 *out = IPSEC_POLICY_ACTION_##f; \
248 return (0);
249 foreach_ipsec_policy_action
250#undef _
251 }
252 return (VNET_API_ERROR_UNIMPLEMENTED);
253}
254
255static void vl_api_ipsec_spd_entry_add_del_t_handler
256 (vl_api_ipsec_spd_entry_add_del_t * mp)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100257{
258 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
Neale Ranns17dcec02019-01-09 21:22:20 -0800259 vl_api_ipsec_spd_entry_add_del_reply_t *rmp;
260 ip46_type_t itype;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800261 u32 stat_index;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100262 int rv;
263
Neale Ranns8c2dd1b2019-02-19 08:27:34 -0800264 stat_index = ~0;
265
Damjan Mariona9a951f2017-01-16 22:06:10 +0100266#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100267 ipsec_policy_t p;
268
Dave Barachb7b92992018-10-17 10:38:51 -0400269 clib_memset (&p, 0, sizeof (p));
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100270
Neale Ranns17dcec02019-01-09 21:22:20 -0800271 p.id = ntohl (mp->entry.spd_id);
272 p.priority = ntohl (mp->entry.priority);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100273
Neale Ranns17dcec02019-01-09 21:22:20 -0800274 itype = ip_address_decode (&mp->entry.remote_address_start, &p.raddr.start);
275 ip_address_decode (&mp->entry.remote_address_stop, &p.raddr.stop);
276 ip_address_decode (&mp->entry.local_address_start, &p.laddr.start);
277 ip_address_decode (&mp->entry.local_address_stop, &p.laddr.stop);
278
279 p.is_ipv6 = (itype == IP46_TYPE_IP6);
280
281 p.protocol = mp->entry.protocol;
Neale Rannsa4d24312019-07-10 13:46:21 +0000282 p.rport.start = ntohs (mp->entry.remote_port_start);
283 p.rport.stop = ntohs (mp->entry.remote_port_stop);
284 p.lport.start = ntohs (mp->entry.local_port_start);
285 p.lport.stop = ntohs (mp->entry.local_port_stop);
Neale Ranns17dcec02019-01-09 21:22:20 -0800286
287 rv = ipsec_spd_action_decode (mp->entry.policy, &p.policy);
288
289 if (rv)
290 goto out;
291
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100292 /* policy action resolve unsupported */
Neale Ranns17dcec02019-01-09 21:22:20 -0800293 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100294 {
295 clib_warning ("unsupported action: 'resolve'");
296 rv = VNET_API_ERROR_UNIMPLEMENTED;
297 goto out;
298 }
Neale Ranns17dcec02019-01-09 21:22:20 -0800299 p.sa_id = ntohl (mp->entry.sa_id);
Neale Ranns9f231d42019-03-19 10:06:00 +0000300 rv =
301 ipsec_policy_mk_type (mp->entry.is_outbound, p.is_ipv6, p.policy,
302 &p.type);
303 if (rv)
304 goto out;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100305
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800306 rv = ipsec_add_del_policy (vm, &p, mp->is_add, &stat_index);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100307 if (rv)
308 goto out;
309
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100310#else
311 rv = VNET_API_ERROR_UNIMPLEMENTED;
312 goto out;
313#endif
314
315out:
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800316 /* *INDENT-OFF* */
317 REPLY_MACRO2 (VL_API_IPSEC_SPD_ENTRY_ADD_DEL_REPLY,
318 ({
319 rmp->stat_index = ntohl(stat_index);
320 }));
321 /* *INDENT-ON* */
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100322}
323
Neale Ranns17dcec02019-01-09 21:22:20 -0800324static int
325ipsec_proto_decode (vl_api_ipsec_proto_t in, ipsec_protocol_t * out)
326{
327 in = clib_net_to_host_u32 (in);
328
329 switch (in)
330 {
331 case IPSEC_API_PROTO_ESP:
332 *out = IPSEC_PROTOCOL_ESP;
333 return (0);
334 case IPSEC_API_PROTO_AH:
335 *out = IPSEC_PROTOCOL_AH;
336 return (0);
337 }
Neale Rannsaf3f0782019-03-26 08:21:25 +0000338 return (VNET_API_ERROR_INVALID_PROTOCOL);
Neale Ranns17dcec02019-01-09 21:22:20 -0800339}
340
Neale Ranns8d7c5022019-02-06 01:41:05 -0800341static vl_api_ipsec_proto_t
342ipsec_proto_encode (ipsec_protocol_t p)
343{
344 switch (p)
345 {
346 case IPSEC_PROTOCOL_ESP:
347 return clib_host_to_net_u32 (IPSEC_API_PROTO_ESP);
348 case IPSEC_PROTOCOL_AH:
349 return clib_host_to_net_u32 (IPSEC_API_PROTO_AH);
350 }
351 return (VNET_API_ERROR_UNIMPLEMENTED);
352}
353
Neale Ranns17dcec02019-01-09 21:22:20 -0800354static int
355ipsec_crypto_algo_decode (vl_api_ipsec_crypto_alg_t in,
356 ipsec_crypto_alg_t * out)
357{
358 in = clib_net_to_host_u32 (in);
359
360 switch (in)
361 {
362#define _(v,f,s) case IPSEC_API_CRYPTO_ALG_##f: \
363 *out = IPSEC_CRYPTO_ALG_##f; \
364 return (0);
365 foreach_ipsec_crypto_alg
366#undef _
367 }
Neale Rannsaf3f0782019-03-26 08:21:25 +0000368 return (VNET_API_ERROR_INVALID_ALGORITHM);
Neale Ranns17dcec02019-01-09 21:22:20 -0800369}
370
Neale Ranns8d7c5022019-02-06 01:41:05 -0800371static vl_api_ipsec_crypto_alg_t
372ipsec_crypto_algo_encode (ipsec_crypto_alg_t c)
373{
374 switch (c)
375 {
376#define _(v,f,s) case IPSEC_CRYPTO_ALG_##f: \
377 return clib_host_to_net_u32(IPSEC_API_CRYPTO_ALG_##f);
378 foreach_ipsec_crypto_alg
379#undef _
380 case IPSEC_CRYPTO_N_ALG:
381 break;
382 }
383 ASSERT (0);
384 return (VNET_API_ERROR_UNIMPLEMENTED);
385}
386
Neale Ranns17dcec02019-01-09 21:22:20 -0800387static int
388ipsec_integ_algo_decode (vl_api_ipsec_integ_alg_t in, ipsec_integ_alg_t * out)
389{
390 in = clib_net_to_host_u32 (in);
391
392 switch (in)
393 {
394#define _(v,f,s) case IPSEC_API_INTEG_ALG_##f: \
395 *out = IPSEC_INTEG_ALG_##f; \
396 return (0);
397 foreach_ipsec_integ_alg
398#undef _
399 }
Neale Rannsaf3f0782019-03-26 08:21:25 +0000400 return (VNET_API_ERROR_INVALID_ALGORITHM);
Neale Ranns17dcec02019-01-09 21:22:20 -0800401}
402
Neale Ranns8d7c5022019-02-06 01:41:05 -0800403static vl_api_ipsec_integ_alg_t
404ipsec_integ_algo_encode (ipsec_integ_alg_t i)
Neale Ranns17dcec02019-01-09 21:22:20 -0800405{
Neale Ranns8d7c5022019-02-06 01:41:05 -0800406 switch (i)
407 {
408#define _(v,f,s) case IPSEC_INTEG_ALG_##f: \
409 return (clib_host_to_net_u32(IPSEC_API_INTEG_ALG_##f));
410 foreach_ipsec_integ_alg
411#undef _
412 case IPSEC_INTEG_N_ALG:
413 break;
414 }
415 ASSERT (0);
416 return (VNET_API_ERROR_UNIMPLEMENTED);
Neale Ranns17dcec02019-01-09 21:22:20 -0800417}
418
419static void
Neale Ranns8d7c5022019-02-06 01:41:05 -0800420ipsec_key_decode (const vl_api_key_t * key, ipsec_key_t * out)
Neale Ranns17dcec02019-01-09 21:22:20 -0800421{
Neale Ranns8d7c5022019-02-06 01:41:05 -0800422 ipsec_mk_key (out, key->data, key->length);
423}
424
425static void
426ipsec_key_encode (const ipsec_key_t * in, vl_api_key_t * out)
427{
428 out->length = in->len;
429 clib_memcpy (out->data, in->data, out->length);
430}
431
432static ipsec_sa_flags_t
433ipsec_sa_flags_decode (vl_api_ipsec_sad_flags_t in)
434{
435 ipsec_sa_flags_t flags = IPSEC_SA_FLAG_NONE;
Neale Ranns17dcec02019-01-09 21:22:20 -0800436 in = clib_net_to_host_u32 (in);
437
Neale Rannse524d452019-02-19 15:22:46 +0000438 if (in & IPSEC_API_SAD_FLAG_USE_ESN)
439 flags |= IPSEC_SA_FLAG_USE_ESN;
440 if (in & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY)
441 flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;
442 if (in & IPSEC_API_SAD_FLAG_IS_TUNNEL)
443 flags |= IPSEC_SA_FLAG_IS_TUNNEL;
444 if (in & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6)
445 flags |= IPSEC_SA_FLAG_IS_TUNNEL_V6;
446 if (in & IPSEC_API_SAD_FLAG_UDP_ENCAP)
447 flags |= IPSEC_SA_FLAG_UDP_ENCAP;
448
449 return (flags);
Neale Ranns17dcec02019-01-09 21:22:20 -0800450}
451
Neale Ranns8d7c5022019-02-06 01:41:05 -0800452static vl_api_ipsec_sad_flags_t
453ipsec_sad_flags_encode (const ipsec_sa_t * sa)
454{
455 vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
456
Damjan Marion1e3aa5e2019-03-28 10:58:59 +0100457 if (ipsec_sa_is_set_USE_ESN (sa))
458 flags |= IPSEC_API_SAD_FLAG_USE_ESN;
Damjan Mariond709cbc2019-03-26 13:16:42 +0100459 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
Neale Ranns8d7c5022019-02-06 01:41:05 -0800460 flags |= IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY;
Damjan Mariond709cbc2019-03-26 13:16:42 +0100461 if (ipsec_sa_is_set_IS_TUNNEL (sa))
Neale Ranns8d7c5022019-02-06 01:41:05 -0800462 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
Damjan Mariond709cbc2019-03-26 13:16:42 +0100463 if (ipsec_sa_is_set_IS_TUNNEL_V6 (sa))
Neale Ranns8d7c5022019-02-06 01:41:05 -0800464 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Mariond709cbc2019-03-26 13:16:42 +0100465 if (ipsec_sa_is_set_UDP_ENCAP (sa))
Neale Ranns8d7c5022019-02-06 01:41:05 -0800466 flags |= IPSEC_API_SAD_FLAG_UDP_ENCAP;
467
468 return clib_host_to_net_u32 (flags);
469}
Neale Ranns17dcec02019-01-09 21:22:20 -0800470
471static void vl_api_ipsec_sad_entry_add_del_t_handler
472 (vl_api_ipsec_sad_entry_add_del_t * mp)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100473{
474 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
Neale Ranns17dcec02019-01-09 21:22:20 -0800475 vl_api_ipsec_sad_entry_add_del_reply_t *rmp;
Neale Ranns8d7c5022019-02-06 01:41:05 -0800476 ip46_address_t tun_src = { }, tun_dst =
477 {
478 };
479 ipsec_key_t crypto_key, integ_key;
480 ipsec_crypto_alg_t crypto_alg;
481 ipsec_integ_alg_t integ_alg;
482 ipsec_protocol_t proto;
483 ipsec_sa_flags_t flags;
Dave Baracha5160d72019-03-13 15:29:15 -0400484 u32 id, spi, sa_index = ~0;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100485 int rv;
Neale Ranns8d7c5022019-02-06 01:41:05 -0800486
Damjan Mariona9a951f2017-01-16 22:06:10 +0100487#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100488
Neale Ranns8d7c5022019-02-06 01:41:05 -0800489 id = ntohl (mp->entry.sad_id);
490 spi = ntohl (mp->entry.spi);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100491
Neale Ranns8d7c5022019-02-06 01:41:05 -0800492 rv = ipsec_proto_decode (mp->entry.protocol, &proto);
Neale Ranns17dcec02019-01-09 21:22:20 -0800493
494 if (rv)
495 goto out;
496
Neale Ranns8d7c5022019-02-06 01:41:05 -0800497 rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
Neale Ranns17dcec02019-01-09 21:22:20 -0800498
499 if (rv)
500 goto out;
501
Neale Ranns8d7c5022019-02-06 01:41:05 -0800502 rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
Neale Ranns17dcec02019-01-09 21:22:20 -0800503
504 if (rv)
505 goto out;
506
Neale Ranns8d7c5022019-02-06 01:41:05 -0800507 ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
508 ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
Neale Ranns17dcec02019-01-09 21:22:20 -0800509
Neale Ranns8d7c5022019-02-06 01:41:05 -0800510 flags = ipsec_sa_flags_decode (mp->entry.flags);
Neale Ranns17dcec02019-01-09 21:22:20 -0800511
Neale Ranns8d7c5022019-02-06 01:41:05 -0800512 ip_address_decode (&mp->entry.tunnel_src, &tun_src);
513 ip_address_decode (&mp->entry.tunnel_dst, &tun_dst);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100514
Neale Ranns8d7c5022019-02-06 01:41:05 -0800515 if (mp->is_add)
Neale Ranns495d7ff2019-07-12 09:15:26 +0000516 rv = ipsec_sa_add_and_lock (id, spi, proto,
517 crypto_alg, &crypto_key,
518 integ_alg, &integ_key, flags,
519 0, mp->entry.salt, &tun_src, &tun_dst,
520 &sa_index);
Neale Ranns8d7c5022019-02-06 01:41:05 -0800521 else
Neale Ranns495d7ff2019-07-12 09:15:26 +0000522 rv = ipsec_sa_unlock_id (id);
Neale Ranns8d7c5022019-02-06 01:41:05 -0800523
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100524#else
525 rv = VNET_API_ERROR_UNIMPLEMENTED;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100526#endif
527
528out:
Neale Rannseba31ec2019-02-17 18:04:27 +0000529 /* *INDENT-OFF* */
530 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_REPLY,
531 {
532 rmp->stat_index = htonl (sa_index);
533 });
534 /* *INDENT-ON* */
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100535}
536
537static void
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700538send_ipsec_spds_details (ipsec_spd_t * spd, vl_api_registration_t * reg,
539 u32 context)
540{
541 vl_api_ipsec_spds_details_t *mp;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800542 u32 n_policies = 0;
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700543
544 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400545 clib_memset (mp, 0, sizeof (*mp));
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700546 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPDS_DETAILS);
547 mp->context = context;
548
549 mp->spd_id = htonl (spd->id);
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800550#define _(s, n) n_policies += vec_len (spd->policies[IPSEC_SPD_POLICY_##s]);
551 foreach_ipsec_spd_policy_type
552#undef _
553 mp->npolicies = htonl (n_policies);
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700554
555 vl_api_send_msg (reg, (u8 *) mp);
556}
557
558static void
559vl_api_ipsec_spds_dump_t_handler (vl_api_ipsec_spds_dump_t * mp)
560{
561 vl_api_registration_t *reg;
562 ipsec_main_t *im = &ipsec_main;
563 ipsec_spd_t *spd;
564#if WITH_LIBSSL > 0
565 reg = vl_api_client_index_to_registration (mp->client_index);
566 if (!reg)
567 return;
568
569 /* *INDENT-OFF* */
570 pool_foreach (spd, im->spds, ({
571 send_ipsec_spds_details (spd, reg, mp->context);
572 }));
573 /* *INDENT-ON* */
574#else
575 clib_warning ("unimplemented");
576#endif
577}
578
Neale Ranns17dcec02019-01-09 21:22:20 -0800579vl_api_ipsec_spd_action_t
580ipsec_spd_action_encode (ipsec_policy_action_t in)
581{
582 vl_api_ipsec_spd_action_t out = IPSEC_API_SPD_ACTION_BYPASS;
583
584 switch (in)
585 {
586#define _(v,f,s) case IPSEC_POLICY_ACTION_##f: \
587 out = IPSEC_API_SPD_ACTION_##f; \
588 break;
589 foreach_ipsec_policy_action
590#undef _
591 }
592 return (clib_host_to_net_u32 (out));
593}
594
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700595static void
Florin Coras6c4dae22018-01-09 06:39:23 -0800596send_ipsec_spd_details (ipsec_policy_t * p, vl_api_registration_t * reg,
597 u32 context)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100598{
599 vl_api_ipsec_spd_details_t *mp;
600
601 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400602 clib_memset (mp, 0, sizeof (*mp));
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100603 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_DETAILS);
604 mp->context = context;
605
Neale Ranns17dcec02019-01-09 21:22:20 -0800606 mp->entry.spd_id = htonl (p->id);
607 mp->entry.priority = htonl (p->priority);
Neale Ranns9f231d42019-03-19 10:06:00 +0000608 mp->entry.is_outbound = ((p->type == IPSEC_SPD_POLICY_IP6_OUTBOUND) ||
609 (p->type == IPSEC_SPD_POLICY_IP4_OUTBOUND));
Neale Ranns17dcec02019-01-09 21:22:20 -0800610
611 ip_address_encode (&p->laddr.start, IP46_TYPE_ANY,
612 &mp->entry.local_address_start);
613 ip_address_encode (&p->laddr.stop, IP46_TYPE_ANY,
614 &mp->entry.local_address_stop);
615 ip_address_encode (&p->raddr.start, IP46_TYPE_ANY,
616 &mp->entry.remote_address_start);
617 ip_address_encode (&p->raddr.stop, IP46_TYPE_ANY,
618 &mp->entry.remote_address_stop);
Neale Rannsa4d24312019-07-10 13:46:21 +0000619 mp->entry.local_port_start = htons (p->lport.start);
620 mp->entry.local_port_stop = htons (p->lport.stop);
621 mp->entry.remote_port_start = htons (p->rport.start);
622 mp->entry.remote_port_stop = htons (p->rport.stop);
Neale Ranns17dcec02019-01-09 21:22:20 -0800623 mp->entry.protocol = p->protocol;
624 mp->entry.policy = ipsec_spd_action_encode (p->policy);
625 mp->entry.sa_id = htonl (p->sa_id);
626
Florin Coras6c4dae22018-01-09 06:39:23 -0800627 vl_api_send_msg (reg, (u8 *) mp);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100628}
629
630static void
631vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp)
632{
Florin Coras6c4dae22018-01-09 06:39:23 -0800633 vl_api_registration_t *reg;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100634 ipsec_main_t *im = &ipsec_main;
Neale Ranns9f231d42019-03-19 10:06:00 +0000635 ipsec_spd_policy_type_t ptype;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100636 ipsec_policy_t *policy;
637 ipsec_spd_t *spd;
638 uword *p;
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800639 u32 spd_index, *ii;
Damjan Mariona9a951f2017-01-16 22:06:10 +0100640#if WITH_LIBSSL > 0
Florin Coras6c4dae22018-01-09 06:39:23 -0800641 reg = vl_api_client_index_to_registration (mp->client_index);
642 if (!reg)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100643 return;
644
645 p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id));
646 if (!p)
647 return;
648
649 spd_index = p[0];
650 spd = pool_elt_at_index (im->spds, spd_index);
651
652 /* *INDENT-OFF* */
Neale Rannsa09c1ff2019-02-04 01:10:30 -0800653 FOR_EACH_IPSEC_SPD_POLICY_TYPE(ptype) {
654 vec_foreach(ii, spd->policies[ptype])
655 {
656 policy = pool_elt_at_index(im->policies, *ii);
657
658 if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id)
659 send_ipsec_spd_details (policy, reg, mp->context);
660 }
661 }
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100662 /* *INDENT-ON* */
663#else
664 clib_warning ("unimplemented");
665#endif
666}
667
668static void
Filip Varga871bca92018-11-02 13:51:44 +0100669send_ipsec_spd_interface_details (vl_api_registration_t * reg, u32 spd_index,
670 u32 sw_if_index, u32 context)
671{
672 vl_api_ipsec_spd_interface_details_t *mp;
673
674 mp = vl_msg_api_alloc (sizeof (*mp));
675 clib_memset (mp, 0, sizeof (*mp));
676 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_INTERFACE_DETAILS);
677 mp->context = context;
678
679 mp->spd_index = htonl (spd_index);
680 mp->sw_if_index = htonl (sw_if_index);
681
682 vl_api_send_msg (reg, (u8 *) mp);
683}
684
685static void
686vl_api_ipsec_spd_interface_dump_t_handler (vl_api_ipsec_spd_interface_dump_t *
687 mp)
688{
689 ipsec_main_t *im = &ipsec_main;
690 vl_api_registration_t *reg;
691 u32 k, v, spd_index;
692
693#if WITH_LIBSSL > 0
694 reg = vl_api_client_index_to_registration (mp->client_index);
695 if (!reg)
696 return;
697
698 if (mp->spd_index_valid)
699 {
700 spd_index = ntohl (mp->spd_index);
701 /* *INDENT-OFF* */
702 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
703 if (v == spd_index)
704 send_ipsec_spd_interface_details(reg, v, k, mp->context);
705 }));
706 /* *INDENT-ON* */
707 }
708 else
709 {
710 /* *INDENT-OFF* */
711 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
712 send_ipsec_spd_interface_details(reg, v, k, mp->context);
713 }));
714 /* *INDENT-ON* */
715 }
716
717#else
718 clib_warning ("unimplemented");
719#endif
720}
721
Neale Ranns12989b52019-09-26 16:20:19 +0000722static u32
723ipsec_tun_mk_input_sa_id (u32 ti)
724{
725 return (0x80000000 | ti);
726}
727
728static u32
729ipsec_tun_mk_output_sa_id (u32 ti)
730{
731 return (0xc0000000 | ti);
732}
733
Filip Varga871bca92018-11-02 13:51:44 +0100734static void
Matthew Smithb0972cb2017-05-02 16:20:41 -0500735vl_api_ipsec_tunnel_if_add_del_t_handler (vl_api_ipsec_tunnel_if_add_del_t *
736 mp)
737{
738 vl_api_ipsec_tunnel_if_add_del_reply_t *rmp;
Matthew Smithe04d09d2017-05-14 21:47:18 -0500739 u32 sw_if_index = ~0;
Matthew Smithb0972cb2017-05-02 16:20:41 -0500740 int rv;
741
742#if WITH_LIBSSL > 0
Neale Ranns12989b52019-09-26 16:20:19 +0000743 ip46_address_t local_ip = ip46_address_initializer;
744 ip46_address_t remote_ip = ip46_address_initializer;
745 ipsec_key_t crypto_key, integ_key;
746 ipsec_sa_flags_t flags;
747 ip46_type_t local_ip_type, remote_ip_type;
748 ipip_transport_t transport;
749 u32 fib_index;
Matthew Smithb0972cb2017-05-02 16:20:41 -0500750
Neale Ranns12989b52019-09-26 16:20:19 +0000751 local_ip_type = ip_address_decode (&mp->local_ip, &local_ip);
752 remote_ip_type = ip_address_decode (&mp->remote_ip, &remote_ip);
753 transport = (IP46_TYPE_IP6 == local_ip_type ?
754 IPIP_TRANSPORT_IP6 : IPIP_TRANSPORT_IP4);
Matthew Smithb0972cb2017-05-02 16:20:41 -0500755
Neale Ranns12989b52019-09-26 16:20:19 +0000756 if (local_ip_type != remote_ip_type)
757 {
758 rv = VNET_API_ERROR_INVALID_VALUE;
759 goto done;
760 }
Matthew Smithb0972cb2017-05-02 16:20:41 -0500761
Neale Ranns12989b52019-09-26 16:20:19 +0000762 flags = IPSEC_SA_FLAG_NONE;
763
764 if (mp->udp_encap)
765 flags |= IPSEC_SA_FLAG_UDP_ENCAP;
766 if (mp->esn)
767 flags |= IPSEC_SA_FLAG_USE_ESN;
768 if (mp->anti_replay)
769 flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;
770
771 ipsec_mk_key (&crypto_key, mp->remote_crypto_key,
772 mp->remote_crypto_key_len);
773 ipsec_mk_key (&integ_key, mp->remote_integ_key, mp->remote_integ_key_len);
774 ipsec_mk_key (&crypto_key, mp->local_crypto_key, mp->local_crypto_key_len);
775 ipsec_mk_key (&integ_key, mp->local_integ_key, mp->local_integ_key_len);
776
777 fib_index =
778 fib_table_find (fib_proto_from_ip46 (local_ip_type),
779 ntohl (mp->tx_table_id));
780
781 if (~0 == fib_index)
782 {
783 rv = VNET_API_ERROR_NO_SUCH_FIB;
784 goto done;
785 }
786
787 if (mp->is_add)
788 {
789 // remote = input, local = output
790 /* create an ip-ip tunnel, then the two SA, then bind them */
791 rv = ipip_add_tunnel (transport,
792 ntohl (mp->show_instance),
793 &local_ip,
794 &remote_ip, fib_index, 0, &sw_if_index);
795
796 if (rv)
797 goto done;
798
799 rv = ipsec_sa_add_and_lock (ipsec_tun_mk_input_sa_id (sw_if_index),
800 ntohl (mp->remote_spi),
801 IPSEC_PROTOCOL_ESP,
802 mp->crypto_alg,
803 &crypto_key,
804 mp->integ_alg,
805 &integ_key,
806 (flags | IPSEC_SA_FLAG_IS_INBOUND),
807 ntohl (mp->tx_table_id),
808 mp->salt, &remote_ip, &local_ip, NULL);
809
810 if (rv)
811 goto done;
812
813 rv = ipsec_sa_add_and_lock (ipsec_tun_mk_output_sa_id (sw_if_index),
814 ntohl (mp->local_spi),
815 IPSEC_PROTOCOL_ESP,
816 mp->crypto_alg,
817 &crypto_key,
818 mp->integ_alg,
819 &integ_key,
820 flags,
821 ntohl (mp->tx_table_id),
822 mp->salt, &local_ip, &remote_ip, NULL);
823
824 if (rv)
825 goto done;
826
827 rv = ipsec_tun_protect_update_one (sw_if_index,
828 ipsec_tun_mk_output_sa_id
829 (sw_if_index),
830 ipsec_tun_mk_input_sa_id
831 (sw_if_index));
832 if (rv)
833 goto done;
834
835 /* the SAs are locked as a result of being used for proection,
836 * they cannot be removed from the API, since they cannot be refered
837 * to by the API. unlock them now, so that if the tunnel is rekeyed
838 * they-ll disapper
839 */
840 ipsec_sa_unlock_id (ipsec_tun_mk_input_sa_id (sw_if_index));
841 ipsec_sa_unlock_id (ipsec_tun_mk_output_sa_id (sw_if_index));
842 }
843 else
844 {
845
846 ipip_tunnel_key_t key = {
847 .transport = transport,
848 .fib_index = fib_index,
849 .src = local_ip,
850 .dst = remote_ip
851 };
852 ipip_tunnel_t *t = ipip_tunnel_db_find (&key);
853
854 rv = ipsec_tun_protect_del (t->sw_if_index);
855 ipip_del_tunnel (t->sw_if_index);
856 }
Matthew Smithb0972cb2017-05-02 16:20:41 -0500857
858#else
859 rv = VNET_API_ERROR_UNIMPLEMENTED;
860#endif
Neale Ranns12989b52019-09-26 16:20:19 +0000861done:
Neale Ranns8d7c5022019-02-06 01:41:05 -0800862 /* *INDENT-OFF* */
863 REPLY_MACRO2 (VL_API_IPSEC_TUNNEL_IF_ADD_DEL_REPLY,
864 ({
865 rmp->sw_if_index = htonl (sw_if_index);
866 }));
867 /* *INDENT-ON* */
Matthew Smithb0972cb2017-05-02 16:20:41 -0500868}
869
Neale Ranns12989b52019-09-26 16:20:19 +0000870typedef struct ipsec_sa_dump_match_ctx_t_
Matthew Smith28029532017-09-26 13:33:44 -0500871{
Neale Ranns12989b52019-09-26 16:20:19 +0000872 index_t sai;
873 u32 sw_if_index;
874} ipsec_sa_dump_match_ctx_t;
875
876static walk_rc_t
877ipsec_sa_dump_match_sa (index_t itpi, void *arg)
878{
879 ipsec_sa_dump_match_ctx_t *ctx = arg;
880 ipsec_tun_protect_t *itp;
881 index_t sai;
882
883 itp = ipsec_tun_protect_get (itpi);
884
885 if (itp->itp_out_sa == ctx->sai)
886 {
887 ctx->sw_if_index = itp->itp_sw_if_index;
888 return (WALK_STOP);
889 }
890 /* *INDENT-OFF* */
891 FOR_EACH_IPSEC_PROTECT_INPUT_SAI (itp, sai,
892 ({
893 if (sai == ctx->sai)
894 {
895 ctx->sw_if_index = itp->itp_sw_if_index;
896 return (WALK_STOP);
897 }
898 }));
899 /* *INDENT-OFF* */
900
901 return (WALK_CONTINUE);
902}
903
904static walk_rc_t
905send_ipsec_sa_details (ipsec_sa_t * sa, void *arg)
906{
907 ipsec_dump_walk_ctx_t *ctx = arg;
Matthew Smith28029532017-09-26 13:33:44 -0500908 vl_api_ipsec_sa_details_t *mp;
Neale Ranns12989b52019-09-26 16:20:19 +0000909 ipsec_main_t *im = &ipsec_main;
Matthew Smith28029532017-09-26 13:33:44 -0500910
911 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400912 clib_memset (mp, 0, sizeof (*mp));
Matthew Smith28029532017-09-26 13:33:44 -0500913 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_DETAILS);
Neale Ranns12989b52019-09-26 16:20:19 +0000914 mp->context = ctx->context;
Matthew Smith28029532017-09-26 13:33:44 -0500915
Neale Ranns8d7c5022019-02-06 01:41:05 -0800916 mp->entry.sad_id = htonl (sa->id);
917 mp->entry.spi = htonl (sa->spi);
918 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
919 mp->entry.tx_table_id =
920 htonl (fib_table_get_table_id (sa->tx_fib_index, FIB_PROTOCOL_IP4));
Matthew Smith28029532017-09-26 13:33:44 -0500921
Neale Ranns8d7c5022019-02-06 01:41:05 -0800922 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
923 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
Matthew Smith28029532017-09-26 13:33:44 -0500924
Neale Ranns8d7c5022019-02-06 01:41:05 -0800925 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
926 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
Matthew Smith28029532017-09-26 13:33:44 -0500927
Neale Ranns8d7c5022019-02-06 01:41:05 -0800928 mp->entry.flags = ipsec_sad_flags_encode (sa);
Neale Ranns12989b52019-09-26 16:20:19 +0000929 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 = {
934 .sai = sa - im->sad,
935 .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;
Matthew Smith28029532017-09-26 13:33:44 -0500943
Damjan Mariond709cbc2019-03-26 13:16:42 +0100944 if (ipsec_sa_is_set_IS_TUNNEL (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500945 {
Neale Ranns8d7c5022019-02-06 01:41:05 -0800946 ip_address_encode (&sa->tunnel_src_addr, IP46_TYPE_ANY,
947 &mp->entry.tunnel_src);
948 ip_address_encode (&sa->tunnel_dst_addr, IP46_TYPE_ANY,
949 &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -0500950 }
951
Matthew Smith28029532017-09-26 13:33:44 -0500952 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
953 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
Damjan Marion1e3aa5e2019-03-28 10:58:59 +0100954 if (ipsec_sa_is_set_USE_ESN (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500955 {
956 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
957 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
958 }
Damjan Mariond709cbc2019-03-26 13:16:42 +0100959 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
Matthew Smith28029532017-09-26 13:33:44 -0500960 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
Pierre Pfister4c422f92018-12-10 11:19:08 +0100961
Neale Ranns12989b52019-09-26 16:20:19 +0000962 vl_api_send_msg (ctx->reg, (u8 *) mp);
Matthew Smith28029532017-09-26 13:33:44 -0500963
Neale Ranns12989b52019-09-26 16:20:19 +0000964 return (WALK_CONTINUE);
965}
Matthew Smith28029532017-09-26 13:33:44 -0500966
967static void
968vl_api_ipsec_sa_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
969{
Florin Coras6c4dae22018-01-09 06:39:23 -0800970 vl_api_registration_t *reg;
Matthew Smith28029532017-09-26 13:33:44 -0500971
972#if WITH_LIBSSL > 0
Florin Coras6c4dae22018-01-09 06:39:23 -0800973 reg = vl_api_client_index_to_registration (mp->client_index);
Neale Ranns12989b52019-09-26 16:20:19 +0000974 if (!reg)
Matthew Smith28029532017-09-26 13:33:44 -0500975 return;
976
Neale Ranns12989b52019-09-26 16:20:19 +0000977 ipsec_dump_walk_ctx_t ctx = {
978 .reg = reg,
979 .context = mp->context,
980 };
Matthew Smith28029532017-09-26 13:33:44 -0500981
Neale Ranns12989b52019-09-26 16:20:19 +0000982 ipsec_sa_walk (send_ipsec_sa_details, &ctx);
Matthew Smith28029532017-09-26 13:33:44 -0500983
Matthew Smith28029532017-09-26 13:33:44 -0500984#else
985 clib_warning ("unimplemented");
986#endif
987}
988
Matthew Smith75d85602017-10-05 19:03:05 -0500989static void
Matthew Smithca514fd2017-10-12 12:06:59 -0500990vl_api_ipsec_tunnel_if_set_sa_t_handler (vl_api_ipsec_tunnel_if_set_sa_t * mp)
991{
992 vl_api_ipsec_tunnel_if_set_sa_reply_t *rmp;
Matthew Smithca514fd2017-10-12 12:06:59 -0500993 int rv;
994
995#if WITH_LIBSSL > 0
Neale Ranns12989b52019-09-26 16:20:19 +0000996 VALIDATE_SW_IF_INDEX(mp);
Matthew Smithca514fd2017-10-12 12:06:59 -0500997
Neale Ranns12989b52019-09-26 16:20:19 +0000998 if (mp->is_outbound)
999 rv = ipsec_tun_protect_update_out (ntohl (mp->sw_if_index),
1000 ntohl (mp->sa_id));
1001 else
1002 rv = ipsec_tun_protect_update_in (ntohl (mp->sw_if_index),
1003 ntohl (mp->sa_id));
1004
Matthew Smithca514fd2017-10-12 12:06:59 -05001005#else
1006 clib_warning ("unimplemented");
1007#endif
1008
Neale Ranns12989b52019-09-26 16:20:19 +00001009 BAD_SW_IF_INDEX_LABEL;
1010
Matthew Smithca514fd2017-10-12 12:06:59 -05001011 REPLY_MACRO (VL_API_IPSEC_TUNNEL_IF_SET_SA_REPLY);
1012}
1013
Klement Sekerab4d30532018-11-08 13:00:02 +01001014static void
1015vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp)
1016{
1017 vl_api_registration_t *rp;
1018 ipsec_main_t *im = &ipsec_main;
1019 u32 context = mp->context;
1020
1021 rp = vl_api_client_index_to_registration (mp->client_index);
1022
1023 if (rp == 0)
1024 {
1025 clib_warning ("Client %d AWOL", mp->client_index);
1026 return;
1027 }
1028
1029 ipsec_ah_backend_t *ab;
1030 ipsec_esp_backend_t *eb;
1031 /* *INDENT-OFF* */
1032 pool_foreach (ab, im->ah_backends, {
1033 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1034 clib_memset (mp, 0, sizeof (*mp));
1035 mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
1036 mp->context = context;
1037 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (ab->name),
1038 ab->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001039 mp->protocol = ntohl (IPSEC_API_PROTO_AH);
Klement Sekerab4d30532018-11-08 13:00:02 +01001040 mp->index = ab - im->ah_backends;
1041 mp->active = mp->index == im->ah_current_backend ? 1 : 0;
1042 vl_api_send_msg (rp, (u8 *)mp);
1043 });
1044 pool_foreach (eb, im->esp_backends, {
1045 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1046 clib_memset (mp, 0, sizeof (*mp));
1047 mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
1048 mp->context = context;
1049 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (eb->name),
1050 eb->name);
Neale Ranns17dcec02019-01-09 21:22:20 -08001051 mp->protocol = ntohl (IPSEC_API_PROTO_ESP);
Klement Sekerab4d30532018-11-08 13:00:02 +01001052 mp->index = eb - im->esp_backends;
1053 mp->active = mp->index == im->esp_current_backend ? 1 : 0;
1054 vl_api_send_msg (rp, (u8 *)mp);
1055 });
1056 /* *INDENT-ON* */
1057}
1058
1059static void
1060vl_api_ipsec_select_backend_t_handler (vl_api_ipsec_select_backend_t * mp)
1061{
1062 ipsec_main_t *im = &ipsec_main;
1063 vl_api_ipsec_select_backend_reply_t *rmp;
Neale Ranns17dcec02019-01-09 21:22:20 -08001064 ipsec_protocol_t protocol;
Klement Sekerab4d30532018-11-08 13:00:02 +01001065 int rv = 0;
1066 if (pool_elts (im->sad) > 0)
1067 {
1068 rv = VNET_API_ERROR_INSTANCE_IN_USE;
1069 goto done;
1070 }
Neale Ranns17dcec02019-01-09 21:22:20 -08001071
1072 rv = ipsec_proto_decode (mp->protocol, &protocol);
1073
1074 if (rv)
1075 goto done;
1076
Klement Sekerab4d30532018-11-08 13:00:02 +01001077#if WITH_LIBSSL > 0
Neale Ranns17dcec02019-01-09 21:22:20 -08001078 switch (protocol)
Klement Sekerab4d30532018-11-08 13:00:02 +01001079 {
1080 case IPSEC_PROTOCOL_ESP:
Neale Rannse8915fc2019-04-23 20:57:55 -04001081 rv = ipsec_select_esp_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001082 break;
1083 case IPSEC_PROTOCOL_AH:
Neale Rannse8915fc2019-04-23 20:57:55 -04001084 rv = ipsec_select_ah_backend (im, mp->index);
Klement Sekerab4d30532018-11-08 13:00:02 +01001085 break;
1086 default:
Neale Rannse8915fc2019-04-23 20:57:55 -04001087 rv = VNET_API_ERROR_INVALID_PROTOCOL;
Klement Sekerab4d30532018-11-08 13:00:02 +01001088 break;
1089 }
1090#else
1091 clib_warning ("unimplemented"); /* FIXME */
1092#endif
1093done:
1094 REPLY_MACRO (VL_API_IPSEC_SELECT_BACKEND_REPLY);
1095}
1096
Neale Ranns7c44d782019-02-25 10:28:29 +00001097/*
1098 * ipsec_api_hookup
1099 * Add vpe's API message handlers to the table.
1100 * vlib has already mapped shared memory and
1101 * added the client registration handlers.
1102 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
1103 */
1104#define vl_msg_name_crc_list
1105#include <vnet/vnet_all_api_h.h>
1106#undef vl_msg_name_crc_list
1107
1108static void
1109setup_message_id_table (api_main_t * am)
1110{
1111#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1112 foreach_vl_msg_name_crc_ipsec;
1113#undef _
1114}
1115
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001116static clib_error_t *
1117ipsec_api_hookup (vlib_main_t * vm)
1118{
1119 api_main_t *am = &api_main;
1120
1121#define _(N,n) \
1122 vl_msg_api_set_handlers(VL_API_##N, #n, \
1123 vl_api_##n##_t_handler, \
1124 vl_noop_handler, \
1125 vl_api_##n##_t_endian, \
1126 vl_api_##n##_t_print, \
1127 sizeof(vl_api_##n##_t), 1);
1128 foreach_vpe_api_msg;
1129#undef _
1130
1131 /*
Neale Rannsc87b66c2019-02-07 07:26:12 -08001132 * Adding and deleting SAs is MP safe since when they are added/delete
1133 * no traffic is using them
1134 */
1135 am->is_mp_safe[VL_API_IPSEC_SAD_ENTRY_ADD_DEL] = 1;
1136 am->is_mp_safe[VL_API_IPSEC_SAD_ENTRY_ADD_DEL_REPLY] = 1;
1137
1138 /*
Pavel Kotucek9c7ef032016-12-21 07:46:45 +01001139 * Set up the (msg_name, crc, message-id) table
1140 */
1141 setup_message_id_table (am);
1142
1143 return 0;
1144}
1145
1146VLIB_API_INIT_FUNCTION (ipsec_api_hookup);
1147
1148/*
1149 * fd.io coding-style-patch-verification: ON
1150 *
1151 * Local Variables:
1152 * eval: (c-set-style "gnu")
1153 * End:
1154 */