diff options
Diffstat (limited to 'net/sched/cls_rsvp.h')
-rw-r--r-- | net/sched/cls_rsvp.h | 26 |
1 files changed, 11 insertions, 15 deletions
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 61286a0f7a3e..7034ea4530e5 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h | |||
@@ -397,6 +397,15 @@ static u32 gen_tunnel(struct rsvp_head *data) | |||
397 | return 0; | 397 | return 0; |
398 | } | 398 | } |
399 | 399 | ||
400 | static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = { | ||
401 | [TCA_RSVP_CLASSID] = { .type = NLA_U32 }, | ||
402 | [TCA_RSVP_DST] = { .type = NLA_BINARY, | ||
403 | .len = RSVP_DST_LEN * sizeof(u32) }, | ||
404 | [TCA_RSVP_SRC] = { .type = NLA_BINARY, | ||
405 | .len = RSVP_DST_LEN * sizeof(u32) }, | ||
406 | [TCA_RSVP_PINFO] = { .len = sizeof(struct tc_rsvp_pinfo) }, | ||
407 | }; | ||
408 | |||
400 | static int rsvp_change(struct tcf_proto *tp, unsigned long base, | 409 | static int rsvp_change(struct tcf_proto *tp, unsigned long base, |
401 | u32 handle, | 410 | u32 handle, |
402 | struct nlattr **tca, | 411 | struct nlattr **tca, |
@@ -416,7 +425,7 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, | |||
416 | if (opt == NULL) | 425 | if (opt == NULL) |
417 | return handle ? -EINVAL : 0; | 426 | return handle ? -EINVAL : 0; |
418 | 427 | ||
419 | err = nla_parse_nested(tb, TCA_RSVP_MAX, opt, NULL); | 428 | err = nla_parse_nested(tb, TCA_RSVP_MAX, opt, rsvp_policy); |
420 | if (err < 0) | 429 | if (err < 0) |
421 | return err; | 430 | return err; |
422 | 431 | ||
@@ -452,30 +461,17 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, | |||
452 | 461 | ||
453 | h2 = 16; | 462 | h2 = 16; |
454 | if (tb[TCA_RSVP_SRC-1]) { | 463 | if (tb[TCA_RSVP_SRC-1]) { |
455 | err = -EINVAL; | ||
456 | if (nla_len(tb[TCA_RSVP_SRC-1]) != sizeof(f->src)) | ||
457 | goto errout; | ||
458 | memcpy(f->src, nla_data(tb[TCA_RSVP_SRC-1]), sizeof(f->src)); | 464 | memcpy(f->src, nla_data(tb[TCA_RSVP_SRC-1]), sizeof(f->src)); |
459 | h2 = hash_src(f->src); | 465 | h2 = hash_src(f->src); |
460 | } | 466 | } |
461 | if (tb[TCA_RSVP_PINFO-1]) { | 467 | if (tb[TCA_RSVP_PINFO-1]) { |
462 | err = -EINVAL; | ||
463 | if (nla_len(tb[TCA_RSVP_PINFO-1]) < sizeof(struct tc_rsvp_pinfo)) | ||
464 | goto errout; | ||
465 | pinfo = nla_data(tb[TCA_RSVP_PINFO-1]); | 468 | pinfo = nla_data(tb[TCA_RSVP_PINFO-1]); |
466 | f->spi = pinfo->spi; | 469 | f->spi = pinfo->spi; |
467 | f->tunnelhdr = pinfo->tunnelhdr; | 470 | f->tunnelhdr = pinfo->tunnelhdr; |
468 | } | 471 | } |
469 | if (tb[TCA_RSVP_CLASSID-1]) { | 472 | if (tb[TCA_RSVP_CLASSID-1]) |
470 | err = -EINVAL; | ||
471 | if (nla_len(tb[TCA_RSVP_CLASSID-1]) != 4) | ||
472 | goto errout; | ||
473 | f->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID-1]); | 473 | f->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID-1]); |
474 | } | ||
475 | 474 | ||
476 | err = -EINVAL; | ||
477 | if (nla_len(tb[TCA_RSVP_DST-1]) != sizeof(f->src)) | ||
478 | goto errout; | ||
479 | dst = nla_data(tb[TCA_RSVP_DST-1]); | 475 | dst = nla_data(tb[TCA_RSVP_DST-1]); |
480 | h1 = hash_dst(dst, pinfo ? pinfo->protocol : 0, pinfo ? pinfo->tunnelid : 0); | 476 | h1 = hash_dst(dst, pinfo ? pinfo->protocol : 0, pinfo ? pinfo->tunnelid : 0); |
481 | 477 | ||