diff options
author | David S. Miller <davem@davemloft.net> | 2008-08-09 02:23:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-08-09 02:23:39 -0400 |
commit | 8123b421e8ed944671d7241323ed3198cccb4041 (patch) | |
tree | fb9e5634b36cce181781e764e71406c972dd2e8c | |
parent | 76aab2c1eae491a5d73ac83deec97dd28ebac584 (diff) |
pkt_sched: Fix ingress deletion and filter attachment.
Based upon bug reports by Stephen Hemminger.
We still had some cases using ->qdisc instead of ->qdisc_sleeping.
Also, qdisc_lookup() should return ingress qdiscs.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/sched/sch_api.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index ba1d121f3127..bbf149dd7818 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -183,6 +183,21 @@ EXPORT_SYMBOL(unregister_qdisc); | |||
183 | (root qdisc, all its children, children of children etc.) | 183 | (root qdisc, all its children, children of children etc.) |
184 | */ | 184 | */ |
185 | 185 | ||
186 | struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle) | ||
187 | { | ||
188 | struct Qdisc *q; | ||
189 | |||
190 | if (!(root->flags & TCQ_F_BUILTIN) && | ||
191 | root->handle == handle) | ||
192 | return root; | ||
193 | |||
194 | list_for_each_entry(q, &root->list, list) { | ||
195 | if (q->handle == handle) | ||
196 | return q; | ||
197 | } | ||
198 | return NULL; | ||
199 | } | ||
200 | |||
186 | struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) | 201 | struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) |
187 | { | 202 | { |
188 | unsigned int i; | 203 | unsigned int i; |
@@ -191,16 +206,11 @@ struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) | |||
191 | struct netdev_queue *txq = netdev_get_tx_queue(dev, i); | 206 | struct netdev_queue *txq = netdev_get_tx_queue(dev, i); |
192 | struct Qdisc *q, *txq_root = txq->qdisc_sleeping; | 207 | struct Qdisc *q, *txq_root = txq->qdisc_sleeping; |
193 | 208 | ||
194 | if (!(txq_root->flags & TCQ_F_BUILTIN) && | 209 | q = qdisc_match_from_root(txq_root, handle); |
195 | txq_root->handle == handle) | 210 | if (q) |
196 | return txq_root; | 211 | return q; |
197 | |||
198 | list_for_each_entry(q, &txq_root->list, list) { | ||
199 | if (q->handle == handle) | ||
200 | return q; | ||
201 | } | ||
202 | } | 212 | } |
203 | return NULL; | 213 | return qdisc_match_from_root(dev->rx_queue.qdisc_sleeping, handle); |
204 | } | 214 | } |
205 | 215 | ||
206 | static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid) | 216 | static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid) |
@@ -908,7 +918,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
908 | return -ENOENT; | 918 | return -ENOENT; |
909 | q = qdisc_leaf(p, clid); | 919 | q = qdisc_leaf(p, clid); |
910 | } else { /* ingress */ | 920 | } else { /* ingress */ |
911 | q = dev->rx_queue.qdisc; | 921 | q = dev->rx_queue.qdisc_sleeping; |
912 | } | 922 | } |
913 | } else { | 923 | } else { |
914 | struct netdev_queue *dev_queue; | 924 | struct netdev_queue *dev_queue; |
@@ -978,7 +988,7 @@ replay: | |||
978 | return -ENOENT; | 988 | return -ENOENT; |
979 | q = qdisc_leaf(p, clid); | 989 | q = qdisc_leaf(p, clid); |
980 | } else { /*ingress */ | 990 | } else { /*ingress */ |
981 | q = dev->rx_queue.qdisc; | 991 | q = dev->rx_queue.qdisc_sleeping; |
982 | } | 992 | } |
983 | } else { | 993 | } else { |
984 | struct netdev_queue *dev_queue; | 994 | struct netdev_queue *dev_queue; |
@@ -1529,11 +1539,11 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) | |||
1529 | t = 0; | 1539 | t = 0; |
1530 | 1540 | ||
1531 | dev_queue = netdev_get_tx_queue(dev, 0); | 1541 | dev_queue = netdev_get_tx_queue(dev, 0); |
1532 | if (tc_dump_tclass_root(dev_queue->qdisc, skb, tcm, cb, &t, s_t) < 0) | 1542 | if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0) |
1533 | goto done; | 1543 | goto done; |
1534 | 1544 | ||
1535 | dev_queue = &dev->rx_queue; | 1545 | dev_queue = &dev->rx_queue; |
1536 | if (tc_dump_tclass_root(dev_queue->qdisc, skb, tcm, cb, &t, s_t) < 0) | 1546 | if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0) |
1537 | goto done; | 1547 | goto done; |
1538 | 1548 | ||
1539 | done: | 1549 | done: |