• 沒有找到結果。

第一節、硬體和系統環境

為了在真的環境上面實作,查閱了相關的研究,去找尋有公開原始碼的 驅動程式(Open Source Driver),Atheros 有公開晶片 Linux 驅動程式的原 始碼,使用 Atheros 晶片的網卡都可以使用這個

驅動程式來驅動。所以我們選擇了幾台筆記型電 腦,每台上面均裝有 D-link DWL-AG650 的網路 卡,它是使用 Atheros 的晶片,這讓我們可以修

改公開的原始碼來把我們的管理協定實作在上面。 圖 4-1、D-link 網路卡

圖 4-2、實作環境

我們利用這些筆記型電腦當成是一個個的存取點,讓它們形成隨建即連 網路(Ad-Hoc Network),並固定其位置模擬無線網狀網路(Mesh Network),

無線網狀網路和隨建即連網路有很大的共通性,差別在於無線網狀網路有 閘 道 可 以 連 上 網 際 網 路 (Internet) , 且 無 線 網 狀 網 路 沒 有 行 動 性 (Mobility) , 我 們 讓 這 些 筆 記 型 電 腦 模 擬 一 個 無 線 網 狀 網 路 的 雛 形 (Prototype)來當成我們要的環境。

第二節、程式架構

我 們 的 管 理 協 定 是 屬 於 OSI 七 層 網 路 模 型 的 鏈 結 層 (Data Link Layer),而在 Linux 的網路架構下是簡易的分成四層,我們所要修改的是 最底層鏈結層。

下圖 4-3 為 Linux 使用者空間(User Space)、核心空間(Kernel Space) 和網路驅動程式(Network Driver)之間的關係,上層使用者空間的行程 (User Space Processes)透過系統呼叫(System Call)跟核心來通溝,而核 心內行程的溝通都是使用函式呼叫(Function Call)的方式,在 Linux 的網 路分層架構下,每一層之間都有佇列(Queue)把出境封包暫存起來,等到有 時間可以處理時,才使用函式呼叫去處理送出的動作,而外來的封包則是 使用中斷(Interrupt)的方式來通知驅動程式,驅動程式需處理鏈結層的一 些必要動作,例如拿掉鍵結層的標頭(Header)、過濾封包…,處理完後再 使用軟體中斷(Software Interrupt)通知核心處理更上層的工作。

圖 4-3、 Linux User Space、Kernel 和 Network Driver 之間的關係

process

(cause by interface layer)

hardware interrupt

(cause by network device) user space

(cause by interface layer)

hardware interrupt

(cause by network device) user space

kernel

driver

圖 4-4 是我們使用的 Madwifi 驅動程式和 Linux 核心之間的架構,驅動 程式利用模組(Module)方式掛載(Mount)進入核心時,會跟核心註冊一些函 式。當核心需要送出資料封包時,會先將資料排入「出境佇列」(Outgoing Queue),然後呼叫網路介面的 hard_start_transmit()作業方法。在 Madwifi 驅動程式裡是註冊 ath_start()這個函式作為 hard_start_transmit()的函 式指標。利用 request_irg()函式註冊 Madwifi 驅動程式的 ath_intr()為 中斷函式,而 netif_rx()是核心給驅動程式呼叫用來通知上層處理接收到 的封包。

圖 4-4、Madwifi Driver 和 Linux Kernel 之間的架構

下圖 4-5 為對 Madwifi 程式我們所要修改新增的部分。當有封包要送出

Link Layer (802.3 Ethernet) ./madwifi/ath/

./madwifi/net80211/

詢排程資料表,如果進入的是廣播時槽(Broadcast Slot),則切換至共同

1. check channel usage and necessary change receiving channel 2. check traffic pattern to

modify schedule 3. every K times, reset

priority of all queues check schedule

1. check channel usage and necessary change receiving channel 2. check traffic pattern to

modify schedule 3. every K times, reset

priority of all queues check schedule

做置換(context switch)的動作,所以不用能 while 迴圈或 sleep 去實作,

會耗盡 CPU 的時間,其它的工作都停滯不動,其它的行程也都受到牽涉。

我們研究 Linux 核心可用的函式庫及語法,利用 timer_list 這個資料結構 來實作,向核心註冊中斷時間和中斷服務函式,時間一到,核心會自動去 呼叫註冊的中斷服務函式,就可以達成不吃 CPU 時間而且 5 秒中斷一次。

我們最後成功的在驅動程式裡加入計時器中斷,完成分時的概念。

接下在我們在 Linux 核心和驅動程式間之間加新一層暫存區,把上層的 封包用佇列(queue)暫存,等到適當的傳送時槽(sending slot)再傳送出 去,佇列怎麼做?經過一番的努力,發現核心經手的每一個封包,都是包 裝成一個 struct sk_buff 結構,要把封包用佇列暫存,需要加上一個 sk_buff_head 把上層下來的封包串起來,便可行成一個佇列。分析封包要 傳送的位置,便可利用多個 sk_buff_head 來實作成頻道佇列(per channel queue)或鄰居佇列(per neighbor queue), 我們是以鄰居佇列為實作佇列 的方式。

