SDN控制器之POX篇

Posted 造夢先森

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDN控制器之POX篇相关的知识,希望对你有一定的参考价值。


1. 安装POX

POX基于Python2.7的环境运行,官方版本的POX可以运行在Windows、Mac OS、以及Linux操作系统中。POX源码已在github发布,可将POX的源码下载到本地机器进行安装使用。

在Linux系统下可以直接使用git 将pox源码下载下来,如:

$git clone http://github.com/noxrepo/pox

或在 https://github.com/pkpk8/pox 下载


2.配置POX


(1)修改监听端口

POX的监听端口默认是6633,修改监听端口的方式有以下两种:

1)临时修改方法

每次启动POX时指定监听端口,如指定的端口为6636,则在命令行后添加:

openflow.of_01 –port=6636

2)修改控制器的默认端口方法

修改/pox/openflow/of_01.py文件,如指定的端口为6636,则将文件中所有的port=6633改为port=6636。

(2)配置Web界面端口

1)获取POXDesk

cd pox/ext
git clone https://github.com/MurphyMc/poxdesk

2)获取qooxdoo

下载qooxdoo代码压缩包,然后把解压后文件夹名字改成qx

cd poxdesk
wget http://downloads.sourceforge.net/qooxdoo/qooxdoo-2.0.2-sdk.zip
unzip qooxdoo-2.0.2-sdk.zip
mv qooxdoo-2.0.2-sdk qx

3)初始化poxdesk
进入poxdesk目录,执行命令./generate.py

cd poxdesk
./generate.py

4)启动POX

cd ../../..
./pox.py samples.pretty_log web messenger messenger.log_service messenger.ajax_transport openflow.of_service poxdesk

Samples.pretty.log是一个组件,可以让pox开启的时候有字体有颜色,不添加也可以,但是界面比较难看。

这种启动pox-ui的方式只能启动监听并且开启ui视图,但是无法给switch下发消息(poxdesk的web中的terminal是打算用其他虚拟of-switch的工具来控制下发规则,但是我们是真实的of-switch)
完整的使用方式如下:

./pox.py samples.pretty_log web messenger messenger.log_service 
messenger.ajax_transport openflow.of_service poxdesk openflow.discovery poxdesk.tinytopo py

poxdesk.tinytopo可以自动识别topo。上面命令的结尾添加py就可以出现熟悉的pox>命令模式,这时可以在web上看到下联的of-switch.

5)访问Web
用浏览器访问localhost:8000/poxdesk,默认端口8000
点击网页左下角的图标pox,可以打开许多小框。


3.POX加mininet测试

把环境都安装好了之后,分别在terminal下输入命令启动pox和poxdesk(启动命令以上的github的guide中都有),然后启动mininet(sudo mn),最后在浏览器中打开http://127.0.0.1:8000/poxdesk/source/ ,在浏览器左下角的POX按钮处选择topo viewer,然后在mininet动态配置拓扑,即可以在topo viewer中看到可视化的拓扑。

(1)简单测试:


启动POX时,需要运行pox.py 或debug-pox.py。前者是在一般的情况下运行POX,后者主要用于调试POX控制器,因此如果要在POX中做开发,通常会选用debug-pox.py来启动POX。POS启动命令中的可选参数主要包括verbose、no-cli、no-openflow,具体描述信息及其他参数可以借助命令./pox.py –help查看。

启动pox:

cd pox
./pox.py openflow.of_01 forwarding.l2_learning
或
./pox.py samples.pretty_log web messenger messenger.log_service messenger.ajax_transport openflow.of_service poxdesk  poxdesk.terminal  poxdesk.tinytopo openflow.discovery forwarding.l2_learning py 

pox.py是程序的入口,需要openflow.of_01库解释后面的参数,forwarding.l2_learning为POX提供的组件。POX默认开启6633端口监听。

poxdesk.tinytopo可以自动识别topo,poxdesk.terminal可以使用linux terminal(在web上操作terminal)。上面命令的结尾添加py就可以出现熟悉的pox>命令模式,这时可以在web上看到下联的of-switch.

若出现端口占用问题:

netstat -anp|grep 6633
kill 3204(进程号)

开启mininet执行:

