From b245e4092c5a7f09729e64868a42e13f48ac5db8 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 12 Oct 2010 13:24:08 +0200 Subject: 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 --- src/conntrack/bsf.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src/conntrack/bsf.c') 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 +#include /* 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]); -- cgit v1.2.3