Linux – GRE keepalive with Linux and RouterOS

greiplinuxrouterostunneling

I have a Linux host and couple of routerboadrs. I created a GRE tunnel, but Linux does not answer keepalive packages. Then router mark gre connection as unreachable, so I cant send to Linux host from router subnet. If linux sends something into tunnel (ping, etc.) – RouterOS mark connection as reacheble. Second and next packages routed nicely until one minute idle (no traffic).

Tunnel in linux a make in this way:

remote=x.x.x.x
dev=gre21
network=10.21.0.0/16

ip tunnel add ${dev} mode gre remote ${remote} ttl 255
ip addr add 172.16.1.1/24 peer 172.16.1.21 dev ${dev}
ip link set ${dev} up
ip route add ${network} dev ${dev}

And ip l:

14: gre21: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1476 qdisc noqueue state UNKNOWN 
    link/gre 0.0.0.0 peer 109.60.170.15

How to set state "running"?

How to keep alive tunnel? Ping in cron?

Best Answer

The answer is too late, but you probably want this one: https://github.com/Jamesits/linux-gre-keepalive

If you are interested why setting accept_local helps, here is an answer: https://bv2ex.com/t/588215

A GRE Keepalive is a "host to router" GRE packet encapsulated inside a "router to host" GRE packet. The idea being the host (in this case Linux) receives the packet, sees the packet is actually a GRE packet for the router, and sends it back out. The router receives this packet and knows the remote end is still responding.

The Linux FIB code is such that if it receives traffic where the source is a local unicast address, the traffic is considered invalid.

Observe the following code:

net/ipv4/fib_frontend.c

if (res.type != RTN_UNICAST) {
if (res.type != RTN_LOCAL || !accept_local)
goto e_inval_res;
}