一文讀懂Linux網(wǎng)絡(luò)新基石——XDP技術(shù)
Labs 導(dǎo)讀
隨著1000Mbps/10Gbps/40Gbps高速率網(wǎng)卡的普及,Linux內(nèi)核協(xié)議棧在海量數(shù)據(jù)、低時(shí)延的場(chǎng)景下顯得力不從心,其復(fù)雜冗余的包處理邏輯,使得性能瓶頸變的尤為突出。故而針對(duì)內(nèi)核協(xié)議棧的各種優(yōu)化接踵而來(lái),但實(shí)際效果卻不明顯,于是乎kernel bypass技術(shù)應(yīng)運(yùn)而生,而DPDK就是其高性能網(wǎng)絡(luò)應(yīng)用開發(fā)解決方案中的佼佼者,并逐漸成為了獨(dú)樹一幟的成熟技術(shù)體系。但是DPDK并不能與Linux Kernel的技術(shù)生態(tài)很好的結(jié)合,與現(xiàn)有操作系統(tǒng)集成的難度較大。
Part 01、 XDP概述
XDP(eXpress Data Path,快速數(shù)據(jù)面)是近些年興起的網(wǎng)絡(luò)數(shù)據(jù)面技術(shù),為L(zhǎng)inux內(nèi)核提供高性能、可編程的網(wǎng)絡(luò)數(shù)據(jù)包處理框架。本質(zhì)上是Linux Kernel中的一個(gè)eBPF Hook(鉤子),可以動(dòng)態(tài)掛載,使得ebpf程序能夠在數(shù)據(jù)報(bào)文到達(dá)網(wǎng)絡(luò)驅(qū)動(dòng)層時(shí)提前進(jìn)行針對(duì)性的高速處理。XDP可以與內(nèi)核協(xié)同工作,既可以繞過(guò)繁瑣的TCP/IP協(xié)議棧,也可以復(fù)用TCP/IP協(xié)議棧以及內(nèi)核基礎(chǔ)設(shè)施。由于其較早的收包路徑,對(duì)于快速識(shí)別丟棄報(bào)文具有很高的性能,廣泛應(yīng)用于DDoS防御、防火墻、負(fù)載均衡等領(lǐng)域。
而AF_XDP作為一種內(nèi)核的協(xié)議族可以與XDP進(jìn)行交互,實(shí)現(xiàn)XDP收包重定向至AF_XDP指定的UMEM,使得用戶態(tài)應(yīng)用可以通過(guò)AF_XDP Socket完成數(shù)據(jù)幀的讀取和寫入。
Part 02、 XDP架構(gòu)設(shè)計(jì)
XDP系統(tǒng)主要有五個(gè)組成部分:
1??XDP driver hook
即網(wǎng)卡驅(qū)動(dòng)中的一個(gè)XDP程序的掛載點(diǎn),運(yùn)行于網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)中,由于其駐留在內(nèi)核空間,無(wú)需上下文切換,更加安全、快速,每當(dāng)網(wǎng)卡接收到一個(gè)數(shù)據(jù)包就會(huì)執(zhí)行這個(gè)XDP程序。XDP程序可以對(duì)數(shù)據(jù)包進(jìn)行逐層解析、按規(guī)則進(jìn)行過(guò)濾,或者對(duì)數(shù)據(jù)包進(jìn)行封裝、解封裝、轉(zhuǎn)發(fā)等。根據(jù)不同的工作模式其掛載點(diǎn)也不同,如下圖所示,根據(jù)網(wǎng)卡支持情況有三處掛載點(diǎn)(藍(lán)色方框內(nèi)):
圖片
- Native XDP(默認(rèn)):即驅(qū)動(dòng)模式,在這種模式中,XDP BPF 程序直接運(yùn)行在網(wǎng)絡(luò)驅(qū)動(dòng)的早期接收路徑上,需要驅(qū)動(dòng)支持。
- Offloaded XDP:在該模式下XDP BPF程序直接offload到網(wǎng)卡,相較于Native,具有更高的性能,需要網(wǎng)卡支持。
- Generic XDP:對(duì)于還沒有實(shí)現(xiàn)Native或Offloaded XDP的驅(qū)動(dòng),內(nèi)核提供了一個(gè)Generic XDP選項(xiàng)。該模式下的XDP BPF Program運(yùn)行于驅(qū)動(dòng)程序之后的位置,無(wú)需驅(qū)動(dòng)程序的支持,但性能較差,主要面向測(cè)試程序的開發(fā)者。
2??eBPF虛擬機(jī)
XDP程序通過(guò)Clang編譯成BPF字節(jié)碼,而BPF字節(jié)碼加載到內(nèi)核中是運(yùn)行在eBPF虛擬機(jī)上,eBPF VM支持XDP程序的動(dòng)態(tài)加載和卸載。
3??BPF maps
內(nèi)核中的key/value存儲(chǔ),作為圖中各系統(tǒng)的主要通信通道,類似于進(jìn)程間通信的共享內(nèi)存訪問(wèn)。用戶態(tài)程序可以在BPF Maps中預(yù)定義規(guī)則,XDP程序可以匹配Maps中的規(guī)則對(duì)數(shù)據(jù)包進(jìn)行過(guò)濾等;XDP程序也可以將數(shù)據(jù)包統(tǒng)計(jì)信息等存入Maps,用戶態(tài)程序可訪問(wèn)Maps獲取數(shù)據(jù)包統(tǒng)計(jì)信息。
4??eBPF verifier
由于eBPF代碼直接運(yùn)行在內(nèi)核地址空間,此它能直接訪問(wèn)(破壞)任何內(nèi)存。為防止這種情況發(fā)生,Verifier(程序校驗(yàn)器)需要在XDP字節(jié)碼加載到內(nèi)核之前對(duì)字節(jié)碼進(jìn)行安全檢查。
5??XDP Action
XDP程序?qū)τ趫?bào)文的處理有如下幾種方式:
- XDP_DROP:在驅(qū)動(dòng)層丟棄報(bào)文,通常用于實(shí)現(xiàn)DDos或防火墻。
- XDP_PASS:允許報(bào)文上送到內(nèi)核網(wǎng)絡(luò)棧,同時(shí)處理該報(bào)文的CPU會(huì)分配并填充一個(gè)skb,將其傳遞到內(nèi)核協(xié)議棧。
- XDP_TX:從當(dāng)前網(wǎng)卡發(fā)送出去。
- XDP_REDIRECT:將包重定向到其他網(wǎng)絡(luò)接口(包括虛擬機(jī)的虛擬網(wǎng)卡),或者通過(guò)AF_XDP socket重定向到用戶空間。
- XDP_ABORTED:表示程序產(chǎn)生了異常,其行為和XDP_DROP相同,但XDP_ABORTED會(huì)經(jīng)過(guò)trace_xdp_exception tracepoint,因此可以通過(guò)tracing工具來(lái)監(jiān)控這種非正常行為。
下圖基于XDP/AF_XDP系統(tǒng)數(shù)據(jù)流示例圖。實(shí)線為數(shù)據(jù)面流向,虛線的控制面流向。
網(wǎng)卡收到包之后,會(huì)先執(zhí)行掛載的XDP eBPF程序,用戶態(tài)應(yīng)用在此之前通過(guò)bpf map下放規(guī)則,XDP收到數(shù)據(jù)包之后讀取bpf map中的規(guī)則實(shí)現(xiàn)數(shù)據(jù)包的過(guò)濾分發(fā),即xdp action處理,是DROP,重定向到AF_XDP,還是PASS到內(nèi)核協(xié)議棧。
從圖中可以看出,不同eBPF程序之間可以通過(guò)BPF maps進(jìn)行通信,并且內(nèi)核態(tài)也可以通過(guò)BPF map與用戶態(tài)應(yīng)用進(jìn)行交互,從而實(shí)現(xiàn)數(shù)據(jù)共享。
Part 03、 VPP的擴(kuò)展性
XDP專為高性能而設(shè)計(jì),相較與DPDK來(lái)說(shuō),具有以下優(yōu)點(diǎn):
- 無(wú)需專門硬件,無(wú)需大頁(yè)內(nèi)存,無(wú)需獨(dú)占CPU等資源,任何有Linux驅(qū)動(dòng)的網(wǎng)卡都可以支持,無(wú)需引入第三方代碼庫(kù)。
- 兼容內(nèi)核協(xié)議棧,可選擇性復(fù)用內(nèi)核已有的功能。
- 保持了內(nèi)核的安全邊界,提供與內(nèi)核API一樣穩(wěn)定的接口。
- 無(wú)需對(duì)網(wǎng)絡(luò)配置或管理工具做任何修改。
- 服務(wù)不中斷的前提下動(dòng)態(tài)重新編程,這意味著可以按需加入或移除功能,而不會(huì)引起任何流量中斷,也能動(dòng)態(tài)響應(yīng)系統(tǒng)其他部分的的變化。
- 主流的發(fā)行版中,Linux內(nèi)核已經(jīng)內(nèi)置并啟用了XDP,并且支持主流的高速網(wǎng)絡(luò)驅(qū)動(dòng),4.8+的內(nèi)核已內(nèi)置,5.4+能夠完全使用。
缺點(diǎn):
- XDP不提供緩存隊(duì)列(qdisc),TX設(shè)備太慢時(shí)會(huì)直接丟包,因而不能在RX比TX快的設(shè)備上使用XDP。
- 由于不具備緩存隊(duì)列,對(duì)與IP分片不太友好。
- XDP程序是專用的,不具備網(wǎng)絡(luò)協(xié)議棧的通用性。
適用案例:
? 軟件路由(XDP routing)
Linux內(nèi)核實(shí)現(xiàn)了一個(gè)功能完全的路由表,生態(tài)系統(tǒng)功能豐富,結(jié)合XDP包處理框架實(shí)現(xiàn)了一個(gè)完美的路由功能。其性能與常規(guī)的Linux內(nèi)核網(wǎng)絡(luò)棧相比提升了2.5 - 3倍左右。
? ACL/DDoS防御
XDP可以直接在應(yīng)用服務(wù)器上部署包過(guò)濾程序來(lái)防御此類攻擊,無(wú)須修改應(yīng)用代碼。如果應(yīng)用部署在虛擬機(jī)里,XDP程序還可以部署在宿主機(jī)上,保護(hù)機(jī)器上所有的虛擬機(jī)。其性能單核可以輕松處理10Gbps的最小包Dos流量。這種DDOS防御的部署更加靈活。
相比iptables相對(duì)較晚的hook點(diǎn),XDP的丟包速率要比iptables高4倍左右。
? 負(fù)載均衡(load balancing)
其原理是通過(guò)對(duì)包頭進(jìn)行哈希,以此選擇目標(biāo)應(yīng)用服務(wù)器,然后將數(shù)據(jù)包進(jìn)行封裝,發(fā)送給應(yīng)用服務(wù)器,應(yīng)用解封,處理請(qǐng)求,會(huì)包給客戶端。在次過(guò)程中,XDP服務(wù)哈希,封包發(fā)送。通過(guò)bpf map進(jìn)行配置,其性能比Linux內(nèi)核IPVS高4倍左右。
Part 04、未來(lái)展望
ebpf/XDP作為L(zhǎng)inux網(wǎng)絡(luò)革新技術(shù)正在悄悄的改變著Linux網(wǎng)絡(luò)發(fā)展模式,當(dāng)前,XDP技術(shù)被OVS、Cilium、Polycube等用于網(wǎng)絡(luò)快速路徑的新選擇,DPDK也相應(yīng)的做了AF_XDP PMD。XDP程序在CPU可用來(lái)處理的最早時(shí)間點(diǎn)被執(zhí)行,尤其適合DDoS防御、防火墻、負(fù)載均衡。基于XDP+eBPF的的ACL解決方案也有望改善目前的性能瓶頸,有望取代iptables解決方案。
XDP作為一個(gè)安全、快速、可編程、集成到操作系統(tǒng)內(nèi)核的包處理框架。XDP性能雖然與基于kernel bypass的DPDK仍有差距,但優(yōu)異的可擴(kuò)展性,可編程性等提供了非常有競(jìng)爭(zhēng)力的優(yōu)勢(shì)。相比于kernel bypass這種非此即彼、完全繞開內(nèi)核的方式,我們相信XDP有更廣闊的的應(yīng)用前景。