ikev2: add support for custom ipsec-over-udp port
[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 extern ikev2_main_t ikev2_main;
34
35 #define IKEV2_PLUGIN_VERSION_MAJOR 1
36 #define IKEV2_PLUGIN_VERSION_MINOR 0
37 #define REPLY_MSG_ID_BASE ikev2_main.msg_id_base
38 #include <vlibapi/api_helper_macros.h>
39
40 static void
41 vl_api_ikev2_plugin_get_version_t_handler (vl_api_ikev2_plugin_get_version_t *
42                                            mp)
43 {
44   ikev2_main_t *im = &ikev2_main;
45   vl_api_ikev2_plugin_get_version_reply_t *rmp;
46   int msg_size = sizeof (*rmp);
47   vl_api_registration_t *reg;
48
49   reg = vl_api_client_index_to_registration (mp->client_index);
50   if (!reg)
51     return;
52
53   rmp = vl_msg_api_alloc (msg_size);
54   clib_memset (rmp, 0, msg_size);
55   rmp->_vl_msg_id =
56     ntohs (VL_API_IKEV2_PLUGIN_GET_VERSION_REPLY + im->msg_id_base);
57   rmp->context = mp->context;
58   rmp->major = htonl (IKEV2_PLUGIN_VERSION_MAJOR);
59   rmp->minor = htonl (IKEV2_PLUGIN_VERSION_MINOR);
60
61   vl_api_send_msg (reg, (u8 *) rmp);
62 }
63
64 static void
65 vl_api_ikev2_profile_add_del_t_handler (vl_api_ikev2_profile_add_del_t * mp)
66 {
67   vl_api_ikev2_profile_add_del_reply_t *rmp;
68   int rv = 0;
69
70 #if WITH_LIBSSL > 0
71   vlib_main_t *vm = vlib_get_main ();
72   clib_error_t *error;
73   u8 *tmp = format (0, "%s", mp->name);
74   error = ikev2_add_del_profile (vm, tmp, mp->is_add);
75   vec_free (tmp);
76   if (error)
77     rv = VNET_API_ERROR_UNSPECIFIED;
78 #else
79   rv = VNET_API_ERROR_UNIMPLEMENTED;
80 #endif
81
82   REPLY_MACRO (VL_API_IKEV2_PROFILE_ADD_DEL_REPLY);
83 }
84
85 static void
86   vl_api_ikev2_profile_set_auth_t_handler
87   (vl_api_ikev2_profile_set_auth_t * mp)
88 {
89   vl_api_ikev2_profile_set_auth_reply_t *rmp;
90   int rv = 0;
91
92 #if WITH_LIBSSL > 0
93   vlib_main_t *vm = vlib_get_main ();
94   clib_error_t *error;
95   int data_len = ntohl (mp->data_len);
96   u8 *tmp = format (0, "%s", mp->name);
97   u8 *data = vec_new (u8, data_len);
98   clib_memcpy (data, mp->data, data_len);
99   error = ikev2_set_profile_auth (vm, tmp, mp->auth_method, data, mp->is_hex);
100   vec_free (tmp);
101   vec_free (data);
102   if (error)
103     rv = VNET_API_ERROR_UNSPECIFIED;
104 #else
105   rv = VNET_API_ERROR_UNIMPLEMENTED;
106 #endif
107
108   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_AUTH_REPLY);
109 }
110
111 static void
112 vl_api_ikev2_profile_set_id_t_handler (vl_api_ikev2_profile_set_id_t * mp)
113 {
114   vl_api_ikev2_profile_set_id_reply_t *rmp;
115   int rv = 0;
116
117 #if WITH_LIBSSL > 0
118   vlib_main_t *vm = vlib_get_main ();
119   clib_error_t *error;
120   u8 *tmp = format (0, "%s", mp->name);
121   int data_len = ntohl (mp->data_len);
122   u8 *data = vec_new (u8, data_len);
123   clib_memcpy (data, mp->data, data_len);
124   error = ikev2_set_profile_id (vm, tmp, mp->id_type, data, mp->is_local);
125   vec_free (tmp);
126   vec_free (data);
127   if (error)
128     rv = VNET_API_ERROR_UNSPECIFIED;
129 #else
130   rv = VNET_API_ERROR_UNIMPLEMENTED;
131 #endif
132
133   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_ID_REPLY);
134 }
135
136 static void
137   vl_api_ikev2_profile_set_udp_encap_t_handler
138   (vl_api_ikev2_profile_set_udp_encap_t * mp)
139 {
140   vl_api_ikev2_profile_set_udp_encap_reply_t *rmp;
141   int rv = 0;
142
143 #if WITH_LIBSSL > 0
144   vlib_main_t *vm = vlib_get_main ();
145   clib_error_t *error;
146   u8 *tmp = format (0, "%s", mp->name);
147   error = ikev2_set_profile_udp_encap (vm, tmp);
148   vec_free (tmp);
149   if (error)
150     rv = VNET_API_ERROR_UNSPECIFIED;
151 #else
152   rv = VNET_API_ERROR_UNIMPLEMENTED;
153 #endif
154
155   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_UDP_ENCAP);
156 }
157
158 static void
159 vl_api_ikev2_profile_set_ts_t_handler (vl_api_ikev2_profile_set_ts_t * mp)
160 {
161   vl_api_ikev2_profile_set_ts_reply_t *rmp;
162   int rv = 0;
163
164 #if WITH_LIBSSL > 0
165   vlib_main_t *vm = vlib_get_main ();
166   clib_error_t *error;
167   u8 *tmp = format (0, "%s", mp->name);
168   error =
169     ikev2_set_profile_ts (vm, tmp, mp->proto,
170                           clib_net_to_host_u16 (mp->start_port),
171                           clib_net_to_host_u16 (mp->end_port),
172                           (ip4_address_t) mp->start_addr,
173                           (ip4_address_t) mp->end_addr, mp->is_local);
174   vec_free (tmp);
175   if (error)
176     rv = VNET_API_ERROR_UNSPECIFIED;
177 #else
178   rv = VNET_API_ERROR_UNIMPLEMENTED;
179 #endif
180
181   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_TS_REPLY);
182 }
183
184 static void
185 vl_api_ikev2_set_local_key_t_handler (vl_api_ikev2_set_local_key_t * mp)
186 {
187   vl_api_ikev2_set_local_key_reply_t *rmp;
188   int rv = 0;
189
190 #if WITH_LIBSSL > 0
191   vlib_main_t *vm = vlib_get_main ();
192   clib_error_t *error;
193
194   error = ikev2_set_local_key (vm, mp->key_file);
195   if (error)
196     rv = VNET_API_ERROR_UNSPECIFIED;
197 #else
198   rv = VNET_API_ERROR_UNIMPLEMENTED;
199 #endif
200
201   REPLY_MACRO (VL_API_IKEV2_SET_LOCAL_KEY_REPLY);
202 }
203
204 static void
205 vl_api_ikev2_set_responder_t_handler (vl_api_ikev2_set_responder_t * mp)
206 {
207   vl_api_ikev2_set_responder_reply_t *rmp;
208   int rv = 0;
209
210 #if WITH_LIBSSL > 0
211   vlib_main_t *vm = vlib_get_main ();
212   clib_error_t *error;
213
214   u8 *tmp = format (0, "%s", mp->name);
215   ip4_address_t ip4;
216   clib_memcpy (&ip4, mp->address, sizeof (ip4));
217
218   error = ikev2_set_profile_responder (vm, tmp, ntohl (mp->sw_if_index), ip4);
219   vec_free (tmp);
220   if (error)
221     rv = VNET_API_ERROR_UNSPECIFIED;
222 #else
223   rv = VNET_API_ERROR_UNIMPLEMENTED;
224 #endif
225
226   REPLY_MACRO (VL_API_IKEV2_SET_RESPONDER_REPLY);
227 }
228
229 static void
230 vl_api_ikev2_set_ike_transforms_t_handler (vl_api_ikev2_set_ike_transforms_t *
231                                            mp)
232 {
233   vl_api_ikev2_set_ike_transforms_reply_t *rmp;
234   int rv = 0;
235
236 #if WITH_LIBSSL > 0
237   vlib_main_t *vm = vlib_get_main ();
238   clib_error_t *error;
239
240   u8 *tmp = format (0, "%s", mp->name);
241
242   error =
243     ikev2_set_profile_ike_transforms (vm, tmp, ntohl (mp->crypto_alg),
244                                       ntohl (mp->integ_alg),
245                                       ntohl (mp->dh_group),
246                                       ntohl (mp->crypto_key_size));
247   vec_free (tmp);
248   if (error)
249     rv = VNET_API_ERROR_UNSPECIFIED;
250 #else
251   rv = VNET_API_ERROR_UNIMPLEMENTED;
252 #endif
253
254   REPLY_MACRO (VL_API_IKEV2_SET_IKE_TRANSFORMS_REPLY);
255 }
256
257 static void
258 vl_api_ikev2_set_esp_transforms_t_handler (vl_api_ikev2_set_esp_transforms_t *
259                                            mp)
260 {
261   vl_api_ikev2_set_esp_transforms_reply_t *rmp;
262   int rv = 0;
263
264 #if WITH_LIBSSL > 0
265   vlib_main_t *vm = vlib_get_main ();
266   clib_error_t *error;
267
268   u8 *tmp = format (0, "%s", mp->name);
269
270   error =
271     ikev2_set_profile_esp_transforms (vm, tmp, ntohl (mp->crypto_alg),
272                                       ntohl (mp->integ_alg),
273                                       ntohl (mp->dh_group),
274                                       ntohl (mp->crypto_key_size));
275   vec_free (tmp);
276   if (error)
277     rv = VNET_API_ERROR_UNSPECIFIED;
278 #else
279   rv = VNET_API_ERROR_UNIMPLEMENTED;
280 #endif
281
282   REPLY_MACRO (VL_API_IKEV2_SET_ESP_TRANSFORMS_REPLY);
283 }
284
285 static void
286 vl_api_ikev2_set_sa_lifetime_t_handler (vl_api_ikev2_set_sa_lifetime_t * mp)
287 {
288   vl_api_ikev2_set_sa_lifetime_reply_t *rmp;
289   int rv = 0;
290
291 #if WITH_LIBSSL > 0
292   vlib_main_t *vm = vlib_get_main ();
293   clib_error_t *error;
294
295   u8 *tmp = format (0, "%s", mp->name);
296
297   error =
298     ikev2_set_profile_sa_lifetime (vm, tmp,
299                                    clib_net_to_host_u64 (mp->lifetime),
300                                    ntohl (mp->lifetime_jitter),
301                                    ntohl (mp->handover),
302                                    clib_net_to_host_u64
303                                    (mp->lifetime_maxdata));
304   vec_free (tmp);
305   if (error)
306     rv = VNET_API_ERROR_UNSPECIFIED;
307 #else
308   rv = VNET_API_ERROR_UNIMPLEMENTED;
309 #endif
310
311   REPLY_MACRO (VL_API_IKEV2_SET_SA_LIFETIME_REPLY);
312 }
313
314 static void
315   vl_api_ikev2_profile_set_ipsec_udp_port_t_handler
316   (vl_api_ikev2_profile_set_ipsec_udp_port_t * mp)
317 {
318   vl_api_ikev2_profile_set_ipsec_udp_port_reply_t *rmp;
319   int rv = 0;
320
321 #if WITH_LIBSSL > 0
322   vlib_main_t *vm = vlib_get_main ();
323
324   u8 *tmp = format (0, "%s", mp->name);
325
326   rv =
327     ikev2_set_profile_ipsec_udp_port (vm, tmp,
328                                       clib_net_to_host_u16 (mp->port),
329                                       mp->is_set);
330   vec_free (tmp);
331 #else
332   rv = VNET_API_ERROR_UNIMPLEMENTED;
333 #endif
334
335   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_IPSEC_UDP_PORT_REPLY);
336 }
337
338 static void
339   vl_api_ikev2_set_tunnel_interface_t_handler
340   (vl_api_ikev2_set_tunnel_interface_t * mp)
341 {
342   vl_api_ikev2_set_tunnel_interface_reply_t *rmp;
343   int rv = 0;
344
345   VALIDATE_SW_IF_INDEX (mp);
346
347 #if WITH_LIBSSL > 0
348   u8 *tmp = format (0, "%s", mp->name);
349   clib_error_t *error;
350
351   error = ikev2_set_profile_tunnel_interface (vlib_get_main (), tmp,
352                                               ntohl (mp->sw_if_index));
353
354   if (error)
355     rv = VNET_API_ERROR_UNSPECIFIED;
356   vec_free (tmp);
357 #else
358   rv = VNET_API_ERROR_UNIMPLEMENTED;
359 #endif
360
361   BAD_SW_IF_INDEX_LABEL;
362   REPLY_MACRO (VL_API_IKEV2_SET_TUNNEL_INTERFACE_REPLY);
363 }
364
365 static void
366 vl_api_ikev2_initiate_sa_init_t_handler (vl_api_ikev2_initiate_sa_init_t * mp)
367 {
368   vl_api_ikev2_initiate_sa_init_reply_t *rmp;
369   int rv = 0;
370
371 #if WITH_LIBSSL > 0
372   vlib_main_t *vm = vlib_get_main ();
373   clib_error_t *error;
374
375   u8 *tmp = format (0, "%s", mp->name);
376
377   error = ikev2_initiate_sa_init (vm, tmp);
378   vec_free (tmp);
379   if (error)
380     rv = VNET_API_ERROR_UNSPECIFIED;
381 #else
382   rv = VNET_API_ERROR_UNIMPLEMENTED;
383 #endif
384
385   REPLY_MACRO (VL_API_IKEV2_INITIATE_SA_INIT_REPLY);
386 }
387
388 static void
389 vl_api_ikev2_initiate_del_ike_sa_t_handler (vl_api_ikev2_initiate_del_ike_sa_t
390                                             * mp)
391 {
392   vl_api_ikev2_initiate_del_ike_sa_reply_t *rmp;
393   int rv = 0;
394
395 #if WITH_LIBSSL > 0
396   vlib_main_t *vm = vlib_get_main ();
397   clib_error_t *error;
398
399   error = ikev2_initiate_delete_ike_sa (vm, mp->ispi);
400   if (error)
401     rv = VNET_API_ERROR_UNSPECIFIED;
402 #else
403   rv = VNET_API_ERROR_UNIMPLEMENTED;
404 #endif
405
406   REPLY_MACRO (VL_API_IKEV2_INITIATE_DEL_IKE_SA_REPLY);
407 }
408
409 static void
410   vl_api_ikev2_initiate_del_child_sa_t_handler
411   (vl_api_ikev2_initiate_del_child_sa_t * mp)
412 {
413   vl_api_ikev2_initiate_del_child_sa_reply_t *rmp;
414   int rv = 0;
415
416 #if WITH_LIBSSL > 0
417   vlib_main_t *vm = vlib_get_main ();
418   clib_error_t *error;
419
420   error = ikev2_initiate_delete_child_sa (vm, mp->ispi);
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_INITIATE_DEL_CHILD_SA_REPLY);
428 }
429
430 static void
431   vl_api_ikev2_initiate_rekey_child_sa_t_handler
432   (vl_api_ikev2_initiate_rekey_child_sa_t * mp)
433 {
434   vl_api_ikev2_initiate_rekey_child_sa_reply_t *rmp;
435   int rv = 0;
436
437 #if WITH_LIBSSL > 0
438   vlib_main_t *vm = vlib_get_main ();
439   clib_error_t *error;
440
441   error = ikev2_initiate_rekey_child_sa (vm, mp->ispi);
442   if (error)
443     rv = VNET_API_ERROR_UNSPECIFIED;
444 #else
445   rv = VNET_API_ERROR_UNIMPLEMENTED;
446 #endif
447
448   REPLY_MACRO (VL_API_IKEV2_INITIATE_REKEY_CHILD_SA_REPLY);
449 }
450
451 #include <ikev2/ikev2.api.c>
452 static clib_error_t *
453 ikev2_api_init (vlib_main_t * vm)
454 {
455   ikev2_main_t *im = &ikev2_main;
456
457   /* Ask for a correctly-sized block of API message decode slots */
458   im->msg_id_base = setup_message_id_table ();
459
460   return 0;
461 }
462
463 VLIB_INIT_FUNCTION (ikev2_api_init);
464
465 /*
466  * fd.io coding-style-patch-verification: ON
467  *
468  * Local Variables:
469  * eval: (c-set-style "gnu")
470  * End:
471  */