cnat: Add sctp support
[vpp.git] / src / plugins / cnat / cnat_node.h
index 80d803c..c304c5c 100644 (file)
@@ -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;
     }