ikev2: add support for custom ipsec-over-udp port
[vpp.git] / src / plugins / ikev2 / ikev2_cli.c
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <vlib/vlib.h>
16 #include <vnet/vnet.h>
17 #include <vnet/pg/pg.h>
18 #include <vppinfra/error.h>
19 #include <vnet/udp/udp.h>
20 #include <vnet/ipsec/ipsec_sa.h>
21 #include <plugins/ikev2/ikev2.h>
22 #include <plugins/ikev2/ikev2_priv.h>
23
24 u8 *
25 format_ikev2_id_type_and_data (u8 * s, va_list * args)
26 {
27   ikev2_id_t *id = va_arg (*args, ikev2_id_t *);
28
29   if (id->type == 0 || vec_len (id->data) == 0)
30     return format (s, "none");
31
32   s = format (s, "%U", format_ikev2_id_type, id->type);
33
34   if (id->type == IKEV2_ID_TYPE_ID_FQDN ||
35       id->type == IKEV2_ID_TYPE_ID_RFC822_ADDR)
36     {
37       s = format (s, " %v", id->data);
38     }
39   else
40     {
41       s =
42         format (s, " %U", format_hex_bytes, &id->data,
43                 (uword) (vec_len (id->data)));
44     }
45
46   return s;
47 }
48
49
50 static clib_error_t *
51 show_ikev2_sa_command_fn (vlib_main_t * vm,
52                           unformat_input_t * input, vlib_cli_command_t * cmd)
53 {
54   ikev2_main_t *km = &ikev2_main;
55   ikev2_main_per_thread_data_t *tkm;
56   ikev2_sa_t *sa;
57   ikev2_ts_t *ts;
58   ikev2_child_sa_t *child;
59   ikev2_sa_transform_t *tr;
60
61   vec_foreach (tkm, km->per_thread_data)
62   {
63     /* *INDENT-OFF* */
64     pool_foreach (sa, tkm->sas, ({
65       u8 * s = 0;
66       vlib_cli_output(vm, " iip %U ispi %lx rip %U rspi %lx",
67                       format_ip4_address, &sa->iaddr, sa->ispi,
68                       format_ip4_address, &sa->raddr, sa->rspi);
69
70        tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
71        s = format(s, "%U ", format_ikev2_sa_transform, tr);
72
73        tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);
74        s = format(s, "%U ", format_ikev2_sa_transform, tr);
75
76        tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);
77        s = format(s, "%U ", format_ikev2_sa_transform, tr);
78
79        tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_DH);
80        s = format(s, "%U ", format_ikev2_sa_transform, tr);
81
82       vlib_cli_output(vm, " %v", s);
83       vec_free(s);
84
85       vlib_cli_output(vm, "  nonce i:%U\n        r:%U",
86                       format_hex_bytes, sa->i_nonce,  vec_len(sa->i_nonce),
87                       format_hex_bytes, sa->r_nonce,  vec_len(sa->r_nonce));
88
89       vlib_cli_output(vm, "  SK_d    %U",
90                       format_hex_bytes, sa->sk_d,  vec_len(sa->sk_d));
91       vlib_cli_output(vm, "  SK_a  i:%U\n        r:%U",
92                       format_hex_bytes, sa->sk_ai, vec_len(sa->sk_ai),
93                       format_hex_bytes, sa->sk_ar, vec_len(sa->sk_ar));
94       vlib_cli_output(vm, "  SK_e  i:%U\n        r:%U",
95                       format_hex_bytes, sa->sk_ei, vec_len(sa->sk_ei),
96                       format_hex_bytes, sa->sk_er, vec_len(sa->sk_er));
97       vlib_cli_output(vm, "  SK_p  i:%U\n        r:%U",
98                       format_hex_bytes, sa->sk_pi, vec_len(sa->sk_pi),
99                       format_hex_bytes, sa->sk_pr, vec_len(sa->sk_pr));
100
101       vlib_cli_output(vm, "  identifier (i) %U",
102                       format_ikev2_id_type_and_data, &sa->i_id);
103       vlib_cli_output(vm, "  identifier (r) %U",
104                       format_ikev2_id_type_and_data, &sa->r_id);
105
106       vec_foreach(child, sa->childs)
107         {
108           vlib_cli_output(vm, "  child sa %u:", child - sa->childs);
109
110           tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
111           s = format(s, "%U ", format_ikev2_sa_transform, tr);
112
113           tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);
114           s = format(s, "%U ", format_ikev2_sa_transform, tr);
115
116           tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_ESN);
117           s = format(s, "%U ", format_ikev2_sa_transform, tr);
118
119           vlib_cli_output(vm, "    %v", s);
120           vec_free(s);
121
122           vlib_cli_output(vm, "    spi(i) %lx spi(r) %lx",
123                           child->i_proposals ? child->i_proposals[0].spi : 0,
124                           child->r_proposals ? child->r_proposals[0].spi : 0);
125
126           vlib_cli_output(vm, "    SK_e  i:%U\n          r:%U",
127                           format_hex_bytes, child->sk_ei, vec_len(child->sk_ei),
128                           format_hex_bytes, child->sk_er, vec_len(child->sk_er));
129           if (child->sk_ai)
130             {
131               vlib_cli_output(vm, "    SK_a  i:%U\n          r:%U",
132                               format_hex_bytes, child->sk_ai, vec_len(child->sk_ai),
133                               format_hex_bytes, child->sk_ar, vec_len(child->sk_ar));
134               vlib_cli_output(vm, "    traffic selectors (i):");
135             }
136           vec_foreach(ts, child->tsi)
137             {
138               vlib_cli_output(vm, "      %u type %u protocol_id %u addr "
139                               "%U - %U port %u - %u",
140                               ts - child->tsi,
141                               ts->ts_type, ts->protocol_id,
142                               format_ip4_address, &ts->start_addr,
143                               format_ip4_address, &ts->end_addr,
144                               clib_net_to_host_u16( ts->start_port),
145                               clib_net_to_host_u16( ts->end_port));
146             }
147           vlib_cli_output(vm, "    traffic selectors (r):");
148           vec_foreach(ts, child->tsr)
149             {
150               vlib_cli_output(vm, "      %u type %u protocol_id %u addr "
151                               "%U - %U port %u - %u",
152                               ts - child->tsr,
153                               ts->ts_type, ts->protocol_id,
154                               format_ip4_address, &ts->start_addr,
155                               format_ip4_address, &ts->end_addr,
156                               clib_net_to_host_u16( ts->start_port),
157                               clib_net_to_host_u16( ts->end_port));
158             }
159         }
160       vlib_cli_output(vm, "");
161     }));
162     /* *INDENT-ON* */
163   }
164   return 0;
165 }
166
167 /* *INDENT-OFF* */
168 VLIB_CLI_COMMAND (show_ikev2_sa_command, static) = {
169     .path = "show ikev2 sa",
170     .short_help = "show ikev2 sa",
171     .function = show_ikev2_sa_command_fn,
172 };
173 /* *INDENT-ON* */
174
175 static clib_error_t *
176 ikev2_profile_add_del_command_fn (vlib_main_t * vm,
177                                   unformat_input_t * input,
178                                   vlib_cli_command_t * cmd)
179 {
180   vnet_main_t *vnm = vnet_get_main ();
181   unformat_input_t _line_input, *line_input = &_line_input;
182   u8 *name = 0;
183   clib_error_t *r = 0;
184   u32 id_type;
185   u8 *data = 0;
186   u32 tmp1, tmp2, tmp3;
187   u64 tmp4, tmp5;
188   ip4_address_t ip4;
189   ip4_address_t end_addr;
190   u32 responder_sw_if_index = (u32) ~ 0;
191   u32 tun_sw_if_index = (u32) ~ 0;
192   ip4_address_t responder_ip4;
193   ikev2_transform_encr_type_t crypto_alg;
194   ikev2_transform_integ_type_t integ_alg;
195   ikev2_transform_dh_type_t dh_type;
196
197   const char *valid_chars = "a-zA-Z0-9_";
198
199   if (!unformat_user (input, unformat_line_input, line_input))
200     return 0;
201
202   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
203     {
204       if (unformat (line_input, "add %U", unformat_token, valid_chars, &name))
205         {
206           r = ikev2_add_del_profile (vm, name, 1);
207           goto done;
208         }
209       else
210         if (unformat
211             (line_input, "del %U", unformat_token, valid_chars, &name))
212         {
213           r = ikev2_add_del_profile (vm, name, 0);
214           goto done;
215         }
216       else if (unformat (line_input, "set %U auth shared-key-mic string %v",
217                          unformat_token, valid_chars, &name, &data))
218         {
219           r =
220             ikev2_set_profile_auth (vm, name,
221                                     IKEV2_AUTH_METHOD_SHARED_KEY_MIC, data,
222                                     0);
223           goto done;
224         }
225       else if (unformat (line_input, "set %U auth shared-key-mic hex %U",
226                          unformat_token, valid_chars, &name,
227                          unformat_hex_string, &data))
228         {
229           r =
230             ikev2_set_profile_auth (vm, name,
231                                     IKEV2_AUTH_METHOD_SHARED_KEY_MIC, data,
232                                     1);
233           goto done;
234         }
235       else if (unformat (line_input, "set %U auth rsa-sig cert-file %v",
236                          unformat_token, valid_chars, &name, &data))
237         {
238           r =
239             ikev2_set_profile_auth (vm, name, IKEV2_AUTH_METHOD_RSA_SIG, data,
240                                     0);
241           goto done;
242         }
243       else if (unformat (line_input, "set %U id local %U %U",
244                          unformat_token, valid_chars, &name,
245                          unformat_ikev2_id_type, &id_type,
246                          unformat_ip4_address, &ip4))
247         {
248           data = vec_new (u8, 4);
249           clib_memcpy (data, ip4.as_u8, 4);
250           r =
251             ikev2_set_profile_id (vm, name, (u8) id_type, data, /*local */ 1);
252           goto done;
253         }
254       else if (unformat (line_input, "set %U id local %U 0x%U",
255                          unformat_token, valid_chars, &name,
256                          unformat_ikev2_id_type, &id_type,
257                          unformat_hex_string, &data))
258         {
259           r =
260             ikev2_set_profile_id (vm, name, (u8) id_type, data, /*local */ 1);
261           goto done;
262         }
263       else if (unformat (line_input, "set %U id local %U %v",
264                          unformat_token, valid_chars, &name,
265                          unformat_ikev2_id_type, &id_type, &data))
266         {
267           r =
268             ikev2_set_profile_id (vm, name, (u8) id_type, data, /*local */ 1);
269           goto done;
270         }
271       else if (unformat (line_input, "set %U id remote %U %U",
272                          unformat_token, valid_chars, &name,
273                          unformat_ikev2_id_type, &id_type,
274                          unformat_ip4_address, &ip4))
275         {
276           data = vec_new (u8, 4);
277           clib_memcpy (data, ip4.as_u8, 4);
278           r = ikev2_set_profile_id (vm, name, (u8) id_type, data,       /*remote */
279                                     0);
280           goto done;
281         }
282       else if (unformat (line_input, "set %U id remote %U 0x%U",
283                          unformat_token, valid_chars, &name,
284                          unformat_ikev2_id_type, &id_type,
285                          unformat_hex_string, &data))
286         {
287           r = ikev2_set_profile_id (vm, name, (u8) id_type, data,       /*remote */
288                                     0);
289           goto done;
290         }
291       else if (unformat (line_input, "set %U id remote %U %v",
292                          unformat_token, valid_chars, &name,
293                          unformat_ikev2_id_type, &id_type, &data))
294         {
295           r = ikev2_set_profile_id (vm, name, (u8) id_type, data,       /*remote */
296                                     0);
297           goto done;
298         }
299       else if (unformat (line_input, "set %U traffic-selector local "
300                          "ip-range %U - %U port-range %u - %u protocol %u",
301                          unformat_token, valid_chars, &name,
302                          unformat_ip4_address, &ip4,
303                          unformat_ip4_address, &end_addr,
304                          &tmp1, &tmp2, &tmp3))
305         {
306           r =
307             ikev2_set_profile_ts (vm, name, (u8) tmp3, (u16) tmp1, (u16) tmp2,
308                                   ip4, end_addr, /*local */ 1);
309           goto done;
310         }
311       else if (unformat (line_input, "set %U traffic-selector remote "
312                          "ip-range %U - %U port-range %u - %u protocol %u",
313                          unformat_token, valid_chars, &name,
314                          unformat_ip4_address, &ip4,
315                          unformat_ip4_address, &end_addr,
316                          &tmp1, &tmp2, &tmp3))
317         {
318           r =
319             ikev2_set_profile_ts (vm, name, (u8) tmp3, (u16) tmp1, (u16) tmp2,
320                                   ip4, end_addr, /*remote */ 0);
321           goto done;
322         }
323       else if (unformat (line_input, "set %U responder %U %U",
324                          unformat_token, valid_chars, &name,
325                          unformat_vnet_sw_interface, vnm,
326                          &responder_sw_if_index, unformat_ip4_address,
327                          &responder_ip4))
328         {
329           r =
330             ikev2_set_profile_responder (vm, name, responder_sw_if_index,
331                                          responder_ip4);
332           goto done;
333         }
334       else if (unformat (line_input, "set %U tunnel %U",
335                          unformat_token, valid_chars, &name,
336                          unformat_vnet_sw_interface, vnm, &tun_sw_if_index))
337         {
338           r = ikev2_set_profile_tunnel_interface (vm, name, tun_sw_if_index);
339           goto done;
340         }
341       else
342         if (unformat
343             (line_input,
344              "set %U ike-crypto-alg %U %u ike-integ-alg %U ike-dh %U",
345              unformat_token, valid_chars, &name,
346              unformat_ikev2_transform_encr_type, &crypto_alg, &tmp1,
347              unformat_ikev2_transform_integ_type, &integ_alg,
348              unformat_ikev2_transform_dh_type, &dh_type))
349         {
350           r =
351             ikev2_set_profile_ike_transforms (vm, name, crypto_alg, integ_alg,
352                                               dh_type, tmp1);
353           goto done;
354         }
355       else
356         if (unformat
357             (line_input,
358              "set %U esp-crypto-alg %U %u esp-integ-alg %U esp-dh %U",
359              unformat_token, valid_chars, &name,
360              unformat_ikev2_transform_encr_type, &crypto_alg, &tmp1,
361              unformat_ikev2_transform_integ_type, &integ_alg,
362              unformat_ikev2_transform_dh_type, &dh_type))
363         {
364           r =
365             ikev2_set_profile_esp_transforms (vm, name, crypto_alg, integ_alg,
366                                               dh_type, tmp1);
367           goto done;
368         }
369       else if (unformat
370                (line_input,
371                 "set %U esp-crypto-alg %U %u esp-dh %U",
372                 unformat_token, valid_chars, &name,
373                 unformat_ikev2_transform_encr_type, &crypto_alg, &tmp1,
374                 unformat_ikev2_transform_dh_type, &dh_type))
375         {
376           r =
377             ikev2_set_profile_esp_transforms (vm, name, crypto_alg, 0,
378                                               dh_type, tmp1);
379           goto done;
380         }
381       else if (unformat (line_input, "set %U sa-lifetime %lu %u %u %lu",
382                          unformat_token, valid_chars, &name,
383                          &tmp4, &tmp1, &tmp2, &tmp5))
384         {
385           r =
386             ikev2_set_profile_sa_lifetime (vm, name, tmp4, tmp1, tmp2, tmp5);
387           goto done;
388         }
389       else if (unformat (line_input, "set %U udp-encap",
390                          unformat_token, valid_chars, &name))
391         {
392           r = ikev2_set_profile_udp_encap (vm, name);
393           goto done;
394         }
395       else if (unformat (line_input, "set %U ipsec-over-udp port %u",
396                          unformat_token, valid_chars, &name, &tmp1))
397         {
398           int rv = ikev2_set_profile_ipsec_udp_port (vm, name, tmp1, 1);
399           if (rv)
400             r = clib_error_return (0, "Error: %U", format_vnet_api_errno, rv);
401           goto done;
402         }
403       else
404         break;
405     }
406
407   r = clib_error_return (0, "parse error: '%U'",
408                          format_unformat_error, line_input);
409
410 done:
411   vec_free (name);
412   vec_free (data);
413   unformat_free (line_input);
414   return r;
415 }
416
417 /* *INDENT-OFF* */
418 VLIB_CLI_COMMAND (ikev2_profile_add_del_command, static) = {
419     .path = "ikev2 profile",
420     .short_help =
421     "ikev2 profile [add|del] <id>\n"
422     "ikev2 profile set <id> auth [rsa-sig|shared-key-mic] [cert-file|string|hex]"
423     " <data>\n"
424     "ikev2 profile set <id> id <local|remote> <type> <data>\n"
425     "ikev2 profile set <id> tunnel <interface>\n"
426     "ikev2 profile set <id> udp-encap\n"
427     "ikev2 profile set <id> traffic-selector <local|remote> ip-range "
428     "<start-addr> - <end-addr> port-range <start-port> - <end-port> "
429     "protocol <protocol-number>\n"
430     "ikev2 profile set <id> responder <interface> <addr>\n"
431     "ikev2 profile set <id> ike-crypto-alg <crypto alg> <key size> ike-integ-alg <integ alg> ike-dh <dh type>\n"
432     "ikev2 profile set <id> esp-crypto-alg <crypto alg> <key size> "
433       "[esp-integ-alg <integ alg>] esp-dh <dh type>\n"
434     "ikev2 profile set <id> sa-lifetime <seconds> <jitter> <handover> <max bytes>",
435     .function = ikev2_profile_add_del_command_fn,
436 };
437 /* *INDENT-ON* */
438
439 static clib_error_t *
440 show_ikev2_profile_command_fn (vlib_main_t * vm,
441                                unformat_input_t * input,
442                                vlib_cli_command_t * cmd)
443 {
444   ikev2_main_t *km = &ikev2_main;
445   ikev2_profile_t *p;
446
447   /* *INDENT-OFF* */
448   pool_foreach (p, km->profiles, ({
449     vlib_cli_output(vm, "profile %v", p->name);
450
451     if (p->auth.data)
452       {
453         if (p->auth.hex)
454           vlib_cli_output(vm, "  auth-method %U auth data 0x%U",
455                           format_ikev2_auth_method, p->auth.method,
456                           format_hex_bytes, p->auth.data, vec_len(p->auth.data));
457         else
458           vlib_cli_output(vm, "  auth-method %U auth data %v",
459                    format_ikev2_auth_method, p->auth.method, p->auth.data);
460       }
461
462     if (p->loc_id.data)
463       {
464         if (p->loc_id.type == IKEV2_ID_TYPE_ID_IPV4_ADDR)
465           vlib_cli_output(vm, "  local id-type %U data %U",
466                           format_ikev2_id_type, p->loc_id.type,
467                           format_ip4_address, p->loc_id.data);
468         else if (p->loc_id.type == IKEV2_ID_TYPE_ID_KEY_ID)
469           vlib_cli_output(vm, "  local id-type %U data 0x%U",
470                           format_ikev2_id_type, p->loc_id.type,
471                           format_hex_bytes, p->loc_id.data,
472                           vec_len(p->loc_id.data));
473         else
474           vlib_cli_output(vm, "  local id-type %U data %v",
475                           format_ikev2_id_type, p->loc_id.type, p->loc_id.data);
476       }
477
478     if (p->rem_id.data)
479       {
480         if (p->rem_id.type == IKEV2_ID_TYPE_ID_IPV4_ADDR)
481           vlib_cli_output(vm, "  remote id-type %U data %U",
482                           format_ikev2_id_type, p->rem_id.type,
483                           format_ip4_address, p->rem_id.data);
484         else if (p->rem_id.type == IKEV2_ID_TYPE_ID_KEY_ID)
485           vlib_cli_output(vm, "  remote id-type %U data 0x%U",
486                           format_ikev2_id_type, p->rem_id.type,
487                           format_hex_bytes, p->rem_id.data,
488                           vec_len(p->rem_id.data));
489         else
490           vlib_cli_output(vm, "  remote id-type %U data %v",
491                           format_ikev2_id_type, p->rem_id.type, p->rem_id.data);
492       }
493
494     if (p->loc_ts.end_addr.as_u32)
495       vlib_cli_output(vm, "  local traffic-selector addr %U - %U port %u - %u"
496                       " protocol %u",
497                       format_ip4_address, &p->loc_ts.start_addr,
498                       format_ip4_address, &p->loc_ts.end_addr,
499                       p->loc_ts.start_port, p->loc_ts.end_port,
500                       p->loc_ts.protocol_id);
501
502     if (p->rem_ts.end_addr.as_u32)
503       vlib_cli_output(vm, "  remote traffic-selector addr %U - %U port %u - %u"
504                       " protocol %u",
505                       format_ip4_address, &p->rem_ts.start_addr,
506                       format_ip4_address, &p->rem_ts.end_addr,
507                       p->rem_ts.start_port, p->rem_ts.end_port,
508                       p->rem_ts.protocol_id);
509     if (~0 != p->tun_itf)
510       vlib_cli_output(vm, "  protected tunnel %U",
511                       format_vnet_sw_if_index_name, vnet_get_main(), p->tun_itf);
512     if (p->udp_encap)
513       vlib_cli_output(vm, "  udp-encap");
514
515     if (p->dst_port != IPSEC_UDP_PORT_NONE)
516       vlib_cli_output(vm, "  ipsec-over-udp port %d", p->dst_port);
517   }));
518   /* *INDENT-ON* */
519
520   return 0;
521 }
522
523 /* *INDENT-OFF* */
524 VLIB_CLI_COMMAND (show_ikev2_profile_command, static) = {
525     .path = "show ikev2 profile",
526     .short_help = "show ikev2 profile",
527     .function = show_ikev2_profile_command_fn,
528 };
529 /* *INDENT-ON* */
530
531 static clib_error_t *
532 set_ikev2_local_key_command_fn (vlib_main_t * vm,
533                                 unformat_input_t * input,
534                                 vlib_cli_command_t * cmd)
535 {
536   unformat_input_t _line_input, *line_input = &_line_input;
537   clib_error_t *r = 0;
538   u8 *data = 0;
539
540   if (!unformat_user (input, unformat_line_input, line_input))
541     return 0;
542
543   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
544     {
545       if (unformat (line_input, "%s", &data))
546         {
547           r = ikev2_set_local_key (vm, data);
548           goto done;
549         }
550       else
551         break;
552     }
553
554   r = clib_error_return (0, "parse error: '%U'",
555                          format_unformat_error, line_input);
556
557 done:
558   vec_free (data);
559   unformat_free (line_input);
560   return r;
561 }
562
563 /* *INDENT-OFF* */
564 VLIB_CLI_COMMAND (set_ikev2_local_key_command, static) = {
565     .path = "set ikev2 local key",
566     .short_help =
567     "set ikev2 local key <file>",
568     .function = set_ikev2_local_key_command_fn,
569 };
570 /* *INDENT-ON* */
571
572
573 static clib_error_t *
574 ikev2_initiate_command_fn (vlib_main_t * vm,
575                            unformat_input_t * input, vlib_cli_command_t * cmd)
576 {
577   unformat_input_t _line_input, *line_input = &_line_input;
578   clib_error_t *r = 0;
579   u8 *name = 0;
580   u32 tmp1;
581   u64 tmp2;
582
583   const char *valid_chars = "a-zA-Z0-9_";
584
585   if (!unformat_user (input, unformat_line_input, line_input))
586     return 0;
587
588   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
589     {
590       if (unformat
591           (line_input, "sa-init %U", unformat_token, valid_chars, &name))
592         {
593           r = ikev2_initiate_sa_init (vm, name);
594           goto done;
595         }
596       else if (unformat (line_input, "del-child-sa %x", &tmp1))
597         {
598           r = ikev2_initiate_delete_child_sa (vm, tmp1);
599           goto done;
600         }
601       else if (unformat (line_input, "del-sa %lx", &tmp2))
602         {
603           r = ikev2_initiate_delete_ike_sa (vm, tmp2);
604           goto done;
605         }
606       else if (unformat (line_input, "rekey-child-sa %x", &tmp1))
607         {
608           r = ikev2_initiate_rekey_child_sa (vm, tmp1);
609           goto done;
610         }
611       else
612         break;
613     }
614
615   r = clib_error_return (0, "parse error: '%U'",
616                          format_unformat_error, line_input);
617
618 done:
619   vec_free (name);
620   unformat_free (line_input);
621   return r;
622 }
623
624 /* *INDENT-OFF* */
625 VLIB_CLI_COMMAND (ikev2_initiate_command, static) = {
626     .path = "ikev2 initiate",
627     .short_help =
628         "ikev2 initiate sa-init <profile id>\n"
629         "ikev2 initiate del-child-sa <child sa ispi>\n"
630         "ikev2 initiate del-sa <sa ispi>\n"
631         "ikev2 initiate rekey-child-sa <profile id> <child sa ispi>\n",
632     .function = ikev2_initiate_command_fn,
633 };
634 /* *INDENT-ON* */
635
636 void
637 ikev2_cli_reference (void)
638 {
639 }
640
641 static clib_error_t *
642 ikev2_set_log_level_command_fn (vlib_main_t * vm,
643                                 unformat_input_t * input,
644                                 vlib_cli_command_t * cmd)
645 {
646   unformat_input_t _line_input, *line_input = &_line_input;
647   u8 log_level = IKEV2_LOG_NONE;
648   clib_error_t *error = 0;
649
650   /* Get a line of input. */
651   if (!unformat_user (input, unformat_line_input, line_input))
652     return 0;
653
654   if (!unformat (line_input, "%d", &log_level))
655     {
656       error = clib_error_return (0, "unknown input '%U'",
657                                  format_unformat_error, line_input);
658       goto done;
659     }
660   int rc = ikev2_set_log_level (log_level);
661   if (rc < 0)
662     error = clib_error_return (0, "setting log level failed!");
663
664 done:
665   unformat_free (line_input);
666   return error;
667 }
668
669 /* *INDENT-OFF* */
670 VLIB_CLI_COMMAND (ikev2_set_log_level_command, static) = {
671   .path = "ikev2 set logging level",
672   .function = ikev2_set_log_level_command_fn,
673   .short_help = "ikev2 set logging level <0-5>",
674 };
675 /* *INDENT-ON* */
676
677 /*
678  * fd.io coding-style-patch-verification: ON
679  *
680  * Local Variables:
681  * eval: (c-set-style "gnu")
682  * End:
683  */