cls_api.c (edfbeecd92b0c4a648ed96a7e255bfc9a1bc4642) cls_api.c (dac9c9790e542777079999900594fd069ba10489)
1/*
2 * net/sched/cls_api.c Packet classifier 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 *

--- 226 unchanged lines hidden (view full) ---

235static void tcf_chain_destroy(struct tcf_chain *chain)
236{
237 struct tcf_block *block = chain->block;
238
239 list_del(&chain->list);
240 if (!chain->index)
241 block->chain0.chain = NULL;
242 kfree(chain);
1/*
2 * net/sched/cls_api.c Packet classifier 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 *

--- 226 unchanged lines hidden (view full) ---

235static void tcf_chain_destroy(struct tcf_chain *chain)
236{
237 struct tcf_block *block = chain->block;
238
239 list_del(&chain->list);
240 if (!chain->index)
241 block->chain0.chain = NULL;
242 kfree(chain);
243 if (list_empty(&block->chain_list) && block->refcnt == 0)
244 kfree(block);
243 if (list_empty(&block->chain_list) && !refcount_read(&block->refcnt))
244 kfree_rcu(block, rcu);
245}
246
247static void tcf_chain_hold(struct tcf_chain *chain)
248{
249 ++chain->refcnt;
250}
251
252static bool tcf_chain_held_by_acts_only(struct tcf_chain *chain)

--- 215 unchanged lines hidden (view full) ---

468 kfree(item);
469 return;
470 }
471 }
472 WARN_ON(1);
473}
474
475struct tcf_net {
245}
246
247static void tcf_chain_hold(struct tcf_chain *chain)
248{
249 ++chain->refcnt;
250}
251
252static bool tcf_chain_held_by_acts_only(struct tcf_chain *chain)

--- 215 unchanged lines hidden (view full) ---

468 kfree(item);
469 return;
470 }
471 }
472 WARN_ON(1);
473}
474
475struct tcf_net {
476 spinlock_t idr_lock; /* Protects idr */
476 struct idr idr;
477};
478
479static unsigned int tcf_net_id;
480
481static int tcf_block_insert(struct tcf_block *block, struct net *net,
482 struct netlink_ext_ack *extack)
483{
484 struct tcf_net *tn = net_generic(net, tcf_net_id);
477 struct idr idr;
478};
479
480static unsigned int tcf_net_id;
481
482static int tcf_block_insert(struct tcf_block *block, struct net *net,
483 struct netlink_ext_ack *extack)
484{
485 struct tcf_net *tn = net_generic(net, tcf_net_id);
486 int err;
485
487
486 return idr_alloc_u32(&tn->idr, block, &block->index, block->index,
487 GFP_KERNEL);
488 idr_preload(GFP_KERNEL);
489 spin_lock(&tn->idr_lock);
490 err = idr_alloc_u32(&tn->idr, block, &block->index, block->index,
491 GFP_NOWAIT);
492 spin_unlock(&tn->idr_lock);
493 idr_preload_end();
494
495 return err;
488}
489
490static void tcf_block_remove(struct tcf_block *block, struct net *net)
491{
492 struct tcf_net *tn = net_generic(net, tcf_net_id);
493
496}
497
498static void tcf_block_remove(struct tcf_block *block, struct net *net)
499{
500 struct tcf_net *tn = net_generic(net, tcf_net_id);
501
502 spin_lock(&tn->idr_lock);
494 idr_remove(&tn->idr, block->index);
503 idr_remove(&tn->idr, block->index);
504 spin_unlock(&tn->idr_lock);
495}
496
497static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q,
498 u32 block_index,
499 struct netlink_ext_ack *extack)
500{
501 struct tcf_block *block;
502
503 block = kzalloc(sizeof(*block), GFP_KERNEL);
504 if (!block) {
505 NL_SET_ERR_MSG(extack, "Memory allocation for block failed");
506 return ERR_PTR(-ENOMEM);
507 }
508 INIT_LIST_HEAD(&block->chain_list);
509 INIT_LIST_HEAD(&block->cb_list);
510 INIT_LIST_HEAD(&block->owner_list);
511 INIT_LIST_HEAD(&block->chain0.filter_chain_list);
512
505}
506
507static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q,
508 u32 block_index,
509 struct netlink_ext_ack *extack)
510{
511 struct tcf_block *block;
512
513 block = kzalloc(sizeof(*block), GFP_KERNEL);
514 if (!block) {
515 NL_SET_ERR_MSG(extack, "Memory allocation for block failed");
516 return ERR_PTR(-ENOMEM);
517 }
518 INIT_LIST_HEAD(&block->chain_list);
519 INIT_LIST_HEAD(&block->cb_list);
520 INIT_LIST_HEAD(&block->owner_list);
521 INIT_LIST_HEAD(&block->chain0.filter_chain_list);
522
513 block->refcnt = 1;
523 refcount_set(&block->refcnt, 1);
514 block->net = net;
515 block->index = block_index;
516
517 /* Don't store q pointer for blocks which are shared */
518 if (!tcf_block_shared(block))
519 block->q = q;
520 return block;
521}
522
523static struct tcf_block *tcf_block_lookup(struct net *net, u32 block_index)
524{
525 struct tcf_net *tn = net_generic(net, tcf_net_id);
526
527 return idr_find(&tn->idr, block_index);
528}
529
524 block->net = net;
525 block->index = block_index;
526
527 /* Don't store q pointer for blocks which are shared */
528 if (!tcf_block_shared(block))
529 block->q = q;
530 return block;
531}
532
533static struct tcf_block *tcf_block_lookup(struct net *net, u32 block_index)
534{
535 struct tcf_net *tn = net_generic(net, tcf_net_id);
536
537 return idr_find(&tn->idr, block_index);
538}
539
540static struct tcf_block *tcf_block_refcnt_get(struct net *net, u32 block_index)
541{
542 struct tcf_block *block;
543
544 rcu_read_lock();
545 block = tcf_block_lookup(net, block_index);
546 if (block && !refcount_inc_not_zero(&block->refcnt))
547 block = NULL;
548 rcu_read_unlock();
549
550 return block;
551}
552
553static void tcf_block_flush_all_chains(struct tcf_block *block)
554{
555 struct tcf_chain *chain;
556
557 /* Hold a refcnt for all chains, so that they don't disappear
558 * while we are iterating.
559 */
560 list_for_each_entry(chain, &block->chain_list, list)
561 tcf_chain_hold(chain);
562
563 list_for_each_entry(chain, &block->chain_list, list)
564 tcf_chain_flush(chain);
565}
566
567static void tcf_block_put_all_chains(struct tcf_block *block)
568{
569 struct tcf_chain *chain, *tmp;
570
571 /* At this point, all the chains should have refcnt >= 1. */
572 list_for_each_entry_safe(chain, tmp, &block->chain_list, list) {
573 tcf_chain_put_explicitly_created(chain);
574 tcf_chain_put(chain);
575 }
576}
577
578static void __tcf_block_put(struct tcf_block *block, struct Qdisc *q,
579 struct tcf_block_ext_info *ei)
580{
581 if (refcount_dec_and_test(&block->refcnt)) {
582 /* Flushing/putting all chains will cause the block to be
583 * deallocated when last chain is freed. However, if chain_list
584 * is empty, block has to be manually deallocated. After block
585 * reference counter reached 0, it is no longer possible to
586 * increment it or add new chains to block.
587 */
588 bool free_block = list_empty(&block->chain_list);
589
590 if (tcf_block_shared(block))
591 tcf_block_remove(block, block->net);
592 if (!free_block)
593 tcf_block_flush_all_chains(block);
594
595 if (q)
596 tcf_block_offload_unbind(block, q, ei);
597
598 if (free_block)
599 kfree_rcu(block, rcu);
600 else
601 tcf_block_put_all_chains(block);
602 } else if (q) {
603 tcf_block_offload_unbind(block, q, ei);
604 }
605}
606
607static void tcf_block_refcnt_put(struct tcf_block *block)
608{
609 __tcf_block_put(block, NULL, NULL);
610}
611
530/* Find tcf block.
531 * Set q, parent, cl when appropriate.
532 */
533
534static struct tcf_block *tcf_block_find(struct net *net, struct Qdisc **q,
535 u32 *parent, unsigned long *cl,
536 int ifindex, u32 block_index,
537 struct netlink_ext_ack *extack)
538{
539 struct tcf_block *block;
612/* Find tcf block.
613 * Set q, parent, cl when appropriate.
614 */
615
616static struct tcf_block *tcf_block_find(struct net *net, struct Qdisc **q,
617 u32 *parent, unsigned long *cl,
618 int ifindex, u32 block_index,
619 struct netlink_ext_ack *extack)
620{
621 struct tcf_block *block;
622 int err = 0;
540
541 if (ifindex == TCM_IFINDEX_MAGIC_BLOCK) {
623
624 if (ifindex == TCM_IFINDEX_MAGIC_BLOCK) {
542 block = tcf_block_lookup(net, block_index);
625 block = tcf_block_refcnt_get(net, block_index);
543 if (!block) {
544 NL_SET_ERR_MSG(extack, "Block of given index was not found");
545 return ERR_PTR(-EINVAL);
546 }
547 } else {
548 const struct Qdisc_class_ops *cops;
549 struct net_device *dev;
550
626 if (!block) {
627 NL_SET_ERR_MSG(extack, "Block of given index was not found");
628 return ERR_PTR(-EINVAL);
629 }
630 } else {
631 const struct Qdisc_class_ops *cops;
632 struct net_device *dev;
633
634 rcu_read_lock();
635
551 /* Find link */
636 /* Find link */
552 dev = __dev_get_by_index(net, ifindex);
553 if (!dev)
637 dev = dev_get_by_index_rcu(net, ifindex);
638 if (!dev) {
639 rcu_read_unlock();
554 return ERR_PTR(-ENODEV);
640 return ERR_PTR(-ENODEV);
641 }
555
556 /* Find qdisc */
557 if (!*parent) {
558 *q = dev->qdisc;
559 *parent = (*q)->handle;
560 } else {
642
643 /* Find qdisc */
644 if (!*parent) {
645 *q = dev->qdisc;
646 *parent = (*q)->handle;
647 } else {
561 *q = qdisc_lookup(dev, TC_H_MAJ(*parent));
648 *q = qdisc_lookup_rcu(dev, TC_H_MAJ(*parent));
562 if (!*q) {
563 NL_SET_ERR_MSG(extack, "Parent Qdisc doesn't exists");
649 if (!*q) {
650 NL_SET_ERR_MSG(extack, "Parent Qdisc doesn't exists");
564 return ERR_PTR(-EINVAL);
651 err = -EINVAL;
652 goto errout_rcu;
565 }
566 }
567
653 }
654 }
655
656 *q = qdisc_refcount_inc_nz(*q);
657 if (!*q) {
658 NL_SET_ERR_MSG(extack, "Parent Qdisc doesn't exists");
659 err = -EINVAL;
660 goto errout_rcu;
661 }
662
568 /* Is it classful? */
569 cops = (*q)->ops->cl_ops;
570 if (!cops) {
571 NL_SET_ERR_MSG(extack, "Qdisc not classful");
663 /* Is it classful? */
664 cops = (*q)->ops->cl_ops;
665 if (!cops) {
666 NL_SET_ERR_MSG(extack, "Qdisc not classful");
572 return ERR_PTR(-EINVAL);
667 err = -EINVAL;
668 goto errout_rcu;
573 }
574
575 if (!cops->tcf_block) {
576 NL_SET_ERR_MSG(extack, "Class doesn't support blocks");
669 }
670
671 if (!cops->tcf_block) {
672 NL_SET_ERR_MSG(extack, "Class doesn't support blocks");
577 return ERR_PTR(-EOPNOTSUPP);
673 err = -EOPNOTSUPP;
674 goto errout_rcu;
578 }
579
675 }
676
677 /* At this point we know that qdisc is not noop_qdisc,
678 * which means that qdisc holds a reference to net_device
679 * and we hold a reference to qdisc, so it is safe to release
680 * rcu read lock.
681 */
682 rcu_read_unlock();
683
580 /* Do we search for filter, attached to class? */
581 if (TC_H_MIN(*parent)) {
582 *cl = cops->find(*q, *parent);
583 if (*cl == 0) {
584 NL_SET_ERR_MSG(extack, "Specified class doesn't exist");
684 /* Do we search for filter, attached to class? */
685 if (TC_H_MIN(*parent)) {
686 *cl = cops->find(*q, *parent);
687 if (*cl == 0) {
688 NL_SET_ERR_MSG(extack, "Specified class doesn't exist");
585 return ERR_PTR(-ENOENT);
689 err = -ENOENT;
690 goto errout_qdisc;
586 }
587 }
588
589 /* And the last stroke */
590 block = cops->tcf_block(*q, *cl, extack);
691 }
692 }
693
694 /* And the last stroke */
695 block = cops->tcf_block(*q, *cl, extack);
591 if (!block)
592 return ERR_PTR(-EINVAL);
696 if (!block) {
697 err = -EINVAL;
698 goto errout_qdisc;
699 }
593 if (tcf_block_shared(block)) {
594 NL_SET_ERR_MSG(extack, "This filter block is shared. Please use the block index to manipulate the filters");
700 if (tcf_block_shared(block)) {
701 NL_SET_ERR_MSG(extack, "This filter block is shared. Please use the block index to manipulate the filters");
595 return ERR_PTR(-EOPNOTSUPP);
702 err = -EOPNOTSUPP;
703 goto errout_qdisc;
596 }
704 }
705
706 /* Always take reference to block in order to support execution
707 * of rules update path of cls API without rtnl lock. Caller
708 * must release block when it is finished using it. 'if' block
709 * of this conditional obtain reference to block by calling
710 * tcf_block_refcnt_get().
711 */
712 refcount_inc(&block->refcnt);
597 }
598
599 return block;
713 }
714
715 return block;
716
717errout_rcu:
718 rcu_read_unlock();
719errout_qdisc:
720 if (*q) {
721 qdisc_put(*q);
722 *q = NULL;
723 }
724 return ERR_PTR(err);
600}
601
725}
726
727static void tcf_block_release(struct Qdisc *q, struct tcf_block *block)
728{
729 if (!IS_ERR_OR_NULL(block))
730 tcf_block_refcnt_put(block);
731
732 if (q)
733 qdisc_put(q);
734}
735
602struct tcf_block_owner_item {
603 struct list_head list;
604 struct Qdisc *q;
605 enum tcf_block_binder_type binder_type;
606};
607
608static void
609tcf_block_owner_netif_keep_dst(struct tcf_block *block,

--- 49 unchanged lines hidden (view full) ---

659}
660
661int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
662 struct tcf_block_ext_info *ei,
663 struct netlink_ext_ack *extack)
664{
665 struct net *net = qdisc_net(q);
666 struct tcf_block *block = NULL;
736struct tcf_block_owner_item {
737 struct list_head list;
738 struct Qdisc *q;
739 enum tcf_block_binder_type binder_type;
740};
741
742static void
743tcf_block_owner_netif_keep_dst(struct tcf_block *block,

--- 49 unchanged lines hidden (view full) ---

793}
794
795int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
796 struct tcf_block_ext_info *ei,
797 struct netlink_ext_ack *extack)
798{
799 struct net *net = qdisc_net(q);
800 struct tcf_block *block = NULL;
667 bool created = false;
668 int err;
669
801 int err;
802
670 if (ei->block_index) {
803 if (ei->block_index)
671 /* block_index not 0 means the shared block is requested */
804 /* block_index not 0 means the shared block is requested */
672 block = tcf_block_lookup(net, ei->block_index);
673 if (block)
674 block->refcnt++;
675 }
805 block = tcf_block_refcnt_get(net, ei->block_index);
676
677 if (!block) {
678 block = tcf_block_create(net, q, ei->block_index, extack);
679 if (IS_ERR(block))
680 return PTR_ERR(block);
806
807 if (!block) {
808 block = tcf_block_create(net, q, ei->block_index, extack);
809 if (IS_ERR(block))
810 return PTR_ERR(block);
681 created = true;
682 if (tcf_block_shared(block)) {
683 err = tcf_block_insert(block, net, extack);
684 if (err)
685 goto err_block_insert;
686 }
687 }
688
689 err = tcf_block_owner_add(block, q, ei->binder_type);

--- 13 unchanged lines hidden (view full) ---

703 *p_block = block;
704 return 0;
705
706err_block_offload_bind:
707 tcf_chain0_head_change_cb_del(block, ei);
708err_chain0_head_change_cb_add:
709 tcf_block_owner_del(block, q, ei->binder_type);
710err_block_owner_add:
811 if (tcf_block_shared(block)) {
812 err = tcf_block_insert(block, net, extack);
813 if (err)
814 goto err_block_insert;
815 }
816 }
817
818 err = tcf_block_owner_add(block, q, ei->binder_type);

--- 13 unchanged lines hidden (view full) ---

832 *p_block = block;
833 return 0;
834
835err_block_offload_bind:
836 tcf_chain0_head_change_cb_del(block, ei);
837err_chain0_head_change_cb_add:
838 tcf_block_owner_del(block, q, ei->binder_type);
839err_block_owner_add:
711 if (created) {
712 if (tcf_block_shared(block))
713 tcf_block_remove(block, net);
714err_block_insert:
840err_block_insert:
715 kfree(block);
716 } else {
717 block->refcnt--;
718 }
841 tcf_block_refcnt_put(block);
719 return err;
720}
721EXPORT_SYMBOL(tcf_block_get_ext);
722
723static void tcf_chain_head_change_dflt(struct tcf_proto *tp_head, void *priv)
724{
725 struct tcf_proto __rcu **p_filter_chain = priv;
726

--- 15 unchanged lines hidden (view full) ---

742EXPORT_SYMBOL(tcf_block_get);
743
744/* XXX: Standalone actions are not allowed to jump to any chain, and bound
745 * actions should be all removed after flushing.
746 */
747void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q,
748 struct tcf_block_ext_info *ei)
749{
842 return err;
843}
844EXPORT_SYMBOL(tcf_block_get_ext);
845
846static void tcf_chain_head_change_dflt(struct tcf_proto *tp_head, void *priv)
847{
848 struct tcf_proto __rcu **p_filter_chain = priv;
849

--- 15 unchanged lines hidden (view full) ---

865EXPORT_SYMBOL(tcf_block_get);
866
867/* XXX: Standalone actions are not allowed to jump to any chain, and bound
868 * actions should be all removed after flushing.
869 */
870void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q,
871 struct tcf_block_ext_info *ei)
872{
750 struct tcf_chain *chain, *tmp;
751
752 if (!block)
753 return;
754 tcf_chain0_head_change_cb_del(block, ei);
755 tcf_block_owner_del(block, q, ei->binder_type);
756
873 if (!block)
874 return;
875 tcf_chain0_head_change_cb_del(block, ei);
876 tcf_block_owner_del(block, q, ei->binder_type);
877
757 if (block->refcnt == 1) {
758 if (tcf_block_shared(block))
759 tcf_block_remove(block, block->net);
760
761 /* Hold a refcnt for all chains, so that they don't disappear
762 * while we are iterating.
763 */
764 list_for_each_entry(chain, &block->chain_list, list)
765 tcf_chain_hold(chain);
766
767 list_for_each_entry(chain, &block->chain_list, list)
768 tcf_chain_flush(chain);
769 }
770
771 tcf_block_offload_unbind(block, q, ei);
772
773 if (block->refcnt == 1) {
774 /* At this point, all the chains should have refcnt >= 1. */
775 list_for_each_entry_safe(chain, tmp, &block->chain_list, list) {
776 tcf_chain_put_explicitly_created(chain);
777 tcf_chain_put(chain);
778 }
779
780 block->refcnt--;
781 if (list_empty(&block->chain_list))
782 kfree(block);
783 } else {
784 block->refcnt--;
785 }
878 __tcf_block_put(block, q, ei);
786}
787EXPORT_SYMBOL(tcf_block_put_ext);
788
789void tcf_block_put(struct tcf_block *block)
790{
791 struct tcf_block_ext_info ei = {0, };
792
793 if (!block)

--- 533 unchanged lines hidden (view full) ---

1327 } else {
1328 if (tp_created)
1329 tcf_proto_destroy(tp, NULL);
1330 }
1331
1332errout:
1333 if (chain)
1334 tcf_chain_put(chain);
879}
880EXPORT_SYMBOL(tcf_block_put_ext);
881
882void tcf_block_put(struct tcf_block *block)
883{
884 struct tcf_block_ext_info ei = {0, };
885
886 if (!block)

--- 533 unchanged lines hidden (view full) ---

1420 } else {
1421 if (tp_created)
1422 tcf_proto_destroy(tp, NULL);
1423 }
1424
1425errout:
1426 if (chain)
1427 tcf_chain_put(chain);
1428 tcf_block_release(q, block);
1335 if (err == -EAGAIN)
1336 /* Replay the request. */
1337 goto replay;
1338 return err;
1339}
1340
1341static int tc_del_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
1342 struct netlink_ext_ack *extack)

