RFC总结之GRE协议


一、简介
        GRE(Generic Routing Encapsulation)是一种通用路由封装协议,是隧道业务的一种。
        GRE相关的RFC有很多,如rfc1701、rfc1702、rfc2784、rfc2890、rfc6245等。我们以此为顺序来介绍在RFC中规定的GRE报文结构和转发行为。

二、基本概念

        在网络传输过程中,如果有报文需要进行封装然后转发,我们就称这个报文为负载报文(Payload packet);在GRE业务中,负载报文被封装在GRE报文头。只有GRE报文头的报文是无法直接在网络中传输的,需要将其封装在其他的协议中进行传输。我们称这个外层协议为传输头(Delivery Hearder)。因此GRE报文在网络中的传输格式就如下图所示:Delivery Header + GRE Header + Payload packet。

RFC总结之GRE协议_第1张图片

三、RFC1701
在RFC1701中规定了GRE Header的格式,如下图所示:

RFC总结之GRE协议_第2张图片

在报文首部的标记位有五个,分别如下:

  • C(bit0):校验和存在位,置位1则表示Checksum存在且包含有效信s息。
  • R(bit1):路由存在位,置位1则表示Offset和Routing存在且包含有效信息。
  • K(bit2):key存在位,置位1则表示Key存在且包含有效信息。
  • S(bit3):序列号存在位,置位1则表示Sequence Number存在且包含有效信息。
  • s(bit4):Strict Source route,置位1则表示,路由信息全部为严格源路由。
  • bit5~bit15都默认置0

注:如果C和R任意一个置位1,则表示Checksum和Offset都存在GRE报文中。

Protocol Type(2字节)
        “协议类型”字段包含负载报文的协议类型。通常,该值将是数据包的以太网协议类型字段。下面列出了当前定义的协议类型。其他的值可以在其他文档中定义。

Offset(2字节)
        offset字段表示要检测的主源路由表项从“Routing”字段开始到第一个字节的偏移量。当Routing present位或Checksum present位设置为1时,该字段才会出现。只有当Routing present位设置为1时,该字段才会包含有效的信息。

Checksum(2字节)
        校验和字段包含GRE报文头以及负载。

Key(4字节)
        Key字段长度为四个字节,是由封装者封装在报文中。可以被接收者用来验证报文的来源。

Sequence Number(4字节)
        序列号字段长度为四个字节,是由封装者封装在报文中。接收者使用序列号来对接收的报文进行排序.

Routing(变长)
        Routing的长度是可变的,是由一系列的SREs(Source Route Entries)组成的,其报文结构如下图所示:

RFC总结之GRE协议_第3张图片

四、RFC1702
        RFC1701中定义了GRE的报文,在RFC1702中,主要是关于GRE over IPv4的说明。这里ipv4既可以作为传输协议也可以作为负载也可以二者都是。

  • IP作为传输协议时,IP的protocol字段需要被设置成47。
  • IP作为负载时,GRE的protocol type字段需要设置成0x0800。
  • IP既作为负载有作为传输协议:在封装时,外层IP报文中的TTL、TOS、IP安全选项等字段可以从负载中获取。在解封装时,负载报文的TTL必须减一。

五、RFC2784
        RFC2784是2000.03修订的。这一版本的RFC简化了GRE头的定义,使其更加简单明了。其GRE报文格式如下:

RFC总结之GRE协议_第4张图片

        可以看到,相比于RFC1701,RFC2784在GRE报文前两个字节的定义简单了许多,只有一个关键字C,其含义与RFC701一致,表明校验和存在位,置位1则表示Checksum存在且包含有效信息。
        规范指出,对于那些没有实现RFC1701的设备,bit1-5必须为0,否则需要将报文丢弃。bit6-12供以后使用,必须设置为0,且接受者不需要不对其检验。
        对于Ver(Version Number)、protocol type和Checksum字段,则与RFC1701一样。
        Reserved1占两个字节,如果C置位1,Reserved1字段就必须存在,且为全0。

1、转发细则
        当IPv4报文作为负载时,protocol type必须为0x0800。
        隧道终结时,如果GRE报文中的负载是IPv4,ipv4报文的dip必须用来进行转发,且内层ipv4报文的TTL必须缩减。当IPv4作为外层报文时,其协议字段必须为47,在网络中的转发行为与IPv4的转发行为一致。

2、与RFC1701兼容性说明
        RFC2784新增了对RFC1701的说明,将GRE报文前两个字节的标记位简化至只有C字段。并且指出,接收者如使用RFC1701需要明确指出执行RFC1701。

3、GRE Version Numbers
        一般情况下,该字段默认置0,如果改字段置1,则表示为PPTP协议。

4、已知问题
        PMTU问题:当用IPv4作为传送协议时,现有实现并不实现路径MTU发现和不设置禁止分片标志。当传送大包时,在隧道中会分片,在隧道端再重组。如果一个隧道端希望实现Path MTU发现,那么该隧道也需要实现把ICMP不可达错误信息报文(需要分片,设置DF位)回复给报文产生者。否则,假如报文产生者设置了不分片标志,那么报文在隧道中可能会被丢弃,但没有把该ICMP错误信息传回给产生者,那么后续的报文也将使用相同的PMTU,导致后续报文都被丢弃。
        IPv6+GRE问题,此规范中并未给出IPv6+GRE的格式及转发行为。

六、RFC2890
        可能是因为在RFC2784中,将GRE报文前两个字节简化的太严重,只剩下一个标记位,因此在同年九月份,RFC2890中对RFC2784进行了更新说明。更新之后的GRE报文格式如下:

RFC总结之GRE协议_第5张图片

  • C(bit0):校验和存在位,置位1则表示Checksum存在且包含有效信息。如果C置位1,则表示Checksum和Offset都存在GRE报文中。
  • K(bit2):key存在位,置位1则表示Key存在且包含有效信息。
  • S(bit3):序列号存在位,置位1则表示Sequence Number存在且包含有效信息。

Key(4字节)
        Key字段占四个字节,在转发时由发送端进行封装。“Key”字段用于标识隧道内的单个流量流。例如,可能需要根据报文头中不存在的信息来对数据包进行转发。Key字段提供了这个功能,并定义了发送端和接收端之间的逻辑通信流。

Sequence Number(4字节)
        Sequence Number字段占四个字节,在转发时由发送端进行封装。序列号字段是一个四个字节的字段,当序列号显示位被设置时由封装器插入。接收方必须使用序列号来确定数据包从封装器传输到接收方的顺序。Sequence Field的预期用途是提供不可靠但有序的交付。如果设置了Key present位(第2位),则序列号针对Key字段所标识的流量。请注意,没有序列位集的数据包可以与序列位集的数据包交叉。

参考文献:RFC1701、RFC1702、RFC2784、RFC2890

你可能感兴趣的:(RFC规范,网络协议,网络,rfc)