Previous Page
Next Page

4.4. GRE

Protocols, such as IP-in-IP and PPPoE, must each have their own specification, and require encapsulation-specific processing code in the stacks that implement them. In general, if there are n protocols, there will be O(n2) encapsulations of the type protocol X over protocol Y. We can use Generic Routing Encapsulation (GRE) to reduce this to a more manageable size. The idea is that to tunnel protocol X over protocol Y, we would encapsulate as shown in Figure 4.14.

Figure 4.14. Using GRE to Encapsulate Protocol X in Y


If we consider this from the point of view of the encapsulator, we immediately see the advantage. Rather than provide code to encapsulate protocol X in protocol Y for each protocol pair (X, Y), the encapsulating node provides a gre interfacesimilar to the FreeBSD gif interface we used for IP-in-IP encapsulationthat protocol X can be routed to. The gre interface performs any processing required by the GRE protocol, prepends the GRE header, and forwards the resulting packet to protocol Y for transmission. Similar steps take place at the other end of the tunnel: The protocol Y packet arrives and is forwarded to the gre interface, where the protocol X packet is decapsulated and forwarded to protocol X for further processing. The system administrator can configure the gre interface to encapsulate an arbitrary protocol, X, in another arbitrary protocol, Y.

The GRE header is shown in Figure 4.15. This format is specified by RFC 2784 [Farinacci, Li, Hanks, Meyer, and Traina 2000] and its extension, RFC 2890 [Dommety 2000]. These two RFCs largely recreated the specification of GRE given in the informational RFC 1701 [Hanks, Li, Farinacci, and Traina 1994].

Figure 4.15. The GRE Header


The header shown in Figure 4.15 differs from that of RFC 1701 only in the absence of an optional routing field and valid bit, and a recursion control field that was used to indicate the number of additional encapsulations permitted. RFC 1701 also reserved, but did not define, a 5-bit flags field.

The C bit indicates that the checksum field is present and valid. When the C bit is set, the optional reserved1 field is also present. If the C bit is not set, the entire second 32-bit word of the header is not present.

The K bit indicates that the key field is present and valid. If the K bit is not set, the key field is not present in the header.

The S bit indicates that the sequence number field is present and valid. If the S bit is not set, the sequence number field is not present in the header.

The version field indicates the header version number. The header shown in Figure 4.15 is version 0. When GRE is used with PPTP (see Section 4.5), the key field is used for a different purpose, and an optional 32-bit acknowledgment field is added. In this case, the version field is set to 1.

The protocol type field contains the payload protocol type. These protocol types are the same as those used in the Ethernet protocol field. Thus, for example, IP has a protocol type of 0x0800. The complete, up-to-date list of these protocol numbers is available online from the Internet Assigned Numbers Authority (IANA) FTP server at <ftp://ftp.isi.edu/in-notes/iana/assignments/ethernet-numbers>.

The optional checksum field is present only when the C bit is set, in which case it contains the normal Internet checksum of the GRE header and its payload. When calculating the checksum, the checksum field is initially set to 0. When the checksum field is present, so is the reserved1 field.

The optional key field is present only when the K bit is set. This field is intended to identify a particular traffic flow within the tunnel. RFC 2890 leaves the exact semantics and structure of this field up to the implementer. As we mentioned earlier, PPTP has a completely different interpretation of this field.

The optional sequence number field is present only when the S bit is set. This field's intended use is to allow GRE to provide unreliable but in-sequence delivery of its payload packets. RFC 2890 specifies that the treatment of packets containing sequence numbers should be similar to that of IP packet fragment reassembly: Packets with sequence numbers that have already been received should be silently discarded; packets with a sequence number greater than that expected can be placed on a holding queue pending receipt of the missing packet or packets; packets on the holding queue should time out and be discarded after some interval, and the length of the holding queue should not be allowed to grow beyond a threshold size.

The Linux TCP/IP stack supports GRE tunnels through its ip command. To see how the configuration of such a tunnel would work and to see GRE encapsulation in action, let's configure a GRE tunnel between linuxlt and linux, as shown in Figure 4.16.

Figure 4.16. A GRE Tunnel


We first configure the tunnel on linuxlt, using the Linux ip command:

linuxlt: # ip tunnel add gretun mode gre remote 172.30.0.4
    local 172.30.0.15 key 0xaabbccdd
linuxlt: # ip link set gretun up
linuxlt: # ip addr add 192.168.123.1 dev gretun
linuxlt: # ip route add 192.168.122.0/24 dev gretun
linuxlt: # ping 192.168.122.1

