SDN

POX 控制器 API (一)——基础篇

2018-10-09  本文已影响51人  顽强的猫尾草

全网都找不到详尽的 API 介绍,自己试着从各处总结一些。

一种开始构建自己的 POX 模块的常用方法是将现有模块(例如 forwarding/l2_learning.py)复制到 ext 目录(例如 ext/my_component.py)。然后,可以修改新文件并将 POX 调用为 ./pox.py my_component

POX 有一个名为 “core” 的对象,它作为 POX 大部分 API 的核心。POX 中的许多模块都会希望访问 core 对象。一般通过导入 core 即可:

from pox.core import core

注册组件

core.register() 接受两个参数。第二个是我们想要在核心上注册的对象,第一个是我们给它起的名字。下例是一个非常简单的组件,它有一个 launch() 函数,注册后就可以通过 core 来调用 thing 里面的 foo 函数了:

class MyComponent (object):
  def __init__ (self, an_arg):
    self.arg = an_arg
    print "MyComponent instance registered with arg:", self.arg
 
  def foo (self):
    print "MyComponent with arg:", self.arg


def launch ():
  component = MyComponent("spam")
  core.register("thing", component)
  core.thing.foo()    # prints "MyComponent with arg: spam"

处理地址:pox.lib.addresses

POX 中的 IPv4、IPv6 和以太网地址由 pox.lib.addresses 的 IPAddr、IPAddr6 和 EthAddr 类表示。在某些情况下,其他地址格式可能有效(例如,点分四个数字的 IP 地址),但使用地址类应该始终有效。

例如,使用 IP 地址时:

from pox.lib.addresses import IPAddr, IPAddr6, EthAddr
 
ip = IPAddr("192.168.1.1")
print str(ip)    # Prints "192.168.1.1"
print ip.toUnsignedN()    # Convert to network-order unsigned integer -- 16885952
print ip.raw    # Returns a length-four bytes object (a four byte string, more or less)
 
ip = IPAddr(16885952, networkOrder=True)
print str(ip)    # Also prints "192.168.1.1" !

pox.lib.addresses 还包含各种实用工具函数,用于解析网络掩码、CIDR 表示法、检查IP是否在特定子网内,等等。

处理数据包:pox.lib.packet

POX 中的许多应用程序与数据包交互(例如,你可能希望构造数据包并将其发送出交换机,或者你可以通过 ofp_packet_in OpenFlow 消息从交换机接收数据包)。为此,POX 有一个用于解析和构造数据包的库。该库支持许多不同的数据包类型。

大多数数据包都有某种头部和某种有效载荷。有效载荷通常是另一种类型的包。例如在 POX 中,通常使用以太网数据包,这些数据包通常包含 ipv4 数据包(ipv4 数据包通常又包含 tcp 数据包......)。POX 支持的一些数据包类型是:

POX 中的所有数据包类都可以在 pox/lib/packet 中找到。可以简单地通过 import 导入:

import pox.lib.packet as pkt

可以通过两种方式解析封装的数据包:使用数据包对象的 payload 属性,或使用 find() 方法。例如,以下是使用 payload 属性解析 ICMP 消息的方法:

def parse_icmp (eth_packet):
    if eth_packet.type == pkt.IP_TYPE:
        ip_packet = eth_packet.payload
        src_ip = ip_packet.srcip    # 源 IP
        if ip_packet.protocol == pkt.ICMP_PROTOCOL:
            icmp_packet = ip_packet.payload
            icmp_code = icmp_packet.code    # ICMP sequence number
...

分组对象的 find() 方法可用于通过所需类型名称(例如 “icmp”)或其类(例如 pkt.ICMP)来查找特定的封装分组。如果数据包对象未封装所请求类型的数据包,则返回 None。 例如:

def handle_IP_packet (packet):
    ip = packet.find('ipv4')
    if ip is None:
        # This packet isn't IP!
        return
    print "Source IP:", ip.srcip

接下来介绍一些支持的数据包类型的一些有用的属性/方法/常量。

上一篇下一篇

猜你喜欢

热点阅读