cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xt_NFQUEUE.c (3830B)


      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);