FD.io VPP  v19.04.2-12-g66b1689
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 
26 u8 *
27 format_ipsec_policy_action (u8 * s, va_list * args)
28 {
29  u32 i = va_arg (*args, u32);
30  char *t = 0;
31 
32  switch (i)
33  {
34 #define _(v,f,str) case IPSEC_POLICY_ACTION_##f: t = str; break;
36 #undef _
37  default:
38  s = format (s, "unknown");
39  }
40  s = format (s, "%s", t);
41  return s;
42 }
43 
44 u8 *
45 format_ipsec_policy_type (u8 * s, va_list * args)
46 {
47  u32 i = va_arg (*args, u32);
48  char *t = 0;
49 
50  switch (i)
51  {
52 #define _(f,str) case IPSEC_SPD_POLICY_##f: t = str; break;
54 #undef _
55  default:
56  s = format (s, "unknown");
57  }
58  s = format (s, "%s", t);
59  return s;
60 }
61 
62 uword
64 {
65  u32 *r = va_arg (*args, u32 *);
66 
67  if (0);
68 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
70 #undef _
71  else
72  return 0;
73  return 1;
74 }
75 
76 u8 *
77 format_ipsec_crypto_alg (u8 * s, va_list * args)
78 {
79  u32 i = va_arg (*args, u32);
80  u8 *t = 0;
81 
82  switch (i)
83  {
84 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
86 #undef _
87  default:
88  s = format (s, "unknown");
89  }
90  s = format (s, "%s", t);
91  return s;
92 }
93 
94 uword
96 {
97  u32 *r = va_arg (*args, u32 *);
98 
99  if (0);
100 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
102 #undef _
103  else
104  return 0;
105  return 1;
106 }
107 
108 u8 *
109 format_ipsec_integ_alg (u8 * s, va_list * args)
110 {
111  u32 i = va_arg (*args, u32);
112  u8 *t = 0;
113 
114  switch (i)
115  {
116 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
118 #undef _
119  default:
120  s = format (s, "unknown");
121  }
122  s = format (s, "%s", t);
123  return s;
124 }
125 
126 uword
128 {
129  u32 *r = va_arg (*args, u32 *);
130 
131  if (0);
132 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
134 #undef _
135  else
136  return 0;
137  return 1;
138 }
139 
140 u8 *
141 format_ipsec_replay_window (u8 * s, va_list * args)
142 {
143  u64 w = va_arg (*args, u64);
144  u8 i;
145 
146  for (i = 0; i < 64; i++)
147  {
148  s = format (s, "%u", w & (1ULL << i) ? 1 : 0);
149  }
150 
151  return s;
152 }
153 
154 u8 *
155 format_ipsec_policy (u8 * s, va_list * args)
156 {
157  u32 pi = va_arg (*args, u32);
158  ipsec_main_t *im = &ipsec_main;
159  ipsec_policy_t *p;
160  vlib_counter_t counts;
161  ip46_type_t ip_type;
162 
163  p = pool_elt_at_index (im->policies, pi);
164 
165  s = format (s, " [%d] priority %d action %U type %U protocol ",
166  pi, p->priority,
169  if (p->protocol)
170  {
171  s = format (s, "%U", format_ip_protocol, p->protocol);
172  }
173  else
174  {
175  s = format (s, "any");
176  }
177  if (p->policy == IPSEC_POLICY_ACTION_PROTECT)
178  {
179  s = format (s, " sa %u", p->sa_id);
180  }
181  if (p->is_ipv6)
182  {
183  ip_type = IP46_TYPE_IP6;
184  }
185 
186  s = format (s, "\n local addr range %U - %U port range %u - %u",
187  format_ip46_address, &p->laddr.start, ip_type,
188  format_ip46_address, &p->laddr.stop, ip_type,
189  p->lport.start, p->lport.stop);
190  s = format (s, "\n remote addr range %U - %U port range %u - %u",
191  format_ip46_address, &p->raddr.start, ip_type,
192  format_ip46_address, &p->raddr.stop, ip_type,
193  p->rport.start, p->rport.stop);
194 
196  s = format (s, "\n packets %u bytes %u", counts.packets, counts.bytes);
197 
198  return (s);
199 }
200 
201 u8 *
202 format_ipsec_spd (u8 * s, va_list * args)
203 {
204  u32 si = va_arg (*args, u32);
205  ipsec_main_t *im = &ipsec_main;
206  ipsec_spd_t *spd;
207  u32 *i;
208 
209  if (pool_is_free_index (im->spds, si))
210  {
211  s = format (s, "No such SPD index: %d", si);
212  goto done;
213  }
214 
215  spd = pool_elt_at_index (im->spds, si);
216 
217  s = format (s, "spd %u", spd->id);
218 
219 #define _(v, n) \
220  s = format (s, "\n %s:", n); \
221  vec_foreach(i, spd->policies[IPSEC_SPD_POLICY_##v]) \
222  { \
223  s = format (s, "\n %U", format_ipsec_policy, *i); \
224  }
226 #undef _
227 
228 done:
229  return (s);
230 }
231 
232 u8 *
233 format_ipsec_key (u8 * s, va_list * args)
234 {
235  ipsec_key_t *key = va_arg (*args, ipsec_key_t *);
236 
237  return (format (s, "%U", format_hex_bytes, key->data, key->len));
238 }
239 
240 uword
241 unformat_ipsec_key (unformat_input_t * input, va_list * args)
242 {
243  ipsec_key_t *key = va_arg (*args, ipsec_key_t *);
244  u8 *data;
245 
246  if (unformat (input, "%U", unformat_hex_string, &data))
247  {
248  ipsec_mk_key (key, data, vec_len (data));
249  vec_free (data);
250  }
251  else
252  return 0;
253  return 1;
254 }
255 
256 u8 *
257 format_ipsec_sa_flags (u8 * s, va_list * args)
258 {
259  ipsec_sa_flags_t flags = va_arg (*args, int);
260 
261  if (0)
262  ;
263 #define _(v, f, str) else 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 0x%x spi %u mode %s%s protocol %s %U",
288  sai, sa->id, sa->spi,
289  ipsec_sa_is_set_IS_TUNNEL (sa) ? "tunnel" : "transport",
290  ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ? "-ip6" : "",
291  sa->protocol ? "esp" : "ah", format_ipsec_sa_flags, sa->flags);
292 
293  if (!(flags & IPSEC_FORMAT_DETAIL))
294  goto done;
295 
296  s = format (s, "\n salt 0x%x", sa->salt);
297  s = format (s, "\n seq %u seq-hi %u", sa->seq, sa->seq_hi);
298  s = format (s, "\n last-seq %u last-seq-hi %u window %U",
299  sa->last_seq, sa->last_seq_hi,
301  s = format (s, "\n crypto alg %U%s%U",
303  sa->crypto_alg ? " key " : "",
305  s = format (s, "\n integrity alg %U%s%U",
307  sa->integ_alg ? " key " : "", format_ipsec_key, &sa->integ_key);
309  s = format (s, "\n packets %u bytes %u", counts.packets, counts.bytes);
310 
311  if (ipsec_sa_is_set_IS_TUNNEL (sa))
312  {
313  tx_table_id = fib_table_get_table_id (sa->tx_fib_index,
315  s = format (s, "\n table-ID %d tunnel src %U dst %U",
316  tx_table_id,
319  if (!ipsec_sa_is_set_IS_INBOUND (sa))
320  {
321  s =
322  format (s, "\n resovle via fib-entry: %d",
323  sa->fib_entry_index);
324  s = format (s, "\n stacked on:");
325  s =
326  format (s, "\n %U", format_dpo_id,
327  &sa->dpo[IPSEC_PROTOCOL_ESP], 6);
328  }
329  }
330 
331 done:
332  return (s);
333 }
334 
335 u8 *
336 format_ipsec_tunnel (u8 * s, va_list * args)
337 {
338  ipsec_main_t *im = &ipsec_main;
339  u32 ti = va_arg (*args, u32);
342 
344  {
345  s = format (s, "No such tunnel index: %d", ti);
346  goto done;
347  }
348 
349  t = pool_elt_at_index (im->tunnel_interfaces, ti);
350 
351  if (t->hw_if_index == ~0)
352  goto done;
353 
355 
356  s = format (s, "%s\n", hi->name);
357 
358  s = format (s, " out-bound sa: ");
359  s = format (s, "%U\n", format_ipsec_sa, t->output_sa_index,
361 
362  s = format (s, " in-bound sa: ");
363  s = format (s, "%U\n", format_ipsec_sa, t->input_sa_index,
365 
366 done:
367  return (s);
368 }
369 
370 /*
371  * fd.io coding-style-patch-verification: ON
372  *
373  * Local Variables:
374  * eval: (c-set-style "gnu")
375  * End:
376  */
u32 tx_table_id
Definition: ipsec.api:284
vmrglw vmrglh hi
format_function_t format_ip_protocol
Definition: format.h:45
u8 * format_ipsec_integ_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:109
ipsec_spd_t * spds
Definition: ipsec.h:93
u32 flags
Definition: vhost_user.h:115
ipsec_tunnel_if_t * tunnel_interfaces
Definition: ipsec.h:100
ip46_address_t tunnel_src_addr
Definition: ipsec_sa.h:156
unsigned long u64
Definition: types.h:89
ip46_address_range_t laddr
#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:151
ipsec_integ_alg_t integ_alg
Definition: ipsec_sa.h:153
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
Combined counter to hold both packets and byte differences.
Definition: counter_types.h:26
int i
#define foreach_ipsec_integ_alg
Definition: ipsec_sa.h:51
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:248
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:54
unsigned char u8
Definition: types.h:56
u32 seq_hi
Definition: ipsec_sa.h:123
u64 replay_window
Definition: ipsec_sa.h:126
ipsec_main_t ipsec_main
Definition: ipsec.c:28
uword unformat_ipsec_crypto_alg(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:95
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:141
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:77
unsigned int u32
Definition: types.h:88
ipsec_sa_flags_t flags
Definition: ipsec_sa.h:116
u32 last_seq
Definition: ipsec_sa.h:124
u32 tx_fib_index
Definition: ipsec_sa.h:162
#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:202
u32 salt
Definition: ipsec_sa.h:163
vnet_main_t * vnet_main
Definition: ipsec.h:106
struct _unformat_input_t unformat_input_t
fib_node_index_t fib_entry_index
Definition: ipsec_sa.h:159
u32 last_seq_hi
Definition: ipsec_sa.h:125
u8 * format_ipsec_tunnel(u8 *s, va_list *args)
Definition: ipsec_format.c:336
ipsec_spd_policy_type_t type
ip46_address_t tunnel_dst_addr
Definition: ipsec_sa.h:157
u8 * format_ipsec_policy(u8 *s, va_list *args)
Definition: ipsec_format.c:155
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 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:25
u8 data[IPSEC_KEY_MAX_LEN]
Definition: ipsec_sa.h:80
ipsec_policy_t * policies
Definition: ipsec.h:97
ip46_type_t
Definition: ip6_packet.h:70
ipsec_sa_t * sad
Definition: ipsec.h:95
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:1053
dpo_id_t dpo[IPSEC_N_PROTOCOLS]
Definition: ipsec_sa.h:132
uword unformat_ipsec_integ_alg(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:127
u8 * format_ipsec_policy_type(u8 *s, va_list *args)
Definition: ipsec_format.c:45
ipsec_protocol_t protocol
Definition: ipsec_sa.h:148
u8 * format_ipsec_policy_action(u8 *s, va_list *args)
Definition: ipsec_format.c:27
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject
Definition: dpo.c:147
uword unformat_ipsec_policy_action(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:63
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
u64 uword
Definition: types.h:112
typedef key
Definition: ipsec.api:244
u32 id
the User&#39;s ID for this policy
Definition: ipsec_spd.h:47
ipsec_crypto_alg_t crypto_alg
Definition: ipsec_sa.h:150
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:257
ipsec_key_t integ_key
Definition: ipsec_sa.h:154
uword unformat_ipsec_key(unformat_input_t *input, va_list *args)
Definition: ipsec_format.c:241
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
u8 * format_ipsec_key(u8 *s, va_list *args)
Definition: ipsec_format.c:233