[v6,9/12] linux-gen: packet: support SCTP packet insertion

Message ID 1534870807-18456-10-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 support for insertion of checksum into SCTP packets.

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
 **/
 .../include/odp_packet_internal.h             |  2 +
 platform/linux-generic/odp_packet.c           | 49 +++++++++++++++++++
 2 files changed, 51 insertions(+)

Patch

diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h
index 4b5127d93..0dccc97da 100644
--- a/platform/linux-generic/include/odp_packet_internal.h
+++ b/platform/linux-generic/include/odp_packet_internal.h
@@ -308,6 +308,8 @@  int _odp_packet_cmp_data(odp_packet_t pkt, uint32_t offset,
 int _odp_packet_ipv4_chksum_insert(odp_packet_t pkt);
 int _odp_packet_tcp_chksum_insert(odp_packet_t pkt);
 int _odp_packet_udp_chksum_insert(odp_packet_t pkt);
+int _odp_packet_sctp_chksum_insert(odp_packet_t pkt);
+
 
 #ifdef __cplusplus
 }
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index 885aec8d8..ae63ef4a3 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -2017,6 +2017,31 @@  static uint16_t packet_sum_ones_comp16(odp_packet_hdr_t *pkt_hdr,
 	return sum;
 }
 
+static uint32_t packet_sum_crc32c(odp_packet_hdr_t *pkt_hdr,
+				  uint32_t offset,
+				  uint32_t len,
+				  uint32_t init_val)
+{
+	uint32_t sum = init_val;
+
+	if (offset + len > pkt_hdr->frame_len)
+		return sum;
+
+	while (len > 0) {
+		uint32_t seglen = 0; /* GCC */
+		void *mapaddr = packet_map(pkt_hdr, offset, &seglen, NULL);
+
+		if (seglen > len)
+			seglen = len;
+
+		sum = odp_hash_crc32c(mapaddr, seglen, sum);
+		len -= seglen;
+		offset += seglen;
+	}
+
+	return sum;
+}
+
 /** Parser helper function for Ethernet packets */
 static inline uint16_t parse_eth(packet_parser_t *prs, const uint8_t **parseptr,
 				 uint32_t *offset, uint32_t frame_len)
@@ -2617,6 +2642,30 @@  int _odp_packet_udp_chksum_insert(odp_packet_t pkt)
 	return _odp_packet_tcp_udp_chksum_insert(pkt, _ODP_IPPROTO_UDP);
 }
 
+/**
+ * Calculate and fill in SCTP checksum
+ *
+ * @param pkt  ODP packet
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ */
+int _odp_packet_sctp_chksum_insert(odp_packet_t pkt)
+{
+	odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
+	uint32_t sum;
+
+	if (pkt_hdr->p.l4_offset == ODP_PACKET_OFFSET_INVALID)
+		return -1;
+
+	sum = 0;
+	odp_packet_copy_from_mem(pkt, pkt_hdr->p.l4_offset + 8, 4, &sum);
+	sum = ~packet_sum_crc32c(pkt_hdr, pkt_hdr->p.l4_offset,
+				 pkt_hdr->frame_len - pkt_hdr->p.l4_offset,
+				 ~0);
+	return odp_packet_copy_from_mem(pkt, pkt_hdr->p.l4_offset + 8, 4, &sum);
+}
+
 static int packet_l4_chksum(odp_packet_hdr_t *pkt_hdr,
 			    odp_proto_chksums_t chksums,
 			    uint32_t l4_part_sum)