From: Ken-ichirou MATSUZAWA <chamaken@gmail.com>
To: The netfilter developer mailinglist <netfilter-devel@vger.kernel.org>
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
Subject: [PATCH libnetfilter_conntrack v2 2/2] conntrack: add zone event filter
Date: Mon, 9 Jun 2014 19:04:04 +0900 [thread overview]
Message-ID: <20140609100404.GC28658@gmail.com> (raw)
In-Reply-To: <20140609095948.GA28658@gmail.com>
This patch adds zone filter for event listener.
Signed-off-by: Ken-ichirou MATSUZAWA <chamas@h4.dion.ne.jp>
---
include/internal/object.h | 4 ++
.../libnetfilter_conntrack.h | 1 +
src/conntrack/bsf.c | 71 +++++++++++++++++++---
src/conntrack/filter.c | 10 +++
4 files changed, 77 insertions(+), 9 deletions(-)
diff --git a/include/internal/object.h b/include/internal/object.h
index 1259467..83d9010 100644
--- a/include/internal/object.h
+++ b/include/internal/object.h
@@ -270,6 +270,10 @@ struct nfct_filter {
u_int32_t mask;
} mark[__FILTER_MARK_MAX];
+ u_int32_t zone_elems;
+#define __FILTER_ZONE_MAX 511
+ u_int16_t zone[__FILTER_ZONE_MAX];
+
u_int32_t set[1];
};
diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
index 03bf3ca..52fee85 100644
--- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h
+++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
@@ -499,6 +499,7 @@ enum nfct_filter_attr {
NFCT_FILTER_SRC_IPV6, /* struct nfct_filter_ipv6 */
NFCT_FILTER_DST_IPV6, /* struct nfct_filter_ipv6 */
NFCT_FILTER_MARK, /* struct nfct_filter_dump_mark */
+ NFCT_FILTER_ZONE, /* u_int16_t */
NFCT_FILTER_MAX
};
diff --git a/src/conntrack/bsf.c b/src/conntrack/bsf.c
index d4dfaec..2a46d4d 100644
--- a/src/conntrack/bsf.c
+++ b/src/conntrack/bsf.c
@@ -316,6 +316,20 @@ bsf_cmp_subsys(struct sock_filter *this, int pos, u_int8_t subsys)
}
static int
+nfct_bsf_skip_if_a(struct sock_filter *this, int pos,
+ u_int32_t aval, u_int8_t nskip)
+{
+ struct sock_filter __code = {
+ .code = BPF_JMP|BPF_JEQ|BPF_K,
+ .k = aval,
+ .jt = nskip,
+ .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,
unsigned int cta_protoinfo_state,
@@ -683,13 +697,6 @@ bsf_add_mark_filter(const struct nfct_filter *f, struct sock_filter *this)
unsigned int jt;
struct stack *s;
struct jump jmp;
- struct sock_filter __code = {
- /* if (A == 0) skip next two */
- .code = BPF_JMP|BPF_JEQ|BPF_K,
- .k = 0,
- .jt = 2,
- .jf = 0,
- };
/* nothing to filter, skip */
if (f->mark_elems == 0)
@@ -706,8 +713,7 @@ bsf_add_mark_filter(const struct nfct_filter *f, struct sock_filter *this)
j = 0;
j += nfct_bsf_load_payload_offset(this, j);
j += nfct_bsf_find_attr(this, CTA_MARK, j);
- memcpy(&this[j], &__code, sizeof(__code));
- j += NEW_POS(__code);
+ j += nfct_bsf_skip_if_a(this, j, 0, 2);
j += nfct_bsf_x_equal_a(this, j);
j += nfct_bsf_load_attr(this, BPF_W, j);
j += nfct_bsf_x_equal_a(this, j);
@@ -733,6 +739,50 @@ bsf_add_mark_filter(const struct nfct_filter *f, struct sock_filter *this)
return j;
}
+static int
+bsf_add_zone_filter(const struct nfct_filter *f, struct sock_filter *this)
+{
+ unsigned int i, j;
+ unsigned int jt;
+ struct stack *s;
+ struct jump jmp;
+
+ /* nothing to filter, skip */
+ if (f->zone_elems == 0)
+ return 0;
+
+ s = stack_create(sizeof(struct jump), 3 + 511);
+ if (s == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ jt = 1;
+ j = 0;
+ j += nfct_bsf_load_payload_offset(this, j);
+ j += nfct_bsf_find_attr(this, CTA_ZONE, j);
+ /* A message which does not contain CTA_ZONE is regarded
+ * as its value is 0. */
+ j += nfct_bsf_skip_if_a(this, j, 0, 2);
+ j += nfct_bsf_x_equal_a(this, j);
+ j += nfct_bsf_load_attr(this, BPF_H, j);
+
+ for (i = 0; i < f->zone_elems; i++)
+ j += nfct_bsf_cmp_k_stack(this, f->zone[i], jt - j, j, s);
+
+ while (stack_pop(s, &jmp) != -1)
+ this[jmp.line].jt += jmp.jt + j;
+
+ if (f->logic[NFCT_FILTER_ZONE] == NFCT_FILTER_LOGIC_NEGATIVE)
+ j += nfct_bsf_jump_to(this, 1, j);
+
+ j += nfct_bsf_ret_verdict(this, NFCT_FILTER_REJECT, j);
+
+ stack_destroy(s);
+
+ return j;
+}
+
/* this buffer must be big enough to store all the autogenerated lines */
#define BSF_BUFFER_SIZE 2048
@@ -769,6 +819,9 @@ int __setup_netlink_socket_filter(int fd, struct nfct_filter *f)
j += bsf_add_mark_filter(f, &bsf[j]);
show_filter(bsf, from, j, "---- check mark ----");
from = j;
+ j += bsf_add_zone_filter(f, &bsf[j]);
+ show_filter(bsf, from, j, "---- check zone ----");
+ from = j;
/* nothing to filter, skip */
if (j == 0)
diff --git a/src/conntrack/filter.c b/src/conntrack/filter.c
index 78fbbc5..34be99b 100644
--- a/src/conntrack/filter.c
+++ b/src/conntrack/filter.c
@@ -91,6 +91,15 @@ static void filter_attr_mark(struct nfct_filter *filter, const void *value)
filter->mark_elems++;
}
+static void filter_attr_zone(struct nfct_filter *filter, const void *value)
+{
+ if (filter->zone_elems >= __FILTER_ZONE_MAX)
+ return;
+
+ filter->zone[filter->zone_elems] = *(u_int16_t *)value;
+ filter->zone_elems++;
+}
+
const filter_attr filter_attr_array[NFCT_FILTER_MAX] = {
[NFCT_FILTER_L4PROTO] = filter_attr_l4proto,
[NFCT_FILTER_L4PROTO_STATE] = filter_attr_l4proto_state,
@@ -99,4 +108,5 @@ const filter_attr filter_attr_array[NFCT_FILTER_MAX] = {
[NFCT_FILTER_SRC_IPV6] = filter_attr_src_ipv6,
[NFCT_FILTER_DST_IPV6] = filter_attr_dst_ipv6,
[NFCT_FILTER_MARK] = filter_attr_mark,
+ [NFCT_FILTER_ZONE] = filter_attr_zone,
};
--
1.9.1
prev parent reply other threads:[~2014-06-09 10:04 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-09 9:59 [PATCH libnetfilter_conntrack v2 0/2] add event filters Ken-ichirou MATSUZAWA
2014-06-09 10:01 ` [PATCH libnetfilter_conntrack v2 1/2] conntrack: add mark event filter Ken-ichirou MATSUZAWA
2014-06-09 10:04 ` Ken-ichirou MATSUZAWA [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140609100404.GC28658@gmail.com \
--to=chamaken@gmail.com \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.