Openflow细节理解之—Buffer_id篇

OpenFlow消息中buffer_Id是什么?

Openflow中buffer_id分别在三类消息中定义,并且起到的作用均是不同的。

✔ Packetin消息:用于标记缓存在交换机中的数据报文id,如报文被action上送到控制器中maxlen字段或者table_miss消息限制长度,而通过bufferid将报文缓存在交换机中,以便被另外两种消息来调用;

✔ Packetout消息:用于控制器将原先buffer在交换机中的报文,通过Packetout个形式从交换机的某个物理口送出去;

✔ Flowmod消息:如果flowmod中带有bufferid,那么说明这个flowmod需要做两件事情,第一是正常下发一条flow,其次是把交换机中先前buffer的那个数据报文,Packetout到table来匹配一次下的这条flow;注意以上两个指令都是通过这个带有bufferid的消息执行的,不需要控制器另外下packet_out消息,这种设计思路是非常巧妙的。

为什么要引入buffer_Id?

优点没必要多说,Packet_in到控制器的报文决策之后,大部分报文必然还是要扔回交换机的,为何不在交换机上缓存起来,只送个tag上去呢?

Openflow针对buffer_id的设计思想

✔ 协议针对packetin/packetout中buffer_id的设计思想很简单,一个上去,一个下来,具体思路参考下面例子。

✔ 协议针对Flowmod中bufferid设计思想就非常巧妙了,前面我已经提过,如果flowmod中带有bufferid,那么说明这个flowmod需要做两件事情,第一是正常下发一条flow,其次是把交换机中先前buffer的那个数据报文,Packetout到table来匹配一次下的这条flow;我这里举个例子大家就明白为什么这么设计了:

举例

✔ 假设现在从交换机的某个口进来一个arp请求的报文,通过tablemiss直接Packetin(bufferid是0x100)上送到controller了,controller收到之后这个arp请求之后肯定会通过Packetout(bufferid填0x100)把这个报文给广播出去,这个过程数据报文不用真正整个都送到控制器,只要送上去指定长度部分,并通过bufferid来交互数据报文内容

✔ 现在又假设交换机上某个口挂的host响应了这个arp请求,并回复了arp reply,交换机收到依然果断Packetin(bufferid是0x100)送控制器,这个时候控制器已经知道了往哪里回复,那控制器这个时候不Packetout了,干脆下个flowmod(bufferid是0x100)吧,反正以后肯定还要有报文交互,那flowmod下下去了来匹配转发来个host的报文,那怎么来保证你本次这个arp应答也被转发呢?所以这个时候设计者非常巧妙地又让这个报文通过Packet_out到table再次进入交换机pipline通道一次,以保证本次交互不需要其他动作也能成功

Ryu测试buffer_id完整app代码

from ryu.base import app_manager
from ryu.controller.handler import CONFIG_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.controller import ofp_event
import logging
import time
import itertools
from ryu.ofproto import ofproto_v1_3
from ryu.lib import mac
LOG = logging.getLogger("buffer_id_test")
class buffer_id_test(app_manager.RyuApp):
    def __init__(self, *args, **kwargs):
        self.__name__ = "buffer_id_test"
        super(buffer_id_test, self).__init__(*args, **kwargs)
    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def buffer_id_test(self, ev):
        datapath = ev.msg.datapath
        ofp = datapath.ofproto
        parser = datapath.ofproto_parser
        print "#######"
        print '''Test Start'''
        print "#######"
        print "#######"
        print '''step 1. + Add table_miss_flow'''
        print "#######"      
        match = parser.OFPMatch()
        oas = []
        oa = parser.OFPActionOutput(ofproto_v1_3.OFPP_CONTROLLER, ofproto_v1_3.OFPCML_MAX)
        oas.append(oa)
        inst = parser.OFPInstructionActions(ofproto_v1_3.OFPIT_APPLY_ACTIONS, oas)
        insts = []
        insts.append(inst)
        fm = parser.OFPFlowMod(datapath,
                                        0, 0,
                                        0, # table 0
                                        ofproto_v1_3.OFPFC_ADD,
                                        0, 0,
                                        0, # must have higher priority.
                                        0xffffffff,
                                        ofproto_v1_3.OFPP_ANY,
                                        0xffffffff,
                                        0,
                                        match,
                                        insts)
        datapath.send_msg(fm)    
        print "#######"
        print '''step 2. + Send pkt ip_dst=1.1.1.1,send to controller'''
        print "#######"   
        ###这里报文自己拿工具去发,推荐scapy  
        time.sleep(10)
        print "#######"
        print '''step 3_1.(Flow_mod) + Add Flow with buffer_id of 0x100'''
        print "#######"            
        match = parser.OFPMatch()
        match.set_dl_type(int(int(0x800)))
        match.set_ipv4_dst(int(16843009))
        oas = []
        oa = parser.OFPActionOutput(6, ofproto_v1_3.OFPCML_MAX)
        oas.append(oa)
        inst = parser.OFPInstructionActions(ofproto_v1_3.OFPIT_APPLY_ACTIONS, oas)
        insts = []
        insts.append(inst)
        fm = parser.OFPFlowMod(datapath,
                                            0, 0,
                                            0, # table 0
                                            ofproto_v1_3.OFPFC_ADD,
                                            0, 0,
                                            10, # must have higher priority.
                                            0x100,
                                            ofproto_v1_3.OFPP_ANY,
                                            0xffffffff,
                                            0,
                                            match,
                                            insts)
        datapath.send_msg(fm)     
        print "#######"
        print '''step 3_2.(Packet_out) + Add Packet_out message with buffer_id of 0x100'''
        print "#######"              
        oa = parser.OFPActionOutput(6, ofproto_v1_3.OFPCML_MAX)
        oas = []
        oas.append(oa)        
            #pkt="\x00\x00\x00\x01\x01\x01\x00\x00\x00\x02\x02\x02\x08\x00\x45\x111111111111111111111111111111111111"
        po = parser.OFPPacketOut(datapath, 0x100, 0,
                                              oas
                                              )
        datapath.send_msg(po)

