美文网首页
OpenFlow控制器与OpenFlow交换机之间的通信

OpenFlow控制器与OpenFlow交换机之间的通信

作者: 墨痕hz | 来源:发表于2017-12-23 19:14 被阅读1181次

1.建立安全通道

OpenFlow控制器是通过安全通道和OpenFlow交换机进行通信的,安全通道由控制面网络建立,不受OpenFlow交换机中的流表项的影响。在OpenFlow中,安全通道通过TLS来实现,控制器与交换机之间通过服务器证书和客户机证书进行认证。在一些OpenFlow版本中(1.1及以上),控制器和交换机之间的连接有时也会通过TCP明文来实现。

OpenFlow控制器启动后,对指定端口进行监听,默认的TCP端口为6633,后更改为6653。通过三次握手后,连接建立。

2.消息

OpenFlow消息由64比特(8字节)组成,所有的OpenFlow消息都是从OpenFlow头开始,图2-1为OpenFlow头格式。


图2-1.png
  • 各字段及其含义
字段 比特数 内容
version 8 OpenFlow的协议版本号
type 8 消息类型(见2.1)
length 16 该头中包含的八位字节数
xid 32 分配给数据包的id

2.1 OpenFlow消息类型

表2-1(参考1.3版本)

类型 名称
OFPT_HELLO Hello消息
OFPT_ERROR Error消息
OFPT_ECHO_REQUEST Echo请求消息
OFPT_ECHO_REPLY Echo响应消息
OFPT_EXPERIMENTER Experimenter消息
OFPT_FEATURES_REQUEST Features请求消息
OFPT_FEATURES_REPLY Features响应消息
OFPT_GET_CONFIG_REQUEST GET_CONFIG请求消息
OFPT_GET_CONFIG_REPLY GET_CONFIG响应消息
OFPT_SET_CONFIG SET_CONFIG消息
OFPT_PACKET_IN Packet-In消息
OFPT_FLOW_REMOVED Flow-Remove消息
OFPT_PORT_STATUS Port-Status消息
OFPT_PACKET_OUT Packet-Out消息
OFPT_FLOW_MOD Flow-Mod消息
OFPT_GROUP_MOD GROUP_MOD消息
OFPT_PORT_MOD PORT-MOD消息
OFPT_TABLE_MOD TABLE_MOD消息
OFPT_MULTIPART_REQUEST MULTIPART请求消息
OFPT_MULTIPART_REPLY MULTIPART响应消息
OFPT_BARRIER_REQUEST BARRIER请求消息
OFPT_BARRIER_REPLY BARRIER响应消息
OFPT_QUERU_GET_CONFIG_REQUEST QUERU_GET_CONFIG请求消息
OFPT_QUEUE_GET_CONFIG_REPLY QUERU_GET_CONFIG响应消息
OFPT_ROLE_REQUEST Role请求消息
OFPT_ROLE_REPLE Role响应消息
OFPT_GET_ASYNC_REQUEST GET_ASYNC请求消息
OFPT_GET_ASYNC_REPLY GET_ASYNC响应消息
OFPT_SET_ASYNC SET_ASYNC消息
OFPT_METER_MOD METER消息
  • OFPT_HELLO消息

OpenFlow交换机与OpenFlow控制器建立安全通道后,会相互发送hello包。hello消息仅有OpenFlow头构成。且由交换机连向路由器。

  • 目的:用于OpenFlow协议版本的协商。

  • 内容:发送双方各自支持的最高版本协议。

  • 结果:选择双方支持的最低协议版本。

  • 成功:建立连接。

  • 失败:发送OFPT_ERROR,终止连接。

  • Features消息(握手过程)

通过互发hello消息建立连接后,执行控制器和交换机之间的握手过程。控制器通过握手过程了解交换机的相关配置信息,即可以对交换机进行控制。

  • 发送数据:OFPT_FEATURES_REQUEST(Features请求)
  • 接收数据:OFPT_FEATURES_REPLY(Features响应)
Features请求消息
  • type=5
  • 只包含openflow头
Features响应消息
  • type=6

  • Features响应消息格式(如图2-2所示)


    图2-2.png
  • 各个字段的含义

字段 比特数 内容
datapath_id 64 OpenFlow中将各交换机称为datapath,datapath_id是唯一识别datapath的ID
n_buffers 32 交换机可以同时缓存的数据包的最大个数
n_tables 8 交换机中支持的流表数量
pad 24 用于64位对其的填充
capabilities 32 支持的容量
actions 32 支持的行动
ports 长度可变 OpenFlow1.3之后废除,在此不再介绍

