hsa: detach fifo segments in echo app
[vpp.git] / src / plugins / cnat / cnat_node_snat.c
index aaa9e16..8166df6 100644 (file)
@@ -16,6 +16,8 @@
 #include <vlibmemory/api.h>
 #include <cnat/cnat_node.h>
 #include <cnat/cnat_snat.h>
+#include <cnat/cnat_inline.h>
+#include <cnat/cnat_src_policy.h>
 
 typedef enum cnat_snat_next_
 {
@@ -25,8 +27,9 @@ typedef enum cnat_snat_next_
 
 typedef struct cnat_snat_trace_
 {
-  u32 found;
   cnat_session_t session;
+  u32 found_session;
+  u32 created_session;
 } cnat_snat_trace_t;
 
 vlib_node_registration_t cnat_snat_ip4_node;
@@ -39,8 +42,11 @@ format_cnat_snat_trace (u8 * s, va_list * args)
   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
   cnat_snat_trace_t *t = va_arg (*args, cnat_snat_trace_t *);
 
-  if (t->found)
+  if (t->found_session)
     s = format (s, "found: %U", format_cnat_session, &t->session, 1);
+  else if (t->created_session)
+    s = format (s, "created: %U\n  tr: %U",
+               format_cnat_session, &t->session, 1);
   else
     s = format (s, "not found");
   return s;
@@ -49,16 +55,17 @@ format_cnat_snat_trace (u8 * s, va_list * args)
 /* CNat sub for source NAT as a feature arc on ip[46]-unicast
    This node's sub shouldn't apply to the same flows as
    cnat_vip_inline */
-always_inline uword
-cnat_snat_inline (vlib_main_t * vm,
-                 vlib_node_runtime_t * node,
-                 vlib_buffer_t * b,
-                 cnat_node_ctx_t * ctx, int rv, cnat_session_t * session)
+static uword
+cnat_snat_node_fn (vlib_main_t * vm,
+                  vlib_node_runtime_t * node,
+                  vlib_buffer_t * b,
+                  cnat_node_ctx_t * ctx, int rv, cnat_session_t * session)
 {
   cnat_main_t *cm = &cnat_main;
-  ip4_header_t *ip4;
+  int created_session = 0;
+  ip4_header_t *ip4 = NULL;
   ip_protocol_t iproto;
-  ip6_header_t *ip6;
+  ip6_header_t *ip6 = NULL;
   udp_header_t *udp0;
   u32 arc_next0;
   u16 next0;
@@ -114,22 +121,21 @@ cnat_snat_inline (vlib_main_t * vm,
       if (AF_IP4 == ctx->af)
        {
          ip46_address_set_ip4 (&session->value.cs_ip[VLIB_RX],
-                               &cm->snat_ip4);
+                               &ip_addr_v4 (&cm->snat_ip4.ce_ip));
          ip46_address_set_ip4 (&session->value.cs_ip[VLIB_TX],
                                &ip4->dst_address);
        }
       else
        {
          ip46_address_set_ip6 (&session->value.cs_ip[VLIB_RX],
-                               &cm->snat_ip6);
+                               &ip_addr_v6 (&cm->snat_ip6.ce_ip));
          ip46_address_set_ip6 (&session->value.cs_ip[VLIB_TX],
                                &ip6->dst_address);
        }
 
-      /* Port allocation, first try to use the original port, allocate one
-         if it is already used */
-      sport = udp0->src_port;
-      rv = cnat_allocate_port (cm, &sport);
+
+      sport = 0;
+      rv = cnat_allocate_port (&sport, iproto);
       if (rv)
        {
          vlib_node_increment_counter (vm, cnat_snat_ip4_node.index,
@@ -137,13 +143,16 @@ cnat_snat_inline (vlib_main_t * vm,
          next0 = CNAT_SNAT_NEXT_DROP;
          goto trace;
        }
-
       session->value.cs_port[VLIB_RX] = sport;
-      session->value.cs_port[VLIB_TX] = udp0->dst_port;
+      session->value.cs_port[VLIB_TX] = sport;
+      if (iproto == IP_PROTOCOL_TCP || iproto == IP_PROTOCOL_UDP)
+       session->value.cs_port[VLIB_TX] = udp0->dst_port;
+
       session->value.cs_lbi = INDEX_INVALID;
       session->value.flags =
        CNAT_SESSION_FLAG_NO_CLIENT | CNAT_SESSION_FLAG_ALLOC_PORT;
 
+      created_session = 1;
       cnat_session_create (session, ctx, CNAT_SESSION_FLAG_HAS_SNAT);
     }
 
@@ -160,7 +169,9 @@ trace:
 
       t = vlib_add_trace (vm, node, b, sizeof (*t));
 
-      if (NULL != session)
+      t->found_session = !rv;
+      t->created_session = created_session;
+      if (t->found_session || t->created_session)
        clib_memcpy (&t->session, session, sizeof (t->session));
     }
   return next0;
@@ -171,9 +182,9 @@ VLIB_NODE_FN (cnat_snat_ip4_node) (vlib_main_t * vm,
                                   vlib_frame_t * frame)
 {
   if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
-    return cnat_node_inline (vm, node, frame, cnat_snat_inline, AF_IP4,
+    return cnat_node_inline (vm, node, frame, cnat_snat_node_fn, AF_IP4,
                             1 /* do_trace */ );
-  return cnat_node_inline (vm, node, frame, cnat_snat_inline, AF_IP4,
+  return cnat_node_inline (vm, node, frame, cnat_snat_node_fn, AF_IP4,
                           0 /* do_trace */ );
 }
 
@@ -182,9 +193,9 @@ VLIB_NODE_FN (cnat_snat_ip6_node) (vlib_main_t * vm,
                                   vlib_frame_t * frame)
 {
   if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
-    return cnat_node_inline (vm, node, frame, cnat_snat_inline, AF_IP6,
+    return cnat_node_inline (vm, node, frame, cnat_snat_node_fn, AF_IP6,
                             1 /* do_trace */ );
-  return cnat_node_inline (vm, node, frame, cnat_snat_inline, AF_IP6,
+  return cnat_node_inline (vm, node, frame, cnat_snat_node_fn, AF_IP6,
                           0 /* do_trace */ );
 }
 
@@ -218,16 +229,20 @@ VLIB_REGISTER_NODE (cnat_snat_ip6_node) =
     [CNAT_SNAT_NEXT_DROP] = "ip6-drop",
   }
 };
-/* *INDENT-ON* */
-
 
 VNET_FEATURE_INIT (cnat_snat_ip4_node, static) =
 {
-.arc_name = "ip4-unicast",.node_name = "ip4-cnat-snat",};
+  .arc_name = "ip4-unicast",
+  .node_name = "ip4-cnat-snat",
+};
 
 VNET_FEATURE_INIT (cnat_snat_ip6_node, static) =
 {
-.arc_name = "ip6-unicast",.node_name = "ip6-cnat-snat",};
+  .arc_name = "ip6-unicast",
+  .node_name = "ip6-cnat-snat",
+};
+
+/* *INDENT-ON* */
 
 /*
  * fd.io coding-style-patch-verification: ON