一、路由模式(no sw 带ip模式)

路由模式指的是Service Chain节点本身具备三层转发功能,其与交换设备之间互联通道需要配置IP地址,交换设备发送报文到这些节点是通过三层路由的方式到达,报文在这些节点返回交换设备时也是通过三层路由的方式到达。

以下图作为路由模式下的引流模型来进行阐述:

                                             

为案例覆盖方便,设定P1、P5属于SVI下的两个成员口,P4属于路由口。

P2、P3属于路由口分别与对应的FW或者WAF互联。

交换机其他任意口与控制器互联(三层可达即可),用于传递配置命令和OpenFlow流表。

1.1 ARP学习

image.png

FW/WAF完成IP和其对应网关配置后会向Switch请求对应ARP信息,这时的ARP请求由Switch进行应答,这个过程和传统流程一致。

由于控制器后续下发的Service Chain流表需要用到FW/WAF节点的MAC地址,因此控制器需要获取FW/WAF的ARP信息。但是如果如无特殊表项设置的话,FW/WAF的ARP应答会被Switch本身的ARP模块拦截,因此控制器需要预先设置一条OpenFlow流表,该流表包含如下内容(以上述的例子为例):



Match

Action

FW

Flow1

In_Port == P2 && Ether_Type == ARP_Reply

Output_Port = Controller

Flow2

In_Port == P3 && Ether_Type == ARP_Reply

Output_Port = Controller

Switch端在收到这些流表之后,通过Switch端的OpenFlow PI模块将这些流表最终设置到交换芯片上(到芯片上的流表转义成送cpu的行为,由OpenFlow PI模块劫走这个ARP Reply报文,并转换成OpenFlow Packet_in报文上送控制器)。

Controller完成流表下发后,通过OpenFlow Packet_out消息将FW/WAF的ARP Request报文发送给Switch,Switch的OpenFlow PI模块将OpenFlow Packet_out报文中的ARP请求解析出来并通过Switch发送到FW/WAF上,当FW/WAF应答ARP Reply后,该报文会被之前设置的表项送到Switch端的CPU继而通过OpenFlow PI模块最终发送到控制器上,从而控制器完成FW/WAF的ARP学习。

 

ARP请求的流表如下:

{table="0",   duration_sec="10929", priority="5100", flags   ="0x0",idle_timeout="0", hard_timeout="0",   cookie="0xe516189520000", packet_count="0",   byte_count="0". match=oxm{in_port="2", eth_type="0x806"}   instructions=[apply{acts=[output{port="controller",   max_len="65535"}]}]}

 

1)     in_port=“2”:这里的端口指的是“引流口”和“回流口”,即与安全设备互联的接口

2)     eth_type=“0x806“:0x806代表ARP报文,这里只需要匹配ARP报文即可。

3)     output{port=“controller”:将arp送控制器一份,这样控制器下发引流的流表时,才可以修改流表中的源目MAC,然后交换机转发数据时,就根据流表中的源目MAC去修改报文。

4)     其他字段说明参见透明模式的流表解析

 

1.2 特征流三层转发

设定存在一条从P1输入的流需要三层转发到P4接口。(注意:Service Chain不会改变原有数据流在Switch上的出口,只是将该数据流流经Switch时的过程路径做了改变。)

在控制器上构建服务链使得最终P1àP4的数据流经过如下路径:

image.png

当构建出这条Service Chain后,控制器会下发如下4条流:

流量方向


Match

Action

去流

Flow1

In_Port == P1 && 用户定义的特征流

Output_Port = P2&& SET_SMAC = Switch_MAC &&   SET_DMAC = FW_MAC

Flow2

In_Port == P3 && 用户定义的特征流

Output_Port=Normal

回流

Flow3

In_Port == P4 && 用户定义的特征流

Output_Port = P3&& SET_SMAC = Switch_MAC &&   SET_DMAC = FW_MAC

Flow4

In_Port == P2 && 用户定义的特征流

Output_Port=Normal

同样通过Switch端的OpenFlow PI模块经由交换适配层将这两条流表最终设置到交换芯片上(对应的VLAN信息由交换适配层根据P2的vlan自行添加上,控制器不感知P2路由口的vlan信息)。

