summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2012-03-06 12:10:55 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2012-03-06 12:10:55 +0100
commit94e75add9867fb6f0e05e73b23f723f139da829e (patch)
treef190e2dae69449c0a6ca547e629a8fd5356116b1
parent62ed08f2d25ef0f332fe65fd40a97ff4dc4eda93 (diff)
qa: add some stress tools to test conntrack via ctnetlink
ct_stress adds plenty of flows in assured state (worst case for the conntrack table). ct_events_reliable forces reliable event delivery. You have to use this tools together: ./ct_events_reliable & then: ./ct_stress 65535 # your ct table size If things go well, you will end up hitting ENOMEM. Both as root, of course. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--qa/Makefile.am10
-rw-r--r--qa/ct_events_reliable.c59
-rw-r--r--qa/ct_stress.c75
3 files changed, 143 insertions, 1 deletions
diff --git a/qa/Makefile.am b/qa/Makefile.am
index 2bf568a..cb49aa4 100644
--- a/qa/Makefile.am
+++ b/qa/Makefile.am
@@ -1,6 +1,6 @@
include $(top_srcdir)/Make_global.am
-check_PROGRAMS = test_api test_filter
+check_PROGRAMS = test_api test_filter ct_stress ct_events_reliable
test_api_SOURCES = test_api.c
test_api_LDADD = ../src/libnetfilter_conntrack.la
@@ -9,3 +9,11 @@ test_api_LDFLAGS = -dynamic -ldl
test_filter_SOURCES = test_filter.c
test_filter_LDADD = ../src/libnetfilter_conntrack.la
test_filter_LDFLAGS = -dynamic -ldl
+
+ct_stress_SOURCES = ct_stress.c
+ct_stress_LDADD = ../src/libnetfilter_conntrack.la
+ct_stress_LDFLAGS = -dynamic -ldl
+
+ct_events_reliable_SOURCES = ct_events_reliable.c
+ct_events_reliable_LDADD = ../src/libnetfilter_conntrack.la
+ct_events_reliable_LDFLAGS = -dynamic -ldl
diff --git a/qa/ct_events_reliable.c b/qa/ct_events_reliable.c
new file mode 100644
index 0000000..e95623a
--- /dev/null
+++ b/qa/ct_events_reliable.c
@@ -0,0 +1,59 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+
+static int event_cb(enum nf_conntrack_msg_type type,
+ struct nf_conntrack *ct,
+ void *data)
+{
+ static int i = 0;
+ static int new, destroy;
+
+ if (type == NFCT_T_NEW)
+ new++;
+ else if (type == NFCT_T_DESTROY)
+ destroy++;
+
+ if ((++i % 10000) == 0)
+ printf("%d events received (%d new, %d destroy)\n",
+ i, new, destroy);
+
+ return NFCT_CB_CONTINUE;
+}
+
+int main(void)
+{
+ int ret;
+ struct nfct_handle *h;
+ int on = 1;
+
+ h = nfct_open(CONNTRACK, NFCT_ALL_CT_GROUPS);
+ if (!h) {
+ perror("nfct_open");
+ return 0;
+ }
+
+ setsockopt(nfct_fd(h), SOL_NETLINK,
+ NETLINK_BROADCAST_SEND_ERROR, &on, sizeof(int));
+ setsockopt(nfct_fd(h), SOL_NETLINK,
+ NETLINK_NO_ENOBUFS, &on, sizeof(int));
+
+ nfct_callback_register(h, NFCT_T_ALL, event_cb, NULL);
+
+ printf("TEST: waiting for events...\n");
+
+ ret = nfct_catch(h);
+
+ printf("TEST: conntrack events ");
+ if (ret == -1)
+ printf("(%d)(%s)\n", ret, strerror(errno));
+ else
+ printf("(OK)\n");
+
+ nfct_close(h);
+
+ ret == -1 ? exit(EXIT_FAILURE) : exit(EXIT_SUCCESS);
+}
diff --git a/qa/ct_stress.c b/qa/ct_stress.c
new file mode 100644
index 0000000..36aa1a0
--- /dev/null
+++ b/qa/ct_stress.c
@@ -0,0 +1,75 @@
+/* simple tool to generate random of flow entries to fill hard the
+ conntrack table. Early drop will not save our day then, because
+ the table will be plenty of assured flows. If things go well,
+ we hit ENOMEM at some point.
+
+ You have to use conntrack_events_reliable together with this tool.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <time.h>
+
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_tcp.h>
+
+int main(int argc, char *argv[])
+{
+ time_t t;
+ int ret, i, r;
+ struct nfct_handle *h;
+ struct nf_conntrack *ct;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s [ct_table_size]\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ time(&t);
+ srandom(t);
+ r = random();
+
+ ct = nfct_new();
+ if (!ct) {
+ perror("nfct_new");
+ return 0;
+ }
+
+ h = nfct_open(CONNTRACK, 0);
+ if (!h) {
+ perror("nfct_open");
+ nfct_destroy(ct);
+ return -1;
+ }
+
+ for (i = r;i < (r + atoi(argv[1]) * 2); i++) {
+ nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
+ nfct_set_attr_u32(ct, ATTR_IPV4_SRC, inet_addr("1.1.1.1") + i);
+ nfct_set_attr_u32(ct, ATTR_IPV4_DST, inet_addr("2.2.2.2") + i);
+
+ nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_TCP);
+ nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(10));
+ nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(20));
+
+ nfct_setobjopt(ct, NFCT_SOPT_SETUP_REPLY);
+
+ nfct_set_attr_u8(ct, ATTR_TCP_STATE, TCP_CONNTRACK_ESTABLISHED);
+ nfct_set_attr_u32(ct, ATTR_TIMEOUT, 1000);
+ nfct_set_attr_u32(ct, ATTR_STATUS, IPS_ASSURED);
+
+ if (i % 10000 == 0)
+ printf("added %d flow entries\n", i);
+
+ ret = nfct_query(h, NFCT_Q_CREATE, ct);
+ if (ret == -1)
+ perror("nfct_query: ");
+ }
+ nfct_close(h);
+
+ nfct_destroy(ct);
+
+ exit(EXIT_SUCCESS);
+}