[conntrack-tools] add support for kernel-space filtering via BSF

Pablo Neira netfilter-cvslog-bounces at lists.netfilter.org
Wed Jul 23 16:51:54 CEST 2008


Gitweb:		http://git.netfilter.org/cgi-bin/gitweb.cgi?p=conntrack-tools.git;a=commit;h=167a57cb822eb6ce3759f5de3a11c59849b494e4
commit 167a57cb822eb6ce3759f5de3a11c59849b494e4
Author:     Pablo Neira Ayuso <pablo at netfilter.org>
AuthorDate: Wed Jul 23 16:51:39 2008 +0200
Commit:     Pablo Neira Ayuso <pablo at netfilter.org>
CommitDate: Wed Jul 23 16:51:39 2008 +0200

    add support for kernel-space filtering via BSF
    
    This patch adds support for kernel-space filtering via BSF by means of
    the libnetfilter_conntrack's BSF high-level API.
    
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
       via  167a57cb822eb6ce3759f5de3a11c59849b494e4 (commit)
      from  77b1fdb824eb45213df4f57224e8e799fed43ded (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 167a57cb822eb6ce3759f5de3a11c59849b494e4
Author: Pablo Neira Ayuso <pablo at netfilter.org>
Date:   Wed Jul 23 16:51:39 2008 +0200

    add support for kernel-space filtering via BSF
    
    This patch adds support for kernel-space filtering via BSF by means of
    the libnetfilter_conntrack's BSF high-level API.
    
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

-----------------------------------------------------------------------

 configure.in         |    2 +-
 include/conntrackd.h |    2 +
 src/netlink.c        |   14 ++++++++
 src/read_config_yy.y |   90 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 107 insertions(+), 1 deletions(-)
This patch adds support for kernel-space filtering via BSF by means of
the libnetfilter_conntrack's BSF high-level API.

Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

diff --git a/configure.in b/configure.in
index 0a6b8fe..30eaba1 100644
--- a/configure.in
+++ b/configure.in
@@ -18,7 +18,7 @@ esac
 
 dnl Dependencies
 LIBNFNETLINK_REQUIRED=0.0.33
-LIBNETFILTER_CONNTRACK_REQUIRED=0.0.94
+LIBNETFILTER_CONNTRACK_REQUIRED=0.0.97
 
 AC_CHECK_PROG(HAVE_PKG_CONFIG, pkg-config, yes)
 if test "x$HAVE_PKG_CONFIG" = "x"
diff --git a/include/conntrackd.h b/include/conntrackd.h
index cd02f1f..d2c8931 100644
--- a/include/conntrackd.h
+++ b/include/conntrackd.h
@@ -106,6 +106,8 @@ struct ct_general_state {
 	struct ct_filter		*us_filter;
 
 	struct nfct_handle		*event;         /* event handler */
+	struct nfct_filter		*filter;	/* event filter */
+
 	struct nfct_handle		*dump;		/* dump handler */
 	struct nfct_handle		*overrun;	/* overrun handler */
 	struct alarm_block		overrun_alarm;
diff --git a/src/netlink.c b/src/netlink.c
index 1823280..1287454 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -85,6 +85,20 @@ int nl_init_event_handler(void)
 	if (!STATE(event))
 		return -1;
 
+	if (STATE(filter)) {
+		if (nfct_filter_attach(nfct_fd(STATE(event)),
+				       STATE(filter)) == -1) {
+			dlog(LOG_NOTICE, "cannot set netlink kernel-space "
+					 "event filtering, defaulting to "
+					 "user-space. We suggest you to "
+					 "upgrade your Linux kernel to "
+					 ">= 2.6.26. Operation returns: %s", 
+					 strerror(errno));
+			/* don't fail here, old kernels don't support this */
+		}
+		nfct_filter_destroy(STATE(filter));
+	}
+
 	fcntl(nfct_fd(STATE(event)), F_SETFL, O_NONBLOCK);
 
 	/* set up socket buffer size */
diff --git a/src/read_config_yy.y b/src/read_config_yy.y
index 2a1c88c..33a435c 100644
--- a/src/read_config_yy.y
+++ b/src/read_config_yy.y
@@ -27,12 +27,16 @@
 #include "conntrackd.h"
 #include "bitops.h"
 #include <syslog.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
 #include <libnetfilter_conntrack/libnetfilter_conntrack_tcp.h>
 
 extern char *yytext;
 extern int   yylineno;
 
 struct ct_conf conf;
+
+static void __kernel_filter_start(void);
+static void __kernel_filter_add_state(int value);
 %}
 
 %union {
@@ -558,54 +562,72 @@ tcp_state: T_SYN_SENT
 	ct_filter_add_state(STATE(us_filter),
 			    IPPROTO_TCP,
 			    TCP_CONNTRACK_SYN_SENT);
+
+	__kernel_filter_add_state(TCP_CONNTRACK_SYN_SENT);
 };
 tcp_state: T_SYN_RECV
 {
 	ct_filter_add_state(STATE(us_filter),
 			    IPPROTO_TCP,
 			    TCP_CONNTRACK_SYN_RECV);
+
+	__kernel_filter_add_state(TCP_CONNTRACK_SYN_RECV);
 };
 tcp_state: T_ESTABLISHED
 {
 	ct_filter_add_state(STATE(us_filter),
 			    IPPROTO_TCP,
 			    TCP_CONNTRACK_ESTABLISHED);
+
+	__kernel_filter_add_state(TCP_CONNTRACK_ESTABLISHED);
 };
 tcp_state: T_FIN_WAIT
 {
 	ct_filter_add_state(STATE(us_filter),
 			    IPPROTO_TCP,
 			    TCP_CONNTRACK_FIN_WAIT);
+
+	__kernel_filter_add_state(TCP_CONNTRACK_FIN_WAIT);
 };
 tcp_state: T_CLOSE_WAIT
 {
 	ct_filter_add_state(STATE(us_filter),
 			    IPPROTO_TCP,
 			    TCP_CONNTRACK_CLOSE_WAIT);
+
+	__kernel_filter_add_state(TCP_CONNTRACK_CLOSE_WAIT);
 };
 tcp_state: T_LAST_ACK
 {
 	ct_filter_add_state(STATE(us_filter),
 			    IPPROTO_TCP,
 			    TCP_CONNTRACK_LAST_ACK);
+
+	__kernel_filter_add_state(TCP_CONNTRACK_LAST_ACK);
 };
 tcp_state: T_TIME_WAIT
 {
 	ct_filter_add_state(STATE(us_filter),
 			    IPPROTO_TCP,
 			    TCP_CONNTRACK_TIME_WAIT);
+
+	__kernel_filter_add_state(TCP_CONNTRACK_TIME_WAIT);
 };
 tcp_state: T_CLOSE
 {
 	ct_filter_add_state(STATE(us_filter),
 			    IPPROTO_TCP,
 			    TCP_CONNTRACK_CLOSE);
+
+	__kernel_filter_add_state(TCP_CONNTRACK_CLOSE);
 };
 tcp_state: T_LISTEN
 {
 	ct_filter_add_state(STATE(us_filter),
 			    IPPROTO_TCP,
 			    TCP_CONNTRACK_LISTEN);
+
+	__kernel_filter_add_state(TCP_CONNTRACK_LISTEN);
 };
 
 cache_writethrough: T_WRITE_THROUGH T_ON
@@ -666,6 +688,8 @@ filter_item : T_PROTOCOL T_ACCEPT '{' filter_protocol_list '}'
 	ct_filter_set_logic(STATE(us_filter),
 			    CT_FILTER_L4PROTO,
 			    CT_FILTER_POSITIVE);
+
+	__kernel_filter_start();
 };
 
 filter_item : T_PROTOCOL T_IGNORE '{' filter_protocol_list '}'
