Make etherread4() safe for LRO.
authorAndrew Gallatin <gallatin@google.com>
Mon, 11 Aug 2014 14:30:19 +0000 (07:30 -0700)
committerAndrew Gallatin <gallatin@google.com>
Mon, 11 Aug 2014 14:30:19 +0000 (07:30 -0700)
This patch allows etherread4() read up to 128K, rather than just an MTU
size.  This is required because qbread() is used to read, and
the semantics of qbread() are to give you one block of at most len bytes.
If a block is > len (which will be the case for LRO, when len == MTU), then
it will split the block.   When the block is split  when feeding packets from
dev/ether to ethermedium, you wind up looking in the middle of the
payload for headers, and it is a total mess.  Ideally, there would
be some sort of qbreadall() that would not take a length argument
that would just return the next block on the queue (eg, a blocking
qget()).

128K was chosen because it is roughly 2x the size of the largest
imaginable MTU and/or LRO packet size (due to both IPv4 and
IPv6 being limited to roughly 64K + headers per packet).

Discussed with: Barret Rhoden, Ronald Minnich

Signed-off-by: Andrew Gallatin <gallatin@google.com>
kern/src/net/ethermedium.c

index b2a11c2..4143b5b 100644 (file)
@@ -409,7 +409,7 @@ static void etherread4(void *a)
                return;
        }
        for (;;) {
-               bp = devtab[er->mchan4->type].bread(er->mchan4, ifc->maxtu, 0);
+               bp = devtab[er->mchan4->type].bread(er->mchan4, 128 * 1024, 0);
                if (!canrlock(&ifc->rwlock)) {
                        freeb(bp);
                        continue;