Skip to contentSkip to conversation

add mark filter

PATCH Superseded Ken-ichirou MATSUZAWA 2 participants 7 messages Apr 8, 2014 – Apr 15, 2014 netfilter

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover add mark filter

Hello,

This patch series enables mark filtering in NFCT plugin. Would you review it? I think there are two issues:

* libnetfilter_conntrack
I reused struct nfct_filter_dump_mark for NFCT_FILTER_MARK nfct_filter_add_attr(). Should I introduce a new one which will be the same field?

* ulogd
I've changed all dump function to use nfct_filter_dump excepting in do_purge(). It may require many tests so that is it better having a field to check mark filter has set and checking it on dumping?

Thanks.

#1 lore raw

PATCH 1/3 conntrack: add mark event filter

This patch adds mark filter for event listener, using same struct nfct_filter_dump_mark.

---
 include/internal/object.h                          |  7 ++++
 .../libnetfilter_conntrack.h                       |  1 +
 src/conntrack/bsf.c                                | 49 ++++++++++++++++++++++
 src/conntrack/filter.c                             | 13 ++++++
 4 files changed, 70 insertions(+)
include/internal/object.h +7 -0
index 540ad0d..1259467 100644
@@ -263,6 +263,13 @@ struct nfct_filter {
 		u_int32_t 	mask[4];
 	} l3proto_ipv6[2][__FILTER_IPV6_MAX];
 
+	u_int32_t 		mark_elems;
+	struct {
+#define __FILTER_MARK_MAX	127
+		u_int32_t 	val;
+		u_int32_t 	mask;
+	} mark[__FILTER_MARK_MAX];
+
 	u_int32_t 		set[1];
 };
 
include/libnetfilter_conntrack/libnetfilter_conntrack.h +1 -0
index d4542ba..890721a 100644
@@ -496,6 +496,7 @@ enum nfct_filter_attr {
 	NFCT_FILTER_DST_IPV4,		/* struct nfct_filter_ipv4 */
 	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_MAX
 };
 
src/conntrack/bsf.c +49 -0

61 lines not on this page · raw message

src/conntrack/filter.c +13 -0
index 026545a..78fbbc5 100644
@@ -79,6 +79,18 @@ static void filter_attr_dst_ipv6(struct nfct_filter *filter, const void *value)
 	filter->l3proto_elems_ipv6[1]++;
 }
 
+static void filter_attr_mark(struct nfct_filter *filter, const void *value)
+{
+	const struct nfct_filter_dump_mark *this = value;
+
+	if (filter->mark_elems >= __FILTER_MARK_MAX)
+		return;
+
+	filter->mark[filter->mark_elems].val = this->val;
+	filter->mark[filter->mark_elems].mask = this->mask;
+	filter->mark_elems++;
+}
+
 const filter_attr filter_attr_array[NFCT_FILTER_MAX] = {
 	[NFCT_FILTER_L4PROTO]		= filter_attr_l4proto,
 	[NFCT_FILTER_L4PROTO_STATE]	= filter_attr_l4proto_state,
@@ -86,4 +98,5 @@ const filter_attr filter_attr_array[NFCT_FILTER_MAX] = {
 	[NFCT_FILTER_DST_IPV4]		= filter_attr_dst_ipv4,
 	[NFCT_FILTER_SRC_IPV6]		= filter_attr_src_ipv6,
 	[NFCT_FILTER_DST_IPV6]		= filter_attr_dst_ipv6,
+	[NFCT_FILTER_MARK]		= filter_attr_mark,
 };
Signature · 1 line
1.8.5.3
#2 lore raw

Re: [libnetfilter_conntrack PATCH 1/3] conntrack: add mark event filter

Quoted 2 lines · Ken-ichirou MATSUZAWA

This patch adds mark filter for event listener, using same struct nfct_filter_dump_mark.

OK, let's put this in the tree.

#3 lore raw

PATCH RESEND 1/3 conntrack: add mark event filter

This patch adds mark filter for event listener, using same struct nfct_filter_dump_mark.

Signed-off-by Ken-ichirou MATSUZAWA <[email protected]>

---
 include/internal/object.h                          |  7 +++
 .../libnetfilter_conntrack.h                       |  1 +
 src/conntrack/bsf.c                                | 55 ++++++++++++++++++++++
 src/conntrack/filter.c                             | 13 +++++
 4 files changed, 76 insertions(+)
include/internal/object.h +7 -0
index 540ad0d..1259467 100644
@@ -263,6 +263,13 @@ struct nfct_filter {
 		u_int32_t 	mask[4];
 	} l3proto_ipv6[2][__FILTER_IPV6_MAX];
 
+	u_int32_t 		mark_elems;
+	struct {
+#define __FILTER_MARK_MAX	127
+		u_int32_t 	val;
+		u_int32_t 	mask;
+	} mark[__FILTER_MARK_MAX];
+
 	u_int32_t 		set[1];
 };
 
