summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--include/Makefile.am2
-rw-r--r--include/conntrackd.h1
-rw-r--r--include/event.h14
-rw-r--r--src/Makefile.am2
-rw-r--r--src/event.c73
-rw-r--r--src/sync-ftfw.c5
-rw-r--r--src/sync-mode.c28
8 files changed, 117 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 2d4f332..dec7537 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -34,6 +34,7 @@ o use generic nfct_cmp() to compare objects
o improve network message sanity checkings
o add Mcast[Snd|Rcv]SocketBuffer clauses to tune multicast socket buffers
o add missing string.h required by strdup in config parsing
+o add eventfd emulation to communicate receiver -> sender
version 0.9.6 (2008/03/08)
------------------------------
diff --git a/include/Makefile.am b/include/Makefile.am
index 92ebbcc..d68f10a 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -3,5 +3,5 @@ noinst_HEADERS = alarm.h jhash.h slist.h cache.h linux_list.h linux_rbtree.h \
sync.h conntrackd.h local.h us-conntrack.h \
debug.h log.h hash.h mcast.h conntrack.h \
state_helper.h network.h ignore.h queue.h \
- traffic_stats.h netlink.h fds.h
+ traffic_stats.h netlink.h fds.h eventfd.h
diff --git a/include/conntrackd.h b/include/conntrackd.h
index b266289..c7a65be 100644
--- a/include/conntrackd.h
+++ b/include/conntrackd.h
@@ -125,6 +125,7 @@ struct ct_sync_state {
struct mcast_sock *mcast_server; /* multicast socket: incoming */
struct mcast_sock *mcast_client; /* multicast socket: outgoing */
+ struct evfd *evfd; /* event fd */
struct sync_mode *sync; /* sync mode */
diff --git a/include/event.h b/include/event.h
new file mode 100644
index 0000000..b6bff5a
--- /dev/null
+++ b/include/event.h
@@ -0,0 +1,14 @@
+#ifndef _EVENT_H_
+#define _EVENT_H_
+
+struct evfd *create_evfd(void);
+
+void destroy_evfd(struct evfd *e);
+
+int get_read_evfd(struct evfd *evfd);
+
+int write_evfd(struct evfd *evfd);
+
+int read_evfd(struct evfd *evfd);
+
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index d3fc020..554074f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,7 +12,7 @@ conntrack_LDFLAGS = $(all_libraries) @LIBNETFILTER_CONNTRACK_LIBS@
conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c rbtree.c \
local.c log.c mcast.c netlink.c \
- ignore_pool.c fds.c \
+ ignore_pool.c fds.c event.c \
cache.c cache_iterators.c \
cache_lifetime.c cache_timer.c cache_wt.c \
sync-mode.c sync-alarm.c sync-ftfw.c \
diff --git a/src/event.c b/src/event.c
new file mode 100644
index 0000000..ed78835
--- /dev/null
+++ b/src/event.c
@@ -0,0 +1,73 @@
+/*
+ * (C) 2006-2007 by Pablo Neira Ayuso <pablo@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "event.h"
+
+struct evfd {
+ int read;
+ int fds[2];
+};
+
+struct evfd *create_evfd(void)
+{
+ struct evfd *e;
+
+ e = calloc(1, sizeof(struct evfd));
+ if (e == NULL)
+ return NULL;
+
+ if (pipe(e->fds) == -1) {
+ free(e);
+ return NULL;
+ }
+
+ return e;
+}
+
+void destroy_evfd(struct evfd *e)
+{
+ close(e->fds[0]);
+ close(e->fds[1]);
+ free(e);
+}
+
+int get_read_evfd(struct evfd *evfd)
+{
+ return evfd->fds[0];
+}
+
+int write_evfd(struct evfd *evfd)
+{
+ int data = 0;
+
+ if (evfd->read)
+ return 0;
+
+ evfd->read = 1;
+ return write(evfd->fds[1], &data, sizeof(data));
+}
+
+int read_evfd(struct evfd *evfd)
+{
+ int data;
+
+ evfd->read = 0;
+ return read(evfd->fds[0], &data, sizeof(data));
+}
diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c
index 77f8fd4..adfdda9 100644
--- a/src/sync-ftfw.c
+++ b/src/sync-ftfw.c
@@ -25,6 +25,7 @@
#include "alarm.h"
#include "log.h"
#include "cache.h"
+#include "event.h"
#include <string.h>
@@ -97,6 +98,7 @@ static void tx_queue_add_ctlmsg(uint32_t flags, uint32_t from, uint32_t to)
};
queue_add(tx_queue, &ack, NETHDR_ACK_SIZ);
+ write_evfd(STATE_SYNC(evfd));
}
static void ftfw_run(void);
@@ -191,6 +193,7 @@ static int do_cache_to_tx(void *data1, void *data2)
/* add to tx list */
list_add_tail(&cn->tx_list, &tx_list);
tx_list_len++;
+ write_evfd(STATE_SYNC(evfd));
return 0;
}
@@ -225,6 +228,7 @@ static int rs_queue_to_tx(void *data1, const void *data2)
dp("rs_queue_to_tx sq: %u fl:%u len:%u\n",
net->seq, net->flags, net->len);
queue_add(tx_queue, net, net->len);
+ write_evfd(STATE_SYNC(evfd));
queue_del(rs_queue, net);
}
return 0;
@@ -256,6 +260,7 @@ static void rs_list_to_tx(struct cache *c, unsigned int from, unsigned int to)
rs_list_len--;
list_add_tail(&cn->tx_list, &tx_list);
tx_list_len++;
+ write_evfd(STATE_SYNC(evfd));
}
}
}
diff --git a/src/sync-mode.c b/src/sync-mode.c
index ad55adc..2fe7406 100644
--- a/src/sync-mode.c
+++ b/src/sync-mode.c
@@ -26,6 +26,7 @@
#include "us-conntrack.h"
#include "network.h"
#include "fds.h"
+#include "event.h"
#include "debug.h"
#include <errno.h>
@@ -232,6 +233,12 @@ static int init_sync(void)
return -1;
}
+ STATE_SYNC(evfd) = create_evfd();
+ if (STATE_SYNC(evfd) == NULL) {
+ dlog(LOG_ERR, "cannot open evfd");
+ return -1;
+ }
+
/* initialization of multicast sequence generation */
STATE_SYNC(last_seq_sent) = time(NULL);
@@ -240,21 +247,26 @@ static int init_sync(void)
static int register_fds_sync(struct fds *fds)
{
- return register_fd(STATE_SYNC(mcast_server->fd), fds);
+ if (register_fd(STATE_SYNC(mcast_server->fd), fds) == -1)
+ return -1;
+
+ return register_fd(get_read_evfd(STATE_SYNC(evfd)), fds);
}
static void run_sync(fd_set *readfds)
{
/* multicast packet has been received */
- if (FD_ISSET(STATE_SYNC(mcast_server->fd), readfds)) {
+ if (FD_ISSET(STATE_SYNC(mcast_server->fd), readfds))
mcast_handler();
- if (STATE_SYNC(sync)->run)
- STATE_SYNC(sync)->run();
-
- /* flush pending messages */
- mcast_buffered_pending_netmsg(STATE_SYNC(mcast_client));
+ if (FD_ISSET(get_read_evfd(STATE_SYNC(evfd)), readfds) &&
+ STATE_SYNC(sync)->run) {
+ read_evfd(STATE_SYNC(evfd));
+ STATE_SYNC(sync)->run();
}
+
+ /* flush pending messages */
+ mcast_buffered_pending_netmsg(STATE_SYNC(mcast_client));
}
static void kill_sync(void)
@@ -265,6 +277,8 @@ static void kill_sync(void)
mcast_server_destroy(STATE_SYNC(mcast_server));
mcast_client_destroy(STATE_SYNC(mcast_client));
+ destroy_evfd(STATE_SYNC(evfd));
+
mcast_buffered_destroy();
if (STATE_SYNC(sync)->kill)