--- 105 unchanged lines hidden (view full) ---

1448 tcf_chain_tp_remove(chain, &chain_info, tp);
1449 tcf_proto_destroy(tp, extack);
1450 }
1451 }
1452
1453errout:
1454 if (chain)
1455 tcf_chain_put(chain);
1429 if (err == -EAGAIN)
1430 /* Replay the request. */
1431 goto replay;
1432 return err;
1433}
1434
1435static int tc_del_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
1436 struct netlink_ext_ack *extack)

--- 105 unchanged lines hidden (view full) ---

1542 tcf_chain_tp_remove(chain, &chain_info, tp);
1543 tcf_proto_destroy(tp, extack);
1544 }
1545 }
1546
1547errout:
1548 if (chain)
1549 tcf_chain_put(chain);
1550 tcf_block_release(q, block);
1456 return err;
1457}
1458
1459static int tc_get_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
1460 struct netlink_ext_ack *extack)
1461{
1462 struct net *net = sock_net(skb->sk);
1463 struct nlattr *tca[TCA_MAX + 1];

--- 69 unchanged lines hidden (view full) ---

1533 fh, RTM_NEWTFILTER, true);
1534 if (err < 0)
1535 NL_SET_ERR_MSG(extack, "Failed to send filter notify message");
1536 }
1537
1538errout:
1539 if (chain)
1540 tcf_chain_put(chain);
1551 return err;
1552}
1553
1554static int tc_get_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
1555 struct netlink_ext_ack *extack)
1556{
1557 struct net *net = sock_net(skb->sk);
1558 struct nlattr *tca[TCA_MAX + 1];

--- 69 unchanged lines hidden (view full) ---

1628 fh, RTM_NEWTFILTER, true);
1629 if (err < 0)
1630 NL_SET_ERR_MSG(extack, "Failed to send filter notify message");
1631 }
1632
1633errout:
1634 if (chain)
1635 tcf_chain_put(chain);
1636 tcf_block_release(q, block);
1541 return err;
1542}
1543
1544struct tcf_dump_args {
1545 struct tcf_walker w;
1546 struct sk_buff *skb;
1547 struct netlink_callback *cb;
1548 struct tcf_block *block;

--- 77 unchanged lines hidden (view full) ---

1626 long index_start;
1627 long index;
1628 u32 parent;
1629 int err;
1630
1631 if (nlmsg_len(cb->nlh) < sizeof(*tcm))
1632 return skb->len;
1633
1637 return err;
1638}
1639
1640struct tcf_dump_args {
1641 struct tcf_walker w;
1642 struct sk_buff *skb;
1643 struct netlink_callback *cb;
1644 struct tcf_block *block;

--- 77 unchanged lines hidden (view full) ---

1722 long index_start;
1723 long index;
1724 u32 parent;
1725 int err;
1726
1727 if (nlmsg_len(cb->nlh) < sizeof(*tcm))
1728 return skb->len;
1729
1634 err = nlmsg_parse(cb->nlh, sizeof(*tcm), tca, TCA_MAX, NULL, NULL);
1730 err = nlmsg_parse(cb->nlh, sizeof(*tcm), tca, TCA_MAX, NULL,
1731 cb->extack);
1635 if (err)
1636 return err;
1637
1638 if (tcm->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) {
1732 if (err)
1733 return err;
1734
1735 if (tcm->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) {
1639 block = tcf_block_lookup(net, tcm->tcm_block_index);
1736 block = tcf_block_refcnt_get(net, tcm->tcm_block_index);
1640 if (!block)
1641 goto out;
1642 /* If we work with block index, q is NULL and parent value
1643 * will never be used in the following code. The check
1644 * in tcf_fill_node prevents it. However, compiler does not
1645 * see that far, so set parent to zero to silence the warning
1646 * about parent being uninitialized.
1647 */

--- 42 unchanged lines hidden (view full) ---

1690 continue;
1691 if (!tcf_chain_dump(chain, q, parent, skb, cb,
1692 index_start, &index)) {
1693 err = -EMSGSIZE;
1694 break;
1695 }
1696 }
1697
1737 if (!block)
1738 goto out;
1739 /* If we work with block index, q is NULL and parent value
1740 * will never be used in the following code. The check
1741 * in tcf_fill_node prevents it. However, compiler does not
1742 * see that far, so set parent to zero to silence the warning
1743 * about parent being uninitialized.
1744 */

--- 42 unchanged lines hidden (view full) ---

1787 continue;
1788 if (!tcf_chain_dump(chain, q, parent, skb, cb,
1789 index_start, &index)) {
1790 err = -EMSGSIZE;
1791 break;
1792 }
1793 }
1794
1795 if (tcm->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK)
1796 tcf_block_refcnt_put(block);
1698 cb->args[0] = index;
1699
1700out:
1701 /* If we did no progress, the error (EMSGSIZE) is real */
1702 if (skb->len == 0 && err)
1703 return err;
1704 return skb->len;
1705}

