01.06 SDN(軟件定義網絡)初體驗----Mininet

弈心:從事計算機網絡工作十年(新加坡7年,沙特3年),2013年考取CCIE,在新加坡先後任職於AT&T,新加坡交通部,蘋果,Equinix,蘇格蘭皇家銀行等大型企業、銀行和政府部門。 目前供職於“世界第一土豪大學“沙特阿卜杜拉國王科技大學(KAUST),擔任Senior Network Engineer,為KAUST校史上第一位也是唯一一位華人IT部門高級職員。2019年6月在知乎發佈了華語圈第一本專門為編程零基礎的網絡工程師量身打造的Python教程《網絡工程師的Python之路》。

還記得我2013年考下CCIE RS後,在國外一個技術論壇偶然讀到了一篇介紹SDN的文章,作者把SDN寫得神乎其神,中心思想就是:完全靠網絡工程師手動配置和手動排錯,效率低下的傳統網絡遲早有”壽終正寢“的一天,而取而代之的就是能夠帶來”革命性改變“的SDN。的確,IT技術日新月異,當年CCIE RS v1 v2考試大綱裡的那些古董級別的Apple Talk, FDDI, Token Ring, X.25, ATM等等,現在還有幾個人有興趣去花時間理解它們?由此自己開始關注Software Defined Network (軟件定義網絡)。

本篇文章是我2014年自學Mininet時的一些心得和筆記,溫故知新,如今回味起來依然能學到不少東西:


1. SDN和傳統網絡最大的區別在於:SDN具有靈活的軟件編程能力,讓網絡的自動化管理和控制能力獲得空前的提升,能夠有效地解決當前網絡系統所面臨的資源規模擴展受限、組網靈活性差的問題。

2. 傳統網絡設備的Control Plane和Data Plane在SDN中被完全拆開,互不干涉。

3. SDN的轉發機制不再是Destination-based,而是Flow-based。

4. SDN的Control logic由SDN Controller(類似於現在的IOS之類的命令行操作系統,但運行方式不同)掌控。

5. Openflow, Opendaylight, OpenContrail等都是SDN的一部分。

6. 。。。。。。。。。。。


理論太多,不想贅述,因為學再多理論也比不過親自動手嘗試,還好最近找到了一款叫做Mininet的東西,這對所有SDN的初學者是一個福音。作為一個輕量級網絡研究平臺,Mininet已經出現很多年了,有志於研究SDN(openflow)的都知道它的來歷和用途,關於Mininet的背景就不多做介紹了。下面是自己使用Mininet時做的一些筆記:


安裝Mininet的步驟:

