概述
Floodlight模块编写——初涉江湖
准备
完成环境配置安装的准备工作,我安装的是最新版的floodlight,配合mininet虚拟环境进行实验
在Eclipse里添加类
1)右键“src/main/java”新建类
2)包名取作“net.floodlightcontroller.mactracker”,类名:“MACTracker”
3)接口选项“Add…”,添加“IOFloodlightModule”、“IOFMessageListener”
4)“finish”创建完成
生成的类包含以下初始代码:
package net.floodlightcontroller.mactracker;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFType;
import org.slf4j.Logger;
import net.floodlightcontroller.core.FloodlightContext;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFMessageListener;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
public class MACTracker implements IFloodlightModule, IOFMessageListener {
@Override
public String getName() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isCallbackOrderingPrereq(OFType type, String name) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isCallbackOrderingPostreq(OFType type, String name) {
// TODO Auto-generated method stub
return false;
}
@Override
public net.floodlightcontroller.core.IListener.Command receive(IOFSwitch sw, OFMessage msg,
FloodlightContext cntx) {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<Class<? extends IFloodlightService>> getModuleServices() {
// TODO Auto-generated method stub
return null;
}
@Override
public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
// TODO Auto-generated method stub
return null;
}
@Override
public void init(FloodlightModuleContext context) throws FloodlightModuleException {
// TODO Auto-generated method stub
}
@Override
public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
// TODO Auto-generated method stub
}
}
具体实现模块
模块依赖的建立
- 由于需要获取OpenFlow消息,必须获取FloodlightProvider模块的服务,下面这个方法用于建立和其他模块的依赖,建立依赖的模块类类型都存储于L这个数组中,从而调用这些模块的功能
protected IFloodlightProviderService floodlightProvider;
...
@Override
public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
Collection<Class<? extends IFloodlightService>> l =
new ArrayList<Class<? extends IFloodlightService>>();
l.add(IFloodlightProviderService.class);
return l;
}
- 还需要一个集合set来存储获取到的MAC地址
protected Set<Long> macAddresses;
模块初始化
- 初始化函数作用是加载依赖关系,并初始化相关数据结构
@Override
public void init(FloodlightModuleContext context) throws FloodlightModuleException {
floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
macAddresses = new ConcurrentSkipListSet<Long>();
logger = LoggerFactory.getLogger(MACTracker.class);
}
处理Packet-In消息
- 首先在startUp()方法里注册Packet-In消息
@Override
public void startUp(FloodlightModuleContext context) {
floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
}
- 解析来定义当收到该消息时需要做的操作,获取消息的以太网帧类,由Ethrnet类的接口方法得到源MAC地址,完成简单的注册。
- 这里注意continue表示在这个模块处理完该消息后还允许其他模块继续处理它
@Override
public net.floodlightcontroller.core.IListener.Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
Ethernet eth =
IFloodlightProviderService.bcStore.get(cntx,
IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
Long sourceMACHash = eth.getSourceMACAddress().getLong();
if (!macAddresses.contains(sourceMACHash)) {
macAddresses.add(sourceMACHash);
logger.info("MAC Address: {} seen on switch: {}",
eth.getSourceMACAddress().toString(),
sw.getId().toString());
}
return Command.CONTINUE;
}
- 想要解析更多的包内数据,可以查看Packet-In handle
关于各模块处理消息顺序问题
- 交换机发往控制器的消息,同一时间段只能被一个模块所处理。那么这里就有一个先后顺序的问题
- isCallbackOrderingPrereq() defines modules that should run before our module when processing a particular type of OpenFlow message.
- isCallbackOrderingPostreq() defines modules that should run after our module when processing a particular type of OpenFlow message.
- 一个最常见的情况是,当我们用自己的算法去自定义了一种流下发策略,那么必须将Forwording模块设置为在自己模块之后,用第二个方法。
- 而floodlight已实现的模块中也有例可循,如Forwarding模块在计算路径时需要调用设备管理模块的接口,来获取主机的位置,因此DeviceManager模块必须在Forwarding模块之前处理消息
@Override
public boolean isCallbackOrderingPrereq(OFType type, String name) {
return (type.equals(OFType.PACKET_IN) && (name.equals("topology") || name.equals("devicemanager")));
}
添加模块配置文件
- 第一个文件注册这个模块是存在的,配置文件:src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
- 直接添加:net.floodlightcontroller.mactracker.MACTracker
- 第二个文件注册这个模块默认被加载,配置文件:src/main/resources/floodlightdefault.properties
- 按格式添加:net.floodlightcontroller.mactracker.MACTracker
最后
以上就是等待咖啡为你收集整理的欢迎使用CSDN-markdown编辑器Floodlight模块编写——初涉江湖的全部内容,希望文章能够帮你解决欢迎使用CSDN-markdown编辑器Floodlight模块编写——初涉江湖所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复