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 <harouth@codeaurora.org>
This commit is contained in:
Harout Hedeshian 2014-11-13 08:35:50 -07:00
parent b37e387197
commit 773dfb64dd
3 changed files with 7 additions and 1 deletions

View File

@ -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

View File

@ -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
};

View File

@ -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,