[dpdk-dev] [PATCH v5 16/26] app/testpmd: add rte_flow bit-field support
Adrien Mazarguil
adrien.mazarguil at 6wind.com
Wed Dec 21 15:51:32 CET 2016
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 at 6wind.com>
Acked-by: Olga Shern <olgas at mellanox.com>
---
app/test-pmd/cmdline_flow.c | 70 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 9a6f37d..fc4d824 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -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:
--
2.1.4
More information about the dev
mailing list