nat: elog rewrite for multi-worker support
[vpp.git] / src / plugins / nat / out2in_ed.c
index 41f9bfe..560c23e 100644 (file)
@@ -167,7 +167,7 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
       ed_kv.key[0] = ed_key.as_u64[0];
       ed_kv.key[1] = ed_key.as_u64[1];
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0))
-       nat_log_warn ("in2out_ed key del failed");
+       nat_elog_warn ("in2out_ed key del failed");
 
       if (snat_is_unk_proto_session (s))
        goto delete;
@@ -244,14 +244,14 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
   if (PREDICT_FALSE (maximum_sessions_exceeded (sm, thread_index)))
     {
       b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_SESSIONS_EXCEEDED];
-      nat_log_notice ("maximum sessions exceeded");
+      nat_elog_notice ("maximum sessions exceeded");
       return 0;
     }
 
   u = nat_user_get_or_create (sm, &l_key.addr, l_key.fib_index, thread_index);
   if (!u)
     {
-      nat_log_warn ("create NAT user failed");
+      nat_elog_warn ("create NAT user failed");
       return 0;
     }
 
@@ -259,7 +259,7 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
   if (!s)
     {
       nat44_delete_user_with_no_session (sm, u, thread_index);
-      nat_log_warn ("create NAT session failed");
+      nat_elog_warn ("create NAT session failed");
       return 0;
     }
 
@@ -288,7 +288,7 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
   if (clib_bihash_add_or_overwrite_stale_16_8 (&tsm->out2in_ed, &kv,
                                               nat44_o2i_ed_is_idle_session_cb,
                                               &ctx))
-    nat_log_notice ("out2in-ed key add failed");
+    nat_elog_notice ("out2in-ed key add failed");
 
   if (twice_nat == TWICE_NAT || (twice_nat == TWICE_NAT_SELF &&
                                 ip->src_address.as_u32 == l_key.addr.as_u32))
@@ -302,7 +302,7 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
          b->error = node->errors[NAT_OUT2IN_ED_ERROR_OUT_OF_PORTS];
          nat44_delete_session (sm, s, thread_index);
          if (clib_bihash_add_del_16_8 (&tsm->out2in_ed, &kv, 0))
-           nat_log_notice ("out2in-ed key del failed");
+           nat_elog_notice ("out2in-ed key del failed");
          return 0;
        }
       s->ext_host_nat_addr.as_u32 = eh_key.addr.as_u32;
@@ -320,7 +320,7 @@ create_session_for_static_mapping_ed (snat_main_t * sm,
   if (clib_bihash_add_or_overwrite_stale_16_8 (&tsm->in2out_ed, &kv,
                                               nat44_i2o_ed_is_idle_session_cb,
                                               &ctx))
-    nat_log_notice ("in2out-ed key add failed");
+    nat_elog_notice ("in2out-ed key add failed");
 
   snat_ipfix_logging_nat44_ses_create (thread_index,
                                       s->in2out.addr.as_u32,
@@ -452,6 +452,8 @@ create_bypass_for_fwd (snat_main_t * sm, ip4_header_t * ip, u32 rx_fib_index,
     }
   else
     {
+      u32 proto;
+
       if (PREDICT_FALSE (maximum_sessions_exceeded (sm, thread_index)))
        return;
 
@@ -459,7 +461,7 @@ create_bypass_for_fwd (snat_main_t * sm, ip4_header_t * ip, u32 rx_fib_index,
                                  thread_index);
       if (!u)
        {
-         nat_log_warn ("create NAT user failed");
+         nat_elog_warn ("create NAT user failed");
          return;
        }
 
@@ -467,23 +469,30 @@ create_bypass_for_fwd (snat_main_t * sm, ip4_header_t * ip, u32 rx_fib_index,
       if (!s)
        {
          nat44_delete_user_with_no_session (sm, u, thread_index);
-         nat_log_warn ("create NAT session failed");
+         nat_elog_warn ("create NAT session failed");
          return;
        }
 
+      proto = ip_proto_to_snat_proto (key.proto);
+
       s->ext_host_addr = key.r_addr;
       s->ext_host_port = key.r_port;
       s->flags |= SNAT_SESSION_FLAG_FWD_BYPASS;
       s->out2in.addr = key.l_addr;
       s->out2in.port = key.l_port;
-      s->out2in.protocol = ip_proto_to_snat_proto (key.proto);
+      s->out2in.protocol = proto;
+      if (proto == ~0)
+       {
+         s->flags |= SNAT_SESSION_FLAG_UNKNOWN_PROTO;
+         s->out2in.port = ip->protocol;
+       }
       s->out2in.fib_index = 0;
       s->in2out = s->out2in;
       user_session_increment (sm, u, 0);
 
       kv.value = s - tsm->sessions;
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &kv, 1))
-       nat_log_notice ("in2out_ed key add failed");
+       nat_elog_notice ("in2out_ed key add failed");
     }
 
   if (ip->protocol == IP_PROTOCOL_TCP)
@@ -499,6 +508,18 @@ create_bypass_for_fwd (snat_main_t * sm, ip4_header_t * ip, u32 rx_fib_index,
   nat44_session_update_lru (sm, s, thread_index);
 }
 
+static inline void
+create_bypass_for_fwd_worker (snat_main_t * sm, ip4_header_t * ip,
+                             u32 rx_fib_index)
+{
+  ip4_header_t ip_wkr = {
+    .src_address = ip->dst_address,
+  };
+  u32 thread_index = sm->worker_in2out_cb (&ip_wkr, rx_fib_index);
+
+  create_bypass_for_fwd (sm, ip, rx_fib_index, thread_index);
+}
+
 #ifndef CLIB_MARCH_VARIANT
 u32
 icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
@@ -561,7 +582,10 @@ icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
                  next = NAT44_ED_OUT2IN_NEXT_IN2OUT;
                  goto out;
                }
