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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).