aboutsummaryrefslogtreecommitdiff
path: root/helper/chksum.c
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>2018-08-16 11:55:07 +0300
committerMaxim Uvarov <maxim.uvarov@linaro.org>2018-08-22 17:59:28 +0300
commit4c5a303d05406afe4f821f732254c83d387c259b (patch)
treeee990da8228218004b2acab5c9b8aa20070ee9dd /helper/chksum.c
parent3e8d0eeb61b49034d0c13c2e675b8cd8eb77a4b4 (diff)
helper: add SCTP handling functions
Add functions to set and verify SCTP packet checksum. Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org> Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'helper/chksum.c')
-rw-r--r--helper/chksum.c75
1 files changed, 75 insertions, 0 deletions
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;
+}