xref: /openbmc/linux/net/sched/act_api.c (revision 9ce7677c)
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 0 /* 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, res);
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_REPEAT)
175 				goto repeat;	/* we need a ttl - JHS */
176 			if (ret != TC_ACT_PIPE)
177 				goto exec_done;
178 		}
179 		act = a->next;
180 	}
181 exec_done:
182 	return ret;
183 }
184 
185 void tcf_action_destroy(struct tc_action *act, int bind)
186 {
187 	struct tc_action *a;
188 
189 	for (a = act; a; a = act) {
190 		if (a->ops && a->ops->cleanup) {
191 			DPRINTK("tcf_action_destroy destroying %p next %p\n",
192 			        a, a->next);
193 			if (a->ops->cleanup(a, bind) == ACT_P_DELETED)
194 				module_put(a->ops->owner);
195 			act = act->next;
196 			kfree(a);
197 		} else { /*FIXME: Remove later - catch insertion bugs*/
198 			printk("tcf_action_destroy: BUG? destroying NULL ops\n");
199 			act = act->next;
200 			kfree(a);
201 		}
202 	}
203 }
204 
205 int
206 tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
207 {
208 	int err = -EINVAL;
209 
210 	if (a->ops == NULL || a->ops->dump == NULL)
211 		return err;
212 	return a->ops->dump(skb, a, bind, ref);
213 }
214 
215 int
216 tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
217 {
218 	int err = -EINVAL;
219 	unsigned char *b = skb->tail;
220 	struct rtattr *r;
221 
222 	if (a->ops == NULL || a->ops->dump == NULL)
223 		return err;
224 
225 	RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
226 	if (tcf_action_copy_stats(skb, a, 0))
227 		goto rtattr_failure;
228 	r = (struct rtattr*) skb->tail;
229 	RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
230 	if ((err = tcf_action_dump_old(skb, a, bind, ref)) > 0) {
231 		r->rta_len = skb->tail - (u8*)r;
232 		return err;
233 	}
234 
235 rtattr_failure:
236 	skb_trim(skb, b - skb->data);
237 	return -1;
238 }
239 
240 int
241 tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
242 {
243 	struct tc_action *a;
244 	int err = -EINVAL;
245 	unsigned char *b = skb->tail;
246 	struct rtattr *r ;
247 
248 	while ((a = act) != NULL) {
249 		r = (struct rtattr*) skb->tail;
250 		act = a->next;
251 		RTA_PUT(skb, a->order, 0, NULL);
252 		err = tcf_action_dump_1(skb, a, bind, ref);
253 		if (err < 0)
254 			goto rtattr_failure;
255 		r->rta_len = skb->tail - (u8*)r;
256 	}
257 
258 	return 0;
259 
260 rtattr_failure:
261 	skb_trim(skb, b - skb->data);
262 	return -err;
263 }
264 
265 struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est,
266                                     char *name, int ovr, int bind, int *err)
267 {
268 	struct tc_action *a;
269 	struct tc_action_ops *a_o;
270 	char act_name[IFNAMSIZ];
271 	struct rtattr *tb[TCA_ACT_MAX+1];
272 	struct rtattr *kind;
273 
274 	*err = -EINVAL;
275 
276 	if (name == NULL) {
277 		if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0)
278 			goto err_out;
279 		kind = tb[TCA_ACT_KIND-1];
280 		if (kind == NULL)
281 			goto err_out;
282 		if (rtattr_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
283 			goto err_out;
284 	} else {
285 		if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ)
286 			goto err_out;
287 	}
288 
289 	a_o = tc_lookup_action_n(act_name);
290 	if (a_o == NULL) {
291 #ifdef CONFIG_KMOD
292 		rtnl_unlock();
293 		request_module(act_name);
294 		rtnl_lock();
295 
296 		a_o = tc_lookup_action_n(act_name);
297 
298 		/* We dropped the RTNL semaphore in order to
299 		 * perform the module load.  So, even if we
300 		 * succeeded in loading the module we have to
301 		 * tell the caller to replay the request.  We
302 		 * indicate this using -EAGAIN.
303 		 */
304 		if (a_o != NULL) {
305 			*err = -EAGAIN;
306 			goto err_mod;
307 		}
308 #endif
309 		goto err_out;
310 	}
311 
312 	*err = -ENOMEM;
313 	a = kmalloc(sizeof(*a), GFP_KERNEL);
314 	if (a == NULL)
315 		goto err_mod;
316 	memset(a, 0, sizeof(*a));
317 
318 	/* backward compatibility for policer */
319 	if (name == NULL)
320 		*err = a_o->init(tb[TCA_ACT_OPTIONS-1], est, a, ovr, bind);
321 	else
322 		*err = a_o->init(rta, est, a, ovr, bind);
323 	if (*err < 0)
324 		goto err_free;
325 
326 	/* module count goes up only when brand new policy is created
327 	   if it exists and is only bound to in a_o->init() then
328 	   ACT_P_CREATED is not returned (a zero is).
329 	*/
330 	if (*err != ACT_P_CREATED)
331 		module_put(a_o->owner);
332 	a->ops = a_o;
333 	DPRINTK("tcf_action_init_1: successfull %s\n", act_name);
334 
335 	*err = 0;
336 	return a;
337 
338 err_free:
339 	kfree(a);
340 err_mod:
341 	module_put(a_o->owner);
342 err_out:
343 	return NULL;
344 }
345 
346 struct tc_action *tcf_action_init(struct rtattr *rta, struct rtattr *est,
347                                   char *name, int ovr, int bind, int *err)
348 {
349 	struct rtattr *tb[TCA_ACT_MAX_PRIO+1];
350 	struct tc_action *head = NULL, *act, *act_prev = NULL;
351 	int i;
352 
353 	if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0) {
354 		*err = -EINVAL;
355 		return head;
356 	}
357 
358 	for (i=0; i < TCA_ACT_MAX_PRIO && tb[i]; i++) {
359 		act = tcf_action_init_1(tb[i], est, name, ovr, bind, err);
360 		if (act == NULL)
361 			goto err;
362 		act->order = i+1;
363 
364 		if (head == NULL)
365 			head = act;
366 		else
367 			act_prev->next = act;
368 		act_prev = act;
369 	}
370 	return head;
371 
372 err:
373 	if (head != NULL)
374 		tcf_action_destroy(head, bind);
375 	return NULL;
376 }
377 
378 int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
379 			  int compat_mode)
380 {
381 	int err = 0;
382 	struct gnet_dump d;
383 	struct tcf_act_hdr *h = a->priv;
384 
385 	if (h == NULL)
386 		goto errout;
387 
388 	/* compat_mode being true specifies a call that is supposed
389 	 * to add additional backward compatiblity statistic TLVs.
390 	 */
391 	if (compat_mode) {
392 		if (a->type == TCA_OLD_COMPAT)
393 			err = gnet_stats_start_copy_compat(skb, 0,
394 				TCA_STATS, TCA_XSTATS, h->stats_lock, &d);
395 		else
396 			return 0;
397 	} else
398 		err = gnet_stats_start_copy(skb, TCA_ACT_STATS,
399 			h->stats_lock, &d);
400 
401 	if (err < 0)
402 		goto errout;
403 
404 	if (a->ops != NULL && a->ops->get_stats != NULL)
405 		if (a->ops->get_stats(skb, a) < 0)
406 			goto errout;
407 
408 	if (gnet_stats_copy_basic(&d, &h->bstats) < 0 ||
409 #ifdef CONFIG_NET_ESTIMATOR
410 	    gnet_stats_copy_rate_est(&d, &h->rate_est) < 0 ||
411 #endif
412 	    gnet_stats_copy_queue(&d, &h->qstats) < 0)
413 		goto errout;
414 
415 	if (gnet_stats_finish_copy(&d) < 0)
416 		goto errout;
417 
418 	return 0;
419 
420 errout:
421 	return -1;
422 }
423 
424 static int
425 tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
426              u16 flags, int event, int bind, int ref)
427 {
428 	struct tcamsg *t;
429 	struct nlmsghdr *nlh;
430 	unsigned char *b = skb->tail;
431 	struct rtattr *x;
432 
433 	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
434 
435 	t = NLMSG_DATA(nlh);
436 	t->tca_family = AF_UNSPEC;
437 	t->tca__pad1 = 0;
438 	t->tca__pad2 = 0;
439 
440 	x = (struct rtattr*) skb->tail;
441 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
442 
443 	if (tcf_action_dump(skb, a, bind, ref) < 0)
444 		goto rtattr_failure;
445 
446 	x->rta_len = skb->tail - (u8*)x;
447 
448 	nlh->nlmsg_len = skb->tail - b;
449 	return skb->len;
450 
451 rtattr_failure:
452 nlmsg_failure:
453 	skb_trim(skb, b - skb->data);
454 	return -1;
455 }
456 
457 static int
458 act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event)
459 {
460 	struct sk_buff *skb;
461 	int err = 0;
462 
463 	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
464 	if (!skb)
465 		return -ENOBUFS;
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 	err = netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT);
471 	if (err > 0)
472 		err = 0;
473 	return err;
474 }
475 
476 static struct tc_action *
477 tcf_action_get_1(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int *err)
478 {
479 	struct rtattr *tb[TCA_ACT_MAX+1];
480 	struct tc_action *a;
481 	int index;
482 
483 	*err = -EINVAL;
484 	if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0)
485 		return NULL;
486 
487 	if (tb[TCA_ACT_INDEX - 1] == NULL ||
488 	    RTA_PAYLOAD(tb[TCA_ACT_INDEX - 1]) < sizeof(index))
489 		return NULL;
490 	index = *(int *)RTA_DATA(tb[TCA_ACT_INDEX - 1]);
491 
492 	*err = -ENOMEM;
493 	a = kmalloc(sizeof(struct tc_action), GFP_KERNEL);
494 	if (a == NULL)
495 		return NULL;
496 	memset(a, 0, sizeof(struct tc_action));
497 
498 	*err = -EINVAL;
499 	a->ops = tc_lookup_action(tb[TCA_ACT_KIND - 1]);
500 	if (a->ops == NULL)
501 		goto err_free;
502 	if (a->ops->lookup == NULL)
503 		goto err_mod;
504 	*err = -ENOENT;
505 	if (a->ops->lookup(a, index) == 0)
506 		goto err_mod;
507 
508 	module_put(a->ops->owner);
509 	*err = 0;
510 	return a;
511 err_mod:
512 	module_put(a->ops->owner);
513 err_free:
514 	kfree(a);
515 	return NULL;
516 }
517 
518 static void cleanup_a(struct tc_action *act)
519 {
520 	struct tc_action *a;
521 
522 	for (a = act; a; a = act) {
523 		act = a->next;
524 		kfree(a);
525 	}
526 }
527 
528 static struct tc_action *create_a(int i)
529 {
530 	struct tc_action *act;
531 
532 	act = kmalloc(sizeof(*act), GFP_KERNEL);
533 	if (act == NULL) {
534 		printk("create_a: failed to alloc!\n");
535 		return NULL;
536 	}
537 	memset(act, 0, sizeof(*act));
538 	act->order = i;
539 	return act;
540 }
541 
542 static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid)
543 {
544 	struct sk_buff *skb;
545 	unsigned char *b;
546 	struct nlmsghdr *nlh;
547 	struct tcamsg *t;
548 	struct netlink_callback dcb;
549 	struct rtattr *x;
550 	struct rtattr *tb[TCA_ACT_MAX+1];
551 	struct rtattr *kind;
552 	struct tc_action *a = create_a(0);
553 	int err = -EINVAL;
554 
555 	if (a == NULL) {
556 		printk("tca_action_flush: couldnt create tc_action\n");
557 		return err;
558 	}
559 
560 	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
561 	if (!skb) {
562 		printk("tca_action_flush: failed skb alloc\n");
563 		kfree(a);
564 		return -ENOBUFS;
565 	}
566 
567 	b = (unsigned char *)skb->tail;
568 
569 	if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0)
570 		goto err_out;
571 
572 	kind = tb[TCA_ACT_KIND-1];
573 	a->ops = tc_lookup_action(kind);
574 	if (a->ops == NULL)
575 		goto err_out;
576 
577 	nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t));
578 	t = NLMSG_DATA(nlh);
579 	t->tca_family = AF_UNSPEC;
580 	t->tca__pad1 = 0;
581 	t->tca__pad2 = 0;
582 
583 	x = (struct rtattr *) skb->tail;
584 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
585 
586 	err = a->ops->walk(skb, &dcb, RTM_DELACTION, a);
587 	if (err < 0)
588 		goto rtattr_failure;
589 
590 	x->rta_len = skb->tail - (u8 *) x;
591 
592 	nlh->nlmsg_len = skb->tail - b;
593 	nlh->nlmsg_flags |= NLM_F_ROOT;
594 	module_put(a->ops->owner);
595 	kfree(a);
596 	err = rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
597 	if (err > 0)
598 		return 0;
599 
600 	return err;
601 
602 rtattr_failure:
603 	module_put(a->ops->owner);
604 nlmsg_failure:
605 err_out:
606 	kfree_skb(skb);
607 	kfree(a);
608 	return err;
609 }
610 
611 static int
612 tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event)
613 {
614 	int i, ret = 0;
615 	struct rtattr *tb[TCA_ACT_MAX_PRIO+1];
616 	struct tc_action *head = NULL, *act, *act_prev = NULL;
617 
618 	if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0)
619 		return -EINVAL;
620 
621 	if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) {
622 		if (tb[0] != NULL && tb[1] == NULL)
623 			return tca_action_flush(tb[0], n, pid);
624 	}
625 
626 	for (i=0; i < TCA_ACT_MAX_PRIO && tb[i]; i++) {
627 		act = tcf_action_get_1(tb[i], n, pid, &ret);
628 		if (act == NULL)
629 			goto err;
630 		act->order = i+1;
631 
632 		if (head == NULL)
633 			head = act;
634 		else
635 			act_prev->next = act;
636 		act_prev = act;
637 	}
638 
639 	if (event == RTM_GETACTION)
640 		ret = act_get_notify(pid, n, head, event);
641 	else { /* delete */
642 		struct sk_buff *skb;
643 
644 		skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
645 		if (!skb) {
646 			ret = -ENOBUFS;
647 			goto err;
648 		}
649 
650 		if (tca_get_fill(skb, head, pid, n->nlmsg_seq, 0, event,
651 		                 0, 1) <= 0) {
652 			kfree_skb(skb);
653 			ret = -EINVAL;
654 			goto err;
655 		}
656 
657 		/* now do the delete */
658 		tcf_action_destroy(head, 0);
659 		ret = rtnetlink_send(skb, pid, RTNLGRP_TC,
660 		                     n->nlmsg_flags&NLM_F_ECHO);
661 		if (ret > 0)
662 			return 0;
663 		return ret;
664 	}
665 err:
666 	cleanup_a(head);
667 	return ret;
668 }
669 
670 static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
671                           u16 flags)
672 {
673 	struct tcamsg *t;
674 	struct nlmsghdr *nlh;
675 	struct sk_buff *skb;
676 	struct rtattr *x;
677 	unsigned char *b;
678 	int err = 0;
679 
680 	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
681 	if (!skb)
682 		return -ENOBUFS;
683 
684 	b = (unsigned char *)skb->tail;
685 
686 	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
687 	t = NLMSG_DATA(nlh);
688 	t->tca_family = AF_UNSPEC;
689 	t->tca__pad1 = 0;
690 	t->tca__pad2 = 0;
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_group = RTNLGRP_TC;
702 
703 	err = rtnetlink_send(skb, pid, RTNLGRP_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 	t->tca__pad1 = 0;
847 	t->tca__pad2 = 0;
848 
849 	x = (struct rtattr *) skb->tail;
850 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
851 
852 	ret = a_o->walk(skb, cb, RTM_GETACTION, &a);
853 	if (ret < 0)
854 		goto rtattr_failure;
855 
856 	if (ret > 0) {
857 		x->rta_len = skb->tail - (u8 *) x;
858 		ret = skb->len;
859 	} else
860 		skb_trim(skb, (u8*)x - skb->data);
861 
862 	nlh->nlmsg_len = skb->tail - b;
863 	if (NETLINK_CB(cb->skb).pid && ret)
864 		nlh->nlmsg_flags |= NLM_F_MULTI;
865 	module_put(a_o->owner);
866 	return skb->len;
867 
868 rtattr_failure:
869 nlmsg_failure:
870 	module_put(a_o->owner);
871 	skb_trim(skb, b - skb->data);
872 	return skb->len;
873 }
874 
875 static int __init tc_action_init(void)
876 {
877 	struct rtnetlink_link *link_p = rtnetlink_links[PF_UNSPEC];
878 
879 	if (link_p) {
880 		link_p[RTM_NEWACTION-RTM_BASE].doit = tc_ctl_action;
881 		link_p[RTM_DELACTION-RTM_BASE].doit = tc_ctl_action;
882 		link_p[RTM_GETACTION-RTM_BASE].doit = tc_ctl_action;
883 		link_p[RTM_GETACTION-RTM_BASE].dumpit = tc_dump_action;
884 	}
885 
886 	printk("TC classifier action (bugs to netdev@vger.kernel.org cc "
887 	       "hadi@cyberus.ca)\n");
888 	return 0;
889 }
890 
891 subsys_initcall(tc_action_init);
892 
893 EXPORT_SYMBOL(tcf_register_action);
894 EXPORT_SYMBOL(tcf_unregister_action);
895 EXPORT_SYMBOL(tcf_action_exec);
896 EXPORT_SYMBOL(tcf_action_dump_1);
897