From 773dfb64dd6815a2f83f9aea50c63994f1a8cb95 Mon Sep 17 00:00:00 2001 From: Harout Hedeshian Date: Thu, 13 Nov 2014 08:35:50 -0700 Subject: [PATCH] net: rmnet_data: Checksum offload handle IPv4 UDP frames with 0 checksum Checksum offload routine should skip checksum fixup computation on IPv4 UDP packets which have the checksum field set to 0 by the sender. This is allowed by RFC768. Packets are marked as checksum unnecessary and shipped up the stack as-is. CRs-Fixed: 755544 Change-Id: I0432c3e1b25196134ecc8bbbe23c9cab46666d5c Signed-off-by: Harout Hedeshian --- net/rmnet_data/rmnet_data_handlers.c | 3 ++- net/rmnet_data/rmnet_map.h | 1 + net/rmnet_data/rmnet_map_data.c | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/net/rmnet_data/rmnet_data_handlers.c b/net/rmnet_data/rmnet_data_handlers.c index ed25dc508ba4..b131cb1134f2 100644 --- a/net/rmnet_data/rmnet_data_handlers.c +++ b/net/rmnet_data/rmnet_data_handlers.c @@ -286,7 +286,8 @@ static rx_handler_result_t _rmnet_map_ingress_handler(struct sk_buff *skb, ckresult = rmnet_map_checksum_downlink_packet(skb); trace_rmnet_map_checksum_downlink_packet(skb, ckresult); rmnet_stats_dl_checksum(ckresult); - if (likely(ckresult == RMNET_MAP_CHECKSUM_OK)) + if (likely((ckresult == RMNET_MAP_CHECKSUM_OK) + || (ckresult == RMNET_MAP_CHECKSUM_SKIPPED))) skb->ip_summed |= CHECKSUM_UNNECESSARY; else if (ckresult != RMNET_MAP_CHECKSUM_ERR_UNKNOWN_IP_VERSION && ckresult != RMNET_MAP_CHECKSUM_ERR_UNKNOWN_TRANSPORT diff --git a/net/rmnet_data/rmnet_map.h b/net/rmnet_data/rmnet_map.h index 8fd11ad03faf..d368f2536c4b 100644 --- a/net/rmnet_data/rmnet_map.h +++ b/net/rmnet_data/rmnet_map.h @@ -92,6 +92,7 @@ enum rmnet_map_checksum_errors_e { RMNET_MAP_CHECKSUM_ERR_UNKNOWN_IP_VERSION, RMNET_MAP_CHECKSUM_ERR_UNKNOWN_TRANSPORT, RMNET_MAP_CHECKSUM_FRAGMENTED_PACKET, + RMNET_MAP_CHECKSUM_SKIPPED, /* This should always be the last element */ RMNET_MAP_CHECKSUM_ENUM_LENGTH }; diff --git a/net/rmnet_data/rmnet_map_data.c b/net/rmnet_data/rmnet_map_data.c index 24db006c7591..96ce624e5df0 100644 --- a/net/rmnet_data/rmnet_map_data.c +++ b/net/rmnet_data/rmnet_map_data.c @@ -377,6 +377,10 @@ static int rmnet_map_validate_ipv4_packet_checksum(unsigned char *map_payload, if (unlikely(!checksum_field)) return RMNET_MAP_CHECKSUM_ERR_UNKNOWN_TRANSPORT; + /* RFC 768 - Skip IPv4 UDP packets where sender checksum field is 0 */ + if ((*checksum_field == 0) && (ip4h->protocol == IPPROTO_UDP)) + return RMNET_MAP_CHECKSUM_SKIPPED; + checksum_value = ~ntohs(cksum_trailer->checksum_value); ip_hdr_checksum = ~ip_fast_csum(ip4h, (int)ip4h->ihl); ip_payload_checksum = rmnet_map_subtract_checksums(checksum_value,