BPF

✍ dations ◷ 2025-12-04 19:58:07 #BPF

伯克利包过滤器(Berkeley Packet Filter,缩写 BPF),是类Unix系统上数据链路层的一种原始接口,提供原始链路层封包的收发。除此之外,如果网卡驱动支持混杂模式,那么它可以让网卡处于此种模式,这样可以收到网络上的所有包,不管他们的目的地是不是所在主机。

另外,BPF支持过滤数据包——用户态的进程可以提供一个过滤程序来声明它想收到哪些数据包。通过这种过滤可以避免从操作系统内核向用户态复制其他对用户态程序无用的数据包,从而极大地提高性能。

BPF有时也只表示过滤机制,而不是整个接口。一些系统,比如Linux和Tru64 Unix,提供了数据链路层的原始接口,而不是BPF的接口,但使用了BPF的过滤机制。

BSD 内核实现例程如 bpf_mtap()bpf_tap(),以BPF_MTAP()BPF_TAP()等宏定义的形式进行包裹由网卡驱动(以及伪驱动pseudo-drivers) 向BPF机制发送进出的封包。

原始的论文由Steven McCanne 和 Van Jacobson于1992年在劳伦斯伯克利国家实验室工作时编写,于1993年在San Diego举办的USENIX冬季会议上正式发表。

许多版本的Unix操作系统提供了用于捕获数据包的设施,使得监控当前网络情况成为了可能。但是,因为网络监控程序运行在用户态,数据包必须被拷贝来通过内核与用户态之间的边界。可以通过使用一种被称为“数据包过滤器”的内核代理来减少拷贝的数量,它会尽量早地丢弃不想要的数据包。早先的数据包过滤器被实现为基于栈的虚拟机,在RISC CPU上性能不佳。BPF使用了一种新的基于寄存器(Register)的虚拟机,在性能上有显著提升。

BPF的过滤功能是以对于BPF虚拟机机器语言的一种解释器的形式实现的,使用这种语言编写的程序可以抓取数据包,对数据包中的数据采取算术操作,并将结果与常量或数据包中的数据或结果中的测试位比较,根据比较的结果决定接受还是拒绝封包。

传统的Unix BPF实现能够被用于用户态,尽管它是为内核态编写。这是通过编译时的条件预处理完成的。

一些项目使用了不同以往的BPF指令集或者执行方法。

包括FreeBSD和WinPcap在内的一些平台,使用即时编译(JIT)编译器来把BPF指令转换为原始字节码,以进一步提高性能。Linux有一个BPF JIT编译器,但被默认禁用。

此虚拟机语言的内核态解释器则被用于其他操作系统的原始数据链路机制,例如Tru64 Unix系统,以及Linux内核中的套接字过滤器,和WinPcap数据包抓取机制。

用户态解释器由实现了pcap API的libpcap/WinPcap提供,因此,在对此过滤机制没有内核态支持的系统上抓取数据包时,数据包可以在内核态过滤,使用pcap API的代码可以工作于此两种模式;在使用用户态过滤的系统上,所有数据包由内核态复制到用户态,包括将被过滤出去的封包。这种解释器也可以用于包含由pcap抓取的封包的文件。

2007年,Robert Watson(英语:Robert Watson (computer scientist))与Christian Peron为FreeBSD操作系统中BPF的实现加入了zero-copy buffer extension,使得驱动程序中断处理器中的内核封包抓取能直接向用户内存写,以避免BPF设备收到的所有封包数据的两次复制需要,一份副本存在于用户进程的接收路径中,这保证了不同BPF设备调用者的独立性,同时使得只把封包头部放入BPF缓冲区,而不是复制整个封包数据。

Will Drewry为seccomp(安全计算)系统调用策略添加了BPF过滤器,这也是BPF第一次在网络领域之外的使用。

从3.18版本开始,Linux 内核提供了一种扩展的BPF虚拟机,被称为“extended BPF”,简称为eBPF。它能够被用于非网络相关的功能,比如附在不同的tracepoints上,从而获取当前内核运行的许多信息。

传统的BPF,现在被称为cBPF(classical BPF)。

eBPF由Alexei Starovoitov在PluMgrid工作时设计,这家公司专注于研究新的方法来设计软件定义网络解决方案。在它只是一个提议时,Daniel Borkmann——Red Hat公司的内核工程师,帮助修改使得它能够进入内核代码并完全替代已有的BPF实现。这是二十年来BPF首次主要的更新,使得BPF成为了一个通用的虚拟机。

eBPF被Linux内核合并的事件线如下:

