cnat: Introduce parametric source policy
Type: feature Change-Id: I60ae9dd1c100b587d1902a20596b99a5c8a95df7 Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
This commit is contained in:
committed by
Dave Barach
parent
613b2c3c78
commit
ce25b60de5
@@ -49,15 +49,6 @@
|
||||
|
||||
#define MIN_SRC_PORT ((u16) 0xC000)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CNAT_SPORT_PROTO_TCP,
|
||||
CNAT_SPORT_PROTO_UDP,
|
||||
CNAT_SPORT_PROTO_ICMP,
|
||||
CNAT_SPORT_PROTO_ICMP6,
|
||||
CNAT_N_SPORT_PROTO
|
||||
} cnat_sport_proto_t;
|
||||
|
||||
typedef struct cnat_endpoint_t_
|
||||
{
|
||||
ip_address_t ce_ip;
|
||||
@@ -93,15 +84,6 @@ typedef struct
|
||||
ip6_address_t ip_masks[129];
|
||||
} cnat_snat_pfx_table_t;
|
||||
|
||||
typedef struct cnat_src_port_allocator_
|
||||
{
|
||||
/* Source ports bitmap for snat */
|
||||
clib_bitmap_t *bmap;
|
||||
|
||||
/* Lock for src_ports access */
|
||||
clib_spinlock_t lock;
|
||||
} cnat_src_port_allocator_t;
|
||||
|
||||
typedef struct cnat_main_
|
||||
{
|
||||
/* Memory size of the session bihash */
|
||||
@@ -135,9 +117,6 @@ typedef struct cnat_main_
|
||||
/* Lock for the timestamp pool */
|
||||
clib_rwlock_t ts_lock;
|
||||
|
||||
/* Per proto source ports allocator for snat */
|
||||
cnat_src_port_allocator_t *src_ports;
|
||||
|
||||
/* Ip4 Address to use for source NATing */
|
||||
ip4_address_t snat_ip4;
|
||||
|
||||
@@ -167,7 +146,7 @@ typedef struct cnat_timestamp_t_
|
||||
u16 refcnt;
|
||||
} cnat_timestamp_t;
|
||||
|
||||
typedef struct cnat_node_ctx_t_
|
||||
typedef struct cnat_node_ctx_
|
||||
{
|
||||
f64 now;
|
||||
u64 seed;
|
||||
@@ -176,6 +155,7 @@ typedef struct cnat_node_ctx_t_
|
||||
u8 do_trace;
|
||||
} cnat_node_ctx_t;
|
||||
|
||||
cnat_main_t *cnat_get_main ();
|
||||
extern u8 *format_cnat_endpoint (u8 * s, va_list * args);
|
||||
extern uword unformat_cnat_ep_tuple (unformat_input_t * input,
|
||||
va_list * args);
|
||||
@@ -212,134 +192,6 @@ extern void cnat_lazy_init ();
|
||||
*/
|
||||
extern void cnat_enable_disable_scanner (cnat_scanner_cmd_t event_type);
|
||||
|
||||
/*
|
||||
Dataplane functions
|
||||
*/
|
||||
|
||||
always_inline u32
|
||||
cnat_timestamp_new (f64 t)
|
||||
{
|
||||
u32 index;
|
||||
cnat_timestamp_t *ts;
|
||||
clib_rwlock_writer_lock (&cnat_main.ts_lock);
|
||||
pool_get (cnat_timestamps, ts);
|
||||
ts->last_seen = t;
|
||||
ts->lifetime = cnat_main.session_max_age;
|
||||
ts->refcnt = CNAT_TIMESTAMP_INIT_REFCNT;
|
||||
index = ts - cnat_timestamps;
|
||||
clib_rwlock_writer_unlock (&cnat_main.ts_lock);
|
||||
return index;
|
||||
}
|
||||
|
||||
always_inline void
|
||||
cnat_timestamp_inc_refcnt (u32 index)
|
||||
{
|
||||
clib_rwlock_reader_lock (&cnat_main.ts_lock);
|
||||
cnat_timestamp_t *ts = pool_elt_at_index (cnat_timestamps, index);
|
||||
ts->refcnt++;
|
||||
clib_rwlock_reader_unlock (&cnat_main.ts_lock);
|
||||
}
|
||||
|
||||
always_inline void
|
||||
cnat_timestamp_update (u32 index, f64 t)
|
||||
{
|
||||
clib_rwlock_reader_lock (&cnat_main.ts_lock);
|
||||
cnat_timestamp_t *ts = pool_elt_at_index (cnat_timestamps, index);
|
||||
ts->last_seen = t;
|
||||
clib_rwlock_reader_unlock (&cnat_main.ts_lock);
|
||||
}
|
||||
|
||||
always_inline void
|
||||
cnat_timestamp_set_lifetime (u32 index, u16 lifetime)
|
||||
{
|
||||
clib_rwlock_reader_lock (&cnat_main.ts_lock);
|
||||
cnat_timestamp_t *ts = pool_elt_at_index (cnat_timestamps, index);
|
||||
ts->lifetime = lifetime;
|
||||
clib_rwlock_reader_unlock (&cnat_main.ts_lock);
|
||||
}
|
||||
|
||||
always_inline f64
|
||||
cnat_timestamp_exp (u32 index)
|
||||
{
|
||||
f64 t;
|
||||
if (INDEX_INVALID == index)
|
||||
return -1;
|
||||
clib_rwlock_reader_lock (&cnat_main.ts_lock);
|
||||
cnat_timestamp_t *ts = pool_elt_at_index (cnat_timestamps, index);
|
||||
t = ts->last_seen + (f64) ts->lifetime;
|
||||
clib_rwlock_reader_unlock (&cnat_main.ts_lock);
|
||||
return t;
|
||||
}
|
||||
|
||||
always_inline void
|
||||
cnat_timestamp_free (u32 index)
|
||||
{
|
||||
if (INDEX_INVALID == index)
|
||||
return;
|
||||
clib_rwlock_writer_lock (&cnat_main.ts_lock);
|
||||
cnat_timestamp_t *ts = pool_elt_at_index (cnat_timestamps, index);
|
||||
ts->refcnt--;
|
||||
if (0 == ts->refcnt)
|
||||
pool_put (cnat_timestamps, ts);
|
||||
clib_rwlock_writer_unlock (&cnat_main.ts_lock);
|
||||
}
|
||||
|
||||
always_inline cnat_src_port_allocator_t *
|
||||
cnat_get_src_port_allocator (ip_protocol_t iproto)
|
||||
{
|
||||
cnat_main_t *cm = &cnat_main;
|
||||
switch (iproto)
|
||||
{
|
||||
case IP_PROTOCOL_TCP:
|
||||
return &cm->src_ports[CNAT_SPORT_PROTO_TCP];
|
||||
case IP_PROTOCOL_UDP:
|
||||
return &cm->src_ports[CNAT_SPORT_PROTO_UDP];
|
||||
case IP_PROTOCOL_ICMP:
|
||||
return &cm->src_ports[CNAT_SPORT_PROTO_ICMP];
|
||||
case IP_PROTOCOL_ICMP6:
|
||||
return &cm->src_ports[CNAT_SPORT_PROTO_ICMP6];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
always_inline void
|
||||
cnat_free_port (u16 port, ip_protocol_t iproto)
|
||||
{
|
||||
cnat_src_port_allocator_t *ca;
|
||||
ca = cnat_get_src_port_allocator (iproto);
|
||||
if (!ca)
|
||||
return;
|
||||
clib_spinlock_lock (&ca->lock);
|
||||
clib_bitmap_set_no_check (ca->bmap, port, 0);
|
||||
clib_spinlock_unlock (&ca->lock);
|
||||
}
|
||||
|
||||
always_inline int
|
||||
cnat_allocate_port (u16 * port, ip_protocol_t iproto)
|
||||
{
|
||||
*port = clib_net_to_host_u16 (*port);
|
||||
if (*port == 0)
|
||||
*port = MIN_SRC_PORT;
|
||||
cnat_src_port_allocator_t *ca;
|
||||
ca = cnat_get_src_port_allocator (iproto);
|
||||
if (!ca)
|
||||
return -1;
|
||||
clib_spinlock_lock (&ca->lock);
|
||||
if (clib_bitmap_get_no_check (ca->bmap, *port))
|
||||
{
|
||||
*port = clib_bitmap_next_clear (ca->bmap, *port);
|
||||
if (PREDICT_FALSE (*port >= UINT16_MAX))
|
||||
*port = clib_bitmap_next_clear (ca->bmap, MIN_SRC_PORT);
|
||||
if (PREDICT_FALSE (*port >= UINT16_MAX))
|
||||
return -1;
|
||||
}
|
||||
clib_bitmap_set_no_check (ca->bmap, *port, 1);
|
||||
*port = clib_host_to_net_u16 (*port);
|
||||
clib_spinlock_unlock (&ca->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user