IPv6 firewall filter - invalid conn drop = no traffic flows

RB750G, running 4.17. IPv6 stopped working. Reduced my firewall filter set for IPv6 to just the below when troubleshooting why IPv6 wasn’t working anymore via an HE 6to4 tunnel.

[felix@rb750g] /ipv6 firewall filter> exp
# mar/05/2011 11:20:54 by RouterOS 4.17
# software id = 9BLJ-TZ8Y
#
/ipv6 firewall filter
add action=accept chain=input comment="" connection-state=established disabled=no
add action=accept chain=input comment="" connection-state=related disabled=no
add action=drop chain=input comment="" connection-state=invalid disabled=no
add action=accept chain=input comment="" disabled=no

I can’t ping ipv6.google.com.

sh-3.2$ ping6 ipv6.google.com
PING6(56=40+8+8 bytes) 2001:470:f037:1:c62c:3ff:fe10:750e --> 2001:4860:8004::63
Request timeout for icmp_seq=0
Request timeout for icmp_seq=1
Request timeout for icmp_seq=2
^C
--- ipv6.l.google.com ping6 statistics ---
4 packets transmitted, 0 packets received, 100.0% packet loss

sh-3.2$

I disable just the rule that drops invalid connections in the input chain:

[felix@rb750g] /ipv6 firewall filter> pri
Flags: X - disabled, I - invalid, D - dynamic 
 0   chain=input action=accept connection-state=established 

 1   chain=input action=accept connection-state=related 

 2   chain=input action=drop connection-state=invalid 

 3   chain=input action=accept 
[felix@rb750g] /ipv6 firewall filter> dis 2
[felix@rb750g] /ipv6 firewall filter> pri
Flags: X - disabled, I - invalid, D - dynamic 
 0   chain=input action=accept connection-state=established 

 1   chain=input action=accept connection-state=related 

 2 X chain=input action=drop connection-state=invalid 

 3   chain=input action=accept 
[felix@rb750g] /ipv6 firewall filter>

And I can ping fine.

sh-3.2$ ping6 ipv6.google.com
PING6(56=40+8+8 bytes) 2001:470:f037:1:c62c:3ff:fe10:750e --> 2001:4860:8004::63
16 bytes from 2001:4860:8004::63, icmp_seq=0 hlim=52 time=309.807 ms
16 bytes from 2001:4860:8004::63, icmp_seq=1 hlim=52 time=46.118 ms
16 bytes from 2001:4860:8004::63, icmp_seq=2 hlim=52 time=59.523 ms
^C
--- ipv6.l.google.com ping6 statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 46.118/138.483/309.807/121.268 ms

sh-3.2$

Am I missing something blindingly obvious here, or is that a huge bug?

This appears to be due to neighbor solicitations being treated as ‘invalid’. With this rule set:

[felix@rb750g] /ipv6 firewall filter> p
Flags: X - disabled, I - invalid, D - dynamic 
 0   chain=input action=accept connection-state=established 
 1   chain=input action=accept connection-state=related 
 2 X chain=input action=accept protocol=icmpv6 
 3   chain=input action=drop connection-state=invalid 
 4   chain=input action=drop

I get the following packet dump on the machine trying to ping6 ipv6.google.com:

sh-3.2# tcpdump -n -i en0 icmp6
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en0, link-type EN10MB (Ethernet), capture size 65535 bytes
12:08:40.788603 IP6 2001:470:f037:1:c62c:3ff:fe10:750e > ff02::1:ff70:1299: ICMP6, neighbor solicitation, who has fe80::20c:42ff:fe70:1299, length 32
12:08:41.788733 IP6 2001:470:f037:1:c62c:3ff:fe10:750e > ff02::1:ff70:1299: ICMP6, neighbor solicitation, who has fe80::20c:42ff:fe70:1299, length 32
12:08:42.788868 IP6 2001:470:f037:1:c62c:3ff:fe10:750e > ff02::1:ff70:1299: ICMP6, neighbor solicitation, who has fe80::20c:42ff:fe70:1299, length 32
12:08:44.789009 IP6 2001:470:f037:1:c62c:3ff:fe10:750e > ff02::1:ff70:1299: ICMP6, neighbor solicitation, who has fe80::20c:42ff:fe70:1299, length 32
12:08:45.789137 IP6 2001:470:f037:1:c62c:3ff:fe10:750e > ff02::1:ff70:1299: ICMP6, neighbor solicitation, who has fe80::20c:42ff:fe70:1299, length 32
^C
5 packets captured
2898 packets received by filter
0 packets dropped by kernel
sh-3.2#

I turn on the disabled rule that unconditionally accepts all ICMPv6, I get an neighbor advertisement back:

