Floodlight中 处理packetin消息的顺序(1)
当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 IListener< OFType>
{
//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.其它的没有查看。
总结。通过上面的代码阅读能够得到例如以下的结构图:
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]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2015-02-24 unity3d脚本编程
2015-02-24 C# 窗口间传递数据
2015-02-24 Thrift官方安装手冊(译)
2015-02-24 从用python做zoj1011发生Non-zero Exit Code错误说起
2015-02-24 POJ 1637 Sightseeing tour(最大流)
2015-02-24 js中substr与substring的差别
2015-02-24 xcode armv6 armv7 armv7s arm64