diff --git a/sys/dev/netmap/netmap.c b/sys/dev/netmap/netmap.c index 4de5c7150..39eaf8cac 100644 --- a/sys/dev/netmap/netmap.c +++ b/sys/dev/netmap/netmap.c @@ -1730,6 +1730,12 @@ netmap_interp_ringid(struct netmap_priv_d *priv, uint16_t ringid, uint32_t flags case NR_REG_PIPE_MASTER: case NR_REG_PIPE_SLAVE: for_rx_tx(t) { + if ((t == NR_RX && (flags & NR_TX_RINGS_ONLY)) || + (t == NR_TX && (flags & NR_RX_RINGS_ONLY))) { + priv->np_qfirst[t] = priv->np_qlast[t] = 0; + continue; + } + priv->np_qfirst[t] = 0; priv->np_qlast[t] = nma_get_nrings(na, t); } @@ -1743,6 +1749,18 @@ netmap_interp_ringid(struct netmap_priv_d *priv, uint16_t ringid, uint32_t flags return EINVAL; } for_rx_tx(t) { + if ((t == NR_RX && (flags & NR_TX_RINGS_ONLY)) || + (t == NR_TX && (flags & NR_RX_RINGS_ONLY))) { + /* + * NR_[TX|RX]_RINGS_ONLY affects only hw + * rings, so keep sw rings on in any + * case + */ + priv->np_qfirst[t] = nma_get_nrings(na, t); + priv->np_qlast[t] = nma_get_nrings(na, t) + 1; + continue; + } + priv->np_qfirst[t] = (reg == NR_REG_SW ? nma_get_nrings(na, t) : 0); priv->np_qlast[t] = nma_get_nrings(na, t) + 1; @@ -1756,6 +1774,12 @@ netmap_interp_ringid(struct netmap_priv_d *priv, uint16_t ringid, uint32_t flags return EINVAL; } for_rx_tx(t) { + if ((t == NR_RX && (flags & NR_TX_RINGS_ONLY)) || + (t == NR_TX && (flags & NR_RX_RINGS_ONLY))) { + priv->np_qfirst[t] = priv->np_qlast[t] = 0; + continue; + } + /* if not enough rings, use the first one */ j = i; if (j >= nma_get_nrings(na, t)) diff --git a/sys/net/netmap.h b/sys/net/netmap.h index b18eb3043..b03ff02ae 100644 --- a/sys/net/netmap.h +++ b/sys/net/netmap.h @@ -532,6 +532,8 @@ enum { NR_REG_DEFAULT = 0, /* backward compat, should not be used. */ /* request ptnetmap host support */ #define NR_PASSTHROUGH_HOST NR_PTNETMAP_HOST /* deprecated */ #define NR_PTNETMAP_HOST 0x1000 +#define NR_RX_RINGS_ONLY 0x2000 +#define NR_TX_RINGS_ONLY 0x4000 /* diff --git a/sys/net/netmap_user.h b/sys/net/netmap_user.h index 928f7c370..029de5909 100644 --- a/sys/net/netmap_user.h +++ b/sys/net/netmap_user.h @@ -313,6 +313,8 @@ typedef void (*nm_cb_t)(u_char *, const struct nm_pkthdr *, const u_char *d); * z zero copy monitor * t monitor tx side * r monitor rx side + * R bind only RX ring(s) + * T bind only TX ring(s) * * req provides the initial values of nmreq before parsing ifname. * Remember that the ifname parsing will override the ring @@ -701,6 +703,12 @@ nm_open(const char *ifname, const struct nmreq *req, case 'r': nr_flags |= NR_MONITOR_RX; break; + case 'R': + nr_flags |= NR_RX_RINGS_ONLY; + break; + case 'T': + nr_flags |= NR_TX_RINGS_ONLY; + break; default: snprintf(errmsg, MAXERRMSG, "unrecognized flag: '%c'", *port); goto fail;