成人免费久久精品国产片久久影院-成人免费看吃奶视频网站-成人免费看黄页网址大全-成人免费毛片一区二区三区-成人免费视频大全

您現(xiàn)在的位置:首頁 > 服務(wù)支持 > 資訊動態(tài)資訊動態(tài)

Linux 網(wǎng)絡(luò)設(shè)備驅(qū)動開發(fā)(一) —— linux內(nèi)核網(wǎng)絡(luò)分層結(jié)構(gòu)

    Linux內(nèi)核對網(wǎng)絡(luò)驅(qū)動程序使用統(tǒng)一的接口,并且對于網(wǎng)絡(luò)設(shè)備采用面向?qū)ο蟮乃枷朐O(shè)計。

    Linux內(nèi)核采用分層結(jié)構(gòu)處理網(wǎng)絡(luò)數(shù)據(jù)包。分層結(jié)構(gòu)與網(wǎng)絡(luò)協(xié)議的結(jié)構(gòu)匹配,既能簡化數(shù)據(jù)包處理流程,又便于擴展和維護。

 

    一、內(nèi)核網(wǎng)絡(luò)結(jié)構(gòu)

     在Linux內(nèi)核中,對網(wǎng)絡(luò)部分按照網(wǎng)絡(luò)協(xié)議層、網(wǎng)絡(luò)設(shè)備層、設(shè)備驅(qū)動功能層和網(wǎng)絡(luò)媒介層的分層體系設(shè)計。

    網(wǎng)絡(luò)驅(qū)動功能層主要通過網(wǎng)絡(luò)驅(qū)動程序?qū)崿F(xiàn)。

     在Linux內(nèi)核,所有的網(wǎng)絡(luò)設(shè)備都被抽象為一個接口處理,該接口提供了所有的網(wǎng)絡(luò)操作。

    net_device結(jié)構(gòu)表示網(wǎng)絡(luò)設(shè)備在內(nèi)核中的情況,也就是網(wǎng)絡(luò)設(shè)備接口。網(wǎng)絡(luò)設(shè)備接口既包括軟件虛擬的網(wǎng)絡(luò)設(shè)備接口,如環(huán)路設(shè)備,也包括了網(wǎng)絡(luò)硬件設(shè)備,如以太網(wǎng)卡。

    Linux內(nèi)核有一個dev_base的全局指針,指向一個設(shè)備鏈表,包括了系統(tǒng)內(nèi)的所有網(wǎng)絡(luò)設(shè)備。該設(shè)備鏈表每個節(jié)點是一個網(wǎng)絡(luò)設(shè)備。

    在net_device結(jié)構(gòu)中提供了許多供系統(tǒng)訪問和協(xié)議層調(diào)用的設(shè)備方法,包括初始化、打開關(guān)閉設(shè)備、數(shù)據(jù)包發(fā)送和接收等。

 

     二、與網(wǎng)絡(luò)有關(guān)的數(shù)據(jù)結(jié)構(gòu)

    內(nèi)核對網(wǎng)絡(luò)數(shù)據(jù)包的處理都是基于sk_buff結(jié)構(gòu)的,該結(jié)構(gòu)是內(nèi)核網(wǎng)絡(luò)部分最重要的數(shù)據(jù)結(jié)構(gòu)。

     網(wǎng)絡(luò)協(xié)議棧中各層協(xié)議都可以通過對該結(jié)構(gòu)的操作實現(xiàn)本層協(xié)議數(shù)據(jù)的添加或者刪除。使用sk_buff結(jié)構(gòu)避免了網(wǎng)絡(luò)協(xié)議棧各層來回復(fù)制數(shù)據(jù)導(dǎo)致的效率低下。

