Commit my hack (yes, I still call it hack) - command line switch for zebra

daemon to change netlink receive buffer size.
This commit is contained in:
hasso 2004-08-31 13:41:49 +00:00
parent 7b90143f14
commit c34b6b577e
5 changed files with 104 additions and 17 deletions

View File

@ -1,3 +1,7 @@
2004-08-31 Hasso Tepper <hasso at quagga.net>
* zebra.8: Document -s/--nl-bufsize command line switch.
2004-08-27 Hasso Tepper <hasso at quagga.net>
* Update vtysh man page to reflect changes in shell.

View File

@ -71,6 +71,18 @@ name at the moment. Default is \fIquagga\fR.
\fB\-r\fR, \fB\-\-retain\fR
When the program terminates, retain routes added by \fBzebra\fR.
.TP
\fB\-s\fR, \fB\-\-nl-bufsize \fR\fInetlink-buffer-size\fR
Set netlink receive buffer size. There are cases where zebra daemon can't
handle flood of netlink messages from kernel. If you ever see "recvmsg overrun"
messages in zebra log, you are in trouble.
Solution is to increase receive buffer of netlink socket. Note that kernel
doesn't allow to increase it over maximum value defined in
\fI/proc/sys/net/core/rmem_max\fR. If you want to do it, you have to increase
maximum before starting zebra.
Note that this affects Linux only.
.TP
\fB\-v\fR, \fB\-\-version\fR
Print the version and exit.
.SH FILES

View File

@ -1,3 +1,8 @@
2004-08-31 Hasso Tepper <hasso at quagga.net>
* main.c, rt_netlink.c: Added -s command line switch for tuning
netlink receive buffer size in Linux to avoid buffer overruns.
2004-08-26 Miles Nordin <carton@Ivy.NET>
* ipforward_sysctl.c (mib_ipv6): Use size_t for len, per

View File

@ -57,6 +57,11 @@ int retain_mode = 0;
/* Don't delete kernel route. */
int keep_kernel_mode = 0;
#ifdef HAVE_NETLINK
/* Receive buffer size for netlink socket */
u_int32_t nl_rcvbufsize = 0;
#endif /* HAVE_NETLINK */
/* Command line options. */
struct option longopts[] =
{
@ -70,6 +75,9 @@ struct option longopts[] =
{ "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'},
{ "retain", no_argument, NULL, 'r'},
#ifdef HAVE_NETLINK
{ "nl-bufsize", no_argument, NULL, 's'},
#endif /* HAVE_NETLINK */
{ "user", required_argument, NULL, 'u'},
{ "version", no_argument, NULL, 'v'},
{ 0 }
@ -111,23 +119,28 @@ usage (char *progname, int status)
fprintf (stderr, "Try `%s --help' for more information.\n", progname);
else
{
printf ("Usage : %s [OPTION...]\n\n\
Daemon which manages kernel routing table management and \
redistribution between different routing protocols.\n\n\
-b, --batch Runs in batch mode\n\
-d, --daemon Runs in daemon mode\n\
-f, --config_file Set configuration file name\n\
-i, --pid_file Set process identifier file name\n\
-k, --keep_kernel Don't delete old routes which installed by zebra.\n\
-l, --log_mode Set verbose log mode flag\n\
-A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\n\
-r, --retain When program terminates, retain added route by zebra.\n\
-u, --user User and group to run as\n\
-v, --version Print program version\n\
-h, --help Display this help and exit\n\
\n\
Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
printf ("Usage : %s [OPTION...]\n\n"\
"Daemon which manages kernel routing table management and "\
"redistribution between different routing protocols.\n\n"\
"-b, --batch Runs in batch mode\n"\
"-d, --daemon Runs in daemon mode\n"\
"-f, --config_file Set configuration file name\n"\
"-i, --pid_file Set process identifier file name\n"\
"-k, --keep_kernel Don't delete old routes which installed by "\
"zebra.\n"\
"-l, --log_mode Set verbose log mode flag\n"\
"-A, --vty_addr Set vty's bind address\n"\
"-P, --vty_port Set vty's port number\n"\
"-r, --retain When program terminates, retain added route "\
"by zebra.\n"\
"-u, --user User and group to run as\n", progname);
#ifdef HAVE_NETLINK
printf ("-s, --nl-bufsize Set netlink receive buffer size\n");
#endif /* HAVE_NETLINK */
printf ("-v, --version Print program version\n"\
"-h, --help Display this help and exit\n"\
"\n"\
"Report bugs to %s\n", ZEBRA_BUG_ADDRESS);
}
exit (status);
@ -216,7 +229,11 @@ main (int argc, char **argv)
{
int opt;
#ifdef HAVE_NETLINK
opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:vs:", longopts, 0);
#else
opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:v", longopts, 0);
#endif /* HAVE_NETLINK */
if (opt == EOF)
break;
@ -259,6 +276,11 @@ main (int argc, char **argv)
case 'r':
retain_mode = 1;
break;
#ifdef HAVE_NETLINK
case 's':
nl_rcvbufsize = atoi (optarg);
break;
#endif /* HAVE_NETLINK */
case 'u':
zserv_privs.user = zserv_privs.group = optarg;
break;

View File

@ -84,6 +84,8 @@ extern struct zebra_t zebrad;
extern struct zebra_privs_t zserv_privs;
extern u_int32_t nl_rcvbufsize;
/* Make socket for Linux netlink interface. */
static int
netlink_socket (struct nlsock *nl, unsigned long groups)
@ -110,6 +112,48 @@ netlink_socket (struct nlsock *nl, unsigned long groups)
return -1;
}
/* Set receive buffer size if it's set from command line */
if (nl_rcvbufsize)
{
u_int32_t oldsize, oldlen;
u_int32_t newsize, newlen;
oldlen = sizeof(oldsize);
newlen = sizeof(newsize);
ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen);
if (ret < 0)
{
zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
strerror (errno));
close (sock);
return -1;
}
ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize,
sizeof(nl_rcvbufsize));
if (ret < 0)
{
zlog (NULL, LOG_ERR, "Can't set %s receive buffer size: %s", nl->name,
strerror (errno));
close (sock);
return -1;
}
ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen);
if (ret < 0)
{
zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
strerror (errno));
close (sock);
return -1;
}
zlog (NULL, LOG_INFO,
"Setting netlink socket receive buffer size: %u -> %u",
oldsize, newsize);
}
memset (&snl, 0, sizeof snl);
snl.nl_family = AF_NETLINK;
snl.nl_groups = groups;