• Home
  • Raw
  • Download

Lines Matching refs:chain

52 	return jhash_3words(tp->chain->index, tp->prio,  in destroy_obj_hashfn()
56 static void tcf_proto_signal_destroying(struct tcf_chain *chain, in tcf_proto_signal_destroying() argument
59 struct tcf_block *block = chain->block; in tcf_proto_signal_destroying()
70 return tp1->chain->index == tp2->chain->index && in tcf_proto_cmp()
75 static bool tcf_proto_exists_destroying(struct tcf_chain *chain, in tcf_proto_exists_destroying() argument
83 hash_for_each_possible_rcu(chain->block->proto_destroy_ht, iter, in tcf_proto_exists_destroying()
96 tcf_proto_signal_destroyed(struct tcf_chain *chain, struct tcf_proto *tp) in tcf_proto_signal_destroyed() argument
98 struct tcf_block *block = chain->block; in tcf_proto_signal_destroyed()
250 u32 prio, struct tcf_chain *chain, in tcf_proto_create() argument
269 tp->chain = chain; in tcf_proto_create()
290 static void tcf_chain_put(struct tcf_chain *chain);
297 tcf_proto_signal_destroyed(tp->chain, tp); in tcf_proto_destroy()
298 tcf_chain_put(tp->chain); in tcf_proto_destroy()
349 struct tcf_chain *chain; in tcf_chain_create() local
353 chain = kzalloc(sizeof(*chain), GFP_KERNEL); in tcf_chain_create()
354 if (!chain) in tcf_chain_create()
356 list_add_tail_rcu(&chain->list, &block->chain_list); in tcf_chain_create()
357 mutex_init(&chain->filter_chain_lock); in tcf_chain_create()
358 chain->block = block; in tcf_chain_create()
359 chain->index = chain_index; in tcf_chain_create()
360 chain->refcnt = 1; in tcf_chain_create()
361 if (!chain->index) in tcf_chain_create()
362 block->chain0.chain = chain; in tcf_chain_create()
363 return chain; in tcf_chain_create()
373 static void tcf_chain0_head_change(struct tcf_chain *chain, in tcf_chain0_head_change() argument
377 struct tcf_block *block = chain->block; in tcf_chain0_head_change()
379 if (chain->index) in tcf_chain0_head_change()
390 static bool tcf_chain_detach(struct tcf_chain *chain) in tcf_chain_detach() argument
392 struct tcf_block *block = chain->block; in tcf_chain_detach()
396 list_del_rcu(&chain->list); in tcf_chain_detach()
397 if (!chain->index) in tcf_chain_detach()
398 block->chain0.chain = NULL; in tcf_chain_detach()
414 static void tcf_chain_destroy(struct tcf_chain *chain, bool free_block) in tcf_chain_destroy() argument
416 struct tcf_block *block = chain->block; in tcf_chain_destroy()
418 mutex_destroy(&chain->filter_chain_lock); in tcf_chain_destroy()
419 kfree_rcu(chain, rcu); in tcf_chain_destroy()
424 static void tcf_chain_hold(struct tcf_chain *chain) in tcf_chain_hold() argument
426 ASSERT_BLOCK_LOCKED(chain->block); in tcf_chain_hold()
428 ++chain->refcnt; in tcf_chain_hold()
431 static bool tcf_chain_held_by_acts_only(struct tcf_chain *chain) in tcf_chain_held_by_acts_only() argument
433 ASSERT_BLOCK_LOCKED(chain->block); in tcf_chain_held_by_acts_only()
438 return chain->refcnt == chain->action_refcnt; in tcf_chain_held_by_acts_only()
444 struct tcf_chain *chain; in tcf_chain_lookup() local
448 list_for_each_entry(chain, &block->chain_list, list) { in tcf_chain_lookup()
449 if (chain->index == chain_index) in tcf_chain_lookup()
450 return chain; in tcf_chain_lookup()
459 struct tcf_chain *chain; in tcf_chain_lookup_rcu() local
461 list_for_each_entry_rcu(chain, &block->chain_list, list) { in tcf_chain_lookup_rcu()
462 if (chain->index == chain_index) in tcf_chain_lookup_rcu()
463 return chain; in tcf_chain_lookup_rcu()
469 static int tc_chain_notify(struct tcf_chain *chain, struct sk_buff *oskb,
476 struct tcf_chain *chain = NULL; in __tcf_chain_get() local
480 chain = tcf_chain_lookup(block, chain_index); in __tcf_chain_get()
481 if (chain) { in __tcf_chain_get()
482 tcf_chain_hold(chain); in __tcf_chain_get()
486 chain = tcf_chain_create(block, chain_index); in __tcf_chain_get()
487 if (!chain) in __tcf_chain_get()
492 ++chain->action_refcnt; in __tcf_chain_get()
493 is_first_reference = chain->refcnt - chain->action_refcnt == 1; in __tcf_chain_get()
502 tc_chain_notify(chain, NULL, 0, NLM_F_CREATE | NLM_F_EXCL, in __tcf_chain_get()
505 return chain; in __tcf_chain_get()
509 return chain; in __tcf_chain_get()
531 static void __tcf_chain_put(struct tcf_chain *chain, bool by_act, in __tcf_chain_put() argument
534 struct tcf_block *block = chain->block; in __tcf_chain_put()
542 if (!chain->explicitly_created) { in __tcf_chain_put()
546 chain->explicitly_created = false; in __tcf_chain_put()
550 chain->action_refcnt--; in __tcf_chain_put()
556 refcnt = --chain->refcnt; in __tcf_chain_put()
557 non_act_refcnt = refcnt - chain->action_refcnt; in __tcf_chain_put()
558 tmplt_ops = chain->tmplt_ops; in __tcf_chain_put()
559 tmplt_priv = chain->tmplt_priv; in __tcf_chain_put()
561 if (non_act_refcnt == chain->explicitly_created && !by_act) { in __tcf_chain_put()
564 chain->index, block, NULL, 0, 0, in __tcf_chain_put()
567 chain->flushing = false; in __tcf_chain_put()
571 free_block = tcf_chain_detach(chain); in __tcf_chain_put()
576 tcf_chain_destroy(chain, free_block); in __tcf_chain_put()
580 static void tcf_chain_put(struct tcf_chain *chain) in tcf_chain_put() argument
582 __tcf_chain_put(chain, false, false); in tcf_chain_put()
585 void tcf_chain_put_by_act(struct tcf_chain *chain) in tcf_chain_put_by_act() argument
587 __tcf_chain_put(chain, true, false); in tcf_chain_put_by_act()
591 static void tcf_chain_put_explicitly_created(struct tcf_chain *chain) in tcf_chain_put_explicitly_created() argument
593 __tcf_chain_put(chain, false, true); in tcf_chain_put_explicitly_created()
596 static void tcf_chain_flush(struct tcf_chain *chain, bool rtnl_held) in tcf_chain_flush() argument
600 mutex_lock(&chain->filter_chain_lock); in tcf_chain_flush()
601 tp = tcf_chain_dereference(chain->filter_chain, chain); in tcf_chain_flush()
604 tcf_proto_signal_destroying(chain, tp); in tcf_chain_flush()
607 tp = tcf_chain_dereference(chain->filter_chain, chain); in tcf_chain_flush()
608 RCU_INIT_POINTER(chain->filter_chain, NULL); in tcf_chain_flush()
609 tcf_chain0_head_change(chain, NULL); in tcf_chain_flush()
610 chain->flushing = true; in tcf_chain_flush()
611 mutex_unlock(&chain->filter_chain_lock); in tcf_chain_flush()
777 chain0 = block->chain0.chain; in tcf_chain0_head_change_cb_add()
815 if (block->chain0.chain) in tcf_chain0_head_change_cb_del()
910 __tcf_get_next_chain(struct tcf_block *block, struct tcf_chain *chain) in __tcf_get_next_chain() argument
913 if (chain) in __tcf_get_next_chain()
914 chain = list_is_last(&chain->list, &block->chain_list) ? in __tcf_get_next_chain()
915 NULL : list_next_entry(chain, list); in __tcf_get_next_chain()
917 chain = list_first_entry_or_null(&block->chain_list, in __tcf_get_next_chain()
921 while (chain && tcf_chain_held_by_acts_only(chain)) in __tcf_get_next_chain()
922 chain = list_is_last(&chain->list, &block->chain_list) ? in __tcf_get_next_chain()
923 NULL : list_next_entry(chain, list); in __tcf_get_next_chain()
925 if (chain) in __tcf_get_next_chain()
926 tcf_chain_hold(chain); in __tcf_get_next_chain()
929 return chain; in __tcf_get_next_chain()
942 tcf_get_next_chain(struct tcf_block *block, struct tcf_chain *chain) in tcf_get_next_chain() argument
944 struct tcf_chain *chain_next = __tcf_get_next_chain(block, chain); in tcf_get_next_chain()
946 if (chain) in tcf_get_next_chain()
947 tcf_chain_put(chain); in tcf_get_next_chain()
954 __tcf_get_next_proto(struct tcf_chain *chain, struct tcf_proto *tp) in __tcf_get_next_proto() argument
959 mutex_lock(&chain->filter_chain_lock); in __tcf_get_next_proto()
962 tp = tcf_chain_dereference(chain->filter_chain, chain); in __tcf_get_next_proto()
969 tp = tcf_chain_dereference(chain->filter_chain, chain); in __tcf_get_next_proto()
971 for (; tp; tp = tcf_chain_dereference(tp->next, chain)) in __tcf_get_next_proto()
975 tp = tcf_chain_dereference(tp->next, chain); in __tcf_get_next_proto()
981 mutex_unlock(&chain->filter_chain_lock); in __tcf_get_next_proto()
995 tcf_get_next_proto(struct tcf_chain *chain, struct tcf_proto *tp) in tcf_get_next_proto() argument
997 struct tcf_proto *tp_next = __tcf_get_next_proto(chain, tp); in tcf_get_next_proto()
1008 struct tcf_chain *chain; in tcf_block_flush_all_chains() local
1013 for (chain = tcf_get_next_chain(block, NULL); in tcf_block_flush_all_chains()
1014 chain; in tcf_block_flush_all_chains()
1015 chain = tcf_get_next_chain(block, chain)) { in tcf_block_flush_all_chains()
1016 tcf_chain_put_explicitly_created(chain); in tcf_block_flush_all_chains()
1017 tcf_chain_flush(chain, rtnl_held); in tcf_block_flush_all_chains()
1404 struct tcf_chain *chain, *chain_prev; in tcf_block_playback_offloads() local
1410 for (chain = __tcf_get_next_chain(block, NULL); in tcf_block_playback_offloads()
1411 chain; in tcf_block_playback_offloads()
1412 chain_prev = chain, in tcf_block_playback_offloads()
1413 chain = __tcf_get_next_chain(block, chain), in tcf_block_playback_offloads()
1415 for (tp = __tcf_get_next_proto(chain, NULL); tp; in tcf_block_playback_offloads()
1417 tp = __tcf_get_next_proto(chain, tp), in tcf_block_playback_offloads()
1436 tcf_chain_put(chain); in tcf_block_playback_offloads()
1554 *last_executed_chain = first_tp->chain->index; in __tcf_classify()
1571 tp->chain->block->index, in __tcf_classify()
1593 u32 last_executed_chain = tp ? tp->chain->index : 0; in tcf_classify()
1601 if (ext && ext->chain) { in tcf_classify()
1604 fchain = tcf_chain_lookup_rcu(block, ext->chain); in tcf_classify()
1626 ext->chain = last_executed_chain; in tcf_classify()
1644 static struct tcf_proto *tcf_chain_tp_prev(struct tcf_chain *chain, in tcf_chain_tp_prev() argument
1647 return tcf_chain_dereference(*chain_info->pprev, chain); in tcf_chain_tp_prev()
1650 static int tcf_chain_tp_insert(struct tcf_chain *chain, in tcf_chain_tp_insert() argument
1654 if (chain->flushing) in tcf_chain_tp_insert()
1657 RCU_INIT_POINTER(tp->next, tcf_chain_tp_prev(chain, chain_info)); in tcf_chain_tp_insert()
1658 if (*chain_info->pprev == chain->filter_chain) in tcf_chain_tp_insert()
1659 tcf_chain0_head_change(chain, tp); in tcf_chain_tp_insert()
1666 static void tcf_chain_tp_remove(struct tcf_chain *chain, in tcf_chain_tp_remove() argument
1670 struct tcf_proto *next = tcf_chain_dereference(chain_info->next, chain); in tcf_chain_tp_remove()
1673 if (tp == chain->filter_chain) in tcf_chain_tp_remove()
1674 tcf_chain0_head_change(chain, next); in tcf_chain_tp_remove()
1678 static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain,
1688 static struct tcf_proto *tcf_chain_tp_insert_unique(struct tcf_chain *chain, in tcf_chain_tp_insert_unique() argument
1697 mutex_lock(&chain->filter_chain_lock); in tcf_chain_tp_insert_unique()
1699 if (tcf_proto_exists_destroying(chain, tp_new)) { in tcf_chain_tp_insert_unique()
1700 mutex_unlock(&chain->filter_chain_lock); in tcf_chain_tp_insert_unique()
1705 tp = tcf_chain_tp_find(chain, &chain_info, in tcf_chain_tp_insert_unique()
1708 err = tcf_chain_tp_insert(chain, &chain_info, tp_new); in tcf_chain_tp_insert_unique()
1709 mutex_unlock(&chain->filter_chain_lock); in tcf_chain_tp_insert_unique()
1722 static void tcf_chain_tp_delete_empty(struct tcf_chain *chain, in tcf_chain_tp_delete_empty() argument
1731 mutex_lock(&chain->filter_chain_lock); in tcf_chain_tp_delete_empty()
1734 for (pprev = &chain->filter_chain; in tcf_chain_tp_delete_empty()
1735 (tp_iter = tcf_chain_dereference(*pprev, chain)); in tcf_chain_tp_delete_empty()
1749 mutex_unlock(&chain->filter_chain_lock); in tcf_chain_tp_delete_empty()
1753 tcf_proto_signal_destroying(chain, tp); in tcf_chain_tp_delete_empty()
1754 next = tcf_chain_dereference(chain_info.next, chain); in tcf_chain_tp_delete_empty()
1755 if (tp == chain->filter_chain) in tcf_chain_tp_delete_empty()
1756 tcf_chain0_head_change(chain, next); in tcf_chain_tp_delete_empty()
1758 mutex_unlock(&chain->filter_chain_lock); in tcf_chain_tp_delete_empty()
1763 static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain, in tcf_chain_tp_find() argument
1772 for (pprev = &chain->filter_chain; in tcf_chain_tp_find()
1773 (tp = tcf_chain_dereference(*pprev, chain)); in tcf_chain_tp_find()
1823 if (nla_put_u32(skb, TCA_CHAIN, tp->chain->index)) in tcf_fill_node()
1921 struct tcf_chain *chain, int event) in tfilter_notify_chain() argument
1925 for (tp = tcf_get_next_proto(chain, NULL); in tfilter_notify_chain()
1926 tp; tp = tcf_get_next_proto(chain, tp)) in tfilter_notify_chain()
1951 struct tcf_chain *chain; in tc_new_tfilter() local
1981 chain = NULL; in tc_new_tfilter()
2038 chain = tcf_chain_get(block, chain_index, true); in tc_new_tfilter()
2039 if (!chain) { in tc_new_tfilter()
2045 mutex_lock(&chain->filter_chain_lock); in tc_new_tfilter()
2046 tp = tcf_chain_tp_find(chain, &chain_info, protocol, in tc_new_tfilter()
2057 if (chain->flushing) { in tc_new_tfilter()
2077 prio = tcf_auto_prio(tcf_chain_tp_prev(chain, in tc_new_tfilter()
2080 mutex_unlock(&chain->filter_chain_lock); in tc_new_tfilter()
2081 tp_new = tcf_proto_create(name, protocol, prio, chain, in tc_new_tfilter()
2089 tp = tcf_chain_tp_insert_unique(chain, tp_new, protocol, prio, in tc_new_tfilter()
2096 mutex_unlock(&chain->filter_chain_lock); in tc_new_tfilter()
2120 if (chain->tmplt_ops && chain->tmplt_ops != tp->ops) { in tc_new_tfilter()
2144 tcf_chain_tp_delete_empty(chain, tp, rtnl_held, NULL); in tc_new_tfilter()
2146 if (chain) { in tc_new_tfilter()
2150 tcf_chain_put(chain); in tc_new_tfilter()
2168 mutex_unlock(&chain->filter_chain_lock); in tc_new_tfilter()
2185 struct tcf_chain *chain = NULL; in tc_del_tfilter() local
2250 chain = tcf_chain_get(block, chain_index, false); in tc_del_tfilter()
2251 if (!chain) { in tc_del_tfilter()
2266 chain, RTM_DELTFILTER); in tc_del_tfilter()
2267 tcf_chain_flush(chain, rtnl_held); in tc_del_tfilter()
2272 mutex_lock(&chain->filter_chain_lock); in tc_del_tfilter()
2273 tp = tcf_chain_tp_find(chain, &chain_info, protocol, in tc_del_tfilter()
2284 tcf_proto_signal_destroying(chain, tp); in tc_del_tfilter()
2285 tcf_chain_tp_remove(chain, &chain_info, tp); in tc_del_tfilter()
2286 mutex_unlock(&chain->filter_chain_lock); in tc_del_tfilter()
2294 mutex_unlock(&chain->filter_chain_lock); in tc_del_tfilter()
2311 tcf_chain_tp_delete_empty(chain, tp, rtnl_held, extack); in tc_del_tfilter()
2315 if (chain) { in tc_del_tfilter()
2318 tcf_chain_put(chain); in tc_del_tfilter()
2328 mutex_unlock(&chain->filter_chain_lock); in tc_del_tfilter()
2345 struct tcf_chain *chain = NULL; in tc_get_tfilter() local
2406 chain = tcf_chain_get(block, chain_index, false); in tc_get_tfilter()
2407 if (!chain) { in tc_get_tfilter()
2413 mutex_lock(&chain->filter_chain_lock); in tc_get_tfilter()
2414 tp = tcf_chain_tp_find(chain, &chain_info, protocol, in tc_get_tfilter()
2416 mutex_unlock(&chain->filter_chain_lock); in tc_get_tfilter()
2441 if (chain) { in tc_get_tfilter()
2444 tcf_chain_put(chain); in tc_get_tfilter()
2475 static bool tcf_chain_dump(struct tcf_chain *chain, struct Qdisc *q, u32 parent, in tcf_chain_dump() argument
2480 struct tcf_block *block = chain->block; in tcf_chain_dump()
2485 for (tp = __tcf_get_next_proto(chain, NULL); in tcf_chain_dump()
2488 tp = __tcf_get_next_proto(chain, tp), in tcf_chain_dump()
2543 struct tcf_chain *chain, *chain_prev; in tc_dump_tfilter() local
2618 for (chain = __tcf_get_next_chain(block, NULL); in tc_dump_tfilter()
2619 chain; in tc_dump_tfilter()
2620 chain_prev = chain, in tc_dump_tfilter()
2621 chain = __tcf_get_next_chain(block, chain), in tc_dump_tfilter()
2624 nla_get_u32(tca[TCA_CHAIN]) != chain->index) in tc_dump_tfilter()
2626 if (!tcf_chain_dump(chain, q, parent, skb, cb, in tc_dump_tfilter()
2628 tcf_chain_put(chain); in tc_dump_tfilter()
2695 static int tc_chain_notify(struct tcf_chain *chain, struct sk_buff *oskb, in tc_chain_notify() argument
2699 struct tcf_block *block = chain->block; in tc_chain_notify()
2708 if (tc_chain_fill_node(chain->tmplt_ops, chain->tmplt_priv, in tc_chain_notify()
2709 chain->index, net, skb, block, portid, in tc_chain_notify()
2749 static int tc_chain_tmplt_add(struct tcf_chain *chain, struct net *net, in tc_chain_tmplt_add() argument
2775 tmplt_priv = ops->tmplt_create(net, chain, tca, extack); in tc_chain_tmplt_add()
2780 chain->tmplt_ops = ops; in tc_chain_tmplt_add()
2781 chain->tmplt_priv = tmplt_priv; in tc_chain_tmplt_add()
2807 struct tcf_chain *chain; in tc_ctl_chain() local
2840 chain = tcf_chain_lookup(block, chain_index); in tc_ctl_chain()
2842 if (chain) { in tc_ctl_chain()
2843 if (tcf_chain_held_by_acts_only(chain)) { in tc_ctl_chain()
2847 tcf_chain_hold(chain); in tc_ctl_chain()
2859 chain = tcf_chain_create(block, chain_index); in tc_ctl_chain()
2860 if (!chain) { in tc_ctl_chain()
2867 if (!chain || tcf_chain_held_by_acts_only(chain)) { in tc_ctl_chain()
2872 tcf_chain_hold(chain); in tc_ctl_chain()
2881 tcf_chain_hold(chain); in tc_ctl_chain()
2882 chain->explicitly_created = true; in tc_ctl_chain()
2888 err = tc_chain_tmplt_add(chain, net, tca, extack); in tc_ctl_chain()
2890 tcf_chain_put_explicitly_created(chain); in tc_ctl_chain()
2894 tc_chain_notify(chain, NULL, 0, NLM_F_CREATE | NLM_F_EXCL, in tc_ctl_chain()
2899 chain, RTM_DELTFILTER); in tc_ctl_chain()
2901 tcf_chain_flush(chain, true); in tc_ctl_chain()
2905 tcf_chain_put_explicitly_created(chain); in tc_ctl_chain()
2908 err = tc_chain_notify(chain, skb, n->nlmsg_seq, in tc_ctl_chain()
2920 tcf_chain_put(chain); in tc_ctl_chain()
2941 struct tcf_chain *chain; in tc_dump_chain() local
2995 list_for_each_entry(chain, &block->chain_list, list) { in tc_dump_chain()
2997 nla_get_u32(tca[TCA_CHAIN]) != chain->index)) in tc_dump_chain()
3003 if (tcf_chain_held_by_acts_only(chain)) in tc_dump_chain()
3005 err = tc_chain_fill_node(chain->tmplt_ops, chain->tmplt_priv, in tc_dump_chain()
3006 chain->index, net, skb, block, in tc_dump_chain()