1.png

 

    sk_buff結(jié)構(gòu)可以分為兩個部分,一部分是存儲數(shù)據(jù)包緩存,在圖中表示為PackertData,另一部分是由一組用于內(nèi)核管理的指針組成。

       sk_buff管理的指針最主要的是下面4個:

  •     head指向數(shù)據(jù)緩沖(PackertData)的內(nèi)核首地址;

  •     data指向當前數(shù)據(jù)包的首地址;

  •     tail指向當前數(shù)據(jù)包的尾地址;

  •     end 指向數(shù)據(jù)緩沖的內(nèi)核尾地址。

     數(shù)據(jù)包的大小在內(nèi)核網(wǎng)絡(luò)協(xié)議棧的處理過程中會發(fā)生改變,因此data和tail指針也會不斷變化,而head和tail指針是不會發(fā)生改變的。

     對于一個TCP數(shù)據(jù)包為例,sk_buff還提供了幾個指針直接指向各層協(xié)議頭。mac指針指向數(shù)據(jù)的mac頭;nh指針指向網(wǎng)絡(luò)協(xié)議頭,一般是IP協(xié)議頭;h指向傳輸層協(xié)議頭,在本例中是TCP協(xié)議頭。

       對各層設(shè)置指針的是方便了協(xié)議棧對數(shù)據(jù)包的處理。

 

    三、net_device結(jié)構(gòu)

       Linux內(nèi)核中網(wǎng)絡(luò)設(shè)備最重要的數(shù)據(jù)結(jié)構(gòu)就是net_device結(jié)構(gòu)了,它是網(wǎng)絡(luò)驅(qū)動程序最重要的部分。

     net_device結(jié)構(gòu)保存在include/linux/netdevices.h頭文件,理解該結(jié)構(gòu)對理解網(wǎng)絡(luò)設(shè)備驅(qū)動有很大幫助。

   內(nèi)核中所有網(wǎng)絡(luò)設(shè)備的信息和操作都在net_device設(shè)備中,無論是注冊網(wǎng)絡(luò)設(shè)備,還是設(shè)置網(wǎng)絡(luò)設(shè)備參數(shù),都用到該結(jié)構(gòu)。

 

   下面是主要數(shù)據(jù)成員。

  • 設(shè)備名稱

  • 總線參數(shù)

  • 協(xié)議參數(shù)

  • 鏈接層變量

  • 接口標志

 

    四、數(shù)據(jù)包接收流程

   在Linux內(nèi)核中,一個網(wǎng)絡(luò)數(shù)據(jù)包從網(wǎng)卡接收到用戶空間需要經(jīng)過鏈路層、傳輸層和socket的處理,最終到達用戶空間。

2.png

     以DM9000網(wǎng)卡為例,當網(wǎng)卡收到數(shù)據(jù)包以后,調(diào)用中斷處理函數(shù) dm9000_interrupt(),該函數(shù)檢查中斷處理類型,如果是接收數(shù)據(jù)包中斷,則調(diào)用 dm9000_rx()函數(shù)接收數(shù)據(jù)包到內(nèi)核空間。

       dm9000_rx()函數(shù)收到數(shù)據(jù)包完成后,內(nèi)核會繼續(xù)調(diào)用 netif_rx()函數(shù),函數(shù)的作用是把網(wǎng)卡接收到數(shù)據(jù)提交給協(xié)議棧處理。

       協(xié)議棧使用 net_rx_action()函數(shù)處理接收數(shù)據(jù)包隊列,該函數(shù)處理數(shù)據(jù)包后如果是 IP數(shù)據(jù)包則提交給ip_recv()函數(shù)處理。ip_recv()函數(shù)主要是檢查一個數(shù)據(jù)包IP頭的合法性,檢查通過后交給 ip_local_deliver()和 ip_local_deliver_finish()函數(shù)處理,之所以分開處理是因為內(nèi)核中有防火墻相關(guān)的代碼需要動態(tài)加載到此處。

       IP頭處理完畢后,以UDP數(shù)據(jù)包為例將交由 udp_recv()函數(shù)處理,與 ip_recv()函數(shù)類億,該函數(shù)檢查 UDP頭的合法性,然后交給 udp_queue_recv()函數(shù)處理,最后提交給 sock_queue_recv()函數(shù)處理。

       數(shù)據(jù)包進入 socket部分的第一個函數(shù)是 skb_recv_datagram(),該函數(shù)從內(nèi)核的 socket隊列取出數(shù)據(jù)包,交給 socket部分的 udp_recvmsg()函數(shù),該函數(shù)負責(zé)處理UDP的數(shù)據(jù),sock_recvmsg()處理提交給 sock_read()函數(shù)。

       sock_read()函數(shù)讀取接收到的數(shù)據(jù)緩沖,把數(shù)據(jù)返回給 sys_read()系統(tǒng)調(diào)用。sys_read()函數(shù)調(diào)用最終把數(shù)據(jù)復(fù)制到用戶空間,供用戶使得。

 

    五、數(shù)據(jù)包發(fā)送流程

    以UDP數(shù)據(jù)包發(fā)送流程為例,在DM9000網(wǎng)卡上如何發(fā)送一個數(shù)據(jù)包。