sh-3.2# tcpdump -n -i en0 icmp6
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en0, link-type EN10MB (Ethernet), capture size 65535 bytes
12:09:58.796735 IP6 2001:470:f037:1:c62c:3ff:fe10:750e > ff02::1:ff70:1299: ICMP6, neighbor solicitation, who has fe80::20c:42ff:fe70:1299, length 32
12:09:58.797384 IP6 fe80::20c:42ff:fe70:1299 > 2001:470:f037:1:c62c:3ff:fe10:750e: ICMP6, neighbor advertisement, tgt is fe80::20c:42ff:fe70:1299, length 32
12:09:58.797458 IP6 2001:470:f037:1:c62c:3ff:fe10:750e > 2001:4860:8004::63: ICMP6, echo request, seq 0, length 16
12:09:58.844435 IP6 2001:4860:8004::63 > 2001:470:f037:1:c62c:3ff:fe10:750e: ICMP6, echo reply, seq 0, length 16
12:09:59.398935 IP6 2001:470:f037:1:c62c:3ff:fe10:750e > 2001:4860:8004::63: ICMP6, echo request, seq 1, length 16
12:09:59.472874 IP6 2001:4860:8004::63 > 2001:470:f037:1:c62c:3ff:fe10:750e: ICMP6, echo reply, seq 1, length 16
12:10:00.399017 IP6 2001:470:f037:1:c62c:3ff:fe10:750e > 2001:4860:8004::63: ICMP6, echo request, seq 2, length 16
12:10:00.448445 IP6 2001:4860:8004::63 > 2001:470:f037:1:c62c:3ff:fe10:750e: ICMP6, echo reply, seq 2, length 16
12:10:01.399013 IP6 2001:470:f037:1:c62c:3ff:fe10:750e > 2001:4860:8004::63: ICMP6, echo request, seq 3, length 16
12:10:01.449038 IP6 2001:4860:8004::63 > 2001:470:f037:1:c62c:3ff:fe10:750e: ICMP6, echo reply, seq 3, length 16
12:10:02.398997 IP6 2001:470:f037:1:c62c:3ff:fe10:750e > 2001:4860:8004::63: ICMP6, echo request, seq 4, length 16
12:10:02.463431 IP6 2001:4860:8004::63 > 2001:470:f037:1:c62c:3ff:fe10:750e: ICMP6, echo reply, seq 4, length 16
12:10:03.398944 IP6 2001:470:f037:1:c62c:3ff:fe10:750e > 2001:4860:8004::63: ICMP6, echo request, seq 5, length 16
12:10:03.446907 IP6 2001:4860:8004::63 > 2001:470:f037:1:c62c:3ff:fe10:750e: ICMP6, echo reply, seq 5, length 16
12:10:03.788352 IP6 fe80::20c:42ff:fe70:1299 > 2001:470:f037:1:c62c:3ff:fe10:750e: ICMP6, neighbor solicitation, who has 2001:470:f037:1:c62c:3ff:fe10:750e, length 32
12:10:03.788387 IP6 fe80::c62c:3ff:fe10:750e > fe80::20c:42ff:fe70:1299: ICMP6, neighbor advertisement, tgt is 2001:470:f037:1:c62c:3ff:fe10:750e, length 24
^C
16 packets captured
9907 packets received by filter
0 packets dropped by kernel
sh-3.2#

Is this due to the fact that the global IPv6 address of the node is soliciting the link local address of the router? The link local is the default gateway for the node:

sh-3.2$ route -n get -inet6 default
   route to: ::
destination: ::
       mask: default
    gateway: fe80::20c:42ff:fe70:1299%en0
  interface: en0
      flags: <UP,GATEWAY,DONE,PRCLONING>
 recvpipe  sendpipe  ssthresh  rtt,msec    rttvar  hopcount      mtu     expire
       0         0         0         0         0         0      1500         0 
sh-3.2$

Yet the node treats the global as the preferred address. I’ll try and run some more tests with other node operating systems next week, I guess. Still not sure why the packet filter treats them as invalid if the stack handles them in fine when they make it through.

Well, all the RAs certainly come from the router’s link local address, so it should be the default gateway. According to all documentation I can find that’s expected, gateways are always link local when acquired via stateless auto configuration.
In that case the ICMPv6 NS is a valid request, and should not match connection-state=invalid.

I think I ran into this problem a while back and ended up just allowing all ICMPv6 for the time being… I had a note on that rule to ‘come back and fix’ : )

According to support it’s fixed in RC10. Tried RC11 just now, and I can’t recreate the issue.

Still wish it was fixed in stable as well.