第一个应用

激发你的兴趣

如果你想以你自己的方式管理网络设备(交换机、路由器等),你需要编写你的 OS-Ken 应用。你的应用告诉 OS-Ken 你希望如何管理这些设备。然后 OS-Ken 将使用 OpenFlow 协议等来配置这些设备。

编写 OS-Ken 应用很简单。它只是 Python 脚本。

开始编写

我们展示一个 OS-Ken 应用,使 OpenFlow 交换机工作如一个简单的二层交换机。

打开一个文本编辑器,创建一个包含以下内容的新文件

from os_ken.base import app_manager

class L2Switch(app_manager.OSKenApp):
    def __init__(self, *args, **kwargs):
        super(L2Switch, self).__init__(*args, **kwargs)

OS-Ken 应用只是一个 Python 脚本,所以你可以用任何名称、扩展名和任何你想要的地方保存这个文件。让我们将文件命名为 'l2.py' 并保存在你的主目录下。

这个应用目前还没有任何实际用处,但它是一个完整的 OS-Ken 应用。事实上,你可以运行这个 OS-Ken 应用

% osken-manager ~/l2.py
loading app /Users/fujita/l2.py
instantiating app /Users/fujita/l2.py

你所需要做的就是定义一个继承自 OSKenApp 的新子类,来将你的 Python 脚本作为 OS-Ken 应用运行。

接下来,让我们添加将接收到的数据包发送到所有端口的功能。

from os_ken.base import app_manager
from os_ken.controller import ofp_event
from os_ken.controller.handler import MAIN_DISPATCHER
from os_ken.controller.handler import set_ev_cls
from os_ken.ofproto import ofproto_v1_0

class L2Switch(app_manager.OSKenApp):
    OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION]

    def __init__(self, *args, **kwargs):
        super(L2Switch, self).__init__(*args, **kwargs)

    @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
    def packet_in_handler(self, ev):
        msg = ev.msg
        dp = msg.datapath
        ofp = dp.ofproto
        ofp_parser = dp.ofproto_parser

        actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)]
        out = ofp_parser.OFPPacketOut(
            datapath=dp, buffer_id=msg.buffer_id, in_port=msg.in_port,
            actions=actions)
        dp.send_msg(out)

一个名为 'packet_in_handler' 的新方法被添加到 L2Switch 类中。当 OS-Ken 接收到 OpenFlow packet_in 消息时,会调用这个方法。关键在于 'set_ev_cls' 装饰器。这个装饰器告诉 OS-Ken 应该在什么情况下调用被装饰的函数。

装饰器的第一个参数指示触发函数调用的事件。正如你容易预料的那样,每次 OS-Ken 收到 packet_in 消息时,这个函数都会被调用。

装饰器的第二个参数指示交换机的状态。可能你希望在 OS-Ken 和交换机之间的协商完成之前忽略 packet_in 消息。使用 'MAIN_DISPATCHER' 作为第二个参数意味着只有在协商完成后才会调用这个函数。

接下来,让我们看看 'packet_in_handler' 函数的前半部分。

  • ev.msg 是一个表示 packet_in 数据结构的的对象。

  • msg.dp 是一个表示数据路径(交换机)的对象。

  • dp.ofproto 和 dp.ofproto_parser 是表示 OS-Ken 和交换机协商的 OpenFlow 协议的对象。

准备好后半部分了。

  • OFPActionOutput 类与 packet_out 消息一起使用,以指定你想要发送数据包的交换机端口。这个应用需要一个交换机来从所有端口发送数据包,因此使用了 OFPP_FLOOD 常量。

  • OFPPacketOut 类用于构建 packet_out 消息。

  • 如果你使用 OpenFlow 消息类对象调用 Datapath 类的方法 send_msg,OS-Ken 将构建并发送线上的数据格式到交换机。

现在,你完成了你的第一个 OS-Ken 应用的实现。你已经准备好运行这个有实际用途的 OS-Ken 应用了。

一个简单的二层交换机太简单了?你想实现一个学习型二层交换机吗?请移步 下一步。你可以在 os_ken/app 目录和 integrated tests 目录中学习现有的 OS-Ken 应用。