openflow通信流程总结

参考链接
switch由secure channnel 和flow table 组成,of1.3之后table变成多级流表,有256级。
Secure Channel是与控制器通信的模块,switch和controller之间的连接时通过socket连接实现。
Flow table里面存放这数据的转发规则,是switch的交换转发模块。数据进入switch之后,在table中寻找对应的flow进行匹配,并执行相应的action,若无匹配的flow则产生packet_in
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”}
通信:
1 3次握手,sw与con建立socket连接
2 sw 与con 互相发送OFTP_HELLO数据包,使用双方支持的最低版本协议,建立连接
3 OFPT_ECHO_REQUEST, OFPT_ECHO_REPLY:查询连接状态,确保通信通畅。当没有其他的数据包进行交换时,controller会定期循环给sw发送OFPT_ECHO_REQUEST。
4获取交换机的信息 当sw跟controller完成连接之后,控制器会向交换机下发OFPT_FEATURES_REQUEST的数据包,目的是请求交换机的信息。对称数据:OFPT_FEATURES_REPLY
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”
fields_desc=[ BitFieldLenField(‘datapath_id’, None, 64, length_of=‘varfield’),
BitFieldLenField(‘n_buffers’, None, 32, length_of=‘varfield’),
XByteField(“n_tables”, 0),
X3BytesField(“pad”, 0),
#features
BitField(“NOT DEFINED”, 0, 24),
BitField(“OFPC_ARP_MATCH_IP”, 0, 1), #1<<7 Match IP address in ARP packets
BitField(“OFPC_QUEUE_STATS”, 0, 1), #1<<6 Queue statistics
BitField(“OFPC_IP_STREAM”, 0, 1), #1<<5 Can reassemble IP fragments
BitField(“OFPC_RESERVED”, 0, 1), #1<<4 Reserved, must be zero
BitField(“OFPC_STP”, 0, 1), #1<<3 802.1d spanning tree
BitField(“OFPC_PORT_STATS”, 0, 1), #1<<2 Port statistics
BitField(“OFPC_TABLE_STATS”, 0, 1), #1<<1 Table statistics
BitField(“OFPC_FLOW_STATS”, 0, 1), #1<<0 Flow statistics
BitFieldLenField(‘actions’, None, 32, length_of=‘varfield’),
]
bind_layers( ofp_header, ofp_features_reply, type=6 )
交换机和端口的配置信息在整一个通信过程起着至关的作用,因为所有关于的操作都需要从features里面提取相关的信息,如dpid、port_no,等在整个通信过程中多次被用到的重要数据。所以,对这两个数据结构了然于心,对于研究OpenFlow来说,至关重要。
5 OFPT_PACKET_IN
对于进入交换机而没有匹配流表,不知道如何操作的数据包,交换机会将其封装在packet_in中发给controller。包含在packet_in中的数据可能是很多种类型,arp和icmp是最常见的类型。
产生packet_in的原因主要有一下两种:
OFPR_NO_MATCH
OFPR_ACTION
packet_in事件之后,一般会触发两类事件:
packet_out
flow_mod
packet_out的作用在与指导交换机做flood操作,并把ARP包广播出去,packet_out本身并不携带arp数据包。
6 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,
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, out_port=msg.payload.payload.payload.payload.port,
buffer_id=buffer_id,
flags=1)
header是所有数据包的报头,有三个参数:
type:类型
length:整个数据包的长度
xid:数据包的编号
比如ofp_flow_mod的type就是14,具体的哪一种数据的类型将在文章最后给出。length最基本长度为72,每一个action长度为8。所以长度必定为8的倍数才是一个正确的数据长度
WILDCARDS
这是从match域提取出来的前32bit。在1.3的时候,这个逻辑改成了正常的与逻辑。即1为使能匹配,0为默认不匹配。
MATCH
这个数据结构会出现在机会所有重要的数据包中,因为他存的就是控制信息。
FLOW_MOD
class ofp_flow_mod(Packet):
name = “OpenFlow Flow Modify”
fields_desc=[ BitField(“cookie”, 0, 64), #Opaque controller-issued identifier
ShortEnumField(“command”, 0, ofp_flow_mod_command),
ShortField(“idle_timeout”, 60),
ShortField(“hard_timeout”, 0),
ShortField(“priority”, 0),
IntField(“buffer_id”, 0),
ShortField(“out_port”, 0),
#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”, 0)]
command里面的类型决定了flow_mod的操作是添加,修改还是删除等。
ofp_flow_mod_command = { 0: “OFPFC_ADD”, # New flow
1: “OFPFC_MODIFY”, # Modify all matching flows
2: “OFPFC_MODIFY_STRICT”, # Modify entry strictly matching wildcards
3: “OFPFC_DELETE”, # Delete all matching flows
4: “OFPFC_DELETE_STRICT”} # Strictly match wildcards and priority
如果要添加一条新流,command=0。

两个时间参数idle_timeout & hard_timeout:

idle_timeout:如值为10,则某条流在10秒之内没有被匹配,则删除,可以称之为活跃时间吧。
hard_timeout:如值为30,则30秒到达的时候,一定删除这条流,即使他还活跃,即被匹配。
priority是流的优先级的字段,字数越大则优先级越高,存放在号数越小的table中。
由交换机指定的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”,
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(),然后再接一个实体。
具体的action类型:
ofp_action_type = { 0: “OFPAT_OUTPUT”,
1: “OFPAT_SET_VLAN_VID”,
2: “OFPAT_SET_VLAN_PCP”,
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”
}
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()
作用:在流失效的时候回复控制器,并携带若干统计数据。
class ofp_flow_removed(Packet):
name = “OpenFlow flow removed”
fields_desc = [ BitField(“cookie”, 0, 64),
BitField(“priority”, 0,16),
BitField(“reason”, 0, 8),
ByteField(“pad”, None),
BitField(“duration_sec”, 0, 32),
BitField(“duration_nsec”, 0, 32),
BitField(“idle_timeout”, 0, 16),
ByteField(“pad”, 0),
ByteField(“pad”, 0),
BitField(“packet_count”, 0, 64),
BitField(“byte_count”, 0, 64)
]
其实的duration_sec是流存在的时间,单位为秒,duration_nsec单位为纳秒。
OFPT_STATS_REQUEST && REPLY
以上的数据都是通信过程中必须的部分。还有一些数据包是为了某些目的而设计的,如
OFPT_STATS_REQUEST && REPLY可以获得统计信息,我们可以利用统计信息做的事情就太多了。如:负载平衡, 流量监控等基于流量的操作。*
class ofp_stats_request(Packet):
name = “OpenFlow Stats Request”
fields_desc=[ ShortEnumField(“type”, 0, ofp_stats_types),
ShortField(“flag”, 0)]*
0:请求交换机版本信息,制造商家等信息。
1:单流请求信息
2:多流请求信息
3:流表请求信息
4:端口信息请求
5:队列请求信息
6:vendor请求信息,有时候没有定义。

2
3
4
5
6
7
8
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
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
}
每一种请求信息都会对应一种回复信息。我们只介绍最重要的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,如流量监控,负载均衡等等。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值