treewide: Add SPDX license identifier for more missed files
[linux-2.6-block.git] / net / ipv4 / netfilter / arptable_filter.c
CommitLineData
09c434b8 1// SPDX-License-Identifier: GPL-2.0-only
1da177e4
LT
2/*
3 * Filtering ARP tables module.
4 *
5 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
6 *
7 */
8
9#include <linux/module.h>
e3eaa991 10#include <linux/netfilter/x_tables.h>
1da177e4 11#include <linux/netfilter_arp/arp_tables.h>
5a0e3ad6 12#include <linux/slab.h>
1da177e4
LT
13
14MODULE_LICENSE("GPL");
15MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
16MODULE_DESCRIPTION("arptables filter table");
17
18#define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \
19 (1 << NF_ARP_FORWARD))
20
b9e69e12
FW
21static int __net_init arptable_filter_table_init(struct net *net);
22
35aad0ff 23static const struct xt_table packet_filter = {
1da177e4
LT
24 .name = "filter",
25 .valid_hooks = FILTER_VALID_HOOKS,
1da177e4 26 .me = THIS_MODULE,
ee999d8b 27 .af = NFPROTO_ARP,
2b95efe7 28 .priority = NF_IP_PRI_FILTER,
b9e69e12 29 .table_init = arptable_filter_table_init,
1da177e4
LT
30};
31
32/* The work comes in here from netfilter.c */
737535c5 33static unsigned int
06198b34 34arptable_filter_hook(void *priv, struct sk_buff *skb,
238e54c9 35 const struct nf_hook_state *state)
1da177e4 36{
6cb8ff3f 37 return arpt_do_table(skb, state, state->net->ipv4.arptable_filter);
3918fed5
AD
38}
39
2b95efe7 40static struct nf_hook_ops *arpfilter_ops __read_mostly;
1da177e4 41
b9e69e12 42static int __net_init arptable_filter_table_init(struct net *net)
9ea0cb26 43{
e3eaa991 44 struct arpt_replace *repl;
a67dd266
FW
45 int err;
46
b9e69e12
FW
47 if (net->ipv4.arptable_filter)
48 return 0;
49
e3eaa991
JE
50 repl = arpt_alloc_initial_table(&packet_filter);
51 if (repl == NULL)
52 return -ENOMEM;
a67dd266
FW
53 err = arpt_register_table(net, &packet_filter, repl, arpfilter_ops,
54 &net->ipv4.arptable_filter);
e3eaa991 55 kfree(repl);
a67dd266 56 return err;
9ea0cb26
AD
57}
58
59static void __net_exit arptable_filter_net_exit(struct net *net)
60{
b9e69e12
FW
61 if (!net->ipv4.arptable_filter)
62 return;
a67dd266 63 arpt_unregister_table(net, net->ipv4.arptable_filter, arpfilter_ops);
b9e69e12 64 net->ipv4.arptable_filter = NULL;
9ea0cb26
AD
65}
66
67static struct pernet_operations arptable_filter_net_ops = {
9ea0cb26
AD
68 .exit = arptable_filter_net_exit,
69};
70
65b4b4e8 71static int __init arptable_filter_init(void)
1da177e4 72{
964ddaa1 73 int ret;
1da177e4 74
b9e69e12
FW
75 arpfilter_ops = xt_hook_ops_alloc(&packet_filter, arptable_filter_hook);
76 if (IS_ERR(arpfilter_ops))
77 return PTR_ERR(arpfilter_ops);
78
9ea0cb26 79 ret = register_pernet_subsys(&arptable_filter_net_ops);
b9e69e12
FW
80 if (ret < 0) {
81 kfree(arpfilter_ops);
9ea0cb26 82 return ret;
2b95efe7 83 }
1da177e4 84
ff76def3
FW
85 ret = arptable_filter_table_init(&init_net);
86 if (ret) {
87 unregister_pernet_subsys(&arptable_filter_net_ops);
88 kfree(arpfilter_ops);
89 }
90
1da177e4
LT
91 return ret;
92}
93
65b4b4e8 94static void __exit arptable_filter_fini(void)
1da177e4 95{
9ea0cb26 96 unregister_pernet_subsys(&arptable_filter_net_ops);
b9e69e12 97 kfree(arpfilter_ops);
1da177e4
LT
98}
99
65b4b4e8
AM
100module_init(arptable_filter_init);
101module_exit(arptable_filter_fini);