本文是读C. Filsfils et al. 所著的Segment Routing第一卷第十二章所作的总结与摘要。
当使用SR IPv6数据平面传送IPv6数据包 (通常称为SRv6) 时,Segment List被压入到数据包报头中的SR报头 (SRH) 中。该报头是新类型的路由报头,路由报头是IETF RFC 2460中描述的一种扩展报头。SRH中的指针指向编码在报头中的Segment List中的active segment。当segment完成后,该segment不是从列表中删除,而是更新指针以指向列表中的下一个segment。
SRv6中的SID使用128位的IPv6进行表示的。从信令角度来看,与MPLS数据平面相比,这更简单,不需要通告除IPv6前缀之外的任何信息。前缀就是SID。 IPv6地址不仅可以表示路由器,还可以表示接口、设备、业务和应用等,或者也可以表示上述任何一种对象的集合。
IPv6报头回顾
IPv6使用两种不同类型的报头:IPv6主报头和IPv6扩展报头 (Extension Header)。IPv6主报头等效于IPv4基本报头。IPv6报头删除了IPv4报头中的选项字段,该字段原本是用来传递与数据包有关或与数据包处理方式有关的附加信息。相应的功能通过一组称为 “扩展报头” 的附加报头实现。因此主IPv6报头具有固定大小 (40 bytes),而定制化的扩展报头可以根据需要添加。
IPv6扩展报头
使用扩展报头以允许扩展IPv6来支持未来的需求和能力。IPv6数据包可以携带一个或多个不同长度的扩展报头。典型的IPv6中不存在扩展报头。如果数据包需要对其路径上的中间结点或目的结点进行特殊处理,则可在数据包报头中添加一个或多个扩展报头。扩展报头位于数据包的主IPv6报头和上层报头之间。
路由报头 (Routing Header)
IPv6的扩展报头类型之一就是路由报头 (Routing Header),其类型号是43,。IPv6源结点使用路由报头列出一个或多个中间结点,使得数据包在去往最终目的地的路径上经过这些结点。因此源结点可以使用路由报头来实现数据包的源路由。由此可见,segment在IPv6并不是新概念。
路由报头的格式可见书P519。下面对其中的重要字段进行讲解。
扩展报头长度 (Hdr Ext Len):路由报头的长度。
路由类型 (Routing Type):该路由报头的类型。
剩余Segment (Segment Left):剩余的路由段数,即在到达最终目的地之前需要访问的中间结点数量。这一字段很重要。
类型特定数据 (type-specific data):对应于路由报头类型的数据。
通常,到数据包目的地路径上的中间结点不检查或处理扩展报头,中间结点基于IPv6的主报头中的目的地址转发数据包。有例外的情况,这里不阐述。
如果结点收到数据包,并且数据包的目的地址对应于该结点的地址,则该数据包检查扩展报头 (如果存在)。如果扩展报头中含有结点不能识别的路由类型的路由报头,结点的行为取决于 “Segment Left” 的值:
如果Segment Left = 0,则节点忽略路由报头并处理数据包的下一报头。
如果Segment Left != 0,则节点丢失数据包,并且向数据包的源地址发送ICMP “参数问题 (Parameter Problem)” 的消息。
SRH
SRH是路由报头的新类型,所建议的路由类型为4。
SRH继承路由报头属性:它应该只在数据包中出现一次,并且如果Segment Left = 0,则忽略 (但不丢弃) SRH,并且基于数据包中的下一报头来处理数据包。
SRH的格式见书P520。下面针对其中的类型特定数据进行讲解:
剩余Segment (Segment Left):虽然这个不是数据字段中的,但是因为它很重要,就在这里重申了一下。
首Segment (First Segment):SRH的Segment List所表示的路径中的第一个Segment的索引。由于Segment List的元素是逆序排序的,因此这个字段实际表示的是Segment List的最后一个元素,这有助于访问紧跟在Segment List之后的TLV。
标志字段
– C-flag (清理,Clean-up):如果置位,则必须在把数据包发往最后一个Segment前从数据包中删除SRH,这类似与MPLS倒数第二跳行为。
– P-flag (受保护,Protected):当Segment端节点通过FRR机制重新路由数据包时置位。
– O-flag (OAM):如果置位,则该数据包是操作和管理 (OAM) 数据包。
– A-flag (警告,Alert):如果置位,则SRH中存在重要的TLV对象。
– H-flag (HMAC):如果置位,则存在HMAC TLV,并且被编码为SRH的最后一个TLV。HMAC TLV用于解决安全隐患问题。
– 未使用:供未来使用。
保留 (Reserved):供未来使用。
Segment List:128位的条目,代表路径上的每个Segment。采用对路径进行逆序排序的方式对Segment List进行编码:最后一个Segment在列表的第一个位置 (Segment List[0]),第一个Segment在最后位置(Segment List[n-1])。
可选类型/长度/值对象 (Optional Type/Length/Value object):SRH中的可选TLV包含可有Segment端节点使用的信息,Segment端节点是与数据包的IPv6目的地址相对应的结点。这些TLV的主要用途是向数据包的最终目的地提供数据包的路径信息。路由层不使用TLV中的信息,但它可有用于其他目的,如OAM。
– 入口节点TLV:可选,包含一个128位字段,用于标识数据包进入SR域的入口节点。
– 出口结点TLV:可选,包含一个128位字段,用于标识数据包离开SR域的预期出口结点。
– 不透明容器TLV:可选,包含一个128位字段。此数据与路由层无关,但用于将其他信息传送到数据包的目的结点。
– 填充TLV:可选,用于将SRH对齐至8个8位字节边界。
– HMAC TLV:可选,包含HMAC信息。
SRH处理过程
SRv6路径上分为三种不同角色的结点。
源结点
源结点是可以产生带有SRH的IPv6数据包的任何结点:
产生带有SRH的IPv6数据包的主机
插入SRH或压入新的带有SRH的外部IPv6报头的SRv6域入口节点
当源结点产生数据包时,它会为数据包创建SRH,如下所示,并将其插入报头。
Segment List:采用对路径进行逆序排序的方式编码n个Segment。第一个位置是最后的Segment,最后位置是第一个Segment。
Segment Left:设置为n-1。
First Segment:设置为n-1。
Des-address:数据包地址设置为路径的第一个Segment。
HMAC TLV和 (或) 其他TLV可以添加到SRH。
事实上,SRv6主报头中的目的地址会被编码为active segment对应的IPv6地址。
Segment端节点
带有SRH的IPv6数据包的目的地址如果与结点的地址一样,则该节点称为Segment端节点。
Segment端节点接收到一个带有SRH的数据包时的操作如下:
if “Des-address == self-address” then
— if “Segment Left > 0” then
—— Segment Left - 1 (next Segment become active)
—— update Des-address to active SID (IPv6 address)
—— if “Segment Left ==0” then
——— if “C-flag == 1” then
———— remove SRH
——— endif
—— else
——— process next header
—— endif
— endif
endif
avtive Segment是Segment Left指向的Segment List中的Segment。Active Segment也被设置为数据包的目的地址。在每个Segment端节点处,通过在Segment List中找到的下一个active Segment来更新目的地址。
中转结点
中转结点是数据包路径上的一个结点,但不是Segment端节点。IPv6规范规定中转结点必须将数据包转发到其IPv6目的地址,且不改动SRH。中转结点不需要支持SRv6来转发数据包。
插入SRH与压入IPv6报头
SRv6允许多种操作模式:
在数据包的源结点插入SRH。
在SR域入口结点插入SRH。
在SR域入口结点压入新的带有SRH的外部IPv6报头 (即将带有SRH的IPv6报头封装在数据包之前)。
书中提供了这三种情形的例子,具体见P525,这里不多阐述。需要注意的是,第一种情况,SRH中的C-flag可以置为0或1,而第二种情况,C-flag必须为1,即到达最后一个Segment前必须将SRH刨除,而最后一种情况C-flag必须为0。