diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_main.c')
| -rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 13 | 
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 484bbedffe2..79b83458318 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1338,26 +1338,29 @@ static unsigned int ixgbe_get_headlen(unsigned char *data,  		if (hlen < sizeof(struct iphdr))  			return hdr.network - data; -		/* record next protocol */ -		nexthdr = hdr.ipv4->protocol; -		hdr.network += hlen; +		/* record next protocol if header is present */ +		if (!hdr.ipv4->frag_off) +			nexthdr = hdr.ipv4->protocol;  	} else if (protocol == __constant_htons(ETH_P_IPV6)) {  		if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr)))  			return max_len;  		/* record next protocol */  		nexthdr = hdr.ipv6->nexthdr; -		hdr.network += sizeof(struct ipv6hdr); +		hlen = sizeof(struct ipv6hdr);  #ifdef IXGBE_FCOE  	} else if (protocol == __constant_htons(ETH_P_FCOE)) {  		if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN))  			return max_len; -		hdr.network += FCOE_HEADER_LEN; +		hlen = FCOE_HEADER_LEN;  #endif  	} else {  		return hdr.network - data;  	} +	/* relocate pointer to start of L4 header */ +	hdr.network += hlen; +  	/* finally sort out TCP/UDP */  	if (nexthdr == IPPROTO_TCP) {  		if ((hdr.network - data) > (max_len - sizeof(struct tcphdr)))  |