25
25
#include <assert.h>
26
26
#include <arpa/inet.h>
27
27
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
+
28
32
static int stop = 0 ;
29
33
static unsigned long long fwd = 0 ;
30
34
static unsigned long long tot = 0 ;
@@ -44,23 +48,6 @@ struct filtrule {
44
48
uint8_t pad ;
45
49
};
46
50
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
-
64
51
static inline int
65
52
pkt_select (const char * buf , struct filtrule * rules ,
66
53
int num_rules )
@@ -96,6 +83,7 @@ static void
96
83
forward_pkts (struct nm_desc * src , struct nm_desc * dst , struct filtrule * rules ,
97
84
int num_rules , int zerocopy )
98
85
{
86
+ #ifdef MULTIRING
99
87
unsigned int si = src -> first_rx_ring ;
100
88
unsigned int di = dst -> first_tx_ring ;
101
89
@@ -146,10 +134,69 @@ forward_pkts(struct nm_desc *src, struct nm_desc *dst, struct filtrule *rules,
146
134
ntx -- ;
147
135
fwd ++ ;
148
136
}
149
- /* Update state of netmap ring . */
137
+ /* Update the pointers in the netmap rings . */
150
138
rxring -> head = rxring -> cur = rxhead ;
151
139
txring -> head = txring -> cur = txhead ;
152
140
}
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 */
153
200
}
154
201
155
202
static int
0 commit comments