~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/sched/cls_api.c

Version: ~ [ linux-4.18-rc5 ] ~ [ linux-4.17.6 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.55 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.112 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.140 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.115 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.57 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.27.62 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * net/sched/cls_api.c  Packet classifier API.
  3  *
  4  *              This program is free software; you can redistribute it and/or
  5  *              modify it under the terms of the GNU General Public License
  6  *              as published by the Free Software Foundation; either version
  7  *              2 of the License, or (at your option) any later version.
  8  *
  9  * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
 10  *
 11  * Changes:
 12  *
 13  * Eduardo J. Blanco <ejbs@netlabs.com.uy> :990222: kmod support
 14  *
 15  */
 16 
 17 #include <linux/module.h>
 18 #include <linux/types.h>
 19 #include <linux/kernel.h>
 20 #include <linux/string.h>
 21 #include <linux/errno.h>
 22 #include <linux/err.h>
 23 #include <linux/skbuff.h>
 24 #include <linux/init.h>
 25 #include <linux/kmod.h>
 26 #include <linux/slab.h>
 27 #include <linux/idr.h>
 28 #include <net/net_namespace.h>
 29 #include <net/sock.h>
 30 #include <net/netlink.h>
 31 #include <net/pkt_sched.h>
 32 #include <net/pkt_cls.h>
 33 
 34 /* The list of all installed classifier types */
 35 static LIST_HEAD(tcf_proto_base);
 36 
 37 /* Protects list of registered TC modules. It is pure SMP lock. */
 38 static DEFINE_RWLOCK(cls_mod_lock);
 39 
 40 /* Find classifier type by string name */
 41 
 42 static const struct tcf_proto_ops *tcf_proto_lookup_ops(const char *kind)
 43 {
 44         const struct tcf_proto_ops *t, *res = NULL;
 45 
 46         if (kind) {
 47                 read_lock(&cls_mod_lock);
 48                 list_for_each_entry(t, &tcf_proto_base, head) {
 49                         if (strcmp(kind, t->kind) == 0) {
 50                                 if (try_module_get(t->owner))
 51                                         res = t;
 52                                 break;
 53                         }
 54                 }
 55                 read_unlock(&cls_mod_lock);
 56         }
 57         return res;
 58 }
 59 
 60 /* Register(unregister) new classifier type */
 61 
 62 int register_tcf_proto_ops(struct tcf_proto_ops *ops)
 63 {
 64         struct tcf_proto_ops *t;
 65         int rc = -EEXIST;
 66 
 67         write_lock(&cls_mod_lock);
 68         list_for_each_entry(t, &tcf_proto_base, head)
 69                 if (!strcmp(ops->kind, t->kind))
 70                         goto out;
 71 
 72         list_add_tail(&ops->head, &tcf_proto_base);
 73         rc = 0;
 74 out:
 75         write_unlock(&cls_mod_lock);
 76         return rc;
 77 }
 78 EXPORT_SYMBOL(register_tcf_proto_ops);
 79 
 80 static struct workqueue_struct *tc_filter_wq;
 81 
 82 int unregister_tcf_proto_ops(struct tcf_proto_ops *ops)
 83 {
 84         struct tcf_proto_ops *t;
 85         int rc = -ENOENT;
 86 
 87         /* Wait for outstanding call_rcu()s, if any, from a
 88          * tcf_proto_ops's destroy() handler.
 89          */
 90         rcu_barrier();
 91         flush_workqueue(tc_filter_wq);
 92 
 93         write_lock(&cls_mod_lock);
 94         list_for_each_entry(t, &tcf_proto_base, head) {
 95                 if (t == ops) {
 96                         list_del(&t->head);
 97                         rc = 0;
 98                         break;
 99                 }
100         }
101         write_unlock(&cls_mod_lock);
102         return rc;
103 }
104 EXPORT_SYMBOL(unregister_tcf_proto_ops);
105 
106 bool tcf_queue_work(struct rcu_work *rwork, work_func_t func)
107 {
108         INIT_RCU_WORK(rwork, func);
109         return queue_rcu_work(tc_filter_wq, rwork);
110 }
111 EXPORT_SYMBOL(tcf_queue_work);
112 
113 /* Select new prio value from the range, managed by kernel. */
114 
115 static inline u32 tcf_auto_prio(struct tcf_proto *tp)
116 {
117         u32 first = TC_H_MAKE(0xC0000000U, 0U);
118 
119         if (tp)
120                 first = tp->prio - 1;
121 
122         return TC_H_MAJ(first);
123 }
124 
125 static struct tcf_proto *tcf_proto_create(const char *kind, u32 protocol,
126                                           u32 prio, struct tcf_chain *chain,
127                                           struct netlink_ext_ack *extack)
128 {
129         struct tcf_proto *tp;
130         int err;
131 
132         tp = kzalloc(sizeof(*tp), GFP_KERNEL);
133         if (!tp)
134                 return ERR_PTR(-ENOBUFS);
135 
136         err = -ENOENT;
137         tp->ops = tcf_proto_lookup_ops(kind);
138         if (!tp->ops) {
139 #ifdef CONFIG_MODULES
140                 rtnl_unlock();
141                 request_module("cls_%s", kind);
142                 rtnl_lock();
143                 tp->ops = tcf_proto_lookup_ops(kind);
144                 /* We dropped the RTNL semaphore in order to perform
145                  * the module load. So, even if we succeeded in loading
146                  * the module we have to replay the request. We indicate
147                  * this using -EAGAIN.
148                  */
149                 if (tp->ops) {
150                         module_put(tp->ops->owner);
151                         err = -EAGAIN;
152                 } else {
153                         NL_SET_ERR_MSG(extack, "TC classifier not found");
154                         err = -ENOENT;
155                 }
156 #endif
157                 goto errout;
158         }
159         tp->classify = tp->ops->classify;
160         tp->protocol = protocol;
161         tp->prio = prio;
162         tp->chain = chain;
163 
164         err = tp->ops->init(tp);
165         if (err) {
166                 module_put(tp->ops->owner);
167                 goto errout;
168         }
169         return tp;
170 
171 errout:
172         kfree(tp);
173         return ERR_PTR(err);
174 }
175 
176 static void tcf_proto_destroy(struct tcf_proto *tp,
177                               struct netlink_ext_ack *extack)
178 {
179         tp->ops->destroy(tp, extack);
180         module_put(tp->ops->owner);
181         kfree_rcu(tp, rcu);
182 }
183 
184 struct tcf_filter_chain_list_item {
185         struct list_head list;
186         tcf_chain_head_change_t *chain_head_change;
187         void *chain_head_change_priv;
188 };
189 
190 static struct tcf_chain *tcf_chain_create(struct tcf_block *block,
191                                           u32 chain_index)
192 {
193         struct tcf_chain *chain;
194 
195         chain = kzalloc(sizeof(*chain), GFP_KERNEL);
196         if (!chain)
197                 return NULL;
198         INIT_LIST_HEAD(&chain->filter_chain_list);
199         list_add_tail(&chain->list, &block->chain_list);
200         chain->block = block;
201         chain->index = chain_index;
202         chain->refcnt = 1;
203         return chain;
204 }
205 
206 static void tcf_chain_head_change_item(struct tcf_filter_chain_list_item *item,
207                                        struct tcf_proto *tp_head)
208 {
209         if (item->chain_head_change)
210                 item->chain_head_change(tp_head, item->chain_head_change_priv);
211 }
212 static void tcf_chain_head_change(struct tcf_chain *chain,
213                                   struct tcf_proto *tp_head)
214 {
215         struct tcf_filter_chain_list_item *item;
216 
217         list_for_each_entry(item, &chain->filter_chain_list, list)
218                 tcf_chain_head_change_item(item, tp_head);
219 }
220 
221 static void tcf_chain_flush(struct tcf_chain *chain)
222 {
223         struct tcf_proto *tp = rtnl_dereference(chain->filter_chain);
224 
225         tcf_chain_head_change(chain, NULL);
226         while (tp) {
227                 RCU_INIT_POINTER(chain->filter_chain, tp->next);
228                 tcf_proto_destroy(tp, NULL);
229                 tp = rtnl_dereference(chain->filter_chain);
230                 tcf_chain_put(chain);
231         }
232 }
233 
234 static void tcf_chain_destroy(struct tcf_chain *chain)
235 {
236         struct tcf_block *block = chain->block;
237 
238         list_del(&chain->list);
239         kfree(chain);
240         if (list_empty(&block->chain_list))
241                 kfree(block);
242 }
243 
244 static void tcf_chain_hold(struct tcf_chain *chain)
245 {
246         ++chain->refcnt;
247 }
248 
249 struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
250                                 bool create)
251 {
252         struct tcf_chain *chain;
253 
254         list_for_each_entry(chain, &block->chain_list, list) {
255                 if (chain->index == chain_index) {
256                         tcf_chain_hold(chain);
257                         return chain;
258                 }
259         }
260 
261         return create ? tcf_chain_create(block, chain_index) : NULL;
262 }
263 EXPORT_SYMBOL(tcf_chain_get);
264 
265 void tcf_chain_put(struct tcf_chain *chain)
266 {
267         if (--chain->refcnt == 0)
268                 tcf_chain_destroy(chain);
269 }
270 EXPORT_SYMBOL(tcf_chain_put);
271 
272 static bool tcf_block_offload_in_use(struct tcf_block *block)
273 {
274         return block->offloadcnt;
275 }
276 
277 static int tcf_block_offload_cmd(struct tcf_block *block,
278                                  struct net_device *dev,
279                                  struct tcf_block_ext_info *ei,
280                                  enum tc_block_command command)
281 {
282         struct tc_block_offload bo = {};
283 
284         bo.command = command;
285         bo.binder_type = ei->binder_type;
286         bo.block = block;
287         return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_BLOCK, &bo);
288 }
289 
290 static int tcf_block_offload_bind(struct tcf_block *block, struct Qdisc *q,
291                                   struct tcf_block_ext_info *ei)
292 {
293         struct net_device *dev = q->dev_queue->dev;
294         int err;
295 
296         if (!dev->netdev_ops->ndo_setup_tc)
297                 goto no_offload_dev_inc;
298 
299         /* If tc offload feature is disabled and the block we try to bind
300          * to already has some offloaded filters, forbid to bind.
301          */
302         if (!tc_can_offload(dev) && tcf_block_offload_in_use(block))
303                 return -EOPNOTSUPP;
304 
305         err = tcf_block_offload_cmd(block, dev, ei, TC_BLOCK_BIND);
306         if (err == -EOPNOTSUPP)
307                 goto no_offload_dev_inc;
308         return err;
309 
310 no_offload_dev_inc:
311         if (tcf_block_offload_in_use(block))
312                 return -EOPNOTSUPP;
313         block->nooffloaddevcnt++;
314         return 0;
315 }
316 
317 static void tcf_block_offload_unbind(struct tcf_block *block, struct Qdisc *q,
318                                      struct tcf_block_ext_info *ei)
319 {
320         struct net_device *dev = q->dev_queue->dev;
321         int err;
322 
323         if (!dev->netdev_ops->ndo_setup_tc)
324                 goto no_offload_dev_dec;
325         err = tcf_block_offload_cmd(block, dev, ei, TC_BLOCK_UNBIND);
326         if (err == -EOPNOTSUPP)
327                 goto no_offload_dev_dec;
328         return;
329 
330 no_offload_dev_dec:
331         WARN_ON(block->nooffloaddevcnt-- == 0);
332 }
333 
334 static int
335 tcf_chain_head_change_cb_add(struct tcf_chain *chain,
336                              struct tcf_block_ext_info *ei,
337                              struct netlink_ext_ack *extack)
338 {
339         struct tcf_filter_chain_list_item *item;
340 
341         item = kmalloc(sizeof(*item), GFP_KERNEL);
342         if (!item) {
343                 NL_SET_ERR_MSG(extack, "Memory allocation for head change callback item failed");
344                 return -ENOMEM;
345         }
346         item->chain_head_change = ei->chain_head_change;
347         item->chain_head_change_priv = ei->chain_head_change_priv;
348         if (chain->filter_chain)
349                 tcf_chain_head_change_item(item, chain->filter_chain);
350         list_add(&item->list, &chain->filter_chain_list);
351         return 0;
352 }
353 
354 static void
355 tcf_chain_head_change_cb_del(struct tcf_chain *chain,
356                              struct tcf_block_ext_info *ei)
357 {
358         struct tcf_filter_chain_list_item *item;
359 
360         list_for_each_entry(item, &chain->filter_chain_list, list) {
361                 if ((!ei->chain_head_change && !ei->chain_head_change_priv) ||
362                     (item->chain_head_change == ei->chain_head_change &&
363                      item->chain_head_change_priv == ei->chain_head_change_priv)) {
364                         tcf_chain_head_change_item(item, NULL);
365                         list_del(&item->list);
366                         kfree(item);
367                         return;
368                 }
369         }
370         WARN_ON(1);
371 }
372 
373 struct tcf_net {
374         struct idr idr;
375 };
376 
377 static unsigned int tcf_net_id;
378 
379 static int tcf_block_insert(struct tcf_block *block, struct net *net,
380                             struct netlink_ext_ack *extack)
381 {
382         struct tcf_net *tn = net_generic(net, tcf_net_id);
383 
384         return idr_alloc_u32(&tn->idr, block, &block->index, block->index,
385                              GFP_KERNEL);
386 }
387 
388 static void tcf_block_remove(struct tcf_block *block, struct net *net)
389 {
390         struct tcf_net *tn = net_generic(net, tcf_net_id);
391 
392         idr_remove(&tn->idr, block->index);
393 }
394 
395 static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q,
396                                           u32 block_index,
397                                           struct netlink_ext_ack *extack)
398 {
399         struct tcf_block *block;
400         struct tcf_chain *chain;
401         int err;
402 
403         block = kzalloc(sizeof(*block), GFP_KERNEL);
404         if (!block) {
405                 NL_SET_ERR_MSG(extack, "Memory allocation for block failed");
406                 return ERR_PTR(-ENOMEM);
407         }
408         INIT_LIST_HEAD(&block->chain_list);
409         INIT_LIST_HEAD(&block->cb_list);
410         INIT_LIST_HEAD(&block->owner_list);
411 
412         /* Create chain 0 by default, it has to be always present. */
413         chain = tcf_chain_create(block, 0);
414         if (!chain) {
415                 NL_SET_ERR_MSG(extack, "Failed to create new tcf chain");
416                 err = -ENOMEM;
417                 goto err_chain_create;
418         }
419         block->refcnt = 1;
420         block->net = net;
421         block->index = block_index;
422 
423         /* Don't store q pointer for blocks which are shared */
424         if (!tcf_block_shared(block))
425                 block->q = q;
426         return block;
427 
428 err_chain_create:
429         kfree(block);
430         return ERR_PTR(err);
431 }
432 
433 static struct tcf_block *tcf_block_lookup(struct net *net, u32 block_index)
434 {
435         struct tcf_net *tn = net_generic(net, tcf_net_id);
436 
437         return idr_find(&tn->idr, block_index);
438 }
439 
440 /* Find tcf block.
441  * Set q, parent, cl when appropriate.
442  */
443 
444 static struct tcf_block *tcf_block_find(struct net *net, struct Qdisc **q,
445                                         u32 *parent, unsigned long *cl,
446                                         int ifindex, u32 block_index,
447                                         struct netlink_ext_ack *extack)
448 {
449         struct tcf_block *block;
450 
451         if (ifindex == TCM_IFINDEX_MAGIC_BLOCK) {
452                 block = tcf_block_lookup(net, block_index);
453                 if (!block) {
454                         NL_SET_ERR_MSG(extack, "Block of given index was not found");
455                         return ERR_PTR(-EINVAL);
456                 }
457         } else {
458                 const struct Qdisc_class_ops *cops;
459                 struct net_device *dev;
460 
461                 /* Find link */
462                 dev = __dev_get_by_index(net, ifindex);
463                 if (!dev)
464                         return ERR_PTR(-ENODEV);
465 
466                 /* Find qdisc */
467                 if (!*parent) {
468                         *q = dev->qdisc;
469                         *parent = (*q)->handle;
470                 } else {
471                         *q = qdisc_lookup(dev, TC_H_MAJ(*parent));
472                         if (!*q) {
473                                 NL_SET_ERR_MSG(extack, "Parent Qdisc doesn't exists");
474                                 return ERR_PTR(-EINVAL);
475                         }
476                 }
477 
478                 /* Is it classful? */
479                 cops = (*q)->ops->cl_ops;
480                 if (!cops) {
481                         NL_SET_ERR_MSG(extack, "Qdisc not classful");
482                         return ERR_PTR(-EINVAL);
483                 }
484 
485                 if (!cops->tcf_block) {
486                         NL_SET_ERR_MSG(extack, "Class doesn't support blocks");
487                         return ERR_PTR(-EOPNOTSUPP);
488                 }
489 
490                 /* Do we search for filter, attached to class? */
491                 if (TC_H_MIN(*parent)) {
492                         *cl = cops->find(*q, *parent);
493                         if (*cl == 0) {
494                                 NL_SET_ERR_MSG(extack, "Specified class doesn't exist");
495                                 return ERR_PTR(-ENOENT);
496                         }
497                 }
498 
499                 /* And the last stroke */
500                 block = cops->tcf_block(*q, *cl, extack);
501                 if (!block)
502                         return ERR_PTR(-EINVAL);
503                 if (tcf_block_shared(block)) {
504                         NL_SET_ERR_MSG(extack, "This filter block is shared. Please use the block index to manipulate the filters");
505                         return ERR_PTR(-EOPNOTSUPP);
506                 }
507         }
508 
509         return block;
510 }
511 
512 static struct tcf_chain *tcf_block_chain_zero(struct tcf_block *block)
513 {
514         return list_first_entry(&block->chain_list, struct tcf_chain, list);
515 }
516 
517 struct tcf_block_owner_item {
518         struct list_head list;
519         struct Qdisc *q;
520         enum tcf_block_binder_type binder_type;
521 };
522 
523 static void
524 tcf_block_owner_netif_keep_dst(struct tcf_block *block,
525                                struct Qdisc *q,
526                                enum tcf_block_binder_type binder_type)
527 {
528         if (block->keep_dst &&
529             binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS &&
530             binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS)
531                 netif_keep_dst(qdisc_dev(q));
532 }
533 
534 void tcf_block_netif_keep_dst(struct tcf_block *block)
535 {
536         struct tcf_block_owner_item *item;
537 
538         block->keep_dst = true;
539         list_for_each_entry(item, &block->owner_list, list)
540                 tcf_block_owner_netif_keep_dst(block, item->q,
541                                                item->binder_type);
542 }
543 EXPORT_SYMBOL(tcf_block_netif_keep_dst);
544 
545 static int tcf_block_owner_add(struct tcf_block *block,
546                                struct Qdisc *q,
547                                enum tcf_block_binder_type binder_type)
548 {
549         struct tcf_block_owner_item *item;
550 
551         item = kmalloc(sizeof(*item), GFP_KERNEL);
552         if (!item)
553                 return -ENOMEM;
554         item->q = q;
555         item->binder_type = binder_type;
556         list_add(&item->list, &block->owner_list);
557         return 0;
558 }
559 
560 static void tcf_block_owner_del(struct tcf_block *block,
561                                 struct Qdisc *q,
562                                 enum tcf_block_binder_type binder_type)
563 {
564         struct tcf_block_owner_item *item;
565 
566         list_for_each_entry(item, &block->owner_list, list) {
567                 if (item->q == q && item->binder_type == binder_type) {
568                         list_del(&item->list);
569                         kfree(item);
570                         return;
571                 }
572         }
573         WARN_ON(1);
574 }
575 
576 int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
577                       struct tcf_block_ext_info *ei,
578                       struct netlink_ext_ack *extack)
579 {
580         struct net *net = qdisc_net(q);
581         struct tcf_block *block = NULL;
582         bool created = false;
583         int err;
584 
585         if (ei->block_index) {
586                 /* block_index not 0 means the shared block is requested */
587                 block = tcf_block_lookup(net, ei->block_index);
588                 if (block)
589                         block->refcnt++;
590         }
591 
592         if (!block) {
593                 block = tcf_block_create(net, q, ei->block_index, extack);
594                 if (IS_ERR(block))
595                         return PTR_ERR(block);
596                 created = true;
597                 if (tcf_block_shared(block)) {
598                         err = tcf_block_insert(block, net, extack);
599                         if (err)
600                                 goto err_block_insert;
601                 }
602         }
603 
604         err = tcf_block_owner_add(block, q, ei->binder_type);
605         if (err)
606                 goto err_block_owner_add;
607 
608         tcf_block_owner_netif_keep_dst(block, q, ei->binder_type);
609 
610         err = tcf_chain_head_change_cb_add(tcf_block_chain_zero(block),
611                                            ei, extack);
612         if (err)
613                 goto err_chain_head_change_cb_add;
614 
615         err = tcf_block_offload_bind(block, q, ei);
616         if (err)
617                 goto err_block_offload_bind;
618 
619         *p_block = block;
620         return 0;
621 
622 err_block_offload_bind:
623         tcf_chain_head_change_cb_del(tcf_block_chain_zero(block), ei);
624 err_chain_head_change_cb_add:
625         tcf_block_owner_del(block, q, ei->binder_type);
626 err_block_owner_add:
627         if (created) {
628                 if (tcf_block_shared(block))
629                         tcf_block_remove(block, net);
630 err_block_insert:
631                 kfree(tcf_block_chain_zero(block));
632                 kfree(block);
633         } else {
634                 block->refcnt--;
635         }
636         return err;
637 }
638 EXPORT_SYMBOL(tcf_block_get_ext);
639 
640 static void tcf_chain_head_change_dflt(struct tcf_proto *tp_head, void *priv)
641 {
642         struct tcf_proto __rcu **p_filter_chain = priv;
643 
644         rcu_assign_pointer(*p_filter_chain, tp_head);
645 }
646 
647 int tcf_block_get(struct tcf_block **p_block,
648                   struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
649                   struct netlink_ext_ack *extack)
650 {
651         struct tcf_block_ext_info ei = {
652                 .chain_head_change = tcf_chain_head_change_dflt,
653                 .chain_head_change_priv = p_filter_chain,
654         };
655 
656         WARN_ON(!p_filter_chain);
657         return tcf_block_get_ext(p_block, q, &ei, extack);
658 }
659 EXPORT_SYMBOL(tcf_block_get);
660 
661 /* XXX: Standalone actions are not allowed to jump to any chain, and bound
662  * actions should be all removed after flushing.
663  */
664 void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q,
665                        struct tcf_block_ext_info *ei)
666 {
667         struct tcf_chain *chain, *tmp;
668 
669         if (!block)
670                 return;
671         tcf_chain_head_change_cb_del(tcf_block_chain_zero(block), ei);
672         tcf_block_owner_del(block, q, ei->binder_type);
673 
674         if (--block->refcnt == 0) {
675                 if (tcf_block_shared(block))
676                         tcf_block_remove(block, block->net);
677 
678                 /* Hold a refcnt for all chains, so that they don't disappear
679                  * while we are iterating.
680                  */
681                 list_for_each_entry(chain, &block->chain_list, list)
682                         tcf_chain_hold(chain);
683 
684                 list_for_each_entry(chain, &block->chain_list, list)
685                         tcf_chain_flush(chain);
686         }
687 
688         tcf_block_offload_unbind(block, q, ei);
689 
690         if (block->refcnt == 0) {
691                 /* At this point, all the chains should have refcnt >= 1. */
692                 list_for_each_entry_safe(chain, tmp, &block->chain_list, list)
693                         tcf_chain_put(chain);
694 
695                 /* Finally, put chain 0 and allow block to be freed. */
696                 tcf_chain_put(tcf_block_chain_zero(block));
697         }
698 }
699 EXPORT_SYMBOL(tcf_block_put_ext);
700 
701 void tcf_block_put(struct tcf_block *block)
702 {
703         struct tcf_block_ext_info ei = {0, };
704 
705         if (!block)
706                 return;
707         tcf_block_put_ext(block, block->q, &ei);
708 }
709 
710 EXPORT_SYMBOL(tcf_block_put);
711 
712 struct tcf_block_cb {
713         struct list_head list;
714         tc_setup_cb_t *cb;
715         void *cb_ident;
716         void *cb_priv;
717         unsigned int refcnt;
718 };
719 
720 void *tcf_block_cb_priv(struct tcf_block_cb *block_cb)
721 {
722         return block_cb->cb_priv;
723 }
724 EXPORT_SYMBOL(tcf_block_cb_priv);
725 
726 struct tcf_block_cb *tcf_block_cb_lookup(struct tcf_block *block,
727                                          tc_setup_cb_t *cb, void *cb_ident)
728 {       struct tcf_block_cb *block_cb;
729 
730         list_for_each_entry(block_cb, &block->cb_list, list)
731                 if (block_cb->cb == cb && block_cb->cb_ident == cb_ident)
732                         return block_cb;
733         return NULL;
734 }
735 EXPORT_SYMBOL(tcf_block_cb_lookup);
736 
737 void tcf_block_cb_incref(struct tcf_block_cb *block_cb)
738 {
739         block_cb->refcnt++;
740 }
741 EXPORT_SYMBOL(tcf_block_cb_incref);
742 
743 unsigned int tcf_block_cb_decref(struct tcf_block_cb *block_cb)
744 {
745         return --block_cb->refcnt;
746 }
747 EXPORT_SYMBOL(tcf_block_cb_decref);
748 
749 struct tcf_block_cb *__tcf_block_cb_register(struct tcf_block *block,
750                                              tc_setup_cb_t *cb, void *cb_ident,
751                                              void *cb_priv)
752 {
753         struct tcf_block_cb *block_cb;
754 
755         /* At this point, playback of previous block cb calls is not supported,
756          * so forbid to register to block which already has some offloaded
757          * filters present.
758          */
759         if (tcf_block_offload_in_use(block))
760                 return ERR_PTR(-EOPNOTSUPP);
761 
762         block_cb = kzalloc(sizeof(*block_cb), GFP_KERNEL);
763         if (!block_cb)
764                 return ERR_PTR(-ENOMEM);
765         block_cb->cb = cb;
766         block_cb->cb_ident = cb_ident;
767         block_cb->cb_priv = cb_priv;
768         list_add(&block_cb->list, &block->cb_list);
769         return block_cb;
770 }
771 EXPORT_SYMBOL(__tcf_block_cb_register);
772 
773 int tcf_block_cb_register(struct tcf_block *block,
774                           tc_setup_cb_t *cb, void *cb_ident,
775                           void *cb_priv)
776 {
777         struct tcf_block_cb *block_cb;
778 
779         block_cb = __tcf_block_cb_register(block, cb, cb_ident, cb_priv);
780         return IS_ERR(block_cb) ? PTR_ERR(block_cb) : 0;
781 }
782 EXPORT_SYMBOL(tcf_block_cb_register);
783 
784 void __tcf_block_cb_unregister(struct tcf_block_cb *block_cb)
785 {
786         list_del(&block_cb->list);
787         kfree(block_cb);
788 }
789 EXPORT_SYMBOL(__tcf_block_cb_unregister);
790 
791 void tcf_block_cb_unregister(struct tcf_block *block,
792                              tc_setup_cb_t *cb, void *cb_ident)
793 {
794         struct tcf_block_cb *block_cb;
795 
796         block_cb = tcf_block_cb_lookup(block, cb, cb_ident);
797         if (!block_cb)
798                 return;
799         __tcf_block_cb_unregister(block_cb);
800 }
801 EXPORT_SYMBOL(tcf_block_cb_unregister);
802 
803 static int tcf_block_cb_call(struct tcf_block *block, enum tc_setup_type type,
804                              void *type_data, bool err_stop)
805 {
806         struct tcf_block_cb *block_cb;
807         int ok_count = 0;
808         int err;
809 
810         /* Make sure all netdevs sharing this block are offload-capable. */
811         if (block->nooffloaddevcnt && err_stop)
812                 return -EOPNOTSUPP;
813 
814         list_for_each_entry(block_cb, &block->cb_list, list) {
815                 err = block_cb->cb(type, type_data, block_cb->cb_priv);
816                 if (err) {
817                         if (err_stop)
818                                 return err;
819                 } else {
820                         ok_count++;
821                 }
822         }
823         return ok_count;
824 }
825 
826 /* Main classifier routine: scans classifier chain attached
827  * to this qdisc, (optionally) tests for protocol and asks
828  * specific classifiers.
829  */
830 int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
831                  struct tcf_result *res, bool compat_mode)
832 {
833         __be16 protocol = tc_skb_protocol(skb);
834 #ifdef CONFIG_NET_CLS_ACT
835         const int max_reclassify_loop = 4;
836         const struct tcf_proto *orig_tp = tp;
837         const struct tcf_proto *first_tp;
838         int limit = 0;
839 
840 reclassify:
841 #endif
842         for (; tp; tp = rcu_dereference_bh(tp->next)) {
843                 int err;
844 
845                 if (tp->protocol != protocol &&
846                     tp->protocol != htons(ETH_P_ALL))
847                         continue;
848 
849                 err = tp->classify(skb, tp, res);
850 #ifdef CONFIG_NET_CLS_ACT
851                 if (unlikely(err == TC_ACT_RECLASSIFY && !compat_mode)) {
852                         first_tp = orig_tp;
853                         goto reset;
854                 } else if (unlikely(TC_ACT_EXT_CMP(err, TC_ACT_GOTO_CHAIN))) {
855                         first_tp = res->goto_tp;
856                         goto reset;
857                 }
858 #endif
859                 if (err >= 0)
860                         return err;
861         }
862 
863         return TC_ACT_UNSPEC; /* signal: continue lookup */
864 #ifdef CONFIG_NET_CLS_ACT
865 reset:
866         if (unlikely(limit++ >= max_reclassify_loop)) {
867                 net_notice_ratelimited("%u: reclassify loop, rule prio %u, protocol %02x\n",
868                                        tp->chain->block->index,
869                                        tp->prio & 0xffff,
870                                        ntohs(tp->protocol));
871                 return TC_ACT_SHOT;
872         }
873 
874         tp = first_tp;
875         protocol = tc_skb_protocol(skb);
876         goto reclassify;
877 #endif
878 }
879 EXPORT_SYMBOL(tcf_classify);
880 
881 struct tcf_chain_info {
882         struct tcf_proto __rcu **pprev;
883         struct tcf_proto __rcu *next;
884 };
885 
886 static struct tcf_proto *tcf_chain_tp_prev(struct tcf_chain_info *chain_info)
887 {
888         return rtnl_dereference(*chain_info->pprev);
889 }
890 
891 static void tcf_chain_tp_insert(struct tcf_chain *chain,
892                                 struct tcf_chain_info *chain_info,
893                                 struct tcf_proto *tp)
894 {
895         if (*chain_info->pprev == chain->filter_chain)
896                 tcf_chain_head_change(chain, tp);
897         RCU_INIT_POINTER(tp->next, tcf_chain_tp_prev(chain_info));
898         rcu_assign_pointer(*chain_info->pprev, tp);
899         tcf_chain_hold(chain);
900 }
901 
902 static void tcf_chain_tp_remove(struct tcf_chain *chain,
903                                 struct tcf_chain_info *chain_info,
904                                 struct tcf_proto *tp)
905 {
906         struct tcf_proto *next = rtnl_dereference(chain_info->next);
907 
908         if (tp == chain->filter_chain)
909                 tcf_chain_head_change(chain, next);
910         RCU_INIT_POINTER(*chain_info->pprev, next);
911         tcf_chain_put(chain);
912 }
913 
914 static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain,
915                                            struct tcf_chain_info *chain_info,
916                                            u32 protocol, u32 prio,
917                                            bool prio_allocate)
918 {
919         struct tcf_proto **pprev;
920         struct tcf_proto *tp;
921 
922         /* Check the chain for existence of proto-tcf with this priority */
923         for (pprev = &chain->filter_chain;
924              (tp = rtnl_dereference(*pprev)); pprev = &tp->next) {
925                 if (tp->prio >= prio) {
926                         if (tp->prio == prio) {
927                                 if (prio_allocate ||
928                                     (tp->protocol != protocol && protocol))
929                                         return ERR_PTR(-EINVAL);
930                         } else {
931                                 tp = NULL;
932                         }
933                         break;
934                 }
935         }
936         chain_info->pprev = pprev;
937         chain_info->next = tp ? tp->next : NULL;
938         return tp;
939 }
940 
941 static int tcf_fill_node(struct net *net, struct sk_buff *skb,
942                          struct tcf_proto *tp, struct tcf_block *block,
943                          struct Qdisc *q, u32 parent, void *fh,
944                          u32 portid, u32 seq, u16 flags, int event)
945 {
946         struct tcmsg *tcm;
947         struct nlmsghdr  *nlh;
948         unsigned char *b = skb_tail_pointer(skb);
949 
950         nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags);
951         if (!nlh)
952                 goto out_nlmsg_trim;
953         tcm = nlmsg_data(nlh);
954         tcm->tcm_family = AF_UNSPEC;
955         tcm->tcm__pad1 = 0;
956         tcm->tcm__pad2 = 0;
957         if (q) {
958                 tcm->tcm_ifindex = qdisc_dev(q)->ifindex;
959                 tcm->tcm_parent = parent;
960         } else {
961                 tcm->tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK;
962                 tcm->tcm_block_index = block->index;
963         }
964         tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
965         if (nla_put_string(skb, TCA_KIND, tp->ops->kind))
966                 goto nla_put_failure;
967         if (nla_put_u32(skb, TCA_CHAIN, tp->chain->index))
968                 goto nla_put_failure;
969         if (!fh) {
970                 tcm->tcm_handle = 0;
971         } else {
972                 if (tp->ops->dump && tp->ops->dump(net, tp, fh, skb, tcm) < 0)
973                         goto nla_put_failure;
974         }
975         nlh->nlmsg_len = skb_tail_pointer(skb) - b;
976         return skb->len;
977 
978 out_nlmsg_trim:
979 nla_put_failure:
980         nlmsg_trim(skb, b);
981         return -1;
982 }
983 
984 static int tfilter_notify(struct net *net, struct sk_buff *oskb,
985                           struct nlmsghdr *n, struct tcf_proto *tp,
986                           struct tcf_block *block, struct Qdisc *q,
987                           u32 parent, void *fh, int event, bool unicast)
988 {
989         struct sk_buff *skb;
990         u32 portid = oskb ? NETLINK_CB(oskb).portid : 0;
991 
992         skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
993         if (!skb)
994                 return -ENOBUFS;
995 
996         if (tcf_fill_node(net, skb, tp, block, q, parent, fh, portid,
997                           n->nlmsg_seq, n->nlmsg_flags, event) <= 0) {
998                 kfree_skb(skb);
999                 return -EINVAL;
1000         }
1001 
1002         if (unicast)
1003                 return netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT);
1004 
1005         return rtnetlink_send(skb, net, portid, RTNLGRP_TC,
1006                               n->nlmsg_flags & NLM_F_ECHO);
1007 }
1008 
1009 static int tfilter_del_notify(struct net *net, struct sk_buff *oskb,
1010                               struct nlmsghdr *n, struct tcf_proto *tp,
1011                               struct tcf_block *block, struct Qdisc *q,
1012                               u32 parent, void *fh, bool unicast, bool *last,
1013                               struct netlink_ext_ack *extack)
1014 {
1015         struct sk_buff *skb;
1016         u32 portid = oskb ? NETLINK_CB(oskb).portid : 0;
1017         int err;
1018 
1019         skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1020         if (!skb)
1021                 return -ENOBUFS;
1022 
1023         if (tcf_fill_node(net, skb, tp, block, q, parent, fh, portid,
1024                           n->nlmsg_seq, n->nlmsg_flags, RTM_DELTFILTER) <= 0) {
1025                 NL_SET_ERR_MSG(extack, "Failed to build del event notification");
1026                 kfree_skb(skb);
1027                 return -EINVAL;
1028         }
1029 
1030         err = tp->ops->delete(tp, fh, last, extack);
1031         if (err) {
1032                 kfree_skb(skb);
1033                 return err;
1034         }
1035 
1036         if (unicast)
1037                 return netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT);
1038 
1039         err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
1040                              n->nlmsg_flags & NLM_F_ECHO);
1041         if (err < 0)
1042                 NL_SET_ERR_MSG(extack, "Failed to send filter delete notification");
1043         return err;
1044 }
1045 
1046 static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb,
1047                                  struct tcf_block *block, struct Qdisc *q,
1048                                  u32 parent, struct nlmsghdr *n,
1049                                  struct tcf_chain *chain, int event)
1050 {
1051         struct tcf_proto *tp;
1052 
1053         for (tp = rtnl_dereference(chain->filter_chain);
1054              tp; tp = rtnl_dereference(tp->next))
1055                 tfilter_notify(net, oskb, n, tp, block,
1056                                q, parent, 0, event, false);
1057 }
1058 
1059 static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
1060                           struct netlink_ext_ack *extack)
1061 {
1062         struct net *net = sock_net(skb->sk);
1063         struct nlattr *tca[TCA_MAX + 1];
1064         struct tcmsg *t;
1065         u32 protocol;
1066         u32 prio;
1067         bool prio_allocate;
1068         u32 parent;
1069         u32 chain_index;
1070         struct Qdisc *q = NULL;
1071         struct tcf_chain_info chain_info;
1072         struct tcf_chain *chain = NULL;
1073         struct tcf_block *block;
1074         struct tcf_proto *tp;
1075         unsigned long cl;
1076         void *fh;
1077         int err;
1078         int tp_created;
1079 
1080         if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
1081                 return -EPERM;
1082 
1083 replay:
1084         tp_created = 0;
1085 
1086         err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL, extack);
1087         if (err < 0)
1088                 return err;
1089 
1090         t = nlmsg_data(n);
1091         protocol = TC_H_MIN(t->tcm_info);
1092         prio = TC_H_MAJ(t->tcm_info);
1093         prio_allocate = false;
1094         parent = t->tcm_parent;
1095         cl = 0;
1096 
1097         if (prio == 0) {
1098                 /* If no priority is provided by the user,
1099                  * we allocate one.
1100                  */
1101                 if (n->nlmsg_flags & NLM_F_CREATE) {
1102                         prio = TC_H_MAKE(0x80000000U, 0U);
1103                         prio_allocate = true;
1104                 } else {
1105                         NL_SET_ERR_MSG(extack, "Invalid filter command with priority of zero");
1106                         return -ENOENT;
1107                 }
1108         }
1109 
1110         /* Find head of filter chain. */
1111 
1112         block = tcf_block_find(net, &q, &parent, &cl,
1113                                t->tcm_ifindex, t->tcm_block_index, extack);
1114         if (IS_ERR(block)) {
1115                 err = PTR_ERR(block);
1116                 goto errout;
1117         }
1118 
1119         chain_index = tca[TCA_CHAIN] ? nla_get_u32(tca[TCA_CHAIN]) : 0;
1120         if (chain_index > TC_ACT_EXT_VAL_MASK) {
1121                 NL_SET_ERR_MSG(extack, "Specified chain index exceeds upper limit");
1122                 err = -EINVAL;
1123                 goto errout;
1124         }
1125         chain = tcf_chain_get(block, chain_index, true);
1126         if (!chain) {
1127                 NL_SET_ERR_MSG(extack, "Cannot find specified filter chain");
1128                 err = -ENOMEM;
1129                 goto errout;
1130         }
1131 
1132         tp = tcf_chain_tp_find(chain, &chain_info, protocol,
1133                                prio, prio_allocate);
1134         if (IS_ERR(tp)) {
1135                 NL_SET_ERR_MSG(extack, "Filter with specified priority/protocol not found");
1136                 err = PTR_ERR(tp);
1137                 goto errout;
1138         }
1139 
1140         if (tp == NULL) {
1141                 /* Proto-tcf does not exist, create new one */
1142 
1143                 if (tca[TCA_KIND] == NULL || !protocol) {
1144                         NL_SET_ERR_MSG(extack, "Filter kind and protocol must be specified");
1145                         err = -EINVAL;
1146                         goto errout;
1147                 }
1148 
1149                 if (!(n->nlmsg_flags & NLM_F_CREATE)) {
1150                         NL_SET_ERR_MSG(extack, "Need both RTM_NEWTFILTER and NLM_F_CREATE to create a new filter");
1151                         err = -ENOENT;
1152                         goto errout;
1153                 }
1154 
1155                 if (prio_allocate)
1156                         prio = tcf_auto_prio(tcf_chain_tp_prev(&chain_info));
1157 
1158                 tp = tcf_proto_create(nla_data(tca[TCA_KIND]),
1159                                       protocol, prio, chain, extack);
1160                 if (IS_ERR(tp)) {
1161                         err = PTR_ERR(tp);
1162                         goto errout;
1163                 }
1164                 tp_created = 1;
1165         } else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind)) {
1166                 NL_SET_ERR_MSG(extack, "Specified filter kind does not match existing one");
1167                 err = -EINVAL;
1168                 goto errout;
1169         }
1170 
1171         fh = tp->ops->get(tp, t->tcm_handle);
1172 
1173         if (!fh) {
1174                 if (!(n->nlmsg_flags & NLM_F_CREATE)) {
1175                         NL_SET_ERR_MSG(extack, "Need both RTM_NEWTFILTER and NLM_F_CREATE to create a new filter");
1176                         err = -ENOENT;
1177                         goto errout;
1178                 }
1179         } else if (n->nlmsg_flags & NLM_F_EXCL) {
1180                 NL_SET_ERR_MSG(extack, "Filter already exists");
1181                 err = -EEXIST;
1182                 goto errout;
1183         }
1184 
1185         err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh,
1186                               n->nlmsg_flags & NLM_F_CREATE ? TCA_ACT_NOREPLACE : TCA_ACT_REPLACE,
1187                               extack);
1188         if (err == 0) {
1189                 if (tp_created)
1190                         tcf_chain_tp_insert(chain, &chain_info, tp);
1191                 tfilter_notify(net, skb, n, tp, block, q, parent, fh,
1192                                RTM_NEWTFILTER, false);
1193         } else {
1194                 if (tp_created)
1195                         tcf_proto_destroy(tp, NULL);
1196         }
1197 
1198 errout:
1199         if (chain)
1200                 tcf_chain_put(chain);
1201         if (err == -EAGAIN)
1202                 /* Replay the request. */
1203                 goto replay;
1204         return err;
1205 }
1206 
1207 static int tc_del_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
1208                           struct netlink_ext_ack *extack)
1209 {
1210         struct net *net = sock_net(skb->sk);
1211         struct nlattr *tca[TCA_MAX + 1];
1212         struct tcmsg *t;
1213         u32 protocol;
1214         u32 prio;
1215         u32 parent;
1216         u32 chain_index;
1217         struct Qdisc *q = NULL;
1218         struct tcf_chain_info chain_info;
1219         struct tcf_chain *chain = NULL;
1220         struct tcf_block *block;
1221         struct tcf_proto *tp = NULL;
1222         unsigned long cl = 0;
1223         void *fh = NULL;
1224         int err;
1225 
1226         if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
1227                 return -EPERM;
1228 
1229         err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL, extack);
1230         if (err < 0)
1231                 return err;
1232 
1233         t = nlmsg_data(n);
1234         protocol = TC_H_MIN(t->tcm_info);
1235         prio = TC_H_MAJ(t->tcm_info);
1236         parent = t->tcm_parent;
1237 
1238         if (prio == 0 && (protocol || t->tcm_handle || tca[TCA_KIND])) {
1239                 NL_SET_ERR_MSG(extack, "Cannot flush filters with protocol, handle or kind set");
1240                 return -ENOENT;
1241         }
1242 
1243         /* Find head of filter chain. */
1244 
1245         block = tcf_block_find(net, &q, &parent, &cl,
1246                                t->tcm_ifindex, t->tcm_block_index, extack);
1247         if (IS_ERR(block)) {
1248                 err = PTR_ERR(block);
1249                 goto errout;
1250         }
1251 
1252         chain_index = tca[TCA_CHAIN] ? nla_get_u32(tca[TCA_CHAIN]) : 0;
1253         if (chain_index > TC_ACT_EXT_VAL_MASK) {
1254                 NL_SET_ERR_MSG(extack, "Specified chain index exceeds upper limit");
1255                 err = -EINVAL;
1256                 goto errout;
1257         }
1258         chain = tcf_chain_get(block, chain_index, false);
1259         if (!chain) {
1260                 NL_SET_ERR_MSG(extack, "Cannot find specified filter chain");
1261                 err = -EINVAL;
1262                 goto errout;
1263         }
1264 
1265         if (prio == 0) {
1266                 tfilter_notify_chain(net, skb, block, q, parent, n,
1267                                      chain, RTM_DELTFILTER);
1268                 tcf_chain_flush(chain);
1269                 err = 0;
1270                 goto errout;
1271         }
1272 
1273         tp = tcf_chain_tp_find(chain, &chain_info, protocol,
1274                                prio, false);
1275         if (!tp || IS_ERR(tp)) {
1276                 NL_SET_ERR_MSG(extack, "Filter with specified priority/protocol not found");
1277                 err = tp ? PTR_ERR(tp) : -ENOENT;
1278                 goto errout;
1279         } else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind)) {
1280                 NL_SET_ERR_MSG(extack, "Specified filter kind does not match existing one");
1281                 err = -EINVAL;
1282                 goto errout;
1283         }
1284 
1285         fh = tp->ops->get(tp, t->tcm_handle);
1286 
1287         if (!fh) {
1288                 if (t->tcm_handle == 0) {
1289                         tcf_chain_tp_remove(chain, &chain_info, tp);
1290                         tfilter_notify(net, skb, n, tp, block, q, parent, fh,
1291                                        RTM_DELTFILTER, false);
1292                         tcf_proto_destroy(tp, extack);
1293                         err = 0;
1294                 } else {
1295                         NL_SET_ERR_MSG(extack, "Specified filter handle not found");
1296                         err = -ENOENT;
1297                 }
1298         } else {
1299                 bool last;
1300 
1301                 err = tfilter_del_notify(net, skb, n, tp, block,
1302                                          q, parent, fh, false, &last,
1303                                          extack);
1304                 if (err)
1305                         goto errout;
1306                 if (last) {
1307                         tcf_chain_tp_remove(chain, &chain_info, tp);
1308                         tcf_proto_destroy(tp, extack);
1309                 }
1310         }
1311 
1312 errout:
1313         if (chain)
1314                 tcf_chain_put(chain);
1315         return err;
1316 }
1317 
1318 static int tc_get_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
1319                           struct netlink_ext_ack *extack)
1320 {
1321         struct net *net = sock_net(skb->sk);
1322         struct nlattr *tca[TCA_MAX + 1];
1323         struct tcmsg *t;
1324         u32 protocol;
1325         u32 prio;
1326         u32 parent;
1327         u32 chain_index;
1328         struct Qdisc *q = NULL;
1329         struct tcf_chain_info chain_info;
1330         struct tcf_chain *chain = NULL;
1331         struct tcf_block *block;
1332         struct tcf_proto *tp = NULL;
1333         unsigned long cl = 0;
1334         void *fh = NULL;
1335         int err;
1336 
1337         err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL, extack);
1338         if (err < 0)
1339                 return err;
1340 
1341         t = nlmsg_data(n);
1342         protocol = TC_H_MIN(t->tcm_info);
1343         prio = TC_H_MAJ(t->tcm_info);
1344         parent = t->tcm_parent;
1345 
1346         if (prio == 0) {
1347                 NL_SET_ERR_MSG(extack, "Invalid filter command with priority of zero");
1348                 return -ENOENT;
1349         }
1350 
1351         /* Find head of filter chain. */
1352 
1353         block = tcf_block_find(net, &q, &parent, &cl,
1354                                t->tcm_ifindex, t->tcm_block_index, extack);
1355         if (IS_ERR(block)) {
1356                 err = PTR_ERR(block);
1357                 goto errout;
1358         }
1359 
1360         chain_index = tca[TCA_CHAIN] ? nla_get_u32(tca[TCA_CHAIN]) : 0;
1361         if (chain_index > TC_ACT_EXT_VAL_MASK) {
1362                 NL_SET_ERR_MSG(extack, "Specified chain index exceeds upper limit");
1363                 err = -EINVAL;
1364                 goto errout;
1365         }
1366         chain = tcf_chain_get(block, chain_index, false);
1367         if (!chain) {
1368                 NL_SET_ERR_MSG(extack, "Cannot find specified filter chain");
1369                 err = -EINVAL;
1370                 goto errout;
1371         }
1372 
1373         tp = tcf_chain_tp_find(chain, &chain_info, protocol,
1374                                prio, false);
1375         if (!tp || IS_ERR(tp)) {
1376                 NL_SET_ERR_MSG(extack, "Filter with specified priority/protocol not found");
1377                 err = tp ? PTR_ERR(tp) : -ENOENT;
1378                 goto errout;
1379         } else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind)) {
1380                 NL_SET_ERR_MSG(extack, "Specified filter kind does not match existing one");
1381                 err = -EINVAL;
1382                 goto errout;
1383         }
1384 
1385         fh = tp->ops->get(tp, t->tcm_handle);
1386 
1387         if (!fh) {
1388                 NL_SET_ERR_MSG(extack, "Specified filter handle not found");
1389                 err = -ENOENT;
1390         } else {
1391                 err = tfilter_notify(net, skb, n, tp, block, q, parent,
1392                                      fh, RTM_NEWTFILTER, true);
1393                 if (err < 0)
1394                         NL_SET_ERR_MSG(extack, "Failed to send filter notify message");
1395         }
1396 
1397 errout:
1398         if (chain)
1399                 tcf_chain_put(chain);
1400         return err;
1401 }
1402 
1403 struct tcf_dump_args {
1404         struct tcf_walker w;
1405         struct sk_buff *skb;
1406         struct netlink_callback *cb;
1407         struct tcf_block *block;
1408         struct Qdisc *q;
1409         u32 parent;
1410 };
1411 
1412 static int tcf_node_dump(struct tcf_proto *tp, void *n, struct tcf_walker *arg)
1413 {
1414         struct tcf_dump_args *a = (void *)arg;
1415         struct net *net = sock_net(a->skb->sk);
1416 
1417         return tcf_fill_node(net, a->skb, tp, a->block, a->q, a->parent,
1418                              n, NETLINK_CB(a->cb->skb).portid,
1419                              a->cb->nlh->nlmsg_seq, NLM_F_MULTI,
1420                              RTM_NEWTFILTER);
1421 }
1422 
1423 static bool tcf_chain_dump(struct tcf_chain *chain, struct Qdisc *q, u32 parent,
1424                            struct sk_buff *skb, struct netlink_callback *cb,
1425                            long index_start, long *p_index)
1426 {
1427         struct net *net = sock_net(skb->sk);
1428         struct tcf_block *block = chain->block;
1429         struct tcmsg *tcm = nlmsg_data(cb->nlh);
1430         struct tcf_dump_args arg;
1431         struct tcf_proto *tp;
1432 
1433         for (tp = rtnl_dereference(chain->filter_chain);
1434              tp; tp = rtnl_dereference(tp->next), (*p_index)++) {
1435                 if (*p_index < index_start)
1436                         continue;
1437                 if (TC_H_MAJ(tcm->tcm_info) &&
1438                     TC_H_MAJ(tcm->tcm_info) != tp->prio)
1439                         continue;
1440                 if (TC_H_MIN(tcm->tcm_info) &&
1441                     TC_H_MIN(tcm->tcm_info) != tp->protocol)
1442                         continue;
1443                 if (*p_index > index_start)
1444                         memset(&cb->args[1], 0,
1445                                sizeof(cb->args) - sizeof(cb->args[0]));
1446                 if (cb->args[1] == 0) {
1447                         if (tcf_fill_node(net, skb, tp, block, q, parent, 0,
1448                                           NETLINK_CB(cb->skb).portid,
1449                                           cb->nlh->nlmsg_seq, NLM_F_MULTI,
1450                                           RTM_NEWTFILTER) <= 0)
1451                                 return false;
1452 
1453                         cb->args[1] = 1;
1454                 }
1455                 if (!tp->ops->walk)
1456                         continue;
1457                 arg.w.fn = tcf_node_dump;
1458                 arg.skb = skb;
1459                 arg.cb = cb;
1460                 arg.block = block;
1461                 arg.q = q;
1462                 arg.parent = parent;
1463                 arg.w.stop = 0;
1464                 arg.w.skip = cb->args[1] - 1;
1465                 arg.w.count = 0;
1466                 tp->ops->walk(tp, &arg.w);
1467                 cb->args[1] = arg.w.count + 1;
1468                 if (arg.w.stop)
1469                         return false;
1470         }
1471         return true;
1472 }
1473 
1474 /* called with RTNL */
1475 static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
1476 {
1477         struct net *net = sock_net(skb->sk);
1478         struct nlattr *tca[TCA_MAX + 1];
1479         struct Qdisc *q = NULL;
1480         struct tcf_block *block;
1481         struct tcf_chain *chain;
1482         struct tcmsg *tcm = nlmsg_data(cb->nlh);
1483         long index_start;
1484         long index;
1485         u32 parent;
1486         int err;
1487 
1488         if (nlmsg_len(cb->nlh) < sizeof(*tcm))
1489                 return skb->len;
1490 
1491         err = nlmsg_parse(cb->nlh, sizeof(*tcm), tca, TCA_MAX, NULL, NULL);
1492         if (err)
1493                 return err;
1494 
1495         if (tcm->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) {
1496                 block = tcf_block_lookup(net, tcm->tcm_block_index);
1497                 if (!block)
1498                         goto out;
1499                 /* If we work with block index, q is NULL and parent value
1500                  * will never be used in the following code. The check
1501                  * in tcf_fill_node prevents it. However, compiler does not
1502                  * see that far, so set parent to zero to silence the warning
1503                  * about parent being uninitialized.
1504                  */
1505                 parent = 0;
1506         } else {
1507                 const struct Qdisc_class_ops *cops;
1508                 struct net_device *dev;
1509                 unsigned long cl = 0;
1510 
1511                 dev = __dev_get_by_index(net, tcm->tcm_ifindex);
1512                 if (!dev)
1513                         return skb->len;
1514 
1515                 parent = tcm->tcm_parent;
1516                 if (!parent) {
1517                         q = dev->qdisc;
1518                         parent = q->handle;
1519                 } else {
1520                         q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent));
1521                 }
1522                 if (!q)
1523                         goto out;
1524                 cops = q->ops->cl_ops;
1525                 if (!cops)
1526                         goto out;
1527                 if (!cops->tcf_block)
1528                         goto out;
1529                 if (TC_H_MIN(tcm->tcm_parent)) {
1530                         cl = cops->find(q, tcm->tcm_parent);
1531                         if (cl == 0)
1532                                 goto out;
1533                 }
1534                 block = cops->tcf_block(q, cl, NULL);
1535                 if (!block)
1536                         goto out;
1537                 if (tcf_block_shared(block))
1538                         q = NULL;
1539         }
1540 
1541         index_start = cb->args[0];
1542         index = 0;
1543 
1544         list_for_each_entry(chain, &block->chain_list, list) {
1545                 if (tca[TCA_CHAIN] &&
1546                     nla_get_u32(tca[TCA_CHAIN]) != chain->index)
1547                         continue;
1548                 if (!tcf_chain_dump(chain, q, parent, skb, cb,
1549                                     index_start, &index)) {
1550                         err = -EMSGSIZE;
1551                         break;
1552                 }
1553         }
1554 
1555         cb->args[0] = index;
1556 
1557 out:
1558         /* If we did no progress, the error (EMSGSIZE) is real */
1559         if (skb->len == 0 && err)
1560                 return err;
1561         return skb->len;
1562 }
1563 
1564 void tcf_exts_destroy(struct tcf_exts *exts)
1565 {
1566 #ifdef CONFIG_NET_CLS_ACT
1567         LIST_HEAD(actions);
1568 
1569         ASSERT_RTNL();
1570         tcf_exts_to_list(exts, &actions);
1571         tcf_action_destroy(&actions, TCA_ACT_UNBIND);
1572         kfree(exts->actions);
1573         exts->nr_actions = 0;
1574 #endif
1575 }
1576 EXPORT_SYMBOL(tcf_exts_destroy);
1577 
1578 int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
1579                       struct nlattr *rate_tlv, struct tcf_exts *exts, bool ovr,
1580                       struct netlink_ext_ack *extack)
1581 {
1582 #ifdef CONFIG_NET_CLS_ACT
1583         {
1584                 struct tc_action *act;
1585                 size_t attr_size = 0;
1586 
1587                 if (exts->police && tb[exts->police]) {
1588                         act = tcf_action_init_1(net, tp, tb[exts->police],
1589                                                 rate_tlv, "police", ovr,
1590                                                 TCA_ACT_BIND, extack);
1591                         if (IS_ERR(act))
1592                                 return PTR_ERR(act);
1593 
1594                         act->type = exts->type = TCA_OLD_COMPAT;
1595                         exts->actions[0] = act;
1596                         exts->nr_actions = 1;
1597                 } else if (exts->action && tb[exts->action]) {
1598                         LIST_HEAD(actions);
1599                         int err, i = 0;
1600 
1601                         err = tcf_action_init(net, tp, tb[exts->action],
1602                                               rate_tlv, NULL, ovr, TCA_ACT_BIND,
1603                                               &actions, &attr_size, extack);
1604                         if (err)
1605                                 return err;
1606                         list_for_each_entry(act, &actions, list)
1607                                 exts->actions[i++] = act;
1608                         exts->nr_actions = i;
1609                 }
1610                 exts->net = net;
1611         }
1612 #else
1613         if ((exts->action && tb[exts->action]) ||
1614             (exts->police && tb[exts->police])) {
1615                 NL_SET_ERR_MSG(extack, "Classifier actions are not supported per compile options (CONFIG_NET_CLS_ACT)");
1616                 return -EOPNOTSUPP;
1617         }
1618 #endif
1619 
1620         return 0;
1621 }
1622 EXPORT_SYMBOL(tcf_exts_validate);
1623 
1624 void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src)
1625 {
1626 #ifdef CONFIG_NET_CLS_ACT
1627         struct tcf_exts old = *dst;
1628 
1629         *dst = *src;
1630         tcf_exts_destroy(&old);
1631 #endif
1632 }
1633 EXPORT_SYMBOL(tcf_exts_change);
1634 
1635 #ifdef CONFIG_NET_CLS_ACT
1636 static struct tc_action *tcf_exts_first_act(struct tcf_exts *exts)
1637 {
1638         if (exts->nr_actions == 0)
1639                 return NULL;
1640         else
1641                 return exts->actions[0];
1642 }
1643 #endif
1644 
1645 int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts)
1646 {
1647 #ifdef CONFIG_NET_CLS_ACT
1648         struct nlattr *nest;
1649 
1650         if (exts->action && tcf_exts_has_actions(exts)) {
1651                 /*
1652                  * again for backward compatible mode - we want
1653                  * to work with both old and new modes of entering
1654                  * tc data even if iproute2  was newer - jhs
1655                  */
1656                 if (exts->type != TCA_OLD_COMPAT) {
1657                         LIST_HEAD(actions);
1658 
1659                         nest = nla_nest_start(skb, exts->action);
1660                         if (nest == NULL)
1661                                 goto nla_put_failure;
1662 
1663                         tcf_exts_to_list(exts, &actions);
1664                         if (tcf_action_dump(skb, &actions, 0, 0) < 0)
1665                                 goto nla_put_failure;
1666                         nla_nest_end(skb, nest);
1667                 } else if (exts->police) {
1668                         struct tc_action *act = tcf_exts_first_act(exts);
1669                         nest = nla_nest_start(skb, exts->police);
1670                         if (nest == NULL || !act)
1671                                 goto nla_put_failure;
1672                         if (tcf_action_dump_old(skb, act, 0, 0) < 0)
1673                                 goto nla_put_failure;
1674                         nla_nest_end(skb, nest);
1675                 }
1676         }
1677         return 0;
1678 
1679 nla_put_failure:
1680         nla_nest_cancel(skb, nest);
1681         return -1;
1682 #else
1683         return 0;
1684 #endif
1685 }
1686 EXPORT_SYMBOL(tcf_exts_dump);
1687 
1688 
1689 int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts)
1690 {
1691 #ifdef CONFIG_NET_CLS_ACT
1692         struct tc_action *a = tcf_exts_first_act(exts);
1693         if (a != NULL && tcf_action_copy_stats(skb, a, 1) < 0)
1694                 return -1;
1695 #endif
1696         return 0;
1697 }
1698 EXPORT_SYMBOL(tcf_exts_dump_stats);
1699 
1700 static int tc_exts_setup_cb_egdev_call(struct tcf_exts *exts,
1701                                        enum tc_setup_type type,
1702                                        void *type_data, bool err_stop)
1703 {
1704         int ok_count = 0;
1705 #ifdef CONFIG_NET_CLS_ACT
1706         const struct tc_action *a;
1707         struct net_device *dev;
1708         int i, ret;
1709 
1710         if (!tcf_exts_has_actions(exts))
1711                 return 0;
1712 
1713         for (i = 0; i < exts->nr_actions; i++) {
1714                 a = exts->actions[i];
1715                 if (!a->ops->get_dev)
1716                         continue;
1717                 dev = a->ops->get_dev(a);
1718                 if (!dev)
1719                         continue;
1720                 ret = tc_setup_cb_egdev_call(dev, type, type_data, err_stop);
1721                 if (ret < 0)
1722                         return ret;
1723                 ok_count += ret;
1724         }
1725 #endif
1726         return ok_count;
1727 }
1728 
1729 int tc_setup_cb_call(struct tcf_block *block, struct tcf_exts *exts,
1730                      enum tc_setup_type type, void *type_data, bool err_stop)
1731 {
1732         int ok_count;
1733         int ret;
1734 
1735         ret = tcf_block_cb_call(block, type, type_data, err_stop);
1736         if (ret < 0)
1737                 return ret;
1738         ok_count = ret;
1739 
1740         if (!exts || ok_count)
1741                 return ok_count;
1742         ret = tc_exts_setup_cb_egdev_call(exts, type, type_data, err_stop);
1743         if (ret < 0)
1744                 return ret;
1745         ok_count += ret;
1746 
1747         return ok_count;
1748 }
1749 EXPORT_SYMBOL(tc_setup_cb_call);
1750 
1751 static __net_init int tcf_net_init(struct net *net)
1752 {
1753         struct tcf_net *tn = net_generic(net, tcf_net_id);
1754 
1755         idr_init(&tn->idr);
1756         return 0;
1757 }
1758 
1759 static void __net_exit tcf_net_exit(struct net *net)
1760 {
1761         struct tcf_net *tn = net_generic(net, tcf_net_id);
1762 
1763         idr_destroy(&tn->idr);
1764 }
1765 
1766 static struct pernet_operations tcf_net_ops = {
1767         .init = tcf_net_init,
1768         .exit = tcf_net_exit,
1769         .id   = &tcf_net_id,
1770         .size = sizeof(struct tcf_net),
1771 };
1772 
1773 static int __init tc_filter_init(void)
1774 {
1775         int err;
1776 
1777         tc_filter_wq = alloc_ordered_workqueue("tc_filter_workqueue", 0);
1778         if (!tc_filter_wq)
1779                 return -ENOMEM;
1780 
1781         err = register_pernet_subsys(&tcf_net_ops);
1782         if (err)
1783                 goto err_register_pernet_subsys;
1784 
1785         rtnl_register(PF_UNSPEC, RTM_NEWTFILTER, tc_new_tfilter, NULL, 0);
1786         rtnl_register(PF_UNSPEC, RTM_DELTFILTER, tc_del_tfilter, NULL, 0);
1787         rtnl_register(PF_UNSPEC, RTM_GETTFILTER, tc_get_tfilter,
1788                       tc_dump_tfilter, 0);
1789 
1790         return 0;
1791 
1792 err_register_pernet_subsys:
1793         destroy_workqueue(tc_filter_wq);
1794         return err;
1795 }
1796 
1797 subsys_initcall(tc_filter_init);
1798 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp