diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2010-10-12 13:24:08 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2010-11-08 23:40:33 +0100 |
commit | b245e4092c5a7f09729e64868a42e13f48ac5db8 (patch) | |
tree | a31692d718120b9c17951e2e583c3a7d554602ab /src/conntrack/bsf.c | |
parent | 417dc5fb87ade355d699ea523de870abc6dd1657 (diff) |
src: allow to use nfct handler for conntrack and expectations at the same time
This patch re-works the callback handling to allow the use the same socket
to send/receive commands and listen to events of both conntrack and
expectation subsystems. Now you can register one callback for conntrack
and one for expectation with the same handler with no problems (before
this patch, this was not possible, you required two different handlers).
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/conntrack/bsf.c')
-rw-r--r-- | src/conntrack/bsf.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/conntrack/bsf.c b/src/conntrack/bsf.c index 69a7f14..ae7fa4a 100644 --- a/src/conntrack/bsf.c +++ b/src/conntrack/bsf.c @@ -8,6 +8,7 @@ #include "internal/internal.h" #include "internal/stack.h" #include <linux/filter.h> +#include <stddef.h> /* offsetof */ #ifndef SKF_AD_NLATTR #define SKF_AD_NLATTR 12 @@ -214,6 +215,33 @@ nfct_bsf_jump_to(struct sock_filter *this, int line, int pos) return NEW_POS(__code); }; +/* this helps to skip messages coming from the ctnetlink expectation subsys. */ +static int +bsf_cmp_subsys(struct sock_filter *this, int pos, u_int8_t subsys) +{ + struct sock_filter __code[] = { + [0] = { + /* X = offset to nlh->nlmsg_type */ + .code = BPF_LDX|BPF_IMM, + .k = offsetof(struct nlmsghdr, nlmsg_type), + }, + [1] = { + /* A = skb->data[X+k:B] (subsys_id) */ + .code = BPF_LD|BPF_B|BPF_IND, + .k = sizeof(u_int8_t), + }, + [2] = { + /* A == subsys ? jump +1 : accept */ + .code = BPF_JMP|BPF_JEQ|BPF_K, + .k = subsys, + .jt = 1, + .jf = 0, + }, + }; + memcpy(&this[pos], &__code, sizeof(__code)); + return NEW_POS(__code); +} + static int add_state_filter_cta(struct sock_filter *this, unsigned int cta_protoinfo_proto, @@ -584,6 +612,8 @@ int __setup_netlink_socket_filter(int fd, struct nfct_filter *f) memset(bsf, 0, sizeof(bsf)); + j += bsf_cmp_subsys(&bsf[j], j, NFNL_SUBSYS_CTNETLINK); + j += nfct_bsf_ret_verdict(bsf, NFCT_FILTER_ACCEPT, j); j += bsf_add_proto_filter(f, &bsf[j]); j += bsf_add_saddr_ipv4_filter(f, &bsf[j]); j += bsf_add_daddr_ipv4_filter(f, &bsf[j]); |