ikev2: add per SA stats
[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.api.h>
36 #include <plugins/ikev2/ikev2_types.api.h>
37 #undef vl_endianfun
38
39 extern ikev2_main_t ikev2_main;
40
41 #define IKEV2_PLUGIN_VERSION_MAJOR 1
42 #define IKEV2_PLUGIN_VERSION_MINOR 0
43 #define REPLY_MSG_ID_BASE ikev2_main.msg_id_base
44 #include <vlibapi/api_helper_macros.h>
45
46 static u32
47 ikev2_encode_sa_index (u32 sai, u32 ti)
48 {
49   return (ti << 16) | sai;
50 }
51
52 static void
53 ikev2_decode_sa_index (u32 api_sai, u32 * sai, u32 * ti)
54 {
55   *sai = api_sai & 0xffff;
56   *ti = api_sai >> 16;
57 }
58
59 static void
60 cp_ike_transforms (vl_api_ikev2_ike_transforms_t * vl_api_ts,
61                    ikev2_transforms_set * ts)
62 {
63   vl_api_ts->crypto_alg = ts->crypto_alg;
64   vl_api_ts->integ_alg = ts->integ_alg;
65   vl_api_ts->dh_group = ts->dh_type;
66   vl_api_ts->crypto_key_size = ts->crypto_key_size;
67 }
68
69 static void
70 cp_esp_transforms (vl_api_ikev2_esp_transforms_t * vl_api_ts,
71                    ikev2_transforms_set * ts)
72 {
73   vl_api_ts->crypto_alg = ts->crypto_alg;
74   vl_api_ts->integ_alg = ts->integ_alg;
75   vl_api_ts->crypto_key_size = ts->crypto_key_size;
76 }
77
78 static void
79 cp_id (vl_api_ikev2_id_t * vl_api_id, ikev2_id_t * id)
80 {
81   if (!id->data)
82     return;
83
84   int size_data = 0;
85   vl_api_id->type = id->type;
86   size_data = sizeof (vl_api_id->data) - 1;     // size without zero ending character
87   if (vec_len (id->data) < size_data)
88     size_data = vec_len (id->data);
89
90   vl_api_id->data_len = size_data;
91   clib_memcpy (vl_api_id->data, id->data, size_data);
92 }
93
94 static void
95 cp_ts (vl_api_ikev2_ts_t * vl_api_ts, ikev2_ts_t * ts, u8 is_local)
96 {
97   vl_api_ts->is_local = is_local;
98   vl_api_ts->protocol_id = ts->protocol_id;
99   vl_api_ts->start_port = ts->start_port;
100   vl_api_ts->end_port = ts->end_port;
101   ip_address_encode2 (&ts->start_addr, &vl_api_ts->start_addr);
102   ip_address_encode2 (&ts->end_addr, &vl_api_ts->end_addr);
103 }
104
105 static void
106 cp_auth (vl_api_ikev2_auth_t * vl_api_auth, ikev2_auth_t * auth)
107 {
108   vl_api_auth->method = auth->method;
109   vl_api_auth->data_len = vec_len (auth->data);
110   vl_api_auth->hex = auth->hex;
111   clib_memcpy (&vl_api_auth->data, auth->data, vec_len (auth->data));
112 }
113
114 static void
115 cp_responder (vl_api_ikev2_responder_t * vl_api_responder,
116               ikev2_responder_t * responder)
117 {
118   vl_api_responder->sw_if_index = responder->sw_if_index;
119   ip_address_encode2 (&responder->addr, &vl_api_responder->addr);
120 }
121
122 void
123 cp_sa_transform (vl_api_ikev2_sa_transform_t * vl_tr,
124                  ikev2_sa_transform_t * tr)
125 {
126   vl_tr->transform_type = tr->type;
127   vl_tr->key_len = tr->key_len;
128   vl_tr->key_trunc = tr->key_trunc;
129   vl_tr->block_size = tr->block_size;
130   vl_tr->dh_group = tr->dh_group;
131   vl_tr->transform_id = tr->encr_type;
132 }
133
134 static void
135 send_profile (ikev2_profile_t * profile, vl_api_registration_t * reg,
136               u32 context)
137 {
138   vl_api_ikev2_profile_details_t *rmp = 0;
139
140   rmp = vl_msg_api_alloc (sizeof (*rmp) + vec_len (profile->auth.data));
141   clib_memset (rmp, 0, sizeof (*rmp) + vec_len (profile->auth.data));
142   ikev2_main_t *im = &ikev2_main;
143   rmp->_vl_msg_id = ntohs (VL_API_IKEV2_PROFILE_DETAILS + im->msg_id_base);
144   rmp->context = context;
145
146   int size_data = sizeof (rmp->profile.name) - 1;
147   if (vec_len (profile->name) < size_data)
148     size_data = vec_len (profile->name);
149   clib_memcpy (rmp->profile.name, profile->name, size_data);
150
151   cp_ike_transforms (&rmp->profile.ike_ts, &profile->ike_ts);
152   cp_esp_transforms (&rmp->profile.esp_ts, &profile->esp_ts);
153
154   cp_id (&rmp->profile.loc_id, &profile->loc_id);
155   cp_id (&rmp->profile.rem_id, &profile->rem_id);
156
157   cp_ts (&rmp->profile.rem_ts, &profile->rem_ts, 0 /* is_local */ );
158   cp_ts (&rmp->profile.loc_ts, &profile->loc_ts, 1 /* is_local */ );
159
160   cp_auth (&rmp->profile.auth, &profile->auth);
161
162   cp_responder (&rmp->profile.responder, &profile->responder);
163
164   rmp->profile.udp_encap = profile->udp_encap;
165   rmp->profile.tun_itf = profile->tun_itf;
166   rmp->profile.natt_disabled = profile->natt_disabled;
167   rmp->profile.ipsec_over_udp_port = profile->ipsec_over_udp_port;
168
169   rmp->profile.lifetime = profile->lifetime;
170   rmp->profile.lifetime_maxdata = profile->lifetime_maxdata;
171   rmp->profile.lifetime_jitter = profile->lifetime_jitter;
172   rmp->profile.handover = profile->handover;
173
174   vl_api_ikev2_profile_t_endian (&rmp->profile);
175
176   vl_api_send_msg (reg, (u8 *) rmp);
177 }
178
179 static void
180 vl_api_ikev2_profile_dump_t_handler (vl_api_ikev2_profile_dump_t * mp)
181 {
182   ikev2_main_t *im = &ikev2_main;
183   ikev2_profile_t *profile;
184   vl_api_registration_t *reg;
185   reg = vl_api_client_index_to_registration (mp->client_index);
186   if (!reg)
187     return;
188
189   /* *INDENT-OFF* */
190   pool_foreach (profile, im->profiles)
191    {
192     send_profile (profile, reg, mp->context);
193   }
194   /* *INDENT-ON* */
195 }
196
197 static void
198 ikev2_copy_stats (vl_api_ikev2_sa_stats_t *dst, const ikev2_stats_t *src)
199 {
200   dst->n_rekey_req = src->n_rekey_req;
201   dst->n_keepalives = src->n_keepalives;
202   dst->n_retransmit = src->n_retransmit;
203   dst->n_init_sa_retransmit = src->n_init_retransmit;
204   dst->n_sa_init_req = src->n_sa_init_req;
205   dst->n_sa_auth_req = src->n_sa_auth_req;
206 }
207
208 static void
209 send_sa (ikev2_sa_t * sa, vl_api_ikev2_sa_dump_t * mp, u32 api_sa_index)
210 {
211   vl_api_ikev2_sa_details_t *rmp = 0;
212   int rv = 0;
213   ikev2_sa_transform_t *tr;
214
215   /* *INDENT-OFF* */
216   REPLY_MACRO2_ZERO (VL_API_IKEV2_SA_DETAILS,
217   {
218     vl_api_ikev2_sa_t *rsa = &rmp->sa;
219     vl_api_ikev2_keys_t* k = &rsa->keys;
220     rsa->profile_index = rsa->profile_index;
221     rsa->sa_index = api_sa_index;
222     ip_address_encode2 (&sa->iaddr, &rsa->iaddr);
223     ip_address_encode2 (&sa->raddr, &rsa->raddr);
224     rsa->ispi = sa->ispi;
225     rsa->rspi = sa->rspi;
226     cp_id(&rsa->i_id, &sa->i_id);
227     cp_id(&rsa->r_id, &sa->r_id);
228
229     tr = ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
230     if (tr)
231       cp_sa_transform (&rsa->encryption, tr);
232
233     tr = ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);
234     if (tr)
235       cp_sa_transform (&rsa->prf, tr);
236
237     tr = ikev2_sa_get_td_for_type (sa->r_proposals,
238                                    IKEV2_TRANSFORM_TYPE_INTEG);
239     if (tr)
240       cp_sa_transform (&rsa->integrity, tr);
241
242     tr = ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_DH);
243     if (tr)
244       cp_sa_transform (&rsa->dh, tr);
245
246     k->sk_d_len = vec_len (sa->sk_d);
247     clib_memcpy (&k->sk_d, sa->sk_d, k->sk_d_len);
248
249     k->sk_ai_len = vec_len (sa->sk_ai);
250     clib_memcpy (&k->sk_ai, sa->sk_ai, k->sk_ai_len);
251
252     k->sk_ar_len = vec_len (sa->sk_ar);
253     clib_memcpy (&k->sk_ar, sa->sk_ar, k->sk_ar_len);
254
255     k->sk_ei_len = vec_len (sa->sk_ei);
256     clib_memcpy (&k->sk_ei, sa->sk_ei, k->sk_ei_len);
257
258     k->sk_er_len = vec_len (sa->sk_er);
259     clib_memcpy (&k->sk_er, sa->sk_er, k->sk_er_len);
260
261     k->sk_pi_len = vec_len (sa->sk_pi);
262     clib_memcpy (&k->sk_pi, sa->sk_pi, k->sk_pi_len);
263
264     k->sk_pr_len = vec_len (sa->sk_pr);
265     clib_memcpy (&k->sk_pr, sa->sk_pr, k->sk_pr_len);
266
267     ikev2_copy_stats (&rsa->stats, &sa->stats);
268
269     vl_api_ikev2_sa_t_endian(rsa);
270   });
271   /* *INDENT-ON* */
272 }
273
274 static void
275 vl_api_ikev2_sa_dump_t_handler (vl_api_ikev2_sa_dump_t * mp)
276 {
277   ikev2_main_t *km = &ikev2_main;
278   ikev2_main_per_thread_data_t *tkm;
279   ikev2_sa_t *sa;
280
281   vec_foreach (tkm, km->per_thread_data)
282   {
283     /* *INDENT-OFF* */
284     pool_foreach (sa, tkm->sas)
285      {
286       u32 api_sa_index = ikev2_encode_sa_index (sa - tkm->sas,
287                                               tkm - km->per_thread_data);
288       send_sa (sa, mp, api_sa_index);
289     }
290     /* *INDENT-ON* */
291   }
292 }
293
294
295 static void
296 send_child_sa (ikev2_child_sa_t * child,
297                vl_api_ikev2_child_sa_dump_t * mp, u32 child_sa_index,
298                u32 sa_index)
299 {
300   vl_api_ikev2_child_sa_details_t *rmp = 0;
301   int rv = 0;
302   ikev2_sa_transform_t *tr;
303
304   /* *INDENT-OFF* */
305   REPLY_MACRO2_ZERO (VL_API_IKEV2_CHILD_SA_DETAILS,
306   {
307     vl_api_ikev2_keys_t *k = &rmp->child_sa.keys;
308     rmp->child_sa.child_sa_index = child_sa_index;
309     rmp->child_sa.sa_index = sa_index;
310     rmp->child_sa.i_spi =
311       child->i_proposals ? child->i_proposals[0].spi : 0;
312     rmp->child_sa.r_spi =
313       child->r_proposals ? child->r_proposals[0].spi : 0;
314
315     tr = ikev2_sa_get_td_for_type (child->r_proposals,
316                                    IKEV2_TRANSFORM_TYPE_ENCR);
317     if (tr)
318       cp_sa_transform (&rmp->child_sa.encryption, tr);
319
320     tr = ikev2_sa_get_td_for_type (child->r_proposals,
321                                    IKEV2_TRANSFORM_TYPE_INTEG);
322     if (tr)
323       cp_sa_transform (&rmp->child_sa.integrity, tr);
324
325     tr = ikev2_sa_get_td_for_type (child->r_proposals,
326                                    IKEV2_TRANSFORM_TYPE_ESN);
327     if (tr)
328       cp_sa_transform (&rmp->child_sa.esn, tr);
329
330     k->sk_ei_len = vec_len (child->sk_ei);
331     clib_memcpy (&k->sk_ei, child->sk_ei, k->sk_ei_len);
332
333     k->sk_er_len = vec_len (child->sk_er);
334     clib_memcpy (&k->sk_er, child->sk_er, k->sk_er_len);
335
336     if (vec_len (child->sk_ai))
337       {
338         k->sk_ai_len = vec_len (child->sk_ai);
339         clib_memcpy (&k->sk_ai, child->sk_ai,
340                      k->sk_ai_len);
341
342         k->sk_ar_len = vec_len (child->sk_ar);
343         clib_memcpy (&k->sk_ar, child->sk_ar,
344                      k->sk_ar_len);
345       }
346
347     vl_api_ikev2_child_sa_t_endian (&rmp->child_sa);
348   });
349   /* *INDENT-ON* */
350 }
351
352 static void
353 vl_api_ikev2_child_sa_dump_t_handler (vl_api_ikev2_child_sa_dump_t * mp)
354 {
355   ikev2_main_t *im = &ikev2_main;
356   ikev2_main_per_thread_data_t *tkm;
357   ikev2_sa_t *sa;
358   ikev2_child_sa_t *child;
359   u32 sai = ~0, ti = ~0;
360
361   ikev2_decode_sa_index (clib_net_to_host_u32 (mp->sa_index), &sai, &ti);
362
363   if (vec_len (im->per_thread_data) <= ti)
364     return;
365
366   tkm = vec_elt_at_index (im->per_thread_data, ti);
367
368   if (pool_len (tkm->sas) <= sai || pool_is_free_index (tkm->sas, sai))
369     return;
370
371   sa = pool_elt_at_index (tkm->sas, sai);
372
373   vec_foreach (child, sa->childs)
374   {
375     u32 child_sa_index = child - sa->childs;
376     send_child_sa (child, mp, child_sa_index, sai);
377   }
378 }
379
380 static void
381   vl_api_ikev2_traffic_selector_dump_t_handler
382   (vl_api_ikev2_traffic_selector_dump_t * mp)
383 {
384   ikev2_main_t *im = &ikev2_main;
385   ikev2_main_per_thread_data_t *tkm;
386   ikev2_sa_t *sa;
387   ikev2_child_sa_t *child;
388   ikev2_ts_t *ts;
389   u32 sai = ~0, ti = ~0;
390
391   u32 api_sa_index = clib_net_to_host_u32 (mp->sa_index);
392   u32 child_sa_index = clib_net_to_host_u32 (mp->child_sa_index);
393   ikev2_decode_sa_index (api_sa_index, &sai, &ti);
394
395   if (vec_len (im->per_thread_data) <= ti)
396     return;
397
398   tkm = vec_elt_at_index (im->per_thread_data, ti);
399
400   if (pool_len (tkm->sas) <= sai || pool_is_free_index (tkm->sas, sai))
401     return;
402
403   sa = pool_elt_at_index (tkm->sas, sai);
404
405   if (vec_len (sa->childs) <= child_sa_index)
406     return;
407
408   child = vec_elt_at_index (sa->childs, child_sa_index);
409
410   vec_foreach (ts, mp->is_initiator ? child->tsi : child->tsr)
411   {
412     vl_api_ikev2_traffic_selector_details_t *rmp = 0;
413     int rv = 0;
414
415     /* *INDENT-OFF* */
416     REPLY_MACRO2_ZERO (VL_API_IKEV2_TRAFFIC_SELECTOR_DETAILS,
417     {
418       rmp->ts.sa_index = api_sa_index;
419       rmp->ts.child_sa_index = child_sa_index;
420       cp_ts (&rmp->ts, ts, mp->is_initiator);
421       vl_api_ikev2_ts_t_endian (&rmp->ts);
422     });
423     /* *INDENT-ON* */
424   }
425 }
426
427 static void
428 vl_api_ikev2_nonce_get_t_handler (vl_api_ikev2_nonce_get_t * mp)
429 {
430   ikev2_main_t *im = &ikev2_main;
431   ikev2_main_per_thread_data_t *tkm;
432   ikev2_sa_t *sa;
433   u32 sai = ~0, ti = ~0;
434
435   ikev2_decode_sa_index (clib_net_to_host_u32 (mp->sa_index), &sai, &ti);
436
437   if (vec_len (im->per_thread_data) <= ti)
438     return;
439
440   tkm = vec_elt_at_index (im->per_thread_data, ti);
441
442   if (pool_len (tkm->sas) <= sai || pool_is_free_index (tkm->sas, sai))
443     return;
444
445   sa = pool_elt_at_index (tkm->sas, sai);
446
447   u8 *nonce = mp->is_initiator ? sa->i_nonce : sa->r_nonce;
448   vl_api_ikev2_nonce_get_reply_t *rmp = 0;
449   int data_len = vec_len (nonce);
450   int rv = 0;
451
452   /* *INDENT-OFF* */
453   REPLY_MACRO3_ZERO (VL_API_IKEV2_NONCE_GET_REPLY, data_len,
454   {
455     rmp->data_len = clib_host_to_net_u32 (data_len);
456     clib_memcpy (rmp->nonce, nonce, data_len);
457   });
458   /* *INDENT-ON* */
459 }
460
461 static void
462 vl_api_ikev2_plugin_get_version_t_handler (vl_api_ikev2_plugin_get_version_t *
463                                            mp)
464 {
465   ikev2_main_t *im = &ikev2_main;
466   vl_api_ikev2_plugin_get_version_reply_t *rmp;
467   int msg_size = sizeof (*rmp);
468   vl_api_registration_t *reg;
469
470   reg = vl_api_client_index_to_registration (mp->client_index);
471   if (!reg)
472     return;
473
474   rmp = vl_msg_api_alloc (msg_size);
475   clib_memset (rmp, 0, msg_size);
476   rmp->_vl_msg_id =
477     ntohs (VL_API_IKEV2_PLUGIN_GET_VERSION_REPLY + im->msg_id_base);
478   rmp->context = mp->context;
479   rmp->major = htonl (IKEV2_PLUGIN_VERSION_MAJOR);
480   rmp->minor = htonl (IKEV2_PLUGIN_VERSION_MINOR);
481
482   vl_api_send_msg (reg, (u8 *) rmp);
483 }
484
485 static void
486   vl_api_ikev2_profile_set_liveness_t_handler
487   (vl_api_ikev2_profile_set_liveness_t * mp)
488 {
489   vl_api_ikev2_profile_set_liveness_reply_t *rmp;
490   int rv = 0;
491
492 #if WITH_LIBSSL > 0
493   clib_error_t *error;
494   error = ikev2_set_liveness_params (clib_net_to_host_u32 (mp->period),
495                                      clib_net_to_host_u32 (mp->max_retries));
496   if (error)
497     {
498       ikev2_log_error ("%U", format_clib_error, error);
499       clib_error_free (error);
500       rv = VNET_API_ERROR_UNSPECIFIED;
501     }
502 #else
503   rv = VNET_API_ERROR_UNIMPLEMENTED;
504 #endif
505
506   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_LIVENESS_REPLY);
507 }
508
509 static void
510 vl_api_ikev2_profile_add_del_t_handler (vl_api_ikev2_profile_add_del_t * mp)
511 {
512   vl_api_ikev2_profile_add_del_reply_t *rmp;
513   int rv = 0;
514
515 #if WITH_LIBSSL > 0
516   vlib_main_t *vm = vlib_get_main ();
517   clib_error_t *error;
518   u8 *tmp = format (0, "%s", mp->name);
519   error = ikev2_add_del_profile (vm, tmp, mp->is_add);
520   vec_free (tmp);
521   if (error)
522     {
523       ikev2_log_error ("%U", format_clib_error, error);
524       clib_error_free (error);
525       rv = VNET_API_ERROR_UNSPECIFIED;
526     }
527 #else
528   rv = VNET_API_ERROR_UNIMPLEMENTED;
529 #endif
530
531   REPLY_MACRO (VL_API_IKEV2_PROFILE_ADD_DEL_REPLY);
532 }
533
534 static void
535   vl_api_ikev2_profile_set_auth_t_handler
536   (vl_api_ikev2_profile_set_auth_t * mp)
537 {
538   vl_api_ikev2_profile_set_auth_reply_t *rmp;
539   int rv = 0;
540
541 #if WITH_LIBSSL > 0
542   vlib_main_t *vm = vlib_get_main ();
543   clib_error_t *error;
544   int data_len = ntohl (mp->data_len);
545   u8 *tmp = format (0, "%s", mp->name);
546   u8 *data = vec_new (u8, data_len);
547   clib_memcpy (data, mp->data, data_len);
548   error = ikev2_set_profile_auth (vm, tmp, mp->auth_method, data, mp->is_hex);
549   vec_free (tmp);
550   vec_free (data);
551   if (error)
552     {
553       ikev2_log_error ("%U", format_clib_error, error);
554       clib_error_free (error);
555       rv = VNET_API_ERROR_UNSPECIFIED;
556     }
557 #else
558   rv = VNET_API_ERROR_UNIMPLEMENTED;
559 #endif
560
561   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_AUTH_REPLY);
562 }
563
564 static void
565 vl_api_ikev2_profile_set_id_t_handler (vl_api_ikev2_profile_set_id_t * mp)
566 {
567   vl_api_ikev2_profile_set_id_reply_t *rmp;
568   int rv = 0;
569
570 #if WITH_LIBSSL > 0
571   vlib_main_t *vm = vlib_get_main ();
572   clib_error_t *error;
573   u8 *tmp = format (0, "%s", mp->name);
574   int data_len = ntohl (mp->data_len);
575   u8 *data = vec_new (u8, data_len);
576   clib_memcpy (data, mp->data, data_len);
577   error = ikev2_set_profile_id (vm, tmp, mp->id_type, data, mp->is_local);
578   vec_free (tmp);
579   vec_free (data);
580   if (error)
581     {
582       ikev2_log_error ("%U", format_clib_error, error);
583       clib_error_free (error);
584       rv = VNET_API_ERROR_UNSPECIFIED;
585     }
586 #else
587   rv = VNET_API_ERROR_UNIMPLEMENTED;
588 #endif
589
590   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_ID_REPLY);
591 }
592
593 static void
594   vl_api_ikev2_profile_set_udp_encap_t_handler
595   (vl_api_ikev2_profile_set_udp_encap_t * mp)
596 {
597   vl_api_ikev2_profile_set_udp_encap_reply_t *rmp;
598   int rv = 0;
599
600 #if WITH_LIBSSL > 0
601   vlib_main_t *vm = vlib_get_main ();
602   clib_error_t *error;
603   u8 *tmp = format (0, "%s", mp->name);
604   error = ikev2_set_profile_udp_encap (vm, tmp);
605   vec_free (tmp);
606   if (error)
607     {
608       ikev2_log_error ("%U", format_clib_error, error);
609       clib_error_free (error);
610       rv = VNET_API_ERROR_UNSPECIFIED;
611     }
612 #else
613   rv = VNET_API_ERROR_UNIMPLEMENTED;
614 #endif
615
616   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_UDP_ENCAP_REPLY);
617 }
618
619 static void
620 vl_api_ikev2_profile_set_ts_t_handler (vl_api_ikev2_profile_set_ts_t * mp)
621 {
622   vl_api_ikev2_profile_set_ts_reply_t *rmp;
623   int rv = 0;
624
625 #if WITH_LIBSSL > 0
626   vlib_main_t *vm = vlib_get_main ();
627   clib_error_t *error;
628   u8 *tmp = format (0, "%s", mp->name);
629   ip_address_t start_addr, end_addr;
630   ip_address_decode2 (&mp->ts.start_addr, &start_addr);
631   ip_address_decode2 (&mp->ts.end_addr, &end_addr);
632   error =
633     ikev2_set_profile_ts (vm, tmp, mp->ts.protocol_id,
634                           clib_net_to_host_u16 (mp->ts.start_port),
635                           clib_net_to_host_u16 (mp->ts.end_port),
636                           start_addr, end_addr, mp->ts.is_local);
637   vec_free (tmp);
638   if (error)
639     {
640       ikev2_log_error ("%U", format_clib_error, error);
641       clib_error_free (error);
642       rv = VNET_API_ERROR_UNSPECIFIED;
643     }
644 #else
645   rv = VNET_API_ERROR_UNIMPLEMENTED;
646 #endif
647
648   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_TS_REPLY);
649 }
650
651 static void
652 vl_api_ikev2_set_local_key_t_handler (vl_api_ikev2_set_local_key_t * mp)
653 {
654   vl_api_ikev2_set_local_key_reply_t *rmp;
655   int rv = 0;
656
657 #if WITH_LIBSSL > 0
658   vlib_main_t *vm = vlib_get_main ();
659   clib_error_t *error;
660
661   error = ikev2_set_local_key (vm, mp->key_file);
662   if (error)
663     {
664       ikev2_log_error ("%U", format_clib_error, error);
665       clib_error_free (error);
666       rv = VNET_API_ERROR_UNSPECIFIED;
667     }
668 #else
669   rv = VNET_API_ERROR_UNIMPLEMENTED;
670 #endif
671
672   REPLY_MACRO (VL_API_IKEV2_SET_LOCAL_KEY_REPLY);
673 }
674
675 static void
676 vl_api_ikev2_set_responder_t_handler (vl_api_ikev2_set_responder_t * mp)
677 {
678   vl_api_ikev2_set_responder_reply_t *rmp;
679   int rv = 0;
680
681 #if WITH_LIBSSL > 0
682   vlib_main_t *vm = vlib_get_main ();
683   clib_error_t *error;
684
685   u8 *tmp = format (0, "%s", mp->name);
686   ip_address_t ip;
687   ip_address_decode2 (&mp->responder.addr, &ip);
688   u32 sw_if_index = clib_net_to_host_u32 (mp->responder.sw_if_index);
689
690   error = ikev2_set_profile_responder (vm, tmp, sw_if_index, ip);
691   vec_free (tmp);
692   if (error)
693     {
694       ikev2_log_error ("%U", format_clib_error, error);
695       clib_error_free (error);
696       rv = VNET_API_ERROR_UNSPECIFIED;
697     }
698 #else
699   rv = VNET_API_ERROR_UNIMPLEMENTED;
700 #endif
701
702   REPLY_MACRO (VL_API_IKEV2_SET_RESPONDER_REPLY);
703 }
704
705 static void
706 vl_api_ikev2_set_ike_transforms_t_handler (vl_api_ikev2_set_ike_transforms_t *
707                                            mp)
708 {
709   vl_api_ikev2_set_ike_transforms_reply_t *rmp;
710   int rv = 0;
711
712 #if WITH_LIBSSL > 0
713   vlib_main_t *vm = vlib_get_main ();
714   clib_error_t *error;
715
716   u8 *tmp = format (0, "%s", mp->name);
717
718   error =
719     ikev2_set_profile_ike_transforms (vm, tmp, mp->tr.crypto_alg,
720                                       mp->tr.integ_alg,
721                                       mp->tr.dh_group,
722                                       ntohl (mp->tr.crypto_key_size));
723   vec_free (tmp);
724   if (error)
725     {
726       ikev2_log_error ("%U", format_clib_error, error);
727       clib_error_free (error);
728       rv = VNET_API_ERROR_UNSPECIFIED;
729     }
730 #else
731   rv = VNET_API_ERROR_UNIMPLEMENTED;
732 #endif
733
734   REPLY_MACRO (VL_API_IKEV2_SET_IKE_TRANSFORMS_REPLY);
735 }
736
737 static void
738 vl_api_ikev2_set_esp_transforms_t_handler (vl_api_ikev2_set_esp_transforms_t *
739                                            mp)
740 {
741   vl_api_ikev2_set_esp_transforms_reply_t *rmp;
742   int rv = 0;
743
744 #if WITH_LIBSSL > 0
745   vlib_main_t *vm = vlib_get_main ();
746   clib_error_t *error;
747
748   u8 *tmp = format (0, "%s", mp->name);
749
750   error =
751     ikev2_set_profile_esp_transforms (vm, tmp, mp->tr.crypto_alg,
752                                       mp->tr.integ_alg,
753                                       ntohl (mp->tr.crypto_key_size));
754   vec_free (tmp);
755   if (error)
756     {
757       ikev2_log_error ("%U", format_clib_error, error);
758       clib_error_free (error);
759       rv = VNET_API_ERROR_UNSPECIFIED;
760     }
761 #else
762   rv = VNET_API_ERROR_UNIMPLEMENTED;
763 #endif
764
765   REPLY_MACRO (VL_API_IKEV2_SET_ESP_TRANSFORMS_REPLY);
766 }
767
768 static void
769 vl_api_ikev2_set_sa_lifetime_t_handler (vl_api_ikev2_set_sa_lifetime_t * mp)
770 {
771   vl_api_ikev2_set_sa_lifetime_reply_t *rmp;
772   int rv = 0;
773
774 #if WITH_LIBSSL > 0
775   vlib_main_t *vm = vlib_get_main ();
776   clib_error_t *error;
777
778   u8 *tmp = format (0, "%s", mp->name);
779
780   error =
781     ikev2_set_profile_sa_lifetime (vm, tmp,
782                                    clib_net_to_host_u64 (mp->lifetime),
783                                    ntohl (mp->lifetime_jitter),
784                                    ntohl (mp->handover),
785                                    clib_net_to_host_u64
786                                    (mp->lifetime_maxdata));
787   vec_free (tmp);
788   if (error)
789     {
790       ikev2_log_error ("%U", format_clib_error, error);
791       clib_error_free (error);
792       rv = VNET_API_ERROR_UNSPECIFIED;
793     }
794 #else
795   rv = VNET_API_ERROR_UNIMPLEMENTED;
796 #endif
797
798   REPLY_MACRO (VL_API_IKEV2_SET_SA_LIFETIME_REPLY);
799 }
800
801 static void
802   vl_api_ikev2_profile_set_ipsec_udp_port_t_handler
803   (vl_api_ikev2_profile_set_ipsec_udp_port_t * mp)
804 {
805   vl_api_ikev2_profile_set_ipsec_udp_port_reply_t *rmp;
806   int rv = 0;
807
808 #if WITH_LIBSSL > 0
809   vlib_main_t *vm = vlib_get_main ();
810
811   u8 *tmp = format (0, "%s", mp->name);
812
813   rv =
814     ikev2_set_profile_ipsec_udp_port (vm, tmp,
815                                       clib_net_to_host_u16 (mp->port),
816                                       mp->is_set);
817   vec_free (tmp);
818 #else
819   rv = VNET_API_ERROR_UNIMPLEMENTED;
820 #endif
821
822   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_IPSEC_UDP_PORT_REPLY);
823 }
824
825 static void
826   vl_api_ikev2_set_tunnel_interface_t_handler
827   (vl_api_ikev2_set_tunnel_interface_t * mp)
828 {
829   vl_api_ikev2_set_tunnel_interface_reply_t *rmp;
830   int rv = 0;
831
832   VALIDATE_SW_IF_INDEX (mp);
833
834 #if WITH_LIBSSL > 0
835   u8 *tmp = format (0, "%s", mp->name);
836   clib_error_t *error;
837
838   error = ikev2_set_profile_tunnel_interface (vlib_get_main (), tmp,
839                                               ntohl (mp->sw_if_index));
840
841   if (error)
842     {
843       ikev2_log_error ("%U", format_clib_error, error);
844       clib_error_free (error);
845       rv = VNET_API_ERROR_UNSPECIFIED;
846     }
847   vec_free (tmp);
848 #else
849   rv = VNET_API_ERROR_UNIMPLEMENTED;
850 #endif
851
852   BAD_SW_IF_INDEX_LABEL;
853   REPLY_MACRO (VL_API_IKEV2_SET_TUNNEL_INTERFACE_REPLY);
854 }
855
856 static void
857 vl_api_ikev2_initiate_sa_init_t_handler (vl_api_ikev2_initiate_sa_init_t * mp)
858 {
859   vl_api_ikev2_initiate_sa_init_reply_t *rmp;
860   int rv = 0;
861
862 #if WITH_LIBSSL > 0
863   vlib_main_t *vm = vlib_get_main ();
864   clib_error_t *error;
865
866   u8 *tmp = format (0, "%s", mp->name);
867
868   error = ikev2_initiate_sa_init (vm, tmp);
869   vec_free (tmp);
870   if (error)
871     {
872       ikev2_log_error ("%U", format_clib_error, error);
873       clib_error_free (error);
874       rv = VNET_API_ERROR_UNSPECIFIED;
875     }
876 #else
877   rv = VNET_API_ERROR_UNIMPLEMENTED;
878 #endif
879
880   REPLY_MACRO (VL_API_IKEV2_INITIATE_SA_INIT_REPLY);
881 }
882
883 static void
884 vl_api_ikev2_initiate_del_ike_sa_t_handler (vl_api_ikev2_initiate_del_ike_sa_t
885                                             * mp)
886 {
887   vl_api_ikev2_initiate_del_ike_sa_reply_t *rmp;
888   int rv = 0;
889
890 #if WITH_LIBSSL > 0
891   vlib_main_t *vm = vlib_get_main ();
892   clib_error_t *error;
893
894   error = ikev2_initiate_delete_ike_sa (vm, mp->ispi);
895   if (error)
896     {
897       ikev2_log_error ("%U", format_clib_error, error);
898       clib_error_free (error);
899       rv = VNET_API_ERROR_UNSPECIFIED;
900     }
901 #else
902   rv = VNET_API_ERROR_UNIMPLEMENTED;
903 #endif
904
905   REPLY_MACRO (VL_API_IKEV2_INITIATE_DEL_IKE_SA_REPLY);
906 }
907
908 static void
909   vl_api_ikev2_initiate_del_child_sa_t_handler
910   (vl_api_ikev2_initiate_del_child_sa_t * mp)
911 {
912   vl_api_ikev2_initiate_del_child_sa_reply_t *rmp;
913   int rv = 0;
914
915 #if WITH_LIBSSL > 0
916   vlib_main_t *vm = vlib_get_main ();
917   clib_error_t *error;
918
919   error = ikev2_initiate_delete_child_sa (vm, mp->ispi);
920   if (error)
921     {
922       ikev2_log_error ("%U", format_clib_error, error);
923       clib_error_free (error);
924       rv = VNET_API_ERROR_UNSPECIFIED;
925     }
926 #else
927   rv = VNET_API_ERROR_UNIMPLEMENTED;
928 #endif
929
930   REPLY_MACRO (VL_API_IKEV2_INITIATE_DEL_CHILD_SA_REPLY);
931 }
932
933 static void
934   vl_api_ikev2_profile_disable_natt_t_handler
935   (vl_api_ikev2_profile_disable_natt_t * mp)
936 {
937   vl_api_ikev2_profile_disable_natt_reply_t *rmp;
938   int rv = 0;
939
940 #if WITH_LIBSSL > 0
941   clib_error_t *error;
942
943   u8 *tmp = format (0, "%s", mp->name);
944   error = ikev2_profile_natt_disable (tmp);
945   vec_free (tmp);
946   if (error)
947     {
948       ikev2_log_error ("%U", format_clib_error, error);
949       clib_error_free (error);
950       rv = VNET_API_ERROR_UNSPECIFIED;
951     }
952 #else
953   rv = VNET_API_ERROR_UNIMPLEMENTED;
954 #endif
955
956   REPLY_MACRO (VL_API_IKEV2_PROFILE_DISABLE_NATT_REPLY);
957 }
958
959 static void
960   vl_api_ikev2_initiate_rekey_child_sa_t_handler
961   (vl_api_ikev2_initiate_rekey_child_sa_t * mp)
962 {
963   vl_api_ikev2_initiate_rekey_child_sa_reply_t *rmp;
964   int rv = 0;
965
966 #if WITH_LIBSSL > 0
967   vlib_main_t *vm = vlib_get_main ();
968   clib_error_t *error;
969
970   error = ikev2_initiate_rekey_child_sa (vm, mp->ispi);
971   if (error)
972     {
973       ikev2_log_error ("%U", format_clib_error, error);
974       clib_error_free (error);
975       rv = VNET_API_ERROR_UNSPECIFIED;
976     }
977 #else
978   rv = VNET_API_ERROR_UNIMPLEMENTED;
979 #endif
980
981   REPLY_MACRO (VL_API_IKEV2_INITIATE_REKEY_CHILD_SA_REPLY);
982 }
983
984 #include <ikev2/ikev2.api.c>
985 static clib_error_t *
986 ikev2_api_init (vlib_main_t * vm)
987 {
988   ikev2_main_t *im = &ikev2_main;
989
990   /* Ask for a correctly-sized block of API message decode slots */
991   im->msg_id_base = setup_message_id_table ();
992
993   return 0;
994 }
995
996 VLIB_INIT_FUNCTION (ikev2_api_init);
997
998 /*
999  * fd.io coding-style-patch-verification: ON
1000  *
1001  * Local Variables:
1002  * eval: (c-set-style "gnu")
1003  * End:
1004  */