困擾著我們最久的是切換頻道的問題,我們試了諸多的切換頻道的方 法,第一種,直接下 iwconfig 系統呼叫(System Call)去切換頻道,是屬 於使用者空間的方法,第二種,使用 Madwifi 驅動程式被 iwconfig 下命令 著第一個呼叫的函式,並傳入相同的參鷜,第三種,在 Madwifi 驅動程式 與 IEEE 802.11 無關的程式碼裡選一個最直接切換 channel 的函式去切換,

發現一件事,切換頻道均沒有問題,但是同時兩個存取點同時換到同一個 頻道時,有時連得起來,有時連不起來,有時連的很快,有時連的很慢,

這對我們的管理協定有非常嚴重的效能折扣。第四種,我們直接去呼叫燒 在網路卡的韌體函式去切換頻道,發現沒有效果,根本不能切換頻道。正 當一切均失敗的時候,我去查閱了 IEEE 802.11 的書藉,找到 802.11 在

Ad-Hoc 模式下為了要同步的關係,需要產生信號彈(Beacon),我們發現,

當一起切換到相同的頻道,當信號彈 BSSID 有合併的時候,網路才有辦法 連線,所以我們去追蹤查詢,換頻道的時候會重新產生 BSSID,就是即使隨 建即連(Ad-Hoc)網路的名稱相同,BSSID 也會不同,推測因為 BSSID 的不同,

所以封包在過濾的時候被過濾掉了,所以連線連不起來,當 BSSID 合併才 連得起來,我們查到網路卡支援一種 Ad-Hoc Demo 的模式可以把 BSSID 一 直維持在 00:00:00:00:00:00,所有封包都會收進來,如此才成功的解決問 題。

第四節、測試程式

我們的程式碼架構在驅動程式裡,為了監控驅動程式的狀態以及測試效 能,我們在使用者空間透過共享記憶體的方式去監控驅動程式的狀態,並 在上面使用 UDP 的封包進行頻寬的測試,測試畫面如下圖。

圖 4-6、測試監控程式

看圖 4-6,這是 192.168.0.2 筆記型電腦的測試監控程式的截取畫面,

此存取會對其它鄰居紀錄一些資訊,驅動程式儲的資訊放在畫面中 Network Messages 的上方,例如排程、MAC 位址、比重(Weight)、對方對我的比重 (OtherW)、目前佇列的長度(QueueLen)以及優先權(Priority),為了實作 上的方便,比重有就是 1,沒有就是 0,因為這個不是實作上的重點,所以 用最簡單的方式。畫面中 R=ch1 表示存取點的接收頻道是頻道 1,一個個藍 色小方框裡標著 B、R、F、S 是鄰居和自己存取點的排程,會有紅色的長條 顯示目前在那一個時槽,而長條中標示的 ch6 表示自已目前這個時槽是用 頻道 6,當自己在傳送時槽時而鄰居又剛好在接收時槽時,最右方會 有”Match”的紅色標示,這個傳送時槽目前傳輸的對象會在最右邊標 示”send to ”的字眼,以上是驅動程式的資訊,用共享記憶體的方式讀 取出來顯示在畫面上。

在 Network Messages 的下方在網路層的監控和測試工具,在 Network Messages 可以看目前產生的封包序號或接收到的封包序號,而下方藍色大 方框可以看目前網路層有接收到從那來的流量,Cur Speed 是目前這一秒鐘 的傳輸速度,而 Avg Speed 是過去一段時間傳輸速度的平均,因為我們有 分時槽的關係,用 Cur Speed 來看傳輸速度是不準確的,有時是 700 KBps 而有時是 0 KBps,所以要加 Avg Speed 來測試頻寬。最下方的命令列可以 用來下命令測試頻寬,例如”send UPD 192.168.0.4”可以起始一條新的 流量(最佳傳輸的方法)給 192.168.0.4 這個存取點。

第五節、測試結果

我們利用測試監控程式來測試所設計的協定,下圖 4-7 為我們測試的第

一個網路環境,四個存取點都在互相的干擾範圍內,A 使用最佳傳送的方式

達成這個效果,此時 A 使用最佳傳送的方法傳送 UDP 封包至 D,會經過 B 和 C 最後才到達 D。下圖 4-9 為四個存取點在此環境下排程變化的最終結 果,可以看到 A 有三個時槽使用頻道 11 傳送到 B,同一時刻,C 也利用這 些時槽使用頻道 1 傳送到 D,此時便有使用到多重頻道帶來的好處,增進 鏈狀傳輸的效能。由表 4-2 可看出在我們的多重頻道協定是單一頻道效能的 122%。

B R F S S R S

B R F S S R S

192.168.0.2

B

B R R F R R R

B R R F R R R

192.168.0.4

D

B S S R R S F

B S S R R S F

192.168.0.3

C

B S S R F S R

B S S R F S R

192.168.0.1

A Ch1

Ch11

Ch6

Ch1

相關文件