aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorFX Le Bail <fx.lebail@yahoo.com>2014-01-22 01:42:37 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-23 00:57:05 -0500
commit7c90cc2d40cab15adc78545edba8b5996bd4cade (patch)
tree64222b6892e1ffd29f91102cada60da71ea7a40f /net
parenteb97768acb3f7749a3a03ee35fee9088244113ea (diff)
ipv6: enable anycast addresses as source addresses for datagrams
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>
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/anycast.c11
-rw-r--r--net/ipv6/datagram.c4
2 files changed, 14 insertions, 1 deletions
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 5a80f15a9de2..210183244689 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -383,6 +383,17 @@ bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
383 return found; 383 return found;
384} 384}
385 385
386/* check if this anycast address is link-local on given interface or
387 * is global
388 */
389bool ipv6_chk_acast_addr_src(struct net *net, struct net_device *dev,
390 const struct in6_addr *addr)
391{
392 return ipv6_chk_acast_addr(net,
393 (ipv6_addr_type(addr) & IPV6_ADDR_LINKLOCAL ?
394 dev : NULL),
395 addr);
396}
386 397
387#ifdef CONFIG_PROC_FS 398#ifdef CONFIG_PROC_FS
388struct ac6_iter_state { 399struct ac6_iter_state {
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 2f5e2f154d21..c3bf2d2e519e 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -699,7 +699,9 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
699 int strict = __ipv6_addr_src_scope(addr_type) <= IPV6_ADDR_SCOPE_LINKLOCAL; 699 int strict = __ipv6_addr_src_scope(addr_type) <= IPV6_ADDR_SCOPE_LINKLOCAL;
700 if (!(inet_sk(sk)->freebind || inet_sk(sk)->transparent) && 700 if (!(inet_sk(sk)->freebind || inet_sk(sk)->transparent) &&
701 !ipv6_chk_addr(net, &src_info->ipi6_addr, 701 !ipv6_chk_addr(net, &src_info->ipi6_addr,
702 strict ? dev : NULL, 0)) 702 strict ? dev : NULL, 0) &&
703 !ipv6_chk_acast_addr_src(net, dev,
704 &src_info->ipi6_addr))
703 err = -EINVAL; 705 err = -EINVAL;
704 else 706 else
705 fl6->saddr = src_info->ipi6_addr; 707 fl6->saddr = src_info->ipi6_addr;