Configuring Generic Routing Encapsulation (GRE) tunnels on Cisco IOS
Generic routing encapsulation (GRE) is a tunneling protocol which was initially developed by Cisco, and later it has been adopted as an industry standard in RFC 2784. GRE allows the encapsulation of a wide variety of network layer protocols inside virtual point-to-point links. This means that the original packet is encapsulated inside a GRE header and a new IP header containing the source and the destination of the tunnel endpoints. The GRE protocol does not provide any security for the data being transported so if encryption is needed GRE must be used in conjunction with IPsec protocol. Some of the reasons for using GRE are the need to transport multicast traffic, or to provide workarounds for networks with limited hops. In this article we will demonstrate how two networks which do not have reachability can be connected through an GRE tunnel.
GRE tunnelling concepts
GRE tunnelling configuration involves the creation of tunnel interfaces. Tunnel interfaces are logical interfaces which are configured in the same manner as physical or loopback interfaces. Since the tunnel interfaces are behaving as point-to-point interfaces the IP addresses configured on both sides must be in the same subnet. When setting up the GRE tunnel each side must specify a source and a destination. The IP address of the source on side A of the tunnel must match the IP address of the destination on side B of the tunnel and vice versa.
IP reachability between the tunnel endpoints is critical otherwise the GRE tunnel will not come up. The GRE tunnel interface comes up as soon as it is configured and it stays up as long as there is a valid tunnel source address or interface which is up. When a packet is sent through the GRE tunnel it gets encapsulated with a GRE header and an outer IP header and these headers are removed when the packet exits the GRE tunnel. GRE tunnels are designed to be completely stateless. This means that if one side of the tunnel goes down the other side might remain up because it cannot detect if the remote tunnel endpoint is unreachable. In this situation packets that go through the GRE tunnel will be dropped. Fortunately there is a solution for this issue by enabling keepalives on both sides of the tunnel. We’ll discuss this in more detail in the troubleshooting section.
Initial IP configuration and routing
First let’s proceed and configure the IP addressing and routing. Below is the topology I will use to demonstrate how GRE tunnels work. In order to simplify the routing I have used OSPF as the routing protocol and configured all the routers to be in the same area 0. Hosts PC1 and PC2 will be used to test reachability through the GRE tunnel.
The IP addressing scheme is configured as displayed in the topology above. We will assign an router ID (RID) following a simple scheme (i’ll use 126.96.36.199 for R1, 188.8.131.52 for R2 and so on) and then enable OSPF on all interfaces in area 0. Below is the OSPF configuration snippet for all four routers.
R1(config)# router ospf 1 R1(config-router)# router-id 184.108.40.206 R1(config-router)# network 10.10.12.0 0.0.0.255 area 0
R1(config)# router ospf 1 R2(config-router)# router-id 220.127.116.11 R2(config-router)# network 10.10.12.0 0.0.0.255 area 0 R2(config-router)# network 10.10.23.0 0.0.0.255 area 0
R1(config)# router ospf 1 R3(config-router)# router-id 18.104.22.168 R3(config-router)# network 10.10.23.0 0.0.0.255 area 0 R3(config-router)# network 10.10.34.0 0.0.0.255 area 0
R1(config)# router ospf 1 R4(config-router)# router-id 22.214.171.124 R4(config-router)# network 10.10.34.0 0.0.0.255 area 0
After this OSPF neighborship should come up and you should have reachability between interface Gi0/1 of router R1 and Gi0/0 of router R4. Let’s test this by running a traceroute from R1 to R4.
R1# traceroute 10.10.34.4 Tracing the route to 10.10.34.4 VRF info: (vrf in name/id, vrf out name/id) 1 10.10.12.2 1 msec 1 msec 0 msec 2 10.10.23.3 3 msec 2 msec 1 msec 3 10.10.34.4 3 msec 2 msec 1 msec
As you can see router R1 can reach router R4. The goal of this configuration is that host PC1 can reach host PC2 and viceversa via the GRE tunnel.
Creating a GRE tunnel
First we need to create two tunnel interfaces one (Tunnel1) on router R1 and the other (Tunnel2) on router R4. The tunnel will be established between these two routers. The tunnel interfaces on both routers must always be configured with an IP address that needs to be from the same subnet. In my topology, both tunnel interfaces will use IPs from 172.30.1.0/30 network. Let’s create and configure the Tunnel1 interface on router R1.
R1(config)# interface Tunnel1 R1(config-if)# ip address 172.30.1.1 255.255.255.252 R1(config-if)# ip mtu 1400 R1(config-if)# ip tcp adjust-mss 1360 R1(config-if)# tunnel source 10.10.12.1 R1(config-if)# tunnel destination 10.10.34.4 R1(config-if)# exit
After we complete the tunnel configuration, the router will confirm the creation of the tunnel by displaying a message on the console similar to the one below.
*Jun 1 13:56:54.588: %LINEPROTO-5-UPDOWN: Line protocol on Interface Tunnel1, changed state to up
Since GRE is encapsulating protocol this adds some extra overhead to the original packet and can cause fragmentation. In this case we can adjust the maximum transmission unit (MTU) value to 1400 bytes and maximum segment size (MSS) to 1360 bytes. TCP MSS defines the maximum amount of data that a host is willing to accept in a single TCP/IP datagram and it’s usually 40 bytes less than the MTU of the interface. Using a value of 1400 is a common practice and will ensure unnecessary packet fragmentation is kept to a minimum. A similar configuration needs to be applied for interface Tunnel2 on router R4 with the exception that the tunnel source and destination are reversed.
R4(config)# interface Tunnel2 R4(config-if)# ip address 172.30.1.2 255.255.255.252 R4(config-if)# ip mtu 1400 R4(config-if)# ip tcp adjust-mss 1360 R4(config-if)# tunnel source 10.10.34.4 R4(config-if)# tunnel destination 10.10.12.1 R4(config-if)# exit
GRE tunnels doesn’t provide encryption, but we can provide a key on each side of the tunnel by using the tunnel key command.
R1(config)# interface Tunnel1 R1(config-if)# tunnel key 100
R1(config)# interface Tunnel2 R4(config-if)# tunnel key 100
This can be thinked as a simple clear-text password authentication mechanism with no encryption. Tunnel ID keys are locally configured and can be used as a form of weak security to prevent improper configuration or injection of packets from a foreign source. They need to match on both sides. It’s not recommended to rely on this key for security purposes, instead you can use IPsec to protect GRE tunnel traffic.
At this point, both tunnel endpoints and should be able to communicate between them. Let’s test this by running a ping from router R1 using Tunnel1 as source to the IP address of the Tunnel2 interface on router R4.
R1# ping 172.30.1.2 source Tunnel1 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 172.30.1.2, timeout is 2 seconds: Packet sent with a source address of 172.30.1.1 !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 2/2/3 ms
As we can see the test is successful. Although the GRE tunnel is up hosts PC1 and PC2 are still not able to communicate yet. We need to setup a static route on both endpoints. On router R1 we need to add a static route to the remote network 192.168.20.0/24 via Tunnel1 interface which connects the remote end of our GRE Tunnel. Therefore, when R1 receives a packet destined for 192.168.20.0 network, it knows that the exit interface is Tunnel1 and it will route the packet through the GRE tunnel.
R1(config)# ip route 192.168.20.0 255.255.255.0 Tunnel1
The same configuration must be repeated for R2:
R4(config)# ip route 192.168.10.0 255.255.255.0 Tunnel2
Now both hosts PC1 and PC2 should have full reachability over the GRE tunnel.
GRE tunnel verification and troubleshooting
We can check the operational status of the tunnel interface using the show interfaces Tunnel command. Let’s check the status of Tunnel1 interface on router R1.
R1(config)# show interfaces Tunnel1 Tunnel1 is up, line protocol is up Hardware is Tunnel Internet address is 172.30.1.1/30 MTU 17916 bytes, BW 100 Kbit/sec, DLY 50000 usec, reliability 255/255, txload 1/255, rxload 1/255 Encapsulation TUNNEL, loopback not set Keepalive not set Tunnel linestate evaluation up Tunnel source 10.10.12.1, destination 10.10.34.4 Tunnel protocol/transport GRE/IP Key disabled, sequencing disabled Checksumming of packets disabled Tunnel TTL 255, Fast tunneling enabled Tunnel transport MTU 1476 bytes Tunnel transmit bandwidth 8000 (kbps) Tunnel receive bandwidth 8000 (kbps) Last input 00:44:31, output 00:44:31, output hang never Last clearing of "show interface" counters 04:49:44 Input queue: 0/75/0/0 (size/max/drops/flushes); Total output drops: 0 Queueing strategy: fifo Output queue: 0/0 (size/max) 5 minute input rate 0 bits/sec, 0 packets/sec 5 minute output rate 0 bits/sec, 0 packets/sec 892 packets input, 44212 bytes, 0 no buffer Received 0 broadcasts (0 IP multicasts) 0 runts, 0 giants, 0 throttles 0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored, 0 abort 28 packets output, 3256 bytes, 0 underruns 0 output errors, 0 collisions, 0 interface resets 0 unknown protocol drops 0 output buffer failures, 0 output buffers swapped out
The output of this command displays a lot of useful information for troubleshooting and debugging. I have highlighted in red the most important lines from the output. We can see that the Tunnel1 interface is up and the transport protocol is GRE. Also we can see the source and destination endpoints and the fact that traffic is being passed in both directions. Let’s run some tests to verify reachability between hosts PC1 and PC2. First let’s ping PC2 from PC1.
PC1> ping 192.168.20.100 Pinging 192.168.20.100 with 32 bytes of data: Reply from 192.168.20.100: bytes=32 time=4ms TTL=126 Reply from 192.168.20.100: bytes=32 time=3ms TTL=126
Now let’s run a traceroute from PC1 to PC2
PC1> tracert 192.168.20.100 Tracing route to 192.168.20.100 over a maximum of 30 hops 1 <1ms <1ms <1ms 192.168.10.1 2 2ms 2ms 2ms 172.30.1.2 3 2ms 2ms 2ms 192.168.20.100
From the traceroute output we can see that the path goes through the GRE tunnel. Since GRE tunnels are stateless, by default they cannot detect the operational status of the remote tunnel interface. So if one interface can go down while the other side remains up. We can resolve this by enabling keepalive packets on each side of the tunnel. By doing this, each side of the tunnel periodically sends a keepalive to the other side. If one side doesn’t receive a keepalive in the specified time, the tunnels go down on each side. Let’s configure both interfaces to send keepalives at every 30 seconds.
R1(config)# interface Tunnel1 R4(config-if)# keepalive 10 3
R4(config)# interface Tunnel2 R4(config-if)# keepalive 10 3
We configured both tunnel interfaces to send 3 keepalives at interval of 10 seconds. In this case if 3 keepalives are missed after 30 seconds the interfaces status should go down. From the output of the show interface Tunnel command we should see that keepalives have been set.
R1(config)# show interfaces Tunnel1 | include Keepalive Keepalive set (10 sec), retries 3
Let’s simulate a failure by shutting down interface Gi0/1 on router R3. After 30 seconds both tunnel interfaces will go down and the following message will be displayed on the router console.
*Jun 1 19:26:14.358: %LINEPROTO-5-UPDOWN: Line protocol on Interface Tunnel1, changed state to down
If we check the operational status the interfaces it will display that the line protocol is down.
R1#show interface tunnel 1 | include Tunnel1 Tunnel1 is up, line protocol is down
Some things to keep in mind when troubleshooting GRE tunnels:
- make sure the source and destination tunnels are setup correctly
- if using tunnel keys check that they match on both sides
- check the routing tables for missing routes
- check for any access lists blocking GRE traffic
In this article we discussed basic concepts and configuration of GRE tunnels. GRE is used as the core protocol for DMVPN which allows you to build scalable networks where a single tunnel interface can be used to reach numerous remote sites. In situations where encryption is needed GRE can be used in conjunction with IPsec to protect the traffic for security reasons.