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