diff options
Diffstat (limited to 'net/ipv6/datagram.c')
| -rw-r--r-- | net/ipv6/datagram.c | 20 | 
1 files changed, 12 insertions, 8 deletions
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index f5a54782a34..4b56cbbc789 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -124,7 +124,7 @@ ipv4_connected:  		goto out;  	} -	if (addr_type&IPV6_ADDR_LINKLOCAL) { +	if (__ipv6_addr_needs_scope_id(addr_type)) {  		if (addr_len >= sizeof(struct sockaddr_in6) &&  		    usin->sin6_scope_id) {  			if (sk->sk_bound_dev_if && @@ -355,18 +355,19 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)  		sin->sin6_family = AF_INET6;  		sin->sin6_flowinfo = 0;  		sin->sin6_port = serr->port; -		sin->sin6_scope_id = 0;  		if (skb->protocol == htons(ETH_P_IPV6)) {  			const struct ipv6hdr *ip6h = container_of((struct in6_addr *)(nh + serr->addr_offset),  								  struct ipv6hdr, daddr);  			sin->sin6_addr = ip6h->daddr;  			if (np->sndflow)  				sin->sin6_flowinfo = ip6_flowinfo(ip6h); -			if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) -				sin->sin6_scope_id = IP6CB(skb)->iif; +			sin->sin6_scope_id = +				ipv6_iface_scope_id(&sin->sin6_addr, +						    IP6CB(skb)->iif);  		} else {  			ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset),  					       &sin->sin6_addr); +			sin->sin6_scope_id = 0;  		}  	} @@ -376,18 +377,19 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)  	if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) {  		sin->sin6_family = AF_INET6;  		sin->sin6_flowinfo = 0; -		sin->sin6_scope_id = 0;  		if (skb->protocol == htons(ETH_P_IPV6)) {  			sin->sin6_addr = ipv6_hdr(skb)->saddr;  			if (np->rxopt.all)  				ip6_datagram_recv_ctl(sk, msg, skb); -			if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) -				sin->sin6_scope_id = IP6CB(skb)->iif; +			sin->sin6_scope_id = +				ipv6_iface_scope_id(&sin->sin6_addr, +						    IP6CB(skb)->iif);  		} else {  			struct inet_sock *inet = inet_sk(sk);  			ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr,  					       &sin->sin6_addr); +			sin->sin6_scope_id = 0;  			if (inet->cmsg_flags)  				ip_cmsg_recv(msg, skb);  		} @@ -592,7 +594,9 @@ int ip6_datagram_recv_ctl(struct sock *sk, struct msghdr *msg,  			sin6.sin6_addr = ipv6_hdr(skb)->daddr;  			sin6.sin6_port = ports[1];  			sin6.sin6_flowinfo = 0; -			sin6.sin6_scope_id = 0; +			sin6.sin6_scope_id = +				ipv6_iface_scope_id(&ipv6_hdr(skb)->daddr, +						    opt->iif);  			put_cmsg(msg, SOL_IPV6, IPV6_ORIGDSTADDR, sizeof(sin6), &sin6);  		}  |