Blame view
net/netfilter/xt_NFQUEUE.c
3.74 KB
d2912cb15 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
2e4e6a17a [NETFILTER] x_tab... |
2 3 4 |
/* iptables module for using new netfilter netlink queue * * (C) 2005 by Harald Welte <laforge@netfilter.org> |
2e4e6a17a [NETFILTER] x_tab... |
5 |
*/ |
e016c5e43 netfilter: xt_NFQ... |
6 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
2e4e6a17a [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 netfilter: xt_NFQ... |
14 |
#include <net/netfilter/nf_queue.h> |
2e4e6a17a [NETFILTER] x_tab... |
15 |
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); |
2ae15b64e [NETFILTER]: Upda... |
16 |
MODULE_DESCRIPTION("Xtables: packet forwarding to netlink"); |
2e4e6a17a [NETFILTER] x_tab... |
17 18 19 20 |
MODULE_LICENSE("GPL"); MODULE_ALIAS("ipt_NFQUEUE"); MODULE_ALIAS("ip6t_NFQUEUE"); MODULE_ALIAS("arpt_NFQUEUE"); |
10662aa30 netfilter: xt_NFQ... |
21 |
static u32 jhash_initval __read_mostly; |
2e4e6a17a [NETFILTER] x_tab... |
22 |
static unsigned int |
4b560b447 netfilter: xtable... |
23 |
nfqueue_tg(struct sk_buff *skb, const struct xt_action_param *par) |
2e4e6a17a [NETFILTER] x_tab... |
24 |
{ |
7eb355865 netfilter: xtable... |
25 |
const struct xt_NFQ_info *tinfo = par->targinfo; |
2e4e6a17a [NETFILTER] x_tab... |
26 27 28 |
return NF_QUEUE_NR(tinfo->queuenum); } |
5c33448c4 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 netfilter: xt_NFQ... |
34 35 |
if (info->queues_total > 1) { queue = nfqueue_hash(skb, queue, info->queues_total, |
613dbd957 netfilter: x_tabl... |
36 |
xt_family(par), jhash_initval); |
97a2d41c4 netfilter: xt_NFQ... |
37 |
} |
10662aa30 netfilter: xt_NFQ... |
38 39 |
return NF_QUEUE_NR(queue); } |
10662aa30 netfilter: xt_NFQ... |
40 |
|
94b27cc36 netfilter: allow ... |
41 42 |
static unsigned int nfqueue_tg_v2(struct sk_buff *skb, const struct xt_action_param *par) |
10662aa30 netfilter: xt_NFQ... |
43 |
{ |
94b27cc36 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 netfilter: xt_NFQ... |
54 |
const struct xt_NFQ_info_v3 *info = par->targinfo; |
10662aa30 netfilter: xt_NFQ... |
55 |
u32 maxid; |
97a2d41c4 netfilter: xt_NFQ... |
56 |
init_hashrandom(&jhash_initval); |
10662aa30 netfilter: xt_NFQ... |
57 |
if (info->queues_total == 0) { |
e016c5e43 netfilter: xt_NFQ... |
58 59 |
pr_info_ratelimited("number of total queues is 0 "); |
d6b00a534 netfilter: xtable... |
60 |
return -EINVAL; |
10662aa30 netfilter: xt_NFQ... |
61 62 63 |
} maxid = info->queues_total - 1 + info->queuenum; if (maxid > 0xffff) { |
e016c5e43 netfilter: xt_NFQ... |
64 65 66 |
pr_info_ratelimited("number of queues (%u) out of range (got %u) ", info->queues_total, maxid); |
4a5a5c73b netfilter: xtable... |
67 |
return -ERANGE; |
10662aa30 netfilter: xt_NFQ... |
68 |
} |
8746ddcf1 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 netfilter: allow ... |
72 |
return -EINVAL; |
8746ddcf1 netfilter: xt_NFQ... |
73 |
|
d6b00a534 netfilter: xtable... |
74 |
return 0; |
10662aa30 netfilter: xt_NFQ... |
75 |
} |
8746ddcf1 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 netfilter: xt_NFQ... |
81 |
int ret; |
8746ddcf1 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 netfilter: xt_NFQ... |
88 89 |
} else { queue = nfqueue_hash(skb, queue, info->queues_total, |
613dbd957 netfilter: x_tabl... |
90 |
xt_family(par), jhash_initval); |
97a2d41c4 netfilter: xt_NFQ... |
91 |
} |
8746ddcf1 netfilter: xt_NFQ... |
92 |
} |
5c33448c4 netfilter: xt_NFQ... |
93 |
|
d95477732 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 netfilter: xt_NFQ... |
99 |
} |
d3c5ee6d5 [NETFILTER]: x_ta... |
100 |
static struct xt_target nfqueue_tg_reg[] __read_mostly = { |
4470bbc74 [NETFILTER]: x_ta... |
101 102 |
{ .name = "NFQUEUE", |
61f5abcab netfilter: xt_NFQ... |
103 |
.family = NFPROTO_UNSPEC, |
d3c5ee6d5 [NETFILTER]: x_ta... |
104 |
.target = nfqueue_tg, |
4470bbc74 [NETFILTER]: x_ta... |
105 106 107 |
.targetsize = sizeof(struct xt_NFQ_info), .me = THIS_MODULE, }, |
10662aa30 netfilter: xt_NFQ... |
108 109 110 |
{ .name = "NFQUEUE", .revision = 1, |
f76a47c83 netfilter: xt_NFQ... |
111 |
.family = NFPROTO_UNSPEC, |
94b27cc36 netfilter: allow ... |
112 |
.checkentry = nfqueue_tg_check, |
f76a47c83 netfilter: xt_NFQ... |
113 |
.target = nfqueue_tg_v1, |
10662aa30 netfilter: xt_NFQ... |
114 115 116 |
.targetsize = sizeof(struct xt_NFQ_info_v1), .me = THIS_MODULE, }, |
94b27cc36 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 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 [NETFILTER] x_tab... |
135 |
}; |
d3c5ee6d5 [NETFILTER]: x_ta... |
136 |
static int __init nfqueue_tg_init(void) |
2e4e6a17a [NETFILTER] x_tab... |
137 |
{ |
d3c5ee6d5 [NETFILTER]: x_ta... |
138 |
return xt_register_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg)); |
2e4e6a17a [NETFILTER] x_tab... |
139 |
} |
d3c5ee6d5 [NETFILTER]: x_ta... |
140 |
static void __exit nfqueue_tg_exit(void) |
2e4e6a17a [NETFILTER] x_tab... |
141 |
{ |
d3c5ee6d5 [NETFILTER]: x_ta... |
142 |
xt_unregister_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg)); |
2e4e6a17a [NETFILTER] x_tab... |
143 |
} |
d3c5ee6d5 [NETFILTER]: x_ta... |
144 145 |
module_init(nfqueue_tg_init); module_exit(nfqueue_tg_exit); |