国产精品影视_二区视频_91精品国产91久久久久久吃药_久久久久久久久久久综合_久久精品免费国产_免费a视频在线观看

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

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

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

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

 

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

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

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

     在Linux內(nèi)核,所有的網(wǎng)絡(luò)設(shè)備都被抽象為一個(gè)接口處理,該接口提供了所有的網(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)核有一個(gè)dev_base的全局指針,指向一個(gè)設(shè)備鏈表,包括了系統(tǒng)內(nèi)的所有網(wǎng)絡(luò)設(shè)備。該設(shè)備鏈表每個(gè)節(jié)點(diǎn)是一個(gè)網(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)的操作實(shí)現(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)可以分為兩個(gè)部分,一部分是存儲數(shù)據(jù)包緩存,在圖中表示為PackertData,另一部分是由一組用于內(nèi)核管理的指針組成。

       sk_buff管理的指針最主要的是下面4個(gè):

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

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

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

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

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

     對于一個(gè)TCP數(shù)據(jù)包為例,sk_buff還提供了幾個(gè)指針直接指向各層協(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ū)動(dòng)程序最重要的部分。

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

   內(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ù)

  • 鏈接層變量

  • 接口標(biāo)志

 

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

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

2.png

     以DM9000網(wǎng)卡為例,當(dā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ù)包隊(duì)列,該函數(shù)處理數(shù)據(jù)包后如果是 IP數(shù)據(jù)包則提交給ip_recv()函數(shù)處理。ip_recv()函數(shù)主要是檢查一個(gè)數(shù)據(jù)包IP頭的合法性,檢查通過后交給 ip_local_deliver()和 ip_local_deliver_finish()函數(shù)處理,之所以分開處理是因?yàn)閮?nèi)核中有防火墻相關(guān)的代碼需要?jiǎng)討B(tài)加載到此處。

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

       數(shù)據(jù)包進(jìn)入 socket部分的第一個(gè)函數(shù)是 skb_recv_datagram(),該函數(shù)從內(nèi)核的 socket隊(duì)列取出數(shù)據(jù)包,交給 socket部分的 udp_recvmsg()函數(shù),該函數(shù)負(fù)責(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ā)送一個(gè)數(shù)據(jù)包。

3.png

    當(dāng)用戶空間的應(yīng)用程序通過 socket函數(shù) sento()發(fā)送一個(gè)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ù)前加入U(xiǎn)DP頭,然后把數(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ā)送隊(duì)列,寫入完成后由 ip_finish_output()函數(shù)處理后續(xù)工作。

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

主站蜘蛛池模板: 蜜桃网站在线观看 | 国产精品爱久久久久久久 | 国产一级片91 | 叶子楣成人爽a毛片免费啪啪 | 日韩视频www | 国产午夜精品久久久久 | 精品一二三区视频 | 久久久国产精品免费观看 | 他也色在线视频 | 毛片免费看电影 | 国产亚洲自拍一区 | 日韩黄色免费电影 | 特色一级黄色片 | 欧美成人一区二区三区电影 | 中文字幕 欧美 日韩 | 国产一级毛片av | 国产成人高清成人av片在线看 | 欧美日韩视频在线播放 | 久久久久久久久久91 | 日韩精品免费一区二区三区 | 99视频有精品视频高清 | 欧美日韩国产一区二区三区在线观看 | www.91成人| av老司机久久 | 免费三级大片 | 美女在线视频一区二区 | 久久久久97国产精 | 999插插插| 国产精品久久久久久久久久三级 | 国产精品亚洲一区二区三区久久 | 夜夜夜精品视频 | 国产精品一区2区3区 | 成人免费午夜视频 | 欧美在线一级 | 91精品中文字幕 | 91精品国产综合久久婷婷香蕉 | 成年人在线免费播放视频 | 久久免费综合视频 | 欧美成人激情 | 久久久久久久不卡 | 久久网页 |