diff options
| author | Eric Dumazet <edumazet@google.com> | 2012-07-24 01:19:31 +0000 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2012-07-24 13:54:15 -0700 | 
| commit | 9cb429d692b341e972b12e6cd097364050ebbb26 (patch) | |
| tree | 39450b1d5650322fc6cffca581f34edbc06233ee | |
| parent | c20cd5d753a452807b080bbf390e2f844d7991b3 (diff) | |
| download | olio-linux-3.10-9cb429d692b341e972b12e6cd097364050ebbb26.tar.xz olio-linux-3.10-9cb429d692b341e972b12e6cd097364050ebbb26.zip  | |
tcp: early_demux fixes
1) Remove a non needed pskb_may_pull() in tcp_v4_early_demux()
   and fix a potential bug if skb->head was reallocated
   (iph & th pointers were not reloaded)
TCP stack will pull/check headers anyway.
2) must reload iph in ip_rcv_finish() after early_demux()
 call since skb->head might have changed.
3) skb->dev->ifindex can be now replaced by skb->skb_iif
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/ipv4/ip_input.c | 5 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 9 | 
2 files changed, 6 insertions, 8 deletions
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 4ebc6feee25..93134b0eab0 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -326,8 +326,11 @@ static int ip_rcv_finish(struct sk_buff *skb)  		rcu_read_lock();  		ipprot = rcu_dereference(inet_protos[protocol]); -		if (ipprot && ipprot->early_demux) +		if (ipprot && ipprot->early_demux) {  			ipprot->early_demux(skb); +			/* must reload iph, skb->head might have changed */ +			iph = ip_hdr(skb); +		}  		rcu_read_unlock();  	} diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 3e30548ac32..b6b07c93924 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1686,7 +1686,6 @@ void tcp_v4_early_demux(struct sk_buff *skb)  	struct net *net = dev_net(skb->dev);  	const struct iphdr *iph;  	const struct tcphdr *th; -	struct net_device *dev;  	struct sock *sk;  	if (skb->pkt_type != PACKET_HOST) @@ -1701,14 +1700,10 @@ void tcp_v4_early_demux(struct sk_buff *skb)  	if (th->doff < sizeof(struct tcphdr) / 4)  		return; -	if (!pskb_may_pull(skb, ip_hdrlen(skb) + th->doff * 4)) -		return; - -	dev = skb->dev;  	sk = __inet_lookup_established(net, &tcp_hashinfo,  				       iph->saddr, th->source,  				       iph->daddr, ntohs(th->dest), -				       dev->ifindex); +				       skb->skb_iif);  	if (sk) {  		skb->sk = sk;  		skb->destructor = sock_edemux; @@ -1718,7 +1713,7 @@ void tcp_v4_early_demux(struct sk_buff *skb)  			if (dst)  				dst = dst_check(dst, 0);  			if (dst && -			    icsk->rx_dst_ifindex == dev->ifindex) +			    icsk->rx_dst_ifindex == skb->skb_iif)  				skb_dst_set_noref(skb, dst);  		}  	}  |