diff options
Diffstat (limited to 'net/sched/act_csum.c')
| -rw-r--r-- | net/sched/act_csum.c | 39 | 
1 files changed, 25 insertions, 14 deletions
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 08fa1e8a4ca..3a4c0caa1f7 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -166,15 +166,17 @@ static int tcf_csum_ipv4_igmp(struct sk_buff *skb,  	return 1;  } -static int tcf_csum_ipv6_icmp(struct sk_buff *skb, struct ipv6hdr *ip6h, +static int tcf_csum_ipv6_icmp(struct sk_buff *skb,  			      unsigned int ihl, unsigned int ipl)  {  	struct icmp6hdr *icmp6h; +	const struct ipv6hdr *ip6h;  	icmp6h = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*icmp6h));  	if (icmp6h == NULL)  		return 0; +	ip6h = ipv6_hdr(skb);  	icmp6h->icmp6_cksum = 0;  	skb->csum = csum_partial(icmp6h, ipl - ihl, 0);  	icmp6h->icmp6_cksum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, @@ -186,15 +188,17 @@ static int tcf_csum_ipv6_icmp(struct sk_buff *skb, struct ipv6hdr *ip6h,  	return 1;  } -static int tcf_csum_ipv4_tcp(struct sk_buff *skb, struct iphdr *iph, +static int tcf_csum_ipv4_tcp(struct sk_buff *skb,  			     unsigned int ihl, unsigned int ipl)  {  	struct tcphdr *tcph; +	const struct iphdr *iph;  	tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph));  	if (tcph == NULL)  		return 0; +	iph = ip_hdr(skb);  	tcph->check = 0;  	skb->csum = csum_partial(tcph, ipl - ihl, 0);  	tcph->check = tcp_v4_check(ipl - ihl, @@ -205,15 +209,17 @@ static int tcf_csum_ipv4_tcp(struct sk_buff *skb, struct iphdr *iph,  	return 1;  } -static int tcf_csum_ipv6_tcp(struct sk_buff *skb, struct ipv6hdr *ip6h, +static int tcf_csum_ipv6_tcp(struct sk_buff *skb,  			     unsigned int ihl, unsigned int ipl)  {  	struct tcphdr *tcph; +	const struct ipv6hdr *ip6h;  	tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph));  	if (tcph == NULL)  		return 0; +	ip6h = ipv6_hdr(skb);  	tcph->check = 0;  	skb->csum = csum_partial(tcph, ipl - ihl, 0);  	tcph->check = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, @@ -225,10 +231,11 @@ static int tcf_csum_ipv6_tcp(struct sk_buff *skb, struct ipv6hdr *ip6h,  	return 1;  } -static int tcf_csum_ipv4_udp(struct sk_buff *skb, struct iphdr *iph, +static int tcf_csum_ipv4_udp(struct sk_buff *skb,  			     unsigned int ihl, unsigned int ipl, int udplite)  {  	struct udphdr *udph; +	const struct iphdr *iph;  	u16 ul;  	/* @@ -242,6 +249,7 @@ static int tcf_csum_ipv4_udp(struct sk_buff *skb, struct iphdr *iph,  	if (udph == NULL)  		return 0; +	iph = ip_hdr(skb);  	ul = ntohs(udph->len);  	if (udplite || udph->check) { @@ -276,10 +284,11 @@ ignore_obscure_skb:  	return 1;  } -static int tcf_csum_ipv6_udp(struct sk_buff *skb, struct ipv6hdr *ip6h, +static int tcf_csum_ipv6_udp(struct sk_buff *skb,  			     unsigned int ihl, unsigned int ipl, int udplite)  {  	struct udphdr *udph; +	const struct ipv6hdr *ip6h;  	u16 ul;  	/* @@ -293,6 +302,7 @@ static int tcf_csum_ipv6_udp(struct sk_buff *skb, struct ipv6hdr *ip6h,  	if (udph == NULL)  		return 0; +	ip6h = ipv6_hdr(skb);  	ul = ntohs(udph->len);  	udph->check = 0; @@ -328,7 +338,7 @@ ignore_obscure_skb:  static int tcf_csum_ipv4(struct sk_buff *skb, u32 update_flags)  { -	struct iphdr *iph; +	const struct iphdr *iph;  	int ntkoff;  	ntkoff = skb_network_offset(skb); @@ -353,19 +363,19 @@ static int tcf_csum_ipv4(struct sk_buff *skb, u32 update_flags)  		break;  	case IPPROTO_TCP:  		if (update_flags & TCA_CSUM_UPDATE_FLAG_TCP) -			if (!tcf_csum_ipv4_tcp(skb, iph, iph->ihl * 4, +			if (!tcf_csum_ipv4_tcp(skb, iph->ihl * 4,  					       ntohs(iph->tot_len)))  				goto fail;  		break;  	case IPPROTO_UDP:  		if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP) -			if (!tcf_csum_ipv4_udp(skb, iph, iph->ihl * 4, +			if (!tcf_csum_ipv4_udp(skb, iph->ihl * 4,  					       ntohs(iph->tot_len), 0))  				goto fail;  		break;  	case IPPROTO_UDPLITE:  		if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE) -			if (!tcf_csum_ipv4_udp(skb, iph, iph->ihl * 4, +			if (!tcf_csum_ipv4_udp(skb, iph->ihl * 4,  					       ntohs(iph->tot_len), 1))  				goto fail;  		break; @@ -377,7 +387,7 @@ static int tcf_csum_ipv4(struct sk_buff *skb, u32 update_flags)  		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))  			goto fail; -		ip_send_check(iph); +		ip_send_check(ip_hdr(skb));  	}  	return 1; @@ -456,6 +466,7 @@ static int tcf_csum_ipv6(struct sk_buff *skb, u32 update_flags)  			ixhl = ipv6_optlen(ip6xh);  			if (!pskb_may_pull(skb, hl + ixhl + ntkoff))  				goto fail; +			ip6xh = (void *)(skb_network_header(skb) + hl);  			if ((nexthdr == NEXTHDR_HOP) &&  			    !(tcf_csum_ipv6_hopopts(ip6xh, ixhl, &pl)))  				goto fail; @@ -464,25 +475,25 @@ static int tcf_csum_ipv6(struct sk_buff *skb, u32 update_flags)  			break;  		case IPPROTO_ICMPV6:  			if (update_flags & TCA_CSUM_UPDATE_FLAG_ICMP) -				if (!tcf_csum_ipv6_icmp(skb, ip6h, +				if (!tcf_csum_ipv6_icmp(skb,  							hl, pl + sizeof(*ip6h)))  					goto fail;  			goto done;  		case IPPROTO_TCP:  			if (update_flags & TCA_CSUM_UPDATE_FLAG_TCP) -				if (!tcf_csum_ipv6_tcp(skb, ip6h, +				if (!tcf_csum_ipv6_tcp(skb,  						       hl, pl + sizeof(*ip6h)))  					goto fail;  			goto done;  		case IPPROTO_UDP:  			if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP) -				if (!tcf_csum_ipv6_udp(skb, ip6h, hl, +				if (!tcf_csum_ipv6_udp(skb, hl,  						       pl + sizeof(*ip6h), 0))  					goto fail;  			goto done;  		case IPPROTO_UDPLITE:  			if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE) -				if (!tcf_csum_ipv6_udp(skb, ip6h, hl, +				if (!tcf_csum_ipv6_udp(skb, hl,  						       pl + sizeof(*ip6h), 1))  					goto fail;  			goto done;  |