NAT: syslog - sessions logging (VPP-1139)
[vpp.git] / src / plugins / nat / out2in.c
index eeecf16..74d2088 100755 (executable)
@@ -29,6 +29,7 @@
 #include <nat/nat_ipfix_logging.h>
 #include <nat/nat_reass.h>
 #include <nat/nat_inlines.h>
+#include <nat/nat_syslog.h>
 
 #include <vppinfra/hash.h>
 #include <vppinfra/error.h>
@@ -132,6 +133,11 @@ nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg)
                                           s->out2in.port,
                                           s->in2out.fib_index);
 
+      nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index,
+                              &s->in2out.addr, s->in2out.port,
+                              &s->out2in.addr, s->out2in.port,
+                              s->in2out.protocol);
+
       if (!snat_is_session_static (s))
        snat_free_outside_address_and_port (sm->addresses, ctx->thread_index,
                                            &s->out2in);
@@ -229,6 +235,11 @@ create_session_for_static_mapping (snat_main_t * sm,
                                       s->in2out.protocol,
                                       s->in2out.port,
                                       s->out2in.port, s->in2out.fib_index);
+
+  nat_syslog_nat44_apmadd (s->user_index, s->in2out.fib_index,
+                          &s->in2out.addr, s->in2out.port, &s->out2in.addr,
+                          s->out2in.port, s->in2out.protocol);
+
   return s;
 }
 
@@ -775,17 +786,17 @@ snat_out2in_node_fn (vlib_main_t * vm,
              goto trace0;
            }
 
-         if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
+         if (PREDICT_FALSE (ip4_is_fragment (ip0)))
            {
-             next0 = icmp_out2in_slow_path
-               (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
-                next0, now, thread_index, &s0);
+             next0 = SNAT_OUT2IN_NEXT_REASS;
              goto trace0;
            }
 
-         if (PREDICT_FALSE (ip4_is_fragment (ip0)))
+         if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
            {
-             next0 = SNAT_OUT2IN_NEXT_REASS;
+             next0 = icmp_out2in_slow_path
+               (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
+                next0, now, thread_index, &s0);
              goto trace0;
            }
 
@@ -936,17 +947,17 @@ snat_out2in_node_fn (vlib_main_t * vm,
              goto trace1;
            }
 
-         if (PREDICT_FALSE (proto1 == SNAT_PROTOCOL_ICMP))
+         if (PREDICT_FALSE (ip4_is_fragment (ip1)))
            {
-             next1 = icmp_out2in_slow_path
-               (sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
-                next1, now, thread_index, &s1);
+             next1 = SNAT_OUT2IN_NEXT_REASS;
              goto trace1;
            }
 
-         if (PREDICT_FALSE (ip4_is_fragment (ip1)))
+         if (PREDICT_FALSE (proto1 == SNAT_PROTOCOL_ICMP))
            {
-             next1 = SNAT_OUT2IN_NEXT_REASS;
+             next1 = icmp_out2in_slow_path
+               (sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
+                next1, now, thread_index, &s1);
              goto trace1;
            }
 
@@ -1134,17 +1145,17 @@ snat_out2in_node_fn (vlib_main_t * vm,
              goto trace00;
            }
 
-         if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
+         if (PREDICT_FALSE (ip4_is_fragment (ip0)))
            {
-             next0 = icmp_out2in_slow_path
-               (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
-                next0, now, thread_index, &s0);
+             next0 = SNAT_OUT2IN_NEXT_REASS;
              goto trace00;
            }
 
-         if (PREDICT_FALSE (ip4_is_fragment (ip0)))
+         if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
            {
-             next0 = SNAT_OUT2IN_NEXT_REASS;
+             next0 = icmp_out2in_slow_path
+               (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
+                next0, now, thread_index, &s0);
              goto trace00;
            }
 
@@ -1336,6 +1347,7 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
          nat_reass_ip4_t *reass0;
          udp_header_t *udp0;
          tcp_header_t *tcp0;
+         icmp46_header_t *icmp0;
          snat_session_key_t key0, sm0;
          clib_bihash_kv_8_8_t kv0, value0;
          snat_session_t *s0 = 0;
@@ -1369,6 +1381,7 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
          ip0 = (ip4_header_t *) vlib_buffer_get_current (b0);
          udp0 = ip4_next_header (ip0);
          tcp0 = (tcp_header_t *) udp0;
+         icmp0 = (icmp46_header_t *) udp0;
          proto0 = ip_proto_to_snat_proto (ip0->protocol);
 
          reass0 = nat_ip4_reass_find_or_create (ip0->src_address,
@@ -1387,6 +1400,26 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
 
          if (PREDICT_FALSE (ip4_is_first_fragment (ip0)))
            {
+             if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
+               {
+                 next0 = icmp_out2in_slow_path
+                   (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
+                    next0, now, thread_index, &s0);
+
+                 if (PREDICT_TRUE (next0 != SNAT_OUT2IN_NEXT_DROP))
+                   {
+                     if (s0)
+                       reass0->sess_index = s0 - per_thread_data->sessions;
+                     else
+                       reass0->flags |= NAT_REASS_FLAG_ED_DONT_TRANSLATE;
+                     reass0->thread_index = thread_index;
+                     nat_ip4_reass_get_frags (reass0,
+                                              &fragments_to_loopback);
+                   }
+
+                 goto trace0;
+               }
+
              key0.addr = ip0->dst_address;
              key0.port = udp0->dst_port;
              key0.protocol = proto0;
@@ -1421,6 +1454,12 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
                            node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
                          next0 = SNAT_OUT2IN_NEXT_DROP;
                        }
+                     else
+                       {
+                         reass0->flags |= NAT_REASS_FLAG_ED_DONT_TRANSLATE;
+                         nat_ip4_reass_get_frags (reass0,
+                                                  &fragments_to_loopback);
+                       }
                      goto trace0;
                    }
 
@@ -1452,6 +1491,8 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
            }
          else
            {
+             if (reass0->flags & NAT_REASS_FLAG_ED_DONT_TRANSLATE)
+               goto trace0;
              if (PREDICT_FALSE (reass0->sess_index == (u32) ~ 0))
                {
                  if (nat_ip4_reass_add_fragment
@@ -1546,17 +1587,16 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
              u32 len = vec_len (fragments_to_loopback);
              if (len <= VLIB_FRAME_SIZE)
                {
-                 clib_memcpy (from, fragments_to_loopback,
-                              sizeof (u32) * len);
+                 clib_memcpy_fast (from, fragments_to_loopback,
+                                   sizeof (u32) * len);
                  n_left_from = len;
                  vec_reset_length (fragments_to_loopback);
                }
              else
                {
-                 clib_memcpy (from,
-                              fragments_to_loopback + (len -
-                                                       VLIB_FRAME_SIZE),
-                              sizeof (u32) * VLIB_FRAME_SIZE);
+                 clib_memcpy_fast (from, fragments_to_loopback +
+                                   (len - VLIB_FRAME_SIZE),
+                                   sizeof (u32) * VLIB_FRAME_SIZE);
                  n_left_from = VLIB_FRAME_SIZE;
                  _vec_len (fragments_to_loopback) = len - VLIB_FRAME_SIZE;
                }