Openflow协议通信流程解读
前言
接触了这么久的SDN,Openflow协议前前后后也读过好多遍,但是一直没有时间总结一下自己的一些见解。现在有时间了,就写一写自己对Openflow协议通信流程的一些理解。
SDN中Switch和controller
在SDN中很重要的两个实体是Switch跟Controller。Controller在网络中相当于上帝,可以知道网络中所有的消息,可以给交换机下发指令。Switch就是一个实现Controller指令的实体,只不过这个交换机跟传统的交换机不一样,他的转发规则由流表指定,而流表由控制器发送。
switch组成与传统交换机的差异 switch组成
页脚内容 OPC通讯协议介绍 switch由一个Secure Channel和一个flow table组成,of1.3之后table变成多级流表,有256级。而of1.0中table只在table0中。
Secure Channel是与控制器通信的模块,switch和controller之间的连接时通过socket连接实现。
Flow table里面存放这数据的转发规则,是switch的交换转发模块。数据进入switch之后,在table中寻找对应的flow进行匹配,并执行相应的action,若无匹配的flow则产生packet_in(后面有讲)
of中sw与传统交换机的差异
匹配层次高达4层,可以匹配到端口,而传统交换机只是2层的设备。 运行of协议,实现许多路由器的功能,比如组播。 求补充!!(如果你知道,请告诉我,非常感谢!)
openflow的switch可以从以下方式获得
实体of交换机,目前市场上有一些厂商已经制造出of交换机,但是普遍反映价格较贵!性能最好。
在实体机上安装OVS,OVS可以使计算机变成一个openflow交换机。性能相对稳定。 使用mininet模拟环境。可以搭建许多交换机,任意拓扑,搭建拓扑具体教程本博客有一篇。性能依赖虚拟机的性能。
controller组成
控制器有许多种,不同的语言,如python写的pox,ryu,如java写的floodlight等等。从功能层面controller分为以下几个模块:
底层通信模块:openflow中目前controller与switch之间使用的是socket连接,所以控制器底层的通信是socket。
openflow协议。socket收到的数据的处理规则需按照openflow协议去处理。 上层应用:根据openflow协议处理后的数据,开发上层应用,比如pox中就l2_learning,l3_learning等应用。更多的应用需要用户自己去开发。
Openflow通信流程
以下教程环境为:mininet+自编简单控制器
建立连接
页脚内容 OPC通讯协议介绍 首先启动mininet,mininet会自行启动一个default拓扑,你也可以自己建立你的拓扑。sw建立完成之后,会像controllerIP:controllerport发送数据。
controller启动之后,监听指定端口,默认6633,但是好像以后的都改了,因为该端口被其他协议占用。
3次握手之后,建立连接,这个是底层的通信,是整一套系统的基础设施。
OFPT_HELLO
创建socket之后,sw跟controller会彼此发送hello数据包。
目的:协议协商。
内容:本方支持的最高版本的协议 成果:使用双方都支持的最低版本协议。 成功:建立连接
失败:OFPT_ERROR (TYPE:OFPT_HELLO_FAILED,CODE =0),终止连接。
OFPT_ERROR
说到OFPT_ERROR,我们不妨先了解一下。
ofp_error_type = { 0: \"OFPET_HELLO_FAILED\ 1: \"OFPET_BAD_REQUEST\ 2: \"OFPET_BAD_ACTION\ 3: \"OFPET_FLOW_MOD_FAILED\ 4: \"OFPET_PORT_MOD_FAILED\ 5: \"OFPET_QUEUE_OP_FAILED\ 错误类型如上所示。对应的type还会有对应的code.所以报错的格式为:
OFPT_ERROR TYPE: 页脚内容 OPC通讯协议介绍 CODE: [PAYLOAD]具体的错误信息。 如 TYPE:0 CODE:0为:*OFPHFC_INCOMPATIBLE* 具体对应的关系,请自行查看OF协议。
OFPT_ECHO
分类:对称信息 OFPT_ECHO_REQUEST, OFPT_ECHO_REPLY 作用:查询连接状态,确保通信通畅。
当没有其他的数据包进行交换时,controller会定期循环给sw发送OFPT_ECHO_REQUEST。
OFPT_FEATURES
当sw跟controller完成连接之后,控制器会向交换机下发OFPT_FEATYRES_REQUEST的数据包,目的是请求交换机的信息。
发送时间:连接建立完成之后 发送数据:OFPT_FEATURES_REQUEST 对称数据:OFPT_FEATURES_REPLY 目的:获取交换机的信息
OFPT_FEATURES_REQUEST
TYPE=5 Without data
OFPT_FEATURES_REPLY
TYPE =6 [0:8]为header
[8:32]长度24byte为sw的features
[32:]长度与端口数成正比,存放port的信息。每一个port信息长度为48byte。
class ofp_features_reply(Packet): name = \"OpenFlow Switch Features Reply\" 页脚内容 OPC通讯协议介绍 fields_desc=[ BitFieldLenField('datapath_id', None, , length_of='varfield'), BitFieldLenField('n_buffers', None, 32, length_of='varfield'), XByteField(\"n_tables\ X3BytesField(\"pad\ #features BitField(\"NOT DEFINED\ BitField(\"OFPC_ARP_MATCH_IP\ BitField(\"OFPC_QUEUE_STATS\ BitField(\"OFPC_IP_STREAM\ BitField(\"OFPC_RESERVED\ BitField(\"OFPC_STP\ BitField(\"OFPC_PORT_STATS\ BitField(\"OFPC_TABLE_STATS\ BitField(\"OFPC_FLOW_STATS\ BitFieldLenField('actions', None, 32, length_of='varfield'), ] bind_layers( ofp_header, ofp_features_reply, type=6 ) 以上的结构是交换机的features,紧跟在后面的是端口的结构:
class ofp_phy_port(Packet): name = \"OpenFlow Port\" fields_desc=[ ShortEnumField(\"port_no\ MACField(\"hw_addr\ 页脚内容 OPC通讯协议介绍 StrFixedLenField(\"port_name\ BitField(\"not_defined\ BitField(\"OFPPC_NO_PACKET_IN\ BitField(\"OFPPC_NO_FWD\ BitField(\"OFPPC_NO_FLOOD\ BitField(\"OFPPC_NO_RECV_STP\ BitField(\"OFPPC_NO_RECV\ BitField(\"OFPPC_NO_STP\ BitField(\"OFPPC_PORT_DOWN\ #uint32_t for state BitField(\"else\ BitField(\"OFPPS_LINK_DOWN\ #uint32_t for Current features BitField(\"not_defined\ BitField(\"OFPPF_PAUSE_ASYM\ BitField(\"OFPPF_PAUSE\ BitField(\"OFPPF_AUTONEG\ BitField(\"OFPPF_FIBER\ BitField(\"OFPPF_COPPER\ BitField(\"OFPPF_10GB_FD\ BitField(\"OFPPF_1GB_FD\ BitField(\"OFPPF_1GB_HD\ 页脚内容 OPC通讯协议介绍 BitField(\"OFPPF_100MB_FD\ BitField(\"OFPPF_100MB_HD\ BitField(\"OFPPF_10MB_FD\ BitField(\"OFPPF_10MB_HD\ #uint32_t for features being advised by the port BitField(\"advertised\ #uint32_t for features supported by the port BitField(\"supported\ #uint32_t for features advertised by peer BitField(\"peer\ 交换机和端口的配置信息在整一个通信过程起着至关的作用,因为所有关于的操作都需要从features里面提取相关的信息,如dpid,port_no,等在整个通信过程中多次被用到的重要数据。所以,对这两个数据结构了然于心,对于研究openflow来说,至关重要。每一次交换机连到控制器,都会收到控制器的features_request,当sw将自己的features回复给控制器之后,控制器就对交换机有了一个全面的了解,从而为后面的控制提供的控制信息。
OFPT_PACKET_IN
在控制器获取完交换机的特性之后,交换机开始处理数据。
对于进入交换机而没有匹配流表,不知道如何操作的数据包,交换机会将其封装在packet_in中发给controller。包含在packet_in中的数据可能是很多种类型,arp和icmp是最常见的类型。 当然产生packet_in的原因不止一种,产生packet_in的原因主要有一下两种:
OFPR_NO_MATCH OFPR_ACTION
页脚内容 OPC通讯协议介绍 无法匹配的数据包会产生packet_in,action也可以指定将数据包发给packet_in,也就是说我们可以利用这一点,将需要的数据包发给控制器。 packet_in事件之后,一般会触发两类事件:
packet_out flow_mod
如果是广播包,如arp,控制器一般会将其包装起来,封装成packet_out数据包,将其发给交换机,让其flood,flood操作是将数据包往除去in_port以外的所有端口发送数据包。
OFPT_PACKET_OUT
很多人不是特别了解packet_out的作用。
作用:通过控制器发送交换机希望发送的数据
例子:arp在广播的时候,在ofsw中不能直接将arp广播,而是,将其封装在packet_out里面,交换机泛洪的是packet_out。
我个人观点,这个数据包,是一个兼容性之的数据包,为了实现信令,不得不处理arp,但是arp又不能直接处理,所以将其封装在packet_out,从而能够在of的sw中传播,从而在openflow里实现arp等IP网的功能。
OFPT_FLOW_MOD
OFPT_FLOW_MOD是整一个Openflow协议中最重要的数据结构,没有之一。
OFPT_FLOW_MOD由header+match+flow_mod+action[]组成。为了操作简单,以下的结构是将wildcards和match分开的形式,形成两个结构,在编程的时候能更方便一些。由于这个数据包很重要,所以,我将把这个数据包仔细拆分解读。
flow_mod = of.ofp_header(type=14,length=72)/of.ofp_flow_wildcards(OFPFW_NW_TOS=1, OFPFW_DL_VLAN_PCP=1, OFPFW_NW_DST_MASK=0, OFPFW_NW_SRC_MASK=0, 页脚内容 OPC通讯协议介绍 OFPFW_TP_DST=1, OFPFW_TP_SRC=1, OFPFW_NW_PROTO=1, OFPFW_DL_TYPE=1, OFPFW_DL_VLAN=1, OFPFW_IN_PORT=1, OFPFW_DL_DST=1, OFPFW_DL_SRC=1)\\ /of.ofp_match(in_port=msg.payload.payload.payload.in_port, dl_src=pkt_parsed.src, dl_dst=pkt_parsed.dst, dl_type=pkt_parsed.type, dl_vlan=pkt_parsed.payload.vlan, nw_tos=pkt_parsed.payload.tos, nw_proto=pkt_parsed.payload.proto, nw_src=pkt_parsed.payload.src, nw_dst=pkt_parsed.payload.dst, tp_src = 0, tp_dst = 0)\\ /of.ofp_flow_mod(cookie=0, command=0, idle_timeout=10, hard_timeout=30, 页脚内容 OPC通讯协议介绍 out_port=msg.payload.payload.payload.payload.port, buffer_id=buffer_id, flags=1) OFP_HEADER
header是所有数据包的报头,有三个参数:
type:类型
length:整个数据包的长度 xid:数据包的编号
比如ofp_flow_mod的type就是14,具体的哪一种数据的类型将在文章最后给出。length最基本长度为72,每一个action长度为8。所以长度必定为8的倍数才是一个正确的数据长度。
WILDCARDS
这是从match域提取出来的前32bit。
在of1.0中这里的0,1意义跟我们平时接触的如子网掩码等意义相反,如
OFPFW_NW_DST_MASK=0则表示全匹配目标IP。如果为63,则表示不匹配IP。为什么拿这个举例?原因就在于,他的长度是6bit,最大是63,需要将数值转变成对应2进制数值才是我们想要的匹配规则,且注意,1是忽略,0是匹配。如果wildcards全0,则表示由match精确指定,即所有12元组都匹配。
当然高兴的是,在1.3的时候,这个逻辑改成了正常的与逻辑。即1为使能匹配,0为默认不匹配。
MATCH
这个数据结构会出现在几乎所有重要的数据包中,因为他存的就是控制信息。
如有packet_in引发的下发流表,则match部分应对应填上对应的数据,这样下发的流表才是正确的。
但是在下发的时候还需要注意许多细节,比如:
页脚内容 OPC通讯协议介绍 并不是所有的数据包都有vlan_tag。如0×0800就是纯IP,并没有携带vlan_tag,所以填充式应根据packet_in的具体情况填充。
并不是所有的数据都有四层端口,所以四层的源端口,目的端口都不是任何时候都能由packet_in去填充的。不去管就好了,默认的会填充一个默认值,匹配的时候不去匹配4层端口就没有问题。
FLOW_MOD
这里面的信息也是至关重要的。
class ofp_flow_mod(Packet): name = \"OpenFlow Flow Modify\" fields_desc=[ BitField(\"cookie\ ShortEnumField(\"command\ ShortField(\"idle_timeout\ ShortField(\"hard_timeout\ ShortField(\"priority\ IntField(\"buffer_id\ ShortField(\"out_port\ #flags are important, the 1<<0 bit is OFPFF_SEND_FLOW_REM, send OFPT_FLOW_REMOVED #1<<1 bit is OFPFF_CHECK_OVERLAP, checking if the entries' field overlaps(among same priority) #1<<2 bit is OFPFF_EMERG, used only switch disconnected with controller) ShortField(\"flags\ command里面的类型决定了flow_mod的操作是添加,修改还是删除等。类型如下
ofp_flow_mod_command = { 0: \"OFPFC_ADD\ 1: \"OFPFC_MODIFY\ 页脚内容 OPC通讯协议介绍 2: \"OFPFC_MODIFY_STRICT\ 3: \"OFPFC_DELETE\ 4: \"OFPFC_DELETE_STRICT\ 例如:如果要添加一条新流,command=0。
两个时间参数idle_timeout & idle_timeout:
idle_timeout:如值为10,则某条流在10秒之内没有被匹配,则删除,可以称之为活跃时间吧。
hard_timeout:如值为30,则30秒到达的时候,一定删除这条流,即使他还活跃,即被匹配。
priority
priority是流的优先级的字段,字数越大则优先级越高,存放在号数越小的table中。
buffer_id
由交换机指定的buffei_id,准确的说是由dpid指定的。如果是手动下发的流,buffer_id应填-1,即0xffff,告诉交换机这个数据包并没有缓存在队列中。
out_port
指定流的出口,但是这个出口并不是直接指导流转发的,至少我是这么觉得,指导流转发的出口会在action里面添加,这个端口是为了在flow_removed的时候查询,并返回控制器的作用。(求纠正!)
有一些端口是很特殊的,如flood,local等。具体分类如下:
ofp_port = { 0xff00: \"OFPP_MAX\ 0xfff8: \"OFPP_IN_PORT\ 0xfff9: \"OFPP_TABLE\ 0xfffa: \"OFPP_NORMAL\ 页脚内容 OPC通讯协议介绍 0xfffb: \"OFPP_FLOOD\ 0xfffc: \"OFPP_ALL\ 0xfffd: \"OFPP_CONTROLLER\ 0xfffe: \"OFPP_LOCAL\ 0xffff: \"OFPP_NONE\ 如果你不知道端口是多少,最好填flood,也就是0xfffb。
flags
在上面的注释中也说得比较清楚了。如果没有特殊用处,请将他置1,因为这样能让交换机在删除一条流的时候给交换机上报flow_removed信息。
ACTION
action是openflow里面最重要的结构。对,他也是最重要的。每一条流都必须指定必要的action,不然匹配上之后,没有指定action,交换机会默认执行drop操作。 action有2种类型:
必备行动: Forward and Drop 选择行动:FLOOD,NALMAL 等
如添加output就是一个必须要添加的action.每一个action最好有一个action_header(),然后再接一个实体。如:
ofp_action_header(type=0)/ofp_action_output(type =0, port =oxfffb,len =8) 具体的action类型如下:
ofp_action_type = { 0: \"OFPAT_OUTPUT\ 1: \"OFPAT_SET_VLAN_VID\ 2: \"OFPAT_SET_VLAN_PCP\ 页脚内容 OPC通讯协议介绍 3: \"OFPAT_STRIP_VLAN\ 4: \"OFPAT_SET_DL_SRC\ 5: \"OFPAT_SET_DL_DST\ 6: \"OFPAT_SET_NW_SRC\ 7: \"OFPAT_SET_NW_DST\ 8: \"OFPAT_SET_NW_TOS\ 9: \"OFPAT_SET_TP_SRC\ 10: \"OFPAT_SET_TP_DST\ 11: \"OFPAT_ENQUEUE\" } action不仅仅会出现在flow_mod中,也会出现在如stats_reply中。
OFPT_BARRIER_REQUEST && REPLY
这个数据包可以的作用很简单,交换机在收到OFPT_BARRIER_REQUEST的时候,会回复控制器一个OFPT_BARRIER_REPLY。我们默认数据下发的顺序不会在传输中发生变化,在进入消息队列之后处理也是按照FIFO进行的,那么只要在flow_mod之后发送这个数据,当收到reply之后,交换机默认flow已经写成功。也许你会问他只是保证了flow_mod命令执行了,写入的结果如何并没有保证,如何确定确实写入流表了呢?
如果非逻辑错误,那么交换机在处理flow_mod的时候会报错。所以我们会知道写入结果。
如果是逻辑错误,那么会写进去,但是逻辑错误应该是人的问题,所以barrier还是有他的功能的。
OFPT_FLOW_REMOVED
如果flow_mod的flags填成1,则该流在失效之后会回复控制器一条OFPT_FLOW_REMOVED信息。
结构:header()/wildcards()/match()/flow_removed()
页脚内容 OPC通讯协议介绍 作用:在流失效的时候回复控制器,并携带若干统计数据。
class ofp_flow_removed(Packet): name = \"Openflow flow removed\" fields_desc = [ BitField(\"cookie\ BitField(\"priority\ BitField(\"reason\ ByteField(\"pad\ BitField(\"duration_sec\ BitField(\"duration_nsec\ BitField(\"idle_timeout\ ByteField(\"pad\ ByteField(\"pad\ BitField(\"packet_count\ BitField(\"byte_count\ ] 其实的duration_sec是流存在的时间,单位为秒,duration_nsec单位为纳秒。
OFPT_STATS_REQUEST && REPLY
以上的数据都是通信过程中必须的部分。还有一些数据包是为了某些目的而设计的,如OFPT_STATS_REQUEST && REPLY可以获得统计信息,我们可以利用统计信息做的事情就太多了。如:负载平衡, 流量监控等基于流量的操作。
OFPT_STATS_REQUEST
OFPT_STATS_REQUEST类型有很多,回复的类型也很多。
页脚内容 OPC通讯协议介绍 class ofp_stats_request(Packet): name = \"OpenFlow Stats Request\" fields_desc=[ ShortEnumField(\"type\ ShortField(\"flag\ Type
0:请求交换机版本信息,制造商家等信息。 1:单流请求信息 2:多流请求信息 3:流表请求信息 4:端口信息请求 5:队列请求信息
6:vendor请求信息,有时候没有定义。
msg = { 0: of.ofp_header(type = 16, length = 12)/of.ofp_stats_request(type = 0), #Type of OFPST_DESC (0) 1: of.ofp_header(type = 16, length = 56)/of.ofp_stats_request(type =1)/ofp_flow_wildcards/ofp_match/of.ofp_flow_stats_request(out_port = ofp_flow_mod.out_port), #flow stats 2: of.ofp_header(type = 16, length =56)/of.ofp_stats_request(type = 2)/ofp_flow_wildcards/of.ofp_match/of.ofp_aggregate_stats_request(), # aggregate stats request 3: of.ofp_header(type = 16, length = 12)/of.ofp_stats_request(type = 3), #Type of OFPST_TABLE (0) 4: of.ofp_header(type = 16, length =20)/of.ofp_stats_request(type = 4)/of.ofp_port_stats_request(port_no = port), # port stats request 页脚内容 OPC通讯协议介绍 5: of.ofp_header(type = 16, length =20)/of.ofp_stats_request(type =5)/of.ofp_queue_stats_request(), #queue request 6: of.ofp_header(type = 16, length = 12)/of.ofp_stats_request(type = 0xffff) #vendor request } OFPT_STATS_REPLY
每一种请求信息都会对应一种回复信息。我们只介绍最重要的flow_stats_reply。
结构:header(type=17)/reply_header()/flow_stats/wildcards/match/ flow_stats_data 作用:携带流的统计信息,如通过的数据包个数,字节数。
ofp_flow_stats(body[4:8])里面会有的table_id字段表明该流存放在哪一个流表里。
flow_stats_data里面有packet_count和byte_count是最有价值的字段,流量统计就是由这两个字段提供的信息。
如想统计某条流的速率:前后两个reply的字节数相减除以duration_time只差就可以求得速率 由速率我们可以做很多基于流量的app,如流量监控,负载均衡等等。
值得注意的是,在这些数据之后,其实还有一些action,但是目前我还没有查看这些action到底是干什么用的。
后续
写到这里,我使用到的数据包都写了一遍,其他的报文其实道理也是一样的。如
OFPT_GET_CONFIG_REQUEST和REPLY,道理应该和stats一样,只是数据结构不一样罢了。不再多说。
最后把我们用的一些比较多的信息帖出来让大家更好的学习。
ERROR
页脚内容 OPC通讯协议介绍 在调试的过程中遇到错误是再所难免的,前面也提到了error的结构。这里就贴一下type跟code吧。
Type
ofp_error_type = { 0: \"OFPET_HELLO_FAILED\ 1: \"OFPET_BAD_REQUEST\ 2: \"OFPET_BAD_ACTION\ 3: \"OFPET_FLOW_MOD_FAILED\ 4: \"OFPET_PORT_MOD_FAILED\ 5: \"OFPET_QUEUE_OP_FAILED\ Code:
ofp_hello_failed_code = { 0: \"OFPHFC_INCOMPATIBLE\ 1: \"OFPHFC_EPERM\ ofp_bad_request_code = { 0: \"OFPBRC_BAD_VERSION\ 1: \"OFPBRC_BAD_TYPE\ 2: \"OFPBRC_BAD_STAT\ 3: \"OFPBRC_BAD_VENDOR\ 4: \"OFPBRC_BAD_SUBTYPE\ 5: \"OFPBRC_EPERM\ 6: \"OFPBRC_BAD_LEN\ 7: \"OFPBRC_BUFFER_EMPTY\ 8: \"OFPBRC_BUFFER_UNKNOWN\ ofp_bad_action_code = { 0: \"OFPBAC_BAD_TYPE\ 页脚内容 OPC通讯协议介绍 1: \"OFPBAC_BAD_LEN\ 2: \"OFPBAC_BAD_VENDOR\ 3: \"OFPBAC_BAD_VENDOR_TYPE\ 4: \"OFPBAC_BAD_OUT_PORT\ 6: \"OFPBAC_BAD_ARGUMENT\ 7: \"OFPBAC_EPERM\ 8: \"OFPBAC_TOOMANY\ 9: \"OFPBAC_BAD_QUEUE\ ofp_flow_mod_failed_code = { 0: \"OFPFMFC_ALL_TABLES_FULL\ 1: \"OFPFMFC_OVERLAP\ 2: \"OFPFMFC_EPERM\ 3: \"OFPFMFC_BAD_EMERG_TIMEOUT\ 4: \"OFPFMFC_BAD_COMMAND\ 5: \"OFPFMFC_UNSUPPORT\ ofp_port_mod_failed_code = { 0: \"OFPPMFC_BAD_PORT\ 1: \"OFPPFMC_BAD_HW_ADDR\ ofp_queue_op_failed_code = { 0: \"OFPQOFC_BAD_PORT\ 1: \"OFPQOFC_BAD_QUEUE\
页脚内容 OPC通讯协议介绍
第二章 理论基础
2.1软件定义网络SDN
软件定义网络(英语:Software-defined networking,缩写为SDN),一种网络虚拟化(Network virtualization)技术,由美国史丹佛大学Clean State提出。利用OpenFlow协定,把路由器的控制平面(control plane)从数据平面(data plane)中分离出来,以软件方式实做。这个架构可以让网络管理员,在不更动硬件装置的前提下,以控制方式,用程式重新规划网络,为控制网络流量提供了新的方法,也提供了核心网络及应用创新的良好平台。
2.2 openflow网络架构
OpenFlow网络由OpenFlow交换机、FlowVisor和Controller三部分组成。OpenFlow交换机进行数据层的转发;FlowVisor对网络进行虚拟化;Controller对网络进行集中控制,实现控制层的功能。如下图所示:
页脚内容 OPC通讯协议介绍
2.2.1 openflow交换机
OpenFlow交换机由流表、安全通道和OpenFlow协议三部分组成。OpenFlow交换机是整个OpenFlow网络的核心部件,主要管理数据层的转发。OpenFlow交换机接收到数据包后,首先在本地的流表上查找转发目标端口,如果没有匹配,则把数据包转发给Controller,由控制层决定转发端口。
2.2.1.1 流表
流表包括包头域(header fileds,匹配包头多个域)、活动计数器(counters)、0 个或多个执行行动(actions)如图二所示。对每一个包进行查找,如果匹配则执行相关策略,否则通过安全通道将包转发到控制器,控制器来决策相关行为。流表项可以将包转发到一个或者多个接口。
Head Fileds
Counter
Actions 图二:流表
包头域包括12 个域,如图三所示,包括:进入接口,Ethernet 源地址、目标地址、类型,vlan id,vlan 优先级,IP 源地址、目标地址、协议、IP ToS 位,TCP/UDP 目标端口、源端口。每一个域包括一个确定值或者所有值(any),更准确的匹配可以通过掩码实现。
页脚内容 OPC通讯协议介绍 Ingress Port Ether Source
Ether Dst
Ether Type
Vlan id
Vlan Priority
IP IP src dst
IP proto IP Tos bits TCP/UDP src Port TCP/UDP Dst Port 图三:包头域
计数器可以针对每张表、每个流、每个端口、每个队列来维护。用来统计流量的一些信息,例如活动表项、查找次数、发送包数等。统计信息所需要的计数器如图四所示:
每个表项对应到0 个或者多个行动,如果没有转发行动,则默认丢弃。多个行动的执行需要依照优先级顺序依次进行。但对包的发送不保证顺序。另外交换机可以对不支持的行动返回错误(unspported flow error)。
行动可以分为两种类型:必备行动(Required Actions)和可选行动(Optional Actions),必备行动是默认支持的,交换机需要通知控制器它支持的可选行动。
必备行动-转发(Forward)
ALL 转发到所有出口(不包括入口) CONTROLLER 封装并转发给控制器 LOCAL 转发给本地网络栈
TABLE 对要发出的包执行流表中的行动 IN_PORT 从入口发出
必备行动-丢弃(Drop)
没有明确指明处理行动的表项,所匹配的所有网包默认丢弃。 可选行动-转发
NORMAL 按照传统交换机的2 层或3 层进行转发处理。
页脚内容 OPC通讯协议介绍 FLOOD 通过最小生成树从出口泛洪发出,注意不包括入口。
可选行动-入队(Enqueue)
将包转发到绑定到某个端口的队列中。 可选行动-修改域(Modify-field) 修改包头内容。 Counter Per Table Active Entries Packet Lookups Per Flow Received Packets Received Bytes Durations(seconds) Per Port Received Packets Transmitted Packets Received Bytes Transmitted Bytes Received Drops Transmit Drops Received Errors Bits 32 32 页脚内容 OPC通讯协议介绍 Transmit Drops Receive Frame Alignment Errors Receive Overrun Errors Receive CRC Errors Collisions Per Queue Transmit Packets Transmit Bytes Transmit Overrun Errors
图四:信息统计计数器
2.2.1.2 流表匹配
每个包按照优先级依次去匹配流表中表项,匹配包的优先级最高的表项即为匹配结果。一旦匹配成功,对应的计数器将更新;如果没能找到匹配的表项,则转发给控制器。整体流程参见图五,具体包头解析匹配过程见图六。
页脚内容 图五:整体匹配流程
OPC通讯协议介绍
图六: 包头解析的匹配流程
页脚内容 OPC通讯协议介绍
2.2.2 openflow 控制器
OpenFlow实现了数据层和控制层的分离,其中OpenFlow交换机进行数据层的转发,而Controller实现了控制层的功能。Controller通过OpenFlow协议这个标准接口对OpenFlow交换机中的流表进行控制,从而实现对整个网络进行集中控制。Controller的这一切功能都要通过运行NOX来实现,因此NOX就像是OpenFlow网络的操作系统。
NOX 主要功能包括两部分,一是针对下层的SDN 交换机(例如of 交换机)作为控制器,解析交换机行为和进行管理操作;一是针对上层网络管理app 开发者,作为一个抽象层(操作系统)提供易用的开发接口。针对这两部分功能,NOX 的开发模型主要包括两个部分。
一是集中的编程模型。开发者不需要关心网络的实际架构,部署在单一节点上的NOX管理网络中的所有交换设备,解析后呈现给开发者。在开发者看来整个网络就好像一台单独的机器一样,有统一的资源分配和接口管理。
二是抽象的开发模型。应用程序开发需要面向的是NOX 提供的高层接口,而不是底层。例如,应用面向的是用户、机器名,但不面向IP 地址、MAC 地址等。正如计算机操作系统本身并不实现复杂的各种软件功能,NOX 本身并不完成对网络管理任务,而是通过在其上运行的各种“应用”(Application)来实现具体的管理任务。
页脚内容 OPC通讯协议介绍
2.2.3 openflow 虚拟化
类比计算机的虚拟化,FlowVisor就是位于硬件结构元件和软件之间的网络虚拟层。FlowVisor允许多个控制同时控制一台OpenFlow交换机,但是每个控制器仅仅可以控制经过这个OpenFlow交换机的某一个虚拟网络(即slice)。因此通过FlowVisor建立的试验平台可以在不影响商业流的转发速度的情况下,允许多个网络试验在不同的虚拟网络上同时进行。FlowVisor与一般的商用交换机是兼容的,
而不需要使用FPGA和网络处理器等可编程硬件。
2.3 安全通道
安全通道用来连接交换机和控制器,所有安全通道必须遵守of 协议。控制器可以配置、管理交换机、接收交换机的事件信息,并通过交换机发出网包等。
2.3.1 OF协议
of 协议支持三种消息类型:controller-to-switch,asynchronous(异步)和symmetric(对称),每一类消息又有多个子消息类型。controller-to-switch 消息由控制器发起,用
页脚内容 OPC通讯协议介绍 来管理或获取switch 状态;asynchronous 消息由switch 发起,用来将网络事件或交换机状态变化更新到控制器;symmetric 消息可由交换机或控制器发起。
2.3.1.1 controller—to—switch 消息
由控制器(controller)发起,可能需要或不需要来自交换机的应答消息。包括Features、Configuration、Modify-state、Read-state、Send-packet、Barrier 等。
Features
在建立传输层安全会话(Transport Layer Security Session)的时候,控制器发送feature请求消息给交换机,交换机需要应答自身支持的功能。
Configuration
控制器设置或查询交换机上的配置信息。交换机仅需要应答查询消息。 Modify 修改-state
控制器管理交换机流表项和端口状态等。 Read-state
控制器向交换机请求一些诸如流、网包等统计信息。 Send-packet
控制器通过交换机指定端口发出网包。 Barrier 障碍物
控制器确保消息依赖满足,或接收完成操作的通知。 2.3.1.2 asynchronous 消息
页脚内容 OPC通讯协议介绍 asynchronous 不需要控制器请求发起,主要用于交换机向控制器通知状态变化等事件信息。主要消息包括Packet-in、Flow-removed、Port-status、Error 等。
Packet-in
交换机收到一个网包,在流表中没有匹配项,则发送Packet-in 消息给控制器。如果交换机缓存足够多,网包被临时放在缓存中,网包的部分内容(默认128 字节)和在交换机缓存中的的序号也一同发给控制器;如果交换机缓存不足以存储网包,则将整个网包作为消息的附带内容发给控制器。
Flow-removed
交换机中的流表项因为超时或修改等原因被删除掉,会触发Flow-removed 消息。
Port-status
交换机端口状态发生变化时(例如down 掉),触发Port-status 消息。 Error
交换机通过Error 消息来通知控制器发生的问题。
2.3.1.3 symmetric 消息
symmetric 消息也不必通过请求建立,包括Hello、Echo、Vendor 等。 Hello
交换机和控制器用来建立连接。 Echo
页脚内容 OPC通讯协议介绍 交换机和控制器均可以向对方发出Echo 消息,接收者则需要回复Echo reply。该消息用来测量延迟、是否连接保持等。
Vendor
交换机提供额外的附加信息功能。为未来版本预留。
2.3.2 建立连接
通过安全通道建立连接,所有流量都不经过交换机流表检查。因此交换机必须将安全通道认为是本地链接。今后版本中将介绍动态发现控制器的协议。
当 of 连接建立起来后,两边必须先发送OFPT_HELLO 消息给对方,该消息携带支持的最高协议版本号,接受方将采用双方都支持的最低协议版本进行通信。一旦发现两者拥有共同支持的协议版本, 则连接建立, 否则发送OFPT_ERROR 消息( 类型为OFPET_HELLO_FAILED,代码为OFPHFC_COMPATIBLE),描述失败原因,并终止连接。
2.3.3 连接中断
当连接发生异常时,交换机应尝试连接备份的控制器。当多次尝试均失败后,交换机将进入紧急模式,并重置所有的TCP 连接。此时,所有包将匹配指定的紧急模式表项,其他所有正常表项将从流表中删除。此外,当交换机刚启动时,默认进入紧急模式。
页脚内容 OPC通讯协议介绍 2.3.4 加密
安全通道采用TLS(Transport Layer Security)连接加密。当交换机启动时,尝试连接到控制器的6633 TCP 端口。双方通过交换证书进行认证。因此,每个交换机至少需配置两个证书,一个是用来认证控制器,一个用来向控制器发出认证。
2.3.5 生成树
交换机可以选择支持802.1D 生成树协议。如果支持,所有相关包在查找流
表之前应该先在本地进行传统处理。支持生成树协议的交换机在
OFPT_FEATURES_REPLY 消息的compabilities 域需要设置OFPC_STP 位,并且需要在所有的物理端口均支持生成树协议,
但无需在虚拟端口支持。生成树协议会设置端口状态,来发到OFP_FLOOD 的网包仅被转发到生成树指定的端口。需要注意指定出口的转发或OFP_ALL 的网包会忽略生成树指定的端口状态,按照规则设置端口转发。如果交换机不支持802.1D 生成树协议,则必须允许控制器指定泛洪时的端口状态。
页脚内容
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- yrrf.cn 版权所有 赣ICP备2024042794号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务