include/libnetfilter_conntrack/libnetfilter_conntrack.h +1 -0
index d4542ba..890721a 100644
@@ -496,6 +496,7 @@ enum nfct_filter_attr {
 	NFCT_FILTER_DST_IPV4,		/* struct nfct_filter_ipv4 */
 	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_MAX
 };
 
src/conntrack/bsf.c +55 -0

67 lines not on this page · raw message

src/conntrack/filter.c +13 -0
index 026545a..78fbbc5 100644
@@ -79,6 +79,18 @@ static void filter_attr_dst_ipv6(struct nfct_filter *filter, const void *value)
 	filter->l3proto_elems_ipv6[1]++;
 }
 
+static void filter_attr_mark(struct nfct_filter *filter, const void *value)
+{
+	const struct nfct_filter_dump_mark *this = value;
+
+	if (filter->mark_elems >= __FILTER_MARK_MAX)
+		return;
+
+	filter->mark[filter->mark_elems].val = this->val;
+	filter->mark[filter->mark_elems].mask = this->mask;
+	filter->mark_elems++;
+}
+
 const filter_attr filter_attr_array[NFCT_FILTER_MAX] = {
 	[NFCT_FILTER_L4PROTO]		= filter_attr_l4proto,
 	[NFCT_FILTER_L4PROTO_STATE]	= filter_attr_l4proto_state,
@@ -86,4 +98,5 @@ const filter_attr filter_attr_array[NFCT_FILTER_MAX] = {
 	[NFCT_FILTER_DST_IPV4]		= filter_attr_dst_ipv4,
 	[NFCT_FILTER_SRC_IPV6]		= filter_attr_src_ipv6,
 	[NFCT_FILTER_DST_IPV6]		= filter_attr_dst_ipv6,
+	[NFCT_FILTER_MARK]		= filter_attr_mark,
 };
Signature · 1 line
1.9.1
#4 lore raw

PATCH 2/3 add mark event filter

In reply to Ken-ichirou MATSUZAWA

This patch adds a new configuration variable which is used to limit conntrack event to connection of the mark.

---
 configure.ac                    | 15 +++++++++
 input/flow/ulogd_inpflow_NFCT.c | 75 +++++++++++++++++++++++++++++++++++++++--
 2 files changed, 88 insertions(+), 2 deletions(-)
configure.ac +15 -0
index 522c345..7e5f5fc 100644
@@ -58,6 +58,20 @@ AS_IF([test "x$enable_nfct" = "xyes"], [
     AC_DEFINE([BUILD_NFCT], [1], [Building nfct module])
 ])
 AM_CONDITIONAL([BUILD_NFCT], [test "x$enable_nfct" = "xyes"])
+AS_IF([test "x$enable_nfct" = "xyes"], [
+    AC_MSG_CHECKING([for enable mark filter for event])
+    AC_CACHE_VAL(ac_cv_nfct_filter_mark,
+    AC_TRY_COMPILE(
+        [ #include <libnetfilter_conntrack/libnetfilter_conntrack.h>],
+        [ int i = NFCT_FILTER_MARK; ],
+        ac_cv_nfct_filter_mark=yes,
+        ac_cv_nfct_filter_mark=no))
+    AC_MSG_RESULT($ac_cv_nfct_filter_mark)
+    AS_IF([test "x$ac_cv_nfct_filter_mark" = "xyes"], [
+        AC_DEFINE([HAVE_NFCT_FILTER_MARK], [1], [Building nfct mark event filter])
+    ])
+])
+
 AC_ARG_ENABLE(nfacct,
        AS_HELP_STRING([--enable-nfacct], [Enable nfacct module [default=yes]]),,[enable_nfacct=yes])
 AS_IF([test "x$enable_nfacct" = "xyes"], [
@@ -156,6 +170,7 @@ Ulogd configuration:
   Input plugins:
     NFLOG plugin:			${enable_nflog}
     NFCT plugin:			${enable_nfct}
+      with MARK event filter		${ac_cv_nfct_filter_mark}
     NFACCT plugin:			${enable_nfacct}
   Output plugins:
     PCAP plugin:			${enable_pcap}
input/flow/ulogd_inpflow_NFCT.c +73 -2

117 lines not on this page · raw message

Signature · 1 line
1.8.5.3
#5 lore raw

Re: [ulogd PATCH 2/3] add mark event filter

Quoted 20 lines · Ken-ichirou MATSUZAWA

This patch adds a new configuration variable which is used to limit conntrack event to connection of the mark.

---
 configure.ac                    | 15 +++++++++
 input/flow/ulogd_inpflow_NFCT.c | 75 +++++++++++++++++++++++++++++++++++++++--
 2 files changed, 88 insertions(+), 2 deletions(-)
configure.ac +3 -0
index 522c345..7e5f5fc 100644
@@ -58,6 +58,20 @@ AS_IF([test "x$enable_nfct" = "xyes"], [
     AC_DEFINE([BUILD_NFCT], [1], [Building nfct module])
 ])
 AM_CONDITIONAL([BUILD_NFCT], [test "x$enable_nfct" = "xyes"])
+AS_IF([test "x$enable_nfct" = "xyes"], [
+    AC_MSG_CHECKING([for enable mark filter for event])
+    AC_CACHE_VAL(ac_cv_nfct_filter_mark,

configure.ac AS_IF([test "x$enable_nfct" = "xyes"], [ · line 73

Quoted 10 lines
configure.ac +10 -0
+    AC_TRY_COMPILE(
+        [ #include <libnetfilter_conntrack/libnetfilter_conntrack.h>],
+        [ int i = NFCT_FILTER_MARK; ],
+        ac_cv_nfct_filter_mark=yes,
+        ac_cv_nfct_filter_mark=no))
+    AC_MSG_RESULT($ac_cv_nfct_filter_mark)
+    AS_IF([test "x$ac_cv_nfct_filter_mark" = "xyes"], [
+        AC_DEFINE([HAVE_NFCT_FILTER_MARK], [1], [Building nfct mark event filter])
+    ])
+])

I don't find a good reason to add a compile time option for this.

Eric?

#6 lore raw

PATCH 3/3 add mark dump filter

In reply to Ken-ichirou MATSUZAWA

This patch makes enable to filter dump by mark.

---
 input/flow/ulogd_inpflow_NFCT.c | 63 +++++++++++++++++++++++++++--------------
 1 file changed, 42 insertions(+), 21 deletions(-)
input/flow/ulogd_inpflow_NFCT.c +42 -21
index a5cf854..37b45e8 100644
@@ -71,6 +71,7 @@ struct nfct_pluginstance {
 	struct ulogd_timer ov_timer;	/* overrun retry timer */
 	struct hashtable *ct_active;
 	int nlbufsiz;			/* current netlink buffer size */
+	struct nfct_filter_dump *filter_dump;
 	struct nf_conntrack *ct;
 };
 
@@ -1003,8 +1004,9 @@ dump_reset_handler(enum nf_conntrack_msg_type type,
 
 static void get_ctr_zero(struct ulogd_pluginstance *upi)
 {
+	struct nfct_pluginstance *cpi =
+			(struct nfct_pluginstance *)upi->private;
 	struct nfct_handle *h;
-	int family = AF_UNSPEC;
 
 	h = nfct_open(CONNTRACK, 0);
 	if (h == NULL) {
@@ -1012,7 +1014,7 @@ static void get_ctr_zero(struct ulogd_pluginstance *upi)
 		return;
 	}
 	nfct_callback_register(h, NFCT_T_ALL, &dump_reset_handler, upi);
-	if (nfct_query(h, NFCT_Q_DUMP_RESET, &family) == -1)
+	if (nfct_query(h, NFCT_Q_DUMP_FILTER_RESET, cpi->filter_dump) == -1)
 		ulogd_log(ULOGD_FATAL, "Cannot dump and reset counters\n");
 
 	nfct_close(h);
@@ -1023,9 +1025,8 @@ static void polling_timer_cb(struct ulogd_timer *t, void *data)
 	struct ulogd_pluginstance *upi = data;
 	struct nfct_pluginstance *cpi =
 			(struct nfct_pluginstance *)upi->private;
-	int family = AF_UNSPEC;
 
-	nfct_query(cpi->pgh, NFCT_Q_DUMP, &family);
+	nfct_query(cpi->pgh, NFCT_Q_DUMP_FILTER, cpi->filter_dump);
 	hashtable_iterate(cpi->ct_active, upi, do_purge);
 	ulogd_add_timer(&cpi->timer, pollint_ce(upi->config_kset).u.value);
 }
@@ -1044,12 +1045,11 @@ static int configure_nfct(struct ulogd_pluginstance *upi,
 
 static void overrun_timeout(struct ulogd_timer *a, void *data)
 {
-	int family = AF_UNSPEC;
 	struct ulogd_pluginstance *upi = data;
 	struct nfct_pluginstance *cpi =
 			(struct nfct_pluginstance *)upi->private;
 
-	nfct_send(cpi->ovh, NFCT_Q_DUMP, &family);
+	nfct_send(cpi->ovh, NFCT_Q_DUMP_FILTER, cpi->filter_dump);
 }
 
 
@@ -1228,8 +1228,8 @@ static int build_nfct_filter_proto(struct nfct_filter *filter, char* filter_stri
 	return 0;
 }
 
-#if defined HAVE_NFCT_FILTER_MARK
-static int build_nfct_filter_mark(struct nfct_filter *filter, char* filter_string)
+static int build_nfct_filter_mark(struct nfct_filter *filter, char* filter_string,
+				struct nfct_filter_dump *filter_dump)
 {
 	char *p, *endptr;
 	uintmax_t v;
@@ -1264,24 +1264,27 @@ static int build_nfct_filter_mark(struct nfct_filter *filter, char* filter_strin
 		filter_mark.mask = UINT32_MAX;
 	}
 
-	ulogd_log(ULOGD_NOTICE, "adding mark to filter: \"%u/%u\"\n",
+	if (filter != NULL) {
+#if defined HAVE_NFCT_FILTER_MARK
+		nfct_filter_add_attr(filter, NFCT_FILTER_MARK, &filter_mark);
+		ulogd_log(ULOGD_NOTICE, "adding mark to event filter: \"%u/%u\"\n",
+			  filter_mark.val, filter_mark.mask);
+#else
+		ulogd_log(ULOGD_FATAL, "mark event filter is not supported\n");
+		return -1;
+#endif
+	}
+	nfct_filter_dump_set_attr(filter_dump, NFCT_FILTER_DUMP_MARK,
+					&filter_mark);
+	ulogd_log(ULOGD_NOTICE, "adding mark to dump filter: \"%u/%u\"\n",
 		  filter_mark.val, filter_mark.mask);
-	nfct_filter_add_attr(filter, NFCT_FILTER_MARK, &filter_mark);
 
 	return 0;
 
 invalid_error:
 	ulogd_log(ULOGD_FATAL, "invalid val/mask %s\n", filter_string);
 	return -1;
-
-}
-#else
-static int build_nfct_filter_mark(struct nfct_filter *filter, char* filter_string)
-{
-	ulogd_log(ULOGD_FATAL, "mark filter is not supported\n");
-	return -1;
 }
-#endif /* HAVE_NFCT_FILTER_MARK */
 
 static int build_nfct_filter(struct ulogd_pluginstance *upi)
 {
@@ -1327,7 +1330,7 @@ static int build_nfct_filter(struct ulogd_pluginstance *upi)
 
 	if (strlen(mark_filter_ce(upi->config_kset).u.string) != 0) {
 		char *filter_string = mark_filter_ce(upi->config_kset).u.string;
-		if (build_nfct_filter_mark(filter, filter_string) != 0) {
+		if (build_nfct_filter_mark(filter, filter_string, cpi->filter_dump) != 0) {
 			ulogd_log(ULOGD_FATAL,
 					"Unable to create mark filter\n");
 			goto err_filter;
@@ -1412,7 +1415,6 @@ static int constructor_nfct_events(struct ulogd_pluginstance *upi)
 		goto err_nfctobj;
 
 	if (usehash_ce(upi->config_kset).u.value != 0) {
-		int family = AF_UNSPEC;
 		struct nfct_handle *h;
 
 		/* we use a hashtable to cache entries in userspace. */
@@ -1436,7 +1438,7 @@ static int constructor_nfct_events(struct ulogd_pluginstance *upi)
 		}
 		nfct_callback_register(h, NFCT_T_ALL,
 				       &event_handler_hashtable, upi);
-		nfct_query(h, NFCT_Q_DUMP, &family);
+		nfct_query(h, NFCT_Q_DUMP_FILTER, cpi->filter_dump);
 		nfct_close(h);
 
 		/* the overrun handler only make sense with the hashtable,
@@ -1500,6 +1502,14 @@ static int constructor_nfct_polling(struct ulogd_pluginstance *upi)
 		ulogd_log(ULOGD_FATAL, "error opening ctnetlink\n");
 		goto err;
 	}
+	if (strlen(mark_filter_ce(upi->config_kset).u.string) != 0) {
+		char *filter_string = mark_filter_ce(upi->config_kset).u.string;
+		if (build_nfct_filter_mark(NULL, filter_string,
+					   cpi->filter_dump) != 0) {
+			ulogd_log(ULOGD_FATAL, "error creating NFCT mark filter\n");
+			goto err_hashtable;
+		}
+	}
 	nfct_callback_register(cpi->pgh, NFCT_T_ALL, &polling_handler, upi);
 
 	cpi->ct_active =
@@ -1534,6 +1544,15 @@ err:
 
 static int constructor_nfct(struct ulogd_pluginstance *upi)
 {
+	struct nfct_pluginstance *cpi =
+			(struct nfct_pluginstance *) upi->private;
+
+	cpi->filter_dump = nfct_filter_dump_create();
+	if (cpi->filter_dump == NULL) {
+		ulogd_log(ULOGD_FATAL, "could not create filter_dump\n");
+		return -1;
+	}
+
 	if (pollint_ce(upi->config_kset).u.value == 0) {
 		/* listen to ctnetlink events. */
 		return constructor_nfct_events(upi);
@@ -1553,6 +1572,8 @@ static int destructor_nfct_events(struct ulogd_pluginstance *upi)
 
 	ulogd_unregister_fd(&cpi->nfct_fd);
 
+	nfct_filter_dump_destroy(cpi->filter_dump);
+
 	rc = nfct_close(cpi->cth);
 	if (rc < 0)
 		return rc;
Signature · 1 line
1.8.5.3