path: root/include
diff options
authorPablo Neira Ayuso <>2015-12-05 20:04:21 +0100
committerPablo Neira Ayuso <>2015-12-14 20:32:55 +0100
commit4a9a38727957731e56b5302960da5ef1e0275d61 (patch)
treeb3d3c546cc6db893866c8d4707861dd06c2a8963 /include
parent210f479bff5b6cf8483383aa27ad9ded3925326c (diff)
src: fix sub-byte protocol header definitions
Update bitfield definitions to match according to the way they are expressed in RFC and IEEE specifications. This required a bit of update for c3f0501 ("src: netlink_linearize: handle sub-byte lengths"). >From the linearize step, to calculate the shift based on the bitfield offset, we need to obtain the length of the word in bytes: len = round_up(expr->len, BITS_PER_BYTE); Then, we substract the offset bits and the bitfield length. shift = len - (offset + expr->len); From the delinearize, payload_expr_trim() needs to obtain the real offset through: off = round_up(mask->len, BITS_PER_BYTE) - mask_len; For vlan id (offset 12), this gets the position of the last bit set in the mask (ie. 12), then we substract the length we fetch in bytes (16), so we obtain the real bitfield offset (4). Then, we add that to the original payload offset that was expressed in bytes: payload_offset += off; Note that payload_expr_trim() now also adjusts the payload expression to its real length and offset so we don't need to propagate the mask expression. Reported-by: Patrick McHardy <> Signed-off-by: Pablo Neira Ayuso <>
Diffstat (limited to 'include')
3 files changed, 4 insertions, 4 deletions
diff --git a/include/payload.h b/include/payload.h
index ca9b0138..9192d6e5 100644
--- a/include/payload.h
+++ b/include/payload.h
@@ -20,9 +20,8 @@ extern struct expr *payload_expr_join(const struct expr *e1,
const struct expr *e2);
bool payload_expr_trim(struct expr *expr, struct expr *mask,
- const struct proto_ctx *ctx);
+ const struct proto_ctx *ctx, unsigned int *shift);
extern void payload_expr_expand(struct list_head *list, struct expr *expr,
- struct expr *mask,
const struct proto_ctx *ctx);
extern void payload_expr_complete(struct expr *expr,
const struct proto_ctx *ctx);
diff --git a/include/proto.h b/include/proto.h
index 974116f1..d90bccd0 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -159,9 +159,9 @@ enum eth_hdr_fields {
enum vlan_hdr_fields {
diff --git a/include/utils.h b/include/utils.h
index e94ae81a..8a1dc5ef 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -69,6 +69,7 @@
#define field_sizeof(t, f) (sizeof(((t *)NULL)->f))
#define array_size(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
#define div_round_up(n, d) (((n) + (d) - 1) / (d))
+#define round_up(n, b) (div_round_up(n, b) * b)
#define min(x, y) ({ \
typeof(x) _min1 = (x); \