18d01dc6ffb336f19b04d9b79a10a6f358819632
[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 #include <vnet/ip/ip_types_api.h>
27
28 #define __plugin_msg_base ikev2_test_main.msg_id_base
29 #include <vlibapi/vat_helper_macros.h>
30
31 /* Declare message IDs */
32 #include <vnet/format_fns.h>
33 #include <ikev2/ikev2.api_enum.h>
34 #include <ikev2/ikev2.api_types.h>
35 #include <vlibmemory/vlib.api_types.h>
36
37 #define vl_endianfun            /* define message structures */
38 #include <plugins/ikev2/ikev2.api.h>
39 #undef vl_endianfun
40
41 typedef struct
42 {
43   /* API message ID base */
44   u16 msg_id_base;
45   u32 ping_id;
46   vat_main_t *vat_main;
47 } ikev2_test_main_t;
48
49 static const char *valid_chars = "a-zA-Z0-9_";
50 ikev2_test_main_t ikev2_test_main;
51
52 uword
53 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
54 {
55   u32 *r = va_arg (*args, u32 *);
56
57   if (0);
58 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
59   foreach_ikev2_auth_method
60 #undef _
61     else
62     return 0;
63   return 1;
64 }
65
66
67 uword
68 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
69 {
70   u32 *r = va_arg (*args, u32 *);
71
72   if (0);
73 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
74   foreach_ikev2_id_type
75 #undef _
76     else
77     return 0;
78   return 1;
79 }
80
81 #define MACRO_FORMAT(lc)                                \
82 u8 * format_ikev2_##lc (u8 * s, va_list * args)         \
83 {                                                       \
84   u32 i = va_arg (*args, u32);                          \
85   char * t = 0;                                         \
86   switch (i) {                                          \
87         foreach_ikev2_##lc                              \
88       default:                                          \
89         return format (s, "unknown (%u)", i);           \
90     }                                                   \
91   s = format (s, "%s", t);                              \
92   return s;                                             \
93 }
94
95 #define _(v,f,str) case IKEV2_AUTH_METHOD_##f: t = str; break;
96 MACRO_FORMAT (auth_method)
97 #undef _
98 #define _(v,f,str) case IKEV2_ID_TYPE_##f: t = str; break;
99   MACRO_FORMAT (id_type)
100 #undef _
101 #define _(v,f,str) case IKEV2_TRANSFORM_TYPE_##f: t = str; break;
102   MACRO_FORMAT (transform_type)
103 #undef _
104 #define _(v,f,str) case IKEV2_TRANSFORM_ENCR_TYPE_##f: t = str; break;
105   MACRO_FORMAT (transform_encr_type)
106 #undef _
107 #define _(v,f,str) case IKEV2_TRANSFORM_PRF_TYPE_##f: t = str; break;
108   MACRO_FORMAT (transform_prf_type)
109 #undef _
110 #define _(v,f,str) case IKEV2_TRANSFORM_INTEG_TYPE_##f: t = str; break;
111   MACRO_FORMAT (transform_integ_type)
112 #undef _
113 #define _(v,f,str) case IKEV2_TRANSFORM_DH_TYPE_##f: t = str; break;
114   MACRO_FORMAT (transform_dh_type)
115 #undef _
116 #define _(v,f,str) case IKEV2_TRANSFORM_ESN_TYPE_##f: t = str; break;
117   MACRO_FORMAT (transform_esn_type)
118 #undef _
119      u8 *format_ikev2_id_type_and_data (u8 * s, va_list * args)
120 {
121   vl_api_ikev2_id_t *id = va_arg (*args, vl_api_ikev2_id_t *);
122
123   if (id->type == 0)
124     return format (s, "none");
125
126   s = format (s, "%U", format_ikev2_id_type, id->type);
127
128   switch (id->type)
129     {
130     case 0:
131       return format (s, "none");
132     case IKEV2_ID_TYPE_ID_FQDN:
133       s = format (s, " %s", id->data);
134       break;
135     case IKEV2_ID_TYPE_ID_RFC822_ADDR:
136       s = format (s, " %s", id->data);
137       break;
138     case IKEV2_ID_TYPE_ID_IPV4_ADDR:
139       s = format (s, " %U", format_ip_address, id->data);
140       break;
141     case IKEV2_ID_TYPE_ID_KEY_ID:
142       s = format (s, " 0x%U", format_hex_bytes, id->data, id->data_len);
143       break;
144     default:
145       s = format (s, " %s", id->data);
146     }
147
148   return s;
149 }
150
151 u8 *
152 format_ikev2_sa_transform (u8 * s, va_list * args)
153 {
154   vl_api_ikev2_sa_transform_t *tr =
155     va_arg (*args, vl_api_ikev2_sa_transform_t *);
156
157   if (!tr)
158     return s;
159
160   if (tr->transform_type >= IKEV2_TRANSFORM_NUM_TYPES)
161     return s;
162
163   s = format (s, "%U:", format_ikev2_transform_type, tr->transform_type);
164
165   switch (tr->transform_type)
166     {
167     case IKEV2_TRANSFORM_TYPE_ENCR:
168       s =
169         format (s, "%U", format_ikev2_transform_encr_type, tr->transform_id);
170       break;
171     case IKEV2_TRANSFORM_TYPE_PRF:
172       s = format (s, "%U", format_ikev2_transform_prf_type, tr->transform_id);
173       break;
174     case IKEV2_TRANSFORM_TYPE_INTEG:
175       s =
176         format (s, "%U", format_ikev2_transform_integ_type, tr->transform_id);
177       break;
178     case IKEV2_TRANSFORM_TYPE_DH:
179       s = format (s, "%U", format_ikev2_transform_dh_type, tr->transform_id);
180       break;
181     case IKEV2_TRANSFORM_TYPE_ESN:
182       s = format (s, "%U", format_ikev2_transform_esn_type, tr->transform_id);
183       break;
184     default:
185       break;
186     }
187
188   if (tr->transform_type == IKEV2_TRANSFORM_TYPE_ENCR &&
189       tr->transform_id == IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC && tr->key_len)
190     s = format (s, "-%u", tr->key_len * 8);
191
192   return s;
193 }
194
195 static int
196 api_ikev2_profile_disable_natt (vat_main_t * vam)
197 {
198   unformat_input_t *i = vam->input;
199   vl_api_ikev2_profile_disable_natt_t *mp;
200   u8 *name = 0;
201   int ret;
202
203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
204     {
205       if (unformat (i, "%U", unformat_token, valid_chars, &name))
206         vec_add1 (name, 0);
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   M (IKEV2_PROFILE_DISABLE_NATT, mp);
227
228   clib_memcpy (mp->name, name, vec_len (name));
229   vec_free (name);
230
231   S (mp);
232   W (ret);
233   return ret;
234 }
235
236 static int
237 api_ikev2_profile_dump (vat_main_t * vam)
238 {
239   ikev2_test_main_t *ik = &ikev2_test_main;
240   vl_api_ikev2_profile_dump_t *mp;
241   vl_api_control_ping_t *mp_ping;
242   int ret;
243
244   /* Construct the API message */
245   M (IKEV2_PROFILE_DUMP, mp);
246
247   /* send it... */
248   S (mp);
249
250   /* Use a control ping for synchronization */
251   if (!ik->ping_id)
252     ik->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
253   mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
254   mp_ping->_vl_msg_id = htons (ik->ping_id);
255   mp_ping->client_index = vam->my_client_index;
256
257   vam->result_ready = 0;
258   S (mp_ping);
259
260   /* Wait for a reply... */
261   W (ret);
262   return ret;
263 }
264
265 static void vl_api_ikev2_profile_details_t_handler
266   (vl_api_ikev2_profile_details_t * mp)
267 {
268   vat_main_t *vam = ikev2_test_main.vat_main;
269   vl_api_ikev2_profile_t *p = &mp->profile;
270
271   fformat (vam->ofp, "profile %s\n", p->name);
272
273   if (p->auth.method)
274     {
275       if (p->auth.hex)
276         fformat (vam->ofp, "  auth-method %U auth data 0x%U\n",
277                  format_ikev2_auth_method, p->auth.method,
278                  format_hex_bytes, p->auth.data,
279                  clib_net_to_host_u32 (p->auth.data_len));
280       else
281         fformat (vam->ofp, "  auth-method %U auth data %v\n",
282                  format_ikev2_auth_method, p->auth.method, format (0,
283                                                                    "%s",
284                                                                    p->
285                                                                    auth.data));
286     }
287
288   if (p->loc_id.type)
289     {
290       fformat (vam->ofp, "  local id-type data %U\n",
291                format_ikev2_id_type_and_data, &p->loc_id);
292     }
293
294   if (p->rem_id.type)
295     {
296       fformat (vam->ofp, "  remote id-type data %U\n",
297                format_ikev2_id_type_and_data, &p->rem_id);
298     }
299
300   fformat (vam->ofp, "  local traffic-selector addr %U - %U port %u - %u"
301            " protocol %u\n",
302            format_ip_address, &p->loc_ts.start_addr,
303            format_ip_address, &p->loc_ts.end_addr,
304            clib_net_to_host_u16 (p->loc_ts.start_port),
305            clib_net_to_host_u16 (p->loc_ts.end_port), p->loc_ts.protocol_id);
306
307   fformat (vam->ofp, "  remote traffic-selector addr %U - %U port %u - %u"
308            " protocol %u\n",
309            format_ip_address, &p->rem_ts.start_addr,
310            format_ip_address, &p->rem_ts.end_addr,
311            clib_net_to_host_u16 (p->rem_ts.start_port),
312            clib_net_to_host_u16 (p->rem_ts.end_port), p->rem_ts.protocol_id);
313   u32 tun_itf = clib_net_to_host_u32 (p->tun_itf);
314   if (~0 != tun_itf)
315     fformat (vam->ofp, "  protected tunnel idx %d\n", tun_itf);
316
317   u32 sw_if_index = clib_net_to_host_u32 (p->responder.sw_if_index);
318   if (~0 != sw_if_index)
319     fformat (vam->ofp, "  responder idx %d %U\n",
320              sw_if_index, format_ip_address, &p->responder.addr);
321
322   if (p->udp_encap)
323     fformat (vam->ofp, "  udp-encap\n");
324
325   if (p->natt_disabled)
326     fformat (vam->ofp, "  NAT-T disabled\n");
327
328   u32 ipsec_over_udp_port = clib_net_to_host_u16 (p->ipsec_over_udp_port);
329   if (ipsec_over_udp_port != IPSEC_UDP_PORT_NONE)
330     fformat (vam->ofp, "  ipsec-over-udp port %d\n", ipsec_over_udp_port);
331
332   u32 crypto_key_size = clib_net_to_host_u32 (p->ike_ts.crypto_key_size);
333   if (p->ike_ts.crypto_alg || p->ike_ts.integ_alg || p->ike_ts.dh_group
334       || crypto_key_size)
335     fformat (vam->ofp, "  ike-crypto-alg %U %u ike-integ-alg %U ike-dh %U\n",
336              format_ikev2_transform_encr_type, p->ike_ts.crypto_alg,
337              crypto_key_size, format_ikev2_transform_integ_type,
338              p->ike_ts.integ_alg, format_ikev2_transform_dh_type,
339              p->ike_ts.dh_group);
340
341   crypto_key_size = clib_net_to_host_u32 (p->esp_ts.crypto_key_size);
342   if (p->esp_ts.crypto_alg || p->esp_ts.integ_alg)
343     fformat (vam->ofp, "  esp-crypto-alg %U %u esp-integ-alg %U\n",
344              format_ikev2_transform_encr_type, p->esp_ts.crypto_alg,
345              crypto_key_size,
346              format_ikev2_transform_integ_type, p->esp_ts.integ_alg);
347
348   fformat (vam->ofp, "  lifetime %d jitter %d handover %d maxdata %d\n",
349            clib_net_to_host_u64 (p->lifetime),
350            clib_net_to_host_u32 (p->lifetime_jitter),
351            clib_net_to_host_u32 (p->handover),
352            clib_net_to_host_u64 (p->lifetime_maxdata));
353
354   vam->result_ready = 1;
355 }
356
357 static int
358 api_ikev2_sa_dump (vat_main_t * vam)
359 {
360   ikev2_test_main_t *im = &ikev2_test_main;
361   vl_api_ikev2_sa_dump_t *mp;
362   vl_api_control_ping_t *mp_ping;
363   int ret;
364
365   /* Construct the API message */
366   M (IKEV2_SA_DUMP, mp);
367
368   /* send it... */
369   S (mp);
370
371   /* Use a control ping for synchronization */
372   if (!im->ping_id)
373     im->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
374   mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
375   mp_ping->_vl_msg_id = htons (im->ping_id);
376   mp_ping->client_index = vam->my_client_index;
377   vam->result_ready = 0;
378
379   S (mp_ping);
380
381   /* Wait for a reply... */
382   W (ret);
383   return ret;
384 }
385
386 static void
387 vl_api_ikev2_sa_details_t_handler (vl_api_ikev2_sa_details_t * mp)
388 {
389   vat_main_t *vam = ikev2_test_main.vat_main;
390   vl_api_ikev2_sa_t *sa = &mp->sa;
391   ip_address_t iaddr;
392   ip_address_t raddr;
393   vl_api_ikev2_keys_t *k = &sa->keys;
394   vl_api_ikev2_sa_t_endian (sa);
395
396   ip_address_decode2 (&sa->iaddr, &iaddr);
397   ip_address_decode2 (&sa->raddr, &raddr);
398
399   fformat (vam->ofp, "profile index %u sa index: %d\n", mp->sa.profile_index,
400            mp->sa.sa_index);
401   fformat (vam->ofp, " iip %U ispi %lx rip %U rspi %lx\n", format_ip_address,
402            &iaddr, sa->ispi, format_ip_address, &raddr, sa->rspi);
403   fformat (vam->ofp, " %U ", format_ikev2_sa_transform, &sa->encryption);
404   fformat (vam->ofp, "%U ", format_ikev2_sa_transform, &sa->prf);
405   fformat (vam->ofp, "%U ", format_ikev2_sa_transform, &sa->integrity);
406   fformat (vam->ofp, "%U \n", format_ikev2_sa_transform, &sa->dh);
407
408   fformat (vam->ofp, "  SK_d    %U\n", format_hex_bytes, k->sk_d, k->sk_d_len);
409
410   fformat (vam->ofp, "  SK_a  i:%U\n        r:%U\n", format_hex_bytes,
411            k->sk_ai, k->sk_ai_len, format_hex_bytes, k->sk_ar, k->sk_ar_len);
412
413   fformat (vam->ofp, "  SK_e  i:%U\n        r:%U\n", format_hex_bytes,
414            k->sk_ei, k->sk_ei_len, format_hex_bytes, k->sk_er, k->sk_er_len);
415
416   fformat (vam->ofp, "  SK_p  i:%U\n        r:%U\n", format_hex_bytes,
417            k->sk_pi, k->sk_pi_len, format_hex_bytes, k->sk_pr, k->sk_pr_len);
418
419   fformat (vam->ofp, "  identifier (i) %U\n", format_ikev2_id_type_and_data,
420            &sa->i_id);
421   fformat (vam->ofp, "  identifier (r) %U\n", format_ikev2_id_type_and_data,
422            &sa->r_id);
423
424   vam->result_ready = 1;
425 }
426
427 static int
428 api_ikev2_sa_v2_dump (vat_main_t *vam)
429 {
430   ikev2_test_main_t *im = &ikev2_test_main;
431   vl_api_ikev2_sa_v2_dump_t *mp;
432   vl_api_control_ping_t *mp_ping;
433   int ret;
434
435   /* Construct the API message */
436   M (IKEV2_SA_V2_DUMP, mp);
437
438   /* send it... */
439   S (mp);
440
441   /* Use a control ping for synchronization */
442   if (!im->ping_id)
443     im->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
444   mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
445   mp_ping->_vl_msg_id = htons (im->ping_id);
446   mp_ping->client_index = vam->my_client_index;
447   vam->result_ready = 0;
448
449   S (mp_ping);
450
451   /* Wait for a reply... */
452   W (ret);
453   return ret;
454 }
455
456 static void
457 vl_api_ikev2_sa_v2_details_t_handler (vl_api_ikev2_sa_v2_details_t *mp)
458 {
459   vat_main_t *vam = ikev2_test_main.vat_main;
460   vl_api_ikev2_sa_v2_t *sa = &mp->sa;
461   ip_address_t iaddr;
462   ip_address_t raddr;
463   vl_api_ikev2_keys_t *k = &sa->keys;
464   vl_api_ikev2_sa_v2_t_endian (sa);
465
466   ip_address_decode2 (&sa->iaddr, &iaddr);
467   ip_address_decode2 (&sa->raddr, &raddr);
468
469   fformat (vam->ofp, "profile name %s sa index: %d\n", mp->sa.profile_name,
470            mp->sa.sa_index);
471   fformat (vam->ofp, " iip %U ispi %lx rip %U rspi %lx\n", format_ip_address,
472            &iaddr, sa->ispi, format_ip_address, &raddr, sa->rspi);
473   fformat (vam->ofp, " %U ", format_ikev2_sa_transform, &sa->encryption);
474   fformat (vam->ofp, "%U ", format_ikev2_sa_transform, &sa->prf);
475   fformat (vam->ofp, "%U ", format_ikev2_sa_transform, &sa->integrity);
476   fformat (vam->ofp, "%U \n", format_ikev2_sa_transform, &sa->dh);
477
478   fformat (vam->ofp, "  SK_d    %U\n",
479            format_hex_bytes, k->sk_d, k->sk_d_len);
480
481   fformat (vam->ofp, "  SK_a  i:%U\n        r:%U\n",
482            format_hex_bytes, k->sk_ai, k->sk_ai_len, format_hex_bytes,
483            k->sk_ar, k->sk_ar_len);
484
485   fformat (vam->ofp, "  SK_e  i:%U\n        r:%U\n", format_hex_bytes,
486            k->sk_ei, k->sk_ei_len, format_hex_bytes, k->sk_er, k->sk_er_len);
487
488   fformat (vam->ofp, "  SK_p  i:%U\n        r:%U\n", format_hex_bytes,
489            k->sk_pi, k->sk_pi_len, format_hex_bytes, k->sk_pr, k->sk_pr_len);
490
491   fformat (vam->ofp, "  identifier (i) %U\n",
492            format_ikev2_id_type_and_data, &sa->i_id);
493   fformat (vam->ofp, "  identifier (r) %U\n",
494            format_ikev2_id_type_and_data, &sa->r_id);
495
496   vam->result_ready = 1;
497 }
498
499 static int
500 api_ikev2_child_sa_dump (vat_main_t * vam)
501 {
502   unformat_input_t *i = vam->input;
503   ikev2_test_main_t *im = &ikev2_test_main;
504   vl_api_ikev2_child_sa_dump_t *mp;
505   vl_api_control_ping_t *mp_ping;
506   int ret;
507   u32 sa_index = ~0;
508
509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
510     {
511       if (unformat (i, "sa_index %d", &sa_index))
512         ;
513       else
514         {
515           errmsg ("parse error '%U'", format_unformat_error, i);
516           return -99;
517         }
518     }
519
520   if (sa_index == ~0)
521     return -99;
522
523   /* Construct the API message */
524   M (IKEV2_CHILD_SA_DUMP, mp);
525
526   mp->sa_index = clib_net_to_host_u32 (sa_index);
527
528   /* send it... */
529   S (mp);
530
531   /* Use a control ping for synchronization */
532   if (!im->ping_id)
533     im->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
534   mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
535   mp_ping->_vl_msg_id = htons (im->ping_id);
536   mp_ping->client_index = vam->my_client_index;
537   vam->result_ready = 0;
538
539   S (mp_ping);
540
541   /* Wait for a reply... */
542   W (ret);
543   return ret;
544 }
545
546 static void
547 vl_api_ikev2_child_sa_details_t_handler (vl_api_ikev2_child_sa_details_t * mp)
548 {
549   vat_main_t *vam = ikev2_test_main.vat_main;
550   vl_api_ikev2_child_sa_t *child_sa = &mp->child_sa;
551   vl_api_ikev2_keys_t *k = &child_sa->keys;
552   vl_api_ikev2_child_sa_t_endian (child_sa);
553
554   fformat (vam->ofp, "  child sa %u:\n", child_sa->child_sa_index);
555
556   fformat (vam->ofp, "    %U ", format_ikev2_sa_transform,
557            &child_sa->encryption);
558   fformat (vam->ofp, "%U ", format_ikev2_sa_transform, &child_sa->integrity);
559   fformat (vam->ofp, "%U \n", format_ikev2_sa_transform, &child_sa->esn);
560
561   fformat (vam->ofp, "    spi(i) %lx spi(r) %lx\n",
562            child_sa->i_spi, child_sa->r_spi);
563
564   fformat (vam->ofp, "    SK_e  i:%U\n          r:%U\n",
565            format_hex_bytes, k->sk_ei, k->sk_ei_len,
566            format_hex_bytes, k->sk_er, k->sk_er_len);
567   if (k->sk_ai_len)
568     {
569       fformat (vam->ofp, "    SK_a  i:%U\n          r:%U\n",
570                format_hex_bytes, k->sk_ai, k->sk_ai_len,
571                format_hex_bytes, k->sk_ar, k->sk_ar_len);
572     }
573   vam->result_ready = 1;
574 }
575
576 static int
577 api_ikev2_traffic_selector_dump (vat_main_t * vam)
578 {
579   unformat_input_t *i = vam->input;
580   ikev2_test_main_t *im = &ikev2_test_main;
581   vl_api_ikev2_traffic_selector_dump_t *mp;
582   vl_api_control_ping_t *mp_ping;
583   int is_initiator = ~0;
584   int sa_index = ~0;
585   int child_sa_index = ~0;
586   int ret;
587
588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
589     {
590       if (unformat (i, "initiator"))
591         is_initiator = 1;
592       else if (unformat (i, "responder"))
593         is_initiator = 0;
594       else if (unformat (i, "sa_index %d", &sa_index))
595         ;
596       else if (unformat (i, "child_sa_index %d", &child_sa_index))
597         ;
598       else
599         {
600           errmsg ("parse error '%U'", format_unformat_error, i);
601           return -99;
602         }
603     }
604
605   if (child_sa_index == ~0 || sa_index == ~0 || is_initiator == ~0)
606     return -99;
607
608   /* Construct the API message */
609   M (IKEV2_TRAFFIC_SELECTOR_DUMP, mp);
610
611   mp->is_initiator = is_initiator;
612   mp->sa_index = clib_host_to_net_u32 (sa_index);
613   mp->child_sa_index = clib_host_to_net_u32 (child_sa_index);
614
615   /* send it... */
616   S (mp);
617
618   /* Use a control ping for synchronization */
619   if (!im->ping_id)
620     im->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
621   mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
622   mp_ping->_vl_msg_id = htons (im->ping_id);
623   mp_ping->client_index = vam->my_client_index;
624   vam->result_ready = 0;
625
626   S (mp_ping);
627
628   /* Wait for a reply... */
629   W (ret);
630   return ret;
631 }
632
633 static void
634   vl_api_ikev2_traffic_selector_details_t_handler
635   (vl_api_ikev2_traffic_selector_details_t * mp)
636 {
637   vat_main_t *vam = ikev2_test_main.vat_main;
638   vl_api_ikev2_ts_t *ts = &mp->ts;
639   ip_address_t start_addr, end_addr;
640   vl_api_ikev2_ts_t_endian (ts);
641
642   ip_address_decode2 (&ts->start_addr, &start_addr);
643   ip_address_decode2 (&ts->end_addr, &end_addr);
644
645   fformat (vam->ofp, " %s protocol_id %u addr "
646            "%U - %U port %u - %u\n",
647            ts->is_local, ts->protocol_id,
648            format_ip_address, &start_addr,
649            format_ip_address, &end_addr, ts->start_port, ts->end_port);
650   vam->result_ready = 1;
651 }
652
653 static int
654 api_ikev2_nonce_get (vat_main_t * vam)
655 {
656   unformat_input_t *i = vam->input;
657   ikev2_test_main_t *im = &ikev2_test_main;
658   vl_api_ikev2_nonce_get_t *mp;
659   vl_api_control_ping_t *mp_ping;
660   u32 is_initiator = ~0;
661   u32 sa_index = ~0;
662   int ret;
663
664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
665     {
666       if (unformat (i, "initiator"))
667         is_initiator = 1;
668       else if (unformat (i, "responder"))
669         is_initiator = 0;
670       else if (unformat (i, "sa_index %d", &sa_index))
671         ;
672       else
673         {
674           errmsg ("parse error '%U'", format_unformat_error, i);
675           return -99;
676         }
677     }
678
679   if (sa_index == ~0 || is_initiator == ~0)
680     return -99;
681
682   /* Construct the API message */
683   M (IKEV2_NONCE_GET, mp);
684
685   mp->is_initiator = is_initiator;
686   mp->sa_index = clib_host_to_net_u32 (sa_index);
687
688   /* send it... */
689   S (mp);
690
691   /* Use a control ping for synchronization */
692   if (!im->ping_id)
693     im->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
694   mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
695   mp_ping->_vl_msg_id = htons (im->ping_id);
696   mp_ping->client_index = vam->my_client_index;
697   vam->result_ready = 0;
698
699   S (mp_ping);
700
701   /* Wait for a reply... */
702   W (ret);
703   return ret;
704 }
705
706 static void
707 vl_api_ikev2_nonce_get_reply_t_handler (vl_api_ikev2_nonce_get_reply_t * mp)
708 {
709   vat_main_t *vam = ikev2_test_main.vat_main;
710   mp->data_len = clib_net_to_host_u32 (mp->data_len);
711
712   fformat (vam->ofp, "  nonce:%U\n",
713            format_hex_bytes, mp->nonce, mp->data_len);
714
715   vam->result_ready = 1;
716 }
717
718 static int
719 api_ikev2_plugin_get_version (vat_main_t * vam)
720 {
721   ikev2_test_main_t *sm = &ikev2_test_main;
722   vl_api_ikev2_plugin_get_version_t *mp;
723   u32 msg_size = sizeof (*mp);
724   int ret;
725
726   vam->result_ready = 0;
727   mp = vl_msg_api_alloc_as_if_client (msg_size);
728   clib_memset (mp, 0, msg_size);
729   mp->_vl_msg_id = ntohs (VL_API_IKEV2_PLUGIN_GET_VERSION + sm->msg_id_base);
730   mp->client_index = vam->my_client_index;
731
732   /* send it... */
733   S (mp);
734
735   /* Wait for a reply... */
736   W (ret);
737   return ret;
738 }
739
740 static void vl_api_ikev2_plugin_get_version_reply_t_handler
741   (vl_api_ikev2_plugin_get_version_reply_t * mp)
742 {
743   vat_main_t *vam = ikev2_test_main.vat_main;
744   clib_warning ("IKEv2 plugin version: %d.%d", ntohl (mp->major),
745                 ntohl (mp->minor));
746   vam->result_ready = 1;
747 }
748
749 static int
750 api_ikev2_profile_set_ipsec_udp_port (vat_main_t * vam)
751 {
752   return 0;
753 }
754
755 static int
756 api_ikev2_profile_set_liveness (vat_main_t * vam)
757 {
758   unformat_input_t *i = vam->input;
759   vl_api_ikev2_profile_set_liveness_t *mp;
760   u32 period = 0, max_retries = 0;
761   int ret;
762
763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
764     {
765       if (!unformat (i, "period %d max-retries %d", &period, &max_retries))
766         {
767           errmsg ("parse error '%U'", format_unformat_error, i);
768           return -99;
769         }
770     }
771
772   M (IKEV2_PROFILE_SET_LIVENESS, mp);
773
774   mp->period = clib_host_to_net_u32 (period);
775   mp->max_retries = clib_host_to_net_u32 (max_retries);
776
777   S (mp);
778   W (ret);
779
780   return ret;
781 }
782
783 static int
784 api_ikev2_profile_add_del (vat_main_t * vam)
785 {
786   unformat_input_t *i = vam->input;
787   vl_api_ikev2_profile_add_del_t *mp;
788   u8 is_add = 1;
789   u8 *name = 0;
790   int ret;
791
792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
793     {
794       if (unformat (i, "del"))
795         is_add = 0;
796       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
797         vec_add1 (name, 0);
798       else
799         {
800           errmsg ("parse error '%U'", format_unformat_error, i);
801           return -99;
802         }
803     }
804
805   if (!vec_len (name))
806     {
807       errmsg ("profile name must be specified");
808       return -99;
809     }
810
811   if (vec_len (name) > 64)
812     {
813       errmsg ("profile name too long");
814       return -99;
815     }
816
817   M (IKEV2_PROFILE_ADD_DEL, mp);
818
819   clib_memcpy (mp->name, name, vec_len (name));
820   mp->is_add = is_add;
821   vec_free (name);
822
823   S (mp);
824   W (ret);
825   return ret;
826 }
827
828 static int
829 api_ikev2_profile_set_auth (vat_main_t * vam)
830 {
831   unformat_input_t *i = vam->input;
832   vl_api_ikev2_profile_set_auth_t *mp;
833   u8 *name = 0;
834   u8 *data = 0;
835   u32 auth_method = 0;
836   u8 is_hex = 0;
837   int ret;
838
839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
840     {
841       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
842         vec_add1 (name, 0);
843       else if (unformat (i, "auth_method %U",
844                          unformat_ikev2_auth_method, &auth_method))
845         ;
846       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
847         is_hex = 1;
848       else if (unformat (i, "auth_data %v", &data))
849         ;
850       else
851         {
852           errmsg ("parse error '%U'", format_unformat_error, i);
853           return -99;
854         }
855     }
856
857   if (!vec_len (name))
858     {
859       errmsg ("profile name must be specified");
860       return -99;
861     }
862
863   if (vec_len (name) > 64)
864     {
865       errmsg ("profile name too long");
866       return -99;
867     }
868
869   if (!vec_len (data))
870     {
871       errmsg ("auth_data must be specified");
872       return -99;
873     }
874
875   if (!auth_method)
876     {
877       errmsg ("auth_method must be specified");
878       return -99;
879     }
880
881   M (IKEV2_PROFILE_SET_AUTH, mp);
882
883   mp->is_hex = is_hex;
884   mp->auth_method = (u8) auth_method;
885   mp->data_len = vec_len (data);
886   clib_memcpy (mp->name, name, vec_len (name));
887   clib_memcpy (mp->data, data, vec_len (data));
888   vec_free (name);
889   vec_free (data);
890
891   S (mp);
892   W (ret);
893   return ret;
894 }
895
896 static int
897 api_ikev2_profile_set_id (vat_main_t * vam)
898 {
899   unformat_input_t *i = vam->input;
900   vl_api_ikev2_profile_set_id_t *mp;
901   u8 *name = 0;
902   u8 *data = 0;
903   u8 is_local = 0;
904   u32 id_type = 0;
905   ip_address_t ip;
906   int ret;
907
908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
909     {
910       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
911         vec_add1 (name, 0);
912       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
913         ;
914       else if (unformat (i, "id_data %U", unformat_ip_address, &ip))
915         {
916           data = vec_new (u8, ip_address_size (&ip));
917           clib_memcpy (data, ip_addr_bytes (&ip), ip_address_size (&ip));
918         }
919       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
920         ;
921       else if (unformat (i, "id_data %v", &data))
922         ;
923       else if (unformat (i, "local"))
924         is_local = 1;
925       else if (unformat (i, "remote"))
926         is_local = 0;
927       else
928         {
929           errmsg ("parse error '%U'", format_unformat_error, i);
930           return -99;
931         }
932     }
933
934   if (!vec_len (name))
935     {
936       errmsg ("profile name must be specified");
937       return -99;
938     }
939
940   if (vec_len (name) > 64)
941     {
942       errmsg ("profile name too long");
943       return -99;
944     }
945
946   if (!vec_len (data))
947     {
948       errmsg ("id_data must be specified");
949       return -99;
950     }
951
952   if (!id_type)
953     {
954       errmsg ("id_type must be specified");
955       return -99;
956     }
957
958   M (IKEV2_PROFILE_SET_ID, mp);
959
960   mp->is_local = is_local;
961   mp->id_type = (u8) id_type;
962   mp->data_len = vec_len (data);
963   clib_memcpy (mp->name, name, vec_len (name));
964   clib_memcpy (mp->data, data, vec_len (data));
965   vec_free (name);
966   vec_free (data);
967
968   S (mp);
969   W (ret);
970   return ret;
971 }
972
973 static int
974 api_ikev2_profile_set_ts (vat_main_t * vam)
975 {
976   unformat_input_t *i = vam->input;
977   vl_api_ikev2_profile_set_ts_t *mp;
978   u8 *name = 0;
979   u8 is_local = 0;
980   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
981   ip_address_t start_addr, end_addr;
982   u8 start_addr_set = 0, end_addr_set = 0;
983   int ret;
984
985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
986     {
987       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
988         vec_add1 (name, 0);
989       else if (unformat (i, "protocol %d", &proto))
990         ;
991       else if (unformat (i, "start_port %d", &start_port))
992         ;
993       else if (unformat (i, "end_port %d", &end_port))
994         ;
995       else
996         if (unformat (i, "start_addr %U", unformat_ip_address, &start_addr))
997         start_addr_set = 1;
998       else if (unformat (i, "end_addr %U", unformat_ip_address, &end_addr))
999         end_addr_set = 1;
1000       else if (unformat (i, "local"))
1001         is_local = 1;
1002       else if (unformat (i, "remote"))
1003         is_local = 0;
1004       else
1005         {
1006           errmsg ("parse error '%U'", format_unformat_error, i);
1007           return -99;
1008         }
1009     }
1010
1011   if (!start_addr_set || !end_addr_set)
1012     {
1013       errmsg ("missing start or end address");
1014       return -99;
1015     }
1016
1017   if (!vec_len (name))
1018     {
1019       errmsg ("profile name must be specified");
1020       return -99;
1021     }
1022
1023   if (vec_len (name) > 64)
1024     {
1025       errmsg ("profile name too long");
1026       return -99;
1027     }
1028
1029   M (IKEV2_PROFILE_SET_TS, mp);
1030
1031   mp->ts.is_local = is_local;
1032   mp->ts.protocol_id = (u8) proto;
1033   mp->ts.start_port = clib_host_to_net_u16 ((u16) start_port);
1034   mp->ts.end_port = clib_host_to_net_u16 ((u16) end_port);
1035   ip_address_encode2 (&start_addr, &mp->ts.start_addr);
1036   ip_address_encode2 (&end_addr, &mp->ts.end_addr);
1037   clib_memcpy (mp->name, name, vec_len (name));
1038   vec_free (name);
1039
1040   S (mp);
1041   W (ret);
1042   return ret;
1043 }
1044
1045 static int
1046 api_ikev2_set_local_key (vat_main_t * vam)
1047 {
1048   unformat_input_t *i = vam->input;
1049   vl_api_ikev2_set_local_key_t *mp;
1050   u8 *file = 0;
1051   int ret;
1052
1053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1054     {
1055       if (unformat (i, "file %v", &file))
1056         vec_add1 (file, 0);
1057       else
1058         {
1059           errmsg ("parse error '%U'", format_unformat_error, i);
1060           return -99;
1061         }
1062     }
1063
1064   if (!vec_len (file))
1065     {
1066       errmsg ("RSA key file must be specified");
1067       return -99;
1068     }
1069
1070   if (vec_len (file) > 256)
1071     {
1072       errmsg ("file name too long");
1073       return -99;
1074     }
1075
1076   M (IKEV2_SET_LOCAL_KEY, mp);
1077
1078   clib_memcpy (mp->key_file, file, vec_len (file));
1079   vec_free (file);
1080
1081   S (mp);
1082   W (ret);
1083   return ret;
1084 }
1085
1086 static int
1087 api_ikev2_profile_set_udp_encap (vat_main_t * vam)
1088 {
1089   unformat_input_t *i = vam->input;
1090   vl_api_ikev2_profile_set_udp_encap_t *mp;
1091   int ret;
1092   u8 *name = 0;
1093
1094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1095     {
1096       if (unformat (i, "%U udp-encap", unformat_token, valid_chars, &name))
1097         vec_add1 (name, 0);
1098       else
1099         {
1100           errmsg ("parse error '%U'", format_unformat_error, i);
1101           return -99;
1102         }
1103     }
1104
1105   if (!vec_len (name))
1106     {
1107       errmsg ("profile name must be specified");
1108       return -99;
1109     }
1110
1111   if (vec_len (name) > 64)
1112     {
1113       errmsg ("profile name too long");
1114       return -99;
1115     }
1116
1117   M (IKEV2_PROFILE_SET_UDP_ENCAP, mp);
1118
1119   clib_memcpy (mp->name, name, vec_len (name));
1120   vec_free (name);
1121
1122   S (mp);
1123   W (ret);
1124   return ret;
1125 }
1126
1127 static int
1128 api_ikev2_set_tunnel_interface (vat_main_t * vam)
1129 {
1130   return (0);
1131 }
1132
1133 static int
1134 api_ikev2_set_responder_hostname (vat_main_t *vam)
1135 {
1136   unformat_input_t *i = vam->input;
1137   vl_api_ikev2_set_responder_hostname_t *mp;
1138   int ret;
1139   u8 *name = 0, *hn = 0;
1140
1141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1142     {
1143       if (unformat (i, "%U hostname %v", unformat_token, valid_chars, &name,
1144                     &hn))
1145         {
1146           vec_add1 (name, 0);
1147           vec_add1 (hn, 0);
1148         }
1149       else
1150         {
1151           errmsg ("parse error '%U'", format_unformat_error, i);
1152           return -99;
1153         }
1154     }
1155
1156   if (!vec_len (name))
1157     {
1158       errmsg ("profile name must be specified");
1159       return -99;
1160     }
1161
1162   if (vec_len (name) > 64)
1163     {
1164       errmsg ("profile name too long");
1165       return -99;
1166     }
1167
1168   M (IKEV2_SET_RESPONDER_HOSTNAME, mp);
1169
1170   clib_memcpy (mp->name, name, vec_len (name));
1171   clib_memcpy (mp->hostname, hn, vec_len (hn));
1172   vec_free (name);
1173   vec_free (hn);
1174
1175   S (mp);
1176   W (ret);
1177   return ret;
1178 }
1179
1180 static int
1181 api_ikev2_set_responder (vat_main_t * vam)
1182 {
1183   unformat_input_t *i = vam->input;
1184   vl_api_ikev2_set_responder_t *mp;
1185   int ret;
1186   u8 *name = 0;
1187   u32 sw_if_index = ~0;
1188   ip_address_t address;
1189
1190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1191     {
1192       if (unformat
1193           (i, "%U interface %d address %U", unformat_token, valid_chars,
1194            &name, &sw_if_index, unformat_ip_address, &address))
1195         vec_add1 (name, 0);
1196       else
1197         {
1198           errmsg ("parse error '%U'", format_unformat_error, i);
1199           return -99;
1200         }
1201     }
1202
1203   if (!vec_len (name))
1204     {
1205       errmsg ("profile name must be specified");
1206       return -99;
1207     }
1208
1209   if (vec_len (name) > 64)
1210     {
1211       errmsg ("profile name too long");
1212       return -99;
1213     }
1214
1215   M (IKEV2_SET_RESPONDER, mp);
1216
1217   clib_memcpy (mp->name, name, vec_len (name));
1218   vec_free (name);
1219
1220   mp->responder.sw_if_index = clib_host_to_net_u32 (sw_if_index);
1221   ip_address_encode2 (&address, &mp->responder.addr);
1222
1223   S (mp);
1224   W (ret);
1225   return ret;
1226 }
1227
1228 static int
1229 api_ikev2_set_ike_transforms (vat_main_t * vam)
1230 {
1231   unformat_input_t *i = vam->input;
1232   vl_api_ikev2_set_ike_transforms_t *mp;
1233   int ret;
1234   u8 *name = 0;
1235   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
1236
1237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1238     {
1239       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
1240                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
1241         vec_add1 (name, 0);
1242       else
1243         {
1244           errmsg ("parse error '%U'", format_unformat_error, i);
1245           return -99;
1246         }
1247     }
1248
1249   if (!vec_len (name))
1250     {
1251       errmsg ("profile name must be specified");
1252       return -99;
1253     }
1254
1255   if (vec_len (name) > 64)
1256     {
1257       errmsg ("profile name too long");
1258       return -99;
1259     }
1260
1261   M (IKEV2_SET_IKE_TRANSFORMS, mp);
1262
1263   clib_memcpy (mp->name, name, vec_len (name));
1264   vec_free (name);
1265   mp->tr.crypto_alg = crypto_alg;
1266   mp->tr.crypto_key_size = clib_host_to_net_u32 (crypto_key_size);
1267   mp->tr.integ_alg = integ_alg;
1268   mp->tr.dh_group = dh_group;
1269
1270   S (mp);
1271   W (ret);
1272   return ret;
1273 }
1274
1275
1276 static int
1277 api_ikev2_set_esp_transforms (vat_main_t * vam)
1278 {
1279   unformat_input_t *i = vam->input;
1280   vl_api_ikev2_set_esp_transforms_t *mp;
1281   int ret;
1282   u8 *name = 0;
1283   u32 crypto_alg, crypto_key_size, integ_alg;
1284
1285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1286     {
1287       if (unformat (i, "%U %d %d %d", unformat_token, valid_chars, &name,
1288                     &crypto_alg, &crypto_key_size, &integ_alg))
1289         vec_add1 (name, 0);
1290       else
1291         {
1292           errmsg ("parse error '%U'", format_unformat_error, i);
1293           return -99;
1294         }
1295     }
1296
1297   if (!vec_len (name))
1298     {
1299       errmsg ("profile name must be specified");
1300       return -99;
1301     }
1302
1303   if (vec_len (name) > 64)
1304     {
1305       errmsg ("profile name too long");
1306       return -99;
1307     }
1308
1309   M (IKEV2_SET_ESP_TRANSFORMS, mp);
1310
1311   clib_memcpy (mp->name, name, vec_len (name));
1312   vec_free (name);
1313   mp->tr.crypto_alg = crypto_alg;
1314   mp->tr.crypto_key_size = clib_host_to_net_u32 (crypto_key_size);
1315   mp->tr.integ_alg = integ_alg;
1316
1317   S (mp);
1318   W (ret);
1319   return ret;
1320 }
1321
1322 static int
1323 api_ikev2_set_sa_lifetime (vat_main_t * vam)
1324 {
1325   unformat_input_t *i = vam->input;
1326   vl_api_ikev2_set_sa_lifetime_t *mp;
1327   int ret;
1328   u8 *name = 0;
1329   u64 lifetime, lifetime_maxdata;
1330   u32 lifetime_jitter, handover;
1331
1332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1333     {
1334       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
1335                     &lifetime, &lifetime_jitter, &handover,
1336                     &lifetime_maxdata))
1337         vec_add1 (name, 0);
1338       else
1339         {
1340           errmsg ("parse error '%U'", format_unformat_error, i);
1341           return -99;
1342         }
1343     }
1344
1345   if (!vec_len (name))
1346     {
1347       errmsg ("profile name must be specified");
1348       return -99;
1349     }
1350
1351   if (vec_len (name) > 64)
1352     {
1353       errmsg ("profile name too long");
1354       return -99;
1355     }
1356
1357   M (IKEV2_SET_SA_LIFETIME, mp);
1358
1359   clib_memcpy (mp->name, name, vec_len (name));
1360   vec_free (name);
1361   mp->lifetime = lifetime;
1362   mp->lifetime_jitter = lifetime_jitter;
1363   mp->handover = handover;
1364   mp->lifetime_maxdata = lifetime_maxdata;
1365
1366   S (mp);
1367   W (ret);
1368   return ret;
1369 }
1370
1371 static int
1372 api_ikev2_initiate_sa_init (vat_main_t * vam)
1373 {
1374   unformat_input_t *i = vam->input;
1375   vl_api_ikev2_initiate_sa_init_t *mp;
1376   int ret;
1377   u8 *name = 0;
1378
1379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1380     {
1381       if (unformat (i, "%U", unformat_token, valid_chars, &name))
1382         vec_add1 (name, 0);
1383       else
1384         {
1385           errmsg ("parse error '%U'", format_unformat_error, i);
1386           return -99;
1387         }
1388     }
1389
1390   if (!vec_len (name))
1391     {
1392       errmsg ("profile name must be specified");
1393       return -99;
1394     }
1395
1396   if (vec_len (name) > 64)
1397     {
1398       errmsg ("profile name too long");
1399       return -99;
1400     }
1401
1402   M (IKEV2_INITIATE_SA_INIT, mp);
1403
1404   clib_memcpy (mp->name, name, vec_len (name));
1405   vec_free (name);
1406
1407   S (mp);
1408   W (ret);
1409   return ret;
1410 }
1411
1412 static int
1413 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
1414 {
1415   unformat_input_t *i = vam->input;
1416   vl_api_ikev2_initiate_del_ike_sa_t *mp;
1417   int ret;
1418   u64 ispi;
1419
1420
1421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1422     {
1423       if (unformat (i, "%lx", &ispi))
1424         ;
1425       else
1426         {
1427           errmsg ("parse error '%U'", format_unformat_error, i);
1428           return -99;
1429         }
1430     }
1431
1432   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
1433
1434   mp->ispi = ispi;
1435
1436   S (mp);
1437   W (ret);
1438   return ret;
1439 }
1440
1441 static int
1442 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
1443 {
1444   unformat_input_t *i = vam->input;
1445   vl_api_ikev2_initiate_del_child_sa_t *mp;
1446   int ret;
1447   u32 ispi;
1448
1449
1450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1451     {
1452       if (unformat (i, "%x", &ispi))
1453         ;
1454       else
1455         {
1456           errmsg ("parse error '%U'", format_unformat_error, i);
1457           return -99;
1458         }
1459     }
1460
1461   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
1462
1463   mp->ispi = ispi;
1464
1465   S (mp);
1466   W (ret);
1467   return ret;
1468 }
1469
1470 static int
1471 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
1472 {
1473   unformat_input_t *i = vam->input;
1474   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
1475   int ret;
1476   u32 ispi;
1477
1478
1479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1480     {
1481       if (unformat (i, "%x", &ispi))
1482         ;
1483       else
1484         {
1485           errmsg ("parse error '%U'", format_unformat_error, i);
1486           return -99;
1487         }
1488     }
1489
1490   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
1491
1492   mp->ispi = ispi;
1493
1494   S (mp);
1495   W (ret);
1496   return ret;
1497 }
1498
1499 #include <ikev2/ikev2.api_test.c>
1500
1501 /*
1502  * fd.io coding-style-patch-verification: ON
1503  *
1504  * Local Variables:
1505  * eval: (c-set-style "gnu")
1506  * End:
1507  */