diff options
author | Patrick McHardy <kaber@trash.net> | 2007-07-30 20:07:14 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-31 05:28:18 -0400 |
commit | bdba91ec70fb5ccbdeb1c7068319adc6ea9e1a7d (patch) | |
tree | a5897654a7a6ef6338ea15bab7d11b2315b4f19e | |
parent | 20283d84c7d922ca225b20db651d9a062716e8e3 (diff) |
[NET_SCHED]: Fix prio/ingress classification logic error
Fix handling of empty or completely non-matching filter chains. In
that case -1 is returned and tcf_result is uninitialized, the
qdisc should fall back to default classification in that case.
Noticed by PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com>.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/sched/sch_ingress.c | 3 | ||||
-rw-r--r-- | net/sched/sch_prio.c | 7 |
2 files changed, 4 insertions, 6 deletions
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c index 51f16b0af198..2d32fd27496e 100644 --- a/net/sched/sch_ingress.c +++ b/net/sched/sch_ingress.c | |||
@@ -158,9 +158,8 @@ static int ingress_enqueue(struct sk_buff *skb,struct Qdisc *sch) | |||
158 | break; | 158 | break; |
159 | case TC_ACT_RECLASSIFY: | 159 | case TC_ACT_RECLASSIFY: |
160 | case TC_ACT_OK: | 160 | case TC_ACT_OK: |
161 | case TC_ACT_UNSPEC: | ||
162 | default: | ||
163 | skb->tc_index = TC_H_MIN(res.classid); | 161 | skb->tc_index = TC_H_MIN(res.classid); |
162 | default: | ||
164 | result = TC_ACT_OK; | 163 | result = TC_ACT_OK; |
165 | break; | 164 | break; |
166 | } | 165 | } |
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 2d8c08493d6e..71bafde353a6 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c | |||
@@ -38,9 +38,11 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) | |||
38 | struct prio_sched_data *q = qdisc_priv(sch); | 38 | struct prio_sched_data *q = qdisc_priv(sch); |
39 | u32 band = skb->priority; | 39 | u32 band = skb->priority; |
40 | struct tcf_result res; | 40 | struct tcf_result res; |
41 | int err; | ||
41 | 42 | ||
42 | *qerr = NET_XMIT_BYPASS; | 43 | *qerr = NET_XMIT_BYPASS; |
43 | if (TC_H_MAJ(skb->priority) != sch->handle) { | 44 | if (TC_H_MAJ(skb->priority) != sch->handle) { |
45 | err = tc_classify(skb, q->filter_list, &res); | ||
44 | #ifdef CONFIG_NET_CLS_ACT | 46 | #ifdef CONFIG_NET_CLS_ACT |
45 | switch (tc_classify(skb, q->filter_list, &res)) { | 47 | switch (tc_classify(skb, q->filter_list, &res)) { |
46 | case TC_ACT_STOLEN: | 48 | case TC_ACT_STOLEN: |
@@ -49,11 +51,8 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) | |||
49 | case TC_ACT_SHOT: | 51 | case TC_ACT_SHOT: |
50 | return NULL; | 52 | return NULL; |
51 | } | 53 | } |
52 | |||
53 | if (!q->filter_list ) { | ||
54 | #else | ||
55 | if (!q->filter_list || tc_classify(skb, q->filter_list, &res)) { | ||
56 | #endif | 54 | #endif |
55 | if (!q->filter_list || err < 0) { | ||
57 | if (TC_H_MAJ(band)) | 56 | if (TC_H_MAJ(band)) |
58 | band = 0; | 57 | band = 0; |
59 | band = q->prio2band[band&TC_PRIO_MAX]; | 58 | band = q->prio2band[band&TC_PRIO_MAX]; |