cnat: flag to disable rsession
This adds a flag on the translation asking the VIP & input-feature nodes not to create the return session when translating / load-balancing an incoming flow. This is needed with maglev & DSR Type: feature Change-Id: I699012310ddc59f6ceeeb4878638eac6da5128dc Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
This commit is contained in:

committed by
Beno�t Ganne

parent
cad2111129
commit
6631032791
@ -27,6 +27,7 @@ import "vnet/interface_types.api";
|
|||||||
enum cnat_translation_flags:u8
|
enum cnat_translation_flags:u8
|
||||||
{
|
{
|
||||||
CNAT_TRANSLATION_ALLOC_PORT = 1,
|
CNAT_TRANSLATION_ALLOC_PORT = 1,
|
||||||
|
CNAT_TRANSLATION_NO_RETURN_SESSION = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum cnat_endpoint_tuple_flags:u8
|
enum cnat_endpoint_tuple_flags:u8
|
||||||
|
@ -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
|
* Session lookup : ``rv`` will be set to ``0`` if a session was found
|
||||||
* Translation primitives ``cnat_translation_ip4`` based on sessions
|
* Translation primitives ``cnat_translation_ip4`` based on sessions
|
||||||
* A session creation primitive ``cnat_session_create``
|
* 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),
|
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.
|
||||||
and call a NAT node back that will perform the translation.
|
|
||||||
|
|
||||||
Known limitations
|
Known limitations
|
||||||
_________________
|
_________________
|
||||||
|
|
||||||
This plugin is still under development, it lacks the following features :
|
This plugin is still under development, it lacks the following features :
|
||||||
* Load balancing doesn't support parametric probabilities
|
* 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
|
* Programmatic session handling (deletion, lifetime updates) aren't supported
|
||||||
* ICMP is not yet supported
|
* translations (i.e. rewriting the destination address) only match on the three
|
||||||
* Traffic matching is only done based on ``(proto, dst_addr, dst_port)`` source matching isn't supported
|
tuple ``(proto, dst_addr, dst_port)`` other matches are not supported
|
||||||
* Statistics & session tracking are still rudimentary.
|
* Statistics & session tracking are still rudimentary.
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
* rsession_location is the location the (return) session will be
|
||||||
* matched at
|
* matched at
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static_always_inline void
|
static_always_inline void
|
||||||
cnat_session_create (cnat_session_t *session, cnat_node_ctx_t *ctx,
|
cnat_session_create (cnat_session_t *session, cnat_node_ctx_t *ctx)
|
||||||
cnat_session_location_t rsession_location,
|
{
|
||||||
u8 rsession_flags)
|
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_client_t *cc;
|
||||||
cnat_bihash_kv_t rkey;
|
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;
|
int rv, n_retries = 0;
|
||||||
static u32 sport_seed = 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 */
|
/* First create the return session */
|
||||||
ip46_address_copy (&rsession->key.cs_ip[VLIB_RX],
|
ip46_address_copy (&rsession->key.cs_ip[VLIB_RX],
|
||||||
|
@ -143,7 +143,10 @@ cnat_input_feature_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
|
|||||||
|
|
||||||
/* refcnt session in current client */
|
/* refcnt session in current client */
|
||||||
cnat_client_cnt_session (cc);
|
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;
|
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;
|
CNAT_SESSION_FLAG_NO_CLIENT | CNAT_SESSION_FLAG_ALLOC_PORT;
|
||||||
|
|
||||||
trace_flags |= CNAT_TRACE_SESSION_CREATED;
|
trace_flags |= CNAT_TRACE_SESSION_CREATED;
|
||||||
cnat_session_create (session, ctx, CNAT_LOCATION_INPUT,
|
|
||||||
CNAT_SESSION_FLAG_NO_CLIENT |
|
cnat_session_create (session, ctx);
|
||||||
CNAT_SESSION_RETRY_SNAT);
|
cnat_rsession_create (session, ctx, CNAT_LOCATION_INPUT,
|
||||||
|
CNAT_SESSION_FLAG_NO_CLIENT |
|
||||||
|
CNAT_SESSION_RETRY_SNAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AF_IP4 == ctx->af)
|
if (AF_IP4 == ctx->af)
|
||||||
|
@ -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;
|
CNAT_SESSION_FLAG_NO_CLIENT | CNAT_SESSION_FLAG_ALLOC_PORT;
|
||||||
trace_flags |= CNAT_TRACE_SESSION_CREATED;
|
trace_flags |= CNAT_TRACE_SESSION_CREATED;
|
||||||
|
|
||||||
cnat_session_create (session, ctx, CNAT_LOCATION_FIB,
|
cnat_session_create (session, ctx);
|
||||||
CNAT_SESSION_FLAG_HAS_SNAT);
|
cnat_rsession_create (session, ctx, CNAT_LOCATION_FIB,
|
||||||
|
CNAT_SESSION_FLAG_HAS_SNAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AF_IP4 == ctx->af)
|
if (AF_IP4 == ctx->af)
|
||||||
|
@ -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 */
|
/* refcnt session in current client */
|
||||||
cnat_client_cnt_session (cc);
|
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;
|
trace_flags |= CNAT_TRACE_SESSION_CREATED;
|
||||||
|
|
||||||
next0 = ct->ct_lb.dpoi_next_node;
|
next0 = ct->ct_lb.dpoi_next_node;
|
||||||
|
@ -59,8 +59,8 @@ cnat_vip_default_source_policy (vlib_main_t * vm,
|
|||||||
u16 sport;
|
u16 sport;
|
||||||
sport = udp0->src_port;
|
sport = udp0->src_port;
|
||||||
/* Allocate a port only if asked and if we actually sNATed */
|
/* Allocate a port only if asked and if we actually sNATed */
|
||||||
if ((ct->flags & CNAT_TRANSLATION_FLAG_ALLOCATE_PORT)
|
if ((ct->flags & CNAT_TR_FLAG_ALLOCATE_PORT) &&
|
||||||
&& (*rsession_flags & CNAT_SESSION_FLAG_HAS_SNAT))
|
(*rsession_flags & CNAT_SESSION_FLAG_HAS_SNAT))
|
||||||
{
|
{
|
||||||
sport = 0; /* force allocation */
|
sport = 0; /* force allocation */
|
||||||
session->value.flags |= CNAT_SESSION_FLAG_ALLOC_PORT;
|
session->value.flags |= CNAT_SESSION_FLAG_ALLOC_PORT;
|
||||||
|
@ -233,7 +233,7 @@ cnat_translation_stack (cnat_translation_t * ct)
|
|||||||
|
|
||||||
dpo_set (&ct->ct_lb, DPO_LOAD_BALANCE, dproto, lbi);
|
dpo_set (&ct->ct_lb, DPO_LOAD_BALANCE, dproto, lbi);
|
||||||
dpo_stack (cnat_client_dpo, dproto, &ct->ct_lb, &ct->ct_lb);
|
dpo_stack (cnat_client_dpo, dproto, &ct->ct_lb, &ct->ct_lb);
|
||||||
ct->flags |= CNAT_TRANSLATION_STACKED;
|
ct->flags |= CNAT_TR_FLAG_STACKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -315,7 +315,7 @@ cnat_translation_update (cnat_endpoint_t *vip, ip_protocol_t proto,
|
|||||||
}
|
}
|
||||||
|
|
||||||
vec_reset_length (ct->ct_paths);
|
vec_reset_length (ct->ct_paths);
|
||||||
ct->flags &= ~CNAT_TRANSLATION_STACKED;
|
ct->flags &= ~CNAT_TR_FLAG_STACKED;
|
||||||
|
|
||||||
u64 path_idx = 0;
|
u64 path_idx = 0;
|
||||||
vec_foreach (path, paths)
|
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
|
/* If we have more than FIB_PATH_LIST_POPULAR paths
|
||||||
* we might get called during path tracking
|
* we might get called during path tracking
|
||||||
* (cnat_tracker_track) */
|
* (cnat_tracker_track) */
|
||||||
if (!(ct->flags & CNAT_TRANSLATION_STACKED))
|
if (!(ct->flags & CNAT_TR_FLAG_STACKED))
|
||||||
return (FIB_NODE_BACK_WALK_CONTINUE);
|
return (FIB_NODE_BACK_WALK_CONTINUE);
|
||||||
|
|
||||||
cnat_translation_stack (ct);
|
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;
|
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_tracker_track (ar->cti, trk);
|
||||||
|
|
||||||
cnat_translation_stack (ct);
|
cnat_translation_stack (ct);
|
||||||
ct->flags |= CNAT_TRANSLATION_STACKED;
|
ct->flags |= CNAT_TR_FLAG_STACKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -60,12 +60,14 @@ typedef struct cnat_ep_trk_t_
|
|||||||
typedef enum cnat_translation_flag_t_
|
typedef enum cnat_translation_flag_t_
|
||||||
{
|
{
|
||||||
/* Do allocate a source port */
|
/* Do allocate a source port */
|
||||||
CNAT_TRANSLATION_FLAG_ALLOCATE_PORT = (1 << 0),
|
CNAT_TR_FLAG_ALLOCATE_PORT = (1 << 0),
|
||||||
/* Has this translation been satcked ?
|
/* Has this translation been satcked ?
|
||||||
* this allow not being called twice when
|
* this allow not being called twice when
|
||||||
* with more then FIB_PATH_LIST_POPULAR backends */
|
* with more then FIB_PATH_LIST_POPULAR backends */
|
||||||
CNAT_TRANSLATION_STACKED = (1 << 1),
|
CNAT_TR_FLAG_STACKED = (1 << 1),
|
||||||
} cnat_translation_flag_t;
|
/* Do not create a return session */
|
||||||
|
CNAT_TR_FLAG_NO_RETURN_SESSION = (1 << 2),
|
||||||
|
} __clib_packed cnat_translation_flag_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@ -76,11 +78,11 @@ typedef enum
|
|||||||
CNAT_ADDR_N_RESOLUTIONS,
|
CNAT_ADDR_N_RESOLUTIONS,
|
||||||
} cnat_addr_resol_type_t;
|
} cnat_addr_resol_type_t;
|
||||||
|
|
||||||
typedef enum __attribute__ ((__packed__))
|
typedef enum
|
||||||
{
|
{
|
||||||
CNAT_LB_DEFAULT,
|
CNAT_LB_DEFAULT,
|
||||||
CNAT_LB_MAGLEV,
|
CNAT_LB_MAGLEV,
|
||||||
} cnat_lb_type_t;
|
} __clib_packed cnat_lb_type_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry used to account for a translation's backend
|
* Entry used to account for a translation's backend
|
||||||
@ -160,7 +162,7 @@ typedef struct cnat_translation_t_
|
|||||||
/**
|
/**
|
||||||
* Translation flags
|
* Translation flags
|
||||||
*/
|
*/
|
||||||
u8 flags;
|
cnat_translation_flag_t flags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type of load balancing
|
* Type of load balancing
|
||||||
|
@ -50,8 +50,10 @@
|
|||||||
* from fib_source.h */
|
* from fib_source.h */
|
||||||
#define CNAT_FIB_SOURCE_PRIORITY 0x02
|
#define CNAT_FIB_SOURCE_PRIORITY 0x02
|
||||||
|
|
||||||
/* Initial refcnt for timestamps (2 : session & rsession) */
|
/* Initial number of timestamps for a session
|
||||||
#define CNAT_TIMESTAMP_INIT_REFCNT 2
|
* 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)
|
#define MIN_SRC_PORT ((u16) 0xC000)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user