Skip to content

Commit 94134bf

Browse files
committed
Merge branch 'sched-cls_api-small-cleanup'
Jiri Pirko says: ==================== sched: cls_api: small cleanup This patchset makes couple of things in cls_api code a bit nicer and easier for reader to digest. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents b4c4ebc + 40c81b2 commit 94134bf

File tree

15 files changed

+126
-104
lines changed

15 files changed

+126
-104
lines changed

include/net/pkt_cls.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ struct tcf_walker {
1717
int register_tcf_proto_ops(struct tcf_proto_ops *ops);
1818
int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
1919

20+
void tcf_destroy_chain(struct tcf_proto __rcu **fl);
21+
2022
static inline unsigned long
2123
__cls_set_class(unsigned long *clp, unsigned long cl)
2224
{

include/net/sch_generic.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,6 @@ struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
405405
const struct Qdisc_ops *ops, u32 parentid);
406406
void __qdisc_calculate_pkt_len(struct sk_buff *skb,
407407
const struct qdisc_size_table *stab);
408-
bool tcf_destroy(struct tcf_proto *tp, bool force);
409-
void tcf_destroy_chain(struct tcf_proto __rcu **fl);
410408
int skb_do_redirect(struct sk_buff *);
411409

412410
static inline void skb_reset_tc(struct sk_buff *skb)

net/sched/cls_api.c

Lines changed: 113 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/kernel.h>
2020
#include <linux/string.h>
2121
#include <linux/errno.h>
22+
#include <linux/err.h>
2223
#include <linux/skbuff.h>
2324
#include <linux/init.h>
2425
#include <linux/kmod.h>
@@ -38,14 +39,14 @@ static DEFINE_RWLOCK(cls_mod_lock);
3839

3940
/* Find classifier type by string name */
4041

41-
static const struct tcf_proto_ops *tcf_proto_lookup_ops(struct nlattr *kind)
42+
static const struct tcf_proto_ops *tcf_proto_lookup_ops(const char *kind)
4243
{
4344
const struct tcf_proto_ops *t, *res = NULL;
4445

4546
if (kind) {
4647
read_lock(&cls_mod_lock);
4748
list_for_each_entry(t, &tcf_proto_base, head) {
48-
if (nla_strcmp(kind, t->kind) == 0) {
49+
if (strcmp(kind, t->kind) == 0) {
4950
if (try_module_get(t->owner))
5051
res = t;
5152
break;
@@ -127,6 +128,77 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp)
127128
return first;
128129
}
129130

131+
static struct tcf_proto *tcf_proto_create(const char *kind, u32 protocol,
132+
u32 prio, u32 parent, struct Qdisc *q)
133+
{
134+
struct tcf_proto *tp;
135+
int err;
136+
137+
tp = kzalloc(sizeof(*tp), GFP_KERNEL);
138+
if (!tp)
139+
return ERR_PTR(-ENOBUFS);
140+
141+
err = -ENOENT;
142+
tp->ops = tcf_proto_lookup_ops(kind);
143+
if (!tp->ops) {
144+
#ifdef CONFIG_MODULES
145+
rtnl_unlock();
146+
request_module("cls_%s", kind);
147+
rtnl_lock();
148+
tp->ops = tcf_proto_lookup_ops(kind);
149+
/* We dropped the RTNL semaphore in order to perform
150+
* the module load. So, even if we succeeded in loading
151+
* the module we have to replay the request. We indicate
152+
* this using -EAGAIN.
153+
*/
154+
if (tp->ops) {
155+
module_put(tp->ops->owner);
156+
err = -EAGAIN;
157+
} else {
158+
err = -ENOENT;
159+
}
160+
goto errout;
161+
#endif
162+
}
163+
tp->classify = tp->ops->classify;
164+
tp->protocol = protocol;
165+
tp->prio = prio;
166+
tp->classid = parent;
167+
tp->q = q;
168+
169+
err = tp->ops->init(tp);
170+
if (err) {
171+
module_put(tp->ops->owner);
172+
goto errout;
173+
}
174+
return tp;
175+
176+
errout:
177+
kfree(tp);
178+
return ERR_PTR(err);
179+
}
180+
181+
static bool tcf_proto_destroy(struct tcf_proto *tp, bool force)
182+
{
183+
if (tp->ops->destroy(tp, force)) {
184+
module_put(tp->ops->owner);
185+
kfree_rcu(tp, rcu);
186+
return true;
187+
}
188+
return false;
189+
}
190+
191+
void tcf_destroy_chain(struct tcf_proto __rcu **fl)
192+
{
193+
struct tcf_proto *tp;
194+
195+
while ((tp = rtnl_dereference(*fl)) != NULL) {
196+
RCU_INIT_POINTER(*fl, tp->next);
197+
tcf_proto_destroy(tp, true);
198+
}
199+
}
200+
EXPORT_SYMBOL(tcf_destroy_chain);
201+
130202
/* Add/change/delete/get a filter node */
131203

132204
static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
@@ -142,8 +214,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
142214
struct Qdisc *q;
143215
struct tcf_proto __rcu **back;
144216
struct tcf_proto __rcu **chain;
217+
struct tcf_proto *next;
145218
struct tcf_proto *tp;
146-
const struct tcf_proto_ops *tp_ops;
147219
const struct Qdisc_class_ops *cops;
148220
unsigned long cl;
149221
unsigned long fh;
@@ -222,9 +294,10 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
222294

223295
/* And the last stroke */
224296
chain = cops->tcf_chain(q, cl);
225-
err = -EINVAL;
226-
if (chain == NULL)
297+
if (chain == NULL) {
298+
err = -EINVAL;
227299
goto errout;
300+
}
228301
if (n->nlmsg_type == RTM_DELTFILTER && prio == 0) {
229302
tfilter_notify_chain(net, skb, n, chain, RTM_DELTFILTER);
230303
tcf_destroy_chain(chain);
@@ -239,121 +312,83 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
239312
if (tp->prio >= prio) {
240313
if (tp->prio == prio) {
241314
if (!nprio ||
242-
(tp->protocol != protocol && protocol))
315+
(tp->protocol != protocol && protocol)) {
316+
err = -EINVAL;
243317
goto errout;
244-
} else
318+
}
319+
} else {
245320
tp = NULL;
321+
}
246322
break;
247323
}
248324
}
249325

250326
if (tp == NULL) {
251327
/* Proto-tcf does not exist, create new one */
252328

253-
if (tca[TCA_KIND] == NULL || !protocol)
329+
if (tca[TCA_KIND] == NULL || !protocol) {
330+
err = -EINVAL;
254331
goto errout;
332+
}
255333

256-
err = -ENOENT;
257334
if (n->nlmsg_type != RTM_NEWTFILTER ||
258-
!(n->nlmsg_flags & NLM_F_CREATE))
335+
!(n->nlmsg_flags & NLM_F_CREATE)) {
336+
err = -ENOENT;
259337
goto errout;
338+
}
260339

340+
if (!nprio)
341+
nprio = TC_H_MAJ(tcf_auto_prio(rtnl_dereference(*back)));
261342

262-
/* Create new proto tcf */
263-
264-
err = -ENOBUFS;
265-
tp = kzalloc(sizeof(*tp), GFP_KERNEL);
266-
if (tp == NULL)
267-
goto errout;
268-
err = -ENOENT;
269-
tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND]);
270-
if (tp_ops == NULL) {
271-
#ifdef CONFIG_MODULES
272-
struct nlattr *kind = tca[TCA_KIND];
273-
char name[IFNAMSIZ];
274-
275-
if (kind != NULL &&
276-
nla_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
277-
rtnl_unlock();
278-
request_module("cls_%s", name);
279-
rtnl_lock();
280-
tp_ops = tcf_proto_lookup_ops(kind);
281-
/* We dropped the RTNL semaphore in order to
282-
* perform the module load. So, even if we
283-
* succeeded in loading the module we have to
284-
* replay the request. We indicate this using
285-
* -EAGAIN.
286-
*/
287-
if (tp_ops != NULL) {
288-
module_put(tp_ops->owner);
289-
err = -EAGAIN;
290-
}
291-
}
292-
#endif
293-
kfree(tp);
343+
tp = tcf_proto_create(nla_data(tca[TCA_KIND]),
344+
protocol, nprio, parent, q);
345+
if (IS_ERR(tp)) {
346+
err = PTR_ERR(tp);
294347
goto errout;
295348
}
296-
tp->ops = tp_ops;
297-
tp->protocol = protocol;
298-
tp->prio = nprio ? :
299-
TC_H_MAJ(tcf_auto_prio(rtnl_dereference(*back)));
300-
tp->q = q;
301-
tp->classify = tp_ops->classify;
302-
tp->classid = parent;
303-
304-
err = tp_ops->init(tp);
305-
if (err != 0) {
306-
module_put(tp_ops->owner);
307-
kfree(tp);
308-
goto errout;
309-
}
310-
311349
tp_created = 1;
312-
313-
} else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind))
350+
} else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind)) {
351+
err = -EINVAL;
314352
goto errout;
353+
}
315354

