summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2009-01-15 23:19:35 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2009-01-15 23:19:35 +0100
commitb28224b0326636ff5832b38817b7720f48070ee7 (patch)
treee1b6856b8c852d9c672af2559e17ecab78355246
parent4556b3fb39dd80e958ff70f3496d06ec04f3839d (diff)
run: limit the number of iterations over the event handling
Currently, the event handling can starve other event file descriptors. This patch limits the number of event handling iterations. The parameter is tunable via configuration file. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--doc/sync/alarm/conntrackd.conf11
-rw-r--r--doc/sync/ftfw/conntrackd.conf11
-rw-r--r--doc/sync/notrack/conntrackd.conf11
-rw-r--r--include/conntrackd.h2
-rw-r--r--src/read_config_lex.l1
-rw-r--r--src/read_config_yy.y11
-rw-r--r--src/run.c11
7 files changed, 54 insertions, 4 deletions
diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf
index f42a799..f16f439 100644
--- a/doc/sync/alarm/conntrackd.conf
+++ b/doc/sync/alarm/conntrackd.conf
@@ -165,6 +165,17 @@ General {
SocketBufferSizeMaxGrowth 8388608
#
+ # The daemon prioritizes the handling of state-change events coming
+ # from the core. With this clause, you can set the maximum number of
+ # state-change events (those coming from kernel-space) that the daemon
+ # will handle after which it will handle other events coming from the
+ # network or userspace. A low value improves interactivity (in terms of
+ # real-time behaviour) at the cost of extra CPU consumption.
+ # Default (if not set) is 100.
+ #
+ # EventIterationLimit 100
+
+ #
# Event filtering: This clause allows you to filter certain traffic,
# There are currently three filter-sets: Protocol, Address and
# State. The filter is attached to an action that can be: Accept or
diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf
index e12a745..d85fc28 100644
--- a/doc/sync/ftfw/conntrackd.conf
+++ b/doc/sync/ftfw/conntrackd.conf
@@ -173,6 +173,17 @@ General {
SocketBufferSizeMaxGrowth 8388608
#
+ # The daemon prioritizes the handling of state-change events coming
+ # from the core. With this clause, you can set the maximum number of
+ # state-change events (those coming from kernel-space) that the daemon
+ # will handle after which it will handle other events coming from the
+ # network or userspace. A low value improves interactivity (in terms of
+ # real-time behaviour) at the cost of extra CPU consumption.
+ # Default (if not set) is 100.
+ #
+ # EventIterationLimit 100
+
+ #
# Event filtering: This clause allows you to filter certain traffic,
# There are currently three filter-sets: Protocol, Address and
# State. The filter is attached to an action that can be: Accept or
diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf
index cbc26ee..4d03234 100644
--- a/doc/sync/notrack/conntrackd.conf
+++ b/doc/sync/notrack/conntrackd.conf
@@ -155,6 +155,17 @@ General {
SocketBufferSizeMaxGrowth 8388608
#
+ # The daemon prioritizes the handling of state-change events coming
+ # from the core. With this clause, you can set the maximum number of
+ # state-change events (those coming from kernel-space) that the daemon
+ # will handle after which it will handle other events coming from the
+ # network or userspace. A low value improves interactivity (in terms of
+ # real-time behaviour) at the cost of extra CPU consumption.
+ # Default (if not set) is 100.
+ #
+ # EventIterationLimit 100
+
+ #
# Event filtering: This clause allows you to filter certain traffic,
# There are currently three filter-sets: Protocol, Address and
# State. The filter is attached to an action that can be: Accept or
diff --git a/include/conntrackd.h b/include/conntrackd.h
index df36ec4..67397b8 100644
--- a/include/conntrackd.h
+++ b/include/conntrackd.h
@@ -84,6 +84,7 @@ struct ct_conf {
unsigned int window_size;
int cache_write_through;
int filter_from_kernelspace;
+ int event_iterations_limit;
struct {
char logfile[FILENAME_MAXLEN];
int syslog_facility;
@@ -103,6 +104,7 @@ struct ct_general_state {
struct nfct_handle *event; /* event handler */
struct nfct_filter *filter; /* event filter */
+ int event_iterations_limit;
struct nfct_handle *dump; /* dump handler */
struct nfct_handle *request; /* request handler */
diff --git a/src/read_config_lex.l b/src/read_config_lex.l
index 67c95d3..f8b0ba1 100644
--- a/src/read_config_lex.l
+++ b/src/read_config_lex.l
@@ -117,6 +117,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k]
"From" { return T_FROM; }
"Userspace" { return T_USERSPACE; }
"Kernelspace" { return T_KERNELSPACE; }
+"EventIterationLimit" { return T_EVENT_ITER_LIMIT; }
{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 69a7eff..274bfc3 100644
--- a/src/read_config_yy.y
+++ b/src/read_config_yy.y
@@ -59,7 +59,7 @@ static void __kernel_filter_add_state(int value);
%token T_SYSLOG T_WRITE_THROUGH T_STAT_BUFFER_SIZE T_DESTROY_TIMEOUT
%token T_MCAST_RCVBUFF T_MCAST_SNDBUFF T_NOTRACK
%token T_FILTER T_ADDRESS T_PROTOCOL T_STATE T_ACCEPT T_IGNORE
-%token T_FROM T_USERSPACE T_KERNELSPACE
+%token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT
%token <string> T_IP T_PATH_VAL
%token <val> T_NUMBER
@@ -681,6 +681,7 @@ general_line: hashsize
| netlink_buffer_size
| netlink_buffer_size_max_grown
| family
+ | event_iterations_limit
| filter
;
@@ -702,6 +703,11 @@ family : T_FAMILY T_STRING
conf.family = AF_INET;
};
+event_iterations_limit : T_EVENT_ITER_LIMIT T_NUMBER
+{
+ CONFIG(event_iterations_limit) = $2;
+};
+
filter : T_FILTER '{' filter_list '}'
{
CONFIG(filter_from_kernelspace) = 0;
@@ -1096,5 +1102,8 @@ init_config(char *filename)
if (conf.flags & CTD_SYNC_FTFW && CONFIG(del_timeout) == 0)
CONFIG(del_timeout) = 240;
+ if (CONFIG(event_iterations_limit) == 0)
+ CONFIG(event_iterations_limit) = 100;
+
return 0;
}
diff --git a/src/run.c b/src/run.c
index 7958665..caf0b38 100644
--- a/src/run.c
+++ b/src/run.c
@@ -219,7 +219,7 @@ static int event_handler(enum nf_conntrack_msg_type type,
/* skip user-space filtering if already do it in the kernel */
if (ct_filter_conntrack(ct, !CONFIG(filter_from_kernelspace))) {
STATE(stats).nl_events_filtered++;
- return NFCT_CB_STOP;
+ goto out;
}
switch(type) {
@@ -238,7 +238,12 @@ static int event_handler(enum nf_conntrack_msg_type type,
break;
}
- return NFCT_CB_CONTINUE;
+out:
+ if (STATE(event_iterations_limit)-- <= 0) {
+ STATE(event_iterations_limit) = CONFIG(event_iterations_limit);
+ return NFCT_CB_STOP;
+ } else
+ return NFCT_CB_CONTINUE;
}
static int dump_handler(enum nf_conntrack_msg_type type,
@@ -397,7 +402,7 @@ static void __run(struct timeval *next_alarm)
/* conntrack event has happened */
if (FD_ISSET(nfct_fd(STATE(event)), &readfds)) {
- while ((ret = nfct_catch(STATE(event))) != -1);
+ ret = nfct_catch(STATE(event));
if (ret == -1) {
switch(errno) {
case ENOBUFS: