Skip to content

Commit 4656ba5

Browse files
committed
bugfix: some off-by-one corrections to sampling logic and pool counter.
1 parent f635995 commit 4656ba5

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

sflow/node.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,19 @@ VLIB_NODE_FN (sflow_node) (vlib_main_t * vm,
8484
uword thread_index = os_get_thread_index();
8585
sflow_per_thread_data_t *sfwk = vec_elt_at_index(smp->per_thread_data, thread_index);
8686

87+
/* note that sfwk->skip==1 means "take the next packet",
88+
so we never see sfwk->skip==0. */
89+
8790
u32 pkts = n_left_from;
88-
if(PREDICT_TRUE(sfwk->skip >= pkts)) {
91+
if(PREDICT_TRUE(sfwk->skip > pkts)) {
8992
/* skip the whole frame-vector */
9093
sfwk->skip -= pkts;
9194
sfwk->pool += pkts;
9295
}
9396
else {
94-
while(pkts > sfwk->skip) {
97+
while(pkts >= sfwk->skip) {
9598
/* reach in to get the one we want. */
96-
vlib_buffer_t *bN = vlib_get_buffer (vm, from[sfwk->skip]);
99+
vlib_buffer_t *bN = vlib_get_buffer (vm, from[sfwk->skip - 1]);
97100

98101
/* Sample this packet header. */
99102
u32 hdr = bN->current_length;
@@ -135,14 +138,18 @@ VLIB_NODE_FN (sflow_node) (vlib_main_t * vm,
135138
sfwk->pool += sfwk->skip;
136139
sfwk->skip = sflow_next_random_skip(sfwk);
137140
}
141+
/* We took a sample (or several) from this frame-vector, but now we are
142+
skipping the rest. */
143+
sfwk->skip -= pkts;
144+
sfwk->pool += pkts;
138145
}
139146

140147
/* the rest of this is boilerplate code just to make sure
141148
* that packets are passed on the same way as they would
142149
* have been if this node were not enabled.
143-
*
144-
* Not sure at all if this is right.
145-
* There has got to be an easier way?
150+
* TODO: If there is ever a way to do this in one step
151+
* (i.e. pass on the whole frame-vector unchanged) then it
152+
* might help performance.
146153
*/
147154

148155
next_index = node->cached_next_index;

sflow/sflow.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,12 @@ extern sflow_main_t sflow_main;
171171
extern vlib_node_registration_t sflow_node;
172172

173173
static inline u32 sflow_next_random_skip(sflow_per_thread_data_t *sfwk) {
174+
/* skip==1 means "take the next packet" so this
175+
fn must never return 0 */
174176
if(sfwk->smpN <= 1)
175177
return 1;
176-
return (random_u32(&sfwk->seed) % (2 * sfwk->smpN) - 1) + 1;
178+
u32 lim = (2 * sfwk->smpN) - 1;
179+
return (random_u32(&sfwk->seed) % lim) + 1;
177180
}
178181

179182
#endif /* __included_sflow_h__ */

0 commit comments

Comments
 (0)