ikev2: add support for custom ipsec-over-udp port
[vpp.git] / src / plugins / ikev2 / ikev2_test.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-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 <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vppinfra/error.h>
24 #include <plugins/ikev2/ikev2.h>
25
26 #define __plugin_msg_base ikev2_test_main.msg_id_base
27 #include <vlibapi/vat_helper_macros.h>
28
29 /* Declare message IDs */
30 #include <vnet/format_fns.h>
31 #include <ikev2/ikev2.api_enum.h>
32 #include <ikev2/ikev2.api_types.h>
33
34 typedef struct
35 {
36   /* API message ID base */
37   u16 msg_id_base;
38   vat_main_t *vat_main;
39 } ikev2_test_main_t;
40
41 ikev2_test_main_t ikev2_test_main;
42
43 uword
44 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
45 {
46   u32 *r = va_arg (*args, u32 *);
47
48   if (0);
49 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
50   foreach_ikev2_auth_method
51 #undef _
52     else
53     return 0;
54   return 1;
55 }
56
57 uword
58 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
59 {
60   u32 *r = va_arg (*args, u32 *);
61
62   if (0);
63 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
64   foreach_ikev2_id_type
65 #undef _
66     else
67     return 0;
68   return 1;
69 }
70
71 static int
72 api_ikev2_plugin_get_version (vat_main_t * vam)
73 {
74   ikev2_test_main_t *sm = &ikev2_test_main;
75   vl_api_ikev2_plugin_get_version_t *mp;
76   u32 msg_size = sizeof (*mp);
77   int ret;
78
79   vam->result_ready = 0;
80   mp = vl_msg_api_alloc_as_if_client (msg_size);
81   clib_memset (mp, 0, msg_size);
82   mp->_vl_msg_id = ntohs (VL_API_IKEV2_PLUGIN_GET_VERSION + sm->msg_id_base);
83   mp->client_index = vam->my_client_index;
84
85   /* send it... */
86   S (mp);
87
88   /* Wait for a reply... */
89   W (ret);
90   return ret;
91 }
92
93 static void vl_api_ikev2_plugin_get_version_reply_t_handler
94   (vl_api_ikev2_plugin_get_version_reply_t * mp)
95 {
96   vat_main_t *vam = ikev2_test_main.vat_main;
97   clib_warning ("IKEv2 plugin version: %d.%d", ntohl (mp->major),
98                 ntohl (mp->minor));
99   vam->result_ready = 1;
100 }
101
102 static int
103 api_ikev2_profile_set_ipsec_udp_port (vat_main_t * vam)
104 {
105   return 0;
106 }
107
108 static int
109 api_ikev2_profile_add_del (vat_main_t * vam)
110 {
111   unformat_input_t *i = vam->input;
112   vl_api_ikev2_profile_add_del_t *mp;
113   u8 is_add = 1;
114   u8 *name = 0;
115   int ret;
116
117   const char *valid_chars = "a-zA-Z0-9_";
118
119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
120     {
121       if (unformat (i, "del"))
122         is_add = 0;
123       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
124         vec_add1 (name, 0);
125       else
126         {
127           errmsg ("parse error '%U'", format_unformat_error, i);
128           return -99;
129         }
130     }
131
132   if (!vec_len (name))
133     {
134       errmsg ("profile name must be specified");
135       return -99;
136     }
137
138   if (vec_len (name) > 64)
139     {
140       errmsg ("profile name too long");
141       return -99;
142     }
143
144   M (IKEV2_PROFILE_ADD_DEL, mp);
145
146   clib_memcpy (mp->name, name, vec_len (name));
147   mp->is_add = is_add;
148   vec_free (name);
149
150   S (mp);
151   W (ret);
152   return ret;
153 }
154
155 static int
156 api_ikev2_profile_set_auth (vat_main_t * vam)
157 {
158   unformat_input_t *i = vam->input;
159   vl_api_ikev2_profile_set_auth_t *mp;
160   u8 *name = 0;
161   u8 *data = 0;
162   u32 auth_method = 0;
163   u8 is_hex = 0;
164   int ret;
165
166   const char *valid_chars = "a-zA-Z0-9_";
167
168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
169     {
170       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
171         vec_add1 (name, 0);
172       else if (unformat (i, "auth_method %U",
173                          unformat_ikev2_auth_method, &auth_method))
174         ;
175       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
176         is_hex = 1;
177       else if (unformat (i, "auth_data %v", &data))
178         ;
179       else
180         {
181           errmsg ("parse error '%U'", format_unformat_error, i);
182           return -99;
183         }
184     }
185
186   if (!vec_len (name))
187     {
188       errmsg ("profile name must be specified");
189       return -99;
190     }
191
192   if (vec_len (name) > 64)
193     {
194       errmsg ("profile name too long");
195       return -99;
196     }
197
198   if (!vec_len (data))
199     {
200       errmsg ("auth_data must be specified");
201       return -99;
202     }
203
204   if (!auth_method)
205     {
206       errmsg ("auth_method must be specified");
207       return -99;
208     }
209
210   M (IKEV2_PROFILE_SET_AUTH, mp);
211
212   mp->is_hex = is_hex;
213   mp->auth_method = (u8) auth_method;
214   mp->data_len = vec_len (data);
215   clib_memcpy (mp->name, name, vec_len (name));
216   clib_memcpy (mp->data, data, vec_len (data));
217   vec_free (name);
218   vec_free (data);
219
220   S (mp);
221   W (ret);
222   return ret;
223 }
224
225 static int
226 api_ikev2_profile_set_id (vat_main_t * vam)
227 {
228   unformat_input_t *i = vam->input;
229   vl_api_ikev2_profile_set_id_t *mp;
230   u8 *name = 0;
231   u8 *data = 0;
232   u8 is_local = 0;
233   u32 id_type = 0;
234   ip4_address_t ip4;
235   int ret;
236
237   const char *valid_chars = "a-zA-Z0-9_";
238
239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
240     {
241       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
242         vec_add1 (name, 0);
243       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
244         ;
245       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
246         {
247           data = vec_new (u8, 4);
248           clib_memcpy (data, ip4.as_u8, 4);
249         }
250       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
251         ;
252       else if (unformat (i, "id_data %v", &data))
253         ;
254       else if (unformat (i, "local"))
255         is_local = 1;
256       else if (unformat (i, "remote"))
257         is_local = 0;
258       else
259         {
260           errmsg ("parse error '%U'", format_unformat_error, i);
261           return -99;
262         }
263     }
264
265   if (!vec_len (name))
266     {
267       errmsg ("profile name must be specified");
268       return -99;
269     }
270
271   if (vec_len (name) > 64)
272     {
273       errmsg ("profile name too long");
274       return -99;
275     }
276
277   if (!vec_len (data))
278     {
279       errmsg ("id_data must be specified");
280       return -99;
281     }
282
283   if (!id_type)
284     {
285       errmsg ("id_type must be specified");
286       return -99;
287     }
288
289   M (IKEV2_PROFILE_SET_ID, mp);
290
291   mp->is_local = is_local;
292   mp->id_type = (u8) id_type;
293   mp->data_len = vec_len (data);
294   clib_memcpy (mp->name, name, vec_len (name));
295   clib_memcpy (mp->data, data, vec_len (data));
296   vec_free (name);
297   vec_free (data);
298
299   S (mp);
300   W (ret);
301   return ret;
302 }
303
304 static int
305 api_ikev2_profile_set_ts (vat_main_t * vam)
306 {
307   unformat_input_t *i = vam->input;
308   vl_api_ikev2_profile_set_ts_t *mp;
309   u8 *name = 0;
310   u8 is_local = 0;
311   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
312   ip4_address_t start_addr, end_addr;
313
314   const char *valid_chars = "a-zA-Z0-9_";
315   int ret;
316
317   start_addr.as_u32 = 0;
318   end_addr.as_u32 = (u32) ~ 0;
319
320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
321     {
322       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
323         vec_add1 (name, 0);
324       else if (unformat (i, "protocol %d", &proto))
325         ;
326       else if (unformat (i, "start_port %d", &start_port))
327         ;
328       else if (unformat (i, "end_port %d", &end_port))
329         ;
330       else
331         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
332         ;
333       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
334         ;
335       else if (unformat (i, "local"))
336         is_local = 1;
337       else if (unformat (i, "remote"))
338         is_local = 0;
339       else
340         {
341           errmsg ("parse error '%U'", format_unformat_error, i);
342           return -99;
343         }
344     }
345
346   if (!vec_len (name))
347     {
348       errmsg ("profile name must be specified");
349       return -99;
350     }
351
352   if (vec_len (name) > 64)
353     {
354       errmsg ("profile name too long");
355       return -99;
356     }
357
358   M (IKEV2_PROFILE_SET_TS, mp);
359
360   mp->is_local = is_local;
361   mp->proto = (u8) proto;
362   mp->start_port = (u16) start_port;
363   mp->end_port = (u16) end_port;
364   mp->start_addr = start_addr.as_u32;
365   mp->end_addr = end_addr.as_u32;
366   clib_memcpy (mp->name, name, vec_len (name));
367   vec_free (name);
368
369   S (mp);
370   W (ret);
371   return ret;
372 }
373
374 static int
375 api_ikev2_set_local_key (vat_main_t * vam)
376 {
377   unformat_input_t *i = vam->input;
378   vl_api_ikev2_set_local_key_t *mp;
379   u8 *file = 0;
380   int ret;
381
382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
383     {
384       if (unformat (i, "file %v", &file))
385         vec_add1 (file, 0);
386       else
387         {
388           errmsg ("parse error '%U'", format_unformat_error, i);
389           return -99;
390         }
391     }
392
393   if (!vec_len (file))
394     {
395       errmsg ("RSA key file must be specified");
396       return -99;
397     }
398
399   if (vec_len (file) > 256)
400     {
401       errmsg ("file name too long");
402       return -99;
403     }
404
405   M (IKEV2_SET_LOCAL_KEY, mp);
406
407   clib_memcpy (mp->key_file, file, vec_len (file));
408   vec_free (file);
409
410   S (mp);
411   W (ret);
412   return ret;
413 }
414
415 static int
416 api_ikev2_profile_set_udp_encap (vat_main_t * vam)
417 {
418   unformat_input_t *i = vam->input;
419   vl_api_ikev2_set_responder_t *mp;
420   int ret;
421   u8 *name = 0;
422
423   const char *valid_chars = "a-zA-Z0-9_";
424
425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
426     {
427       if (unformat (i, "%U udp-encap", unformat_token, valid_chars, &name))
428         vec_add1 (name, 0);
429       else
430         {
431           errmsg ("parse error '%U'", format_unformat_error, i);
432           return -99;
433         }
434     }
435
436   if (!vec_len (name))
437     {
438       errmsg ("profile name must be specified");
439       return -99;
440     }
441
442   if (vec_len (name) > 64)
443     {
444       errmsg ("profile name too long");
445       return -99;
446     }
447
448   M (IKEV2_PROFILE_SET_UDP_ENCAP, mp);
449
450   clib_memcpy (mp->name, name, vec_len (name));
451   vec_free (name);
452
453   S (mp);
454   W (ret);
455   return ret;
456 }
457
458 static int
459 api_ikev2_set_tunnel_interface (vat_main_t * vam)
460 {
461   return (0);
462 }
463
464 static int
465 api_ikev2_set_responder (vat_main_t * vam)
466 {
467   unformat_input_t *i = vam->input;
468   vl_api_ikev2_set_responder_t *mp;
469   int ret;
470   u8 *name = 0;
471   u32 sw_if_index = ~0;
472   ip4_address_t address;
473
474   const char *valid_chars = "a-zA-Z0-9_";
475
476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
477     {
478       if (unformat
479           (i, "%U interface %d address %U", unformat_token, valid_chars,
480            &name, &sw_if_index, unformat_ip4_address, &address))
481         vec_add1 (name, 0);
482       else
483         {
484           errmsg ("parse error '%U'", format_unformat_error, i);
485           return -99;
486         }
487     }
488
489   if (!vec_len (name))
490     {
491       errmsg ("profile name must be specified");
492       return -99;
493     }
494
495   if (vec_len (name) > 64)
496     {
497       errmsg ("profile name too long");
498       return -99;
499     }
500
501   M (IKEV2_SET_RESPONDER, mp);
502
503   clib_memcpy (mp->name, name, vec_len (name));
504   vec_free (name);
505
506   mp->sw_if_index = sw_if_index;
507   clib_memcpy (mp->address, &address, sizeof (address));
508
509   S (mp);
510   W (ret);
511   return ret;
512 }
513
514 static int
515 api_ikev2_set_ike_transforms (vat_main_t * vam)
516 {
517   unformat_input_t *i = vam->input;
518   vl_api_ikev2_set_ike_transforms_t *mp;
519   int ret;
520   u8 *name = 0;
521   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
522
523   const char *valid_chars = "a-zA-Z0-9_";
524
525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
526     {
527       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
528                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
529         vec_add1 (name, 0);
530       else
531         {
532           errmsg ("parse error '%U'", format_unformat_error, i);
533           return -99;
534         }
535     }
536
537   if (!vec_len (name))
538     {
539       errmsg ("profile name must be specified");
540       return -99;
541     }
542
543   if (vec_len (name) > 64)
544     {
545       errmsg ("profile name too long");
546       return -99;
547     }
548
549   M (IKEV2_SET_IKE_TRANSFORMS, mp);
550
551   clib_memcpy (mp->name, name, vec_len (name));
552   vec_free (name);
553   mp->crypto_alg = crypto_alg;
554   mp->crypto_key_size = crypto_key_size;
555   mp->integ_alg = integ_alg;
556   mp->dh_group = dh_group;
557
558   S (mp);
559   W (ret);
560   return ret;
561 }
562
563
564 static int
565 api_ikev2_set_esp_transforms (vat_main_t * vam)
566 {
567   unformat_input_t *i = vam->input;
568   vl_api_ikev2_set_esp_transforms_t *mp;
569   int ret;
570   u8 *name = 0;
571   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
572
573   const char *valid_chars = "a-zA-Z0-9_";
574
575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
576     {
577       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
578                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
579         vec_add1 (name, 0);
580       else
581         {
582           errmsg ("parse error '%U'", format_unformat_error, i);
583           return -99;
584         }
585     }
586
587   if (!vec_len (name))
588     {
589       errmsg ("profile name must be specified");
590       return -99;
591     }
592
593   if (vec_len (name) > 64)
594     {
595       errmsg ("profile name too long");
596       return -99;
597     }
598
599   M (IKEV2_SET_ESP_TRANSFORMS, mp);
600
601   clib_memcpy (mp->name, name, vec_len (name));
602   vec_free (name);
603   mp->crypto_alg = crypto_alg;
604   mp->crypto_key_size = crypto_key_size;
605   mp->integ_alg = integ_alg;
606   mp->dh_group = dh_group;
607
608   S (mp);
609   W (ret);
610   return ret;
611 }
612
613 static int
614 api_ikev2_set_sa_lifetime (vat_main_t * vam)
615 {
616   unformat_input_t *i = vam->input;
617   vl_api_ikev2_set_sa_lifetime_t *mp;
618   int ret;
619   u8 *name = 0;
620   u64 lifetime, lifetime_maxdata;
621   u32 lifetime_jitter, handover;
622
623   const char *valid_chars = "a-zA-Z0-9_";
624
625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
626     {
627       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
628                     &lifetime, &lifetime_jitter, &handover,
629                     &lifetime_maxdata))
630         vec_add1 (name, 0);
631       else
632         {
633           errmsg ("parse error '%U'", format_unformat_error, i);
634           return -99;
635         }
636     }
637
638   if (!vec_len (name))
639     {
640       errmsg ("profile name must be specified");
641       return -99;
642     }
643
644   if (vec_len (name) > 64)
645     {
646       errmsg ("profile name too long");
647       return -99;
648     }
649
650   M (IKEV2_SET_SA_LIFETIME, mp);
651
652   clib_memcpy (mp->name, name, vec_len (name));
653   vec_free (name);
654   mp->lifetime = lifetime;
655   mp->lifetime_jitter = lifetime_jitter;
656   mp->handover = handover;
657   mp->lifetime_maxdata = lifetime_maxdata;
658
659   S (mp);
660   W (ret);
661   return ret;
662 }
663
664 static int
665 api_ikev2_initiate_sa_init (vat_main_t * vam)
666 {
667   unformat_input_t *i = vam->input;
668   vl_api_ikev2_initiate_sa_init_t *mp;
669   int ret;
670   u8 *name = 0;
671
672   const char *valid_chars = "a-zA-Z0-9_";
673
674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
675     {
676       if (unformat (i, "%U", unformat_token, valid_chars, &name))
677         vec_add1 (name, 0);
678       else
679         {
680           errmsg ("parse error '%U'", format_unformat_error, i);
681           return -99;
682         }
683     }
684
685   if (!vec_len (name))
686     {
687       errmsg ("profile name must be specified");
688       return -99;
689     }
690
691   if (vec_len (name) > 64)
692     {
693       errmsg ("profile name too long");
694       return -99;
695     }
696
697   M (IKEV2_INITIATE_SA_INIT, mp);
698
699   clib_memcpy (mp->name, name, vec_len (name));
700   vec_free (name);
701
702   S (mp);
703   W (ret);
704   return ret;
705 }
706
707 static int
708 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
709 {
710   unformat_input_t *i = vam->input;
711   vl_api_ikev2_initiate_del_ike_sa_t *mp;
712   int ret;
713   u64 ispi;
714
715
716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
717     {
718       if (unformat (i, "%lx", &ispi))
719         ;
720       else
721         {
722           errmsg ("parse error '%U'", format_unformat_error, i);
723           return -99;
724         }
725     }
726
727   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
728
729   mp->ispi = ispi;
730
731   S (mp);
732   W (ret);
733   return ret;
734 }
735
736 static int
737 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
738 {
739   unformat_input_t *i = vam->input;
740   vl_api_ikev2_initiate_del_child_sa_t *mp;
741   int ret;
742   u32 ispi;
743
744
745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
746     {
747       if (unformat (i, "%x", &ispi))
748         ;
749       else
750         {
751           errmsg ("parse error '%U'", format_unformat_error, i);
752           return -99;
753         }
754     }
755
756   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
757
758   mp->ispi = ispi;
759
760   S (mp);
761   W (ret);
762   return ret;
763 }
764
765 static int
766 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
767 {
768   unformat_input_t *i = vam->input;
769   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
770   int ret;
771   u32 ispi;
772
773
774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
775     {
776       if (unformat (i, "%x", &ispi))
777         ;
778       else
779         {
780           errmsg ("parse error '%U'", format_unformat_error, i);
781           return -99;
782         }
783     }
784
785   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
786
787   mp->ispi = ispi;
788
789   S (mp);
790   W (ret);
791   return ret;
792 }
793
794 #include <ikev2/ikev2.api_test.c>
795
796 /*
797  * fd.io coding-style-patch-verification: ON
798  *
799  * Local Variables:
800  * eval: (c-set-style "gnu")
801  * End:
802  */