对于Features消息,每一次交换机连接到控制器,都会收到控制器的features_request,当交换机将features_reply回复给控制器后,控制器就会对交换机有了全面的了解,从而为交换机提供控制信息。

  • OFPT_PACKET_IN消息

为了将到达OpenFlow交换机的数据包发送至控制器,使用Packet-In消息,当存在:

  • 不存在与流表项一致,即没有流表进行匹配时(Table-miss)
  • 匹配的流表项存在发送至控制器的行为时

可发送Packet-In消息,包含在Packet-In中的数据可能是很多种类型,ARP和ICMP为最常见类型。
如果是广播包,控制器就会将其包装,封装成Packet-Out数据包,将其发送给交换机,让其进行泛洪处理(flood),即将数据包发往除in_port之外的所有端口。

  • OFPT_PACKET_OUT消息
  • 作用:通过控制器发送交换机希望发送的数据

  • 例子:当一个没有匹配上流表项的数据上报控制器时,控制器可以下发packet_out,指定交换机对该数据包做泛洪或丢弃动作。

若OpenFlow交换机的缓存中已存在数据包,而OpenFlow控制器发出发送数据包的命令时,该消息指定表示响应数据包的buffer_id。使用Packet-out还可以将OpenFlow控制器创建的数据包发送给交换机,此时,buffer_id设置为-1.在Packet-out消息后添加数据包数据。

  • OFPT_FLOW_MOD消息

Flow-Mod消息是由OpenFlow控制器对OpenFlow交换机设置流表项的消息。可对流表项进行添加、删除、变更设置等操作。Flow-Mod消息具体命令种类如下:

名称 内容
OFPFC_ADD 添加流表项
OFPFC_MODIFY 变更匹配的流表项设置(OpenFlow1.2版本以上删除此项)
OFPFC_MODIFY_STRICT 仅变更完全匹配的流表项设置
OFPFC_DELETE 删除匹配的流表项
OFPFC_DELETE_STRICT 仅删除完全匹配的流表项
    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

OFPT_FLOW_MOD由header+match+flow_mod+action构成。

    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)
  • OFP_HEADER

见2.消息中OpenFlow头结构。

  • MATCH(数据包匹配)

这个数据结构会出现在几乎所有重要的数据包中,因为他存的就是控制信息。

如有packet_in引发的下发流表,则match部分应对应填上对应的数据,这样下发的流表才是正确的。

但是在下发的时候还需要注意许多细节,比如:

  • 并不是所有的数据包都有vlan_tag。如0x0800就是纯IP,并没有携带vlan_tag,所以填充式应根据packet_in的具体情况填充。
  • 并不是所有的数据都有四层端口,所以四层的源端口,目的端口都不是任何时候都能由packet_in去填充的。不去管就好了,默认的会填充一个默认值,匹配的时候不去匹配4层端口就没有问题。
  • WILDCARDS(通配符)

在of1.0中这里的0,1意义跟我们平时接触的如子网掩码等意义相反,如OFPFW_NW_DST_MASK=0则表示全匹配目标IP。如果为63,则表示不匹配IP。在1.3的时候,这个逻辑改成了正常的与逻辑。即1为使能匹配,0为默认不匹配。

因匹配字段在1.2版本之后变化较大,请自行查看OpenFlow协议。

  • Flow-Mod消息的行动信息

Flow-Mod消息的行动信息结构如图2-3所示:


图2-3.png

相关代码如下:

    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 16 表示Flow-Mod消息动作的ofp_flow_mod_command(具体参看上表具体命令)
idle_timeout 16 如果与流表项匹配的数据包超过idle_timeout的时间还未到,则删除流表项
hard_timeout 16 流表项添加的时间超过hard_timeout则删除
priority 16 多个流表项与数据包匹配时的优先级
buffer_id 32 OpenFlow交换机一侧保存的数据包的缓存ID
out_port 16 仅在DELETE及DELETE_STRICT命令中使用,该值已指定时,仅删除行动中描述了与该数值一致的输出物理端口的流表项
flags 16 标志。
actions 长度可变 行动描述部分

例如:
如果要添加一条新流,command=0。

两个时间参数idle_timeout & hard_timeout:

