summaryrefslogtreecommitdiffstats
path: root/src/conntrack/bsf.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2010-10-12 13:24:08 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2010-11-08 23:40:33 +0100
commitb245e4092c5a7f09729e64868a42e13f48ac5db8 (patch)
treea31692d718120b9c17951e2e583c3a7d554602ab /src/conntrack/bsf.c
parent417dc5fb87ade355d699ea523de870abc6dd1657 (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.c30
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]);