IP Tunnels: IPIP, 6in4, and 4in6
IP Tunnels: IPIP, 6in4, and 4in6
Section titled “IP Tunnels: IPIP, 6in4, and 4in6”RouterOS supports three lightweight IP encapsulation tunnel types for carrying traffic across an existing network without complex protocol machinery:
| Type | Interface | Carries | Over | IP protocol |
|---|---|---|---|---|
| IPIP | /interface ipip | IPv4 | IPv4 | 4 |
| 6in4 | /interface 6to4 | IPv6 | IPv4 | 41 |
| 4in6 | /interface 4in6 | IPv4 | IPv6 | 4 |
None of these provide encryption. For encrypted tunnels, layer IPsec on top or use WireGuard instead.
Concepts
Section titled “Concepts”How IP encapsulation tunnels work
Section titled “How IP encapsulation tunnels work”Each tunnel type creates a virtual point-to-point interface. RouterOS wraps the original IP packet in an outer header addressed to the remote tunnel endpoint. The receiving router strips the outer header and delivers the inner packet normally.
Original packet: [ Inner IP header | Payload ]
After encapsulation: [ Outer IP header | Inner IP header | Payload ]- Transport addresses (
local-address,remote-address) — the outer IP header. Must be routable between endpoints. - Tunnel addresses — IP/IPv6 addresses assigned to the tunnel interface. Used for routing over the tunnel.
MTU overview
Section titled “MTU overview”Encapsulation adds an outer header, reducing the space available for the inner payload. On a standard 1500-byte Ethernet path:
| Tunnel type | Outer header | Recommended tunnel MTU | Safe TCP MSS |
|---|---|---|---|
| IPIP (IPv4-in-IPv4) | 20 bytes IPv4 | 1480 | 1440 |
| 6in4 (IPv6-in-IPv4) | 20 bytes IPv4 | 1480 | 1440 |
| 4in6 (IPv4-in-IPv6) | 40 bytes IPv6 | 1460 | 1420 |
If the physical path MTU between endpoints is smaller than 1500 bytes (e.g., over PPPoE at 1492), subtract the same overhead from 1492 instead.
IPIP Tunnel (IPv4-in-IPv4)
Section titled “IPIP Tunnel (IPv4-in-IPv4)”IPIP is the simplest IP tunnel: one IPv4 packet wrapped in another. Use it when you need to carry IPv4 unicast between two endpoints with minimum overhead. It carries no keepalive or multicast support.
Create the interface
Section titled “Create the interface”/interface ipip add \ name=ipip-to-branch \ local-address=198.51.100.1 \ remote-address=203.0.113.2Key properties:
| Property | Default | Description |
|---|---|---|
local-address | 0.0.0.0 | Source IPv4 for the outer header. Set explicitly when you have multiple public IPs. |
remote-address | — | Destination IPv4 for the outer header. |
mtu | 1480 | Tunnel MTU (1500 − 20 bytes overhead). |
clamp-tcp-mss | yes | Rewrites TCP SYN MSS to prevent fragmentation black holes. |
allow-fast-path | yes | Enable fast-path/hardware acceleration. |
dscp | inherit | DSCP in the outer header. inherit copies from the inner packet. |
Assign an address and add routes
Section titled “Assign an address and add routes”# Assign a /30 to the tunnel interface/ip address add address=10.10.10.1/30 interface=ipip-to-branch
# Route the remote LAN via the tunnel peer IP/ip route add dst-address=192.168.20.0/24 gateway=10.10.10.2Firewall — allow IPIP
Section titled “Firewall — allow IPIP”Permit IP protocol 4 (ipencap) on the input chain from the peer’s transport address:
/ip firewall filter add \ chain=input \ protocol=ipencap \ src-address=203.0.113.2 \ action=accept \ comment="Allow IPIP from branch"Place this before any default drop rule.
Verify
Section titled “Verify”# Interface flags: R = running/interface ipip print detail
# Ping the remote tunnel IP/ping 10.10.10.2
# Confirm route is active/ip route print where dst-address=192.168.20.0/246in4 Tunnel (IPv6-over-IPv4)
Section titled “6in4 Tunnel (IPv6-over-IPv4)”6in4 carries IPv6 packets inside IPv4 (IP protocol 41). This is how Hurricane Electric (HE) tunnel broker endpoints connect an IPv6-capable router to the global IPv6 internet over an IPv4 uplink.
RouterOS uses the /interface 6to4 menu for 6in4 tunnels. When remote-address is set to the HE server IPv4, it is a static point-to-point 6in4 tunnel — not the automatic 2002::/16 6to4 mechanism.
Hurricane Electric setup
Section titled “Hurricane Electric setup”From your HE tunnel broker details page you need four values:
| HE field | RouterOS parameter |
|---|---|
| Server IPv4 Address | remote-address |
| Client IPv4 Address | local-address |
| Server IPv6 Address | IPv6 default route gateway |
| Client IPv6 Address | address assigned to the tunnel interface |
Create the interface
Section titled “Create the interface”/interface 6to4 add \ name=he-ipv6 \ local-address=203.0.113.2 \ remote-address=216.66.80.30 \ mtu=1480Replace 203.0.113.2 with your router’s public IPv4 (must match what HE has registered) and 216.66.80.30 with HE’s server IPv4 for your tunnel.
Assign the tunnel IPv6 address
Section titled “Assign the tunnel IPv6 address”# HE assigns a /64 for the tunnel link; assign the client side/ipv6 address add \ interface=he-ipv6 \ address=2001:db8:1234:1::2/64 \ advertise=noAdd the IPv6 default route
Section titled “Add the IPv6 default route”/ipv6 route add dst-address=::/0 gateway=2001:db8:1234:1::12001:db8:1234:1::1 is HE’s server-side tunnel IPv6 (the ::1 address in the /64 HE allocates for the tunnel link).
Use the routed prefix on the LAN
Section titled “Use the routed prefix on the LAN”HE typically routes a /48 or additional /64 to your endpoint. Assign addresses from that block to internal interfaces:
# Assign a /64 from your routed prefix to the LAN bridge/ipv6 address add \ interface=bridge-lan \ address=2001:db8:abcd:1::1/64 \ advertise=yesFirewall — allow 6in4 traffic
Section titled “Firewall — allow 6in4 traffic”6in4 uses IPv4 protocol 41. Permit it on the IPv4 input chain:
/ip firewall filter add \ chain=input \ protocol=41 \ src-address=216.66.80.30 \ action=accept \ comment="Allow 6in4 from HE tunnel server"Important: protocol 41 and NAT
Section titled “Important: protocol 41 and NAT”HE 6in4 requires IPv4 protocol 41 to reach your router unmodified. Protocol 41 cannot traverse NAT (it has no port numbers). If your router is behind CGNAT or a carrier NAT that does not pass protocol 41, the tunnel will not work. You need a public IPv4 address directly on the router’s WAN interface.
Verify
Section titled “Verify”# Check interface state/interface 6to4 print detail
# Ping HE's server-side tunnel IPv6/ping 2001:db8:1234:1::1
# Ping an external IPv6 address/ping 2606:4700:4700::1111
# Check IPv6 routing table/ipv6 route print4in6 Tunnel (IPv4-over-IPv6)
Section titled “4in6 Tunnel (IPv4-over-IPv6)”4in6 carries IPv4 packets inside IPv6 (IP protocol 4). Use it when you have IPv6 connectivity between two sites but need to carry IPv4 traffic between them — for example, during a network migration or when an upstream only provides IPv6 transit.
4in6 is point-to-point only. Both endpoints need reachable IPv6 transport addresses.
Create the interface
Section titled “Create the interface”/interface 4in6 add \ name=tun4 \ local-address=2001:db8:1::1 \ remote-address=2001:db8:2::1Key properties:
| Property | Default | Description |
|---|---|---|
local-address | :: | Source IPv6 for the outer header. |
remote-address | — | Destination IPv6 for the outer header. |
mtu | 1460 | Tunnel MTU (1500 − 40 bytes IPv6 overhead). |
clamp-tcp-mss | yes | Rewrites TCP SYN MSS to prevent fragmentation black holes. |
allow-fast-path | yes | Enable fast-path acceleration. |
dont-fragment | no | Whether to set the DF bit. |
dscp | inherit | DSCP in the outer header. |
keepalive | — | Interval and retry count for keepalive probes. |
Assign an IPv4 address to the tunnel
Section titled “Assign an IPv4 address to the tunnel”Use a /30 for the point-to-point link:
# Local side/ip address add address=10.10.10.1/30 interface=tun4The remote side uses 10.10.10.2/30.
Add routes over the tunnel
Section titled “Add routes over the tunnel”# Route the remote IPv4 LAN via the tunnel peer address/ip route add dst-address=192.0.2.0/24 gateway=10.10.10.2You can also specify the tunnel interface as the gateway directly:
/ip route add dst-address=192.0.2.0/24 gateway=tun4Firewall — allow 4in6 traffic
Section titled “Firewall — allow 4in6 traffic”4in6 uses IPv6 protocol 4 (ipv4). Permit it on the IPv6 input chain:
/ipv6 firewall filter add \ chain=input \ protocol=ipv4 \ src-address=2001:db8:2::1 \ action=accept \ comment="Allow 4in6 from remote"Verify
Section titled “Verify”# Check interface state (R = running)/interface 4in6 print detail
# Ping the remote tunnel IPv4/ping 10.10.10.2
# Ping a host in the remote IPv4 LAN/ping 192.0.2.1
# Check IPv4 route is active/ip route print where dst-address=192.0.2.0/24MTU and MSS Clamping
Section titled “MTU and MSS Clamping”Why tunnel MTU matters
Section titled “Why tunnel MTU matters”Every encapsulated packet gains an outer header. If the resulting outer packet exceeds the physical path MTU, it must be fragmented or dropped. Fragmentation adds latency; misconfigured PMTU Discovery (PMTUD) causes connection stalls (“black holes”).
The standard pattern:
- Set the tunnel interface
mtuto account for encapsulation overhead. - Keep
clamp-tcp-mss=yes(the default) to automatically rewrite TCP SYN MSS. - If PMTUD is broken end-to-end, add a mangle rule to enforce MSS.
MTU reference
Section titled “MTU reference”| Encapsulation | Outer header | Physical path MTU | Tunnel MTU | TCP MSS |
|---|---|---|---|---|
| IPIP | 20 bytes IPv4 | 1500 | 1480 | 1440 |
| 6in4 | 20 bytes IPv4 | 1500 | 1480 | 1440 |
| 4in6 | 40 bytes IPv6 | 1500 | 1460 | 1420 |
| IPIP over PPPoE | 20 bytes IPv4 | 1492 | 1472 | 1432 |
| 4in6 over PPPoE | 40 bytes IPv6 | 1492 | 1452 | 1412 |
Adjusting MTU on an existing tunnel
Section titled “Adjusting MTU on an existing tunnel”# Reduce IPIP tunnel MTU for a PPPoE upstream/interface ipip set ipip-to-branch mtu=1472
# Reduce 4in6 tunnel MTU/interface 4in6 set tun4 mtu=1452Manual MSS clamping with mangle
Section titled “Manual MSS clamping with mangle”If clamp-tcp-mss is not sufficient (e.g., the tunnel is used for forwarded traffic from other hosts), add a mangle rule:
# Clamp TCP MSS on forwarded traffic leaving the tunnel (IPIP example)/ip firewall mangle add \ chain=forward \ action=change-mss \ new-mss=1440 \ protocol=tcp \ tcp-flags=syn \ tcp-mss=1441-65535 \ out-interface=ipip-to-branch \ comment="Clamp MSS for IPIP tunnel"Adjust new-mss and tcp-mss range to match your tunnel type’s values from the table above.
Routing Over Tunnels
Section titled “Routing Over Tunnels”Static routes
Section titled “Static routes”The standard approach for all three tunnel types is to assign a /30 (or /127 for IPv6) to the tunnel interface and use static routes pointing at the peer’s tunnel address:
# IPIP: route remote LAN via peer tunnel IP/ip route add dst-address=192.168.20.0/24 gateway=10.10.10.2
# 4in6: route remote LAN via peer tunnel IP/ip route add dst-address=172.16.0.0/16 gateway=10.20.20.2
# 6in4: default IPv6 route via HE tunnel server/ipv6 route add dst-address=::/0 gateway=2001:db8:1234:1::1Dynamic routing (OSPF/BGP over IPIP)
Section titled “Dynamic routing (OSPF/BGP over IPIP)”IPIP does not support multicast, which OSPF requires for hello packets. To run OSPF over IPIP, use GRE instead — or switch to BGP (unicast only, works natively over IPIP):
# IPIP is unicast only — use BGP for dynamic routing/routing bgp connection add \ name=ibgp-branch \ remote.address=10.10.10.2/32 \ remote.as=65001 \ local.role=ibgpFor OSPF, use a GRE tunnel (which supports multicast) rather than IPIP or 4in6.
Multiple tunnels, single router
Section titled “Multiple tunnels, single router”When a router terminates multiple tunnels, use a dedicated tunnel subnet for each:
# Tunnel to Site B (IPIP)/interface ipip add name=ipip-site-b local-address=198.51.100.1 remote-address=203.0.113.2/ip address add address=10.10.10.1/30 interface=ipip-site-b/ip route add dst-address=192.168.20.0/24 gateway=10.10.10.2
# Tunnel to Site C (IPIP)/interface ipip add name=ipip-site-c local-address=198.51.100.1 remote-address=203.0.113.50/ip address add address=10.10.20.1/30 interface=ipip-site-c/ip route add dst-address=192.168.30.0/24 gateway=10.10.20.2Site-to-Site Example: 4in6
Section titled “Site-to-Site Example: 4in6”Connect Site A (IPv4 LAN 192.168.10.0/24, IPv6 transport 2001:db8:a::1) to Site B (IPv4 LAN 192.168.20.0/24, IPv6 transport 2001:db8:b::1). Tunnel subnet: 10.99.0.0/30.
Site A
Section titled “Site A”# Tunnel interface/interface 4in6 add name=4in6-to-b local-address=2001:db8:a::1 remote-address=2001:db8:b::1
# Tunnel IPv4 address/ip address add address=10.99.0.1/30 interface=4in6-to-b
# Route to Site B LAN/ip route add dst-address=192.168.20.0/24 gateway=10.99.0.2
# Firewall: allow 4in6 protocol from Site B/ipv6 firewall filter add chain=input protocol=ipv4 src-address=2001:db8:b::1 action=accept comment="4in6 from Site B"/ip firewall filter add chain=forward in-interface=4in6-to-b action=accept comment="4in6 forward"Site B
Section titled “Site B”# Tunnel interface/interface 4in6 add name=4in6-to-a local-address=2001:db8:b::1 remote-address=2001:db8:a::1
# Tunnel IPv4 address/ip address add address=10.99.0.2/30 interface=4in6-to-a
# Route to Site A LAN/ip route add dst-address=192.168.10.0/24 gateway=10.99.0.1
# Firewall: allow 4in6 protocol from Site A/ipv6 firewall filter add chain=input protocol=ipv4 src-address=2001:db8:a::1 action=accept comment="4in6 from Site A"/ip firewall filter add chain=forward in-interface=4in6-to-a action=accept comment="4in6 forward"Verify
Section titled “Verify”/interface 4in6 print detail/ping 10.99.0.2/ping 192.168.20.1/ip route print where dst-address=192.168.20.0/24Troubleshooting
Section titled “Troubleshooting”Check interface state
Section titled “Check interface state”/interface ipip print detail/interface 6to4 print detail/interface 4in6 print detailAn interface with R in the flags column is running. A missing R flag means the interface is disabled or not passing traffic.
Packet capture — verify encapsulation is occurring
Section titled “Packet capture — verify encapsulation is occurring”# IPIP and 4in6 both use IP protocol 4 in their respective outer headers/tool sniffer quick ip-proto=4 ;# captures IPIP outer packets (IPv4 underlay)
# 6in4 uses IPv4 protocol 41/tool sniffer quick ip-proto=41 ;# captures 6in4 / IP6IP6 outer packetsEnable debug logging
Section titled “Enable debug logging”/system logging add topics=interface,debug action=memory/log print where topics~"interface"Common problems
Section titled “Common problems”| Symptom | Likely cause | Fix |
|---|---|---|
Interface has no R flag | Firewall dropping encapsulation protocol | Add input accept rule for protocol 4 (IPIP/4in6) or 41 (6in4) |
| Interface running, no traffic | Missing route | Add /ip route or /ipv6 route for the remote prefix |
| Interface running, no traffic | Forward chain drop | Add forward accept rule for the tunnel interface |
| TCP connections stall, UDP works | MTU/MSS mismatch | Lower tunnel MTU; verify clamp-tcp-mss=yes; add mangle MSS rule |
| 6in4 tunnel never comes up | Protocol 41 blocked by carrier/CGNAT | You need a public IPv4 directly on the WAN; CGNAT cannot pass proto 41 |
| 4in6 tunnel up, asymmetric routing | Wrong local-address picked | Set local-address explicitly to the routable IPv6 on the WAN interface |
| High packet loss | Path MTU smaller than expected | Reduce mtu on the tunnel interface to match actual path MTU |
Step-by-step ping trace
Section titled “Step-by-step ping trace”# 1. Is the tunnel interface running?/interface print where name=<tunnel-name>
# 2. Can you reach the remote tunnel IP?/ping <peer-tunnel-ip>
# 3. Can you reach a host in the remote LAN?/ping <remote-host-ip>
# 4. Is there a route for the remote network?/ip route print where dst-address=<remote-prefix>
# 5. Are firewall rules allowing the traffic?/ip firewall filter print where chain=input/ip firewall filter print where chain=forwardSee Also
Section titled “See Also”- IPIP and IP6IP6 Tunnels — detailed IPIP and IP6IP6 property reference
- 6to4 Tunneling — full 6to4 property reference and automatic 2002::/16 mode
- GRE and IPIP Tunnels — GRE with keepalive and multicast support
- IPsec — add encryption to any IP tunnel with transport-mode IPsec policies
- WireGuard VPN — modern encrypted tunnel; better choice than unencrypted IP tunnels for untrusted paths