Skip to content

Commit

Permalink
ipv6: enable anycast addresses as source addresses for datagrams
Browse files Browse the repository at this point in the history
This change allows to consider an anycast address valid as source address
when given via an IPV6_PKTINFO or IPV6_2292PKTINFO ancillary data item.
So, when sending a datagram with ancillary data, the unicast and anycast
addresses are handled in the same way.

- Adds ipv6_chk_acast_addr_src() to check if an anycast address is link-local
  on given interface or is global.
- Uses it in ip6_datagram_send_ctl().

Signed-off-by: Francois-Xavier Le Bail <fx.lebail@yahoo.com>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
FX Le Bail authored and David S. Miller committed Jan 23, 2014
1 parent eb97768 commit 7c90cc2
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 3 deletions.
5 changes: 3 additions & 2 deletions include/net/addrconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,9 @@ void ipv6_sock_ac_close(struct sock *sk);
int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr);
int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr);
bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
const struct in6_addr *addr);

const struct in6_addr *addr);
bool ipv6_chk_acast_addr_src(struct net *net, struct net_device *dev,
const struct in6_addr *addr);

/* Device notifier */
int register_inet6addr_notifier(struct notifier_block *nb);
Expand Down
11 changes: 11 additions & 0 deletions net/ipv6/anycast.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,17 @@ bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
return found;
}

/* check if this anycast address is link-local on given interface or
* is global
*/
bool ipv6_chk_acast_addr_src(struct net *net, struct net_device *dev,
const struct in6_addr *addr)
{
return ipv6_chk_acast_addr(net,
(ipv6_addr_type(addr) & IPV6_ADDR_LINKLOCAL ?
dev : NULL),
addr);
}

#ifdef CONFIG_PROC_FS
struct ac6_iter_state {
Expand Down
4 changes: 3 additions & 1 deletion net/ipv6/datagram.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,9 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
int strict = __ipv6_addr_src_scope(addr_type) <= IPV6_ADDR_SCOPE_LINKLOCAL;
if (!(inet_sk(sk)->freebind || inet_sk(sk)->transparent) &&
!ipv6_chk_addr(net, &src_info->ipi6_addr,
strict ? dev : NULL, 0))
strict ? dev : NULL, 0) &&
!ipv6_chk_acast_addr_src(net, dev,
&src_info->ipi6_addr))
err = -EINVAL;
else
fl6->saddr = src_info->ipi6_addr;
Expand Down

0 comments on commit 7c90cc2

Please sign in to comment.