基于Linux內核模式的PPPoE優(yōu)化與實(shí)現
2.1 PPPoE會(huì )話(huà)初始化
PPPoE的初始化包括整個(gè)Discovery階段以及Session階段的IPCP和LCP等其他鏈路協(xié)商過(guò)程,所有的工作都在用戶(hù)空間完成,圖3描述了整個(gè)初始化的流程。本文引用地址:http://dyxdggzs.com/article/157118.htm
首先通過(guò)Raw socket發(fā)送PADS、PADR、PADO、PADI,當這個(gè)請求完成后,得到遠端服務(wù)器的MAC地址以及雙方建立起來(lái)的Session_ID。由于后面的內核封包需要用到這些數據,所以需要將這些數據切換到內核空間去。由于數據量較小,則采用proc文件系統完成內核空間與用戶(hù)空間的數據切換。
對于proc中的數據,設計以下數據格式:接口名詞SMAC DMAC SESSION_ID RX TX。
其中“接口名詞”為接口名稱(chēng),設計中不再用虛擬PPP接口傳輸數據,而是將數據遷移到物理網(wǎng)卡上,這樣在某種程度上減輕了路由模塊的負擔,但需要去proc文件讀取接口名稱(chēng)以此判斷該物理接口是否啟用PPPoE撥號。“SMAC”和“DMAC”參數為雙方的MAC地址,在內核封包中用到。“SESSION_ID”雙方建立起來(lái)的Session_ID,也用于內核封包。而“RX”和“TX”是用于記錄最后一次解包與封包的時(shí)間點(diǎn),該數據用于按需撥號。
在建立好PPP連接后就進(jìn)行IPCP協(xié)商,這個(gè)過(guò)程將為協(xié)商到雙方的IP的地址,并將這個(gè)IP地址配置到物理口上,而這些數據將通過(guò)PPP口通信。除此之外,還需要為PPPoE鏈路配置相應的路由、更新ARP列表以及獲取相應的DNS服務(wù)器地址。
2.2 PPPoE數據接收
PPPoE數據接收主要是對數據進(jìn)行解包,其全部動(dòng)作在內核空間完成。當一個(gè)PPPoE數據包從網(wǎng)卡驅動(dòng)里面讀出來(lái)時(shí),是一個(gè)完整的PPPoE包。而上層模塊無(wú)法識別這樣的包,所以需要將中間的那些PPP協(xié)議數據從包中剝離出來(lái),使其變成一個(gè)普通的IP數據包,圖4描述了PPPoE接收數據的整體流程。
當從網(wǎng)卡驅動(dòng)上讀取數據時(shí),也就是獲取數據的SKB,首先需要判斷這個(gè)SKB是否有效,然后再判斷該網(wǎng)卡是否起動(dòng)了PPPoE服務(wù),很顯然這里需要讀取proc的接口信息。如果已經(jīng)PPPoE撥號服務(wù),還需要判斷該包是不是一個(gè)LCP或者IPCP等其他協(xié)商數據,也就是判斷協(xié)議域的數據是不是0X0021。因為如果是協(xié)商數據,則不需要解包,而直接將其轉發(fā)到PPP虛擬接口上。對于具體的解包過(guò)程將進(jìn)行代碼分析。解完包以后該數據包就屬于普通的IP包,后續流程與普通的IP包處理相同。
2.3 PPPoE數據發(fā)送
PPPoE數據發(fā)送流程基本上是數據接收的逆過(guò)程,圖5描述整個(gè)數據發(fā)送過(guò)程。首先從用戶(hù)空間或者FORWARDING模塊獲取一個(gè)數據包,這個(gè)數據包屬于正常的IP包。很顯然這個(gè)包是無(wú)法發(fā)送到PPP鏈路上的,因為PPPoE服務(wù)器并不識別這樣的數據包。所以需要利用proc文件中的Session_ID、遠端MAC和本地MAC數據來(lái)封裝IP包,使其成為一個(gè)標準的PPP包。
評論