[quagga-dev 10213] [PATCH] use SO_RCVBUFFORCE for netlink socket

Ulrich Weber ulrich.weber at sophos.com
Tue Jan 22 11:22:23 GMT 2013


so net.core.rmem_max must not be adjusted. Requires
linux kernel >= 2.6.14, falls back to SO_RCVBUF on error

Signed-off-by: Ulrich Weber <ulrich.weber at sophos.com>
---
 doc/zebra.8        |    2 +-
 zebra/rt_netlink.c |   16 +++++++++++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/doc/zebra.8 b/doc/zebra.8
index 23703e7..a40909a 100644
--- a/doc/zebra.8
+++ b/doc/zebra.8
@@ -80,7 +80,7 @@ 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
+< 2.6.14 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.
 
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 0c2a006..612d0e8 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -101,6 +101,10 @@ set_ifindex(struct interface *ifp, unsigned int ifi_index)
   ifp->ifindex = ifi_index;
 }
 
+#ifndef SO_RCVBUFFORCE
+#define SO_RCVBUFFORCE  (33)
+#endif
+
 static int
 netlink_recvbuf (struct nlsock *nl, uint32_t newsize)
 {
@@ -117,15 +121,25 @@ netlink_recvbuf (struct nlsock *nl, uint32_t newsize)
       return -1;
     }
 
-  ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize,
+  if ( zserv_privs.change (ZPRIVS_RAISE) )
+    zlog_err ("routing_socket: Can't raise privileges");
+
+  /* Try force option (linux >= 2.6.14) and fall back to normal set */
+  ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE, &nl_rcvbufsize,
 		   sizeof(nl_rcvbufsize));
   if (ret < 0)
+     ret = setsockopt(nl->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,
 	    safe_strerror (errno));
       return -1;
     }
 
+  if ( zserv_privs.change (ZPRIVS_LOWER) )
+    zlog_err ("routing_socket: Can't lower privileges");
+
   ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen);
   if (ret < 0)
     {
-- 
1.7.9.5





More information about the Quagga-dev mailing list