@@ -673,6 +697,12 @@ filter_item : T_PROTOCOL T_IGNORE '{' filter_protocol_list '}'
 	ct_filter_set_logic(STATE(us_filter),
 			    CT_FILTER_L4PROTO,
 			    CT_FILTER_NEGATIVE);
+
+	__kernel_filter_start();
+
+	nfct_filter_set_logic(STATE(filter),
+			      NFCT_FILTER_L4PROTO,
+			      NFCT_FILTER_LOGIC_NEGATIVE);
 };
 
 filter_protocol_list :
@@ -689,6 +719,12 @@ filter_protocol_item : T_STRING
 		break;
 	}
 	ct_filter_add_proto(STATE(us_filter), pent->p_proto);
+
+	__kernel_filter_start();
+
+	nfct_filter_add_attr_u32(STATE(filter),
+				 NFCT_FILTER_L4PROTO,
+				 pent->p_proto);
 };
 
 filter_item : T_ADDRESS T_ACCEPT '{' filter_address_list '}'
@@ -696,6 +732,8 @@ filter_item : T_ADDRESS T_ACCEPT '{' filter_address_list '}'
 	ct_filter_set_logic(STATE(us_filter),
 			    CT_FILTER_ADDRESS,
 			    CT_FILTER_POSITIVE);
