日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

万字长文|深入理解XDP全景指南

發(fā)布時(shí)間:2024/4/11 编程问答 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 万字长文|深入理解XDP全景指南 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

譯者序

本文翻譯自 2018 年 ACM?CoNEXT?大會(huì)上的一篇文章:

The eXpress Data Path: Fast Programmable Packet Processing in the Operating System Kernel

作者陣容豪華,包括來(lái)自 Cilium 的 Daniel Borkmann、John Fastabend 等。

論文引用信息:

Toke H?iland-J?rgensen, Jesper Dangaard Brouer, Daniel Borkmann, John Fastabend, Tom Herbert, David Ahern, and David Miller. 2018. The eXpress Data Path: Fast Programmable Packet Processing in the Operating System Kernel. In CoNEXT ’18: International Conference on emerging Networking EXperiments and Technologies, December 4–7, 2018, Heraklion, Greece. ACM, New York, NY, USA, 13 pages. https://doi.org/10.1145/3281411.3281443

由于譯者水平有限,本文不免存在遺漏或錯(cuò)誤之處。如有疑問(wèn),請(qǐng)查閱原文。

以下是譯文。

  • 譯者序

  • 摘要

  • 1 引言

    • 1.1 現(xiàn)有方案(kernel bypass)存在的問(wèn)題

    • 1.2 新方案:給內(nèi)核網(wǎng)絡(luò)棧添加可編程能力

    • 1.3 新方案(XDP)的優(yōu)點(diǎn)

    • 1.4 本文組織結(jié)構(gòu)

  • 2 相關(guān)工作

    • 2.1 用戶態(tài)輪詢 vs. XDP

    • 2.2 內(nèi)核模塊 vs. XDP

    • 2.3 可編程硬件 vs. XDP

    • 2.4 小結(jié)

  • 3 XDP 設(shè)計(jì)

    • 唯一加載入口:bpf()?系統(tǒng)調(diào)用

    • 校驗(yàn)器工作原理:two-pass DAG

    • 內(nèi)存越界和空指針檢查:職責(zé)上移到程序自身/開(kāi)發(fā)者

    • 跟蹤數(shù)據(jù)訪問(wèn)操作和值范圍

    • 不同類型數(shù)據(jù)的校驗(yàn)信息來(lái)源(source of truth)

    • 校驗(yàn)器的目的

    • 在設(shè)備驅(qū)動(dòng)中執(zhí)行,無(wú)需上下文切換

    • 在軟件最早能處理包的位置執(zhí)行,性能最優(yōu)

    • XDP 程序典型執(zhí)行流

    • 3.0 XDP 系統(tǒng)架構(gòu)

    • 3.1 XDP driver hook

    • 3.2 eBPF 虛擬機(jī)

    • 3.3 BPF maps

    • 3.4 eBPF verifier

    • 3.5 XDP 程序示例

    • 3.6 小結(jié)

  • 4 性能評(píng)估

    • XDP 未做底層代碼優(yōu)化

    • 通用目的操作系統(tǒng),首要目標(biāo):更好的擴(kuò)展和配置,而非極致性能

    • 轉(zhuǎn)發(fā)吞吐(pps)

    • 轉(zhuǎn)發(fā)延遲

    • 4.1 直接棄包(packet drop)性能

    • 4.2 CPU Usage

    • 4.3 包轉(zhuǎn)發(fā)性能

    • 4.4 討論:XDP 性能與 DPDK 還有差距的原因

  • 5 真實(shí)場(chǎng)景使用案例

    • Facebook Katran

    • 性能

    • 模擬 Cloudflare 防御架構(gòu)

    • 程序邏輯

    • 性能

    • 內(nèi)核數(shù)據(jù)平面 & 控制平面(BIRD/FRR)

    • XDP:直接查詢內(nèi)核路由表并轉(zhuǎn)發(fā)

    • 測(cè)試:XDP routing + 全球 BGP 路由表

    • 性能:2.5x

    • 5.1 案例一:軟件路由(software routing)

    • 5.2 案例二:Inline DoS Mitigation

    • 5.3 案例三:負(fù)載均衡(load balancing)

  • 6 XDP 的未來(lái)方向

    • 校驗(yàn)邏輯偏保守

    • 缺少標(biāo)準(zhǔn)庫(kù)

    • 一個(gè)網(wǎng)卡接口只能 attach 一個(gè) XDP 程序

    • 6.1 eBPF 程序的限制

    • 6.2 用戶體驗(yàn)和調(diào)試

    • 6.3 驅(qū)動(dòng)支持

    • 6.4 性能提升

    • 6.5 QoS 和 Rate Transitions

    • 6.6 加速傳輸層協(xié)議

    • 6.7 內(nèi)核-用戶空間零拷貝(zero-copy to userspace)

    • 6.8 XDP 作為基礎(chǔ)構(gòu)建模塊(XDP as a building block)

  • 7 總結(jié)

  • 致謝

  • 參考文獻(xiàn)

摘要

近些年業(yè)界流行通過(guò)內(nèi)核旁路(kernel bypass)的方式實(shí)現(xiàn)?可編程的包處理過(guò)程(programmable packet processing)。實(shí)現(xiàn)方式是 將網(wǎng)絡(luò)硬件完全交由某個(gè)專門(mén)的用戶空間應(yīng)用(userspace application) 接管,從而避免內(nèi)核和用戶態(tài)上下文切換的昂貴性能開(kāi)銷。

但是,操作系統(tǒng)被旁路(繞過(guò))之后,它的應(yīng)用隔離(application isolation) 和安全機(jī)制(security mechanisms)就都失效了;一起失效的還有各種經(jīng)過(guò)已經(jīng) 充分測(cè)試的配置、部署和管理工具。

為解決這個(gè)問(wèn)題,我們提出一種新的可編程包處理方式:eXpress Data Path (XDP)。

  • XDP 提供了一個(gè)仍然基于操作系統(tǒng)內(nèi)核的安全執(zhí)行環(huán)境,在設(shè)備驅(qū)動(dòng)上下文?(device driver context)中執(zhí)行,可用于定制各種包處理應(yīng)用。

  • XDP 是主線內(nèi)核(mainline Linux kernel)的一部分,與現(xiàn)有的內(nèi)核 網(wǎng)絡(luò)棧(kernel’s networking stack)完全兼容,二者協(xié)同工作。

  • XDP 應(yīng)用(application)通過(guò) C 等高層語(yǔ)言編寫(xiě),然后編譯成特定字節(jié)碼;出于安 全考慮,內(nèi)核會(huì)首先對(duì)這些字節(jié)碼執(zhí)行靜態(tài)分析,然后再將它們翻譯成?處理器原生指令(native instructions)。

  • 測(cè)試結(jié)果顯示,XDP 能達(dá)到?24Mpps/core?的處理性能。

