Configuring Generic Routing Encapsulation (GRE) tunnels on Cisco IOS

4.7/5 - (4 votes)



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 for R1, 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
R1(config-router)# network area 0
R1(config)# router ospf 1
R2(config-router)# router-id
R2(config-router)# network area 0
R2(config-router)# network area 0
R1(config)# router ospf 1
R3(config-router)# router-id
R3(config-router)# network area 0
R3(config-router)# network area 0
R1(config)# router ospf 1
R4(config-router)# router-id
R4(config-router)# network 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
Tracing the route to
VRF info: (vrf in name/id, vrf out name/id)
1  1 msec  1 msec  0 msec
2  3 msec  2 msec  1 msec   
3  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 network. Let’s create and configure the Tunnel1 interface on router R1.

R1(config)# interface Tunnel1
R1(config-if)# ip address
R1(config-if)# ip mtu 1400
R1(config-if)# ip tcp adjust-mss 1360
R1(config-if)# tunnel source
R1(config-if)# tunnel destination
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
R4(config-if)# ip mtu 1400
R4(config-if)# ip tcp adjust-mss 1360
R4(config-if)# tunnel source
R4(config-if)# tunnel destination
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 source Tunnel1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to, timeout is 2 seconds:
Packet sent with a source address of 
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 via Tunnel1 interface which connects the remote end of our GRE Tunnel. Therefore, when R1 receives a packet destined for network, it knows that the exit interface is Tunnel1 and it will route the packet through the GRE tunnel.

R1(config)# ip route Tunnel1

The same configuration must be repeated for R2:

R4(config)# ip route 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
  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, destination
  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
Pinging with 32 bytes of data:
Reply from bytes=32 time=4ms TTL=126
Reply from bytes=32 time=3ms TTL=126

Now let’s run a traceroute from PC1 to PC2

PC1> tracert
Tracing route to over a maximum of 30 hops
1    <1ms    <1ms    <1ms
2     2ms     2ms     2ms
3     2ms     2ms     2ms

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.

Leave a Reply

Your email address will not be published.