Skip to content

Commit

Permalink
net_sched: sch_hfsc: fix classification loops
Browse files Browse the repository at this point in the history
When attaching filters to a class pointing to a class higher up in the
hierarchy, classification may enter an endless loop. Currently this is
prevented for filters that are already resolved, but not for filters
resolved at runtime.

Only allow filters to point downwards in the hierarchy, similar to what
CBQ does.

Reported-by: Pawel Staszewski <pstaszewski@itcare.pl>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Patrick McHardy authored and David S. Miller committed May 18, 2010
1 parent e1bc7ee commit a2f7922
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion net/sched/sch_hfsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,7 @@ static struct hfsc_class *
hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
{
struct hfsc_sched *q = qdisc_priv(sch);
struct hfsc_class *cl;
struct hfsc_class *head, *cl;
struct tcf_result res;
struct tcf_proto *tcf;
int result;
Expand All @@ -1166,6 +1166,7 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
return cl;

*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
head = &q->root;
tcf = q->root.filter_list;
while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
#ifdef CONFIG_NET_CLS_ACT
Expand All @@ -1180,13 +1181,16 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
if ((cl = (struct hfsc_class *)res.class) == NULL) {
if ((cl = hfsc_find_class(res.classid, sch)) == NULL)
break; /* filter selected invalid classid */
if (cl->level >= head->level)
break; /* filter may only point downwards */
}

if (cl->level == 0)
return cl; /* hit leaf class */

/* apply inner filter chain */
tcf = cl->filter_list;
head = cl;
}

/* classification failed, try default class */
Expand Down

0 comments on commit a2f7922

Please sign in to comment.