diff options
| author | Vincenzo Maffione <vmaffione@FreeBSD.org> | 2018-12-05 11:57:16 +0000 |
|---|---|---|
| committer | Vincenzo Maffione <vmaffione@FreeBSD.org> | 2018-12-05 11:57:16 +0000 |
| commit | b6e66be22bdce2aadcf52ee6230faa1e6cd3f805 (patch) | |
| tree | e9311c45835e19b2d58f105e0627078f15f1cd63 /sys/net/netmap_user.h | |
| parent | abc73e04c2a0add60dea19c7aab5a0a4d51ab418 (diff) | |
Notes
Diffstat (limited to 'sys/net/netmap_user.h')
| -rw-r--r-- | sys/net/netmap_user.h | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/sys/net/netmap_user.h b/sys/net/netmap_user.h index a86bcb6b6e3e..e9ce9c43e278 100644 --- a/sys/net/netmap_user.h +++ b/sys/net/netmap_user.h @@ -138,11 +138,12 @@ nm_tx_pending(struct netmap_ring *r) return nm_ring_next(r, r->tail) != r->head; } - +/* Compute the number of slots available in the netmap ring. We use + * ring->head as explained in the comment above nm_ring_empty(). */ static inline uint32_t nm_ring_space(struct netmap_ring *ring) { - int ret = ring->tail - ring->cur; + int ret = ring->tail - ring->head; if (ret < 0) ret += ring->num_slots; return ret; @@ -1091,18 +1092,36 @@ nm_dispatch(struct nm_desc *d, int cnt, nm_cb_t cb, u_char *arg) ring = NETMAP_RXRING(d->nifp, ri); for ( ; !nm_ring_empty(ring) && cnt != got; got++) { u_int idx, i; + u_char *oldbuf; + struct netmap_slot *slot; if (d->hdr.buf) { /* from previous round */ cb(arg, &d->hdr, d->hdr.buf); } i = ring->cur; - idx = ring->slot[i].buf_idx; + slot = &ring->slot[i]; + idx = slot->buf_idx; /* d->cur_rx_ring doesn't change inside this loop, but * set it here, so it reflects d->hdr.buf's ring */ d->cur_rx_ring = ri; - d->hdr.slot = &ring->slot[i]; - d->hdr.buf = (u_char *)NETMAP_BUF(ring, idx); + d->hdr.slot = slot; + oldbuf = d->hdr.buf = (u_char *)NETMAP_BUF(ring, idx); // __builtin_prefetch(buf); - d->hdr.len = d->hdr.caplen = ring->slot[i].len; + d->hdr.len = d->hdr.caplen = slot->len; + while (slot->flags & NS_MOREFRAG) { + u_char *nbuf; + u_int oldlen = slot->len; + i = nm_ring_next(ring, i); + slot = &ring->slot[i]; + d->hdr.len += slot->len; + nbuf = (u_char *)NETMAP_BUF(ring, slot->buf_idx); + if (oldbuf != NULL && nbuf - oldbuf == ring->nr_buf_size && + oldlen == ring->nr_buf_size) { + d->hdr.caplen += slot->len; + oldbuf = nbuf; + } else { + oldbuf = NULL; + } + } d->hdr.ts = ring->ts; ring->head = ring->cur = nm_ring_next(ring, i); } |
