Revert "ipsec: Use the new tunnel API types to add flow label and TTL copy"
[vpp.git] / src / vnet / ipsec / ipsec_format.c
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;
37       foreach_ipsec_policy_action
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;
55       foreach_ipsec_spd_policy_type
56 #undef _
57     default:
58       s = format (s, "unknown");
59     }
60   s = format (s, "%s", t);
61   return s;
62 }
63
64 uword
65 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
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;
71   foreach_ipsec_policy_action
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;
87       foreach_ipsec_crypto_alg
88 #undef _
89     default:
90       s = format (s, "unknown");
91     }
92   s = format (s, "%s", t);
93   return s;
94 }
95
96 uword
97 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
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;
103   foreach_ipsec_crypto_alg
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;
119       foreach_ipsec_integ_alg
120 #undef _
121     default:
122       s = format (s, "unknown");
123     }
124   s = format (s, "%s", t);
125   return s;
126 }
127
128 uword
129 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
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;
135   foreach_ipsec_integ_alg
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,
169               format_ipsec_policy_action, p->policy,
170               format_ipsec_policy_type, p->type);
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
197   vlib_get_combined_counter (&ipsec_spd_policy_counters, pi, &counts);
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   }
227   foreach_ipsec_spd_policy_type;
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);
264   foreach_ipsec_sa_flags
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);
273   ipsec_format_flags_t flags = va_arg (*args, ipsec_format_flags_t);
274   ipsec_main_t *im = &ipsec_main;
275   vlib_counter_t counts;
276   u32 tx_table_id;
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-index:%d", sa->thread_index);
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,
300               format_ipsec_replay_window, sa->replay_window);
301   s = format (s, "\n   crypto alg %U",
302               format_ipsec_crypto_alg, sa->crypto_alg);
303   if (sa->crypto_alg && (flags & IPSEC_FORMAT_INSECURE))
304     s = format (s, " key %U", format_ipsec_key, &sa->crypto_key);
305   else
306     s = format (s, " key [redacted]");
307   s = format (s, "\n   integrity alg %U",
308               format_ipsec_integ_alg, sa->integ_alg);
309   if (sa->integ_alg && (flags & IPSEC_FORMAT_INSECURE))
310     s = format (s, " key %U", format_ipsec_key, &sa->integ_key);
311   else
312     s = format (s, " key [redacted]");
313   s = format (s, "\n   UDP:[src:%d dst:%d]",
314               clib_host_to_net_u16 (sa->udp_hdr.src_port),
315               clib_host_to_net_u16 (sa->udp_hdr.dst_port));
316
317   vlib_get_combined_counter (&ipsec_sa_counters, sai, &counts);
318   s = format (s, "\n   packets %u bytes %u", counts.packets, counts.bytes);
319
320   if (ipsec_sa_is_set_IS_TUNNEL (sa))
321     {
322       tx_table_id = fib_table_get_table_id (
323         sa->tx_fib_index,
324         (ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ? FIB_PROTOCOL_IP6 :
325                                              FIB_PROTOCOL_IP4));
326       s = format (s, "\n   table-ID %d tunnel %U src %U dst %U flags %U",
327                   tx_table_id,
328                   format_ip_dscp, sa->dscp,
329                   format_ip46_address, &sa->tunnel_src_addr, IP46_TYPE_ANY,
330                   format_ip46_address, &sa->tunnel_dst_addr, IP46_TYPE_ANY,
331                   format_tunnel_encap_decap_flags, sa->tunnel_flags);
332       if (!ipsec_sa_is_set_IS_INBOUND (sa))
333         {
334           s =
335             format (s, "\n    resovle via fib-entry: %d",
336                     sa->fib_entry_index);
337           s = format (s, "\n    stacked on:");
338           s = format (s, "\n      %U", format_dpo_id, &sa->dpo, 6);
339         }
340     }
341
342 done:
343   return (s);
344 }
345
346 u8 *
347 format_ipsec_tun_protect_index (u8 * s, va_list * args)
348 {
349   u32 itpi = va_arg (*args, index_t);
350   ipsec_tun_protect_t *itp;
351
352   if (pool_is_free_index (ipsec_tun_protect_pool, itpi))
353     return (format (s, "No such tunnel index: %d", itpi));
354
355   itp = pool_elt_at_index (ipsec_tun_protect_pool, itpi);
356
357   return (format (s, "%U", format_ipsec_tun_protect, itp));
358 }
359
360 u8 *
361 format_ipsec_tun_protect_flags (u8 * s, va_list * args)
362 {
363   ipsec_protect_flags_t flags = va_arg (*args, int);
364
365   if (IPSEC_PROTECT_NONE == flags)
366     s = format (s, "none");
367 #define _(a,b,c)                                \
368   else if (flags & IPSEC_PROTECT_##a)           \
369     s = format (s, "%s", c);                    \
370   foreach_ipsec_protect_flags
371 #undef _
372
373   return (s);
374 }
375
376 u8 *
377 format_ipsec_tun_protect (u8 * s, va_list * args)
378 {
379   ipsec_tun_protect_t *itp = va_arg (*args, ipsec_tun_protect_t *);
380   u32 sai;
381
382   s = format (s, "%U flags:[%U]", format_vnet_sw_if_index_name,
383               vnet_get_main (), itp->itp_sw_if_index,
384               format_ipsec_tun_protect_flags, itp->itp_flags);
385   if (!ip_address_is_zero (itp->itp_key))
386     s = format (s, ": %U", format_ip_address, itp->itp_key);
387   s = format (s, "\n output-sa:");
388   s = format (s, "\n  %U", format_ipsec_sa, itp->itp_out_sa,
389               IPSEC_FORMAT_BRIEF);
390
391   s = format (s, "\n input-sa:");
392   /* *INDENT-OFF* */
393   FOR_EACH_IPSEC_PROTECT_INPUT_SAI(itp, sai,
394   ({
395   s = format (s, "\n  %U", format_ipsec_sa, sai, IPSEC_FORMAT_BRIEF);
396   }));
397   /* *INDENT-ON* */
398
399   return (s);
400 }
401
402 u8 *
403 format_ipsec4_tunnel_kv (u8 * s, va_list * args)
404 {
405   ipsec4_tunnel_kv_t *kv = va_arg (*args, ipsec4_tunnel_kv_t *);
406   ip4_address_t ip;
407   u32 spi;
408
409   ipsec4_tunnel_extract_key (kv, &ip, &spi);
410
411   s = format (s, "remote:%U spi:%u (0x%08x) sa:%d tun:%d",
412               format_ip4_address, &ip,
413               clib_net_to_host_u32 (spi),
414               clib_net_to_host_u32 (spi),
415               kv->value.sa_index, kv->value.tun_index);
416
417   return (s);
418 }
419
420 u8 *
421 format_ipsec6_tunnel_kv (u8 * s, va_list * args)
422 {
423   ipsec6_tunnel_kv_t *kv = va_arg (*args, ipsec6_tunnel_kv_t *);
424
425   s = format (s, "remote:%U spi:%u (0x%08x) sa:%d tun:%d",
426               format_ip6_address, &kv->key.remote_ip,
427               clib_net_to_host_u32 (kv->key.spi),
428               clib_net_to_host_u32 (kv->key.spi),
429               kv->value.sa_index, kv->value.tun_index);
430
431   return (s);
432 }
433
434 u8 *
435 format_ipsec_itf (u8 * s, va_list * a)
436 {
437   index_t ii = va_arg (*a, index_t);
438   ipsec_itf_t *itf;
439
440   itf = ipsec_itf_get (ii);
441   s = format (s, "[%d] %U %U",
442               ii, format_vnet_sw_if_index_name, vnet_get_main (),
443               itf->ii_sw_if_index, format_tunnel_mode, itf->ii_mode);
444
445   return (s);
446 }
447
448 /*
449  * fd.io coding-style-patch-verification: ON
450  *
451  * Local Variables:
452  * eval: (c-set-style "gnu")
453  * End:
454  */