]> git.puffer.fish Git - matthieu/frr.git/commitdiff
BSD: Detect route(4) overflows
authorRoy Marples <roy@marples.name>
Sun, 4 Oct 2020 19:32:26 +0000 (20:32 +0100)
committerRoy Marples <roy@marples.name>
Sun, 4 Oct 2020 19:32:26 +0000 (20:32 +0100)
NetBSD and DragonFlyBSD support reporting of route(4) overflows
by setting the socket option SO_RERROR.

This is handled the same as on Linux by exiting with a -1 error code.

Signed-off-by: Roy Marples <roy@marples.name>
zebra/kernel_socket.c

index 40ac44b77f9f8dce8d94f92304b982fdc4096583..16a9669e891f2d9da49cda346281c80012132dc7 100644 (file)
@@ -1340,13 +1340,27 @@ static int kernel_read(struct thread *thread)
 
        nbytes = read(sock, &buf, sizeof(buf));
 
-       if (nbytes <= 0) {
-               if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
+       if (nbytes < 0) {
+               if (errno == ENOBUFS) {
+                       flog_err(EC_ZEBRA_RECVMSG_OVERRUN,
+                                "routing socket overrun: %s",
+                                safe_strerror(errno));
+                       /*
+                        *  In this case we are screwed.
+                        *  There is no good way to
+                        *  recover zebra at this point.
+                        */
+                       exit(-1);
+               }
+               if (errno != EAGAIN && errno != EWOULDBLOCK)
                        flog_err_sys(EC_LIB_SOCKET, "routing socket error: %s",
                                     safe_strerror(errno));
                return 0;
        }
 
+       if (nbytes == 0)
+               return 0;
+
        thread_add_read(zrouter.master, kernel_read, NULL, sock, NULL);
 
        if (IS_ZEBRA_DEBUG_KERNEL)
@@ -1412,6 +1426,14 @@ static void routing_socket(struct zebra_ns *zns)
                return;
        }
 
+#ifdef SO_RERROR
+       /* Allow reporting of route(4) buffer overflow errors */
+       int n = 1;
+       if (setsockopt(routing_sock, SOL_SOCKET, SO_RERROR, &n, sizeof(n)) < 0)
+               flog_err_sys(EC_LIB_SOCKET,
+                            "Can't set SO_RERROR on routing socket");
+#endif
+
        /* XXX: Socket should be NONBLOCK, however as we currently
         * discard failed writes, this will lead to inconsistencies.
         * For now, socket must be blocking.