Use thread local storage for thread index
[vpp.git] / src / plugins / snat / snat.h
index 47f2e6e..f4e1c5c 100644 (file)
 #include <vppinfra/error.h>
 #include <vlibapi/api.h>
 
+
+#define SNAT_UDP_TIMEOUT 300
+#define SNAT_TCP_TRANSITORY_TIMEOUT 240
+#define SNAT_TCP_ESTABLISHED_TIMEOUT 7440
+
 /* Key */
 typedef struct {
   union 
@@ -43,6 +48,19 @@ typedef struct {
   };
 } snat_session_key_t;
 
+typedef struct {
+  union
+  {
+    struct
+    {
+      ip4_address_t ext_host_addr;
+      u16 ext_host_port;
+      u16 out_port;
+    };
+    u64 as_u64;
+  };
+} snat_det_out_key_t;
+
 typedef struct {
   union
   {
@@ -81,6 +99,22 @@ typedef enum {
 } snat_protocol_t;
 
 
+#define foreach_snat_session_state          \
+  _(0, UNKNOWN, "unknown")                 \
+  _(1, UDP_ACTIVE, "udp-active")           \
+  _(2, TCP_SYN_SENT, "tcp-syn-sent")       \
+  _(3, TCP_ESTABLISHED, "tcp-established") \
+  _(4, TCP_FIN_WAIT, "tcp-fin-wait")       \
+  _(5, TCP_CLOSE_WAIT, "tcp-close-wait")   \
+  _(6, TCP_LAST_ACK, "tcp-last-ack")
+
+typedef enum {
+#define _(v, N, s) SNAT_SESSION_##N = v,
+  foreach_snat_session_state
+#undef _
+} snat_session_state_t;
+
+
 #define SNAT_SESSION_FLAG_STATIC_MAPPING 1
 
 typedef CLIB_PACKED(struct {
@@ -118,6 +152,7 @@ typedef struct {
 
 typedef struct {
   ip4_address_t addr;
+  u32 fib_index;
 #define _(N, i, n, s) \
   u32 busy_##n##_ports; \
   uword * busy_##n##_port_bitmap;
@@ -125,6 +160,25 @@ typedef struct {
 #undef _
 } snat_address_t;
 
+typedef struct {
+  u16 in_port;
+  snat_det_out_key_t out;
+  u8 state;
+  u32 expire;
+} snat_det_session_t;
+
+typedef struct {
+  ip4_address_t in_addr;
+  u8 in_plen;
+  ip4_address_t out_addr;
+  u8 out_plen;
+  u32 sharing_ratio;
+  u16 ports_per_host;
+  u32 ses_num;
+  /* vector of sessions */
+  snat_det_session_t * sessions;
+} snat_det_map_t;
+
 typedef struct {
   ip4_address_t local_addr;
   ip4_address_t external_addr;
@@ -163,7 +217,20 @@ typedef struct {
   dlist_elt_t * list_pool;
 } snat_main_per_thread_data_t;
 
-typedef struct {
+struct snat_main_s;
+
+typedef u32 snat_icmp_match_function_t (struct snat_main_s *sm,
+                                        vlib_node_runtime_t *node,
+                                        u32 thread_index,
+                                        vlib_buffer_t *b0,
+                                        snat_session_key_t *p_key,
+                                        snat_session_key_t *p_value,
+                                        u8 *p_dont_translate,
+                                        void *d);
+
+typedef u32 (snat_get_worker_function_t) (ip4_header_t * ip, u32 rx_fib_index);
+
+typedef struct snat_main_s {
   /* Main lookup tables */
   clib_bihash_8_8_t out2in;
   clib_bihash_8_8_t in2out;
@@ -177,10 +244,15 @@ typedef struct {
   /* Translated packets worker lookup => IP address + port number */
   clib_bihash_8_8_t worker_by_out;
 
+  snat_icmp_match_function_t * icmp_match_in2out_cb;
+  snat_icmp_match_function_t * icmp_match_out2in_cb;
+
   u32 num_workers;
   u32 first_worker_index;
   u32 next_worker;
   u32 * workers;
+  snat_get_worker_function_t * worker_in2out_cb;
+  snat_get_worker_function_t * worker_out2in_cb;
 
   /* Per thread data */
   snat_main_per_thread_data_t * per_thread_data;
@@ -213,9 +285,17 @@ typedef struct {
   u32 fq_in2out_index;
   u32 fq_out2in_index;
 
+  /* in2out and out2in node index */
+  u32 in2out_node_index;
+  u32 out2in_node_index;
+
+  /* Deterministic NAT */
+  snat_det_map_t * det_maps;
+
   /* Config parameters */
   u8 static_mapping_only;
   u8 static_mapping_connection_tracking;
+  u8 deterministic;
   u32 translation_buckets;
   u32 translation_memory_size;
   u32 user_buckets;
@@ -226,6 +306,9 @@ typedef struct {
   u32 inside_vrf_id;
   u32 inside_fib_index;
 
+  /* tenant VRF aware address pool activation flag */
+  u8 vrf_mode;
+
   /* API message ID base */
   u16 msg_id_base;
 
@@ -244,12 +327,15 @@ extern vlib_node_registration_t snat_in2out_fast_node;
 extern vlib_node_registration_t snat_out2in_fast_node;
 extern vlib_node_registration_t snat_in2out_worker_handoff_node;
 extern vlib_node_registration_t snat_out2in_worker_handoff_node;
+extern vlib_node_registration_t snat_det_in2out_node;
+extern vlib_node_registration_t snat_det_out2in_node;
 
 void snat_free_outside_address_and_port (snat_main_t * sm, 
                                          snat_session_key_t * k, 
                                          u32 address_index);
 
 int snat_alloc_outside_address_and_port (snat_main_t * sm, 
+                                         u32 fib_index,
                                          snat_session_key_t * k,
                                          u32 * address_indexp);
 
@@ -258,6 +344,11 @@ int snat_static_mapping_match (snat_main_t * sm,
                                snat_session_key_t * mapping,
                                u8 by_external);
 
+void snat_add_del_addr_to_fib (ip4_address_t * addr,
+                               u8 p_len,
+                               u32 sw_if_index,
+                               int is_add);
+
 format_function_t format_snat_user;
 
 typedef struct {
@@ -306,4 +397,45 @@ snat_proto_to_ip_proto (snat_protocol_t snat_proto)
   return ip_proto;
 }
 
+typedef struct {
+  u16 src_port, dst_port;
+} tcp_udp_header_t;
+
+u32 icmp_match_in2out_fast(snat_main_t *sm, vlib_node_runtime_t *node,
+                           u32 thread_index, vlib_buffer_t *b0,
+                           snat_session_key_t *p_key,
+                           snat_session_key_t *p_value,
+                           u8 *p_dont_translate, void *d);
+u32 icmp_match_in2out_slow(snat_main_t *sm, vlib_node_runtime_t *node,
+                           u32 thread_index, vlib_buffer_t *b0,
+                           snat_session_key_t *p_key,
+                           snat_session_key_t *p_value,
+                           u8 *p_dont_translate, void *d);
+u32 icmp_match_out2in_fast(snat_main_t *sm, vlib_node_runtime_t *node,
+                           u32 thread_index, vlib_buffer_t *b0,
+                           snat_session_key_t *p_key,
+                           snat_session_key_t *p_value,
+                           u8 *p_dont_translate, void *d);
+u32 icmp_match_out2in_slow(snat_main_t *sm, vlib_node_runtime_t *node,
+                           u32 thread_index, vlib_buffer_t *b0,
+                           snat_session_key_t *p_key,
+                           snat_session_key_t *p_value,
+                           u8 *p_dont_translate, void *d);
+
+static_always_inline u8
+icmp_is_error_message (icmp46_header_t * icmp)
+{
+  switch(icmp->type)
+    {
+    case ICMP4_destination_unreachable:
+    case ICMP4_time_exceeded:
+    case ICMP4_parameter_problem:
+    case ICMP4_source_quench:
+    case ICMP4_redirect:
+    case ICMP4_alternate_host_address:
+      return 1;
+    }
+  return 0;
+}
+
 #endif /* __included_snat_h__ */