OpenFlow Flow-Mod消息学习

任务目的

1、初步了解OpenFlow协议的三大消息类型,并着重学习Flow-Mod消息。
2、进一步巩固抓包工具Wireshark的使用方法,通过抓包详细分析Flow-Mod消息。

任务环境

设备名称 软件环境(镜像) 硬件环境
控制器 Ubuntu 14.04桌面版
Floodlight 1.0
CPU:1核 内存:2G 磁盘:20G
主机 Ubuntu 14.04桌面版
Mininet 2.2.0
CPU:1核 内存:2G 磁盘:20G

注:系统默认的账户为root/root@openlab,openlab/user@openlab。

任务内容

1、通过Flow-Mod消息对流表进行添加、删除、变更设置等操作。
2、使用Wireshark工具捕获OpenFlow数据包,了解、学习Flow-Mod消息。

实验原理

OpenFlow 协议支持3种消息类型:Controller-to-Switch(控制器—交换机)、Asynchronous(异步)和Symmetric(对称),每一类消息又有多个子消息类型。
1、 Controller-Switch(控制器—交换机)消息,这类消息由控制器发起,包括Features、Configuration、Modify-State、Read-State、Send-Packet、Barrier等几类消息,用于对OF交换机的管理。
2、 Asynchronous(异步)消息,这类消息用来将网络事件或交换机状态的变化更新到控制器。主要包括4种子类型:Packet-in、Flow-Removed、Port-status和Error消息。
3、 Symmetric(同步)消息与前两类消息有所不同,Symmetric类的消息可由控制器或者OF交换机中的任意一侧发起,这类消息包括以下3种类型:Hello、Echo和Vendor。
Modify-State消息是OpenFlow消息中最为重要的消息类型,控制器通过Port-mod消息用来管理端口状态,通过Flow-mod消息增删交换机的流表项,考虑到流表在OpenFlow的重要意义,在此针对Flow-mod消息进行详尽分析。
图1是Flow-mod消息的具体格式,前4个字段是OpenFlow消息的通用报头。wildcard表示匹配时12元组的掩码位,被掩盖掉的元组不参加匹配。中间部分从in_port到tp_dst字段说明了流表项12元组的信息,其中的pad负责对齐占位,不代表任何意义。cookie字段在处理数据分组时不会用到,控制器通过cookie来过滤流的统计信息。command字段表示对流表的操作,包括增加(Add)、删除(Delete)、修改(Modify)等。idle_time和hard_time给出了该流表项的生存时间,其中idle_time表示当这条流表项在这段时间内没有匹配到数据分组,则该流表项失效,hard_time表示自流表项下发后只要过了这段时间即刻失效;两者同时设置时,以先到的生存时间为准;两者同时为0时,流表项不会自动失效。priority(优先级)字段的设置参考流表匹配那一小节,原则上优先级越高,所属的Table号就越小。buffer_id表示对应Packet-in消息的buffer_id。out_port仅在command为Delete或者Delete Strict时有效,表明当某表项不仅匹配了Flow-mod中给出的12元组,且转发动作中指定端口等于该out_port的动作时才予以删除,即对删除操作的一种额外限制。flags字段为标志位,OpenFlow v1.0中包括3项:OFPFF_SEND_FLOW_REM(流表失效时是否向控制器发送Flow-removed消息),OFPFF_CHECK_OVERLAP(交换机是否检测流表冲突),OFPFF_EMERG(该流表项将被存于Emergency Flow Cache中,仅在交换机处于紧急模式时生效)。消息中最后的actions数组是对动作表的描述actions[0]即代表其中第一个动作。


图1 OpenFlow v1.0中的Flow-mod消息格式

实验步骤

一、实验环境检查

步骤1 登录控制器,查看控制器IP。桌面版镜像可以通过双击桌面上的“Terminal”图标打开命令终端,也可以使用Ctrl+Alt+t快捷方式打开命令终端,如下图所示。

步骤2 登录Mininet所在主机,查看Mininet的IP,如下图所示。

二、Flow-Mod消息解析

  • 场景一 控制器自动下发流表

步骤1 登录Floodlight控制器,启动抓包工具Wireshark,捕获控制器与交换机建立连接后,控制器自动发送给交换机的flow_mod消息。执行以下命令:

$ sudo wireshark