-             create_bypass_for_fwd (sm, ip, rx_fib_index, thread_index);
+             if (sm->num_workers > 1)
+               create_bypass_for_fwd_worker (sm, ip, rx_fib_index);
+             else
+               create_bypass_for_fwd (sm, ip, rx_fib_index, thread_index);
              goto out;
            }
        }
@@ -650,7 +674,7 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm,
       if (PREDICT_FALSE (maximum_sessions_exceeded (sm, thread_index)))
        {
          b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_SESSIONS_EXCEEDED];
-         nat_log_notice ("maximum sessions exceeded");
+         nat_elog_notice ("maximum sessions exceeded");
          return 0;
        }
 
@@ -670,7 +694,7 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm,
                                  thread_index);
       if (!u)
        {
-         nat_log_warn ("create NAT user failed");
+         nat_elog_warn ("create NAT user failed");
          return 0;
        }
 
@@ -679,7 +703,7 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm,
       if (!s)
        {
          nat44_delete_user_with_no_session (sm, u, thread_index);
-         nat_log_warn ("create NAT session failed");
+         nat_elog_warn ("create NAT session failed");
          return 0;
        }
 
@@ -697,13 +721,13 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm,
       /* Add to lookup tables */
       s_kv.value = s - tsm->sessions;
       if (clib_bihash_add_del_16_8 (&tsm->out2in_ed, &s_kv, 1))
-       nat_log_notice ("out2in key add failed");
+       nat_elog_notice ("out2in key add failed");
 
       make_ed_kv (&s_kv, &ip->dst_address, &ip->src_address, ip->protocol,
                  m->fib_index, 0, 0);
       s_kv.value = s - tsm->sessions;
       if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &s_kv, 1))
-       nat_log_notice ("in2out key add failed");
+       nat_elog_notice ("in2out key add failed");
     }
 
   /* Update IP checksum */
@@ -914,8 +938,12 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
                              next0 = NAT44_ED_OUT2IN_NEXT_IN2OUT;
                              goto trace00;
                            }
-                         create_bypass_for_fwd (sm, ip0, rx_fib_index0,
-                                                thread_index);
+                         if (sm->num_workers > 1)
+                           create_bypass_for_fwd_worker (sm, ip0,
+                                                         rx_fib_index0);
+                         else
+                           create_bypass_for_fwd (sm, ip0, rx_fib_index0,
+                                                  thread_index);
                        }
                      goto trace00;
                    }
@@ -1148,8 +1176,12 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
                              next1 = NAT44_ED_OUT2IN_NEXT_IN2OUT;
                              goto trace01;
                            }
-                         create_bypass_for_fwd (sm, ip1, rx_fib_index1,
-                                                thread_index);
+                         if (sm->num_workers > 1)
+                           create_bypass_for_fwd_worker (sm, ip1,
+                                                         rx_fib_index1);
+                         else
+                           create_bypass_for_fwd (sm, ip1, rx_fib_index1,
+                                                  thread_index);
                        }
                      goto trace01;
                    }
@@ -1416,8 +1448,12 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
                              next0 = NAT44_ED_OUT2IN_NEXT_IN2OUT;
                              goto trace0;
                            }
-                         create_bypass_for_fwd (sm, ip0, rx_fib_index0,
-                                                thread_index);
+                         if (sm->num_workers > 1)
+                           create_bypass_for_fwd_worker (sm, ip0,
+                                                         rx_fib_index0);
+                         else
+                           create_bypass_for_fwd (sm, ip0, rx_fib_index0,
+                                                  thread_index);
                        }
                      goto trace0;
                    }
@@ -1697,7 +1733,7 @@ VLIB_NODE_FN (nat44_ed_out2in_reass_node) (vlib_main_t * vm,
            {
              next0 = NAT44_ED_OUT2IN_NEXT_DROP;
              b0->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_REASS];
-             nat_log_notice ("maximum reassemblies exceeded");
+             nat_elog_notice ("maximum reassemblies exceeded");
              goto trace0;
            }
 
@@ -1769,8 +1805,12 @@ VLIB_NODE_FN (nat44_ed_out2in_reass_node) (vlib_main_t * vm,
                              next0 = NAT44_ED_OUT2IN_NEXT_IN2OUT;
                              goto trace0;
                            }
-                         create_bypass_for_fwd (sm, ip0, rx_fib_index0,
-                                                thread_index);
+                         if (sm->num_workers > 1)
+                           create_bypass_for_fwd_worker (sm, ip0,
+                                                         rx_fib_index0);
+                         else
+                           create_bypass_for_fwd (sm, ip0, rx_fib_index0,
+                                                  thread_index);
                          reass0->flags |= NAT_REASS_FLAG_ED_DONT_TRANSLATE;
                          nat_ip4_reass_get_frags (reass0,
                                                   &fragments_to_loopback);
@@ -1825,7 +1865,7 @@ VLIB_NODE_FN (nat44_ed_out2in_reass_node) (vlib_main_t * vm,
                      (thread_index, reass0, bi0, &fragments_to_drop))
                    {
                      b0->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_FRAG];
-                     nat_log_notice
+                     nat_elog_notice
                        ("maximum fragments per reassembly exceeded");
                      next0 = NAT44_ED_OUT2IN_NEXT_DROP;
                      goto trace0;