diff options
author | Dave Barach <dave@barachs.net> | 2020-04-07 10:52:43 -0400 |
---|---|---|
committer | John Lo <loj@cisco.com> | 2020-04-07 22:14:26 +0000 |
commit | 95e19253320ab07748787f4c8a7620704563f6b8 (patch) | |
tree | 1b8f6b2805d561e43f9a5e5aa31a9a6db9353ef8 /src | |
parent | 85bee7548bc5a360851d92807dae6d4159b68314 (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
Diffstat (limited to 'src')
-rw-r--r-- | src/vlib/buffer_funcs.h | 4 | ||||
-rw-r--r-- | src/vnet/l2/l2_flood.c | 10 |
2 files changed, 10 insertions, 4 deletions
diff --git a/src/vlib/buffer_funcs.h b/src/vlib/buffer_funcs.h index 7103227a965..98ee2055833 100644 --- a/src/vlib/buffer_funcs.h +++ b/src/vlib/buffer_funcs.h @@ -1208,11 +1208,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)) { |