Lines Matching +full:t +full:- +full:head
1 // SPDX-License-Identifier: GPL-2.0-or-later
55 struct fw_head *head = rcu_dereference_bh(tp->root); in fw_classify() local
58 u32 id = skb->mark; in fw_classify()
60 if (head != NULL) { in fw_classify()
61 id &= head->mask; in fw_classify()
63 for (f = rcu_dereference_bh(head->ht[fw_hash(id)]); f; in fw_classify()
64 f = rcu_dereference_bh(f->next)) { in fw_classify()
65 if (f->id == id) { in fw_classify()
66 *res = f->res; in fw_classify()
67 if (!tcf_match_indev(skb, f->ifindex)) in fw_classify()
69 r = tcf_exts_exec(skb, &f->exts, res); in fw_classify()
77 struct Qdisc *q = tcf_block_q(tp->chain->block); in fw_classify()
81 !(TC_H_MAJ(id ^ q->handle)))) { in fw_classify()
82 res->classid = id; in fw_classify()
83 res->class = 0; in fw_classify()
88 return -1; in fw_classify()
93 struct fw_head *head = rtnl_dereference(tp->root); in fw_get() local
96 if (head == NULL) in fw_get()
99 f = rtnl_dereference(head->ht[fw_hash(handle)]); in fw_get()
100 for (; f; f = rtnl_dereference(f->next)) { in fw_get()
101 if (f->id == handle) in fw_get()
109 /* We don't allocate fw_head here, because in the old method in fw_init()
110 * we don't need it at all. in fw_init()
117 tcf_exts_destroy(&f->exts); in __fw_delete_filter()
118 tcf_exts_put_net(&f->exts); in __fw_delete_filter()
135 struct fw_head *head = rtnl_dereference(tp->root); in fw_destroy() local
139 if (head == NULL) in fw_destroy()
143 while ((f = rtnl_dereference(head->ht[h])) != NULL) { in fw_destroy()
144 RCU_INIT_POINTER(head->ht[h], in fw_destroy()
145 rtnl_dereference(f->next)); in fw_destroy()
146 tcf_unbind_filter(tp, &f->res); in fw_destroy()
147 if (tcf_exts_get_net(&f->exts)) in fw_destroy()
148 tcf_queue_work(&f->rwork, fw_delete_filter_work); in fw_destroy()
153 kfree_rcu(head, rcu); in fw_destroy()
159 struct fw_head *head = rtnl_dereference(tp->root); in fw_delete() local
163 int ret = -EINVAL; in fw_delete()
166 if (head == NULL || f == NULL) in fw_delete()
169 fp = &head->ht[fw_hash(f->id)]; in fw_delete()
172 fp = &pfp->next, pfp = rtnl_dereference(*fp)) { in fw_delete()
174 RCU_INIT_POINTER(*fp, rtnl_dereference(f->next)); in fw_delete()
175 tcf_unbind_filter(tp, &f->res); in fw_delete()
176 tcf_exts_get_net(&f->exts); in fw_delete()
177 tcf_queue_work(&f->rwork, fw_delete_filter_work); in fw_delete()
185 if (rcu_access_pointer(head->ht[h])) { in fw_delete()
206 struct fw_head *head = rtnl_dereference(tp->root); in fw_set_parms() local
210 err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &f->exts, flags, in fw_set_parms()
220 f->ifindex = ret; in fw_set_parms()
223 err = -EINVAL; in fw_set_parms()
226 if (mask != head->mask) in fw_set_parms()
228 } else if (head->mask != 0xFFFFFFFF) in fw_set_parms()
232 f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); in fw_set_parms()
233 tcf_bind_filter(tp, &f->res, base); in fw_set_parms()
244 struct fw_head *head = rtnl_dereference(tp->root); in fw_change() local
251 return handle ? -EINVAL : 0; /* Succeed if it is old method. */ in fw_change()
262 if (f->id != handle && handle) in fw_change()
263 return -EINVAL; in fw_change()
267 return -ENOBUFS; in fw_change()
269 fnew->id = f->id; in fw_change()
270 fnew->ifindex = f->ifindex; in fw_change()
271 fnew->tp = f->tp; in fw_change()
273 err = tcf_exts_init(&fnew->exts, net, TCA_FW_ACT, in fw_change()
282 tcf_exts_destroy(&fnew->exts); in fw_change()
287 fp = &head->ht[fw_hash(fnew->id)]; in fw_change()
289 fp = &pfp->next, pfp = rtnl_dereference(*fp)) in fw_change()
293 RCU_INIT_POINTER(fnew->next, rtnl_dereference(pfp->next)); in fw_change()
295 tcf_unbind_filter(tp, &f->res); in fw_change()
296 tcf_exts_get_net(&f->exts); in fw_change()
297 tcf_queue_work(&f->rwork, fw_delete_filter_work); in fw_change()
304 return -EINVAL; in fw_change()
306 if (!head) { in fw_change()
311 head = kzalloc(sizeof(*head), GFP_KERNEL); in fw_change()
312 if (!head) in fw_change()
313 return -ENOBUFS; in fw_change()
314 head->mask = mask; in fw_change()
316 rcu_assign_pointer(tp->root, head); in fw_change()
321 return -ENOBUFS; in fw_change()
323 err = tcf_exts_init(&f->exts, net, TCA_FW_ACT, TCA_FW_POLICE); in fw_change()
326 f->id = handle; in fw_change()
327 f->tp = tp; in fw_change()
333 RCU_INIT_POINTER(f->next, head->ht[fw_hash(handle)]); in fw_change()
334 rcu_assign_pointer(head->ht[fw_hash(handle)], f); in fw_change()
340 tcf_exts_destroy(&f->exts); in fw_change()
348 struct fw_head *head = rtnl_dereference(tp->root); in fw_walk() local
351 if (head == NULL) in fw_walk()
352 arg->stop = 1; in fw_walk()
354 if (arg->stop) in fw_walk()
360 for (f = rtnl_dereference(head->ht[h]); f; in fw_walk()
361 f = rtnl_dereference(f->next)) { in fw_walk()
369 struct sk_buff *skb, struct tcmsg *t, bool rtnl_held) in fw_dump() argument
371 struct fw_head *head = rtnl_dereference(tp->root); in fw_dump() local
376 return skb->len; in fw_dump()
378 t->tcm_handle = f->id; in fw_dump()
380 if (!f->res.classid && !tcf_exts_has_actions(&f->exts)) in fw_dump()
381 return skb->len; in fw_dump()
387 if (f->res.classid && in fw_dump()
388 nla_put_u32(skb, TCA_FW_CLASSID, f->res.classid)) in fw_dump()
390 if (f->ifindex) { in fw_dump()
392 dev = __dev_get_by_index(net, f->ifindex); in fw_dump()
393 if (dev && nla_put_string(skb, TCA_FW_INDEV, dev->name)) in fw_dump()
396 if (head->mask != 0xFFFFFFFF && in fw_dump()
397 nla_put_u32(skb, TCA_FW_MASK, head->mask)) in fw_dump()
400 if (tcf_exts_dump(skb, &f->exts) < 0) in fw_dump()
405 if (tcf_exts_dump_stats(skb, &f->exts) < 0) in fw_dump()
408 return skb->len; in fw_dump()
412 return -1; in fw_dump()
420 tc_cls_bind_class(classid, cl, q, &f->res, base); in fw_bind_class()