当Controller和SW建立连接之后,就能够处理来自SW的各种OF msg。当接收到 packetin 消息之后,会将其分发给各个监听了这个OFMessage的listeners,所以假设我们要设计自己的控制器模块,仅仅须要实现对应的接口方法。约定运行顺序就可以。

接口IListener 主要抽象了监听器模块的名字,运行顺序,接口IOFMessageListener则抽象了我们的Controller怎样处理详细的这个openflow消息。这里通过阅读代码来推断这些模块处理packetin消息的相对顺序。



public interface IListener<T>
{
    public enum Command
{
        CONTINUE , STOP
    }
   
    //这个监听者的名字
    public String
getName();

    //名为name的module在处理这个消息的时候,要在这个module之前
    public boolean isCallbackOrderingPrereq(T
type, String name);

    //在处理type消息的时候,name_module 要在这个模块之后
    public boolean isCallbackOrderingPostreq(T
type, String name);
}

public interface IOFMessageListener extends IListenerOFType>
{
      //Floodlight利用这种方法呼叫这些listeners来处理这个OF
MSG;
       public Command receive(IOFSwitch sw, OFMessage msg,
FloodlightContext cntx);
}

通过查看type hierarchy能够知道全部实现了这个接口的模块。



接下来看看详细细节。

1.Divice manager 要在topology之前。

     @Override
    public String getName() {
        return "devicemanager" ;
    }

    @Override
    public boolean isCallbackOrderingPrereq(OFType type,
String name) {
        return ((type
== OFType.PACKET_IN || type == OFType.FLOW_MOD)
                && name.equals( "topology" ));
    }

    @Override
    public boolean isCallbackOrderingPostreq(OFType type,
String name) {
        return false ;
    }

    @Override
    public Command receive(IOFSwitch sw, OFMessage msg,FloodlightContext
cntx) {
        switch (msg.getType())
{
            case PACKET_IN:
                return this .processPacketInMessage(sw,(OFPacketIn)
msg, cntx);
        }

        logger.error("received
an unexpected message {} from switch {}",
                     msg, sw);
        return Command.CONTINUE;
    }


