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