diff options
author | Hannes Frederic Sowa <hannes@stressinduktion.org> | 2013-03-07 21:07:19 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-08 12:29:22 -0500 |
commit | 842df0739776fc9af7ac15968b44415a31ba9be4 (patch) | |
tree | 68bf5467c9ac66494655795fa59b4fa58ef86dd9 /net/ipv6/raw.c | |
parent | b7ef213ef65256168df83ddfbb8131ed9adc10f9 (diff) |
ipv6: use newly introduced __ipv6_addr_needs_scope_id and ipv6_iface_scope_id
This patch requires multicast interface-scoped addresses to supply a
sin6_scope_id. Because the sin6_scope_id is now also correctly used
in case of interface-scoped multicast traffic this enables one to use
interface scoped addresses over interfaces which are not targeted by the
default multicast route (the route has to be put there manually, though).
getsockname() and getpeername() now return the correct sin6_scope_id in
case of interface-local mc addresses.
v2:
a) rebased ontop of patch 1/4 (now uses ipv6_addr_props)
v3:
a) reverted changes for ipv6_addr_props
v4:
a) unchanged
Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>dave
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r-- | net/ipv6/raw.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 330b5e7b7df6..eedff8ccded5 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -263,7 +263,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
263 | if (addr_type != IPV6_ADDR_ANY) { | 263 | if (addr_type != IPV6_ADDR_ANY) { |
264 | struct net_device *dev = NULL; | 264 | struct net_device *dev = NULL; |
265 | 265 | ||
266 | if (addr_type & IPV6_ADDR_LINKLOCAL) { | 266 | if (__ipv6_addr_needs_scope_id(addr_type)) { |
267 | if (addr_len >= sizeof(struct sockaddr_in6) && | 267 | if (addr_len >= sizeof(struct sockaddr_in6) && |
268 | addr->sin6_scope_id) { | 268 | addr->sin6_scope_id) { |
269 | /* Override any existing binding, if another | 269 | /* Override any existing binding, if another |
@@ -498,9 +498,8 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
498 | sin6->sin6_port = 0; | 498 | sin6->sin6_port = 0; |
499 | sin6->sin6_addr = ipv6_hdr(skb)->saddr; | 499 | sin6->sin6_addr = ipv6_hdr(skb)->saddr; |
500 | sin6->sin6_flowinfo = 0; | 500 | sin6->sin6_flowinfo = 0; |
501 | sin6->sin6_scope_id = 0; | 501 | sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr, |
502 | if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) | 502 | IP6CB(skb)->iif); |
503 | sin6->sin6_scope_id = IP6CB(skb)->iif; | ||
504 | } | 503 | } |
505 | 504 | ||
506 | sock_recv_ts_and_drops(msg, sk, skb); | 505 | sock_recv_ts_and_drops(msg, sk, skb); |
@@ -802,7 +801,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
802 | 801 | ||
803 | if (addr_len >= sizeof(struct sockaddr_in6) && | 802 | if (addr_len >= sizeof(struct sockaddr_in6) && |
804 | sin6->sin6_scope_id && | 803 | sin6->sin6_scope_id && |
805 | ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) | 804 | __ipv6_addr_needs_scope_id(__ipv6_addr_type(daddr))) |
806 | fl6.flowi6_oif = sin6->sin6_scope_id; | 805 | fl6.flowi6_oif = sin6->sin6_scope_id; |
807 | } else { | 806 | } else { |
808 | if (sk->sk_state != TCP_ESTABLISHED) | 807 | if (sk->sk_state != TCP_ESTABLISHED) |