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