步骤2 双击eth0网卡,查看eth0网卡上数据包收发情况,如下图所示。

步骤3 登录Mininet虚拟机,执行以下命令启动Mininet。

通过“—controller”参数设置Mininet连接远程控制器,并指定控制器的IP和端口号。

$ sudo mn --controller=remote,ip=30.0.1.3,port=6633 --switch=ovsk,protocols=OpenFlow13

步骤4 登录Floodlight控制器,停止Wireshark,观察数据包列表。

可以看出控制器发送的第一条flow_mod消息就是删除交换机中的流表项。这条flow_mod消息中table-id设为OFPTT_ALL,表明匹配的流表项将都会被删除。Commend显示为DELETE,Commend表示对流表进行的操作,具体包括五种操作类型:ADD、DELETE、DELETE‐STRICT、MODIFY、MODIFY‐STRICT,当Commend为DELETE就代表删除所有符合一定条件的流表项,如下图所示。

步骤5 发送完DELETE类型的消息后,控制器会发送ADD类型的flow_mod消息来添加新的流表项。

ADD消息可以分为三部分:openflow主体部分、match部分、instruction部分,其中instruction部分可以省略。match部分是匹配条件,instruction部分是指令,当一个数据包满足匹配条件就会执行instruction中的指令。控制器发送的add消息中action为output,而output的端口是controller,也就是说让交换机将符合匹配要求的数据包都转发给控制器,如下图所示。

  • 场景二 手动下发流表

步骤1 登录Floodlight控制器,启动Wireshark。

说明:控制器自动发送的flow_mod消息通常就是以上两种,为了进一步了解flow_mod消息,可以通过手动添加、删除流表项触发flow_mod消息。

步骤2 在控制器中再打开一个Terminal,输入以下命令获取交换机DPID。

其中:127.0.0.1是控制器所在的IP,8080是floodlightRest Api的端口。

$ curl http://127.0.0.1:8080/wm/core/controller/switches/json


说明:Floodlight控制器将自己的API通过Rest Api的形式向外暴露,用户可以通过Floodlight的Rest Api来向Floodlight请求交换机信息,添加、删除、查看流表项等。

步骤3 执行以下命令添加流表项。

其中switch的值就是上面获取到的DPID,name是流表项的名称,需要注意name的值必须是唯一的。priority是流表项的优先级,默认值是32767,最大值也是32767。以第二条命令为例,可以理解为“将交换机port1端口接收到的数据包都从port2转发出去”。

$ curl -X POST -d '{"switch":"00:00:00:00:00:00:00:01", "name":"ovs1", "cookie":"0", "priority":"34","in_port":"2","active":"true","actions":"output=1"}' http://127.0.0.1:8080/wm/staticflowpusher/json
$ curl -X POST -d '{"switch":"00:00:00:00:00:00:00:01", "name":"ovs2", "cookie":"0", "priority":"35","in_port":"1","active":"true","actions":"output=2"}' http://127.0.0.1:8080/wm/staticflowpusher/json

步骤4 查看flow_mod消息,从priority可以看出这个第二条流表项,Commend为ADD。匹配条件是in_port为1,对应的动作是output到端口2,如下图所示。



步骤5 执行以下命令删除流表项“ovs1”。

$ curl -X DELETE -d '{"name":"ovs1"}' http://127.0.0.1:8080/wm/staticflowpusher/json

步骤6 查看对应的flow_mod消息,Commend是DELETE_STRICT,DELETE_STRICT类型消息表示删除某一条指定的流表项。该消息表明删除的流表项的priority是34,匹配条件是in_port为2,如下图所示。

步骤7 执行以下命令修改流表项“ovs2”。

如果修改名称、优先级、匹配条件等字段,就会被认为是添加新的流表项。如果只是修改actions,则是修改流表项。

$ curl -X POST -d '{"switch":"00:00:00:00:00:00:00:01", "name":"ovs2", "cookie":"0", "priority":"35","in_port":"1","active":"true","actions":"output=3"}' http://127.0.0.1:8080/wm/staticflowpusher/json

步骤8 查看对应的flow_mod消息,Commend是MODIFY_STRICT,MODIFY_STRICT类型息用来修改某一条指定的流表项。从消息可以看出被修改的流表项的priority是35,匹配条件是in_port为1,如下图所示。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章