Lines Matching +full:tp +full:- +full:link

1 // SPDX-License-Identifier: GPL-2.0-or-later
34 struct tcf_proto *tp; member
35 struct list_head link; member
41 const struct tcf_proto *tp, in basic_classify() argument
45 struct basic_head *head = rcu_dereference_bh(tp->root); in basic_classify()
48 list_for_each_entry_rcu(f, &head->flist, link) { in basic_classify()
49 __this_cpu_inc(f->pf->rcnt); in basic_classify()
50 if (!tcf_em_tree_match(skb, &f->ematches, NULL)) in basic_classify()
52 __this_cpu_inc(f->pf->rhit); in basic_classify()
53 *res = f->res; in basic_classify()
54 r = tcf_exts_exec(skb, &f->exts, res); in basic_classify()
59 return -1; in basic_classify()
62 static void *basic_get(struct tcf_proto *tp, u32 handle) in basic_get() argument
64 struct basic_head *head = rtnl_dereference(tp->root); in basic_get()
67 list_for_each_entry(f, &head->flist, link) { in basic_get()
68 if (f->handle == handle) { in basic_get()
76 static int basic_init(struct tcf_proto *tp) in basic_init() argument
82 return -ENOBUFS; in basic_init()
83 INIT_LIST_HEAD(&head->flist); in basic_init()
84 idr_init(&head->handle_idr); in basic_init()
85 rcu_assign_pointer(tp->root, head); in basic_init()
91 tcf_exts_destroy(&f->exts); in __basic_delete_filter()
92 tcf_em_tree_destroy(&f->ematches); in __basic_delete_filter()
93 tcf_exts_put_net(&f->exts); in __basic_delete_filter()
94 free_percpu(f->pf); in __basic_delete_filter()
108 static void basic_destroy(struct tcf_proto *tp, bool rtnl_held, in basic_destroy() argument
111 struct basic_head *head = rtnl_dereference(tp->root); in basic_destroy()
114 list_for_each_entry_safe(f, n, &head->flist, link) { in basic_destroy()
115 list_del_rcu(&f->link); in basic_destroy()
116 tcf_unbind_filter(tp, &f->res); in basic_destroy()
117 idr_remove(&head->handle_idr, f->handle); in basic_destroy()
118 if (tcf_exts_get_net(&f->exts)) in basic_destroy()
119 tcf_queue_work(&f->rwork, basic_delete_filter_work); in basic_destroy()
123 idr_destroy(&head->handle_idr); in basic_destroy()
127 static int basic_delete(struct tcf_proto *tp, void *arg, bool *last, in basic_delete() argument
130 struct basic_head *head = rtnl_dereference(tp->root); in basic_delete()
133 list_del_rcu(&f->link); in basic_delete()
134 tcf_unbind_filter(tp, &f->res); in basic_delete()
135 idr_remove(&head->handle_idr, f->handle); in basic_delete()
136 tcf_exts_get_net(&f->exts); in basic_delete()
137 tcf_queue_work(&f->rwork, basic_delete_filter_work); in basic_delete()
138 *last = list_empty(&head->flist); in basic_delete()
147 static int basic_set_parms(struct net *net, struct tcf_proto *tp, in basic_set_parms() argument
155 err = tcf_exts_validate(net, tp, tb, est, &f->exts, flags, extack); in basic_set_parms()
159 err = tcf_em_tree_validate(tp, tb[TCA_BASIC_EMATCHES], &f->ematches); in basic_set_parms()
164 f->res.classid = nla_get_u32(tb[TCA_BASIC_CLASSID]); in basic_set_parms()
165 tcf_bind_filter(tp, &f->res, base); in basic_set_parms()
168 f->tp = tp; in basic_set_parms()
173 struct tcf_proto *tp, unsigned long base, u32 handle, in basic_change() argument
178 struct basic_head *head = rtnl_dereference(tp->root); in basic_change()
184 return -EINVAL; in basic_change()
192 if (handle && fold->handle != handle) in basic_change()
193 return -EINVAL; in basic_change()
198 return -ENOBUFS; in basic_change()
200 err = tcf_exts_init(&fnew->exts, net, TCA_BASIC_ACT, TCA_BASIC_POLICE); in basic_change()
206 err = idr_alloc_u32(&head->handle_idr, fnew, &handle, in basic_change()
209 err = idr_alloc_u32(&head->handle_idr, fnew, &handle, in basic_change()
214 fnew->handle = handle; in basic_change()
215 fnew->pf = alloc_percpu(struct tc_basic_pcnt); in basic_change()
216 if (!fnew->pf) { in basic_change()
217 err = -ENOMEM; in basic_change()
221 err = basic_set_parms(net, tp, fnew, base, tb, tca[TCA_RATE], flags, in basic_change()
225 idr_remove(&head->handle_idr, fnew->handle); in basic_change()
232 idr_replace(&head->handle_idr, fnew, fnew->handle); in basic_change()
233 list_replace_rcu(&fold->link, &fnew->link); in basic_change()
234 tcf_unbind_filter(tp, &fold->res); in basic_change()
235 tcf_exts_get_net(&fold->exts); in basic_change()
236 tcf_queue_work(&fold->rwork, basic_delete_filter_work); in basic_change()
238 list_add_rcu(&fnew->link, &head->flist); in basic_change()
243 free_percpu(fnew->pf); in basic_change()
244 tcf_exts_destroy(&fnew->exts); in basic_change()
249 static void basic_walk(struct tcf_proto *tp, struct tcf_walker *arg, in basic_walk() argument
252 struct basic_head *head = rtnl_dereference(tp->root); in basic_walk()
255 list_for_each_entry(f, &head->flist, link) { in basic_walk()
256 if (!tc_cls_stats_dump(tp, arg, f)) in basic_walk()
266 tc_cls_bind_class(classid, cl, q, &f->res, base); in basic_bind_class()
269 static int basic_dump(struct net *net, struct tcf_proto *tp, void *fh, in basic_dump() argument
278 return skb->len; in basic_dump()
280 t->tcm_handle = f->handle; in basic_dump()
286 if (f->res.classid && in basic_dump()
287 nla_put_u32(skb, TCA_BASIC_CLASSID, f->res.classid)) in basic_dump()
291 struct tc_basic_pcnt *pf = per_cpu_ptr(f->pf, cpu); in basic_dump()
293 gpf.rcnt += pf->rcnt; in basic_dump()
294 gpf.rhit += pf->rhit; in basic_dump()
302 if (tcf_exts_dump(skb, &f->exts) < 0 || in basic_dump()
303 tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0) in basic_dump()
308 if (tcf_exts_dump_stats(skb, &f->exts) < 0) in basic_dump()
311 return skb->len; in basic_dump()
315 return -1; in basic_dump()