blob: ced2c9ce6cd6c0625c1de159fb6af5d9730a21b4 [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>
26
27#include <vnet/vnet_msg_enum.h>
28
Damjan Mariona9a951f2017-01-16 22:06:10 +010029#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010030#include <vnet/ipsec/ipsec.h>
31#include <vnet/ipsec/ikev2.h>
32#endif /* IPSEC */
33
34#define vl_typedefs /* define message structures */
35#include <vnet/vnet_all_api_h.h>
36#undef vl_typedefs
37
38#define vl_endianfun /* define message structures */
39#include <vnet/vnet_all_api_h.h>
40#undef vl_endianfun
41
42/* instantiate all the print functions we know about */
43#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
44#define vl_printfun
45#include <vnet/vnet_all_api_h.h>
46#undef vl_printfun
47
48#include <vlibapi/api_helper_macros.h>
49
50#define foreach_vpe_api_msg \
51_(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \
52_(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \
53_(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry) \
54_(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry) \
55_(IPSEC_SA_SET_KEY, ipsec_sa_set_key) \
Matthew Smith28029532017-09-26 13:33:44 -050056_(IPSEC_SA_DUMP, ipsec_sa_dump) \
Matus Fabiana9a0b2c2018-10-02 01:13:25 -070057_(IPSEC_SPDS_DUMP, ipsec_spds_dump) \
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010058_(IPSEC_SPD_DUMP, ipsec_spd_dump) \
Filip Varga871bca92018-11-02 13:51:44 +010059_(IPSEC_SPD_INTERFACE_DUMP, ipsec_spd_interface_dump) \
Matthew Smithb0972cb2017-05-02 16:20:41 -050060_(IPSEC_TUNNEL_IF_ADD_DEL, ipsec_tunnel_if_add_del) \
Matthew Smith75d85602017-10-05 19:03:05 -050061_(IPSEC_TUNNEL_IF_SET_KEY, ipsec_tunnel_if_set_key) \
Matthew Smithca514fd2017-10-12 12:06:59 -050062_(IPSEC_TUNNEL_IF_SET_SA, ipsec_tunnel_if_set_sa) \
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010063_(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del) \
64_(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth) \
65_(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id) \
66_(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts) \
Radu Nicolaucb33dc22017-02-16 16:49:46 +000067_(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key) \
68_(IKEV2_SET_RESPONDER, ikev2_set_responder) \
69_(IKEV2_SET_IKE_TRANSFORMS, ikev2_set_ike_transforms) \
70_(IKEV2_SET_ESP_TRANSFORMS, ikev2_set_esp_transforms) \
71_(IKEV2_SET_SA_LIFETIME, ikev2_set_sa_lifetime) \
72_(IKEV2_INITIATE_SA_INIT, ikev2_initiate_sa_init) \
73_(IKEV2_INITIATE_DEL_IKE_SA, ikev2_initiate_del_ike_sa) \
74_(IKEV2_INITIATE_DEL_CHILD_SA, ikev2_initiate_del_child_sa) \
75_(IKEV2_INITIATE_REKEY_CHILD_SA, ikev2_initiate_rekey_child_sa)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010076
77static void vl_api_ipsec_spd_add_del_t_handler
78 (vl_api_ipsec_spd_add_del_t * mp)
79{
Damjan Mariona9a951f2017-01-16 22:06:10 +010080#if WITH_LIBSSL == 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010081 clib_warning ("unimplemented");
82#else
83
84 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
85 vl_api_ipsec_spd_add_del_reply_t *rmp;
86 int rv;
87
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010088 rv = ipsec_add_del_spd (vm, ntohl (mp->spd_id), mp->is_add);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +010089
90 REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_REPLY);
91#endif
92}
93
94static void vl_api_ipsec_interface_add_del_spd_t_handler
95 (vl_api_ipsec_interface_add_del_spd_t * mp)
96{
97 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
98 vl_api_ipsec_interface_add_del_spd_reply_t *rmp;
99 int rv;
100 u32 sw_if_index __attribute__ ((unused));
101 u32 spd_id __attribute__ ((unused));
102
103 sw_if_index = ntohl (mp->sw_if_index);
104 spd_id = ntohl (mp->spd_id);
105
106 VALIDATE_SW_IF_INDEX (mp);
107
Damjan Mariona9a951f2017-01-16 22:06:10 +0100108#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100109 rv = ipsec_set_interface_spd (vm, sw_if_index, spd_id, mp->is_add);
110#else
111 rv = VNET_API_ERROR_UNIMPLEMENTED;
112#endif
113
114 BAD_SW_IF_INDEX_LABEL;
115
116 REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY);
117}
118
119static void vl_api_ipsec_spd_add_del_entry_t_handler
120 (vl_api_ipsec_spd_add_del_entry_t * mp)
121{
122 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
123 vl_api_ipsec_spd_add_del_entry_reply_t *rmp;
124 int rv;
125
Damjan Mariona9a951f2017-01-16 22:06:10 +0100126#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100127 ipsec_policy_t p;
128
Dave Barachb7b92992018-10-17 10:38:51 -0400129 clib_memset (&p, 0, sizeof (p));
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100130
131 p.id = ntohl (mp->spd_id);
132 p.priority = ntohl (mp->priority);
133 p.is_outbound = mp->is_outbound;
134 p.is_ipv6 = mp->is_ipv6;
135
136 if (mp->is_ipv6 || mp->is_ip_any)
137 {
138 clib_memcpy (&p.raddr.start, mp->remote_address_start, 16);
139 clib_memcpy (&p.raddr.stop, mp->remote_address_stop, 16);
140 clib_memcpy (&p.laddr.start, mp->local_address_start, 16);
141 clib_memcpy (&p.laddr.stop, mp->local_address_stop, 16);
142 }
143 else
144 {
145 clib_memcpy (&p.raddr.start.ip4.data, mp->remote_address_start, 4);
146 clib_memcpy (&p.raddr.stop.ip4.data, mp->remote_address_stop, 4);
147 clib_memcpy (&p.laddr.start.ip4.data, mp->local_address_start, 4);
148 clib_memcpy (&p.laddr.stop.ip4.data, mp->local_address_stop, 4);
149 }
150 p.protocol = mp->protocol;
151 p.rport.start = ntohs (mp->remote_port_start);
152 p.rport.stop = ntohs (mp->remote_port_stop);
153 p.lport.start = ntohs (mp->local_port_start);
154 p.lport.stop = ntohs (mp->local_port_stop);
155 /* policy action resolve unsupported */
156 if (mp->policy == IPSEC_POLICY_ACTION_RESOLVE)
157 {
158 clib_warning ("unsupported action: 'resolve'");
159 rv = VNET_API_ERROR_UNIMPLEMENTED;
160 goto out;
161 }
162 p.policy = mp->policy;
163 p.sa_id = ntohl (mp->sa_id);
164
165 rv = ipsec_add_del_policy (vm, &p, mp->is_add);
166 if (rv)
167 goto out;
168
169 if (mp->is_ip_any)
170 {
171 p.is_ipv6 = 1;
172 rv = ipsec_add_del_policy (vm, &p, mp->is_add);
173 }
174#else
175 rv = VNET_API_ERROR_UNIMPLEMENTED;
176 goto out;
177#endif
178
179out:
180 REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_ENTRY_REPLY);
181}
182
183static void vl_api_ipsec_sad_add_del_entry_t_handler
184 (vl_api_ipsec_sad_add_del_entry_t * mp)
185{
186 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
187 vl_api_ipsec_sad_add_del_entry_reply_t *rmp;
188 int rv;
Damjan Mariona9a951f2017-01-16 22:06:10 +0100189#if WITH_LIBSSL > 0
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +0000190 ipsec_main_t *im = &ipsec_main;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100191 ipsec_sa_t sa;
192
Dave Barachb7b92992018-10-17 10:38:51 -0400193 clib_memset (&sa, 0, sizeof (sa));
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100194
195 sa.id = ntohl (mp->sad_id);
196 sa.spi = ntohl (mp->spi);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100197 sa.protocol = mp->protocol;
198 /* check for unsupported crypto-alg */
Dave Baracha8d47642018-07-13 11:22:23 -0400199 if (mp->crypto_algorithm >= IPSEC_CRYPTO_N_ALG)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100200 {
201 clib_warning ("unsupported crypto-alg: '%U'", format_ipsec_crypto_alg,
202 mp->crypto_algorithm);
203 rv = VNET_API_ERROR_UNIMPLEMENTED;
204 goto out;
205 }
206 sa.crypto_alg = mp->crypto_algorithm;
207 sa.crypto_key_len = mp->crypto_key_length;
208 clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key));
209 /* check for unsupported integ-alg */
Pavel Kotucek78053e12017-03-10 10:03:59 +0100210 if (mp->integrity_algorithm >= IPSEC_INTEG_N_ALG)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100211 {
212 clib_warning ("unsupported integ-alg: '%U'", format_ipsec_integ_alg,
213 mp->integrity_algorithm);
214 rv = VNET_API_ERROR_UNIMPLEMENTED;
215 goto out;
216 }
217
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100218 sa.integ_alg = mp->integrity_algorithm;
219 sa.integ_key_len = mp->integrity_key_length;
220 clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key));
221 sa.use_esn = mp->use_extended_sequence_number;
222 sa.is_tunnel = mp->is_tunnel;
223 sa.is_tunnel_ip6 = mp->is_tunnel_ipv6;
Radu Nicolau717de092018-08-03 10:37:24 +0100224 sa.udp_encap = mp->udp_encap;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100225 if (sa.is_tunnel_ip6)
226 {
227 clib_memcpy (&sa.tunnel_src_addr, mp->tunnel_src_address, 16);
228 clib_memcpy (&sa.tunnel_dst_addr, mp->tunnel_dst_address, 16);
229 }
230 else
231 {
232 clib_memcpy (&sa.tunnel_src_addr.ip4.data, mp->tunnel_src_address, 4);
233 clib_memcpy (&sa.tunnel_dst_addr.ip4.data, mp->tunnel_dst_address, 4);
234 }
Matthew Smithca514fd2017-10-12 12:06:59 -0500235 sa.use_anti_replay = mp->use_anti_replay;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100236
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +0000237 ASSERT (im->cb.check_support_cb);
238 clib_error_t *err = im->cb.check_support_cb (&sa);
239 if (err)
240 {
241 clib_warning ("%s", err->what);
242 rv = VNET_API_ERROR_UNIMPLEMENTED;
243 goto out;
244 }
245
Radu Nicolau717de092018-08-03 10:37:24 +0100246 rv = ipsec_add_del_sa (vm, &sa, mp->is_add);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100247#else
248 rv = VNET_API_ERROR_UNIMPLEMENTED;
249 goto out;
250#endif
251
252out:
253 REPLY_MACRO (VL_API_IPSEC_SAD_ADD_DEL_ENTRY_REPLY);
254}
255
256static void
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700257send_ipsec_spds_details (ipsec_spd_t * spd, vl_api_registration_t * reg,
258 u32 context)
259{
260 vl_api_ipsec_spds_details_t *mp;
261
262 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400263 clib_memset (mp, 0, sizeof (*mp));
Matus Fabiana9a0b2c2018-10-02 01:13:25 -0700264 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPDS_DETAILS);
265 mp->context = context;
266
267 mp->spd_id = htonl (spd->id);
268 mp->npolicies = htonl (pool_len (spd->policies));
269
270 vl_api_send_msg (reg, (u8 *) mp);
271}
272
273static void
274vl_api_ipsec_spds_dump_t_handler (vl_api_ipsec_spds_dump_t * mp)
275{
276 vl_api_registration_t *reg;
277 ipsec_main_t *im = &ipsec_main;
278 ipsec_spd_t *spd;
279#if WITH_LIBSSL > 0
280 reg = vl_api_client_index_to_registration (mp->client_index);
281 if (!reg)
282 return;
283
284 /* *INDENT-OFF* */
285 pool_foreach (spd, im->spds, ({
286 send_ipsec_spds_details (spd, reg, mp->context);
287 }));
288 /* *INDENT-ON* */
289#else
290 clib_warning ("unimplemented");
291#endif
292}
293
294static void
Florin Coras6c4dae22018-01-09 06:39:23 -0800295send_ipsec_spd_details (ipsec_policy_t * p, vl_api_registration_t * reg,
296 u32 context)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100297{
298 vl_api_ipsec_spd_details_t *mp;
299
300 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400301 clib_memset (mp, 0, sizeof (*mp));
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100302 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_DETAILS);
303 mp->context = context;
304
305 mp->spd_id = htonl (p->id);
306 mp->priority = htonl (p->priority);
307 mp->is_outbound = p->is_outbound;
308 mp->is_ipv6 = p->is_ipv6;
309 if (p->is_ipv6)
310 {
311 memcpy (mp->local_start_addr, &p->laddr.start.ip6, 16);
312 memcpy (mp->local_stop_addr, &p->laddr.stop.ip6, 16);
313 memcpy (mp->remote_start_addr, &p->raddr.start.ip6, 16);
314 memcpy (mp->remote_stop_addr, &p->raddr.stop.ip6, 16);
315 }
316 else
317 {
318 memcpy (mp->local_start_addr, &p->laddr.start.ip4, 4);
319 memcpy (mp->local_stop_addr, &p->laddr.stop.ip4, 4);
320 memcpy (mp->remote_start_addr, &p->raddr.start.ip4, 4);
321 memcpy (mp->remote_stop_addr, &p->raddr.stop.ip4, 4);
322 }
323 mp->local_start_port = htons (p->lport.start);
324 mp->local_stop_port = htons (p->lport.stop);
325 mp->remote_start_port = htons (p->rport.start);
326 mp->remote_stop_port = htons (p->rport.stop);
327 mp->protocol = p->protocol;
328 mp->policy = p->policy;
329 mp->sa_id = htonl (p->sa_id);
330 mp->bytes = clib_host_to_net_u64 (p->counter.bytes);
331 mp->packets = clib_host_to_net_u64 (p->counter.packets);
332
Florin Coras6c4dae22018-01-09 06:39:23 -0800333 vl_api_send_msg (reg, (u8 *) mp);
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100334}
335
336static void
337vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp)
338{
Florin Coras6c4dae22018-01-09 06:39:23 -0800339 vl_api_registration_t *reg;
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100340 ipsec_main_t *im = &ipsec_main;
341 ipsec_policy_t *policy;
342 ipsec_spd_t *spd;
343 uword *p;
344 u32 spd_index;
Damjan Mariona9a951f2017-01-16 22:06:10 +0100345#if WITH_LIBSSL > 0
Florin Coras6c4dae22018-01-09 06:39:23 -0800346 reg = vl_api_client_index_to_registration (mp->client_index);
347 if (!reg)
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100348 return;
349
350 p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id));
351 if (!p)
352 return;
353
354 spd_index = p[0];
355 spd = pool_elt_at_index (im->spds, spd_index);
356
357 /* *INDENT-OFF* */
358 pool_foreach (policy, spd->policies,
359 ({
360 if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id)
Florin Coras6c4dae22018-01-09 06:39:23 -0800361 send_ipsec_spd_details (policy, reg,
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100362 mp->context);}
363 ));
364 /* *INDENT-ON* */
365#else
366 clib_warning ("unimplemented");
367#endif
368}
369
370static void
Filip Varga871bca92018-11-02 13:51:44 +0100371send_ipsec_spd_interface_details (vl_api_registration_t * reg, u32 spd_index,
372 u32 sw_if_index, u32 context)
373{
374 vl_api_ipsec_spd_interface_details_t *mp;
375
376 mp = vl_msg_api_alloc (sizeof (*mp));
377 clib_memset (mp, 0, sizeof (*mp));
378 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_INTERFACE_DETAILS);
379 mp->context = context;
380
381 mp->spd_index = htonl (spd_index);
382 mp->sw_if_index = htonl (sw_if_index);
383
384 vl_api_send_msg (reg, (u8 *) mp);
385}
386
387static void
388vl_api_ipsec_spd_interface_dump_t_handler (vl_api_ipsec_spd_interface_dump_t *
389 mp)
390{
391 ipsec_main_t *im = &ipsec_main;
392 vl_api_registration_t *reg;
393 u32 k, v, spd_index;
394
395#if WITH_LIBSSL > 0
396 reg = vl_api_client_index_to_registration (mp->client_index);
397 if (!reg)
398 return;
399
400 if (mp->spd_index_valid)
401 {
402 spd_index = ntohl (mp->spd_index);
403 /* *INDENT-OFF* */
404 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
405 if (v == spd_index)
406 send_ipsec_spd_interface_details(reg, v, k, mp->context);
407 }));
408 /* *INDENT-ON* */
409 }
410 else
411 {
412 /* *INDENT-OFF* */
413 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
414 send_ipsec_spd_interface_details(reg, v, k, mp->context);
415 }));
416 /* *INDENT-ON* */
417 }
418
419#else
420 clib_warning ("unimplemented");
421#endif
422}
423
424static void
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100425vl_api_ipsec_sa_set_key_t_handler (vl_api_ipsec_sa_set_key_t * mp)
426{
427 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
428 vl_api_ipsec_sa_set_key_reply_t *rmp;
429 int rv;
Damjan Mariona9a951f2017-01-16 22:06:10 +0100430#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100431 ipsec_sa_t sa;
432 sa.id = ntohl (mp->sa_id);
433 sa.crypto_key_len = mp->crypto_key_length;
434 clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key));
435 sa.integ_key_len = mp->integrity_key_length;
436 clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key));
437
438 rv = ipsec_set_sa_key (vm, &sa);
439#else
440 rv = VNET_API_ERROR_UNIMPLEMENTED;
441#endif
442
443 REPLY_MACRO (VL_API_IPSEC_SA_SET_KEY_REPLY);
444}
445
446static void
Matthew Smithb0972cb2017-05-02 16:20:41 -0500447vl_api_ipsec_tunnel_if_add_del_t_handler (vl_api_ipsec_tunnel_if_add_del_t *
448 mp)
449{
450 vl_api_ipsec_tunnel_if_add_del_reply_t *rmp;
Matthew Smithe04d09d2017-05-14 21:47:18 -0500451 ipsec_main_t *im = &ipsec_main;
452 vnet_main_t *vnm = im->vnet_main;
453 u32 sw_if_index = ~0;
Matthew Smithb0972cb2017-05-02 16:20:41 -0500454 int rv;
455
456#if WITH_LIBSSL > 0
457 ipsec_add_del_tunnel_args_t tun;
458
Dave Barachb7b92992018-10-17 10:38:51 -0400459 clib_memset (&tun, 0, sizeof (ipsec_add_del_tunnel_args_t));
Matthew Smithb0972cb2017-05-02 16:20:41 -0500460
461 tun.is_add = mp->is_add;
462 tun.esn = mp->esn;
463 tun.anti_replay = mp->anti_replay;
464 tun.local_spi = ntohl (mp->local_spi);
465 tun.remote_spi = ntohl (mp->remote_spi);
466 tun.crypto_alg = mp->crypto_alg;
467 tun.local_crypto_key_len = mp->local_crypto_key_len;
468 tun.remote_crypto_key_len = mp->remote_crypto_key_len;
469 tun.integ_alg = mp->integ_alg;
470 tun.local_integ_key_len = mp->local_integ_key_len;
471 tun.remote_integ_key_len = mp->remote_integ_key_len;
472 memcpy (&tun.local_ip, mp->local_ip, 4);
473 memcpy (&tun.remote_ip, mp->remote_ip, 4);
474 memcpy (&tun.local_crypto_key, &mp->local_crypto_key,
475 mp->local_crypto_key_len);
476 memcpy (&tun.remote_crypto_key, &mp->remote_crypto_key,
477 mp->remote_crypto_key_len);
478 memcpy (&tun.local_integ_key, &mp->local_integ_key,
479 mp->local_integ_key_len);
480 memcpy (&tun.remote_integ_key, &mp->remote_integ_key,
481 mp->remote_integ_key_len);
Matthew Smith8e1039a2018-04-12 07:32:56 -0500482 tun.renumber = mp->renumber;
483 tun.show_instance = ntohl (mp->show_instance);
Matthew Smithb0972cb2017-05-02 16:20:41 -0500484
Matthew Smithe04d09d2017-05-14 21:47:18 -0500485 rv = ipsec_add_del_tunnel_if_internal (vnm, &tun, &sw_if_index);
Matthew Smithb0972cb2017-05-02 16:20:41 -0500486
487#else
488 rv = VNET_API_ERROR_UNIMPLEMENTED;
489#endif
490
Matthew Smithe04d09d2017-05-14 21:47:18 -0500491 REPLY_MACRO2 (VL_API_IPSEC_TUNNEL_IF_ADD_DEL_REPLY, (
492 {
493 rmp->sw_if_index =
494 htonl (sw_if_index);
495 }));
Matthew Smithb0972cb2017-05-02 16:20:41 -0500496}
497
Matthew Smith28029532017-09-26 13:33:44 -0500498static void
Florin Coras6c4dae22018-01-09 06:39:23 -0800499send_ipsec_sa_details (ipsec_sa_t * sa, vl_api_registration_t * reg,
Matthew Smith28029532017-09-26 13:33:44 -0500500 u32 context, u32 sw_if_index)
501{
502 vl_api_ipsec_sa_details_t *mp;
503
504 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400505 clib_memset (mp, 0, sizeof (*mp));
Matthew Smith28029532017-09-26 13:33:44 -0500506 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_DETAILS);
507 mp->context = context;
508
509 mp->sa_id = htonl (sa->id);
510 mp->sw_if_index = htonl (sw_if_index);
511
512 mp->spi = htonl (sa->spi);
513 mp->protocol = sa->protocol;
514
515 mp->crypto_alg = sa->crypto_alg;
516 mp->crypto_key_len = sa->crypto_key_len;
517 memcpy (mp->crypto_key, sa->crypto_key, sa->crypto_key_len);
518
519 mp->integ_alg = sa->integ_alg;
520 mp->integ_key_len = sa->integ_key_len;
521 memcpy (mp->integ_key, sa->integ_key, sa->integ_key_len);
522
523 mp->use_esn = sa->use_esn;
524 mp->use_anti_replay = sa->use_anti_replay;
525
526 mp->is_tunnel = sa->is_tunnel;
527 mp->is_tunnel_ip6 = sa->is_tunnel_ip6;
528
529 if (sa->is_tunnel)
530 {
531 if (sa->is_tunnel_ip6)
532 {
533 memcpy (mp->tunnel_src_addr, &sa->tunnel_src_addr.ip6, 16);
534 memcpy (mp->tunnel_dst_addr, &sa->tunnel_dst_addr.ip6, 16);
535 }
536 else
537 {
538 memcpy (mp->tunnel_src_addr, &sa->tunnel_src_addr.ip4, 4);
539 memcpy (mp->tunnel_dst_addr, &sa->tunnel_dst_addr.ip4, 4);
540 }
541 }
542
543 mp->salt = clib_host_to_net_u32 (sa->salt);
544 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
545 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
546 if (sa->use_esn)
547 {
548 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
549 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
550 }
551 if (sa->use_anti_replay)
552 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
553 mp->total_data_size = clib_host_to_net_u64 (sa->total_data_size);
Klement Sekera4b089f22018-04-17 18:04:57 +0200554 mp->udp_encap = sa->udp_encap;
Matthew Smith28029532017-09-26 13:33:44 -0500555
Florin Coras6c4dae22018-01-09 06:39:23 -0800556 vl_api_send_msg (reg, (u8 *) mp);
Matthew Smith28029532017-09-26 13:33:44 -0500557}
558
559
560static void
561vl_api_ipsec_sa_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
562{
Florin Coras6c4dae22018-01-09 06:39:23 -0800563 vl_api_registration_t *reg;
Matthew Smith28029532017-09-26 13:33:44 -0500564 ipsec_main_t *im = &ipsec_main;
565 vnet_main_t *vnm = im->vnet_main;
566 ipsec_sa_t *sa;
567 ipsec_tunnel_if_t *t;
568 u32 *sa_index_to_tun_if_index = 0;
569
570#if WITH_LIBSSL > 0
Florin Coras6c4dae22018-01-09 06:39:23 -0800571 reg = vl_api_client_index_to_registration (mp->client_index);
572 if (!reg || pool_elts (im->sad) == 0)
Matthew Smith28029532017-09-26 13:33:44 -0500573 return;
574
575 vec_validate_init_empty (sa_index_to_tun_if_index, vec_len (im->sad) - 1,
576 ~0);
577
578 /* *INDENT-OFF* */
579 pool_foreach (t, im->tunnel_interfaces,
580 ({
581 vnet_hw_interface_t *hi;
582 u32 sw_if_index = ~0;
583
584 hi = vnet_get_hw_interface (vnm, t->hw_if_index);
585 sw_if_index = hi->sw_if_index;
586 sa_index_to_tun_if_index[t->input_sa_index] = sw_if_index;
587 sa_index_to_tun_if_index[t->output_sa_index] = sw_if_index;
588 }));
589
590 pool_foreach (sa, im->sad,
591 ({
592 if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == sa->id)
Florin Coras6c4dae22018-01-09 06:39:23 -0800593 send_ipsec_sa_details (sa, reg, mp->context,
Matthew Smith28029532017-09-26 13:33:44 -0500594 sa_index_to_tun_if_index[sa - im->sad]);
595 }));
596 /* *INDENT-ON* */
597
598 vec_free (sa_index_to_tun_if_index);
599#else
600 clib_warning ("unimplemented");
601#endif
602}
603
Matthew Smithe04d09d2017-05-14 21:47:18 -0500604
Matthew Smithb0972cb2017-05-02 16:20:41 -0500605static void
Matthew Smith75d85602017-10-05 19:03:05 -0500606vl_api_ipsec_tunnel_if_set_key_t_handler (vl_api_ipsec_tunnel_if_set_key_t *
607 mp)
608{
609 vl_api_ipsec_tunnel_if_set_key_reply_t *rmp;
610 ipsec_main_t *im = &ipsec_main;
611 vnet_main_t *vnm = im->vnet_main;
612 vnet_sw_interface_t *sw;
613 u8 *key = 0;
614 int rv;
615
616#if WITH_LIBSSL > 0
617 sw = vnet_get_sw_interface (vnm, ntohl (mp->sw_if_index));
618
619 switch (mp->key_type)
620 {
621 case IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO:
622 case IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO:
623 if (mp->alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
Dave Baracha8d47642018-07-13 11:22:23 -0400624 mp->alg >= IPSEC_CRYPTO_N_ALG)
Matthew Smith75d85602017-10-05 19:03:05 -0500625 {
626 rv = VNET_API_ERROR_UNIMPLEMENTED;
627 goto out;
628 }
629 break;
630 case IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG:
631 case IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG:
Dave Baracha8d47642018-07-13 11:22:23 -0400632 if (mp->alg >= IPSEC_INTEG_N_ALG)
Matthew Smith75d85602017-10-05 19:03:05 -0500633 {
634 rv = VNET_API_ERROR_UNIMPLEMENTED;
635 goto out;
636 }
637 break;
638 case IPSEC_IF_SET_KEY_TYPE_NONE:
639 default:
640 rv = VNET_API_ERROR_UNIMPLEMENTED;
641 goto out;
642 break;
643 }
644
645 key = vec_new (u8, mp->key_len);
646 clib_memcpy (key, mp->key, mp->key_len);
647
648 rv = ipsec_set_interface_key (vnm, sw->hw_if_index, mp->key_type, mp->alg,
649 key);
650 vec_free (key);
651#else
652 clib_warning ("unimplemented");
653#endif
654
655out:
656 REPLY_MACRO (VL_API_IPSEC_TUNNEL_IF_SET_KEY_REPLY);
657}
658
659
660static void
Matthew Smithca514fd2017-10-12 12:06:59 -0500661vl_api_ipsec_tunnel_if_set_sa_t_handler (vl_api_ipsec_tunnel_if_set_sa_t * mp)
662{
663 vl_api_ipsec_tunnel_if_set_sa_reply_t *rmp;
664 ipsec_main_t *im = &ipsec_main;
665 vnet_main_t *vnm = im->vnet_main;
666 vnet_sw_interface_t *sw;
667 int rv;
668
669#if WITH_LIBSSL > 0
670 sw = vnet_get_sw_interface (vnm, ntohl (mp->sw_if_index));
671
672 rv = ipsec_set_interface_sa (vnm, sw->hw_if_index, ntohl (mp->sa_id),
673 mp->is_outbound);
674#else
675 clib_warning ("unimplemented");
676#endif
677
678 REPLY_MACRO (VL_API_IPSEC_TUNNEL_IF_SET_SA_REPLY);
679}
680
681
682static void
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100683vl_api_ikev2_profile_add_del_t_handler (vl_api_ikev2_profile_add_del_t * mp)
684{
685 vl_api_ikev2_profile_add_del_reply_t *rmp;
686 int rv = 0;
687
Damjan Mariona9a951f2017-01-16 22:06:10 +0100688#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100689 vlib_main_t *vm = vlib_get_main ();
690 clib_error_t *error;
691 u8 *tmp = format (0, "%s", mp->name);
692 error = ikev2_add_del_profile (vm, tmp, mp->is_add);
693 vec_free (tmp);
694 if (error)
695 rv = VNET_API_ERROR_UNSPECIFIED;
696#else
697 rv = VNET_API_ERROR_UNIMPLEMENTED;
698#endif
699
700 REPLY_MACRO (VL_API_IKEV2_PROFILE_ADD_DEL_REPLY);
701}
702
703static void
704 vl_api_ikev2_profile_set_auth_t_handler
705 (vl_api_ikev2_profile_set_auth_t * mp)
706{
707 vl_api_ikev2_profile_set_auth_reply_t *rmp;
708 int rv = 0;
709
Damjan Mariona9a951f2017-01-16 22:06:10 +0100710#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100711 vlib_main_t *vm = vlib_get_main ();
712 clib_error_t *error;
713 u8 *tmp = format (0, "%s", mp->name);
714 u8 *data = vec_new (u8, mp->data_len);
715 clib_memcpy (data, mp->data, mp->data_len);
716 error = ikev2_set_profile_auth (vm, tmp, mp->auth_method, data, mp->is_hex);
717 vec_free (tmp);
718 vec_free (data);
719 if (error)
720 rv = VNET_API_ERROR_UNSPECIFIED;
721#else
722 rv = VNET_API_ERROR_UNIMPLEMENTED;
723#endif
724
725 REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_AUTH_REPLY);
726}
727
728static void
729vl_api_ikev2_profile_set_id_t_handler (vl_api_ikev2_profile_set_id_t * mp)
730{
731 vl_api_ikev2_profile_add_del_reply_t *rmp;
732 int rv = 0;
733
Damjan Mariona9a951f2017-01-16 22:06:10 +0100734#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100735 vlib_main_t *vm = vlib_get_main ();
736 clib_error_t *error;
737 u8 *tmp = format (0, "%s", mp->name);
738 u8 *data = vec_new (u8, mp->data_len);
739 clib_memcpy (data, mp->data, mp->data_len);
740 error = ikev2_set_profile_id (vm, tmp, mp->id_type, data, mp->is_local);
741 vec_free (tmp);
742 vec_free (data);
743 if (error)
744 rv = VNET_API_ERROR_UNSPECIFIED;
745#else
746 rv = VNET_API_ERROR_UNIMPLEMENTED;
747#endif
748
749 REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_ID_REPLY);
750}
751
752static void
753vl_api_ikev2_profile_set_ts_t_handler (vl_api_ikev2_profile_set_ts_t * mp)
754{
755 vl_api_ikev2_profile_set_ts_reply_t *rmp;
756 int rv = 0;
757
Damjan Mariona9a951f2017-01-16 22:06:10 +0100758#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100759 vlib_main_t *vm = vlib_get_main ();
760 clib_error_t *error;
761 u8 *tmp = format (0, "%s", mp->name);
762 error = ikev2_set_profile_ts (vm, tmp, mp->proto, mp->start_port,
763 mp->end_port, (ip4_address_t) mp->start_addr,
764 (ip4_address_t) mp->end_addr, mp->is_local);
765 vec_free (tmp);
766 if (error)
767 rv = VNET_API_ERROR_UNSPECIFIED;
768#else
769 rv = VNET_API_ERROR_UNIMPLEMENTED;
770#endif
771
772 REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_TS_REPLY);
773}
774
775static void
776vl_api_ikev2_set_local_key_t_handler (vl_api_ikev2_set_local_key_t * mp)
777{
778 vl_api_ikev2_profile_set_ts_reply_t *rmp;
779 int rv = 0;
780
Damjan Mariona9a951f2017-01-16 22:06:10 +0100781#if WITH_LIBSSL > 0
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100782 vlib_main_t *vm = vlib_get_main ();
783 clib_error_t *error;
784
785 error = ikev2_set_local_key (vm, mp->key_file);
786 if (error)
787 rv = VNET_API_ERROR_UNSPECIFIED;
788#else
789 rv = VNET_API_ERROR_UNIMPLEMENTED;
790#endif
791
792 REPLY_MACRO (VL_API_IKEV2_SET_LOCAL_KEY_REPLY);
793}
794
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000795static void
796vl_api_ikev2_set_responder_t_handler (vl_api_ikev2_set_responder_t * mp)
797{
798 vl_api_ikev2_set_responder_reply_t *rmp;
799 int rv = 0;
800
801#if WITH_LIBSSL > 0
802 vlib_main_t *vm = vlib_get_main ();
803 clib_error_t *error;
804
805 u8 *tmp = format (0, "%s", mp->name);
806 ip4_address_t ip4;
807 clib_memcpy (&ip4, mp->address, sizeof (ip4));
808
809 error = ikev2_set_profile_responder (vm, tmp, mp->sw_if_index, ip4);
810 vec_free (tmp);
811 if (error)
812 rv = VNET_API_ERROR_UNSPECIFIED;
813#else
814 rv = VNET_API_ERROR_UNIMPLEMENTED;
815#endif
816
817 REPLY_MACRO (VL_API_IKEV2_SET_RESPONDER_REPLY);
818}
819
820static void
821vl_api_ikev2_set_ike_transforms_t_handler (vl_api_ikev2_set_ike_transforms_t *
822 mp)
823{
824 vl_api_ikev2_set_ike_transforms_reply_t *rmp;
825 int rv = 0;
826
827#if WITH_LIBSSL > 0
828 vlib_main_t *vm = vlib_get_main ();
829 clib_error_t *error;
830
831 u8 *tmp = format (0, "%s", mp->name);
832
833 error =
834 ikev2_set_profile_ike_transforms (vm, tmp, mp->crypto_alg, mp->integ_alg,
835 mp->dh_group, mp->crypto_key_size);
836 vec_free (tmp);
837 if (error)
838 rv = VNET_API_ERROR_UNSPECIFIED;
839#else
840 rv = VNET_API_ERROR_UNIMPLEMENTED;
841#endif
842
843 REPLY_MACRO (VL_API_IKEV2_SET_IKE_TRANSFORMS_REPLY);
844}
845
846static void
847vl_api_ikev2_set_esp_transforms_t_handler (vl_api_ikev2_set_esp_transforms_t *
848 mp)
849{
850 vl_api_ikev2_set_esp_transforms_reply_t *rmp;
851 int rv = 0;
852
853#if WITH_LIBSSL > 0
854 vlib_main_t *vm = vlib_get_main ();
855 clib_error_t *error;
856
857 u8 *tmp = format (0, "%s", mp->name);
858
859 error =
860 ikev2_set_profile_esp_transforms (vm, tmp, mp->crypto_alg, mp->integ_alg,
861 mp->dh_group, mp->crypto_key_size);
862 vec_free (tmp);
863 if (error)
864 rv = VNET_API_ERROR_UNSPECIFIED;
865#else
866 rv = VNET_API_ERROR_UNIMPLEMENTED;
867#endif
868
869 REPLY_MACRO (VL_API_IKEV2_SET_ESP_TRANSFORMS_REPLY);
870}
871
872static void
873vl_api_ikev2_set_sa_lifetime_t_handler (vl_api_ikev2_set_sa_lifetime_t * mp)
874{
875 vl_api_ikev2_set_sa_lifetime_reply_t *rmp;
876 int rv = 0;
877
878#if WITH_LIBSSL > 0
879 vlib_main_t *vm = vlib_get_main ();
880 clib_error_t *error;
881
882 u8 *tmp = format (0, "%s", mp->name);
883
884 error =
885 ikev2_set_profile_sa_lifetime (vm, tmp, mp->lifetime, mp->lifetime_jitter,
886 mp->handover, mp->lifetime_maxdata);
887 vec_free (tmp);
888 if (error)
889 rv = VNET_API_ERROR_UNSPECIFIED;
890#else
891 rv = VNET_API_ERROR_UNIMPLEMENTED;
892#endif
893
894 REPLY_MACRO (VL_API_IKEV2_SET_SA_LIFETIME_REPLY);
895}
896
897static void
898vl_api_ikev2_initiate_sa_init_t_handler (vl_api_ikev2_initiate_sa_init_t * mp)
899{
900 vl_api_ikev2_initiate_sa_init_reply_t *rmp;
901 int rv = 0;
902
903#if WITH_LIBSSL > 0
904 vlib_main_t *vm = vlib_get_main ();
905 clib_error_t *error;
906
907 u8 *tmp = format (0, "%s", mp->name);
908
909 error = ikev2_initiate_sa_init (vm, tmp);
910 vec_free (tmp);
911 if (error)
912 rv = VNET_API_ERROR_UNSPECIFIED;
913#else
914 rv = VNET_API_ERROR_UNIMPLEMENTED;
915#endif
916
917 REPLY_MACRO (VL_API_IKEV2_INITIATE_SA_INIT_REPLY);
918}
919
920static void
921vl_api_ikev2_initiate_del_ike_sa_t_handler (vl_api_ikev2_initiate_del_ike_sa_t
922 * mp)
923{
924 vl_api_ikev2_initiate_del_ike_sa_reply_t *rmp;
925 int rv = 0;
926
927#if WITH_LIBSSL > 0
928 vlib_main_t *vm = vlib_get_main ();
929 clib_error_t *error;
930
931 error = ikev2_initiate_delete_ike_sa (vm, mp->ispi);
932 if (error)
933 rv = VNET_API_ERROR_UNSPECIFIED;
934#else
935 rv = VNET_API_ERROR_UNIMPLEMENTED;
936#endif
937
938 REPLY_MACRO (VL_API_IKEV2_INITIATE_DEL_IKE_SA_REPLY);
939}
940
941static void
942 vl_api_ikev2_initiate_del_child_sa_t_handler
943 (vl_api_ikev2_initiate_del_child_sa_t * mp)
944{
945 vl_api_ikev2_initiate_del_child_sa_reply_t *rmp;
946 int rv = 0;
947
948#if WITH_LIBSSL > 0
949 vlib_main_t *vm = vlib_get_main ();
950 clib_error_t *error;
951
952 error = ikev2_initiate_delete_child_sa (vm, mp->ispi);
953 if (error)
954 rv = VNET_API_ERROR_UNSPECIFIED;
955#else
956 rv = VNET_API_ERROR_UNIMPLEMENTED;
957#endif
958
959 REPLY_MACRO (VL_API_IKEV2_INITIATE_DEL_CHILD_SA_REPLY);
960}
961
962static void
963 vl_api_ikev2_initiate_rekey_child_sa_t_handler
964 (vl_api_ikev2_initiate_rekey_child_sa_t * mp)
965{
966 vl_api_ikev2_initiate_rekey_child_sa_reply_t *rmp;
967 int rv = 0;
968
969#if WITH_LIBSSL > 0
970 vlib_main_t *vm = vlib_get_main ();
971 clib_error_t *error;
972
973 error = ikev2_initiate_rekey_child_sa (vm, mp->ispi);
974 if (error)
975 rv = VNET_API_ERROR_UNSPECIFIED;
976#else
977 rv = VNET_API_ERROR_UNIMPLEMENTED;
978#endif
979
980 REPLY_MACRO (VL_API_IKEV2_INITIATE_REKEY_CHILD_SA_REPLY);
981}
982
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100983/*
984 * ipsec_api_hookup
985 * Add vpe's API message handlers to the table.
Paul Vinciguerrabdc0e6b2018-09-22 05:32:50 -0700986 * vlib has already mapped shared memory and
Pavel Kotucek9c7ef032016-12-21 07:46:45 +0100987 * added the client registration handlers.
988 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
989 */
990#define vl_msg_name_crc_list
991#include <vnet/vnet_all_api_h.h>
992#undef vl_msg_name_crc_list
993
994static void
995setup_message_id_table (api_main_t * am)
996{
997#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
998 foreach_vl_msg_name_crc_ipsec;
999#undef _
1000}
1001
1002static clib_error_t *
1003ipsec_api_hookup (vlib_main_t * vm)
1004{
1005 api_main_t *am = &api_main;
1006
1007#define _(N,n) \
1008 vl_msg_api_set_handlers(VL_API_##N, #n, \
1009 vl_api_##n##_t_handler, \
1010 vl_noop_handler, \
1011 vl_api_##n##_t_endian, \
1012 vl_api_##n##_t_print, \
1013 sizeof(vl_api_##n##_t), 1);
1014 foreach_vpe_api_msg;
1015#undef _
1016
1017 /*
1018 * Set up the (msg_name, crc, message-id) table
1019 */
1020 setup_message_id_table (am);
1021
1022 return 0;
1023}
1024
1025VLIB_API_INIT_FUNCTION (ipsec_api_hookup);
1026
1027/*
1028 * fd.io coding-style-patch-verification: ON
1029 *
1030 * Local Variables:
1031 * eval: (c-set-style "gnu")
1032 * End:
1033 */