diff options
Diffstat (limited to 'net/ipv6/raw.c')
| -rw-r--r-- | net/ipv6/raw.c | 13 | 
1 files changed, 8 insertions, 5 deletions
| diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 60be012fe708..e4462b0ff801 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -72,7 +72,7 @@ EXPORT_SYMBOL_GPL(raw_v6_hashinfo);  struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,  		unsigned short num, const struct in6_addr *loc_addr, -		const struct in6_addr *rmt_addr, int dif) +		const struct in6_addr *rmt_addr, int dif, int sdif)  {  	bool is_multicast = ipv6_addr_is_multicast(loc_addr); @@ -86,7 +86,9 @@ struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,  			    !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr))  				continue; -			if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) +			if (sk->sk_bound_dev_if && +			    sk->sk_bound_dev_if != dif && +			    sk->sk_bound_dev_if != sdif)  				continue;  			if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) { @@ -178,7 +180,8 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)  		goto out;  	net = dev_net(skb->dev); -	sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, inet6_iif(skb)); +	sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, +			     inet6_iif(skb), inet6_sdif(skb));  	while (sk) {  		int filtered; @@ -222,7 +225,7 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)  			}  		}  		sk = __raw_v6_lookup(net, sk_next(sk), nexthdr, daddr, saddr, -				     inet6_iif(skb)); +				     inet6_iif(skb), inet6_sdif(skb));  	}  out:  	read_unlock(&raw_v6_hashinfo.lock); @@ -378,7 +381,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,  		net = dev_net(skb->dev);  		while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr, -						inet6_iif(skb)))) { +					     inet6_iif(skb), inet6_iif(skb)))) {  			rawv6_err(sk, skb, NULL, type, code,  					inner_offset, info);  			sk = sk_next(sk); |