diff mbox

[ODP/PATCH] implement ipv4 checksum functions

Message ID 1393590442-6091-1-git-send-email-maxim.uvarov@linaro.org
State Accepted, archived
Headers show

Commit Message

Maxim Uvarov Feb. 28, 2014, 12:27 p.m. UTC
Implement ipv4 functions to validate and set ipv4 checksum.

Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
---
 include/helper/odp_ip.h | 57 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)
diff mbox

Patch

diff --git a/include/helper/odp_ip.h b/include/helper/odp_ip.h
index d37daca..4fef9e3 100644
--- a/include/helper/odp_ip.h
+++ b/include/helper/odp_ip.h
@@ -22,6 +22,8 @@  extern "C" {
 #include <odp_debug.h>
 #include <odp_byteorder.h>
 
+#include <string.h>
+
 #define ODP_IPV4           4  /**< IP version 4 */
 #define ODP_IPHDR_LEN     20  /**< Min length of IP header (no options) */
 #define ODP_IPHDR_IHL_MIN  5  /**< Minimum IHL value*/
@@ -44,6 +46,61 @@  typedef struct ODP_PACKED {
 
 ODP_ASSERT(sizeof(odp_ipv4hdr_t) == ODP_IPHDR_LEN, ODP_IPV4HDR_T__SIZE_ERROR);
 
+static inline int odp_ipv4_csum_valid(odp_packet_t pkt)
+{
+	int sum = 0;
+	uint16be_t res = 0;
+	uint16_t *w;
+	int nleft = sizeof(odp_ipv4hdr_t);
+	odp_ipv4hdr_t ip;
+	uint16be_t chksum;
+
+	if (!odp_packet_l3_offset(pkt))
+		return 0;
+
+	memcpy(&ip, odp_packet_l3(pkt), sizeof(odp_ipv4hdr_t));
+	w = (uint16_t *)(void *)&ip;
+	chksum = ip.chksum;
+	ip.chksum = 0x0;
+
+	while (nleft > 1) {
+		sum += *w++;
+		nleft -= 2;
+	}
+
+	sum = (sum >> 16) + (sum & 0xFFFF);
+	sum += sum >> 16;
+	res = ~sum;
+	return (res == chksum) ? 1 : 0;
+}
+
+static inline uint16be_t odp_ipv4_csum_update(odp_packet_t pkt)
+{
+	int sum = 0;
+	uint16be_t res = 0;
+	uint16_t *w;
+	odp_ipv4hdr_t *ip;
+	int nleft = sizeof(odp_ipv4hdr_t);
+
+	if (!odp_packet_l3_offset(pkt))
+		return 0;
+
+	ip = (odp_ipv4hdr_t *)odp_packet_l3(pkt);
+	w = (uint16_t *)(void *)ip;
+	ip->chksum = 0x0;
+
+	while (nleft > 1) {
+		sum += *w++;
+		nleft -= 2;
+	}
+
+	sum = (sum >> 16) + (sum & 0xFFFF);
+	sum += sum >> 16;
+	res = ~sum;
+	ip->chksum = res;
+	return res;
+}
+
 /* IP header protocol ('proto') field values, a selected few  */
 #define ODP_IPPROTO_ICMP 0x01 /**< Internet Control Message Protocol */
 #define ODP_IPPROTO_TCP  0x06 /**< Transmission Control Protocol */