]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[linux] Impose receive quota on tap driver
authorMichael Brown <mcb30@ipxe.org>
Mon, 4 Sep 2017 17:00:34 +0000 (18:00 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 4 Sep 2017 17:00:34 +0000 (18:00 +0100)
The tap driver can retrieve a potentially unlimited number of packets
in a single poll.  This can lead to heap exhaustion under heavy load.

Fix by imposing an artificial receive quota (as already used in other
drivers without natural receive limits).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/linux/tap.c

index 6fe76fd4da6906c92002c9dcafd74152909d6771..db3b7955b2b2f6123e7fb326493963b3e3069480 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/if_tun.h>
 
 #define RX_BUF_SIZE 1536
+#define RX_QUOTA 4
 
 /** @file
  *
@@ -127,6 +128,7 @@ static void tap_poll(struct net_device *netdev)
        struct tap_nic * nic = netdev->priv;
        struct pollfd pfd;
        struct io_buffer * iobuf;
+       unsigned int quota = RX_QUOTA;
        int r;
 
        pfd.fd = nic->fd;
@@ -144,7 +146,8 @@ static void tap_poll(struct net_device *netdev)
        if (! iobuf)
                goto allocfail;
 
-       while ((r = linux_read(nic->fd, iobuf->data, RX_BUF_SIZE)) > 0) {
+       while (quota-- &&
+              ((r = linux_read(nic->fd, iobuf->data, RX_BUF_SIZE)) > 0)) {
                DBGC2(nic, "tap %p read %d bytes\n", nic, r);
 
                iob_put(iobuf, r);