]> git.puffer.fish Git - matthieu/frr.git/commitdiff
Commit my hack (yes, I still call it hack) - command line switch for zebra
authorhasso <hasso>
Tue, 31 Aug 2004 13:41:49 +0000 (13:41 +0000)
committerhasso <hasso>
Tue, 31 Aug 2004 13:41:49 +0000 (13:41 +0000)
daemon to change netlink receive buffer size.

doc/ChangeLog
doc/zebra.8
zebra/ChangeLog
zebra/main.c
zebra/rt_netlink.c

index 63b736ccdd5d471ec52059b833d7e028796ccd93..97dddeceb1f9c87543ebdd51934c25981bc7a42c 100644 (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.
index 8f830152f57fadc15767d5198735f5b3715f375d..25cbb36392012761d0538057db10aaaf5021d167 100644 (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
index 9dd031cbec50d019623c8f8a4f0adb18e80ae968..b6798077f8ae9dcd3d31aa69307bb4f665bfd690 100644 (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
index 6d40d7084e8ad5b6f56455a3e362fe773585af25..0c1a7ddb4c378a336f5b6ec2e0dd7c1c6c476c27 100644 (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;
index 2ca0de43f3dd135eff152dadae053a1751396501..9e6c440b0c4679fc4168ffddaacbd2b6b86996d1 100644 (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;