aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/addrconf.h5
-rw-r--r--net/ipv6/anycast.c11
-rw-r--r--net/ipv6/datagram.c4
3 files changed, 17 insertions, 3 deletions
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 66c4a44d8f5c..50e39a8822b4 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -205,8 +205,9 @@ void ipv6_sock_ac_close(struct sock *sk);
205int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr); 205int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr);
206int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr); 206int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr);
207bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev, 207bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
208 const struct in6_addr *addr); 208 const struct in6_addr *addr);
209 209bool ipv6_chk_acast_addr_src(struct net *net, struct net_device *dev,
210 const struct in6_addr *addr);
210 211
211/* Device notifier */ 212/* Device notifier */
212int register_inet6addr_notifier(struct notifier_block *nb); 213int register_inet6addr_notifier(struct notifier_block *nb);
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;