因为eBPF虚拟机使用的是类似于汇编语言的指令,对于程序编写来说直接使用难度非常大。和将C语言生成汇编语言类似,现在的编译器正在逐步完善从更高级的语言生成BPF虚拟机使用的指令。LLVM在3.7版本开始支持BPF作为后端输出。GCC 10也将会支持BPF作为后端。BCC是IOVisor项目下的编译器工具集,用于创建内核跟踪(tracing)工具。bpftrace是为eBPF设计的高级跟踪语言,在Linux内核(4.x)中提供。

eBPF现在被应用于网络、跟踪、内核优化、硬件建模等领域。

Spectre攻击可以利用Linux内核的eBPF JIT编译器来从其它内核进程提取信息。

相关

  • 照度照度(英语:Illuminance)是每单位面积所接收到的光通量。SI制单位是勒克斯(lx=lux)或辐透(ph=phot),1勒克斯=1流明/平方米,1 辐透 = 1流明/平方厘米,1 辐透 = 10000勒克斯。居家的一般
  • 最中最中(日语:もなか)是一种日本甜食,做法是将糯米粉溶于水中杆成薄皮,放入模型中烤制成型,最后再将红豆馅填入烤好的外皮中。原本以外皮包着红豆内馅才称为最中,现在里头包着其他食材
  • 三疣梭子蟹Neptunus trituberculatus Miers, 1876三疣梭子蟹(学名:Portunus trituberculatus)为梭子蟹科梭子蟹属的动物。头胸甲宽大,两侧具有长棘,略呈梭形;暗紫色,有青白色云斑;蟹足长大,第四
  • 低密度脂蛋白低密度脂蛋白(英语:low-density lipoprotein,缩写为LDL)指一类及范围的脂蛋白粒子,有着约18-25纳米直径的大小,负责在血液内运载脂肪酸分子至全身供细胞使用。它是由肝脏所产生的
  • 老挝观光老挝观光是老挝发展速度最蓬勃的产业,该产业由位于老挝首都永珍的国家观光管理局管辖。
  • 马特·布拉德马修·戈登·布拉德(英语:Matthew Gordon Bullard,1967年6月5日-),生于爱荷华州的West Des Moines,美国前职业篮球运动员,他从爱荷华大学毕业后未能在NBA选秀中被摘牌。 布拉德在休斯敦火箭度过了九个赛季(1990-94, 1996-2001),也在亚特兰大老鹰(1995-96)和夏洛特黄蜂(2001-02)各待了一个赛季,他也在1994-95赛季效力过希腊联赛劲旅萨洛尼卡篮球俱乐部(英语:PAOK BC)。他的职业生涯平均每场得5.3分和两个篮板。在休斯敦火箭时期
  • 决战第一名决战第一名(英语:Super Star No. 1),台湾模特儿选秀节目,主持为蔡康永及白歆惠。第一季于2007年12月至2008年3月播出。第二季则于2008年5月至8月播出。
  • 工业社会工业社会是以工业生产为经济主导的社会,是继农业社会或传统社会之后的发展阶段,主要以资本主义为发展手段。有时又称为现代社会。在社会学中,工业社会是一个由工业科技技术驱动的社会,以实现专业化大规模生产,支持具有高分工能力的大量人口。这样的结构发展在工业革命之后,并取代了前工业时代。工业社会通常是群众社会,经常形成对比传统的、以血缘和地缘来互相连结的社会。十八世纪中,英国人瓦特改良了蒸汽机和纺织机。之后工业革命散播至西欧大陆,在一百多年内,更由欧陆蔓延到北美、东欧,乃至东亚各国,不久全世界的大都市都渐渐发展为发
  • 利亚姆·麦肯泰尔利亚姆·麦肯泰尔(Liam McIntyre,1982年2月8日- )是一位澳洲演员,出生在阿德莱德。麦肯泰尔在Starz电视剧《斯巴达克斯:复仇》和《斯巴达克斯:诅咒之战》中饰演主角。他也出演电影《大力神》、电视剧《闪电侠》、电子游戏《战争机器4》和《》。2014年1月5日,他和女演员Erin Hasan结婚。2016年3月13日,他与Smosh Games合作制作了一段YouTube影片,以推广他的卡牌游戏Monster Lab。
  • 普罗米修斯计划普罗米修斯计划 (波兰语:Prometeizm)是由波兰的约瑟夫·毕苏斯基建立的政治计划。其目的是通过支持居住在俄罗斯帝国,及其继承者苏联边界上的主要的非俄罗斯民族的民族独立运动,来削弱上述两个国家。 在两次世界大战之间,普罗米修斯计划和毕苏斯基的另一想法“海间联邦”构成了他和他的部分政治继承者的两大互补地缘政治战略。毕苏斯基之所以得出普罗米修斯计划,是因为他精通关于俄罗斯的知识,而这些知识是在他被俄罗斯帝国流放到东西伯利亚后得到的。“普罗米修斯计划”一词来自希腊神话当中的普罗米修斯,他给人类带来火,成为