--- 143 unchanged lines hidden (view full) ---

1849 block = tcf_block_find(net, &q, &parent, &cl,
1850 t->tcm_ifindex, t->tcm_block_index, extack);
1851 if (IS_ERR(block))
1852 return PTR_ERR(block);
1853
1854 chain_index = tca[TCA_CHAIN] ? nla_get_u32(tca[TCA_CHAIN]) : 0;
1855 if (chain_index > TC_ACT_EXT_VAL_MASK) {
1856 NL_SET_ERR_MSG(extack, "Specified chain index exceeds upper limit");
1797 cb->args[0] = index;
1798
1799out:
1800 /* If we did no progress, the error (EMSGSIZE) is real */
1801 if (skb->len == 0 && err)
1802 return err;
1803 return skb->len;
1804}

--- 143 unchanged lines hidden (view full) ---

1948 block = tcf_block_find(net, &q, &parent, &cl,
1949 t->tcm_ifindex, t->tcm_block_index, extack);
1950 if (IS_ERR(block))
1951 return PTR_ERR(block);
1952
1953 chain_index = tca[TCA_CHAIN] ? nla_get_u32(tca[TCA_CHAIN]) : 0;
1954 if (chain_index > TC_ACT_EXT_VAL_MASK) {
1955 NL_SET_ERR_MSG(extack, "Specified chain index exceeds upper limit");
1857 return -EINVAL;
1956 err = -EINVAL;
1957 goto errout_block;
1858 }
1859 chain = tcf_chain_lookup(block, chain_index);
1860 if (n->nlmsg_type == RTM_NEWCHAIN) {
1861 if (chain) {
1862 if (tcf_chain_held_by_acts_only(chain)) {
1863 /* The chain exists only because there is
1864 * some action referencing it.
1865 */
1866 tcf_chain_hold(chain);
1867 } else {
1868 NL_SET_ERR_MSG(extack, "Filter chain already exists");
1958 }
1959 chain = tcf_chain_lookup(block, chain_index);
1960 if (n->nlmsg_type == RTM_NEWCHAIN) {
1961 if (chain) {
1962 if (tcf_chain_held_by_acts_only(chain)) {
1963 /* The chain exists only because there is
1964 * some action referencing it.
1965 */
1966 tcf_chain_hold(chain);
1967 } else {
1968 NL_SET_ERR_MSG(extack, "Filter chain already exists");
1869 return -EEXIST;
1969 err = -EEXIST;
1970 goto errout_block;
1870 }
1871 } else {
1872 if (!(n->nlmsg_flags & NLM_F_CREATE)) {
1873 NL_SET_ERR_MSG(extack, "Need both RTM_NEWCHAIN and NLM_F_CREATE to create a new chain");
1971 }
1972 } else {
1973 if (!(n->nlmsg_flags & NLM_F_CREATE)) {
1974 NL_SET_ERR_MSG(extack, "Need both RTM_NEWCHAIN and NLM_F_CREATE to create a new chain");
1874 return -ENOENT;
1975 err = -ENOENT;
1976 goto errout_block;
1875 }
1876 chain = tcf_chain_create(block, chain_index);
1877 if (!chain) {
1878 NL_SET_ERR_MSG(extack, "Failed to create filter chain");
1977 }
1978 chain = tcf_chain_create(block, chain_index);
1979 if (!chain) {
1980 NL_SET_ERR_MSG(extack, "Failed to create filter chain");
1879 return -ENOMEM;
1981 err = -ENOMEM;
1982 goto errout_block;
1880 }
1881 }
1882 } else {
1883 if (!chain || tcf_chain_held_by_acts_only(chain)) {
1884 NL_SET_ERR_MSG(extack, "Cannot find specified filter chain");
1983 }
1984 }
1985 } else {
1986 if (!chain || tcf_chain_held_by_acts_only(chain)) {
1987 NL_SET_ERR_MSG(extack, "Cannot find specified filter chain");
1885 return -EINVAL;
1988 err = -EINVAL;
1989 goto errout_block;
1886 }
1887 tcf_chain_hold(chain);
1888 }
1889
1890 switch (n->nlmsg_type) {
1891 case RTM_NEWCHAIN:
1892 err = tc_chain_tmplt_add(chain, net, tca, extack);
1893 if (err)

--- 27 unchanged lines hidden (view full) ---

1921 default:
1922 err = -EOPNOTSUPP;
1923 NL_SET_ERR_MSG(extack, "Unsupported message type");
1924 goto errout;
1925 }
1926
1927errout:
1928 tcf_chain_put(chain);
1990 }
1991 tcf_chain_hold(chain);
1992 }
1993
1994 switch (n->nlmsg_type) {
1995 case RTM_NEWCHAIN:
1996 err = tc_chain_tmplt_add(chain, net, tca, extack);
1997 if (err)

--- 27 unchanged lines hidden (view full) ---

2025 default:
2026 err = -EOPNOTSUPP;
2027 NL_SET_ERR_MSG(extack, "Unsupported message type");
2028 goto errout;
2029 }
2030
2031errout:
2032 tcf_chain_put(chain);
2033errout_block:
2034 tcf_block_release(q, block);
1929 if (err == -EAGAIN)
1930 /* Replay the request. */
1931 goto replay;
1932 return err;
1933}
1934
1935/* called with RTNL */
1936static int tc_dump_chain(struct sk_buff *skb, struct netlink_callback *cb)

