Floodlight开发——怎样写一个floodlight模块

一 前提

  • 安装mininet和Open vSwitch软件,也可以直接下载一个装有mininet和Open vSwitch的虚拟机 Virtual Machine Image (OVF format, 64-bit, Mininet 2.0)
  • 下载Floodlight源码,并导入Eclipse中

我们将编写一个简单的Floodlight模块,用来检测在网络中新的、未被发现的MAC地址,并记录被检测到的MAC地址和交换机。

二 创建监听器

2.1在Eclipse中添加类

a). 将“floodlight”项目导入Eclipse中,并在包管理器中展开,然后找到
“src/main/java”目录。
b). 右键单击“src/main/java”目录,选择“New / Class”.
c). 在“Package”框中输入“net.floodlightcontroller.mactracker”。
d). 在“Name”框中输入“MACTracker”。
e). 接下来找到“Interface”那一栏,点击旁边的“Add...”按钮。
f). 添加“IOFMessageListener”和“IFloodlightModule”,点击“OK”按钮。
g). 点击对话框上的“Finish”按钮。

最后你会得到一个类,如下所示:

package net.floodlightcontroller.mactracker;

import java.util.Collection;
import java.util.Map;
 
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.types.MacAddress;
 
import net.floodlightcontroller.core.FloodlightContext;
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 IOFMessageListener, IFloodlightModule {
 
    @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 Collection> getModuleServices() {
        // TODO Auto-generated method stub
        return null;
    }
 
    @Override
    public Map, IFloodlightService> getServiceImpls() {
        // TODO Auto-generated method stub
        return null;
    }
 
    @Override
    public Collection> 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) {
        // TODO Auto-generated method stub
 
    }
 
    @Override
    public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
        // TODO Auto-generated method stub
        return null;
    }
 
}

2.2 设置模块的依赖关系和初始化

在开始前,我们需要引入一些依赖包。使用像eclipse一样的工具可以很方便的添加,如果你没有使用eclipse,只需要将下面的代码添加到类的前面。

import net.floodlightcontroller.core.IFloodlightProviderService;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.Set;
import net.floodlightcontroller.packet.Ethernet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

现在,我们有了类的框架,我们还需要实现相关的功能才能使得模块能够被加载。首先,我们添加一些在类中需要的成员变量。因为要监听OpenFLow的消息,我们需要用FloodlightProvider(IFloodlightProviderService类)注册信息,我们也需要一个Set集合来存储被检测到的MAC地址,最后,我们使用一个日志类logger打印出被检测出的信息。

protected IFloodlightProviderService floodlightProvider;
protected Set macAddresses;
protected static Logger logger;

我们需要将其连接到模块加载系统。通过修改getModuleDependencies() 方法告诉模块加载器它与该类的依赖关系。

@Override
public Collection> getModuleDependencies() {
    Collection> l =
        new ArrayList>();
    l.add(IFloodlightProviderService.class);
    return l;
}

现在我们开始写模块的初始化方法init(),init()会在控制器启动过程的早期被调用——它主要用来加载相关依赖和初始化数据结构。

@Override
public void init(FloodlightModuleContext context) throws FloodlightModuleException {
    floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
    macAddresses = new ConcurrentSkipListSet();
    logger = LoggerFactory.getLogger(MACTracker.class);
}

2.3 处理Packet-In消息

接下来实现基本的监听器。我们将在startUp()方法中注册PACKET_IN消息。在这里,我们确保其他被依赖的模块已经被初始化。

@Override
public void startUp(FloodlightModuleContext context) {
    floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
}

我们也必须在OFMessage消息监听器中设置一个ID,这可以在getName()方法中实现。

@Override
public String getName() {
    return MACTracker.class.getSimpleName();
}

现在我们来定义我们想要的对PACKET_IN消息的处理行为。注意,为了使PACKET_IN
消息在后面可以继续被其他相关消息处理程序处理,我们需要返回Command.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;
    }

2.4 注册模块

我们已经基本完成了模块的编写工作,现在我们只需要告诉Floodlight在启动的时候加载本模块。首先,我们必须告诉加载器本模块的存在,这需要在文件src/main/resources/META-INF/services/
net.floodlightcontroller.core.module.IFloodlightModule 中添加一行模块的全名。打开该文件,然后在下面添加一行:

net.floodlightcontroller.mactracker.MACTracker

接下来需要让模块被加载。我们可以在Floodlight模块配置文件中添加MACTracker模块,这个默认的文件在src/main/resources/floodlightdefault.properties。它的key值是floodlight.modules,value是一个将模块名用逗号分割的列表。

floodlight.modules = , net.floodlightcontroller.mactracker.MACTracker

最后运行控制器,右键Main.java文件,选择"Run As... / Java Application"。

三 检验模块功能

3.1 建立网络拓扑

打开mininet虚拟机,输入命令

sudo mn --topo single,3 --controller=remote,ip=<你本机的ip地址>,port=6653 --switch ovsk,protocols=OpenFlow13

结果如下图所示:

Floodlight开发——怎样写一个floodlight模块_第1张图片

3.2 查看floodlight输出结果

在Eclipse的控制台输出信息里,查找MACTracker,可以看到如下信息,可以看到网络中新接入设备的MAC地址和相关交换机


你可能感兴趣的:(Floodlight开发——怎样写一个floodlight模块)