Blame view

net/netfilter/xt_NFQUEUE.c 3.74 KB
d2912cb15   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
2
3
4
  /* iptables module for using new netfilter netlink queue
   *
   * (C) 2005 by Harald Welte <laforge@netfilter.org>
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
5
   */
e016c5e43   Florian Westphal   netfilter: xt_NFQ...
6
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
7
8
9
10
11
12
13
  #include <linux/module.h>
  #include <linux/skbuff.h>
  
  #include <linux/netfilter.h>
  #include <linux/netfilter_arp.h>
  #include <linux/netfilter/x_tables.h>
  #include <linux/netfilter/xt_NFQUEUE.h>
97a2d41c4   Eric Leblond   netfilter: xt_NFQ...
14
  #include <net/netfilter/nf_queue.h>
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
15
  MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
2ae15b64e   Jan Engelhardt   [NETFILTER]: Upda...
16
  MODULE_DESCRIPTION("Xtables: packet forwarding to netlink");
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
17
18
19
20
  MODULE_LICENSE("GPL");
  MODULE_ALIAS("ipt_NFQUEUE");
  MODULE_ALIAS("ip6t_NFQUEUE");
  MODULE_ALIAS("arpt_NFQUEUE");
10662aa30   Florian Westphal   netfilter: xt_NFQ...
21
  static u32 jhash_initval __read_mostly;
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
22
  static unsigned int
4b560b447   Jan Engelhardt   netfilter: xtable...
23
  nfqueue_tg(struct sk_buff *skb, const struct xt_action_param *par)
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
24
  {
7eb355865   Jan Engelhardt   netfilter: xtable...
25
  	const struct xt_NFQ_info *tinfo = par->targinfo;
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
26
27
28
  
  	return NF_QUEUE_NR(tinfo->queuenum);
  }
5c33448c4   holger@eitzenberger.org   netfilter: xt_NFQ...
29
30
31
32
33
  static unsigned int
  nfqueue_tg_v1(struct sk_buff *skb, const struct xt_action_param *par)
  {
  	const struct xt_NFQ_info_v1 *info = par->targinfo;
  	u32 queue = info->queuenum;
97a2d41c4   Eric Leblond   netfilter: xt_NFQ...
34
35
  	if (info->queues_total > 1) {
  		queue = nfqueue_hash(skb, queue, info->queues_total,
613dbd957   Pablo Neira Ayuso   netfilter: x_tabl...
36
  				     xt_family(par), jhash_initval);
97a2d41c4   Eric Leblond   netfilter: xt_NFQ...
37
  	}
10662aa30   Florian Westphal   netfilter: xt_NFQ...
38
39
  	return NF_QUEUE_NR(queue);
  }
10662aa30   Florian Westphal   netfilter: xt_NFQ...
40

94b27cc36   Florian Westphal   netfilter: allow ...
41
42
  static unsigned int
  nfqueue_tg_v2(struct sk_buff *skb, const struct xt_action_param *par)
