BPF

✍ dations ◷ 2025-09-13 20:53:01 #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编译器来从其它内核进程提取信息。

相关

  • 反鸟反鸟(学名:Enantiornis leali)是一种掠食性的鸟翼类恐龙,是反鸟目反鸟科反鸟属的唯一个已知物种,生存于白垩纪晚期的阿根廷。反鸟是反鸟亚纲中较大体型的成员,体长约1米。其生态位
  • 弗朗西斯科·佛朗哥独裁时期弗朗西斯科·佛朗哥独裁时期(西班牙语:Dictadura de Francisco Franco)是指西班牙历史上1939年-1975年弗朗西斯科·佛朗哥实行独裁统治的时期。该时期西班牙的正式国号为西班牙
  • A SONG FOR YOU为你歌唱《为你歌唱》(韩语:어송포유,英语:A Song For You)是由KBS制作的全球互动性音乐节目!由全球190多国中的粉丝留言及视频来与嘉宾进行互动,并演唱粉丝们所点播的歌曲,第二季由2013年8
  • 恭顺皇贵妃恭顺皇贵妃(1787年-1860年4月23日),钮祜禄氏。满洲镶黄旗人。主事善庆之女,嘉庆帝之皇贵妃。乾隆五十二年出生。恭顺皇贵妃虽然并非出自嫡流大宗,但也是官宦世家出身。钮祜禄氏的
  • 可计算数 N ⊆ Z ⊆ Q ⊆ R ⊆
  • 春子《春子》是一部描写翁春子师姐真实人生的电视剧,共5集,于2015年2月9日至2015年2月13日在大爱电视《长情剧展》时段(台湾时间星期一至星期五晚上22:00)播放。 本段时间均以二十
  • 北长山岛北长山岛位于华北平原山东半岛以北的渤海海峡中,是庙岛群岛中一座岛屿。北长山岛原属长岛县管辖,2020年长岛县与蓬莱市合并成立了烟台市蓬莱区,现北长山岛属于蓬莱区北长山乡管辖。历史上,北长山岛与南长山岛合称为“长山岛”,因岛形南北狭长故名。北长山岛略呈长形,长轴北西向延展,长约5.1千米,东西最宽处约2.5千米。面积7.9778平方千米,海岸线长15.40千米。最高点位于岛中部的蒿山,海拔195.7米。北长山岛与南长山岛之间有玉石街大坝和南北长山联岛大桥相连。
  • 田村亮 (演员)田村亮(1946年5月24日-),本名田村幸照,是出身于京都府京都市右京区的演员,毕业于成城大学经济学部。他是演员阪东妻三郎(本名:田村传吉)的四男(么子),还在小学一年级的时候就失去父亲。而他的兄弟包括演员田村高广(长男)、田村正和(三男),他们被合称为“田村三兄弟”,长期在影剧圈内活跃。至于二哥田村登志磨,则已退出演艺界,所以事实上田村兄弟一共有四人。1966年他以电影‘狂暴豪右卫门’出道,之后出演不少时代剧与现代剧。他的特色是拥有一种独特魅力的声音。至于现代剧的部分,他因经常参与两小时特别剧的演出而
  • 萨利姆·多萨里萨利姆·多萨里(阿拉伯语:سالم محمد الدوسري‎,1991年8月19日-)是沙特阿拉伯的职业足球运动员,司职边锋,现效力于沙特阿拉伯职业足球联赛的沙特希拉尔足球俱乐部。2018年,作为沙特阿拉伯足球协会和西班牙足球甲级联赛合作计划的一部分,他被租借至西甲联赛的比利亚雷亚尔效力,出场一次。他在2012年被沙特阿拉伯国家足球队征召参加2014年国际足联世界杯预选赛,在对澳大利亚的客场比赛中打进他的首粒国家队进球。2018年5月他入选沙特阿拉伯征战2018年国际足联世界杯的大名单。截至2018年5
  • 十角星十角星,又称十芒星,是指一种有十只尖角,并以十条直线画成的星星图形。在几何学中,十角星是边自我相交的十边形。正十角星只有一种,其施莱夫利符号为{10/3},与所述第二数字差别在绘制十角星时顶点间隔数。正十角星每边为 5 − 2 {\displaystyle {\sqrt {5}}-2} ,正十角星各边的长度比例,以及在每个边的交叉点比