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
  • 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控制器下發流表項了,這裏先介紹一下下發流表項中各個匹配項和動作的命令。

匹配字段

  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)
  • 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中進行分析

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章