diff mbox

[net-next] IPv6: enable bind() to assign an anycast address

Message ID 1389377544-3119-1-git-send-email-fx.lebail@yahoo.com
State Superseded, archived
Delegated to: David Miller
Headers show

Commit Message

FX Le Bail Jan. 10, 2014, 6:12 p.m. UTC
- Add ipv6_chk_acast_addr_src() to check if an anycast address is link-local
  on given interface or is global (on any interface).
- Use it in inet6_bind().

Signed-off-by: Francois-Xavier Le Bail <fx.lebail@yahoo.com>
---
Tested with link-local and global anycast addresses.
Tested with SOCK_DGRAM socket, bind and UDP traffic OK.
Tested with SOCK_STREAM socket, bind OK, traffic need another change.

 include/net/addrconf.h |    5 +++--
 net/ipv6/af_inet6.c    |    4 +++-
 net/ipv6/anycast.c     |   11 +++++++++++
 3 files changed, 17 insertions(+), 3 deletions(-)

--
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

Comments

Hannes Frederic Sowa Jan. 10, 2014, 8:51 p.m. UTC | #1
Hi!

On Fri, Jan 10, 2014 at 07:12:24PM +0100, Francois-Xavier Le Bail wrote:
> - Add ipv6_chk_acast_addr_src() to check if an anycast address is link-local
>   on given interface or is global (on any interface).
> - Use it in inet6_bind().
> 
> Signed-off-by: Francois-Xavier Le Bail <fx.lebail@yahoo.com>
> ---
> Tested with link-local and global anycast addresses.
> Tested with SOCK_DGRAM socket, bind and UDP traffic OK.

> Tested with SOCK_STREAM socket, bind OK, traffic need another change.

What do you mean with that?

Bye,

  Hannes

--
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
FX Le Bail Jan. 10, 2014, 10:01 p.m. UTC | #2
On Fri, 1/10/14, Hannes Frederic Sowa <hannes@stressinduktion.org> wrote:

>On Fri, Jan 10, 2014 at 07:12:24PM +0100, Francois-Xavier Le Bail wrote:
>> - Add ipv6_chk_acast_addr_src() to check if an anycast address is link-local
>>   on given interface or is global (on any interface).
>> - Use it in inet6_bind().
>> 
>> Signed-off-by: Francois-Xavier Le Bail <fx.lebail@yahoo.com>
>> ---
>> Tested with link-local and global anycast addresses.
>> Tested with SOCK_DGRAM socket, bind and UDP traffic OK.
>>
>> Tested with SOCK_STREAM socket, bind OK, traffic need another change.

> What do you mean with that?

In actual TCP code, if the destination address is not unicast, the request is dropped:

	if (!ipv6_unicast_destination(skb))
		goto drop;

I will send another patch to allow anycat addresses destinations fot TCP. 

bye,
Francois-Xavier

--
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
FX Le Bail Jan. 13, 2014, 4:43 p.m. UTC | #3
On Fri, 1/10/14, Francois-Xavier Le Bail <fx.lebail@yahoo.com> wrote:

> - Add ipv6_chk_acast_addr_src() to check if an anycast address is link-local
>   on given interface or is global (on any interface).
> - Use it in inet6_bind().
> 
> Signed-off-by: Francois-Xavier Le Bail <fx.lebail@yahoo.com>
> ---

I will divide this patch in 2 patches : one for adding ipv6_chk_acast_addr_src(), one (v2) for updating bind().
--
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 mbox

Patch

diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 66c4a44..50e39a8 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -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);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index c921d5d..68b81e9 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -347,7 +347,9 @@  int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 			if (!(addr_type & IPV6_ADDR_MULTICAST))	{
 				if (!(inet->freebind || inet->transparent) &&
 				    !ipv6_chk_addr(net, &addr->sin6_addr,
-						   dev, 0)) {
+						   dev, 0) &&
+				    !ipv6_chk_acast_addr_src(net, dev,
+							     &addr->sin6_addr)) {
 					err = -EADDRNOTAVAIL;
 					goto out_unlock;
 				}
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 5a80f15..9f25dda 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,
 	return found;
 }
 
+/*	check if address is link-local on given interface
+ *	or is global on any interface
+ */
+bool ipv6_chk_acast_addr_src(struct net *net, struct net_device *dev,
+			     const struct in6_addr *addr)
+{
+	if (ipv6_addr_type(addr) & IPV6_ADDR_LINKLOCAL)
+		return ipv6_chk_acast_dev(dev, addr);
+	else
+		return ipv6_chk_acast_addr(net, NULL, addr);
+}
 
 #ifdef CONFIG_PROC_FS
 struct ac6_iter_state {