LWN:利用硬體offload來加速netfilter——第一部分

語言: CN / TW / HK

關注了就能看到更多這麼棒的文章哦~

Accelerating netfilter with hardware offload, part 1

January 14, 2020

This article was contributed by Marta Rybczyńska

原文來自:https://lwn.net/Articles/809333/

如今,純粹用軟體來支援高速場景下的網路協議,已經越來越困難了。目前已經有一些網路介面能達到25-100Gb/s的速度了,並且也開始出現一些能達到200-400Gb/s的。針對100Gb/s的速度要想及時完成network packet處理的話,每一筆需要在<200個cycle內處理掉,這樣就沒有留給作業系統多少時間了。幸運的是,許多操作可以由硬體來完成,包括校驗和的驗證,以及把一部分發送、接受packet的動作轉移到硬體上(offload)去做。

現在的硬體功能更強大,有許多可能性了。5.3 kernel裡面包含了Pablo Neira Ayuso的一個patch set,可以利用netfilter來把一些packet過濾的工作來offload到硬體上去做。這個patch set增加了offload功能的支援,同時也對網路通用程式碼和網絡卡驅動裡面的現有的offload程式碼路徑進行了重構。在後面的kernel釋出版本里面還有更多的相關工作。因此現在是一個合適的時機來審視一下近期在network stack裡面的offloading功能的演進。

Offloads in network cards

我們先回顧欻下網絡卡(network card,網路介面卡)提供了什麼功能。一個網路包(network packet)會先經過一些硬體處理之後才可能傳遞給kernel的網路協議棧。第一步它會被一個物理層(PHY, physical layer)處理器接收下來,PHY會處理好那些底層因素,包括傳輸介質(銅導線或者光纖乙太網線),頻率,調製方式(modulation)等等。接下來會把network packet傳遞給medium access control (MAC)單元,MAC把它複製到系統記憶體裡面去,把packet的描述符寫入接收佇列,然後可能會觸發一次中斷。這樣一來裝置驅動程式就可以開始經過網路協議棧來處理資料包。

不過,MAC控制器通常還包含其他一些邏輯單元,包括特定的一個處理器或者FPGA,這樣就可以不侷限於僅僅做個DMA傳輸了。首先,可以用MAC來處理多個接收佇列,這樣可以把資料包的處理分發到系統裡的不同CPU上去。它也可以把擁有相同的來源和目的地IP與埠號的packet排好序(這些可以成為資料流flow)。不同的資料流可以放到專門的接收佇列裡面去。這樣可以提高效能,例如這樣能剛好的利用cache。除此以外,MAC層還可以針對不同的資料流來做一些處理,例如把它們直接轉發到別的網路介面上去(如果同一個MAC在支援多個網路介面的話),或者針對DoS(拒絕服務攻擊)來把相關的網路包丟棄掉,等等等等。

要實現netfilter offload的話,硬體裡需要兩個重要功能模組:一個parser(解析器)和一個classifier(分類器)。parser會從網路資料包裡實時地(at line speed)提取資訊,它可以解析若干種網路協議,這樣一來就可以從多個網路層的角度來對資料包進行處理。通常它會提取那些重要的資料(例如IP地址和埠號等)以及軟體需要的一些資訊。第二步裡classifier會利用parser提供的這些資訊來對這個網路資料包packet進行處理。

上述著兩個模組在硬體實現的時候都需要利用到一個名為ternary content-addressable memory (TCAM)的結構,這是一種特殊的memory,不同於常見的使用兩個值(0和1)的memory,它會使用3個值(0,1,X)。新增的這個X值,表示在做資料比對(compare)的時候,不用在乎這個值("don't care"),既能匹配0,也能匹配1。典型來說parser會提供若干個TCAM資料條目(entries),每個條目都跟另一塊memory區域(存放了具體要做的action)關聯起來。這樣實現出來之後就可以利用正則表示式來對packet進行匹配,硬體會對每個packet都跟現有的TCAM條目逐項對比,命中後得到條目索引,也就能查到該對這個packet做什麼具體的action 了。

