OpenFlow1.3协议wireshark抓包分析
OpenFlow v1.0
v1.0协议消息列表如下:
分为三类消息:Controller-to-switch,asynchronous和symmertric。
v1.0(包含至少一个流表,每个流表包含多个流表项)流表项构成:
头字段 | 计数器 | 行动 |
In Port,Source Address,Destination Address... |
Per Table:Active Entries[0],Packet Lookups[0]... Per Flow:Received Packets[10]... |
Forward/Drop |
... | ... | ... |
头字段:
内容 | 说明 |
In port | 入端口 |
Ethernet source address | 以太网帧的源以太网地址 |
Ethernet destination address | 以太网帧的目标以太网地址 |
Ethernet type | 以太网帧的类型字段 |
Vlan id | Vlan标签的VID |
Vlan priority | |
IP source address | IP源地址 |
IP destination address | IP目的地址 |
IP protocol | IP头的协议字段 |
ToS | IP头的ToS字段 |
Transport source port/ICMP type | TCP/UDP的源端口号;ICMP头的类型 |
Transport destination port/ICMP code | TCP/UDP的目的端口号;ICMP头的代码 |
计数器:
1.各流表的Per Table计数器:
内容 | 比特数 |
Active Entries | 32 |
Packet Lookups | 64 |
Packet Matches | 64 |
2.各物理端口的Per Port计数器:
内容 | 比特数 |
Received Packets | 64 |
Received Bytes | 64 |
Duration(msec) | 32 |
Duration(usec) | 32 |
3.各流表项的Per Flow计数器:
内容 | 比特数 |
Transmit Packets | 64 |
Transmit Bytes | 64 |
Transmit Overrun Errors | 64 |
4.各队列的Per Queue计数器:
内容 | 比特数 |
Received Packets | 64 |
Transmitted Packets | 64 |
Received Bytes | 64 |
Transmitted Bytes | 64 |
Receive Drops | 64 |
Transmit Drops | 64 |
Receive Errors | 64 |
Transmit Errors | 64 |
Receive Frame Alignment Errors | 64 |
Receive Overrun Errors | 64 |
Receive CRC Errors | 64 |
Collisions | 64 |
行动:
Forward,Drop,Enqueue,Modify-Field。
v1.0数据包只能与一个流表的一个流表项匹配。而v1.1以上数据包可以与多个流表的一个流表项匹配。
v1.1流表项构成:
匹配字段(即v1.0的头字段),计数器,指令。
指令:对与流表项匹配的数据包所执行的命令,提供了执行行动,在之后批量执行的行动集中添加及删除行动、写入元数据等功能,移动到已指定流表的动作等指令。
五种指令如下:
1.Apply-Actions:不变更行动集,仅执行指定的行动列表。用于在2个流表中传递并修改数据包或执行同一类型的多个行动时。
2.Clear-Actions:清楚行动集中的所有行动。
3.Write-Actions:将指定的多个行动合并到当前的行动集中,行动集中已存在同一类型时将其覆盖,不存在同一类型时进行添加。
4.Write-Metadata:写入元数据中。
5.Goto-Table:Goto语句。移动到流水线后方连接的流表中,不能跳转到现有位置前方的流表中。最后的流表中不能包含Goto语句。
v1.3流表项构成:
匹配字段,优先级,计数器,指令,超时,Cookie。
下面是OF1.3的数据包结构:
消息格式:of协议数据包由OF Header 和OF Message两部分组成:
Header结构:
1 struct ofp_header { 2 uint8_t version; /*OFP_VERSION.*/ 3 uint8_t type; /*One of the OFPT_constants.*/ 4 uint16_t length; /*Length including this ofp_header.*/ 5 uint32_t xid; /*Transaction id associated with this packet.*/ 6 };
Message结构与具体消息类型有关,上面的type类型有以下几种:
1 enum ofp_type { 2 /* Immutable messages. */ 3 OFPT_HELLO=0, /* Symmetric message */ 4 OFPT_ERROR=1, /* Symmetric message */ 5 OFPT_ECHO_REQUEST=2, /* Symmetric message */ 6 OFPT_ECHO_REPLY=3, /* Symmetric message */ 7 OFPT_VENDOR=4, /* Symmetric message */ 8 9 /* Switch configuration messages. */ 10 OFPT_FEATURES_REQUEST=5, /* Controller/switch message */ 11 OFPT_FEATURES_REPLY=6, /* Controller/switch message */ 12 OFPT_GET_CONFIG_REQUEST=7, /* Controller/switch message */ 13 OFPT_GET_CONFIG_REPLY=8, /* Controller/switch message */ 14 OFPT_SET_CONFIG=9, /* Controller/switch message */ 15 16 /* Asynchronous messages. */ 17 OFPT_PACKET_IN=10, /* Async message */ 18 OFPT_FLOW_REMOVED=11, /* Async message */ 19 OFPT_PORT_STATUS=12, /* Async message */ 20 21 /* Controller command messages. */ 22 OFPT_PACKET_OUT=13, /* Controller/switch message */ 23 OFPT_FLOW_MOD=14, /* Controller/switch message */ 24 OFPT_GROUP_MOD=15, /* Controller/switch message */ 25 OFPT_PORT_MOD=16, /* Controller/switch message */ 26 OFPT_TABLE_MOD=17, /* Controller/switch message */ 27 28 /*Multipart messages.*/ 29 OFPT_MULTIPART_REQUEST=18, /* Controller/switch message */ 30 OFPT_MULTIPART_REPLY=19, /* Controller/switch message */ 31 32 /* Barrier messages. */ 33 OFPT_BARRIER_REQUEST=20, /* Controller/switch message */ 34 OFPT_BARRIER_REPLY=21, /* Controller/switch message */ 35 36 /* Queue Configuration messages. */ 37 OFPT_QUEUE_GET_CONFIG_REQUEST=22, /* Controller/switch message */ 38 OFPT_QUEUE_GET_CONFIG_REPLY=23, /* Controller/switch message */ 39 40 /* Controller role change request messages. */ 41 OFPT_ROLE_REQUEST=24, /* Controller/switch message */ 42 OFPT_ROLE_REPLY=25, /* Controller/switch message */ 43 44 /* Asynchronous message configuration. */ 45 OFPT_GET_ASYNC_REQUEST=26, /* Controller/switch message */ 46 OFPT_GET_ASYNC_REPLY=27, /* Controller/switch message */ 47 OFPT_SET_ASYNC=28, /* Controller/switch message */ 48 49 /* Meters and rate limiters configuration messages. */ 50 OFPT_METER_MOD=29, /* Controller/switch message */ 51 };
控制器与交换机沟通交流过程:
1.hello消息
当交换机连接到控制器时,交换机与控制器会相互发送hello包,而hello消息中只包含of Header,of Header中的version字段为发送方支持的最高版本的of协议版本。如果两者协议版本兼容,则建立of连接,否则发送error消息,断开连接。交换机向控制器发送的Hello消息如下所示:
2.features消息
连接建立后,控制器向交换机发送一个features Request消息查询交换机的特性,features request消息也只包含of Header,交换机接受到该消息之后会返回一个features reply消息,这个消息就包含Header和Message。ps:request和reply两个消息的Transaction ID是一样的。
控制器向交换机发送的OFPT_FEATURES_REQUEST消息:
交换机向控制器响应的OFPT_FEATURES_REPLY消息:
reply消息分析:
[0:8]为header(version、type、length、xid)
[8:32]长度24byte为sw的features,包含如下:
datapath_id:交换机的标识符,低48位是一个MAC地址,高16位是自定义的。
n_buffers:一次最多缓存的数据包数量。
n_tables:表示交换机支持的流表数量。每个流表可以设置不同的通配符和不同数量的流表项。控制器和交换机第一次通信的时候,控制器会从feature_reply消息中找出交换机支持多少流表,如果控制器还想了解大小、类型和流表查询的顺序,就发送一个ofpst_table stats请求,交换机必须按照数据包遍历流表的顺序把这些流表回复给控制器,并且精确匹配流表排在通配流表前。
auxiliary_id:标识辅助连接。
capabilities:所支持的功能。交换机的一些详细信息。
reserved:保留字段。
3.OFPT_MULTIPART_*消息:
1)OFPMP_PORT_DESC:用于传递端口信息
控制器向交换机发送请求端口信息OFPT_MULTIPART_REQUEST,OFPMP_PORT_DESC:
交换机向控制器发送端口回应信息,包括local以及其他连接端口,OFPT_MULTIPART_REPLY,OFPMP_PORT_DESC:
2)OFPMP_DESC:描述交换机的一些额外信息
控制器请求交换机的一些额外信息,OFPT_MULTIPART_REQUEST,OFPMP_DESC:
交换机向控制器回送一些额外信息,OFPT_MULTIPART_REPLY,OFPMP_DESC:
3)OFPMP_TABLE_FEATURES:获取流表信息
控制器请求交换机的流表信息,OFPT_MULTIPART_REQUEST,OFPMP_TABLE_FEATURES:
交换机回送给控制器自己的流表信息,table_id表示第几级流表,OFPT_MULTIPART_REPLY,OFPMP_TABLE_FEATURES[Malformed Packet]:
4.config消息
Of交换机中需要控制器配置的属性有两个flags和miss_send_len。Flags用来指示交换机如何处理IP分片数据包;miss_send_len用来表示当一个交换机无法处理数据,将数据上报给控制器时发送的最大字节数。与转发action中的output中定义的max_len字段一致。
控制器向交换机发送OFPT_GET_CONFIG_REQUEST消息:
消息解释:为了确保配置项已经被写入交换机,控制器会在发送了SET_CONFIG消息之后立即发送一个BARRIER_REQUEST消息,这个消息的作用就是让交换机执行完这个消息之前的所有命令再执行此消息之后的请求,确保交换机的flags和miss send length属性设置成功。当然是有BARRIER_REPLAY消息的。
而SET_CONFIG消息是没有应答消息的,控制器在设置完交换机属性之后会发送GET_CONFIG_REQUEST消息查询交换机的属性。这个消息也是只有of_header的。交换机接收到此消息之会返回一个GET_CONFIG_REPLAY消息。
交换机向控制器发送OFPT_BARRIER_REPLY:
交换机向控制器发送OFPT_GET_CONFIG_REPLY:
5.role消息
一个交换机可能同时与多个处于同等地位的控制器相连。多个控制器处于Slave状态,至多一个控制器处于 Master 状态。每一个控制器都会通过一个OFPT_ROLE_REQUEST消息与交换机交流它的角色,并且交换机必须记住每一个连接的控制器的角色。控制器可能在任何时刻改变自己角色。
控制器向交换机下发OFPT_ROLE_REQUEST消息:
消息解释:这里Role表示该控制器是master角色。
交换机向控制器下发OFPT_ROLE_REPLY消息:
6.flow_mod消息
Flow-Mod消息用于添加、删除、修改openflow交换机的流表项信息;Flow-Mod消息共有5种类型:ADD、DEKETE、DELETE-STRICT、MODIFY、MODIFY_STRICT。
ADD类型消息用来添加一条新的流表项(flow entry)
DELETE类型消息用来删除所有符合一定条件的流表项
DELETE‐STRICT类型消息用来删除某一条指定的流表项
MODIFY类型消息用来修改所有符合一定条件的流表项
MODIFY‐STRICT类型息用来修改某一条指定的流表项
ps:Flow-Mod消息对应修改的是流表中的流表项(flow entry)而不是整个流表(flow table)。
控制器向交换机下发OFPT_FLOW_MOD之DELETE消息:
消息解释:
Cookie为控制器定义流表项标识符
Command是flow-mod的类型,可以是ADD、DELETE、DELETE-STRICT、MODIFY、MODIFY-STRCT;
Ldle_timeout是流表项的空闲超时时间;
Hard_timeout是流表项的最大生存时间;
Priority为流表项的优先级,交换机优先匹配高优先级的流表项;
Buffer_id为交换机中的缓冲区ID,flow-mod消息可以指定一个缓冲区的ID,该缓冲区的数据包会按照此flow-mod消息的action列处理。如果是手动下发的流,buffer_id应填-1,即0xffff,告诉交换机这个数据包并没有缓存在队列中。
Out_port为删除流表的flow_mod消息提供的额外的匹配参数。
Flags为flow-mod命令的一些标志位,可以用来指示流表删除后是否发送flow-removed消息,添加流表时是否检查流表重复项,添加的流表项是否为应急流表项。
当OFPFF_SEND_FLOW_REM 被设置的时候,表项超时删除会触发一条表项删除的信息。
当OFPFF_CHECK_OVERLAP 被设置的时候,交换机必须检查同优先级的表项之间是否有匹配范围的冲突。
当OFPFF_EMERG_被设置的时候,交换机将表项当作紧急表项,只有当与控制器连接断的时候才启用。
控制器向交换机下发OFPT_FLOW_MOD之ADD消息,这里output是指向controller:
7.group_mode消息
这里抓取了四个OFPT_GROUP_MODE消息,还不知道干嘛的?
四个消息分别如下所示:
8.PACKET_OUT消息
Packet-out消息的应用场景:
指定某一个数据包的处理方法
让交换机产生一个数据包并按照action流表处理。
典型应用:链路发现
控制器向一个交换机发送packet-out消息,buffer_id=-1,data段为某种特殊数据包,actions为从交换机的某个端口进行转发,如果发出这个数据包的端口另一端也连接一个openflow交换机,对端的交换机会产生一个packet-in消息将这个特殊的数据包包上交给控制器,从而控制器他侧到一条链路的存在(控制器实现链路发现,就是依靠packet-out消息)。
当控制器断电或者交换机与控制器之间的连接断开,则交换机会寻找备用控制器,当无法找到备用控制器时便会进入紧急模式(交换机初始化时也是在这个模式下),在紧急模式下,交换机默认将所有接受到的数据包丢弃。
控制器向交换机下发OFPT_PACKET_OUT消息:
协议解释:
buffer_id为交换机中缓存数据的buffer_id(同flow-mod);特别注意的是当buffer_id为”-1”的时候,指定的缓冲区为packet-out消息的data段。
In_port为packet-out消息提供额外的匹配信息,当packet-out的buffer_id=-1,并且action流表中指定了output=TABLE的动作,in_port将作为data段数据包的额外匹配信息进行流表查询。
action_len指定了action列表的长度,用来区分actions和data段Data为一个缓冲区,可以存储一个以太网帧。
9.PACKET_IN消息
Packet-in事件在以下两种情况下会被触发:
1.当交换机收到一个数据包后,并未与流表中匹配成功,那么交换机就会将数据封装在Packer-in消息中,发送给控制器处理。此时数据包会被缓存在交换机中等待处理。
2.交换机流表所指示的action列表中包含转发给控制器的动作(Output=Controller),此时数据不会被缓存在控制器中。
交换机向控制器递交OFPT_PACKET_IN消息:
协议解释:
buffer_id是packet-in消息所携带的数据包在交换机中的缓存ID
Total_len为data段的长度
In_port数据包进入交换机的入端口号
Reason为packet-in事件的产生原因
同时,从reason的消息格式也可以看出触发packet-in的两种情况:OFPR_NO_MATCH和OFPR_ACTION。
10.echo消息
查询连接状态,确保通信通畅。当没有其他的数据包进行交换时,controller会定期循环给sw发送OFPT_ECHO_REQUEST。
控制器向交换机发送OFPT_ECHO_REQUEST消息:
交换机向控制器发送OFPT_ECHO_REPLY消息:
11.OFPT_PORT_STATUS,交换机向控制器下报告自己的端口状态