NAT: VPP-1537 IPFIX per worker processing
[vpp.git] / src / plugins / nat / nat.c
index 2e1aa77..8d02e56 100755 (executable)
@@ -264,7 +264,8 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index)
     return;
 
   /* log NAT event */
-  snat_ipfix_logging_nat44_ses_delete (s->in2out.addr.as_u32,
+  snat_ipfix_logging_nat44_ses_delete (thread_index,
+                                      s->in2out.addr.as_u32,
                                       s->out2in.addr.as_u32,
                                       s->in2out.protocol,
                                       s->in2out.port,
@@ -322,6 +323,9 @@ nat_user_get_or_create (snat_main_t * sm, ip4_address_t * addr, u32 fib_index,
       /* add user */
       if (clib_bihash_add_del_8_8 (&tsm->user_hash, &kv, 1))
        nat_log_warn ("user_hash keay add failed");
+
+      vlib_set_simple_counter (&sm->total_users, thread_index, 0,
+                              pool_elts (tsm->users));
     }
   else
     {
@@ -397,6 +401,8 @@ nat_session_alloc_or_recycle (snat_main_t * sm, snat_user_t * u,
                          per_user_translation_list_elt - tsm->list_pool);
 
       s->user_index = u - tsm->users;
+      vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
+                              pool_elts (tsm->sessions));
     }
 
   return s;
@@ -449,7 +455,7 @@ nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u, u32 thread_index,
          nat_log_warn ("max translations per user %U", format_ip4_address,
                        &u->addr);
          snat_ipfix_logging_max_entries_per_user
-           (sm->max_translations_per_user, u->addr.as_u32);
+           (thread_index, sm->max_translations_per_user, u->addr.as_u32);
          return 0;
        }
       else
@@ -471,6 +477,9 @@ nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u, u32 thread_index,
                              s->per_user_list_head_index,
                              per_user_translation_list_elt - tsm->list_pool);
        }
+
+      vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
+                              pool_elts (tsm->sessions));
     }
 
   return s;
@@ -1567,6 +1576,8 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
   }));
   /* *INDENT-ON* */
 
+  ASSERT (vec_len (locals) > 1);
+
   local = pool_elt_at_index (m->locals, locals[0]);
   local->prefix = local->probability;
   for (i = 1; i < vec_len (locals); i++)
@@ -1958,6 +1969,10 @@ snat_interface_add_del_output_feature (u32 sw_if_index,
   snat_interface_t *i;
   snat_address_t *ap;
   snat_static_mapping_t *m;
+  nat_outside_fib_t *outside_fib;
+  u32 fib_index = fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4,
+                                                      sw_if_index);
+
 
   if (sm->deterministic ||
       (sm->static_mapping_only && !(sm->static_mapping_connection_tracking)))
@@ -1971,6 +1986,34 @@ snat_interface_add_del_output_feature (u32 sw_if_index,
   }));
   /* *INDENT-ON* */
 
+  if (!is_inside)
+    {
+      /* *INDENT-OFF* */
+      vec_foreach (outside_fib, sm->outside_fibs)
+        {
+          if (outside_fib->fib_index == fib_index)
+            {
+              if (is_del)
+                {
+                  outside_fib->refcount--;
+                  if (!outside_fib->refcount)
+                    vec_del1 (sm->outside_fibs, outside_fib - sm->outside_fibs);
+                }
+              else
+                outside_fib->refcount++;
+              goto feature_set;
+            }
+        }
+      /* *INDENT-ON* */
+      if (!is_del)
+       {
+         vec_add2 (sm->outside_fibs, outside_fib, 1);
+         outside_fib->refcount = 1;
+         outside_fib->fib_index = fib_index;
+       }
+    }
+
+feature_set:
   if (is_inside)
     {
       if (sm->endpoint_dependent)
@@ -2207,6 +2250,16 @@ snat_init (vlib_main_t * vm)
 
   nat_dpo_module_init ();
 
+  /* Init counters */
+  sm->total_users.name = "total-users";
+  sm->total_users.stat_segment_name = "/nat44/total-users";
+  vlib_validate_simple_counter (&sm->total_users, 0);
+  vlib_zero_simple_counter (&sm->total_users, 0);
+  sm->total_sessions.name = "total-sessions";
+  sm->total_sessions.stat_segment_name = "/nat44/total-sessions";
+  vlib_validate_simple_counter (&sm->total_sessions, 0);
+  vlib_zero_simple_counter (&sm->total_sessions, 0);
+
   /* Init IPFIX logging */
   snat_ipfix_logging_init (vm);
 
@@ -2505,7 +2558,7 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses,
     }
 
   /* Totally out of translations to use... */
-  snat_ipfix_logging_addresses_exhausted (0);
+  snat_ipfix_logging_addresses_exhausted (thread_index, 0);
   return 1;
 }
 
@@ -2555,7 +2608,7 @@ nat_alloc_addr_and_port_mape (snat_address_t * addresses,
 
 exhausted:
   /* Totally out of translations to use... */
-  snat_ipfix_logging_addresses_exhausted (0);
+  snat_ipfix_logging_addresses_exhausted (thread_index, 0);
   return 1;
 }
 
@@ -2603,7 +2656,7 @@ nat_alloc_addr_and_port_range (snat_address_t * addresses,
 
 exhausted:
   /* Totally out of translations to use... */
-  snat_ipfix_logging_addresses_exhausted (0);
+  snat_ipfix_logging_addresses_exhausted (thread_index, 0);
   return 1;
 }