網(wǎng)絡(luò)包的內(nèi)核漂流記 Part 1 - 圖解網(wǎng)絡(luò)包接收流程

image.png

注,原文來自 https://blog.mygraphql.com/zh/notes/low-tec/network/kernel-net-stack/ 锌钮。如你看到的轉(zhuǎn)載圖片不清诞帐,請回到原文。

目錄

《網(wǎng)絡(luò)包的內(nèi)核漂流記》系列介紹

大家知道,網(wǎng)絡(luò)數(shù)據(jù)來源于網(wǎng)線轮洋、光纖、無線電波上的比特(bit)抬旺,然后到網(wǎng)卡弊予,到內(nèi)核黔漂,最后到應(yīng)用進程 socket搁胆。事情好像很簡單。但如果是 SRE/DevOps 或是 Performance Engineer 淹辞,需要做細致的監(jiān)控和優(yōu)化時床未,這些顯然是不夠的竭翠。引用本文主要參考作者的原話:

Optimizing and monitoring the network stack is impossible unless you carefully read and understand how it works. You cannot monitor code you don’t understand at a deep level.
除非您仔細閱讀并了解其工作原理,否則無法優(yōu)化和監(jiān)控網(wǎng)絡(luò)堆棧薇搁。 您無法深入監(jiān)控您不理解的代碼斋扰。
—— Joe Damato

《網(wǎng)絡(luò)包的內(nèi)核漂流記》嘗試分析和跟蹤一個網(wǎng)絡(luò)包在內(nèi)核各子系統(tǒng)間的流轉(zhuǎn)和觸發(fā)的協(xié)作。

開始前先做個預告啃洋,《網(wǎng)絡(luò)包的內(nèi)核漂流記》 系統(tǒng)(將)包括:

  • Part 1: 圖解網(wǎng)絡(luò)包接收流程
  • Part 2: BPF 跟蹤網(wǎng)絡(luò)包的內(nèi)核漂流
    • 我將演示如何用 bpftrace 蹤網(wǎng)絡(luò)包的內(nèi)核漂流传货。

為免嚇跑人,還是老套路宏娄,多圖少代碼问裕。不過有的圖有點點復雜。??

本系列主要參考:Monitoring and Tuning the Linux Networking Stack: Receiving Data 孵坚。是的粮宛,這是篇被轉(zhuǎn)載窥淆、參考到泛濫的文章。幾乎你能在網(wǎng)上找到的所有講 Linux 網(wǎng)卡和網(wǎng)絡(luò)棧收發(fā)的文章巍杈,都會參考它忧饭。但有句話是:

一千個人眼中就有一千個 “哈姆雷特”。 —— 無名高人

風格筷畦、樣式词裤、本文的交互閱讀方式 ??

雖然不是寫書,不過還是說明一下吧:

  1. 我不打算像八股文的 Linux 內(nèi)核文章一樣鳖宾,貼一堆源碼吼砂,讓文章看起來內(nèi)容很豐滿但無趣。我用交互 SVG 圖片的的方法去引用源碼 ?? 攘滩。
  2. https://blog.mygraphql.com/zh/notes/low-tec/network/kernel-net-stack/ 的原文是 SVG 圖片帅刊。如果你是在其它地方看到本文,請轉(zhuǎn)回原文漂问。
  3. 正確瀏覽 SVG 圖片的姿勢是瀏覽器中圖片處右鍵赖瞒,選擇 “新 Tab 中打開圖片” 。
  4. SVG 圖片可以點擊鏈接蚤假,直接跳轉(zhuǎn)到相應(yīng)內(nèi)核源碼網(wǎng)頁栏饮,精確到源碼行。 是的磷仰,你不需要 git clone那大陀源碼 ?? 袍嬉,只需要一個瀏覽器就可以。如果你在電腦前開雙屏灶平,結(jié)合源碼和圖看伺通,相信我,內(nèi)核源碼不是什么天書逢享,你能看懂大部分的罐监。
  5. 瀏覽內(nèi)核源碼我用 https://elixir.bootlin.com/linux/v5.4/source 。這個是很好的內(nèi)核源碼瀏覽網(wǎng)站瞒爬,內(nèi)置源碼引用跳轉(zhuǎn)和搜索功能弓柱。

