diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/read_config_lex.l | 1 | ||||
-rw-r--r-- | src/read_config_yy.y | 13 | ||||
-rw-r--r-- | src/run.c | 41 |
3 files changed, 42 insertions, 13 deletions
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; @@ -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) { |