Tolerate ENOBUFS from kernel netlink code in second call to recvmsg.
authorroot <root@salsa.nicira.com>
Wed, 23 Apr 2008 22:20:58 +0000 (15:20 -0700)
committerroot <root@salsa.nicira.com>
Wed, 23 Apr 2008 22:20:58 +0000 (15:20 -0700)
The Linux kernel returns ENOBUFS to userspace code to indicate that
a netlink message that the kernel wanted to send could not be due to
a lack of buffer space.  We checked for this and dealt with it in
one recvmsg call but not in another.  This change tolerates it in
both places.

Should fix a problem encountered on the OF6k under "hping3 --flood".

** This fix was done by Ben. **

lib/netlink.c

index 36754ee48edb5fcb676b799760561c6abeb7e165..1bb4af480deb6cc012e6e580e41cd9968973cf68 100644 (file)
@@ -296,11 +296,20 @@ try_again:
     iov.iov_len = 1;
     do {
         nbytes2 = recvmsg(sock->fd, &msg, MSG_DONTWAIT);
-        if (nbytes2 < 0) {
-            VLOG_ERR("failed to remove nlmsg from socket: %d\n", errno);
-        }
     } while (nbytes2 < 0 && errno == EINTR);
-
+    if (nbytes2 < 0) {
+        if (errno == ENOBUFS) {
+            /* The kernel is notifying us that a message it tried to send to us
+             * was dropped.  We have to pass this along to the caller in case
+             * it wants to retry a request.  So kill the buffer, which we can
+             * re-read next time. */
+            buffer_delete(buf);
+            return ENOBUFS;
+        } else {
+            VLOG_ERR("failed to remove nlmsg from socket: %s\n",
+                     strerror(errno));
+        }
+    }
     if (!NLMSG_OK(nlmsghdr, nbytes)) {
         VLOG_ERR("received invalid nlmsg (%zd bytes < %d)",
                  bufsize, NLMSG_HDRLEN);