SDN控制器Floodlight源码学习(五)--控制器和交换机交互(3)
来源:互联网 发布:js 倒计时 编辑:程序博客网 时间:2024/06/05 08:28
上两篇诣在说明控制器和交换机的交互,但是感觉还是没有理的特别清楚
http://blog.csdn.net/crystonesc/article/details/70143117
http://blog.csdn.net/crystonesc/article/details/70170482
今天打算结合openflow协议和代码来说明,openflow版本较多,我选了具有代表性的1.0和1.3版本进行学习,主要还是要搞清楚floodlight中控制器和交换机的交互过程.
前面的两篇文章讲到,控制器与交换机建立连接后,是通过netty的pipeline交由
net.floodlightcontroller.core.internal.OFChannelHandler
这个handler来处理,这个handler主要完成hello,Feature,echo的状态交互,完成这些简单的握手后,OFChannelHandler将连接传递给更高级的处理层面,它是: net.floodlightcontroller.core.internal.OFSwitchHandshakeHandler
那么这个handler完成更多复杂的交互.值得说明这两个handler都在其内部设置了类似于状态机的内部类来完成状态的切换,所以通过查看这两个状态类,能够很快的跟踪到交互的过程。以下是OFChannelHandler的状态机类:
OFSwitchHandshakeHandler 状态机类如下:
当然通过抓包也能够很快的看出交互的过程,以下分别为of1.0和of1.3的抓包截图:
具体这些交互过程在做什么这里不做具体的介绍,有兴趣可以参考 OpenFlow Switch Specification(1.0/1.3)
我们继续往下看代码,在交换机和控制器交互的过程中,控制器会声明自己的角色(master/slave/equal),这里多嘴一句,只有master的控制器才能对交换机进行写的操作,而slave状态的控制器只能够进行读操作。那么我们看看作为master的控制器要做哪些工作:
public class MasterState extends OFSwitchHandshakeState { MasterState() { super(true); } @Override void enterState() { if (OFSwitchManager.clearTablesOnEachTransitionToMaster) { log.info("Clearing flow tables of {} on upcoming transition to MASTER.", sw.getId().toString()); //清除已有的流表 clearAllTables(); } else if (OFSwitchManager.clearTablesOnInitialConnectAsMaster && initialRole == null) { /* don't do it if we were slave first */ initialRole = OFControllerRole.ROLE_MASTER; log.info("Clearing flow tables of {} on upcoming initial role as MASTER.", sw.getId().toString()); clearAllTables(); } sendBarrier(); /* Need to make sure the tables are clear before adding default flows */ addDefaultFlows(); /* * We also need a barrier between adding flows and notifying modules of the * transition to master. Some modules might modify the flow tables and expect * the clear/default flow operations above to have completed. */ sendBarrier(); setSwitchStatus(SwitchStatus.MASTER); }}
可以看到,在master状态的交换机,首先要清除交换机的流表信息,然后添加默认的流表信息,最后将交换机的中自己的角色设置为master。(交换机是不能够自己修改其中维护的controller的角色的)
同时处于master的控制器还承担这分发交换机上传消息的职责,例如pack_i数据包:
@Overridevoid processOFPacketIn(OFPacketIn m) { dispatchMessage(m);}/** * Dispatches the message to the controller packet pipeline */private void dispatchMessage(OFMessage m) { this.switchManager.handleMessage(this.sw, m, null);} @Override public void handleMessage(IOFSwitchBackend sw, OFMessage m, FloodlightContext bContext) { floodlightProvider.handleMessage(sw, m, bContext); }
最终pack_in数据包的处理是在floodlightProvider中来处理,也就是controller类中.
//controller将消息分发到IOFMessageListeners@Overridepublic void handleMessage(IOFSwitch sw, OFMessage m, FloodlightContext bContext) { Ethernet eth = null; log.trace("Dispatching OFMessage to listeners."); //如果contrller角色不是master,则不进行分发 if (this.notifiedRole == HARole.STANDBY) { counters.dispatchMessageWhileStandby.increment(); // We are SLAVE. Do not dispatch messages to listeners. return; } counters.dispatchMessage.increment(); switch (m.getType()) { case PACKET_IN: counters.packetIn.increment(); OFPacketIn pi = (OFPacketIn)m; //获取packet-in消息的数据 if (pi.getData().length <= 0) { log.error("Ignoring PacketIn (Xid = " + pi.getXid() + ") because the data field is empty."); return; } //反序列化pack-in消息中的data if (alwaysDecodeEth) { eth = new Ethernet(); eth.deserialize(pi.getData(), 0, pi.getData().length); } // fall through to default case... default: List<IOFMessageListener> listeners = null; if (messageListeners.containsKey(m.getType())) { listeners = messageListeners.get(m.getType()).getOrderedListeners(); } FloodlightContext bc = null; if (listeners != null) { // Check if floodlight context is passed from the calling // function, if so use that floodlight context, otherwise // allocate one if (bContext == null) { bc = flcontext_alloc(); } else { bc = bContext; } if (eth != null) { IFloodlightProviderService.bcStore.put(bc, IFloodlightProviderService.CONTEXT_PI_PAYLOAD, eth); } // Get the starting time (overall and per-component) of // the processing chain for this packet if performance // monitoring is turned on pktinProcTimeService.bootstrap(listeners); pktinProcTimeService.recordStartTimePktIn(); Command cmd; for (IOFMessageListener listener : listeners) { pktinProcTimeService.recordStartTimeComp(listener); cmd = listener.receive(sw, m, bc); pktinProcTimeService.recordEndTimeComp(listener); if (Command.STOP.equals(cmd)) { break; } } pktinProcTimeService.recordEndTimePktIn(sw, m, bc); } // paag // And just before we exit the controller loop we see if anyone // is interested in knowing that we are exiting the loop for (IControllerCompletionListener listener : completionListeners) listener.onMessageConsumed(sw, m, bc); if ((bContext == null) && (bc != null)) flcontext_free(bc); } }
可以看出pack_in消息会通过controller传递给其它实现了IOFMessageListeners的模块,由模块进行处理。至此交换机和控制器的数据就进入了各个模块中进行处理。下一节应该学习学习模块了.
- SDN控制器Floodlight源码学习(五)--控制器和交换机交互(3)
- SDN控制器Floodlight源码学习(三)--控制器和交换机交互(1)
- SDN控制器Floodlight源码学习(四)--控制器和交换机交互(2)
- SDN控制器Floodlight源码学习(二)--控制器(1)
- SDN控制器Floodlight源码学习(七)--拓扑管理模块(TopologyManager)
- SDN控制器Floodlight源码学习(八)--转发模块(Forwarding)
- 搭建SDN控制器floodlight
- SDN控制器测试专题五:Floodlight性能测试报告(上)
- SDN控制器Floodlight源码学习(六)--链路发现模块(LinkDiscovery)
- 使用SDN控制器 Floodlight 管理 OVS
- SDN控制器Floodlight--容错部署(FT)
- ovs和连接控制器floodlight
- SDN控制器与交换机如何建立连接
- SDN 实践之floodlight控制器统计流量种类
- SDN开发之基于floodlight控制器做QoS策略
- Floodlight控制器的安装以及SDN环境的配置
- SDN开发之基于floodlight控制器做QoS策略
- SDN 实践之floodlight控制器统计流量种类
- 谈谈canvas的性能优化(主要讲缓存问题)
- synchronized的初级使用
- linux系统IO分析心得
- tr
- 斗地主AI算法——第十五章の测试模块
- SDN控制器Floodlight源码学习(五)--控制器和交换机交互(3)
- VUE进阶(路由等)
- NYOJ 99 单词拼接 欧拉回路
- LightOJ1317-Throwing Balls into the Baskets
- HTTP状态码
- Scrapy+PhantomJS+Selenium动态爬虫
- Linux ARP缓存配置和状态查看命令
- HomeBrew的安装和简单使用
- EditText,这篇就够了