diff mbox

[net-next,v5] IPv6: add the option to use anycast addresses as source addresses in echo reply

Message ID 1389103047-3380-1-git-send-email-fx.lebail@yahoo.com
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

FX Le Bail Jan. 7, 2014, 1:57 p.m. UTC
This change allows to follow a recommandation of RFC4942.

- Add "anycast_src_echo_reply" sysctl to control the use of anycast addresses
  as source addresses for ICMPv6 echo reply. This sysctl is false by default
  to preserve existing behavior.
- Add inline check ipv6_anycast_destination().
- Use them in icmpv6_echo_reply().

Reference:
RFC4942 - IPv6 Transition/Coexistence Security Considerations
   (http://tools.ietf.org/html/rfc4942#section-2.1.6)

2.1.6. Anycast Traffic Identification and Security

   [...]
   To avoid exposing knowledge about the internal structure of the
   network, it is recommended that anycast servers now take advantage of
   the ability to return responses with the anycast address as the
   source address if possible.

Signed-off-by: Francois-Xavier Le Bail <fx.lebail@yahoo.com>
---
v4: update Subject and Documentation, this work also with anycast addresses
    created via API, not just with Subnet-Router anycast addresses.

v5: alternative way, replace ipv6_chk_acast_addr() test by
    ipv6_anycast_destination() test.

 Documentation/networking/ip-sysctl.txt |    7 +++++++
 include/net/ip6_route.h                |    7 +++++++
 include/net/netns/ipv6.h               |    1 +
 net/ipv6/icmp.c                        |    4 +++-
 net/ipv6/sysctl_net_ipv6.c             |    8 ++++++++
 5 files changed, 26 insertions(+), 1 deletion(-)

--
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. 7, 2014, 7:14 p.m. UTC | #1
On Tue, Jan 07, 2014 at 02:57:27PM +0100, Francois-Xavier Le Bail wrote:
> This change allows to follow a recommandation of RFC4942.
> 
> - Add "anycast_src_echo_reply" sysctl to control the use of anycast addresses
>   as source addresses for ICMPv6 echo reply. This sysctl is false by default
>   to preserve existing behavior.
> - Add inline check ipv6_anycast_destination().
> - Use them in icmpv6_echo_reply().
> 
> Reference:
> RFC4942 - IPv6 Transition/Coexistence Security Considerations
>    (http://tools.ietf.org/html/rfc4942#section-2.1.6)
> 
> 2.1.6. Anycast Traffic Identification and Security
> 
>    [...]
>    To avoid exposing knowledge about the internal structure of the
>    network, it is recommended that anycast servers now take advantage of
>    the ability to return responses with the anycast address as the
>    source address if possible.
> 
> Signed-off-by: Francois-Xavier Le Bail <fx.lebail@yahoo.com>

Works and best solution IMHO.

Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>

Thanks,

  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
Hannes Frederic Sowa Jan. 7, 2014, 8:51 p.m. UTC | #2
On Tue, Jan 07, 2014 at 02:57:27PM +0100, Francois-Xavier Le Bail wrote:
> --- a/include/net/netns/ipv6.h
> +++ b/include/net/netns/ipv6.h
> @@ -73,6 +73,7 @@ struct netns_ipv6 {
>  #endif
>  	atomic_t		dev_addr_genid;
>  	atomic_t		rt_genid;
> +	int			anycast_src_echo_reply;
>  };
>  

Sorry, I missed that on first review and you could also do that as a
follow-up:

Could you move anycast_src_echo_reply to netns_sysctl_ipv6?

Thanks,

  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
David Miller Jan. 7, 2014, 8:52 p.m. UTC | #3
From: Francois-Xavier Le Bail <fx.lebail@yahoo.com>
Date: Tue,  7 Jan 2014 14:57:27 +0100

> This change allows to follow a recommandation of RFC4942.
> 
> - Add "anycast_src_echo_reply" sysctl to control the use of anycast addresses
>   as source addresses for ICMPv6 echo reply. This sysctl is false by default
>   to preserve existing behavior.
> - Add inline check ipv6_anycast_destination().
> - Use them in icmpv6_echo_reply().
> 
> Reference:
> RFC4942 - IPv6 Transition/Coexistence Security Considerations
>    (http://tools.ietf.org/html/rfc4942#section-2.1.6)
> 
> 2.1.6. Anycast Traffic Identification and Security
> 
>    [...]
>    To avoid exposing knowledge about the internal structure of the
>    network, it is recommended that anycast servers now take advantage of
>    the ability to return responses with the anycast address as the
>    source address if possible.
> 
> Signed-off-by: Francois-Xavier Le Bail <fx.lebail@yahoo.com>

Looks good, applied, thanks.
--
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
Bill Fink Jan. 7, 2014, 10:55 p.m. UTC | #4
On Tue,  7 Jan 2014, Francois-Xavier Le Bail wrote:

> This change allows to follow a recommandation of RFC4942.
> 
> - Add "anycast_src_echo_reply" sysctl to control the use of anycast addresses
>   as source addresses for ICMPv6 echo reply. This sysctl is false by default
>   to preserve existing behavior.
> - Add inline check ipv6_anycast_destination().
> - Use them in icmpv6_echo_reply().
> 
> Reference:
> RFC4942 - IPv6 Transition/Coexistence Security Considerations
>    (http://tools.ietf.org/html/rfc4942#section-2.1.6)
> 
> 2.1.6. Anycast Traffic Identification and Security
> 
>    [...]
>    To avoid exposing knowledge about the internal structure of the
>    network, it is recommended that anycast servers now take advantage of
>    the ability to return responses with the anycast address as the
>    source address if possible.
> 
> Signed-off-by: Francois-Xavier Le Bail <fx.lebail@yahoo.com>
> ---
> v4: update Subject and Documentation, this work also with anycast addresses
>     created via API, not just with Subnet-Router anycast addresses.
> 
> v5: alternative way, replace ipv6_chk_acast_addr() test by
>     ipv6_anycast_destination() test.

Why is ICMPV6 Echo Reply special?  Can't the internal structure
of the network be divined from other ICMPv6 responses such as
Destination Unreachable, Time Exceeded (Hop Limit), and Parameter
Problem.

					-Bill
--
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
Hannes Frederic Sowa Jan. 7, 2014, 11:01 p.m. UTC | #5
On Tue, Jan 07, 2014 at 05:55:07PM -0500, Bill Fink wrote:
> On Tue,  7 Jan 2014, Francois-Xavier Le Bail wrote:
> 
> > This change allows to follow a recommandation of RFC4942.
> > 
> > - Add "anycast_src_echo_reply" sysctl to control the use of anycast addresses
> >   as source addresses for ICMPv6 echo reply. This sysctl is false by default
> >   to preserve existing behavior.
> > - Add inline check ipv6_anycast_destination().
> > - Use them in icmpv6_echo_reply().
> > 
> > Reference:
> > RFC4942 - IPv6 Transition/Coexistence Security Considerations
> >    (http://tools.ietf.org/html/rfc4942#section-2.1.6)
> > 
> > 2.1.6. Anycast Traffic Identification and Security
> > 
> >    [...]
> >    To avoid exposing knowledge about the internal structure of the
> >    network, it is recommended that anycast servers now take advantage of
> >    the ability to return responses with the anycast address as the
> >    source address if possible.
> > 
> > Signed-off-by: Francois-Xavier Le Bail <fx.lebail@yahoo.com>
> > ---
> > v4: update Subject and Documentation, this work also with anycast addresses
> >     created via API, not just with Subnet-Router anycast addresses.
> > 
> > v5: alternative way, replace ipv6_chk_acast_addr() test by
> >     ipv6_anycast_destination() test.
> 
> Why is ICMPV6 Echo Reply special?  Can't the internal structure
> of the network be divined from other ICMPv6 responses such as
> Destination Unreachable, Time Exceeded (Hop Limit), and Parameter
> Problem.

No, here destination must match the source address so that the other side
handles accordingly when the icmp error is pushed up to the socket layer.

Greetings,

  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
Hannes Frederic Sowa Jan. 7, 2014, 11:17 p.m. UTC | #6
On Wed, Jan 08, 2014 at 12:01:34AM +0100, Hannes Frederic Sowa wrote:
> On Tue, Jan 07, 2014 at 05:55:07PM -0500, Bill Fink wrote:
> > On Tue,  7 Jan 2014, Francois-Xavier Le Bail wrote:
> > 
> > > This change allows to follow a recommandation of RFC4942.
> > > 
> > > - Add "anycast_src_echo_reply" sysctl to control the use of anycast addresses
> > >   as source addresses for ICMPv6 echo reply. This sysctl is false by default
> > >   to preserve existing behavior.
> > > - Add inline check ipv6_anycast_destination().
> > > - Use them in icmpv6_echo_reply().
> > > 
> > > Reference:
> > > RFC4942 - IPv6 Transition/Coexistence Security Considerations
> > >    (http://tools.ietf.org/html/rfc4942#section-2.1.6)
> > > 
> > > 2.1.6. Anycast Traffic Identification and Security
> > > 
> > >    [...]
> > >    To avoid exposing knowledge about the internal structure of the
> > >    network, it is recommended that anycast servers now take advantage of
> > >    the ability to return responses with the anycast address as the
> > >    source address if possible.
> > > 
> > > Signed-off-by: Francois-Xavier Le Bail <fx.lebail@yahoo.com>
> > > ---
> > > v4: update Subject and Documentation, this work also with anycast addresses
> > >     created via API, not just with Subnet-Router anycast addresses.
> > > 
> > > v5: alternative way, replace ipv6_chk_acast_addr() test by
> > >     ipv6_anycast_destination() test.
> > 
> > Why is ICMPV6 Echo Reply special?  Can't the internal structure
> > of the network be divined from other ICMPv6 responses such as
> > Destination Unreachable, Time Exceeded (Hop Limit), and Parameter
> > Problem.
> 
> No, here destination must match the source address so that the other side
> handles accordingly when the icmp error is pushed up to the socket layer.

I forgot to mention, rest of kernel followes the old RFC advise to never
use anycast addresses as source addresses.

I guess this will be weakend with upcoming patches so in future this
depends on socket settings and other tweaks. If that's the case default will
be to also respond with anycast source if original destination was anycast.

Greetings,

  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
David Miller Jan. 7, 2014, 11:33 p.m. UTC | #7
From: Bill Fink <billfink@mindspring.com>
Date: Tue, 7 Jan 2014 17:55:07 -0500

> Why is ICMPV6 Echo Reply special?  Can't the internal structure
> of the network be divined from other ICMPv6 responses such as
> Destination Unreachable, Time Exceeded (Hop Limit), and Parameter
> Problem.

Right, this RFC is talking about source address selection in general,
so this anycast handling should be in a generic place too.
--
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
Hannes Frederic Sowa Jan. 7, 2014, 11:39 p.m. UTC | #8
On Tue, Jan 07, 2014 at 06:33:05PM -0500, David Miller wrote:
> From: Bill Fink <billfink@mindspring.com>
> Date: Tue, 7 Jan 2014 17:55:07 -0500
> 
> > Why is ICMPV6 Echo Reply special?  Can't the internal structure
> > of the network be divined from other ICMPv6 responses such as
> > Destination Unreachable, Time Exceeded (Hop Limit), and Parameter
> > Problem.
> 
> Right, this RFC is talking about source address selection in general,
> so this anycast handling should be in a generic place too.

I think it would be reasonable to change future behavior to always
send back icmp errors with the anycast address (same as original packet
destination). Ping is a bit special as it is used for service discovery.

UDP sockets can use their source address at will. So I still think this change
is reasonable.

--
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. 8, 2014, 8:06 a.m. UTC | #9
On Tue, 1/7/14, Hannes Frederic Sowa <hannes@stressinduktion.org> wrote:

> On Tue, Jan 07, 2014 at 02:57:27PM +0100, Francois-Xavier Le Bail wrote:
> > This change allows to follow a recommandation of RFC4942.
> > 
> > - Add "anycast_src_echo_reply" sysctl to control the use of anycast addresses
> >   as source addresses for ICMPv6 echo reply. This sysctl is false by default
> >   to preserve existing behavior.
> > - Add inline check ipv6_anycast_destination().
> > - Use them in icmpv6_echo_reply().
 
> Works and best solution IMHO.

Yes. Thank you for testing.

BR
François-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. 8, 2014, 8:17 a.m. UTC | #10
On Tue, 1/7/14, Hannes Frederic Sowa <hannes@stressinduktion.org> wrote:

> On Tue, Jan 07, 2014 at 02:57:27PM +0100, Francois-Xavier Le Bail wrote:
> > --- a/include/net/netns/ipv6.h
> > +++ b/include/net/netns/ipv6.h
> > @@ -73,6 +73,7 @@ struct netns_ipv6 {
> >  #endif
> >  	atomic_t		dev_addr_genid;
> >  	atomic_t		rt_genid;
> > +	int			anycast_src_echo_reply;
> >  };

> Sorry, I missed that on first review and you could also do that as a
> follow-up:

> Could you move anycast_src_echo_reply to netns_sysctl_ipv6?

I can do that, but please explain what this change is needed.

BR
François-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
Hannes Frederic Sowa Jan. 8, 2014, 8:22 a.m. UTC | #11
On Wed, Jan 08, 2014 at 12:17:46AM -0800, François-Xavier Le Bail wrote:
> On Tue, 1/7/14, Hannes Frederic Sowa <hannes@stressinduktion.org> wrote:
> 
> > On Tue, Jan 07, 2014 at 02:57:27PM +0100, Francois-Xavier Le Bail wrote:
> > > --- a/include/net/netns/ipv6.h
> > > +++ b/include/net/netns/ipv6.h
> > > @@ -73,6 +73,7 @@ struct netns_ipv6 {
> > >  #endif
> > >  	atomic_t		dev_addr_genid;
> > >  	atomic_t		rt_genid;
> > > +	int			anycast_src_echo_reply;
> > >  };
> 
> > Sorry, I missed that on first review and you could also do that as a
> > follow-up:
> 
> > Could you move anycast_src_echo_reply to netns_sysctl_ipv6?
> 
> I can do that, but please explain what this change is needed.

I think it is just a matter of style so that the ipv6 knobs are kept
together.

Greetings,

  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. 8, 2014, 9:56 a.m. UTC | #12
On Tue, 1/7/14, Hannes Frederic Sowa <hannes@stressinduktion.org> wrote:

> I forgot to mention, rest of kernel followes the old RFC
> advise to never
> use anycast addresses as source addresses.
 
> I guess this will be weakend with upcoming patches so in
> future this
> depends on socket settings and other tweaks. If that's the
> case default will
> be to also respond with anycast source if original
> destination was anycast.
 
The next patch will address the datagrams case.

BR
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
diff mbox

Patch

diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index d71afa8..7373115 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1094,6 +1094,13 @@  bindv6only - BOOLEAN
 
 	Default: FALSE (as specified in RFC3493)
 
+anycast_src_echo_reply - BOOLEAN
+	Controls the use of anycast addresses as source addresses for ICMPv6
+	echo reply
+	TRUE:  enabled
+	FALSE: disabled
+	Default: FALSE
+
 IPv6 Fragmentation:
 
 ip6frag_high_thresh - INTEGER
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 1fb6cdd..017badb 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -152,6 +152,13 @@  static inline bool ipv6_unicast_destination(const struct sk_buff *skb)
 	return rt->rt6i_flags & RTF_LOCAL;
 }
 
+static inline bool ipv6_anycast_destination(const struct sk_buff *skb)
+{
+	struct rt6_info *rt = (struct rt6_info *) skb_dst(skb);
+
+	return rt->rt6i_flags & RTF_ANYCAST;
+}
+
 int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
 
 static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 0fb2401..76fc7d1 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -73,6 +73,7 @@  struct netns_ipv6 {
 #endif
 	atomic_t		dev_addr_genid;
 	atomic_t		rt_genid;
+	int			anycast_src_echo_reply;
 };
 
 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 5d42009..9a809a4 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -556,7 +556,9 @@  static void icmpv6_echo_reply(struct sk_buff *skb)
 
 	saddr = &ipv6_hdr(skb)->daddr;
 
-	if (!ipv6_unicast_destination(skb))
+	if (!ipv6_unicast_destination(skb) &&
+	    !(net->ipv6.anycast_src_echo_reply &&
+	      ipv6_anycast_destination(skb)))
 		saddr = NULL;
 
 	memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 107b2f1..6b6a2c8 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -24,6 +24,13 @@  static struct ctl_table ipv6_table_template[] = {
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec
 	},
+	{
+		.procname	= "anycast_src_echo_reply",
+		.data		= &init_net.ipv6.anycast_src_echo_reply,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec
+	},
 	{ }
 };
 
@@ -51,6 +58,7 @@  static int __net_init ipv6_sysctl_net_init(struct net *net)
 	if (!ipv6_table)
 		goto out;
 	ipv6_table[0].data = &net->ipv6.sysctl.bindv6only;
+	ipv6_table[1].data = &net->ipv6.anycast_src_echo_reply;
 
 	ipv6_route_table = ipv6_route_sysctl_init(net);
 	if (!ipv6_route_table)