ikev2: support responder hostname
[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 <vpp/api/vpe.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 %d sa index: %d\n",
400            mp->sa.profile_index, 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",
409            format_hex_bytes, k->sk_d, k->sk_d_len);
410
411   fformat (vam->ofp, "  SK_a  i:%U\n        r:%U\n",
412            format_hex_bytes, k->sk_ai, k->sk_ai_len, format_hex_bytes,
413            k->sk_ar, k->sk_ar_len);
414
415   fformat (vam->ofp, "  SK_e  i:%U\n        r:%U\n", format_hex_bytes,
416            k->sk_ei, k->sk_ei_len, format_hex_bytes, k->sk_er, k->sk_er_len);
417
418   fformat (vam->ofp, "  SK_p  i:%U\n        r:%U\n", format_hex_bytes,
419            k->sk_pi, k->sk_pi_len, format_hex_bytes, k->sk_pr, k->sk_pr_len);
420
421   fformat (vam->ofp, "  identifier (i) %U\n",
422            format_ikev2_id_type_and_data, &sa->i_id);
423   fformat (vam->ofp, "  identifier (r) %U\n",
424            format_ikev2_id_type_and_data, &sa->r_id);
425
426   vam->result_ready = 1;
427 }
428
429 static int
430 api_ikev2_child_sa_dump (vat_main_t * vam)
431 {
432   unformat_input_t *i = vam->input;
433   ikev2_test_main_t *im = &ikev2_test_main;
434   vl_api_ikev2_child_sa_dump_t *mp;
435   vl_api_control_ping_t *mp_ping;
436   int ret;
437   u32 sa_index = ~0;
438
439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
440     {
441       if (unformat (i, "sa_index %d", &sa_index))
442         ;
443       else
444         {
445           errmsg ("parse error '%U'", format_unformat_error, i);
446           return -99;
447         }
448     }
449
450   if (sa_index == ~0)
451     return -99;
452
453   /* Construct the API message */
454   M (IKEV2_CHILD_SA_DUMP, mp);
455
456   mp->sa_index = clib_net_to_host_u32 (sa_index);
457
458   /* send it... */
459   S (mp);
460
461   /* Use a control ping for synchronization */
462   if (!im->ping_id)
463     im->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
464   mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
465   mp_ping->_vl_msg_id = htons (im->ping_id);
466   mp_ping->client_index = vam->my_client_index;
467   vam->result_ready = 0;
468
469   S (mp_ping);
470
471   /* Wait for a reply... */
472   W (ret);
473   return ret;
474 }
475
476 static void
477 vl_api_ikev2_child_sa_details_t_handler (vl_api_ikev2_child_sa_details_t * mp)
478 {
479   vat_main_t *vam = ikev2_test_main.vat_main;
480   vl_api_ikev2_child_sa_t *child_sa = &mp->child_sa;
481   vl_api_ikev2_keys_t *k = &child_sa->keys;
482   vl_api_ikev2_child_sa_t_endian (child_sa);
483
484   fformat (vam->ofp, "  child sa %u:\n", child_sa->child_sa_index);
485
486   fformat (vam->ofp, "    %U ", format_ikev2_sa_transform,
487            &child_sa->encryption);
488   fformat (vam->ofp, "%U ", format_ikev2_sa_transform, &child_sa->integrity);
489   fformat (vam->ofp, "%U \n", format_ikev2_sa_transform, &child_sa->esn);
490
491   fformat (vam->ofp, "    spi(i) %lx spi(r) %lx\n",
492            child_sa->i_spi, child_sa->r_spi);
493
494   fformat (vam->ofp, "    SK_e  i:%U\n          r:%U\n",
495            format_hex_bytes, k->sk_ei, k->sk_ei_len,
496            format_hex_bytes, k->sk_er, k->sk_er_len);
497   if (k->sk_ai_len)
498     {
499       fformat (vam->ofp, "    SK_a  i:%U\n          r:%U\n",
500                format_hex_bytes, k->sk_ai, k->sk_ai_len,
501                format_hex_bytes, k->sk_ar, k->sk_ar_len);
502     }
503   vam->result_ready = 1;
504 }
505
506 static int
507 api_ikev2_traffic_selector_dump (vat_main_t * vam)
508 {
509   unformat_input_t *i = vam->input;
510   ikev2_test_main_t *im = &ikev2_test_main;
511   vl_api_ikev2_traffic_selector_dump_t *mp;
512   vl_api_control_ping_t *mp_ping;
513   int is_initiator = ~0;
514   int sa_index = ~0;
515   int child_sa_index = ~0;
516   int ret;
517
518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
519     {
520       if (unformat (i, "initiator"))
521         is_initiator = 1;
522       else if (unformat (i, "responder"))
523         is_initiator = 0;
524       else if (unformat (i, "sa_index %d", &sa_index))
525         ;
526       else if (unformat (i, "child_sa_index %d", &child_sa_index))
527         ;
528       else
529         {
530           errmsg ("parse error '%U'", format_unformat_error, i);
531           return -99;
532         }
533     }
534
535   if (child_sa_index == ~0 || sa_index == ~0 || is_initiator == ~0)
536     return -99;
537
538   /* Construct the API message */
539   M (IKEV2_TRAFFIC_SELECTOR_DUMP, mp);
540
541   mp->is_initiator = is_initiator;
542   mp->sa_index = clib_host_to_net_u32 (sa_index);
543   mp->child_sa_index = clib_host_to_net_u32 (child_sa_index);
544
545   /* send it... */
546   S (mp);
547
548   /* Use a control ping for synchronization */
549   if (!im->ping_id)
550     im->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
551   mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
552   mp_ping->_vl_msg_id = htons (im->ping_id);
553   mp_ping->client_index = vam->my_client_index;
554   vam->result_ready = 0;
555
556   S (mp_ping);
557
558   /* Wait for a reply... */
559   W (ret);
560   return ret;
561 }
562
563 static void
564   vl_api_ikev2_traffic_selector_details_t_handler
565   (vl_api_ikev2_traffic_selector_details_t * mp)
566 {
567   vat_main_t *vam = ikev2_test_main.vat_main;
568   vl_api_ikev2_ts_t *ts = &mp->ts;
569   ip_address_t start_addr, end_addr;
570   vl_api_ikev2_ts_t_endian (ts);
571
572   ip_address_decode2 (&ts->start_addr, &start_addr);
573   ip_address_decode2 (&ts->end_addr, &end_addr);
574
575   fformat (vam->ofp, " %s protocol_id %u addr "
576            "%U - %U port %u - %u\n",
577            ts->is_local, ts->protocol_id,
578            format_ip_address, &start_addr,
579            format_ip_address, &end_addr, ts->start_port, ts->end_port);
580   vam->result_ready = 1;
581 }
582
583 static int
584 api_ikev2_nonce_get (vat_main_t * vam)
585 {
586   unformat_input_t *i = vam->input;
587   ikev2_test_main_t *im = &ikev2_test_main;
588   vl_api_ikev2_nonce_get_t *mp;
589   vl_api_control_ping_t *mp_ping;
590   u32 is_initiator = ~0;
591   u32 sa_index = ~0;
592   int ret;
593
594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
595     {
596       if (unformat (i, "initiator"))
597         is_initiator = 1;
598       else if (unformat (i, "responder"))
599         is_initiator = 0;
600       else if (unformat (i, "sa_index %d", &sa_index))
601         ;
602       else
603         {
604           errmsg ("parse error '%U'", format_unformat_error, i);
605           return -99;
606         }
607     }
608
609   if (sa_index == ~0 || is_initiator == ~0)
610     return -99;
611
612   /* Construct the API message */
613   M (IKEV2_NONCE_GET, mp);
614
615   mp->is_initiator = is_initiator;
616   mp->sa_index = clib_host_to_net_u32 (sa_index);
617
618   /* send it... */
619   S (mp);
620
621   /* Use a control ping for synchronization */
622   if (!im->ping_id)
623     im->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
624   mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
625   mp_ping->_vl_msg_id = htons (im->ping_id);
626   mp_ping->client_index = vam->my_client_index;
627   vam->result_ready = 0;
628
629   S (mp_ping);
630
631   /* Wait for a reply... */
632   W (ret);
633   return ret;
634 }
635
636 static void
637 vl_api_ikev2_nonce_get_reply_t_handler (vl_api_ikev2_nonce_get_reply_t * mp)
638 {
639   vat_main_t *vam = ikev2_test_main.vat_main;
640   mp->data_len = clib_net_to_host_u32 (mp->data_len);
641
642   fformat (vam->ofp, "  nonce:%U\n",
643            format_hex_bytes, mp->nonce, mp->data_len);
644
645   vam->result_ready = 1;
646 }
647
648 static int
649 api_ikev2_plugin_get_version (vat_main_t * vam)
650 {
651   ikev2_test_main_t *sm = &ikev2_test_main;
652   vl_api_ikev2_plugin_get_version_t *mp;
653   u32 msg_size = sizeof (*mp);
654   int ret;
655
656   vam->result_ready = 0;
657   mp = vl_msg_api_alloc_as_if_client (msg_size);
658   clib_memset (mp, 0, msg_size);
659   mp->_vl_msg_id = ntohs (VL_API_IKEV2_PLUGIN_GET_VERSION + sm->msg_id_base);
660   mp->client_index = vam->my_client_index;
661
662   /* send it... */
663   S (mp);
664
665   /* Wait for a reply... */
666   W (ret);
667   return ret;
668 }
669
670 static void vl_api_ikev2_plugin_get_version_reply_t_handler
671   (vl_api_ikev2_plugin_get_version_reply_t * mp)
672 {
673   vat_main_t *vam = ikev2_test_main.vat_main;
674   clib_warning ("IKEv2 plugin version: %d.%d", ntohl (mp->major),
675                 ntohl (mp->minor));
676   vam->result_ready = 1;
677 }
678
679 static int
680 api_ikev2_profile_set_ipsec_udp_port (vat_main_t * vam)
681 {
682   return 0;
683 }
684
685 static int
686 api_ikev2_profile_set_liveness (vat_main_t * vam)
687 {
688   unformat_input_t *i = vam->input;
689   vl_api_ikev2_profile_set_liveness_t *mp;
690   u32 period = 0, max_retries = 0;
691   int ret;
692
693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
694     {
695       if (!unformat (i, "period %d max-retries %d", &period, &max_retries))
696         {
697           errmsg ("parse error '%U'", format_unformat_error, i);
698           return -99;
699         }
700     }
701
702   M (IKEV2_PROFILE_SET_LIVENESS, mp);
703
704   mp->period = clib_host_to_net_u32 (period);
705   mp->max_retries = clib_host_to_net_u32 (max_retries);
706
707   S (mp);
708   W (ret);
709
710   return ret;
711 }
712
713 static int
714 api_ikev2_profile_add_del (vat_main_t * vam)
715 {
716   unformat_input_t *i = vam->input;
717   vl_api_ikev2_profile_add_del_t *mp;
718   u8 is_add = 1;
719   u8 *name = 0;
720   int ret;
721
722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
723     {
724       if (unformat (i, "del"))
725         is_add = 0;
726       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
727         vec_add1 (name, 0);
728       else
729         {
730           errmsg ("parse error '%U'", format_unformat_error, i);
731           return -99;
732         }
733     }
734
735   if (!vec_len (name))
736     {
737       errmsg ("profile name must be specified");
738       return -99;
739     }
740
741   if (vec_len (name) > 64)
742     {
743       errmsg ("profile name too long");
744       return -99;
745     }
746
747   M (IKEV2_PROFILE_ADD_DEL, mp);
748
749   clib_memcpy (mp->name, name, vec_len (name));
750   mp->is_add = is_add;
751   vec_free (name);
752
753   S (mp);
754   W (ret);
755   return ret;
756 }
757
758 static int
759 api_ikev2_profile_set_auth (vat_main_t * vam)
760 {
761   unformat_input_t *i = vam->input;
762   vl_api_ikev2_profile_set_auth_t *mp;
763   u8 *name = 0;
764   u8 *data = 0;
765   u32 auth_method = 0;
766   u8 is_hex = 0;
767   int ret;
768
769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
770     {
771       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
772         vec_add1 (name, 0);
773       else if (unformat (i, "auth_method %U",
774                          unformat_ikev2_auth_method, &auth_method))
775         ;
776       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
777         is_hex = 1;
778       else if (unformat (i, "auth_data %v", &data))
779         ;
780       else
781         {
782           errmsg ("parse error '%U'", format_unformat_error, i);
783           return -99;
784         }
785     }
786
787   if (!vec_len (name))
788     {
789       errmsg ("profile name must be specified");
790       return -99;
791     }
792
793   if (vec_len (name) > 64)
794     {
795       errmsg ("profile name too long");
796       return -99;
797     }
798
799   if (!vec_len (data))
800     {
801       errmsg ("auth_data must be specified");
802       return -99;
803     }
804
805   if (!auth_method)
806     {
807       errmsg ("auth_method must be specified");
808       return -99;
809     }
810
811   M (IKEV2_PROFILE_SET_AUTH, mp);
812
813   mp->is_hex = is_hex;
814   mp->auth_method = (u8) auth_method;
815   mp->data_len = vec_len (data);
816   clib_memcpy (mp->name, name, vec_len (name));
817   clib_memcpy (mp->data, data, vec_len (data));
818   vec_free (name);
819   vec_free (data);
820
821   S (mp);
822   W (ret);
823   return ret;
824 }
825
826 static int
827 api_ikev2_profile_set_id (vat_main_t * vam)
828 {
829   unformat_input_t *i = vam->input;
830   vl_api_ikev2_profile_set_id_t *mp;
831   u8 *name = 0;
832   u8 *data = 0;
833   u8 is_local = 0;
834   u32 id_type = 0;
835   ip_address_t ip;
836   int ret;
837
838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
839     {
840       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
841         vec_add1 (name, 0);
842       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
843         ;
844       else if (unformat (i, "id_data %U", unformat_ip_address, &ip))
845         {
846           data = vec_new (u8, ip_address_size (&ip));
847           clib_memcpy (data, ip_addr_bytes (&ip), ip_address_size (&ip));
848         }
849       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
850         ;
851       else if (unformat (i, "id_data %v", &data))
852         ;
853       else if (unformat (i, "local"))
854         is_local = 1;
855       else if (unformat (i, "remote"))
856         is_local = 0;
857       else
858         {
859           errmsg ("parse error '%U'", format_unformat_error, i);
860           return -99;
861         }
862     }
863
864   if (!vec_len (name))
865     {
866       errmsg ("profile name must be specified");
867       return -99;
868     }
869
870   if (vec_len (name) > 64)
871     {
872       errmsg ("profile name too long");
873       return -99;
874     }
875
876   if (!vec_len (data))
877     {
878       errmsg ("id_data must be specified");
879       return -99;
880     }
881
882   if (!id_type)
883     {
884       errmsg ("id_type must be specified");
885       return -99;
886     }
887
888   M (IKEV2_PROFILE_SET_ID, mp);
889
890   mp->is_local = is_local;
891   mp->id_type = (u8) id_type;
892   mp->data_len = vec_len (data);
893   clib_memcpy (mp->name, name, vec_len (name));
894   clib_memcpy (mp->data, data, vec_len (data));
895   vec_free (name);
896   vec_free (data);
897
898   S (mp);
899   W (ret);
900   return ret;
901 }
902
903 static int
904 api_ikev2_profile_set_ts (vat_main_t * vam)
905 {
906   unformat_input_t *i = vam->input;
907   vl_api_ikev2_profile_set_ts_t *mp;
908   u8 *name = 0;
909   u8 is_local = 0;
910   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
911   ip_address_t start_addr, end_addr;
912   u8 start_addr_set = 0, end_addr_set = 0;
913   int ret;
914
915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
916     {
917       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
918         vec_add1 (name, 0);
919       else if (unformat (i, "protocol %d", &proto))
920         ;
921       else if (unformat (i, "start_port %d", &start_port))
922         ;
923       else if (unformat (i, "end_port %d", &end_port))
924         ;
925       else
926         if (unformat (i, "start_addr %U", unformat_ip_address, &start_addr))
927         start_addr_set = 1;
928       else if (unformat (i, "end_addr %U", unformat_ip_address, &end_addr))
929         end_addr_set = 1;
930       else if (unformat (i, "local"))
931         is_local = 1;
932       else if (unformat (i, "remote"))
933         is_local = 0;
934       else
935         {
936           errmsg ("parse error '%U'", format_unformat_error, i);
937           return -99;
938         }
939     }
940
941   if (!start_addr_set || !end_addr_set)
942     {
943       errmsg ("missing start or end address");
944       return -99;
945     }
946
947   if (!vec_len (name))
948     {
949       errmsg ("profile name must be specified");
950       return -99;
951     }
952
953   if (vec_len (name) > 64)
954     {
955       errmsg ("profile name too long");
956       return -99;
957     }
958
959   M (IKEV2_PROFILE_SET_TS, mp);
960
961   mp->ts.is_local = is_local;
962   mp->ts.protocol_id = (u8) proto;
963   mp->ts.start_port = clib_host_to_net_u16 ((u16) start_port);
964   mp->ts.end_port = clib_host_to_net_u16 ((u16) end_port);
965   ip_address_encode2 (&start_addr, &mp->ts.start_addr);
966   ip_address_encode2 (&end_addr, &mp->ts.end_addr);
967   clib_memcpy (mp->name, name, vec_len (name));
968   vec_free (name);
969
970   S (mp);
971   W (ret);
972   return ret;
973 }
974
975 static int
976 api_ikev2_set_local_key (vat_main_t * vam)
977 {
978   unformat_input_t *i = vam->input;
979   vl_api_ikev2_set_local_key_t *mp;
980   u8 *file = 0;
981   int ret;
982
983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
984     {
985       if (unformat (i, "file %v", &file))
986         vec_add1 (file, 0);
987       else
988         {
989           errmsg ("parse error '%U'", format_unformat_error, i);
990           return -99;
991         }
992     }
993
994   if (!vec_len (file))
995     {
996       errmsg ("RSA key file must be specified");
997       return -99;
998     }
999
1000   if (vec_len (file) > 256)
1001     {
1002       errmsg ("file name too long");
1003       return -99;
1004     }
1005
1006   M (IKEV2_SET_LOCAL_KEY, mp);
1007
1008   clib_memcpy (mp->key_file, file, vec_len (file));
1009   vec_free (file);
1010
1011   S (mp);
1012   W (ret);
1013   return ret;
1014 }
1015
1016 static int
1017 api_ikev2_profile_set_udp_encap (vat_main_t * vam)
1018 {
1019   unformat_input_t *i = vam->input;
1020   vl_api_ikev2_profile_set_udp_encap_t *mp;
1021   int ret;
1022   u8 *name = 0;
1023
1024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1025     {
1026       if (unformat (i, "%U udp-encap", unformat_token, valid_chars, &name))
1027         vec_add1 (name, 0);
1028       else
1029         {
1030           errmsg ("parse error '%U'", format_unformat_error, i);
1031           return -99;
1032         }
1033     }
1034
1035   if (!vec_len (name))
1036     {
1037       errmsg ("profile name must be specified");
1038       return -99;
1039     }
1040
1041   if (vec_len (name) > 64)
1042     {
1043       errmsg ("profile name too long");
1044       return -99;
1045     }
1046
1047   M (IKEV2_PROFILE_SET_UDP_ENCAP, mp);
1048
1049   clib_memcpy (mp->name, name, vec_len (name));
1050   vec_free (name);
1051
1052   S (mp);
1053   W (ret);
1054   return ret;
1055 }
1056
1057 static int
1058 api_ikev2_set_tunnel_interface (vat_main_t * vam)
1059 {
1060   return (0);
1061 }
1062
1063 static int
1064 api_ikev2_set_responder_hostname (vat_main_t *vam)
1065 {
1066   unformat_input_t *i = vam->input;
1067   vl_api_ikev2_set_responder_hostname_t *mp;
1068   int ret;
1069   u8 *name = 0, *hn = 0;
1070
1071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1072     {
1073       if (unformat (i, "%U hostname %v", unformat_token, valid_chars, &name,
1074                     &hn))
1075         {
1076           vec_add1 (name, 0);
1077           vec_add1 (hn, 0);
1078         }
1079       else
1080         {
1081           errmsg ("parse error '%U'", format_unformat_error, i);
1082           return -99;
1083         }
1084     }
1085
1086   if (!vec_len (name))
1087     {
1088       errmsg ("profile name must be specified");
1089       return -99;
1090     }
1091
1092   if (vec_len (name) > 64)
1093     {
1094       errmsg ("profile name too long");
1095       return -99;
1096     }
1097
1098   M (IKEV2_SET_RESPONDER_HOSTNAME, mp);
1099
1100   clib_memcpy (mp->name, name, vec_len (name));
1101   clib_memcpy (mp->hostname, hn, vec_len (hn));
1102   vec_free (name);
1103   vec_free (hn);
1104
1105   S (mp);
1106   W (ret);
1107   return ret;
1108 }
1109
1110 static int
1111 api_ikev2_set_responder (vat_main_t * vam)
1112 {
1113   unformat_input_t *i = vam->input;
1114   vl_api_ikev2_set_responder_t *mp;
1115   int ret;
1116   u8 *name = 0;
1117   u32 sw_if_index = ~0;
1118   ip_address_t address;
1119
1120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1121     {
1122       if (unformat
1123           (i, "%U interface %d address %U", unformat_token, valid_chars,
1124            &name, &sw_if_index, unformat_ip_address, &address))
1125         vec_add1 (name, 0);
1126       else
1127         {
1128           errmsg ("parse error '%U'", format_unformat_error, i);
1129           return -99;
1130         }
1131     }
1132
1133   if (!vec_len (name))
1134     {
1135       errmsg ("profile name must be specified");
1136       return -99;
1137     }
1138
1139   if (vec_len (name) > 64)
1140     {
1141       errmsg ("profile name too long");
1142       return -99;
1143     }
1144
1145   M (IKEV2_SET_RESPONDER, mp);
1146
1147   clib_memcpy (mp->name, name, vec_len (name));
1148   vec_free (name);
1149
1150   mp->responder.sw_if_index = clib_host_to_net_u32 (sw_if_index);
1151   ip_address_encode2 (&address, &mp->responder.addr);
1152
1153   S (mp);
1154   W (ret);
1155   return ret;
1156 }
1157
1158 static int
1159 api_ikev2_set_ike_transforms (vat_main_t * vam)
1160 {
1161   unformat_input_t *i = vam->input;
1162   vl_api_ikev2_set_ike_transforms_t *mp;
1163   int ret;
1164   u8 *name = 0;
1165   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
1166
1167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1168     {
1169       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
1170                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
1171         vec_add1 (name, 0);
1172       else
1173         {
1174           errmsg ("parse error '%U'", format_unformat_error, i);
1175           return -99;
1176         }
1177     }
1178
1179   if (!vec_len (name))
1180     {
1181       errmsg ("profile name must be specified");
1182       return -99;
1183     }
1184
1185   if (vec_len (name) > 64)
1186     {
1187       errmsg ("profile name too long");
1188       return -99;
1189     }
1190
1191   M (IKEV2_SET_IKE_TRANSFORMS, mp);
1192
1193   clib_memcpy (mp->name, name, vec_len (name));
1194   vec_free (name);
1195   mp->tr.crypto_alg = crypto_alg;
1196   mp->tr.crypto_key_size = clib_host_to_net_u32 (crypto_key_size);
1197   mp->tr.integ_alg = integ_alg;
1198   mp->tr.dh_group = dh_group;
1199
1200   S (mp);
1201   W (ret);
1202   return ret;
1203 }
1204
1205
1206 static int
1207 api_ikev2_set_esp_transforms (vat_main_t * vam)
1208 {
1209   unformat_input_t *i = vam->input;
1210   vl_api_ikev2_set_esp_transforms_t *mp;
1211   int ret;
1212   u8 *name = 0;
1213   u32 crypto_alg, crypto_key_size, integ_alg;
1214
1215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1216     {
1217       if (unformat (i, "%U %d %d %d", unformat_token, valid_chars, &name,
1218                     &crypto_alg, &crypto_key_size, &integ_alg))
1219         vec_add1 (name, 0);
1220       else
1221         {
1222           errmsg ("parse error '%U'", format_unformat_error, i);
1223           return -99;
1224         }
1225     }
1226
1227   if (!vec_len (name))
1228     {
1229       errmsg ("profile name must be specified");
1230       return -99;
1231     }
1232
1233   if (vec_len (name) > 64)
1234     {
1235       errmsg ("profile name too long");
1236       return -99;
1237     }
1238
1239   M (IKEV2_SET_ESP_TRANSFORMS, mp);
1240
1241   clib_memcpy (mp->name, name, vec_len (name));
1242   vec_free (name);
1243   mp->tr.crypto_alg = crypto_alg;
1244   mp->tr.crypto_key_size = clib_host_to_net_u32 (crypto_key_size);
1245   mp->tr.integ_alg = integ_alg;
1246
1247   S (mp);
1248   W (ret);
1249   return ret;
1250 }
1251
1252 static int
1253 api_ikev2_set_sa_lifetime (vat_main_t * vam)
1254 {
1255   unformat_input_t *i = vam->input;
1256   vl_api_ikev2_set_sa_lifetime_t *mp;
1257   int ret;
1258   u8 *name = 0;
1259   u64 lifetime, lifetime_maxdata;
1260   u32 lifetime_jitter, handover;
1261
1262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1263     {
1264       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
1265                     &lifetime, &lifetime_jitter, &handover,
1266                     &lifetime_maxdata))
1267         vec_add1 (name, 0);
1268       else
1269         {
1270           errmsg ("parse error '%U'", format_unformat_error, i);
1271           return -99;
1272         }
1273     }
1274
1275   if (!vec_len (name))
1276     {
1277       errmsg ("profile name must be specified");
1278       return -99;
1279     }
1280
1281   if (vec_len (name) > 64)
1282     {
1283       errmsg ("profile name too long");
1284       return -99;
1285     }
1286
1287   M (IKEV2_SET_SA_LIFETIME, mp);
1288
1289   clib_memcpy (mp->name, name, vec_len (name));
1290   vec_free (name);
1291   mp->lifetime = lifetime;
1292   mp->lifetime_jitter = lifetime_jitter;
1293   mp->handover = handover;
1294   mp->lifetime_maxdata = lifetime_maxdata;
1295
1296   S (mp);
1297   W (ret);
1298   return ret;
1299 }
1300
1301 static int
1302 api_ikev2_initiate_sa_init (vat_main_t * vam)
1303 {
1304   unformat_input_t *i = vam->input;
1305   vl_api_ikev2_initiate_sa_init_t *mp;
1306   int ret;
1307   u8 *name = 0;
1308
1309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1310     {
1311       if (unformat (i, "%U", unformat_token, valid_chars, &name))
1312         vec_add1 (name, 0);
1313       else
1314         {
1315           errmsg ("parse error '%U'", format_unformat_error, i);
1316           return -99;
1317         }
1318     }
1319
1320   if (!vec_len (name))
1321     {
1322       errmsg ("profile name must be specified");
1323       return -99;
1324     }
1325
1326   if (vec_len (name) > 64)
1327     {
1328       errmsg ("profile name too long");
1329       return -99;
1330     }
1331
1332   M (IKEV2_INITIATE_SA_INIT, mp);
1333
1334   clib_memcpy (mp->name, name, vec_len (name));
1335   vec_free (name);
1336
1337   S (mp);
1338   W (ret);
1339   return ret;
1340 }
1341
1342 static int
1343 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
1344 {
1345   unformat_input_t *i = vam->input;
1346   vl_api_ikev2_initiate_del_ike_sa_t *mp;
1347   int ret;
1348   u64 ispi;
1349
1350
1351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1352     {
1353       if (unformat (i, "%lx", &ispi))
1354         ;
1355       else
1356         {
1357           errmsg ("parse error '%U'", format_unformat_error, i);
1358           return -99;
1359         }
1360     }
1361
1362   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
1363
1364   mp->ispi = ispi;
1365
1366   S (mp);
1367   W (ret);
1368   return ret;
1369 }
1370
1371 static int
1372 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
1373 {
1374   unformat_input_t *i = vam->input;
1375   vl_api_ikev2_initiate_del_child_sa_t *mp;
1376   int ret;
1377   u32 ispi;
1378
1379
1380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1381     {
1382       if (unformat (i, "%x", &ispi))
1383         ;
1384       else
1385         {
1386           errmsg ("parse error '%U'", format_unformat_error, i);
1387           return -99;
1388         }
1389     }
1390
1391   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
1392
1393   mp->ispi = ispi;
1394
1395   S (mp);
1396   W (ret);
1397   return ret;
1398 }
1399
1400 static int
1401 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
1402 {
1403   unformat_input_t *i = vam->input;
1404   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
1405   int ret;
1406   u32 ispi;
1407
1408
1409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1410     {
1411       if (unformat (i, "%x", &ispi))
1412         ;
1413       else
1414         {
1415           errmsg ("parse error '%U'", format_unformat_error, i);
1416           return -99;
1417         }
1418     }
1419
1420   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
1421
1422   mp->ispi = ispi;
1423
1424   S (mp);
1425   W (ret);
1426   return ret;
1427 }
1428
1429 #include <ikev2/ikev2.api_test.c>
1430
1431 /*
1432  * fd.io coding-style-patch-verification: ON
1433  *
1434  * Local Variables:
1435  * eval: (c-set-style "gnu")
1436  * End:
1437  */