The first line specifies that we want a GRE tunnel between linuxlt (172.30.0.15) and linux (172.30.0.4) with a key of 0xaabbccdd. This command creates an interface that we named gretun. Next, we configure the gretun interface up. This command is equivalent to the ifconfig command, which we could have used instead. The third line adds the address 192.168.123.1 to our gretun interface. Again, this is similar to the same operation using ifconfig. Finally, we add a route to the other end of the tunnel. We could have used the route command here instead.

We configure linux similarly and then ping linux from linuxlt. Here is the tcpdump output of the first ping and its reply:

1   15:30:17.466883 172.30.0.15 > 172.30.0.4: gre [Kv0] K:aabbccdd
    192.168.123.1 > 192.168.122.1: icmp: echo request (DF) (DF)
1.1    4500 0070 0d6b 4000 402f d4a4 ac1e 000f    E..p.k@.@/......
1.2    ac1e 0004 2000 0800 aabb ccdd 4500 0054    ............E..T
1.3    0d6a 4000 4001 b6eb c0a8 7b01 c0a8 7a01    .j@.@.....{...z.
1.4    0800 f8ac 420a 00b1 d934 4a40 a71f 0700    ....B....4J@....
1.5    0809 0a0b 0c0d 0e0f 1011 1213 1415 1617    ................
1.6    1819 1a1b 1c1d 1e1f 2021 2223 2425 2627    .........!"#$%&'
1.7    2829 2a2b 2c2d 2e2f 3031 3233 3435 3637    ()*+,-./01234567
2   15:30:17.469906 172.30.0.4 > 172.30.0.15: gre [Kv0] K:aabbccdd
    192.168.122.1 > 192.168.123.1: icmp: echo reply (DF)
2.1    4500 0070 0970 4000 402f d89f ac1e 0004    E..p.p@.@/......
2.2    ac1e 000f 2000 0800 aabb ccdd 4500 0054    ............E..T
2.3    096f 0000 4001 fae6 c0a8 7a01 c0a8 7b01    .o..@.....z...{.
2.4    0000 00ad 420a 00b1 d934 4a40 a71f 0700    ....B....4J@....
2.5    0809 0a0b 0c0d 0e0f 1011 1213 1415 1617    ................
2.6    1819 1a1b 1c1d 1e1f 2021 2223 2425 2627    .........!"#$%&'
2.7    2829 2a2b 2c2d 2e2f 3031 3233 3435 3637    ()*+,-./01234567

Line 1 shows a summary of the echo request: The IP datagram is from linuxlt (172.30.0.15) to linux (172.30.0.4). The datagram contains a version 0 GRE packet with the key field present ([Kv0]), and the key is 0xaabbccdd. The inner IP datagram is from the gretun interface on linuxlt (192.168.123.1) to the gretun interface on linux (192.168.122.1) and carries an ICMP echo request.

Let's look at the packet itself, so that we can see the encapsulation. The outer IP header is on lines 1.1 and 1.2:

1.1    4500 0070 0d6b 4000 402f d4a4 ac1e 000f    E..p.k@.@/......
1.2    ac1e 0004 2000 0800 aabb ccdd 4500 0054    ............E..T

The tenth byte is the protocol field (ip_p), which is set to 47 (0x2f), indicating GRE (see Figure 2.12). The source and destination addresses are 172.30.0.15 (0xac1e000f) and 172.30.0.4 (0xac1e0004).

Right after the outer IP header is the GRE header on line 1.2:

1.2    ac1e 000f 2000 0800 aabb ccdd 4500 0054    ............E..T

The 0x20 in the first byte shows that the K flag is set, indicating that the key field is present; the 0x00 in the second byte shows that this is version 0 of the GRE header. The next two bytes (0x0800) are the payload protocol type, indicating that the payload is another IP datagram. Because the C flag is not set, the optional checksum fields and the corresponding reserved field are not present. Next comes the key field, which is set to 0xaabbccdd, as expected. Because the S flag is not set, the optional sequence number field is not present, so the GRE header ends with the key field.

The remainder of the packet, on lines 1.21.7, is the encapsulated IP datagram. It is a normal ping packet from 192.168.123.1 (0xc0a87b01) to 192.168.122.1 (0xc0a87a01). The second packet is similar except that it is from linux to linuxlt, and the payload is an ICMP echo reply.

GRE is important for us because many tunnels and VPNs use it in their encapsulation. Indeed, Cisco tunnels use GRE by default. We shall see several examples of GRE encapsulations later in the text.


Previous Page
Next Page