Netfilter hook on router not getting called for br

2019-09-12 07:31发布

问题:

I have a Linux kernel module that I'm running on a router: Netgear DGN2200v2 running Linux 2.6.30).

The kernel module registers a netfilter hook like so:

static struct nf_hook_ops nfho;

// ...

nfho.hook = hook_func;
nfho.owner = THIS_MODULE;
nfho.hooknum = 0; /* NF_IP_PRE_ROUTING */
nfho.pf = 0x20000000; // PF_INET
nfho.priority = INT_MIN;

int rc = nf_register_hook(&nfho);

I have two machines connected to my router, one via wifi and one using an Ethernet cable. The router itself is not connected to the Internet (i.e. all of my testing is on an isolated network).

My problem is that according to the printks in my hook function, the hook is getting called only for packets that are being sent directly to the router (i.e. if I ping the router from my machine) or directly from the router (i.e. if I telnet to the router and ping my machine from it).

However, the hook is not being called if the two machines ping each other, even though this traffic obviously still flows through the router.

According to http://www.tldp.org/HOWTO/html_single/Ethernet-Bridge-netfilter-HOWTO and http://www.linux-kongress.org/2002/papers/lk2002-spenneberg.pdf, if I set up a bridge in my router, then netfilter (or iptables) should be able to filter packets flowing through it. Looking at the output of brctl on the router (I can attach it if needed), it seems that such a bridge is already set up, yet my hook is not seeing those packets.

Is there a way to get netfilter hooks called for such packets as well?

回答1:

Just in case someone else runs into the same problem - the issue was that I used the wrong type of hook. I should have used PF_BRIDGE (0x07) rather than PF_INET (0x02). See also http://ebtables.netfilter.org/ebtables-hacking/ebtables-hacking-HOWTO-4.html.



回答2:

Use the following settings in your nf_hook_ops and make sure CONFIG_BRIDGE_NETFILTER is enabled in your kernel build.

.pf     = PF_BRIDGE,
.hooknum    = NF_BR_PRE_ROUTING,
.priority   = NF_BR_PRI_FIRST,