Linux Audio

Check our new training course

Loading...
v5.14.15
  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
 19MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 20MODULE_DESCRIPTION("Xtables: packet forwarding to netlink");
 21MODULE_LICENSE("GPL");
 22MODULE_ALIAS("ipt_NFQUEUE");
 23MODULE_ALIAS("ip6t_NFQUEUE");
 24MODULE_ALIAS("arpt_NFQUEUE");
 25
 26static u32 jhash_initval __read_mostly;
 27
 28static unsigned int
 29nfqueue_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
 36static unsigned int
 37nfqueue_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
 49static unsigned int
 50nfqueue_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
 60static 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
 85static unsigned int
 86nfqueue_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
110static 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
147static int __init nfqueue_tg_init(void)
148{
149	return xt_register_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg));
150}
151
152static void __exit nfqueue_tg_exit(void)
153{
154	xt_unregister_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg));
155}
156
157module_init(nfqueue_tg_init);
158module_exit(nfqueue_tg_exit);
v5.4
  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
 19MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 20MODULE_DESCRIPTION("Xtables: packet forwarding to netlink");
 21MODULE_LICENSE("GPL");
 22MODULE_ALIAS("ipt_NFQUEUE");
 23MODULE_ALIAS("ip6t_NFQUEUE");
 24MODULE_ALIAS("arpt_NFQUEUE");
 25
 26static u32 jhash_initval __read_mostly;
 27
 28static unsigned int
 29nfqueue_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
 36static unsigned int
 37nfqueue_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
 49static unsigned int
 50nfqueue_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
 60static 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
 85static unsigned int
 86nfqueue_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
110static 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
147static int __init nfqueue_tg_init(void)
148{
149	return xt_register_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg));
150}
151
152static void __exit nfqueue_tg_exit(void)
153{
154	xt_unregister_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg));
155}
156
157module_init(nfqueue_tg_init);
158module_exit(nfqueue_tg_exit);