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