nat: nat44-ed cleanup & fixes
[vpp.git] / src / plugins / nat / nat44-ed / nat44_ed_format.c
1 /*
2  * Copyright (c) 2018 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
16 #include <nat/nat44-ed/nat44_ed.h>
17 #include <nat/nat44-ed/nat44_ed_inlines.h>
18
19 u8 *
20 format_ed_session_kvp (u8 *s, va_list *args)
21 {
22   clib_bihash_kv_16_8_t *v = va_arg (*args, clib_bihash_kv_16_8_t *);
23
24   u8 proto;
25   u16 r_port, l_port;
26   ip4_address_t l_addr, r_addr;
27   u32 fib_index;
28
29   split_ed_kv (v, &l_addr, &r_addr, &proto, &fib_index, &l_port, &r_port);
30   s = format (s,
31               "local %U:%d remote %U:%d proto %U fib %d thread-index %u "
32               "session-index %u",
33               format_ip4_address, &l_addr, clib_net_to_host_u16 (l_port),
34               format_ip4_address, &r_addr, clib_net_to_host_u16 (r_port),
35               format_ip_protocol, proto, fib_index,
36               ed_value_get_thread_index (v), ed_value_get_session_index (v));
37
38   return s;
39 }
40
41 u8 *
42 format_snat_session (u8 * s, va_list * args)
43 {
44   snat_main_t *sm = va_arg (*args, snat_main_t *);
45   snat_main_per_thread_data_t *tsm =
46     va_arg (*args, snat_main_per_thread_data_t *);
47   snat_session_t *sess = va_arg (*args, snat_session_t *);
48   f64 now = va_arg (*args, f64);
49
50   if (nat44_ed_is_unk_proto (sess->proto))
51     {
52       s = format (s, "  i2o %U proto %u fib %u\n",
53                   format_ip4_address, &sess->in2out.addr,
54                   sess->in2out.port, sess->in2out.fib_index);
55       s =
56         format (s, "    o2i %U proto %u fib %u\n", format_ip4_address,
57                 &sess->out2in.addr, sess->out2in.port, sess->out2in.fib_index);
58     }
59   else
60     {
61       s = format (s, "  i2o %U proto %U port %d fib %d\n", format_ip4_address,
62                   &sess->in2out.addr, format_ip_protocol, sess->proto,
63                   clib_net_to_host_u16 (sess->in2out.port),
64                   sess->in2out.fib_index);
65       s = format (s, "    o2i %U proto %U port %d fib %d\n",
66                   format_ip4_address, &sess->out2in.addr, format_ip_protocol,
67                   sess->proto, clib_net_to_host_u16 (sess->out2in.port),
68                   sess->out2in.fib_index);
69     }
70   if (nat44_ed_is_twice_nat_session (sess))
71     {
72       s = format (s, "       external host o2i %U:%d i2o %U:%d\n",
73                   format_ip4_address, &sess->ext_host_addr,
74                   clib_net_to_host_u16 (sess->ext_host_port),
75                   format_ip4_address, &sess->ext_host_nat_addr,
76                   clib_net_to_host_u16 (sess->ext_host_nat_port));
77     }
78       else
79         {
80           if (sess->ext_host_addr.as_u32)
81             s = format (s, "       external host %U:%u\n",
82                         format_ip4_address, &sess->ext_host_addr,
83                         clib_net_to_host_u16 (sess->ext_host_port));
84         }
85       s = format (s, "       i2o flow: %U\n", format_nat_6t_flow, &sess->i2o);
86       s = format (s, "       o2i flow: %U\n", format_nat_6t_flow, &sess->o2i);
87   s = format (s, "       index %llu\n", sess - tsm->sessions);
88   s = format (s, "       last heard %.2f\n", sess->last_heard);
89   s = format (s, "       timeout in %.2f\n",
90               nat44_session_get_timeout (sm, sess) - (now - sess->last_heard));
91   s = format (s, "       total pkts %d, total bytes %lld\n", sess->total_pkts,
92               sess->total_bytes);
93   if (nat44_ed_is_session_static (sess))
94     s = format (s, "       static translation\n");
95   else
96     s = format (s, "       dynamic translation\n");
97   if (na44_ed_is_fwd_bypass_session (sess))
98     s = format (s, "       forwarding-bypass\n");
99   if (nat44_ed_is_lb_session (sess))
100     s = format (s, "       load-balancing\n");
101   if (nat44_ed_is_twice_nat_session (sess))
102     s = format (s, "       twice-nat\n");
103   return s;
104 }
105
106 u8 *
107 format_snat_static_mapping (u8 * s, va_list * args)
108 {
109   snat_static_mapping_t *m = va_arg (*args, snat_static_mapping_t *);
110   nat44_lb_addr_port_t *local;
111
112   if (is_sm_identity_nat (m->flags))
113     {
114       if (is_sm_addr_only (m->flags))
115         s = format (s, "identity mapping %U",
116                     format_ip4_address, &m->local_addr);
117       else
118         s = format (s, "identity mapping %U %U:%d", format_ip_protocol,
119                     m->proto, format_ip4_address, &m->local_addr,
120                     clib_net_to_host_u16 (m->local_port));
121
122       pool_foreach (local, m->locals)
123        {
124         s = format (s, " vrf %d", local->vrf_id);
125       }
126
127       return s;
128     }
129
130   if (is_sm_addr_only (m->flags))
131     s =
132       format (s, "local %U external %U vrf %d %s %s", format_ip4_address,
133               &m->local_addr, format_ip4_address, &m->external_addr, m->vrf_id,
134               is_sm_twice_nat (m->flags) ?
135                 "twice-nat" :
136                 is_sm_self_twice_nat (m->flags) ? "self-twice-nat" : "",
137               is_sm_out2in_only (m->flags) ? "out2in-only" : "");
138   else
139     {
140       if (is_sm_lb (m->flags))
141         {
142           s =
143             format (s, "%U external %U:%d %s %s", format_ip_protocol, m->proto,
144                     format_ip4_address, &m->external_addr,
145                     clib_net_to_host_u16 (m->external_port),
146                     is_sm_twice_nat (m->flags) ?
147                       "twice-nat" :
148                       is_sm_self_twice_nat (m->flags) ? "self-twice-nat" : "",
149                     is_sm_out2in_only (m->flags) ? "out2in-only" : "");
150
151           pool_foreach (local, m->locals)
152             {
153               s = format (s, "\n  local %U:%d vrf %d probability %d\%",
154                           format_ip4_address, &local->addr,
155                           clib_net_to_host_u16 (local->port), local->vrf_id,
156                           local->probability);
157             }
158         }
159       else
160         s = format (s, "%U local %U:%d external %U:%d vrf %d %s %s",
161                     format_ip_protocol, m->proto, format_ip4_address,
162                     &m->local_addr, clib_net_to_host_u16 (m->local_port),
163                     format_ip4_address, &m->external_addr,
164                     clib_net_to_host_u16 (m->external_port), m->vrf_id,
165                     is_sm_twice_nat (m->flags) ?
166                       "twice-nat" :
167                       is_sm_self_twice_nat (m->flags) ? "self-twice-nat" : "",
168                     is_sm_out2in_only (m->flags) ? "out2in-only" : "");
169     }
170   return s;
171 }
172
173 u8 *
174 format_snat_static_map_to_resolve (u8 * s, va_list * args)
175 {
176   snat_static_mapping_resolve_t *m =
177     va_arg (*args, snat_static_mapping_resolve_t *);
178   vnet_main_t *vnm = vnet_get_main ();
179
180   if (is_sm_addr_only (m->flags))
181     s = format (s, "local %U external %U vrf %d",
182                 format_ip4_address, &m->l_addr,
183                 format_vnet_sw_if_index_name, vnm, m->sw_if_index, m->vrf_id);
184   else
185     s = format (s, "%U local %U:%d external %U:%d vrf %d", format_ip_protocol,
186                 m->proto, format_ip4_address, &m->l_addr,
187                 clib_net_to_host_u16 (m->l_port), format_vnet_sw_if_index_name,
188                 vnm, m->sw_if_index, clib_net_to_host_u16 (m->e_port),
189                 m->vrf_id);
190
191   return s;
192 }
193
194 u8 *
195 format_nat_ed_translation_error (u8 *s, va_list *args)
196 {
197   nat_translation_error_e e = va_arg (*args, nat_translation_error_e);
198
199   switch (e)
200     {
201     case NAT_ED_TRNSL_ERR_SUCCESS:
202       s = format (s, "success");
203       break;
204     case NAT_ED_TRNSL_ERR_TRANSLATION_FAILED:
205       s = format (s, "translation-failed");
206       break;
207     case NAT_ED_TRNSL_ERR_FLOW_MISMATCH:
208       s = format (s, "flow-mismatch");
209       break;
210     case NAT_ED_TRNSL_ERR_PACKET_TRUNCATED:
211       s = format (s, "packet-truncated");
212       break;
213     case NAT_ED_TRNSL_ERR_INNER_IP_CORRUPT:
214       s = format (s, "inner-ip-corrupted");
215       break;
216     case NAT_ED_TRNSL_ERR_INVALID_CSUM:
217       s = format (s, "invalid-checksum");
218       break;
219     }
220   return s;
221 }
222
223 u8 *
224 format_nat_6t_flow (u8 *s, va_list *args)
225 {
226   nat_6t_flow_t *f = va_arg (*args, nat_6t_flow_t *);
227
228   s = format (s, "match: %U ", format_nat_6t, &f->match);
229   int r = 0;
230   if (f->ops & NAT_FLOW_OP_SADDR_REWRITE)
231     {
232       s = format (s, "rewrite: saddr %U ", format_ip4_address,
233                   f->rewrite.saddr.as_u8);
234       r = 1;
235     }
236   if (f->ops & NAT_FLOW_OP_SPORT_REWRITE)
237     {
238       if (!r)
239         {
240           s = format (s, "rewrite: ");
241           r = 1;
242         }
243       s = format (s, "sport %u ", clib_net_to_host_u16 (f->rewrite.sport));
244     }
245   if (f->ops & NAT_FLOW_OP_DADDR_REWRITE)
246     {
247       if (!r)
248         {
249           s = format (s, "rewrite: ");
250           r = 1;
251         }
252       s = format (s, "daddr %U ", format_ip4_address, f->rewrite.daddr.as_u8);
253     }
254   if (f->ops & NAT_FLOW_OP_DPORT_REWRITE)
255     {
256       if (!r)
257         {
258           s = format (s, "rewrite: ");
259           r = 1;
260         }
261       s = format (s, "dport %u ", clib_net_to_host_u16 (f->rewrite.dport));
262     }
263   if (f->ops & NAT_FLOW_OP_ICMP_ID_REWRITE)
264     {
265       if (!r)
266         {
267           s = format (s, "rewrite: ");
268           r = 1;
269         }
270       s = format (s, "icmp-id %u ", clib_net_to_host_u16 (f->rewrite.icmp_id));
271     }
272   if (f->ops & NAT_FLOW_OP_TXFIB_REWRITE)
273     {
274       if (!r)
275         {
276           s = format (s, "rewrite: ");
277           r = 1;
278         }
279       s = format (s, "txfib %u ", f->rewrite.fib_index);
280     }
281   return s;
282 }
283
284 u8 *
285 format_nat_6t (u8 *s, va_list *args)
286 {
287   nat_6t_t *t = va_arg (*args, nat_6t_t *);
288
289   s = format (s, "saddr %U sport %u daddr %U dport %u proto %U fib_idx %u",
290               format_ip4_address, t->saddr.as_u8,
291               clib_net_to_host_u16 (t->sport), format_ip4_address,
292               t->daddr.as_u8, clib_net_to_host_u16 (t->dport),
293               format_ip_protocol, t->proto, t->fib_index);
294   return s;
295 }
296
297 u8 *
298 format_nat44_ed_tcp_state (u8 *s, va_list *args)
299 {
300   nat44_ed_tcp_state_e e = va_arg (*args, nat44_ed_tcp_state_e);
301   switch (e)
302     {
303     case NAT44_ED_TCP_STATE_CLOSED:
304       s = format (s, "closed");
305       break;
306     case NAT44_ED_TCP_STATE_SYN_I2O:
307       s = format (s, "SYN seen in in2out direction");
308       break;
309     case NAT44_ED_TCP_STATE_SYN_O2I:
310       s = format (s, "SYN seen in out2in direction");
311       break;
312     case NAT44_ED_TCP_STATE_ESTABLISHED:
313       s = format (s, "SYN seen in both directions/established");
314       break;
315     case NAT44_ED_TCP_STATE_FIN_I2O:
316       s = format (s, "FIN seen in in2out direction");
317       break;
318     case NAT44_ED_TCP_STATE_FIN_O2I:
319       s = format (s, "FIN seen in out2in direction");
320       break;
321     case NAT44_ED_TCP_STATE_RST_TRANS:
322       s = format (s, "RST seen/transitory timeout");
323       break;
324     case NAT44_ED_TCP_STATE_FIN_TRANS:
325       s = format (s, "FIN seen in both directions/transitory timeout");
326       break;
327     case NAT44_ED_TCP_STATE_FIN_REOPEN_SYN_O2I:
328       s = format (s, "FIN seen in both directions/transitory timeout/session "
329                      "reopening in out2in direction");
330       break;
331     case NAT44_ED_TCP_STATE_FIN_REOPEN_SYN_I2O:
332       s = format (s, "FIN seen in both directions/transitory timeout/session "
333                      "reopening in in2out direction");
334       break;
335     case NAT44_ED_TCP_N_STATE:
336       s = format (s, "BUG! unexpected N_STATE! BUG!");
337       break;
338     }
339   return s;
340 }
341
342 /*
343  * fd.io coding-style-patch-verification: ON
344  *
345  * Local Variables:
346  * eval: (c-set-style "gnu")
347  * End:
348  */