diff options
author | Jamal Hadi Salim <jhs@mojatatu.com> | 2013-12-04 09:26:52 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-05 19:28:42 -0500 |
commit | 76c82d7a3d24a4ae1f9b098287c18055546c1a47 (patch) | |
tree | 2c0f3f545ffb0de469a8d816b60c65f8de70f65c | |
parent | e1ca87bb1b64b044163e686ff3bb71405156c561 (diff) |
net_sched: Fail if missing mandatory action operation methods
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/sched/act_api.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index fd7072827a40..618695e84190 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -270,6 +270,10 @@ 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 | |||
273 | write_lock(&act_mod_lock); | 277 | write_lock(&act_mod_lock); |
274 | for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) { | 278 | for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) { |
275 | if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { | 279 | if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { |
@@ -381,7 +385,7 @@ int tcf_action_exec(struct sk_buff *skb, const struct tc_action *act, | |||
381 | } | 385 | } |
382 | while ((a = act) != NULL) { | 386 | while ((a = act) != NULL) { |
383 | repeat: | 387 | repeat: |
384 | if (a->ops && a->ops->act) { | 388 | if (a->ops) { |
385 | ret = a->ops->act(skb, a, res); | 389 | ret = a->ops->act(skb, a, res); |
386 | if (TC_MUNGED & skb->tc_verd) { | 390 | if (TC_MUNGED & skb->tc_verd) { |
387 | /* copied already, allow trampling */ | 391 | /* copied already, allow trampling */ |
@@ -405,7 +409,7 @@ void tcf_action_destroy(struct tc_action *act, int bind) | |||
405 | struct tc_action *a; | 409 | struct tc_action *a; |
406 | 410 | ||
407 | for (a = act; a; a = act) { | 411 | for (a = act; a; a = act) { |
408 | if (a->ops && a->ops->cleanup) { | 412 | if (a->ops) { |
409 | if (a->ops->cleanup(a, bind) == ACT_P_DELETED) | 413 | if (a->ops->cleanup(a, bind) == ACT_P_DELETED) |
410 | module_put(a->ops->owner); | 414 | module_put(a->ops->owner); |
411 | act = act->next; | 415 | act = act->next; |
@@ -424,7 +428,7 @@ tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
424 | { | 428 | { |
425 | int err = -EINVAL; | 429 | int err = -EINVAL; |
426 | 430 | ||
427 | if (a->ops == NULL || a->ops->dump == NULL) | 431 | if (a->ops == NULL) |
428 | return err; | 432 | return err; |
429 | return a->ops->dump(skb, a, bind, ref); | 433 | return a->ops->dump(skb, a, bind, ref); |
430 | } | 434 | } |
@@ -436,7 +440,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); | 440 | unsigned char *b = skb_tail_pointer(skb); |
437 | struct nlattr *nest; | 441 | struct nlattr *nest; |
438 | 442 | ||
439 | if (a->ops == NULL || a->ops->dump == NULL) | 443 | if (a->ops == NULL) |
440 | return err; | 444 | return err; |
441 | 445 | ||
442 | if (nla_put_string(skb, TCA_KIND, a->ops->kind)) | 446 | if (nla_put_string(skb, TCA_KIND, a->ops->kind)) |