| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * net/sched/cls_route.c ROUTE4 classifier. |
|---|
| 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 | 4 | * |
|---|
| 9 | 5 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> |
|---|
| 10 | 6 | */ |
|---|
| .. | .. |
|---|
| 276 | 272 | tcf_queue_work(&f->rwork, route4_delete_filter_work); |
|---|
| 277 | 273 | } |
|---|
| 278 | 274 | |
|---|
| 279 | | -static void route4_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack) |
|---|
| 275 | +static void route4_destroy(struct tcf_proto *tp, bool rtnl_held, |
|---|
| 276 | + struct netlink_ext_ack *extack) |
|---|
| 280 | 277 | { |
|---|
| 281 | 278 | struct route4_head *head = rtnl_dereference(tp->root); |
|---|
| 282 | 279 | int h1, h2; |
|---|
| .. | .. |
|---|
| 312 | 309 | } |
|---|
| 313 | 310 | |
|---|
| 314 | 311 | static int route4_delete(struct tcf_proto *tp, void *arg, bool *last, |
|---|
| 315 | | - struct netlink_ext_ack *extack) |
|---|
| 312 | + bool rtnl_held, struct netlink_ext_ack *extack) |
|---|
| 316 | 313 | { |
|---|
| 317 | 314 | struct route4_head *head = rtnl_dereference(tp->root); |
|---|
| 318 | 315 | struct route4_filter *f = arg; |
|---|
| .. | .. |
|---|
| 393 | 390 | struct route4_bucket *b; |
|---|
| 394 | 391 | int err; |
|---|
| 395 | 392 | |
|---|
| 396 | | - err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, extack); |
|---|
| 393 | + err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, true, extack); |
|---|
| 397 | 394 | if (err < 0) |
|---|
| 398 | 395 | return err; |
|---|
| 399 | 396 | |
|---|
| .. | .. |
|---|
| 425 | 422 | nhandle |= handle & 0x7F00; |
|---|
| 426 | 423 | if (nhandle != handle) |
|---|
| 427 | 424 | return -EINVAL; |
|---|
| 425 | + } |
|---|
| 426 | + |
|---|
| 427 | + if (!nhandle) { |
|---|
| 428 | + NL_SET_ERR_MSG(extack, "Replacing with handle of 0 is invalid"); |
|---|
| 429 | + return -EINVAL; |
|---|
| 428 | 430 | } |
|---|
| 429 | 431 | |
|---|
| 430 | 432 | h1 = to_hash(nhandle); |
|---|
| .. | .. |
|---|
| 468 | 470 | static int route4_change(struct net *net, struct sk_buff *in_skb, |
|---|
| 469 | 471 | struct tcf_proto *tp, unsigned long base, u32 handle, |
|---|
| 470 | 472 | struct nlattr **tca, void **arg, bool ovr, |
|---|
| 471 | | - struct netlink_ext_ack *extack) |
|---|
| 473 | + bool rtnl_held, struct netlink_ext_ack *extack) |
|---|
| 472 | 474 | { |
|---|
| 473 | 475 | struct route4_head *head = rtnl_dereference(tp->root); |
|---|
| 474 | 476 | struct route4_filter __rcu **fp; |
|---|
| .. | .. |
|---|
| 480 | 482 | int err; |
|---|
| 481 | 483 | bool new = true; |
|---|
| 482 | 484 | |
|---|
| 485 | + if (!handle) { |
|---|
| 486 | + NL_SET_ERR_MSG(extack, "Creating with handle of 0 is invalid"); |
|---|
| 487 | + return -EINVAL; |
|---|
| 488 | + } |
|---|
| 489 | + |
|---|
| 483 | 490 | if (opt == NULL) |
|---|
| 484 | 491 | return handle ? -EINVAL : 0; |
|---|
| 485 | 492 | |
|---|
| 486 | | - err = nla_parse_nested(tb, TCA_ROUTE4_MAX, opt, route4_policy, NULL); |
|---|
| 493 | + err = nla_parse_nested_deprecated(tb, TCA_ROUTE4_MAX, opt, |
|---|
| 494 | + route4_policy, NULL); |
|---|
| 487 | 495 | if (err < 0) |
|---|
| 488 | 496 | return err; |
|---|
| 489 | 497 | |
|---|
| .. | .. |
|---|
| 496 | 504 | if (!f) |
|---|
| 497 | 505 | goto errout; |
|---|
| 498 | 506 | |
|---|
| 499 | | - err = tcf_exts_init(&f->exts, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE); |
|---|
| 507 | + err = tcf_exts_init(&f->exts, net, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE); |
|---|
| 500 | 508 | if (err < 0) |
|---|
| 501 | 509 | goto errout; |
|---|
| 502 | 510 | |
|---|
| 503 | 511 | if (fold) { |
|---|
| 504 | 512 | f->id = fold->id; |
|---|
| 505 | 513 | f->iif = fold->iif; |
|---|
| 506 | | - f->res = fold->res; |
|---|
| 507 | 514 | f->handle = fold->handle; |
|---|
| 508 | 515 | |
|---|
| 509 | 516 | f->tp = fold->tp; |
|---|
| .. | .. |
|---|
| 528 | 535 | rcu_assign_pointer(f->next, f1); |
|---|
| 529 | 536 | rcu_assign_pointer(*fp, f); |
|---|
| 530 | 537 | |
|---|
| 531 | | - if (fold && fold->handle && f->handle != fold->handle) { |
|---|
| 538 | + if (fold) { |
|---|
| 532 | 539 | th = to_hash(fold->handle); |
|---|
| 533 | 540 | h = from_hash(fold->handle >> 16); |
|---|
| 534 | 541 | b = rtnl_dereference(head->table[th]); |
|---|
| .. | .. |
|---|
| 560 | 567 | return err; |
|---|
| 561 | 568 | } |
|---|
| 562 | 569 | |
|---|
| 563 | | -static void route4_walk(struct tcf_proto *tp, struct tcf_walker *arg) |
|---|
| 570 | +static void route4_walk(struct tcf_proto *tp, struct tcf_walker *arg, |
|---|
| 571 | + bool rtnl_held) |
|---|
| 564 | 572 | { |
|---|
| 565 | 573 | struct route4_head *head = rtnl_dereference(tp->root); |
|---|
| 566 | 574 | unsigned int h, h1; |
|---|
| 567 | 575 | |
|---|
| 568 | | - if (head == NULL) |
|---|
| 569 | | - arg->stop = 1; |
|---|
| 570 | | - |
|---|
| 571 | | - if (arg->stop) |
|---|
| 576 | + if (head == NULL || arg->stop) |
|---|
| 572 | 577 | return; |
|---|
| 573 | 578 | |
|---|
| 574 | 579 | for (h = 0; h <= 256; h++) { |
|---|
| .. | .. |
|---|
| 597 | 602 | } |
|---|
| 598 | 603 | |
|---|
| 599 | 604 | static int route4_dump(struct net *net, struct tcf_proto *tp, void *fh, |
|---|
| 600 | | - struct sk_buff *skb, struct tcmsg *t) |
|---|
| 605 | + struct sk_buff *skb, struct tcmsg *t, bool rtnl_held) |
|---|
| 601 | 606 | { |
|---|
| 602 | 607 | struct route4_filter *f = fh; |
|---|
| 603 | 608 | struct nlattr *nest; |
|---|
| .. | .. |
|---|
| 608 | 613 | |
|---|
| 609 | 614 | t->tcm_handle = f->handle; |
|---|
| 610 | 615 | |
|---|
| 611 | | - nest = nla_nest_start(skb, TCA_OPTIONS); |
|---|
| 616 | + nest = nla_nest_start_noflag(skb, TCA_OPTIONS); |
|---|
| 612 | 617 | if (nest == NULL) |
|---|
| 613 | 618 | goto nla_put_failure; |
|---|
| 614 | 619 | |
|---|