Skip to content

Commit 7ab7545

Browse files
Mahesh Bandewarkuba-moo
authored andcommitted
ipv6: add icmpv6_error_anycast_as_unicast for ICMPv6
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>
1 parent b7b871f commit 7ab7545

4 files changed

Lines changed: 22 additions & 2 deletions

File tree

Documentation/networking/ip-sysctl.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2721,6 +2721,13 @@ echo_ignore_anycast - BOOLEAN
27212721

27222722
Default: 0
27232723

2724+
error_anycast_as_unicast - BOOLEAN
2725+
If set to 1, then the kernel will respond with ICMP Errors
2726+
resulting from requests sent to it over the IPv6 protocol destined
2727+
to anycast address essentially treating anycast as unicast.
2728+
2729+
Default: 0
2730+
27242731
xfrm6_gc_thresh - INTEGER
27252732
(Obsolete since linux-4.14)
27262733
The threshold at which we will start garbage collecting for IPv6

include/net/netns/ipv6.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct netns_sysctl_ipv6 {
5555
u64 ioam6_id_wide;
5656
bool skip_notify_on_dev_down;
5757
u8 fib_notify_on_flag_change;
58+
u8 icmpv6_error_anycast_as_unicast;
5859
};
5960

6061
struct netns_ipv6 {

net/ipv6/af_inet6.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,7 @@ static int __net_init inet6_net_init(struct net *net)
952952
net->ipv6.sysctl.icmpv6_echo_ignore_all = 0;
953953
net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0;
954954
net->ipv6.sysctl.icmpv6_echo_ignore_anycast = 0;
955+
net->ipv6.sysctl.icmpv6_error_anycast_as_unicast = 0;
955956

956957
/* By default, rate limit error messages.
957958
* Except for pmtu discovery, it would break it.

net/ipv6/icmp.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,10 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net,
362362

363363
/*
364364
* We won't send icmp if the destination is known
365-
* anycast.
365+
* anycast unless we need to treat anycast as unicast.
366366
*/
367-
if (ipv6_anycast_destination(dst, &fl6->daddr)) {
367+
if (!READ_ONCE(net->ipv6.sysctl.icmpv6_error_anycast_as_unicast) &&
368+
ipv6_anycast_destination(dst, &fl6->daddr)) {
368369
net_dbg_ratelimited("icmp6_send: acast source\n");
369370
dst_release(dst);
370371
return ERR_PTR(-EINVAL);
@@ -1195,6 +1196,15 @@ static struct ctl_table ipv6_icmp_table_template[] = {
11951196
.mode = 0644,
11961197
.proc_handler = proc_do_large_bitmap,
11971198
},
1199+
{
1200+
.procname = "error_anycast_as_unicast",
1201+
.data = &init_net.ipv6.sysctl.icmpv6_error_anycast_as_unicast,
1202+
.maxlen = sizeof(u8),
1203+
.mode = 0644,
1204+
.proc_handler = proc_dou8vec_minmax,
1205+
.extra1 = SYSCTL_ZERO,
1206+
.extra2 = SYSCTL_ONE,
1207+
},
11981208
{ },
11991209
};
12001210

@@ -1212,6 +1222,7 @@ struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net)
12121222
table[2].data = &net->ipv6.sysctl.icmpv6_echo_ignore_multicast;
12131223
table[3].data = &net->ipv6.sysctl.icmpv6_echo_ignore_anycast;
12141224
table[4].data = &net->ipv6.sysctl.icmpv6_ratemask_ptr;
1225+
table[5].data = &net->ipv6.sysctl.icmpv6_error_anycast_as_unicast;
12151226
}
12161227
return table;
12171228
}

0 commit comments

Comments
 (0)