Skip to content

Commit e194c7d

Browse files
committed
stateless-filter: add single-ring simplified implementation
1 parent 4d6a6f8 commit e194c7d

File tree

1 file changed

+65
-18
lines changed

1 file changed

+65
-18
lines changed

fosdem2019/stateless-filter.c

+65-18
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
#include <assert.h>
2626
#include <arpa/inet.h>
2727

28+
/* You can undef MULTIRING to get the simpler code, which assumes
29+
* that each netmap port has a single RX ring and a single TX ring. */
30+
#define MULTIRING
31+
2832
static int stop = 0;
2933
static unsigned long long fwd = 0;
3034
static unsigned long long tot = 0;
@@ -44,23 +48,6 @@ struct filtrule {
4448
uint8_t pad;
4549
};
4650

47-
static inline int
48-
rx_ready(struct nm_desc *nmd)
49-
{
50-
unsigned int ri;
51-
52-
for (ri = nmd->first_rx_ring; ri <= nmd->last_rx_ring; ri++) {
53-
struct netmap_ring *ring;
54-
55-
ring = NETMAP_RXRING(nmd->nifp, ri);
56-
if (nm_ring_space(ring)) {
57-
return 1; /* there is something to read */
58-
}
59-
}
60-
61-
return 0;
62-
}
63-
6451
static inline int
6552
pkt_select(const char *buf, struct filtrule *rules,
6653
int num_rules)
@@ -96,6 +83,7 @@ static void
9683
forward_pkts(struct nm_desc *src, struct nm_desc *dst, struct filtrule *rules,
9784
int num_rules, int zerocopy)
9885
{
86+
#ifdef MULTIRING
9987
unsigned int si = src->first_rx_ring;
10088
unsigned int di = dst->first_tx_ring;
10189

@@ -146,10 +134,69 @@ forward_pkts(struct nm_desc *src, struct nm_desc *dst, struct filtrule *rules,
146134
ntx--;
147135
fwd++;
148136
}
149-
/* Update state of netmap ring. */
137+
/* Update the pointers in the netmap rings. */
150138
rxring->head = rxring->cur = rxhead;
151139
txring->head = txring->cur = txhead;
152140
}
141+
#else /* !MULTIRING */
142+
struct netmap_ring *txring;
143+
struct netmap_ring *rxring;
144+
unsigned int rxhead, txhead;
145+
146+
rxring = NETMAP_RXRING(src->nifp, 0);
147+
txring = NETMAP_TXRING(dst->nifp, 0);
148+
149+
for (rxhead = rxring->head, txhead = txring->head;
150+
rxhead != rxring->tail; tot++,
151+
rxhead = nm_ring_next(rxring, rxhead)) {
152+
struct netmap_slot *rs = &rxring->slot[rxhead];
153+
struct netmap_slot *ts = &txring->slot[txhead];
154+
char *rxbuf = NETMAP_BUF(rxring, rs->buf_idx);
155+
156+
if (rules && !pkt_select(rxbuf, rules, num_rules)) {
157+
continue; /* discard */
158+
}
159+
160+
ts->len = rs->len;
161+
if (zerocopy) {
162+
uint32_t idx = ts->buf_idx;
163+
ts->buf_idx = rs->buf_idx;
164+
rs->buf_idx = idx;
165+
/* report the buffer change. */
166+
ts->flags |= NS_BUF_CHANGED;
167+
rs->flags |= NS_BUF_CHANGED;
168+
} else {
169+
char *txbuf = NETMAP_BUF(txring, ts->buf_idx);
170+
memcpy(txbuf, rxbuf, ts->len);
171+
}
172+
txhead = nm_ring_next(txring, txhead);
173+
fwd++;
174+
}
175+
/* Update the pointers in the netmap rings. */
176+
rxring->head = rxring->cur = rxhead;
177+
txring->head = txring->cur = txhead;
178+
#endif /* !MULTIRING */
179+
}
180+
181+
static inline int
182+
rx_ready(struct nm_desc *nmd)
183+
{
184+
#ifdef MULTIRING
185+
unsigned int ri;
186+
187+
for (ri = nmd->first_rx_ring; ri <= nmd->last_rx_ring; ri++) {
188+
struct netmap_ring *ring;
189+
190+
ring = NETMAP_RXRING(nmd->nifp, ri);
191+
if (nm_ring_space(ring)) {
192+
return 1; /* there is something to read */
193+
}
194+
}
195+
196+
return 0;
197+
#else /* !MULTIRING */
198+
return nm_ring_space(NETMAP_RXRING(nmd->nifp, 0));
199+
#endif /* !MULTIRING */
153200
}
154201

155202
static int

0 commit comments

Comments
 (0)