summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/cnat/cnat_node.h41
-rw-r--r--src/plugins/cnat/cnat_types.h11
2 files changed, 52 insertions, 0 deletions
diff --git a/src/plugins/cnat/cnat_node.h b/src/plugins/cnat/cnat_node.h
index 80d803c4b61..c304c5c83e8 100644
--- a/src/plugins/cnat/cnat_node.h
+++ b/src/plugins/cnat/cnat_node.h
@@ -226,6 +226,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])
{
ip4_address_t old_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;
}
diff --git a/src/plugins/cnat/cnat_types.h b/src/plugins/cnat/cnat_types.h
index 7b779a66a4e..bf2726fa63a 100644
--- a/src/plugins/cnat/cnat_types.h
+++ b/src/plugins/cnat/cnat_types.h
@@ -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) */