TCAM條目的數量是有限的,比如Marvell SoC裡的Armada 70xx和80xx等控制器都有256個TCAM條目(這個資訊來自Maxime Chevallier在2019 Embedded Linux Conference Europe會議上建議在網路驅動裡面支援classification offload的演講pdfhttps://static.sched.com/hosted_files/osseu19/3d/chevallier-network-classification-offload.pdf )。而相應地,netfilter的配置裡面通常會有幾千條規則。很明顯,要配置這樣的一個網路控制器,一大挑戰就是如何限制TCAM裡面新增的規則的數量。驅動程式需要負責配置此裝置特有的action,以及可供使用的各種classifier。目前的硬體通常都很複雜,並且驅動程式通常只支援少數幾個硬體。

MAC控制器裡的的offload功能還有可能更加精緻複雜,還有可以對完整的TCP stack進行offloading的,被稱為TCP offload engines。目前Linux尚未支援這種,因為在許多年前有人提交這部分支援程式碼的時候收到了network stack maintainers的很多反對意見(https://lwn.net/Articles/148697/  )。因此,Linux kernel沒有支援TCP offloading,而是提供了一些特定的無狀態的offload功能的支援。

對offload開發歷史感興趣的讀者可以讀Jesse Brandeburg和Anjali Singhai Jain在2018 Linux Plubers Conference上的論文(http://vger.kernel.org/lpc_net2018_talks/Brandeburg_networking_hardware_offloads.pdf  )。

Kernel subsystems with filtering offloads

networking subsystem核心程式碼裡面支援了許多種offload到網路裝置的功能,包括計算校驗和,零散包歸集(scatter/gather)處理,分包處理(segmentation)等等。讀者們可以看一下他們PC上所支援的、已經啟用的offload功能,用如下命令即可:

    ethtool --show-offload <interface>

不同的網路介面都有不同的offload功能列表,這取決於硬體和對應的驅動支援哪些功能。ethtool也可以配置這些offload功能,在它的man page(http://man7.org/linux/man-pages/man8/ethtool.8.html )裡面可以看到許多已有功能。

還有一個subsystem也利用了硬體offload功能,這就是traffic control(它的配置工具名字是tc)。tc的man page也介紹了現有功能的綜述,特別是flower classifier,可以供系統管理員來配置網路包的排程。常見的使用tc的例子是針對各個服務(service)來限制頻寬,或者對某些網路資料提升優先順序。感興趣的讀者可以閱讀2017年11月的NetDev 2.2會議上Simon Horman的文章(https://netdevconf.info/2.2/papers/horman-tcflower-talk.pdf  )

到目前為止,無論tc還是ethtool都可以過濾offload功能。這兩種功能在kernel裡是分別實現的,因此某種意義上說是個重複工作,導致網絡卡驅動開發者需要做雙份的工作,因為每種offload實現都需要使用不同的驅動callback函式。如果今後有第三個系統也來增加offload功能的話,開發者就會需要來統一一下實現了,這就需要對一些公用程式碼進行重構,以及對驅動程式實現的回撥函式進行修改。

Summary

在高速網路介面上對網路包的處理不是那麼容易的,所能利用的CPU cycle數實在太少了。幸運的是,硬體提供的offload功能可以被kernel利用來減少難度。在本文中,我們介紹了網絡卡是如何工作的,以及一些基本的offload只是。這是為了第二篇文章打好基礎,在第二篇裡面,我們會仔細介紹netfilter offloading功能帶來的變動,包括公共程式碼的改動以及對驅動程式作者的影響,當然也會介紹如何使用offload。

全文完

LWN文章遵循CC BY-SA 4.0許可協議。

歡迎分享、轉載及基於現有協議再創作~

長按下面二維碼關注,關注LWN深度文章以及開源社群的各種新近言論~