cnat: Add sctp support
This patch adds SCTP support in the CNat translation primitives. It also exposes a clib_crc32c_with_init function allowing to set the init value to start the crc32 with instead of 0. Type: feature Change-Id: I86add4cfcac08f2a5a34d1e1841122fafd349fe7 Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
This commit is contained in:
committed by
Beno�t Ganne
parent
2a6f35f24c
commit
f284c14c7b
@@ -225,6 +225,29 @@ cnat_ip4_translate_l4 (ip4_header_t * ip4, udp_header_t * udp,
|
||||
}
|
||||
}
|
||||
|
||||
static_always_inline void
|
||||
cnat_ip4_translate_sctp (ip4_header_t *ip4, sctp_header_t *sctp,
|
||||
u16 new_port[VLIB_N_DIR])
|
||||
{
|
||||
/* Fastpath no checksum */
|
||||
if (PREDICT_TRUE (0 == sctp->checksum))
|
||||
{
|
||||
sctp->dst_port = new_port[VLIB_TX];
|
||||
sctp->src_port = new_port[VLIB_RX];
|
||||
return;
|
||||
}
|
||||
|
||||
if (new_port[VLIB_TX])
|
||||
sctp->dst_port = new_port[VLIB_TX];
|
||||
if (new_port[VLIB_RX])
|
||||
sctp->src_port = new_port[VLIB_RX];
|
||||
|
||||
sctp->checksum = 0;
|
||||
sctp->checksum = clib_host_to_little_u32 (~clib_crc32c_with_init (
|
||||
(u8 *) sctp, ntohs (ip4->length) - sizeof (ip4_header_t),
|
||||
~0 /* init value */));
|
||||
}
|
||||
|
||||
static_always_inline void
|
||||
cnat_ip4_translate_l3 (ip4_header_t * ip4, ip4_address_t new_addr[VLIB_N_DIR])
|
||||
{
|
||||
@@ -407,6 +430,12 @@ cnat_translation_ip4 (const cnat_session_t * session,
|
||||
udp->checksum = ip_csum_fold (sum);
|
||||
cnat_ip4_translate_l3 (ip4, new_addr);
|
||||
}
|
||||
else if (ip4->protocol == IP_PROTOCOL_SCTP)
|
||||
{
|
||||
sctp_header_t *sctp = (sctp_header_t *) udp;
|
||||
cnat_ip4_translate_sctp (ip4, sctp, new_port);
|
||||
cnat_ip4_translate_l3 (ip4, new_addr);
|
||||
}
|
||||
else if (ip4->protocol == IP_PROTOCOL_ICMP)
|
||||
{
|
||||
icmp46_header_t *icmp = (icmp46_header_t *) udp;
|
||||
@@ -743,6 +772,18 @@ cnat_session_make_key (vlib_buffer_t *b, ip_address_family_t af,
|
||||
session->key.cs_port[VLIB_RX] = udp->src_port;
|
||||
session->key.cs_port[VLIB_TX] = udp->dst_port;
|
||||
}
|
||||
else if (ip4->protocol == IP_PROTOCOL_SCTP)
|
||||
{
|
||||
sctp_header_t *sctp;
|
||||
sctp = (sctp_header_t *) (ip4 + 1);
|
||||
ip46_address_set_ip4 (&session->key.cs_ip[VLIB_TX],
|
||||
&ip4->dst_address);
|
||||
ip46_address_set_ip4 (&session->key.cs_ip[VLIB_RX],
|
||||
&ip4->src_address);
|
||||
session->key.cs_proto = ip4->protocol;
|
||||
session->key.cs_port[VLIB_RX] = sctp->src_port;
|
||||
session->key.cs_port[VLIB_TX] = sctp->dst_port;
|
||||
}
|
||||
else
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,17 @@
|
||||
|
||||
#define MIN_SRC_PORT ((u16) 0xC000)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Source and destination port. */
|
||||
u16 src_port, dst_port;
|
||||
|
||||
/* Random value to distinguish connections. */
|
||||
u32 verification_tag;
|
||||
|
||||
u32 checksum;
|
||||
} sctp_header_t;
|
||||
|
||||
typedef enum cnat_trk_flag_t_
|
||||
{
|
||||
/* Endpoint is active (static or dhcp resolved) */
|
||||
|
||||
+12
-8
@@ -76,23 +76,27 @@ clib_crc32c_u64 (u32 last, u64 data)
|
||||
|
||||
#ifdef clib_crc32c_uses_intrinsics
|
||||
static_always_inline u32
|
||||
clib_crc32c (u8 * s, int len)
|
||||
clib_crc32c_with_init (u8 *s, int len, u32 last)
|
||||
{
|
||||
u32 v = 0;
|
||||
|
||||
for (; len >= 8; len -= 8, s += 8)
|
||||
v = clib_crc32c_u64 (v, *((u64u *) s));
|
||||
last = clib_crc32c_u64 (last, *((u64u *) s));
|
||||
|
||||
for (; len >= 4; len -= 4, s += 4)
|
||||
v = clib_crc32c_u32 (v, *((u32u *) s));
|
||||
last = clib_crc32c_u32 (last, *((u32u *) s));
|
||||
|
||||
for (; len >= 2; len -= 2, s += 2)
|
||||
v = clib_crc32c_u16 (v, *((u16u *) s));
|
||||
last = clib_crc32c_u16 (last, *((u16u *) s));
|
||||
|
||||
for (; len >= 1; len -= 1, s += 1)
|
||||
v = clib_crc32c_u8 (v, *((u8 *) s));
|
||||
last = clib_crc32c_u8 (last, *((u8 *) s));
|
||||
|
||||
return v;
|
||||
return last;
|
||||
}
|
||||
|
||||
static_always_inline u32
|
||||
clib_crc32c (u8 *s, int len)
|
||||
{
|
||||
return clib_crc32c_with_init (s, len, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user