此时设备端的行为如下:

报文转发(流表生成4个流条目)

1)    P1口收到报文(A->B),根据流表(引流,修改目标MAC),从P2口发出(B->C1);

2)    P3口收到报文(C2->B),根据流表(传统转发),从P4口发出(B->D);

3)    P4口收到报文(D->B),根据流表(引流,修改目标MAC),从P3口发出(B->C2);

4)    P2口收到报文(C1->B),根据流表(传统转发),从P1口发出(B->A)。

从而就实现了指定数据流按如下方式转发的行为,这也就是服务链的一个基本过程:

image.png

引流流表如下(flow1):

{table="0", duration_sec="177",   priority="1500", flags ="0x0",idle_timeout="0",   hard_timeout="0", cookie="0xe51efb3520000",   packet_count="0", byte_count="0".   match=oxm{in_port="1", eth_type="0x800",   ipv4_dst=“30.7.0.0", ipv4_dst_mask="255.255.255.0"}   instructions=[apply{acts=[set_field{field:eth_src=   “00:d0:f8:22:33:e5"},set_field{field:eth_dst=" 00:d0:f8:22:33:d9   "}, output{port="3"}]}]}

主要字段说明:

1)     in_port=“1”:这里指的是数据进SDN交换机的接口

2)     set_field{field:eth_src=“00:d0:f8:22:33:e5 "}, set_field{field:eth_dst=" 00:d0:f8:22:33:d9 "}:如果匹配到了报文,则将报文源MAC修改为00:d0:f8:22:33:e5 ,目的MAC修改为00:d0:f8:22:33:d9

3)     其他字段说明参见透明模式的流表解析

 

1.3 特征流二层转发

如果特征流本身是二层转发行为,则目前的Service Chain方案不支持这种类型的流在路由模式下转发,具体参考下文分析。

在推导的过程可以先以能够支撑这种二层流进入Service Chain来描述,看在哪个环节会出现与现有转发逻辑相违背的地方,从而得出不支持的结论。前文设定P1和P5端口是同属于一个SVI口下的两个物理端口,因此这两个端口同属于一个VLAN,它们之间的转发行为归属于二层转发行为,为了与三层转发有个明显的对比,我们设定转发数据流如下:

image.png

同样从控制器上设定如下表项:

流量方向


Match

Action

去流

Flow1

In_Port == P1 && 用户定义的特征流

Output_Port = P2&& SET_SMAC = Switch_MAC &&   SET_DMAC = FW_MAC

Flow2

In_Port == P3 && 用户定义的特征流

Output_Port=Normal

回流

Flow3

In_Port == P5 && 用户定义的特征流

Output_Port = P3&& SET_SMAC = Switch_MAC &&   SET_DMAC = FW_MAC

Flow4

In_Port == P2 && 用户定义的特征流

Output_Port=Normal

 

同样通过Switch端的OpenFlow PI模块经由交换适配层将这两条流表最终设置到交换芯片上(对应的VLAN信息由交换适配层根据P3、P5的vlan自行添加上,控制器不感知P3、P5路由口的vlan信息)。

此时设备端的行为如下:

报文转发MAC A访问MAC E:

1)    P1口收到报文(A->B),根据流表(引流,修改目标MAC),从P2口发出(B->C1);

2)    P3口收到报文(C2->B),根据流表(传统转发),从P5口发出(B->D);——该过程无法实现,P3收到报文的目的MAC已经不是E,数据将丢失。

3)    P4口收到报文(D->B),根据流表(引流,修改目标MAC),从P3口发出(B->C2);

4)    P2口收到报文(C1->B),根据流表(传统转发),从P1口发出(B->A);——该过程无法实现,P2收到报文的目的MAC已经不是A,数据将丢失。

从上文可见,二层流一旦被Service Chain捕获,则会导致最终的断流,对于用户来说这是一个故障。因此在路由模式下发对应的Service Chain流表时,都必须在交换适配层为对应的流表加上MyMAC_hit/L3_Route_hit等类似的标志位,目的是仅让触发了三层转发行为的报文才能进入Service Chain流表,避免用户误配置后导致转发不通的问题。