vserver 1.9.3
[linux-2.6.git] / net / sched / act_api.c
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 <asm/uaccess.h>
15 #include <asm/system.h>
16 #include <asm/bitops.h>
17 #include <linux/config.h>
18 #include <linux/types.h>
19 #include <linux/kernel.h>
20 #include <linux/sched.h>
21 #include <linux/string.h>
22 #include <linux/mm.h>
23 #include <linux/socket.h>
24 #include <linux/sockios.h>
25 #include <linux/in.h>
26 #include <linux/errno.h>
27 #include <linux/interrupt.h>
28 #include <linux/netdevice.h>
29 #include <linux/skbuff.h>
30 #include <linux/rtnetlink.h>
31 #include <linux/init.h>
32 #include <linux/kmod.h>
33 #include <net/sock.h>
34 #include <net/pkt_sched.h>
35
36 #if 1 /* control */
37 #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
38 #else
39 #define DPRINTK(format,args...)
40 #endif
41 #if 0 /* data */
42 #define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args)
43 #else
44 #define D2PRINTK(format,args...)
45 #endif
46
47 static struct tc_action_ops *act_base = NULL;
48 static rwlock_t act_mod_lock = RW_LOCK_UNLOCKED;
49
50 int tcf_register_action(struct tc_action_ops *act)
51 {
52         struct tc_action_ops *a, **ap;
53
54         write_lock(&act_mod_lock);
55         for (ap = &act_base; (a=*ap)!=NULL; ap = &a->next) {
56                 if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) {
57                         write_unlock(&act_mod_lock);
58                         return -EEXIST;
59                 }
60         }
61
62         act->next = NULL;
63         *ap = act;
64
65         write_unlock(&act_mod_lock);
66
67         return 0;
68 }
69
70 int tcf_unregister_action(struct tc_action_ops *act)
71 {
72         struct tc_action_ops *a, **ap;
73         int err = -ENOENT;
74
75         write_lock(&act_mod_lock);
76         for (ap = &act_base; (a=*ap)!=NULL; ap = &a->next) 
77                 if(a == act)
78                         break;
79
80         if (a) {
81                 *ap = a->next;
82                 a->next = NULL;
83                 err = 0;
84         }
85         write_unlock(&act_mod_lock);
86         return err;
87 }
88
89 /* lookup by name */
90 struct tc_action_ops *tc_lookup_action_n(char *kind)
91 {
92
93         struct tc_action_ops *a = NULL;
94
95         if (kind) {
96                 read_lock(&act_mod_lock);
97                 for (a = act_base; a; a = a->next) {
98                         if (strcmp(kind,a->kind) == 0) {
99                                 if (!try_module_get(a->owner)) {
100                                         read_unlock(&act_mod_lock);
101                                         return NULL;
102                                 } 
103                                 break;
104                         }
105                 }
106                 read_unlock(&act_mod_lock);
107         }
108
109         return a;
110 }
111
112 /* lookup by rtattr */
113 struct tc_action_ops *tc_lookup_action(struct rtattr *kind)
114 {
115
116         struct tc_action_ops *a = NULL;
117
118         if (kind) {
119                 read_lock(&act_mod_lock);
120                 for (a = act_base; a; a = a->next) {
121
122                         if (strcmp((char*)RTA_DATA(kind),a->kind) == 0){
123                                 if (!try_module_get(a->owner)) {
124                                         read_unlock(&act_mod_lock);
125                                         return NULL;
126                                 } 
127                                 break;
128                         }
129                 }
130                 read_unlock(&act_mod_lock);
131         }
132
133         return a;
134 }
135
136 /* lookup by id */
137 struct tc_action_ops *tc_lookup_action_id(u32 type)
138 {
139         struct tc_action_ops *a = NULL;
140
141         if (type) {
142                 read_lock(&act_mod_lock);
143                 for (a = act_base; a; a = a->next) {
144                         if (a->type == type) {
145                                 if (!try_module_get(a->owner)) {
146                                         read_unlock(&act_mod_lock);
147                                         return NULL;
148                                 } 
149                                 break;
150                         }
151                 }
152                 read_unlock(&act_mod_lock);
153         }
154
155         return a;
156 }
157
158 int tcf_action_exec(struct sk_buff *skb,struct tc_action *act, struct tcf_result *res)
159 {
160
161         struct tc_action *a;
162         int ret = -1; 
163
164         if (skb->tc_verd & TC_NCLS) {
165                 skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
166                 D2PRINTK("(%p)tcf_action_exec: cleared TC_NCLS in %s out %s\n",skb,skb->input_dev?skb->input_dev->name:"xxx",skb->dev->name);
167                 ret = TC_ACT_OK;
168                 goto exec_done;
169         }
170         while ((a = act) != NULL) {
171 repeat:
172                 if (a->ops && a->ops->act) {
173                         ret = a->ops->act(&skb,a);
174                                 if (TC_MUNGED & skb->tc_verd) {
175                                         /* copied already, allow trampling */
176                                         skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
177                                         skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd);
178                                 }
179
180                         if (ret != TC_ACT_PIPE)
181                                 goto exec_done;
182                         if (ret == TC_ACT_REPEAT)
183                                 goto repeat;    /* we need a ttl - JHS */
184
185                 }
186                 act = a->next;
187         }
188
189 exec_done:
190         if (skb->tc_classid > 0) {
191                 res->classid = skb->tc_classid;
192                 res->class = 0;
193                 skb->tc_classid = 0;
194         }
195
196         return ret;
197 }
198
199 void tcf_action_destroy(struct tc_action *act, int bind)
200 {
201         struct tc_action *a;
202
203         for (a = act; act; a = act) {
204                 if (a && a->ops && a->ops->cleanup) {
205                         DPRINTK("tcf_action_destroy destroying %p next %p\n", a,a->next?a->next:NULL);
206                         act = act->next;
207                         if (ACT_P_DELETED == a->ops->cleanup(a, bind)) {
208                                 module_put(a->ops->owner);
209                         }
210                         
211                         a->ops = NULL;  
212                         kfree(a);
213                 } else { /*FIXME: Remove later - catch insertion bugs*/
214                         printk("tcf_action_destroy: BUG? destroying NULL ops \n");
215                         if (a) {
216                                 act = act->next;
217                                 kfree(a);
218                         } else {
219                                 printk("tcf_action_destroy: BUG? destroying NULL action! \n");
220                                 break;
221                         }
222                 }
223         }
224 }
225
226 int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
227 {
228         int err = -EINVAL;
229
230
231         if ( (NULL == a) || (NULL == a->ops)
232            || (NULL == a->ops->dump) )
233                 return err;
234         return a->ops->dump(skb, a, bind, ref);
235
236 }
237
238
239 int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
240 {
241         int err = -EINVAL;
242         unsigned char    *b = skb->tail;
243         struct rtattr *r;
244
245
246         if ( (NULL == a) || (NULL == a->ops)
247            || (NULL == a->ops->dump) || (NULL == a->ops->kind))
248                 return err;
249
250
251         RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
252         if (tcf_action_copy_stats(skb,a))
253                 goto rtattr_failure;
254         r = (struct rtattr*) skb->tail;
255         RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
256         if ((err = tcf_action_dump_old(skb, a, bind, ref)) > 0) {
257                 r->rta_len = skb->tail - (u8*)r;
258                 return err;
259         }
260
261
262 rtattr_failure:
263         skb_trim(skb, b - skb->data);
264         return -1;
265
266 }
267
268 int tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
269 {
270         struct tc_action *a;
271         int err = -EINVAL;
272         unsigned char    *b = skb->tail;
273         struct rtattr *r ;
274
275         while ((a = act) != NULL) {
276                 r = (struct rtattr*) skb->tail;
277                 act = a->next;
278                 RTA_PUT(skb, a->order, 0, NULL);
279                 err = tcf_action_dump_1(skb, a, bind, ref);
280                 if (0 > err) 
281                         goto rtattr_failure;
282
283                 r->rta_len = skb->tail - (u8*)r;
284         }
285
286         return 0;
287
288 rtattr_failure:
289         skb_trim(skb, b - skb->data);
290         return -err;
291         
292 }
293
294 int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action *a, char *name, int ovr, int bind )
295 {
296         struct tc_action_ops *a_o;
297         char act_name[4 + IFNAMSIZ + 1];
298         struct rtattr *tb[TCA_ACT_MAX+1];
299         struct rtattr *kind = NULL;
300
301         int err = -EINVAL;
302
303         if (NULL == name) {
304                 if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta))<0)
305                         goto err_out;
306                 kind = tb[TCA_ACT_KIND-1];
307                 if (NULL != kind) {
308                         sprintf(act_name, "%s", (char*)RTA_DATA(kind));
309                         if (RTA_PAYLOAD(kind) >= IFNAMSIZ) {
310                                 printk(" Action %s bad\n", (char*)RTA_DATA(kind));
311                                 goto err_out;
312                         }
313
314                 } else {
315                         printk("Action bad kind\n");
316                         goto err_out;
317                 }
318                 a_o = tc_lookup_action(kind);
319         } else {
320                 sprintf(act_name, "%s", name);
321                 DPRINTK("tcf_action_init_1: finding  %s\n",act_name);
322                 a_o = tc_lookup_action_n(name);
323         }
324 #ifdef CONFIG_KMOD
325         if (NULL == a_o) {
326                 DPRINTK("tcf_action_init_1: trying to load module %s\n",act_name);
327                 request_module (act_name);
328                 a_o = tc_lookup_action_n(act_name);
329         }
330
331 #endif
332         if (NULL == a_o) {
333                 printk("failed to find %s\n",act_name);
334                 goto err_out;
335         }
336
337         if (NULL == a) {
338                 goto err_mod;
339         }
340
341         /* backward compatibility for policer */
342         if (NULL == name) {
343                 err = a_o->init(tb[TCA_ACT_OPTIONS-1], est, a, ovr, bind);
344                 if (0 > err ) {
345                         err = -EINVAL;
346                         goto err_mod;
347                 }
348         } else {
349                 err = a_o->init(rta, est, a, ovr, bind);
350                 if (0 > err ) {
351                         err = -EINVAL;
352                         goto err_mod;
353                 }
354         }
355
356         /* module count goes up only when brand new policy is created
357            if it exists and is only bound to in a_o->init() then
358            ACT_P_CREATED is not returned (a zero is).
359         */
360         if (ACT_P_CREATED != err) {
361                 module_put(a_o->owner);
362         } 
363         a->ops = a_o;
364         DPRINTK("tcf_action_init_1: successfull %s \n",act_name);
365
366         return 0;
367 err_mod:
368         module_put(a_o->owner);
369 err_out:
370         return err;
371 }
372
373 int tcf_action_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, char *name, int ovr , int bind)
374 {
375         struct rtattr *tb[TCA_ACT_MAX_PRIO+1];
376         int i;
377         struct tc_action *act = a, *a_s = a;
378
379         int err = -EINVAL;
380
381         if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(rta), RTA_PAYLOAD(rta))<0)
382                 return err;
383
384         for (i=0; i < TCA_ACT_MAX_PRIO ; i++) {
385                 if (tb[i]) {
386                         if (NULL == act) {
387                                 act = kmalloc(sizeof(*act),GFP_KERNEL);
388                                 if (NULL == act) {
389                                         err = -ENOMEM;
390                                         goto bad_ret;
391                                 }
392                                 memset(act, 0,sizeof(*act));
393                         }
394                         act->next = NULL;
395                         if (0 > tcf_action_init_1(tb[i],est,act,name,ovr,bind)) {
396                                 printk("Error processing action order %d\n",i);
397                                 return err;
398                         }
399
400                         act->order = i+1;
401                         if (a_s != act) {
402                                 a_s->next = act;
403                                 a_s = act;
404                         }
405                         act = NULL;
406                 }
407
408         }
409
410         return 0;
411 bad_ret:
412         tcf_action_destroy(a, bind);
413         return err;
414 }
415
416 int tcf_action_copy_stats (struct sk_buff *skb,struct tc_action *a)
417 {
418 #ifdef CONFIG_KMOD
419         /* place holder */
420 #endif
421
422         if (NULL == a->ops || NULL == a->ops->get_stats)
423                 return 1;
424
425         return a->ops->get_stats(skb,a);
426 }
427
428
429 static int
430 tca_get_fill(struct sk_buff *skb,  struct tc_action *a,
431               u32 pid, u32 seq, unsigned flags, int event, int bind, int ref)
432 {
433         struct tcamsg *t;
434         struct nlmsghdr  *nlh;
435         unsigned char    *b = skb->tail;
436         struct rtattr *x;
437
438         nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*t));
439         nlh->nlmsg_flags = flags;
440         t = NLMSG_DATA(nlh);
441         t->tca_family = AF_UNSPEC;
442         
443         x = (struct rtattr*) skb->tail;
444         RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
445
446         if (0 > tcf_action_dump(skb, a, bind, ref)) {
447                 goto rtattr_failure;
448         }
449
450         x->rta_len = skb->tail - (u8*)x;
451         
452         nlh->nlmsg_len = skb->tail - b;
453         return skb->len;
454
455 rtattr_failure:
456 nlmsg_failure:
457         skb_trim(skb, b - skb->data);
458         return -1;
459 }
460
461 static int act_get_notify(u32 pid, struct nlmsghdr *n,
462                            struct tc_action *a, int event)
463 {
464         struct sk_buff *skb;
465
466         int err = 0;
467
468         skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
469         if (!skb)
470                 return -ENOBUFS;
471
472         if (tca_get_fill(skb, a,  pid, n->nlmsg_seq, 0, event, 0, 0) <= 0) {
473                 kfree_skb(skb);
474                 return -EINVAL;
475         }
476
477         err =  netlink_unicast(rtnl,skb, pid, MSG_DONTWAIT);
478         if (err > 0)
479                 err = 0;
480         return err;
481 }
482
483 int tcf_action_get_1(struct rtattr *rta, struct tc_action *a, struct nlmsghdr *n, u32 pid)
484 {
485         struct tc_action_ops *a_o;
486         char act_name[4 + IFNAMSIZ + 1];
487         struct rtattr *tb[TCA_ACT_MAX+1];
488         struct rtattr *kind = NULL;
489         int index;
490
491         int err = -EINVAL;
492
493         if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta))<0)
494                 goto err_out;
495
496
497         kind = tb[TCA_ACT_KIND-1];
498         if (NULL != kind) {
499                 sprintf(act_name, "%s", (char*)RTA_DATA(kind));
500                 if (RTA_PAYLOAD(kind) >= IFNAMSIZ) {
501                         printk("tcf_action_get_1: action %s bad\n", (char*)RTA_DATA(kind));
502                         goto err_out;
503                 }
504
505         } else {
506                 printk("tcf_action_get_1: action bad kind\n");
507                 goto err_out;
508         }
509
510         if (tb[TCA_ACT_INDEX - 1]) {
511                 index = *(int *)RTA_DATA(tb[TCA_ACT_INDEX - 1]);
512         } else {
513                 printk("tcf_action_get_1: index not received\n");
514                 goto err_out;
515         }
516
517         a_o = tc_lookup_action(kind);
518 #ifdef CONFIG_KMOD
519         if (NULL == a_o) {
520                 request_module (act_name);
521                 a_o = tc_lookup_action_n(act_name);
522         }
523
524 #endif
525         if (NULL == a_o) {
526                 printk("failed to find %s\n",act_name);
527                 goto err_out;
528         }
529
530         if (NULL == a) {
531                 goto err_mod;
532         }
533
534         a->ops = a_o;
535
536         if (NULL == a_o->lookup || 0 == a_o->lookup(a, index)) {
537                 a->ops = NULL;
538                 err = -EINVAL;
539                 goto err_mod;
540         }
541
542         module_put(a_o->owner);
543         return 0;
544 err_mod:
545         module_put(a_o->owner);
546 err_out:
547         return err;
548 }
549
550 void cleanup_a (struct tc_action *act) 
551 {
552         struct tc_action *a;
553
554         for (a = act; act; a = act) {
555                 if (a) {
556                         act = act->next;
557                         a->ops = NULL;
558                         a->priv = NULL;
559                         kfree(a);
560                 } else {
561                         printk("cleanup_a: BUG? empty action\n");
562                 }
563         }
564 }
565
566 struct tc_action_ops *get_ao(struct rtattr *kind, struct tc_action *a)
567 {
568         char act_name[4 + IFNAMSIZ + 1];
569         struct tc_action_ops *a_o = NULL;
570
571         if (NULL != kind) {
572                 sprintf(act_name, "%s", (char*)RTA_DATA(kind));
573                 if (RTA_PAYLOAD(kind) >= IFNAMSIZ) {
574                         printk("get_ao: action %s bad\n", (char*)RTA_DATA(kind));
575                         return NULL;
576                 }
577
578         } else {
579                 printk("get_ao: action bad kind\n");
580                 return NULL;
581         }
582
583         a_o = tc_lookup_action(kind);
584 #ifdef CONFIG_KMOD
585         if (NULL == a_o) {
586                 DPRINTK("get_ao: trying to load module %s\n",act_name);
587                 request_module (act_name);
588                 a_o = tc_lookup_action_n(act_name);
589         }
590 #endif
591
592         if (NULL == a_o) {
593                 printk("get_ao: failed to find %s\n",act_name);
594                 return NULL;
595         }
596
597         a->ops = a_o;
598         return a_o;
599 }
600
601 struct tc_action *create_a(int i)
602 {
603         struct tc_action *act = NULL;
604
605         act = kmalloc(sizeof(*act),GFP_KERNEL);
606         if (NULL == act) { /* grrr .. */
607                 printk("create_a: failed to alloc! \n");
608                 return NULL;
609         }
610
611         memset(act, 0,sizeof(*act));
612
613         act->order = i;
614
615         return act;
616 }
617
618 int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid)
619 {
620         struct sk_buff *skb;
621         unsigned char *b;
622         struct nlmsghdr *nlh;
623         struct tcamsg *t;
624         struct netlink_callback dcb;
625         struct rtattr *x;
626         struct rtattr *tb[TCA_ACT_MAX+1];
627         struct rtattr *kind = NULL;
628         struct tc_action *a = create_a(0);
629         int err = -EINVAL;
630
631         if (NULL == a) {
632                 printk("tca_action_flush: couldnt create tc_action\n");
633                 return err;
634         }
635
636         skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
637         if (!skb) {
638                 printk("tca_action_flush: failed skb alloc\n");
639                 kfree(a);
640                 return -ENOBUFS;
641         }
642
643         b = (unsigned char *)skb->tail;
644
645         if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta))<0) {
646                 goto err_out;
647         }
648
649         kind = tb[TCA_ACT_KIND-1];
650         if (NULL == get_ao(kind, a)) {
651                 goto err_out;
652         }
653
654         nlh = NLMSG_PUT(skb, pid,  n->nlmsg_seq, RTM_DELACTION, sizeof (*t));
655         t = NLMSG_DATA(nlh);
656         t->tca_family = AF_UNSPEC;
657
658         x = (struct rtattr *) skb->tail;
659         RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
660
661         err = a->ops->walk(skb, &dcb, RTM_DELACTION, a);
662         if (0 > err ) {
663                 goto rtattr_failure;
664         }
665
666         x->rta_len = skb->tail - (u8 *) x;
667
668         nlh->nlmsg_len = skb->tail - b;
669         nlh->nlmsg_flags |= NLM_F_ROOT;
670         module_put(a->ops->owner);
671         kfree(a);
672         err = rtnetlink_send(skb, pid, RTMGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
673         if (err > 0)
674                 return 0;
675
676         return err;
677
678
679 rtattr_failure:
680         module_put(a->ops->owner);
681 nlmsg_failure:
682 err_out:
683         kfree_skb(skb);
684         kfree(a);
685         return err;
686 }
687
688 int tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event )
689 {
690
691         int s = 0;
692         int i, ret = 0;
693         struct tc_action *act = NULL;
694         struct rtattr *tb[TCA_ACT_MAX_PRIO+1];
695         struct tc_action *a = NULL, *a_s = NULL;
696
697         if (event != RTM_GETACTION  && event != RTM_DELACTION)
698                 ret = -EINVAL;
699
700         if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(rta), RTA_PAYLOAD(rta))<0) {
701                 ret = -EINVAL;
702                 goto nlmsg_failure;
703         }
704
705         if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) {
706                 if (NULL != tb[0]  && NULL == tb[1]) {
707                         return tca_action_flush(tb[0],n,pid);
708                 }
709         }
710
711         for (i=0; i < TCA_ACT_MAX_PRIO ; i++) {
712
713                 if (NULL == tb[i])
714                         break;
715
716                 act = create_a(i+1);
717                 if (NULL != a && a != act) {
718                         a->next = act;
719                         a = act;
720                 } else {
721                         a = act;
722                 }
723
724                 if (!s) {
725                         s = 1;
726                         a_s = a;
727                 }
728
729                 ret = tcf_action_get_1(tb[i],act,n,pid);
730                 if (ret < 0) {
731                         printk("tcf_action_get: failed to get! \n");
732                         ret = -EINVAL;
733                         goto rtattr_failure;
734                 }
735
736         }
737
738
739         if (RTM_GETACTION == event) {
740                 ret = act_get_notify(pid, n, a_s, event);
741         } else { /* delete */
742
743                 struct sk_buff *skb;
744
745                 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
746                 if (!skb) {
747                         ret = -ENOBUFS;
748                         goto nlmsg_failure;
749                 }
750
751                 if (tca_get_fill(skb, a_s,  pid, n->nlmsg_seq, 0, event, 0 , 1) <= 0) {
752                         kfree_skb(skb);
753                         ret = -EINVAL;
754                         goto nlmsg_failure;
755                 }
756
757                 /* now do the delete */
758                 tcf_action_destroy(a_s, 0);
759
760                 ret = rtnetlink_send(skb, pid, RTMGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
761                 if (ret > 0)
762                         return 0;
763                 return ret;
764         }
765 rtattr_failure:
766 nlmsg_failure:
767         cleanup_a(a_s);
768         return ret;
769 }
770
771
772 int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, unsigned flags) 
773 {
774         struct tcamsg *t;
775         struct nlmsghdr  *nlh;
776         struct sk_buff *skb;
777         struct rtattr *x;
778         unsigned char *b;
779
780
781         int err = 0;
782
783         skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
784         if (!skb)
785                 return -ENOBUFS;
786
787         b = (unsigned char *)skb->tail;
788
789         nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*t));
790         nlh->nlmsg_flags = flags;
791         t = NLMSG_DATA(nlh);
792         t->tca_family = AF_UNSPEC;
793         
794         x = (struct rtattr*) skb->tail;
795         RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
796
797         if (0 > tcf_action_dump(skb, a, 0, 0)) {
798                 goto rtattr_failure;
799         }
800
801         x->rta_len = skb->tail - (u8*)x;
802         
803         nlh->nlmsg_len = skb->tail - b;
804         NETLINK_CB(skb).dst_groups = RTMGRP_TC;
805         
806         err = rtnetlink_send(skb, pid, RTMGRP_TC, flags&NLM_F_ECHO);
807         if (err > 0)
808                 err = 0;
809
810         return err;
811
812 rtattr_failure:
813 nlmsg_failure:
814         skb_trim(skb, b - skb->data);
815         return -1;
816 }
817
818         
819 int tcf_action_add(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int ovr ) 
820 {
821         int ret = 0;
822         struct tc_action *act = NULL;
823         struct tc_action *a = NULL;
824         u32 seq = n->nlmsg_seq;
825
826         act = kmalloc(sizeof(*act),GFP_KERNEL);
827         if (NULL == act)
828                 return -ENOMEM;
829
830         memset(act, 0, sizeof(*act));
831
832         ret = tcf_action_init(rta, NULL,act,NULL,ovr,0);
833         /* NOTE: We have an all-or-none model
834          * This means that of any of the actions fail
835          * to update then all are undone.
836          * */
837         if (0 > ret) {
838                 tcf_action_destroy(act, 0);
839                 goto done;
840         }
841
842         /* dump then free all the actions after update; inserted policy
843          * stays intact
844          * */
845         ret = tcf_add_notify(act, pid, seq, RTM_NEWACTION, n->nlmsg_flags); 
846         for (a = act; act; a = act) {
847                 if (a) {
848                         act = act->next;
849                         a->ops = NULL;
850                         a->priv = NULL;
851                         kfree(a);
852                 } else {
853                         printk("tcf_action_add: BUG? empty action\n");
854                 }
855         }
856 done:
857
858         return ret;
859 }
860
861 static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
862 {
863         struct rtattr **tca = arg;
864         u32 pid = skb ? NETLINK_CB(skb).pid : 0;
865
866         int ret = 0, ovr = 0;
867
868         if (NULL == tca[TCA_ACT_TAB-1]) {
869                         printk("tc_ctl_action: received NO action attribs\n");
870                         return -EINVAL;
871         }
872
873         /* n->nlmsg_flags&NLM_F_CREATE
874          * */
875         switch (n->nlmsg_type) {
876         case RTM_NEWACTION:    
877                 /* we are going to assume all other flags
878                  * imply create only if it doesnt exist
879                  * Note that CREATE | EXCL implies that
880                  * but since we want avoid ambiguity (eg when flags
881                  * is zero) then just set this
882                  */
883                 if (n->nlmsg_flags&NLM_F_REPLACE) {
884                         ovr = 1;
885                 }
886                 ret =  tcf_action_add(tca[TCA_ACT_TAB-1], n, pid, ovr);
887                 break;
888         case RTM_DELACTION:
889                 ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid,RTM_DELACTION);
890                 break;
891         case RTM_GETACTION:
892                 ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid,RTM_GETACTION);
893                 break;
894         default:
895                 printk(" Unknown cmd was detected\n");
896                 break;
897         }
898
899         return ret;
900 }
901
902 char *
903 find_dump_kind(struct nlmsghdr *n)
904 {
905         struct rtattr *tb1, *tb2[TCA_ACT_MAX+1];
906         struct rtattr *tb[TCA_ACT_MAX_PRIO + 1];
907         struct rtattr *rta[TCAA_MAX + 1];
908         struct rtattr *kind = NULL;
909         int min_len = NLMSG_LENGTH(sizeof (struct tcamsg));
910
911         int attrlen = n->nlmsg_len - NLMSG_ALIGN(min_len);
912         struct rtattr *attr = (void *) n + NLMSG_ALIGN(min_len);
913
914         if (rtattr_parse(rta, TCAA_MAX, attr, attrlen) < 0)
915                 return NULL;
916         tb1 = rta[TCA_ACT_TAB - 1];
917         if (NULL == tb1) {
918                 return NULL;
919         }
920
921         if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(tb1), NLMSG_ALIGN(RTA_PAYLOAD(tb1))) < 0)
922                 return NULL;
923         if (NULL == tb[0]) 
924                 return NULL;
925
926         if (rtattr_parse(tb2, TCA_ACT_MAX, RTA_DATA(tb[0]), RTA_PAYLOAD(tb[0]))<0)
927                 return NULL;
928         kind = tb2[TCA_ACT_KIND-1];
929
930         return (char *) RTA_DATA(kind);
931 }
932
933 static int
934 tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
935 {
936         struct nlmsghdr *nlh;
937         unsigned char *b = skb->tail;
938         struct rtattr *x;
939         struct tc_action_ops *a_o;
940         struct tc_action a;
941         int ret = 0;
942
943         struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
944         char *kind = find_dump_kind(cb->nlh);
945         if (NULL == kind) {
946                 printk("tc_dump_action: action bad kind\n");
947                 return 0;
948         }
949
950         a_o = tc_lookup_action_n(kind);
951
952         if (NULL == a_o) {
953                 printk("failed to find %s\n", kind);
954                 return 0;
955         }
956
957         memset(&a,0,sizeof(struct tc_action));
958         a.ops = a_o;
959
960         if (NULL == a_o->walk) {
961                 printk("tc_dump_action: %s !capable of dumping table\n",kind);
962                 goto rtattr_failure;
963         }
964
965         nlh = NLMSG_PUT(skb, NETLINK_CB(cb->skb).pid,  cb->nlh->nlmsg_seq, cb->nlh->nlmsg_type, sizeof (*t));
966         t = NLMSG_DATA(nlh);
967         t->tca_family = AF_UNSPEC;
968
969         x = (struct rtattr *) skb->tail;
970         RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
971
972         ret = a_o->walk(skb, cb, RTM_GETACTION, &a);
973         if (0 > ret ) {
974                 goto rtattr_failure;
975         }
976
977         if (ret > 0) {
978                 x->rta_len = skb->tail - (u8 *) x;
979                 ret = skb->len;
980         } else {
981                 skb_trim(skb, (u8*)x - skb->data);
982         }
983
984         nlh->nlmsg_len = skb->tail - b;
985         if (NETLINK_CB(cb->skb).pid && ret) 
986                 nlh->nlmsg_flags |= NLM_F_MULTI;
987         module_put(a_o->owner);
988         return skb->len;
989
990 rtattr_failure:
991 nlmsg_failure:
992         module_put(a_o->owner);
993         skb_trim(skb, b - skb->data);
994         return skb->len;
995 }
996
997 static int __init tc_action_init(void)
998 {
999         struct rtnetlink_link *link_p = rtnetlink_links[PF_UNSPEC];
1000
1001         if (link_p) {
1002                 link_p[RTM_NEWACTION-RTM_BASE].doit = tc_ctl_action;
1003                 link_p[RTM_DELACTION-RTM_BASE].doit = tc_ctl_action;
1004                 link_p[RTM_GETACTION-RTM_BASE].doit = tc_ctl_action;
1005                 link_p[RTM_GETACTION-RTM_BASE].dumpit = tc_dump_action;
1006         }
1007
1008         printk("TC classifier action (bugs to netdev@oss.sgi.com cc hadi@cyberus.ca)\n");
1009         return 0;
1010 }
1011
1012 subsys_initcall(tc_action_init);
1013
1014 EXPORT_SYMBOL(tcf_register_action);
1015 EXPORT_SYMBOL(tcf_unregister_action);
1016 EXPORT_SYMBOL(tcf_action_init_1);
1017 EXPORT_SYMBOL(tcf_action_init);
1018 EXPORT_SYMBOL(tcf_action_destroy);
1019 EXPORT_SYMBOL(tcf_action_exec);
1020 EXPORT_SYMBOL(tcf_action_copy_stats);
1021 EXPORT_SYMBOL(tcf_action_dump);
1022 EXPORT_SYMBOL(tcf_action_dump_1);
1023 EXPORT_SYMBOL(tcf_action_dump_old);