From 7b1ce8e2a08454839c52b8cc02fdde5c78e7c40e Mon Sep 17 00:00:00 2001 From: Ales Musil Date: Thu, 12 Dec 2024 12:09:45 +0100 Subject: [PATCH] ofpbuf: Add helper method to truncate the buffer. Add helper to truncate the buffer to certain size which might be useful if some earlier part of the buffer can be reused multiple times without copying the whole buffer. Signed-off-by: Ales Musil Signed-off-by: Ilya Maximets --- include/openvswitch/ofpbuf.h | 7 +++++++ lib/ofp-actions.c | 2 +- tests/test-ofpbuf.c | 10 ++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/openvswitch/ofpbuf.h b/include/openvswitch/ofpbuf.h index 1fc4a3a7f87..0dfa51ecb3e 100644 --- a/include/openvswitch/ofpbuf.h +++ b/include/openvswitch/ofpbuf.h @@ -292,6 +292,13 @@ static inline bool ofpbuf_oversized(const struct ofpbuf *ofpacts) return (char *)ofpbuf_tail(ofpacts) - (char *)ofpacts->header > UINT16_MAX; } +/* Truncates the buffer to 'new_size' bytes from the tail end of 'b'. */ +static inline void ofpbuf_truncate(struct ofpbuf *b, size_t new_size) +{ + ovs_assert(b->size >= new_size); + b->size = new_size; +} + #ifdef __cplusplus } #endif diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index 8a05f7c9c82..102abbc2397 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -9674,7 +9674,7 @@ ofpacts_parse(char *str, const struct ofpact_parse_params *pp, uint32_t orig_size = pp->ofpacts->size; char *error = ofpacts_parse__(str, pp, allow_instructions, outer_action); if (error) { - pp->ofpacts->size = orig_size; + ofpbuf_truncate(pp->ofpacts, orig_size); } CONST_CAST(struct ofpact_parse_params *, pp)->depth--; return error; diff --git a/tests/test-ofpbuf.c b/tests/test-ofpbuf.c index 3d7fab90ff6..296d308a784 100644 --- a/tests/test-ofpbuf.c +++ b/tests/test-ofpbuf.c @@ -24,6 +24,7 @@ #define BUF_SIZE 100 #define HDR_OFS 10 #define MSG_OFS 50 +#define DATA_SIZE 16 static void test_ofpbuf_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) @@ -59,6 +60,15 @@ test_ofpbuf_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) ovs_assert(buf->header == (char *) buf->base + BUF_SIZE + HDR_OFS); ovs_assert(buf->msg == (char *) buf->base + BUF_SIZE + MSG_OFS); + size_t prev_size = buf->size; + ofpbuf_put_uninit(buf, DATA_SIZE); + ofpbuf_truncate(buf, prev_size); + /* Check that everything else is unchanged after truncate. */ + ovs_assert(!buf->size); + ovs_assert((char *) buf->base + BUF_SIZE == buf->data); + ovs_assert(buf->header == (char *) buf->base + BUF_SIZE + HDR_OFS); + ovs_assert(buf->msg == (char *) buf->base + BUF_SIZE + MSG_OFS); + ofpbuf_delete(buf); exit(exit_code); }