"Usage: ... flow ...\n"
"\n"
" [mapping mode]: map key KEY [ OPS ] ...\n"
-" [hashing mode]: hash keys KEY-LIST ...\n"
+" [hashing mode]: hash keys KEY-LIST ... [ perturb SECS ]\n"
"\n"
" [ divisor NUM ] [ baseclass ID ] [ match EMATCH_TREE ]\n"
" [ police POLICE_SPEC ] [ action ACTION_SPEC ]\n"
"KEY := [ src | dst | proto | proto-src | proto-dst | iif | priority | \n"
" mark | nfct | nfct-src | nfct-dst | nfct-proto-src | \n"
" nfct-proto-dst | rt-classid | sk-uid | sk-gid |\n"
-" vlan-tag ]\n"
+" vlan-tag | rxhash ]\n"
"OPS := [ or NUM | and NUM | xor NUM | rshift NUM | addend NUM ]\n"
"ID := X:Y\n"
);
[FLOW_KEY_SKUID] = "sk-uid",
[FLOW_KEY_SKGID] = "sk-gid",
[FLOW_KEY_VLAN_TAG] = "vlan-tag",
+ [FLOW_KEY_RXHASH] = "rxhash",
};
static int flow_parse_keys(__u32 *keys, __u32 *nkeys, char *argv)
return -1;
}
addattr32(n, 4096, TCA_FLOW_BASECLASS, tmp);
+ } else if (matches(*argv, "perturb") == 0) {
+ NEXT_ARG();
+ if (get_u32(&tmp, *argv, 0)) {
+ fprintf(stderr, "Illegal \"perturb\"\n");
+ return -1;
+ }
+ addattr32(n, 4096, TCA_FLOW_PERTURB, tmp);
} else if (matches(*argv, "police") == 0) {
NEXT_ARG();
if (parse_police(&argc, &argv, TCA_FLOW_POLICE, n)) {
fprintf(f, "handle 0x%x ", handle);
if (tb[TCA_FLOW_MODE]) {
- __u32 mode = *(__u32 *)RTA_DATA(tb[TCA_FLOW_MODE]);
+ __u32 mode = rta_getattr_u32(tb[TCA_FLOW_MODE]);
switch (mode) {
case FLOW_MODE_MAP:
}
if (tb[TCA_FLOW_KEYS]) {
- __u32 keymask = *(__u32 *)RTA_DATA(tb[TCA_FLOW_KEYS]);
+ __u32 keymask = rta_getattr_u32(tb[TCA_FLOW_KEYS]);
char *sep = "";
fprintf(f, "keys ");
}
if (tb[TCA_FLOW_MASK])
- mask = *(__u32 *)RTA_DATA(tb[TCA_FLOW_MASK]);
+ mask = rta_getattr_u32(tb[TCA_FLOW_MASK]);
if (tb[TCA_FLOW_XOR])
- val = *(__u32 *)RTA_DATA(tb[TCA_FLOW_XOR]);
+ val = rta_getattr_u32(tb[TCA_FLOW_XOR]);
if (mask != ~0 || val != 0) {
__u32 or = (mask & val) ^ val;
if (tb[TCA_FLOW_RSHIFT])
fprintf(f, "rshift %u ",
- *(__u32 *)RTA_DATA(tb[TCA_FLOW_RSHIFT]));
+ rta_getattr_u32(tb[TCA_FLOW_RSHIFT]));
if (tb[TCA_FLOW_ADDEND])
fprintf(f, "addend 0x%x ",
- *(__u32 *)RTA_DATA(tb[TCA_FLOW_ADDEND]));
+ rta_getattr_u32(tb[TCA_FLOW_ADDEND]));
if (tb[TCA_FLOW_DIVISOR])
fprintf(f, "divisor %u ",
- *(__u32 *)RTA_DATA(tb[TCA_FLOW_DIVISOR]));
+ rta_getattr_u32(tb[TCA_FLOW_DIVISOR]));
if (tb[TCA_FLOW_BASECLASS])
fprintf(f, "baseclass %s ",
- sprint_tc_classid(*(__u32 *)RTA_DATA(tb[TCA_FLOW_BASECLASS]), b1));
+ sprint_tc_classid(rta_getattr_u32(tb[TCA_FLOW_BASECLASS]), b1));
+
+ if (tb[TCA_FLOW_PERTURB])
+ fprintf(f, "perturb %usec ",
+ rta_getattr_u32(tb[TCA_FLOW_PERTURB]));
if (tb[TCA_FLOW_EMATCHES])
print_ematch(f, tb[TCA_FLOW_EMATCHES]);