10662aa30   Florian Westphal   netfilter: xt_NFQ...
43
  {
94b27cc36   Florian Westphal   netfilter: allow ...
44
45
46
47
48
49
50
51
52
53
  	const struct xt_NFQ_info_v2 *info = par->targinfo;
  	unsigned int ret = nfqueue_tg_v1(skb, par);
  
  	if (info->bypass)
  		ret |= NF_VERDICT_FLAG_QUEUE_BYPASS;
  	return ret;
  }
  
  static int nfqueue_tg_check(const struct xt_tgchk_param *par)
  {
8746ddcf1   holger@eitzenberger.org   netfilter: xt_NFQ...
54
  	const struct xt_NFQ_info_v3 *info = par->targinfo;
10662aa30   Florian Westphal   netfilter: xt_NFQ...
55
  	u32 maxid;
97a2d41c4   Eric Leblond   netfilter: xt_NFQ...
56
  	init_hashrandom(&jhash_initval);
10662aa30   Florian Westphal   netfilter: xt_NFQ...
57
  	if (info->queues_total == 0) {
e016c5e43   Florian Westphal   netfilter: xt_NFQ...
58
59
  		pr_info_ratelimited("number of total queues is 0
  ");
d6b00a534   Jan Engelhardt   netfilter: xtable...
60
  		return -EINVAL;
10662aa30   Florian Westphal   netfilter: xt_NFQ...
61
62
63
  	}
  	maxid = info->queues_total - 1 + info->queuenum;
  	if (maxid > 0xffff) {
e016c5e43   Florian Westphal   netfilter: xt_NFQ...
64
65
66
  		pr_info_ratelimited("number of queues (%u) out of range (got %u)
  ",
  				    info->queues_total, maxid);
4a5a5c73b   Jan Engelhardt   netfilter: xtable...
67
  		return -ERANGE;
10662aa30   Florian Westphal   netfilter: xt_NFQ...
68
  	}
8746ddcf1   holger@eitzenberger.org   netfilter: xt_NFQ...
69
70
71
  	if (par->target->revision == 2 && info->flags > 1)
  		return -EINVAL;
  	if (par->target->revision == 3 && info->flags & ~NFQ_FLAG_MASK)
94b27cc36   Florian Westphal   netfilter: allow ...
72
  		return -EINVAL;
8746ddcf1   holger@eitzenberger.org   netfilter: xt_NFQ...
73

d6b00a534   Jan Engelhardt   netfilter: xtable...
74
  	return 0;
10662aa30   Florian Westphal   netfilter: xt_NFQ...
75
  }
8746ddcf1   holger@eitzenberger.org   netfilter: xt_NFQ...
76
77
78
79
80
  static unsigned int
  nfqueue_tg_v3(struct sk_buff *skb, const struct xt_action_param *par)
  {
  	const struct xt_NFQ_info_v3 *info = par->targinfo;
  	u32 queue = info->queuenum;
d95477732   Holger Eitzenberger   netfilter: xt_NFQ...
81
  	int ret;
8746ddcf1   holger@eitzenberger.org   netfilter: xt_NFQ...
82
83
84
85
86
87
  
  	if (info->queues_total > 1) {
  		if (info->flags & NFQ_FLAG_CPU_FANOUT) {
  			int cpu = smp_processor_id();
  
  			queue = info->queuenum + cpu % info->queues_total;
97a2d41c4   Eric Leblond   netfilter: xt_NFQ...
88
89
  		} else {
  			queue = nfqueue_hash(skb, queue, info->queues_total,
613dbd957   Pablo Neira Ayuso   netfilter: x_tabl...
90
  					     xt_family(par), jhash_initval);
97a2d41c4   Eric Leblond   netfilter: xt_NFQ...
91
  		}
8746ddcf1   holger@eitzenberger.org   netfilter: xt_NFQ...
92
  	}
5c33448c4   holger@eitzenberger.org   netfilter: xt_NFQ...
93

d95477732   Holger Eitzenberger   netfilter: xt_NFQ...
94
95
96
97
98
  	ret = NF_QUEUE_NR(queue);
  	if (info->flags & NFQ_FLAG_BYPASS)
  		ret |= NF_VERDICT_FLAG_QUEUE_BYPASS;
  
  	return ret;
8746ddcf1   holger@eitzenberger.org   netfilter: xt_NFQ...
99
  }
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
100
  static struct xt_target nfqueue_tg_reg[] __read_mostly = {
4470bbc74   Patrick McHardy   [NETFILTER]: x_ta...
101
102
  	{
  		.name		= "NFQUEUE",
61f5abcab   Florian Westphal   netfilter: xt_NFQ...
103
  		.family		= NFPROTO_UNSPEC,
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
104
  		.target		= nfqueue_tg,
4470bbc74   Patrick McHardy   [NETFILTER]: x_ta...
105
106
107
  		.targetsize	= sizeof(struct xt_NFQ_info),
  		.me		= THIS_MODULE,
  	},
10662aa30   Florian Westphal   netfilter: xt_NFQ...
108
109
110
  	{
  		.name		= "NFQUEUE",
  		.revision	= 1,
f76a47c83   Jan Engelhardt   netfilter: xt_NFQ...
111
  		.family		= NFPROTO_UNSPEC,
94b27cc36   Florian Westphal   netfilter: allow ...
112
  		.checkentry	= nfqueue_tg_check,
f76a47c83   Jan Engelhardt   netfilter: xt_NFQ...
113
  		.target		= nfqueue_tg_v1,
10662aa30   Florian Westphal   netfilter: xt_NFQ...
114
115
116
  		.targetsize	= sizeof(struct xt_NFQ_info_v1),
  		.me		= THIS_MODULE,
  	},
94b27cc36   Florian Westphal   netfilter: allow ...
117
118
119
120
121
122
123
124
125
  	{
  		.name		= "NFQUEUE",
  		.revision	= 2,
  		.family		= NFPROTO_UNSPEC,
  		.checkentry	= nfqueue_tg_check,
  		.target		= nfqueue_tg_v2,
  		.targetsize	= sizeof(struct xt_NFQ_info_v2),
  		.me		= THIS_MODULE,
  	},
8746ddcf1   holger@eitzenberger.org   netfilter: xt_NFQ...
126
127
128
129
130
131
132
133
134
  	{
  		.name		= "NFQUEUE",
  		.revision	= 3,
  		.family		= NFPROTO_UNSPEC,
  		.checkentry	= nfqueue_tg_check,
  		.target		= nfqueue_tg_v3,
  		.targetsize	= sizeof(struct xt_NFQ_info_v3),
  		.me		= THIS_MODULE,
  	},
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
135
  };
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
136
  static int __init nfqueue_tg_init(void)
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
137
  {
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
138
  	return xt_register_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg));
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
139
  }
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
140
  static void __exit nfqueue_tg_exit(void)
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
141
  {
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
142
  	xt_unregister_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg));
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
143
  }
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
144
145
  module_init(nfqueue_tg_init);
  module_exit(nfqueue_tg_exit);