summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vnet/dpo/replicate_dpo.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/vnet/dpo/replicate_dpo.c b/src/vnet/dpo/replicate_dpo.c
index 8bad75ee5ed..c779516f3d4 100644
--- a/src/vnet/dpo/replicate_dpo.c
+++ b/src/vnet/dpo/replicate_dpo.c
@@ -664,6 +664,20 @@ replicate_inline (vlib_main_t * vm,
/* ship copies to the rest of the buckets */
for (bucket = 1; bucket < rep0->rep_n_buckets; bucket++)
{
+ /*
+ * After the enqueue of the first buffer, and of all subsequent
+ * buffers in this loop, it is possible that we over-flow the
+ * frame of the to-next node. When this happens we need to 'put'
+ * that full frame to the node and get a fresh empty one.
+ * Note that these are macros with side effects that change
+ * to_next & n_left_to_next
+ */
+ if (PREDICT_FALSE(0 == n_left_to_next))
+ {
+ vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+ vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+ }
+
/* Make a copy */
c0 = vlib_buffer_copy(vm, b0);
ci0 = vlib_get_buffer_index(vm, c0);
@@ -676,9 +690,9 @@ replicate_inline (vlib_main_t * vm,
next0 = dpo0->dpoi_next_node;
vnet_buffer (c0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
- if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
+ if (PREDICT_FALSE(c0->flags & VLIB_BUFFER_IS_TRACED))
{
- replicate_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
+ replicate_trace_t *t = vlib_add_trace (vm, node, c0, sizeof (*t));
t->rep_index = repi0;
t->dpo = *dpo0;
}