vserver 1.9.5.x5
[linux-2.6.git] / net / sched / sch_dsmark.c
index 28b61f0..8a3db9d 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/rtnetlink.h>
 #include <net/pkt_sched.h>
 #include <net/dsfield.h>
+#include <net/inet_ecn.h>
 #include <asm/byteorder.h>
 
 
@@ -124,8 +125,7 @@ static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent,
            "arg 0x%lx\n",sch,p,classid,parent,*arg);
        if (*arg > p->indices)
                return -ENOENT;
-       if (!opt || rtattr_parse(tb, TCA_DSMARK_MAX, RTA_DATA(opt),
-                                RTA_PAYLOAD(opt)))
+       if (!opt || rtattr_parse_nested(tb, TCA_DSMARK_MAX, opt))
                return -EINVAL;
        if (tb[TCA_DSMARK_MASK-1]) {
                if (!RTA_PAYLOAD(tb[TCA_DSMARK_MASK-1]))
@@ -198,10 +198,12 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
                /* FIXME: Safe with non-linear skbs? --RR */
                switch (skb->protocol) {
                        case __constant_htons(ETH_P_IP):
-                               skb->tc_index = ipv4_get_dsfield(skb->nh.iph);
+                               skb->tc_index = ipv4_get_dsfield(skb->nh.iph)
+                                       & ~INET_ECN_MASK;
                                break;
                        case __constant_htons(ETH_P_IPV6):
-                               skb->tc_index = ipv6_get_dsfield(skb->nh.ipv6h);
+                               skb->tc_index = ipv6_get_dsfield(skb->nh.ipv6h)
+                                       & ~INET_ECN_MASK;
                                break;
                        default:
                                skb->tc_index = 0;
@@ -241,11 +243,11 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
 #endif
 
            ((ret = p->q->enqueue(skb,p->q)) != 0)) {
-               sch->stats.drops++;
+               sch->qstats.drops++;
                return ret;
        }
-       sch->stats.bytes += skb->len;
-       sch->stats.packets++;
+       sch->bstats.bytes += skb->len;
+       sch->bstats.packets++;
        sch->q.qlen++;
        return ret;
 }
@@ -297,9 +299,10 @@ static int dsmark_requeue(struct sk_buff *skb,struct Qdisc *sch)
        D2PRINTK("dsmark_requeue(skb %p,sch %p,[qdisc %p])\n",skb,sch,p);
         if ((ret = p->q->ops->requeue(skb, p->q)) == 0) {
                sch->q.qlen++;
+               sch->qstats.requeues++;
                return 0;
        }
-       sch->stats.drops++;
+       sch->qstats.drops++;
        return ret;
 }
 
@@ -319,7 +322,7 @@ static unsigned int dsmark_drop(struct Qdisc *sch)
 }
 
 
-int dsmark_init(struct Qdisc *sch,struct rtattr *opt)
+static int dsmark_init(struct Qdisc *sch,struct rtattr *opt)
 {
        struct dsmark_qdisc_data *p = PRIV(sch);
        struct rtattr *tb[TCA_DSMARK_MAX];