.. | .. |
---|
41 | 41 | #include <net/tc_act/tc_gate.h> |
---|
42 | 42 | #include <net/flow_offload.h> |
---|
43 | 43 | |
---|
44 | | -extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1]; |
---|
45 | | - |
---|
46 | 44 | /* The list of all installed classifier types */ |
---|
47 | 45 | static LIST_HEAD(tcf_proto_base); |
---|
48 | 46 | |
---|
.. | .. |
---|
535 | 533 | { |
---|
536 | 534 | struct tcf_block *block = chain->block; |
---|
537 | 535 | const struct tcf_proto_ops *tmplt_ops; |
---|
| 536 | + unsigned int refcnt, non_act_refcnt; |
---|
538 | 537 | bool free_block = false; |
---|
539 | | - unsigned int refcnt; |
---|
540 | 538 | void *tmplt_priv; |
---|
541 | 539 | |
---|
542 | 540 | mutex_lock(&block->lock); |
---|
.. | .. |
---|
556 | 554 | * save these to temporary variables. |
---|
557 | 555 | */ |
---|
558 | 556 | refcnt = --chain->refcnt; |
---|
| 557 | + non_act_refcnt = refcnt - chain->action_refcnt; |
---|
559 | 558 | tmplt_ops = chain->tmplt_ops; |
---|
560 | 559 | tmplt_priv = chain->tmplt_priv; |
---|
561 | 560 | |
---|
562 | | - /* The last dropped non-action reference will trigger notification. */ |
---|
563 | | - if (refcnt - chain->action_refcnt == 0 && !by_act) { |
---|
564 | | - tc_chain_notify_delete(tmplt_ops, tmplt_priv, chain->index, |
---|
565 | | - block, NULL, 0, 0, false); |
---|
| 561 | + if (non_act_refcnt == chain->explicitly_created && !by_act) { |
---|
| 562 | + if (non_act_refcnt == 0) |
---|
| 563 | + tc_chain_notify_delete(tmplt_ops, tmplt_priv, |
---|
| 564 | + chain->index, block, NULL, 0, 0, |
---|
| 565 | + false); |
---|
566 | 566 | /* Last reference to chain, no need to lock. */ |
---|
567 | 567 | chain->flushing = false; |
---|
568 | 568 | } |
---|
.. | .. |
---|
1466 | 1466 | |
---|
1467 | 1467 | err_unroll: |
---|
1468 | 1468 | list_for_each_entry_safe(block_cb, next, &bo->cb_list, list) { |
---|
| 1469 | + list_del(&block_cb->driver_list); |
---|
1469 | 1470 | if (i-- > 0) { |
---|
1470 | 1471 | list_del(&block_cb->list); |
---|
1471 | 1472 | tcf_block_playback_offloads(block, block_cb->cb, |
---|
.. | .. |
---|
2773 | 2774 | return PTR_ERR(ops); |
---|
2774 | 2775 | if (!ops->tmplt_create || !ops->tmplt_destroy || !ops->tmplt_dump) { |
---|
2775 | 2776 | NL_SET_ERR_MSG(extack, "Chain templates are not supported with specified classifier"); |
---|
| 2777 | + module_put(ops->owner); |
---|
2776 | 2778 | return -EOPNOTSUPP; |
---|
2777 | 2779 | } |
---|
2778 | 2780 | |
---|