diff options
Diffstat (limited to 'net/sched/act_api.c')
-rw-r--r-- | net/sched/act_api.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index fd7072827a40..69cb848e8345 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -270,6 +270,16 @@ int tcf_register_action(struct tc_action_ops *act) | |||
270 | { | 270 | { |
271 | struct tc_action_ops *a, **ap; | 271 | struct tc_action_ops *a, **ap; |
272 | 272 | ||
273 | /* Must supply act, dump, cleanup and init */ | ||
274 | if (!act->act || !act->dump || !act->cleanup || !act->init) | ||
275 | return -EINVAL; | ||
276 | |||
277 | /* Supply defaults */ | ||
278 | if (!act->lookup) | ||
279 | act->lookup = tcf_hash_search; | ||
280 | if (!act->walk) | ||
281 | act->walk = tcf_generic_walker; | ||
282 | |||
273 | write_lock(&act_mod_lock); | 283 | write_lock(&act_mod_lock); |
274 | for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) { | 284 | for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) { |
275 | if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { | 285 | if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { |
@@ -381,7 +391,7 @@ int tcf_action_exec(struct sk_buff *skb, const struct tc_action *act, | |||
381 | } | 391 | } |
382 | while ((a = act) != NULL) { | 392 | while ((a = act) != NULL) { |
383 | repeat: | 393 | repeat: |
384 | if (a->ops && a->ops->act) { | 394 | if (a->ops) { |
385 | ret = a->ops->act(skb, a, res); | 395 | ret = a->ops->act(skb, a, res); |
386 | if (TC_MUNGED & skb->tc_verd) { | 396 | if (TC_MUNGED & skb->tc_verd) { |
387 | /* copied already, allow trampling */ | 397 | /* copied already, allow trampling */ |
@@ -405,7 +415,7 @@ void tcf_action_destroy(struct tc_action *act, int bind) | |||
405 | struct tc_action *a; | 415 | struct tc_action *a; |
406 | 416 | ||
407 | for (a = act; a; a = act) { | 417 | for (a = act; a; a = act) { |
408 | if (a->ops && a->ops->cleanup) { | 418 | if (a->ops) { |
409 | if (a->ops->cleanup(a, bind) == ACT_P_DELETED) | 419 | if (a->ops->cleanup(a, bind) == ACT_P_DELETED) |
410 | module_put(a->ops->owner); | 420 | module_put(a->ops->owner); |
411 | act = act->next; | 421 | act = act->next; |
@@ -424,7 +434,7 @@ tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
424 | { | 434 | { |
425 | int err = -EINVAL; | 435 | int err = -EINVAL; |
426 | 436 | ||
427 | if (a->ops == NULL || a->ops->dump == NULL) | 437 | if (a->ops == NULL) |
428 | return err; | 438 | return err; |
429 | return a->ops->dump(skb, a, bind, ref); | 439 | return a->ops->dump(skb, a, bind, ref); |
430 | } | 440 | } |
@@ -436,7 +446,7 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
436 | unsigned char *b = skb_tail_pointer(skb); | 446 | unsigned char *b = skb_tail_pointer(skb); |
437 | struct nlattr *nest; | 447 | struct nlattr *nest; |
438 | 448 | ||
439 | if (a->ops == NULL || a->ops->dump == NULL) | 449 | if (a->ops == NULL) |
440 | return err; | 450 | return err; |
441 | 451 | ||
442 | if (nla_put_string(skb, TCA_KIND, a->ops->kind)) | 452 | if (nla_put_string(skb, TCA_KIND, a->ops->kind)) |
@@ -723,8 +733,6 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid) | |||
723 | a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); | 733 | a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); |
724 | if (a->ops == NULL) | 734 | if (a->ops == NULL) |
725 | goto err_free; | 735 | goto err_free; |
726 | if (a->ops->lookup == NULL) | ||
727 | goto err_mod; | ||
728 | err = -ENOENT; | 736 | err = -ENOENT; |
729 | if (a->ops->lookup(a, index) == 0) | 737 | if (a->ops->lookup(a, index) == 0) |
730 | goto err_mod; | 738 | goto err_mod; |
@@ -1084,12 +1092,6 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) | |||
1084 | memset(&a, 0, sizeof(struct tc_action)); | 1092 | memset(&a, 0, sizeof(struct tc_action)); |
1085 | a.ops = a_o; | 1093 | a.ops = a_o; |
1086 | 1094 | ||
1087 | if (a_o->walk == NULL) { | ||
1088 | WARN(1, "tc_dump_action: %s !capable of dumping table\n", | ||
1089 | a_o->kind); | ||
1090 | goto out_module_put; | ||
1091 | } | ||
1092 | |||
1093 | nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, | 1095 | nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, |
1094 | cb->nlh->nlmsg_type, sizeof(*t), 0); | 1096 | cb->nlh->nlmsg_type, sizeof(*t), 0); |
1095 | if (!nlh) | 1097 | if (!nlh) |