aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/act_simple.c45
-rw-r--r--net/sched/sch_htb.c8
2 files changed, 28 insertions, 25 deletions
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index 64b2d136c78e..1d421d059caf 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -6,7 +6,7 @@
6 * as published by the Free Software Foundation; either version 6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version. 7 * 2 of the License, or (at your option) any later version.
8 * 8 *
9 * Authors: Jamal Hadi Salim (2005) 9 * Authors: Jamal Hadi Salim (2005-8)
10 * 10 *
11 */ 11 */
12 12
@@ -34,6 +34,7 @@ static struct tcf_hashinfo simp_hash_info = {
34 .lock = &simp_lock, 34 .lock = &simp_lock,
35}; 35};
36 36
37#define SIMP_MAX_DATA 32
37static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res) 38static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
38{ 39{
39 struct tcf_defact *d = a->priv; 40 struct tcf_defact *d = a->priv;
@@ -69,23 +70,28 @@ static int tcf_simp_release(struct tcf_defact *d, int bind)
69 return ret; 70 return ret;
70} 71}
71 72
72static int alloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata) 73static int alloc_defdata(struct tcf_defact *d, char *defdata)
73{ 74{
74 d->tcfd_defdata = kmemdup(defdata, datalen, GFP_KERNEL); 75 d->tcfd_defdata = kstrndup(defdata, SIMP_MAX_DATA, GFP_KERNEL);
75 if (unlikely(!d->tcfd_defdata)) 76 if (unlikely(!d->tcfd_defdata))
76 return -ENOMEM; 77 return -ENOMEM;
77 d->tcfd_datalen = datalen; 78
78 return 0; 79 return 0;
79} 80}
80 81
81static int realloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata) 82static void reset_policy(struct tcf_defact *d, char *defdata,
83 struct tc_defact *p)
82{ 84{
83 kfree(d->tcfd_defdata); 85 spin_lock_bh(&d->tcf_lock);
84 return alloc_defdata(d, datalen, defdata); 86 d->tcf_action = p->action;
87 memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
88 strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
89 spin_unlock_bh(&d->tcf_lock);
85} 90}
86 91
87static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = { 92static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {
88 [TCA_DEF_PARMS] = { .len = sizeof(struct tc_defact) }, 93 [TCA_DEF_PARMS] = { .len = sizeof(struct tc_defact) },
94 [TCA_DEF_DATA] = { .type = NLA_STRING, .len = SIMP_MAX_DATA },
89}; 95};
90 96
91static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, 97static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
@@ -95,28 +101,24 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
95 struct tc_defact *parm; 101 struct tc_defact *parm;
96 struct tcf_defact *d; 102 struct tcf_defact *d;
97 struct tcf_common *pc; 103 struct tcf_common *pc;
98 void *defdata; 104 char *defdata;
99 u32 datalen = 0;
100 int ret = 0, err; 105 int ret = 0, err;
101 106
102 if (nla == NULL) 107 if (nla == NULL)
103 return -EINVAL; 108 return -EINVAL;
104 109
105 err = nla_parse_nested(tb, TCA_DEF_MAX, nla, NULL); 110 err = nla_parse_nested(tb, TCA_DEF_MAX, nla, simple_policy);
106 if (err < 0) 111 if (err < 0)
107 return err; 112 return err;
108 113
109 if (tb[TCA_DEF_PARMS] == NULL) 114 if (tb[TCA_DEF_PARMS] == NULL)
110 return -EINVAL; 115 return -EINVAL;
111 116
112 parm = nla_data(tb[TCA_DEF_PARMS]); 117 if (tb[TCA_DEF_DATA] == NULL)
113 defdata = nla_data(tb[TCA_DEF_DATA]);
114 if (defdata == NULL)
115 return -EINVAL; 118 return -EINVAL;
116 119
117 datalen = nla_len(tb[TCA_DEF_DATA]); 120 parm = nla_data(tb[TCA_DEF_PARMS]);
118 if (datalen == 0) 121 defdata = nla_data(tb[TCA_DEF_DATA]);
119 return -EINVAL;
120 122
121 pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info); 123 pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info);
122 if (!pc) { 124 if (!pc) {
@@ -126,11 +128,12 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
126 return -ENOMEM; 128 return -ENOMEM;
127 129
128 d = to_defact(pc); 130 d = to_defact(pc);
129 ret = alloc_defdata(d, datalen, defdata); 131 ret = alloc_defdata(d, defdata);
130 if (ret < 0) { 132 if (ret < 0) {
131 kfree(pc); 133 kfree(pc);
132 return ret; 134 return ret;
133 } 135 }
136 d->tcf_action = parm->action;
134 ret = ACT_P_CREATED; 137 ret = ACT_P_CREATED;
135 } else { 138 } else {
136 d = to_defact(pc); 139 d = to_defact(pc);
@@ -138,13 +141,9 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
138 tcf_simp_release(d, bind); 141 tcf_simp_release(d, bind);
139 return -EEXIST; 142 return -EEXIST;
140 } 143 }
141 realloc_defdata(d, datalen, defdata); 144 reset_policy(d, defdata, parm);
142 } 145 }
143 146
144 spin_lock_bh(&d->tcf_lock);
145 d->tcf_action = parm->action;
146 spin_unlock_bh(&d->tcf_lock);
147
148 if (ret == ACT_P_CREATED) 147 if (ret == ACT_P_CREATED)
149 tcf_hash_insert(pc, &simp_hash_info); 148 tcf_hash_insert(pc, &simp_hash_info);
150 return ret; 149 return ret;
@@ -172,7 +171,7 @@ static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
172 opt.bindcnt = d->tcf_bindcnt - bind; 171 opt.bindcnt = d->tcf_bindcnt - bind;
173 opt.action = d->tcf_action; 172 opt.action = d->tcf_action;
174 NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt); 173 NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
175 NLA_PUT(skb, TCA_DEF_DATA, d->tcfd_datalen, d->tcfd_defdata); 174 NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata);
176 t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install); 175 t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
177 t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse); 176 t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse);
178 t.expires = jiffies_to_clock_t(d->tcf_tm.expires); 177 t.expires = jiffies_to_clock_t(d->tcf_tm.expires);
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 66148cc4759e..5bc1ed490180 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1197,12 +1197,16 @@ static inline int htb_parent_last_child(struct htb_class *cl)
1197 return 1; 1197 return 1;
1198} 1198}
1199 1199
1200static void htb_parent_to_leaf(struct htb_class *cl, struct Qdisc *new_q) 1200static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl,
1201 struct Qdisc *new_q)
1201{ 1202{
1202 struct htb_class *parent = cl->parent; 1203 struct htb_class *parent = cl->parent;
1203 1204
1204 BUG_TRAP(!cl->level && cl->un.leaf.q && !cl->prio_activity); 1205 BUG_TRAP(!cl->level && cl->un.leaf.q && !cl->prio_activity);
1205 1206
1207 if (parent->cmode != HTB_CAN_SEND)
1208 htb_safe_rb_erase(&parent->pq_node, q->wait_pq + parent->level);
1209
1206 parent->level = 0; 1210 parent->level = 0;
1207 memset(&parent->un.inner, 0, sizeof(parent->un.inner)); 1211 memset(&parent->un.inner, 0, sizeof(parent->un.inner));
1208 INIT_LIST_HEAD(&parent->un.leaf.drop_list); 1212 INIT_LIST_HEAD(&parent->un.leaf.drop_list);
@@ -1300,7 +1304,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
1300 htb_deactivate(q, cl); 1304 htb_deactivate(q, cl);
1301 1305
1302 if (last_child) 1306 if (last_child)
1303 htb_parent_to_leaf(cl, new_q); 1307 htb_parent_to_leaf(q, cl, new_q);
1304 1308
1305 if (--cl->refcnt == 0) 1309 if (--cl->refcnt == 0)
1306 htb_destroy_class(sch, cl); 1310 htb_destroy_class(sch, cl);