Lines Matching full:chain
54 const struct tcf_chain *chain; member
91 n->chain_index = tp->chain->index; in tcf_exts_miss_cookie_base_alloc()
92 n->chain = tp->chain; in tcf_exts_miss_cookie_base_alloc()
174 return jhash_3words(tp->chain->index, tp->prio, in destroy_obj_hashfn()
178 static void tcf_proto_signal_destroying(struct tcf_chain *chain, in tcf_proto_signal_destroying() argument
181 struct tcf_block *block = chain->block; in tcf_proto_signal_destroying()
192 return tp1->chain->index == tp2->chain->index && in tcf_proto_cmp()
197 static bool tcf_proto_exists_destroying(struct tcf_chain *chain, in tcf_proto_exists_destroying() argument
205 hash_for_each_possible_rcu(chain->block->proto_destroy_ht, iter, in tcf_proto_exists_destroying()
218 tcf_proto_signal_destroyed(struct tcf_chain *chain, struct tcf_proto *tp) in tcf_proto_signal_destroyed() argument
220 struct tcf_block *block = chain->block; in tcf_proto_signal_destroyed()
373 u32 prio, struct tcf_chain *chain, in tcf_proto_create() argument
392 tp->chain = chain; in tcf_proto_create()
417 struct tcf_block *block = tp->chain->block; in tcf_proto_count_usesw()
441 static void tcf_chain_put(struct tcf_chain *chain);
449 tcf_proto_signal_destroyed(tp->chain, tp); in tcf_proto_destroy()
450 tcf_chain_put(tp->chain); in tcf_proto_destroy()
501 struct tcf_chain *chain; in tcf_chain_create() local
505 chain = kzalloc(sizeof(*chain), GFP_KERNEL); in tcf_chain_create()
506 if (!chain) in tcf_chain_create()
508 list_add_tail_rcu(&chain->list, &block->chain_list); in tcf_chain_create()
509 mutex_init(&chain->filter_chain_lock); in tcf_chain_create()
510 chain->block = block; in tcf_chain_create()
511 chain->index = chain_index; in tcf_chain_create()
512 chain->refcnt = 1; in tcf_chain_create()
513 if (!chain->index) in tcf_chain_create()
514 block->chain0.chain = chain; in tcf_chain_create()
515 return chain; in tcf_chain_create()
525 static void tcf_chain0_head_change(struct tcf_chain *chain, in tcf_chain0_head_change() argument
529 struct tcf_block *block = chain->block; in tcf_chain0_head_change()
531 if (chain->index) in tcf_chain0_head_change()
542 static bool tcf_chain_detach(struct tcf_chain *chain) in tcf_chain_detach() argument
544 struct tcf_block *block = chain->block; in tcf_chain_detach()
548 list_del_rcu(&chain->list); in tcf_chain_detach()
549 if (!chain->index) in tcf_chain_detach()
550 block->chain0.chain = NULL; in tcf_chain_detach()
567 static void tcf_chain_destroy(struct tcf_chain *chain, bool free_block) in tcf_chain_destroy() argument
569 struct tcf_block *block = chain->block; in tcf_chain_destroy()
571 mutex_destroy(&chain->filter_chain_lock); in tcf_chain_destroy()
572 kfree_rcu(chain, rcu); in tcf_chain_destroy()
577 static void tcf_chain_hold(struct tcf_chain *chain) in tcf_chain_hold() argument
579 ASSERT_BLOCK_LOCKED(chain->block); in tcf_chain_hold()
581 ++chain->refcnt; in tcf_chain_hold()
584 static bool tcf_chain_held_by_acts_only(struct tcf_chain *chain) in tcf_chain_held_by_acts_only() argument
586 ASSERT_BLOCK_LOCKED(chain->block); in tcf_chain_held_by_acts_only()
589 * chain should not be shown to the user. in tcf_chain_held_by_acts_only()
591 return chain->refcnt == chain->action_refcnt; in tcf_chain_held_by_acts_only()
597 struct tcf_chain *chain; in tcf_chain_lookup() local
601 list_for_each_entry(chain, &block->chain_list, list) { in tcf_chain_lookup()
602 if (chain->index == chain_index) in tcf_chain_lookup()
603 return chain; in tcf_chain_lookup()
612 struct tcf_chain *chain; in tcf_chain_lookup_rcu() local
614 list_for_each_entry_rcu(chain, &block->chain_list, list) { in tcf_chain_lookup_rcu()
615 if (chain->index == chain_index) in tcf_chain_lookup_rcu()
616 return chain; in tcf_chain_lookup_rcu()
622 static int tc_chain_notify(struct tcf_chain *chain, struct sk_buff *oskb,
630 struct tcf_chain *chain = NULL; in __tcf_chain_get() local
634 chain = tcf_chain_lookup(block, chain_index); in __tcf_chain_get()
635 if (chain) { in __tcf_chain_get()
636 tcf_chain_hold(chain); in __tcf_chain_get()
640 chain = tcf_chain_create(block, chain_index); in __tcf_chain_get()
641 if (!chain) in __tcf_chain_get()
646 ++chain->action_refcnt; in __tcf_chain_get()
647 is_first_reference = chain->refcnt - chain->action_refcnt == 1; in __tcf_chain_get()
651 * non-action reference. Until then, the chain acts only as in __tcf_chain_get()
656 tc_chain_notify(chain, NULL, 0, NLM_F_CREATE | NLM_F_EXCL, in __tcf_chain_get()
659 return chain; in __tcf_chain_get()
663 return chain; in __tcf_chain_get()
685 static void __tcf_chain_put(struct tcf_chain *chain, bool by_act, in __tcf_chain_put() argument
688 struct tcf_block *block = chain->block; in __tcf_chain_put()
696 if (!chain->explicitly_created) { in __tcf_chain_put()
700 chain->explicitly_created = false; in __tcf_chain_put()
704 chain->action_refcnt--; in __tcf_chain_put()
707 * However, when block is unlocked chain can be changed concurrently, so in __tcf_chain_put()
710 refcnt = --chain->refcnt; in __tcf_chain_put()
711 non_act_refcnt = refcnt - chain->action_refcnt; in __tcf_chain_put()
712 tmplt_ops = chain->tmplt_ops; in __tcf_chain_put()
713 tmplt_priv = chain->tmplt_priv; in __tcf_chain_put()
715 if (non_act_refcnt == chain->explicitly_created && !by_act) { in __tcf_chain_put()
718 chain->index, block, NULL, 0, 0); in __tcf_chain_put()
719 /* Last reference to chain, no need to lock. */ in __tcf_chain_put()
720 chain->flushing = false; in __tcf_chain_put()
724 free_block = tcf_chain_detach(chain); in __tcf_chain_put()
729 tcf_chain_destroy(chain, free_block); in __tcf_chain_put()
733 static void tcf_chain_put(struct tcf_chain *chain) in tcf_chain_put() argument
735 __tcf_chain_put(chain, false, false); in tcf_chain_put()
738 void tcf_chain_put_by_act(struct tcf_chain *chain) in tcf_chain_put_by_act() argument
740 __tcf_chain_put(chain, true, false); in tcf_chain_put_by_act()
744 static void tcf_chain_put_explicitly_created(struct tcf_chain *chain) in tcf_chain_put_explicitly_created() argument
746 __tcf_chain_put(chain, false, true); in tcf_chain_put_explicitly_created()
749 static void tcf_chain_flush(struct tcf_chain *chain, bool rtnl_held) in tcf_chain_flush() argument
753 mutex_lock(&chain->filter_chain_lock); in tcf_chain_flush()
754 tp = tcf_chain_dereference(chain->filter_chain, chain); in tcf_chain_flush()
757 tcf_proto_signal_destroying(chain, tp); in tcf_chain_flush()
760 tp = tcf_chain_dereference(chain->filter_chain, chain); in tcf_chain_flush()
761 RCU_INIT_POINTER(chain->filter_chain, NULL); in tcf_chain_flush()
762 tcf_chain0_head_change(chain, NULL); in tcf_chain_flush()
763 chain->flushing = true; in tcf_chain_flush()
764 mutex_unlock(&chain->filter_chain_lock); in tcf_chain_flush()
930 chain0 = block->chain0.chain; in tcf_chain0_head_change_cb_add()
968 if (block->chain0.chain) in tcf_chain0_head_change_cb_del()
1065 __tcf_get_next_chain(struct tcf_block *block, struct tcf_chain *chain) in __tcf_get_next_chain() argument
1068 if (chain) in __tcf_get_next_chain()
1069 chain = list_is_last(&chain->list, &block->chain_list) ? in __tcf_get_next_chain()
1070 NULL : list_next_entry(chain, list); in __tcf_get_next_chain()
1072 chain = list_first_entry_or_null(&block->chain_list, in __tcf_get_next_chain()
1076 while (chain && tcf_chain_held_by_acts_only(chain)) in __tcf_get_next_chain()
1077 chain = list_is_last(&chain->list, &block->chain_list) ? in __tcf_get_next_chain()
1078 NULL : list_next_entry(chain, list); in __tcf_get_next_chain()
1080 if (chain) in __tcf_get_next_chain()
1081 tcf_chain_hold(chain); in __tcf_get_next_chain()
1084 return chain; in __tcf_get_next_chain()
1088 * block. It properly obtains block->lock and takes reference to chain before
1089 * returning it. Users of this function must be tolerant to concurrent chain
1090 * insertion/deletion or ensure that no concurrent chain modification is
1097 tcf_get_next_chain(struct tcf_block *block, struct tcf_chain *chain) in tcf_get_next_chain() argument
1099 struct tcf_chain *chain_next = __tcf_get_next_chain(block, chain); in tcf_get_next_chain()
1101 if (chain) in tcf_get_next_chain()
1102 tcf_chain_put(chain); in tcf_get_next_chain()
1109 __tcf_get_next_proto(struct tcf_chain *chain, struct tcf_proto *tp) in __tcf_get_next_proto() argument
1114 mutex_lock(&chain->filter_chain_lock); in __tcf_get_next_proto()
1117 tp = tcf_chain_dereference(chain->filter_chain, chain); in __tcf_get_next_proto()
1119 /* 'deleting' flag is set and chain->filter_chain_lock was in __tcf_get_next_proto()
1124 tp = tcf_chain_dereference(chain->filter_chain, chain); in __tcf_get_next_proto()
1126 for (; tp; tp = tcf_chain_dereference(tp->next, chain)) in __tcf_get_next_proto()
1130 tp = tcf_chain_dereference(tp->next, chain); in __tcf_get_next_proto()
1136 mutex_unlock(&chain->filter_chain_lock); in __tcf_get_next_proto()
1142 * chain. Users of this function must be tolerant to concurrent tp
1143 * insertion/deletion or ensure that no concurrent chain modification is
1150 tcf_get_next_proto(struct tcf_chain *chain, struct tcf_proto *tp) in tcf_get_next_proto() argument
1152 struct tcf_proto *tp_next = __tcf_get_next_proto(chain, tp); in tcf_get_next_proto()
1163 struct tcf_chain *chain; in tcf_block_flush_all_chains() local
1168 for (chain = tcf_get_next_chain(block, NULL); in tcf_block_flush_all_chains()
1169 chain; in tcf_block_flush_all_chains()
1170 chain = tcf_get_next_chain(block, chain)) { in tcf_block_flush_all_chains()
1171 tcf_chain_put_explicitly_created(chain); in tcf_block_flush_all_chains()
1172 tcf_chain_flush(chain, rtnl_held); in tcf_block_flush_all_chains()
1317 * deallocated when last chain is freed. However, if chain_list in __tcf_block_put()
1547 /* XXX: Standalone actions are not allowed to jump to any chain, and bound
1582 struct tcf_chain *chain, *chain_prev; in tcf_block_playback_offloads() local
1588 for (chain = __tcf_get_next_chain(block, NULL); in tcf_block_playback_offloads()
1589 chain; in tcf_block_playback_offloads()
1590 chain_prev = chain, in tcf_block_playback_offloads()
1591 chain = __tcf_get_next_chain(block, chain), in tcf_block_playback_offloads()
1593 if (chain->tmplt_ops && add) in tcf_block_playback_offloads()
1594 chain->tmplt_ops->tmplt_reoffload(chain, true, cb, in tcf_block_playback_offloads()
1596 for (tp = __tcf_get_next_proto(chain, NULL); tp; in tcf_block_playback_offloads()
1598 tp = __tcf_get_next_proto(chain, tp), in tcf_block_playback_offloads()
1611 if (chain->tmplt_ops && !add) in tcf_block_playback_offloads()
1612 chain->tmplt_ops->tmplt_reoffload(chain, false, cb, in tcf_block_playback_offloads()
1620 tcf_chain_put(chain); in tcf_block_playback_offloads()
1708 /* Main classifier routine: scans classifier chain attached
1738 /* We re-lookup the tp and chain based on index instead in __tcf_classify()
1740 * check if any of tp,chain,exts was replaced by the in __tcf_classify()
1743 if (unlikely(n->tp != tp || n->tp->chain != n->chain || in __tcf_classify()
1769 *last_executed_chain = first_tp->chain->index; in __tcf_classify()
1792 tp->chain->block->index, in __tcf_classify()
1816 u32 last_executed_chain = tp ? tp->chain->index : 0; in tcf_classify()
1826 if (ext && (ext->chain || ext->act_miss)) { in tcf_classify()
1828 u32 chain; in tcf_classify()
1839 chain = n->chain_index; in tcf_classify()
1841 chain = ext->chain; in tcf_classify()
1844 fchain = tcf_chain_lookup_rcu(block, chain); in tcf_classify()
1864 /* If we missed on some chain */ in tcf_classify()
1873 ext->chain = last_executed_chain; in tcf_classify()
1892 static struct tcf_proto *tcf_chain_tp_prev(struct tcf_chain *chain, in tcf_chain_tp_prev() argument
1895 return tcf_chain_dereference(*chain_info->pprev, chain); in tcf_chain_tp_prev()
1898 static int tcf_chain_tp_insert(struct tcf_chain *chain, in tcf_chain_tp_insert() argument
1902 if (chain->flushing) in tcf_chain_tp_insert()
1905 RCU_INIT_POINTER(tp->next, tcf_chain_tp_prev(chain, chain_info)); in tcf_chain_tp_insert()
1906 if (*chain_info->pprev == chain->filter_chain) in tcf_chain_tp_insert()
1907 tcf_chain0_head_change(chain, tp); in tcf_chain_tp_insert()
1914 static void tcf_chain_tp_remove(struct tcf_chain *chain, in tcf_chain_tp_remove() argument
1918 struct tcf_proto *next = tcf_chain_dereference(chain_info->next, chain); in tcf_chain_tp_remove()
1921 if (tp == chain->filter_chain) in tcf_chain_tp_remove()
1922 tcf_chain0_head_change(chain, next); in tcf_chain_tp_remove()
1926 static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain,
1937 static struct tcf_proto *tcf_chain_tp_insert_unique(struct tcf_chain *chain, in tcf_chain_tp_insert_unique() argument
1946 mutex_lock(&chain->filter_chain_lock); in tcf_chain_tp_insert_unique()
1948 if (tcf_proto_exists_destroying(chain, tp_new)) { in tcf_chain_tp_insert_unique()
1949 mutex_unlock(&chain->filter_chain_lock); in tcf_chain_tp_insert_unique()
1954 tp = tcf_chain_tp_find(chain, &chain_info, protocol, prio, false, NULL); in tcf_chain_tp_insert_unique()
1956 err = tcf_chain_tp_insert(chain, &chain_info, tp_new); in tcf_chain_tp_insert_unique()
1957 mutex_unlock(&chain->filter_chain_lock); in tcf_chain_tp_insert_unique()
1970 static void tcf_chain_tp_delete_empty(struct tcf_chain *chain, in tcf_chain_tp_delete_empty() argument
1979 mutex_lock(&chain->filter_chain_lock); in tcf_chain_tp_delete_empty()
1981 /* Atomically find and remove tp from chain. */ in tcf_chain_tp_delete_empty()
1982 for (pprev = &chain->filter_chain; in tcf_chain_tp_delete_empty()
1983 (tp_iter = tcf_chain_dereference(*pprev, chain)); in tcf_chain_tp_delete_empty()
1997 mutex_unlock(&chain->filter_chain_lock); in tcf_chain_tp_delete_empty()
2001 tcf_proto_signal_destroying(chain, tp); in tcf_chain_tp_delete_empty()
2002 next = tcf_chain_dereference(chain_info.next, chain); in tcf_chain_tp_delete_empty()
2003 if (tp == chain->filter_chain) in tcf_chain_tp_delete_empty()
2004 tcf_chain0_head_change(chain, next); in tcf_chain_tp_delete_empty()
2006 mutex_unlock(&chain->filter_chain_lock); in tcf_chain_tp_delete_empty()
2011 static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain, in tcf_chain_tp_find() argument
2020 /* Check the chain for existence of proto-tcf with this priority */ in tcf_chain_tp_find()
2021 for (pprev = &chain->filter_chain; in tcf_chain_tp_find()
2022 (tp = tcf_chain_dereference(*pprev, chain)); in tcf_chain_tp_find()
2079 if (nla_put_u32(skb, TCA_CHAIN, tp->chain->index)) in tcf_fill_node()
2209 struct tcf_chain *chain, int event, in tfilter_notify_chain() argument
2214 for (tp = tcf_get_next_proto(chain, NULL); in tfilter_notify_chain()
2215 tp; tp = tcf_get_next_proto(chain, tp)) in tfilter_notify_chain()
2245 struct tcf_chain *chain; in tc_new_tfilter() local
2272 chain = NULL; in tc_new_tfilter()
2288 /* Find head of filter chain. */ in tc_new_tfilter()
2325 NL_SET_ERR_MSG(extack, "Specified chain index exceeds upper limit"); in tc_new_tfilter()
2329 chain = tcf_chain_get(block, chain_index, true); in tc_new_tfilter()
2330 if (!chain) { in tc_new_tfilter()
2331 NL_SET_ERR_MSG(extack, "Cannot create specified filter chain"); in tc_new_tfilter()
2336 mutex_lock(&chain->filter_chain_lock); in tc_new_tfilter()
2337 tp = tcf_chain_tp_find(chain, &chain_info, protocol, in tc_new_tfilter()
2347 if (chain->flushing) { in tc_new_tfilter()
2367 prio = tcf_auto_prio(tcf_chain_tp_prev(chain, in tc_new_tfilter()
2370 mutex_unlock(&chain->filter_chain_lock); in tc_new_tfilter()
2371 tp_new = tcf_proto_create(name, protocol, prio, chain, in tc_new_tfilter()
2379 tp = tcf_chain_tp_insert_unique(chain, tp_new, protocol, prio, in tc_new_tfilter()
2386 mutex_unlock(&chain->filter_chain_lock); in tc_new_tfilter()
2410 if (chain->tmplt_ops && chain->tmplt_ops != tp->ops) { in tc_new_tfilter()
2412 NL_SET_ERR_MSG(extack, "Chain template is set to a different filter kind"); in tc_new_tfilter()
2437 tcf_chain_tp_delete_empty(chain, tp, rtnl_held, NULL); in tc_new_tfilter()
2439 if (chain) { in tc_new_tfilter()
2443 tcf_chain_put(chain); in tc_new_tfilter()
2452 * of target chain. in tc_new_tfilter()
2461 mutex_unlock(&chain->filter_chain_lock); in tc_new_tfilter()
2478 struct tcf_chain *chain = NULL; in tc_del_tfilter() local
2501 /* Find head of filter chain. */ in tc_del_tfilter()
2512 /* Take rtnl mutex if flushing whole chain, block is shared (no qdisc in tc_del_tfilter()
2536 NL_SET_ERR_MSG(extack, "Specified chain index exceeds upper limit"); in tc_del_tfilter()
2540 chain = tcf_chain_get(block, chain_index, false); in tc_del_tfilter()
2541 if (!chain) { in tc_del_tfilter()
2542 /* User requested flush on non-existent chain. Nothing to do, in tc_del_tfilter()
2549 NL_SET_ERR_MSG(extack, "Cannot find specified filter chain"); in tc_del_tfilter()
2556 chain, RTM_DELTFILTER, extack); in tc_del_tfilter()
2557 tcf_chain_flush(chain, rtnl_held); in tc_del_tfilter()
2562 mutex_lock(&chain->filter_chain_lock); in tc_del_tfilter()
2563 tp = tcf_chain_tp_find(chain, &chain_info, protocol, in tc_del_tfilter()
2577 tcf_proto_signal_destroying(chain, tp); in tc_del_tfilter()
2578 tcf_chain_tp_remove(chain, &chain_info, tp); in tc_del_tfilter()
2579 mutex_unlock(&chain->filter_chain_lock); in tc_del_tfilter()
2587 mutex_unlock(&chain->filter_chain_lock); in tc_del_tfilter()
2603 tcf_chain_tp_delete_empty(chain, tp, rtnl_held, extack); in tc_del_tfilter()
2607 if (chain) { in tc_del_tfilter()
2610 tcf_chain_put(chain); in tc_del_tfilter()
2620 mutex_unlock(&chain->filter_chain_lock); in tc_del_tfilter()
2637 struct tcf_chain *chain = NULL; in tc_get_tfilter() local
2660 /* Find head of filter chain. */ in tc_get_tfilter()
2694 NL_SET_ERR_MSG(extack, "Specified chain index exceeds upper limit"); in tc_get_tfilter()
2698 chain = tcf_chain_get(block, chain_index, false); in tc_get_tfilter()
2699 if (!chain) { in tc_get_tfilter()
2700 NL_SET_ERR_MSG(extack, "Cannot find specified filter chain"); in tc_get_tfilter()
2705 mutex_lock(&chain->filter_chain_lock); in tc_get_tfilter()
2706 tp = tcf_chain_tp_find(chain, &chain_info, protocol, in tc_get_tfilter()
2708 mutex_unlock(&chain->filter_chain_lock); in tc_get_tfilter()
2736 if (chain) { in tc_get_tfilter()
2739 tcf_chain_put(chain); in tc_get_tfilter()
2770 static bool tcf_chain_dump(struct tcf_chain *chain, struct Qdisc *q, u32 parent, in tcf_chain_dump() argument
2775 struct tcf_block *block = chain->block; in tcf_chain_dump()
2780 for (tp = __tcf_get_next_proto(chain, NULL); in tcf_chain_dump()
2783 tp = __tcf_get_next_proto(chain, tp), in tcf_chain_dump()
2839 struct tcf_chain *chain, *chain_prev; in tc_dump_tfilter() local
2914 for (chain = __tcf_get_next_chain(block, NULL); in tc_dump_tfilter()
2915 chain; in tc_dump_tfilter()
2916 chain_prev = chain, in tc_dump_tfilter()
2917 chain = __tcf_get_next_chain(block, chain), in tc_dump_tfilter()
2920 nla_get_u32(tca[TCA_CHAIN]) != chain->index) in tc_dump_tfilter()
2922 if (!tcf_chain_dump(chain, q, parent, skb, cb, in tc_dump_tfilter()
2924 tcf_chain_put(chain); in tc_dump_tfilter()
2997 static int tc_chain_notify(struct tcf_chain *chain, struct sk_buff *oskb, in tc_chain_notify() argument
3002 struct tcf_block *block = chain->block; in tc_chain_notify()
3014 if (tc_chain_fill_node(chain->tmplt_ops, chain->tmplt_priv, in tc_chain_notify()
3015 chain->index, net, skb, block, portid, in tc_chain_notify()
3055 static int tc_chain_tmplt_add(struct tcf_chain *chain, struct net *net, in tc_chain_tmplt_add() argument
3068 NL_SET_ERR_MSG(extack, "Specified TC chain template name too long"); in tc_chain_tmplt_add()
3077 NL_SET_ERR_MSG(extack, "Chain templates are not supported with specified classifier"); in tc_chain_tmplt_add()
3082 tmplt_priv = ops->tmplt_create(net, chain, tca, extack); in tc_chain_tmplt_add()
3087 chain->tmplt_ops = ops; in tc_chain_tmplt_add()
3088 chain->tmplt_priv = tmplt_priv; in tc_chain_tmplt_add()
3103 /* Add/delete/get a chain */
3114 struct tcf_chain *chain; in tc_ctl_chain() local
3137 NL_SET_ERR_MSG(extack, "Specified chain index exceeds upper limit"); in tc_ctl_chain()
3143 chain = tcf_chain_lookup(block, chain_index); in tc_ctl_chain()
3145 if (chain) { in tc_ctl_chain()
3146 if (tcf_chain_held_by_acts_only(chain)) { in tc_ctl_chain()
3147 /* The chain exists only because there is in tc_ctl_chain()
3150 tcf_chain_hold(chain); in tc_ctl_chain()
3152 NL_SET_ERR_MSG(extack, "Filter chain already exists"); in tc_ctl_chain()
3158 NL_SET_ERR_MSG(extack, "Need both RTM_NEWCHAIN and NLM_F_CREATE to create a new chain"); in tc_ctl_chain()
3162 chain = tcf_chain_create(block, chain_index); in tc_ctl_chain()
3163 if (!chain) { in tc_ctl_chain()
3164 NL_SET_ERR_MSG(extack, "Failed to create filter chain"); in tc_ctl_chain()
3170 if (!chain || tcf_chain_held_by_acts_only(chain)) { in tc_ctl_chain()
3171 NL_SET_ERR_MSG(extack, "Cannot find specified filter chain"); in tc_ctl_chain()
3175 tcf_chain_hold(chain); in tc_ctl_chain()
3179 /* Modifying chain requires holding parent block lock. In case in tc_ctl_chain()
3180 * the chain was successfully added, take a reference to the in tc_ctl_chain()
3181 * chain. This ensures that an empty chain does not disappear at in tc_ctl_chain()
3184 tcf_chain_hold(chain); in tc_ctl_chain()
3185 chain->explicitly_created = true; in tc_ctl_chain()
3191 err = tc_chain_tmplt_add(chain, net, tca, extack); in tc_ctl_chain()
3193 tcf_chain_put_explicitly_created(chain); in tc_ctl_chain()
3197 tc_chain_notify(chain, NULL, 0, NLM_F_CREATE | NLM_F_EXCL, in tc_ctl_chain()
3202 chain, RTM_DELTFILTER, extack); in tc_ctl_chain()
3203 /* Flush the chain first as the user requested chain removal. */ in tc_ctl_chain()
3204 tcf_chain_flush(chain, true); in tc_ctl_chain()
3205 /* In case the chain was successfully deleted, put a reference in tc_ctl_chain()
3206 * to the chain previously taken during addition. in tc_ctl_chain()
3208 tcf_chain_put_explicitly_created(chain); in tc_ctl_chain()
3211 err = tc_chain_notify(chain, skb, n->nlmsg_seq, in tc_ctl_chain()
3214 NL_SET_ERR_MSG(extack, "Failed to send chain notify message"); in tc_ctl_chain()
3223 tcf_chain_put(chain); in tc_ctl_chain()
3244 struct tcf_chain *chain; in tc_dump_chain() local
3298 list_for_each_entry(chain, &block->chain_list, list) { in tc_dump_chain()
3300 nla_get_u32(tca[TCA_CHAIN]) != chain->index)) in tc_dump_chain()
3306 if (tcf_chain_held_by_acts_only(chain)) in tc_dump_chain()
3308 err = tc_chain_fill_node(chain->tmplt_ops, chain->tmplt_priv, in tc_dump_chain()
3309 chain->index, net, skb, block, in tc_dump_chain()