mn --controller=remote,ip=192.168.0.105 --topo=tree,2,2
mininet> dpctl dump-flows                   
mininet>pingall
mininet> dpctl dump-flows             //触发flow entry下发flow entry


(2)流表测试


1,启动pox:

python pox.py openflow.of_01 --address=192.168.0.105 --port=6633 py

2,启动mininet:
virtualbox启动,ifconfig得到其ip为192.168.0.106
开启新终端登入mininet,密码mininet:

ssh -X [email protected]192.168.0.106      

sudo mn --controller=remote,ip=192.168.0.105  //设置控制器
mininet> dpctl dump-flows                   
mininet>pingall                  //无匹配流表,无法ping通
mininet> dump
<Host h1: h1-eth0:10.0.0.1 pid=1980> 
<Host h2: h2-eth0:10.0.0.2 pid=1984> 
<OVSSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=1989> 
<RemoteController{‘ip‘: ‘192.168.0.105‘} c0: 192.168.0.105:6633 pid=1974> 

3,添加流表:

POX> from pox.lib.addresses import IPAddr
POX> from pox.lib.addresses import EthAddr
POX> import pox.openflow.libopenflow_01 as of           //导出核心模块,并命名为of
POX> core.openflow.connections.keys()           //获取连接控制端的openflow switch的key
[1]
POX>msg=of.ofp_flow_mod()               //编辑消息
POX>msg.priority=3
POX>msg.match.in_port=1
POX>msg.actions.append(of.ofp_action_output(port=2))
POX>core.openflow.connections[1].send(msg)
POX> msg.match.in_port=2
POX> msg.actions.append(of.ofp_action_output(port=1))
POX> core.openflow.connections[1].send(msg)

4,mininet端:

mininet> dpctl dump-flows   //显示已添加流表
mininet> pingall           //可以ping通


4.POX控制器下发openflow流表指南

启用pox控制器并同openflow交换机连接后,就可以使用pox控制器下发流表项了,这里先介绍一下下发流表项中各个匹配项和动作的命令。