idle_timeout: 如值为20,则某条流在20秒之内没有被匹配,则删除。

hard_timeout: 如值为30,则30秒到达的时候,一定删除这条流,即使他还活跃,能被匹配。

priority:
priority是流的优先级的字段,字数越大则优先级越高,存放在号数越小的table中。

buffer_id:
由交换机指定的buffei_id,准确的说是由dpid指定的。如果是手动下发的流,buffer_id应填-1,即0xffff,告诉交换机这个数据包并没有缓存在队列中。

out_port:
指定流的出口,有一些端口是很特殊的,如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,若没有指定,交换机会默认执行drop操作。

  • action的两种类型行动。
    1. 必备行动:Forward,Drop
    2. 选择行动:Set-Queue,Set-Field等。

具体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"
                }

各字段及其含义:

名称 内容
OFPAT_OUTPUT 输出至交换机物理端口
OFPAT_SET_VLAN_VID 设置802.1Q的VLAN id
OFPAT_SET_VLAN_PCP 设置802.1Q的PCP
OFPAT_STRIP_VLAN 清除802.1Q的头
OFPAT_SET_DL_SRC 设置发送源以太网地址
OFPAT_SET_DL_DST 设置发送目标以太网地址
OFPAT_SET_NW_SRC 设置发送源IPV4地址
OFPAT_SET_NW_DST 设置发送目标IPV4地址
OFPAT_SET_NW_TOS 设置IPV4的TOS字段
OFPAT_SET_TP_SRC 设置TCP/UDP的发送源端口号或ICMP类型\
OFPAT_SET_TP_DST 设置TCP/UDP的目标端口号或ICMP代码
OFPAT_ENQUEUE 输出至队列
  • Flow-Removed消息

如果flow-mod的flags置为1,则在该流表失效后会回复控制器OFPT_LFOW_REMOVED消息。结构如图2-4所示:


图2-4.png

作用:在流失效的时候回复控制器,并携带若干统计数据。

    class ofp_flow_removed(Packet):
    name = "OpenFlow flow removed"
    fields_desc = [ BitField("cookie", 0, 64),  #在控制器中使用,与flow-mod消息数值相同。
              BitField("priority", 0,16),#流表项的优先级,与flow-mod相同。
              BitField("reason", 0, 8),#流表项删除理由。
              ByteField("pad", None),#用于32位对齐。
              BitField("duration_sec", 0, 32),#流表项有效时间。
              BitField("duration_nsec", 0, 32),#流表项有效时间。
              BitField("idle_timeout", 0, 16),#idle超时时间。
              ByteField("pad", 0),#用于64位对齐。
            
              BitField("packet_count", 0, 64),#与流表项匹配的数据包数。
              BitField("byte_count", 0, 64),#匹配的数据包总字节数。
    ]
  • Error消息

Error消息的作用是通知出现了某种错误,OpenFlow交换机和OpenFlow控制器都可以发送Error消息。
错误消息类型:

名称(type) 内容
OFPET_HELLO_FAILED Hello协议失败
OFPET_BAD_REQUEST 无法解读请求
OFPET_BAD_ACTION 行动的描述中包含错误
OFPET_FLOW_MOD_FAILED 变更流表项时发生错误
OFPET_PORT_MOD_FAILED Port-Mod请求失败
OFPET_QUEUE_OP_FAILED 队列操作失败

具体的type与其对应的相关代码:

    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",
                    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",          #permissions error
                    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"}
  • Barrier消息

交换机在收到OFPT_BARRIER_REQUEST的时候,会回复控制器一个OFPT_BARRIER_REPLY。控制器收到回复之后,确认flow-mod设置流表成功,可以发送Packet-out消息。

  • Echo消息
    1. 分类:对称信息OFPT_ECHO_REQUEST,OFPT_ECHO_REPLY
    2. 作用:确认控制器和交换机之间是否连接,检测通信延迟,测量通信带宽等。
    3. 发送方:交换机和控制器均可发送。
    4. 构成:OpenFlow头和附加数据。
    5. 周期:没有数据包交换时,控制器会定期给交换机发送请求消息。
  • 参考:

北邮-李呈:OpenFlow通信流程解读

《图解OpenFlow协议》

相关文章

网友评论

      本文标题:OpenFlow控制器与OpenFlow交换机之间的通信

      本文链接:https://www.haomeiwen.com/subject/hohzwxtx.html