将两个以太网接口的linux系统做成一个网桥,具备防火墙的功能,其应用场景为
WAN----PPPOE-D server----------linux bridge firewall-------------host (PPPOE client)
<------------------------ADSL link----------------------------------------------->
最后发现linux网桥并不能过滤PPPOE报文,它直接将PPPOE报文转发。
关于Linux内核bridge中的数据包处理流程有很多文章,在此不再赘述!
我的solution:
阅读linux内核的br_netfilter.c源码,发现它目前仅支持ETH报文和802.1q VLAN报文,对于其他类型的报文则直接放过,不会交给IP层做进一步的处理,因此,导致iptables无法对其进行过滤。解决方法很简单,主要修改两个文件的内容,分别是br_netfilter.c和netfilter_bridge.h,参考针对ETH_P_8021Q的一些处理代码,在整个文件中增加针对ETH_P_PPP_DISC和ETH_P_PPP_SES的代码,自己定义PPPOE_HLEN的长度为8,(注意在pppoe头中,ppp_ip为0x0021;同时请严格参考对ETH_P_8021Q的处理代码,有些地方是pull pppoe头,有些地方是push pppoe头)。
重新编译内核,问题解决。