ikev2: add profile dump API
[vpp.git] / src / plugins / ikev2 / ikev2_api.c
1 /*
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 #include <vnet/api_errno.h>
23 #include <vpp/app/version.h>
24
25 #include <ikev2/ikev2.h>
26 #include <ikev2/ikev2_priv.h>
27
28 /* define message IDs */
29 #include <vnet/format_fns.h>
30 #include <plugins/ikev2/ikev2.api_enum.h>
31 #include <plugins/ikev2/ikev2.api_types.h>
32
33
34 #define vl_endianfun            /* define message structures */
35 #include <plugins/ikev2/ikev2_types.api.h>
36 #undef vl_endianfun
37
38 extern ikev2_main_t ikev2_main;
39
40 #define IKEV2_PLUGIN_VERSION_MAJOR 1
41 #define IKEV2_PLUGIN_VERSION_MINOR 0
42 #define REPLY_MSG_ID_BASE ikev2_main.msg_id_base
43 #include <vlibapi/api_helper_macros.h>
44
45 static void
46 cp_transforms (vl_api_ikev2_transforms_set_t * vl_api_ts,
47                ikev2_transforms_set * ts)
48 {
49   vl_api_ts->crypto_alg = ts->crypto_alg;
50   vl_api_ts->integ_alg = ts->integ_alg;
51   vl_api_ts->dh_type = ts->dh_type;
52   vl_api_ts->crypto_key_size = ts->crypto_key_size;
53 }
54
55 static void
56 cp_id (vl_api_ikev2_id_t * vl_api_id, ikev2_id_t * id)
57 {
58   if (!id->data)
59     return;
60
61   int size_data = 0;
62   vl_api_id->type = id->type;
63   size_data = sizeof (vl_api_id->data) - 1;     // size without zero ending character
64   if (vec_len (id->data) < size_data)
65     size_data = vec_len (id->data);
66
67   vl_api_id->data_len = size_data;
68   clib_memcpy (vl_api_id->data, id->data, size_data);
69 }
70
71 static void
72 cp_ts (vl_api_ikev2_ts_t * vl_api_ts, ikev2_ts_t * ts)
73 {
74   vl_api_ts->ts_type = ts->ts_type;
75   vl_api_ts->protocol_id = ts->protocol_id;
76   vl_api_ts->selector_len = ts->selector_len;
77   vl_api_ts->start_port = ts->start_port;
78   vl_api_ts->end_port = ts->end_port;
79   clib_memcpy (&vl_api_ts->start_addr, &ts->start_addr,
80                sizeof (ip4_address_t));
81   clib_memcpy (&vl_api_ts->end_addr, &ts->end_addr, sizeof (ip4_address_t));
82 }
83
84 static void
85 cp_auth (vl_api_ikev2_auth_t * vl_api_auth, ikev2_auth_t * auth)
86 {
87   vl_api_auth->method = auth->method;
88   vl_api_auth->data_len = vec_len (auth->data);
89   vl_api_auth->hex = auth->hex;
90   clib_memcpy (&vl_api_auth->data, auth->data, vec_len (auth->data));
91 }
92
93 static void
94 cp_responder (vl_api_ikev2_responder_t * vl_api_responder,
95               ikev2_responder_t * responder)
96 {
97   vl_api_responder->sw_if_index = responder->sw_if_index;
98   clib_memcpy (&vl_api_responder->ip4, &responder->ip4,
99                sizeof (ip4_address_t));
100 }
101
102 static void
103 send_profile (ikev2_profile_t * profile, vl_api_registration_t * reg,
104               u32 context)
105 {
106   vl_api_ikev2_profile_details_t *rmp = 0;
107
108   rmp = vl_msg_api_alloc (sizeof (*rmp) + vec_len (profile->auth.data));
109   clib_memset (rmp, 0, sizeof (*rmp) + vec_len (profile->auth.data));
110   ikev2_main_t *im = &ikev2_main;
111   rmp->_vl_msg_id = ntohs (VL_API_IKEV2_PROFILE_DETAILS + im->msg_id_base);
112   rmp->context = context;
113
114   int size_data = sizeof (rmp->profile.name) - 1;
115   if (vec_len (profile->name) < size_data)
116     size_data = vec_len (profile->name);
117   clib_memcpy (rmp->profile.name, profile->name, size_data);
118
119   cp_transforms (&rmp->profile.ike_ts, &profile->ike_ts);
120   cp_transforms (&rmp->profile.esp_ts, &profile->esp_ts);
121
122   cp_id (&rmp->profile.loc_id, &profile->loc_id);
123   cp_id (&rmp->profile.rem_id, &profile->rem_id);
124
125   cp_ts (&rmp->profile.rem_ts, &profile->rem_ts);
126   cp_ts (&rmp->profile.loc_ts, &profile->loc_ts);
127
128   cp_auth (&rmp->profile.auth, &profile->auth);
129
130   cp_responder (&rmp->profile.responder, &profile->responder);
131
132   rmp->profile.udp_encap = profile->udp_encap;
133   rmp->profile.tun_itf = profile->tun_itf;
134
135   rmp->profile.ipsec_over_udp_port = profile->ipsec_over_udp_port;
136
137   rmp->profile.lifetime = profile->lifetime;
138   rmp->profile.lifetime_maxdata = profile->lifetime_maxdata;
139   rmp->profile.lifetime_jitter = profile->lifetime_jitter;
140   rmp->profile.handover = profile->handover;
141
142   vl_api_ikev2_profile_t_endian (&rmp->profile);
143
144   vl_api_send_msg (reg, (u8 *) rmp);
145 }
146
147 static void
148 vl_api_ikev2_profile_dump_t_handler (vl_api_ikev2_profile_dump_t * mp)
149 {
150   ikev2_main_t *im = &ikev2_main;
151   ikev2_profile_t *profile;
152   vl_api_registration_t *reg;
153   reg = vl_api_client_index_to_registration (mp->client_index);
154   if (!reg)
155     return;
156
157   /* *INDENT-OFF* */
158   pool_foreach (profile, im->profiles,
159   ({
160     send_profile (profile, reg, mp->context);
161   }));
162   /* *INDENT-ON* */
163 }
164
165 static void
166 vl_api_ikev2_plugin_get_version_t_handler (vl_api_ikev2_plugin_get_version_t *
167                                            mp)
168 {
169   ikev2_main_t *im = &ikev2_main;
170   vl_api_ikev2_plugin_get_version_reply_t *rmp;
171   int msg_size = sizeof (*rmp);
172   vl_api_registration_t *reg;
173
174   reg = vl_api_client_index_to_registration (mp->client_index);
175   if (!reg)
176     return;
177
178   rmp = vl_msg_api_alloc (msg_size);
179   clib_memset (rmp, 0, msg_size);
180   rmp->_vl_msg_id =
181     ntohs (VL_API_IKEV2_PLUGIN_GET_VERSION_REPLY + im->msg_id_base);
182   rmp->context = mp->context;
183   rmp->major = htonl (IKEV2_PLUGIN_VERSION_MAJOR);
184   rmp->minor = htonl (IKEV2_PLUGIN_VERSION_MINOR);
185
186   vl_api_send_msg (reg, (u8 *) rmp);
187 }
188
189 static void
190   vl_api_ikev2_profile_set_liveness_t_handler
191   (vl_api_ikev2_profile_set_liveness_t * mp)
192 {
193   vl_api_ikev2_profile_set_liveness_reply_t *rmp;
194   int rv = 0;
195
196 #if WITH_LIBSSL > 0
197   clib_error_t *error;
198   error = ikev2_set_liveness_params (clib_net_to_host_u32 (mp->period),
199                                      clib_net_to_host_u32 (mp->max_retries));
200   if (error)
201     rv = VNET_API_ERROR_UNSPECIFIED;
202 #else
203   rv = VNET_API_ERROR_UNIMPLEMENTED;
204 #endif
205
206   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_LIVENESS_REPLY);
207 }
208
209 static void
210 vl_api_ikev2_profile_add_del_t_handler (vl_api_ikev2_profile_add_del_t * mp)
211 {
212   vl_api_ikev2_profile_add_del_reply_t *rmp;
213   int rv = 0;
214
215 #if WITH_LIBSSL > 0
216   vlib_main_t *vm = vlib_get_main ();
217   clib_error_t *error;
218   u8 *tmp = format (0, "%s", mp->name);
219   error = ikev2_add_del_profile (vm, tmp, mp->is_add);
220   vec_free (tmp);
221   if (error)
222     rv = VNET_API_ERROR_UNSPECIFIED;
223 #else
224   rv = VNET_API_ERROR_UNIMPLEMENTED;
225 #endif
226
227   REPLY_MACRO (VL_API_IKEV2_PROFILE_ADD_DEL_REPLY);
228 }
229
230 static void
231   vl_api_ikev2_profile_set_auth_t_handler
232   (vl_api_ikev2_profile_set_auth_t * mp)
233 {
234   vl_api_ikev2_profile_set_auth_reply_t *rmp;
235   int rv = 0;
236
237 #if WITH_LIBSSL > 0
238   vlib_main_t *vm = vlib_get_main ();
239   clib_error_t *error;
240   int data_len = ntohl (mp->data_len);
241   u8 *tmp = format (0, "%s", mp->name);
242   u8 *data = vec_new (u8, data_len);
243   clib_memcpy (data, mp->data, data_len);
244   error = ikev2_set_profile_auth (vm, tmp, mp->auth_method, data, mp->is_hex);
245   vec_free (tmp);
246   vec_free (data);
247   if (error)
248     rv = VNET_API_ERROR_UNSPECIFIED;
249 #else
250   rv = VNET_API_ERROR_UNIMPLEMENTED;
251 #endif
252
253   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_AUTH_REPLY);
254 }
255
256 static void
257 vl_api_ikev2_profile_set_id_t_handler (vl_api_ikev2_profile_set_id_t * mp)
258 {
259   vl_api_ikev2_profile_set_id_reply_t *rmp;
260   int rv = 0;
261
262 #if WITH_LIBSSL > 0
263   vlib_main_t *vm = vlib_get_main ();
264   clib_error_t *error;
265   u8 *tmp = format (0, "%s", mp->name);
266   int data_len = ntohl (mp->data_len);
267   u8 *data = vec_new (u8, data_len);
268   clib_memcpy (data, mp->data, data_len);
269   error = ikev2_set_profile_id (vm, tmp, mp->id_type, data, mp->is_local);
270   vec_free (tmp);
271   vec_free (data);
272   if (error)
273     rv = VNET_API_ERROR_UNSPECIFIED;
274 #else
275   rv = VNET_API_ERROR_UNIMPLEMENTED;
276 #endif
277
278   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_ID_REPLY);
279 }
280
281 static void
282   vl_api_ikev2_profile_set_udp_encap_t_handler
283   (vl_api_ikev2_profile_set_udp_encap_t * mp)
284 {
285   vl_api_ikev2_profile_set_udp_encap_reply_t *rmp;
286   int rv = 0;
287
288 #if WITH_LIBSSL > 0
289   vlib_main_t *vm = vlib_get_main ();
290   clib_error_t *error;
291   u8 *tmp = format (0, "%s", mp->name);
292   error = ikev2_set_profile_udp_encap (vm, tmp);
293   vec_free (tmp);
294   if (error)
295     rv = VNET_API_ERROR_UNSPECIFIED;
296 #else
297   rv = VNET_API_ERROR_UNIMPLEMENTED;
298 #endif
299
300   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_UDP_ENCAP);
301 }
302
303 static void
304 vl_api_ikev2_profile_set_ts_t_handler (vl_api_ikev2_profile_set_ts_t * mp)
305 {
306   vl_api_ikev2_profile_set_ts_reply_t *rmp;
307   int rv = 0;
308
309 #if WITH_LIBSSL > 0
310   vlib_main_t *vm = vlib_get_main ();
311   clib_error_t *error;
312   u8 *tmp = format (0, "%s", mp->name);
313   error =
314     ikev2_set_profile_ts (vm, tmp, mp->proto,
315                           clib_net_to_host_u16 (mp->start_port),
316                           clib_net_to_host_u16 (mp->end_port),
317                           (ip4_address_t) mp->start_addr,
318                           (ip4_address_t) mp->end_addr, mp->is_local);
319   vec_free (tmp);
320   if (error)
321     rv = VNET_API_ERROR_UNSPECIFIED;
322 #else
323   rv = VNET_API_ERROR_UNIMPLEMENTED;
324 #endif
325
326   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_TS_REPLY);
327 }
328
329 static void
330 vl_api_ikev2_set_local_key_t_handler (vl_api_ikev2_set_local_key_t * mp)
331 {
332   vl_api_ikev2_set_local_key_reply_t *rmp;
333   int rv = 0;
334
335 #if WITH_LIBSSL > 0
336   vlib_main_t *vm = vlib_get_main ();
337   clib_error_t *error;
338
339   error = ikev2_set_local_key (vm, mp->key_file);
340   if (error)
341     rv = VNET_API_ERROR_UNSPECIFIED;
342 #else
343   rv = VNET_API_ERROR_UNIMPLEMENTED;
344 #endif
345
346   REPLY_MACRO (VL_API_IKEV2_SET_LOCAL_KEY_REPLY);
347 }
348
349 static void
350 vl_api_ikev2_set_responder_t_handler (vl_api_ikev2_set_responder_t * mp)
351 {
352   vl_api_ikev2_set_responder_reply_t *rmp;
353   int rv = 0;
354
355 #if WITH_LIBSSL > 0
356   vlib_main_t *vm = vlib_get_main ();
357   clib_error_t *error;
358
359   u8 *tmp = format (0, "%s", mp->name);
360   ip4_address_t ip4;
361   clib_memcpy (&ip4, mp->address, sizeof (ip4));
362
363   error = ikev2_set_profile_responder (vm, tmp, ntohl (mp->sw_if_index), ip4);
364   vec_free (tmp);
365   if (error)
366     rv = VNET_API_ERROR_UNSPECIFIED;
367 #else
368   rv = VNET_API_ERROR_UNIMPLEMENTED;
369 #endif
370
371   REPLY_MACRO (VL_API_IKEV2_SET_RESPONDER_REPLY);
372 }
373
374 static void
375 vl_api_ikev2_set_ike_transforms_t_handler (vl_api_ikev2_set_ike_transforms_t *
376                                            mp)
377 {
378   vl_api_ikev2_set_ike_transforms_reply_t *rmp;
379   int rv = 0;
380
381 #if WITH_LIBSSL > 0
382   vlib_main_t *vm = vlib_get_main ();
383   clib_error_t *error;
384
385   u8 *tmp = format (0, "%s", mp->name);
386
387   error =
388     ikev2_set_profile_ike_transforms (vm, tmp, ntohl (mp->crypto_alg),
389                                       ntohl (mp->integ_alg),
390                                       ntohl (mp->dh_group),
391                                       ntohl (mp->crypto_key_size));
392   vec_free (tmp);
393   if (error)
394     rv = VNET_API_ERROR_UNSPECIFIED;
395 #else
396   rv = VNET_API_ERROR_UNIMPLEMENTED;
397 #endif
398
399   REPLY_MACRO (VL_API_IKEV2_SET_IKE_TRANSFORMS_REPLY);
400 }
401
402 static void
403 vl_api_ikev2_set_esp_transforms_t_handler (vl_api_ikev2_set_esp_transforms_t *
404                                            mp)
405 {
406   vl_api_ikev2_set_esp_transforms_reply_t *rmp;
407   int rv = 0;
408
409 #if WITH_LIBSSL > 0
410   vlib_main_t *vm = vlib_get_main ();
411   clib_error_t *error;
412
413   u8 *tmp = format (0, "%s", mp->name);
414
415   error =
416     ikev2_set_profile_esp_transforms (vm, tmp, ntohl (mp->crypto_alg),
417                                       ntohl (mp->integ_alg),
418                                       ntohl (mp->dh_group),
419                                       ntohl (mp->crypto_key_size));
420   vec_free (tmp);
421   if (error)
422     rv = VNET_API_ERROR_UNSPECIFIED;
423 #else
424   rv = VNET_API_ERROR_UNIMPLEMENTED;
425 #endif
426
427   REPLY_MACRO (VL_API_IKEV2_SET_ESP_TRANSFORMS_REPLY);
428 }
429
430 static void
431 vl_api_ikev2_set_sa_lifetime_t_handler (vl_api_ikev2_set_sa_lifetime_t * mp)
432 {
433   vl_api_ikev2_set_sa_lifetime_reply_t *rmp;
434   int rv = 0;
435
436 #if WITH_LIBSSL > 0
437   vlib_main_t *vm = vlib_get_main ();
438   clib_error_t *error;
439
440   u8 *tmp = format (0, "%s", mp->name);
441
442   error =
443     ikev2_set_profile_sa_lifetime (vm, tmp,
444                                    clib_net_to_host_u64 (mp->lifetime),
445                                    ntohl (mp->lifetime_jitter),
446                                    ntohl (mp->handover),
447                                    clib_net_to_host_u64
448                                    (mp->lifetime_maxdata));
449   vec_free (tmp);
450   if (error)
451     rv = VNET_API_ERROR_UNSPECIFIED;
452 #else
453   rv = VNET_API_ERROR_UNIMPLEMENTED;
454 #endif
455
456   REPLY_MACRO (VL_API_IKEV2_SET_SA_LIFETIME_REPLY);
457 }
458
459 static void
460   vl_api_ikev2_profile_set_ipsec_udp_port_t_handler
461   (vl_api_ikev2_profile_set_ipsec_udp_port_t * mp)
462 {
463   vl_api_ikev2_profile_set_ipsec_udp_port_reply_t *rmp;
464   int rv = 0;
465
466 #if WITH_LIBSSL > 0
467   vlib_main_t *vm = vlib_get_main ();
468
469   u8 *tmp = format (0, "%s", mp->name);
470
471   rv =
472     ikev2_set_profile_ipsec_udp_port (vm, tmp,
473                                       clib_net_to_host_u16 (mp->port),
474                                       mp->is_set);
475   vec_free (tmp);
476 #else
477   rv = VNET_API_ERROR_UNIMPLEMENTED;
478 #endif
479
480   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_IPSEC_UDP_PORT_REPLY);
481 }
482
483 static void
484   vl_api_ikev2_set_tunnel_interface_t_handler
485   (vl_api_ikev2_set_tunnel_interface_t * mp)
486 {
487   vl_api_ikev2_set_tunnel_interface_reply_t *rmp;
488   int rv = 0;
489
490   VALIDATE_SW_IF_INDEX (mp);
491
492 #if WITH_LIBSSL > 0
493   u8 *tmp = format (0, "%s", mp->name);
494   clib_error_t *error;
495
496   error = ikev2_set_profile_tunnel_interface (vlib_get_main (), tmp,
497                                               ntohl (mp->sw_if_index));
498
499   if (error)
500     rv = VNET_API_ERROR_UNSPECIFIED;
501   vec_free (tmp);
502 #else
503   rv = VNET_API_ERROR_UNIMPLEMENTED;
504 #endif
505
506   BAD_SW_IF_INDEX_LABEL;
507   REPLY_MACRO (VL_API_IKEV2_SET_TUNNEL_INTERFACE_REPLY);
508 }
509
510 static void
511 vl_api_ikev2_initiate_sa_init_t_handler (vl_api_ikev2_initiate_sa_init_t * mp)
512 {
513   vl_api_ikev2_initiate_sa_init_reply_t *rmp;
514   int rv = 0;
515
516 #if WITH_LIBSSL > 0
517   vlib_main_t *vm = vlib_get_main ();
518   clib_error_t *error;
519
520   u8 *tmp = format (0, "%s", mp->name);
521
522   error = ikev2_initiate_sa_init (vm, tmp);
523   vec_free (tmp);
524   if (error)
525     rv = VNET_API_ERROR_UNSPECIFIED;
526 #else
527   rv = VNET_API_ERROR_UNIMPLEMENTED;
528 #endif
529
530   REPLY_MACRO (VL_API_IKEV2_INITIATE_SA_INIT_REPLY);
531 }
532
533 static void
534 vl_api_ikev2_initiate_del_ike_sa_t_handler (vl_api_ikev2_initiate_del_ike_sa_t
535                                             * mp)
536 {
537   vl_api_ikev2_initiate_del_ike_sa_reply_t *rmp;
538   int rv = 0;
539
540 #if WITH_LIBSSL > 0
541   vlib_main_t *vm = vlib_get_main ();
542   clib_error_t *error;
543
544   error = ikev2_initiate_delete_ike_sa (vm, mp->ispi);
545   if (error)
546     rv = VNET_API_ERROR_UNSPECIFIED;
547 #else
548   rv = VNET_API_ERROR_UNIMPLEMENTED;
549 #endif
550
551   REPLY_MACRO (VL_API_IKEV2_INITIATE_DEL_IKE_SA_REPLY);
552 }
553
554 static void
555   vl_api_ikev2_initiate_del_child_sa_t_handler
556   (vl_api_ikev2_initiate_del_child_sa_t * mp)
557 {
558   vl_api_ikev2_initiate_del_child_sa_reply_t *rmp;
559   int rv = 0;
560
561 #if WITH_LIBSSL > 0
562   vlib_main_t *vm = vlib_get_main ();
563   clib_error_t *error;
564
565   error = ikev2_initiate_delete_child_sa (vm, mp->ispi);
566   if (error)
567     rv = VNET_API_ERROR_UNSPECIFIED;
568 #else
569   rv = VNET_API_ERROR_UNIMPLEMENTED;
570 #endif
571
572   REPLY_MACRO (VL_API_IKEV2_INITIATE_DEL_CHILD_SA_REPLY);
573 }
574
575 static void
576   vl_api_ikev2_initiate_rekey_child_sa_t_handler
577   (vl_api_ikev2_initiate_rekey_child_sa_t * mp)
578 {
579   vl_api_ikev2_initiate_rekey_child_sa_reply_t *rmp;
580   int rv = 0;
581
582 #if WITH_LIBSSL > 0
583   vlib_main_t *vm = vlib_get_main ();
584   clib_error_t *error;
585
586   error = ikev2_initiate_rekey_child_sa (vm, mp->ispi);
587   if (error)
588     rv = VNET_API_ERROR_UNSPECIFIED;
589 #else
590   rv = VNET_API_ERROR_UNIMPLEMENTED;
591 #endif
592
593   REPLY_MACRO (VL_API_IKEV2_INITIATE_REKEY_CHILD_SA_REPLY);
594 }
595
596 #include <ikev2/ikev2.api.c>
597 static clib_error_t *
598 ikev2_api_init (vlib_main_t * vm)
599 {
600   ikev2_main_t *im = &ikev2_main;
601
602   /* Ask for a correctly-sized block of API message decode slots */
603   im->msg_id_base = setup_message_id_table ();
604
605   return 0;
606 }
607
608 VLIB_INIT_FUNCTION (ikev2_api_init);
609
610 /*
611  * fd.io coding-style-patch-verification: ON
612  *
613  * Local Variables:
614  * eval: (c-set-style "gnu")
615  * End:
616  */