diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2010-07-07 15:33:14 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2010-07-07 15:33:14 +0200 |
commit | 2cb1a08254740ecd592c7917bb86c8234a34537e (patch) | |
tree | e487c401317462893646e555615d415a7ff3b770 /src | |
parent | 52161a61d1d0db2a9ca8ce652d7272dd4954c59f (diff) |
bsf: fix filtering for several network address/mask
This patch fixes kernel-space filtering via BSF for several
network addresses. The problem is that we store the network
address of the netlink message in the ALU. Then, we perform
an AND of the network mask and the address, this operation
is stored again in the ALU. If we compare the address with
a second address, we have to reload the address to the ALU.
The following example clarifies the problem, in the following
order, we want to filter:
1) 224.0.0.0/4
2) 127.0.0.1/32
Now, we receive traffic from 127.0.0.1, it should be filtered.
However, without this patch, it is not. Let's see why:
ALU 7f000001 (addr=127.0.0.1)
AND f0000000 (cidr=4)
-------------------------------
ALU 70000000
this is stored in the ALU. Then, we check for 127.0.0.1:
ALU 70000000 (addr=127.0.0.1) <-- it should be 7f000001
AND ffffffff (cidr=32)
-------------------------------
ALU 70000000
This does not match 7f000001. To fix this, we have to reload
7f000001 to the ALU. Thus, the second comparison works fine.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/conntrack/bsf.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/conntrack/bsf.c b/src/conntrack/bsf.c index 0b71e8e..69a7f14 100644 --- a/src/conntrack/bsf.c +++ b/src/conntrack/bsf.c @@ -434,11 +434,11 @@ bsf_add_addr_ipv4_filter(const struct nfct_filter *f, j += nfct_bsf_find_attr(this, type, j); j += nfct_bsf_cmp_k_stack(this, 0, label_continue - j, j, s); j += nfct_bsf_x_equal_a(this, j); - j += nfct_bsf_load_attr(this, BPF_W, j); for (i = 0; i < f->l3proto_elems[dir]; i++) { int ip = f->l3proto[dir][i].addr & f->l3proto[dir][i].mask; + j += nfct_bsf_load_attr(this, BPF_W, j); j += nfct_bsf_alu_and(this, f->l3proto[dir][i].mask, j); j += nfct_bsf_cmp_k_stack(this, ip, jt - j, j, s); } |