总结思考

目前ovs针对报文buffer的做法是一个报文就对应一个buffer,不管是不是同一个报文,这样的坏处浪费了交换机buffer的资源,更加优化的做法是交换机收到相同报文只buffer一次并且只上送同一个buffer_id给控制器。

原文发布于微信公众号 - SDNLAB(SDNLAB)

原文发表时间:2016-06-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏即时通讯技术

网络编程懒人入门(四):快速理解TCP和UDP的差异

对于即时通讯开者新手来说,在开始着手编写IM或消息推送系统的代码前,最头疼的问题莫过于到底该选TCP还是UDP作为传输层协议。本文延续《网络编程懒人入门》系列文...

922
来自专栏互联网技术栈

OSI七层模型及对应协议

为数据链路层提供物理连接,在其上串行传送比特流,即所传送数据的单位是比特。此外,该层中还具有确定连接设备的电气特性和物理特性等功能。

4263
来自专栏IT技术精选文摘

就是要你懂 TCP

看过太多tcp相关文章,但是看完总是不过瘾,似懂非懂,反复考虑过后,我觉得是那些文章太过理论,看起来没有体感,所以吸收不了。 希望这篇文章能做到言简意赅,帮助大...

2048
来自专栏QQ会员技术团队的专栏

告知你不为人知的 UDP:疑难杂症和使用

本文承接《告知你不为人知的UDP:连接性和负载均衡》文章的下文,本文主要从UDP疑难杂症、UDP协议与TCP协议高效性的对比以及UDPd的使用场合这三个方面描述...

5.4K4
来自专栏Java编程

什么是框架?

张大胖立志走上Java之路, 听了大神Bill的指点, 先学了Java SE, 把集合、线程、反射、IO、泛型、注解之类的基础知识学了一遍, 在Bill的严厉督...

3757
来自专栏take time, save time

三十天学不会TCP,UDP/IP网络编程-TraceRoute的哲学

新年快乐,继续来部分粘贴复制我的这一系列文章啦,如果对和程序员有关的计算机网络知识,和对计算机网络方面的编程有兴趣,欢迎去gitbook(https://www...

3839
来自专栏用户画像

路由协议

OSPF是基于链路状态的自治系统内部路由协议,链路状态路由协议使用dijkstra的最短路径优先算法计算和选择路由。这类路由协议关心网络中链路和接口的状态(UP...

792
来自专栏我是东东强

TCP分段与IP分片的区别与联系

我们在学习TCP/IP协议时都知道,TCP报文段如果很长的话,会在发送时发生分段(Segmentation),在接收时进行重组,同样IP数据报在长度超过一定值时...

2932
来自专栏栗霖积跬步之旅

第一章计算机网络和因特网-day01

什么是因特网: 其一:构成因特网的基本硬件与软件。 其二:为分布式应用提供服务的联网基础设施。 终端机器称为主机( host ) 或者端系统( end syst...

3335
来自专栏程序猿

OSI与TCP/IP各层的结构与功能,都有哪些协议

在实际的开发中,网络编程占据很大一部分。从基本的应用与服务之间的数据传输,到性能优化;在从那些代理应用,路由跟踪,到匿名网络。无不应用到网络中的...

4065

扫码关注云+社区

领取腾讯云代金券