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, <[EMAIL PROTECTED]>
+ *             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;

Reply via email to