X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=tc%2Ff_u32.c;fp=tc%2Ff_u32.c;h=9d527fc0744ca4e4f2fca62bebf043d0beb51338;hb=fcabec0aee42af28e2846ef3674ed7ba7be72c42;hp=50dc4dfdcadcebb5ac74e0fbdb324d261910cd4b;hpb=cb820e861caa85bb3942ab0c673e04b9408be0ad;p=iproute2.git diff --git a/tc/f_u32.c b/tc/f_u32.c index 50dc4df..9d527fc 100644 --- a/tc/f_u32.c +++ b/tc/f_u32.c @@ -34,7 +34,7 @@ static void explain(void) fprintf(stderr, "or u32 divisor DIVISOR\n"); fprintf(stderr, "\n"); fprintf(stderr, "Where: SELECTOR := SAMPLE SAMPLE ...\n"); - fprintf(stderr, " SAMPLE := { ip | ip6 | udp | tcp | icmp | u{32|16|8} | mark } SAMPLE_ARGS\n"); + fprintf(stderr, " SAMPLE := { ip | ip6 | udp | tcp | icmp | u{32|16|8} | mark } SAMPLE_ARGS [divisor DIVISOR]\n"); fprintf(stderr, " FILTERID := X:Y:Z\n"); } @@ -495,7 +495,7 @@ static int parse_ip6(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) } if (strcmp(*argv, "priority") == 0) { NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 0, 0); + res = parse_u8(&argc, &argv, sel, 4, 0); goto done; } if (strcmp(*argv, "protocol") == 0) { @@ -833,8 +833,9 @@ static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char ** } else if (matches(*argv, "divisor") == 0) { unsigned divisor; NEXT_ARG(); - if (get_unsigned(&divisor, *argv, 0) || divisor == 0 || - divisor > 0x100) { + if (get_unsigned(&divisor, *argv, 0) || + divisor == 0 || + divisor > 0x100 || ((divisor - 1) & divisor)) { fprintf(stderr, "Illegal \"divisor\"\n"); return -1; } @@ -874,10 +875,13 @@ static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char ** htid = (handle&0xFFFFF000); } else if (strcmp(*argv, "sample") == 0) { __u32 hash; + unsigned divisor = 0x100; + struct { struct tc_u32_sel sel; struct tc_u32_key keys[4]; } sel2; + memset(&sel2, 0, sizeof(sel2)); NEXT_ARG(); if (parse_selector(&argc, &argv, &sel2.sel, n)) { fprintf(stderr, "Illegal \"sample\"\n"); @@ -887,10 +891,19 @@ static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char ** fprintf(stderr, "\"sample\" must contain exactly ONE key.\n"); return -1; } + if (*argv != 0 && strcmp(*argv, "divisor") == 0) { + NEXT_ARG(); + if (get_unsigned(&divisor, *argv, 0) || divisor == 0 || + divisor > 0x100 || ((divisor - 1) & divisor)) { + fprintf(stderr, "Illegal sample \"divisor\"\n"); + return -1; + } + NEXT_ARG(); + } hash = sel2.sel.keys[0].val&sel2.sel.keys[0].mask; hash ^= hash>>16; hash ^= hash>>8; - htid = ((hash<<12)&0xFF000)|(htid&0xFFF00000); + htid = ((hash%divisor)<<12)|(htid&0xFFF00000); sample_ok = 1; continue; } else if (strcmp(*argv, "indev") == 0) {