FD.io VPP  v16.06
Vector Packet Processing
ikev2_cli.c
Go to the documentation of this file.
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/ip/udp.h>
20 #include <vnet/ipsec/ikev2.h>
21 #include <vnet/ipsec/ikev2_priv.h>
22 
23 u8 *
24 format_ikev2_id_type_and_data (u8 * s, va_list * args)
25 {
26  ikev2_id_t * id = va_arg (*args, ikev2_id_t *);
27 
28  if (id->type == 0 || vec_len(id->data) == 0)
29  return format(s, "none");
30 
31  s = format(s, "%U", format_ikev2_id_type, id->type);
32 
33  if (id->type == IKEV2_ID_TYPE_ID_FQDN ||
34  id->type == IKEV2_ID_TYPE_ID_RFC822_ADDR)
35  {
36  s = format(s, " %v", id->data);
37  }
38  else
39  {
40  s = format(s, " %U", format_hex_bytes, &id->data, (uword) (vec_len(id->data)));
41  }
42 
43  return s;
44 }
45 
46 
47 static clib_error_t *
49  unformat_input_t * input,
50  vlib_cli_command_t * cmd)
51 {
52  ikev2_main_t * km = &ikev2_main;
53  ikev2_sa_t * sa;
54  ikev2_ts_t * ts;
55  ikev2_child_sa_t * child;
57 
58  pool_foreach (sa, km->sas, ({
59  u8 * s = 0;
60  vlib_cli_output(vm, " iip %U ispi %lx rip %U rspi %lx",
61  format_ip4_address, &sa->iaddr, sa->ispi,
62  format_ip4_address, &sa->raddr, sa->rspi);
63 
64  tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
65  s = format(s, "%U ", format_ikev2_sa_transform, tr);
66 
67  tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);
68  s = format(s, "%U ", format_ikev2_sa_transform, tr);
69 
70  tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);
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_DH);
74  s = format(s, "%U ", format_ikev2_sa_transform, tr);
75 
76  vlib_cli_output(vm, " %v", s);
77  vec_free(s);
78 
79  vlib_cli_output(vm, " nonce i:%U\n r:%U",
80  format_hex_bytes, sa->i_nonce, vec_len(sa->i_nonce),
81  format_hex_bytes, sa->r_nonce, vec_len(sa->r_nonce));
82 
83  vlib_cli_output(vm, " SK_d %U",
84  format_hex_bytes, sa->sk_d, vec_len(sa->sk_d));
85  vlib_cli_output(vm, " SK_a i:%U\n r:%U",
86  format_hex_bytes, sa->sk_ai, vec_len(sa->sk_ai),
87  format_hex_bytes, sa->sk_ar, vec_len(sa->sk_ar));
88  vlib_cli_output(vm, " SK_e i:%U\n r:%U",
89  format_hex_bytes, sa->sk_ei, vec_len(sa->sk_ei),
90  format_hex_bytes, sa->sk_er, vec_len(sa->sk_er));
91  vlib_cli_output(vm, " SK_p i:%U\n r:%U",
92  format_hex_bytes, sa->sk_pi, vec_len(sa->sk_pi),
93  format_hex_bytes, sa->sk_pr, vec_len(sa->sk_pr));
94 
95  vlib_cli_output(vm, " identifier (i) %U",
96  format_ikev2_id_type_and_data, &sa->i_id);
97  vlib_cli_output(vm, " identifier (r) %U",
98  format_ikev2_id_type_and_data, &sa->r_id);
99 
100  vec_foreach(child, sa->childs)
101  {
102  vlib_cli_output(vm, " child sa %u:", child - sa->childs);
103 
104  tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
105  s = format(s, "%U ", format_ikev2_sa_transform, tr);
106 
107  tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);
108  s = format(s, "%U ", format_ikev2_sa_transform, tr);
109 
110  tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_ESN);
111  s = format(s, "%U ", format_ikev2_sa_transform, tr);
112 
113  vlib_cli_output(vm, " %v", s);
114  vec_free(s);
115 
116  vlib_cli_output(vm, " spi(i) %lx spi(r) %lx",
117  child->i_proposals ? child->i_proposals[0].spi : 0,
118  child->r_proposals ? child->r_proposals[0].spi : 0);
119 
120  vlib_cli_output(vm, " SK_e i:%U\n r:%U",
121  format_hex_bytes, child->sk_ei, vec_len(child->sk_ei),
122  format_hex_bytes, child->sk_er, vec_len(child->sk_er));
123  vlib_cli_output(vm, " SK_a i:%U\n r:%U",
124  format_hex_bytes, child->sk_ai, vec_len(child->sk_ai),
125  format_hex_bytes, child->sk_ar, vec_len(child->sk_ar));
126  vlib_cli_output(vm, " traffic selectors (i):");
127  vec_foreach(ts, child->tsi)
128  {
129  vlib_cli_output(vm, " %u type %u protocol_id %u addr "
130  "%U - %U port %u - %u",
131  ts - child->tsi,
132  ts->ts_type, ts->protocol_id,
133  format_ip4_address, &ts->start_addr,
134  format_ip4_address, &ts->end_addr,
135  clib_net_to_host_u16( ts->start_port),
136  clib_net_to_host_u16( ts->end_port));
137  }
138  vlib_cli_output(vm, " traffic selectors (r):");
139  vec_foreach(ts, child->tsr)
140  {
141  vlib_cli_output(vm, " %u type %u protocol_id %u addr "
142  "%U - %U port %u - %u",
143  ts - child->tsr,
144  ts->ts_type, ts->protocol_id,
145  format_ip4_address, &ts->start_addr,
146  format_ip4_address, &ts->end_addr,
147  clib_net_to_host_u16( ts->start_port),
148  clib_net_to_host_u16( ts->end_port));
149  }
150  }
151  vlib_cli_output(vm, "");
152  }));
153  return 0;
154 }
155 
156 VLIB_CLI_COMMAND (show_ikev2_sa_command, static) = {
157  .path = "show ikev2 sa",
158  .short_help = "show ikev2 sa",
159  .function = show_ikev2_sa_command_fn,
160 };
161 
162 static clib_error_t *
164  unformat_input_t * input,
165  vlib_cli_command_t * cmd)
166 {
167  unformat_input_t _line_input, * line_input = &_line_input;
168  u8 * name = 0;
169  clib_error_t * r = 0;
170  u32 id_type;
171  u8 * data = 0;
172  u32 tmp1, tmp2, tmp3;
173  ip4_address_t ip4;
174  ip4_address_t end_addr;
175 
176  const char * valid_chars = "a-zA-Z0-9_";
177 
178  if (! unformat_user (input, unformat_line_input, line_input))
179  return 0;
180 
181  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
182  if (unformat (line_input, "add %U", unformat_token, valid_chars, &name))
183  {
184  r = ikev2_add_del_profile(vm, name, 1);
185  goto done;
186  }
187  else if (unformat (line_input, "del %U", unformat_token, valid_chars, &name))
188  {
189  r = ikev2_add_del_profile(vm, name, 0);
190  goto done;
191  }
192  else if (unformat (line_input, "set %U auth shared-key-mic string %v",
193  unformat_token, valid_chars, &name, &data))
194  {
195  r = ikev2_set_profile_auth(vm, name, IKEV2_AUTH_METHOD_SHARED_KEY_MIC,
196  data, 0);
197  goto done;
198  }
199  else if (unformat (line_input, "set %U auth shared-key-mic hex %U",
200  unformat_token, valid_chars, &name,
201  unformat_hex_string, &data))
202  {
203  r = ikev2_set_profile_auth(vm, name, IKEV2_AUTH_METHOD_SHARED_KEY_MIC,
204  data, 1);
205  goto done;
206  }
207  else if (unformat (line_input, "set %U auth rsa-sig cert-file %v",
208  unformat_token, valid_chars, &name,
209  &data))
210  {
211  r = ikev2_set_profile_auth(vm, name, IKEV2_AUTH_METHOD_RSA_SIG, data, 0);
212  goto done;
213  }
214  else if (unformat (line_input, "set %U id local %U %U",
215  unformat_token, valid_chars, &name,
216  unformat_ikev2_id_type, &id_type,
217  unformat_ip4_address, &ip4))
218  {
219  data = vec_new(u8, 4);
220  clib_memcpy(data, ip4.as_u8, 4);
221  r = ikev2_set_profile_id(vm, name, (u8) id_type, data, /*local*/ 1);
222  goto done;
223  }
224  else if (unformat (line_input, "set %U id local %U 0x%U",
225  unformat_token, valid_chars, &name,
226  unformat_ikev2_id_type, &id_type,
227  unformat_hex_string, &data))
228  {
229  r = ikev2_set_profile_id(vm, name, (u8) id_type, data, /*local*/ 1);
230  goto done;
231  }
232  else if (unformat (line_input, "set %U id local %U %v",
233  unformat_token, valid_chars, &name,
234  unformat_ikev2_id_type, &id_type, &data))
235  {
236  r = ikev2_set_profile_id(vm, name, (u8) id_type, data, /*local*/ 1);
237  goto done;
238  }
239  else if (unformat (line_input, "set %U id remote %U %U",
240  unformat_token, valid_chars, &name,
241  unformat_ikev2_id_type, &id_type,
242  unformat_ip4_address, &ip4))
243  {
244  data = vec_new(u8, 4);
245  clib_memcpy(data, ip4.as_u8, 4);
246  r = ikev2_set_profile_id(vm, name, (u8) id_type, data, /*remote*/ 0);
247  goto done;
248  }
249  else if (unformat (line_input, "set %U id remote %U 0x%U",
250  unformat_token, valid_chars, &name,
251  unformat_ikev2_id_type, &id_type,
252  unformat_hex_string, &data))
253  {
254  r = ikev2_set_profile_id(vm, name, (u8) id_type, data, /*remote*/ 0);
255  goto done;
256  }
257  else if (unformat (line_input, "set %U id remote %U %v",
258  unformat_token, valid_chars, &name,
259  unformat_ikev2_id_type, &id_type, &data))
260  {
261  r = ikev2_set_profile_id(vm, name, (u8) id_type, data, /*remote*/ 0);
262  goto done;
263  }
264  else if (unformat (line_input, "set %U traffic-selector local "
265  "ip-range %U - %U port-range %u - %u protocol %u",
266  unformat_token, valid_chars, &name,
267  unformat_ip4_address, &ip4,
268  unformat_ip4_address, &end_addr,
269  &tmp1, &tmp2, &tmp3))
270  {
271  r = ikev2_set_profile_ts(vm, name, (u8)tmp3, (u16)tmp1, (u16)tmp2,
272  ip4, end_addr, /*local*/ 1);
273  goto done;
274  }
275  else if (unformat (line_input, "set %U traffic-selector remote "
276  "ip-range %U - %U port-range %u - %u protocol %u",
277  unformat_token, valid_chars, &name,
278  unformat_ip4_address, &ip4,
279  unformat_ip4_address, &end_addr,
280  &tmp1, &tmp2, &tmp3))
281  {
282  r = ikev2_set_profile_ts(vm, name, (u8)tmp3, (u16)tmp1, (u16)tmp2,
283  ip4, end_addr, /*remote*/ 0);
284  goto done;
285  }
286  else
287  break;
288  }
289 
290  r = clib_error_return (0, "parse error: '%U'",
291  format_unformat_error, line_input);
292 
293 done:
294  vec_free(name);
295  vec_free(data);
296  unformat_free (line_input);
297  return r;
298 }
299 
300 VLIB_CLI_COMMAND (ikev2_profile_add_del_command, static) = {
301  .path = "ikev2 profile",
302  .short_help =
303  "ikev2 profile [add|del] <id>\n"
304  "ikev2 profile set <id> auth [rsa-sig|shared-key-mic] [cert-file|string|hex]"
305  " <data>\n"
306  "ikev2 profile set <id> id <local|remote> <type> <data>\n"
307  "ikev2 profile set <id> traffic-selector <local|remote> ip-range "
308  "<start-addr> - <end-addr> port-range <start-port> - <end-port> "
309  "protocol <protocol-number>",
311 };
312 
313 static clib_error_t *
315  unformat_input_t * input,
316  vlib_cli_command_t * cmd)
317 {
318  ikev2_main_t * km = &ikev2_main;
319  ikev2_profile_t * p;
320 
321  pool_foreach (p, km->profiles, ({
322  vlib_cli_output(vm, "profile %v", p->name);
323 
324  if (p->auth.data)
325  {
326  if (p->auth.hex)
327  vlib_cli_output(vm, " auth-method %U auth data 0x%U",
328  format_ikev2_auth_method, p->auth.method,
329  format_hex_bytes, p->auth.data, vec_len(p->auth.data));
330  else
331  vlib_cli_output(vm, " auth-method %U auth data %v",
332  format_ikev2_auth_method, p->auth.method, p->auth.data);
333  }
334 
335  if (p->loc_id.data)
336  {
337  if (p->loc_id.type == IKEV2_ID_TYPE_ID_IPV4_ADDR)
338  vlib_cli_output(vm, " local id-type %U data %U",
339  format_ikev2_id_type, p->loc_id.type,
340  format_ip4_address, p->loc_id.data);
341  else if (p->loc_id.type == IKEV2_ID_TYPE_ID_KEY_ID)
342  vlib_cli_output(vm, " local id-type %U data 0x%U",
343  format_ikev2_id_type, p->loc_id.type,
344  format_hex_bytes, p->loc_id.data,
345  vec_len(p->loc_id.data));
346  else
347  vlib_cli_output(vm, " local id-type %U data %v",
348  format_ikev2_id_type, p->loc_id.type, p->loc_id.data);
349  }
350 
351  if (p->rem_id.data)
352  {
353  if (p->rem_id.type == IKEV2_ID_TYPE_ID_IPV4_ADDR)
354  vlib_cli_output(vm, " remote id-type %U data %U",
355  format_ikev2_id_type, p->rem_id.type,
356  format_ip4_address, p->rem_id.data);
357  else if (p->rem_id.type == IKEV2_ID_TYPE_ID_KEY_ID)
358  vlib_cli_output(vm, " remote id-type %U data 0x%U",
359  format_ikev2_id_type, p->rem_id.type,
360  format_hex_bytes, p->rem_id.data,
361  vec_len(p->rem_id.data));
362  else
363  vlib_cli_output(vm, " remote id-type %U data %v",
364  format_ikev2_id_type, p->rem_id.type, p->rem_id.data);
365  }
366 
367  if (p->loc_ts.end_addr.as_u32)
368  vlib_cli_output(vm, " local traffic-selector addr %U - %U port %u - %u"
369  " protocol %u",
373  p->loc_ts.protocol_id);
374 
375  if (p->rem_ts.end_addr.as_u32)
376  vlib_cli_output(vm, " remote traffic-selector addr %U - %U port %u - %u"
377  " protocol %u",
381  p->rem_ts.protocol_id);
382  }));
383 
384  return 0;
385 }
386 
387 VLIB_CLI_COMMAND (show_ikev2_profile_command, static) = {
388  .path = "show ikev2 profile",
389  .short_help = "show ikev2 profile",
390  .function = show_ikev2_profile_command_fn,
391 };
392 
393 static clib_error_t *
395  unformat_input_t * input,
396  vlib_cli_command_t * cmd)
397 {
398  unformat_input_t _line_input, * line_input = &_line_input;
399  clib_error_t * r = 0;
400  u8 * data = 0;
401 
402  if (! unformat_user (input, unformat_line_input, line_input))
403  return 0;
404 
405  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
406  if (unformat (line_input, "%v", &data))
407  {
408  r = ikev2_set_local_key(vm, data);
409  goto done;
410  }
411  else
412  break;
413  }
414 
415  r = clib_error_return (0, "parse error: '%U'",
416  format_unformat_error, line_input);
417 
418 done:
419  vec_free(data);
420  unformat_free (line_input);
421  return r;
422 }
423 
424 VLIB_CLI_COMMAND (set_ikev2_local_key_command, static) = {
425  .path = "set ikev2 local key",
426  .short_help =
427  "set ikev2 local key <file>",
428  .function = set_ikev2_local_key_command_fn,
429 };
430 
431 clib_error_t *
433 {
434  return 0;
435 }
436 
u8 * format_ikev2_id_type_and_data(u8 *s, va_list *args)
Definition: ikev2_cli.c:24
ikev2_id_type_t type
Definition: ikev2_priv.h:104
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:942
clib_error_t * ikev2_add_del_profile(vlib_main_t *vm, u8 *name, int is_add)
Definition: ikev2.c:1956
ikev2_profile_t * profiles
Definition: ikev2_priv.h:217
always_inline void unformat_free(unformat_input_t *i)
Definition: format.h:160
#define UNFORMAT_END_OF_INPUT
Definition: format.h:142
unformat_function_t unformat_token
Definition: format.h:282
uword unformat_ikev2_id_type(unformat_input_t *input, va_list *args)
ikev2_main_t ikev2_main
Definition: ikev2_priv.h:234
format_function_t format_ip4_address
Definition: format.h:71
always_inline uword unformat_check_input(unformat_input_t *i)
Definition: format.h:168
ikev2_id_t rem_id
Definition: ikev2_priv.h:207
static clib_error_t * show_ikev2_sa_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ikev2_cli.c:48
#define pool_foreach(VAR, POOL, BODY)
Definition: pool.h:328
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:109
#define vec_new(T, N)
Create new vector of given type and length (unspecified alignment, no header).
Definition: vec.h:268
unformat_function_t unformat_hex_string
Definition: format.h:285
clib_error_t * ikev2_set_profile_auth(vlib_main_t *vm, u8 *name, u8 auth_method, u8 *auth_data, u8 data_hex_format)
Definition: ikev2.c:1986
ip4_address_t start_addr
Definition: ikev2_priv.h:99
u8 * format_hex_bytes(u8 *s, va_list *va)
Definition: std-formats.c:79
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:953
ikev2_id_t loc_id
Definition: ikev2_priv.h:206
unformat_function_t unformat_ip4_address
Definition: format.h:68
clib_error_t * ikev2_set_profile_id(vlib_main_t *vm, u8 *name, u8 id_type, u8 *data, int is_local)
Definition: ikev2.c:2016
ikev2_ts_t rem_ts
Definition: ikev2_priv.h:209
u16 end_port
Definition: ikev2_priv.h:98
ip4_address_t end_addr
Definition: ikev2_priv.h:100
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:538
clib_error_t * ikev2_set_local_key(vlib_main_t *vm, u8 *file)
Definition: ikev2.c:1944
clib_error_t * ikev2_set_profile_ts(vlib_main_t *vm, u8 *name, u8 protocol_id, u16 start_port, u16 end_port, ip4_address_t start_addr, ip4_address_t end_addr, int is_local)
Definition: ikev2.c:2053
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:298
ikev2_sa_t * sas
Definition: ikev2_priv.h:214
#define clib_memcpy(a, b, c)
Definition: string.h:63
ikev2_ts_t loc_ts
Definition: ikev2_priv.h:208
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:150
u8 protocol_id
Definition: ikev2_priv.h:95
unsigned int u32
Definition: types.h:88
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:87
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:405
u64 uword
Definition: types.h:112
static clib_error_t * show_ikev2_profile_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ikev2_cli.c:314
unsigned short u16
Definition: types.h:57
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u16 start_port
Definition: ikev2_priv.h:97
unsigned char u8
Definition: types.h:56
static clib_error_t * set_ikev2_local_key_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ikev2_cli.c:394
clib_error_t * ikev2_cli_init(vlib_main_t *vm)
Definition: ikev2_cli.c:432
#define clib_error_return(e, args...)
Definition: error.h:112
struct _unformat_input_t unformat_input_t
static clib_error_t * ikev2_profile_add_del_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ikev2_cli.c:163
unformat_function_t unformat_line_input
Definition: format.h:279
u8 * format_ikev2_id_type(u8 *s, va_list *args)