第一个应用¶
激发你的兴趣¶
如果你想以你自己的方式管理网络设备(交换机、路由器等),你需要编写你的 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 应用。