summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2020-04-07 10:52:43 -0400
committerDave Wallace <dwallacelf@gmail.com>2020-04-13 15:02:30 +0000
commit7f094c2212cf906227ecb06e00f3082d886b32a0 (patch)
tree86d102165da82983f1a6db9d0e16152f72fd6091 /src
parente2568b5d0a5e34f02adda788e51ed0147644bec9 (diff)
l2: handle complete clone fail in l2_flood
vlib_buffer_clone(...) may not manage to produce any buffer clones at all. vlib_buffer_clone_256 should not smash the original buffer reference count if no clones are produced. Type: fix Signed-off-by: Dave Barach <dave@barachs.net> Change-Id: I14d9d53637a220485c7a0036cfc75a4149b264ea (cherry picked from commit 95e19253320ab07748787f4c8a7620704563f6b8)
Diffstat (limited to 'src')
-rw-r--r--src/vlib/buffer_funcs.h4
-rw-r--r--src/vnet/l2/l2_flood.c10
2 files changed, 10 insertions, 4 deletions
diff --git a/src/vlib/buffer_funcs.h b/src/vlib/buffer_funcs.h
index 288a36a0c9f..36ec0d1fa96 100644
--- a/src/vlib/buffer_funcs.h
+++ b/src/vlib/buffer_funcs.h
@@ -1147,11 +1147,11 @@ vlib_buffer_clone_256 (vlib_main_t * vm, u32 src_buffer, u32 * buffers,
d->next_buffer = src_buffer;
}
vlib_buffer_advance (s, head_end_offset);
- s->ref_count = n_buffers;
+ s->ref_count = n_buffers ? n_buffers : s->ref_count;
while (s->flags & VLIB_BUFFER_NEXT_PRESENT)
{
s = vlib_get_buffer (vm, s->next_buffer);
- s->ref_count = n_buffers;
+ s->ref_count = n_buffers ? n_buffers : s->ref_count;
}
return n_buffers;
diff --git a/src/vnet/l2/l2_flood.c b/src/vnet/l2/l2_flood.c
index 10e087767e4..b5eb5fe6381 100644
--- a/src/vnet/l2/l2_flood.c
+++ b/src/vnet/l2/l2_flood.c
@@ -230,6 +230,13 @@ VLIB_NODE_FN (l2flood_node) (vlib_main_t * vm,
if (PREDICT_FALSE (n_cloned != n_clones))
{
b0->error = node->errors[L2FLOOD_ERROR_REPL_FAIL];
+ /* Worst-case, no clones, consume the original buf */
+ if (n_cloned == 0)
+ {
+ ci0 = bi0;
+ member = msm->members[thread_index][0];
+ goto use_original_buffer;
+ }
}
/*
@@ -284,6 +291,7 @@ VLIB_NODE_FN (l2flood_node) (vlib_main_t * vm,
member = msm->members[thread_index][0];
}
+ use_original_buffer:
/*
* the last clone that might go to a BVI
*/
@@ -306,8 +314,6 @@ VLIB_NODE_FN (l2flood_node) (vlib_main_t * vm,
clib_memcpy_fast (t->src, h0->src_address, 6);
clib_memcpy_fast (t->dst, h0->dst_address, 6);
}
-
-
/* Forward packet to the current member */
if (PREDICT_FALSE (member->flags & L2_FLOOD_MEMBER_BVI))
{