--- 7 unchanged lines hidden (view full) ---

1944 long index_start;
1945 long index;
1946 u32 parent;
1947 int err;
1948
1949 if (nlmsg_len(cb->nlh) < sizeof(*tcm))
1950 return skb->len;
1951
2035 if (err == -EAGAIN)
2036 /* Replay the request. */
2037 goto replay;
2038 return err;
2039}
2040
2041/* called with RTNL */
2042static int tc_dump_chain(struct sk_buff *skb, struct netlink_callback *cb)

--- 7 unchanged lines hidden (view full) ---

2050 long index_start;
2051 long index;
2052 u32 parent;
2053 int err;
2054
2055 if (nlmsg_len(cb->nlh) < sizeof(*tcm))
2056 return skb->len;
2057
1952 err = nlmsg_parse(cb->nlh, sizeof(*tcm), tca, TCA_MAX, NULL, NULL);
2058 err = nlmsg_parse(cb->nlh, sizeof(*tcm), tca, TCA_MAX, NULL,
2059 cb->extack);
1953 if (err)
1954 return err;
1955
1956 if (tcm->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) {
2060 if (err)
2061 return err;
2062
2063 if (tcm->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) {
1957 block = tcf_block_lookup(net, tcm->tcm_block_index);
2064 block = tcf_block_refcnt_get(net, tcm->tcm_block_index);
1958 if (!block)
1959 goto out;
1960 /* If we work with block index, q is NULL and parent value
1961 * will never be used in the following code. The check
1962 * in tcf_fill_node prevents it. However, compiler does not
1963 * see that far, so set parent to zero to silence the warning
1964 * about parent being uninitialized.
1965 */

--- 50 unchanged lines hidden (view full) ---

2016 NETLINK_CB(cb->skb).portid,
2017 cb->nlh->nlmsg_seq, NLM_F_MULTI,
2018 RTM_NEWCHAIN);
2019 if (err <= 0)
2020 break;
2021 index++;
2022 }
2023
2065 if (!block)
2066 goto out;
2067 /* If we work with block index, q is NULL and parent value
2068 * will never be used in the following code. The check
2069 * in tcf_fill_node prevents it. However, compiler does not
2070 * see that far, so set parent to zero to silence the warning
2071 * about parent being uninitialized.
2072 */

