summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2009-01-17 18:03:53 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2009-01-17 18:03:53 +0100
commit746f7031f4d1e3bccdd6db3c53835d8b85b73c90 (patch)
treea900ab9f0654dd67ae36f2c61ca4cdc3c2c7befe
parent05194422ee8fa038d99fe77a2e9d776d25623fd2 (diff)
src: add state polling support (oppossed to current event-driven)
This patch adds the clause PollSecs that changes the normal behaviour of conntrackd. With PollSecs set to > 0, conntrackd polls every N seconds the entries. This is the opposed behaviour of an event-driven behaviour but may be useful for those that have really strong limitations in terms of CPU consumption and want to perform a relaxed replication. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--doc/stats/conntrackd.conf12
-rw-r--r--doc/sync/alarm/conntrackd.conf12
-rw-r--r--doc/sync/ftfw/conntrackd.conf12
-rw-r--r--doc/sync/notrack/conntrackd.conf12
-rw-r--r--include/conntrackd.h2
-rw-r--r--src/read_config_lex.l1
-rw-r--r--src/read_config_yy.y13
-rw-r--r--src/run.c41
8 files changed, 92 insertions, 13 deletions
diff --git a/doc/stats/conntrackd.conf b/doc/stats/conntrackd.conf
index 1fc21af..889d387 100644
--- a/doc/stats/conntrackd.conf
+++ b/doc/stats/conntrackd.conf
@@ -91,6 +91,18 @@ Stats {
#
LogFile on
+ #
+ # By default, the daemon receives state updates following an
+ # event-driven model. You can modify this behaviour by switching to
+ # polling mode with the PollSecs clause. This clause tells conntrackd
+ # to dump the states in the kernel every N seconds. With regards to
+ # synchronization mode, the polling mode can only guarantee that
+ # long-lifetime states are recovered. The main advantage of this method
+ # is the reduction in the state replication at the cost of reducing the
+ # chances of recovering connections.
+ #
+ # PollSecs 15
+
#
# Enable connection logging via Syslog. Default is off.
# Syslog: on, off or a facility name (daemon (default) or local0..7)
diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf
index 528ff8f..3479a83 100644
--- a/doc/sync/alarm/conntrackd.conf
+++ b/doc/sync/alarm/conntrackd.conf
@@ -183,6 +183,18 @@ General {
#
SocketBufferSizeMaxGrowth 8388608
+ #
+ # By default, the daemon receives state updates following an
+ # event-driven model. You can modify this behaviour by switching to
+ # polling mode with the PollSecs clause. This clause tells conntrackd
+ # to dump the states in the kernel every N seconds. With regards to
+ # synchronization mode, the polling mode can only guarantee that
+ # long-lifetime states are recovered. The main advantage of this method
+ # is the reduction in the state replication at the cost of reducing the
+ # chances of recovering connections.
+ #
+ # PollSecs 15
+
#
# The daemon prioritizes the handling of state-change events coming
# from the core. With this clause, you can set the maximum number of
diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf
index 2e60f2c..77ef76c 100644
--- a/doc/sync/ftfw/conntrackd.conf
+++ b/doc/sync/ftfw/conntrackd.conf
@@ -191,6 +191,18 @@ General {
#
SocketBufferSizeMaxGrowth 8388608
+ #
+ # By default, the daemon receives state updates following an
+ # event-driven model. You can modify this behaviour by switching to
+ # polling mode with the PollSecs clause. This clause tells conntrackd
+ # to dump the states in the kernel every N seconds. With regards to
+ # synchronization mode, the polling mode can only guarantee that
+ # long-lifetime states are recovered. The main advantage of this method
+ # is the reduction in the state replication at the cost of reducing the
+ # chances of recovering connections.
+ #
+ # PollSecs 15
+
#
# The daemon prioritizes the handling of state-change events coming
# from the core. With this clause, you can set the maximum number of
diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf
index 7f8c8a3..5abf589 100644
--- a/doc/sync/notrack/conntrackd.conf
+++ b/doc/sync/notrack/conntrackd.conf
@@ -173,6 +173,18 @@ General {
#
SocketBufferSizeMaxGrowth 8388608
+ #
+ # By default, the daemon receives state updates following an
+ # event-driven model. You can modify this behaviour by switching to
+ # polling mode with the PollSecs clause. This clause tells conntrackd
+ # to dump the states in the kernel every N seconds. With regards to
+ # synchronization mode, the polling mode can only guarantee that
+ # long-lifetime states are recovered. The main advantage of this method
+ # is the reduction in the state replication at the cost of reducing the
+ # chances of recovering connections.
+ #
+ # PollSecs 15
+
#
# The daemon prioritizes the handling of state-change events coming
# from the core. With this clause, you can set the maximum number of
diff --git a/include/conntrackd.h b/include/conntrackd.h
index fbf126a..acf907c 100644
--- a/include/conntrackd.h
+++ b/include/conntrackd.h
@@ -48,6 +48,7 @@
#define CTD_SYNC_FTFW (1UL << 2)
#define CTD_SYNC_ALARM (1UL << 3)
#define CTD_SYNC_NOTRACK (1UL << 4)
+#define CTD_POLL (1UL << 5)
/* FILENAME_MAX is 4096 on my system, perhaps too much? */
#ifndef FILENAME_MAXLEN
@@ -85,6 +86,7 @@ struct ct_conf {
int family; /* protocol family */
unsigned int resend_queue_size; /* FTFW protocol */
unsigned int window_size;
+ int poll_kernel_secs;
int cache_write_through;
int filter_from_kernelspace;
int event_iterations_limit;
diff --git a/src/read_config_lex.l b/src/read_config_lex.l
index e9e5d43..4953974 100644
--- a/src/read_config_lex.l
+++ b/src/read_config_lex.l
@@ -119,6 +119,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k]
"Kernelspace" { return T_KERNELSPACE; }
"EventIterationLimit" { return T_EVENT_ITER_LIMIT; }
"Default" { return T_DEFAULT; }
+"PollSecs" { return T_POLL_SECS; }
{is_on} { return T_ON; }
{is_off} { return T_OFF; }
diff --git a/src/read_config_yy.y b/src/read_config_yy.y
index de6cef3..ce604d9 100644
--- a/src/read_config_yy.y
+++ b/src/read_config_yy.y
@@ -58,7 +58,7 @@ static void __max_mcast_dedicated_links_reached(void);
%token T_ESTABLISHED T_SYN_SENT T_SYN_RECV T_FIN_WAIT
%token T_CLOSE_WAIT T_LAST_ACK T_TIME_WAIT T_CLOSE T_LISTEN
%token T_SYSLOG T_WRITE_THROUGH T_STAT_BUFFER_SIZE T_DESTROY_TIMEOUT
-%token T_MCAST_RCVBUFF T_MCAST_SNDBUFF T_NOTRACK
+%token T_MCAST_RCVBUFF T_MCAST_SNDBUFF T_NOTRACK T_POLL_SECS
%token T_FILTER T_ADDRESS T_PROTOCOL T_STATE T_ACCEPT T_IGNORE
%token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT T_DEFAULT
@@ -715,6 +715,7 @@ general_line: hashsize
| netlink_buffer_size_max_grown
| family
| event_iterations_limit
+ | poll_secs
| filter
;
@@ -741,6 +742,16 @@ event_iterations_limit : T_EVENT_ITER_LIMIT T_NUMBER
CONFIG(event_iterations_limit) = $2;
};
+poll_secs: T_POLL_SECS T_NUMBER
+{
+ conf.flags |= CTD_POLL;
+ conf.poll_kernel_secs = $2;
+ if (conf.poll_kernel_secs == 0) {
+ fprintf(stderr, "ERROR: `PollSecs' clause must be > 0\n");
+ exit(EXIT_FAILURE);
+ }
+};
+
filter : T_FILTER '{' filter_list '}'
{
CONFIG(filter_from_kernelspace) = 0;
diff --git a/src/run.c b/src/run.c
index a6dfe15..a483ab3 100644
--- a/src/run.c
+++ b/src/run.c
@@ -39,7 +39,8 @@ void killer(int foo)
/* no signals while handling signals */
sigprocmask(SIG_BLOCK, &STATE(block), NULL);
- nfct_close(STATE(event));
+ if (!(CONFIG(flags) & CTD_POLL))
+ nfct_close(STATE(event));
nfct_close(STATE(request));
if (STATE(us_filter))
@@ -204,12 +205,18 @@ void local_handler(int fd, void *data)
STATE(stats).local_unknown_request++;
}
-static void do_resync_alarm(struct alarm_block *a, void *data)
+static void do_overrun_resync_alarm(struct alarm_block *a, void *data)
{
nl_send_resync(STATE(resync));
STATE(stats).nl_kernel_table_resync++;
}
+static void do_poll_resync_alarm(struct alarm_block *a, void *data)
+{
+ nl_send_resync(STATE(resync));
+ add_alarm(&STATE(resync_alarm), CONFIG(poll_kernel_secs), 0);
+}
+
static int event_handler(enum nf_conntrack_msg_type type,
struct nf_conntrack *ct,
void *data)
@@ -297,15 +304,18 @@ init(void)
}
register_fd(STATE(local).fd, STATE(fds));
- STATE(event) = nl_init_event_handler();
- if (STATE(event) == NULL) {
- dlog(LOG_ERR, "can't open netlink handler: %s",
- strerror(errno));
- dlog(LOG_ERR, "no ctnetlink kernel support?");
- return -1;
+ if (!(CONFIG(flags) & CTD_POLL)) {
+ STATE(event) = nl_init_event_handler();
+ if (STATE(event) == NULL) {
+ dlog(LOG_ERR, "can't open netlink handler: %s",
+ strerror(errno));
+ dlog(LOG_ERR, "no ctnetlink kernel support?");
+ return -1;
+ }
+ nfct_callback_register(STATE(event), NFCT_T_ALL,
+ event_handler, NULL);
+ register_fd(nfct_fd(STATE(event)), STATE(fds));
}
- nfct_callback_register(STATE(event), NFCT_T_ALL, event_handler, NULL);
- register_fd(nfct_fd(STATE(event)), STATE(fds));
STATE(dump) = nl_init_dump_handler();
if (STATE(dump) == NULL) {
@@ -343,7 +353,13 @@ init(void)
return -1;
}
- init_alarm(&STATE(resync_alarm), NULL, do_resync_alarm);
+ if (CONFIG(flags) & CTD_POLL) {
+ init_alarm(&STATE(resync_alarm), NULL, do_poll_resync_alarm);
+ add_alarm(&STATE(resync_alarm), CONFIG(poll_kernel_secs), 0);
+ dlog(LOG_NOTICE, "running in polling mode");
+ } else {
+ init_alarm(&STATE(resync_alarm), NULL, do_overrun_resync_alarm);
+ }
/* Signals handling */
sigemptyset(&STATE(block));
@@ -397,7 +413,8 @@ static void __run(struct timeval *next_alarm)
do_local_server_step(&STATE(local), NULL, local_handler);
/* conntrack event has happened */
- if (FD_ISSET(nfct_fd(STATE(event)), &readfds)) {
+ if (!(CONFIG(flags) & CTD_POLL) &&
+ FD_ISSET(nfct_fd(STATE(event)), &readfds)) {
ret = nfct_catch(STATE(event));
if (ret == -1) {
switch(errno) {