FD.io VPP  v19.08.3-2-gbabecb413
Vector Packet Processing
ipsec_format.c
Go to the documentation of this file.
1 /*
2  * decap.c : IPSec tunnel support
3  *
4  * Copyright (c) 2015 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vnet/vnet.h>
19 #include <vnet/api_errno.h>
20 #include <vnet/ip/ip.h>
21 #include <vnet/interface.h>
22 #include <vnet/fib/fib_table.h>
23 
24 #include <vnet/ipsec/ipsec.h>
25 #include <vnet/ipsec/ipsec_tun.h>
26 
27 u8 *
28 format_ipsec_policy_action (u8 * s, va_list * args)
29 {
30  u32 i = va_arg (*args, u32);
31  char *t = 0;
32 
33  switch (i)
34  {
35 #define _(v,f,str) case IPSEC_POLICY_ACTION_##f: t = str; break;
37 #undef _
38  default:
39  s = format (s, "unknown");
40  }
41  s = format (s, "%s", t);
42  return s;
43 }
44 
45 u8 *
46 format_ipsec_policy_type (u8 * s, va_list * args)
47 {
48  u32 i = va_arg (*args, u32);
49  char *t = 0;
50 
51  switch (i)
52  {
53 #define _(f,str) case IPSEC_SPD_POLICY_##f: t = str; break;
55 #undef _
56  default:
57  s = format (s, "unknown");
58  }
59  s = format (s, "%s", t);
60  return s;
61 }
62 
63 uword
65 {
66  u32 *r = va_arg (*args, u32 *);
67 
68  if (0);
69 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
71 #undef _
72  else
73  return 0;
74  return 1;
75 }
76 
77 u8 *
78 format_ipsec_crypto_alg (u8 * s, va_list * args)
79 {
80  u32 i = va_arg (*args, u32);
81  u8 *t = 0;
82 
83  switch (i)
84  {
85 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
87 #undef _
88  default:
89  s = format (s, "unknown");
90  }
91  s = format (s, "%s", t);
92  return s;
93 }
94 
95 uword
97 {
98  u32 *r = va_arg (*args, u32 *);
99 
100  if (0);
101 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
103 #undef _
104  else
105  return 0;
106  return 1;
107 }
108 
109 u8 *
110 format_ipsec_integ_alg (u8 * s, va_list * args)
111 {
112  u32 i = va_arg (*args, u32);
113  u8 *t = 0;
114 
115  switch (i)
116  {
117 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
119 #undef _
120  default:
121  s = format (s, "unknown");
122  }
123  s = format (s, "%s", t);
124  return s;
125 }
126 
127 uword
129 {
130  u32 *r = va_arg (*args, u32 *);
131 
132  if (0);
133 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
135 #undef _
136  else
137  return 0;
138  return 1;
139 }
140 
141 u8 *
142 format_ipsec_replay_window (u8 * s, va_list * args)
143 {
144  u64 w = va_arg (*args, u64);
145  u8 i;
146 
147  for (i = 0; i < 64; i++)
148  {
149  s = format (s, "%u", w & (1ULL << i) ? 1 : 0);
150  }
151 
152  return s;
153 }
154 
155 u8 *
156 format_ipsec_policy (u8 * s, va_list * args)
157 {
158  u32 pi = va_arg (*args, u32);
159  ip46_type_t ip_type = IP46_TYPE_IP4;
160  ipsec_main_t *im = &ipsec_main;
161  ipsec_policy_t *p;
162  vlib_counter_t counts;
163 
164  p = pool_elt_at_index (im->policies, pi);
165 
166  s = format (s, " [%d] priority %d action %U type %U protocol ",
167  pi, p->priority,
170  if (p->protocol)
171  {
172  s = format (s, "%U", format_ip_protocol, p->protocol);
173  }
174  else
175  {
176  s = format (s, "any");
177  }
178  if (p->policy == IPSEC_POLICY_ACTION_PROTECT)
179  {
180  s = format (s, " sa %u", p->sa_id);
181  }
182  if (p->is_ipv6)
183  {
184  ip_type = IP46_TYPE_IP6;
185  }
186 
187  s = format (s, "\n local addr range %U - %U port range %u - %u",
188  format_ip46_address, &p->laddr.start, ip_type,
189  format_ip46_address, &p->laddr.stop, ip_type,
190  p->lport.start, p->lport.stop);
191  s = format (s, "\n remote addr range %U - %U port range %u - %u",
192  format_ip46_address, &p->raddr.start, ip_type,
193  format_ip46_address, &p->raddr.stop, ip_type,
194  p->rport.start, p->rport.stop);
195 
197  s = format (s, "\n packets %u bytes %u", counts.packets, counts.bytes);
198 
199  return (s);
200 }
201 
202 u8 *
203 format_ipsec_spd (u8 * s, va_list * args)
204 {
205  u32 si = va_arg (*args, u32);
206  ipsec_main_t *im = &ipsec_main;
207  ipsec_spd_t *spd;
208  u32 *i;
209 
210  if (pool_is_free_index (im->spds, si))
211  {
212  s = format (s, "No such SPD index: %d", si);
213  goto done;
214  }
215 
216  spd = pool_elt_at_index (im->spds, si);
217 
218  s = format (s, "spd %u", spd->id);
219 
220 #define _(v, n) \
221  s = format (s, "\n %s:", n); \
222  vec_foreach(i, spd->policies[IPSEC_SPD_POLICY_##v]) \
223  { \
224  s = format (s, "\n %U", format_ipsec_policy, *i); \
225  }
227 #undef _
228 
229 done:
230  return (s);
231 }
232 
233 u8 *
234 format_ipsec_key (u8 * s, va_list * args)
235 {
236  ipsec_key_t *key = va_arg (*args, ipsec_key_t *);
237 
238  return (format (s, "%U", format_hex_bytes, key->data, key->len));
239 }
240 
241 uword
242 unformat_ipsec_key (unformat_input_t * input, va_list * args)
243 {
244  ipsec_key_t *key = va_arg (*args, ipsec_key_t *);
245  u8 *data;
246 
247  if (unformat (input, "%U", unformat_hex_string, &data))
248  {
249  ipsec_mk_key (key, data, vec_len (data));
250  vec_free (data);
251  }
252  else
253  return 0;
254  return 1;
255 }
256 
257 u8 *
258 format_ipsec_sa_flags (u8 * s, va_list * args)
259 {
260  ipsec_sa_flags_t flags = va_arg (*args, int);
261 
262 #define _(v, f, str) if (flags & IPSEC_SA_FLAG_##f) s = format(s, "%s ", str);
264 #undef _
265  return (s);
266 }
267 
268 u8 *
269 format_ipsec_sa (u8 * s, va_list * args)
270 {
271  u32 sai = va_arg (*args, u32);
273  ipsec_main_t *im = &ipsec_main;
274  vlib_counter_t counts;
276  ipsec_sa_t *sa;
277 
278  if (pool_is_free_index (im->sad, sai))
279  {
280  s = format (s, "No such SA index: %d", sai);
281  goto done;
282  }
283 
284  sa = pool_elt_at_index (im->sad, sai);
285 
286  s = format (s, "[%d] sa %u (0x%x) spi %u (0x%08x) protocol:%s flags:[%U]",
287  sai, sa->id, sa->id, sa->spi, sa->spi,
288  sa->protocol ? "esp" : "ah", format_ipsec_sa_flags, sa->flags);
289 
290  if (!(flags & IPSEC_FORMAT_DETAIL))
291  goto done;
292 
293  s = format (s, "\n locks %d", sa->node.fn_locks);
294  s = format (s, "\n salt 0x%x", clib_net_to_host_u32 (sa->salt));
295  s = format (s, "\n seq %u seq-hi %u", sa->seq, sa->seq_hi);
296  s = format (s, "\n last-seq %u last-seq-hi %u window %U",
297  sa->last_seq, sa->last_seq_hi,
299  s = format (s, "\n crypto alg %U",
301  if (sa->crypto_alg && (flags & IPSEC_FORMAT_INSECURE))
302  s = format (s, " key %U", format_ipsec_key, &sa->crypto_key);
303  else
304  s = format (s, " key [redacted]");
305  s = format (s, "\n integrity alg %U",
307  if (sa->integ_alg && (flags & IPSEC_FORMAT_INSECURE))
308  s = format (s, " key %U", format_ipsec_key, &sa->integ_key);
309  else
310  s = format (s, " key [redacted]");
311 
313  s = format (s, "\n packets %u bytes %u", counts.packets, counts.bytes);
314 
315  if (ipsec_sa_is_set_IS_TUNNEL (sa))
316  {
317  tx_table_id = fib_table_get_table_id (sa->tx_fib_index,
319  s = format (s, "\n table-ID %d tunnel src %U dst %U",
320  tx_table_id,
323  if (!ipsec_sa_is_set_IS_INBOUND (sa))
324  {
325  s =
326  format (s, "\n resovle via fib-entry: %d",
327  sa->fib_entry_index);
328  s = format (s, "\n stacked on:");
329  s = format (s, "\n %U", format_dpo_id, &sa->dpo, 6);
330  }
331  }
332 
333 done:
334  return (s);
335 }
336 
337 u8 *
338 format_ipsec_tunnel (u8 * s, va_list * args)
339 {
340  ipsec_main_t *im = &ipsec_main;
341  u32 ti = va_arg (*args, u32);
343 
345  {
346  s = format (s, "No such tunnel index: %d", ti);
347  goto done;
348  }
349 
350  t = pool_elt_at_index (im->tunnel_interfaces, ti);
351 
352  if (t->hw_if_index == ~0)
353  goto done;
354 
355  s =
357  t->hw_if_index);
358 
359  s = format (s, " out-bound sa: ");
360  s = format (s, "%U\n", format_ipsec_sa, t->output_sa_index,
362 
363  s = format (s, " in-bound sa: ");
364  s = format (s, "%U\n", format_ipsec_sa, t->input_sa_index,
366 
367 done:
368  return (s);
369 }
370 
371 u8 *
372 format_ipsec_tun_protect (u8 * s, va_list * args)
373 {
374  u32 itpi = va_arg (*args, u32);
375  ipsec_tun_protect_t *itp;
376  u32 sai;
377 
379  {
380  s = format (s, "No such tunnel index: %d", itpi);
381  goto done;
382  }
383 
385 
386  s = format (s, "%U", format_vnet_sw_if_index_name,
387  vnet_get_main (), itp->itp_sw_if_index);
388  s = format (s, "\n output-sa:");
389  s =
390  format (s, "\n %U", format_ipsec_sa, itp->itp_out_sa,
392 
393  s = format (s, "\n input-sa:");
394  /* *INDENT-OFF* */
396  ({
397  s = format (s, "\n %U", format_ipsec_sa, sai, IPSEC_FORMAT_BRIEF);
398  }));
399  /* *INDENT-ON* */
400 
401 done:
402  return (s);
403 }
404 
405 u8 *
406 format_ipsec4_tunnel_key (u8 * s, va_list * args)
407 {
408  ipsec4_tunnel_key_t *key = va_arg (*args, ipsec4_tunnel_key_t *);
409 
410  s = format (s, "remote:%U spi:%u (0x%08x)",
411  format_ip4_address, &key->remote_ip,
412  clib_net_to_host_u32 (key->spi),
413  clib_net_to_host_u32 (key->spi));
414 
415  return (s);
416 }
417 
418 u8 *
419 format_ipsec6_tunnel_key (u8 * s, va_list * args)
420 {
421  ipsec6_tunnel_key_t *key = va_arg (*args, ipsec6_tunnel_key_t *);
422 
423  s = format (s, "remote:%U spi:%u (0x%08x)",
424  format_ip6_address, &key->remote_ip,
425  clib_net_to_host_u32 (key->spi),
426  clib_net_to_host_u32 (key->spi));
427 
428  return (s);
429 }
430 
431 /*
432  * fd.io coding-style-patch-verification: ON
433  *
434  * Local Variables:
435  * eval: (c-set-style "gnu")
436  * End:
437  */
u32 tx_table_id
Definition: ipsec.api:288
format_function_t format_ip_protocol
Definition: format.h:45
u8 * format_ipsec_integ_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:110
ipsec_spd_t * spds
Definition: ipsec.h:95
fib_node_t node
Definition: ipsec_sa.h:141
format_function_t format_vnet_hw_if_index_name
u32 flags
Definition: vhost_user.h:141
ipsec_tunnel_if_t * tunnel_interfaces
Definition: ipsec.h:102
ip46_address_t tunnel_src_addr
Definition: ipsec_sa.h:154
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
unsigned long u64
Definition: types.h:89
ip46_address_range_t laddr
#define foreach_ipsec_crypto_alg
Definition: ipsec_sa.h:22
unformat_function_t unformat_hex_string
Definition: format.h:289
enum ipsec_format_flags_t_ ipsec_format_flags_t
ipsec_key_t crypto_key
Definition: ipsec_sa.h:147
ipsec_integ_alg_t integ_alg
Definition: ipsec_sa.h:150
Combined counter to hold both packets and byte differences.
Definition: counter_types.h:26
int i
u8 * format_ipsec6_tunnel_key(u8 *s, va_list *args)
Definition: ipsec_format.c:419
#define foreach_ipsec_integ_alg
Definition: ipsec_sa.h:49
format_function_t format_ip46_address
Definition: format.h:61
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
u8 data[128]
Definition: ipsec.api:251
A Secruity Policy Database.
Definition: ipsec_spd.h:44
void ipsec_mk_key(ipsec_key_t *key, const u8 *data, u8 len)
Definition: ipsec_sa.c:56
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
u32 seq_hi
Definition: ipsec_sa.h:119
u64 replay_window
Definition: ipsec_sa.h:122
format_function_t format_ip4_address
Definition: format.h:75
ipsec_main_t ipsec_main
Definition: ipsec.c:28
u8 * format_ipsec_tun_protect(u8 *s, va_list *args)
Definition: ipsec_format.c:372
uword unformat_ipsec_crypto_alg(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:96
u8 * format_hex_bytes(u8 *s, va_list *va)
Definition: std-formats.c:84
u8 * format_ipsec_replay_window(u8 *s, va_list *args)
Definition: ipsec_format.c:142
port_range_t rport
u8 * format_ipsec_sa(u8 *s, va_list *args)
Definition: ipsec_format.c:269
u8 * format_ipsec_crypto_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:78
unsigned int u32
Definition: types.h:88
ipsec_sa_flags_t flags
Definition: ipsec_sa.h:112
u32 last_seq
Definition: ipsec_sa.h:120
u32 tx_fib_index
Definition: ipsec_sa.h:160
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:514
vlib_combined_counter_main_t ipsec_spd_policy_counters
Policy packet & bytes counters.
counter_t packets
packet counter
Definition: counter_types.h:28
u8 * format_ipsec_spd(u8 *s, va_list *args)
Definition: ipsec_format.c:203
u32 salt
Definition: ipsec_sa.h:163
vnet_main_t * vnet_main
Definition: ipsec.h:108
struct _unformat_input_t unformat_input_t
fib_node_index_t fib_entry_index
Definition: ipsec_sa.h:157
u32 last_seq_hi
Definition: ipsec_sa.h:121
u8 * format_ipsec_tunnel(u8 *s, va_list *args)
Definition: ipsec_format.c:338
ipsec_spd_policy_type_t type
ip46_address_t tunnel_dst_addr
Definition: ipsec_sa.h:155
u8 * format_ipsec_policy(u8 *s, va_list *args)
Definition: ipsec_format.c:156
format_function_t format_ip6_address
Definition: format.h:93
static void vlib_get_combined_counter(const vlib_combined_counter_main_t *cm, u32 index, vlib_counter_t *result)
Get the value of a combined counter, never called in the speed path Scrapes the entire set of per-thr...
Definition: counter.h:259
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
ipsec_policy_action_t policy
ip46_address_t start
enum ipsec_sad_flags_t_ ipsec_sa_flags_t
#define FOR_EACH_IPSEC_PROTECT_INPUT_SAI(_itp, _sai, body)
Definition: ipsec_tun.h:52
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:283
A Secruity Policy.
vlib_combined_counter_main_t ipsec_sa_counters
SA packet & bytes counters.
Definition: ipsec_sa.c:27
u8 data[IPSEC_KEY_MAX_LEN]
Definition: ipsec_sa.h:76
ipsec_policy_t * policies
Definition: ipsec.h:99
ipsec_tun_protect_t * ipsec_protect_pool
Pool of tunnel protection objects.
Definition: ipsec_tun.c:25
ip46_type_t
Definition: ip6_packet.h:70
ipsec_sa_t * sad
Definition: ipsec.h:97
u32 fib_table_get_table_id(u32 fib_index, fib_protocol_t proto)
Get the Table-ID of the FIB from protocol and index.
Definition: fib_table.c:1069
uword unformat_ipsec_integ_alg(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:128
u8 * format_ipsec_policy_type(u8 *s, va_list *args)
Definition: ipsec_format.c:46
ipsec_protocol_t protocol
Definition: ipsec_sa.h:144
u8 * format_ipsec_policy_action(u8 *s, va_list *args)
Definition: ipsec_format.c:28
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject
Definition: dpo.c:148
uword unformat_ipsec_policy_action(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:64
counter_t bytes
byte counter
Definition: counter_types.h:29
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
ip46_address_range_t raddr
u32 fn_locks
Number of dependents on this node.
Definition: fib_node.h:315
u64 uword
Definition: types.h:112
typedef key
Definition: ipsec.api:247
u32 id
the User&#39;s ID for this policy
Definition: ipsec_spd.h:47
dpo_id_t dpo
Definition: ipsec_sa.h:123
ipsec_crypto_alg_t crypto_alg
Definition: ipsec_sa.h:146
port_range_t lport
#define foreach_ipsec_spd_policy_type
Definition: ipsec_spd.h:20
u8 * format_ipsec_sa_flags(u8 *s, va_list *args)
Definition: ipsec_format.c:258
u8 * format_ipsec4_tunnel_key(u8 *s, va_list *args)
Definition: ipsec_format.c:406
ipsec_key_t integ_key
Definition: ipsec_sa.h:151
uword unformat_ipsec_key(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:242
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
u8 * format_ipsec_key(u8 *s, va_list *args)
Definition: ipsec_format.c:234