2. LinkDiscoveryManager 中没有做出对顺序的规定,由其它模块来约束的。
         @Override
         public String getName() {
             return "linkdiscovery" ;
         }
        
         @Override
         public Command receive( IOFSwitch sw, OFMessage msg,
FloodlightContext cntx) {
             switch (msg.getType())
{
                 case PACKET_IN:
                     return this .handlePacketIn(sw,
(OFPacketIn) msg, cntx);
                 case PORT_STATUS:
                     return this .handlePortStatus(sw,
(OFPortStatus) msg);
             }

             log.error( "Received
an unexpected message {} from switch {}", msg, sw);
             return Command.CONTINUE;
         }

3. TopologyManager要在 LinkDiscoveryManager 之后操作。
    @Override
    public String getName() {
        return "topology" ;
    }

    @Override
    public boolean isCallbackOrderingPrereq(OFType type,
String name) {
        return "linkdiscovery" .equals(name);
    }

    @Override
    public boolean isCallbackOrderingPostreq(OFType type,
String name) {
        return false ;
    }

    @Override
    public Command receive(IOFSwitch sw, OFMessage msg,
                           FloodlightContext cntx) {
        switch (msg.getType())
{
            case PACKET_IN:
                return this .processPacketInMessage(sw,
                                                   (OFPacketIn) msg, cntx);
        }

        log.error("received
an unexpected message {} from switch {}",
                  msg, sw);
        return Command.CONTINUE;
    }
4.OFMessageFilterManager 模块在处理packetin消息时的顺序在 DeviceManager 之后,LearningSwitch 之前。这个模块的作用是同意我们加入一些过滤规则。
          @Override
         public String getName() {
             return "messageFilterManager" ;
         }

         @Override
         public boolean isCallbackOrderingPrereq(OFType type,
String name) {
             return (type
== OFType.PACKET_IN && name.equals("devicemanager" ));
         }

         @Override
         public boolean isCallbackOrderingPostreq(OFType type,
String name) {
             return (type
== OFType.PACKET_IN && name.equals("learningswitch" ));
         }

         @Override
         public Command receive( IOFSwitch sw, OFMessage msg,
FloodlightContext cntx) {

             if (filterMap == null || filterMap.isEmpty()) return Command.CONTINUE;

             HashSet<String> matchedFilters = null;
             if (log.isDebugEnabled())
{
                 log.debug( "Received
packet {} from switch {}", msg, sw.getStringId());
             }

             matchedFilters = getMatchedFilters(msg, cntx);
             if (matchedFilters
== null) {
                 return Command.CONTINUE;
             } else {
                 try {
                     sendPacket(matchedFilters, sw, msg, cntx, true );
                 } catch (TException e)
{
                     log.error( "sendPacket
Texception: {}", e);
                 } catch (Exception
e) {
                     log.error( "sendPacket
exception: {}", e);
                 }
             }
            
             return Command.CONTINUE;
         }

5. VirtualNetworkFilter(二层虚拟网络模块,对于不属于这个虚拟网络的packetin会丢弃)的运行顺序在forwarding之前,在devicemanager。linkdiscoveryManager之后。

    @Override
    public String getName() {
        return "virtualizer" ;
    }

    @Override
    public boolean isCallbackOrderingPrereq(OFType type,
String name) {
        // Link discovery should go before us so we
don't block LLDPs
        return (type.equals(OFType.PACKET_IN)
&&
              (name.equals( "linkdiscovery" )
|| (name.equals("devicemanager" ))));
    }

    @Override
    public boolean isCallbackOrderingPostreq(OFType type,
String name) {
        // We need to go before forwarding
        return (type.equals(OFType.PACKET_IN)
&& name.equals("forwarding" ));
    }

    @Override
    public Command receive(IOFSwitch sw, OFMessage msg,
FloodlightContext cntx) {
        switch (msg.getType())
{
            case PACKET_IN:
                return processPacketIn(sw,
(OFPacketIn)msg, cntx);
        }
        log.warn("Received
unexpected message {}" , msg);
        return Command.CONTINUE;
    }

6.ForwardingBase 路由模块未对顺序做限制。
7.其它的没有查看。

总结。通过上面的代码阅读能够得到例如以下的结构图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdm9uemhvdWZ6/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

7.通过调试得到的Listeners有序输出结果是(最后的Distributing是我们自己加入的模块):
OF msg PACKET_IN have listeners:[
net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager@543d8ee8, net.floodlightcontroller.topology.TopologyManager@ea5e9e7, net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl@74e551a4,
net.floodlightcontroller.forwarding.Forwarding@76eb235,
 net.floodlightcontroller.dedu.Distributing@76115ae0]


Floodlight中 处理packetin消息的顺序(1)的更多相关文章

  1. Floodlight中 处理packetin消息的顺序(2)

         前面通过阅读代码知道了怎样推断各个模块处理某个消息的先后顺序.那么内部是怎样实现的呢?      每当一个模块表示对一个消息感兴趣的时候,就会调用IFloodlightProviderSer ...

  2. Floodlight 中创建消息对象的方法

            在 floodlight 中创建各种openflow message 和 action 等採用的是简单工厂方式.BasicFactory类(实现OFMessageFactory接口.) ...

  3. UML中的图的出现顺序

    上接:UML从需求到设计--用例 从开始接触UML到现在对UML逐渐有了更深入的了解.刚开始,对于UML总是感觉UML就是图.一提起UML 就想着这个是画图的东西. 具体这些图都是干什么的.为什么会有 ...

  4. WM_QUIT,WM_CLOSE,WM_DESTROY 消息出现顺序及调用方式

    http://bbs.ednchina.com/BLOG_ARTICLE_3005455.HTM VC中WM_CLOSE.WM_DESTROY.WM_QUIT消息出现顺序及调用方式 wxleasyla ...

  5. rocketmq总结(消息的顺序、重复、事务、消费模式)

    rocketmq总结(消息的顺序.重复.事务.消费模式) 参考: http://www.cnblogs.com/wxd0108/p/6038543.html https://www.cnblogs.c ...

  6. 高可用保证消息绝对顺序消费的BROKER设计方案

    转自: http://www.infoq.com/cn/articles/high-availability-broker-design?utm_source=tuicool&utm_medi ...

  7. 分布式开放消息系统RocketMQ的原理与实践(消息的顺序问题、重复问题、可靠消息/事务消息)

    备注:1.如果您此前未接触过RocketMQ,请先阅读附录部分,以便了解RocketMQ的整体架构和相关术语2.文中的MQServer与Broker表示同一概念 分布式消息系统作为实现分布式系统可扩展 ...

  8. 分布式消息队列RocketMQ&Kafka -- 消息的“顺序消费”

    在说到消息中间件的时候,我们通常都会谈到一个特性:消息的顺序消费问题.这个问题看起来很简单:Producer发送消息1, 2, 3... Consumer按1, 2, 3...顺序消费. 但实际情况却 ...

  9. MQ如何解决消息的顺序性

    一.消息的顺序性 1.延迟队列:设置一个全局变量index,根据实际情况一次按照index++的逻辑一次给消息队列设置延迟时间段,可以是0.5s,甚至1s; 弊端:如果A,B,C..消息队列消费时间不 ...

随机推荐

  1. 6T GPT 移动硬盘在linux下的挂载

    实验室拿来了一个6T的移动硬盘,拿到后没有分区就直接用了,在Windows上用的好好的,插到上Linux后起初不会挂载,折腾了一会,成功挂载,很简单. 运行fdisk –l后,显示如下: 很明显,sd ...

  2. Performing a full database disaster recovery with RMAN

    Performing a full database disaster recovery with RMAN1. Make the RMAN backup set pieces available.2 ...

  3. 浅谈jQuery中 wrap() wrapAll() 与 wrapInner()的差异

    本文结合W3School的文档,分析了jQuery中 wrap() wrapAll() 与 wrapInner()的差异,并给出了图文对比教程,非常的简单实用,有需要的朋友可以参考下 今晚看书的时候发 ...

  4. .net程序员转战android第二篇---牛刀小试

    上篇说道如何搭建android的开发环境,这一篇我们将牛刀小试一下, 完成我们第一个android APP应用. 我就从新建项目说起吧. 首先打开Eclipse,选择顶部的File(文件)——new( ...

  5. JQuery————基础&&基础选择器

    环境搭建 搭建一个jQuery的开发环境非常方便,可以通过下列几个步骤进行. 下载jQuery文件库 在jQuery的官方网站(http://jquery.com)中,下载最新版本的jQuery文件库 ...

  6. HTML——表格与表单

    1.表格 <table></table> background:背景图片. 属性 值 描述 align left center right 不赞成使用.请使用样式代替. 规定表 ...

  7. C语言strcmp()函数:比较字符串(区分大小写)

    头文件:#include <string.h> strcmp() 用来比较字符串(区分大小写),其原型为: int strcmp(const char *s1, const char *s ...

  8. panel控件 换行

    Panel1.Controls.Add(new LiteralControl("<BR/>"));

  9. zoj 1067

    输入一组RGB颜色列表,每行一个颜色,是三个从0~255的整数 前16行是目标颜色组,-1 -1 -1表示结束   16组颜色以后接下来的几行是需要判断的,看它和哪个颜色的距离D最小,找出这个对应的颜 ...

  10. Java多线程并发编程之原子变量与非阻塞同步机制

    1.非阻塞算法 非阻塞算法属于并发算法,它们可以安全地派生它们的线程,不通过锁定派生,而是通过低级的原子性的硬件原生形式 -- 例如比较和交换.非阻塞算法的设计与实现极为困难,但是它们能够提供更好的吞 ...