+
+	__kernel_filter_start();
 };
 
 filter_item : T_ADDRESS T_IGNORE '{' filter_address_list '}'
@@ -703,6 +741,15 @@ filter_item : T_ADDRESS T_IGNORE '{' filter_address_list '}'
 	ct_filter_set_logic(STATE(us_filter),
 			    CT_FILTER_ADDRESS,
 			    CT_FILTER_NEGATIVE);
+
+	__kernel_filter_start();
+
+	nfct_filter_set_logic(STATE(filter),
+			      NFCT_FILTER_SRC_IPV4,
+			      NFCT_FILTER_LOGIC_NEGATIVE);
+	nfct_filter_set_logic(STATE(filter),
+			      NFCT_FILTER_DST_IPV4,
+			      NFCT_FILTER_LOGIC_NEGATIVE);
 };
 
 filter_address_list :
@@ -726,6 +773,16 @@ filter_address_item : T_IPV4_ADDR T_IP
 		if (errno == ENOSPC)
 			fprintf(stderr, "Too many IP in the ignore pool!\n");
 	}
+
+	__kernel_filter_start();
+
+	struct nfct_filter_ipv4 filter_ipv4 = {
+		.addr = htonl(ip.ipv4),
+		.mask = 0xffffffff,
+	};
+
+	nfct_filter_add_attr(STATE(filter), NFCT_FILTER_SRC_IPV4, &filter_ipv4);
+	nfct_filter_add_attr(STATE(filter), NFCT_FILTER_DST_IPV4, &filter_ipv4);
 };
 
 filter_address_item : T_IPV6_ADDR T_IP
@@ -758,6 +815,8 @@ filter_item : T_STATE T_ACCEPT '{' filter_state_list '}'
 	ct_filter_set_logic(STATE(us_filter),
 			    CT_FILTER_STATE,
 			    CT_FILTER_POSITIVE);
+
+	__kernel_filter_start();
 };
 
 filter_item : T_STATE T_IGNORE '{' filter_state_list '}'
@@ -765,6 +824,13 @@ filter_item : T_STATE T_IGNORE '{' filter_state_list '}'
 	ct_filter_set_logic(STATE(us_filter),
 			    CT_FILTER_STATE,
 			    CT_FILTER_NEGATIVE);
+
+
+	__kernel_filter_start();
+
+	nfct_filter_set_logic(STATE(filter),
+			      NFCT_FILTER_L4PROTO_STATE,
+			      NFCT_FILTER_LOGIC_NEGATIVE);
 };
 
 filter_state_list :
@@ -864,6 +930,30 @@ yyerror(char *msg)
 	exit(EXIT_FAILURE);
 }
 
+static void __kernel_filter_start(void)
+{
+	if (!STATE(filter)) {
+		STATE(filter) = nfct_filter_create();
+		if (!STATE(filter)) {
+			fprintf(stderr, "Can't create ignore pool!\n");
+			exit(EXIT_FAILURE);
+		}
+	}
+}
+
+static void __kernel_filter_add_state(int value)
+{
+	__kernel_filter_start();
+
+	struct nfct_filter_proto filter_proto = {
+		.proto = IPPROTO_TCP,
+		.state = value
+	};
+	nfct_filter_add_attr(STATE(filter),
+			     NFCT_FILTER_L4PROTO_STATE,
+			     &filter_proto);
+}
+
 int
 init_config(char *filename)
 {



More information about the netfilter-cvslog mailing list