summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--conntrack.810
-rw-r--r--include/conntrack.h5
-rw-r--r--src/conntrack.c61
3 files changed, 57 insertions, 19 deletions
diff --git a/conntrack.8 b/conntrack.8
index 7c4a168..bfb2de0 100644
--- a/conntrack.8
+++ b/conntrack.8
@@ -82,6 +82,16 @@ event code. Using this parameter, you can reduce the event messages generated
by the kernel to those types to those that you are actually interested in.
.
This option can only be used in conjunction with "-E, --event".
+.BI "-b, --buffer-size " "value (in bytes)"
+Set the Netlink socket buffer size. This option is useful if the command line
+tool reports ENOBUFS errors. If you do not pass this option, the default value
+available at /proc/sys/net/core/rmem_default is used. The tool reports this
+problem if your process is too slow to handle all the event messages or, in
+other words, if the amount of events are big enough to overrun the socket
+buffer. Note that using a big buffer reduces the chances to hit ENOBUFS,
+however, this results in more memory consumption.
+.
+This option can only be used in conjunction with "-E, --event".
.SS FILTER PARAMETERS
.TP
.BI "-s, --orig-src " IP_ADDRESS
diff --git a/include/conntrack.h b/include/conntrack.h
index dc30c13..e8059c8 100644
--- a/include/conntrack.h
+++ b/include/conntrack.h
@@ -132,8 +132,11 @@ enum options {
CT_OPT_SECMARK_BIT = 20,
CT_OPT_SECMARK = (1 << CT_OPT_SECMARK_BIT),
+
+ CT_OPT_BUFFERSIZE_BIT = 21,
+ CT_OPT_BUFFERSIZE = (1 << CT_OPT_BUFFERSIZE_BIT),
- CT_OPT_MAX = CT_OPT_SECMARK_BIT
+ CT_OPT_MAX = CT_OPT_BUFFERSIZE_BIT
};
#define NUMBER_OF_OPT CT_OPT_MAX+1
diff --git a/src/conntrack.c b/src/conntrack.c
index 1ee98e3..7400c1b 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -64,7 +64,7 @@ static const char cmd_need_param[NUMBER_OF_CMD]
static const char *optflags[NUMBER_OF_OPT] = {
"src","dst","reply-src","reply-dst","protonum","timeout","status","zero",
"event-mask","tuple-src","tuple-dst","mask-src","mask-dst","nat-range","mark",
-"id","family","src-nat","dst-nat","output","secmark"};
+"id","family","src-nat","dst-nat","output","secmark","buffersize"};
static struct option original_opts[] = {
{"dump", 2, 0, 'L'},
@@ -99,6 +99,7 @@ static struct option original_opts[] = {
{"src-nat", 2, 0, 'n'},
{"dst-nat", 2, 0, 'g'},
{"output", 1, 0, 'o'},
+ {"buffer-size", 1, 0, 'b'},
{0, 0, 0, 0}
};
@@ -120,22 +121,22 @@ static unsigned int global_option_offset = 0;
static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
/* Well, it's better than "Re: Linux vs FreeBSD" */
{
- /* s d r q p t u z e [ ] { } a m i f n g o c */
-/*CT_LIST*/ {2,2,2,2,2,0,2,2,0,0,0,0,0,0,2,0,2,2,2,2,2},
-/*CT_CREATE*/ {2,2,2,2,1,1,1,0,0,0,0,0,0,2,2,0,0,2,2,0,0},
-/*CT_UPDATE*/ {2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2,0},
-/*CT_DELETE*/ {2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2,0},
-/*CT_GET*/ {2,2,2,2,1,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0},
-/*CT_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-/*CT_EVENT*/ {2,2,2,2,2,0,0,0,2,0,0,0,0,0,2,0,0,2,2,2,2},
-/*VERSION*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-/*HELP*/ {0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-/*EXP_LIST*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0},
-/*EXP_CREATE*/{1,1,2,2,1,1,2,0,0,1,1,1,1,0,0,0,0,0,0,0,0},
-/*EXP_DELETE*/{1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-/*EXP_GET*/ {1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-/*EXP_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-/*EXP_EVENT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ /* s d r q p t u z e [ ] { } a m i f n g o c b*/
+/*CT_LIST*/ {2,2,2,2,2,0,2,2,0,0,0,0,0,0,2,0,2,2,2,2,2,0},
+/*CT_CREATE*/ {2,2,2,2,1,1,1,0,0,0,0,0,0,2,2,0,0,2,2,0,0,0},
+/*CT_UPDATE*/ {2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0},
+/*CT_DELETE*/ {2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0},
+/*CT_GET*/ {2,2,2,2,1,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0},
+/*CT_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+/*CT_EVENT*/ {2,2,2,2,2,0,0,0,2,0,0,0,0,0,2,0,0,2,2,2,2,2},
+/*VERSION*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+/*HELP*/ {0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+/*EXP_LIST*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0},
+/*EXP_CREATE*/{1,1,2,2,1,1,2,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0},
+/*EXP_DELETE*/{1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+/*EXP_GET*/ {1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+/*EXP_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+/*EXP_EVENT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
};
static LIST_HEAD(proto_list);
@@ -540,6 +541,7 @@ static const char usage_parameters[] =
" -f, --family proto\t\tLayer 3 Protocol, eg. 'ipv6'\n"
" -t, --timeout timeout\t\tSet timeout\n"
" -u, --status status\t\tSet status, eg. ASSURED\n"
+ " -b, --buffer-size\t\tNetlink socket buffer size\n"
;
@@ -907,6 +909,7 @@ int main(int argc, char *argv[])
int c, cmd;
unsigned int type = 0, event_mask = 0, l4flags = 0, status = 0;
int res = 0;
+ size_t socketbuffersize = 0;
int family = AF_UNSPEC;
char __obj[nfct_maxsize()];
char __exptuple[nfct_maxsize()];
@@ -933,7 +936,7 @@ int main(int argc, char *argv[])
while ((c = getopt_long(argc, argv, "L::I::U::D::G::E::F::hVs:d:r:q:"
"p:t:u:e:a:z[:]:{:}:m:i:f:o:n::"
- "g::c:",
+ "g::c:b:",
opts, NULL)) != -1) {
switch(c) {
/* commands */
@@ -1105,6 +1108,10 @@ int main(int argc, char *argv[])
"`%s' unsupported protocol",
optarg);
break;
+ case 'b':
+ socketbuffersize = atol(optarg);
+ options |= CT_OPT_BUFFERSIZE;
+ break;
default:
if (h && h->parse_opts
&&!h->parse_opts(c - h->option_offset, obj,
@@ -1297,10 +1304,28 @@ int main(int argc, char *argv[])
if (!cth)
exit_error(OTHER_PROBLEM, "Can't open handler");
+
+ if (options & CT_OPT_BUFFERSIZE) {
+ size_t ret;
+ ret = nfnl_rcvbufsiz(nfct_nfnlh(cth), socketbuffersize);
+ fprintf(stderr, "NOTICE: Netlink socket buffer size "
+ "has been set to %u bytes.\n", ret);
+ }
signal(SIGINT, event_sighandler);
signal(SIGTERM, event_sighandler);
nfct_callback_register(cth, NFCT_T_ALL, event_cb, obj);
res = nfct_catch(cth);
+ if (res == -1) {
+ if (errno == ENOBUFS) {
+ fprintf(stderr,
+ "WARNING: We have hit ENOBUFS! We "
+ "are losing events.\nThis message "
+ "means that the current netlink "
+ "socket buffer size is too small.\n"
+ "Please, check --buffer-size in "
+ "conntrack(8) manpage.\n");
+ }
+ }
nfct_close(cth);
break;