匹配字段

  1. 编辑消息,消息类型为flowmod
    命令:POX> msg=of.ofp_flow_mod(command=0)
    参数:command:0为ADD(添加流),1为MODIFY,2为MODIFY_STRICT(严格匹配掩码和优先级修改流规则),3为DELETE(删除所有流规则),4为DELETE_STRICT(严格匹配掩码和优先级删除流规则)
    缺省情况下,即不标明参数command,如:msg=of.ofp_flow_mod(),command=0,添加流表项。
  2. 设置规则的优先级
    命令:POX> msg.priority=x
    X为优先级数值,范围为1-65535
  3. 匹配入端口
    命令:POX> msg.match.in_port=y
    指定规则匹配的入端口值,y为交换机上端口对应的index值。
  4. 匹配源mac
    命令:POX> msg.match.dl_src=EthAddr(“”)
  5. 匹配目的mac
    命令:POX> msg.match.dl_dst=EthAddr(“ ”)
  6. 匹配以太类型
    命令:POX> msg.match.dl_type=x
    指定规则匹配ip类型报文
  7. 匹配vlan id
    命令:POX> msg.match.dl_vlan=x
    说明:dl_vlan必须为openflow交换机上存在的vlan
  8. 匹配vlan优先级
    命令:POX> msg.match.dl_vlan_pcp=x
    说明:dl_vlan_pcp必须在0-7之内。
  9. 匹配源ip地址
    命令:POX> msg.match.nw_src=“A.B.C.D/X”
    说明:下发匹配源ip地址时,必须指定匹配的以太类型,如:
    POX> msg.match.dl_type=0x800
    POX> msg.match.nw_src=“192.168.2.133/24”
  10. 匹配目的ip地址
    命令:POX> msg.match.nw_dst=“A.B.C.D/X”
    说明:下发匹配目的ip地址时,必须指定匹配的以太类型,如:
    POX> msg.match.dl_type=0x800
    POX> msg.match.nw_dst=“192.168.2.133/24”
  11. 匹配协议类型
    命令:POX> msg.match.nw_proto=x
    说明:必须指定匹配的以太网类型,再匹配ip协议类型,如:
    POX> msg.match.dl_type=0x800
    POX> msg.match.nw_proto=6
  12. 匹配tos
    命令:POX> msg.match.nw_tos=x
    说明:必须指定匹配的以太网类型,再匹配tos值,如:
    POX> msg.match.dl_type=0x800
    POX> msg.match.nw_tos=64
  13. 匹配tcp源端口
    命令:POX> msg.match.tp_src=X
    说明:必须指定匹配的以太网类型,再匹配ip协议类型,最后匹配tcp port,如:
    POX> msg.match.dl_type=0x800
    POX> msg.match.nw_proto=6
    POX> msg.match.tp_src=179
  14. 匹配tcp目的端口
    命令:POX> msg.match.tp_dst=X
    说明:必须指定匹配的以太网类型,再匹配ip协议类型,最后匹配tcp port,如:
    POX> msg.match.dl_type=0x800
    POX> msg.match.nw_proto=6
    POX> msg.match.tp_dst=179
  15. 在idle时间内,如果没有报文触发此动作,该条规则将删除
    命令:POX> msg.idle_timeout=X
    说明:X为时间值,单位为秒。缺省时为0,表示不老化删除。
  16. 在到达hard时间时,无论如何,该条规则将删除
    命令:POX> msg.hard_timeout=X
    说明:X为时间值,单位为秒。缺省时为0,表示不老化删除。
    修改动作
    若规则无动作则默认为丢弃;规则中没有显示的设置出端口的需要在相应动作之后添加出端口。
  17. 指定出端口动作
    命令:POX> msg.actions.append(of.ofp_action_output(port=X))
    说明:port号是openflow vlan内的端口。
    其中,port值可以为特殊参数值,IN_PORT = 0xfff8:从入端口将报文发出。FLOOD= 0xfffb:除了入端口和stp不允许的端口的所有端口。ALL = 0xfffc:除了入端口的其余端口。CONTROLLER = 0xfffd:发送给控制器。NONE = 0xffff:和物理端口无关
  18. 转发指定的端口和队列
    命令:POX> msg.actions.append(of.ofp_action_enqueue(port=x,queue_id=y))
  19. 改变目的mac为指定mac
    命令:POX> msg.actions.append(of.ofp_action_dl_addr.set_dst(“”))
    说明:mac地址形式为ff:ff:ff:ff:ff:ff
  20. 改变源mac为指定mac
    命令:POX> msg.actions.append(of.ofp_action_dl_addr.set_src(“”))
  21. 设定tos值
    命令:POX> msg.actions.append(of.ofp_action_nw_tos(nw_tos=x))
  22. 设定vlan值
    命令:POX> msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=x))
  23. 设定vlan cos值
    命令:POX> msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp=x))
    说明:设置cos值时必须先设置vlan id,如:
    POX> msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=3))
    POX> msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp=4))


POX使用实例

1. 下发匹配入端口,动作为出端口的流表项
命令:

POX>msg=of.ofp_flow_mod()
POX>msg.priority=3
POX>msg.match.in_port=193
POX>msg.actions.append(of.ofp_action_output(port=194))
POX>core.openflow.connections[13136560386L].send(msg)

说明:[13136560386L]为在POX和openflow交换机连接上时,使用命令POX>core.openflow.connections.keys()获取的交换机的key,每次下发流表项或者删除,修改流表项,这个key都是相同的。

2. 下发匹配目的MAC地址,动作为出端口的流表项
命令:

POX>msg=of.ofp_flow_mod()
POX>msg.priority=3
POX>msg.match.dl_src=EthAddr("ff:ff:ff:ff:ff:ff")
POX>msg.actions.append(of.ofp_action_output(port=194))
POX>core.openflow.connections[13136560386L].send(msg)

3. 下发匹配以太网类型,动作为出端口和队列的流表项
命令:

POX>msg=of.ofp_flow_mod()
POX>msg.priority=5
POX>msg.match.dl_type=0x800
POX>msg.actions.append(of.ofp_action_enqueue(queue_id=5,port=194))
POX>core.openflow.connections[13136560386L].send(msg)

4. 下发匹配源mac地址,动作为设置vlan 并指定出端口的流表项
命令:

POX>msg=of.ofp_flow_mod()
POX>msg.priority=5
POX>msg.match.dl_src=EthAddr(“00:03:0f:01:12:43”)
POX>msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=3))
POX>msg.actions.append(of.ofp_action_output(port=194))
POX>core.openflow.connections[13136560386L].send(msg)

