生动的SDN基础内容介绍(二)--OpenFlow协议

背景

上文讲了一些SDN的基础知识,这篇文章将介绍SDN出现的依据之一,也就是OpenFlow协议。

强烈推荐看
1、OpenFlow官方的手册(超级强烈推荐!!!)http://www.cs.columbia.edu/~lierranli/coms6998-8SDNFall2013/papers/openflow-spec-v1.3.2.pdf
2、OpenFlow中文版手册(不太全)https://www.jianshu.com/p/acfeae1771b3

OpenFlow

OpenFlow

这是最经典的一张OpenFlow的图。一个OpenFlow交换机由一个或多个流表和一个组表组成,执行流量包的查找(匹配)和转发,一个OpenFlow通道到一个外部控制器。交换机同控制器通信,控制器通过OpenFlow协议管理交换机。

OpenFlow标准协议允许控制器直接访问和操作网络设备的转发平面,这些设备可以是物理设备,也可以是虚拟的路由器或者交换机(例如OVS,OVS会在后续简单介绍)。

也就是说有了OpenFlow我们才可以让控制平面指挥数据平面干活,那么是怎么指挥的呢。首先需要了解一些基础的概念。

OpenFlow的基础概念

以OpenFlow v1.3为例

流表项

流表项也就是flow entry。
流表项
流表项通过OpenFlow协议被控制器下发到OpenFlow交换机中,每次接收到数据包交换机根据流表项制定的规则进行一系列的操作。按之前的比喻,流表项就是领导下发的一条条规则,人们就靠着着一条条规则来让身体干活。

那么流表项里面都有什么呢:

1、匹配域Match Fields:

流表项的匹配规则
也就是流表项的匹配规则,即这条流表项对哪些数据包起作用。匹配规则有很多种,具体的可以去看官方文档和官方手册。这里以匹配源ip地址为例。如果我们想获取一定时间内源地址为10.0.0.1的包的数量,那么就把匹配域定为“源ip:10.0.0.1”。

如RYU控制器的代码为

match = parser.OFPMatch(eth_type = 0x800,ipv4_src=(net,net_mask))

eth_type表示是ip协议,net为10.0.0.1,net_mask为子网掩码(OpenFlow支持匹配网段,匹配网段通过设置子网掩码实现)。那么以后只要是源ip为10.0.0.1的数据包都会与该流表项相匹配。

那如果有多个流表项匹配域拥有相同的源ip地址,数据包会与哪个流表项匹配呢?
这就是OpenFlow很蛋疼的一个地方。OpenFlow只会匹配一个最先下发的流表项,其他流表项不会与数据包匹配。具体的实验可以看https://blog.csdn.net/weixin_40610952/article/details/80509378

不光是这样,OpenFlow没有解决粗粒度流和细粒度流同时测量的信息丢失问题。例如,流表项A匹配10.0.0.0/29,流表项B匹配10.0.0.1。当一个源地址为 10.0.0.1 的数据包到
达时,只有先下发的流表项A才会计数。

解决这种问题的一个方法就是优先级:如果两个流表项的优先级不同,则只有优先级高的流表项才能与数据包匹配。

2、优先级Priority:

流表项优先级,定义流表项之间的匹配顺序,优先级高的先匹配。
那我要是想都匹配呢?我想要10.0.0.1同时匹配到A和B两个流表项,我的一个想法是用流表,这个在后续介绍流表的时候再说。

3、流表项计数Counters:

统计有多少报文和字节匹配到该流表项,这就很好理解了,如果有一个来自10.0.0.1的数据包匹配上该流表项了,那么byte_count+=该数据包的bytes数,packet_count+=1。Counters在网络管理和网络测量方面极为重要,可以收集网络中的信息。

4、指令与动作Instructions&actions:

该字段表明需要交换机对匹配到的数据包做什么动作/操作。
借用http://www.h3c.com/cn/d_201811/1131080_30005_0.htm中的一些内容。
具体的指令类型如下图所示:
指令的类型
每个流表表项的指令集中每种指令类型最多只能有一个,指令的执行的优先顺序为:
Meter –> Apply-Actions -> Clear Actions -> Write-Actions -> Write-Metadata -> Goto-Table

常见的Action动作的类型如下:
动作的类型

看到这里人可能晕了,为啥有个指令还有个动作,不能把这俩合在一起吗,我第一次看见的时候也很纳闷为啥要分开。后来发现指令是数据包被匹配上之后执行的操作,就相当于领导告诉你要干啥活(整理文档、打代码、打扫卫生等)。而动作是更细致的划分,如整理文档的话可能会有写、改、删除、转发这几个操作。同时,动作可以被放在动作集里在流表中累加传输,这个后续讲到流表的时候再介绍。

以指令为Apply-Actions,动作为Output为例,此时想让匹配到的数据包从端口1转发,那么RYU的代码如下:

out_port = 1
actions = [parser.OFPActionOutput(out_port)]
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                             actions)]

匹配到数据包之后把该数据包从端口1转发,该动作立即执行。

5、超时时间Timeouts:

流表项的超时时间
Idle Time:在Idle Time时间超时后如果没有报文匹配到该流表项,则此流表项被删除。
Hard Time:在Hard Time时间超时后,无论是否有报文匹配到该流表项,此流表项都会被删除。

6、标识Cookie:
控制器下发的流表项的标识。

流表

刚刚提到了好多次流表,一个流表里面会储存很多流表项。
流表项通过匹配字段和优先级决定:在一个流表中匹配字段和优先级共同确定唯一的流表项。所有字段通配 (所有字段省略) 和优先级等于0的流表项被称为table-miss流表项,也就是漏表项(后续会介绍)。

