美文网首页SDN
POX 控制器

POX 控制器

作者: 顽强的猫尾草 | 来源:发表于2018-10-09 09:26 被阅读90次

    默认拓扑

    如果我们不指定控制器直接运行 Mininet 提供给我们的默认拓扑:

    sudo mn
    

    你会发现节点间是 ping 得通的,因为默认的控制器进行 l2 层学习获得了流表。

    要使用 POX 的远程交换机,你可以这样做:

    $ cd ~/pox
    $ ./pox.py forwarding.l2_learning
    

    在另一个窗口,启动 Mininet 连接到“远程”控制器(这实际上是在本地运行,但 Mininet 的控制范围之外):

    $ sudo mn --controller=remote, ip=127.0.0.1, port=6633
    

    注意,这些其实都是默认的 IP 地址和端口值。

    要进入命令行模式的话:

    python pox.py openflow.of_01 py
    

    下发流表(因为我想让两边 ping 通,所以应该配正反两条流表规则,以下只是单方向的):

    POX> from pox.lib.addresses import IPAddr
    POX> from pox.lib.addresses import EthAddr
    POX> import pox.openflow.libopenflow_01 as of
    POX> core.openflow.connections.keys()
    [1]
    POX> msg=of.ofp_flow_mod()
    POX> msg.priority=3    # 数字越大, 优先级越高
    POX> msg.match.nw_src="10.0.0.1"
    POX> msg.match.in_port=2
    POX> msg.actions.append(of.ofp_action_output(port=1))
    POX> core.openflow.connections[1].send(msg)    # 这个 1 就是 connections.keys() 返回的 1
    

    反方向的流表只要交换一下出入端口就 OK 了。

    看一看 Mininet 这边,在配流表之前,ping 不通:

    mininet> dpctl dump-flows
    *** s1 ------------------------------------------------------------------------
    NXST_FLOW reply (xid=0x4):
    mininet> pingall
    *** Ping: testing ping reachability
    h1 -> X 
    h2 -> X 
    *** Results: 100% dropped (0/2 received)
    

    配了单方向流表以后,依然 ping 不通:

    mininet> dpctl dump-flows
    *** s1 ------------------------------------------------------------------------
    NXST_FLOW reply (xid=0x4):
     cookie=0x0, duration=4.827s, table=0, n_packets=0, n_bytes=0, idle_age=4, priority=5,in_port=1 actions=output:2
    mininet> h1 ping h2
    PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
    From 10.0.0.1 icmp_seq=1 Destination Host Unreachable
    From 10.0.0.1 icmp_seq=2 Destination Host Unreachable
    From 10.0.0.1 icmp_seq=3 Destination Host Unreachable
    ^C
    --- 10.0.0.2 ping statistics ---
    5 packets transmitted, 0 received, +3 errors, 100% packet loss, time 4000ms
    

    配了双向的以后:

    mininet> dpctl dump-flows
    *** s1 ------------------------------------------------------------------------
    NXST_FLOW reply (xid=0x4):
     cookie=0x0, duration=151.371s, table=0, n_packets=15, n_bytes=630, idle_age=22, priority=5,in_port=1 actions=output:2
     cookie=0x0, duration=4.423s, table=0, n_packets=0, n_bytes=0, idle_age=4, priority=5,in_port=2 actions=output:1
    mininet> h1 ping h2
    PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
    64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.208 ms
    64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.035 ms
    ^C
    --- 10.0.0.2 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 999ms
    rtt min/avg/max/mdev = 0.035/0.121/0.208/0.087 ms
    mininet> pingall
    *** Ping: testing ping reachability
    h1 -> h2 
    h2 -> h1 
    *** Results: 0% dropped (2/2 received)
    

    成功了!

    【注】交换机的端口号一般就是从 1 按顺序的,可以在启动 Mininet 以后新打开一个窗口用下面的命令查看都有哪些端口:

    $ sudo ovs-vsctl show
    0072de5e-fdb2-4e99-91e7-4f5d33acfa10
        Bridge "s1"
            Controller "tcp:127.0.0.1:6633"
                is_connected: true
            Controller "ptcp:6654"
            fail_mode: secure
            Port "s1-eth2"    # 端口 2
                Interface "s1-eth2"
            Port "s1"
                Interface "s1"
                    type: internal
            Port "s1-eth1"    # 端口 1
                Interface "s1-eth1"
        ovs_version: "2.5.4"
    

    POX 控制器里指定端口时不能用字符串,只能用数字,"s1-eth1" 和 "s1-eth2" 写成 1 和 2 就好。

    (至于端口对应着哪台主机,可以从网页上看,不知道有没有什么直观的从命令行上就可以查看的方式?或者由 API 指定?)
    问题解决,这个顺序是按照 AddLink 的顺序,比如 h1 和 h2 先后与 s1 连,那么 h1 就是端口 1 上的,h2 是端口 2 上的。当然也可以直接在 API 中指定,如:

    # specify a different port to connect host 5 to switch 1
    net.addLink( h5, s1, 1, 9 )    # h5 的 port 1 连接 s1 的 port 9 (注意如果没定义端口 1 就去定义端口 2 会报错)
    

    另外如果不正常退出 Mininet 或 POX 的话,会对下一次运行产生影响,所以最好用 exit 退出 Mininet,用 Ctrl-D 退出 POX。不然就要 sudo mn -c 来清理 Mininet 的缓存,并手动 kill POX 的进程。

    POX 的 API 可以查看这里,是相对很全的了。

    自定义拓扑

    利用 Mininet 的 Python API 可以很方便地开发各种拓扑以及连接远程控制器。给出一个示例:

    #!/usr/bin/python
    #coding=utf-8 
    from mininet.topo import Topo
    from mininet.net import Mininet
    from mininet.util import dumpNodeConnections
    from mininet.log import setLogLevel
    from mininet.cli import CLI
    from mininet.node import RemoteController
    
    class SingleSwitchTopo(Topo):
            def __init__(self, **opts):
                    Topo.__init__(self, **opts)
    
                    switch1 = self.addSwitch( 's1' )    # 添加交换机到拓扑中
                    switch2 = self.addSwitch( 's2' )
                    switch3 = self.addSwitch( 's3' )
                    host1 = self.addHost( 'h1' )    # 添加主机到拓扑中
                    host2 = self.addHost( 'h2' )    # 添加主机到拓扑中
    
                    self.addLink( host1, switch1 )
                    self.addLink( host2, switch2 )    # 添加双向连接
                    self.addLink( switch2, switch1 )
                    self.addLink( switch2, switch3 )
                    self.addLink( switch3, switch1 )
    
    def simpleTest():
            topo = SingleSwitchTopo()
            net = Mininet(topo)    # 主要类来创建和管理网络
            mycontroller = RemoteController("c0", ip = "127.0.0.1", port=6633)    # 创建远程控制器 (控制器的命名最好是 "c数字", 否则可能报错)
            net.controllers = [mycontroller]
            net.start()    # 启动拓扑网络
            print "Dumping host connections"
            dumpNodeConnections(net.hosts)    # 输出指定的网络信息
            print "Testing network connectivity"
            net.pingAll()    # 所有节点彼此测试互连
            # CLI(net)    # 进入 mininet> 提示符 
            net.stop()    # 停止网络
    
    
    if __name__ == '__main__':
            setLogLevel('info')  # 设置 Mininet 默认输出级别,设置 info 它将提供一些有用的信息
            simpleTest()
    

    更多 API 参见:http://mininet.org/api/annotated.html

    相关文章

      网友评论

        本文标题:POX 控制器

        本文链接:https://www.haomeiwen.com/subject/yiycgftx.html