ikev2: cli for disabling dead peer detection
[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 <vppinfra/error.h>
18 #include <vnet/ipsec/ipsec_sa.h>
19 #include <plugins/ikev2/ikev2.h>
20 #include <plugins/ikev2/ikev2_priv.h>
21
22 u8 *
23 format_ikev2_id_type_and_data (u8 * s, va_list * args)
24 {
25   ikev2_id_t *id = va_arg (*args, ikev2_id_t *);
26
27   if (id->type == 0 || vec_len (id->data) == 0)
28     return format (s, "none");
29
30   s = format (s, "%U", format_ikev2_id_type, id->type);
31
32   if (id->type == IKEV2_ID_TYPE_ID_FQDN ||
33       id->type == IKEV2_ID_TYPE_ID_RFC822_ADDR)
34     {
35       s = format (s, " %v", id->data);
36     }
37   else
38     {
39       s =
40         format (s, " %U", format_hex_bytes, &id->data,
41                 (uword) (vec_len (id->data)));
42     }
43
44   return s;
45 }
46
47 static u8 *
48 format_ikev2_traffic_selector (u8 * s, va_list * va)
49 {
50   ikev2_ts_t *ts = va_arg (*va, ikev2_ts_t *);
51   u32 index = va_arg (*va, u32);
52
53   s = format (s, "%u type %u protocol_id %u addr "
54               "%U - %U port %u - %u\n",
55               index, ts->ts_type, ts->protocol_id,
56               format_ip_address, &ts->start_addr,
57               format_ip_address, &ts->end_addr,
58               clib_net_to_host_u16 (ts->start_port),
59               clib_net_to_host_u16 (ts->end_port));
60   return s;
61 }
62
63 static u8 *
64 format_ikev2_child_sa (u8 * s, va_list * va)
65 {
66   ikev2_child_sa_t *child = va_arg (*va, ikev2_child_sa_t *);
67   u32 index = va_arg (*va, u32);
68   ikev2_ts_t *ts;
69   ikev2_sa_transform_t *tr;
70   u8 *c = 0;
71
72   u32 indent = format_get_indent (s);
73   indent += 1;
74
75   s = format (s, "child sa %u:", index);
76
77   tr = ikev2_sa_get_td_for_type (child->r_proposals,
78                                  IKEV2_TRANSFORM_TYPE_ENCR);
79   c = format (c, "%U ", format_ikev2_sa_transform, tr);
80
81   tr = ikev2_sa_get_td_for_type (child->r_proposals,
82                                  IKEV2_TRANSFORM_TYPE_INTEG);
83   c = format (c, "%U ", format_ikev2_sa_transform, tr);
84
85   tr = ikev2_sa_get_td_for_type (child->r_proposals,
86                                  IKEV2_TRANSFORM_TYPE_ESN);
87   c = format (c, "%U ", format_ikev2_sa_transform, tr);
88
89   s = format (s, "%v\n", c);
90   vec_free (c);
91
92   s = format (s, "%Uspi(i) %lx spi(r) %lx\n", format_white_space, indent,
93               child->i_proposals ? child->i_proposals[0].spi : 0,
94               child->r_proposals ? child->r_proposals[0].spi : 0);
95
96   s = format (s, "%USK_e  i:%U\n%Ur:%U\n",
97               format_white_space, indent,
98               format_hex_bytes, child->sk_ei, vec_len (child->sk_ei),
99               format_white_space, indent + 6,
100               format_hex_bytes, child->sk_er, vec_len (child->sk_er));
101   if (child->sk_ai)
102     {
103       s = format (s, "%USK_a  i:%U\n%Ur:%U\n",
104                   format_white_space, indent,
105                   format_hex_bytes, child->sk_ai, vec_len (child->sk_ai),
106                   format_white_space, indent + 6,
107                   format_hex_bytes, child->sk_ar, vec_len (child->sk_ar));
108     }
109   s = format (s, "%Utraffic selectors (i):", format_white_space, indent);
110   vec_foreach (ts, child->tsi)
111     s = format (s, "%U", format_ikev2_traffic_selector, ts, ts - child->tsi);
112   s = format (s, "%Utraffic selectors (r):", format_white_space, indent);
113   vec_foreach (ts, child->tsr)
114     s = format (s, "%U", format_ikev2_traffic_selector, ts, ts - child->tsr);
115   return s;
116 }
117
118 static u8 *
119 format_ikev2_sa (u8 * s, va_list * va)
120 {
121   ikev2_sa_t *sa = va_arg (*va, ikev2_sa_t *);
122   int details = va_arg (*va, int);
123   ikev2_sa_transform_t *tr;
124   ikev2_child_sa_t *child;
125   u32 indent = 1;
126
127   s = format (s, "iip %U ispi %lx rip %U rspi %lx",
128               format_ip_address, &sa->iaddr, sa->ispi,
129               format_ip_address, &sa->raddr, sa->rspi);
130   if (!details)
131     return s;
132
133   s = format (s, "\n%U", format_white_space, indent);
134
135   tr = ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
136   s = format (s, "%U ", format_ikev2_sa_transform, tr);
137
138   tr = ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);
139   s = format (s, "%U ", format_ikev2_sa_transform, tr);
140
141   tr = ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);
142   s = format (s, "%U ", format_ikev2_sa_transform, tr);
143
144   tr = ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_DH);
145   s = format (s, "%U", format_ikev2_sa_transform, tr);
146
147   s = format (s, "\n%U", format_white_space, indent);
148
149   s = format (s, "nonce i:%U\n%Ur:%U\n",
150               format_hex_bytes, sa->i_nonce, vec_len (sa->i_nonce),
151               format_white_space, indent + 6,
152               format_hex_bytes, sa->r_nonce, vec_len (sa->r_nonce));
153
154   s = format (s, "%USK_d    %U\n", format_white_space, indent,
155               format_hex_bytes, sa->sk_d, vec_len (sa->sk_d));
156   if (sa->sk_ai)
157     {
158       s = format (s, "%USK_a  i:%U\n%Ur:%U\n",
159                   format_white_space, indent,
160                   format_hex_bytes, sa->sk_ai, vec_len (sa->sk_ai),
161                   format_white_space, indent + 6,
162                   format_hex_bytes, sa->sk_ar, vec_len (sa->sk_ar));
163     }
164   s = format (s, "%USK_e  i:%U\n%Ur:%U\n",
165               format_white_space, indent,
166               format_hex_bytes, sa->sk_ei, vec_len (sa->sk_ei),
167               format_white_space, indent + 6,
168               format_hex_bytes, sa->sk_er, vec_len (sa->sk_er));
169   s = format (s, "%USK_p  i:%U\n%Ur:%U\n",
170               format_white_space, indent,
171               format_hex_bytes, sa->sk_pi, vec_len (sa->sk_pi),
172               format_white_space, indent + 6,
173               format_hex_bytes, sa->sk_pr, vec_len (sa->sk_pr));
174
175   s = format (s, "%Uidentifier (i) %U\n",
176               format_white_space, indent,
177               format_ikev2_id_type_and_data, &sa->i_id);
178   s = format (s, "%Uidentifier (r) %U\n",
179               format_white_space, indent,
180               format_ikev2_id_type_and_data, &sa->r_id);
181
182   vec_foreach (child, sa->childs)
183   {
184     s = format (s, "%U%U", format_white_space, indent + 2,
185                 format_ikev2_child_sa, child, child - sa->childs);
186   }
187
188   return s;
189 }
190
191 static clib_error_t *
192 show_ikev2_sa_command_fn (vlib_main_t * vm,
193                           unformat_input_t * input, vlib_cli_command_t * cmd)
194 {
195   unformat_input_t _line_input, *line_input = &_line_input;
196   ikev2_main_t *km = &ikev2_main;
197   ikev2_main_per_thread_data_t *tkm;
198   ikev2_sa_t *sa;
199   u64 rspi;
200   u8 *s = 0;
201   int details = 0, show_one = 0;
202
203   if (unformat_user (input, unformat_line_input, line_input))
204     {
205       while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
206         {
207           if (unformat (line_input, "rspi %lx", &rspi))
208             {
209               show_one = 1;
210             }
211           else if (unformat (line_input, "details"))
212             details = 1;
213           else
214             break;
215         }
216       unformat_free (line_input);
217     }
218
219   vec_foreach (tkm, km->per_thread_data)
220   {
221     /* *INDENT-OFF* */
222     pool_foreach (sa, tkm->sas, ({
223       if (show_one)
224         {
225           if (sa->rspi == rspi)
226             {
227               s = format (s, "%U\n", format_ikev2_sa, sa, 1);
228               break;
229             }
230         }
231       else
232         s = format (s, "%U\n", format_ikev2_sa, sa, details);
233     }));
234     /* *INDENT-ON* */
235   }
236
237   vlib_cli_output (vm, "%v", s);
238   vec_free (s);
239   return 0;
240 }
241
242 /* *INDENT-OFF* */
243 VLIB_CLI_COMMAND (show_ikev2_sa_command, static) = {
244     .path = "show ikev2 sa",
245     .short_help = "show ikev2 sa [rspi <rspi>] [details]",
246     .function = show_ikev2_sa_command_fn,
247 };
248 /* *INDENT-ON* */
249
250 static clib_error_t *
251 ikev2_disable_dpd_command_fn (vlib_main_t * vm,
252                               unformat_input_t * input,
253                               vlib_cli_command_t * cmd)
254 {
255   ikev2_disable_dpd ();
256   return 0;
257 }
258
259 /* *INDENT-OFF* */
260 VLIB_CLI_COMMAND (ikev2_cli_disable_dpd_command, static) = {
261   .path = "ikev2 dpd disable",
262   .short_help = "ikev2 dpd disable",
263   .function = ikev2_disable_dpd_command_fn,
264 };
265 /* *INDENT-ON* */
266
267 static uword
268 unformat_ikev2_token (unformat_input_t * input, va_list * va)
269 {
270   u8 **string_return = va_arg (*va, u8 **);
271   const char *token_chars = "a-zA-Z0-9_";
272   if (*string_return)
273     {
274       /* if string_return was already allocated (eg. because of a previous
275        * partial match with a successful unformat_token()), we must free it
276        * before reusing the pointer, otherwise we'll be leaking memory
277        */
278       vec_free (*string_return);
279       *string_return = 0;
280     }
281   return unformat_user (input, unformat_token, token_chars, string_return);
282 }
283
284 static clib_error_t *
285 ikev2_profile_add_del_command_fn (vlib_main_t * vm,
286                                   unformat_input_t * input,
287                                   vlib_cli_command_t * cmd)
288 {
289   vnet_main_t *vnm = vnet_get_main ();
290   unformat_input_t _line_input, *line_input = &_line_input;
291   u8 *name = 0;
292   clib_error_t *r = 0;
293   u32 id_type;
294   u8 *data = 0;
295   u32 tmp1, tmp2, tmp3;
296   u64 tmp4, tmp5;
297   ip_address_t ip, end_addr;
298   u32 responder_sw_if_index = (u32) ~ 0;
299   u32 tun_sw_if_index = (u32) ~ 0;
300   ikev2_transform_encr_type_t crypto_alg;
301   ikev2_transform_integ_type_t integ_alg;
302   ikev2_transform_dh_type_t dh_type;
303
304   if (!unformat_user (input, unformat_line_input, line_input))
305     return 0;
306
307   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
308     {
309       if (unformat (line_input, "add %U", unformat_ikev2_token, &name))
310         {
311           r = ikev2_add_del_profile (vm, name, 1);
312           goto done;
313         }
314       else if (unformat (line_input, "del %U", unformat_ikev2_token, &name))
315         {
316           r = ikev2_add_del_profile (vm, name, 0);
317           goto done;
318         }
319       else if (unformat (line_input, "set %U auth shared-key-mic string %v",
320                          unformat_ikev2_token, &name, &data))
321         {
322           r =
323             ikev2_set_profile_auth (vm, name,
324                                     IKEV2_AUTH_METHOD_SHARED_KEY_MIC, data,
325                                     0);
326           goto done;
327         }
328       else if (unformat (line_input, "set %U auth shared-key-mic hex %U",
329                          unformat_ikev2_token, &name,
330                          unformat_hex_string, &data))
331         {
332           r =
333             ikev2_set_profile_auth (vm, name,
334                                     IKEV2_AUTH_METHOD_SHARED_KEY_MIC, data,
335                                     1);
336           goto done;
337         }
338       else if (unformat (line_input, "set %U auth rsa-sig cert-file %v",
339                          unformat_ikev2_token, &name, &data))
340         {
341           r =
342             ikev2_set_profile_auth (vm, name, IKEV2_AUTH_METHOD_RSA_SIG, data,
343                                     0);
344           goto done;
345         }
346       else if (unformat (line_input, "set %U id local %U %U",
347                          unformat_ikev2_token, &name,
348                          unformat_ikev2_id_type, &id_type,
349                          unformat_ip_address, &ip))
350         {
351           data = vec_new (u8, ip_address_size (&ip));
352           clib_memcpy (data, ip_addr_bytes (&ip), ip_address_size (&ip));
353           r =
354             ikev2_set_profile_id (vm, name, (u8) id_type, data, /*local */ 1);
355           goto done;
356         }
357       else if (unformat (line_input, "set %U id local %U 0x%U",
358                          unformat_ikev2_token, &name,
359                          unformat_ikev2_id_type, &id_type,
360                          unformat_hex_string, &data))
361         {
362           r =
363             ikev2_set_profile_id (vm, name, (u8) id_type, data, /*local */ 1);
364           goto done;
365         }
366       else if (unformat (line_input, "set %U id local %U %v",
367                          unformat_ikev2_token, &name,
368                          unformat_ikev2_id_type, &id_type, &data))
369         {
370           r =
371             ikev2_set_profile_id (vm, name, (u8) id_type, data, /*local */ 1);
372           goto done;
373         }
374       else if (unformat (line_input, "set %U id remote %U %U",
375                          unformat_ikev2_token, &name,
376                          unformat_ikev2_id_type, &id_type,
377                          unformat_ip_address, &ip))
378         {
379           data = vec_new (u8, ip_address_size (&ip));
380           clib_memcpy (data, ip_addr_bytes (&ip), ip_address_size (&ip));
381           r = ikev2_set_profile_id (vm, name, (u8) id_type, data,       /*remote */
382                                     0);
383           goto done;
384         }
385       else if (unformat (line_input, "set %U id remote %U 0x%U",
386                          unformat_ikev2_token, &name,
387                          unformat_ikev2_id_type, &id_type,
388                          unformat_hex_string, &data))
389         {
390           r = ikev2_set_profile_id (vm, name, (u8) id_type, data,       /*remote */
391                                     0);
392           goto done;
393         }
394       else if (unformat (line_input, "set %U id remote %U %v",
395                          unformat_ikev2_token, &name,
396                          unformat_ikev2_id_type, &id_type, &data))
397         {
398           r = ikev2_set_profile_id (vm, name, (u8) id_type, data,       /*remote */
399                                     0);
400           goto done;
401         }
402       else if (unformat (line_input, "set %U traffic-selector local "
403                          "ip-range %U - %U port-range %u - %u protocol %u",
404                          unformat_ikev2_token, &name,
405                          unformat_ip_address, &ip,
406                          unformat_ip_address, &end_addr, &tmp1, &tmp2, &tmp3))
407         {
408           r =
409             ikev2_set_profile_ts (vm, name, (u8) tmp3, (u16) tmp1, (u16) tmp2,
410                                   ip, end_addr, /*local */ 1);
411           goto done;
412         }
413       else if (unformat (line_input, "set %U traffic-selector remote "
414                          "ip-range %U - %U port-range %u - %u protocol %u",
415                          unformat_ikev2_token, &name,
416                          unformat_ip_address, &ip,
417                          unformat_ip_address, &end_addr, &tmp1, &tmp2, &tmp3))
418         {
419           r =
420             ikev2_set_profile_ts (vm, name, (u8) tmp3, (u16) tmp1, (u16) tmp2,
421                                   ip, end_addr, /*remote */ 0);
422           goto done;
423         }
424       else if (unformat (line_input, "set %U responder %U %U",
425                          unformat_ikev2_token, &name,
426                          unformat_vnet_sw_interface, vnm,
427                          &responder_sw_if_index, unformat_ip_address, &ip))
428         {
429           r =
430             ikev2_set_profile_responder (vm, name, responder_sw_if_index, ip);
431           goto done;
432         }
433       else if (unformat (line_input, "set %U tunnel %U",
434                          unformat_ikev2_token, &name,
435                          unformat_vnet_sw_interface, vnm, &tun_sw_if_index))
436         {
437           r = ikev2_set_profile_tunnel_interface (vm, name, tun_sw_if_index);
438           goto done;
439         }
440       else
441         if (unformat
442             (line_input,
443              "set %U ike-crypto-alg %U %u ike-integ-alg %U ike-dh %U",
444              unformat_ikev2_token, &name,
445              unformat_ikev2_transform_encr_type, &crypto_alg, &tmp1,
446              unformat_ikev2_transform_integ_type, &integ_alg,
447              unformat_ikev2_transform_dh_type, &dh_type))
448         {
449           r =
450             ikev2_set_profile_ike_transforms (vm, name, crypto_alg, integ_alg,
451                                               dh_type, tmp1);
452           goto done;
453         }
454       else
455         if (unformat
456             (line_input,
457              "set %U ike-crypto-alg %U %u ike-dh %U",
458              unformat_ikev2_token, &name,
459              unformat_ikev2_transform_encr_type, &crypto_alg, &tmp1,
460              unformat_ikev2_transform_dh_type, &dh_type))
461         {
462           r =
463             ikev2_set_profile_ike_transforms (vm, name, crypto_alg,
464                                               IKEV2_TRANSFORM_INTEG_TYPE_NONE,
465                                               dh_type, tmp1);
466           goto done;
467         }
468       else
469         if (unformat
470             (line_input,
471              "set %U esp-crypto-alg %U %u esp-integ-alg %U",
472              unformat_ikev2_token, &name,
473              unformat_ikev2_transform_encr_type, &crypto_alg, &tmp1,
474              unformat_ikev2_transform_integ_type, &integ_alg))
475         {
476           r =
477             ikev2_set_profile_esp_transforms (vm, name, crypto_alg, integ_alg,
478                                               tmp1);
479           goto done;
480         }
481       else if (unformat
482                (line_input,
483                 "set %U esp-crypto-alg %U %u",
484                 unformat_ikev2_token, &name,
485                 unformat_ikev2_transform_encr_type, &crypto_alg, &tmp1))
486         {
487           r =
488             ikev2_set_profile_esp_transforms (vm, name, crypto_alg, 0, tmp1);
489           goto done;
490         }
491       else if (unformat (line_input, "set %U sa-lifetime %lu %u %u %lu",
492                          unformat_ikev2_token, &name,
493                          &tmp4, &tmp1, &tmp2, &tmp5))
494         {
495           r =
496             ikev2_set_profile_sa_lifetime (vm, name, tmp4, tmp1, tmp2, tmp5);
497           goto done;
498         }
499       else if (unformat (line_input, "set %U udp-encap",
500                          unformat_ikev2_token, &name))
501         {
502           r = ikev2_set_profile_udp_encap (vm, name);
503           goto done;
504         }
505       else if (unformat (line_input, "set %U ipsec-over-udp port %u",
506                          unformat_ikev2_token, &name, &tmp1))
507         {
508           int rv = ikev2_set_profile_ipsec_udp_port (vm, name, tmp1, 1);
509           if (rv)
510             r = clib_error_return (0, "Error: %U", format_vnet_api_errno, rv);
511           goto done;
512         }
513       else
514         break;
515     }
516
517   r = clib_error_return (0, "parse error: '%U'",
518                          format_unformat_error, line_input);
519
520 done:
521   vec_free (name);
522   vec_free (data);
523   unformat_free (line_input);
524   return r;
525 }
526
527 /* *INDENT-OFF* */
528 VLIB_CLI_COMMAND (ikev2_profile_add_del_command, static) = {
529     .path = "ikev2 profile",
530     .short_help =
531     "ikev2 profile [add|del] <id>\n"
532     "ikev2 profile set <id> auth [rsa-sig|shared-key-mic] [cert-file|string|hex]"
533     " <data>\n"
534     "ikev2 profile set <id> id <local|remote> <type> <data>\n"
535     "ikev2 profile set <id> tunnel <interface>\n"
536     "ikev2 profile set <id> udp-encap\n"
537     "ikev2 profile set <id> traffic-selector <local|remote> ip-range "
538     "<start-addr> - <end-addr> port-range <start-port> - <end-port> "
539     "protocol <protocol-number>\n"
540     "ikev2 profile set <id> responder <interface> <addr>\n"
541     "ikev2 profile set <id> ike-crypto-alg <crypto alg> <key size> ike-integ-alg <integ alg> ike-dh <dh type>\n"
542     "ikev2 profile set <id> esp-crypto-alg <crypto alg> <key size> "
543       "[esp-integ-alg <integ alg>]\n"
544     "ikev2 profile set <id> sa-lifetime <seconds> <jitter> <handover> <max bytes>",
545     .function = ikev2_profile_add_del_command_fn,
546 };
547 /* *INDENT-ON* */
548
549 static clib_error_t *
550 show_ikev2_profile_command_fn (vlib_main_t * vm,
551                                unformat_input_t * input,
552                                vlib_cli_command_t * cmd)
553 {
554   ikev2_main_t *km = &ikev2_main;
555   ikev2_profile_t *p;
556
557   /* *INDENT-OFF* */
558   pool_foreach (p, km->profiles, ({
559     vlib_cli_output(vm, "profile %v", p->name);
560
561     if (p->auth.data)
562       {
563         if (p->auth.hex)
564           vlib_cli_output(vm, "  auth-method %U auth data 0x%U",
565                           format_ikev2_auth_method, p->auth.method,
566                           format_hex_bytes, p->auth.data, vec_len(p->auth.data));
567         else
568           vlib_cli_output(vm, "  auth-method %U auth data %v",
569                    format_ikev2_auth_method, p->auth.method, p->auth.data);
570       }
571
572     if (p->loc_id.data)
573       {
574         if (p->loc_id.type == IKEV2_ID_TYPE_ID_IPV4_ADDR)
575           vlib_cli_output(vm, "  local id-type %U data %U",
576                           format_ikev2_id_type, p->loc_id.type,
577                           format_ip_address, p->loc_id.data);
578         else if (p->loc_id.type == IKEV2_ID_TYPE_ID_KEY_ID)
579           vlib_cli_output(vm, "  local id-type %U data 0x%U",
580                           format_ikev2_id_type, p->loc_id.type,
581                           format_hex_bytes, p->loc_id.data,
582                           vec_len(p->loc_id.data));
583         else
584           vlib_cli_output(vm, "  local id-type %U data %v",
585                           format_ikev2_id_type, p->loc_id.type, p->loc_id.data);
586       }
587
588     if (p->rem_id.data)
589       {
590         if (p->rem_id.type == IKEV2_ID_TYPE_ID_IPV4_ADDR)
591           vlib_cli_output(vm, "  remote id-type %U data %U",
592                           format_ikev2_id_type, p->rem_id.type,
593                           format_ip_address, p->rem_id.data);
594         else if (p->rem_id.type == IKEV2_ID_TYPE_ID_KEY_ID)
595           vlib_cli_output(vm, "  remote id-type %U data 0x%U",
596                           format_ikev2_id_type, p->rem_id.type,
597                           format_hex_bytes, p->rem_id.data,
598                           vec_len(p->rem_id.data));
599         else
600           vlib_cli_output(vm, "  remote id-type %U data %v",
601                           format_ikev2_id_type, p->rem_id.type, p->rem_id.data);
602       }
603
604     if (!ip_address_is_zero (&p->loc_ts.start_addr))
605       vlib_cli_output(vm, "  local traffic-selector addr %U - %U port %u - %u"
606                       " protocol %u",
607                       format_ip_address, &p->loc_ts.start_addr,
608                       format_ip_address, &p->loc_ts.end_addr,
609                       p->loc_ts.start_port, p->loc_ts.end_port,
610                       p->loc_ts.protocol_id);
611
612     if (!ip_address_is_zero (&p->rem_ts.start_addr))
613       vlib_cli_output(vm, "  remote traffic-selector addr %U - %U port %u - %u"
614                       " protocol %u",
615                       format_ip_address, &p->rem_ts.start_addr,
616                       format_ip_address, &p->rem_ts.end_addr,
617                       p->rem_ts.start_port, p->rem_ts.end_port,
618                       p->rem_ts.protocol_id);
619     if (~0 != p->tun_itf)
620       vlib_cli_output(vm, "  protected tunnel %U",
621                       format_vnet_sw_if_index_name, vnet_get_main(), p->tun_itf);
622     if (~0 != p->responder.sw_if_index)
623       vlib_cli_output(vm, "  responder %U %U",
624                       format_vnet_sw_if_index_name, vnet_get_main(), p->responder.sw_if_index,
625                       format_ip_address, &p->responder.addr);
626     if (p->udp_encap)
627       vlib_cli_output(vm, "  udp-encap");
628
629     if (p->ipsec_over_udp_port != IPSEC_UDP_PORT_NONE)
630       vlib_cli_output(vm, "  ipsec-over-udp port %d", p->ipsec_over_udp_port);
631
632     if (p->ike_ts.crypto_alg || p->ike_ts.integ_alg || p->ike_ts.dh_type || p->ike_ts.crypto_key_size)
633       vlib_cli_output(vm, "  ike-crypto-alg %U %u ike-integ-alg %U ike-dh %U",
634                     format_ikev2_transform_encr_type, p->ike_ts.crypto_alg, p->ike_ts.crypto_key_size,
635                     format_ikev2_transform_integ_type, p->ike_ts.integ_alg,
636                     format_ikev2_transform_dh_type, p->ike_ts.dh_type);
637
638     if (p->esp_ts.crypto_alg || p->esp_ts.integ_alg || p->esp_ts.dh_type)
639       vlib_cli_output(vm, "  esp-crypto-alg %U %u esp-integ-alg %U",
640                     format_ikev2_transform_encr_type, p->esp_ts.crypto_alg, p->esp_ts.crypto_key_size,
641                     format_ikev2_transform_integ_type, p->esp_ts.integ_alg);
642
643     vlib_cli_output(vm, "  lifetime %d jitter %d handover %d maxdata %d",
644                     p->lifetime, p->lifetime_jitter, p->handover, p->lifetime_maxdata);
645   }));
646   /* *INDENT-ON* */
647
648   return 0;
649 }
650
651 /* *INDENT-OFF* */
652 VLIB_CLI_COMMAND (show_ikev2_profile_command, static) = {
653     .path = "show ikev2 profile",
654     .short_help = "show ikev2 profile",
655     .function = show_ikev2_profile_command_fn,
656 };
657 /* *INDENT-ON* */
658
659 static clib_error_t *
660 set_ikev2_liveness_period_fn (vlib_main_t * vm,
661                               unformat_input_t * input,
662                               vlib_cli_command_t * cmd)
663 {
664   unformat_input_t _line_input, *line_input = &_line_input;
665   clib_error_t *r = 0;
666   u32 period = 0, max_retries = 0;
667
668   if (!unformat_user (input, unformat_line_input, line_input))
669     return 0;
670
671   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
672     {
673       if (unformat (line_input, "%d %d", &period, &max_retries))
674         {
675           r = ikev2_set_liveness_params (period, max_retries);
676           goto done;
677         }
678       else
679         break;
680     }
681
682   r = clib_error_return (0, "parse error: '%U'",
683                          format_unformat_error, line_input);
684
685 done:
686   unformat_free (line_input);
687   return r;
688 }
689
690 /* *INDENT-OFF* */
691 VLIB_CLI_COMMAND (set_ikev2_liveness_command, static) = {
692   .path = "ikev2 set liveness",
693   .short_help = "ikev2 set liveness <period> <max-retires>",
694   .function = set_ikev2_liveness_period_fn,
695 };
696 /* *INDENT-ON* */
697
698 static clib_error_t *
699 set_ikev2_local_key_command_fn (vlib_main_t * vm,
700                                 unformat_input_t * input,
701                                 vlib_cli_command_t * cmd)
702 {
703   unformat_input_t _line_input, *line_input = &_line_input;
704   clib_error_t *r = 0;
705   u8 *data = 0;
706
707   if (!unformat_user (input, unformat_line_input, line_input))
708     return 0;
709
710   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
711     {
712       if (unformat (line_input, "%s", &data))
713         {
714           r = ikev2_set_local_key (vm, data);
715           goto done;
716         }
717       else
718         break;
719     }
720
721   r = clib_error_return (0, "parse error: '%U'",
722                          format_unformat_error, line_input);
723
724 done:
725   vec_free (data);
726   unformat_free (line_input);
727   return r;
728 }
729
730 /* *INDENT-OFF* */
731 VLIB_CLI_COMMAND (set_ikev2_local_key_command, static) = {
732     .path = "set ikev2 local key",
733     .short_help =
734     "set ikev2 local key <file>",
735     .function = set_ikev2_local_key_command_fn,
736 };
737 /* *INDENT-ON* */
738
739
740 static clib_error_t *
741 ikev2_initiate_command_fn (vlib_main_t * vm,
742                            unformat_input_t * input, vlib_cli_command_t * cmd)
743 {
744   unformat_input_t _line_input, *line_input = &_line_input;
745   clib_error_t *r = 0;
746   u8 *name = 0;
747   u32 tmp1;
748   u64 tmp2;
749
750   if (!unformat_user (input, unformat_line_input, line_input))
751     return 0;
752
753   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
754     {
755       if (unformat (line_input, "sa-init %U", unformat_ikev2_token, &name))
756         {
757           r = ikev2_initiate_sa_init (vm, name);
758           goto done;
759         }
760       else if (unformat (line_input, "del-child-sa %x", &tmp1))
761         {
762           r = ikev2_initiate_delete_child_sa (vm, tmp1);
763           goto done;
764         }
765       else if (unformat (line_input, "del-sa %lx", &tmp2))
766         {
767           r = ikev2_initiate_delete_ike_sa (vm, tmp2);
768           goto done;
769         }
770       else if (unformat (line_input, "rekey-child-sa %x", &tmp1))
771         {
772           r = ikev2_initiate_rekey_child_sa (vm, tmp1);
773           goto done;
774         }
775       else
776         break;
777     }
778
779   r = clib_error_return (0, "parse error: '%U'",
780                          format_unformat_error, line_input);
781
782 done:
783   vec_free (name);
784   unformat_free (line_input);
785   return r;
786 }
787
788 /* *INDENT-OFF* */
789 VLIB_CLI_COMMAND (ikev2_initiate_command, static) = {
790     .path = "ikev2 initiate",
791     .short_help =
792         "ikev2 initiate sa-init <profile id>\n"
793         "ikev2 initiate del-child-sa <child sa ispi>\n"
794         "ikev2 initiate del-sa <sa ispi>\n"
795         "ikev2 initiate rekey-child-sa <child sa ispi>\n",
796     .function = ikev2_initiate_command_fn,
797 };
798 /* *INDENT-ON* */
799
800 void
801 ikev2_cli_reference (void)
802 {
803 }
804
805 static clib_error_t *
806 ikev2_set_log_level_command_fn (vlib_main_t * vm,
807                                 unformat_input_t * input,
808                                 vlib_cli_command_t * cmd)
809 {
810   unformat_input_t _line_input, *line_input = &_line_input;
811   u32 log_level = IKEV2_LOG_NONE;
812   clib_error_t *error = 0;
813
814   /* Get a line of input. */
815   if (!unformat_user (input, unformat_line_input, line_input))
816     return 0;
817
818   if (!unformat (line_input, "%d", &log_level))
819     {
820       error = clib_error_return (0, "unknown input '%U'",
821                                  format_unformat_error, line_input);
822       goto done;
823     }
824   int rc = ikev2_set_log_level (log_level);
825   if (rc < 0)
826     error = clib_error_return (0, "setting log level failed!");
827
828 done:
829   unformat_free (line_input);
830   return error;
831 }
832
833 /* *INDENT-OFF* */
834 VLIB_CLI_COMMAND (ikev2_set_log_level_command, static) = {
835   .path = "ikev2 set logging level",
836   .function = ikev2_set_log_level_command_fn,
837   .short_help = "ikev2 set logging level <0-5>",
838 };
839 /* *INDENT-ON* */
840
841 /*
842  * fd.io coding-style-patch-verification: ON
843  *
844  * Local Variables:
845  * eval: (c-set-style "gnu")
846  * End:
847  */