summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/cnat/cnat.api1
-rw-r--r--src/plugins/cnat/cnat.rst10
-rw-r--r--src/plugins/cnat/cnat_node.h18
-rw-r--r--src/plugins/cnat/cnat_node_feature.c13
-rw-r--r--src/plugins/cnat/cnat_node_snat.c5
-rw-r--r--src/plugins/cnat/cnat_node_vip.c4
-rw-r--r--src/plugins/cnat/cnat_src_policy.c4
-rw-r--r--src/plugins/cnat/cnat_translation.c10
-rw-r--r--src/plugins/cnat/cnat_translation.h14
-rw-r--r--src/plugins/cnat/cnat_types.h6
10 files changed, 54 insertions, 31 deletions
diff --git a/src/plugins/cnat/cnat.api b/src/plugins/cnat/cnat.api
index e253084e74e..846917eb2e7 100644
--- a/src/plugins/cnat/cnat.api
+++ b/src/plugins/cnat/cnat.api
@@ -27,6 +27,7 @@ import "vnet/interface_types.api";
enum cnat_translation_flags:u8
{
CNAT_TRANSLATION_ALLOC_PORT = 1,
+ CNAT_TRANSLATION_NO_RETURN_SESSION = 4,
};
enum cnat_endpoint_tuple_flags:u8
diff --git a/src/plugins/cnat/cnat.rst b/src/plugins/cnat/cnat.rst
index a177bc10aa2..b0426f35373 100644
--- a/src/plugins/cnat/cnat.rst
+++ b/src/plugins/cnat/cnat.rst
@@ -134,19 +134,19 @@ This plugin is built to be extensible. For now two NAT types are defined, ``cnat
* Session lookup : ``rv`` will be set to ``0`` if a session was found
* Translation primitives ``cnat_translation_ip4`` based on sessions
* A session creation primitive ``cnat_session_create``
+* A reverse session creation primitive ``cnat_rsession_create``
-Creating a session will also create a reverse session (for matching return traffic),
-and call a NAT node back that will perform the translation.
+Creating a session will also create reverse session matching return traffic unless told otherwise by setting ``CNAT_TR_FLAG_NO_RETURN_SESSION`` on the translation. This will call the NAT nodes on the return flow and perform the inverse translation.
Known limitations
_________________
This plugin is still under development, it lacks the following features :
* Load balancing doesn't support parametric probabilities
-* VRFs aren't supported. All rules apply to fib table 0 only
+* VRFs are not supported, all rules apply regardless of the FIB table.
* Programmatic session handling (deletion, lifetime updates) aren't supported
-* ICMP is not yet supported
-* Traffic matching is only done based on ``(proto, dst_addr, dst_port)`` source matching isn't supported
+* translations (i.e. rewriting the destination address) only match on the three
+tuple ``(proto, dst_addr, dst_port)`` other matches are not supported
* Statistics & session tracking are still rudimentary.
diff --git a/src/plugins/cnat/cnat_node.h b/src/plugins/cnat/cnat_node.h
index 75c1b4ac3ab..d81f6745bc4 100644
--- a/src/plugins/cnat/cnat_node.h
+++ b/src/plugins/cnat/cnat_node.h
@@ -819,10 +819,20 @@ cnat_load_balance (const cnat_translation_t *ct, ip_address_family_t af,
* rsession_location is the location the (return) session will be
* matched at
*/
+
static_always_inline void
-cnat_session_create (cnat_session_t *session, cnat_node_ctx_t *ctx,
- cnat_session_location_t rsession_location,
- u8 rsession_flags)
+cnat_session_create (cnat_session_t *session, cnat_node_ctx_t *ctx)
+{
+ cnat_bihash_kv_t *bkey = (cnat_bihash_kv_t *) session;
+
+ session->value.cs_ts_index = cnat_timestamp_new (ctx->now);
+ cnat_bihash_add_del (&cnat_session_db, bkey, 1);
+}
+
+static_always_inline void
+cnat_rsession_create (cnat_session_t *session, cnat_node_ctx_t *ctx,
+ cnat_session_location_t rsession_location,
+ cnat_session_flag_t rsession_flags)
{
cnat_client_t *cc;
cnat_bihash_kv_t rkey;
@@ -831,7 +841,7 @@ cnat_session_create (cnat_session_t *session, cnat_node_ctx_t *ctx,
int rv, n_retries = 0;
static u32 sport_seed = 0;
- session->value.cs_ts_index = cnat_timestamp_new (ctx->now);
+ cnat_timestamp_inc_refcnt (session->value.cs_ts_index);
/* First create the return session */
ip46_address_copy (&rsession->key.cs_ip[VLIB_RX],
diff --git a/src/plugins/cnat/cnat_node_feature.c b/src/plugins/cnat/cnat_node_feature.c
index 2ab5cb232b4..9b2c0c2fe06 100644
--- a/src/plugins/cnat/cnat_node_feature.c
+++ b/src/plugins/cnat/cnat_node_feature.c
@@ -143,7 +143,10 @@ cnat_input_feature_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
/* refcnt session in current client */
cnat_client_cnt_session (cc);
- cnat_session_create (session, ctx, CNAT_LOCATION_OUTPUT, rsession_flags);
+ cnat_session_create (session, ctx);
+ if (!(ct->flags & CNAT_TR_FLAG_NO_RETURN_SESSION))
+ cnat_rsession_create (session, ctx, CNAT_LOCATION_OUTPUT,
+ rsession_flags);
trace_flags |= CNAT_TRACE_SESSION_CREATED;
}
@@ -320,9 +323,11 @@ cnat_output_feature_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
CNAT_SESSION_FLAG_NO_CLIENT | CNAT_SESSION_FLAG_ALLOC_PORT;
trace_flags |= CNAT_TRACE_SESSION_CREATED;
- cnat_session_create (session, ctx, CNAT_LOCATION_INPUT,
- CNAT_SESSION_FLAG_NO_CLIENT |
- CNAT_SESSION_RETRY_SNAT);
+
+ cnat_session_create (session, ctx);
+ cnat_rsession_create (session, ctx, CNAT_LOCATION_INPUT,
+ CNAT_SESSION_FLAG_NO_CLIENT |
+ CNAT_SESSION_RETRY_SNAT);
}
if (AF_IP4 == ctx->af)
diff --git a/src/plugins/cnat/cnat_node_snat.c b/src/plugins/cnat/cnat_node_snat.c
index f5c8a20121c..57530eb397d 100644
--- a/src/plugins/cnat/cnat_node_snat.c
+++ b/src/plugins/cnat/cnat_node_snat.c
@@ -129,8 +129,9 @@ cnat_snat_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
CNAT_SESSION_FLAG_NO_CLIENT | CNAT_SESSION_FLAG_ALLOC_PORT;
trace_flags |= CNAT_TRACE_SESSION_CREATED;
- cnat_session_create (session, ctx, CNAT_LOCATION_FIB,
- CNAT_SESSION_FLAG_HAS_SNAT);
+ cnat_session_create (session, ctx);
+ cnat_rsession_create (session, ctx, CNAT_LOCATION_FIB,
+ CNAT_SESSION_FLAG_HAS_SNAT);
}
if (AF_IP4 == ctx->af)
diff --git a/src/plugins/cnat/cnat_node_vip.c b/src/plugins/cnat/cnat_node_vip.c
index 5db19d2c61e..d320746c5fa 100644
--- a/src/plugins/cnat/cnat_node_vip.c
+++ b/src/plugins/cnat/cnat_node_vip.c
@@ -168,7 +168,9 @@ cnat_vip_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t *b,
/* refcnt session in current client */
cnat_client_cnt_session (cc);
- cnat_session_create (session, ctx, CNAT_LOCATION_FIB, rsession_flags);
+ cnat_session_create (session, ctx);
+ if (!(ct->flags & CNAT_TR_FLAG_NO_RETURN_SESSION))
+ cnat_rsession_create (session, ctx, CNAT_LOCATION_FIB, rsession_flags);
trace_flags |= CNAT_TRACE_SESSION_CREATED;
next0 = ct->ct_lb.dpoi_next_node;
diff --git a/src/plugins/cnat/cnat_src_policy.c b/src/plugins/cnat/cnat_src_policy.c
index cac24b7742c..8f3f3375148 100644
--- a/src/plugins/cnat/cnat_src_policy.c
+++ b/src/plugins/cnat/cnat_src_policy.c
@@ -59,8 +59,8 @@ cnat_vip_default_source_policy (vlib_main_t * vm,
u16 sport;
sport = udp0->src_port;
/* Allocate a port only if asked and if we actually sNATed */
- if ((ct->flags & CNAT_TRANSLATION_FLAG_ALLOCATE_PORT)
- && (*rsession_flags & CNAT_SESSION_FLAG_HAS_SNAT))
+ if ((ct->flags & CNAT_TR_FLAG_ALLOCATE_PORT) &&
+ (*rsession_flags & CNAT_SESSION_FLAG_HAS_SNAT))
{
sport = 0; /* force allocation */
session->value.flags |= CNAT_SESSION_FLAG_ALLOC_PORT;
diff --git a/src/plugins/cnat/cnat_translation.c b/src/plugins/cnat/cnat_translation.c
index ee3dc780fea..4645c50c3c2 100644
--- a/src/plugins/cnat/cnat_translation.c
+++ b/src/plugins/cnat/cnat_translation.c
@@ -233,7 +233,7 @@ cnat_translation_stack (cnat_translation_t * ct)
dpo_set (&ct->ct_lb, DPO_LOAD_BALANCE, dproto, lbi);
dpo_stack (cnat_client_dpo, dproto, &ct->ct_lb, &ct->ct_lb);
- ct->flags |= CNAT_TRANSLATION_STACKED;
+ ct->flags |= CNAT_TR_FLAG_STACKED;
}
int
@@ -315,7 +315,7 @@ cnat_translation_update (cnat_endpoint_t *vip, ip_protocol_t proto,
}
vec_reset_length (ct->ct_paths);
- ct->flags &= ~CNAT_TRANSLATION_STACKED;
+ ct->flags &= ~CNAT_TR_FLAG_STACKED;
u64 path_idx = 0;
vec_foreach (path, paths)
@@ -513,7 +513,7 @@ cnat_translation_back_walk_notify (fib_node_t * node,
/* If we have more than FIB_PATH_LIST_POPULAR paths
* we might get called during path tracking
* (cnat_tracker_track) */
- if (!(ct->flags & CNAT_TRANSLATION_STACKED))
+ if (!(ct->flags & CNAT_TR_FLAG_STACKED))
return (FIB_NODE_BACK_WALK_CONTINUE);
cnat_translation_stack (ct);
@@ -662,11 +662,11 @@ cnat_if_addr_add_del_backend_cb (addr_resolution_t * ar,
ep->ce_flags |= CNAT_EP_FLAG_RESOLVED;
}
- ct->flags &= ~CNAT_TRANSLATION_STACKED;
+ ct->flags &= ~CNAT_TR_FLAG_STACKED;
cnat_tracker_track (ar->cti, trk);
cnat_translation_stack (ct);
- ct->flags |= CNAT_TRANSLATION_STACKED;
+ ct->flags |= CNAT_TR_FLAG_STACKED;
}
static void
diff --git a/src/plugins/cnat/cnat_translation.h b/src/plugins/cnat/cnat_translation.h
index 97b0c908b42..d5923f04397 100644
--- a/src/plugins/cnat/cnat_translation.h
+++ b/src/plugins/cnat/cnat_translation.h
@@ -60,12 +60,14 @@ typedef struct cnat_ep_trk_t_
typedef enum cnat_translation_flag_t_
{
/* Do allocate a source port */
- CNAT_TRANSLATION_FLAG_ALLOCATE_PORT = (1 << 0),
+ CNAT_TR_FLAG_ALLOCATE_PORT = (1 << 0),
/* Has this translation been satcked ?
* this allow not being called twice when
* with more then FIB_PATH_LIST_POPULAR backends */
- CNAT_TRANSLATION_STACKED = (1 << 1),
-} cnat_translation_flag_t;
+ CNAT_TR_FLAG_STACKED = (1 << 1),
+ /* Do not create a return session */
+ CNAT_TR_FLAG_NO_RETURN_SESSION = (1 << 2),
+} __clib_packed cnat_translation_flag_t;
typedef enum
{
@@ -76,11 +78,11 @@ typedef enum
CNAT_ADDR_N_RESOLUTIONS,
} cnat_addr_resol_type_t;
-typedef enum __attribute__ ((__packed__))
+typedef enum
{
CNAT_LB_DEFAULT,
CNAT_LB_MAGLEV,
-} cnat_lb_type_t;
+} __clib_packed cnat_lb_type_t;
/**
* Entry used to account for a translation's backend
@@ -160,7 +162,7 @@ typedef struct cnat_translation_t_
/**
* Translation flags
*/
- u8 flags;
+ cnat_translation_flag_t flags;
/**
* Type of load balancing
diff --git a/src/plugins/cnat/cnat_types.h b/src/plugins/cnat/cnat_types.h
index bf2726fa63a..84fb7d0b3c3 100644
--- a/src/plugins/cnat/cnat_types.h
+++ b/src/plugins/cnat/cnat_types.h
@@ -50,8 +50,10 @@
* from fib_source.h */
#define CNAT_FIB_SOURCE_PRIORITY 0x02
-/* Initial refcnt for timestamps (2 : session & rsession) */
-#define CNAT_TIMESTAMP_INIT_REFCNT 2
+/* Initial number of timestamps for a session
+ * this will be incremented when adding the reverse
+ * session in cnat_rsession_create */
+#define CNAT_TIMESTAMP_INIT_REFCNT 1
#define MIN_SRC_PORT ((u16) 0xC000)