1e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet/* Kernel module to match running CPU */
2e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet
3e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet/*
4e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet * Might be used to distribute connections on several daemons, if
5e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet * RPS (Remote Packet Steering) is enabled or NIC is multiqueue capable,
6e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet * each RX queue IRQ affined to one CPU (1:1 mapping)
7e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet *
8e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet */
9e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet
10e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet/* (C) 2010 Eric Dumazet
11e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet *
12e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet * This program is free software; you can redistribute it and/or modify
13e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet * it under the terms of the GNU General Public License version 2 as
14e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet * published by the Free Software Foundation.
15e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet */
16e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet
17e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet#include <linux/module.h>
18e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet#include <linux/skbuff.h>
19e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet#include <linux/netfilter/xt_cpu.h>
20e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet#include <linux/netfilter/x_tables.h>
21e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet
22e8648a1fdb54da1f683784b36a17aa65ea56e931Eric DumazetMODULE_LICENSE("GPL");
23e8648a1fdb54da1f683784b36a17aa65ea56e931Eric DumazetMODULE_AUTHOR("Eric Dumazet <eric.dumazet@gmail.com>");
24e8648a1fdb54da1f683784b36a17aa65ea56e931Eric DumazetMODULE_DESCRIPTION("Xtables: CPU match");
25f1e231a356f90a67f8547c2881a62c92084683c6Jan EngelhardtMODULE_ALIAS("ipt_cpu");
26f1e231a356f90a67f8547c2881a62c92084683c6Jan EngelhardtMODULE_ALIAS("ip6t_cpu");
27e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet
28e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazetstatic int cpu_mt_check(const struct xt_mtchk_param *par)
29e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet{
30e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	const struct xt_cpu_info *info = par->matchinfo;
31e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet
32e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	if (info->invert & ~1)
33e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet		return -EINVAL;
34e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	return 0;
35e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet}
36e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet
37e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazetstatic bool cpu_mt(const struct sk_buff *skb, struct xt_action_param *par)
38e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet{
39e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	const struct xt_cpu_info *info = par->matchinfo;
40e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet
41e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	return (info->cpu == smp_processor_id()) ^ info->invert;
42e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet}
43e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet
44e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazetstatic struct xt_match cpu_mt_reg __read_mostly = {
45e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	.name       = "cpu",
46e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	.revision   = 0,
47e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	.family     = NFPROTO_UNSPEC,
48e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	.checkentry = cpu_mt_check,
49e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	.match      = cpu_mt,
50e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	.matchsize  = sizeof(struct xt_cpu_info),
51e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	.me         = THIS_MODULE,
52e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet};
53e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet
54e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazetstatic int __init cpu_mt_init(void)
55e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet{
56e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	return xt_register_match(&cpu_mt_reg);
57e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet}
58e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet
59e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazetstatic void __exit cpu_mt_exit(void)
60e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet{
61e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet	xt_unregister_match(&cpu_mt_reg);
62e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet}
63e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazet
64e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazetmodule_init(cpu_mt_init);
65e8648a1fdb54da1f683784b36a17aa65ea56e931Eric Dumazetmodule_exit(cpu_mt_exit);
66