--- 50 unchanged lines hidden (view full) ---

2123 NETLINK_CB(cb->skb).portid,
2124 cb->nlh->nlmsg_seq, NLM_F_MULTI,
2125 RTM_NEWCHAIN);
2126 if (err <= 0)
2127 break;
2128 index++;
2129 }
2130
2131 if (tcm->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK)
2132 tcf_block_refcnt_put(block);
2024 cb->args[0] = index;
2025
2026out:
2027 /* If we did no progress, the error (EMSGSIZE) is real */
2028 if (skb->len == 0 && err)
2029 return err;
2030 return skb->len;
2031}

--- 176 unchanged lines hidden (view full) ---

2208 return ok_count;
2209}
2210EXPORT_SYMBOL(tc_setup_cb_call);
2211
2212static __net_init int tcf_net_init(struct net *net)
2213{
2214 struct tcf_net *tn = net_generic(net, tcf_net_id);
2215
2133 cb->args[0] = index;
2134
2135out:
2136 /* If we did no progress, the error (EMSGSIZE) is real */
2137 if (skb->len == 0 && err)
2138 return err;
2139 return skb->len;
2140}

--- 176 unchanged lines hidden (view full) ---

2317 return ok_count;
2318}
2319EXPORT_SYMBOL(tc_setup_cb_call);
2320
2321static __net_init int tcf_net_init(struct net *net)
2322{
2323 struct tcf_net *tn = net_generic(net, tcf_net_id);
2324
2325 spin_lock_init(&tn->idr_lock);
2216 idr_init(&tn->idr);
2217 return 0;
2218}
2219
2220static void __net_exit tcf_net_exit(struct net *net)
2221{
2222 struct tcf_net *tn = net_generic(net, tcf_net_id);
2223

--- 39 unchanged lines hidden ---
2326 idr_init(&tn->idr);
2327 return 0;
2328}
2329
2330static void __net_exit tcf_net_exit(struct net *net)
2331{
2332 struct tcf_net *tn = net_generic(net, tcf_net_id);
2333

--- 39 unchanged lines hidden ---