fds.fd = open("/dev/netmap", O_RDWR); strcpy(nmr.nm_name, "ix0"); ioctl(fds.fd, NIOCREG, &nmr); p = mmap(0, nmr.memsize, fds.fd); nifp = NETMAP_IF(p, nmr.offset); fds.events = POLLOUT; for (;;) { poll(fds, 1, -1); for (r = 0; r < nmr.num_queues; r++) { ring = NETMAP_TXRING(nifp, r); while (ring->avail-- > 0) { i = ring->cur; buf = NETMAP_BUF(ring, ring->slot[i].buf_index); ... store the payload into buf ... ring->slot[i].len = ... \/\/ set packet length ring->cur = NETMAP_NEXT(ring, i); } } }
src = &src_nifp->slot[i]; dst = &dst_nifp->slot[j]; tmp = dst->buf_index; dst->buf_index = src->buf_index; src->buf_index = tmp; dst->len = src->len; dst->flags = src->flags = BUF_CHANGED;
$ wc -l net/* dev/netmap/* 283 net/netmap.h 98 net/netmap_user.h 393 dev/netmap/if_bge_netmap.h 425 dev/netmap/if_em_netmap.h 375 dev/netmap/if_lem_netmap.h 436 dev/netmap/if_re_netmap.h 425 dev/netmap/ixgbe_netmap.h 306 dev/netmap/netmap.4 1691 dev/netmap/netmap.c 225 dev/netmap/netmap_kern.h
756 examples/pcap.c
int (*nm_register)(struct ifnet *, int onoff); void (*nm_lock)(void *, int what, u_int ringid); int (*nm_txsync)(void *, u_int ring, int lock); int (*nm_rxsync)(void *, u_int ring, int lock);
... +#ifdef DEV_NETMAP +#include \ +#endif ... +#ifdef DEV_NETMAP + re_netmap_tx_init(sc); +#endif ... +#ifdef DEV_NETMAP + if (ifp->if_capenable & IFCAP_NETMAP) { + selwakeuppri(&NA(ifp)->rx_rings->si, PI_NET); + return 0; + } +#endif ...
int pcap_inject(pcap_t *p, void *buf, size_t size) { int si, idx; for (si = p->begin; si < p->end; si++) { struct netmap_ring *ring = NETMAP_TXRING(p->nifp, si); if (ring->avail == 0) continue; idx = ring->slot[ring->cur].buf_idx; bcopy(buf, NETMAP_BUF(ring, idx), size); ring->cur = NETMAP_RING_NEXT(ring, ring->cur); ring->avail--; return size; } return -1; }
int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { int si, ret = 0; for (si =p->begin; si < p->end; si++) { struct netmap_ring *ring = NETMAP_RXRING(p->nifp, si); while ((cnt == -1 || ret != cnt) && ring->avail > 0) { int i = ring->cur; int idx = ring->slot[i].buf_idx; p->hdr.len = p->hdr.caplen = ring->slot[i].len; callback(user, &p->hdr, NETMAP_BUF(ring, idx)); ring->cur = NETMAP_RING_NEXT(ring, i); ring->avail--; ret++; } } return ret; }