FD.io VPP  v21.01.1
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 #include <vnet/ipsec/ipsec_itf.h>
27 
28 u8 *
29 format_ipsec_policy_action (u8 * s, va_list * args)
30 {
31  u32 i = va_arg (*args, u32);
32  char *t = 0;
33 
34  switch (i)
35  {
36 #define _(v,f,str) case IPSEC_POLICY_ACTION_##f: t = str; break;
38 #undef _
39  default:
40  s = format (s, "unknown");
41  }
42  s = format (s, "%s", t);
43  return s;
44 }
45 
46 u8 *
47 format_ipsec_policy_type (u8 * s, va_list * args)
48 {
49  u32 i = va_arg (*args, u32);
50  char *t = 0;
51 
52  switch (i)
53  {
54 #define _(f,str) case IPSEC_SPD_POLICY_##f: t = str; break;
56 #undef _
57  default:
58  s = format (s, "unknown");
59  }
60  s = format (s, "%s", t);
61  return s;
62 }
63 
64 uword
66 {
67  u32 *r = va_arg (*args, u32 *);
68 
69  if (0);
70 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
72 #undef _
73  else
74  return 0;
75  return 1;
76 }
77 
78 u8 *
79 format_ipsec_crypto_alg (u8 * s, va_list * args)
80 {
81  u32 i = va_arg (*args, u32);
82  u8 *t = 0;
83 
84  switch (i)
85  {
86 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
88 #undef _
89  default:
90  s = format (s, "unknown");
91  }
92  s = format (s, "%s", t);
93  return s;
94 }
95 
96 uword
98 {
99  ipsec_crypto_alg_t *r = va_arg (*args, ipsec_crypto_alg_t *);
100 
101  if (0);
102 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
104 #undef _
105  else
106  return 0;
107  return 1;
108 }
109 
110 u8 *
111 format_ipsec_integ_alg (u8 * s, va_list * args)
112 {
113  u32 i = va_arg (*args, u32);
114  u8 *t = 0;
115 
116  switch (i)
117  {
118 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
120 #undef _
121  default:
122  s = format (s, "unknown");
123  }
124  s = format (s, "%s", t);
125  return s;
126 }
127 
128 uword
130 {
131  ipsec_integ_alg_t *r = va_arg (*args, ipsec_integ_alg_t *);
132 
133  if (0);
134 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
136 #undef _
137  else
138  return 0;
139  return 1;
140 }
141 
142 u8 *
143 format_ipsec_replay_window (u8 * s, va_list * args)
144 {
145  u64 w = va_arg (*args, u64);
146  u8 i;
147 
148  for (i = 0; i < 64; i++)
149  {
150  s = format (s, "%u", w & (1ULL << i) ? 1 : 0);
151  }
152 
153  return s;
154 }
155 
156 u8 *
157 format_ipsec_policy (u8 * s, va_list * args)
158 {
159  u32 pi = va_arg (*args, u32);
160  ip46_type_t ip_type = IP46_TYPE_IP4;
161  ipsec_main_t *im = &ipsec_main;
162  ipsec_policy_t *p;
163  vlib_counter_t counts;
164 
165  p = pool_elt_at_index (im->policies, pi);
166 
167  s = format (s, " [%d] priority %d action %U type %U protocol ",
168  pi, p->priority,
171  if (p->protocol)
172  {
173  s = format (s, "%U", format_ip_protocol, p->protocol);
174  }
175  else
176  {
177  s = format (s, "any");
178  }
179  if (p->policy == IPSEC_POLICY_ACTION_PROTECT)
180  {
181  s = format (s, " sa %u", p->sa_id);
182  }
183  if (p->is_ipv6)
184  {
185  ip_type = IP46_TYPE_IP6;
186  }
187 
188  s = format (s, "\n local addr range %U - %U port range %u - %u",
189  format_ip46_address, &p->laddr.start, ip_type,
190  format_ip46_address, &p->laddr.stop, ip_type,
191  p->lport.start, p->lport.stop);
192  s = format (s, "\n remote addr range %U - %U port range %u - %u",
193  format_ip46_address, &p->raddr.start, ip_type,
194  format_ip46_address, &p->raddr.stop, ip_type,
195  p->rport.start, p->rport.stop);
196 
198  s = format (s, "\n packets %u bytes %u", counts.packets, counts.bytes);
199 
200  return (s);
201 }
202 
203 u8 *
204 format_ipsec_spd (u8 * s, va_list * args)
205 {
206  u32 si = va_arg (*args, u32);
207  ipsec_main_t *im = &ipsec_main;
208  ipsec_spd_t *spd;
209  u32 *i;
210 
211  if (pool_is_free_index (im->spds, si))
212  {
213  s = format (s, "No such SPD index: %d", si);
214  goto done;
215  }
216 
217  spd = pool_elt_at_index (im->spds, si);
218 
219  s = format (s, "spd %u", spd->id);
220 
221 #define _(v, n) \
222  s = format (s, "\n %s:", n); \
223  vec_foreach(i, spd->policies[IPSEC_SPD_POLICY_##v]) \
224  { \
225  s = format (s, "\n %U", format_ipsec_policy, *i); \
226  }
228 #undef _
229 
230 done:
231  return (s);
232 }
233 
234 u8 *
235 format_ipsec_key (u8 * s, va_list * args)
236 {
237  ipsec_key_t *key = va_arg (*args, ipsec_key_t *);
238 
239  return (format (s, "%U", format_hex_bytes, key->data, key->len));
240 }
241 
242 uword
243 unformat_ipsec_key (unformat_input_t * input, va_list * args)
244 {
245  ipsec_key_t *key = va_arg (*args, ipsec_key_t *);
246  u8 *data;
247 
248  if (unformat (input, "%U", unformat_hex_string, &data))
249  {
250  ipsec_mk_key (key, data, vec_len (data));
251  vec_free (data);
252  }
253  else
254  return 0;
255  return 1;
256 }
257 
258 u8 *
259 format_ipsec_sa_flags (u8 * s, va_list * args)
260 {
261  ipsec_sa_flags_t flags = va_arg (*args, int);
262 
263 #define _(v, f, str) if (flags & IPSEC_SA_FLAG_##f) s = format(s, "%s ", str);
265 #undef _
266  return (s);
267 }
268 
269 u8 *
270 format_ipsec_sa (u8 * s, va_list * args)
271 {
272  u32 sai = va_arg (*args, u32);
274  ipsec_main_t *im = &ipsec_main;
275  vlib_counter_t counts;
277  ipsec_sa_t *sa;
278 
279  if (pool_is_free_index (im->sad, sai))
280  {
281  s = format (s, "No such SA index: %d", sai);
282  goto done;
283  }
284 
285  sa = pool_elt_at_index (im->sad, sai);
286 
287  s = format (s, "[%d] sa %u (0x%x) spi %u (0x%08x) protocol:%s flags:[%U]",
288  sai, sa->id, sa->id, sa->spi, sa->spi,
289  sa->protocol ? "esp" : "ah", format_ipsec_sa_flags, sa->flags);
290 
291  if (!(flags & IPSEC_FORMAT_DETAIL))
292  goto done;
293 
294  s = format (s, "\n locks %d", sa->node.fn_locks);
295  s = format (s, "\n salt 0x%x", clib_net_to_host_u32 (sa->salt));
296  s = format (s, "\n thread-indices [encrypt:%d decrypt:%d]",
298  s = format (s, "\n seq %u seq-hi %u", sa->seq, sa->seq_hi);
299  s = format (s, "\n last-seq %u last-seq-hi %u window %U",
300  sa->last_seq, sa->last_seq_hi,
302  s = format (s, "\n crypto alg %U",
304  if (sa->crypto_alg && (flags & IPSEC_FORMAT_INSECURE))
305  s = format (s, " key %U", format_ipsec_key, &sa->crypto_key);
306  else
307  s = format (s, " key [redacted]");
308  s = format (s, "\n integrity alg %U",
310  if (sa->integ_alg && (flags & IPSEC_FORMAT_INSECURE))
311  s = format (s, " key %U", format_ipsec_key, &sa->integ_key);
312  else
313  s = format (s, " key [redacted]");
314  s = format (s, "\n UDP:[src:%d dst:%d]",
315  clib_host_to_net_u16 (sa->udp_hdr.src_port),
316  clib_host_to_net_u16 (sa->udp_hdr.dst_port));
317 
319  s = format (s, "\n packets %u bytes %u", counts.packets, counts.bytes);
320 
321  if (ipsec_sa_is_set_IS_TUNNEL (sa))
322  {
323  tx_table_id = fib_table_get_table_id (sa->tx_fib_index,
325  s = format (s, "\n table-ID %d tunnel %U src %U dst %U flags %U",
326  tx_table_id,
327  format_ip_dscp, sa->dscp,
331  if (!ipsec_sa_is_set_IS_INBOUND (sa))
332  {
333  s =
334  format (s, "\n resovle via fib-entry: %d",
335  sa->fib_entry_index);
336  s = format (s, "\n stacked on:");
337  s = format (s, "\n %U", format_dpo_id, &sa->dpo, 6);
338  }
339  }
340 
341 done:
342  return (s);
343 }
344 
345 u8 *
346 format_ipsec_tun_protect_index (u8 * s, va_list * args)
347 {
348  u32 itpi = va_arg (*args, index_t);
349  ipsec_tun_protect_t *itp;
350 
352  return (format (s, "No such tunnel index: %d", itpi));
353 
355 
356  return (format (s, "%U", format_ipsec_tun_protect, itp));
357 }
358 
359 u8 *
360 format_ipsec_tun_protect_flags (u8 * s, va_list * args)
361 {
362  ipsec_protect_flags_t flags = va_arg (*args, int);
363 
364  if (IPSEC_PROTECT_NONE == flags)
365  s = format (s, "none");
366 #define _(a,b,c) \
367  else if (flags & IPSEC_PROTECT_##a) \
368  s = format (s, "%s", c); \
369  foreach_ipsec_protect_flags
370 #undef _
371 
372  return (s);
373 }
374 
375 u8 *
376 format_ipsec_tun_protect (u8 * s, va_list * args)
377 {
378  ipsec_tun_protect_t *itp = va_arg (*args, ipsec_tun_protect_t *);
379  u32 sai;
380 
381  s = format (s, "%U flags:[%U]", format_vnet_sw_if_index_name,
384  if (!ip_address_is_zero (itp->itp_key))
385  s = format (s, ": %U", format_ip_address, itp->itp_key);
386  s = format (s, "\n output-sa:");
387  s = format (s, "\n %U", format_ipsec_sa, itp->itp_out_sa,
389 
390  s = format (s, "\n input-sa:");
391  /* *INDENT-OFF* */
393  ({
394  s = format (s, "\n %U", format_ipsec_sa, sai, IPSEC_FORMAT_BRIEF);
395  }));
396  /* *INDENT-ON* */
397 
398  return (s);
399 }
400 
401 u8 *
402 format_ipsec4_tunnel_kv (u8 * s, va_list * args)
403 {
404  ipsec4_tunnel_kv_t *kv = va_arg (*args, ipsec4_tunnel_kv_t *);
406  u32 spi;
407 
408  ipsec4_tunnel_extract_key (kv, &ip, &spi);
409 
410  s = format (s, "remote:%U spi:%u (0x%08x) sa:%d tun:%d",
411  format_ip4_address, &ip,
412  clib_net_to_host_u32 (spi),
413  clib_net_to_host_u32 (spi),
414  kv->value.sa_index, kv->value.tun_index);
415 
416  return (s);
417 }
418 
419 u8 *
420 format_ipsec6_tunnel_kv (u8 * s, va_list * args)
421 {
422  ipsec6_tunnel_kv_t *kv = va_arg (*args, ipsec6_tunnel_kv_t *);
423 
424  s = format (s, "remote:%U spi:%u (0x%08x) sa:%d tun:%d",
426  clib_net_to_host_u32 (kv->key.spi),
427  clib_net_to_host_u32 (kv->key.spi),
428  kv->value.sa_index, kv->value.tun_index);
429 
430  return (s);
431 }
432 
433 u8 *
434 format_ipsec_itf (u8 * s, va_list * a)
435 {
436  index_t ii = va_arg (*a, index_t);
437  ipsec_itf_t *itf;
438 
439  itf = ipsec_itf_get (ii);
440  s = format (s, "[%d] %U %U",
443 
444  return (s);
445 }
446 
447 /*
448  * fd.io coding-style-patch-verification: ON
449  *
450  * Local Variables:
451  * eval: (c-set-style "gnu")
452  * End:
453  */
ipsec_itf_t * ipsec_itf_get(index_t ii)
Definition: ipsec_itf.c:34
format_function_t format_ip_protocol
Definition: format.h:45
u8 * format_ipsec_integ_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:111
ipsec_spd_t * spds
Definition: ipsec.h:109
fib_node_t node
Definition: ipsec_sa.h:200
ip46_address_t tunnel_src_addr
Definition: ipsec_sa.h:197
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
a
Definition: bitmap.h:544
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
ip_dscp_t dscp
Definition: ipsec_sa.h:168
unsigned long u64
Definition: types.h:89
ip46_address_range_t laddr
struct ipsec6_tunnel_kv_t_::@463 key
#define foreach_ipsec_crypto_alg
Definition: ipsec_sa.h:24
unformat_function_t unformat_hex_string
Definition: format.h:288
enum ipsec_format_flags_t_ ipsec_format_flags_t
ipsec_key_t crypto_key
Definition: ipsec_sa.h:217
ipsec_integ_alg_t integ_alg
Definition: ipsec_sa.h:214
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
Combined counter to hold both packets and byte differences.
Definition: counter_types.h:26
u32 tx_table_id
#define foreach_ipsec_integ_alg
Definition: ipsec_sa.h:51
A Secruity Policy Database.
Definition: ipsec_spd.h:46
u8 * format_ipsec4_tunnel_kv(u8 *s, va_list *args)
Definition: ipsec_format.c:402
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
u8 data[128]
Definition: ipsec_types.api:90
u8 * format_ipsec_tun_protect_index(u8 *s, va_list *args)
Definition: ipsec_format.c:346
u32 seq_hi
Definition: ipsec_sa.h:123
u64 replay_window
Definition: ipsec_sa.h:126
format_function_t format_ip4_address
Definition: format.h:73
ipsec_main_t ipsec_main
Definition: ipsec.c:28
description fragment has unexpected format
Definition: map.api:433
u8 * format_ipsec_tun_protect(u8 *s, va_list *args)
Definition: ipsec_format.c:376
tunnel_encap_decap_flags_t tunnel_flags
Definition: ipsec_sa.h:167
uword unformat_ipsec_crypto_alg(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:97
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:143
port_range_t rport
u8 * format_ipsec_sa(u8 *s, va_list *args)
Definition: ipsec_format.c:270
u8 * format_ipsec_crypto_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:79
unsigned int u32
Definition: types.h:88
ipsec_sa_flags_t flags
Definition: ipsec_sa.h:114
u8 * format_ip_dscp(u8 *s, va_list *va)
Definition: ip.c:262
u32 last_seq
Definition: ipsec_sa.h:124
u32 encrypt_thread_index
Definition: ipsec_sa.h:119
u32 tx_fib_index
Definition: ipsec_sa.h:210
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:546
vlib_combined_counter_main_t ipsec_spd_policy_counters
Policy packet & bytes counters.
counter_t packets
packet counter
Definition: counter_types.h:28
ipsec_tun_protect_t * ipsec_tun_protect_pool
Pool of tunnel protection objects.
Definition: ipsec_tun.c:43
u8 * format_ipsec_spd(u8 *s, va_list *args)
Definition: ipsec_format.c:204
u32 salt
Definition: ipsec_sa.h:164
struct _unformat_input_t unformat_input_t
fib_node_index_t fib_entry_index
Definition: ipsec_sa.h:208
u32 last_seq_hi
Definition: ipsec_sa.h:125
ipsec_tun_lkup_result_t value
Definition: ipsec_tun.h:54
u8 * format_ipsec_tun_protect_flags(u8 *s, va_list *args)
Definition: ipsec_format.c:360
bool ip_address_is_zero(const ip_address_t *ip)
Definition: ip_types.c:102
ipsec_spd_policy_type_t type
ip46_address_t tunnel_dst_addr
Definition: ipsec_sa.h:198
format_function_t format_ip46_address
Definition: ip46_address.h:50
A dedicated IPSec interface type.
Definition: ipsec_itf.h:94
ipsec_tun_lkup_result_t value
Definition: ipsec_tun.h:88
u8 * format_ipsec_policy(u8 *s, va_list *args)
Definition: ipsec_format.c:157
format_function_t format_ip6_address
Definition: format.h:91
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:278
ip6_address_t remote_ip
Definition: ipsec_tun.h:84
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
ipsec_policy_action_t policy
u8 * format_ipsec6_tunnel_kv(u8 *s, va_list *args)
Definition: ipsec_format.c:420
ip46_address_t start
u8 * format_ip_address(u8 *s, va_list *args)
Definition: ip_types.c:21
udp_header_t udp_hdr
Definition: ipsec_sa.h:161
enum ipsec_sad_flags_t_ ipsec_sa_flags_t
u32 spi
Definition: flow_types.api:140
#define FOR_EACH_IPSEC_PROTECT_INPUT_SAI(_itp, _sai, body)
Definition: ipsec_tun.h:129
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:298
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:78
ipsec_policy_t * policies
Definition: ipsec.h:113
u32 ii_sw_if_index
Definition: ipsec_itf.h:98
ipsec_sa_t * sad
Definition: ipsec.h:111
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:1095
uword unformat_ipsec_integ_alg(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:129
u8 * format_ipsec_policy_type(u8 *s, va_list *args)
Definition: ipsec_format.c:47
ipsec_protocol_t protocol
Definition: ipsec_sa.h:166
u8 * format_ipsec_policy_action(u8 *s, va_list *args)
Definition: ipsec_format.c:29
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:65
typedef key
Definition: ipsec_types.api:86
counter_t bytes
byte counter
Definition: counter_types.h:29
tunnel_mode_t ii_mode
Definition: ipsec_itf.h:96
vl_api_address_t ip
Definition: l2.api:501
#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
ipsec_protect_flags_t itp_flags
Definition: ipsec_tun.h:120
u32 id
the User&#39;s ID for this policy
Definition: ipsec_spd.h:49
u8 * format_ipsec_itf(u8 *s, va_list *a)
Definition: ipsec_format.c:434
dpo_id_t dpo
Definition: ipsec_sa.h:127
ipsec_crypto_alg_t crypto_alg
Definition: ipsec_sa.h:213
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:259
u8 * format_tunnel_mode(u8 *s, va_list *args)
Definition: tunnel.c:21
u8 * format_tunnel_encap_decap_flags(u8 *s, va_list *args)
Definition: tunnel.c:52
ip_address_t * itp_key
Definition: ipsec_tun.h:125
u8 si
Definition: lisp_types.api:47
ipsec_key_t integ_key
Definition: ipsec_sa.h:216
static void ipsec4_tunnel_extract_key(const ipsec4_tunnel_kv_t *k, ip4_address_t *ip, u32 *spi)
Definition: ipsec_tun.h:69
uword unformat_ipsec_key(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:243
u32 decrypt_thread_index
Definition: ipsec_sa.h:120
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:235
enum ipsec_protect_flags_t_ ipsec_protect_flags_t
ip46_type_t
Definition: ip46_address.h:22