freebsd_network: Adjust too-large packet handling in read().
Before ca6a44c133, this function returned
whatever amount of the buffer it could and silently discarded the rest.
After that change and before this one, it would refuse to return anything,
which meant that as soon as we got one packet too large to handle,
we would never receive any more packets (and the errors displayed in
e.g. ifconfig would go up forever.)
Now, we discard too-large packets so RX will not stall completely
and still return E2BIG (so error counts will go up), but we also
print an error to syslog, so that precisely what has gone wrong
will be easily known.
This commit is contained in:
@@ -134,16 +134,17 @@ compat_read(void *cookie, off_t position, void *buffer, size_t *numBytes)
|
||||
} else if (status < B_OK)
|
||||
return status;
|
||||
|
||||
IF_LOCK(&ifp->receive_queue);
|
||||
if (ifp->receive_queue.ifq_head != NULL
|
||||
&& ifp->receive_queue.ifq_head->m_pkthdr.len >= length) {
|
||||
IF_UNLOCK(&ifp->receive_queue);
|
||||
return E2BIG;
|
||||
}
|
||||
_IF_DEQUEUE(&ifp->receive_queue, mb);
|
||||
IF_UNLOCK(&ifp->receive_queue);
|
||||
IF_DEQUEUE(&ifp->receive_queue, mb);
|
||||
} while (mb == NULL);
|
||||
|
||||
if (mb->m_pkthdr.len > length) {
|
||||
if_printf(ifp, "error reading packet: too large! (%d > %" B_PRIuSIZE ")\n",
|
||||
mb->m_pkthdr.len, length);
|
||||
m_freem(mb);
|
||||
*numBytes = 0;
|
||||
return E2BIG;
|
||||
}
|
||||
|
||||
length = min_c(max_c((size_t)mb->m_pkthdr.len, 0), length);
|
||||
|
||||
m_copydata(mb, 0, length, buffer);
|
||||
|
||||
Reference in New Issue
Block a user