diff options
| -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);  		}  	}  |