从OpenFlow1.1开始引入了多级流表和流水线处理机制,即一个交换机中可能有很多流表,每个流表又有很多流表项。要这么多流表干啥,多级流表的出现一方面能够实现对数据包的复杂处理,另一方面又能有效降低单张流表的长度,提高查表效率,可以更好地处理数据包。即让一个数据包可以被不同的网络管理应用执行多次操作。

OpenFlow规范中定义了流水线式的处理流程,数据包匹配处理流程如下图所示:
数据包匹配处理流程
数据包在交换机中的处理过程
当数据包进入交换机后,必须从编号最小的流表开始依次匹配。可以按次序从小到大越级跳转,但不能从某一流表向前跳转至编号更小的流表。

当报文成功匹配一条流表项后,将首先更新该流表项对应的统计数据(如成功匹配数据包总数目和总字节数等),然后根据指令进行相应操作,比如跳转至后续某一流表继续处理,修改或者立即执行该数据包对应的动作集等。

当数据包已经处于最后一个流表时,其对应的动作集中的所有动作将被执行,包括转发至某一端口,修改数据包某一字段,丢弃数据包等。

回到之前考虑的问题:
在介绍流表项的时候提到了“我想要10.0.0.1同时匹配到A和B两个流表项”。假设流表项A是网络管理应用下发的,想要修改数据包的头字段。流表项B是负责正常转发的,想要将10.0.0.1转发到端口1。那么可以把A放在流表0里面,把B放在流表1里面,将添加头字段的动作放入动作集之后从流表0跳到流表1,执行添加头字段的动作与转发的动作。

https://blog.csdn.net/qq_41094042/article/details/121924741的另一个例子。
流表0中匹配主机A到主机B的IP流,然后跳转到其他流表,如流表2。
流表2中在IP流的基础上进一步匹配TCP流或UDP流,根据要求将TCP流正常转发,UDP流丢弃。

多级流表的例子二

跳转的指令为之前提到的Goto-Table,在RYU中的实现为:

go_to_table=1 #跳转到流表1中
inst = [parser.OFPInstructionActions(ofproto.OFPIT_WRITE_ACTIONS,
                                             actions),
                parser.OFPInstructionGotoTable(go_to_table)]

漏表

漏表即table-miss。
每个流表必须包含table-miss表项,table-miss表项指定如何处理流表中与其他流表项未匹配的数据包,比如把数据包发送给控制器、丢弃数据包或直接将包扔到后续的表。

该表项的匹配域为通配,即匹配任何报文,优先级为0,Instructions与正常表项相同。通常,如果table-miss表项不存在,默认行为是丢弃报文。

在RYU中如果想将未匹配到的数据包都交给控制器处理,则代码为:

match = parser.OFPMatch()
actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
                                          ofproto.OFPCML_NO_BUFFER)]
self.add_flow(datapath, 0, match, actions)
#datapath为数据通路,也就是交换机

流表项的下发

在RYU中的流表项下发代码为:

def add_flow(self, datapath, priority, match, actions):
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                             actions)]
        mod = parser.OFPFlowMod(datapath=datapath, priority=priority,
                                    match=match, instructions=inst)
        datapath.send_msg(mod)

流表项的删除

流表项可以通过两种方式在流表中删除,一个是通过控制器的请求,一个是利用交换机的流超时机制。

在RYU中由控制器主动删除流表项的代码为:

def del_flow(self, datapath, match, priority, table_id): #删除特定流表项
	ofproto = datapath.ofproto
	ofp_parser = datapath.ofproto_parser
    instructions=[]
	mod = ofp_parser.OFPFlowMod(datapath, 0, 0, table_id,
                                         ofproto.OFPFC_DELETE, 0, 0,
                                         priority,
                                         ofproto.OFPCML_NO_BUFFER,
                                         ofproto.OFPP_ANY,
                                         ofproto.OFPG_ANY, 0,
                                         match, instructions)        
    datapath.send_msg(mod)

计量表

对流进行测量,从而为流提供QoS功能,如限速、DiffServ。
详情可看这篇博客对计量表的介绍
https://blog.csdn.net/qq_41094042/article/details/121924741

组表

一个OpenFlow交换机中只有一个组表Group Table,一个组表包括若干组表项。 一个流表项指向一个组的能力使得可以实现额外的转发方法。
组表
组表的优点可以参考这篇博客
https://blog.csdn.net/qq_25777079/article/details/105073951

控制器与交换机的通信

OpenFlow通道是每个交换机连接控制器的接口,通过这个接口,控制器配置和管理交换机,接收来自交换机的事件,从交换机发出数据包。

所有 OpenFlow通道消息的格式必须遵循OpenFlow协议。通道通常使用TLS加密。

OpenFlow协议支持三种消息类型:
1、控制器到交换机(controller-to-switch):
消息由控制器发起,用来直接管理或检查交换机的状态。如配置、修改状态、读交换机的各种信息、指定动作等。
2、异步(asynchronous):
用于控制器更新网络事件和交换机状态变化。如table-miss的数据包的发送、流表项的移除、通知控制器某个端口发生变化等。
3、对称(symmetric)

总结

至此部分的OpenFlow基础知识介绍完了,其他部分请看
1、OpenFlow官方的手册(超级强烈推荐!!!)http://www.cs.columbia.edu/~lierranli/coms6998-8SDNFall2013/papers/openflow-spec-v1.3.2.pdf
2、OpenFlow中文版手册(不太全)https://www.jianshu.com/p/acfeae1771b3

下章会介绍关于Ryu控制器的一些内容
https://blog.csdn.net/weixin_44480014/article/details/123258955

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值