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