Message ID | 20130308120719.GA5074@order.stressinduktion.org |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
Hannes Frederic Sowa wrote: > 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> > --- > net/ipv6/af_inet6.c | 6 +++--- > net/ipv6/datagram.c | 16 +++++++++------- > net/ipv6/icmp.c | 2 +- > net/ipv6/inet6_connection_sock.c | 6 ++---- > net/ipv6/raw.c | 9 ++++----- > net/ipv6/udp.c | 13 +++++++------ > 6 files changed, 26 insertions(+), 26 deletions(-) > > diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c > index 6b793bf..f56277f 100644 > --- a/net/ipv6/af_inet6.c > +++ b/net/ipv6/af_inet6.c > @@ -323,7 +323,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) > struct net_device *dev = NULL; > > rcu_read_lock(); > - if (addr_type & IPV6_ADDR_LINKLOCAL) { > + if (__ipv6_addr_needs_scope_id(addr_type)) { > if (addr_len >= sizeof(struct sockaddr_in6) && > addr->sin6_scope_id) { > /* Override any existing binding, if another one > @@ -471,8 +471,8 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr, > > sin->sin6_port = inet->inet_sport; > } > - if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) > - sin->sin6_scope_id = sk->sk_bound_dev_if; > + sin->sin6_scope_id = ipv6_iface_scope_id(&sin->sin6_addr, > + sk->sk_bound_dev_if); > *uaddr_len = sizeof(*sin); > return 0; > } > diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c > index f5a5478..b55e70a 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); > } > diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c > index fff5bdd..71b900c 100644 > --- a/net/ipv6/icmp.c > +++ b/net/ipv6/icmp.c > @@ -434,7 +434,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) > * Source addr check > */ > > - if (addr_type & IPV6_ADDR_LINKLOCAL) > + if (__ipv6_addr_needs_scope_id(addr_type)) > iif = skb->dev->ifindex; > > /* > diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c > index 5f25510..e4311cb 100644 > --- a/net/ipv6/inet6_connection_sock.c > +++ b/net/ipv6/inet6_connection_sock.c > @@ -173,10 +173,8 @@ void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr) > sin6->sin6_port = inet_sk(sk)->inet_dport; > /* We do not store received flowlabel for TCP */ > sin6->sin6_flowinfo = 0; > - sin6->sin6_scope_id = 0; > - if (sk->sk_bound_dev_if && > - ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) > - sin6->sin6_scope_id = sk->sk_bound_dev_if; > + sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr, > + sk->sk_bound_dev_if); > } > > EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr); > diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c > index 330b5e7..eedff8c 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) > if (addr_type != IPV6_ADDR_ANY) { > struct net_device *dev = NULL; > > - if (addr_type & IPV6_ADDR_LINKLOCAL) { > + if (__ipv6_addr_needs_scope_id(addr_type)) { > if (addr_len >= sizeof(struct sockaddr_in6) && > addr->sin6_scope_id) { > /* Override any existing binding, if another > @@ -498,9 +498,8 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, > sin6->sin6_port = 0; > sin6->sin6_addr = ipv6_hdr(skb)->saddr; > sin6->sin6_flowinfo = 0; > - sin6->sin6_scope_id = 0; > - if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) > - sin6->sin6_scope_id = IP6CB(skb)->iif; > + sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr, > + IP6CB(skb)->iif); > } > > sock_recv_ts_and_drops(msg, sk, skb); > @@ -802,7 +801,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, > > if (addr_len >= sizeof(struct sockaddr_in6) && > sin6->sin6_scope_id && > - ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) > + __ipv6_addr_needs_scope_id(__ipv6_addr_type(daddr))) > fl6.flowi6_oif = sin6->sin6_scope_id; > } else { > if (sk->sk_state != TCP_ESTABLISHED) > diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c > index 599e1ba6..3ed57ec 100644 > --- a/net/ipv6/udp.c > +++ b/net/ipv6/udp.c > @@ -450,15 +450,16 @@ try_again: > sin6->sin6_family = AF_INET6; > sin6->sin6_port = udp_hdr(skb)->source; > sin6->sin6_flowinfo = 0; > - sin6->sin6_scope_id = 0; > > - if (is_udp4) > + if (is_udp4) { > ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, > &sin6->sin6_addr); > - else { > + sin6->sin6_scope_id = 0; > + } else { > sin6->sin6_addr = ipv6_hdr(skb)->saddr; > - if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) > - sin6->sin6_scope_id = IP6CB(skb)->iif; > + sin6->sin6_scope_id = > + ipv6_iface_scope_id(&sin6->sin6_addr, > + IP6CB(skb)->iif); > } > > } > @@ -1118,7 +1119,7 @@ do_udp_sendmsg: > > if (addr_len >= sizeof(struct sockaddr_in6) && > sin6->sin6_scope_id && > - ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) > + __ipv6_addr_needs_scope_id(__ipv6_addr_type(daddr))) > fl6.flowi6_oif = sin6->sin6_scope_id; > } else { > if (sk->sk_state != TCP_ESTABLISHED) > Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>dave -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Date: Sat, 09 Mar 2013 01:29:24 +0900 > Hannes Frederic Sowa wrote: >> 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 Applied. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 6b793bf..f56277f 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -323,7 +323,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) struct net_device *dev = NULL; rcu_read_lock(); - if (addr_type & IPV6_ADDR_LINKLOCAL) { + if (__ipv6_addr_needs_scope_id(addr_type)) { if (addr_len >= sizeof(struct sockaddr_in6) && addr->sin6_scope_id) { /* Override any existing binding, if another one @@ -471,8 +471,8 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr, sin->sin6_port = inet->inet_sport; } - if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) - sin->sin6_scope_id = sk->sk_bound_dev_if; + sin->sin6_scope_id = ipv6_iface_scope_id(&sin->sin6_addr, + sk->sk_bound_dev_if); *uaddr_len = sizeof(*sin); return 0; } diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index f5a5478..b55e70a 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); } diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index fff5bdd..71b900c 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -434,7 +434,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) * Source addr check */ - if (addr_type & IPV6_ADDR_LINKLOCAL) + if (__ipv6_addr_needs_scope_id(addr_type)) iif = skb->dev->ifindex; /* diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 5f25510..e4311cb 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -173,10 +173,8 @@ void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr) sin6->sin6_port = inet_sk(sk)->inet_dport; /* We do not store received flowlabel for TCP */ sin6->sin6_flowinfo = 0; - sin6->sin6_scope_id = 0; - if (sk->sk_bound_dev_if && - ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) - sin6->sin6_scope_id = sk->sk_bound_dev_if; + sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr, + sk->sk_bound_dev_if); } EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr); diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 330b5e7..eedff8c 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) if (addr_type != IPV6_ADDR_ANY) { struct net_device *dev = NULL; - if (addr_type & IPV6_ADDR_LINKLOCAL) { + if (__ipv6_addr_needs_scope_id(addr_type)) { if (addr_len >= sizeof(struct sockaddr_in6) && addr->sin6_scope_id) { /* Override any existing binding, if another @@ -498,9 +498,8 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, sin6->sin6_port = 0; sin6->sin6_addr = ipv6_hdr(skb)->saddr; sin6->sin6_flowinfo = 0; - sin6->sin6_scope_id = 0; - if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) - sin6->sin6_scope_id = IP6CB(skb)->iif; + sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr, + IP6CB(skb)->iif); } sock_recv_ts_and_drops(msg, sk, skb); @@ -802,7 +801,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, if (addr_len >= sizeof(struct sockaddr_in6) && sin6->sin6_scope_id && - ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) + __ipv6_addr_needs_scope_id(__ipv6_addr_type(daddr))) fl6.flowi6_oif = sin6->sin6_scope_id; } else { if (sk->sk_state != TCP_ESTABLISHED) diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 599e1ba6..3ed57ec 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -450,15 +450,16 @@ try_again: sin6->sin6_family = AF_INET6; sin6->sin6_port = udp_hdr(skb)->source; sin6->sin6_flowinfo = 0; - sin6->sin6_scope_id = 0; - if (is_udp4) + if (is_udp4) { ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, &sin6->sin6_addr); - else { + sin6->sin6_scope_id = 0; + } else { sin6->sin6_addr = ipv6_hdr(skb)->saddr; - if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) - sin6->sin6_scope_id = IP6CB(skb)->iif; + sin6->sin6_scope_id = + ipv6_iface_scope_id(&sin6->sin6_addr, + IP6CB(skb)->iif); } } @@ -1118,7 +1119,7 @@ do_udp_sendmsg: if (addr_len >= sizeof(struct sockaddr_in6) && sin6->sin6_scope_id && - ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) + __ipv6_addr_needs_scope_id(__ipv6_addr_type(daddr))) fl6.flowi6_oif = sin6->sin6_scope_id; } else { if (sk->sk_state != TCP_ESTABLISHED)