中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux網絡包從中斷到接收的示例分析

發布時間:2021-11-02 17:19:04 來源:億速云 閱讀:190 作者:柒染 欄目:系統運維

這期內容當中小編將會給大家帶來有關Linux網絡包從中斷到接收的示例分析,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

 

Linux網絡包從中斷到接收的示例分析

linux

既然要講,那就把一個包的整個包生都說了算了

觸發中斷

  • 在非虛擬化環境下,網卡通過DMA將packet寫入內核的rx_ring環形隊列緩沖區,并觸發中斷。

  • 如果在虛擬化環境下,VMM配置GIC ITS (Interrupt Translation Service)  ,建立物理中斷與虛擬中斷的映射完成中斷虛擬化使得網卡能直接向VM發出中斷,同時通過IO虛擬化,網卡通過IOMMU將packet直接寫入虛擬機內核的rx_ring

Top Half

  • CPU在收到中斷之后,調用網卡ISR也就是所謂的中斷handler

  • 分配sk_buf并入input_pkt_queue(如果隊列已滿則丟棄)

  • 發出一個軟中斷NET_RX_SOFTIRQ,軟中斷可以被調度例如通過tasklet

Bottom Half

  • sk_buf從input_pkt_queue傳入process_queue,根據協議類型調用網絡層協議的handler

  • ip_rcv執行包頭檢查,ip_router_input()進行路由,決定本機/轉發/丟棄

  • tcp_v4_rcv執行包頭檢查,tcp_v4_lookup查詢對應的socket和connection,如果正常,tcp_prequeue將skb放進socket接收隊列

  • socket隨即喚醒所在的進程

Linux網絡包從中斷到接收的示例分析

kqueue

因為epoll沒有論文,就說說kqueue是怎么做的吧,kqueue會根據socket綁定的knote鏈表(每個監聽的kqueue都可能創建一個knote),將knote通過反向指針獲得kqueue,將knote加入kqueue的就緒隊列末尾。如果此時恰好有進程正在監聽的話,將會喚醒進程,kqueue會被掃描,并從就緒隊列處獲得所有的event,從而了解已經就緒的所有socket。

  • 喚醒的進程調用socket recv系統調用,如果是TCP則調用tcp_recvmsg從sk_buffer拷貝數據

Batch

netif_receive_skb_list()

Linux的NAPI還會繼續延遲軟中斷的處理,等待其積累足夠的skb后進行輪詢,一次性處理所有的skb。

SKB

skb并不是直接存儲報文,而是存儲指針,指針只需要移動,就能完成解包,而本身的報文并不需要修改。上一層的協議棧會在處理當前層的同時設置好下一層的頭指針,并且移動data指針。與此同時,skb本身是雙向鏈表實現的隊列。qlen為鏈表元素長度,lock為添加元素時的鎖。

Linux網絡包從中斷到接收的示例分析

skb結構

談到指針的用法,這里舉個做OS lab時印象深刻的奇淫巧技,也是C的指針變態的地方

#define list_entry(ptr, type, field) \     container_of(ptr, type, field) #define container_of(ptr, type, field) \     ((type *)((void *)(ptr) - (u64)(&(((type *)(0))->field))))

(u64)(&(((type  *)(0))->field))))指的是field在結構體type中的偏移量,通過減去這個偏移量我們就能找出某個對象所在上級type對象的地址,也就是container。

一般來說,我們都會使用下面這樣的方式,讓鏈表節點去包裹數據。

struct page_list_node {         struct page p;     struct list_node *prev;     struct list_node *next; };

但是,通過指針操作,卻可以讓數據去包裹鏈表節點

struct list_head {     struct list_head *prev;     struct list_head *next; };  struct page{     struct list_head      list_node; }

在僅僅知道鏈表節點的情況下,借助成員偏移量即可知道容器對象的位置并取出

list_entry(somenode,struct page,list_node);

list_head本身可以存在于任何對象上,而他們的entry卻能根據參數而指向不同的類型,感覺有點泛型的味道了。

內容來自SJTU,IPADS OS-16-Network

上述就是小編為大家分享的Linux網絡包從中斷到接收的示例分析了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

青阳县| 黔东| 防城港市| 凤庆县| 皮山县| 云梦县| 兴业县| 四子王旗| 苏尼特右旗| 清流县| 高台县| 阜南县| 仲巴县| 南皮县| 铅山县| 习水县| 阿克陶县| 舟山市| 益阳市| 德阳市| 广河县| 马关县| 红原县| 渝中区| 微博| 颍上县| 阿勒泰市| 富源县| 临桂县| 武宁县| 凌海市| 西乌| 惠州市| 泰顺县| 大竹县| 舒城县| 德昌县| 隆化县| 汉源县| 廊坊市| 珲春市|