From 94e75add9867fb6f0e05e73b23f723f139da829e Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 6 Mar 2012 12:10:55 +0100 Subject: 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 --- qa/Makefile.am | 10 ++++++- qa/ct_events_reliable.c | 59 ++++++++++++++++++++++++++++++++++++++ qa/ct_stress.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 qa/ct_events_reliable.c create mode 100644 qa/ct_stress.c (limited to 'qa') 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 +#include +#include +#include + +#include + +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 +#include +#include +#include +#include +#include + +#include +#include + +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); +} -- cgit v1.2.3