5. 下发匹配入端口,动作为设置vlan、cos,并指定出端口的流表项
命令:

POX>msg=of.ofp_flow_mod()
POX>msg.priority=5
POX>msg.match.in_port=193
POX>msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=4))
POX>msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp=5))
POX>msg.actions.append(of.ofp_action_output(port=194))
POX>core.openflow.connections[13136560386L].send(msg)

6. 删除流表项
命令:

POX>msg=of.ofp_flow_mod(command=3)
POX>core.openflow.connections[13136560386L].send(msg)

说明:此命令是删除所有的流表项

7. 删除特定的流表项
命令:

POX>msg=of.ofp_flow_mod(command=4)
POX>msg.wildcards= 4194302
POX>msg.priority=5
POX>core.openflow.connections[13136560386L].send(msg)

说明:删除特定的流表项就是将command值为4,并且精确匹配需要删除的流表项的匹配字段和动作。

8. 修改流表项
命令:

POX>msg=of.ofp_flow_mod(command=2)
POX>msg.priority=5
POX>msg.match.in_port=193
POX>msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=4))
POX>msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp=5))
POX>msg.actions.append(of.ofp_action_output(port=194))
POX>core.openflow.connections[13136560386L].send(msg)

说明:修改流表项,即修改这条流表的动作。


5.POX组件介绍

按照组件的功能进行分类:

L2层地址学习、洪泛
forwarding.hub
forwarding.l2_learning
forwarding.l2_pairs
forwarding.l2_multi
forwarding.l2_nx

L3层地址学习
forwarding.l3_learning

构建拓扑
openflow.discovery
openflow.spanning_tree
forwarding.topo_proactive

openflow 连接相关
openflow.of_01
misc.full_payload
openflow.keepalive

pox内部服务
py
web.webcore
messenger
openflow.debug

pox网络服务应用
proto.arp_responder
proto.pong
proto.dns_spy
proto.dhcp_client
proto.dhcpd
misc.nat
misc.ip_loadbalancer

pox功能扩展
info.packet_dump
misc.of_tutorial
misc.mac_blocker
misc.gephi_topo
openflow.webservice

组件说明:

py
POX的交互式Python解释执行组件,用于DEBUG和交互式实验。默认执行,除非添加命令 –no-cli。其他组件可以向该解释器添加函数和值。

forwarding.hub
该组件每个交换机添加洪泛通配符规则,将所有交换机等效于ethernet集线器

forwarding.l2_learning
该组件使opennflow交换机实现 L2链路层上的地址学习(类似网桥)。但当该组件学习地址学习时,向流表下发的规则会尽可能的准确,而不仅仅是L2层的地址。例如不同的TCP连接将产生不同的表项。

forwarding.l2_pairs
类似于 forwarding.l2_learning,l2_pairs让交换机进行地址学习,但该组件是尽可能的简化规则学习,所有安装的表项时只使用L2层信息(如Mac地址)。

forwarding.l3_learning
该组件并不是一个完整的Router,该组件是可POX的packet library(代码)的一个实现样例,可以构造ARP请求和回复。l3_learning关心IP从哪来,但并不关心IP的填充域,如子网等。

forwarding.l2_multi
L2层地址学习,但该层的学习不是单个交换机的独立学习,而是通过 openflow.discovery交换机之间交换拓扑信息,学习整个网络的拓扑结构。只要网络中有一个交换机学习到一个新的Mac地址及其位置,所有的交换机就都能学会。

forwarding.l2_nx
Open vSwitch的quick-and-dirty组件,需要使用Openvswitch的Nicira扩展安装。

forwarding.topo_proactive
基于重要拓扑的IP地址安装规则。通过DHCP进行地址分配。所有的主机都必须用指定的IP地址,绝大部分规则都是主动安装(?)。该组件被添加至聚合规则复用分支中,路由编码基于l2_multi组件。该组件依赖openflow.discovery以及openflow.spanning_tree组件(有待确认)。

openflow.spanning_tree
该组件使用discovery组件来创建网络拓扑的视图,构造一棵生成树,然后使不在生成树中的交换机端口的洪泛功能失效,使得网络中不存在洪泛回路。需要注意的是该组件同生成树协议没有很大关系,只是有相似的目的。两个选项:

