[v6,6/12] helper: add SCTP handling functions

Message ID 1534870807-18456-7-git-send-email-odpbot@yandex.ru
State New
Headers show
Series
  • SCTP checksums support
Related show

Commit Message

Github ODP bot Aug. 21, 2018, 5 p.m.
From: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>


Add functions to set and verify SCTP packet checksum.

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>

---
/** Email created from pull request 674 (lumag:sctp-checksum)
 ** https://github.com/Linaro/odp/pull/674
 ** Patch: https://github.com/Linaro/odp/pull/674.patch
 ** Base sha: f6c423a7d29e2c7d6d890cbc098a398d0d7e1288
 ** Merge commit sha: d4f772b36da26684194cb0452a01b8da1ba7e3e1
 **/
 helper/chksum.c                    | 75 ++++++++++++++++++++++++++++++
 helper/include/odp/helper/chksum.h | 42 +++++++++++++++++
 2 files changed, 117 insertions(+)

Patch

diff --git a/helper/chksum.c b/helper/chksum.c
index da5625a78..7c7c20a2f 100644
--- a/helper/chksum.c
+++ b/helper/chksum.c
@@ -9,6 +9,7 @@ 
 #include <odp.h>
 #include <odp/helper/ip.h>
 #include <odp/helper/udp.h>
+#include <odp/helper/sctp.h>
 #include <odp/helper/tcp.h>
 #include <odp/helper/chksum.h>
 #include <stddef.h>
@@ -351,3 +352,77 @@  int odph_udp_tcp_chksum(odp_packet_t     odp_pkt,
 
 	return ret_code;
 }
+
+static uint32_t odph_packet_crc32c(odp_packet_t pkt,
+				   uint32_t offset,
+				   uint32_t length,
+				   uint32_t init_val)
+{
+	uint32_t sum = init_val;
+
+	if (offset + length > odp_packet_len(pkt))
+		return sum;
+
+	while (length > 0) {
+		uint32_t seg_len;
+		void *data = odp_packet_offset(pkt, offset, &seg_len, NULL);
+
+		if (seg_len > length)
+			seg_len = length;
+
+		sum = odp_hash_crc32c(data, seg_len, sum);
+		length -= seg_len;
+		offset += seg_len;
+	}
+
+	return sum;
+}
+
+int odph_sctp_chksum_set(odp_packet_t pkt)
+{
+	uint32_t l4_offset = odp_packet_l4_offset(pkt);
+	uint32_t sum = 0;
+
+	if (!odp_packet_has_sctp(pkt))
+		return -1;
+
+	if (l4_offset == ODP_PACKET_OFFSET_INVALID)
+		return -1;
+
+	odp_packet_copy_from_mem(pkt,
+				 l4_offset + ODPH_SCTPHDR_LEN - 4,
+				 4,
+				 &sum);
+
+	sum = ~odph_packet_crc32c(pkt, l4_offset,
+				  odp_packet_len(pkt) - l4_offset,
+				  ~0);
+	return odp_packet_copy_from_mem(pkt,
+					l4_offset + ODPH_SCTPHDR_LEN - 4,
+					4,
+					&sum);
+}
+
+int odph_sctp_chksum_verify(odp_packet_t pkt)
+{
+	uint32_t l4_offset = odp_packet_l4_offset(pkt);
+	uint32_t sum;
+	uint32_t temp = 0;
+
+	if (!odp_packet_has_sctp(pkt))
+		return -1;
+
+	sum = odph_packet_crc32c(pkt, l4_offset,
+				 ODPH_SCTPHDR_LEN - 4,
+				 ~0);
+	sum = odp_hash_crc32c(&temp, 4, sum);
+	sum = ~odph_packet_crc32c(pkt, l4_offset + ODPH_SCTPHDR_LEN,
+				  odp_packet_len(pkt) - l4_offset -
+				  ODPH_SCTPHDR_LEN,
+				  sum);
+
+	odp_packet_copy_to_mem(pkt, l4_offset + ODPH_SCTPHDR_LEN - 4,
+			       4, &temp);
+
+	return (temp == sum) ? 0 : 2;
+}
diff --git a/helper/include/odp/helper/chksum.h b/helper/include/odp/helper/chksum.h
index c03abeb7b..148b98601 100644
--- a/helper/include/odp/helper/chksum.h
+++ b/helper/include/odp/helper/chksum.h
@@ -189,6 +189,48 @@  static inline int odph_udp_chksum_verify(odp_packet_t odp_pkt)
 	return odph_udp_tcp_chksum(odp_pkt, ODPH_CHKSUM_VERIFY, NULL);
 }
 
+/**
+ * Generate SCTP checksum
+ *
+ * This function supports SCTP over either IPv4 or IPV6 - including handling
+ * any IPv4 header options and any IPv6 extension headers.  However it
+ * does not handle tunneled pkts (i.e. any case where there is more than
+ * one IPv4/IPv6 header).
+ * This function also handles non-contiguous pkts.  In particular it can
+ * handle arbitrary packet segmentation, including cases where the segments
+ * are not 2 byte aligned, nor have a length that is a multiple of 2.  This
+ * function also can handle jumbo frames (at least up to 10K).
+ *
+ * This function will insert the calculated CRC32-c checksum into the proper
+ * location in the SCTP header.
+ *
+ * @param  odp_pkt     Calculate and insert chksum for this SCTP pkt, which can
+ *                     be over IPv4 or IPv6.
+ * @retval 0 on success
+ * @retval <0 on failure
+ */
+int odph_sctp_chksum_set(odp_packet_t odp_pkt);
+
+/**
+ * Verify SCTP checksum
+ *
+ * This function supports SCTP over either IPv4 or IPV6 - including handling
+ * any IPv4 header options and any IPv6 extension headers.  However it
+ * does not handle tunneled pkts (i.e. any case where there is more than
+ * one IPv4/IPv6 header).
+ * This function also handles non-contiguous pkts.  In particular it can
+ * handle arbitrary packet segmentation, including cases where the segments
+ * are not 2 byte aligned, nor have a length that is a multiple of 2.  This
+ * function also can handle jumbo frames (at least up to 10K).
+ *
+ * @param  odp_pkt     Calculate and compare the chksum for this SCTP pkt,
+ *                     which can be over IPv4 or IPv6.
+ * @retval <0 on failure
+ * @retval 0 if the incoming chksum field is correct
+ * @retval 2 when the chksum field is incorrect
+ */
+int odph_sctp_chksum_verify(odp_packet_t odp_pkt);
+
 /**
  * @}
  */