ISO 網(wǎng)絡(luò)模型

我并不太學院派,但回顧一下基礎(chǔ)知識還是必須的:

圖:OSI 基本參考模型和 TCP/IP 堆棧之間的邏輯映射

圖:OSI 基本參考模型和 TCP/IP 堆棧之間的邏輯映射侧但,來自這里

下文把第 n 層縮寫為 Ln矢空,如 TRANSPORT 層是第 4 層,縮寫為 L4禀横。

網(wǎng)絡(luò)包接收流程概述

圖:網(wǎng)絡(luò)包接收流程概述

網(wǎng)絡(luò)包接收步驟

從代碼細節(jié)看屁药,網(wǎng)絡(luò)包接收步驟比較多。下面劃分為 4 步來敘述:

  1. 初始化與配置
  2. IRQ 處理
  3. SoftIRQ 中加載網(wǎng)絡(luò)包到內(nèi)存
  4. SoftIRQ 中推送網(wǎng)絡(luò)包到上層

初始化與配置

首先說說柏锄,內(nèi)核啟動時者祖,網(wǎng)絡(luò)子系統(tǒng)的初始化流程立莉。


圖:初始化與配置
  1. 創(chuàng)建 ksoftirqd 內(nèi)核線程(每個 CPU 一個)
  2. ksoftirqd 線程開始在 run_ksoftirqd 函數(shù)中執(zhí)行它們的處理循環(huán)绢彤。
  3. 接下來七问,為每個 CPU 創(chuàng)建一個專用的 softnet_data 對象。茫舶。這些對象又引用了其它處理網(wǎng)絡(luò)數(shù)據(jù)的重要對象械巡。其中之一是下文會提到 poll_list(輪詢列表)。 程序通過調(diào)用 napi_schedule()函數(shù)或來自設(shè)備驅(qū)動程序的其他 NAPI API 來添加 NAPI 到 poll_list中 饶氏。
  4. 然后讥耗,net_dev_init() 通過調(diào)用 open_softirq() 向 softirq 系統(tǒng)注冊 NET_RX_SOFTIRQ 軟中斷。注冊的處理函數(shù)稱為“net_rx_action()”疹启。這是softirq內(nèi)核線程將執(zhí)行以處理數(shù)據(jù)包的函數(shù)古程。

不要心急,第 4 步以后的步驟喊崖,將在下文繼續(xù)挣磨。因需要鋪墊一下其它內(nèi)容。

IRQ 處理

下面荤懂,從網(wǎng)卡在網(wǎng)絡(luò)上接收到數(shù)據(jù)開始茁裙,說說前期的包處理過程。


網(wǎng)絡(luò)包到達網(wǎng)卡觸發(fā) IRQ节仿,IRQ 處理程序完成網(wǎng)絡(luò)包處理前半部分晤锥,并觸發(fā) SoftIRQ
  1. 網(wǎng)卡從網(wǎng)絡(luò)接收數(shù)據(jù)。
  2. NIC 使用 DMA 將網(wǎng)絡(luò)數(shù)據(jù)寫入 RAM廊宪。
  3. NIC 拉起 IRQ 位矾瘾。
  4. 設(shè)備驅(qū)動之前注冊的IRQ處理程序被執(zhí)行。
  5. 清除網(wǎng)卡上的 IRQ箭启,以便它可以為新的數(shù)據(jù)包到達生成 IRQ壕翩。
  6. 通過調(diào)用 napi_schedule() 函數(shù),異步觸發(fā) NAPI softIRQ 輪詢循環(huán)册烈。

有了以上鋪墊知識后戈泼,我們回頭看看上節(jié)的「初始化與配置」中未講解的步驟:

