[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240209170714.370259-1-stephen@networkplumber.org>
Date: Fri, 9 Feb 2024 09:06:17 -0800
From: Stephen Hemminger <stephen@...workplumber.org>
To: netdev@...r.kernel.org
Cc: Stephen Hemminger <stephen@...workplumber.org>
Subject: [RFC iproute2] tc/u32: use standard flexible array
The code to parse selectors was depending on C extension to implement
the array of keys. This would cause warnings if built with clang.
Instead use ISO C99 flexible array.
Also the maximum number of keys was hardcoded already in two places.
Signed-off-by: Stephen Hemminger <stephen@...workplumber.org>
---
tc/f_u32.c | 46 +++++++++++++++++++++++++++-------------------
1 file changed, 27 insertions(+), 19 deletions(-)
diff --git a/tc/f_u32.c b/tc/f_u32.c
index 913ec1de435d..a6e699d53d24 100644
--- a/tc/f_u32.c
+++ b/tc/f_u32.c
@@ -21,6 +21,8 @@
#include "utils.h"
#include "tc_util.h"
+#define SEL_MAX_KEYS 128
+
static void explain(void)
{
fprintf(stderr,
@@ -129,7 +131,7 @@ static int pack_key(struct tc_u32_sel *sel, __u32 key, __u32 mask,
}
}
- if (hwm >= 128)
+ if (hwm >= SEL_MAX_KEYS)
return -1;
if (off % 4)
return -1;
@@ -1017,10 +1019,7 @@ static __u32 u32_hash_fold(struct tc_u32_key *key)
static int u32_parse_opt(struct filter_util *qu, char *handle,
int argc, char **argv, struct nlmsghdr *n)
{
- struct {
- struct tc_u32_sel sel;
- struct tc_u32_key keys[128];
- } sel = {};
+ struct tc_u32_sel *sel;
struct tcmsg *t = NLMSG_DATA(n);
struct rtattr *tail;
int sel_ok = 0, terminal_ok = 0;
@@ -1037,12 +1036,18 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
if (argc == 0)
return 0;
+ sel = alloca(sizeof(*sel) + SEL_MAX_KEYS * sizeof(struct tc_u32_key));
+ if (sel == NULL)
+ return -1;
+
+ memset(sel, 0, sizeof(*sel) + SEL_MAX_KEYS * sizeof(struct tc_u32_key));
+
tail = addattr_nest(n, MAX_MSG, TCA_OPTIONS);
while (argc > 0) {
if (matches(*argv, "match") == 0) {
NEXT_ARG();
- if (parse_selector(&argc, &argv, &sel.sel, n)) {
+ if (parse_selector(&argc, &argv, sel, n)) {
fprintf(stderr, "Illegal \"match\"\n");
return -1;
}
@@ -1050,14 +1055,14 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
continue;
} else if (matches(*argv, "offset") == 0) {
NEXT_ARG();
- if (parse_offset(&argc, &argv, &sel.sel)) {
+ if (parse_offset(&argc, &argv, sel)) {
fprintf(stderr, "Illegal \"offset\"\n");
return -1;
}
continue;
} else if (matches(*argv, "hashkey") == 0) {
NEXT_ARG();
- if (parse_hashkey(&argc, &argv, &sel.sel)) {
+ if (parse_hashkey(&argc, &argv, sel)) {
fprintf(stderr, "Illegal \"hashkey\"\n");
return -1;
}
@@ -1072,7 +1077,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
return -1;
}
addattr_l(n, MAX_MSG, TCA_U32_CLASSID, &flowid, 4);
- sel.sel.flags |= TC_U32_TERMINAL;
+ sel->flags |= TC_U32_TERMINAL;
} else if (matches(*argv, "divisor") == 0) {
unsigned int divisor;
@@ -1122,17 +1127,21 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
} else if (strcmp(*argv, "sample") == 0) {
__u32 hash;
unsigned int divisor = 0x100;
- struct {
- struct tc_u32_sel sel;
- struct tc_u32_key keys[4];
- } sel2 = {};
+ struct tc_u32_sel *sel2;
NEXT_ARG();
- if (parse_selector(&argc, &argv, &sel2.sel, n)) {
+
+ sel2 = alloca(sizeof(*sel) + 4 * sizeof(struct tc_u32_key));
+ if (sel2 == NULL)
+ return -1;
+
+ memset(sel2, 0, sizeof(*sel2));
+
+ if (parse_selector(&argc, &argv, sel2, n)) {
fprintf(stderr, "Illegal \"sample\"\n");
return -1;
}
- if (sel2.sel.nkeys != 1) {
+ if (sel2->nkeys != 1) {
fprintf(stderr, "\"sample\" must contain exactly ONE key.\n");
return -1;
}
@@ -1146,7 +1155,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
}
NEXT_ARG();
}
- hash = u32_hash_fold(&sel2.keys[0]);
+ hash = u32_hash_fold(&sel2->keys[0]);
htid = ((hash % divisor) << 12) | (htid & 0xFFF00000);
sample_ok = 1;
continue;
@@ -1197,7 +1206,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
/* We don't necessarily need class/flowids */
if (terminal_ok)
- sel.sel.flags |= TC_U32_TERMINAL;
+ sel->flags |= TC_U32_TERMINAL;
if (order) {
if (TC_U32_NODE(t->tcm_handle) &&
@@ -1212,8 +1221,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
addattr_l(n, MAX_MSG, TCA_U32_HASH, &htid, 4);
if (sel_ok)
addattr_l(n, MAX_MSG, TCA_U32_SEL, &sel,
- sizeof(sel.sel) +
- sel.sel.nkeys * sizeof(struct tc_u32_key));
+ sizeof(*sel) + sel->nkeys * sizeof(struct tc_u32_key));
if (flags) {
if (!(flags ^ (TCA_CLS_FLAGS_SKIP_HW |
TCA_CLS_FLAGS_SKIP_SW))) {
--
2.43.0
Powered by blists - more mailing lists