[ovs-dev,RFC,v3,2/4] lib/tc: fix 32 bits shift for pedit offset calculation

Message ID 1548678550-6661-3-git-send-email-pieter.jansenvanvuuren@netronome.com
State Accepted
Delegated to: Simon Horman
Headers show
  • extend ovs-tc offload for more pedit action
Related show

Commit Message

Pieter Jansen van Vuuren Jan. 28, 2019, 12:29 p.m.
pedit allows setting entire words with an optional mask and OVS
makes use of such masks to allow setting fields that do not span
entire words. One mask for leading bytes that should not be
updated and another mask for trailing bytes that should not be
updated. The masks are created using bit shifts.

In the case of the mask to omit trailing bytes a right bit shift
is used. Currently the code can produce shifts of 1, 2, 3 or 4
bytes (8, 16, 24 or 32 bits) based on the alignment of the end
of field being set.

However, a shift of 32 bits on a 32bit value is undefined.
As it stands the code relies on the result of UINT32_MAX >> 32
being UINT32_MAX. Or in other words a mask that results in the
pedit action setting all bytes of the word under operation.

This patch adjusts the code to use a shift of 0 for this case,
which gives the same result as the undefined behaviour that was
relied on, and appears logically correct as the desire is for no
trailing bytes (or bits!) to be omitted from the set action.

Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
 lib/tc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


diff --git a/lib/tc.c b/lib/tc.c
index ae5017c17..953fffd01 100644
--- a/lib/tc.c
+++ b/lib/tc.c
@@ -1737,7 +1737,7 @@  calc_offsets(struct tc_flower *flower, struct flower_key_to_pedit *m,
     start_offset = ROUND_DOWN(m->offset, 4);
     diff = m->offset - start_offset;
     total_size = max_offset - start_offset;
-    right_zero_bits = 8 * (4 - (max_offset % 4));
+    right_zero_bits = 8 * (4 - ((max_offset % 4) ? : 4));
     left_zero_bits = 8 * (m->offset - start_offset);
     *cur_offset = start_offset;