Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/sched/act_api.c
15109 views
1
/*
2
* net/sched/act_api.c Packet action API.
3
*
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; either version
7
* 2 of the License, or (at your option) any later version.
8
*
9
* Author: Jamal Hadi Salim
10
*
11
*
12
*/
13
14
#include <linux/types.h>
15
#include <linux/kernel.h>
16
#include <linux/string.h>
17
#include <linux/errno.h>
18
#include <linux/slab.h>
19
#include <linux/skbuff.h>
20
#include <linux/init.h>
21
#include <linux/kmod.h>
22
#include <linux/err.h>
23
#include <net/net_namespace.h>
24
#include <net/sock.h>
25
#include <net/sch_generic.h>
26
#include <net/act_api.h>
27
#include <net/netlink.h>
28
29
void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
30
{
31
unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask);
32
struct tcf_common **p1p;
33
34
for (p1p = &hinfo->htab[h]; *p1p; p1p = &(*p1p)->tcfc_next) {
35
if (*p1p == p) {
36
write_lock_bh(hinfo->lock);
37
*p1p = p->tcfc_next;
38
write_unlock_bh(hinfo->lock);
39
gen_kill_estimator(&p->tcfc_bstats,
40
&p->tcfc_rate_est);
41
/*
42
* gen_estimator est_timer() might access p->tcfc_lock
43
* or bstats, wait a RCU grace period before freeing p
44
*/
45
kfree_rcu(p, tcfc_rcu);
46
return;
47
}
48
}
49
WARN_ON(1);
50
}
51
EXPORT_SYMBOL(tcf_hash_destroy);
52
53
int tcf_hash_release(struct tcf_common *p, int bind,
54
struct tcf_hashinfo *hinfo)
55
{
56
int ret = 0;
57
58
if (p) {
59
if (bind)
60
p->tcfc_bindcnt--;
61
62
p->tcfc_refcnt--;
63
if (p->tcfc_bindcnt <= 0 && p->tcfc_refcnt <= 0) {
64
tcf_hash_destroy(p, hinfo);
65
ret = 1;
66
}
67
}
68
return ret;
69
}
70
EXPORT_SYMBOL(tcf_hash_release);
71
72
static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb,
73
struct tc_action *a, struct tcf_hashinfo *hinfo)
74
{
75
struct tcf_common *p;
76
int err = 0, index = -1, i = 0, s_i = 0, n_i = 0;
77
struct nlattr *nest;
78
79
read_lock_bh(hinfo->lock);
80
81
s_i = cb->args[0];
82
83
for (i = 0; i < (hinfo->hmask + 1); i++) {
84
p = hinfo->htab[tcf_hash(i, hinfo->hmask)];
85
86
for (; p; p = p->tcfc_next) {
87
index++;
88
if (index < s_i)
89
continue;
90
a->priv = p;
91
a->order = n_i;
92
93
nest = nla_nest_start(skb, a->order);
94
if (nest == NULL)
95
goto nla_put_failure;
96
err = tcf_action_dump_1(skb, a, 0, 0);
97
if (err < 0) {
98
index--;
99
nlmsg_trim(skb, nest);
100
goto done;
101
}
102
nla_nest_end(skb, nest);
103
n_i++;
104
if (n_i >= TCA_ACT_MAX_PRIO)
105
goto done;
106
}
107
}
108
done:
109
read_unlock_bh(hinfo->lock);
110
if (n_i)
111
cb->args[0] += n_i;
112
return n_i;
113
114
nla_put_failure:
115
nla_nest_cancel(skb, nest);
116
goto done;
117
}
118
119
static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a,
120
struct tcf_hashinfo *hinfo)
121
{
122
struct tcf_common *p, *s_p;
123
struct nlattr *nest;
124
int i = 0, n_i = 0;
125
126
nest = nla_nest_start(skb, a->order);
127
if (nest == NULL)
128
goto nla_put_failure;
129
NLA_PUT_STRING(skb, TCA_KIND, a->ops->kind);
130
for (i = 0; i < (hinfo->hmask + 1); i++) {
131
p = hinfo->htab[tcf_hash(i, hinfo->hmask)];
132
133
while (p != NULL) {
134
s_p = p->tcfc_next;
135
if (ACT_P_DELETED == tcf_hash_release(p, 0, hinfo))
136
module_put(a->ops->owner);
137
n_i++;
138
p = s_p;
139
}
140
}
141
NLA_PUT_U32(skb, TCA_FCNT, n_i);
142
nla_nest_end(skb, nest);
143
144
return n_i;
145
nla_put_failure:
146
nla_nest_cancel(skb, nest);
147
return -EINVAL;
148
}
149
150
int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb,
151
int type, struct tc_action *a)
152
{
153
struct tcf_hashinfo *hinfo = a->ops->hinfo;
154
155
if (type == RTM_DELACTION) {
156
return tcf_del_walker(skb, a, hinfo);
157
} else if (type == RTM_GETACTION) {
158
return tcf_dump_walker(skb, cb, a, hinfo);
159
} else {
160
WARN(1, "tcf_generic_walker: unknown action %d\n", type);
161
return -EINVAL;
162
}
163
}
164
EXPORT_SYMBOL(tcf_generic_walker);
165
166
struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo)
167
{
168
struct tcf_common *p;
169
170
read_lock_bh(hinfo->lock);
171
for (p = hinfo->htab[tcf_hash(index, hinfo->hmask)]; p;
172
p = p->tcfc_next) {
173
if (p->tcfc_index == index)
174
break;
175
}
176
read_unlock_bh(hinfo->lock);
177
178
return p;
179
}
180
EXPORT_SYMBOL(tcf_hash_lookup);
181
182
u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo)
183
{
184
u32 val = *idx_gen;
185
186
do {
187
if (++val == 0)
188
val = 1;
189
} while (tcf_hash_lookup(val, hinfo));
190
191
return (*idx_gen = val);
192
}
193
EXPORT_SYMBOL(tcf_hash_new_index);
194
195
int tcf_hash_search(struct tc_action *a, u32 index)
196
{
197
struct tcf_hashinfo *hinfo = a->ops->hinfo;
198
struct tcf_common *p = tcf_hash_lookup(index, hinfo);
199
200
if (p) {
201
a->priv = p;
202
return 1;
203
}
204
return 0;
205
}
206
EXPORT_SYMBOL(tcf_hash_search);
207
208
struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind,
209
struct tcf_hashinfo *hinfo)
210
{
211
struct tcf_common *p = NULL;
212
if (index && (p = tcf_hash_lookup(index, hinfo)) != NULL) {
213
if (bind)
214
p->tcfc_bindcnt++;
215
p->tcfc_refcnt++;
216
a->priv = p;
217
}
218
return p;
219
}
220
EXPORT_SYMBOL(tcf_hash_check);
221
222
struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est,
223
struct tc_action *a, int size, int bind,
224
u32 *idx_gen, struct tcf_hashinfo *hinfo)
225
{
226
struct tcf_common *p = kzalloc(size, GFP_KERNEL);
227
228
if (unlikely(!p))
229
return ERR_PTR(-ENOMEM);
230
p->tcfc_refcnt = 1;
231
if (bind)
232
p->tcfc_bindcnt = 1;
233
234
spin_lock_init(&p->tcfc_lock);
235
p->tcfc_index = index ? index : tcf_hash_new_index(idx_gen, hinfo);
236
p->tcfc_tm.install = jiffies;
237
p->tcfc_tm.lastuse = jiffies;
238
if (est) {
239
int err = gen_new_estimator(&p->tcfc_bstats, &p->tcfc_rate_est,
240
&p->tcfc_lock, est);
241
if (err) {
242
kfree(p);
243
return ERR_PTR(err);
244
}
245
}
246
247
a->priv = (void *) p;
248
return p;
249
}
250
EXPORT_SYMBOL(tcf_hash_create);
251
252
void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo)
253
{
254
unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask);
255
256
write_lock_bh(hinfo->lock);
257
p->tcfc_next = hinfo->htab[h];
258
hinfo->htab[h] = p;
259
write_unlock_bh(hinfo->lock);
260
}
261
EXPORT_SYMBOL(tcf_hash_insert);
262
263
static struct tc_action_ops *act_base = NULL;
264
static DEFINE_RWLOCK(act_mod_lock);
265
266
int tcf_register_action(struct tc_action_ops *act)
267
{
268
struct tc_action_ops *a, **ap;
269
270
write_lock(&act_mod_lock);
271
for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) {
272
if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) {
273
write_unlock(&act_mod_lock);
274
return -EEXIST;
275
}
276
}
277
act->next = NULL;
278
*ap = act;
279
write_unlock(&act_mod_lock);
280
return 0;
281
}
282
EXPORT_SYMBOL(tcf_register_action);
283
284
int tcf_unregister_action(struct tc_action_ops *act)
285
{
286
struct tc_action_ops *a, **ap;
287
int err = -ENOENT;
288
289
write_lock(&act_mod_lock);
290
for (ap = &act_base; (a = *ap) != NULL; ap = &a->next)
291
if (a == act)
292
break;
293
if (a) {
294
*ap = a->next;
295
a->next = NULL;
296
err = 0;
297
}
298
write_unlock(&act_mod_lock);
299
return err;
300
}
301
EXPORT_SYMBOL(tcf_unregister_action);
302
303
/* lookup by name */
304
static struct tc_action_ops *tc_lookup_action_n(char *kind)
305
{
306
struct tc_action_ops *a = NULL;
307
308
if (kind) {
309
read_lock(&act_mod_lock);
310
for (a = act_base; a; a = a->next) {
311
if (strcmp(kind, a->kind) == 0) {
312
if (!try_module_get(a->owner)) {
313
read_unlock(&act_mod_lock);
314
return NULL;
315
}
316
break;
317
}
318
}
319
read_unlock(&act_mod_lock);
320
}
321
return a;
322
}
323
324
/* lookup by nlattr */
325
static struct tc_action_ops *tc_lookup_action(struct nlattr *kind)
326
{
327
struct tc_action_ops *a = NULL;
328
329
if (kind) {
330
read_lock(&act_mod_lock);
331
for (a = act_base; a; a = a->next) {
332
if (nla_strcmp(kind, a->kind) == 0) {
333
if (!try_module_get(a->owner)) {
334
read_unlock(&act_mod_lock);
335
return NULL;
336
}
337
break;
338
}
339
}
340
read_unlock(&act_mod_lock);
341
}
342
return a;
343
}
344
345
#if 0
346
/* lookup by id */
347
static struct tc_action_ops *tc_lookup_action_id(u32 type)
348
{
349
struct tc_action_ops *a = NULL;
350
351
if (type) {
352
read_lock(&act_mod_lock);
353
for (a = act_base; a; a = a->next) {
354
if (a->type == type) {
355
if (!try_module_get(a->owner)) {
356
read_unlock(&act_mod_lock);
357
return NULL;
358
}
359
break;
360
}
361
}
362
read_unlock(&act_mod_lock);
363
}
364
return a;
365
}
366
#endif
367
368
int tcf_action_exec(struct sk_buff *skb, struct tc_action *act,
369
struct tcf_result *res)
370
{
371
struct tc_action *a;
372
int ret = -1;
373
374
if (skb->tc_verd & TC_NCLS) {
375
skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
376
ret = TC_ACT_OK;
377
goto exec_done;
378
}
379
while ((a = act) != NULL) {
380
repeat:
381
if (a->ops && a->ops->act) {
382
ret = a->ops->act(skb, a, res);
383
if (TC_MUNGED & skb->tc_verd) {
384
/* copied already, allow trampling */
385
skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
386
skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd);
387
}
388
if (ret == TC_ACT_REPEAT)
389
goto repeat; /* we need a ttl - JHS */
390
if (ret != TC_ACT_PIPE)
391
goto exec_done;
392
}
393
act = a->next;
394
}
395
exec_done:
396
return ret;
397
}
398
EXPORT_SYMBOL(tcf_action_exec);
399
400
void tcf_action_destroy(struct tc_action *act, int bind)
401
{
402
struct tc_action *a;
403
404
for (a = act; a; a = act) {
405
if (a->ops && a->ops->cleanup) {
406
if (a->ops->cleanup(a, bind) == ACT_P_DELETED)
407
module_put(a->ops->owner);
408
act = act->next;
409
kfree(a);
410
} else {
411
/*FIXME: Remove later - catch insertion bugs*/
412
WARN(1, "tcf_action_destroy: BUG? destroying NULL ops\n");
413
act = act->next;
414
kfree(a);
415
}
416
}
417
}
418
419
int
420
tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
421
{
422
int err = -EINVAL;
423
424
if (a->ops == NULL || a->ops->dump == NULL)
425
return err;
426
return a->ops->dump(skb, a, bind, ref);
427
}
428
429
int
430
tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
431
{
432
int err = -EINVAL;
433
unsigned char *b = skb_tail_pointer(skb);
434
struct nlattr *nest;
435
436
if (a->ops == NULL || a->ops->dump == NULL)
437
return err;
438
439
NLA_PUT_STRING(skb, TCA_KIND, a->ops->kind);
440
if (tcf_action_copy_stats(skb, a, 0))
441
goto nla_put_failure;
442
nest = nla_nest_start(skb, TCA_OPTIONS);
443
if (nest == NULL)
444
goto nla_put_failure;
445
err = tcf_action_dump_old(skb, a, bind, ref);
446
if (err > 0) {
447
nla_nest_end(skb, nest);
448
return err;
449
}
450
451
nla_put_failure:
452
nlmsg_trim(skb, b);
453
return -1;
454
}
455
EXPORT_SYMBOL(tcf_action_dump_1);
456
457
int
458
tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
459
{
460
struct tc_action *a;
461
int err = -EINVAL;
462
struct nlattr *nest;
463
464
while ((a = act) != NULL) {
465
act = a->next;
466
nest = nla_nest_start(skb, a->order);
467
if (nest == NULL)
468
goto nla_put_failure;
469
err = tcf_action_dump_1(skb, a, bind, ref);
470
if (err < 0)
471
goto errout;
472
nla_nest_end(skb, nest);
473
}
474
475
return 0;
476
477
nla_put_failure:
478
err = -EINVAL;
479
errout:
480
nla_nest_cancel(skb, nest);
481
return err;
482
}
483
484
struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est,
485
char *name, int ovr, int bind)
486
{
487
struct tc_action *a;
488
struct tc_action_ops *a_o;
489
char act_name[IFNAMSIZ];
490
struct nlattr *tb[TCA_ACT_MAX + 1];
491
struct nlattr *kind;
492
int err;
493
494
if (name == NULL) {
495
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
496
if (err < 0)
497
goto err_out;
498
err = -EINVAL;
499
kind = tb[TCA_ACT_KIND];
500
if (kind == NULL)
501
goto err_out;
502
if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
503
goto err_out;
504
} else {
505
err = -EINVAL;
506
if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ)
507
goto err_out;
508
}
509
510
a_o = tc_lookup_action_n(act_name);
511
if (a_o == NULL) {
512
#ifdef CONFIG_MODULES
513
rtnl_unlock();
514
request_module("act_%s", act_name);
515
rtnl_lock();
516
517
a_o = tc_lookup_action_n(act_name);
518
519
/* We dropped the RTNL semaphore in order to
520
* perform the module load. So, even if we
521
* succeeded in loading the module we have to
522
* tell the caller to replay the request. We
523
* indicate this using -EAGAIN.
524
*/
525
if (a_o != NULL) {
526
err = -EAGAIN;
527
goto err_mod;
528
}
529
#endif
530
err = -ENOENT;
531
goto err_out;
532
}
533
534
err = -ENOMEM;
535
a = kzalloc(sizeof(*a), GFP_KERNEL);
536
if (a == NULL)
537
goto err_mod;
538
539
/* backward compatibility for policer */
540
if (name == NULL)
541
err = a_o->init(tb[TCA_ACT_OPTIONS], est, a, ovr, bind);
542
else
543
err = a_o->init(nla, est, a, ovr, bind);
544
if (err < 0)
545
goto err_free;
546
547
/* module count goes up only when brand new policy is created
548
* if it exists and is only bound to in a_o->init() then
549
* ACT_P_CREATED is not returned (a zero is).
550
*/
551
if (err != ACT_P_CREATED)
552
module_put(a_o->owner);
553
a->ops = a_o;
554
555
return a;
556
557
err_free:
558
kfree(a);
559
err_mod:
560
module_put(a_o->owner);
561
err_out:
562
return ERR_PTR(err);
563
}
564
565
struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est,
566
char *name, int ovr, int bind)
567
{
568
struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
569
struct tc_action *head = NULL, *act, *act_prev = NULL;
570
int err;
571
int i;
572
573
err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL);
574
if (err < 0)
575
return ERR_PTR(err);
576
577
for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
578
act = tcf_action_init_1(tb[i], est, name, ovr, bind);
579
if (IS_ERR(act))
580
goto err;
581
act->order = i;
582
583
if (head == NULL)
584
head = act;
585
else
586
act_prev->next = act;
587
act_prev = act;
588
}
589
return head;
590
591
err:
592
if (head != NULL)
593
tcf_action_destroy(head, bind);
594
return act;
595
}
596
597
int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
598
int compat_mode)
599
{
600
int err = 0;
601
struct gnet_dump d;
602
struct tcf_act_hdr *h = a->priv;
603
604
if (h == NULL)
605
goto errout;
606
607
/* compat_mode being true specifies a call that is supposed
608
* to add additional backward compatibility statistic TLVs.
609
*/
610
if (compat_mode) {
611
if (a->type == TCA_OLD_COMPAT)
612
err = gnet_stats_start_copy_compat(skb, 0,
613
TCA_STATS, TCA_XSTATS, &h->tcf_lock, &d);
614
else
615
return 0;
616
} else
617
err = gnet_stats_start_copy(skb, TCA_ACT_STATS,
618
&h->tcf_lock, &d);
619
620
if (err < 0)
621
goto errout;
622
623
if (a->ops != NULL && a->ops->get_stats != NULL)
624
if (a->ops->get_stats(skb, a) < 0)
625
goto errout;
626
627
if (gnet_stats_copy_basic(&d, &h->tcf_bstats) < 0 ||
628
gnet_stats_copy_rate_est(&d, &h->tcf_bstats,
629
&h->tcf_rate_est) < 0 ||
630
gnet_stats_copy_queue(&d, &h->tcf_qstats) < 0)
631
goto errout;
632
633
if (gnet_stats_finish_copy(&d) < 0)
634
goto errout;
635
636
return 0;
637
638
errout:
639
return -1;
640
}
641
642
static int
643
tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
644
u16 flags, int event, int bind, int ref)
645
{
646
struct tcamsg *t;
647
struct nlmsghdr *nlh;
648
unsigned char *b = skb_tail_pointer(skb);
649
struct nlattr *nest;
650
651
nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
652
653
t = NLMSG_DATA(nlh);
654
t->tca_family = AF_UNSPEC;
655
t->tca__pad1 = 0;
656
t->tca__pad2 = 0;
657
658
nest = nla_nest_start(skb, TCA_ACT_TAB);
659
if (nest == NULL)
660
goto nla_put_failure;
661
662
if (tcf_action_dump(skb, a, bind, ref) < 0)
663
goto nla_put_failure;
664
665
nla_nest_end(skb, nest);
666
667
nlh->nlmsg_len = skb_tail_pointer(skb) - b;
668
return skb->len;
669
670
nla_put_failure:
671
nlmsg_failure:
672
nlmsg_trim(skb, b);
673
return -1;
674
}
675
676
static int
677
act_get_notify(struct net *net, u32 pid, struct nlmsghdr *n,
678
struct tc_action *a, int event)
679
{
680
struct sk_buff *skb;
681
682
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
683
if (!skb)
684
return -ENOBUFS;
685
if (tca_get_fill(skb, a, pid, n->nlmsg_seq, 0, event, 0, 0) <= 0) {
686
kfree_skb(skb);
687
return -EINVAL;
688
}
689
690
return rtnl_unicast(skb, net, pid);
691
}
692
693
static struct tc_action *
694
tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
695
{
696
struct nlattr *tb[TCA_ACT_MAX + 1];
697
struct tc_action *a;
698
int index;
699
int err;
700
701
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
702
if (err < 0)
703
goto err_out;
704
705
err = -EINVAL;
706
if (tb[TCA_ACT_INDEX] == NULL ||
707
nla_len(tb[TCA_ACT_INDEX]) < sizeof(index))
708
goto err_out;
709
index = nla_get_u32(tb[TCA_ACT_INDEX]);
710
711
err = -ENOMEM;
712
a = kzalloc(sizeof(struct tc_action), GFP_KERNEL);
713
if (a == NULL)
714
goto err_out;
715
716
err = -EINVAL;
717
a->ops = tc_lookup_action(tb[TCA_ACT_KIND]);
718
if (a->ops == NULL)
719
goto err_free;
720
if (a->ops->lookup == NULL)
721
goto err_mod;
722
err = -ENOENT;
723
if (a->ops->lookup(a, index) == 0)
724
goto err_mod;
725
726
module_put(a->ops->owner);
727
return a;
728
729
err_mod:
730
module_put(a->ops->owner);
731
err_free:
732
kfree(a);
733
err_out:
734
return ERR_PTR(err);
735
}
736
737
static void cleanup_a(struct tc_action *act)
738
{
739
struct tc_action *a;
740
741
for (a = act; a; a = act) {
742
act = a->next;
743
kfree(a);
744
}
745
}
746
747
static struct tc_action *create_a(int i)
748
{
749
struct tc_action *act;
750
751
act = kzalloc(sizeof(*act), GFP_KERNEL);
752
if (act == NULL) {
753
pr_debug("create_a: failed to alloc!\n");
754
return NULL;
755
}
756
act->order = i;
757
return act;
758
}
759
760
static int tca_action_flush(struct net *net, struct nlattr *nla,
761
struct nlmsghdr *n, u32 pid)
762
{
763
struct sk_buff *skb;
764
unsigned char *b;
765
struct nlmsghdr *nlh;
766
struct tcamsg *t;
767
struct netlink_callback dcb;
768
struct nlattr *nest;
769
struct nlattr *tb[TCA_ACT_MAX + 1];
770
struct nlattr *kind;
771
struct tc_action *a = create_a(0);
772
int err = -ENOMEM;
773
774
if (a == NULL) {
775
pr_debug("tca_action_flush: couldnt create tc_action\n");
776
return err;
777
}
778
779
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
780
if (!skb) {
781
pr_debug("tca_action_flush: failed skb alloc\n");
782
kfree(a);
783
return err;
784
}
785
786
b = skb_tail_pointer(skb);
787
788
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
789
if (err < 0)
790
goto err_out;
791
792
err = -EINVAL;
793
kind = tb[TCA_ACT_KIND];
794
a->ops = tc_lookup_action(kind);
795
if (a->ops == NULL)
796
goto err_out;
797
798
nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t));
799
t = NLMSG_DATA(nlh);
800
t->tca_family = AF_UNSPEC;
801
t->tca__pad1 = 0;
802
t->tca__pad2 = 0;
803
804
nest = nla_nest_start(skb, TCA_ACT_TAB);
805
if (nest == NULL)
806
goto nla_put_failure;
807
808
err = a->ops->walk(skb, &dcb, RTM_DELACTION, a);
809
if (err < 0)
810
goto nla_put_failure;
811
if (err == 0)
812
goto noflush_out;
813
814
nla_nest_end(skb, nest);
815
816
nlh->nlmsg_len = skb_tail_pointer(skb) - b;
817
nlh->nlmsg_flags |= NLM_F_ROOT;
818
module_put(a->ops->owner);
819
kfree(a);
820
err = rtnetlink_send(skb, net, pid, RTNLGRP_TC,
821
n->nlmsg_flags & NLM_F_ECHO);
822
if (err > 0)
823
return 0;
824
825
return err;
826
827
nla_put_failure:
828
nlmsg_failure:
829
module_put(a->ops->owner);
830
err_out:
831
noflush_out:
832
kfree_skb(skb);
833
kfree(a);
834
return err;
835
}
836
837
static int
838
tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
839
u32 pid, int event)
840
{
841
int i, ret;
842
struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
843
struct tc_action *head = NULL, *act, *act_prev = NULL;
844
845
ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL);
846
if (ret < 0)
847
return ret;
848
849
if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) {
850
if (tb[1] != NULL)
851
return tca_action_flush(net, tb[1], n, pid);
852
else
853
return -EINVAL;
854
}
855
856
for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
857
act = tcf_action_get_1(tb[i], n, pid);
858
if (IS_ERR(act)) {
859
ret = PTR_ERR(act);
860
goto err;
861
}
862
act->order = i;
863
864
if (head == NULL)
865
head = act;
866
else
867
act_prev->next = act;
868
act_prev = act;
869
}
870
871
if (event == RTM_GETACTION)
872
ret = act_get_notify(net, pid, n, head, event);
873
else { /* delete */
874
struct sk_buff *skb;
875
876
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
877
if (!skb) {
878
ret = -ENOBUFS;
879
goto err;
880
}
881
882
if (tca_get_fill(skb, head, pid, n->nlmsg_seq, 0, event,
883
0, 1) <= 0) {
884
kfree_skb(skb);
885
ret = -EINVAL;
886
goto err;
887
}
888
889
/* now do the delete */
890
tcf_action_destroy(head, 0);
891
ret = rtnetlink_send(skb, net, pid, RTNLGRP_TC,
892
n->nlmsg_flags & NLM_F_ECHO);
893
if (ret > 0)
894
return 0;
895
return ret;
896
}
897
err:
898
cleanup_a(head);
899
return ret;
900
}
901
902
static int tcf_add_notify(struct net *net, struct tc_action *a,
903
u32 pid, u32 seq, int event, u16 flags)
904
{
905
struct tcamsg *t;
906
struct nlmsghdr *nlh;
907
struct sk_buff *skb;
908
struct nlattr *nest;
909
unsigned char *b;
910
int err = 0;
911
912
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
913
if (!skb)
914
return -ENOBUFS;
915
916
b = skb_tail_pointer(skb);
917
918
nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
919
t = NLMSG_DATA(nlh);
920
t->tca_family = AF_UNSPEC;
921
t->tca__pad1 = 0;
922
t->tca__pad2 = 0;
923
924
nest = nla_nest_start(skb, TCA_ACT_TAB);
925
if (nest == NULL)
926
goto nla_put_failure;
927
928
if (tcf_action_dump(skb, a, 0, 0) < 0)
929
goto nla_put_failure;
930
931
nla_nest_end(skb, nest);
932
933
nlh->nlmsg_len = skb_tail_pointer(skb) - b;
934
NETLINK_CB(skb).dst_group = RTNLGRP_TC;
935
936
err = rtnetlink_send(skb, net, pid, RTNLGRP_TC, flags & NLM_F_ECHO);
937
if (err > 0)
938
err = 0;
939
return err;
940
941
nla_put_failure:
942
nlmsg_failure:
943
kfree_skb(skb);
944
return -1;
945
}
946
947
948
static int
949
tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
950
u32 pid, int ovr)
951
{
952
int ret = 0;
953
struct tc_action *act;
954
struct tc_action *a;
955
u32 seq = n->nlmsg_seq;
956
957
act = tcf_action_init(nla, NULL, NULL, ovr, 0);
958
if (act == NULL)
959
goto done;
960
if (IS_ERR(act)) {
961
ret = PTR_ERR(act);
962
goto done;
963
}
964
965
/* dump then free all the actions after update; inserted policy
966
* stays intact
967
*/
968
ret = tcf_add_notify(net, act, pid, seq, RTM_NEWACTION, n->nlmsg_flags);
969
for (a = act; a; a = act) {
970
act = a->next;
971
kfree(a);
972
}
973
done:
974
return ret;
975
}
976
977
static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
978
{
979
struct net *net = sock_net(skb->sk);
980
struct nlattr *tca[TCA_ACT_MAX + 1];
981
u32 pid = skb ? NETLINK_CB(skb).pid : 0;
982
int ret = 0, ovr = 0;
983
984
ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL);
985
if (ret < 0)
986
return ret;
987
988
if (tca[TCA_ACT_TAB] == NULL) {
989
pr_notice("tc_ctl_action: received NO action attribs\n");
990
return -EINVAL;
991
}
992
993
/* n->nlmsg_flags & NLM_F_CREATE */
994
switch (n->nlmsg_type) {
995
case RTM_NEWACTION:
996
/* we are going to assume all other flags
997
* imply create only if it doesn't exist
998
* Note that CREATE | EXCL implies that
999
* but since we want avoid ambiguity (eg when flags
1000
* is zero) then just set this
1001
*/
1002
if (n->nlmsg_flags & NLM_F_REPLACE)
1003
ovr = 1;
1004
replay:
1005
ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, pid, ovr);
1006
if (ret == -EAGAIN)
1007
goto replay;
1008
break;
1009
case RTM_DELACTION:
1010
ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1011
pid, RTM_DELACTION);
1012
break;
1013
case RTM_GETACTION:
1014
ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1015
pid, RTM_GETACTION);
1016
break;
1017
default:
1018
BUG();
1019
}
1020
1021
return ret;
1022
}
1023
1024
static struct nlattr *
1025
find_dump_kind(const struct nlmsghdr *n)
1026
{
1027
struct nlattr *tb1, *tb2[TCA_ACT_MAX + 1];
1028
struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
1029
struct nlattr *nla[TCAA_MAX + 1];
1030
struct nlattr *kind;
1031
1032
if (nlmsg_parse(n, sizeof(struct tcamsg), nla, TCAA_MAX, NULL) < 0)
1033
return NULL;
1034
tb1 = nla[TCA_ACT_TAB];
1035
if (tb1 == NULL)
1036
return NULL;
1037
1038
if (nla_parse(tb, TCA_ACT_MAX_PRIO, nla_data(tb1),
1039
NLMSG_ALIGN(nla_len(tb1)), NULL) < 0)
1040
return NULL;
1041
1042
if (tb[1] == NULL)
1043
return NULL;
1044
if (nla_parse(tb2, TCA_ACT_MAX, nla_data(tb[1]),
1045
nla_len(tb[1]), NULL) < 0)
1046
return NULL;
1047
kind = tb2[TCA_ACT_KIND];
1048
1049
return kind;
1050
}
1051
1052
static int
1053
tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1054
{
1055
struct nlmsghdr *nlh;
1056
unsigned char *b = skb_tail_pointer(skb);
1057
struct nlattr *nest;
1058
struct tc_action_ops *a_o;
1059
struct tc_action a;
1060
int ret = 0;
1061
struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
1062
struct nlattr *kind = find_dump_kind(cb->nlh);
1063
1064
if (kind == NULL) {
1065
pr_info("tc_dump_action: action bad kind\n");
1066
return 0;
1067
}
1068
1069
a_o = tc_lookup_action(kind);
1070
if (a_o == NULL)
1071
return 0;
1072
1073
memset(&a, 0, sizeof(struct tc_action));
1074
a.ops = a_o;
1075
1076
if (a_o->walk == NULL) {
1077
WARN(1, "tc_dump_action: %s !capable of dumping table\n",
1078
a_o->kind);
1079
goto nla_put_failure;
1080
}
1081
1082
nlh = NLMSG_PUT(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
1083
cb->nlh->nlmsg_type, sizeof(*t));
1084
t = NLMSG_DATA(nlh);
1085
t->tca_family = AF_UNSPEC;
1086
t->tca__pad1 = 0;
1087
t->tca__pad2 = 0;
1088
1089
nest = nla_nest_start(skb, TCA_ACT_TAB);
1090
if (nest == NULL)
1091
goto nla_put_failure;
1092
1093
ret = a_o->walk(skb, cb, RTM_GETACTION, &a);
1094
if (ret < 0)
1095
goto nla_put_failure;
1096
1097
if (ret > 0) {
1098
nla_nest_end(skb, nest);
1099
ret = skb->len;
1100
} else
1101
nla_nest_cancel(skb, nest);
1102
1103
nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1104
if (NETLINK_CB(cb->skb).pid && ret)
1105
nlh->nlmsg_flags |= NLM_F_MULTI;
1106
module_put(a_o->owner);
1107
return skb->len;
1108
1109
nla_put_failure:
1110
nlmsg_failure:
1111
module_put(a_o->owner);
1112
nlmsg_trim(skb, b);
1113
return skb->len;
1114
}
1115
1116
static int __init tc_action_init(void)
1117
{
1118
rtnl_register(PF_UNSPEC, RTM_NEWACTION, tc_ctl_action, NULL);
1119
rtnl_register(PF_UNSPEC, RTM_DELACTION, tc_ctl_action, NULL);
1120
rtnl_register(PF_UNSPEC, RTM_GETACTION, tc_ctl_action, tc_dump_action);
1121
1122
return 0;
1123
}
1124
1125
subsys_initcall(tc_action_init);
1126
1127