Skip to content

Commit

Permalink
ipv6: add icmpv6_error_anycast_as_unicast for ICMPv6
Browse files Browse the repository at this point in the history
ICMPv6 error packets are not sent to the anycast destinations and this
prevents things like traceroute from working. So create a setting similar
to ECHO when dealing with Anycast sources (icmpv6_echo_ignore_anycast).

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Maciej Żenczykowski <maze@google.com>
Link: https://lore.kernel.org/r/20230419013238.2691167-1-maheshb@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Mahesh Bandewar authored and Jakub Kicinski committed Apr 21, 2023
1 parent b7b871f commit 7ab7545
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 2 deletions.
7 changes: 7 additions & 0 deletions Documentation/networking/ip-sysctl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2721,6 +2721,13 @@ echo_ignore_anycast - BOOLEAN

Default: 0

error_anycast_as_unicast - BOOLEAN
If set to 1, then the kernel will respond with ICMP Errors
resulting from requests sent to it over the IPv6 protocol destined
to anycast address essentially treating anycast as unicast.

Default: 0

xfrm6_gc_thresh - INTEGER
(Obsolete since linux-4.14)
The threshold at which we will start garbage collecting for IPv6
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 @@ -55,6 +55,7 @@ struct netns_sysctl_ipv6 {
u64 ioam6_id_wide;
bool skip_notify_on_dev_down;
u8 fib_notify_on_flag_change;
u8 icmpv6_error_anycast_as_unicast;
};

struct netns_ipv6 {
Expand Down
1 change: 1 addition & 0 deletions net/ipv6/af_inet6.c
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,7 @@ static int __net_init inet6_net_init(struct net *net)
net->ipv6.sysctl.icmpv6_echo_ignore_all = 0;
net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0;
net->ipv6.sysctl.icmpv6_echo_ignore_anycast = 0;
net->ipv6.sysctl.icmpv6_error_anycast_as_unicast = 0;

/* By default, rate limit error messages.
* Except for pmtu discovery, it would break it.
Expand Down
15 changes: 13 additions & 2 deletions net/ipv6/icmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,9 +362,10 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net,

/*
* We won't send icmp if the destination is known
* anycast.
* anycast unless we need to treat anycast as unicast.
*/
if (ipv6_anycast_destination(dst, &fl6->daddr)) {
if (!READ_ONCE(net->ipv6.sysctl.icmpv6_error_anycast_as_unicast) &&
ipv6_anycast_destination(dst, &fl6->daddr)) {
net_dbg_ratelimited("icmp6_send: acast source\n");
dst_release(dst);
return ERR_PTR(-EINVAL);
Expand Down Expand Up @@ -1195,6 +1196,15 @@ static struct ctl_table ipv6_icmp_table_template[] = {
.mode = 0644,
.proc_handler = proc_do_large_bitmap,
},
{
.procname = "error_anycast_as_unicast",
.data = &init_net.ipv6.sysctl.icmpv6_error_anycast_as_unicast,
.maxlen = sizeof(u8),
.mode = 0644,
.proc_handler = proc_dou8vec_minmax,
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
{ },
};

Expand All @@ -1212,6 +1222,7 @@ struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net)
table[2].data = &net->ipv6.sysctl.icmpv6_echo_ignore_multicast;
table[3].data = &net->ipv6.sysctl.icmpv6_echo_ignore_anycast;
table[4].data = &net->ipv6.sysctl.icmpv6_ratemask_ptr;
table[5].data = &net->ipv6.sysctl.icmpv6_error_anycast_as_unicast;
}
return table;
}
Expand Down

0 comments on commit 7ab7545

Please sign in to comment.