為展示 XDP 靈活的編程模型,本文還將給出三個(gè)程序示例,

  • layer-3 routing(三層路由轉(zhuǎn)發(fā))

  • inline DDoS protection(DDoS 防護(hù))

  • layer-4 load balancing(四層負(fù)載均衡)

  • 1 引言

    軟件實(shí)現(xiàn)高性能包處理的場(chǎng)景,對(duì)每個(gè)包的處理耗時(shí)有著極高的要求。通用目的操作系統(tǒng)中 的網(wǎng)絡(luò)棧更多是針對(duì)靈活性的優(yōu)化,這意味著它們花在每個(gè)包上 的指令太多了,不適合網(wǎng)絡(luò)高吞吐的場(chǎng)景。

    因此,隨后出現(xiàn)了一些專門(mén)用于包處理的軟件開(kāi)發(fā)工具,例如 Data Plane Development Kit (DPDK) [16]。這些工具一般都會(huì)完全繞過(guò)內(nèi)核,將網(wǎng)絡(luò)硬件直接交 給用戶態(tài)的網(wǎng)絡(luò)應(yīng)用,并需要獨(dú)占一個(gè)或多個(gè) CPU。

    1.1 現(xiàn)有方案(kernel bypass)存在的問(wèn)題

    內(nèi)核旁路方式可以顯著提升性能,但缺點(diǎn)也很明顯:

    • 很難與現(xiàn)有系統(tǒng)集成;

    • 上層應(yīng)用必須要將內(nèi)核中已經(jīng)非常成熟的模塊在用戶態(tài)重新實(shí)現(xiàn)一遍,例如路由表、高層協(xié)議棧等;

    • 最壞的情況下,這種包處理應(yīng)用只能工作在一個(gè)完全隔絕的環(huán)境,因?yàn)閮?nèi)核提供的常見(jiàn)工具和部署方式在這種情況下都不可用了。

    • 導(dǎo)致系統(tǒng)越來(lái)越復(fù)雜,而且破壞了操作系統(tǒng)內(nèi)核在把控的安全邊界。?在基礎(chǔ)設(shè)施逐漸遷移到 Kubernetes/Docker 等容器環(huán)境的背景下,這一點(diǎn)顯得尤其嚴(yán)重, 因?yàn)樵谶@種場(chǎng)景下,內(nèi)核擔(dān)負(fù)著資源抽象和隔離的重任。

    1.2 新方案:給內(nèi)核網(wǎng)絡(luò)棧添加可編程能力

    對(duì)此,本文提供了另一種解決方案:給內(nèi)核網(wǎng)絡(luò)棧添加可編程能力。這使得我們能在?兼容各種現(xiàn)有系統(tǒng)、復(fù)用已有網(wǎng)絡(luò)基礎(chǔ)設(shè)施的前提下,仍然實(shí)現(xiàn)高速包處理。?這個(gè)框架稱為 XDP,

    • XDP 定義了一個(gè)受限的執(zhí)行環(huán)境(a limited execution environment),運(yùn)行在一個(gè)?eBPF 指令虛擬機(jī)中。eBPF 是 BSD Packet Filter (BPF) [37] 的擴(kuò)展。

    • XDP 程序運(yùn)行在內(nèi)核上下文中,此時(shí)內(nèi)核自身都還沒(méi)有接觸到包數(shù)據(jù)( before the kernel itself touches the packet data),這使得我們能在網(wǎng)卡收到包后?最早能處理包的位置,做一些自定義數(shù)據(jù)包處理(包括重定向)。

    • 內(nèi)核在加載(load)時(shí)執(zhí)行靜態(tài)校驗(yàn),以確保用戶提供的 XDP 程序的安全。

    • 之后,程序會(huì)被動(dòng)態(tài)編譯成原生機(jī)器指令(native machine instructions),以獲得高性能。

    XDP 已經(jīng)在過(guò)去的幾個(gè)內(nèi)核 release 中逐漸合并到內(nèi)核,但在本文之前,還沒(méi)有關(guān)于 XDP 系統(tǒng)的 完整架構(gòu)介紹。本文將對(duì) XDP 做一個(gè)高層介紹。

    1.3 新方案(XDP)的優(yōu)點(diǎn)

    我們的測(cè)試結(jié)果顯示 XDP 能取得?24Mpps/core?的處理性能,這雖然與 DPDK 還有差距, 但相比于后者這種 kernel bypass 的方式,XDP 有非常多的優(yōu)勢(shì)。

    具體地,XDP:

  • 與內(nèi)核網(wǎng)絡(luò)棧協(xié)同工作,將硬件的控制權(quán)完全留在內(nèi)核范圍內(nèi)。帶來(lái)的好處:

    • 保持了內(nèi)核的安全邊界

    • 無(wú)需對(duì)網(wǎng)絡(luò)配置或管理工具做任何修改

    無(wú)需任何特殊硬件特性,任何有 Linux 驅(qū)動(dòng)的網(wǎng)卡都可以支持, 現(xiàn)有的驅(qū)動(dòng)只需做一些修改,就能支持 XDP hooks。

    可以選擇性地復(fù)用內(nèi)核網(wǎng)絡(luò)棧中的現(xiàn)有功能,例如路由表或 TCP/IP 協(xié)議棧,在保持配置接口不變的前提下,加速關(guān)鍵性能路徑(critical performance paths)。

    保證 eBPF 指令集和 XDP 相關(guān)的編程接口(API)的穩(wěn)定性。

    與常規(guī) socket 層交互時(shí),沒(méi)有從用戶態(tài)將包重新注入內(nèi)核的昂貴開(kāi)銷。

    對(duì)應(yīng)用透明。這創(chuàng)造了一些新的部署場(chǎng)景/方式,例如直接在應(yīng)用所 在的服務(wù)器上部署 DoS 防御(而非中心式/網(wǎng)關(guān)式 DoS 防御)。

    服務(wù)不中斷的前提下動(dòng)態(tài)重新編程(dynamically re-program), 這意味著可以按需加入或移除功能,而不會(huì)引起任何流量中斷,也能動(dòng)態(tài)響應(yīng)系統(tǒng)其他部分的的變化。

    無(wú)需預(yù)留專門(mén)的 CPU 做包處理,這意味著 CPU 功耗與流量高低直接相關(guān),更節(jié)能。

    1.4 本文組織結(jié)構(gòu)

    接下來(lái)的內(nèi)容介紹 XDP 的設(shè)計(jì),并做一些性能分析。結(jié)構(gòu)組織如下:

    • Section 2?介紹相關(guān)工作;

    • Section 3?介紹 XDP 系統(tǒng)的設(shè)計(jì);

    • Section 4?做一些性能分析;

    • Section 5?提供了幾個(gè)真實(shí) XDP 場(chǎng)景的程序例子;

    • Section 6?討論 XDP 的未來(lái)發(fā)展方向;

    • Section 7?總結(jié)。

    2 相關(guān)工作

    XDP當(dāng)然不是第一個(gè)支持可編程包處理的系統(tǒng) —— 這一領(lǐng)域在過(guò)去幾年發(fā)展勢(shì)頭良好, 并且趨勢(shì)還在持續(xù)。業(yè)內(nèi)已經(jīng)有了幾種可編程包處理框架,以及基于這些框架的新型應(yīng)用,包括:

    • 單一功能的應(yīng)用,如 switching [47], routing [19], named-based forwarding [28], classification [48], caching [33] or traffic generation [14]。

    • 更加通用、且高度可定制的包處理解決方案,能夠處理從多種源收來(lái)的數(shù)據(jù)包 [12, 20, 31, 34, 40, 44]。

    要基于通用(Common Off The Shelf,COTS)硬件實(shí)現(xiàn)高性能包處理,就必須解決?網(wǎng)卡(NIC)和包處理程序之間的所有瓶頸。由于性能瓶頸主要來(lái)源于內(nèi)核和用戶態(tài)應(yīng)用之間的接口(系統(tǒng)調(diào)用開(kāi)銷非常大,另外,內(nèi)核功能豐富,但也非常復(fù)雜), 低層(low-level)框架必須通過(guò)這樣或那樣的方式來(lái)降低這些開(kāi)銷。

    現(xiàn)有的一些框架通過(guò)幾種不同的方式實(shí)現(xiàn)了高性能,XDP構(gòu)建在其中一些技術(shù)之上。?接下來(lái)對(duì) XDP 和它們的異同做一些比較分析。

    2.1 用戶態(tài)輪詢 vs. XDP

    • DPDK?[16] 可能是使用最廣泛的高性能包處理框架。它最初只支持 Intel 網(wǎng)卡,后來(lái)逐 步擴(kuò)展到其他廠商的網(wǎng)卡。DPDK 也稱作內(nèi)核旁路框架(kernel bypass framework), 因?yàn)樗鼘⒕W(wǎng)絡(luò)硬件的控制權(quán)從內(nèi)核轉(zhuǎn)移到了用戶態(tài)的網(wǎng)絡(luò)應(yīng)用,完全避免了內(nèi)核-用戶態(tài) 之間的切換開(kāi)銷。

    • 與DPDK 類似的還有?PF_RING?ZC module [45] 和 hardware-specific Solarflare OpenOnload [24]。

    在現(xiàn)有的所有框架中,內(nèi)核旁路方式性能是最高的?[18];但如引言中指 出,這種方式在管理、維護(hù)和安全方面都存在不足。

    XDP 采用了一種與內(nèi)核旁路截然相反的方式:相比于將網(wǎng)絡(luò)硬件的控制權(quán)上移到用戶空間, XDP 將性能攸關(guān)的包處理操作直接放在內(nèi)核中,在操作系統(tǒng)的網(wǎng)絡(luò)棧之前執(zhí)行。

    • 這種方式同樣避免了內(nèi)核-用戶態(tài)切換開(kāi)銷(所有操作都在內(nèi)核);

    • 但仍然由內(nèi)核來(lái)管理硬件,因此保留了操作系統(tǒng)提供的管理接口和安全防護(hù)能力;

    這里的主要?jiǎng)?chuàng)新是:使用了一個(gè)虛擬執(zhí)行環(huán)境,它能對(duì)加載的 程序進(jìn)行校驗(yàn),確保它們不會(huì)對(duì)內(nèi)核造成破壞。

    2.2 內(nèi)核模塊 vs. XDP

    在 XDP 之前,以內(nèi)核模塊(kernel module)方式實(shí)現(xiàn)包處理功能代價(jià)非常高, 因?yàn)槌绦驁?zhí)行出錯(cuò)時(shí)可能會(huì)導(dǎo)致整個(gè)系統(tǒng)崩潰,而且內(nèi)核的內(nèi)部 API 也會(huì)隨著時(shí)間發(fā)生變化。?因此也就不難理解為什么只有很少的系統(tǒng)采用了這種方式。其中做的比較好包括

    • 虛擬交換機(jī)?Open vSwitch [44]

    • Click [40]

    • 虛擬機(jī)路由器?Contrail [41]

    這幾個(gè)系統(tǒng)都支持靈活的配置,適用于多種場(chǎng)景,取得比較小的平攤代價(jià)。

    XDP通過(guò):

  • 提供一個(gè)安全的執(zhí)行環(huán)境,以及內(nèi)核社區(qū)支持,提供與那些暴露到用戶空間一樣穩(wěn)定的內(nèi)核 API

    極大地降低了那些將處理過(guò)程下沉到內(nèi)核的應(yīng)用(applications of moving processing into the kernel)的成本。

  • 此外,XDP 程序也能夠完全繞過(guò)內(nèi)核網(wǎng)絡(luò)棧(completely bypass), 與在內(nèi)核網(wǎng)絡(luò)棧中做 hook 的傳統(tǒng)內(nèi)核模塊相比,性能也更高。

  • XDP 除了能將處理過(guò)程下沉到內(nèi)核以獲得最高性能之外,還支持在程序中執(zhí)行重定向?(redirection)操作,完全繞過(guò)內(nèi)核網(wǎng)絡(luò)棧,將包送到特殊類型的用戶空間 socket;?甚至能工作在 zero-copy 模式,進(jìn)一步降低開(kāi)銷。

    • 這種模式與 Netmap [46] 和 PF_RING [11] 方式類似,但后者是在沒(méi)有完全繞過(guò)內(nèi) 核的情況下,通過(guò)降低從網(wǎng)絡(luò)設(shè)備到用戶態(tài)應(yīng)用(network device to userspace application)之間的傳輸開(kāi)銷,實(shí)現(xiàn)高性能包處理。

    內(nèi)核模塊方式的另一個(gè)例子是 Packet I/O engine,這是 PacketShader [19] 的組成部分, 后者專用于 Arrakis [43] and ClickOS [36] 之類的特殊目的操作系統(tǒng)。

    2.3 可編程硬件 vs. XDP

    可編程硬件設(shè)備也是一種實(shí)現(xiàn)高性能包處理的方式。

    • 一個(gè)例子是 NetFPGA [32],通過(guò)對(duì)它暴露的 API 進(jìn)行編程,能夠在這種基于 FPGA 的專 用設(shè)備上運(yùn)行任何包處理任務(wù)。

    • P4 編程語(yǔ)言 [7] 致力于將這種可編程能力擴(kuò)展到更廣泛的包處理硬件上?(巧合的是,它還包括了一個(gè) XDP backend [51])。

    某種意義上來(lái)說(shuō),XDP 可以認(rèn)為是一種?offload?方式:

  • 性能敏感的處理邏輯下放到網(wǎng)卡驅(qū)動(dòng)中,以提升性能;

  • 其他的處理邏輯仍然走內(nèi)核網(wǎng)絡(luò)棧;

  • 如果沒(méi)有用到內(nèi)核 helper 函數(shù),那整個(gè) XDP 程序都可以 offload 到網(wǎng)卡(目前 Netronome smart-NICs [27] 已經(jīng)支持)。

  • 2.4 小結(jié)

    XDP 提供了一種高性能包處理方式,與已有方式相比,在性能、與現(xiàn)有系統(tǒng)的集成、靈活性 等方面取得了更好的平衡。接下來(lái)介紹 XDP 是如何取得這種平衡的。

    3 XDP 設(shè)計(jì)

    XDP 的設(shè)計(jì)理念:

    • 高性能包處理

    • 集成到操作系統(tǒng)內(nèi)核(kernel)并與之協(xié)同工作,同時(shí)

    • 確保系統(tǒng)其它部分的安全性(safety)完整性(integrity)

    這種與內(nèi)核的深度集成顯然會(huì)給設(shè)計(jì)帶來(lái)一些限制,在 XDP 組件合并到 Linux 的過(guò)程中,我們也收到了許多來(lái)自社區(qū)的反饋,促使我們不斷調(diào)整 XDP 的設(shè)計(jì),但 這些設(shè)計(jì)反思不在本文討論范圍之內(nèi)。

    3.0 XDP 系統(tǒng)架構(gòu)

    圖 1 描繪了整個(gè) XDP 系統(tǒng),四個(gè)主要組成部分:

  • XDP driver hook:XDP 程序的主入口,在網(wǎng)卡收到包執(zhí)行。

  • eBPF virtual machine:執(zhí)行 XDP 程序的字節(jié)碼,以及對(duì)字節(jié)碼執(zhí)行 JIT 以提升性能。

  • BPF maps:內(nèi)核中的 key/value 存儲(chǔ),作為圖中各系統(tǒng)的主要通信通道。

  • eBPF verifier:加載程序時(shí)對(duì)其執(zhí)行靜態(tài)驗(yàn)證,以確保它們不會(huì)導(dǎo)致內(nèi)核崩潰。

  • Fig 1. XDP 與 Linux 網(wǎng)絡(luò)棧的集成。這里只畫(huà)了 ingress 路徑,以免圖過(guò)于復(fù)雜。

    上圖是 ingress 流程。網(wǎng)卡收到包之后,在處理包數(shù)據(jù)(packet data)之前,會(huì)先執(zhí)行 main XDP hook 中的 eBPF 程序。?這段程序可以選擇:

  • 丟棄(drop)這個(gè)包;或者

  • 通過(guò)當(dāng)前網(wǎng)卡將包再發(fā)送(send)出去;或者

  • 將包重定向(redirect)到其他網(wǎng)絡(luò)接口(包括虛擬機(jī)的虛擬網(wǎng)卡),或者通過(guò) AF_XDP socket 重定向到用戶空間;或者

  • 放行(allow)這個(gè)包,如果后面沒(méi)有其他原因?qū)е碌?drop,這個(gè)包就會(huì)進(jìn)入常規(guī)的內(nèi)核網(wǎng)絡(luò)棧。如果是這種情況,也就是放行包進(jìn)入內(nèi)核網(wǎng)絡(luò)棧,那接下來(lái)在將包放到發(fā)送隊(duì)列之前(before packets are queued for transmission), 還有一個(gè)能執(zhí)行 BPF 程序的地方:TC BPF hook。

  • 此外,圖 1 中還可以看出,不同的 eBPF 程序之間、eBPF 程序和用戶空間應(yīng)用之間,都能夠通過(guò) BPF maps 進(jìn)行通信。

    3.1 XDP driver hook

    在設(shè)備驅(qū)動(dòng)中執(zhí)行,無(wú)需上下文切換

    XDP 程序在網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)中執(zhí)行,網(wǎng)絡(luò)設(shè)備每收到一個(gè)包,程序就執(zhí)行一次。

    相關(guān)代碼實(shí)現(xiàn)為一個(gè)內(nèi)核庫(kù)函數(shù)(library function),因此程序直接 在設(shè)備驅(qū)動(dòng)中執(zhí)行,無(wú)需切換到用戶空間上下文。

    在軟件最早能處理包的位置執(zhí)行,性能最優(yōu)

    回到上面圖 1 可以看到:程序在網(wǎng)卡收到包之后最早能處理包的位置?執(zhí)行 —— 此時(shí)內(nèi)核還沒(méi)有為包分配?struct sk_buff?結(jié)構(gòu)體, 也沒(méi)有執(zhí)行任何解析包的操作。

    XDP 程序典型執(zhí)行流

    下圖是一個(gè)典型的 XDP 程序執(zhí)行流:

    Fig 2. 典型 XDP 程序的執(zhí)行流。

    網(wǎng)卡收到一個(gè)包時(shí),XDP程序依次執(zhí)行:

  • 提取包頭中的信息(例如 IP、MAC、Port、Proto 等),

    執(zhí)行到程序時(shí),系統(tǒng)會(huì)傳遞給它一個(gè)上下文對(duì)象(context object)作為參賽?(即?struct xdp_md *ctx,后面有例子),其中包括了指向原 始包數(shù)據(jù)的指針,以及描述這個(gè)包是從哪個(gè)網(wǎng)卡的哪個(gè)接口接收上來(lái)的等元數(shù)據(jù)字段。

  • 讀取或更新一些資源的元信息(例如更新統(tǒng)計(jì)信息);

    解析包數(shù)據(jù)之后,XDP 程序可以讀取?ctx?中的包元數(shù)據(jù)(packet metadata) 字段,例如從哪個(gè)網(wǎng)卡的哪個(gè)接口收上來(lái)的(ifindex)。除此之外,ctx 對(duì)象還允許 程序訪問(wèn)與包數(shù)據(jù)毗鄰的一塊特殊內(nèi)存區(qū)域(cb, control buffer), 在包穿越整個(gè)系統(tǒng)的過(guò)程中,可以將自定義的數(shù)據(jù)塞在這里。

    除了 per-packet metadata,XDP 程序還可以通過(guò) BPF map 定義和訪問(wèn)自己的持久數(shù)據(jù)?,以及通過(guò)各種 helper 函數(shù)訪問(wèn)內(nèi)核基礎(chǔ)設(shè)施。

    • BPF map 使 BPF 程序能與系統(tǒng)的其他部分之間通信;

    • Helpers 使 BPF 程序能利用到某些已有的內(nèi)核功能(例如路由表), 而無(wú)需穿越整個(gè)內(nèi)核網(wǎng)絡(luò)棧。

    如果有需要,對(duì)這個(gè)包進(jìn)行?rewrite header?操作,

    程序能修改包數(shù)據(jù)的任何部分,包括添加或刪除包頭。這使得 XDP 程序能執(zhí)行封裝/接封裝操作,以及重寫(xiě)(rewrite)地址字段然后轉(zhuǎn)發(fā)等操作。

    內(nèi)核 helper 函數(shù)各有不同用途,例如修改一個(gè)包之后,計(jì)算新的校驗(yàn)和(checksum)。

    進(jìn)行最后的判決(verdict),確定接下來(lái)對(duì)這個(gè)包執(zhí)行什么操作;

    判決結(jié)果包括:

    重定向功能的用途:

    這些不同的路徑,在圖 1 對(duì)應(yīng)的是幾條實(shí)線。

    將重定向判決(verdict)與重定向目標(biāo)(target)分開(kāi),使得重定向目標(biāo)類型很容易擴(kuò)展;?另外,由于重定向參數(shù)(目標(biāo))是通過(guò) BPF map 查詢的,因此無(wú)需修 改 XDP 程序,就能動(dòng)態(tài)修改重定向目標(biāo)。

    • 三種簡(jiǎn)單返回碼:丟棄這個(gè)包、通過(guò)接收時(shí)的網(wǎng)卡將包重新發(fā)送出去、允許這個(gè)包進(jìn)入內(nèi)核網(wǎng)絡(luò)棧;

    • 第四種返回碼 redirect:允許 XDP 程序指定網(wǎng)卡、CPU、用戶態(tài) socket?等,將包重定向過(guò)去。

  • 將原始包通過(guò)另一個(gè)網(wǎng)卡(包括虛擬機(jī)的虛擬網(wǎng)卡)發(fā)送出去;

  • 轉(zhuǎn)發(fā)給指定?CPU?做進(jìn)一步處理;

  • 轉(zhuǎn)發(fā)給?AF_XDP 類型的 socket?做進(jìn)一步處理;

  • 程序還能通過(guò)尾調(diào)用(tail call),將控制權(quán)交給另一個(gè) XDP 程序;?通過(guò)這種方式,可以將一個(gè)大程序拆分成幾個(gè)邏輯上的小程序(例如,根據(jù) IPv4/IPv6)。

    由于 XDP 程序可包含任意指令,因此前三步(讀取包數(shù)據(jù)、處理元數(shù)據(jù)、重寫(xiě)包數(shù)據(jù))?順序可以是任意的,而且支持多層嵌套。?但實(shí)際中為了獲得高性能,大部分情況下還是將執(zhí)行結(jié)構(gòu)組織成這順序的三步。

    3.2 eBPF 虛擬機(jī)

    XDP 程序在 Extended BPF (eBPF) 虛擬機(jī)中執(zhí)行。eBPF 是早期 BSD packet filter (BPF) [37] 的擴(kuò)展,后者在過(guò)去的幾十年中廣泛 應(yīng)用于各種包處理工具。

    BPF 使用?基于寄存器的(register-based) virtual machine 來(lái)描述?過(guò)濾動(dòng)作(filtering actions)。

    eBPF 虛擬機(jī)支持動(dòng)態(tài)加載(loading)和重加載(re-loading)程序,內(nèi)核管理所有 BPF 程序的生命周期。

    3.3 BPF maps

    eBPF 程序在觸發(fā)內(nèi)核事件時(shí)執(zhí)行(例如,觸發(fā) XDP 程序執(zhí)行的,是收包事件)。?程序每次執(zhí)行時(shí),初始狀態(tài)都是相同的(即程序是無(wú)狀態(tài)的),它們無(wú)法直接訪問(wèn)?內(nèi)核中的持久存儲(chǔ)(BPF map)。為此,內(nèi)核提供了訪問(wèn) BPF map 的 helper 函數(shù)。

    BPF map 是 key/value 存儲(chǔ),在加載 eBPF 程序時(shí)定義(defined upon loading an eBPF program)。

    用途:

  • 持久存儲(chǔ)。例如一個(gè) eBPF 程序每次執(zhí)行時(shí),都會(huì)從里面獲取上一次的狀態(tài)。

  • 用于協(xié)調(diào)兩個(gè)或多個(gè) eBPF 程序。例如一個(gè)往里面寫(xiě)數(shù)據(jù),一個(gè)從里面讀數(shù)據(jù)。

  • 用于用戶態(tài)程序和內(nèi)核 eBPF 程序之間的通信。

  • 3.4 eBPF verifier

    唯一加載入口:bpf()?系統(tǒng)調(diào)用

    由于 eBPF 代碼直接運(yùn)行在內(nèi)核地址空間,因此它能直接訪問(wèn) —— 也可 能是破壞 —— 任何內(nèi)存。為防止這種情況發(fā)生,內(nèi)核規(guī)定只能通過(guò)唯一入口(?bpf()?系統(tǒng)調(diào)用)加載 BPF 程序。

    加載 BPF 程序時(shí),位于內(nèi)核中的校驗(yàn)器首先會(huì)對(duì)字節(jié)碼程序進(jìn)行靜態(tài)分析,以確保

    • 程序中沒(méi)有任何不安全的操作(例如訪問(wèn)任意內(nèi)存),

    • 程序會(huì)終止(terminate)。通過(guò)下面這兩點(diǎn)來(lái)實(shí)現(xiàn):

      • 禁止循環(huán)操作

      • 限制程序最大指令數(shù)

    校驗(yàn)器工作原理:two-pass DAG

    校驗(yàn)器的工作原理:首先根據(jù)程序的控制流構(gòu)建一個(gè)有向無(wú)環(huán)圖(DAG), 然后對(duì) DAG 執(zhí)行如下校驗(yàn):

    • 首先,對(duì) DAG 進(jìn)行一次深度優(yōu)先搜索(depth-first search),以 確保它是無(wú)環(huán)的(acyclic),例如,沒(méi)有循環(huán),也不包含不支持或無(wú)法執(zhí)行到的指令。

    • 然后,再掃描一遍,這次會(huì)遍歷 DAG 的所有可能路徑。這次掃描的目的是:

      程序執(zhí)行?load?或?call?指令時(shí),如果參數(shù)不合法,就會(huì)在這里被拒絕。參數(shù)合法 性是通過(guò)在程序執(zhí)行期間跟蹤所有寄存器和棧變量的狀態(tài)(states of registers and stack variables)來(lái)實(shí)現(xiàn)的。

      • 確保程序的內(nèi)存訪問(wèn)都是安全的,

      • 調(diào)用?helper 函數(shù)時(shí)傳的參數(shù)類型是對(duì)的。

    內(nèi)存越界和空指針檢查:職責(zé)上移到程序自身/開(kāi)發(fā)者

    這種跟蹤寄存器狀態(tài)的機(jī)制是為了在無(wú)法預(yù)知內(nèi)存邊界的情況下,仍然確保程序 的內(nèi)存訪問(wèn)不會(huì)越界。無(wú)法預(yù)知內(nèi)存邊界是因?yàn)?#xff1a;

    • 包的大小是不固定的;

    • map 的內(nèi)容也無(wú)法提前預(yù)知,因此也無(wú)法判斷一次 map 查找操作是否會(huì)成功。

    為解決這個(gè)問(wèn)題,校驗(yàn)器會(huì)檢查已加載的程序自身是否會(huì)做如下檢查:

  • 解引用指針前做了內(nèi)存邊界檢查,

  • 查詢 map 之前是檢查了 map 指針是否為空。

  • 這種方式將處理邏輯中的安全檢查和遇到錯(cuò)誤時(shí)如何處理的控制權(quán)都?交給了 BPF 程序的編寫(xiě)者。

    跟蹤數(shù)據(jù)訪問(wèn)操作和值范圍

    為跟蹤數(shù)據(jù)訪問(wèn),校驗(yàn)器會(huì)跟蹤

  • 數(shù)據(jù)類型

  • 指針偏置(pointer offsets)

  • 所有寄存器的可能值范圍

  • 程序開(kāi)始時(shí),

    • R1?寄存器中存儲(chǔ)的是指向 context metadata 的指針(struct xdp_md *ctx),

    • R10?是棧指針(stack pointer),

    • 其他所有寄存器都是未初始化狀態(tài)。

    接下來(lái)程序每執(zhí)行一步,寄存器狀態(tài)就會(huì)更新一次。當(dāng)寄存器中存入一個(gè)新值時(shí),這個(gè)寄存器 還會(huì)繼承與這個(gè)值相關(guān)的狀態(tài)變量(inherits the state variables from the source of the value)。

    算術(shù)操作會(huì)影響標(biāo)量類型的值的范圍(value ranges of scalar types),以及指針類型的 offset。?可能的最大范圍(max possible range)存儲(chǔ)在狀態(tài)變量中,例如往寄存器中 load 一個(gè)字節(jié)時(shí), 這個(gè)寄存器的可能值范圍就設(shè)置為 0~255。指令圖(instruction graph)中的?各邏輯分支就會(huì)根據(jù)操作結(jié)果更新寄存器狀態(tài)。例如,比較操作?R1 > 10,

    • 校驗(yàn)器在一個(gè)分支?if R1 > 10?中會(huì)將 R1 最小值設(shè)為 11,

    • 在另一個(gè)?else?分支中將其最大值設(shè)為 10。

    不同類型數(shù)據(jù)的校驗(yàn)信息來(lái)源(source of truth)

    利用狀態(tài)變量中存儲(chǔ)的范圍信息,校驗(yàn)器就能預(yù)測(cè)每個(gè) load 指令能訪問(wèn)的所有 內(nèi)存范圍,確保它執(zhí)行的都是合法內(nèi)存訪問(wèn)。

  • 對(duì)于包數(shù)據(jù)(packet data)的訪問(wèn),會(huì)與 context 對(duì)象中的?data_end?變量做比較;

  • 對(duì)于?BPF map 中獲取的值,或用到 map 定義中聲明的 data size 信息;

  • 對(duì)于棧上存儲(chǔ)的值,會(huì)檢查狀態(tài)變量中記錄的值范圍;

  • 對(duì)于指針?biāo)阈g(shù)操作(pointer arithmetic)還會(huì)施加額外的限制,指針通常不能被轉(zhuǎn)換成整形值。

  • 只要校驗(yàn)器無(wú)法證明某個(gè)操作是安全,該?BPF 程序在加載時(shí)(load time)就會(huì)被拒絕。?除此之外,校驗(yàn)器還會(huì)利用范圍信息確保內(nèi)存的對(duì)齊訪問(wèn)(enforce aligned memory access)。

    校驗(yàn)器的目的

    需要說(shuō)明的是,校驗(yàn)器的目的是避免將內(nèi)核內(nèi)部(the internals of the kernel )暴露給惡意或有缺陷的 eBPF 程序,而非確保程序中函數(shù)的實(shí)現(xiàn)已經(jīng)是最高效的。

    換句話說(shuō),如果 XDP 程序中處理邏輯過(guò)多,也可能會(huì)導(dǎo)致機(jī)器變慢 ;如果代碼寫(xiě)的有問(wèn)題,也可能會(huì)破壞包數(shù)據(jù)。出于這些原因,加載 BPF 程序需要 管理員權(quán)限(root)。避免這些 bug 的責(zé)任在程序員,但選擇將哪些程序加載 到系統(tǒng)的權(quán)限在管理員。

    3.5 XDP 程序示例

    下面是一個(gè)簡(jiǎn)單的 XDP 程序,展示了前面介紹的一些特性。?程序會(huì)解析包數(shù)據(jù),判斷如果是 UDP 包,直接交換源和目的 MAC 地址,然后將包從相同網(wǎng)卡再發(fā)送回去,

    雖然這是一個(gè)非常簡(jiǎn)單的例子,但真實(shí)世界中的 XDP 程序用到的組件和特性,這里基本都具備了。

    // 從內(nèi)核 BPF 代碼示例 xdp2_kern.c 修改而來(lái)。1 // 用于統(tǒng)計(jì)包數(shù) 2 struct bpf_map_def SEC("maps") rxcnt = { 3 .type = BPF_MAP_TYPE_PERCPU_ARRAY, 4 .key_size = sizeof(u32), // IP 協(xié)議類型,即 IPv4/IPv6 5 .value_size = sizeof(long), // 包數(shù) 6 .max_entries = 256, 7 }; 8 9 // 直接操作包數(shù)據(jù)(direct packet data access),交換 MAC 地址 10 static void swap_src_dst_mac(void *data) 11 { 12 unsigned short *p = data; 13 unsigned short dst[3]; 14 dst[0] = p[0]; dst[1] = p[1]; dst[2] = p[2]; 15 p[0] = p[3]; p[1] = p[4]; p[2] = p[5]; 16 p[3] = dst[0]; p[4] = dst[1]; p[5] = dst[2]; 17 } 18 19 static int parse_ipv4(void *data, u64 nh_off, void *data_end) 20 { 21 struct iphdr *iph = data + nh_off; 22 if (iph + 1 > data_end) 23 return 0; 24 return iph->protocol; 25 } 26 27 SEC("xdp1") // marks main eBPF program entry point 28 int xdp_prog1(struct xdp_md *ctx) 29 { 30 void *data_end = (void *)(long)ctx->data_end; 31 void *data = (void *)(long)ctx->data; 32 struct ethhdr *eth = data; int rc = XDP_DROP; 33 long *value; u16 h_proto; u64 nh_off; u32 ipproto; 34 35 nh_off = sizeof(*eth); 36 if (data + nh_off > data_end) 37 return rc; 38 39 h_proto = eth->h_proto; 40 41 /* check VLAN tag; could be repeated to support double-tagged VLAN */ 42 if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) { 43 struct vlan_hdr *vhdr; 44 45 vhdr = data + nh_off; 46 nh_off += sizeof(struct vlan_hdr); 47 if (data + nh_off > data_end) 48 return rc; 49 h_proto = vhdr->h_vlan_encapsulated_proto; 50 } 51 52 if (h_proto == htons(ETH_P_IP)) 53 ipproto = parse_ipv4(data, nh_off, data_end); 54 else if (h_proto == htons(ETH_P_IPV6)) 55 ipproto = parse_ipv6(data, nh_off, data_end); 56 else 57 ipproto = 0; 58 59 /* lookup map element for ip protocol, used for packet counter */ 60 value = bpf_map_lookup_elem(&rxcnt, &ipproto); 61 if (value) 62 *value += 1; 63 64 /* swap MAC addrs for UDP packets, transmit out this interface */ 65 if (ipproto == IPPROTO_UDP) { 66 swap_src_dst_mac(data); 67 rc = XDP_TX; 68 } 69 return rc; 70 }

    具體地:

    • 定義了一個(gè) BPF map 存儲(chǔ)統(tǒng)計(jì)信息。用戶態(tài)程序可以 poll 這個(gè) map 來(lái)獲取統(tǒng)計(jì)信息。

    • context 對(duì)象?struct xdp_md *ctx?中有包數(shù)據(jù)的 start/end 指針,可用于直接訪問(wèn)包數(shù)據(jù)。

    • 將數(shù)據(jù)指針和?data_end?比較,確保內(nèi)存訪問(wèn)不會(huì)越界。

    • 程序必須自己解析包,包括 VLAN headers 等東西。

    • 直接通過(guò)指針(direct packet data access)修改包頭。

    • 內(nèi)核提供的 map lookup helper。這是程序中唯一的真實(shí)函數(shù)調(diào)用;其他函數(shù)都是內(nèi)聯(lián),包括?htons()。

    • 最終針對(duì)這個(gè)包的判決通過(guò)程序返回值傳遞給調(diào)用方。

    將這段程序安裝到網(wǎng)卡接口上時(shí),它首先會(huì)被編譯成 eBPF 字節(jié)碼,然后經(jīng)受校驗(yàn)器檢查。?這里的檢查項(xiàng)包括:

  • 無(wú)循環(huán)操作;程序大小(指令數(shù)量);

  • 訪問(wèn)包數(shù)據(jù)之前,做了內(nèi)存邊界檢查;

  • 傳遞給 map lookup 函數(shù)的參數(shù),類型與 map 定義相匹配;

  • map lookup 的返回值(value 的內(nèi)存地址)在使用之前,檢查了是否為 NULL。

  • 3.6 小結(jié)

    XDP 系統(tǒng)由四個(gè)主要部分組成:

  • XDP device driver hook:網(wǎng)卡收到包之后直接運(yùn)行;

  • eBPF虛擬機(jī):執(zhí)行 XDP 程序(以及內(nèi)核其他模塊加載的 BPF 程序);

  • BPF maps:使不同 BPF 程序之間、BPF 程序與用戶空間應(yīng)用之間能夠通信;

  • eBPF verifier:確保程序不包含任何可能會(huì)破壞內(nèi)核的操作。

  • 這四部分加在一起,創(chuàng)造了一個(gè)編寫(xiě)自定義包處理應(yīng)用的強(qiáng)大環(huán)境,它能加速包處理的關(guān)鍵 路徑,同時(shí)還與內(nèi)核及現(xiàn)有基礎(chǔ)設(shè)施密切集成。

    接下來(lái)看一下 XDP 應(yīng)用的性能。

    4 性能評(píng)估

    DPDK 是目前性能最高的包處理框架 [18],因此本文將 XDP 與 DPDK 及 Linux 內(nèi)核網(wǎng)絡(luò) 棧的性能做一個(gè)對(duì)比。測(cè)試機(jī)器環(huán)境:

    • CPU:一塊 hexa-core Intel Xeon E5-1650 v4 CPU running at 3.60GHz, 支持 Intel Data Direct I/O (DDIO) 技術(shù),網(wǎng)絡(luò)硬件通過(guò) DMA 能直接將包放到 CPU 緩存。

    • 關(guān)閉超線性(Hyperthreading)。

    • 網(wǎng)卡:兩塊?Mellanox ConnectX-5 Ex VPI dual-port 100Gbps,mlx5 驅(qū)動(dòng)。

    • 內(nèi)核:Linux 4.18

    • 使用基于 DPDK 的 TRex packet generator [9] 生成測(cè)試流量。所有測(cè)試腳本位于 [22]。

    在測(cè)試中,我們主要關(guān)心三個(gè) metric:

    • 直接棄包(packet drop)性能。

      為展示最高的包處理性能,我們將用最簡(jiǎn)單的操作 ——?丟棄接收到的包?—— 來(lái)測(cè)試。?這個(gè)測(cè)試能有效測(cè)量系統(tǒng)的整體開(kāi)銷,也是真正的包處理應(yīng)用能達(dá)到的性能上限。

    • CPU 使用量。

      如引言中指出,XDP 的優(yōu)點(diǎn)之一是 CPU 使用量與流量大小是正相關(guān)的,而無(wú)需預(yù)留專 門(mén)的 CPU 給它用。我們通過(guò)測(cè)量 CPU 利用率隨網(wǎng)絡(luò)負(fù)載的變化來(lái)量化這個(gè)指標(biāo)。

    • 包轉(zhuǎn)發(fā)性能。

      轉(zhuǎn)發(fā)的復(fù)雜性要更高一些,例如,涉及到與多塊網(wǎng)卡的交互、重寫(xiě)二層頭等等。?這里會(huì)將轉(zhuǎn)發(fā)延遲也考慮進(jìn)去。

    我們已經(jīng)驗(yàn)證,使用 MTU(1500 字節(jié))包時(shí),我們的系統(tǒng)單核就能達(dá)到線速(100 Gbps), 而且 CPU 有 50% 是空閑的。顯然,真正的挑戰(zhàn)在于 PPS,而非帶寬,其他一些測(cè)試也已經(jīng)指出了這一點(diǎn) [46]。?出于這個(gè)原因,我們用最小包(64 字節(jié))測(cè)試,衡量指標(biāo)是 PPS。

    對(duì)于 XDP 和 Linux 內(nèi)核網(wǎng)絡(luò)棧的測(cè)試,由于它們沒(méi)有顯式指定某些 CPU 來(lái)處理網(wǎng)絡(luò)包的方式,因此我們通過(guò)配置硬件 RSS(Receive Side Scaling)來(lái)講流量定向到指定 CPU。

    對(duì)網(wǎng)卡、內(nèi)核的一些配置調(diào)優(yōu),見(jiàn)代碼倉(cāng)庫(kù) [22]。

    4.1 直接棄包(packet drop)性能

    Fig 3. 直接棄包(packet drop)性能。DPDK 需要預(yù)留一個(gè) CPU 運(yùn)行控制任務(wù),因此只剩下 5 個(gè) CPU 做包處理。

    上圖是性能與 CPU 數(shù)量的關(guān)系。

    • XDP 基準(zhǔn)性能是?24Mpps/core,DPDK 是?43.5Mpps/core。

    • 二者在分別達(dá)到各自的峰值之前,PPS 都是隨 CPU 數(shù)量線性增長(zhǎng)的。

    • 最終全局性能受限于 PCI 總線,啟用 PCI descriptor compression(在 CPU cycles 和 PCI 總線帶寬之間取舍)之后,能達(dá)到 115Mpps。

    再看圖中 Linux 網(wǎng)絡(luò)棧在兩種配置下的性能:

  • 通過(guò)?iptables 的 raw table?丟棄流量,這是?Linux 網(wǎng)絡(luò)棧中最早能丟棄包的地方;

  • 通過(guò)?conntrack(連接跟蹤)模塊,這個(gè)模塊的開(kāi)銷非常大,但在很多 Linux 發(fā)行版中都是默認(rèn)開(kāi)啟的。

  • conntrack 模式達(dá)到了 1.8Mpps/core,raw 模式是 4.8Mpps/core ;這兩種模式均未達(dá)到硬件瓶頸。?最終的性能,XDP 比常規(guī)網(wǎng)絡(luò)棧的最快方式快了 5 倍。

    Linux raw mode test 中,我們還測(cè)量了 XDP 程序不丟棄包,而是更新包數(shù)統(tǒng)計(jì)然后將包 送到內(nèi)核網(wǎng)絡(luò)棧的場(chǎng)景。?這種情況下,XDP 單核的處理性能會(huì)下降到 4.5Mpps/core,有 13.3ns 處理延遲。?圖中并未給出這個(gè)測(cè)試結(jié)果,因?yàn)檫@個(gè)開(kāi)銷太小了。

    4.2 CPU Usage

    Fig 4. 直接棄包(packet drop)場(chǎng)景下的 CPU 利用率。

    用系統(tǒng)提供的?mpstat?命令測(cè)量 CPU 利用率。結(jié)果如圖 4 。

    • DPDK 是 busy poll 模式,因此 CPU 永遠(yuǎn)是 100%。

    • XDP 和 Linux 內(nèi)核網(wǎng)絡(luò)棧都是隨流量平滑增長(zhǎng):前面一小段是非線性的,后面基本是線性的。

      前面非線性主要是硬中斷帶來(lái)的固定開(kāi)銷,在流量很小時(shí)這一部分占比較大。

    4.3 包轉(zhuǎn)發(fā)性能

    這個(gè)測(cè)試中,轉(zhuǎn)發(fā)應(yīng)用執(zhí)行非常簡(jiǎn)單的 MAC 地址重寫(xiě):直接交換源和目的 MAC 地址,然后轉(zhuǎn)發(fā)。?這是轉(zhuǎn)發(fā)場(chǎng)景下最精簡(jiǎn)的步驟了,因此結(jié)果代表了所有真實(shí)轉(zhuǎn)發(fā)應(yīng)用的性能上限。

    • 圖中包括了同網(wǎng)卡轉(zhuǎn)發(fā)和不同網(wǎng)卡轉(zhuǎn)發(fā)(XDP?程序返回碼不同)的結(jié)果。

    • DPDK 示例程序只支持通過(guò)另一個(gè)網(wǎng)卡轉(zhuǎn)發(fā),因此這里只列出了這種情況下的性能。

    • Linux 網(wǎng)絡(luò)棧不支持這種極簡(jiǎn)轉(zhuǎn)發(fā)模式(minimal forwarding mode),需要設(shè)置完整的 橋接或路由查找(bridging or routing lookup)才能轉(zhuǎn)發(fā)包;路由查找是非常耗時(shí)的 ,由于其他幾種應(yīng)用并沒(méi)有這一步,因此結(jié)果直接對(duì)比是沒(méi)意義的。因此這里略去了 Linux 網(wǎng)絡(luò)棧的結(jié)果。

    轉(zhuǎn)發(fā)吞吐(pps)

    Fig 5. 轉(zhuǎn)發(fā)性能。在同一網(wǎng)卡接口上收發(fā)會(huì)占用同一 PCI port 的帶寬, 這意味著在 70Mpps XDP same-nic 組就已經(jīng)達(dá)到了 PCI 總線的瓶頸

    如圖 5 所示,性能隨 CPU 數(shù)量線性擴(kuò)展,直到達(dá)到全局性能瓶頸。XDP 在同網(wǎng)卡轉(zhuǎn)發(fā)的性能遠(yuǎn)高于 DPDK 異網(wǎng)卡性能,原因是內(nèi)存處理方式不同:

    • packet buffer 是設(shè)備驅(qū)動(dòng)分配的,與接收接口(receiving interface)相關(guān)聯(lián)。

    • 因此,異網(wǎng)卡場(chǎng)景下,當(dāng)包轉(zhuǎn)發(fā)到另一個(gè)接口時(shí),memory buffer 需要還給與之關(guān)聯(lián)的接口。

    轉(zhuǎn)發(fā)延遲

    表 1. 轉(zhuǎn)發(fā)延遲。機(jī)器網(wǎng)卡的兩個(gè)接口直連,在轉(zhuǎn)發(fā)速率分別為 100pps 和 1Mpps 的條件下,持續(xù) 50s 測(cè)量端到端延遲

    高 pps 場(chǎng)景下,XDP 的延遲已經(jīng)接近 DPDK。但在低 pps 場(chǎng)景下,XDP 延遲比 DPDK 大的多,原因是?XDP 是基于中斷的,中斷處理時(shí)間( interrupt processing time)此時(shí)占大頭;而 DPDK 是輪詢模式,延遲相對(duì)比較固定。

    4.4 討論:XDP 性能與 DPDK 還有差距的原因

    XDP 未做底層代碼優(yōu)化

    上一節(jié)已經(jīng)看到,XDP 相比于常規(guī) Linux 網(wǎng)絡(luò)棧性能有了顯著提升。但對(duì)于大部分 XDP 場(chǎng)景來(lái)說(shuō),性能還是與 DPDK 有差距。我們認(rèn)為,這是主要是因?yàn)?DPDK 做了相當(dāng)多的底層 代碼優(yōu)化。舉個(gè)例子來(lái)解釋,考慮 packet drop 例子:

    • XDP 24Mpps/core,對(duì)應(yīng)?41.6ns/packet

    • DPDK 43.5Mpps,對(duì)應(yīng)?22.9ns/packet

    多出來(lái)的 18.7ns 在我們的 3.6GHz 機(jī)器上對(duì)應(yīng) 67 個(gè)時(shí)鐘周期。因此,很顯然?每個(gè)很小的優(yōu)化在這里都會(huì)產(chǎn)生很大的影響。例如,我們測(cè)量出在測(cè)試 機(jī)器上,每次函數(shù)調(diào)用需要 1.3ns。mlx5 驅(qū)動(dòng)處理每個(gè)包都有 10 次 函數(shù)調(diào)用,總計(jì)就是 13ns。

    通用目的操作系統(tǒng),首要目標(biāo):更好的擴(kuò)展和配置,而非極致性能

    另外,在 Linux 這樣的通用目的操作系統(tǒng)中,某些開(kāi)銷是不可避免的, 因?yàn)樵O(shè)備驅(qū)動(dòng)或子系統(tǒng)的組織方式是為了實(shí)現(xiàn)更好的擴(kuò)展和配置,而非極致性能。

    但是,我們認(rèn)為有些優(yōu)化還是有必要的。例如,我們嘗試將內(nèi)核中與測(cè)試網(wǎng)卡無(wú)關(guān)的 DMA 函數(shù)調(diào)用刪掉, 這樣將前面提到的 10 個(gè)函數(shù)調(diào)用降低到了 6 個(gè),測(cè)試結(jié)果顯示這將單核性能提升到了 29Mpps/core。?依此推測(cè)的話,將另外 6 個(gè)函數(shù)調(diào)用也優(yōu)化掉,能將 XDP 的性能提升到?37.6Mpps。?實(shí)際上我們不可能將 6 個(gè)全部去掉,但去掉其中幾個(gè),再加上一些其他優(yōu)化,我 們相信 XDP 和 DPDK 的性能差距將越來(lái)越小。

    其他驅(qū)動(dòng)的測(cè)試結(jié)果也是類似的,例如 i40e driver for 40 Gbps Intel cards。

    基于以上討論,我們相信未來(lái) XDP 與 DPDK 的性能差距將越來(lái)越小。

    另一方面,考慮到 XDP 在靈活性和與內(nèi)核集成方面的優(yōu)勢(shì), XDP 已經(jīng)是很多實(shí)際場(chǎng)景中的非常有競(jìng)爭(zhēng)力的方式。下文給出幾個(gè)例子。

    5 真實(shí)場(chǎng)景使用案例

    本節(jié)給出三個(gè)例子來(lái)具體展示 XDP 在真實(shí)世界中的應(yīng)用。?這幾個(gè)案例都是已經(jīng)真實(shí)在用的,但本文出于解釋目的,將使用簡(jiǎn)化的版本。?同時(shí)也建議讀者參考 [38],后者是獨(dú)立的文章,介紹使用 XDP 解決實(shí)際工作中網(wǎng)絡(luò)服務(wù)所面臨的一些挑戰(zhàn)。

    本節(jié)目的是展示真實(shí) XDP 方案的可行性,因此不會(huì)將重點(diǎn)放在與業(yè)界最新的實(shí)現(xiàn)做詳盡性能對(duì)比上。?我們會(huì)拿常規(guī)的 Linux 內(nèi)核網(wǎng)絡(luò)棧的性能作為 baseline,來(lái)對(duì)比 XDP 應(yīng)用的性能。

    5.1 案例一:軟件路由(software routing)

    內(nèi)核數(shù)據(jù)平面 & 控制平面(BIRD/FRR)

    Linux 內(nèi)核實(shí)現(xiàn)了一個(gè)功能完整的路由表,作為數(shù)據(jù)平面,支持

    • policy routing

    • source-specific routing

    • multipath load balancing, and more.

    對(duì)于控制平面,Bird [10] 或 FRR [17] 這樣的路由守護(hù)進(jìn)程( routing daemons)實(shí)現(xiàn)了多種路由控制平面協(xié)議。Linux 提供的這套生態(tài)系統(tǒng)功能如此豐富 ,因此再在另一個(gè)包處理框架中重新實(shí)現(xiàn)一套類似的路由棧代價(jià)將非常高, 更實(shí)際的方式是對(duì) Linux 內(nèi)核的數(shù)據(jù)平面進(jìn)行優(yōu)化。

    XDP:直接查詢內(nèi)核路由表并轉(zhuǎn)發(fā)

    XDP 非常適合做這件事情,尤其是它提供了一個(gè) helper 函數(shù),能從 XDP 程序中直接查詢內(nèi)核路由表。

    • 如果查詢成功,會(huì)返回?egress interface 和下一跳 MAC 地址, XDP 程序利用這些信息足夠?qū)⒓崔D(zhuǎn)發(fā)出去。

    • 如果下一跳 MAC 還是未知的(因?yàn)橹斑€沒(méi)進(jìn)行過(guò) neighbour lookup),XDP 程序就 能將包傳給內(nèi)核網(wǎng)絡(luò)棧,后者會(huì)解析 neighbor 地址,這樣隨后的包 就能直接被 XDP 程序轉(zhuǎn)發(fā)了。

    測(cè)試:XDP routing + 全球 BGP 路由表

    為展示 XDP 路由的性能,我們用 Linux 內(nèi)核代碼中的 XDP routing 例子 [1],與常規(guī) Linux 內(nèi)核網(wǎng)絡(luò)棧的性能做對(duì)比。?兩組測(cè)試:

  • 路由表中只有一條路由;

  • 路由表中有從 routeviews.org 中 dump 而來(lái)的全球 BGP 路由表(global BGP routing table)。?包含 752,138 條路由。隨機(jī)生成 4000 個(gè)目的 IP 地址,以確保能充分利用到這種路由表。

    如果目的 IP 地址少于 4000 個(gè),實(shí)際用到的路由表部分會(huì)較小,能夠保存在 CPU 緩存中,使得結(jié)果不準(zhǔn)確。?增大 IP 數(shù)量至 4000 個(gè)以上,不會(huì)對(duì)轉(zhuǎn)發(fā)性能造成影響,但可以避免緩存導(dǎo)致的結(jié)果不準(zhǔn)問(wèn)題。

  • 對(duì)于兩組測(cè)試,下一跳 MAC 地址都是與我們的發(fā)送網(wǎng)卡直接相關(guān)的接口的地址。

    性能:2.5x

    Fig 6. 軟件路由的性能。由于性能隨核數(shù)線性增加,這里只給出單核的結(jié)果。

    測(cè)試結(jié)果如上圖所示。

    • full table lookup 性能提升了 2.5 倍;

    • smaller routing table 組,提升了 3 倍。

    這說(shuō)明,XDP 路由程序 + 單核 + 10Gbps 網(wǎng)卡?的軟硬件配置,就能?處理整張全球 BGP 路由表(保守估計(jì)每個(gè)包平均 300 字節(jié))。

    5.2 案例二:Inline DoS Mitigation

    DoS 攻擊還是像瘟疫一樣糾纏著互聯(lián)網(wǎng),現(xiàn)在通常的方式是:通過(guò)已經(jīng)入侵的大量設(shè)備發(fā)起分布式(DDoS)攻擊。

    有了XDP 之后,我們能直接在應(yīng)用服務(wù)器(application servers)上?部署包過(guò)濾程序來(lái)防御此類攻擊(inline DoS mitigation),?無(wú)需修改應(yīng)用代碼。如果應(yīng)用是部署在虛擬機(jī)里,那 XDP 程序還可以 部署在宿主機(jī)(hypervisor)上,這樣單個(gè)程序就能保護(hù)機(jī)器上所有的虛擬機(jī)。

    模擬 Cloudflare 防御架構(gòu)

    為展示工作原理,我們用 XDP 作為過(guò)濾機(jī)制,模擬 Cloudflare 的 DDoS 防御架構(gòu)?[6]。?他們的 Gatebot architecture ,首先在各 PoP 點(diǎn)機(jī)器上采樣,然后統(tǒng)一收起來(lái)做分析, 根據(jù)分析結(jié)果生成防御規(guī)則。

    防御規(guī)則的形式是對(duì)包數(shù)據(jù)(payload)進(jìn)行一系列簡(jiǎn)單檢查, 能直接編譯成 eBPF 代碼然后分發(fā)到 PoP 點(diǎn)的所有服務(wù)器上。這里說(shuō)的代碼是 XDP 程序 ,它會(huì)將匹配到規(guī)則的所有流量丟棄,同時(shí)將統(tǒng)計(jì)信息更新到 BPF map。

    程序邏輯

    為驗(yàn)證這種方案的性能,我們編寫(xiě)一個(gè) XDP 程序,它

  • 解析包頭,執(zhí)行一些簡(jiǎn)單驗(yàn)證。對(duì)每個(gè)包:執(zhí)行四次讀取操作,以解析外層包頭。

  • 將符合攻擊特性的流量丟棄。具體:丟棄 UDP + 特定端口的流量。

  • 將其他流量通過(guò) CPU redirect 方式重定向給另一個(gè) CPU?做進(jìn)一步處理;

  • 性能

    我們用 netperf 做性能壓測(cè) [26]。

    • 用 netperf TCP round-trip benchmark,單個(gè) TCP 連接來(lái)回小的 request/reply,統(tǒng)計(jì) transactions/second。

      模擬的是交互式應(yīng)用,例如小的遠(yuǎn)程過(guò)程調(diào)用(RPC)。

    • 實(shí)驗(yàn)在單核上進(jìn)行,模擬多個(gè)流量(正常流量+攻擊流量)競(jìng)爭(zhēng)同一物理資源的場(chǎng)景。

    • 在?beseline 35K 業(yè)務(wù) TPS(transactions per second)基礎(chǔ)上,打少量 UDP 流量作為攻擊流量。逐漸加大攻擊流量,觀察 TPS 的變化。

    Fig 7. DDoS 性能。業(yè)務(wù)吞吐(TPS)隨攻擊流量的變化。

    結(jié)果如上圖所示,

    • 沒(méi)有 XDP 的一組,性能急劇下降:攻擊流量在 3Mpps 時(shí)性能減半,3.5Mpps 時(shí)基本跌零;

    • 有 XDP 程序的一組,攻擊流量達(dá)到 19.5Mpps 之前,業(yè)務(wù)吞吐保持在 28.5K TPS 以上,過(guò)了這個(gè)臨界點(diǎn)性能才開(kāi)始急劇下降。

    以上結(jié)果表明,XDP 防御 DDoS 攻擊在實(shí)際中是完全可行的,單核就能輕松處理 10Gbps 的、都是最小包(minimum-packet)的 DoS 流量。?這種 DDoS 防御的部署更加靈活,無(wú)需硬件或應(yīng)用做任何改動(dòng)。

    5.3 案例三:負(fù)載均衡(load balancing)

    Facebook Katran

    負(fù)載均衡的場(chǎng)景,我們用 Facebook 開(kāi)源的 Katran 作為例子 [15]。Katran 的工作原理是對(duì)外通告服務(wù)的 IP,這樣目標(biāo)是這個(gè) IP 的流量就會(huì)被路由到 XDP 實(shí)現(xiàn)的負(fù)載均衡器。

    • 負(fù)載均衡器對(duì)包頭(source packet header)進(jìn)行哈希,以此選擇目標(biāo)應(yīng)用服務(wù)器。

    • 然后將對(duì)包進(jìn)行封裝(encap),發(fā)送給應(yīng)用服務(wù)器;

    • 應(yīng)用服務(wù)器解封裝(decap),處理請(qǐng)求,然后直接將回包發(fā)給客戶端(DSR 模式)。

    在這個(gè)過(guò)程中,XDP 程序負(fù)責(zé)哈希、封裝以及將包從接收網(wǎng)卡再發(fā)出去的任務(wù)。?配置信息存儲(chǔ)在 BPF map 中,整個(gè)封裝邏輯是完全在 eBPF 中實(shí)現(xiàn)的。

    性能

    為測(cè)試性能,我們給 Katran XDP 程序配置幾個(gè)固定的目標(biāo)機(jī)器。?對(duì)照組是 IPVS,它是 Linux 內(nèi)核的一部分。性能如表 2 所示,隨 CPU 數(shù)量線性增長(zhǎng), XDP 比 IPVS 性能高 4.3 倍。

    表 2. 負(fù)載均衡器性能(Mpps)

    配置:1 VIP/core, 100 DstIPs/VIP.

    6 XDP 的未來(lái)方向

    XDP已經(jīng)能用于解決真實(shí)問(wèn)題,但作為L(zhǎng)inux內(nèi)核的一部分,XDP 還在快速開(kāi)發(fā)過(guò)程中。

    6.1 eBPF 程序的限制

    前面提到,加載到 eBPF 虛擬機(jī)的程序必須保證其安全性(不會(huì)破壞內(nèi)核),因此對(duì) eBPF 程序作了一下限制,歸結(jié)為兩方面:

  • 確保程序會(huì)終止:在實(shí)現(xiàn)上是通過(guò)禁止循環(huán)和限制程序的最大指令數(shù)(max size of the program);

  • 確保內(nèi)存訪問(wèn)的安全:通過(guò) 3.4 小結(jié)介紹的寄存器狀態(tài)跟蹤(register state tracking)來(lái)實(shí)現(xiàn)。

  • 校驗(yàn)邏輯偏保守

    由于校驗(yàn)器的首要職責(zé)是保證內(nèi)核的安全,因此其校驗(yàn)邏輯比較保守, 凡是它不能證明為安全的,一律都拒絕。有時(shí)這會(huì)導(dǎo)致假陰性(false negatives), 即某些實(shí)際上是安全的程序被拒絕加載;這方面在持續(xù)改進(jìn)。

    • 校驗(yàn)器的錯(cuò)誤提示也已經(jīng)更加友好,以幫助開(kāi)發(fā)者更快定位問(wèn)題。

    • 近期已經(jīng)支持了 BPF 函數(shù)調(diào)用(function calls)。

    • 正在計(jì)劃支持有限循環(huán)(bounded loops)。

    • 正在提升校驗(yàn)器效率,以便處理更大的 BPF 程序。

    缺少標(biāo)準(zhǔn)庫(kù)

    相比于用戶空間 C 程序,eBPF 程序的另一個(gè)限制是缺少標(biāo)準(zhǔn)庫(kù),包括?內(nèi)存分配、線程、鎖等等庫(kù)。

  • 內(nèi)核的生命周期和執(zhí)行上下文管理(life cycle and execution context management )部分地彌補(bǔ)了這一不足,(例如,加載的 XDP 程序會(huì)為每個(gè)收到的包執(zhí)行),

  • 內(nèi)核提供的 helper 函數(shù)也部分地彌補(bǔ)了一不足。

  • 一個(gè)網(wǎng)卡接口只能 attach 一個(gè) XDP 程序

    這個(gè)限制其實(shí)也是可以繞過(guò)的:將 XDP 程序組織成程序數(shù)組,通過(guò)尾 調(diào)用,根據(jù)包上下文在程序之間跳轉(zhuǎn),或者是將幾個(gè)程序做 chaining。

    6.2 用戶體驗(yàn)和調(diào)試

    XDP 程序運(yùn)行在內(nèi)核,因此常規(guī)的用戶空間 debug 工具是用不了的,但內(nèi)核自帶的 debug 和 introspection 功能是可以用在 XDP (及其他 eBPF 程序)上的。?包括:

    • tracepoints and kprobes [13]

    • performance counters that are part of the perf subsystem [42]

    但不熟悉內(nèi)核生態(tài)系統(tǒng)的開(kāi)發(fā)者可能會(huì)對(duì)這些工具感到非常陌生,難以使用。因此,也出 現(xiàn)了一些更方便普通開(kāi)發(fā)者的工具,包括 BCC [50]、bpftool [8]、libbpf 函數(shù)庫(kù) [30] 等等。

    6.3 驅(qū)動(dòng)支持

    設(shè)備要支持 XDP,需要實(shí)現(xiàn)內(nèi)核核心網(wǎng)絡(luò)棧暴露出的一個(gè) API。?寫(xiě)作本文時(shí) Linux 4.18 已經(jīng)有 12 種驅(qū)動(dòng)支持 XDP,包括了大部分高速網(wǎng)卡。?最新列表見(jiàn) [2]。

    隨著 XDP 系統(tǒng)的不斷成熟,核心代碼逐漸上移到內(nèi)核中,驅(qū)動(dòng)需要維護(hù)的代碼越 來(lái)越少。例如,redirection action 支持新的 target 時(shí),無(wú)需驅(qū)動(dòng)做任何改動(dòng)。

    最后,對(duì)于那些不支持 XDP 的驅(qū)動(dòng),內(nèi)核提供了?Generic XDP?feature [39],這是軟件實(shí)現(xiàn)的 XDP,性能會(huì)低一些, 在實(shí)現(xiàn)上就是將 XDP 的執(zhí)行上移到了核心網(wǎng)絡(luò)棧(core networking stack)。

    XDP 在內(nèi)核收包函數(shù)?receive_skb() 之前,

    Generic XDP?在?receive_skb() 之后,

    更多關(guān)于 Generic XDP,可參考參考:容器網(wǎng)絡(luò)|深入理解Cilium

    6.4 性能提升

    XDP 和 DPDK 之間還有一些性能差距,一些改進(jìn)工作正在進(jìn)行中:

    • 驅(qū)動(dòng)代碼 micro-optimisations

    • 刪除核心 XDP 代碼中的非必要操作

    • 通過(guò)批處理平攤處理開(kāi)銷

    6.5 QoS 和 Rate Transitions

    當(dāng)前,XDP 還沒(méi)有任何 QoS 機(jī)制。?尤其是,如果對(duì)端已經(jīng)過(guò)載(例如兩端的網(wǎng)絡(luò)速度或特性不匹配),XDP 程序是收不到任何背壓(back-pressure)的,

    雖然 XDP 中缺少 QoS,但 Linux 內(nèi)核網(wǎng)絡(luò)棧中卻有很多業(yè)界最佳的 Active Queue Management (AQM) 特性和 packet scheduling algorithms [23]。?這些特性中,部分并不適用于 XDP,但我們相信能夠 以一種對(duì)包處理應(yīng)用完全透明的方式,選擇其中部分集成到 XDP。?我們計(jì)劃對(duì)這一方向進(jìn)行更深入研究。

    6.6 加速傳輸層協(xié)議

    我們已經(jīng)證明 XDP 能在保留操作系統(tǒng)原有功能的前提下,集成到操作系統(tǒng)中,實(shí)現(xiàn)高速包數(shù)據(jù)。

    目前的 XDP 還是用于無(wú)狀態(tài)包處理(stateless packet processing) ,如果將這個(gè)模型擴(kuò)展到有狀態(tài)傳輸層協(xié)議(stateful transport protocols),例如 TCP,它能給依賴可靠/有狀態(tài)傳輸?shù)膽?yīng)用提供類似的性能提升。

    實(shí)際上,已經(jīng)有一些研究證明,相比于操作系統(tǒng)的協(xié)議棧,accelerated transport protocols 能顯著提升性能[5, 25, 35, 52]。其中的一個(gè)解決方案 [52] 表明,在保留內(nèi) 核 TCP 協(xié)議棧的的前提下,原始包處理性能(raw packet processing)存在巨大的提升 空間。

    XDP 非常適用于這種場(chǎng)景,目前也已經(jīng)有一些關(guān)于如何實(shí)現(xiàn)的初步討論 [21], 雖然離實(shí)際使用還很遠(yuǎn),但仍然是一個(gè)令人振奮的、擴(kuò)展 XDP 系統(tǒng) scope 的方向。

    6.7 內(nèi)核-用戶空間零拷貝(zero-copy to userspace)

    3.1 小節(jié)提到,XDP 程序能將數(shù)據(jù)包重定向到用戶空間應(yīng)用(userspace application)打 開(kāi)的特殊類型 socket。這可以用于加速客戶端和服務(wù)端在同一臺(tái)機(jī)器?的網(wǎng)絡(luò)密集型應(yīng)用(network-heavy applications running on the local machine)。

    更多信息可參考:?(譯) 利用 ebpf sockmap/redirection 提升 socket 性能(2020)。?這里使用的是 BPF 而非 XDP,但核心原理是一樣的,只是程序執(zhí)行的位置(hook)不同。?譯注。

    但在目前的實(shí)現(xiàn)中,這種方式在底層仍然需要拷貝包數(shù)據(jù),因此性能會(huì)打折扣。

    目前已經(jīng)有工作在進(jìn)行,通過(guò) AF_XDP 實(shí)現(xiàn)真正的數(shù)據(jù)零拷貝。但這項(xiàng)工作需要?對(duì)網(wǎng)絡(luò)設(shè)備的內(nèi)存處理過(guò)程有一些限制,因此需要設(shè)備驅(qū)動(dòng)的顯式支持。?第一個(gè)支持這個(gè)功能的 patch 已經(jīng)合并到?4.19?內(nèi)核,更多驅(qū)動(dòng)的支持 正在添加中。初步的性能測(cè)試結(jié)果還是很樂(lè)觀的,顯示能達(dá)到 20Mpps/core 的內(nèi)核到用戶 空間傳遞(transfer)速度。

    6.8 XDP 作為基礎(chǔ)構(gòu)建模塊(XDP as a building block)

    正如 DPDK 用于高層包處理框架的底層構(gòu)建模塊(例如 [31]),XDP 有望成為高層應(yīng)用的運(yùn)行時(shí)環(huán)境 (runtime environment for higher-level applications)。

    實(shí)際上,我們看到一些基于 XDP 的應(yīng)用和框架已經(jīng)出現(xiàn)了。包括

    • Cilium security middle-ware [3]

    • Suricata network monitor [4]

    • Open vSwitch [49]

    • P4-to-XDP compiler project [51]

    甚至還有人嘗試將 XDP 作為 DPDK 的一種底層驅(qū)動(dòng) [53]。

    7 總結(jié)

    本文描述了 XDP,一個(gè)安全、快速、可編程、集成到操作系統(tǒng)內(nèi)核的包處理框架。?測(cè)試結(jié)果顯示,XDP 能提供 24Mpps/core 的高處理性能,這一數(shù)字雖然與基于 kernel bypass 的 DPDK 仍有差距,但提供了其他一些非常有競(jìng)爭(zhēng)力的優(yōu)勢(shì):

  • 兼容內(nèi)核安全和管理框架(kernel bypass 方式在 bypass 內(nèi)核網(wǎng)絡(luò)棧的同時(shí),也將安全和設(shè)備管理等這些極其重要的基礎(chǔ)設(shè)施 bypass 了);

  • 兼容內(nèi)核網(wǎng)絡(luò)棧,可選擇性利用內(nèi)核已有的基礎(chǔ)設(shè)施和功能;

  • 提供與內(nèi)核 API 一樣穩(wěn)定的編程接口;

  • 對(duì)應(yīng)用完全透明;

  • 更新、替換程序的過(guò)程不會(huì)引起服務(wù)中斷;

  • 無(wú)需專門(mén)硬件,無(wú)需獨(dú)占 CPU 等資源。

  • 相比于 kernel bypass 這種非此即彼、完全繞開(kāi)內(nèi)核的方式,我們相信 XDP 有更廣闊的的應(yīng)用前景。Facebook、Cloudflare 等公司實(shí)際落地的 XDP 應(yīng)用,更加增強(qiáng)了我們的這種信心。

    最后,XDP系統(tǒng)還在快速發(fā)展,前面也列出了一些正在未來(lái)可能會(huì)做的開(kāi)發(fā)/優(yōu)化工作。

    致謝

    XDP has been developed by the Linux networking community for a number of years, and the authors would like to thank everyone who has been involved. In particular,

    • Alexei Starovoitov has been instrumental in the development of the eBPF VM and verifier;

    • Jakub Kicinski has been a driving force behind XDP hardware offloading and the bpftool utility;

    • Bj?rn T?pel and Magnus Karlsson have been leading the AF_XDP and userspace zero-copy efforts.

    We also wish to extend our thanks to the anonymous reviewers, and to our shepherd Srinivas Narayana, for their helpful comments.

    參考文獻(xiàn)

    https://arthurchiao.art/blog/xdp-paper-acm-2018-zh/

    - END -


    看完一鍵三連在看轉(zhuǎn)發(fā)點(diǎn)贊

    是對(duì)文章最大的贊賞,極客重生感謝你

    推薦閱讀

    深入理解Linux內(nèi)核之內(nèi)存尋址


    2022新年重磅技術(shù)分享|深入理解Linux操作系統(tǒng)


    一些優(yōu)秀的后端開(kāi)源項(xiàng)目!


    你好,這里是極客重生,我是阿榮,大家都叫我榮哥,從華為->外企->到互聯(lián)網(wǎng)大廠,目前是大廠資深工程師,多次獲得五星員工,多年職場(chǎng)經(jīng)驗(yàn),技術(shù)扎實(shí),專業(yè)后端開(kāi)發(fā)和后臺(tái)架構(gòu)設(shè)計(jì),熱愛(ài)底層技術(shù),豐富的實(shí)戰(zhàn)經(jīng)驗(yàn),分享技術(shù)的本質(zhì)原理,希望幫助更多人蛻變重生,拿BAT大廠offer,培養(yǎng)高級(jí)工程師能力,成為技術(shù)專家,實(shí)現(xiàn)高薪夢(mèng)想,期待你的關(guān)注!點(diǎn)擊藍(lán)字查看我的成長(zhǎng)之路

    校招/社招/簡(jiǎn)歷/面試技巧/大廠技術(shù)棧分析/后端開(kāi)發(fā)進(jìn)階/優(yōu)秀開(kāi)源項(xiàng)目/直播分享/技術(shù)視野/實(shí)戰(zhàn)高手等,?極客星球希望成為最有技術(shù)價(jià)值星球,盡最大努力為星球的同學(xué)提供技術(shù)和成長(zhǎng)幫助!詳情查看->極客星球

    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 求點(diǎn)贊,在看,分享三連

    的昂貴性能開(kāi)銷。

    但是,操作系統(tǒng)被旁路(繞過(guò))之后,它的應(yīng)用隔離(application isolation) 和安全機(jī)制(security mechanisms)就都失效了;一起失效的還有各種經(jīng)過(guò)已經(jīng) 充分測(cè)試的配置、部署和管理工具。

    為解決這個(gè)問(wèn)題,我們提出一種新的可編程包處理方式:eXpress Data Path (XDP)。

    • XDP 提供了一個(gè)仍然基于操作系統(tǒng)內(nèi)核的安全執(zhí)行環(huán)境,在設(shè)備驅(qū)動(dòng)上下文?(device driver context)中執(zhí)行,可用于定制各種包處理應(yīng)用。

    • XDP 是主線內(nèi)核(mainline Linux kernel)的一部分,與現(xiàn)有的內(nèi)核 網(wǎng)絡(luò)棧(kernel’s networking stack)完全兼容,二者協(xié)同工作。

    • XDP 應(yīng)用(application)通過(guò) C 等高層語(yǔ)言編寫(xiě),然后編譯成特定字節(jié)碼;出于安 全考慮,內(nèi)核會(huì)首先對(duì)這些字節(jié)碼執(zhí)行靜態(tài)分析,然后再將它們翻譯成?處理器原生指令(native instructions)。

    • 測(cè)試結(jié)果顯示,XDP 能達(dá)到?24Mpps/core?的處理性能。

    為展示 XDP 靈活的編程模型,本文還將給出三個(gè)程序示例,

  • layer-3 routing(三層路由轉(zhuǎn)發(fā)

  • inline DDoS protection(DDoS 防護(hù)

  • layer-4 load balancing(四層負(fù)載均衡

  • 1 引言

    軟件實(shí)現(xiàn)高性能包處理的場(chǎng)景,對(duì)每個(gè)包的處理耗時(shí)有著極高的要求。通用目的操作系統(tǒng)中 的網(wǎng)絡(luò)棧更多是針對(duì)靈活性的優(yōu)化,這意味著它們花在每個(gè)包上 的指令太多了,不適合網(wǎng)絡(luò)高吞吐的場(chǎng)景。

    因此,隨后出現(xiàn)了一些專門(mén)用于包處理的軟件開(kāi)發(fā)工具,例如 Data Plane Development Kit (DPDK) [16]。這些工具一般都會(huì)完全繞過(guò)內(nèi)核,將網(wǎng)絡(luò)硬件直接交 給用戶態(tài)的網(wǎng)絡(luò)應(yīng)用,并需要獨(dú)占一個(gè)或多個(gè) CPU。

    1.1 現(xiàn)有方案(kernel bypass)存在的問(wèn)題

    內(nèi)核旁路方式可以顯著提升性能,但缺點(diǎn)也很明顯:

    • 很難與現(xiàn)有系統(tǒng)集成;

    • 上層應(yīng)用必須要將內(nèi)核中已經(jīng)非常成熟的模塊在用戶態(tài)重新實(shí)現(xiàn)一遍,例如路由表、高層協(xié)議棧等;

    • 最壞的情況下,這種包處理應(yīng)用只能工作在一個(gè)完全隔絕的環(huán)境,因?yàn)閮?nèi)核提供的常見(jiàn)工具和部署方式在這種情況下都不可用了。

    • 導(dǎo)致系統(tǒng)越來(lái)越復(fù)雜,而且破壞了操作系統(tǒng)內(nèi)核在把控的安全邊界。?在基礎(chǔ)設(shè)施逐漸遷移到 Kubernetes/Docker 等容器環(huán)境的背景下,這一點(diǎn)顯得尤其嚴(yán)重, 因?yàn)樵谶@種場(chǎng)景下,內(nèi)核擔(dān)負(fù)著資源抽象和隔離的重任。

    1.2 新方案:給內(nèi)核網(wǎng)絡(luò)棧添加可編程能力

    對(duì)此,本文提供了另一種解決方案:給內(nèi)核網(wǎng)絡(luò)棧添加可編程能力。這使得我們能在?兼容各種現(xiàn)有系統(tǒng)、復(fù)用已有網(wǎng)絡(luò)基礎(chǔ)設(shè)施的前提下,仍然實(shí)現(xiàn)高速包處理。?這個(gè)框架稱為XDP,

    • XDP定義了一個(gè)受限的執(zhí)行環(huán)境(a limited execution environment),運(yùn)行在一個(gè)?eBPF 指令虛擬機(jī)中。eBPF 是 BSD Packet Filter (BPF) [37] 的擴(kuò)展。

    • XDP 程序運(yùn)行在內(nèi)核上下文中,此時(shí)內(nèi)核自身都還沒(méi)有接觸到包數(shù)據(jù)( before the kernel itself touches the packet data),這使得我們能在網(wǎng)卡收到包后?最早能處理包的位置,做一些自定義數(shù)據(jù)包處理(包括重定向)。

    • 內(nèi)核在加載(load)時(shí)執(zhí)行靜態(tài)校驗(yàn),以確保用戶提供的 XDP 程序的安全。

    • 之后,程序會(huì)被動(dòng)態(tài)編譯成原生機(jī)器指令(native machine instructions),以獲得高性能。

    XDP已經(jīng)在過(guò)去的幾個(gè)內(nèi)核 release 中逐漸合并到內(nèi)核,但在本文之前,還沒(méi)有關(guān)于 XDP 系統(tǒng)的 完整架構(gòu)介紹。本文將對(duì) XDP 做一個(gè)高層介紹。

    1.3 新方案(XDP)的優(yōu)點(diǎn)

    我們的測(cè)試結(jié)果顯示 XDP 能取得?24Mpps/core?的處理性能,這雖然與 DPDK 還有差距, 但相比于后者這種 kernel bypass 的方式,XDP 有非常多的優(yōu)勢(shì)。

    本文是 2018 年的測(cè)試結(jié)果,更新的一些性能(及場(chǎng)景)對(duì)比可參考?(譯) 為容器時(shí)代設(shè)計(jì)的高級(jí) eBPF 內(nèi)核特性(FOSDEM, 2021)。?譯注。

    具體地,XDP

  • 與內(nèi)核網(wǎng)絡(luò)棧協(xié)同工作,將硬件的控制權(quán)完全留在內(nèi)核范圍內(nèi)。帶來(lái)的好處:

    • 保持了內(nèi)核的安全邊界

    • 無(wú)需對(duì)網(wǎng)絡(luò)配置或管理工具做任何修改

    無(wú)需任何特殊硬件特性,任何有 Linux 驅(qū)動(dòng)的網(wǎng)卡都可以支持, 現(xiàn)有的驅(qū)動(dòng)只需做一些修改,就能支持 XDP hooks。

    可以選擇性地復(fù)用內(nèi)核網(wǎng)絡(luò)棧中的現(xiàn)有功能,例如路由表或 TCP/IP 協(xié)議棧,在保持配置接口不變的前提下,加速關(guān)鍵性能路徑(critical performance paths)。

    保證 eBPF 指令集和 XDP 相關(guān)的編程接口(API)的穩(wěn)定性。

    與常規(guī) socket 層交互時(shí),沒(méi)有從用戶態(tài)將包重新注入內(nèi)核的昂貴開(kāi)銷。

    對(duì)應(yīng)用透明。這創(chuàng)造了一些新的部署場(chǎng)景/方式,例如直接在應(yīng)用所 在的服務(wù)器上部署 DoS 防御(而非中心式/網(wǎng)關(guān)式 DoS 防御)。

    服務(wù)不中斷的前提下動(dòng)態(tài)重新編程(dynamically re-program), 這意味著可以按需加入或移除功能,而不會(huì)引起任何流量中斷,也能動(dòng)態(tài)響應(yīng)系統(tǒng)其他部分的的變化。

    無(wú)需預(yù)留專門(mén)的 CPU 做包處理,這意味著 CPU 功耗與流量高低直接相關(guān),更節(jié)能。

    1.4 本文組織結(jié)構(gòu)

    接下來(lái)的內(nèi)容介紹 XDP 的設(shè)計(jì),并做一些性能分析。結(jié)構(gòu)組織如下:

    • Section 2?介紹相關(guān)工作;

    • Section 3?介紹 XDP 系統(tǒng)的設(shè)計(jì);

    • Section 4?做一些性能分析;

    • Section 5?提供了幾個(gè)真實(shí) XDP 場(chǎng)景的程序例子;

    • Section 6?討論 XDP 的未來(lái)發(fā)展方向;

    • Section 7?總結(jié)。

    2 相關(guān)工作

    XDP 當(dāng)然不是第一個(gè)支持可編程包處理的系統(tǒng) —— 這一領(lǐng)域在過(guò)去幾年發(fā)展勢(shì)頭良好, 并且趨勢(shì)還在持續(xù)。業(yè)內(nèi)已經(jīng)有了幾種可編程包處理框架,以及基于這些框架的新型應(yīng)用,包括:

    • 單一功能的應(yīng)用,如 switching [47], routing [19], named-based forwarding [28], classification [48], caching [33] or traffic generation [14]。

    • 更加通用、且高度可定制的包處理解決方案,能夠處理從多種源收來(lái)的數(shù)據(jù)包 [12, 20, 31, 34, 40, 44]。

    要基于通用(Common Off The Shelf,COTS)硬件實(shí)現(xiàn)高性能包處理,就必須解決?網(wǎng)卡(NIC)和包處理程序之間的所有瓶頸。由于性能瓶頸主要來(lái)源于內(nèi)核和用戶態(tài)應(yīng)用之 間的接口(系統(tǒng)調(diào)用開(kāi)銷非常大,另外,內(nèi)核功能豐富,但也非常復(fù)雜), 低層(low-level)框架必須通過(guò)這樣或那樣的方式來(lái)降低這些開(kāi)銷。

    現(xiàn)有的一些框架通過(guò)幾種不同的方式實(shí)現(xiàn)了高性能,XDP 構(gòu)建在其中一些技術(shù)之上。?接下來(lái)對(duì) XDP 和它們的異同做一些比較分析。

    2.1 用戶態(tài)輪詢 vs. XDP

    • DPDK?[16] 可能是使用最廣泛的高性能包處理框架。它最初只支持 Intel 網(wǎng)卡,后來(lái)逐 步擴(kuò)展到其他廠商的網(wǎng)卡。DPDK 也稱作內(nèi)核旁路框架(kernel bypass framework), 因?yàn)樗鼘⒕W(wǎng)絡(luò)硬件的控制權(quán)從內(nèi)核轉(zhuǎn)移到了用戶態(tài)的網(wǎng)絡(luò)應(yīng)用,完全避免了內(nèi)核-用戶態(tài) 之間的切換開(kāi)銷。

    • 與DPDK類似的還有PF_RING ZC module [45] 和 hardware-specific Solarflare OpenOnload [24]。

    在現(xiàn)有的所有框架中,內(nèi)核旁路方式性能是最高的?[18];但如引言中指 出,這種方式在管理、維護(hù)和安全方面都存在不足。

    XDP 采用了一種與內(nèi)核旁路截然相反的方式:相比于將網(wǎng)絡(luò)硬件的控制權(quán)上移到用戶空間, XDP 將性能攸關(guān)的包處理操作直接放在內(nèi)核中,在操作系統(tǒng)的網(wǎng)絡(luò)棧之前執(zhí)行。

    • 這種方式同樣避免了內(nèi)核-用戶態(tài)切換開(kāi)銷(所有操作都在內(nèi)核),

    • 但仍然由內(nèi)核來(lái)管理硬件,因此保留了操作系統(tǒng)提供的管理接口和安全防護(hù)能力。

      這里的主要?jiǎng)?chuàng)新是:使用了一個(gè)虛擬執(zhí)行環(huán)境,它能對(duì)加載的 程序進(jìn)行校驗(yàn),確保它們不會(huì)對(duì)內(nèi)核造成破壞。

    2.2 內(nèi)核模塊 vs. XDP

    在 XDP 之前,以內(nèi)核模塊(kernel module)方式實(shí)現(xiàn)包處理功能代價(jià)非常高, 因?yàn)槌绦驁?zhí)行出錯(cuò)時(shí)可能會(huì)導(dǎo)致整個(gè)系統(tǒng)崩潰,而且內(nèi)核的內(nèi)部 API 也會(huì)隨著時(shí)間發(fā)生變化。?因此也就不難理解為什么只有很少的系統(tǒng)采用了這種方式。其中做的比較好包括

    • 虛擬交換機(jī)?Open vSwitch [44]

    • Click [40]

    • 虛擬機(jī)路由器?Contrail [41]

    這幾個(gè)系統(tǒng)都支持靈活的配置,適用于多種場(chǎng)景,取得比較小的平攤代價(jià)。

    XDP通過(guò):

  • 提供一個(gè)安全的執(zhí)行環(huán)境,以及內(nèi)核社區(qū)支持,提供與那些暴露到用戶空間一樣穩(wěn)定的內(nèi)核 API

    極大地降低了那些將處理過(guò)程下沉到內(nèi)核的應(yīng)用(applications of moving processing into the kernel)的成本。

  • 此外,XDP 程序也能夠完全繞過(guò)內(nèi)核網(wǎng)絡(luò)棧(completely bypass), 與在內(nèi)核網(wǎng)絡(luò)棧中做 hook 的傳統(tǒng)內(nèi)核模塊相比,性能也更高。

  • XDP 除了能將處理過(guò)程下沉到內(nèi)核以獲得最高性能之外,還支持在程序中執(zhí)行重定向?(redirection)操作,完全繞過(guò)內(nèi)核網(wǎng)絡(luò)棧,將包送到特殊類型的用戶空間 socket;?甚至能工作在 zero-copy 模式,進(jìn)一步降低開(kāi)銷。

  • 這種模式與 Netmap [46] 和 PF_RING?[11] 方式類似,但后者是在沒(méi)有完全繞過(guò)內(nèi) 核的情況下,通過(guò)降低從網(wǎng)絡(luò)設(shè)備到用戶態(tài)應(yīng)用(network device to userspace application)之間的傳輸開(kāi)銷,實(shí)現(xiàn)高性能包處理。

  • 內(nèi)核模塊方式的另一個(gè)例子是 Packet I/O engine,這是 PacketShader [19] 的組成部分, 后者專用于 Arrakis [43] and ClickOS [36] 之類的特殊目的操作系統(tǒng)。

    2.3 可編程硬件 vs. XDP

    可編程硬件設(shè)備也是一種實(shí)現(xiàn)高性能包處理的方式。

    • 一個(gè)例子是?NetFPGA?[32],通過(guò)對(duì)它暴露的 API 進(jìn)行編程,能夠在這種基于 FPGA 的專 用設(shè)備上運(yùn)行任何包處理任務(wù)。

    • P4 編程語(yǔ)言 [7] 致力于將這種可編程能力擴(kuò)展到更廣泛的包處理硬件上?(巧合的是,它還包括了一個(gè) XDP backend [51])。

    某種意義上來(lái)說(shuō),XDP 可以認(rèn)為是一種?offload?方式:

  • 性能敏感的處理邏輯下放到網(wǎng)卡驅(qū)動(dòng)中,以提升性能;

  • 其他的處理邏輯仍然走內(nèi)核網(wǎng)絡(luò)棧;

  • 如果沒(méi)有用到內(nèi)核 helper 函數(shù),那整個(gè) XDP 程序都可以 offload 到網(wǎng)卡(目前 Netronome smart-NICs [27] 已經(jīng)支持)。

  • 2.4 小結(jié)

    XDP 提供了一種高性能包處理方式,與已有方式相比,在性能、與現(xiàn)有系統(tǒng)的集成、靈活性 等方面取得了更好的平衡。接下來(lái)介紹 XDP 是如何取得這種平衡的。

    3 XDP 設(shè)計(jì)

    XDP 的設(shè)計(jì)理念:

    • 高性能包處理

    • 集成到操作系統(tǒng)內(nèi)核(kernel)并與之協(xié)同工作,同時(shí)

    • 確保系統(tǒng)其它部分的安全性(safety)完整性(integrity)

    這種與內(nèi)核的深度集成顯然會(huì)給設(shè)計(jì)帶來(lái)一些限制,在 XDP 組件合并到 Linux 的過(guò)程中,我們也收到了許多來(lái)自社區(qū)的反饋,促使我們不斷調(diào)整 XDP 的設(shè)計(jì),但 這些設(shè)計(jì)反思不在本文討論范圍之內(nèi)。

    3.0 XDP 系統(tǒng)架構(gòu)

    圖 1 描繪了整個(gè) XDP 系統(tǒng),四個(gè)主要組成部分:

  • XDP driver hook:XDP 程序的主入口,在網(wǎng)卡收到包執(zhí)行。

  • eBPF virtual machine:執(zhí)行 XDP 程序的字節(jié)碼,以及對(duì)字節(jié)碼執(zhí)行 JIT 以提升性能。

  • BPF maps:內(nèi)核中的 key/value 存儲(chǔ),作為圖中各系統(tǒng)的主要通信通道。

  • eBPF verifier:加載程序時(shí)對(duì)其執(zhí)行靜態(tài)驗(yàn)證,以確保它們不會(huì)導(dǎo)致內(nèi)核崩潰。

  • Fig 1. XDP 與 Linux 網(wǎng)絡(luò)棧的集成。這里只畫(huà)了 ingress 路徑,以免圖過(guò)于復(fù)雜。

    上圖是 ingress 流程。網(wǎng)卡收到包之后,在處理包數(shù)據(jù)(packet data)之前,會(huì)先執(zhí)行 main XDP hook 中的 eBPF 程序。?這段程序可以選擇:

  • 丟棄(drop)這個(gè)包;或者

  • 通過(guò)當(dāng)前網(wǎng)卡將包再發(fā)送(send)出去;或者

  • 將包重定向(redirect)到其他網(wǎng)絡(luò)接口(包括虛擬機(jī)的虛擬網(wǎng)卡),或者通過(guò) AF_XDP socket 重定向到用戶空間;或者

  • 放行(allow)這個(gè)包,如果后面沒(méi)有其他原因?qū)е碌?drop,這個(gè)包就會(huì)進(jìn)入常規(guī)的內(nèi)核網(wǎng)絡(luò)棧。

    如果是這種情況,也就是放行包進(jìn)入內(nèi)核網(wǎng)絡(luò)棧,那接下來(lái)在將包放到發(fā)送隊(duì)列之前(before packets are queued for transmission), 還有一個(gè)能執(zhí)行 BPF 程序的地方:TC BPF hook。

    更多信息,可參考?(譯) [論文] 邁向完全可編程 tc 分類器(cls_bpf)(NetdevConf,2016)。?譯注。

  • 此外,圖 1 中還可以看出,不同的 eBPF 程序之間、eBPF 程序和用戶空間應(yīng)用之間,都能夠通過(guò) BPF maps 進(jìn)行通信。

    3.1 XDP driver hook

    在設(shè)備驅(qū)動(dòng)中執(zhí)行,無(wú)需上下文切換

    XDP 程序在網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)中執(zhí)行,網(wǎng)絡(luò)設(shè)備每收到一個(gè)包,程序就執(zhí)行一次。

    相關(guān)代碼實(shí)現(xiàn)為一個(gè)內(nèi)核庫(kù)函數(shù)(library function),因此程序直接 在設(shè)備驅(qū)動(dòng)中執(zhí)行,無(wú)需切換到用戶空間上下文。

    在軟件最早能處理包的位置執(zhí)行,性能最優(yōu)

    回到上面圖 1 可以看到:程序在網(wǎng)卡收到包之后最早能處理包的位置?執(zhí)行 —— 此時(shí)內(nèi)核還沒(méi)有為包分配?struct sk_buff?結(jié)構(gòu)體, 也沒(méi)有執(zhí)行任何解析包的操作。

    XDP 程序典型執(zhí)行流

    下圖是一個(gè)典型的 XDP 程序執(zhí)行流:

    Fig 2. 典型 XDP 程序的執(zhí)行流。

    網(wǎng)卡收到一個(gè)包時(shí),XDP 程序依次執(zhí)行:

  • 提取包頭中的信息(例如 IP、MAC、Port、Proto 等),

    執(zhí)行到程序時(shí),系統(tǒng)會(huì)傳遞給它一個(gè)上下文對(duì)象(context object)作為參賽?(即?struct xdp_md *ctx,后面有例子),其中包括了指向原 始包數(shù)據(jù)的指針,以及描述這個(gè)包是從哪個(gè)網(wǎng)卡的哪個(gè)接口接收上來(lái)的等元數(shù)據(jù)字段。

  • 讀取或更新一些資源的元信息(例如更新統(tǒng)計(jì)信息);

    解析包數(shù)據(jù)之后,XDP 程序可以讀取?ctx?中的包元數(shù)據(jù)(packet metadata) 字段,例如從哪個(gè)網(wǎng)卡的哪個(gè)接口收上來(lái)的(ifindex)。除此之外,ctx 對(duì)象還允許 程序訪問(wèn)與包數(shù)據(jù)毗鄰的一塊特殊內(nèi)存區(qū)域(cb, control buffer), 在包穿越整個(gè)系統(tǒng)的過(guò)程中,可以將自定義的數(shù)據(jù)塞在這里。

    除了 per-packet metadata,XDP 程序還可以通過(guò) BPF map 定義和訪問(wèn)自己的持久數(shù)據(jù)?,以及通過(guò)各種 helper 函數(shù)訪問(wèn)內(nèi)核基礎(chǔ)設(shè)施。

    • BPF map 使 BPF 程序能與系統(tǒng)的其他部分之間通信;

    • Helpers 使 BPF 程序能利用到某些已有的內(nèi)核功能(例如路由表), 而無(wú)需穿越整個(gè)內(nèi)核網(wǎng)絡(luò)棧。

    如果有需要,對(duì)這個(gè)包進(jìn)行?rewrite header?操作,

    程序能修改包數(shù)據(jù)的任何部分,包括添加或刪除包頭。這使得 XDP 程序能執(zhí)行封裝/接封裝操作,以及重寫(xiě)(rewrite)地址字段然后轉(zhuǎn)發(fā)等操作。

    內(nèi)核 helper 函數(shù)各有不同用途,例如修改一個(gè)包之后,計(jì)算新的校驗(yàn)和(checksum)。

    進(jìn)行最后的判決(verdict),確定接下來(lái)對(duì)這個(gè)包執(zhí)行什么操作;

    判決結(jié)果包括:

    重定向功能的用途:

    這些不同的路徑,在圖 1 對(duì)應(yīng)的是幾條實(shí)線。

    將重定向判決(verdict)與重定向目標(biāo)(target)分開(kāi),使得重定向目標(biāo)類型很容易擴(kuò)展;?另外,由于重定向參數(shù)(目標(biāo))是通過(guò) BPF map 查詢的,因此無(wú)需修 改 XDP 程序,就能動(dòng)態(tài)修改重定向目標(biāo)。

    • 三種簡(jiǎn)單返回碼:丟棄這個(gè)包、通過(guò)接收時(shí)的網(wǎng)卡將包重新發(fā)送出去、允許這個(gè)包進(jìn)入內(nèi)核網(wǎng)絡(luò)棧;

    • 第四種返回碼 redirect:允許?XDP?程序指定網(wǎng)卡、CPU、用戶態(tài) socket?等,將包重定向過(guò)去。

  • 將原始包通過(guò)另一個(gè)網(wǎng)卡(包括虛擬機(jī)的虛擬網(wǎng)卡)發(fā)送出去;

  • 轉(zhuǎn)發(fā)給指定?CPU?做進(jìn)一步處理;

  • 轉(zhuǎn)發(fā)給?AF_XDP 類型的 socket?做進(jìn)一步處理;

  • 程序還能通過(guò)尾調(diào)用(tail call),將控制權(quán)交給另一個(gè) XDP 程序;?通過(guò)這種方式,可以將一個(gè)大程序拆分成幾個(gè)邏輯上的小程序(例如,根據(jù) IPv4/IPv6)。

    由于 XDP 程序可包含任意指令,因此前三步(讀取包數(shù)據(jù)、處理元數(shù)據(jù)、重寫(xiě)包數(shù)據(jù))?順序可以是任意的,而且支持多層嵌套。?但實(shí)際中為了獲得高性能,大部分情況下還是將執(zhí)行結(jié)構(gòu)組織成這順序的三步。

    3.2 eBPF 虛擬機(jī)

    XDP 程序在 Extended BPF (eBPF) 虛擬機(jī)中執(zhí)行。eBPF 是早期 BSD packet filter (BPF) [37] 的擴(kuò)展,后者在過(guò)去的幾十年中廣泛 應(yīng)用于各種包處理工具。

    BPF 使用?基于寄存器的(register-based) virtual machine 來(lái)描述?過(guò)濾動(dòng)作(filtering actions)。

    eBPF 虛擬機(jī)支持動(dòng)態(tài)加載(loading)和重加載(re-loading)程序,內(nèi)核管理所有 BPF 程序的生命周期。

    3.3 BPF maps

    eBPF 程序在觸發(fā)內(nèi)核事件時(shí)執(zhí)行(例如,觸發(fā) XDP 程序執(zhí)行的,是收包事件)。?程序每次執(zhí)行時(shí),初始狀態(tài)都是相同的(即程序是無(wú)狀態(tài)的),它們無(wú)法直接訪問(wèn)?內(nèi)核中的持久存儲(chǔ)(BPF map)。為此,內(nèi)核提供了訪問(wèn) BPF map 的?helper 函數(shù)。

    BPF map 是 key/value 存儲(chǔ),在加載 eBPF 程序時(shí)定義(defined upon loading an eBPF program)。

    用途:

  • 持久存儲(chǔ)。例如一個(gè) eBPF 程序每次執(zhí)行時(shí),都會(huì)從里面獲取上一次的狀態(tài)。

  • 用于協(xié)調(diào)兩個(gè)或多個(gè) eBPF 程序。例如一個(gè)往里面寫(xiě)數(shù)據(jù),一個(gè)從里面讀數(shù)據(jù)。

  • 用于用戶態(tài)程序和內(nèi)核 eBPF 程序之間的通信。

  • 3.4 eBPF verifier

    唯一加載入口:bpf()?系統(tǒng)調(diào)用

    由于 eBPF 代碼直接運(yùn)行在內(nèi)核地址空間,因此它能直接訪問(wèn) —— 也可 能是破壞 —— 任何內(nèi)存。為防止這種情況發(fā)生,內(nèi)核規(guī)定只能通過(guò)唯一入口(?bpf()?系統(tǒng)調(diào)用)加載 BPF 程序。

    加載 BPF 程序時(shí),位于內(nèi)核中的校驗(yàn)器首先會(huì)對(duì)字節(jié)碼程序進(jìn)行靜態(tài)分析,以確保

    • 程序中沒(méi)有任何不安全的操作(例如訪問(wèn)任意內(nèi)存),

    • 程序會(huì)終止(terminate)。通過(guò)下面這兩點(diǎn)來(lái)實(shí)現(xiàn):

      • 禁止循環(huán)操作

      • 限制程序最大指令數(shù)

    校驗(yàn)器工作原理:two-pass DAG

    校驗(yàn)器的工作原理:首先根據(jù)程序的控制流構(gòu)建一個(gè)有向無(wú)環(huán)圖(DAG), 然后對(duì) DAG 執(zhí)行如下校驗(yàn):

    • 首先,對(duì) DAG 進(jìn)行一次深度優(yōu)先搜索(depth-first search),以 確保它是無(wú)環(huán)的(acyclic),例如,沒(méi)有循環(huán),也不包含不支持或無(wú)法執(zhí)行到的指令。

    • 然后,再掃描一遍,這次會(huì)遍歷 DAG 的所有可能路徑。這次掃描的目的是:

      程序執(zhí)行?load?或?call?指令時(shí),如果參數(shù)不合法,就會(huì)在這里被拒絕。參數(shù)合法 性是通過(guò)在程序執(zhí)行期間跟蹤所有寄存器和棧變量的狀態(tài)(states of registers and stack variables)來(lái)實(shí)現(xiàn)的。

      • 確保程序的內(nèi)存訪問(wèn)都是安全的,

      • 調(diào)用?helper 函數(shù)時(shí)傳的參數(shù)類型是對(duì)的。

    內(nèi)存越界和空指針檢查:職責(zé)上移到程序自身/開(kāi)發(fā)者

    這種跟蹤寄存器狀態(tài)的機(jī)制是為了在無(wú)法預(yù)知內(nèi)存邊界的情況下,仍然確保程序 的內(nèi)存訪問(wèn)不會(huì)越界。無(wú)法預(yù)知內(nèi)存邊界是因?yàn)?#xff1a;

    • 包的大小是不固定的;

    • map 的內(nèi)容也無(wú)法提前預(yù)知,因此也無(wú)法判斷一次 map 查找操作是否會(huì)成功。

    為解決這個(gè)問(wèn)題,校驗(yàn)器會(huì)檢查已加載的程序自身是否會(huì)做如下檢查:

  • 解引用指針前做了內(nèi)存邊界檢查,

  • 查詢 map 之前是檢查了 map 指針是否為空。

  • 這種方式將處理邏輯中的安全檢查和遇到錯(cuò)誤時(shí)如何處理的控制權(quán)都?交給了 BPF 程序的編寫(xiě)者。

    跟蹤數(shù)據(jù)訪問(wèn)操作和值范圍

    為跟蹤數(shù)據(jù)訪問(wèn),校驗(yàn)器會(huì)跟蹤

  • 數(shù)據(jù)類型

  • 指針偏置(pointer offsets)

  • 所有寄存器的可能值范圍

  • 程序開(kāi)始時(shí):

    • R1?寄存器中存儲(chǔ)的是指向 context metadata 的指針(struct xdp_md *ctx),

    • R10?是棧指針(stack pointer),

    • 其他所有寄存器都是未初始化狀態(tài)。

    接下來(lái)程序每執(zhí)行一步,寄存器狀態(tài)就會(huì)更新一次。當(dāng)寄存器中存入一個(gè)新值時(shí),這個(gè)寄存器 還會(huì)繼承與這個(gè)值相關(guān)的狀態(tài)變量(inherits the state variables from the source of the value)。

    算術(shù)操作會(huì)影響標(biāo)量類型的值的范圍(value ranges of scalar types),以及指針類型的 offset。?可能的最大范圍(max possible range)存儲(chǔ)在狀態(tài)變量中,例如往寄存器中 load?一個(gè)字節(jié)時(shí), 這個(gè)寄存器的可能值范圍就設(shè)置為 0~255。指令圖(instruction graph)中的?各邏輯分支就會(huì)根據(jù)操作結(jié)果更新寄存器狀態(tài)。例如,比較操作 R1 > 10,

    • 校驗(yàn)器在一個(gè)分支?if R1 > 10?中會(huì)將 R1 最小值設(shè)為 11,

    • 在另一個(gè)?else?分支中將其最大值設(shè)為 10。

    不同類型數(shù)據(jù)的校驗(yàn)信息來(lái)源(source of truth)

    利用狀態(tài)變量中存儲(chǔ)的范圍信息,校驗(yàn)器就能預(yù)測(cè)每個(gè) load 指令能訪問(wèn)的所有 內(nèi)存范圍,確保它執(zhí)行的都是合法內(nèi)存訪問(wèn)。

  • 對(duì)于包數(shù)據(jù)(packet data)的訪問(wèn),會(huì)與 context 對(duì)象中的?data_end?變量做比較;

  • 對(duì)于?BPF?map 中獲取的值,或用到 map 定義中聲明的 data size 信息;

  • 對(duì)于棧上存儲(chǔ)的值,會(huì)檢查狀態(tài)變量中記錄的值范圍;

  • 對(duì)于指針?biāo)阈g(shù)操作(pointer arithmetic)還會(huì)施加額外的限制,指針通常不能被轉(zhuǎn)換成整形值。

  • 只要校驗(yàn)器無(wú)法證明某個(gè)操作是安全,該?BPF 程序在加載時(shí)(load time)就會(huì)被拒絕。?除此之外,校驗(yàn)器還會(huì)利用范圍信息確保內(nèi)存的對(duì)齊訪問(wèn)(enforce aligned memory access)。

    校驗(yàn)器的目的

    需要說(shuō)明的是,校驗(yàn)器的目的是避免將內(nèi)核內(nèi)部(the internals of the kernel )暴露給惡意或有缺陷的 eBPF 程序,而非確保程序中函數(shù)的實(shí)現(xiàn)已經(jīng)是最高效的。

    換句話說(shuō),如果 XDP 程序中處理邏輯過(guò)多,也可能會(huì)導(dǎo)致機(jī)器變慢 ;如果代碼寫(xiě)的有問(wèn)題,也可能會(huì)破壞包數(shù)據(jù)。出于這些原因,加載 BPF 程序需要 管理員權(quán)限(root)。避免這些 bug 的責(zé)任在程序員,但選擇將哪些程序加載 到系統(tǒng)的權(quán)限在管理員。

    3.5 XDP 程序示例

    下面是一個(gè)簡(jiǎn)單的 XDP 程序,展示了前面介紹的一些特性。?程序會(huì)解析包數(shù)據(jù),判斷如果是 UDP 包,直接交換源和目的 MAC 地址,然后將包從相同網(wǎng)卡再發(fā)送回去,

    雖然這是一個(gè)非常簡(jiǎn)單的例子,但真實(shí)世界中的 XDP 程序用到的組件和特性,這里基本都具備了。

    // 從內(nèi)核 BPF 代碼示例 xdp2_kern.c 修改而來(lái)。1 // 用于統(tǒng)計(jì)包數(shù) 2 struct bpf_map_def SEC("maps") rxcnt = { 3 .type = BPF_MAP_TYPE_PERCPU_ARRAY, 4 .key_size = sizeof(u32), // IP 協(xié)議類型,即 IPv4/IPv6 5 .value_size = sizeof(long), // 包數(shù) 6 .max_entries = 256, 7 }; 8 9 // 直接操作包數(shù)據(jù)(direct packet data access),交換 MAC 地址 10 static void swap_src_dst_mac(void *data) 11 { 12 unsigned short *p = data; 13 unsigned short dst[3]; 14 dst[0] = p[0]; dst[1] = p[1]; dst[2] = p[2]; 15 p[0] = p[3]; p[1] = p[4]; p[2] = p[5]; 16 p[3] = dst[0]; p[4] = dst[1]; p[5] = dst[2]; 17 } 18 19 static int parse_ipv4(void *data, u64 nh_off, void *data_end) 20 { 21 struct iphdr *iph = data + nh_off; 22 if (iph + 1 > data_end) 23 return 0; 24 return iph->protocol; 25 } 26 27 SEC("xdp1") // marks main eBPF program entry point 28 int xdp_prog1(struct xdp_md *ctx) 29 { 30 void *data_end = (void *)(long)ctx->data_end; 31 void *data = (void *)(long)ctx->data; 32 struct ethhdr *eth = data; int rc = XDP_DROP; 33 long *value; u16 h_proto; u64 nh_off; u32 ipproto; 34 35 nh_off = sizeof(*eth); 36 if (data + nh_off > data_end) 37 return rc; 38 39 h_proto = eth->h_proto; 40 41 /* check VLAN tag; could be repeated to support double-tagged VLAN */ 42 if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) { 43 struct vlan_hdr *vhdr; 44 45 vhdr = data + nh_off; 46 nh_off += sizeof(struct vlan_hdr); 47 if (data + nh_off > data_end) 48 return rc; 49 h_proto = vhdr->h_vlan_encapsulated_proto; 50 } 51 52 if (h_proto == htons(ETH_P_IP)) 53 ipproto = parse_ipv4(data, nh_off, data_end); 54 else if (h_proto == htons(ETH_P_IPV6)) 55 ipproto = parse_ipv6(data, nh_off, data_end); 56 else 57 ipproto = 0; 58 59 /* lookup map element for ip protocol, used for packet counter */ 60 value = bpf_map_lookup_elem(&rxcnt, &ipproto); 61 if (value) 62 *value += 1; 63 64 /* swap MAC addrs for UDP packets, transmit out this interface */ 65 if (ipproto == IPPROTO_UDP) { 66 swap_src_dst_mac(data); 67 rc = XDP_TX; 68 } 69 return rc; 70 }

    具體地:

    • 定義了一個(gè) BPF map 存儲(chǔ)統(tǒng)計(jì)信息。用戶態(tài)程序可以 poll 這個(gè) map 來(lái)獲取統(tǒng)計(jì)信息。

    • context 對(duì)象?struct xdp_md *ctx?中有包數(shù)據(jù)的 start/end 指針,可用于直接訪問(wèn)包數(shù)據(jù)。

    • 將數(shù)據(jù)指針和?data_end?比較,確保內(nèi)存訪問(wèn)不會(huì)越界。

    • 程序必須自己解析包,包括 VLAN headers 等東西。

    • 直接通過(guò)指針(direct packet data access)修改包頭。

    • 內(nèi)核提供的 map lookup helper。這是程序中唯一的真實(shí)函數(shù)調(diào)用;其他函數(shù)都是內(nèi)聯(lián),包括?htons()。

    • 最終針對(duì)這個(gè)包的判決通過(guò)程序返回值傳遞給調(diào)用方。

    將這段程序安裝到網(wǎng)卡接口上時(shí),它首先會(huì)被編譯成 eBPF 字節(jié)碼,然后經(jīng)受校驗(yàn)器檢查。?這里的檢查項(xiàng)包括:

  • 無(wú)循環(huán)操作;程序大小(指令數(shù)量);

  • 訪問(wèn)包數(shù)據(jù)之前,做了內(nèi)存邊界檢查;

  • 傳遞給 map lookup 函數(shù)的參數(shù),類型與 map 定義相匹配;

  • map lookup 的返回值(value 的內(nèi)存地址)在使用之前,檢查了是否為 NULL。

  • 3.6 小結(jié)

    XDP 系統(tǒng)由四個(gè)主要部分組成:

  • XDP device driver hook:網(wǎng)卡收到包之后直接運(yùn)行;

  • eBPF 虛擬機(jī):執(zhí)行 XDP 程序(以及內(nèi)核其他模塊加載的 BPF 程序);

  • BPF maps:使不同 BPF 程序之間、BPF 程序與用戶空間應(yīng)用之間能夠通信;

  • eBPF verifier:確保程序不包含任何可能會(huì)破壞內(nèi)核的操作。

  • 這四部分加在一起,創(chuàng)造了一個(gè)編寫(xiě)自定義包處理應(yīng)用的強(qiáng)大環(huán)境,它能加速包處理的關(guān)鍵 路徑,同時(shí)還與內(nèi)核及現(xiàn)有基礎(chǔ)設(shè)施密切集成。

    接下來(lái)看一下 XDP 應(yīng)用的性能。

    4 性能評(píng)估

    DPDK 是目前性能最高的包處理框架 [18],因此本文將 XDP 與 DPDK 及 Linux 內(nèi)核網(wǎng)絡(luò) 棧的性能做一個(gè)對(duì)比。測(cè)試機(jī)器環(huán)境:

    • CPU:一塊 hexa-core Intel Xeon E5-1650 v4 CPU running at 3.60GHz, 支持 Intel Data Direct I/O (DDIO) 技術(shù),網(wǎng)絡(luò)硬件通過(guò) DMA 能直接將包放到 CPU 緩存。

    • 關(guān)閉超線性(Hyperthreading)。

    • 網(wǎng)卡:兩塊?Mellanox ConnectX-5 Ex VPI dual-port 100Gbps,mlx5 驅(qū)動(dòng)。

    • 內(nèi)核:Linux 4.18

    • 使用基于 DPDK 的 TRex packet generator [9] 生成測(cè)試流量。所有測(cè)試腳本位于 [22]。

    在測(cè)試中,我們主要關(guān)心三個(gè) metric:

    • 直接棄包(packet drop)性能。

      為展示最高的包處理性能,我們將用最簡(jiǎn)單的操作 ——?丟棄接收到的包?—— 來(lái)測(cè)試。?這個(gè)測(cè)試能有效測(cè)量系統(tǒng)的整體開(kāi)銷,也是真正的包處理應(yīng)用能達(dá)到的性能上限。

    • CPU 使用量。

      如引言中指出,XDP 的優(yōu)點(diǎn)之一是 CPU 使用量與流量大小是正相關(guān)的,而無(wú)需預(yù)留專 門(mén)的 CPU 給它用。我們通過(guò)測(cè)量 CPU 利用率隨網(wǎng)絡(luò)負(fù)載的變化來(lái)量化這個(gè)指標(biāo)。

    • 包轉(zhuǎn)發(fā)性能。

      轉(zhuǎn)發(fā)的復(fù)雜性要更高一些,例如,涉及到與多塊網(wǎng)卡的交互、重寫(xiě)二層頭等等。?這里會(huì)將轉(zhuǎn)發(fā)延遲也考慮進(jìn)去。

    我們已經(jīng)驗(yàn)證,使用 MTU(1500 字節(jié))包時(shí),我們的系統(tǒng)單核就能達(dá)到線速(100 Gbps), 而且 CPU 有 50% 是空閑的。顯然,真正的挑戰(zhàn)在于 PPS,而非帶寬,其他一些測(cè)試也已經(jīng)指出了這一點(diǎn) [46]。?出于這個(gè)原因,我們用最小包(64 字節(jié))測(cè)試,衡量指標(biāo)是 PPS。

    對(duì)于 XDP 和 Linux 內(nèi)核網(wǎng)絡(luò)棧的測(cè)試,由于它們沒(méi)有顯式指定某些 CPU 來(lái)處理網(wǎng)絡(luò)包的方式,因此我們通過(guò)配置硬件 RSS(Receive Side Scaling)來(lái)講流量定向到指定 CPU。

    對(duì)網(wǎng)卡、內(nèi)核的一些配置調(diào)優(yōu),見(jiàn)代碼倉(cāng)庫(kù) [22]。

    4.1 直接棄包(packet drop)性能

    Fig 3. 直接棄包(packet drop)性能。DPDK 需要預(yù)留一個(gè) CPU 運(yùn)行控制任務(wù),因此只剩下 5 個(gè) CPU 做包處理。

    上圖是性能與 CPU 數(shù)量的關(guān)系。

    • XDP 基準(zhǔn)性能是?24Mpps/core,DPDK 是?43.5Mpps/core。

    • 二者在分別達(dá)到各自的峰值之前,PPS 都是隨 CPU 數(shù)量線性增長(zhǎng)的。

    • 最終全局性能受限于 PCI 總線,啟用 PCI descriptor compression(在 CPU cycles 和 PCI 總線帶寬之間取舍)之后,能達(dá)到 115Mpps。

    再看圖中 Linux 網(wǎng)絡(luò)棧在兩種配置下的性能:

  • 通過(guò)?iptables 的 raw table?丟棄流量,這是?Linux 網(wǎng)絡(luò)棧中最早能丟棄包的地方;

  • 通過(guò)?conntrack(連接跟蹤)模塊,這個(gè)模塊的開(kāi)銷非常大,但在很多 Linux 發(fā)行版中都是默認(rèn)開(kāi)啟的。

  • conntrack 模式達(dá)到了 1.8Mpps/core,raw 模式是 4.8Mpps/core ;這兩種模式均未達(dá)到硬件瓶頸。?最終的性能,XDP 比常規(guī)網(wǎng)絡(luò)棧的最快方式快了 5 倍。

    Linux raw mode test 中,我們還測(cè)量了 XDP 程序不丟棄包,而是更新包數(shù)統(tǒng)計(jì)然后將包 送到內(nèi)核網(wǎng)絡(luò)棧的場(chǎng)景。?這種情況下,XDP 單核的處理性能會(huì)下降到 4.5Mpps/core,有 13.3ns 處理延遲。?圖中并未給出這個(gè)測(cè)試結(jié)果,因?yàn)檫@個(gè)開(kāi)銷太小了。

    4.2 CPU Usage

    Fig 4. 直接棄包(packet drop)場(chǎng)景下的 CPU 利用率。

    用系統(tǒng)提供的?mpstat?命令測(cè)量 CPU 利用率。結(jié)果如圖 4 。

    • DPDK 是 busy poll 模式,因此 CPU 永遠(yuǎn)是 100%。

    • XDP 和 Linux 內(nèi)核網(wǎng)絡(luò)棧都是隨流量平滑增長(zhǎng):前面一小段是非線性的,后面基本是線性的。

      前面非線性主要是硬中斷帶來(lái)的固定開(kāi)銷,在流量很小時(shí)這一部分占比較大。

    4.3 包轉(zhuǎn)發(fā)性能

    這個(gè)測(cè)試中,轉(zhuǎn)發(fā)應(yīng)用執(zhí)行非常簡(jiǎn)單的 MAC 地址重寫(xiě):直接交換源和目的 MAC 地址,然后轉(zhuǎn)發(fā)。?這是轉(zhuǎn)發(fā)場(chǎng)景下最精簡(jiǎn)的步驟了,因此結(jié)果代表了所有真實(shí)轉(zhuǎn)發(fā)應(yīng)用的性能上限。

    • 圖中包括了同網(wǎng)卡轉(zhuǎn)發(fā)和不同網(wǎng)卡轉(zhuǎn)發(fā)(XDP?程序返回碼不同)的結(jié)果。

    • DPDK 示例程序只支持通過(guò)另一個(gè)網(wǎng)卡轉(zhuǎn)發(fā),因此這里只列出了這種情況下的性能。

    • Linux 網(wǎng)絡(luò)棧不支持這種極簡(jiǎn)轉(zhuǎn)發(fā)模式(minimal forwarding mode),需要設(shè)置完整的 橋接或路由查找(bridging or routing lookup)才能轉(zhuǎn)發(fā)包;路由查找是非常耗時(shí)的 ,由于其他幾種應(yīng)用并沒(méi)有這一步,因此結(jié)果直接對(duì)比是沒(méi)意義的。因此這里略去了 Linux 網(wǎng)絡(luò)棧的結(jié)果。

    轉(zhuǎn)發(fā)吞吐(pps)

    Fig 5. 轉(zhuǎn)發(fā)性能。在同一網(wǎng)卡接口上收發(fā)會(huì)占用同一 PCI port 的帶寬, 這意味著在 70Mpps XDP same-nic 組就已經(jīng)達(dá)到了 PCI 總線的瓶頸

    如圖 5 所示,性能隨 CPU 數(shù)量線性擴(kuò)展,直到達(dá)到全局性能瓶頸。XDP 在同網(wǎng)卡轉(zhuǎn)發(fā)的性能遠(yuǎn)高于 DPDK 異網(wǎng)卡性能,原因是內(nèi)存處理方式不同:

    • packet buffer 是設(shè)備驅(qū)動(dòng)分配的,與接收接口(receiving interface)相關(guān)聯(lián)。

    • 因此,異網(wǎng)卡場(chǎng)景下,當(dāng)包轉(zhuǎn)發(fā)到另一個(gè)接口時(shí),memory buffer 需要還給與之關(guān)聯(lián)的接口。

    轉(zhuǎn)發(fā)延遲

    表 1. 轉(zhuǎn)發(fā)延遲。機(jī)器網(wǎng)卡的兩個(gè)接口直連,在轉(zhuǎn)發(fā)速率分別為 100pps 和 1Mpps 的條件下,持續(xù) 50s 測(cè)量端到端延遲

    高 pps 場(chǎng)景下,XDP 的延遲已經(jīng)接近 DPDK。但在低 pps 場(chǎng)景下,XDP 延遲比 DPDK 大的多,原因是?XDP 是基于中斷的,中斷處理時(shí)間( interrupt processing time)此時(shí)占大頭;而 DPDK 是輪詢模式,延遲相對(duì)比較固定。

    4.4 討論:XDP 性能與 DPDK 還有差距的原因

    XDP 未做底層代碼優(yōu)化

    上一節(jié)已經(jīng)看到,XDP 相比于常規(guī) Linux 網(wǎng)絡(luò)棧性能有了顯著提升。但對(duì)于大部分 XDP 場(chǎng)景來(lái)說(shuō),性能還是與 DPDK 有差距。我們認(rèn)為,這是主要是因?yàn)?DPDK 做了相當(dāng)多的底層 代碼優(yōu)化。舉個(gè)例子來(lái)解釋,考慮 packet drop 例子:

    • XDP 24Mpps/core,對(duì)應(yīng)?41.6ns/packet

    • DPDK 43.5Mpps,對(duì)應(yīng)?22.9ns/packet

    多出來(lái)的 18.7ns 在我們的 3.6GHz 機(jī)器上對(duì)應(yīng) 67 個(gè)時(shí)鐘周期。因此,很顯然?每個(gè)很小的優(yōu)化在這里都會(huì)產(chǎn)生很大的影響。例如,我們測(cè)量出在測(cè)試 機(jī)器上,每次函數(shù)調(diào)用需要 1.3ns。mlx5 驅(qū)動(dòng)處理每個(gè)包都有 10 次 函數(shù)調(diào)用,總計(jì)就是 13ns。

    通用目的操作系統(tǒng),首要目標(biāo):更好的擴(kuò)展和配置,而非極致性能

    另外,在 Linux 這樣的通用目的操作系統(tǒng)中,某些開(kāi)銷是不可避免的, 因?yàn)樵O(shè)備驅(qū)動(dòng)或子系統(tǒng)的組織方式是為了實(shí)現(xiàn)更好的擴(kuò)展和配置,而非極致性能。

    但是,我們認(rèn)為有些優(yōu)化還是有必要的。例如,我們嘗試將內(nèi)核中與測(cè)試網(wǎng)卡無(wú)關(guān)的 DMA 函數(shù)調(diào)用刪掉, 這樣將前面提到的 10 個(gè)函數(shù)調(diào)用降低到了 6 個(gè),測(cè)試結(jié)果顯示這將單核性能提升到了 29Mpps/core。?依此推測(cè)的話,將另外 6 個(gè)函數(shù)調(diào)用也優(yōu)化掉,能將 XDP 的性能提升到?37.6Mpps。?實(shí)際上我們不可能將 6 個(gè)全部去掉,但去掉其中幾個(gè),再加上一些其他優(yōu)化,我 們相信 XDP 和 DPDK 的性能差距將越來(lái)越小。

    其他驅(qū)動(dòng)的測(cè)試結(jié)果也是類似的,例如 i40e driver for 40 Gbps Intel cards。

    基于以上討論,我們相信未來(lái) XDP 與 DPDK 的性能差距將越來(lái)越小。

    另一方面,考慮到 XDP 在靈活性和與內(nèi)核集成方面的優(yōu)勢(shì), XDP 已經(jīng)是很多實(shí)際場(chǎng)景中的非常有競(jìng)爭(zhēng)力的方式。下文給出幾個(gè)例子。

    5 真實(shí)場(chǎng)景使用案例

    本節(jié)給出三個(gè)例子來(lái)具體展示 XDP 在真實(shí)世界中的應(yīng)用。?這幾個(gè)案例都是已經(jīng)真實(shí)在用的,但本文出于解釋目的,將使用簡(jiǎn)化的版本。?同時(shí)也建議讀者參考 [38],后者是獨(dú)立的文章,介紹使用 XDP 解決實(shí)際工作中網(wǎng)絡(luò)服務(wù)所面臨的一些挑戰(zhàn)。

    本節(jié)目的是展示真實(shí) XDP 方案的可行性,因此不會(huì)將重點(diǎn)放在與業(yè)界最新的實(shí)現(xiàn)做詳盡性能對(duì)比上。?我們會(huì)拿常規(guī)的 Linux 內(nèi)核網(wǎng)絡(luò)棧的性能作為 baseline,來(lái)對(duì)比 XDP 應(yīng)用的性能。

    5.1 案例一:軟件路由(software routing)

    內(nèi)核數(shù)據(jù)平面 & 控制平面(BIRD/FRR)

    Linux 內(nèi)核實(shí)現(xiàn)了一個(gè)功能完整的路由表,作為數(shù)據(jù)平面,支持

    • policy routing

    • source-specific routing

    • multipath load balancing, and more.

    對(duì)于控制平面,Bird [10] 或 FRR [17] 這樣的路由守護(hù)進(jìn)程( routing daemons)實(shí)現(xiàn)了多種路由控制平面協(xié)議。Linux 提供的這套生態(tài)系統(tǒng)功能如此豐富 ,因此再在另一個(gè)包處理框架中重新實(shí)現(xiàn)一套類似的路由棧代價(jià)將非常高, 更實(shí)際的方式是對(duì) Linux 內(nèi)核的數(shù)據(jù)平面進(jìn)行優(yōu)化。

    XDP:直接查詢內(nèi)核路由表并轉(zhuǎn)發(fā)

    XDP 非常適合做這件事情,尤其是它提供了一個(gè) helper 函數(shù),能從 XDP 程序中直接查詢內(nèi)核路由表。

    • 如果查詢成功,會(huì)返回?egress interface 和下一跳 MAC 地址, XDP 程序利用這些信息足夠?qū)⒓崔D(zhuǎn)發(fā)出去。

    • 如果下一跳 MAC 還是未知的(因?yàn)橹斑€沒(méi)進(jìn)行過(guò) neighbour lookup),XDP 程序就 能將包傳給內(nèi)核網(wǎng)絡(luò)棧,后者會(huì)解析 neighbor 地址,這樣隨后的包 就能直接被 XDP 程序轉(zhuǎn)發(fā)了。

    測(cè)試:XDP routing + 全球 BGP 路由表

    為展示 XDP 路由的性能,我們用 Linux 內(nèi)核代碼中的 XDP routing 例子 [1],與常規(guī) Linux 內(nèi)核網(wǎng)絡(luò)棧的性能做對(duì)比。?兩組測(cè)試:

  • 路由表中只有一條路由;

  • 路由表中有從 routeviews.org 中 dump 而來(lái)的全球 BGP 路由表(global BGP routing table)。?包含 752,138 條路由。隨機(jī)生成 4000 個(gè)目的 IP 地址,以確保能充分利用到這種路由表。

    如果目的 IP 地址少于 4000 個(gè),實(shí)際用到的路由表部分會(huì)較小,能夠保存在 CPU 緩存中,使得結(jié)果不準(zhǔn)確。?增大 IP 數(shù)量至 4000 個(gè)以上,不會(huì)對(duì)轉(zhuǎn)發(fā)性能造成影響,但可以避免緩存導(dǎo)致的結(jié)果不準(zhǔn)問(wèn)題。

  • 對(duì)于兩組測(cè)試,下一跳 MAC 地址都是與我們的發(fā)送網(wǎng)卡直接相關(guān)的接口的地址。

    性能:2.5x

    Fig 6. 軟件路由的性能。由于性能隨核數(shù)線性增加,這里只給出單核的結(jié)果。

    測(cè)試結(jié)果如上圖所示。

    • full table lookup 性能提升了 2.5 倍;

    • smaller routing table 組,提升了 3 倍。

    這說(shuō)明,XDP 路由程序 + 單核 + 10Gbps 網(wǎng)卡?的軟硬件配置,就能?處理整張全球 BGP 路由表(保守估計(jì)每個(gè)包平均 300 字節(jié))。

    5.2 案例二:Inline DoS Mitigation

    DoS 攻擊還是像瘟疫一樣糾纏著互聯(lián)網(wǎng),現(xiàn)在通常的方式是:通過(guò)已經(jīng)入侵的大量設(shè)備發(fā)起分布式(DDoS)攻擊。

    有了XDP 之后,我們能直接在應(yīng)用服務(wù)器(application servers)上?部署包過(guò)濾程序來(lái)防御此類攻擊(inline DoS mitigation),?無(wú)需修改應(yīng)用代碼。如果應(yīng)用是部署在虛擬機(jī)里,那 XDP 程序還可以 部署在宿主機(jī)(hypervisor)上,這樣單個(gè)程序就能保護(hù)機(jī)器上所有的虛擬機(jī)。

    模擬 Cloudflare 防御架構(gòu)

    為展示工作原理,我們用 XDP 作為過(guò)濾機(jī)制,模擬 Cloudflare 的 DDoS 防御架構(gòu)?[6]。?他們的 Gatebot architecture ,首先在各 PoP 點(diǎn)機(jī)器上采樣,然后統(tǒng)一收起來(lái)做分析, 根據(jù)分析結(jié)果生成防御規(guī)則。

    防御規(guī)則的形式是對(duì)包數(shù)據(jù)(payload)進(jìn)行一系列簡(jiǎn)單檢查, 能直接編譯成 eBPF 代碼然后分發(fā)到 PoP 點(diǎn)的所有服務(wù)器上。這里說(shuō)的代碼是 XDP 程序 ,它會(huì)將匹配到規(guī)則的所有流量丟棄,同時(shí)將統(tǒng)計(jì)信息更新到 BPF map。

    程序邏輯

    為驗(yàn)證這種方案的性能,我們編寫(xiě)一個(gè) XDP 程序,它

  • 解析包頭,執(zhí)行一些簡(jiǎn)單驗(yàn)證。對(duì)每個(gè)包:執(zhí)行四次讀取操作,以解析外層包頭。

  • 將符合攻擊特性的流量丟棄。具體:丟棄 UDP + 特定端口的流量。

  • 將其他流量通過(guò) CPU redirect 方式重定向給另一個(gè) CPU?做進(jìn)一步處理;

  • 性能

    我們用 netperf 做性能壓測(cè) [26]。

    • 用 netperf TCP round-trip benchmark,單個(gè) TCP 連接來(lái)回小的 request/reply,統(tǒng)計(jì) transactions/second。

      模擬的是交互式應(yīng)用,例如小的遠(yuǎn)程過(guò)程調(diào)用(RPC)。

    • 實(shí)驗(yàn)在單核上進(jìn)行,模擬多個(gè)流量(正常流量+攻擊流量)競(jìng)爭(zhēng)同一物理資源的場(chǎng)景。

    • 在?beseline 35K 業(yè)務(wù) TPS(transactions per second)基礎(chǔ)上,打少量 UDP 流量作為攻擊流量。逐漸加大攻擊流量,觀察 TPS 的變化。

    Fig 7. DDoS 性能。業(yè)務(wù)吞吐(TPS)隨攻擊流量的變化。

    結(jié)果如上圖所示,

    • 沒(méi)有 XDP 的一組,性能急劇下降:攻擊流量在 3Mpps 時(shí)性能減半,3.5Mpps 時(shí)基本跌零;

    • 有 XDP 程序的一組,攻擊流量達(dá)到 19.5Mpps 之前,業(yè)務(wù)吞吐保持在 28.5K TPS 以上,過(guò)了這個(gè)臨界點(diǎn)性能才開(kāi)始急劇下降。

    以上結(jié)果表明,XDP 防御 DDoS 攻擊在實(shí)際中是完全可行的,單核就能輕松處理 10Gbps 的、都是最小包(minimum-packet)的 DoS 流量。?這種 DDoS 防御的部署更加靈活,無(wú)需硬件或應(yīng)用做任何改動(dòng)。

    5.3 案例三:負(fù)載均衡(load balancing)

    Facebook Katran

    負(fù)載均衡的場(chǎng)景,我們用 Facebook 開(kāi)源的 Katran 作為例子 [15]。Katran 的工作原理是對(duì)外通告服務(wù)的 IP,這樣目標(biāo)是這個(gè) IP 的流量就會(huì)被路由到 XDP 實(shí)現(xiàn)的負(fù)載均衡器。

    • 負(fù)載均衡器對(duì)包頭(source packet header)進(jìn)行哈希,以此選擇目標(biāo)應(yīng)用服務(wù)器。

    • 然后將對(duì)包進(jìn)行封裝(encap),發(fā)送給應(yīng)用服務(wù)器;

    • 應(yīng)用服務(wù)器解封裝(decap),處理請(qǐng)求,然后直接將回包發(fā)給客戶端(DSR 模式)。

    在這個(gè)過(guò)程中,XDP 程序負(fù)責(zé)哈希、封裝以及將包從接收網(wǎng)卡再發(fā)出去的任務(wù)。?配置信息存儲(chǔ)在 BPF map 中,整個(gè)封裝邏輯是完全在 eBPF 中實(shí)現(xiàn)的。

    性能

    為測(cè)試性能,我們給 Katran XDP 程序配置幾個(gè)固定的目標(biāo)機(jī)器。?對(duì)照組是 IPVS,它是 Linux 內(nèi)核的一部分。性能如表 2 所示,隨 CPU 數(shù)量線性增長(zhǎng), XDP 比 IPVS 性能高 4.3 倍。

    表 2. 負(fù)載均衡器性能(Mpps)

    配置:1 VIP/core, 100 DstIPs/VIP.

    6 XDP 的未來(lái)方向

    XDP 已經(jīng)能用于解決真實(shí)問(wèn)題,但作為 Linux 內(nèi)核的一部分,XDP 還在快速開(kāi)發(fā)過(guò)程中。

    6.1 eBPF 程序的限制

    前面提到,加載到 eBPF 虛擬機(jī)的程序必須保證其安全性(不會(huì)破壞內(nèi)核),因此對(duì) eBPF 程序作了一下限制,歸結(jié)為兩方面:

  • 確保程序會(huì)終止:在實(shí)現(xiàn)上是通過(guò)禁止循環(huán)和限制程序的最大指令數(shù)(max size of the program);

  • 確保內(nèi)存訪問(wèn)的安全:通過(guò) 3.4 小結(jié)介紹的寄存器狀態(tài)跟蹤(register state tracking)來(lái)實(shí)現(xiàn)。

  • 校驗(yàn)邏輯偏保守

    由于校驗(yàn)器的首要職責(zé)是保證內(nèi)核的安全,因此其校驗(yàn)邏輯比較保守, 凡是它不能證明為安全的,一律都拒絕。有時(shí)這會(huì)導(dǎo)致假陰性(false negatives), 即某些實(shí)際上是安全的程序被拒絕加載;這方面在持續(xù)改進(jìn)。

    • 校驗(yàn)器的錯(cuò)誤提示也已經(jīng)更加友好,以幫助開(kāi)發(fā)者更快定位問(wèn)題。

    • 近期已經(jīng)支持了 BPF 函數(shù)調(diào)用(function calls)。

    • 正在計(jì)劃支持有限循環(huán)(bounded loops)。

    • 正在提升校驗(yàn)器效率,以便處理更大的 BPF 程序。

    缺少標(biāo)準(zhǔn)庫(kù)

    相比于用戶空間 C 程序,eBPF 程序的另一個(gè)限制是缺少標(biāo)準(zhǔn)庫(kù),包括?內(nèi)存分配、線程、鎖等等庫(kù)。

  • 內(nèi)核的生命周期和執(zhí)行上下文管理(life cycle and execution context management )部分地彌補(bǔ)了這一不足,(例如,加載的 XDP 程序會(huì)為每個(gè)收到的包執(zhí)行),

  • 內(nèi)核提供的 helper 函數(shù)也部分地彌補(bǔ)了一不足。

  • 一個(gè)網(wǎng)卡接口只能 attach 一個(gè) XDP 程序

    這個(gè)限制其實(shí)也是可以繞過(guò)的:將 XDP 程序組織成程序數(shù)組,通過(guò)尾 調(diào)用,根據(jù)包上下文在程序之間跳轉(zhuǎn),或者是將幾個(gè)程序做 chaining。

    6.2 用戶體驗(yàn)和調(diào)試

    XDP 程序運(yùn)行在內(nèi)核,因此常規(guī)的用戶空間 debug 工具是用不了的,但內(nèi)核自帶的 debug 和 introspection 功能是可以用在 XDP (及其他 eBPF 程序)上的。?包括:

    • tracepoints and kprobes [13]

    • performance counters that are part of the perf subsystem [42]

    但不熟悉內(nèi)核生態(tài)系統(tǒng)的開(kāi)發(fā)者可能會(huì)對(duì)這些工具感到非常陌生,難以使用。因此,也出 現(xiàn)了一些更方便普通開(kāi)發(fā)者的工具,包括 BCC [50]、bpftool [8]、libbpf 函數(shù)庫(kù) [30] 等等。

    6.3 驅(qū)動(dòng)支持

    設(shè)備要支持 XDP,需要實(shí)現(xiàn)內(nèi)核核心網(wǎng)絡(luò)棧暴露出的一個(gè) API。?寫(xiě)作本文時(shí) Linux 4.18 已經(jīng)有 12 種驅(qū)動(dòng)支持 XDP,包括了大部分高速網(wǎng)卡。?最新列表見(jiàn) [2]。

    隨著 XDP 系統(tǒng)的不斷成熟,核心代碼逐漸上移到內(nèi)核中,驅(qū)動(dòng)需要維護(hù)的代碼越 來(lái)越少。例如,redirection action 支持新的 target 時(shí),無(wú)需驅(qū)動(dòng)做任何改動(dòng)。

    最后,對(duì)于那些不支持 XDP 的驅(qū)動(dòng),內(nèi)核提供了?Generic XDP?feature [39],這是軟件實(shí)現(xiàn)的 XDP,性能會(huì)低一些, 在實(shí)現(xiàn)上就是將 XDP 的執(zhí)行上移到了核心網(wǎng)絡(luò)棧(core networking stack)。

    XDP 在內(nèi)核收包函數(shù)?receive_skb() 之前,

    Generic XDP?在?receive_skb() 之后,

    更多關(guān)于 Generic XDP,可參考參考:容器網(wǎng)絡(luò)|深入理解Cilium

    6.4 性能提升

    XDPDPDK 之間還有一些性能差距,一些改進(jìn)工作正在進(jìn)行中:

    • 驅(qū)動(dòng)代碼 micro-optimisations

    • 刪除核心 XDP 代碼中的非必要操作

    • 通過(guò)批處理平攤處理開(kāi)銷

    6.5 QoS 和 Rate Transitions

    當(dāng)前,XDP 還沒(méi)有任何 QoS 機(jī)制。?尤其是,如果對(duì)端已經(jīng)過(guò)載(例如兩端的網(wǎng)絡(luò)速度或特性不匹配),XDP 程序是收不到任何背壓(back-pressure)的,

    雖然 XDP 中缺少 QoS,但 Linux 內(nèi)核網(wǎng)絡(luò)棧中卻有很多業(yè)界最佳的 Active Queue Management (AQM) 特性和 packet scheduling algorithms [23]。?這些特性中,部分并不適用于 XDP,但我們相信能夠 以一種對(duì)包處理應(yīng)用完全透明的方式,選擇其中部分集成到 XDP。?我們計(jì)劃對(duì)這一方向進(jìn)行更深入研究。

    6.6 加速傳輸層協(xié)議

    我們已經(jīng)證明 XDP 能在保留操作系統(tǒng)原有功能的前提下,集成到操作系統(tǒng)中,實(shí)現(xiàn)高速包數(shù)據(jù)。

    目前的 XDP 還是用于無(wú)狀態(tài)包處理(stateless packet processing) ,如果將這個(gè)模型擴(kuò)展到有狀態(tài)傳輸層協(xié)議(stateful transport protocols),例如 TCP,它能給依賴可靠/有狀態(tài)傳輸?shù)膽?yīng)用提供類似的性能提升。

    實(shí)際上,已經(jīng)有一些研究證明,相比于操作系統(tǒng)的協(xié)議棧,accelerated transport protocols 能顯著提升性能[5, 25, 35, 52]。其中的一個(gè)解決方案 [52] 表明,在保留內(nèi) 核 TCP 協(xié)議棧的的前提下,原始包處理性能(raw packet processing)存在巨大的提升 空間。

    XDP 非常適用于這種場(chǎng)景,目前也已經(jīng)有一些關(guān)于如何實(shí)現(xiàn)的初步討論 [21], 雖然離實(shí)際使用還很遠(yuǎn),但仍然是一個(gè)令人振奮的、擴(kuò)展 XDP 系統(tǒng) scope 的方向。

    6.7 內(nèi)核-用戶空間零拷貝(zero-copy to userspace)

    3.1 小節(jié)提到,XDP 程序能將數(shù)據(jù)包重定向到用戶空間應(yīng)用(userspace application)打 開(kāi)的特殊類型 socket。這可以用于加速客戶端和服務(wù)端在同一臺(tái)機(jī)器?的網(wǎng)絡(luò)密集型應(yīng)用(network-heavy applications running on the local machine)。

    更多信息可參考:?(譯) 利用 ebpf sockmap/redirection 提升 socket 性能(2020)。?這里使用的是 BPF 而非 XDP,但核心原理是一樣的,只是程序執(zhí)行的位置(hook)不同。?譯注。

    但在目前的實(shí)現(xiàn)中,這種方式在底層仍然需要拷貝包數(shù)據(jù),因此性能會(huì)打折扣。

    目前已經(jīng)有工作在進(jìn)行,通過(guò) AF_XDP 實(shí)現(xiàn)真正的數(shù)據(jù)零拷貝。但這項(xiàng)工作需要?對(duì)網(wǎng)絡(luò)設(shè)備的內(nèi)存處理過(guò)程有一些限制,因此需要設(shè)備驅(qū)動(dòng)的顯式支持。?第一個(gè)支持這個(gè)功能的 patch 已經(jīng)合并到?4.19?內(nèi)核,更多驅(qū)動(dòng)的支持 正在添加中。初步的性能測(cè)試結(jié)果還是很樂(lè)觀的,顯示能達(dá)到 20Mpps/core 的內(nèi)核到用戶 空間傳遞(transfer)速度。

    6.8 XDP 作為基礎(chǔ)構(gòu)建模塊(XDP as a building block)

    正如 DPDK 用于高層包處理框架的底層構(gòu)建模塊(例如 [31]),XDP 有望成為高層應(yīng)用的運(yùn)行時(shí)環(huán)境 (runtime environment for higher-level applications)。

    實(shí)際上,我們看到一些基于 XDP 的應(yīng)用和框架已經(jīng)出現(xiàn)了。包括

    • Cilium security middle-ware [3]

    • Suricata network monitor [4]

    • Open vSwitch [49]

    • P4-to-XDP compiler project [51]

    甚至還有人嘗試將 XDP 作為 DPDK 的一種底層驅(qū)動(dòng) [53]。

    7 總結(jié)

    本文描述了XDP,一個(gè)安全、快速、可編程、集成到操作系統(tǒng)內(nèi)核的包處理框架。?測(cè)試結(jié)果顯示,XDP能提供 24Mpps/core 的高處理性能,這一數(shù)字雖然與基于 kernel bypass 的DPDK仍有差距,但提供了其他一些非常有競(jìng)爭(zhēng)力的優(yōu)勢(shì):

  • 兼容內(nèi)核安全管理框架(kernel bypass 方式在bypass 內(nèi)核網(wǎng)絡(luò)棧的同時(shí),也將安全和設(shè)備管理等這些極其重要的基礎(chǔ)設(shè)施 bypass 了);

  • 兼容內(nèi)核網(wǎng)絡(luò)棧,可選擇性利用內(nèi)核已有的基礎(chǔ)設(shè)施和功能;

  • 提供與內(nèi)核 API 一樣穩(wěn)定的編程接口;

  • 對(duì)應(yīng)用完全透明

  • 更新、替換程序的過(guò)程不會(huì)引起服務(wù)中斷;

  • 無(wú)需專門(mén)硬件,無(wú)需獨(dú)占CPU等資源。

  • 相比于 kernel bypass 這種非此即彼、完全繞開(kāi)內(nèi)核的方式,我們相信 XDP 有更廣闊的的應(yīng)用前景。Facebook、Cloudflare 等公司實(shí)際落地的 XDP 應(yīng)用,更加增強(qiáng)了我們的這種信心。

    最后,XDP系統(tǒng)還在快速發(fā)展,前面也列出了一些正在未來(lái)可能會(huì)做的開(kāi)發(fā)/優(yōu)化工作。

    致謝

    XDP has been developed by the Linux networking community for a number of years, and the authors would like to thank everyone who has been involved. In particular,

    • Alexei Starovoitov has been instrumental in the development of the eBPF VM and verifier;

    • Jakub Kicinski has been a driving force behind XDP hardware offloading and the bpftool utility;

    • Bj?rn T?pel and Magnus Karlsson have been leading the AF_XDP and userspace zero-copy efforts.

    We also wish to extend our thanks to the anonymous reviewers, and to our shepherd Srinivas Narayana, for their helpful comments.

    參考文獻(xiàn)

    https://arthurchiao.art/blog/xdp-paper-acm-2018-zh/

    - END -


    看完一鍵三連在看轉(zhuǎn)發(fā)點(diǎn)贊

    是對(duì)文章最大的贊賞,極客重生感謝你

    推薦閱讀

    深入理解Linux內(nèi)核之內(nèi)存尋址


    2022新年重磅技術(shù)分享|深入理解Linux操作系統(tǒng)


    一些優(yōu)秀的后端開(kāi)源項(xiàng)目!


    你好,這里是極客重生,我是阿榮,大家都叫我榮哥,從華為->外企->到互聯(lián)網(wǎng)大廠,目前是大廠資深工程師,多次獲得五星員工,多年職場(chǎng)經(jīng)驗(yàn),技術(shù)扎實(shí),專業(yè)后端開(kāi)發(fā)和后臺(tái)架構(gòu)設(shè)計(jì),熱愛(ài)底層技術(shù),豐富的實(shí)戰(zhàn)經(jīng)驗(yàn),分享技術(shù)的本質(zhì)原理,希望幫助更多人蛻變重生,拿BAT大廠offer,培養(yǎng)高級(jí)工程師能力,成為技術(shù)專家,實(shí)現(xiàn)高薪夢(mèng)想,期待你的關(guān)注!點(diǎn)擊藍(lán)字查看我的成長(zhǎng)之路

    校招/社招/簡(jiǎn)歷/面試技巧/大廠技術(shù)棧分析/后端開(kāi)發(fā)進(jìn)階/優(yōu)秀開(kāi)源項(xiàng)目/直播分享/技術(shù)視野/實(shí)戰(zhàn)高手等,?極客星球希望成為最有技術(shù)價(jià)值星球,盡最大努力為星球的同學(xué)提供技術(shù)和成長(zhǎng)幫助!詳情查看->極客星球

    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 求點(diǎn)贊,在看,分享三連

    總結(jié)

    以上是生活随笔為你收集整理的万字长文|深入理解XDP全景指南的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    九九热在线免费观看 | 中文字幕婷婷 | 综合久久综合久久 | a爱爱视频 | 视频在线观看亚洲 | 天天干,天天操,天天射 | 亚洲精品玖玖玖av在线看 | 午夜在线资源 | 国产精品资源在线观看 | 在线免费观看国产视频 | 亚洲成人资源在线观看 | 欧美精品一区二区三区四区在线 | 国产电影一区二区三区四区 | 久久人人艹 | 国产精品视频区 | 最新av观看 | 久久激情小说 | 久久国产美女 | 天天操天天色天天射 | 久久爽久久爽久久av东京爽 | 日韩av在线资源 | 成人av一区二区三区 | www色网站 | 四虎影视成人永久免费观看视频 | 91在线视频免费 | 久久精品91久久久久久再现 | 久久一久久 | 97av.com| 精品一区二区三区在线播放 | 在线综合 亚洲 欧美在线视频 | 五月婷在线播放 | 成人在线观看你懂的 | 久久伊人婷婷 | 99精品热视频只有精品10 | 99色在线视频 | 国内精品国产三级国产aⅴ久 | 九九热在线视频免费观看 | 日日干天天爽 | 91麻豆网 | 久久久久久久久久免费 | 888av| 一区二区三区在线播放 | 国内揄拍国内精品 | 97人人模人人爽人人喊网 | 免费福利视频网 | 久草视频在线看 | 久久久穴| 亚洲污视频 | 日韩av不卡播放 | 视频一区二区在线 | 亚洲精品资源在线观看 | 黄色毛片视频免费观看中文 | 亚洲黄色区 | 国产精品成人一区二区三区 | 日韩欧美一区二区三区视频 | 欧美国产大片 | 美女视频免费一区二区 | 正在播放国产一区二区 | 五月婷婷在线综合 | 91精品在线麻豆 | 国产成本人视频在线观看 | 日韩成人免费电影 | 中文字幕免费高清 | 三级在线视频播放 | 一区三区视频在线观看 | 久久午夜精品 | 日韩欧美一区二区三区黑寡妇 | 国产生活一级片 | 国产精品va | 成人欧美一区二区三区黑人麻豆 | 欧美黑人猛交 | 久久久久久久久网站 | 免费看黄色毛片 | 青青网视频 | 精品国产亚洲日本 | 日韩欧美在线影院 | 欧美精品一区二区在线播放 | 日本系列中文字幕 | 欧美超碰在线 | 天天五月天色 | 在线日韩一区 | 午夜黄网 | aaa亚洲精品一二三区 | 亚洲天堂精品视频 | 午夜精品久久久久久久99水蜜桃 | 午夜视频在线观看网站 | 日韩综合在线观看 | 97成人在线观看视频 | 成人av资源网站 | 久久久国产精品免费 | 久久久久网站 | 黄色片免费电影 | 在线亚洲日本 | 日韩中文字幕国产 | 精品一区二区三区久久久 | 一本之道乱码区 | 欧美日韩精品在线免费观看 | 天天做天天爱天天综合网 | 91网站在线视频 | 色九九在线 | 在线观看免费中文字幕 | 欧美色久| 涩涩伊人 | 黄色三级在线看 | 亚洲精品视频第一页 | 亚洲成色777777在线观看影院 | 狠狠狠色丁香婷婷综合久久88 | 国产小视频免费在线观看 | 久久怡红院 | 91福利视频久久久久 | 精品毛片一区二区免费看 | 开心激情五月婷婷 | 久久久久久久久久久久影院 | 在线观看黄 | 国产亚洲精品久久 | 国产精品久久久久久69 | 天天色天天骑天天射 | 色999视频 | 欧美精品久久久久久久久久丰满 | 亚洲色图av | 伊人天天狠天天添日日拍 | 日韩最新av | 日韩精品免费在线 | 成人四虎影院 | 国产精品一区二区免费看 | 国产高清视频在线免费观看 | 久久欧美视频 | 97电影院在线观看 | 99色在线| 成人精品一区二区三区中文字幕 | 天天操伊人 | 亚洲精品高清视频在线观看 | 黄色毛片在线观看 | 最新国产在线 | 国产女教师精品久久av | 中文在线中文a | 久久精品视频国产 | 最新国产在线 | 久久国产精品免费观看 | 日日干综合 | www夜夜| 91av视频在线免费观看 | 黄色一级片视频 | www.五月天婷婷 | 色偷偷88888欧美精品久久久 | 午夜黄色 | 天天干天天操av | 97天堂 | 欧美一区免费观看 | 久久久久久久国产精品 | 国产精品久久久久久超碰 | 国产 日韩 欧美 中文 在线播放 | 狠狠婷婷 | 国产剧情久久 | 一本色道久久精品 | 国产精品中文字幕在线播放 | 九月婷婷综合网 | 免费在线观看av网站 | 在线岛国av | 亚洲精品一区二区在线观看 | 国产黄色片久久 | 午夜国产一区二区三区四区 | 人人澡人人干 | 日韩理论视频 | 中文字幕在线观看完整版 | 国产精品男女 | 精品国产三级a∨在线欧美 免费一级片在线观看 | 久99热| 91色欧美| 黄色av网站在线观看 | 一区二区三区在线播放 | 蜜臀久久99精品久久久酒店新书 | 四虎影视www| 久久精品视频2 | 亚洲专区 国产精品 | 99视频99 | 成人高清av在线 | 日本精品在线 | 国产精品久久久一区二区三区网站 | 美女av在线免费 | 麻豆视频91 | 国产最顶级的黄色片在线免费观看 | av福利资源 | 亚洲视屏在线播放 | 成人亚洲精品国产www | 97电影在线观看 | 成人av电影在线观看 | 草久在线观看视频 | 成人日韩av | 国产玖玖精品视频 | 天堂av高清 | 91成人在线视频观看 | 日韩精品中文字幕在线播放 | 综合久久久久久久久 | 久久成人免费 | 91精品国产91久久久久 | av一级片在线观看 | 五月花丁香婷婷 | 国产美女精品 | 不卡的av电影 | 91亚洲精品久久久 | 在线观看黄色大片 | 久久精品久久久久久久 | 日本激情动作片免费看 | 国产a免费 | 91精品国产91久久久久福利 | 色多多视频在线观看 | 久草在线视频看看 | 国内精品毛片 | 91免费网| 成人免费中文字幕 | 亚洲国产精品99久久久久久久久 | 免费观看视频的网站 | 日韩免费观看一区二区三区 | 国产精品美女久久久久久网站 | 99国产在线视频 | 日韩高清成人在线 | 欧美 亚洲 另类 激情 另类 | 国产福利专区 | 免费av影视 | 麻豆视频在线免费观看 | 亚洲成aⅴ人在线观看 | 日韩精品久久一区二区三区 | 中文国产字幕在线观看 | 免费在线观看视频a | 国内精品中文字幕 | 久久99久久精品国产 | 欧美国产不卡 | 狂野欧美激情性xxxx | 久久刺激视频 | 伊人久在线 | 成人午夜免费剧场 | 91在线播放视频 | 婷婷丁香六月天 | 日韩免费一级电影 | 久草亚洲视频 | 麻豆影视在线播放 | 毛片www| 中文字幕日本特黄aa毛片 | 国产在线视频不卡 | 国产主播大尺度精品福利免费 | 久久精品中文字幕免费mv | 色婷婷狠狠操 | 久久人人97超碰国产公开结果 | 亚洲国内精品在线 | 国产一区在线视频播放 | 亚洲午夜av | 天天射天 | 九九热国产视频 | 波多野结衣精品视频 | 国产精品嫩草影院99网站 | 久久久久久免费毛片精品 | 91精品国产自产老师啪 | 激情久久久久久久久久久久久久久久 | 国产一区二区三区在线免费观看 | 亚洲精品乱码白浆高清久久久久久 | 日韩在线第一区 | 高清在线一区 | 99久久影院 | 久久久精品亚洲 | 亚洲日本va中文字幕 | 婷婷色六月天 | 激情五月视频 | 91日韩在线专区 | 激情欧美丁香 | 青青河边草免费观看完整版高清 | 色亚洲激情 | 国产一区在线观看免费 | 亚洲综合在线视频 | 天天综合入口 | 日本精品中文字幕在线观看 | 在线视频区 | 国产一级二级三级视频 | 亚洲,播放| www99久久 | 九九热在线精品视频 | 久久国产精品久久精品国产演员表 | 欧洲一区二区三区精品 | 97在线播放视频 | 伊甸园永久入口www 99热 精品在线 | 成人va视频| 黄色免费在线看 | 美女一级毛片视频 | 天天操天天操天天操天天操天天操天天操 | 毛片网站观看 | 狠狠地日 | 久久免费视频1 | 成人资源站| 亚洲精品免费在线视频 | av免费看网站| 日韩欧美第二页 | 999男人的天堂 | 欧美一区在线看 | 91电影福利 | 在线视频福利 | 久久免费国产电影 | 一区二区理论片 | 中国老女人日b | 欧美精品亚洲精品日韩精品 | 中文一区二区三区在线观看 | 久久午夜色播影院免费高清 | 99热这里只有精品国产首页 | 国产午夜精品一区二区三区欧美 | 欧美aaa一级| 999久久久久久久久久久 | 国产精品99蜜臀久久不卡二区 | 天堂入口网站 | 96久久精品 | 久久久久99精品国产片 | 天操夜夜操 | 亚洲国产999| 国产美女精品视频 | 最新中文在线视频 | 狠狠色婷婷丁香六月 | 欧美粗又大 | 97视频亚洲 | 正在播放国产91 | 日韩欧美高清视频在线观看 | 免费观看全黄做爰大片国产 | 国产精品久久久久久久久久久不卡 | 亚洲国产婷婷 | 成人小电影在线看 | 久久激情精品 | 精品久久国产一区 | 激情五月在线视频 | 天堂在线视频免费观看 | 婷婷五月色综合 | 九九精品视频在线看 | 日韩欧美国产成人 | 天天操天天艹 | 欧美精品乱码久久久久久按摩 | 美女久久精品 | 69视频国产 | 国产精品免费在线 | 亚洲尺码电影av久久 | 天天操天天射天天 | 一区二区在线影院 | 久久久天堂 | 日本午夜免费福利视频 | 国产不卡一区二区视频 | 天天做日日做天天爽视频免费 | 亚洲免费观看在线视频 | 91成人精品国产刺激国语对白 | 国产精品一区二区三区在线看 | 色噜噜日韩精品一区二区三区视频 | 欧美精品日韩 | 日本精品一区二区 | 久久不卡免费视频 | 国产区精品区 | 91激情 | 97人人人人 | 国产盗摄精品一区二区 | 久久久免费看片 | 91大神dom调教在线观看 | 91色吧 | 亚洲激情网站免费观看 | 亚洲人成人天堂h久久 | 亚洲艳情| 成年免费在线视频 | 99精品视频在线看 | 四虎在线免费视频 | 亚洲国产久 | 国产精品永久 | 狠狠操导航| 在线日韩亚洲 | 中文字幕观看在线 | bbb搡bbb爽爽爽 | 国产在线观看不卡 | 天天干夜夜 | 中文字幕精品三区 | 亚洲国产合集 | 久久综合亚洲鲁鲁五月久久 | 久久久电影网站 | 91精品网站在线观看 | 在线观看国产永久免费视频 | 成人午夜精品 | 天天爽天天摸 | 久久电影中文字幕视频 | 奇米影视8888在线观看大全免费 | 久久热亚洲 | 亚洲综合成人婷婷小说 | 五月亚洲婷婷 | 免费观看成年人视频 | 91九色porn在线资源 | 九九热在线观看视频 | 在线观看不卡视频 | 激情五月综合 | 五月婷婷深开心 | 日韩免费一级电影 | 高清久久久| 激情 一区二区 | 欧美在线18 | 国产手机在线播放 | 亚洲永久国产精品 | 日韩免费福利 | 在线韩国电影免费观影完整版 | 黄色app网站在线观看 | 日本成址在线观看 | 国产小视频福利在线 | 最新国产视频 | 国产福利在线不卡 | 日韩欧美电影 | 综合久久影院 | 成人免费观看在线视频 | 97人人爽 | 国产精品久久久久久久久久 | 亚洲人成人在线 | 欧美男男tv网站 | 日韩a在线看 | 天天干夜夜夜 | 久久激情视频 久久 | 久久久久久久久久久黄色 | 久久久久久久av | 成人av免费在线播放 | 久久人人97超碰国产公开结果 | 一区二区三高清 | 午夜av影院 | 99久久99视频| 91爱爱电影 | a级国产乱理伦片在线播放 久久久久国产精品一区 | 亚洲精品高清在线 | 黄色网址中文字幕 | 日韩av图片 | 91网址在线看 | 久久一区二 | 四虎国产精品永久在线国在线 | 国产一级视频 | 日韩电影在线观看中文字幕 | 2000xxx影视| 国产精品a成v人在线播放 | 在线观看久久久久久 | 成年人av在线播放 | 久草免费电影 | 综合色久 | 麻豆传媒一区二区 | 天天色 天天 | 免费日韩一区二区三区 | 在线观看国产成人av片 | 国产麻豆精品免费视频 | 欧美极度另类 | 狠狠躁夜夜躁人人爽视频 | 三级黄色片在线观看 | 91黄视频在线观看 | 国产精品久一 | 国产99久久久国产精品 | 深夜免费小视频 | 亚洲91中文字幕无线码三区 | 欧美极品xxx | 人人爽人人射 | 五月天激情开心 | 青青草久草在线 | 国产精品成人自产拍在线观看 | 日日夜夜精品免费视频 | 欧美日韩久久一区 | 蜜桃av人人夜夜澡人人爽 | 在线观看日韩视频 | 免费十分钟 | 亚洲午夜精 | 国内精品久久久久影院优 | 亚洲欧美在线综合 | 丰满少妇在线观看资源站 | 91在线免费看片 | 免费日韩av电影 | 天天插夜夜操 | 91视频com | 中文字幕在线高清 | 国产精品 中文字幕 亚洲 欧美 | 黄色软件在线观看免费 | 日日夜夜网| 精品视频不卡 | 日韩成人精品一区二区三区 | 国产国产人免费人成免费视频 | 国际av在线 | 色综合天天色综合 | 免费看一级黄色 | 国产小视频在线观看免费 | 97超碰人人干| 午夜影院一级 | 99久久婷婷国产一区二区三区 | 欧美一级爽 | 午夜丰满寂寞少妇精品 | 日韩午夜三级 | 超碰在线人人爱 | 成人一级免费视频 | 日日夜夜天天射 | 日韩aⅴ视频 | 精品视频在线免费观看 | 天天干天天操天天搞 | 国产一二三在线视频 | 福利电影一区二区 | 日本精品在线视频 | 五月婷婷综合激情网 | 激情av网| 日韩av有码在线 | 最新的av网站 | 日韩欧美一区二区三区在线 | 美女视频黄是免费的 | 日本中文字幕系列 | 六月丁香在线观看 | 久久精品www人人爽人人 | 狠狠操狠狠干天天操 | 日韩免费福利 | 深爱激情综合 | 国产精品99在线观看 | 日韩在线免费视频 | 日韩午夜高清 | 成人免费视频播放 | 综合天天色 | 狠狠干夜夜操 | 久久乱码卡一卡2卡三卡四 五月婷婷久 | 精品毛片在线 | 精品欧美在线视频 | 久久久人人人 | 国产精品久久麻豆 | 在线观看的av | 中文字幕在线观看完整版 | av九九| 精品国产欧美一区二区 | 免费日韩一区二区三区 | 久久艹免费 | 91黄色免费看 | www夜夜| 夜夜爽天天爽 | 国产精品高潮久久av | 99视频一区二区 | 三级av免费| 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 成人欧美日韩国产 | 婷婷色资源 | 91天堂在线观看 | 国产 日韩 欧美 中文 在线播放 | 午夜精品视频一区 | 欧美色一色| 九九在线免费视频 | aaa亚洲精品一二三区 | 久久久精品福利视频 | 久久精品精品电影网 | 久久国产精彩视频 | 91精品国产综合久久福利不卡 | av中文字幕亚洲 | 高清av在线免费观看 | 综合精品久久久 | 婷婷av网站| 欧美日韩国产精品爽爽 | 在线91网 | 国产一区二区三区高清播放 | 激情小说网站亚洲综合网 | 国产精品免费小视频 | 日韩理论片| 在线不卡的av | 国产高清在线观看av | 国产精品www| 在线www色| 国产日韩视频在线观看 | 国产精品专区在线 | 在线黄频 | 日日爱视频 | 97夜夜澡人人爽人人免费 | 在线免费观看视频a | www.夜夜操.com | 中文字幕你懂的 | 成人av电影在线观看 | 一区二区精品在线 | 久久99精品国产麻豆婷婷 | 黄色大片日本 | 天天碰天天操 | 日本中文字幕网站 | 激情 婷婷 | 97精品国产97久久久久久久久久久久 | 亚洲专区中文字幕 | 伊人www22综合色 | 91综合视频在线观看 | 夜夜骑天天操 | 午夜影院在线观看18 | av资源在线观看 | 国产精品久久久久久久久久99 | 超碰人人av| 九色精品免费永久在线 | 亚洲精品黄| 日本资源中文字幕在线 | 中文字幕一区在线 | 久久激情片 | 中文字幕永久 | 日韩毛片在线一区二区毛片 | 亚洲精品www. | 久久久午夜精品福利内容 | 又黄又爽又刺激的视频 | 六月丁香在线观看 | 色婷婷综合激情 | 99热9| 91精品国产91热久久久做人人 | 久久久国产精品一区二区三区 | 99久热在线精品 | 免费精品在线观看 | 国产精品成人久久久久 | 久久人人97超碰国产公开结果 | 久久久久免费精品视频 | 亚洲一区尤物 | 天天干夜夜干 | 一区二区视频在线观看免费 | www看片网站 | 日韩成人xxxx | 久久少妇免费视频 | 精品免费一区 | 色婷婷97| 国产精品粉嫩 | 探花视频在线观看+在线播放 | 久久只有精品 | 国产精品99久久久精品免费观看 | 国产精品99久久久精品免费观看 | 999久久久欧美日韩黑人 | 久久久久久中文字幕 | 国产另类av| 亚洲免费av电影 | 在线国产一区二区 | 欧美视频不卡 | 国产精品a级 | 天天躁日日躁狠狠 | 天天射射天天 | 亚洲作爱视频 | 日韩精选在线观看 | 69久久久 | 欧美性生活大片 | 国产电影黄色av | 久久婷五月 | av在线日韩| av观看在线观看 | 免费观看成年人视频 | 视频在线观看亚洲 | 人人射人人射 | 国产黄色片一级 | 最近日本中文字幕a | 波多野结衣在线中文字幕 | 久久婷亚洲五月一区天天躁 | 久草在线观看视频免费 | 国产精品v欧美精品 | 色综合网 | 日韩欧美精品免费 | 亚洲欧洲美洲av | 亚洲精品小视频 | 精品国产一区二区三区日日嗨 | 国产精品成人久久 | 啪啪免费观看网站 | 97品白浆高清久久久久久 | 夜夜爽88888免费视频4848 | 最新av网址在线观看 | 美女视频是黄的免费观看 | 精品国产一区二区三区噜噜噜 | 97精品视频在线播放 | 美女一区网站 | 国产传媒中文字幕 | 综合网在线视频 | 天堂网在线视频 | 日韩在线视频观看免费 | 国产无遮挡猛进猛出免费软件 | 天天干中文字幕 | 国产一级91 | 美女性爽视频国产免费app | 亚洲干视频在线观看 | av在线之家电影网站 | 日韩欧美精品一区 | 日本中文字幕观看 | 婷婷丁香在线视频 | 久久精品91久久久久久再现 | 91av九色 | 日日夜夜噜| 激情网在线观看 | 国产精品一二三 | 国产精品久久久久久久久岛 | 久久久久久久久久免费视频 | 在线观看福利网站 | 不卡国产在线 | 黄色av网站在线观看免费 | 亚洲一区二区精品 | 日本中文字幕在线播放 | 伊人久久一区 | 国产三级午夜理伦三级 | 国内外成人在线视频 | 免费日韩在线 | 欧洲精品久久久久毛片完整版 | 国内精品久久久久久久久久 | 国产精品v欧美精品v日韩 | 久久66热这里只有精品 | 瑞典xxxx性hd极品 | 成人av片在线观看 | www激情久久| 欧美性极品xxxx娇小 | 美女久久网站 | 久久激五月天综合精品 | 亚洲国产色一区 | 午夜av不卡 | 射久久| 国产五月天婷婷 | 超碰免费av | 色噜噜日韩精品一区二区三区视频 | 亚洲日本一区二区在线 | a午夜在线| 日本护士三级少妇三级999 | 97电影在线 | 美女在线免费观看视频 | 人人射人人射 | 丁香综合网 | 97电影在线观看 | 国产一区视频免费在线观看 | 丁香影院在线 | 99精品在线免费视频 | 激情婷婷av | 日韩视频一二三区 | 久久99精品久久久久久三级 | 天天综合区 | 国产成人精品午夜在线播放 | 蜜臀av网址| 亚洲97在线 | 一级欧美一级日韩 | 亚洲电影久久久 | 黄色视屏av | 天天躁日日躁狠狠躁av中文 | av在线短片 | 91传媒视频在线观看 | 成人av一区二区三区 | 麻豆视频大全 | 麻豆视频在线看 | 日韩精品电影在线播放 | 国产视频日韩 | 久久国产成人午夜av影院宅 | 国产偷国产偷亚洲清高 | 久久国产欧美日韩 | 美女网色| a天堂一码二码专区 | 婷婷精品国产欧美精品亚洲人人爽 | 亚洲精品国产品国语在线 | 中文字幕视频播放 | 一区二区三区在线视频观看58 | 久热免费在线观看 | 欧美日韩综合在线观看 | 最新国产精品视频 | 黄色大全免费观看 | 国产精品porn | 国产艹b视频 | 久久久久久久毛片 | av一级一片 | www天天干com | 欧美另类调教 | 欧美国产日韩一区二区三区 | 免费在线观看av片 | 特级西西444www大胆高清无视频 | 中文字幕中文 | 黄色1级大片 | 在线а√天堂中文官网 | 国产二区av | 日韩欧美精品一区二区三区经典 | 色香蕉在线 | 香蕉视频在线免费看 | 人人网人人爽 | 黄色资源网站 | 欧美激情综合五月色丁香小说 | 日日夜夜婷婷 | 久久精品99久久 | 亚洲成人资源网 | 黄色网在线免费观看 | 在线看国产日韩 | 国产精品久久久久久久久久99 | 在线精品在线 | 狠狠躁夜夜躁人人爽视频 | 99热最新地址 | 免费69视频 | 有码视频在线观看 | 欧美人牲 | 国产五月天婷婷 | bbw av | 日本成人免费在线观看 | a极黄色片 | av高清免费在线 | 色天天天| 国产精品99久久久久久久久久久久 | 黄网站污 | 五月天激情视频在线观看 | 国产三级视频 | 欧美巨大 | 夜夜躁狠狠躁 | 99精品视频在线免费观看 | 久久亚洲私人国产精品va | 国产一级电影网 | 一区二区高清在线 | 精品国产视频在线 | 成人在线播放视频 | 国产精品ssss在线亚洲 | 国产专区视频在线观看 | 免费看的黄色网 | 美女久久网站 | 欧美日韩综合在线 | 91精品久久久久久久99蜜桃 | 国产精品二区在线 | 色五婷婷 | 国产在线观看免费观看 | 国产手机精品视频 | 91久久久国产精品 | 精品国产aⅴ麻豆 | 国产一区二区在线播放视频 | 国产三级午夜理伦三级 | 黄色一级大片免费看 | 日本夜夜草视频网站 | 国产黄在线播放 | 成人黄色大片在线免费观看 | 五月婷婷丁香在线观看 | 国产精品久久久久久久久软件 | 96超碰在线 | 国产在线91在线电影 | 免费激情在线电影 | 天天曰天天爽 | 色偷偷中文字幕 | 中文字幕在线播出 | 国产美女黄网站免费 | 字幕网资源站中文字幕 | 91色影院 | 91丨九色丨国产丨porny精品 | 九九热精品视频在线观看 | 中文字幕日本电影 | 色噜噜噜 | 久草精品网 | 国产在线欧美 | 日本久久高清视频 | 麻豆久久一区二区 | 91视频中文字幕 | 天天爱天天操 | 国产精品一区二区中文字幕 | 国产三级精品三级在线观看 | 国产免码va在线观看免费 | 91麻豆精品国产91久久久更新时间 | 国产黄a三级三级三级三级三级 | 欧美激情综合色综合啪啪五月 | 国产精品大片在线观看 | 在线国产激情视频 | 午夜视频99 | 亚洲国内精品在线 | avwww在线| 久久视频网 | 91精品国产亚洲 | 五月婷婷播播 | 黄色的网站在线 | 91九色网站 | av一区在线 | 欧美色综合天天久久综合精品 | 久久久 精品 | 国产在线一线 | 天天射天天射天天 | 综合网天天色 | 国产精品99久久久久久小说 | 视频在线精品 | 日韩精品欧美视频 | 亚洲dvd | 中文字幕在线看片 | www.91成人 | 日韩精品在线看 | 在线视频一区观看 | 五月婷婷综合激情网 | 99re国产视频| 国产精品免费观看网站 | 亚洲欧美婷婷六月色综合 | 中文字幕日韩一区二区三区不卡 | 免费观看国产精品视频 | 久草在线官网 | 婷婷六月天综合 | 国产精品99视频 | 国产精品11 | jizzjizzjizz亚洲 | 亚洲欧洲精品一区二区精品久久久 | 久久久99国产精品免费 | 亚洲精品国产区 | 久久伦理电影网 | 黄色成年片 | 99久高清在线观看视频99精品热在线观看视频 | 日韩精品三区四区 | 日韩高清不卡在线 | 久久九九精品久久 | 蜜臀av在线一区二区三区 | 最近免费观看的电影完整版 | 久久婷婷色 | 成年人网站免费观看 | 激情综合婷婷 | 天天干天天射天天爽 | 国产成人三级 | 中文成人字幕 | 国产999精品| a视频免费在线观看 | 日本精品一区二区三区在线播放视频 | 久色免费视频 | 九九久久电影 | 在线电影av | 在线免费观看黄色小说 | av电影在线观看完整版一区二区 | 中文字幕一区二区三区在线视频 | 国产午夜精品久久 | 欧美日韩国产mv | 天堂av最新网址 | 精品视频国产一区 | 日韩精品中文字幕久久臀 | 免费看的黄网站 | 国产一二区视频 | 深爱激情亚洲 | 精品色999| 最新婷婷色 | 免费av一级电影 | 久久视频精品在线观看 | 亚洲综合在线播放 | 视频一区久久 | 国产超碰在线观看 | 97香蕉视频| 亚洲国产精品va在线看黑人 | 欧美日韩国产一区 | 亚洲成av人片在线观看 | 久久久久久久久免费视频 | 果冻av在线 | 久久香蕉一区 | 97国产大学生情侣酒店的特点 | 在线观看深夜福利 | 午夜精品一区二区三区免费视频 | 国产99精品| 亚洲黄色在线播放 | 成人在线免费视频 | www.伊人网.com| 久插视频 | 欧美日韩国产网站 | 蜜桃av观看 | 国内成人综合 | 四虎成人精品永久免费av九九 | 亚洲国产成人在线 | 中文字幕在线观看第二页 | 久久伊人综合 | 精品极品在线 | 久久久www成人免费精品 | 久久午夜精品影院一区 | 91免费高清在线观看 | 久久中文字幕导航 | 91精品视频导航 | 久久99免费观看 | 国产精品免费在线 | 婷婷色av| 久久久久久久免费看 | 91免费观看视频网站 | 欧美日韩高清 | 丁香婷婷激情网 | 五月天网页 | 日韩69av| 精品在线二区 | 中文字幕在线观看网站 | 日韩成人在线一区二区 | 九九99| www五月婷婷 | 九九视频精品在线 | 亚洲国产色一区 | 99这里只有久久精品视频 | 久久久久久久久毛片精品 | 91精品国产九九九久久久亚洲 | 日韩欧美在线视频一区二区 | av观看在线观看 | 成人在线观看资源 | 涩涩网站在线 | 中文字幕视频三区 | 国产精品99久久久精品 | 国产一级在线观看视频 | 国产男女免费完整视频 | 日韩女同av | 久久久久久高潮国产精品视 | 国产精品资源网 | 亚洲精品动漫久久久久 | 九九九九九九精品任你躁 | 国产精品久久久久久五月尺 | 国产亚洲情侣一区二区无 | 亚洲欧美成人 | 黄污污网站 | 久久国产日韩 | 玖玖精品在线 | 在线黄色观看 | 97成人在线视频 | 国产一区欧美在线 | 黄色av免费看 | 黄污视频大全 | 中日韩三级视频 | 婷婷九月激情 | 久久综合色天天久久综合图片 | 999视频网| 91夜夜夜 | 成人理论电影 | 久久怡红院 | 91精品资源 | 麻豆国产精品永久免费视频 | 国产一级不卡视频 | 精品在线你懂的 | 亚洲精品综合欧美二区变态 | 天天综合在线观看 | 亚洲国产中文字幕在线观看 | 亚洲少妇xxxx| 欧美在线观看视频一区二区三区 | av免费观看在线 | 免费在线观看不卡av | 在线观看中文av | 亚洲精品在线观看视频 |