From 7f03191fda39ff09640f093b7ad84f461ffd65b2 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 28 Oct 2009 20:50:48 +0100 Subject: [PATCH] iproute uses too small of a receive buffer It uses 1MB as receive buf limit by default (without increasing /proc/sys/net/core/rmem_max it will be limited by less however) and allows to specify the size manually using "-rcvbuf X" (-r is already used, so you need to specify at least -rc). Additionally rtnl_listen() continues on ENOBUFS after printing the error message. --- include/libnetlink.h | 2 ++ ip/ip.c | 16 +++++++++++++++- lib/libnetlink.c | 5 ++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/include/libnetlink.h b/include/libnetlink.h index 0e024682..61da15be 100644 --- a/include/libnetlink.h +++ b/include/libnetlink.h @@ -17,6 +17,8 @@ struct rtnl_handle __u32 dump; }; +extern int rcvbuf; + extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions); extern int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol); extern void rtnl_close(struct rtnl_handle *rth); diff --git a/ip/ip.c b/ip/ip.c index 2bd54b2a..b4c076aa 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -50,7 +50,8 @@ static void usage(void) " tunnel | maddr | mroute | monitor | xfrm }\n" " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n" " -f[amily] { inet | inet6 | ipx | dnet | link } |\n" -" -o[neline] | -t[imestamp] | -b[atch] [filename] }\n"); +" -o[neline] | -t[imestamp] | -b[atch] [filename] |\n" +" -rc[vbuf] [size]}\n"); exit(-1); } @@ -213,6 +214,19 @@ int main(int argc, char **argv) if (argc <= 1) usage(); batch_file = argv[1]; + } else if (matches(opt, "-rcvbuf") == 0) { + unsigned int size; + + argc--; + argv++; + if (argc <= 1) + usage(); + if (get_unsigned(&size, argv[1], 0)) { + fprintf(stderr, "Invalid rcvbuf size '%s'\n", + argv[1]); + exit(-1); + } + rcvbuf = size; } else if (matches(opt, "-help") == 0) { usage(); } else { diff --git a/lib/libnetlink.c b/lib/libnetlink.c index 100dd407..a6c03068 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -25,6 +25,8 @@ #include "libnetlink.h" +int rcvbuf = 1024 * 1024; + void rtnl_close(struct rtnl_handle *rth) { if (rth->fd >= 0) { @@ -38,7 +40,6 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, { socklen_t addr_len; int sndbuf = 32768; - int rcvbuf = 32768; memset(rth, 0, sizeof(*rth)); @@ -409,6 +410,8 @@ int rtnl_listen(struct rtnl_handle *rtnl, continue; fprintf(stderr, "netlink receive error %s (%d)\n", strerror(errno), errno); + if (errno == ENOBUFS) + continue; return -1; } if (status == 0) {