2f83ad3f3e7e7eb0468a1c51feb95de6ff1a9d5a
[vpp.git] / src / plugins / nat / nat44-ed / nat44_ed_out2in.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  * @file
17  * @brief NAT44 endpoint-dependent outside to inside network translation
18  */
19
20 #include <vlib/vlib.h>
21 #include <vnet/vnet.h>
22 #include <vnet/ip/ip.h>
23 #include <vnet/ethernet/ethernet.h>
24 #include <vnet/fib/ip4_fib.h>
25 #include <vnet/udp/udp_local.h>
26 #include <vppinfra/error.h>
27
28 #include <nat/lib/nat_syslog.h>
29 #include <nat/lib/ipfix_logging.h>
30
31 #include <nat/nat44-ed/nat44_ed.h>
32 #include <nat/nat44-ed/nat44_ed_inlines.h>
33
34 static char *nat_out2in_ed_error_strings[] = {
35 #define _(sym,string) string,
36   foreach_nat_out2in_ed_error
37 #undef _
38 };
39
40 typedef struct
41 {
42   u32 sw_if_index;
43   u32 next_index;
44   u32 session_index;
45   nat_translation_error_e translation_error;
46   nat_6t_flow_t i2of;
47   nat_6t_flow_t o2if;
48   clib_bihash_kv_16_8_t search_key;
49   u8 is_slow_path;
50   u8 translation_via_i2of;
51   u8 lookup_skipped;
52 } nat44_ed_out2in_trace_t;
53
54 static u8 *
55 format_nat44_ed_out2in_trace (u8 * s, va_list * args)
56 {
57   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
58   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
59   nat44_ed_out2in_trace_t *t = va_arg (*args, nat44_ed_out2in_trace_t *);
60   char *tag;
61
62   tag =
63     t->is_slow_path ? "NAT44_OUT2IN_ED_SLOW_PATH" :
64     "NAT44_OUT2IN_ED_FAST_PATH";
65
66   s = format (s, "%s: sw_if_index %d, next index %d, session %d", tag,
67               t->sw_if_index, t->next_index, t->session_index);
68   if (~0 != t->session_index)
69     {
70       s = format (s, ", translation result '%U' via %s",
71                   format_nat_ed_translation_error, t->translation_error,
72                   t->translation_via_i2of ? "i2of" : "o2if");
73       s = format (s, "\n  i2of %U", format_nat_6t_flow, &t->i2of);
74       s = format (s, "\n  o2if %U", format_nat_6t_flow, &t->o2if);
75     }
76   if (!t->is_slow_path)
77     {
78       if (t->lookup_skipped)
79         {
80           s = format (s, "\n lookup skipped - cached session index used");
81         }
82       else
83         {
84           s = format (s, "\n  search key %U", format_ed_session_kvp,
85                       &t->search_key);
86         }
87     }
88
89   return s;
90 }
91
92 static int
93 next_src_nat (snat_main_t *sm, ip4_header_t *ip, u16 src_port, u16 dst_port,
94               u32 thread_index, u32 rx_fib_index)
95 {
96   clib_bihash_kv_16_8_t kv, value;
97
98   init_ed_k (&kv, ip->src_address, src_port, ip->dst_address, dst_port,
99              rx_fib_index, ip->protocol);
100   if (!clib_bihash_search_16_8 (&sm->flow_hash, &kv, &value))
101     return 1;
102
103   return 0;
104 }
105
106 static void create_bypass_for_fwd (snat_main_t *sm, vlib_buffer_t *b,
107                                    snat_session_t *s, ip4_header_t *ip,
108                                    u32 rx_fib_index, u32 thread_index);
109
110 static snat_session_t *create_session_for_static_mapping_ed (
111   snat_main_t *sm, vlib_buffer_t *b, ip4_address_t i2o_addr, u16 i2o_port,
112   u32 i2o_fib_index, ip4_address_t o2i_addr, u16 o2i_port, u32 o2i_fib_index,
113   nat_protocol_t nat_proto, vlib_node_runtime_t *node, u32 rx_fib_index,
114   u32 thread_index, twice_nat_type_t twice_nat, lb_nat_type_t lb_nat, f64 now,
115   snat_static_mapping_t *mapping);
116
117 static inline u32
118 icmp_out2in_ed_slow_path (snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip,
119                           icmp46_header_t *icmp, u32 sw_if_index,
120                           u32 rx_fib_index, vlib_node_runtime_t *node,
121                           u32 next, f64 now, u32 thread_index,
122                           snat_session_t **s_p)
123 {
124   vlib_main_t *vm = vlib_get_main ();
125
126   ip_csum_t sum;
127   u16 checksum;
128
129   snat_session_t *s = 0;
130   u8 is_addr_only, identity_nat;
131   ip4_address_t sm_addr;
132   u16 sm_port;
133   u32 sm_fib_index;
134   snat_static_mapping_t *m;
135   u8 lookup_protocol;
136   ip4_address_t lookup_saddr, lookup_daddr;
137   u16 lookup_sport, lookup_dport;
138
139   sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
140   rx_fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index);
141
142   if (nat_get_icmp_session_lookup_values (b, ip, &lookup_saddr, &lookup_sport,
143                                           &lookup_daddr, &lookup_dport,
144                                           &lookup_protocol))
145     {
146       b->error = node->errors[NAT_OUT2IN_ED_ERROR_UNSUPPORTED_PROTOCOL];
147       next = NAT_NEXT_DROP;
148       goto out;
149     }
150
151   if (snat_static_mapping_match (
152         vm, sm, ip->dst_address, lookup_sport, rx_fib_index,
153         ip_proto_to_nat_proto (ip->protocol), &sm_addr, &sm_port,
154         &sm_fib_index, 1, &is_addr_only, 0, 0, 0, &identity_nat, &m))
155     {
156       // static mapping not matched
157       if (!sm->forwarding_enabled)
158         {
159           /* Don't NAT packet aimed at the intfc address */
160           if (!is_interface_addr (sm, node, sw_if_index,
161                                   ip->dst_address.as_u32))
162             {
163               b->error = node->errors[NAT_OUT2IN_ED_ERROR_NO_TRANSLATION];
164               next = NAT_NEXT_DROP;
165             }
166         }
167       else
168         {
169           if (next_src_nat (sm, ip, lookup_sport, lookup_dport, thread_index,
170                             rx_fib_index))
171             {
172               next = NAT_NEXT_IN2OUT_ED_FAST_PATH;
173             }
174           else
175             {
176               create_bypass_for_fwd (sm, b, s, ip, rx_fib_index, thread_index);
177             }
178         }
179       goto out;
180     }
181
182   if (PREDICT_FALSE (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags !=
183                        ICMP4_echo_reply &&
184                      (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags !=
185                         ICMP4_echo_request ||
186                       !is_addr_only)))
187     {
188       b->error = node->errors[NAT_OUT2IN_ED_ERROR_BAD_ICMP_TYPE];
189       next = NAT_NEXT_DROP;
190       goto out;
191     }
192
193   if (PREDICT_FALSE (identity_nat))
194     {
195       goto out;
196     }
197
198   /* Create session initiated by host from external network */
199   s = create_session_for_static_mapping_ed (
200     sm, b, sm_addr, sm_port, sm_fib_index, ip->dst_address, lookup_sport,
201     rx_fib_index, ip_proto_to_nat_proto (lookup_protocol), node, rx_fib_index,
202     thread_index, 0, 0, vlib_time_now (vm), m);
203   if (!s)
204     next = NAT_NEXT_DROP;
205
206   if (PREDICT_TRUE (!ip4_is_fragment (ip)))
207     {
208       sum = ip_incremental_checksum_buffer (
209         vm, b, (u8 *) icmp - (u8 *) vlib_buffer_get_current (b),
210         ntohs (ip->length) - ip4_header_bytes (ip), 0);
211       checksum = ~ip_csum_fold (sum);
212       if (checksum != 0 && checksum != 0xffff)
213         {
214           next = NAT_NEXT_DROP;
215           goto out;
216         }
217     }
218
219   if (PREDICT_TRUE (next != NAT_NEXT_DROP && s))
220     {
221       /* Accounting */
222       nat44_session_update_counters (
223         s, now, vlib_buffer_length_in_chain (vm, b), thread_index);
224       /* Per-user LRU list maintenance */
225       nat44_session_update_lru (sm, s, thread_index);
226     }
227 out:
228   if (NAT_NEXT_DROP == next && s)
229     {
230       nat_ed_session_delete (sm, s, thread_index, 1);
231       s = 0;
232     }
233   *s_p = s;
234   return next;
235 }
236
237 // allocate exact address based on preference
238 static_always_inline int
239 nat_alloc_addr_and_port_exact (snat_address_t * a,
240                                u32 thread_index,
241                                nat_protocol_t proto,
242                                ip4_address_t * addr,
243                                u16 * port,
244                                u16 port_per_thread, u32 snat_thread_index)
245 {
246   snat_main_t *sm = &snat_main;
247   u32 portnum;
248
249   switch (proto)
250     {
251 #define _(N, j, n, s) \
252     case NAT_PROTOCOL_##N: \
253       if (a->busy_##n##_ports_per_thread[thread_index] < port_per_thread) \
254         { \
255           while (1) \
256             { \
257               portnum = (port_per_thread * \
258                 snat_thread_index) + \
259                 snat_random_port(0, port_per_thread - 1) + 1024; \
260               if (a->busy_##n##_port_refcounts[portnum]) \
261                 continue; \
262               --a->busy_##n##_port_refcounts[portnum]; \
263               a->busy_##n##_ports_per_thread[thread_index]++; \
264               a->busy_##n##_ports++; \
265               *addr = a->addr; \
266               *port = clib_host_to_net_u16(portnum); \
267               return 0; \
268             } \
269         } \
270       break;
271       foreach_nat_protocol
272 #undef _
273         default : nat_elog_info (sm, "unknown protocol");
274       return 1;
275     }
276
277   /* Totally out of translations to use... */
278   nat_ipfix_logging_addresses_exhausted (thread_index, 0);
279   return 1;
280 }
281
282 static_always_inline int
283 nat44_ed_alloc_outside_addr_and_port (snat_address_t *addresses, u32 fib_index,
284                                       u32 thread_index, nat_protocol_t proto,
285                                       ip4_address_t *addr, u16 *port,
286                                       u16 port_per_thread,
287                                       u32 snat_thread_index)
288 {
289   snat_main_t *sm = &snat_main;
290   snat_address_t *a, *ga = 0;
291   u32 portnum;
292   int i;
293
294   for (i = 0; i < vec_len (addresses); i++)
295     {
296       a = addresses + i;
297       switch (proto)
298         {
299 #define _(N, j, n, s)                                                         \
300   case NAT_PROTOCOL_##N:                                                      \
301     if (a->busy_##n##_ports_per_thread[thread_index] < port_per_thread)       \
302       {                                                                       \
303         if (a->fib_index == fib_index)                                        \
304           {                                                                   \
305             while (1)                                                         \
306               {                                                               \
307                 portnum = (port_per_thread * snat_thread_index) +             \
308                           snat_random_port (0, port_per_thread - 1) + 1024;   \
309                 if (a->busy_##n##_port_refcounts[portnum])                    \
310                   continue;                                                   \
311                 --a->busy_##n##_port_refcounts[portnum];                      \
312                 a->busy_##n##_ports_per_thread[thread_index]++;               \
313                 a->busy_##n##_ports++;                                        \
314                 *addr = a->addr;                                              \
315                 *port = clib_host_to_net_u16 (portnum);                       \
316                 return 0;                                                     \
317               }                                                               \
318           }                                                                   \
319         else if (a->fib_index == ~0)                                          \
320           {                                                                   \
321             ga = a;                                                           \
322           }                                                                   \
323       }                                                                       \
324     break;
325           foreach_nat_protocol
326 #undef _
327             default : nat_elog_info (sm, "unknown protocol");
328           return 1;
329         }
330     }
331
332   if (ga)
333     {
334       a = ga;
335       switch (proto)
336         {
337 #define _(N, j, n, s)                                                         \
338   case NAT_PROTOCOL_##N:                                                      \
339     while (1)                                                                 \
340       {                                                                       \
341         portnum = (port_per_thread * snat_thread_index) +                     \
342                   snat_random_port (0, port_per_thread - 1) + 1024;           \
343         if (a->busy_##n##_port_refcounts[portnum])                            \
344           continue;                                                           \
345         ++a->busy_##n##_port_refcounts[portnum];                              \
346         a->busy_##n##_ports_per_thread[thread_index]++;                       \
347         a->busy_##n##_ports++;                                                \
348         *addr = a->addr;                                                      \
349         *port = clib_host_to_net_u16 (portnum);                               \
350         return 0;                                                             \
351       }
352           break;
353           foreach_nat_protocol
354 #undef _
355             default : nat_elog_info (sm, "unknown protocol");
356           return 1;
357         }
358     }
359
360   /* Totally out of translations to use... */
361   nat_ipfix_logging_addresses_exhausted (thread_index, 0);
362   return 1;
363 }
364
365 static snat_session_t *
366 create_session_for_static_mapping_ed (
367   snat_main_t *sm, vlib_buffer_t *b, ip4_address_t i2o_addr, u16 i2o_port,
368   u32 i2o_fib_index, ip4_address_t o2i_addr, u16 o2i_port, u32 o2i_fib_index,
369   nat_protocol_t nat_proto, vlib_node_runtime_t *node, u32 rx_fib_index,
370   u32 thread_index, twice_nat_type_t twice_nat, lb_nat_type_t lb_nat, f64 now,
371   snat_static_mapping_t *mapping)
372 {
373   snat_session_t *s;
374   ip4_header_t *ip;
375   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
376
377   if (PREDICT_FALSE
378       (nat44_ed_maximum_sessions_exceeded (sm, rx_fib_index, thread_index)))
379     {
380       b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_SESSIONS_EXCEEDED];
381       nat_elog_notice (sm, "maximum sessions exceeded");
382       return 0;
383     }
384
385   s = nat_ed_session_alloc (sm, thread_index, now, nat_proto);
386   if (!s)
387     {
388       b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_SESSIONS_EXCEEDED];
389       nat_elog_warn (sm, "create NAT session failed");
390       return 0;
391     }
392
393   ip = vlib_buffer_get_current (b);
394
395   s->ext_host_addr.as_u32 = ip->src_address.as_u32;
396   s->ext_host_port =
397     nat_proto == NAT_PROTOCOL_ICMP ? 0 : vnet_buffer (b)->ip.reass.l4_src_port;
398   s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
399   if (lb_nat)
400     s->flags |= SNAT_SESSION_FLAG_LOAD_BALANCING;
401   if (lb_nat == AFFINITY_LB_NAT)
402     s->flags |= SNAT_SESSION_FLAG_AFFINITY;
403   s->flags |= SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT;
404   s->out2in.addr = o2i_addr;
405   s->out2in.port = o2i_port;
406   s->out2in.fib_index = o2i_fib_index;
407   s->in2out.addr = i2o_addr;
408   s->in2out.port = i2o_port;
409   s->in2out.fib_index = i2o_fib_index;
410   s->nat_proto = nat_proto;
411
412   if (NAT_PROTOCOL_ICMP == nat_proto)
413     {
414       nat_6t_o2i_flow_init (sm, thread_index, s, s->ext_host_addr, o2i_port,
415                             o2i_addr, o2i_port, o2i_fib_index, ip->protocol);
416       nat_6t_flow_icmp_id_rewrite_set (&s->o2i, i2o_port);
417     }
418   else
419     {
420       nat_6t_o2i_flow_init (sm, thread_index, s, s->ext_host_addr,
421                             s->ext_host_port, o2i_addr, o2i_port,
422                             o2i_fib_index, ip->protocol);
423       nat_6t_flow_dport_rewrite_set (&s->o2i, i2o_port);
424     }
425   nat_6t_flow_daddr_rewrite_set (&s->o2i, i2o_addr.as_u32);
426   nat_6t_flow_txfib_rewrite_set (&s->o2i, i2o_fib_index);
427
428   if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, s, 1))
429     {
430       b->error = node->errors[NAT_OUT2IN_ED_ERROR_HASH_ADD_FAILED];
431       nat_ed_session_delete (sm, s, thread_index, 1);
432       nat_elog_warn (sm, "out2in flow hash add failed");
433       return 0;
434     }
435
436   if (twice_nat == TWICE_NAT || (twice_nat == TWICE_NAT_SELF &&
437                                  ip->src_address.as_u32 == i2o_addr.as_u32))
438     {
439       int rc = 0;
440       snat_address_t *filter = 0;
441
442       // if exact address is specified use this address
443       if (is_exact_address (mapping))
444         {
445           snat_address_t *ap;
446           vec_foreach (ap, sm->twice_nat_addresses)
447           {
448             if (mapping->pool_addr.as_u32 == ap->addr.as_u32)
449               {
450                 filter = ap;
451                 break;
452               }
453           }
454         }
455
456       if (filter)
457         {
458           rc = nat_alloc_addr_and_port_exact (filter,
459                                               thread_index,
460                                               nat_proto,
461                                               &s->ext_host_nat_addr,
462                                               &s->ext_host_nat_port,
463                                               sm->port_per_thread,
464                                               tsm->snat_thread_index);
465           s->flags |= SNAT_SESSION_FLAG_EXACT_ADDRESS;
466         }
467       else
468         {
469           rc = nat44_ed_alloc_outside_addr_and_port (
470             sm->twice_nat_addresses, 0, thread_index, nat_proto,
471             &s->ext_host_nat_addr, &s->ext_host_nat_port, sm->port_per_thread,
472             tsm->snat_thread_index);
473         }
474
475       if (rc)
476         {
477           b->error = node->errors[NAT_OUT2IN_ED_ERROR_OUT_OF_PORTS];
478           if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, s, 0))
479             {
480               nat_elog_warn (sm, "out2in flow hash del failed");
481             }
482           snat_free_outside_address_and_port (
483             sm->twice_nat_addresses, thread_index, &s->ext_host_nat_addr,
484             s->ext_host_nat_port, s->nat_proto);
485           nat_ed_session_delete (sm, s, thread_index, 1);
486           return 0;
487         }
488
489       s->flags |= SNAT_SESSION_FLAG_TWICE_NAT;
490
491       nat_6t_flow_saddr_rewrite_set (&s->o2i, s->ext_host_nat_addr.as_u32);
492       if (NAT_PROTOCOL_ICMP == nat_proto)
493         {
494           nat_6t_flow_icmp_id_rewrite_set (&s->o2i, s->ext_host_nat_port);
495         }
496       else
497         {
498           nat_6t_flow_sport_rewrite_set (&s->o2i, s->ext_host_nat_port);
499         }
500
501       nat_6t_l3_l4_csum_calc (&s->o2i);
502
503       nat_6t_i2o_flow_init (sm, thread_index, s, i2o_addr, i2o_port,
504                             s->ext_host_nat_addr, s->ext_host_nat_port,
505                             i2o_fib_index, ip->protocol);
506       nat_6t_flow_daddr_rewrite_set (&s->i2o, s->ext_host_addr.as_u32);
507       if (NAT_PROTOCOL_ICMP == nat_proto)
508         {
509           nat_6t_flow_icmp_id_rewrite_set (&s->i2o, s->ext_host_port);
510         }
511       else
512         {
513           nat_6t_flow_dport_rewrite_set (&s->i2o, s->ext_host_port);
514         }
515     }
516   else
517     {
518       if (NAT_PROTOCOL_ICMP == nat_proto)
519         {
520           nat_6t_i2o_flow_init (sm, thread_index, s, i2o_addr, i2o_port,
521                                 s->ext_host_addr, i2o_port, i2o_fib_index,
522                                 ip->protocol);
523         }
524       else
525         {
526           nat_6t_i2o_flow_init (sm, thread_index, s, i2o_addr, i2o_port,
527                                 s->ext_host_addr, s->ext_host_port,
528                                 i2o_fib_index, ip->protocol);
529         }
530     }
531
532   nat_6t_flow_saddr_rewrite_set (&s->i2o, o2i_addr.as_u32);
533   if (NAT_PROTOCOL_ICMP == nat_proto)
534     {
535       nat_6t_flow_icmp_id_rewrite_set (&s->i2o, o2i_port);
536     }
537   else
538     {
539       nat_6t_flow_sport_rewrite_set (&s->i2o, o2i_port);
540     }
541
542   if (nat_ed_ses_i2o_flow_hash_add_del (sm, thread_index, s, 1))
543     {
544       nat_elog_notice (sm, "in2out flow hash add failed");
545       if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, s, 0))
546         {
547           nat_elog_warn (sm, "out2in flow hash del failed");
548         }
549       nat_ed_session_delete (sm, s, thread_index, 1);
550       return 0;
551     }
552
553   nat_ipfix_logging_nat44_ses_create (thread_index,
554                                       s->in2out.addr.as_u32,
555                                       s->out2in.addr.as_u32,
556                                       s->nat_proto,
557                                       s->in2out.port,
558                                       s->out2in.port, s->in2out.fib_index);
559
560   nat_syslog_nat44_sadd (0, s->in2out.fib_index, &s->in2out.addr,
561                          s->in2out.port, &s->ext_host_nat_addr,
562                          s->ext_host_nat_port, &s->out2in.addr, s->out2in.port,
563                          &s->ext_host_addr, s->ext_host_port, s->nat_proto,
564                          is_twice_nat_session (s));
565
566   per_vrf_sessions_register_session (s, thread_index);
567
568   return s;
569 }
570
571 static void
572 create_bypass_for_fwd (snat_main_t *sm, vlib_buffer_t *b, snat_session_t *s,
573                        ip4_header_t *ip, u32 rx_fib_index, u32 thread_index)
574 {
575   clib_bihash_kv_16_8_t kv, value;
576   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
577   vlib_main_t *vm = vlib_get_main ();
578   f64 now = vlib_time_now (vm);
579   u16 lookup_sport, lookup_dport;
580   u8 lookup_protocol;
581   ip4_address_t lookup_saddr, lookup_daddr;
582
583   if (ip->protocol == IP_PROTOCOL_ICMP)
584     {
585       if (nat_get_icmp_session_lookup_values (b, ip, &lookup_saddr,
586                                               &lookup_sport, &lookup_daddr,
587                                               &lookup_dport, &lookup_protocol))
588         return;
589     }
590   else
591     {
592       if (ip->protocol == IP_PROTOCOL_UDP || ip->protocol == IP_PROTOCOL_TCP)
593         {
594           lookup_sport = vnet_buffer (b)->ip.reass.l4_dst_port;
595           lookup_dport = vnet_buffer (b)->ip.reass.l4_src_port;
596         }
597       else
598         {
599           lookup_sport = 0;
600           lookup_dport = 0;
601         }
602       lookup_saddr.as_u32 = ip->dst_address.as_u32;
603       lookup_daddr.as_u32 = ip->src_address.as_u32;
604       lookup_protocol = ip->protocol;
605     }
606
607   init_ed_k (&kv, lookup_saddr, lookup_sport, lookup_daddr, lookup_dport,
608              rx_fib_index, lookup_protocol);
609
610   if (!clib_bihash_search_16_8 (&sm->flow_hash, &kv, &value))
611     {
612       ASSERT (thread_index == ed_value_get_thread_index (&value));
613       s =
614         pool_elt_at_index (tsm->sessions,
615                            ed_value_get_session_index (&value));
616     }
617   else if (ip->protocol == IP_PROTOCOL_ICMP &&
618            icmp_type_is_error_message
619            (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
620     {
621       return;
622     }
623   else
624     {
625       u32 proto;
626
627       if (PREDICT_FALSE
628           (nat44_ed_maximum_sessions_exceeded
629            (sm, rx_fib_index, thread_index)))
630         return;
631
632       s = nat_ed_session_alloc (sm, thread_index, now, ip->protocol);
633       if (!s)
634         {
635           nat_elog_warn (sm, "create NAT session failed");
636           return;
637         }
638
639       proto = ip_proto_to_nat_proto (ip->protocol);
640
641       s->ext_host_addr = ip->src_address;
642       s->ext_host_port = lookup_dport;
643       s->flags |= SNAT_SESSION_FLAG_FWD_BYPASS;
644       s->out2in.addr = ip->dst_address;
645       s->out2in.port = lookup_sport;
646       s->nat_proto = proto;
647       if (proto == NAT_PROTOCOL_OTHER)
648         {
649           s->flags |= SNAT_SESSION_FLAG_UNKNOWN_PROTO;
650           s->out2in.port = ip->protocol;
651         }
652       s->out2in.fib_index = rx_fib_index;
653       s->in2out.addr = s->out2in.addr;
654       s->in2out.port = s->out2in.port;
655       s->in2out.fib_index = s->out2in.fib_index;
656
657       nat_6t_i2o_flow_init (sm, thread_index, s, ip->dst_address, lookup_sport,
658                             ip->src_address, lookup_dport, rx_fib_index,
659                             ip->protocol);
660       nat_6t_flow_txfib_rewrite_set (&s->i2o, rx_fib_index);
661       if (nat_ed_ses_i2o_flow_hash_add_del (sm, thread_index, s, 1))
662         {
663           nat_elog_notice (sm, "in2out flow add failed");
664           nat_ed_session_delete (sm, s, thread_index, 1);
665           return;
666         }
667
668       per_vrf_sessions_register_session (s, thread_index);
669     }
670
671   if (ip->protocol == IP_PROTOCOL_TCP)
672     {
673       tcp_header_t *tcp = ip4_next_header (ip);
674       nat44_set_tcp_session_state_o2i (sm, now, s, tcp->flags,
675                                        tcp->ack_number, tcp->seq_number,
676                                        thread_index);
677     }
678
679   /* Accounting */
680   nat44_session_update_counters (s, now, 0, thread_index);
681   /* Per-user LRU list maintenance */
682   nat44_session_update_lru (sm, s, thread_index);
683 }
684
685 static snat_session_t *
686 nat44_ed_out2in_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b,
687                                         ip4_header_t *ip, u32 rx_fib_index,
688                                         u32 thread_index, f64 now,
689                                         vlib_main_t *vm,
690                                         vlib_node_runtime_t *node)
691 {
692   clib_bihash_kv_8_8_t kv, value;
693   snat_static_mapping_t *m;
694   snat_session_t *s;
695
696   if (PREDICT_FALSE (
697         nat44_ed_maximum_sessions_exceeded (sm, rx_fib_index, thread_index)))
698     {
699       b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_SESSIONS_EXCEEDED];
700       nat_elog_notice (sm, "maximum sessions exceeded");
701       return 0;
702     }
703
704   init_nat_k (&kv, ip->dst_address, 0, 0, 0);
705   if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
706     {
707       b->error = node->errors[NAT_OUT2IN_ED_ERROR_NO_TRANSLATION];
708       return 0;
709     }
710
711   m = pool_elt_at_index (sm->static_mappings, value.value);
712
713   /* Create a new session */
714   s = nat_ed_session_alloc (sm, thread_index, now, ip->protocol);
715   if (!s)
716     {
717       b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_SESSIONS_EXCEEDED];
718       nat_elog_warn (sm, "create NAT session failed");
719       return 0;
720     }
721
722   s->ext_host_addr.as_u32 = ip->src_address.as_u32;
723   s->flags |= SNAT_SESSION_FLAG_UNKNOWN_PROTO;
724   s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
725   s->flags |= SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT;
726   s->out2in.addr.as_u32 = ip->dst_address.as_u32;
727   s->out2in.fib_index = rx_fib_index;
728   s->in2out.addr.as_u32 = m->local_addr.as_u32;
729   s->in2out.fib_index = m->fib_index;
730   s->in2out.port = s->out2in.port = ip->protocol;
731
732   nat_6t_o2i_flow_init (sm, thread_index, s, ip->dst_address, 0,
733                         ip->src_address, 0, m->fib_index, ip->protocol);
734   nat_6t_flow_saddr_rewrite_set (&s->i2o, ip->dst_address.as_u32);
735   if (nat_ed_ses_i2o_flow_hash_add_del (sm, thread_index, s, 1))
736     {
737       nat_elog_notice (sm, "in2out key add failed");
738       nat_ed_session_delete (sm, s, thread_index, 1);
739       return NULL;
740     }
741
742   nat_6t_o2i_flow_init (sm, thread_index, s, ip->src_address, 0,
743                         ip->dst_address, 0, rx_fib_index, ip->protocol);
744   nat_6t_flow_daddr_rewrite_set (&s->o2i, m->local_addr.as_u32);
745   nat_6t_flow_txfib_rewrite_set (&s->o2i, m->fib_index);
746   if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, s, 1))
747     {
748       nat_elog_notice (sm, "out2in flow hash add failed");
749       nat_ed_session_delete (sm, s, thread_index, 1);
750       return NULL;
751     }
752
753   per_vrf_sessions_register_session (s, thread_index);
754
755   /* Accounting */
756   nat44_session_update_counters (s, now, vlib_buffer_length_in_chain (vm, b),
757                                  thread_index);
758   /* Per-user LRU list maintenance */
759   nat44_session_update_lru (sm, s, thread_index);
760
761   return s;
762 }
763
764 static inline uword
765 nat44_ed_out2in_fast_path_node_fn_inline (vlib_main_t * vm,
766                                           vlib_node_runtime_t * node,
767                                           vlib_frame_t * frame,
768                                           int is_multi_worker)
769 {
770   u32 n_left_from, *from;
771   snat_main_t *sm = &snat_main;
772   f64 now = vlib_time_now (vm);
773   u32 thread_index = vm->thread_index;
774   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
775
776   from = vlib_frame_vector_args (frame);
777   n_left_from = frame->n_vectors;
778
779   vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
780   u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
781   vlib_get_buffers (vm, from, b, n_left_from);
782
783   while (n_left_from > 0)
784     {
785       vlib_buffer_t *b0;
786       u32 sw_if_index0, rx_fib_index0;
787       nat_protocol_t proto0;
788       ip4_header_t *ip0;
789       snat_session_t *s0 = 0;
790       clib_bihash_kv_16_8_t kv0, value0;
791       nat_translation_error_e translation_error = NAT_ED_TRNSL_ERR_SUCCESS;
792       nat_6t_flow_t *f = 0;
793       nat_6t_t lookup;
794       int lookup_skipped = 0;
795
796       b0 = *b;
797       b++;
798
799       /* Prefetch next iteration. */
800       if (PREDICT_TRUE (n_left_from >= 2))
801         {
802           vlib_buffer_t *p2;
803
804           p2 = *b;
805
806           vlib_prefetch_buffer_header (p2, LOAD);
807
808           CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, LOAD);
809         }
810
811       next[0] = vnet_buffer2 (b0)->nat.arc_next;
812
813       lookup.sport = vnet_buffer (b0)->ip.reass.l4_src_port;
814       lookup.dport = vnet_buffer (b0)->ip.reass.l4_dst_port;
815
816       vnet_buffer (b0)->snat.flags = 0;
817       ip0 = vlib_buffer_get_current (b0);
818
819       sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
820       rx_fib_index0 =
821         fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, sw_if_index0);
822
823       lookup.fib_index = rx_fib_index0;
824
825       if (PREDICT_FALSE (ip0->ttl == 1))
826         {
827           vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
828           icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
829                                        ICMP4_time_exceeded_ttl_exceeded_in_transit,
830                                        0);
831           next[0] = NAT_NEXT_ICMP_ERROR;
832           goto trace0;
833         }
834
835       proto0 = ip_proto_to_nat_proto (ip0->protocol);
836
837       if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_ICMP))
838         {
839           if (vnet_buffer (b0)->ip.reass.icmp_type_or_tcp_flags !=
840                 ICMP4_echo_request &&
841               vnet_buffer (b0)->ip.reass.icmp_type_or_tcp_flags !=
842                 ICMP4_echo_reply &&
843               !icmp_type_is_error_message (
844                 vnet_buffer (b0)->ip.reass.icmp_type_or_tcp_flags))
845             {
846               b0->error = node->errors[NAT_OUT2IN_ED_ERROR_BAD_ICMP_TYPE];
847               next[0] = NAT_NEXT_DROP;
848               goto trace0;
849             }
850           int err = nat_get_icmp_session_lookup_values (
851             b0, ip0, &lookup.saddr, &lookup.sport, &lookup.daddr,
852             &lookup.dport, &lookup.proto);
853           if (err != 0)
854             {
855               b0->error = node->errors[err];
856               next[0] = NAT_NEXT_DROP;
857               goto trace0;
858             }
859         }
860       else
861         {
862           lookup.saddr.as_u32 = ip0->src_address.as_u32;
863           lookup.daddr.as_u32 = ip0->dst_address.as_u32;
864           lookup.proto = ip0->protocol;
865         }
866
867       /* there might be a stashed index in vnet_buffer2 from handoff or
868        * classify node, see if it can be used */
869       if (is_multi_worker &&
870           !pool_is_free_index (tsm->sessions,
871                                vnet_buffer2 (b0)->nat.cached_session_index))
872         {
873           s0 = pool_elt_at_index (tsm->sessions,
874                                   vnet_buffer2 (b0)->nat.cached_session_index);
875           if (PREDICT_TRUE (nat_6t_t_eq (&s0->o2i.match, &lookup)) ||
876               (s0->flags & SNAT_SESSION_FLAG_TWICE_NAT &&
877                nat_6t_t_eq (&s0->i2o.match, &lookup)))
878             {
879               /* yes, this is the droid we're looking for */
880               lookup_skipped = 1;
881               goto skip_lookup;
882             }
883           s0 = NULL;
884         }
885
886       init_ed_k (&kv0, lookup.saddr, lookup.sport, lookup.daddr, lookup.dport,
887                  lookup.fib_index, lookup.proto);
888
889       // lookup flow
890       if (clib_bihash_search_16_8 (&sm->flow_hash, &kv0, &value0))
891         {
892           // flow does not exist go slow path
893           next[0] = NAT_NEXT_OUT2IN_ED_SLOW_PATH;
894           goto trace0;
895         }
896       ASSERT (thread_index == ed_value_get_thread_index (&value0));
897       s0 =
898         pool_elt_at_index (tsm->sessions,
899                            ed_value_get_session_index (&value0));
900     skip_lookup:
901
902       if (PREDICT_FALSE (per_vrf_sessions_is_expired (s0, thread_index)))
903         {
904           // session is closed, go slow path
905           nat_free_session_data (sm, s0, thread_index, 0);
906           nat_ed_session_delete (sm, s0, thread_index, 1);
907           next[0] = NAT_NEXT_OUT2IN_ED_SLOW_PATH;
908           goto trace0;
909         }
910
911       if (s0->tcp_closed_timestamp)
912         {
913           if (now >= s0->tcp_closed_timestamp)
914             {
915               // session is closed, go slow path, freed in slow path
916               next[0] = NAT_NEXT_OUT2IN_ED_SLOW_PATH;
917             }
918           else
919             {
920               // session in transitory timeout, drop
921               b0->error = node->errors[NAT_OUT2IN_ED_ERROR_TCP_CLOSED];
922               next[0] = NAT_NEXT_DROP;
923             }
924           goto trace0;
925         }
926
927       // drop if session expired
928       u64 sess_timeout_time;
929       sess_timeout_time =
930         s0->last_heard + (f64) nat44_session_get_timeout (sm, s0);
931       if (now >= sess_timeout_time)
932         {
933           // session is closed, go slow path
934           nat_free_session_data (sm, s0, thread_index, 0);
935           nat_ed_session_delete (sm, s0, thread_index, 1);
936           next[0] = NAT_NEXT_OUT2IN_ED_SLOW_PATH;
937           goto trace0;
938         }
939
940       if (nat_6t_t_eq (&s0->o2i.match, &lookup))
941         {
942           f = &s0->o2i;
943         }
944       else if (s0->flags & SNAT_SESSION_FLAG_TWICE_NAT &&
945                nat_6t_t_eq (&s0->i2o.match, &lookup))
946         {
947           f = &s0->i2o;
948         }
949       else
950         {
951           /*
952            * Send DHCP packets to the ipv4 stack, or we won't
953            * be able to use dhcp client on the outside interface
954            */
955           if (PREDICT_FALSE (
956                 proto0 == NAT_PROTOCOL_UDP &&
957                 (vnet_buffer (b0)->ip.reass.l4_dst_port ==
958                  clib_host_to_net_u16 (UDP_DST_PORT_dhcp_to_client))))
959             {
960               goto trace0;
961             }
962
963           if (!sm->forwarding_enabled)
964             {
965               b0->error = node->errors[NAT_OUT2IN_ED_ERROR_NO_TRANSLATION];
966               next[0] = NAT_NEXT_DROP;
967               goto trace0;
968             }
969           else
970             {
971               if (nat_6t_t_eq (&s0->i2o.match, &lookup))
972                 {
973                   f = &s0->i2o;
974                 }
975               else
976                 {
977                   // FIXME TODO bypass ???
978                   //  create_bypass_for_fwd (sm, b0, s0, ip0, rx_fib_index0,
979                   //                       thread_index);
980                   translation_error = NAT_ED_TRNSL_ERR_FLOW_MISMATCH;
981                   nat_free_session_data (sm, s0, thread_index, 0);
982                   nat_ed_session_delete (sm, s0, thread_index, 1);
983                   next[0] = NAT_NEXT_DROP;
984                   goto trace0;
985                 }
986             }
987         }
988
989       if (NAT_ED_TRNSL_ERR_SUCCESS !=
990           (translation_error = nat_6t_flow_buf_translate (
991              sm, b0, ip0, f, proto0, 0 /* is_output_feature */)))
992         {
993           next[0] = NAT_NEXT_DROP;
994           goto trace0;
995         }
996
997       switch (proto0)
998         {
999         case NAT_PROTOCOL_TCP:
1000           vlib_increment_simple_counter (&sm->counters.fastpath.out2in.tcp,
1001                                          thread_index, sw_if_index0, 1);
1002           nat44_set_tcp_session_state_o2i (sm, now, s0,
1003                                            vnet_buffer (b0)->ip.
1004                                            reass.icmp_type_or_tcp_flags,
1005                                            vnet_buffer (b0)->ip.
1006                                            reass.tcp_ack_number,
1007                                            vnet_buffer (b0)->ip.
1008                                            reass.tcp_seq_number,
1009                                            thread_index);
1010           break;
1011         case NAT_PROTOCOL_UDP:
1012           vlib_increment_simple_counter (&sm->counters.fastpath.out2in.udp,
1013                                          thread_index, sw_if_index0, 1);
1014           break;
1015         case NAT_PROTOCOL_ICMP:
1016           vlib_increment_simple_counter (&sm->counters.fastpath.out2in.icmp,
1017                                          thread_index, sw_if_index0, 1);
1018           break;
1019         case NAT_PROTOCOL_OTHER:
1020           vlib_increment_simple_counter (&sm->counters.fastpath.out2in.other,
1021                                          thread_index, sw_if_index0, 1);
1022           break;
1023         }
1024
1025       /* Accounting */
1026       nat44_session_update_counters (s0, now,
1027                                      vlib_buffer_length_in_chain (vm, b0),
1028                                      thread_index);
1029       /* Per-user LRU list maintenance */
1030       nat44_session_update_lru (sm, s0, thread_index);
1031
1032     trace0:
1033       if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
1034                          && (b0->flags & VLIB_BUFFER_IS_TRACED)))
1035         {
1036           nat44_ed_out2in_trace_t *t =
1037             vlib_add_trace (vm, node, b0, sizeof (*t));
1038           t->sw_if_index = sw_if_index0;
1039           t->next_index = next[0];
1040           t->is_slow_path = 0;
1041           t->translation_error = translation_error;
1042           clib_memcpy (&t->search_key, &kv0, sizeof (t->search_key));
1043           t->lookup_skipped = lookup_skipped;
1044
1045           if (s0)
1046             {
1047               t->session_index = s0 - tsm->sessions;
1048               clib_memcpy (&t->i2of, &s0->i2o, sizeof (t->i2of));
1049               clib_memcpy (&t->o2if, &s0->o2i, sizeof (t->o2if));
1050               t->translation_via_i2of = (&s0->i2o == f);
1051             }
1052           else
1053             {
1054               t->session_index = ~0;
1055             }
1056         }
1057
1058       if (next[0] == NAT_NEXT_DROP)
1059         {
1060           vlib_increment_simple_counter (&sm->counters.fastpath.out2in.drops,
1061                                          thread_index, sw_if_index0, 1);
1062         }
1063
1064       n_left_from--;
1065       next++;
1066     }
1067
1068   vlib_buffer_enqueue_to_next (vm, node, from, (u16 *) nexts,
1069                                frame->n_vectors);
1070   return frame->n_vectors;
1071 }
1072
1073 static inline uword
1074 nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm,
1075                                           vlib_node_runtime_t * node,
1076                                           vlib_frame_t * frame)
1077 {
1078   u32 n_left_from, *from;
1079   snat_main_t *sm = &snat_main;
1080   f64 now = vlib_time_now (vm);
1081   u32 thread_index = vm->thread_index;
1082   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
1083   snat_static_mapping_t *m;
1084
1085   from = vlib_frame_vector_args (frame);
1086   n_left_from = frame->n_vectors;
1087
1088   vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
1089   u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
1090   vlib_get_buffers (vm, from, b, n_left_from);
1091
1092   while (n_left_from > 0)
1093     {
1094       vlib_buffer_t *b0;
1095       u32 sw_if_index0, rx_fib_index0;
1096       nat_protocol_t proto0;
1097       ip4_header_t *ip0;
1098       udp_header_t *udp0;
1099       icmp46_header_t *icmp0;
1100       snat_session_t *s0 = 0;
1101       clib_bihash_kv_16_8_t kv0, value0;
1102       lb_nat_type_t lb_nat0;
1103       twice_nat_type_t twice_nat0;
1104       u8 identity_nat0;
1105       ip4_address_t sm_addr;
1106       u16 sm_port;
1107       u32 sm_fib_index;
1108       nat_translation_error_e translation_error = NAT_ED_TRNSL_ERR_SUCCESS;
1109
1110       b0 = *b;
1111       next[0] = vnet_buffer2 (b0)->nat.arc_next;
1112
1113       vnet_buffer (b0)->snat.flags = 0;
1114       ip0 = vlib_buffer_get_current (b0);
1115
1116       sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
1117       rx_fib_index0 =
1118         fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, sw_if_index0);
1119
1120       if (PREDICT_FALSE (ip0->ttl == 1))
1121         {
1122           vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
1123           icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
1124                                        ICMP4_time_exceeded_ttl_exceeded_in_transit,
1125                                        0);
1126           next[0] = NAT_NEXT_ICMP_ERROR;
1127           goto trace0;
1128         }
1129
1130       udp0 = ip4_next_header (ip0);
1131       icmp0 = (icmp46_header_t *) udp0;
1132       proto0 = ip_proto_to_nat_proto (ip0->protocol);
1133
1134       if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_OTHER))
1135         {
1136           s0 = nat44_ed_out2in_slowpath_unknown_proto (
1137             sm, b0, ip0, rx_fib_index0, thread_index, now, vm, node);
1138           if (!sm->forwarding_enabled)
1139             {
1140               if (!s0)
1141                 next[0] = NAT_NEXT_DROP;
1142             }
1143           if (NAT_NEXT_DROP != next[0] &&
1144               NAT_ED_TRNSL_ERR_SUCCESS !=
1145                 (translation_error = nat_6t_flow_buf_translate (
1146                    sm, b0, ip0, &s0->o2i, proto0, 0 /* is_output_feature */)))
1147             {
1148               goto trace0;
1149             }
1150
1151           vlib_increment_simple_counter (&sm->counters.slowpath.out2in.other,
1152                                          thread_index, sw_if_index0, 1);
1153           goto trace0;
1154         }
1155
1156       if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_ICMP))
1157         {
1158           next[0] = icmp_out2in_ed_slow_path
1159             (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
1160              next[0], now, thread_index, &s0);
1161
1162           if (NAT_NEXT_DROP != next[0] && s0 &&
1163               NAT_ED_TRNSL_ERR_SUCCESS !=
1164                 (translation_error = nat_6t_flow_buf_translate (
1165                    sm, b0, ip0, &s0->o2i, proto0, 0 /* is_output_feature */)))
1166             {
1167               goto trace0;
1168             }
1169
1170           vlib_increment_simple_counter (&sm->counters.slowpath.out2in.icmp,
1171                                          thread_index, sw_if_index0, 1);
1172           goto trace0;
1173         }
1174
1175       init_ed_k (&kv0, ip0->src_address,
1176                  vnet_buffer (b0)->ip.reass.l4_src_port, ip0->dst_address,
1177                  vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0,
1178                  ip0->protocol);
1179
1180       s0 = NULL;
1181       if (!clib_bihash_search_16_8 (&sm->flow_hash, &kv0, &value0))
1182         {
1183           ASSERT (thread_index == ed_value_get_thread_index (&value0));
1184           s0 =
1185             pool_elt_at_index (tsm->sessions,
1186                                ed_value_get_session_index (&value0));
1187
1188           if (s0->tcp_closed_timestamp && now >= s0->tcp_closed_timestamp)
1189             {
1190               nat_free_session_data (sm, s0, thread_index, 0);
1191               nat_ed_session_delete (sm, s0, thread_index, 1);
1192               s0 = NULL;
1193             }
1194         }
1195
1196       if (!s0)
1197         {
1198           /* Try to match static mapping by external address and port,
1199              destination address and port in packet */
1200
1201           if (snat_static_mapping_match (
1202                 vm, sm, ip0->dst_address,
1203                 vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0, proto0,
1204                 &sm_addr, &sm_port, &sm_fib_index, 1, 0, &twice_nat0, &lb_nat0,
1205                 &ip0->src_address, &identity_nat0, &m))
1206             {
1207               /*
1208                * Send DHCP packets to the ipv4 stack, or we won't
1209                * be able to use dhcp client on the outside interface
1210                */
1211               if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_UDP
1212                                  && (vnet_buffer (b0)->ip.reass.l4_dst_port ==
1213                                      clib_host_to_net_u16
1214                                      (UDP_DST_PORT_dhcp_to_client))))
1215                 {
1216                   goto trace0;
1217                 }
1218
1219               if (!sm->forwarding_enabled)
1220                 {
1221                   b0->error =
1222                     node->errors[NAT_OUT2IN_ED_ERROR_NO_TRANSLATION];
1223                   next[0] = NAT_NEXT_DROP;
1224                 }
1225               else
1226                 {
1227                   if (next_src_nat
1228                       (sm, ip0, vnet_buffer (b0)->ip.reass.l4_src_port,
1229                        vnet_buffer (b0)->ip.reass.l4_dst_port,
1230                        thread_index, rx_fib_index0))
1231                     {
1232                       next[0] = NAT_NEXT_IN2OUT_ED_FAST_PATH;
1233                     }
1234                   else
1235                     {
1236                       create_bypass_for_fwd (sm, b0, s0, ip0, rx_fib_index0,
1237                                              thread_index);
1238                     }
1239                 }
1240               goto trace0;
1241             }
1242
1243           if (PREDICT_FALSE (identity_nat0))
1244             goto trace0;
1245
1246           if ((proto0 == NAT_PROTOCOL_TCP)
1247               && !tcp_flags_is_init (vnet_buffer (b0)->ip.
1248                                      reass.icmp_type_or_tcp_flags))
1249             {
1250               b0->error = node->errors[NAT_OUT2IN_ED_ERROR_NON_SYN];
1251               next[0] = NAT_NEXT_DROP;
1252               goto trace0;
1253             }
1254
1255           /* Create session initiated by host from external network */
1256           s0 = create_session_for_static_mapping_ed (sm, b0,
1257                                                      sm_addr, sm_port,
1258                                                      sm_fib_index,
1259                                                      ip0->dst_address,
1260                                                      vnet_buffer (b0)->
1261                                                      ip.reass.l4_dst_port,
1262                                                      rx_fib_index0, proto0,
1263                                                      node, rx_fib_index0,
1264                                                      thread_index, twice_nat0,
1265                                                      lb_nat0, now, m);
1266           if (!s0)
1267             {
1268               next[0] = NAT_NEXT_DROP;
1269               goto trace0;
1270             }
1271         }
1272
1273       if (NAT_ED_TRNSL_ERR_SUCCESS !=
1274           (translation_error = nat_6t_flow_buf_translate (
1275              sm, b0, ip0, &s0->o2i, proto0, 0 /* is_output_feature */)))
1276         {
1277           next[0] = NAT_NEXT_DROP;
1278           goto trace0;
1279         }
1280
1281       if (PREDICT_TRUE (proto0 == NAT_PROTOCOL_TCP))
1282         {
1283           vlib_increment_simple_counter (&sm->counters.slowpath.out2in.tcp,
1284                                          thread_index, sw_if_index0, 1);
1285           nat44_set_tcp_session_state_o2i (sm, now, s0,
1286                                            vnet_buffer (b0)->ip.
1287                                            reass.icmp_type_or_tcp_flags,
1288                                            vnet_buffer (b0)->ip.
1289                                            reass.tcp_ack_number,
1290                                            vnet_buffer (b0)->ip.
1291                                            reass.tcp_seq_number,
1292                                            thread_index);
1293         }
1294       else
1295         {
1296           vlib_increment_simple_counter (&sm->counters.slowpath.out2in.udp,
1297                                          thread_index, sw_if_index0, 1);
1298         }
1299
1300       /* Accounting */
1301       nat44_session_update_counters (s0, now,
1302                                      vlib_buffer_length_in_chain (vm, b0),
1303                                      thread_index);
1304       /* Per-user LRU list maintenance */
1305       nat44_session_update_lru (sm, s0, thread_index);
1306
1307     trace0:
1308       if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
1309                          && (b0->flags & VLIB_BUFFER_IS_TRACED)))
1310         {
1311           nat44_ed_out2in_trace_t *t =
1312             vlib_add_trace (vm, node, b0, sizeof (*t));
1313           t->sw_if_index = sw_if_index0;
1314           t->next_index = next[0];
1315           t->is_slow_path = 1;
1316           t->translation_error = translation_error;
1317           clib_memcpy (&t->search_key, &kv0, sizeof (t->search_key));
1318
1319           if (s0)
1320             {
1321               t->session_index = s0 - tsm->sessions;
1322               clib_memcpy (&t->i2of, &s0->i2o, sizeof (t->i2of));
1323               clib_memcpy (&t->o2if, &s0->o2i, sizeof (t->o2if));
1324             }
1325           else
1326             {
1327               t->session_index = ~0;
1328             }
1329         }
1330
1331       if (next[0] == NAT_NEXT_DROP)
1332         {
1333           vlib_increment_simple_counter (&sm->counters.slowpath.out2in.drops,
1334                                          thread_index, sw_if_index0, 1);
1335         }
1336
1337       n_left_from--;
1338       next++;
1339       b++;
1340     }
1341
1342   vlib_buffer_enqueue_to_next (vm, node, from, (u16 *) nexts,
1343                                frame->n_vectors);
1344
1345   return frame->n_vectors;
1346 }
1347
1348 VLIB_NODE_FN (nat44_ed_out2in_node) (vlib_main_t * vm,
1349                                      vlib_node_runtime_t * node,
1350                                      vlib_frame_t * frame)
1351 {
1352   if (snat_main.num_workers > 1)
1353     {
1354       return nat44_ed_out2in_fast_path_node_fn_inline (vm, node, frame, 1);
1355     }
1356   else
1357     {
1358       return nat44_ed_out2in_fast_path_node_fn_inline (vm, node, frame, 0);
1359     }
1360 }
1361
1362 /* *INDENT-OFF* */
1363 VLIB_REGISTER_NODE (nat44_ed_out2in_node) = {
1364   .name = "nat44-ed-out2in",
1365   .vector_size = sizeof (u32),
1366   .sibling_of = "nat-default",
1367   .format_trace = format_nat44_ed_out2in_trace,
1368   .type = VLIB_NODE_TYPE_INTERNAL,
1369   .n_errors = ARRAY_LEN(nat_out2in_ed_error_strings),
1370   .error_strings = nat_out2in_ed_error_strings,
1371   .runtime_data_bytes = sizeof (snat_runtime_t),
1372 };
1373 /* *INDENT-ON* */
1374
1375 VLIB_NODE_FN (nat44_ed_out2in_slowpath_node) (vlib_main_t * vm,
1376                                               vlib_node_runtime_t * node,
1377                                               vlib_frame_t * frame)
1378 {
1379   return nat44_ed_out2in_slow_path_node_fn_inline (vm, node, frame);
1380 }
1381
1382 /* *INDENT-OFF* */
1383 VLIB_REGISTER_NODE (nat44_ed_out2in_slowpath_node) = {
1384   .name = "nat44-ed-out2in-slowpath",
1385   .vector_size = sizeof (u32),
1386   .sibling_of = "nat-default",
1387   .format_trace = format_nat44_ed_out2in_trace,
1388   .type = VLIB_NODE_TYPE_INTERNAL,
1389   .n_errors = ARRAY_LEN(nat_out2in_ed_error_strings),
1390   .error_strings = nat_out2in_ed_error_strings,
1391   .runtime_data_bytes = sizeof (snat_runtime_t),
1392 };
1393 /* *INDENT-ON* */
1394
1395 static u8 *
1396 format_nat_pre_trace (u8 * s, va_list * args)
1397 {
1398   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1399   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1400   nat_pre_trace_t *t = va_arg (*args, nat_pre_trace_t *);
1401   return format (s, "out2in next_index %d arc_next_index %d", t->next_index,
1402                  t->arc_next_index);
1403 }
1404
1405 VLIB_NODE_FN (nat_pre_out2in_node) (vlib_main_t * vm,
1406                                     vlib_node_runtime_t * node,
1407                                     vlib_frame_t * frame)
1408 {
1409   return nat_pre_node_fn_inline (vm, node, frame,
1410                                  NAT_NEXT_OUT2IN_ED_FAST_PATH);
1411 }
1412
1413 /* *INDENT-OFF* */
1414 VLIB_REGISTER_NODE (nat_pre_out2in_node) = {
1415   .name = "nat-pre-out2in",
1416   .vector_size = sizeof (u32),
1417   .sibling_of = "nat-default",
1418   .format_trace = format_nat_pre_trace,
1419   .type = VLIB_NODE_TYPE_INTERNAL,
1420   .n_errors = 0,
1421  };
1422 /* *INDENT-ON* */
1423
1424 /*
1425  * fd.io coding-style-patch-verification: ON
1426  *
1427  * Local Variables:
1428  * eval: (c-set-style "gnu")
1429  * End:
1430  */