summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2010-07-07 15:33:14 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2010-07-07 15:33:14 +0200
commit2cb1a08254740ecd592c7917bb86c8234a34537e (patch)
treee487c401317462893646e555615d415a7ff3b770
parent52161a61d1d0db2a9ca8ce652d7272dd4954c59f (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>
-rw-r--r--src/conntrack/bsf.c2
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);
}