This kind of tunneling has been available in Linux for a long time. It requires 2 kernel modules, ipip.o and new_tunnel.o.
Let's say you have 3 networks: Internal networks A and B, and intermediate network C (or let's say, Internet). So we have network A:
network 10.0.1.0 netmask 255.255.255.0 router 10.0.1.1
The router has address 172.16.17.18 on network C.
and network B:
network 10.0.2.0 netmask 255.255.255.0 router 10.0.2.1
The router has address 172.19.20.21 on network C.
As far as network C is concerned, we assume that it will pass any packet sent from A to B and vice versa. You might even use the Internet for this.
Here's what you do:
First, make sure the modules are installed:
insmod ipip.o insmod new_tunnel.o
Then, on the router of network A, you do the following:
ifconfig tunl0 10.0.1.1 pointopoint 172.19.20.21 route add -net 10.0.2.0 netmask 255.255.255.0 dev tunl0
And on the router of network B:
ifconfig tunl0 10.0.2.1 pointopoint 172.16.17.18 route add -net 10.0.1.0 netmask 255.255.255.0 dev tunl0
And if you're finished with your tunnel:
ifconfig tunl0 down
Presto, you're done. You can't forward broadcast or IPv6 traffic through an IP-in-IP tunnel, though. You just connect 2 IPv4 networks that normally wouldn't be able to talk to each other, that's all. As far as compatibility goes, this code has been around a long time, so it's compatible all the way back to 1.3 kernels. Linux IP-in-IP tunneling doesn't work with other Operating Systems or routers, as far as I know. It's simple, it works. Use it if you have to, otherwise use GRE.