Merge tag 'usb-5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
[linux-2.6-block.git] / net / ipv6 / netfilter / ip6table_raw.c
CommitLineData
09c434b8 1// SPDX-License-Identifier: GPL-2.0-only
1da177e4
LT
2/*
3 * IPv6 raw table, a port of the IPv4 raw table to IPv6
4 *
fe03d474 5 * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@netfilter.org>
1da177e4 6 */
902d6a4c 7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1da177e4
LT
8#include <linux/module.h>
9#include <linux/netfilter_ipv6/ip6_tables.h>
5a0e3ad6 10#include <linux/slab.h>
1da177e4 11
6e23ae2a 12#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
1da177e4 13
b9e69e12
FW
14static int __net_init ip6table_raw_table_init(struct net *net);
15
902d6a4c
SAK
16static bool raw_before_defrag __read_mostly;
17MODULE_PARM_DESC(raw_before_defrag, "Enable raw table before defrag");
18module_param(raw_before_defrag, bool, 0000);
19
b069b37a 20static const struct xt_table packet_raw = {
1ab1457c
YH
21 .name = "raw",
22 .valid_hooks = RAW_VALID_HOOKS,
2e4e6a17 23 .me = THIS_MODULE,
f88e6a8a 24 .af = NFPROTO_IPV6,
9c138866 25 .priority = NF_IP6_PRI_RAW,
b9e69e12 26 .table_init = ip6table_raw_table_init,
1da177e4
LT
27};
28
b069b37a
AB
29static const struct xt_table packet_raw_before_defrag = {
30 .name = "raw",
31 .valid_hooks = RAW_VALID_HOOKS,
32 .me = THIS_MODULE,
33 .af = NFPROTO_IPV6,
34 .priority = NF_IP6_PRI_RAW_BEFORE_DEFRAG,
35 .table_init = ip6table_raw_table_init,
36};
37
1da177e4
LT
38/* The work comes in here from netfilter.c. */
39static unsigned int
06198b34 40ip6table_raw_hook(void *priv, struct sk_buff *skb,
238e54c9 41 const struct nf_hook_state *state)
1da177e4 42{
6cb8ff3f 43 return ip6t_do_table(skb, state, state->net->ipv6.ip6table_raw);
1da177e4
LT
44}
45
2b95efe7 46static struct nf_hook_ops *rawtable_ops __read_mostly;
1da177e4 47
b9e69e12 48static int __net_init ip6table_raw_table_init(struct net *net)
8280aa61 49{
e3eaa991 50 struct ip6t_replace *repl;
b069b37a 51 const struct xt_table *table = &packet_raw;
a67dd266 52 int ret;
e3eaa991 53
b069b37a
AB
54 if (raw_before_defrag)
55 table = &packet_raw_before_defrag;
56
b9e69e12
FW
57 if (net->ipv6.ip6table_raw)
58 return 0;
59
b069b37a 60 repl = ip6t_alloc_initial_table(table);
e3eaa991
JE
61 if (repl == NULL)
62 return -ENOMEM;
b069b37a 63 ret = ip6t_register_table(net, table, repl, rawtable_ops,
a67dd266 64 &net->ipv6.ip6table_raw);
e3eaa991 65 kfree(repl);
a67dd266 66 return ret;
8280aa61
AD
67}
68
69static void __net_exit ip6table_raw_net_exit(struct net *net)
70{
b9e69e12
FW
71 if (!net->ipv6.ip6table_raw)
72 return;
a67dd266 73 ip6t_unregister_table(net, net->ipv6.ip6table_raw, rawtable_ops);
b9e69e12 74 net->ipv6.ip6table_raw = NULL;
8280aa61
AD
75}
76
77static struct pernet_operations ip6table_raw_net_ops = {
8280aa61
AD
78 .exit = ip6table_raw_net_exit,
79};
80
65b4b4e8 81static int __init ip6table_raw_init(void)
1da177e4
LT
82{
83 int ret;
b069b37a 84 const struct xt_table *table = &packet_raw;
1da177e4 85
902d6a4c 86 if (raw_before_defrag) {
b069b37a 87 table = &packet_raw_before_defrag;
902d6a4c
SAK
88
89 pr_info("Enabling raw table before defrag\n");
90 }
91
b9e69e12 92 /* Register hooks */
b069b37a 93 rawtable_ops = xt_hook_ops_alloc(table, ip6table_raw_hook);
b9e69e12
FW
94 if (IS_ERR(rawtable_ops))
95 return PTR_ERR(rawtable_ops);
96
8280aa61 97 ret = register_pernet_subsys(&ip6table_raw_net_ops);
b9e69e12
FW
98 if (ret < 0) {
99 kfree(rawtable_ops);
8280aa61 100 return ret;
2b95efe7 101 }
1da177e4 102
b9e69e12
FW
103 ret = ip6table_raw_table_init(&init_net);
104 if (ret) {
105 unregister_pernet_subsys(&ip6table_raw_net_ops);
106 kfree(rawtable_ops);
107 }
1da177e4
LT
108 return ret;
109}
110
65b4b4e8 111static void __exit ip6table_raw_fini(void)
1da177e4 112{
8280aa61 113 unregister_pernet_subsys(&ip6table_raw_net_ops);
b9e69e12 114 kfree(rawtable_ops);
1da177e4
LT
115}
116
65b4b4e8
AM
117module_init(ip6table_raw_init);
118module_exit(ip6table_raw_fini);
1da177e4 119MODULE_LICENSE("GPL");