1. 下載Mininet(版本2.1.0)的鏡像文件 (https://github.com/mininet/mininet/wiki/Mininet-VM-Images),這是一個基於Ubuntu的虛擬機文件。

2. 用VMware或者Virtual Box打開


Mininet使用筆記:

1. 學習Mininet之前,最好將Mininet官方的Walkthrough過一遍(http://mininet.org/walkthrough/)

2. sudo mn命令將創建一個最簡單的拓撲,包括一個SDN Controller (c0),一個交換機 (s1),兩臺主機 (h1和h2)

3. Mininet幾個比較重要的選項和參數總結如下:


--topo= 這個是Mininet創建的虛擬網絡的拓撲,有4種類型:

minimal – 即上面提到的sudo mn命令,包括一個SDN Controller (c0),一個交換機 (s1),兩臺主機 (h1和h2)

single,X – 一個交換機,下面直連X個主機(自已定義)

linear,X – 創建X個環狀鏈路的交換機,每個交換機下面直連一個主機

tree,X – 樹狀型拓撲,有X個fanout

--switch= 創建不同類型的交換機

ovsk – Mininet默認自帶的Open vSwitch,已經預裝在VM裡面

user – 比ovsk慢很多,不推薦使用

--controller= 即SDN Controller,三個參數

ovsc – Mininet默認自帶的OVS Controller,已經預裝在VM裡面

nox – 顧名思義,NOX controller

remote – 不創建Controller,嘗試連接外部Controller

--mac 創建自定義的MAC地址


來做個實驗具體說明,首先創建一個交換機,3個主機,無Controller的拓撲。

<code>命令: Sudo mn –topo=single,3 –mac –controller=remote/<code>

在SDN中,交換機是沒有Control Plane的,也就是說它僅是一個純粹的轉發設備, 並且這種”無腦型“的Openflow交換機只有在收到SDN controller的指示後,才能做出轉發決定。遇到未知traffic時,Openflow交換機只會做一件事:就是把它們轉發給SDN controller,自己什麼也不管。這大大降低了習慣在傳統網絡的交換機中做各種2層排錯的網工們的工作量。

既然Controller是SDN網絡的大腦,那麼創建一個沒有controller的SDN拓撲還能玩嗎?當然可以,這裡要用到dptcl這個工具,dptcl的作用是可以跳過controller,直接通過TCP 6634這個端口來控制和查看openflow交換機的flow table(記住SDN網絡的轉發機制是flow-based,不是destination-based),不過dptcl和SDN controller是完全不同的兩種東西,不能劃等號,這點切記。


DPTCL的命令格式:

<code>dptcl [show/dump-flows/add-flow] tcp:127.0.0.1:6634/<code>

最終實驗拓撲如下:

SDN(軟件定義網絡)初體驗----Mininet

具體配置和驗證命令:

1. 開啟Wireshark,讓它在後臺運行

<code>mininet@mininet-vm:~$ sudo wireshark/<code>


2. 創建一個交換機(ovsk類型),3個主機,無Controller的SDN網絡

<code>mininet@mininet-vm:~$ sudo mn --topo=single,3 --mac --switch=ovsk --controller=remote
*** Creating network
*** Adding controller
Unable to contact the remote controller at 127.0.0.1:6633 //無controller的拓撲
*** Adding hosts:
h1 h2 h3
*** Adding switches:
s1
*** Adding links:
(h1, s1) (h2, s1) (h3, s1)
*** Configuring hosts
h1 h2 h3
*** Starting controller
*** Starting 1 switches
s1*** Starting CLI:
mininet>/<code>


3. 查看網絡節點

<code>mininet> nodes
available nodes are:
c0 h1 h2 h3 s1
mininet>/<code>


4. 查看物理拓撲

<code>mininet> net
h1 h1-eth0:s1-eth1
h2 h2-eth0:s1-eth2
h3 h3-eth0:s1-eth3
s1 lo: s1-eth1:h1-eth0 s1-eth2:h2-eth0 s1-eth3:h3-eth0
c0
mininet>/<code>


5. 查看各個節點的信息

<code>mininet> dump
<host>
<host>
<host>
<ovsswitch>
<remotecontroller>
mininet>/<remotecontroller>/<ovsswitch>/<host>/<host>/<host>/<code>


驗證SDN交換機工作原理

Scenario #1 (SDN交換機flow table為空)

1. 首先在三個主機(h1,h2,h3)上開啟Xterm (Windows用戶需要安裝Xming,並在putty裡開啟X-forwarding)

<code>mininet> xterm h1 h2 h3/<code>

2. 用dpctl查看交換機當前的flow table信息 (由於還沒有手動添加flow entry,該flow table為空)

<code>mininet> dpctl dump-flows
*** s1 --------------------------------------------
NXST_FLOW reply (xid=0x4):/<code>


3. 在h1上ping h2,在h2上用tcpdump抓包,查看結果

SDN(軟件定義網絡)初體驗----Mininet


結論: Ping失敗,h2上沒有收到任何ICMP echo request packet.

原因: 拓撲裡沒有SDN controller,我們也沒有用dptcl給openflow交換機添加任何flow entry, 所以交換機不會做轉發決定,並直接丟棄h1到h2的ping包。


Scenario #2 (為SDN交換機添加flow entry)


1. 用dpctl給SDN交換機添加雙向的flow entry, 因為ping包除了echo request還有echo reply

<code>mininet@mininet-vm:~$  dpctl add-flow tcp:127.0.0.1:6634 in_port=1,actions=output:2

mininet@mininet-vm:~$ dpctl add-flow tcp:127.0.0.1:6634 in_port=2,actions=output:1/<code>


2. 查看SDN交換機的flow table,兩條flow entry添加成功。

<code>mininet> dpctl dump-flows
*** s1 --------------------------------------------
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=27,213s, table=0, n_packets=5, n_bytes=378, idle_timeout=60, idle_age=7, in_port=1 actions=output:2
cookie=0x0, duration=27,213s, table=0, n_packets=5, n_bytes=378, idle_timeout=60, idle_age=7, in_port=2 actions=output:1/<code>


3. 在h1上ping h2,在h2和h3上用tcpdump抓包,查看結果

SDN(軟件定義網絡)初體驗----Mininet

SDN(軟件定義網絡)初體驗----Mininet

SDN(軟件定義網絡)初體驗----Mininet

結論:h1成功ping到h2,並且h3沒收到任何ping包。


其他一些常用dpctl命令及功能 (拓撲同上)

1. 關閉或開啟openflow交換機的端口(等於對一個端口shutdown / no shutdown)

<code>dpctl mod-port [port num] up/down  /<code>

2. 關閉交換機的端口1(下接h1),

<code>mininet> dpctl mod-port 1 down   /<code>

關閉端口1後再來h1 ping h2,結果當然fail

<code>*** s1 ------------------------------------------------------------------------
mininet> h1 ping h2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
--- 10.0.0.2 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2000ms/<code>

3. 開啟交換機的端口1

<code>mininet> dpctl mod-port 1 up /<code>

ping成功

<code>*** s1 ------------------------------------------------------------------------
mininet> h1 ping -c 2 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=8.37 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=1.02 ms
--- 10.0.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 1.026/4.698/8.370/3.672 ms/<code>

4. 查看端口的統計信息,包括Tx,Rx counters, bytes以及Error counters等等

<code>mininet> dpctl dump-ports
*** s1 ------------------------------------------------------------------------
OFPST_PORT reply (xid=0x2): 4 ports
port 3: rx pkts=7, bytes=558, drop=0, errs=0, frame=0, over=0, crc=0
tx pkts=0, bytes=0, drop=0, errs=0, coll=0
port 1: rx pkts=32, bytes=2076, drop=0, errs=0, frame=0, over=0, crc=0
tx pkts=14, bytes=1092, drop=0, errs=0, coll=0
port 2: rx pkts=33, bytes=2154, drop=0, errs=0, frame=0, over=0, crc=0
tx pkts=26, bytes=1596, drop=0, errs=0, coll=0
port LOCAL: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
tx pkts=0, bytes=0, drop=0, errs=0, coll=0/<code>


5. 查看端口的一層和二層信息

<code>mininet> dpctl show
*** s1 ------------------------------------------------------------------------
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000000000000001
n_tables:254, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions:
OUTPUT SET_VLAN_VID SET_VLAN_PCP STRIP_VLAN SET_DL_SRC SET_DL_DST
SET_NW_SRC SET_NW_DST SET_NW_TOS SET_TP_SRC SET_TP_DST ENQUEUE
1(s1-eth1): addr:66:9a:a3:e0:64:8f
config: 0
state: 0
current: 10GB-FD COPPER
speed: 10000 Mbps now, 0 Mbps max
2(s1-eth2): addr:26:bb:36:e0:99:4e
config: 0
state: 0
current: 10GB-FD COPPER
speed: 10000 Mbps now, 0 Mbps max
3(s1-eth3): addr:76:c9:ca:0e:92:4b
config: 0
state: 0
current: 10GB-FD COPPER
speed: 10000 Mbps now, 0 Mbps max
LOCAL(s1): addr:fe:3f:bf:f6:26:42
config: 0
state: 0
speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0/<code>


開篇時曾提到:默認情況下,SDN交換機的flow table為空,在沒有controller的情況下,可以使用dpctl來查詢和管理交換機的flow table,之前的實驗裡我用dpctl給交換機加了兩個flow,讓h1可以ping通h2。兩條命令如下:

<code>dpctl add-flow in_port=1,actions=output:2
dpctl add-flow in_port=2,actions=output:1/<code>

第一條命令的意思是:用dpctl對交換機添加flow,讓交換機從s1-eth1這個端口接收到的所有traffic都從s1-eth2這個端口發出去。

第二條命令的意思是:用dpctl對交換機添加flow,讓交換機從s1-eth2這個端口接收到的所有traffic都從s1-eth1這個端口發出去。(這裡重點強調“所有traffic",原因後面解釋)

添加這兩條flow後,h1能夠ping通h2.

<code>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=3.80 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.915 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=1.50 ms
^C
--- 10.0.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2005ms
rtt min/avg/max/mdev = 0.915/2.073/3.805/1.248 ms/<code>


除了這種匹配所有traffic的方法外,dpctl還允許自定義更詳細的traffic類型,比如ARP,IPv4, IPv6, MPLS等等,用dpctl的命令來匹配這些traffic不難,關鍵是要弄懂交換機是怎樣識別它收到的traffci是屬於哪種類型的,從而參照自己的flowtable然後對該traffic進行轉發。要弄懂這點,就必須瞭解EtherType(以太網類型字段)這個東西,首先來回顧一下二層幀(frame)的結構:

SDN(軟件定義網絡)初體驗----Mininet

如圖,我已經把EtherType標記出來了,它就在Source MAC字段的後面。

根據IEEE 802.3定義,EtherType字段長度為2Byte,它的作用是用來指明應用於Payload這個字段裡的是什麼協議,它的起始值是0x0800,指代的是IPv4這個協議,常見的EtherType數值和所對應的協議如下:

0x0800 = IPv4

0x0806 = ARP

0x86DD = IPv6

0x8847 = MPLS (unicast)

0x8848 = MPLS (multicast)

在dpctl裡面,我們使用dl_type來指代EtherType,下面來做個試驗,具體說明一下怎麼在dpctl裡面根據EtherType來自定義traffic的協議類型。

首先把之前添加的兩條匹配所有traffic的flow拿掉,這裡用dpctl del-flows這個命令,刪除後用dpctl dump-flows驗證,確保交換機flow table為空。

<code>mininet> dpctl del-flows
*** s1 ------------------------------------------------------------------------
mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):/<code>


然後用dpctl給交換機添加兩條traffic類型為IPv4的flow,命令如下:

<code>dpctl add-flow dl_type=0x0800,nw_dst=10.0.0.2,actions=output:2
dpctl add-flow dl_type=0x0800,nw_dst=10.0.0.1,actions=output:1/<code>

第一條命令的意思是:用dpctl對交換機添加flow,讓交換機把所有EtherType為0x0800(IPv4)並且destiation IP為10.0.0.2的traffic從s1-eth2這個端口發出去。

第二條命令的意思是:用dpctl對交換機添加flow,讓交換機把所有EtherType為0x0800(IPv4)並且destiation IP為10.0.0.1的traffic從s1-eth1這個端口發出去。

添加完後驗證一下交換機的flow table:

<code>mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=477.255s, table=0, n_packets=0, n_bytes=0, idle_age=477, ip,nw_dst=10.0.0.2 actions=output:2
cookie=0x0, duration=469.45s, table=0, n_packets=0, n_bytes=0, idle_age=469, ip,nw_dst=10.0.0.1 actions=output:1/<code>

然後再次嘗試h1是否能ping通h2

<code>mininet> h1 ping -c 3 h2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
--- 10.0.0.2 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2013ms/<code>

結論:Ping失敗!


原因:眾所周知,處在同一網段下的host,它們之間的交流是L2 forwarding,是要靠ARP來解析MAC地址的,之前我們只匹配了0x0800 (IPv4) 這個協議,並沒有匹配到0x0806(ARP),這樣當交換機收到h1的ARP包後,因為沒有controller,flow table裡面也沒有相應的flow告訴它如何轉發這個ARP包,交換機只能將它丟棄,從而導致h1 ping h2失敗。


添加ARP的dpctl命令如下:

<code>dpctl add-flow dl_type=0x0806,actions=NORMAL/<code>

這條命令的意思是:用dpctl對交換機添加flow,讓交換機以NORMAL形式(即廣播)將所有ARP包從各個端口廣播出去。


老規矩,添加完flow後,馬上驗證flow table

mininet> dpctl dump-flows

<code>*** s1 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=1288.291s, table=0, n_packets=22, n_bytes=2156, idle_age=703, ip,nw_dst=10.0.0.2 actions=output:2
cookie=0x0, duration=1280.486s, table=0, n_packets=8, n_bytes=784, idle_age=727, ip,nw_dst=10.0.0.1 actions=output:1
cookie=0x0, duration=8.772s, table=0, n_packets=0, n_bytes=0, idle_age=8, arp actions=NORMAL/<code>

再次嘗試h1是否能ping通h2

<code>mininet> h1 ping -c 3 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=6.34 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.991 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=1.08 ms
--- 10.0.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2006ms
rtt min/avg/max/mdev = 0.991/2.807/6.345/2.502 ms/<code>

結論:IP和ARP的flow都添加完畢後,h1 ping h2成功!


用WIRESHARK抓包,靠實戰理解openflow交換機和Controller之間的工作原理。


1. 首先創建一個最簡單的拓撲,1個Controller, 1個交換機,2臺HOST

<code>mininet@mininet-vm:~$ sudo mn
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2
*** Adding switches:
s1
*** Adding links:
(h1, s1) (h2, s1)
*** Configuring hosts
h1 h2
*** Starting controller
*** Starting 1 switches
s1
*** Starting CLI:
mininet>/<code>

2. 重開一個putty窗口(記住enable X forwarding),ssh進入VM後開啟wireshark

<code>mininet@mininet-vm:~$ sudo wireshark &/<code>

3. Wireshark啟動後,Interface List選lo0 (127.0.0.1),然後點Start,如下圖

SDN(軟件定義網絡)初體驗----Mininet


4.回到第一個putty窗口 (mininet>)下,用pingall命令來讓h1(10.0.0.1)和h2(10.0.0.2)互相ping對方,因為這次的實驗拓撲已經有了一臺controller,所以無需再用dpctl來手動對交換機添加flow,h1已經可以直接ping通h2了。

<code>mininet> pingall
*** Ping: testing ping reachability
h1 -> h2
h2 -> h1
*** Results: 0% dropped (2/2 received)/<code>


5. 回到Wireshark,這個時候應該capture到了很多TCP包,先不管它們,在Filter裡輸入of進行過濾,目的是為了抓到OFP (即Openflow Protocol)的包,如下圖:

SDN(軟件定義網絡)初體驗----Mininet

6. 點開第一個包,即Echo Request (SM)(8B)這個包,如下圖:

SDN(軟件定義網絡)初體驗----Mininet


從這個包裡可以看出的信息是:

a.這個Echo Request是openflow交換機(127.0.0.1:60497) 發給Controller (127.0.0.1:6633)的,之間已經提到過,dpctl是靠TCP 6634這個端口來控制交換機的,而Controller則是用TCP 6633這個端口來控制交換機,而為了監控交換機和Controller之間的connectivity,交換機會不間斷地向Controller發出Echo Request (注意這個不是ICMP的Echo Request),Controller收到Echo Request包後會向交換機返回一個Echo Reply包。

b. 點開最下面的Openflow Protocol(就不截圖了),可以看到OFP的一些基本信息,比如version為0x01,Type為Echo Request (SM) (2),Length為8等等等。


7. 看完交換機和Echo Request和Echo Reply包後,接下來來看剛才用pingall命令,讓h1 (10.0.0.1)和(10.0.0.2)互ping後出現的包。

SDN(軟件定義網絡)初體驗----Mininet

如上圖,在我抓的包裡面:

a. 把序號為436,437,439,440的包分為一組,這一組是10.0.0.1 ping 10.0.0.2的Ping Echo Request以及Ping Echo Reply的包。

b. 把序號為441,442,443,444的包分為一組,這一組是10.0.0.2 ping 10.0.0.1的Ping Echo Request以及Ping Echo Reply的包。


8. 點開436這個包,如下圖:

SDN(軟件定義網絡)初體驗----Mininet


這裡你會感到奇怪,為什麼剛才在第7步裡看到的該包,Source為10.0.0.1,Destination為10.0.0.2,為什麼點開該包後,裡面的內容卻是Source127.0.0.1:60497(交換機), Destination 127.0.0.1:6633(Controller)?要回答這個問題,就需要回到第7步去看436這個包的Protocol,你會發現它已不再是我們在傳統網絡裡理解的那個單獨的ICMP包了,在SDN裡,它已經變成了OFP+ICMP包。對這個OFP+ICMP包應該這樣理解:當10.0.0.1 ping 10.0.0.2的時候,“無腦”的交換機(127.0.0.1:60497) 因為不知道怎麼轉發這個ICMP包,它唯一能做的就是用OFP包將這個ICMP包封裝,將它轉發給Controller (127.0.0.1:6633) 做決定,而這個由交換機重新封裝後的ICMP包就叫做OFP+ICMP包。


9. 點開437這個包, 如下圖:

SDN(軟件定義網絡)初體驗----Mininet


這個包是接436這個包的,它是由Controller收到交換機發給它的OFP+ICMP後,Controller再返回給一個OFP包給交換機,所以它的Source127.0.0.1:6634,Destination127.0.0.1:60497。這裡需要重點關注的是該包OpenFlow Protocol裡面的內容。如圖,依次點開OpenFlow Protocol>Output Actions(s)>Action,這裡可以看到Output port:2 ,顧名思義,它的意思就是說:Controller現在告訴交換機,“關於這個10.0.0.1 ping 10.0.0.2的ICMP包,你把它從s1-eth2這個端口發出去”,這樣h1 (10.0.0.1)的Ping echo request包就能到達h2 (10.0.0.2)了,因為h2就是直連在s1-eth2這個端口下的。


10. 後面的438-444就無需多解釋了,有網絡基礎的都懂,它們和436還有437這兩個包其實都是一個原理,只是source和destination不同。


要把SDN學精,學會寫代碼是必不可少的。整個Mininet的架構基本是用Python 2.0寫出來的(注意不是3.0,前後兩者差別很大),而自己的Python水平大概還停留在入門階段。任重道遠,下面是自己總結的Mininet中常見的一些Class, Methods, Functions還有Variables:


Topo: 用來創建拓撲,Mininet API中最基本的Class

addSwitch(): 在拓撲中創建一個switch,並返回switch name。

addHost(): 在拓撲中創建一個host,並返回host name。

addLink(): 在拓撲中創建一個雙向的link,並返回link key,默認情況下link都是雙向的(bidirectional)。

Mininet: 用來創建和管理一個拓撲的Main Class。

start(): 啟動網絡

pingAll():所有host相互ping對方,用來測試網絡連接性

stop(): 關閉網絡

net.hosts: 表示拓撲內所有的host

dumpNodeConnections(): 顯示指定節點(Node)的connection

setLogLevel( 'info' | 'debug' | 'output' ): 設定Mininet默認的ouput level,一般用info。


舉個簡單的例子,用python寫一個單交換機,下接N個host的拓撲的代碼:

<code>#!/usr/bin/python
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.util import dumpNodeConnections
from mininet.log import setLogLevel/<code>


# 用from import導入python的模塊

<code>class SingleSwitchTopo(Topo):
def __init__(self, n=2, **opts)
Topo.__init__(self, **opts) # 初始化拓撲以及默認的option
switch = self.addSwitch('s1') # 添加一個名為s1的交換機
for h in range(n):
host = self.addHost('h%s' % (h + 1)) #添加主機
self.addLink(host, switch) #添加雙向連接
def simpleTest():
topo = SingleSwitchTopo(n=4)
net = Mininet(topo) #用Main Class來創建拓撲
net.start() #啟動網絡
print "Dumping host connections"
dumpNodeConnections(net.hosts) #顯示拓撲內所有節點(host)的connection信息
print "Testing network connectivity"
net.pingAll() #所有host相互ping對方,用來測試網絡連接性

net.stop()
if __name__ == '__main__':
setLogLevel('info') # 設置 Mininet 默認輸出級別為info
simpleTest()/<code>


驗證:

<code># python test-single.py
*** Creating network
*** Adding controller
*** Adding hosts:h1 h2 h3 h4
*** Adding switches:
s1
*** Adding links:
(h1, s1) (h2, s1) (h3, s1) (h4, s1)
*** Configuring hosts
h1 h2 h3 h4
*** Starting controller
*** Starting 1 switches
s1
Dumping host connections
h1 h1-eth0:s1-eth1
h2 h2-eth0:s1-eth2
h3 h3-eth0:s1-eth3
h4 h4-eth0:s1-eth4
Testing network connectivity
*** Ping: testing ping reachability
h1 -> h2 h3 h4
h2 -> h1 h3 h4
h3 -> h1 h2 h4
h4 -> h1 h2 h3
*** Results: 0% dropped (12/12 received)/<code>


分享到:


相關文章: