1. 安裝POX
POX基於Python2.7的環境運行,官方版本的POX可以運行在Windows、Mac OS、以及Linux操作系統中。POX源碼已在github發佈,可將POX的源碼下載到本地機器進行安裝使用。
在Linux系統下可以直接使用git 將pox源碼下載下來,如:
$git clone http://github.com/noxrepo/pox
- 1
或在 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
- 1
- 2
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
- 1
- 2
- 3
- 4
3)初始化poxdesk
進入poxdesk目錄,執行命令./generate.py
cd poxdesk
./generate.py
- 1
- 2
- 3
4)啓動POX
cd ../../..
./pox.py samples.pretty_log web messenger messenger.log_service messenger.ajax_transport openflow.of_service poxdesk
- 1
- 2
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
- 1
- 2
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中看到可視化的拓撲。
mininet安裝步驟:
# git clone git://github.com/mininet/mininet
# cd mininet
# cat INSTALL
# ./util/install.sh -nfv //只安裝openflow交換機、ovs;若參數爲-a,將pox等一併安裝
# mn --version //查看版本
#卸載命令
sudo rm -rf /usr/local/bin/mn /usr/local/bin/mnexec /usr/local/lib/python*/*/*mininet* /usr/local/bin/ovs-* /usr/local/sbin/ovs-*
sudo apt-get remove mininet
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
(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
- 1
- 2
- 3
- 4
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(進程號)
- 1
- 2
開啓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
- 1
- 2
- 3
- 4
(2)流表測試
1,啓動pox:
python pox.py openflow.of_01 --address=192.168.0.105 --port=6633 py
- 1
2,啓動mininet:
若使用virtualbox啓動,ifconfig得到其ip爲192.168.0.106
開啓新終端登入mininet,密碼mininet:
ssh -X mininet@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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
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)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
4,mininet端:
mininet> dpctl dump-flows //顯示已添加流表
mininet> pingall //可以ping通
- 1
- 2
- 3
4.POX控制器下發openflow流表指南
啓用pox控制器並同openflow交換機連接後,就可以使用pox控制器下發流表項了,這裏先介紹一下下發流表項中各個匹配項和動作的命令。
匹配字段
- 編輯消息,消息類型爲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,添加流表項。 - 設置規則的優先級
命令:POX> msg.priority=x
X爲優先級數值,範圍爲1-65535 - 匹配入端口
命令:POX> msg.match.in_port=y
指定規則匹配的入端口值,y爲交換機上端口對應的index值。 - 匹配源mac
命令:POX> msg.match.dl_src=EthAddr(“”) - 匹配目的mac
命令:POX> msg.match.dl_dst=EthAddr(“ ”) - 匹配以太類型
命令:POX> msg.match.dl_type=x
指定規則匹配ip類型報文 - 匹配vlan id
命令:POX> msg.match.dl_vlan=x
說明:dl_vlan必須爲openflow交換機上存在的vlan - 匹配vlan優先級
命令:POX> msg.match.dl_vlan_pcp=x
說明:dl_vlan_pcp必須在0-7之內。 - 匹配源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” - 匹配目的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” - 匹配協議類型
命令:POX> msg.match.nw_proto=x
說明:必須指定匹配的以太網類型,再匹配ip協議類型,如:
POX> msg.match.dl_type=0x800
POX> msg.match.nw_proto=6 - 匹配tos
命令:POX> msg.match.nw_tos=x
說明:必須指定匹配的以太網類型,再匹配tos值,如:
POX> msg.match.dl_type=0x800
POX> msg.match.nw_tos=64 - 匹配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 - 匹配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 - 在idle時間內,如果沒有報文觸發此動作,該條規則將刪除
命令:POX> msg.idle_timeout=X
說明:X爲時間值,單位爲秒。缺省時爲0,表示不老化刪除。 - 在到達hard時間時,無論如何,該條規則將刪除
命令:POX> msg.hard_timeout=X
說明:X爲時間值,單位爲秒。缺省時爲0,表示不老化刪除。
修改動作
若規則無動作則默認爲丟棄;規則中沒有顯示的設置出端口的需要在相應動作之後添加出端口。 - 指定出端口動作
命令: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:和物理端口無關 - 轉發指定的端口和隊列
命令:POX> msg.actions.append(of.ofp_action_enqueue(port=x,queue_id=y)) - 改變目的mac爲指定mac
命令:POX> msg.actions.append(of.ofp_action_dl_addr.set_dst(“”))
說明:mac地址形式爲ff:ff:ff:ff:ff:ff - 改變源mac爲指定mac
命令:POX> msg.actions.append(of.ofp_action_dl_addr.set_src(“”)) - 設定tos值
命令:POX> msg.actions.append(of.ofp_action_nw_tos(nw_tos=x)) - 設定vlan值
命令:POX> msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=x)) - 設定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)
- 1
- 2
- 3
- 4
- 5
說明:[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)
- 1
- 2
- 3
- 4
- 5
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)
- 1
- 2
- 3
- 4
- 5
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)
- 1
- 2
- 3
- 4
- 5
- 6
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)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
6. 刪除流表項
命令:
POX>msg=of.ofp_flow_mod(command=3)
POX>core.openflow.connections[13136560386L].send(msg)
- 1
- 2
說明:此命令是刪除所有的流表項
7. 刪除特定的流表項
命令:
POX>msg=of.ofp_flow_mod(command=4)
POX>msg.wildcards= 4194302
POX>msg.priority=5
POX>core.openflow.connections[13136560386L].send(msg)
- 1
- 2
- 3
- 4
說明:刪除特定的流表項就是將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)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
說明:修改流表項,即修改這條流表的動作。
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中進行分析