316355
fh = tp->ops->get(tp, t->tcm_handle);
317356

318357
if (fh == 0) {
319358
if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
320-
struct tcf_proto *next = rtnl_dereference(tp->next);
321-
359+
next = rtnl_dereference(tp->next);
322360
RCU_INIT_POINTER(*back, next);
323-
324361
tfilter_notify(net, skb, n, tp, fh,
325362
RTM_DELTFILTER, false);
326-
tcf_destroy(tp, true);
363+
tcf_proto_destroy(tp, true);
327364
err = 0;
328365
goto errout;
329366
}
330367

331-
err = -ENOENT;
332368
if (n->nlmsg_type != RTM_NEWTFILTER ||
333-
!(n->nlmsg_flags & NLM_F_CREATE))
369+
!(n->nlmsg_flags & NLM_F_CREATE)) {
370+
err = -ENOENT;
334371
goto errout;
372+
}
335373
} else {
336374
switch (n->nlmsg_type) {
337375
case RTM_NEWTFILTER:
338-
err = -EEXIST;
339376
if (n->nlmsg_flags & NLM_F_EXCL) {
340377
if (tp_created)
341-
tcf_destroy(tp, true);
378+
tcf_proto_destroy(tp, true);
379+
err = -EEXIST;
342380
goto errout;
343381
}
344382
break;
345383
case RTM_DELTFILTER:
346384
err = tp->ops->delete(tp, fh);
347-
if (err == 0) {
348-
struct tcf_proto *next = rtnl_dereference(tp->next);
349-
350-
tfilter_notify(net, skb, n, tp,
351-
t->tcm_handle,
352-
RTM_DELTFILTER, false);
353-
if (tcf_destroy(tp, false))
354-
RCU_INIT_POINTER(*back, next);
355-
}
356-
goto errout;
385+
if (err)
386+
goto errout;
387+
next = rtnl_dereference(tp->next);
388+
tfilter_notify(net, skb, n, tp, t->tcm_handle,
389+
RTM_DELTFILTER, false);
390+
if (tcf_proto_destroy(tp, false))
391+
RCU_INIT_POINTER(*back, next);
357392
case RTM_GETTFILTER:
358393
err = tfilter_notify(net, skb, n, tp, fh,
359394
RTM_NEWTFILTER, true);
@@ -374,7 +409,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
374409
tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER, false);
375410
} else {
376411
if (tp_created)
377-
tcf_destroy(tp, true);
412+
tcf_proto_destroy(tp, true);
378413
}
379414

