From c34b6b577ef58e7609de1e088e7923c4c056cfeb Mon Sep 17 00:00:00 2001 From: hasso Date: Tue, 31 Aug 2004 13:41:49 +0000 Subject: Commit my hack (yes, I still call it hack) - command line switch for zebra daemon to change netlink receive buffer size. --- zebra/ChangeLog | 5 +++++ zebra/main.c | 56 +++++++++++++++++++++++++++++++++++++----------------- zebra/rt_netlink.c | 44 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 17 deletions(-) (limited to 'zebra') 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 + + * 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 * 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; -- cgit v1.2.1