Hello!
I am glad to announce a patch for u32 to allow matches on nfmark. The patch is non intrusive (few lines).
Why I did this? Because fw classifier cannot be used together with u32. For example, now, you cannot match a mark of 0x90 and a destination port of 80. I know you can do it with iptables to do the marking, but if you use Jamal actions to apply mark to policed packets, you need this.
All stuff can be found at http://kernel.umbrella.ro/ also.
Dave, please consider adding this patch.
Stephen, if Dave accepts the patch, please apply the iproute2 patch. Thank you.
Signed-off-by: Catalin(ux aka Dino) BOIE <catab at umbrella.ro>
Thank you for you time. --- Catalin(ux aka Dino) BOIE catab at deuroconsult.ro http://kernel.umbrella.ro/
--- iproute2-2.6.9/tc/f_u32.c.orig 2004-11-04 15:38:53.000000000 +0200 +++ iproute2-2.6.9/tc/f_u32.c 2004-11-05 12:23:44.000000000 +0200 @@ -7,6 +7,7 @@ * 2 of the License, or (at your option) any later version. * * Authors: Alexey Kuznetsov, <kuznet@xxxxxxxxxxxxx> + * Match mark added by Catalin(ux aka Dino) BOIE <catab at umbrella.ro> [5 nov 2004] * */ @@ -33,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} } SAMPLE_ARGS\n"); + fprintf(stderr, " SAMPLE := { ip | ip6 | udp | tcp | icmp | u{32|16|8} | mark } SAMPLE_ARGS\n"); fprintf(stderr, " FILTERID := X:Y:Z\n"); } @@ -590,7 +591,27 @@ done: return res; } +static int parse_mark(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) +{ + int res = -1; + int argc = *argc_p; + char **argv = *argv_p; + + if (argc <= 0) + return -1; + if (get_u32(&res, *argv, 0)) { + fprintf(stderr, "Illegal \"mark\"\n"); + return -1; + } + NEXT_ARG(); + sel->mark = res; + res = 0; + + *argc_p = argc; + *argv_p = argv; + return res; +} static int parse_selector(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) { @@ -641,6 +662,12 @@ static int parse_selector(int *argc_p, c res = parse_icmp(&argc, &argv, sel); goto done; } + if (matches(*argv, "mark") == 0) { + NEXT_ARG(); + res = parse_mark(&argc, &argv, sel); + goto done; + } + return -1; done: @@ -969,6 +996,8 @@ static int u32_print_opt(struct filter_u struct tc_u32_key *key = sel->keys; if (show_stats && NULL != pf) fprintf(f, " (rule hit %llu success %llu)",pf->rcnt,pf->rhit); + if (sel->mark) + fprintf(f, " mark 0x%x", sel->mark); if (sel->nkeys) { for (i=0; i<sel->nkeys; i++, key++) { fprintf(f, "\n match %08x/%08x at %s%d", --- iproute2-2.6.9/include/linux/pkt_cls.h.orig 2004-11-04 15:42:27.000000000 +0200 +++ iproute2-2.6.9/include/linux/pkt_cls.h 2004-11-05 11:12:22.000000000 +0200 @@ -208,6 +208,7 @@ struct tc_u32_sel unsigned char flags; unsigned char offshift; unsigned char nkeys; + __u32 mark; __u16 offmask; __u16 off;
--- linux.orig/net/sched/cls_u32.c 2004-10-19 00:53:45.000000000 +0300 +++ linux/net/sched/cls_u32.c 2004-11-05 12:14:31.000000000 +0200 @@ -27,6 +27,7 @@ * JHS: We should remove the CONFIG_NET_CLS_IND from here * eventually when the meta match extension is made available * + * nfmark match added by Catalin(ux aka Dino) BOIE <catab at umbrella.ro> */ #include <asm/uaccess.h> @@ -139,6 +140,11 @@ next_knode: n->pf->rcnt +=1; j = 0; #endif + if ((n->sel.mark > 0) && (n->sel.mark != skb->nfmark)) { + n = n->next; + goto next_knode; + } + for (i = n->sel.nkeys; i>0; i--, key++) { if ((*(u32*)(ptr+key->off+(off2&key->offmask))^key->val)&key->mask) { --- linux.orig/include/linux/pkt_cls.h 2004-10-19 00:53:07.000000000 +0300 +++ linux/include/linux/pkt_cls.h 2004-11-05 11:00:27.000000000 +0200 @@ -208,6 +208,7 @@ struct tc_u32_sel unsigned char flags; unsigned char offshift; unsigned char nkeys; + u32 mark; __u16 offmask; __u16 off;