380415
errout:

net/sched/sch_api.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1900,28 +1900,6 @@ int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp,
19001900
}
19011901
EXPORT_SYMBOL(tc_classify);
19021902

1903-
bool tcf_destroy(struct tcf_proto *tp, bool force)
1904-
{
1905-
if (tp->ops->destroy(tp, force)) {
1906-
module_put(tp->ops->owner);
1907-
kfree_rcu(tp, rcu);
1908-
return true;
1909-
}
1910-
1911-
return false;
1912-
}
1913-
1914-
void tcf_destroy_chain(struct tcf_proto __rcu **fl)
1915-
{
1916-
struct tcf_proto *tp;
1917-
1918-
while ((tp = rtnl_dereference(*fl)) != NULL) {
1919-
RCU_INIT_POINTER(*fl, tp->next);
1920-
tcf_destroy(tp, true);
1921-
}
1922-
}
1923-
EXPORT_SYMBOL(tcf_destroy_chain);
1924-
19251903
#ifdef CONFIG_PROC_FS
19261904
static int psched_show(struct seq_file *seq, void *v)
19271905
{

net/sched/sch_atm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/file.h> /* for fput */
1616
#include <net/netlink.h>
1717
#include <net/pkt_sched.h>
18+
#include <net/pkt_cls.h>
1819

1920
/*
2021
* The ATM queuing discipline provides a framework for invoking classifiers

net/sched/sch_cbq.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/skbuff.h>
2020
#include <net/netlink.h>
2121
#include <net/pkt_sched.h>
22+
#include <net/pkt_cls.h>
2223

2324

2425
/* Class-Based Queueing (CBQ) algorithm.

net/sched/sch_choke.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/skbuff.h>
1717
#include <linux/vmalloc.h>
1818
#include <net/pkt_sched.h>
19+
#include <net/pkt_cls.h>
1920
#include <net/inet_ecn.h>
2021
#include <net/red.h>
2122
#include <net/flow_dissector.h>

net/sched/sch_dsmark.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/rtnetlink.h>
1414
#include <linux/bitops.h>
1515
#include <net/pkt_sched.h>
16+
#include <net/pkt_cls.h>
1617
#include <net/dsfield.h>
1718
#include <net/inet_ecn.h>
1819
#include <asm/byteorder.h>

net/sched/sch_fq_codel.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/vmalloc.h>
2424
#include <net/netlink.h>
2525
#include <net/pkt_sched.h>
26+
#include <net/pkt_cls.h>
2627
#include <net/codel.h>
2728
#include <net/codel_impl.h>
2829
#include <net/codel_qdisc.h>

net/sched/sch_htb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <net/netlink.h>
4141
#include <net/sch_generic.h>
4242
#include <net/pkt_sched.h>
43+
#include <net/pkt_cls.h>
4344

4445
/* HTB algorithm.
4546

0 commit comments

Comments
 (0)