–no-flood,只要交换机连接上了就使该交换机的所有端口洪泛失效,对于某些端口,稍后将使能。
–hold-down,防止洪泛控制在一个完整的发现回路完成前被改变

因此该组件最安全的的使用方法是
openflow.spanning_tree –no-flood –hold-down .
openflow.webservice

Openflow的一个简单 JSON-RPC-ish web service交互式接口,由of_service信息服务派生而来,依赖于webcore组件。可以使用HTTP POST方式发送JSON进行访问。

目前支持的方法有:
method
get_flow_stats,获取流表的表项
get_switch_desc,获取指定交换机详细信息
get_switches,获取交换机列表和基本信息
set_table , 设置指定交换机的流表

web.webcore
在Pox进程中启动一个web服务,其他组件可以通过它提供静态或动态内容。

messenger
该组件通过双向JSON消息为POX在进程间提供了一个交互接口。该组件本质上是API,通过TCP Socket和HTTP进行通信。具体的功能通过Services实现。messenger.log_service允许远程操作log(读log信息,配置log等)。openflow.of_service 允许一下Openflow的操作(如显示交换机列表,设置流表表项等)。./tools/pox-log.py是一个独立的Python应用,可以通过TCP同log服务进行交互。

openflow.of_01
该组件同openflow 1.0协议版本的交换机 进行通讯,默认启动。

openflow.discovery
该组件在交换机之间使用特制的LLDP报文来发现整个网络的拓扑结构。当链路生效或者失效时,该组件都会产生一个事件(Raise Events)。

openflow.debug
加载该组件将导致POX创建pcap追踪(进行抓包),包括openflow报文,可导入wireshark进行分析。该工具并不能完全代替wireshark或tcpdump,不过有一个比较好的特性是每一个openflow报文都一个完整的帧中。

openflow.keepalive
该组件令POX向已经连接的交换机周期性的发送echo请求。但这会解决两个问题:

第一,有些交换机(包括推荐交换机)会认为空闲连接意味着同控制器连接丢失,将会在一段silence时间后断开连接。

第二,如果网络与交换机断开,控制器将不会立即获得一个FIN或RST,所以将会很难确定一个交换机失效。通过周期行发送echo请求,并分析交换机的响应,即可解决该问题。

proto.pong
该组件是一个简单的检测ICMP echo请求和应答的样例组件

proto.arp_responder
该组件为一个ARP应用,可以学习和代理ARP请求,也可以通过查询静态的表项来回复ARP请求。该组件提供了一个控制台交互界面来查询和修改arp表。

info.packet_dump
该组件将packet_in信息保存至log中,有点类似于在交换机中运行tcpdump

proto.dns_spy
检测DNS应答并存储应答结果,其他组件可以通过DNSSpy检测这些信息。

proto.dhcp_client
DHCP客户端,在同其他组件进行联合时有用

proto.dhcpd
简单的DHCP服务器端,服务器本身的默认地址为192.168.0.254,下发的地址域为192.168.0.1~192.168.0.253,同时宣称自身为网关和DNS服务器。

misc.of_tutorial
配合openflow tutorial使用的组件,类似于简单的hub,但可以修改成L2 learning的交换机

misc.full_payload
默认情况下,当一个数据包在交换机流表中没有命中时,交换机只向控制器发送数据包的前128bytes,使用该组件可以将每一个交换机配置成发送整个数据包

misc.mac_blocker
具有Tkinter-based界面,可以阻塞Mac地址

misc.nat
实现网络地址转换的组件(木有详细介绍)

misc.ip_loadbalancer
由carp branch(不理解是啥)启用的TCP负载均衡器

misc.gephi_topo
检测拓扑结构,并将其导入到gephi中进行分析

以上是关于SDN控制器之POX篇的主要内容,如果未能解决你的问题,请参考以下文章

请比较懂交换机、网管和LLDP协议的前辈进来指导一下,懂SDN和openflow更好。能留个邮箱是最好了。

T4模板:T4模板之菜鸟篇

T4模板之菜菜鸟篇

POX控制器解决环路拓扑广播风暴问题

4 Mininet测量路径的损耗率

实验5:开源控制器实践——POX