ikev2: add profile dump API
[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 <vnet/ipsec/ipsec_sa.h>
25 #include <plugins/ikev2/ikev2.h>
26
27 #define __plugin_msg_base ikev2_test_main.msg_id_base
28 #include <vlibapi/vat_helper_macros.h>
29
30 /* Declare message IDs */
31 #include <vnet/format_fns.h>
32 #include <ikev2/ikev2.api_enum.h>
33 #include <ikev2/ikev2.api_types.h>
34 #include <vpp/api/vpe.api_types.h>
35
36 typedef struct
37 {
38   /* API message ID base */
39   u16 msg_id_base;
40   u32 ping_id;
41   vat_main_t *vat_main;
42 } ikev2_test_main_t;
43
44 ikev2_test_main_t ikev2_test_main;
45
46 uword
47 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
48 {
49   u32 *r = va_arg (*args, u32 *);
50
51   if (0);
52 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
53   foreach_ikev2_auth_method
54 #undef _
55     else
56     return 0;
57   return 1;
58 }
59
60
61 uword
62 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
63 {
64   u32 *r = va_arg (*args, u32 *);
65
66   if (0);
67 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
68   foreach_ikev2_id_type
69 #undef _
70     else
71     return 0;
72   return 1;
73 }
74
75 #define MACRO_FORMAT(lc)                                \
76 u8 * format_ikev2_##lc (u8 * s, va_list * args)         \
77 {                                                       \
78   u32 i = va_arg (*args, u32);                          \
79   char * t = 0;                                         \
80   switch (i) {                                          \
81         foreach_ikev2_##lc                              \
82       default:                                          \
83         return format (s, "unknown (%u)", i);           \
84     }                                                   \
85   s = format (s, "%s", t);                              \
86   return s;                                             \
87 }
88
89 #define _(v,f,str) case IKEV2_AUTH_METHOD_##f: t = str; break;
90 MACRO_FORMAT (auth_method)
91 #undef _
92 #define _(v,f,str) case IKEV2_ID_TYPE_##f: t = str; break;
93   MACRO_FORMAT (id_type)
94 #undef _
95 #define _(v,f,str) case IKEV2_TRANSFORM_ENCR_TYPE_##f: t = str; break;
96   MACRO_FORMAT (transform_encr_type)
97 #undef _
98 #define _(v,f,str) case IKEV2_TRANSFORM_INTEG_TYPE_##f: t = str; break;
99   MACRO_FORMAT (transform_integ_type)
100 #undef _
101 #define _(v,f,str) case IKEV2_TRANSFORM_DH_TYPE_##f: t = str; break;
102   MACRO_FORMAT (transform_dh_type)
103 #undef _
104      u8 *format_ikev2_id_type_and_data (u8 * s, va_list * args)
105 {
106   vl_api_ikev2_id_t *id = va_arg (*args, vl_api_ikev2_id_t *);
107
108   if (id->type == 0)
109     return format (s, "none");
110
111   s = format (s, "%U", format_ikev2_id_type, id->type);
112
113   switch (id->type)
114     {
115     case 0:
116       return format (s, "none");
117     case IKEV2_ID_TYPE_ID_FQDN:
118       s = format (s, " %s", id->data);
119       break;
120     case IKEV2_ID_TYPE_ID_RFC822_ADDR:
121       s = format (s, " %s", id->data);
122       break;
123     case IKEV2_ID_TYPE_ID_IPV4_ADDR:
124       s = format (s, " %U", format_ip4_address, id->data);
125       break;
126     case IKEV2_ID_TYPE_ID_KEY_ID:
127       s = format (s, " 0x%U", format_hex_bytes, id->data, id->data_len);
128       break;
129     default:
130       s = format (s, " %s", id->data);
131     }
132
133   return s;
134 }
135
136 static int
137 api_ikev2_profile_dump (vat_main_t * vam)
138 {
139   ikev2_test_main_t *ik = &ikev2_test_main;
140   vl_api_ikev2_profile_dump_t *mp;
141   vl_api_control_ping_t *mp_ping;
142   int ret;
143
144   /* Construct the API message */
145   M (IKEV2_PROFILE_DUMP, mp);
146
147   /* send it... */
148   S (mp);
149
150   /* Use a control ping for synchronization */
151   if (!ik->ping_id)
152     ik->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
153   mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
154   mp_ping->_vl_msg_id = htons (ik->ping_id);
155   mp_ping->client_index = vam->my_client_index;
156
157   fformat (vam->ofp, "Sending ping id=%d\n", ik->ping_id);
158
159   vam->result_ready = 0;
160   S (mp_ping);
161
162   /* Wait for a reply... */
163   W (ret);
164   return ret;
165 }
166
167 static void vl_api_ikev2_profile_details_t_handler
168   (vl_api_ikev2_profile_details_t * mp)
169 {
170   vat_main_t *vam = ikev2_test_main.vat_main;
171   vl_api_ikev2_profile_t *p = &mp->profile;
172
173   fformat (vam->ofp, "profile %s\n", p->name);
174
175   if (p->auth.method)
176     {
177       if (p->auth.hex)
178         fformat (vam->ofp, "  auth-method %U auth data 0x%U\n",
179                  format_ikev2_auth_method, p->auth.method,
180                  format_hex_bytes, p->auth.data,
181                  clib_net_to_host_u32 (p->auth.data_len));
182       else
183         fformat (vam->ofp, "  auth-method %U auth data %v\n",
184                  format_ikev2_auth_method, p->auth.method, format (0,
185                                                                    "%s",
186                                                                    p->
187                                                                    auth.data));
188     }
189
190   if (p->loc_id.type)
191     {
192       fformat (vam->ofp, "  local id-type data %U\n",
193                format_ikev2_id_type_and_data, &p->loc_id);
194     }
195
196   if (p->rem_id.type)
197     {
198       fformat (vam->ofp, "  remote id-type data %U\n",
199                format_ikev2_id_type_and_data, &p->rem_id);
200     }
201
202   if (*((u32 *) & p->loc_ts.end_addr))
203     fformat (vam->ofp, "  local traffic-selector addr %U - %U port %u - %u"
204              " protocol %u\n",
205              format_ip4_address, &p->loc_ts.start_addr,
206              format_ip4_address, &p->loc_ts.end_addr,
207              clib_net_to_host_u16 (p->loc_ts.start_port),
208              clib_net_to_host_u16 (p->loc_ts.end_port),
209              p->loc_ts.protocol_id);
210
211   if (*((u32 *) & p->rem_ts.end_addr))
212     fformat (vam->ofp, "  remote traffic-selector addr %U - %U port %u - %u"
213              " protocol %u\n",
214              format_ip4_address, &p->rem_ts.start_addr,
215              format_ip4_address, &p->rem_ts.end_addr,
216              clib_net_to_host_u16 (p->rem_ts.start_port),
217              clib_net_to_host_u16 (p->rem_ts.end_port),
218              p->rem_ts.protocol_id);
219   u32 tun_itf = clib_net_to_host_u32 (p->tun_itf);
220   if (~0 != tun_itf)
221     fformat (vam->ofp, "  protected tunnel idx %d\n", tun_itf);
222
223   u32 sw_if_index = clib_net_to_host_u32 (p->responder.sw_if_index);
224   if (~0 != sw_if_index)
225     fformat (vam->ofp, "  responder idx %d %U\n",
226              sw_if_index, format_ip4_address, &p->responder.ip4);
227
228   if (p->udp_encap)
229     fformat (vam->ofp, "  udp-encap\n");
230
231   u32 ipsec_over_udp_port = clib_net_to_host_u16 (p->ipsec_over_udp_port);
232   if (ipsec_over_udp_port != IPSEC_UDP_PORT_NONE)
233     fformat (vam->ofp, "  ipsec-over-udp port %d\n", ipsec_over_udp_port);
234
235   u32 crypto_key_size = clib_net_to_host_u32 (p->ike_ts.crypto_key_size);
236   if (p->ike_ts.crypto_alg || p->ike_ts.integ_alg || p->ike_ts.dh_type
237       || crypto_key_size)
238     fformat (vam->ofp, "  ike-crypto-alg %U %u ike-integ-alg %U ike-dh %U\n",
239              format_ikev2_transform_encr_type, p->ike_ts.crypto_alg,
240              crypto_key_size, format_ikev2_transform_integ_type,
241              p->ike_ts.integ_alg, format_ikev2_transform_dh_type,
242              p->ike_ts.dh_type);
243
244   crypto_key_size = clib_net_to_host_u32 (p->esp_ts.crypto_key_size);
245   if (p->esp_ts.crypto_alg || p->esp_ts.integ_alg || p->esp_ts.dh_type)
246     fformat (vam->ofp, "  esp-crypto-alg %U %u esp-integ-alg %U\n",
247              format_ikev2_transform_encr_type, p->esp_ts.crypto_alg,
248              crypto_key_size,
249              format_ikev2_transform_integ_type, p->esp_ts.integ_alg);
250
251   fformat (vam->ofp, "  lifetime %d jitter %d handover %d maxdata %d\n",
252            clib_net_to_host_u64 (p->lifetime),
253            clib_net_to_host_u32 (p->lifetime_jitter),
254            clib_net_to_host_u32 (p->handover),
255            clib_net_to_host_u64 (p->lifetime_maxdata));
256
257   vam->result_ready = 1;
258 }
259
260 static int
261 api_ikev2_plugin_get_version (vat_main_t * vam)
262 {
263   ikev2_test_main_t *sm = &ikev2_test_main;
264   vl_api_ikev2_plugin_get_version_t *mp;
265   u32 msg_size = sizeof (*mp);
266   int ret;
267
268   vam->result_ready = 0;
269   mp = vl_msg_api_alloc_as_if_client (msg_size);
270   clib_memset (mp, 0, msg_size);
271   mp->_vl_msg_id = ntohs (VL_API_IKEV2_PLUGIN_GET_VERSION + sm->msg_id_base);
272   mp->client_index = vam->my_client_index;
273
274   /* send it... */
275   S (mp);
276
277   /* Wait for a reply... */
278   W (ret);
279   return ret;
280 }
281
282 static void vl_api_ikev2_plugin_get_version_reply_t_handler
283   (vl_api_ikev2_plugin_get_version_reply_t * mp)
284 {
285   vat_main_t *vam = ikev2_test_main.vat_main;
286   clib_warning ("IKEv2 plugin version: %d.%d", ntohl (mp->major),
287                 ntohl (mp->minor));
288   vam->result_ready = 1;
289 }
290
291 static int
292 api_ikev2_profile_set_ipsec_udp_port (vat_main_t * vam)
293 {
294   return 0;
295 }
296
297 static int
298 api_ikev2_profile_set_liveness (vat_main_t * vam)
299 {
300   unformat_input_t *i = vam->input;
301   vl_api_ikev2_profile_set_liveness_t *mp;
302   u32 period = 0, max_retries = 0;
303   int ret;
304
305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
306     {
307       if (!unformat (i, "period %d max-retries %d", &period, &max_retries))
308         {
309           errmsg ("parse error '%U'", format_unformat_error, i);
310           return -99;
311         }
312     }
313
314   M (IKEV2_PROFILE_SET_LIVENESS, mp);
315
316   mp->period = clib_host_to_net_u32 (period);
317   mp->max_retries = clib_host_to_net_u32 (max_retries);
318
319   S (mp);
320   W (ret);
321
322   return ret;
323 }
324
325 static int
326 api_ikev2_profile_add_del (vat_main_t * vam)
327 {
328   unformat_input_t *i = vam->input;
329   vl_api_ikev2_profile_add_del_t *mp;
330   u8 is_add = 1;
331   u8 *name = 0;
332   int ret;
333
334   const char *valid_chars = "a-zA-Z0-9_";
335
336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
337     {
338       if (unformat (i, "del"))
339         is_add = 0;
340       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
341         vec_add1 (name, 0);
342       else
343         {
344           errmsg ("parse error '%U'", format_unformat_error, i);
345           return -99;
346         }
347     }
348
349   if (!vec_len (name))
350     {
351       errmsg ("profile name must be specified");
352       return -99;
353     }
354
355   if (vec_len (name) > 64)
356     {
357       errmsg ("profile name too long");
358       return -99;
359     }
360
361   M (IKEV2_PROFILE_ADD_DEL, mp);
362
363   clib_memcpy (mp->name, name, vec_len (name));
364   mp->is_add = is_add;
365   vec_free (name);
366
367   S (mp);
368   W (ret);
369   return ret;
370 }
371
372 static int
373 api_ikev2_profile_set_auth (vat_main_t * vam)
374 {
375   unformat_input_t *i = vam->input;
376   vl_api_ikev2_profile_set_auth_t *mp;
377   u8 *name = 0;
378   u8 *data = 0;
379   u32 auth_method = 0;
380   u8 is_hex = 0;
381   int ret;
382
383   const char *valid_chars = "a-zA-Z0-9_";
384
385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
386     {
387       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
388         vec_add1 (name, 0);
389       else if (unformat (i, "auth_method %U",
390                          unformat_ikev2_auth_method, &auth_method))
391         ;
392       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
393         is_hex = 1;
394       else if (unformat (i, "auth_data %v", &data))
395         ;
396       else
397         {
398           errmsg ("parse error '%U'", format_unformat_error, i);
399           return -99;
400         }
401     }
402
403   if (!vec_len (name))
404     {
405       errmsg ("profile name must be specified");
406       return -99;
407     }
408
409   if (vec_len (name) > 64)
410     {
411       errmsg ("profile name too long");
412       return -99;
413     }
414
415   if (!vec_len (data))
416     {
417       errmsg ("auth_data must be specified");
418       return -99;
419     }
420
421   if (!auth_method)
422     {
423       errmsg ("auth_method must be specified");
424       return -99;
425     }
426
427   M (IKEV2_PROFILE_SET_AUTH, mp);
428
429   mp->is_hex = is_hex;
430   mp->auth_method = (u8) auth_method;
431   mp->data_len = vec_len (data);
432   clib_memcpy (mp->name, name, vec_len (name));
433   clib_memcpy (mp->data, data, vec_len (data));
434   vec_free (name);
435   vec_free (data);
436
437   S (mp);
438   W (ret);
439   return ret;
440 }
441
442 static int
443 api_ikev2_profile_set_id (vat_main_t * vam)
444 {
445   unformat_input_t *i = vam->input;
446   vl_api_ikev2_profile_set_id_t *mp;
447   u8 *name = 0;
448   u8 *data = 0;
449   u8 is_local = 0;
450   u32 id_type = 0;
451   ip4_address_t ip4;
452   int ret;
453
454   const char *valid_chars = "a-zA-Z0-9_";
455
456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
457     {
458       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
459         vec_add1 (name, 0);
460       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
461         ;
462       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
463         {
464           data = vec_new (u8, 4);
465           clib_memcpy (data, ip4.as_u8, 4);
466         }
467       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
468         ;
469       else if (unformat (i, "id_data %v", &data))
470         ;
471       else if (unformat (i, "local"))
472         is_local = 1;
473       else if (unformat (i, "remote"))
474         is_local = 0;
475       else
476         {
477           errmsg ("parse error '%U'", format_unformat_error, i);
478           return -99;
479         }
480     }
481
482   if (!vec_len (name))
483     {
484       errmsg ("profile name must be specified");
485       return -99;
486     }
487
488   if (vec_len (name) > 64)
489     {
490       errmsg ("profile name too long");
491       return -99;
492     }
493
494   if (!vec_len (data))
495     {
496       errmsg ("id_data must be specified");
497       return -99;
498     }
499
500   if (!id_type)
501     {
502       errmsg ("id_type must be specified");
503       return -99;
504     }
505
506   M (IKEV2_PROFILE_SET_ID, mp);
507
508   mp->is_local = is_local;
509   mp->id_type = (u8) id_type;
510   mp->data_len = vec_len (data);
511   clib_memcpy (mp->name, name, vec_len (name));
512   clib_memcpy (mp->data, data, vec_len (data));
513   vec_free (name);
514   vec_free (data);
515
516   S (mp);
517   W (ret);
518   return ret;
519 }
520
521 static int
522 api_ikev2_profile_set_ts (vat_main_t * vam)
523 {
524   unformat_input_t *i = vam->input;
525   vl_api_ikev2_profile_set_ts_t *mp;
526   u8 *name = 0;
527   u8 is_local = 0;
528   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
529   ip4_address_t start_addr, end_addr;
530
531   const char *valid_chars = "a-zA-Z0-9_";
532   int ret;
533
534   start_addr.as_u32 = 0;
535   end_addr.as_u32 = (u32) ~ 0;
536
537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
538     {
539       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
540         vec_add1 (name, 0);
541       else if (unformat (i, "protocol %d", &proto))
542         ;
543       else if (unformat (i, "start_port %d", &start_port))
544         ;
545       else if (unformat (i, "end_port %d", &end_port))
546         ;
547       else
548         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
549         ;
550       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
551         ;
552       else if (unformat (i, "local"))
553         is_local = 1;
554       else if (unformat (i, "remote"))
555         is_local = 0;
556       else
557         {
558           errmsg ("parse error '%U'", format_unformat_error, i);
559           return -99;
560         }
561     }
562
563   if (!vec_len (name))
564     {
565       errmsg ("profile name must be specified");
566       return -99;
567     }
568
569   if (vec_len (name) > 64)
570     {
571       errmsg ("profile name too long");
572       return -99;
573     }
574
575   M (IKEV2_PROFILE_SET_TS, mp);
576
577   mp->is_local = is_local;
578   mp->proto = (u8) proto;
579   mp->start_port = (u16) start_port;
580   mp->end_port = (u16) end_port;
581   mp->start_addr = start_addr.as_u32;
582   mp->end_addr = end_addr.as_u32;
583   clib_memcpy (mp->name, name, vec_len (name));
584   vec_free (name);
585
586   S (mp);
587   W (ret);
588   return ret;
589 }
590
591 static int
592 api_ikev2_set_local_key (vat_main_t * vam)
593 {
594   unformat_input_t *i = vam->input;
595   vl_api_ikev2_set_local_key_t *mp;
596   u8 *file = 0;
597   int ret;
598
599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
600     {
601       if (unformat (i, "file %v", &file))
602         vec_add1 (file, 0);
603       else
604         {
605           errmsg ("parse error '%U'", format_unformat_error, i);
606           return -99;
607         }
608     }
609
610   if (!vec_len (file))
611     {
612       errmsg ("RSA key file must be specified");
613       return -99;
614     }
615
616   if (vec_len (file) > 256)
617     {
618       errmsg ("file name too long");
619       return -99;
620     }
621
622   M (IKEV2_SET_LOCAL_KEY, mp);
623
624   clib_memcpy (mp->key_file, file, vec_len (file));
625   vec_free (file);
626
627   S (mp);
628   W (ret);
629   return ret;
630 }
631
632 static int
633 api_ikev2_profile_set_udp_encap (vat_main_t * vam)
634 {
635   unformat_input_t *i = vam->input;
636   vl_api_ikev2_set_responder_t *mp;
637   int ret;
638   u8 *name = 0;
639
640   const char *valid_chars = "a-zA-Z0-9_";
641
642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
643     {
644       if (unformat (i, "%U udp-encap", unformat_token, valid_chars, &name))
645         vec_add1 (name, 0);
646       else
647         {
648           errmsg ("parse error '%U'", format_unformat_error, i);
649           return -99;
650         }
651     }
652
653   if (!vec_len (name))
654     {
655       errmsg ("profile name must be specified");
656       return -99;
657     }
658
659   if (vec_len (name) > 64)
660     {
661       errmsg ("profile name too long");
662       return -99;
663     }
664
665   M (IKEV2_PROFILE_SET_UDP_ENCAP, mp);
666
667   clib_memcpy (mp->name, name, vec_len (name));
668   vec_free (name);
669
670   S (mp);
671   W (ret);
672   return ret;
673 }
674
675 static int
676 api_ikev2_set_tunnel_interface (vat_main_t * vam)
677 {
678   return (0);
679 }
680
681 static int
682 api_ikev2_set_responder (vat_main_t * vam)
683 {
684   unformat_input_t *i = vam->input;
685   vl_api_ikev2_set_responder_t *mp;
686   int ret;
687   u8 *name = 0;
688   u32 sw_if_index = ~0;
689   ip4_address_t address;
690
691   const char *valid_chars = "a-zA-Z0-9_";
692
693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
694     {
695       if (unformat
696           (i, "%U interface %d address %U", unformat_token, valid_chars,
697            &name, &sw_if_index, unformat_ip4_address, &address))
698         vec_add1 (name, 0);
699       else
700         {
701           errmsg ("parse error '%U'", format_unformat_error, i);
702           return -99;
703         }
704     }
705
706   if (!vec_len (name))
707     {
708       errmsg ("profile name must be specified");
709       return -99;
710     }
711
712   if (vec_len (name) > 64)
713     {
714       errmsg ("profile name too long");
715       return -99;
716     }
717
718   M (IKEV2_SET_RESPONDER, mp);
719
720   clib_memcpy (mp->name, name, vec_len (name));
721   vec_free (name);
722
723   mp->sw_if_index = sw_if_index;
724   clib_memcpy (mp->address, &address, sizeof (address));
725
726   S (mp);
727   W (ret);
728   return ret;
729 }
730
731 static int
732 api_ikev2_set_ike_transforms (vat_main_t * vam)
733 {
734   unformat_input_t *i = vam->input;
735   vl_api_ikev2_set_ike_transforms_t *mp;
736   int ret;
737   u8 *name = 0;
738   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
739
740   const char *valid_chars = "a-zA-Z0-9_";
741
742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
743     {
744       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
745                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
746         vec_add1 (name, 0);
747       else
748         {
749           errmsg ("parse error '%U'", format_unformat_error, i);
750           return -99;
751         }
752     }
753
754   if (!vec_len (name))
755     {
756       errmsg ("profile name must be specified");
757       return -99;
758     }
759
760   if (vec_len (name) > 64)
761     {
762       errmsg ("profile name too long");
763       return -99;
764     }
765
766   M (IKEV2_SET_IKE_TRANSFORMS, mp);
767
768   clib_memcpy (mp->name, name, vec_len (name));
769   vec_free (name);
770   mp->crypto_alg = crypto_alg;
771   mp->crypto_key_size = crypto_key_size;
772   mp->integ_alg = integ_alg;
773   mp->dh_group = dh_group;
774
775   S (mp);
776   W (ret);
777   return ret;
778 }
779
780
781 static int
782 api_ikev2_set_esp_transforms (vat_main_t * vam)
783 {
784   unformat_input_t *i = vam->input;
785   vl_api_ikev2_set_esp_transforms_t *mp;
786   int ret;
787   u8 *name = 0;
788   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
789
790   const char *valid_chars = "a-zA-Z0-9_";
791
792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
793     {
794       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
795                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
796         vec_add1 (name, 0);
797       else
798         {
799           errmsg ("parse error '%U'", format_unformat_error, i);
800           return -99;
801         }
802     }
803
804   if (!vec_len (name))
805     {
806       errmsg ("profile name must be specified");
807       return -99;
808     }
809
810   if (vec_len (name) > 64)
811     {
812       errmsg ("profile name too long");
813       return -99;
814     }
815
816   M (IKEV2_SET_ESP_TRANSFORMS, mp);
817
818   clib_memcpy (mp->name, name, vec_len (name));
819   vec_free (name);
820   mp->crypto_alg = crypto_alg;
821   mp->crypto_key_size = crypto_key_size;
822   mp->integ_alg = integ_alg;
823   mp->dh_group = dh_group;
824
825   S (mp);
826   W (ret);
827   return ret;
828 }
829
830 static int
831 api_ikev2_set_sa_lifetime (vat_main_t * vam)
832 {
833   unformat_input_t *i = vam->input;
834   vl_api_ikev2_set_sa_lifetime_t *mp;
835   int ret;
836   u8 *name = 0;
837   u64 lifetime, lifetime_maxdata;
838   u32 lifetime_jitter, handover;
839
840   const char *valid_chars = "a-zA-Z0-9_";
841
842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
843     {
844       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
845                     &lifetime, &lifetime_jitter, &handover,
846                     &lifetime_maxdata))
847         vec_add1 (name, 0);
848       else
849         {
850           errmsg ("parse error '%U'", format_unformat_error, i);
851           return -99;
852         }
853     }
854
855   if (!vec_len (name))
856     {
857       errmsg ("profile name must be specified");
858       return -99;
859     }
860
861   if (vec_len (name) > 64)
862     {
863       errmsg ("profile name too long");
864       return -99;
865     }
866
867   M (IKEV2_SET_SA_LIFETIME, mp);
868
869   clib_memcpy (mp->name, name, vec_len (name));
870   vec_free (name);
871   mp->lifetime = lifetime;
872   mp->lifetime_jitter = lifetime_jitter;
873   mp->handover = handover;
874   mp->lifetime_maxdata = lifetime_maxdata;
875
876   S (mp);
877   W (ret);
878   return ret;
879 }
880
881 static int
882 api_ikev2_initiate_sa_init (vat_main_t * vam)
883 {
884   unformat_input_t *i = vam->input;
885   vl_api_ikev2_initiate_sa_init_t *mp;
886   int ret;
887   u8 *name = 0;
888
889   const char *valid_chars = "a-zA-Z0-9_";
890
891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
892     {
893       if (unformat (i, "%U", unformat_token, valid_chars, &name))
894         vec_add1 (name, 0);
895       else
896         {
897           errmsg ("parse error '%U'", format_unformat_error, i);
898           return -99;
899         }
900     }
901
902   if (!vec_len (name))
903     {
904       errmsg ("profile name must be specified");
905       return -99;
906     }
907
908   if (vec_len (name) > 64)
909     {
910       errmsg ("profile name too long");
911       return -99;
912     }
913
914   M (IKEV2_INITIATE_SA_INIT, mp);
915
916   clib_memcpy (mp->name, name, vec_len (name));
917   vec_free (name);
918
919   S (mp);
920   W (ret);
921   return ret;
922 }
923
924 static int
925 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
926 {
927   unformat_input_t *i = vam->input;
928   vl_api_ikev2_initiate_del_ike_sa_t *mp;
929   int ret;
930   u64 ispi;
931
932
933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
934     {
935       if (unformat (i, "%lx", &ispi))
936         ;
937       else
938         {
939           errmsg ("parse error '%U'", format_unformat_error, i);
940           return -99;
941         }
942     }
943
944   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
945
946   mp->ispi = ispi;
947
948   S (mp);
949   W (ret);
950   return ret;
951 }
952
953 static int
954 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
955 {
956   unformat_input_t *i = vam->input;
957   vl_api_ikev2_initiate_del_child_sa_t *mp;
958   int ret;
959   u32 ispi;
960
961
962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
963     {
964       if (unformat (i, "%x", &ispi))
965         ;
966       else
967         {
968           errmsg ("parse error '%U'", format_unformat_error, i);
969           return -99;
970         }
971     }
972
973   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
974
975   mp->ispi = ispi;
976
977   S (mp);
978   W (ret);
979   return ret;
980 }
981
982 static int
983 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
984 {
985   unformat_input_t *i = vam->input;
986   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
987   int ret;
988   u32 ispi;
989
990
991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
992     {
993       if (unformat (i, "%x", &ispi))
994         ;
995       else
996         {
997           errmsg ("parse error '%U'", format_unformat_error, i);
998           return -99;
999         }
1000     }
1001
1002   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
1003
1004   mp->ispi = ispi;
1005
1006   S (mp);
1007   W (ret);
1008   return ret;
1009 }
1010
1011 #include <ikev2/ikev2.api_test.c>
1012
1013 /*
1014  * fd.io coding-style-patch-verification: ON
1015  *
1016  * Local Variables:
1017  * eval: (c-set-style "gnu")
1018  * End:
1019  */