5. 驅(qū)動中對napi_schedule()的調(diào)用將驅(qū)動的NAPI poll對象添加到當前CPU的poll_list中。
6. 標記 softirq 拉起位赏僧,以便這個 CPU 上的 ksoftirqd 進程知道有數(shù)據(jù)包要處理大猛。
7. run_ksoftirqd() 函數(shù)被調(diào)用(由ksoftirq 內(nèi)核線程循環(huán)運行)執(zhí)行。
8. __do_softirq() 被調(diào)用檢查softirq 拉起位淀零,看到一個 softIRQ 拉起挽绩, 并調(diào)用拉起位相關(guān)的softIRQ注冊的處理程序:net_rx_action(),后續(xù)的網(wǎng)絡(luò)接收數(shù)據(jù)所有重要的工作將在這個函數(shù)中完成驾中。

SoftIRQ 中加載網(wǎng)絡(luò)包到內(nèi)存

圖:SoftIRQ 中加載網(wǎng)絡(luò)包到內(nèi)存

這個圖比較簡單唉堪,不多說模聋。

SoftIRQ 中推送網(wǎng)絡(luò)包到上層

圖:SoftIRQ 中推送網(wǎng)絡(luò)包到上層

Receive Packet Steering(RPS)被禁用的情況流程為:

1. netif_receive_skb() 將數(shù)據(jù)傳遞給 __netif_receive_core()
6. __netif_receive_core() 將數(shù)據(jù)傳送到 TAP(監(jiān)聽模塊) (如 PCAP)唠亚。
7. __netif_receive_core() 將數(shù)據(jù)傳遞給已注冊的協(xié)議層處理程序链方。在大多數(shù)情況下,是 IPv4 協(xié)議棧注冊的 ip_rcv 函數(shù)灶搜。

使用Receive Packet Steering(RPS)的情況流程祟蚀,這里不說了,我暫時未分析到割卖。

如果你心急前酿,想了解 Receive Packet Steering(RPS) 是什么鬼,那么:

結(jié)尾

沒太多好說的鹏溯,好好學習罢维,天天向上。笨人做笨事丙挽,做最好的自己肺孵。

Ending

相關(guān)

如果你關(guān)注云原生,也使用到 Calico取试,那么以下這篇兄弟文章你可能喜歡:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末悬槽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瞬浓,更是在濱河造成了極大的恐慌初婆,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猿棉,死亡現(xiàn)場離奇詭異磅叛,居然都是意外死亡,警方通過查閱死者的電腦和手機萨赁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門弊琴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人杖爽,你說我怎么就攤上這事敲董。” “怎么了慰安?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵腋寨,是天一觀的道長。 經(jīng)常有香客問我化焕,道長萄窜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮查刻,結(jié)果婚禮上键兜,老公的妹妹穿的比我還像新娘。我一直安慰自己穗泵,他們只是感情好普气,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著火欧,像睡著了一般棋电。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上苇侵,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音企锌,去河邊找鬼榆浓。 笑死,一個胖子當著我的面吹牛撕攒,可吹牛的內(nèi)容都是我干的陡鹃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼抖坪,長吁一口氣:“原來是場噩夢啊……” “哼萍鲸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起擦俐,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤脊阴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蚯瞧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嘿期,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年埋合,在試婚紗的時候發(fā)現(xiàn)自己被綠了备徐。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡甚颂,死狀恐怖蜜猾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情振诬,我是刑警寧澤蹭睡,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站贷揽,受9級特大地震影響棠笑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜禽绪,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一蓖救、第九天 我趴在偏房一處隱蔽的房頂上張望洪规。 院中可真熱鬧,春花似錦循捺、人聲如沸斩例。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽念赶。三九已至,卻和暖如春恰力,著一層夾襖步出監(jiān)牢的瞬間叉谜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工踩萎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留停局,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓香府,卻偏偏與公主長得像董栽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子企孩,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容