git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
sch_dsmark: fix invalid skb_cow() usage
[pandora-kernel.git]
/
net
/
sched
/
sch_dsmark.c
diff --git
a/net/sched/sch_dsmark.c
b/net/sched/sch_dsmark.c
index
0f7bf3f
..
fb24bb4
100644
(file)
--- a/
net/sched/sch_dsmark.c
+++ b/
net/sched/sch_dsmark.c
@@
-137,10
+137,10
@@
static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent,
mask = nla_get_u8(tb[TCA_DSMARK_MASK]);
if (tb[TCA_DSMARK_VALUE])
mask = nla_get_u8(tb[TCA_DSMARK_MASK]);
if (tb[TCA_DSMARK_VALUE])
- p->value[*arg
-
1] = nla_get_u8(tb[TCA_DSMARK_VALUE]);
+ p->value[*arg
-
1] = nla_get_u8(tb[TCA_DSMARK_VALUE]);
if (tb[TCA_DSMARK_MASK])
if (tb[TCA_DSMARK_MASK])
- p->mask[*arg
-
1] = mask;
+ p->mask[*arg
-
1] = mask;
err = 0;
err = 0;
@@
-155,8
+155,8
@@
static int dsmark_delete(struct Qdisc *sch, unsigned long arg)
if (!dsmark_valid_index(p, arg))
return -EINVAL;
if (!dsmark_valid_index(p, arg))
return -EINVAL;
- p->mask[arg
-
1] = 0xff;
- p->value[arg
-
1] = 0;
+ p->mask[arg
-
1] = 0xff;
+ p->value[arg
-
1] = 0;
return 0;
}
return 0;
}
@@
-175,7
+175,7
@@
static void dsmark_walk(struct Qdisc *sch, struct qdisc_walker *walker)
if (p->mask[i] == 0xff && !p->value[i])
goto ignore;
if (walker->count >= walker->skip) {
if (p->mask[i] == 0xff && !p->value[i])
goto ignore;
if (walker->count >= walker->skip) {
- if (walker->fn(sch, i
+
1, walker) < 0) {
+ if (walker->fn(sch, i
+
1, walker) < 0) {
walker->stop = 1;
break;
}
walker->stop = 1;
break;
}
@@
-202,9
+202,13
@@
static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
pr_debug("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
if (p->set_tc_index) {
pr_debug("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
if (p->set_tc_index) {
+ int wlen = skb_network_offset(skb);
+
switch (skb->protocol) {
case htons(ETH_P_IP):
switch (skb->protocol) {
case htons(ETH_P_IP):
- if (skb_cow_head(skb, sizeof(struct iphdr)))
+ wlen += sizeof(struct iphdr);
+ if (!pskb_may_pull(skb, wlen) ||
+ skb_try_make_writable(skb, wlen))
goto drop;
skb->tc_index = ipv4_get_dsfield(ip_hdr(skb))
goto drop;
skb->tc_index = ipv4_get_dsfield(ip_hdr(skb))
@@
-212,7
+216,9
@@
static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
break;
case htons(ETH_P_IPV6):
break;
case htons(ETH_P_IPV6):
- if (skb_cow_head(skb, sizeof(struct ipv6hdr)))
+ wlen += sizeof(struct ipv6hdr);
+ if (!pskb_may_pull(skb, wlen) ||
+ skb_try_make_writable(skb, wlen))
goto drop;
skb->tc_index = ipv6_get_dsfield(ipv6_hdr(skb))
goto drop;
skb->tc_index = ipv6_get_dsfield(ipv6_hdr(skb))
@@
-260,6
+266,7
@@
static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
return err;
}
return err;
}
+ sch->qstats.backlog += qdisc_pkt_len(skb);
sch->q.qlen++;
return NET_XMIT_SUCCESS;
sch->q.qlen++;
return NET_XMIT_SUCCESS;
@@
-283,6
+290,7
@@
static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
return NULL;
qdisc_bstats_update(sch, skb);
return NULL;
qdisc_bstats_update(sch, skb);
+ sch->qstats.backlog -= qdisc_pkt_len(skb);
sch->q.qlen--;
index = skb->tc_index & (p->indices - 1);
sch->q.qlen--;
index = skb->tc_index & (p->indices - 1);
@@
-304,9
+312,8
@@
static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
* and don't need yet another qdisc as a bypass.
*/
if (p->mask[index] != 0xff || p->value[index])
* and don't need yet another qdisc as a bypass.
*/
if (p->mask[index] != 0xff || p->value[index])
- printk(KERN_WARNING
- "dsmark_dequeue: unsupported protocol %d\n",
- ntohs(skb->protocol));
+ pr_warning("dsmark_dequeue: unsupported protocol %d\n",
+ ntohs(skb->protocol));
break;
}
break;
}
@@
-399,6
+406,7
@@
static void dsmark_reset(struct Qdisc *sch)
pr_debug("dsmark_reset(sch %p,[qdisc %p])\n", sch, p);
qdisc_reset(p->q);
pr_debug("dsmark_reset(sch %p,[qdisc %p])\n", sch, p);
qdisc_reset(p->q);
+ sch->qstats.backlog = 0;
sch->q.qlen = 0;
}
sch->q.qlen = 0;
}
@@
-424,14
+432,14
@@
static int dsmark_dump_class(struct Qdisc *sch, unsigned long cl,
if (!dsmark_valid_index(p, cl))
return -EINVAL;
if (!dsmark_valid_index(p, cl))
return -EINVAL;
- tcm->tcm_handle = TC_H_MAKE(TC_H_MAJ(sch->handle), cl
-
1);
+ tcm->tcm_handle = TC_H_MAKE(TC_H_MAJ(sch->handle), cl
-
1);
tcm->tcm_info = p->q->handle;
opts = nla_nest_start(skb, TCA_OPTIONS);
if (opts == NULL)
goto nla_put_failure;
tcm->tcm_info = p->q->handle;
opts = nla_nest_start(skb, TCA_OPTIONS);
if (opts == NULL)
goto nla_put_failure;
- NLA_PUT_U8(skb, TCA_DSMARK_MASK, p->mask[cl
-
1]);
- NLA_PUT_U8(skb, TCA_DSMARK_VALUE, p->value[cl
-
1]);
+ NLA_PUT_U8(skb, TCA_DSMARK_MASK, p->mask[cl
-
1]);
+ NLA_PUT_U8(skb, TCA_DSMARK_VALUE, p->value[cl
-
1]);
return nla_nest_end(skb, opts);
return nla_nest_end(skb, opts);