BPF
伯克利包過濾器(Berkeley Packet Filter,縮寫 BPF), 是類 Unix 系統上數據鏈路層的一種原始接口,提供原始鏈路層封包的收發。除了這以外,若是網卡驅動支持濫做伙模式,伊會當予網卡佇遮看著的模式,按呢會當收著網路頂懸所有包,毋管𪜶的目的地是毋是所在主機。
另外咧,BPF 支持過濾數據包—— 用戶態的進程會當提供一个過濾程序來聲明伊想欲收到佗一寡數據包。通過這種過濾會當避免對作業系統內底核向用戶態複製其他對用戶態程序無路用的數據包,對極大的提高性能。
BPF 有當時仔嘛表示過濾機制,毋是規个接口。一寡系統,比如講 Linux 和 Tru 六十四 Unix,提供數據鏈路層的原始接口,毋是 BPF 的接口,猶毋過使用矣 BPF 的過濾機制。
BSD 內底核實現譬如講 ` bpf _ mtap ( ) ` 和 ` bpf _ tap ( ) `,以 ` BPF _ MTAP ( ) ` 和 ` BPF _ TAP ( ) ` 等宏定義的形式進行包裹由網卡驅動 ( 猶閣有偽驅動 pseudo-drivers ) 向 BPF 機製發送出入的封包。
歷史
原始的論文 Steven McCanne 和 Van Jacobson 佇一九九二年佇勞倫斯伯克利國家實驗室工作時編寫,佇一九九三年佇一 San Diego 舉辦的 USENIX 冬季會議上正式發表。
背景
足濟版本的 Unix 作業系統提供了用佇網著數據包的設施,予監控早前網路狀況成做可能。猶毋過,因為網路監控程序運行佇咧用戶態,數據包著愛被副貝來通過內核佮用戶態之間的邊界。會當通過使用一種予人號做「數據包過濾器」的內核代理來減少複貝的數量,伊會盡量早的擲捒無想欲愛的數據包。早前的數據包過濾器予實現為基於棧的虛擬機,佇咧 RISC CPU 頂性能不好。BPF 使用一種新的暫存器 ( Register ) 的虛擬機,佇性能上有顯的提升。
過濾
BPF 的過濾功能是以對 BPF 虛擬機器語言的一種解說器的形式實現的,使用這種語言編寫的程序會當掠數據包,著數據包中的數據採取算術操作,而且結果佮常量抑是數據包中的數據抑是結果中的測試位較,根據較的結果決定接受抑是拒絕封包。
傳統的 Unix BPF 實現會當予人用佇戶態,就算講伊是內核態編寫。這是通過編譯時的條件預處理完成的。
優化
一寡項目使用了無仝的往過的 BPF 指令集抑是講執行方法。
包括講 FreeBSD 和 WinPcap 在內的一寡平台,使用即時編譯(JIT)編譯器來共 BPF 指令轉換做原始字節碼,以進一步提高性能。Linux 有一个 BPF JIT 編譯器,但是予人恬認禁用。
虛擬機語言的內核態解說器予人用佇咧其他作業系統的原始數據鏈路機制,比如講 Tru 六十四 Unix 系統,以及 Linux 內核中的套接字過濾器,和 WinPcap 數據包括機制。
用戶態解說器由實現 pcap API 的 libpcap / WinPcap 提供,所以,佇咧對這个濾機制無內核態支持的系統上掠數據包的時陣,數據包會使在內核態過濾,使用 pcap API 的代碼會當做工課佇這兩種模式;佇咧使用戶態過濾的系統上,所有的數據包佇內核態複製到用戶態,包括將被過濾出去的封包。這種解說器嘛會當用於包含因為 pcap 掠的封包的文件。
二空空七年,Robert Watson 佮 Christian Peron 為 FreeBSD 作業系統當中 BPF 的實現加入了 zero-copy buffer extension,予人驅動的程序斷去處理器內底的內核封皮包去掠會當直接向用戶內底寫,以避免 BPF 設備收著的所有封包數據的兩改複製需要,一份副本存在佇用戶進程的接收路徑內底,這保證著無仝 BPF 設備調用者的獨立性,同時只共封包頭殼囥入 BPF 緩衝區,毋是複製規个封包數據。
Will Drewry 為 seccomp(安全計算)系統調用策略添加矣 BPF 過濾器,按呢嘛是 BPF 第一擺佇網路領域以外的使用。
eBPF
對三鋪一八版本開始,Linux 內核提供一種擴展的 BPF 虛擬機,予人叫做是「extended BPF」,簡稱做 eBPF。伊會當予人用過非網路相關的功能,比如講附佇無仝的 tracepoints 上,對而且得著當前內核運行的濟濟信息。
傳統的 BPF,這馬予人叫做是 cBPF(classical BPF)。
eBPF 由 Alexei Starovoitov 佇咧 PluMgrid 工作時設計,這間公司專注心研究新的方法來設計軟體定義網路解決方案。佇咧伊只是一个提議的時陣,Daniel Borkmann—— Red Hat 公司的內核工程師,幫助修改予伊會當入去內核代碼並且完全替代有的 BPF 實現。這是二十年來 BPF 頭擺主要的更新,予得 BPF 成做一个通用的虛擬機。
eBPF 予被 Linux 內底核合併的事件線如下:
- 二空一四年三月。eBPF 補丁去予人合做伙 Linux 內核。
- 二空一四年六月。JIT 組件被合併到內核三鋪一五版本。
- 二空一四年十二月。bpf 系統調用被合併到內核三鋪一八版本。
- 在後來的 Linux 四 . x 系列版內底閣添加矣嘿著 kprobes、uprobes、tracepoints 以及 perf \ _ events 支持。
因為乎 eBPF 虛擬機使用的是類似佇咧彙編語言的指令,對著程序編寫來講直接使用難度非常大。佮將 C 語言生做彙編語言類似,這馬的編譯器當咧沓沓仔完善對閣較高級的語言生做 BPF 虛擬機使用的指令。LLVM 佇咧三更七版本開始支持 BPF 做為後端輸出。GCC 十嘛將會支持 BPF 作為後端。BCC 是 IOVisor 項目下的編譯器工具集,是用佇創建內核佮蹤(tracing)工具。bpftrace 是為 eBPF 設計的高級佮蹤語言,佇咧 Linux 內核(四 . x)中提供。
eBPF 這馬予人應用佇網路、跟蹤、內核優化、硬體建模等等的領域。
安全
Spectre 攻擊會當利用 Linux 內核的 eBPF JIT 編譯器來對其他內核進程提信息。
參考文獻
外部連結
- The BSD Packet Filter : A New Architecture for User-level Packet Capture ( PDF )
- FreeBSD 開發者大會上講 BPF 中 Zero-copy 的材料 ( PDF )
- FreeBSD 八 . x BPF ( 四 ) 手冊,包含 zero-copy BPF 衝區的描述
- BPF 閱讀清單