@@ -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 ;
0 commit comments