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.
This commit is contained in:
Patrick McHardy 2009-10-28 20:50:48 +01:00 committed by Stephen Hemminger
parent 24f3818244
commit 7f03191fda
3 changed files with 21 additions and 2 deletions

View File

@ -17,6 +17,8 @@ struct rtnl_handle
__u32 dump; __u32 dump;
}; };
extern int rcvbuf;
extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions); extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions);
extern int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol); extern int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol);
extern void rtnl_close(struct rtnl_handle *rth); extern void rtnl_close(struct rtnl_handle *rth);

16
ip/ip.c
View File

@ -50,7 +50,8 @@ static void usage(void)
" tunnel | maddr | mroute | monitor | xfrm }\n" " tunnel | maddr | mroute | monitor | xfrm }\n"
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n" " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
" -f[amily] { inet | inet6 | ipx | dnet | link } |\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); exit(-1);
} }
@ -213,6 +214,19 @@ int main(int argc, char **argv)
if (argc <= 1) if (argc <= 1)
usage(); usage();
batch_file = argv[1]; 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) { } else if (matches(opt, "-help") == 0) {
usage(); usage();
} else { } else {

View File

@ -25,6 +25,8 @@
#include "libnetlink.h" #include "libnetlink.h"
int rcvbuf = 1024 * 1024;
void rtnl_close(struct rtnl_handle *rth) void rtnl_close(struct rtnl_handle *rth)
{ {
if (rth->fd >= 0) { if (rth->fd >= 0) {
@ -38,7 +40,6 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions,
{ {
socklen_t addr_len; socklen_t addr_len;
int sndbuf = 32768; int sndbuf = 32768;
int rcvbuf = 32768;
memset(rth, 0, sizeof(*rth)); memset(rth, 0, sizeof(*rth));
@ -409,6 +410,8 @@ int rtnl_listen(struct rtnl_handle *rtnl,
continue; continue;
fprintf(stderr, "netlink receive error %s (%d)\n", fprintf(stderr, "netlink receive error %s (%d)\n",
strerror(errno), errno); strerror(errno), errno);
if (errno == ENOBUFS)
continue;
return -1; return -1;
} }
if (status == 0) { if (status == 0) {