3.png

    當用戶空間的應(yīng)用程序通過 socket函數(shù) sento()發(fā)送一個UDP數(shù)據(jù)后,會調(diào)用內(nèi)核空間的 sock_writev()函數(shù),然后通過 sock_sendmsg()函數(shù)處理。  

     sock_sendmsg()函數(shù)調(diào)用 inet_sendmsg()函數(shù)處理,inet_sendmsg()函數(shù)會把要發(fā)送的數(shù)據(jù)交給傳輸層的 udp_sendmsg()函數(shù)處理。

   udp_sendmsg()函數(shù)在數(shù)據(jù)前加入UDP頭,然后把數(shù)據(jù)交給 ip_build_xmit()函數(shù)處理,該函數(shù)根據(jù) socket提供的目的 IP和端口信息構(gòu)造IP頭,然后調(diào)用 output_maybe_reroute()函數(shù)處理。out_maybe_reroute()函數(shù)檢查數(shù)據(jù)包是否需要經(jīng)過路由,最后交給 ip_output()函數(shù)寫入到發(fā)送隊列,寫入完成后由 ip_finish_output()函數(shù)處理后續(xù)工作。

   鏈路層的 dev_queue_xmit()函數(shù)處理發(fā)送隊列,調(diào)用 DM9000網(wǎng)卡的發(fā)送數(shù)據(jù)包函數(shù) dm9000_xmit()發(fā)送數(shù)據(jù)包,發(fā)送完畢后,調(diào)用 dm9000_xmit_done函數(shù)處理發(fā)送結(jié)果。

主站蜘蛛池模板: 欧美人妖xxx | 久久亚洲综合色 | 亚洲一区二区三区久久精品 | 国产精品久久久久久久久鸭 | 台湾亚洲精品一区二区tv | 91福利一区二区三区 | 国产亚洲精品国产第一 | 中文字幕日韩视频 | 美女毛片在线 | 欧美性生活视频免费播放网址大全观看 | 久热re在线视频精品免费 | 午夜久久久久久久 | 最新国产精品好看的国产精品 | 免费可在线观看黄的视频 | 特级黄色视频毛片 | 久久精品国产亚洲片 | 五月婷婷六月丁香 | 国产福利视频 | 久久久久久91香蕉国产 | 2021av在线视频 | aⅴ在线免费观看 | 国产视频自拍偷拍 | 青草五月天 | 日日麻批视频 | 365深夜福利在线观看 | 成人久久久精品乱码一区二区三区 | 大香蕉毛片| 那一个欧美一级毛片 | 久久一本久综合久久爱 | 99久视频| 亚洲最大的黄色网 | 国产目拍亚洲精品区一区 | 亚洲一级视频在线观看 | 国产h视频 | 亚洲欧洲国产综合 | 一级二级三级毛片 | 精品黄色录像 | 成人国内精品久久久久影院 | 国产一级淫片a免费播放口之 | 在线成人a毛片免费播放 | 一级毛片视频在线观看 |