1

I set up a 6to4 SIT tunnel on MikroTik following the example for Hurricane Electric in the MikroTik help files.

It worked, but the connection to some resources was painstakingly slow and often timed out. For example, download speeds from default servers during upgrading and reconfiguration of guix lingered around 50 KiB/s and typically failed eventually when downloading the kernel, probably because it is a large package.

The tech support of the tunnel broker suggested that the MTU of 1280 is too small and 1480 should be used instead. Indeed, if I change the tunnel interface's MTU to that value, the connection speed becomes normal and counts in MiBs. I do not know why this works, but probably because at some point the networking equipment does not need to break the larger packets into smaller fragments which would require some overhead.

But I run into a different problem: connections to some servers hang. guix pull hangs. Running curl -v against a problematic URL results in TLS negotiation timing out (curl: (28) SSL connection timeout) or a cryptography library failure (curl: (35) gnutls_handshake() failed: Помилка у функції pull.).

Pinging the server works, but pinging with a message at the size of the MTU (with ping6 -s followed by the number of octets) receives a response Packet too big for the first ping and then drops the rest. A TCP connection succeeds, but the TLS negotiation times out. The MTU is too large for the connection to this server.

RFC 4213 provides:

A node using static tunnel MTU treats the tunnel interface as having a fixed-interface MTU. By default, the MTU MUST be between 1280 and 1480 bytes (inclusive), but it SHOULD be 1280 bytes.

RFC 6343 has a section on "PMTUD Failure", which links to RFC 2923 suggesting to fall back to MTU 1280 for IPv6 unless it is possible to fix "the ICMP black hole".

The example configuration for MikroTik suggests using 1280 to avoid the necessity for MTU negotiation. There is also clamp-tcp-mss setting which is turned on by default:

Controls whether to change MSS size for received TCP SYN packets. When enabled, a router will change the MSS size for received TCP SYN packets if the current MSS size exceeds the tunnel interface MTU (taking into account the TCP/IP overhead). The received encapsulated packet will still contain the original MSS, and only after decapsulation the MSS is changed.

It might explain why ping occasionally allows me to successfully send enormous messages up to 65527 (apparently 65535 minus 8) over the tunnel. However, this tries to match the tunnel MTU while I need to determine the MTU per connection, which might be less than the tunnel MTU. How do I do that, so that I do not need to lower my tunnel MTU?

1 Answers1

1

It looks like the default configuration on MikroTik for IPv6 lacks path MTU discovery. Adding this rule to IPv6 firewall helped (source):

/ipv6 firewall mangle
add action=change-mss chain=forward new-mss=clamp-to-pmtu passthrough=yes protocol=tcp tcp-flags=syn

The meaning of the options:

change-mss - change Maximum Segment Size field value of the packet to a value specified by the new-mss parameter

Clamp-to-pmtu feature sets (DF) bit in the IP header to dynamically discover the PMTU of a path. Host sends all datagrams on that path with the DF bit set until receives ICMP Destination Unreachable messages with a code meaning "fragmentation needed and DF set". Upon receipt of such a message, the source host reduces its assumed PMTU for the path.

syn - new connection

So, the rule tries to figure out the MTU for each new connection. (The above-quoted description is apparently for IPv4. IPv6 specification expects that there is no fragmentation, so no DF bit can be used.)