root/net/netfilter/xt_NFQUEUE.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nfqueue_tg
  2. nfqueue_tg_v1
  3. nfqueue_tg_v2
  4. nfqueue_tg_check
  5. nfqueue_tg_v3
  6. nfqueue_tg_init
  7. nfqueue_tg_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* iptables module for using new netfilter netlink queue
   3  *
   4  * (C) 2005 by Harald Welte <laforge@netfilter.org>
   5  */
   6 
   7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   8 
   9 #include <linux/module.h>
  10 #include <linux/skbuff.h>
  11 
  12 #include <linux/netfilter.h>
  13 #include <linux/netfilter_arp.h>
  14 #include <linux/netfilter/x_tables.h>
  15 #include <linux/netfilter/xt_NFQUEUE.h>
  16 
  17 #include <net/netfilter/nf_queue.h>
  18 
  19 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
  20 MODULE_DESCRIPTION("Xtables: packet forwarding to netlink");
  21 MODULE_LICENSE("GPL");
  22 MODULE_ALIAS("ipt_NFQUEUE");
  23 MODULE_ALIAS("ip6t_NFQUEUE");
  24 MODULE_ALIAS("arpt_NFQUEUE");
  25 
  26 static u32 jhash_initval __read_mostly;
  27 
  28 static unsigned int
  29 nfqueue_tg(struct sk_buff *skb, const struct xt_action_param *par)
  30 {
  31         const struct xt_NFQ_info *tinfo = par->targinfo;
  32 
  33         return NF_QUEUE_NR(tinfo->queuenum);
  34 }
  35 
  36 static unsigned int
  37 nfqueue_tg_v1(struct sk_buff *skb, const struct xt_action_param *par)
  38 {
  39         const struct xt_NFQ_info_v1 *info = par->targinfo;
  40         u32 queue = info->queuenum;
  41 
  42         if (info->queues_total > 1) {
  43                 queue = nfqueue_hash(skb, queue, info->queues_total,
  44                                      xt_family(par), jhash_initval);
  45         }
  46         return NF_QUEUE_NR(queue);
  47 }
  48 
  49 static unsigned int
  50 nfqueue_tg_v2(struct sk_buff *skb, const struct xt_action_param *par)
  51 {
  52         const struct xt_NFQ_info_v2 *info = par->targinfo;
  53         unsigned int ret = nfqueue_tg_v1(skb, par);
  54 
  55         if (info->bypass)
  56                 ret |= NF_VERDICT_FLAG_QUEUE_BYPASS;
  57         return ret;
  58 }
  59 
  60 static int nfqueue_tg_check(const struct xt_tgchk_param *par)
  61 {
  62         const struct xt_NFQ_info_v3 *info = par->targinfo;
  63         u32 maxid;
  64 
  65         init_hashrandom(&jhash_initval);
  66 
  67         if (info->queues_total == 0) {
  68                 pr_info_ratelimited("number of total queues is 0\n");
  69                 return -EINVAL;
  70         }
  71         maxid = info->queues_total - 1 + info->queuenum;
  72         if (maxid > 0xffff) {
  73                 pr_info_ratelimited("number of queues (%u) out of range (got %u)\n",
  74                                     info->queues_total, maxid);
  75                 return -ERANGE;
  76         }
  77         if (par->target->revision == 2 && info->flags > 1)
  78                 return -EINVAL;
  79         if (par->target->revision == 3 && info->flags & ~NFQ_FLAG_MASK)
  80                 return -EINVAL;
  81 
  82         return 0;
  83 }
  84 
  85 static unsigned int
  86 nfqueue_tg_v3(struct sk_buff *skb, const struct xt_action_param *par)
  87 {
  88         const struct xt_NFQ_info_v3 *info = par->targinfo;
  89         u32 queue = info->queuenum;
  90         int ret;
  91 
  92         if (info->queues_total > 1) {
  93                 if (info->flags & NFQ_FLAG_CPU_FANOUT) {
  94                         int cpu = smp_processor_id();
  95 
  96                         queue = info->queuenum + cpu % info->queues_total;
  97                 } else {
  98                         queue = nfqueue_hash(skb, queue, info->queues_total,
  99                                              xt_family(par), jhash_initval);
 100                 }
 101         }
 102 
 103         ret = NF_QUEUE_NR(queue);
 104         if (info->flags & NFQ_FLAG_BYPASS)
 105                 ret |= NF_VERDICT_FLAG_QUEUE_BYPASS;
 106 
 107         return ret;
 108 }
 109 
 110 static struct xt_target nfqueue_tg_reg[] __read_mostly = {
 111         {
 112                 .name           = "NFQUEUE",
 113                 .family         = NFPROTO_UNSPEC,
 114                 .target         = nfqueue_tg,
 115                 .targetsize     = sizeof(struct xt_NFQ_info),
 116                 .me             = THIS_MODULE,
 117         },
 118         {
 119                 .name           = "NFQUEUE",
 120                 .revision       = 1,
 121                 .family         = NFPROTO_UNSPEC,
 122                 .checkentry     = nfqueue_tg_check,
 123                 .target         = nfqueue_tg_v1,
 124                 .targetsize     = sizeof(struct xt_NFQ_info_v1),
 125                 .me             = THIS_MODULE,
 126         },
 127         {
 128                 .name           = "NFQUEUE",
 129                 .revision       = 2,
 130                 .family         = NFPROTO_UNSPEC,
 131                 .checkentry     = nfqueue_tg_check,
 132                 .target         = nfqueue_tg_v2,
 133                 .targetsize     = sizeof(struct xt_NFQ_info_v2),
 134                 .me             = THIS_MODULE,
 135         },
 136         {
 137                 .name           = "NFQUEUE",
 138                 .revision       = 3,
 139                 .family         = NFPROTO_UNSPEC,
 140                 .checkentry     = nfqueue_tg_check,
 141                 .target         = nfqueue_tg_v3,
 142                 .targetsize     = sizeof(struct xt_NFQ_info_v3),
 143                 .me             = THIS_MODULE,
 144         },
 145 };
 146 
 147 static int __init nfqueue_tg_init(void)
 148 {
 149         return xt_register_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg));
 150 }
 151 
 152 static void __exit nfqueue_tg_exit(void)
 153 {
 154         xt_unregister_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg));
 155 }
 156 
 157 module_init(nfqueue_tg_init);
 158 module_exit(nfqueue_tg_exit);

/* [<][>][^][v][top][bottom][index][help] */