|
@@ -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);
|
|
|
}
|