aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/cnat/cnat_types.h
diff options
context:
space:
mode:
authorNathan Skrzypczak <nathan.skrzypczak@gmail.com>2020-09-10 17:44:41 +0200
committerDave Barach <openvpp@barachs.net>2020-09-25 19:55:39 +0000
commit613b2c3c78fbec12cc87a0095ee5488252449698 (patch)
treeb85ba0853e4ad8127a1213242d2a42d85e256b85 /src/plugins/cnat/cnat_types.h
parentece39214bcb05c535ba5de9af97b5f84f6911cba (diff)
cnat: Add support for SNat ICMP
Type: feature snat supports : * echo request/reply by allocating an identifier when translating echo requests * icmp errors in the same manner as dnat Change-Id: I684e983b0181f95c5eace5a984d40084e5625fa4 Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
Diffstat (limited to 'src/plugins/cnat/cnat_types.h')
-rw-r--r--src/plugins/cnat/cnat_types.h81
1 files changed, 63 insertions, 18 deletions
diff --git a/src/plugins/cnat/cnat_types.h b/src/plugins/cnat/cnat_types.h
index ab59aaf2f37..c9c0b70b8c3 100644
--- a/src/plugins/cnat/cnat_types.h
+++ b/src/plugins/cnat/cnat_types.h
@@ -49,6 +49,15 @@
#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;
@@ -61,7 +70,11 @@ typedef struct cnat_endpoint_tuple_t_
cnat_endpoint_t src_ep;
} cnat_endpoint_tuple_t;
-
+typedef struct
+{
+ u16 identifier;
+ u16 sequence;
+} cnat_echo_header_t;
typedef struct
{
@@ -80,6 +93,15 @@ 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 */
@@ -113,11 +135,8 @@ typedef struct cnat_main_
/* Lock for the timestamp pool */
clib_rwlock_t ts_lock;
- /* Source ports bitmap for snat */
- clib_bitmap_t *src_ports;
-
- /* Lock for src_ports access */
- clib_spinlock_t src_ports_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;
@@ -265,33 +284,59 @@ cnat_timestamp_free (u32 index)
clib_rwlock_writer_unlock (&cnat_main.ts_lock);
}
-always_inline void
-cnat_free_port (u16 port)
+always_inline cnat_src_port_allocator_t *
+cnat_get_src_port_allocator (ip_protocol_t iproto)
{
cnat_main_t *cm = &cnat_main;
- clib_spinlock_lock (&cm->src_ports_lock);
- clib_bitmap_set_no_check (cm->src_ports, port, 0);
- clib_spinlock_unlock (&cm->src_ports_lock);
+ 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 (cnat_main_t * cm, u16 * port)
+cnat_allocate_port (u16 * port, ip_protocol_t iproto)
{
*port = clib_net_to_host_u16 (*port);
if (*port == 0)
*port = MIN_SRC_PORT;
- clib_spinlock_lock (&cm->src_ports_lock);
- if (clib_bitmap_get_no_check (cm->src_ports, *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 (cm->src_ports, *port);
+ *port = clib_bitmap_next_clear (ca->bmap, *port);
if (PREDICT_FALSE (*port >= UINT16_MAX))
- *port = clib_bitmap_next_clear (cm->src_ports, MIN_SRC_PORT);
+ *port = clib_bitmap_next_clear (ca->bmap, MIN_SRC_PORT);
if (PREDICT_FALSE (*port >= UINT16_MAX))
return -1;
}
- clib_bitmap_set_no_check (cm->src_ports, *port, 1);
+ clib_bitmap_set_no_check (ca->bmap, *port, 1);
*port = clib_host_to_net_u16 (*port);
- clib_spinlock_unlock (&cm->src_ports_lock);
+ clib_spinlock_unlock (&ca->lock);
return 0;
}