Hi folk,
Here's an ICMPv6 echo request with hlim 1 coming from the WAN with destination a host that's behind the router (AAAA:BBBB:CCCC:c::202
):
~ # tcpdump -nnvvi eth2 "icmp6 and (src XXXX:YYYY:ZZZZ:17::30 or dst XXXX:YYYY:ZZZZ:17::30)"
...
23:37:46.452078 IP6 (hlim 1, next-header ICMPv6 (58) payload length: 64) XXXX:YYYY:ZZZZ:17::30 > AAAA:BBBB:CCCC:c::202: [icmp6 sum ok] ICMP6, echo request, seq 1
eth2
is my wan interface. Why isn't the router sending back an ICMP6, time exceeded in-transit
back to XXXX:YYYY:ZZZZ:17::30
?
If I increase the hop limit by 1 in the source (XXXX:YYYY:ZZZZ:17::30
) the packet is delivered fine downstream as expected.
Just in case I did:
ip6tables -I OUTPUT 1 -d XXXX:YYYY:ZZZZ:17::30 -j ACCEPT
to remove the firewall from the equation but it didn't help.
Could anybody please shed some light on this?
I was looking at the kernel network stats to see if:
And they're all zeroed:
~ # nstat -a -z | grep "Ip6InHdrErrors\|Icmp6OutTimeExcds"
Ip6InHdrErrors 0 0.0
Icmp6OutTimeExcds 0 0.0
Actually all the counters in /proc/net/snmp6
are zeroed.
Making it even more difficult to debug this I'm running out of ideas.
This is why there are no ICMP6 stats:
@@ -123,6 +123,21 @@ struct linux_xfrm_mib {
#define DECLARE_SNMP_STAT(type, name) \
extern __typeof__(type) __percpu *name
+#ifdef CONFIG_PROC_STRIPPED
+#define __SNMP_STATS_DUMMY(mib) \
+ do { (void) mib->mibs[0]; } while(0)
+
+#define __SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
+#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) __SNMP_STATS_DUMMY(mib)
+#define SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
+#define SNMP_DEC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
+#define __SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib)
+#define SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib)
+#define SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib)
+#define __SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib)
+
+#else
+
#define __SNMP_INC_STATS(mib, field) \
__this_cpu_inc(mib->mibs[field])
__IP6_INC_STATS()
-> _DEVINC()
-> SNMP_INC_STATS64()
-> SNMP_INC_STATS()
-> __SNMP_STATS_DUMMY()
"debloat"
1 Like
avioneta:
"debloat"
Sometimes that effort seems to be excessive though it probably is difficult to find a balance in support of devices with lesser hardware capacities.
1 Like
If I do the same exercise but the other way around (sending ICMPv6 echo-requests to the Internet from the LAN with a low-enough hop count so the router is the last allowed hop) the router generates and sends the expected ICMPv6 time-exceeded traffic:
16:21:46.201107 IP6 (flowlabel 0x87b65, hlim 1, next-header ICMPv6 (58) payload length: 64) AAAA:BBBB:CCCC:c::202 > XXXX:YYYY:ZZZZ:17::30: [icmp6 sum ok] ICMP6, echo request, seq 1
16:21:46.201213 IP6 (flowlabel 0x35edf, hlim 64, next-header ICMPv6 (58) payload length: 112) AAAA:BBBB:CCCC:1::1 > AAAA:BBBB:CCCC:c::202: [icmp6 sum ok] ICMP6, time exceeded in-transit for 2001:1458:d00:17::30
The output firewall rules for the wan interface (eth2
) and the interface where the above traffic was generated (br-lan
) are the same -> accept all.
I've logged as well all ICMPv6 traffic in OUTPUT with a catch all -j LOG
as first rule and the missing traffic never reaches netfliter which points me to the fact that the kernel might not been generating the packet at all.
I must be missing something stupid. The consequence of this is that a traceroute6 passing though the router will always have a missing hop due to the router not emitting ICMPv6 time-exceeded towards the WAN. Can't believe this is a general problem. It's too obvious to miss.