diff options
| author | hasso <hasso> | 2004-08-31 13:41:49 +0000 | 
|---|---|---|
| committer | hasso <hasso> | 2004-08-31 13:41:49 +0000 | 
| commit | c34b6b577ef58e7609de1e088e7923c4c056cfeb (patch) | |
| tree | 6cc1c399962c8dec074fe21aad73cc1fc7cad3dd | |
| parent | 7b90143f14ba21f6bd3ff2c8b60f69500f46c0e8 (diff) | |
Commit my hack (yes, I still call it hack) - command line switch for zebra
daemon to change netlink receive buffer size.
| -rw-r--r-- | doc/ChangeLog | 4 | ||||
| -rw-r--r-- | doc/zebra.8 | 12 | ||||
| -rw-r--r-- | zebra/ChangeLog | 5 | ||||
| -rw-r--r-- | zebra/main.c | 56 | ||||
| -rw-r--r-- | zebra/rt_netlink.c | 44 | 
5 files changed, 104 insertions, 17 deletions
| diff --git a/doc/ChangeLog b/doc/ChangeLog index 63b736cc..97dddece 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -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. diff --git a/doc/zebra.8 b/doc/zebra.8 index 8f830152..25cbb363 100644 --- a/doc/zebra.8 +++ b/doc/zebra.8 @@ -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 diff --git a/zebra/ChangeLog b/zebra/ChangeLog index 9dd031cb..b6798077 100644 --- a/zebra/ChangeLog +++ b/zebra/ChangeLog @@ -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 diff --git a/zebra/main.c b/zebra/main.c index 6d40d708..0c1a7ddb 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -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; diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 2ca0de43..9e6c440b 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -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; | 
