app/testpmd: support flow bit-field
Several rte_flow structures expose bit-fields that cannot be set in a generic fashion at byte level. Add bit-mask support to handle them. Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com> Acked-by: Olga Shern <olgas@mellanox.com>
This commit is contained in:
parent
d3f61b7bad
commit
00d78f550f
@ -136,6 +136,7 @@ struct arg {
|
||||
uint32_t sign:1; /**< Value is signed. */
|
||||
uint32_t offset; /**< Relative offset from ctx->object. */
|
||||
uint32_t size; /**< Field size. */
|
||||
const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */
|
||||
};
|
||||
|
||||
/** Parser token definition. */
|
||||
@ -195,6 +196,13 @@ struct token {
|
||||
.size = sizeof(((s *)0)->f), \
|
||||
})
|
||||
|
||||
/** Static initializer for ARGS() to target a bit-field. */
|
||||
#define ARGS_ENTRY_BF(s, f, b) \
|
||||
(&(const struct arg){ \
|
||||
.size = sizeof(s), \
|
||||
.mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \
|
||||
})
|
||||
|
||||
/** Static initializer for ARGS() to target a pointer. */
|
||||
#define ARGS_ENTRY_PTR(s, f) \
|
||||
(&(const struct arg){ \
|
||||
@ -623,6 +631,45 @@ push_args(struct context *ctx, const struct arg *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Spread value into buffer according to bit-mask. */
|
||||
static size_t
|
||||
arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg)
|
||||
{
|
||||
uint32_t i = arg->size;
|
||||
uint32_t end = 0;
|
||||
int sub = 1;
|
||||
int add = 0;
|
||||
size_t len = 0;
|
||||
|
||||
if (!arg->mask)
|
||||
return 0;
|
||||
#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
|
||||
if (!arg->hton) {
|
||||
i = 0;
|
||||
end = arg->size;
|
||||
sub = 0;
|
||||
add = 1;
|
||||
}
|
||||
#endif
|
||||
while (i != end) {
|
||||
unsigned int shift = 0;
|
||||
uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub);
|
||||
|
||||
for (shift = 0; arg->mask[i] >> shift; ++shift) {
|
||||
if (!(arg->mask[i] & (1 << shift)))
|
||||
continue;
|
||||
++len;
|
||||
if (!dst)
|
||||
continue;
|
||||
*buf &= ~(1 << shift);
|
||||
*buf |= (val & 1) << shift;
|
||||
val >>= 1;
|
||||
}
|
||||
i += add;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a prefix length and generate a bit-mask.
|
||||
*
|
||||
@ -649,6 +696,23 @@ parse_prefix(struct context *ctx, const struct token *token,
|
||||
u = strtoumax(str, &end, 0);
|
||||
if (errno || (size_t)(end - str) != len)
|
||||
goto error;
|
||||
if (arg->mask) {
|
||||
uintmax_t v = 0;
|
||||
|
||||
extra = arg_entry_bf_fill(NULL, 0, arg);
|
||||
if (u > extra)
|
||||
goto error;
|
||||
if (!ctx->object)
|
||||
return len;
|
||||
extra -= u;
|
||||
while (u--)
|
||||
(v <<= 1, v |= 1);
|
||||
v <<= extra;
|
||||
if (!arg_entry_bf_fill(ctx->object, v, arg) ||
|
||||
!arg_entry_bf_fill(ctx->objmask, -1, arg))
|
||||
goto error;
|
||||
return len;
|
||||
}
|
||||
bytes = u / 8;
|
||||
extra = u % 8;
|
||||
size = arg->size;
|
||||
@ -1072,6 +1136,12 @@ parse_int(struct context *ctx, const struct token *token,
|
||||
goto error;
|
||||
if (!ctx->object)
|
||||
return len;
|
||||
if (arg->mask) {
|
||||
if (!arg_entry_bf_fill(ctx->object, u, arg) ||
|
||||
!arg_entry_bf_fill(ctx->objmask, -1, arg))
|
||||
goto error;
|
||||
return len;
|
||||
}
|
||||
buf = (uint8_t *)ctx->object + arg->offset;
|
||||
size = arg->size;
|
||||
objmask:
|
||||
|
Loading…
Reference in New Issue
Block a user