欢迎使用CSDN-markdown编辑器

来源:互联网 发布:淘宝印度舞服装 编辑:程序博客网 时间:2024/06/11 01:12

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; ... @Overridepublic 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;

模块初始化

  • 初始化函数作用是加载依赖关系,并初始化相关数据结构
@Overridepublic 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消息
@Overridepublic 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
原创粉丝点击