Skip to content

Commit

Permalink
IPv6: add the option to use anycast addresses as source addresses in …
Browse files Browse the repository at this point in the history
…echo reply

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>
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 7, 2014
1 parent 9ba75fb commit 509aba3
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 1 deletion.
7 changes: 7 additions & 0 deletions Documentation/networking/ip-sysctl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions include/net/ip6_route.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions include/net/netns/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion net/ipv6/icmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
8 changes: 8 additions & 0 deletions net/ipv6/sysctl_net_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
{ }
};

Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 509aba3

Please sign in to comment.