1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 *  ebtable_nat
4 *
5 *	Authors:
6 *	Bart De Schuymer <bdschuym@pandora.be>
7 *
8 *  April, 2002
9 *
10 */
11
12#include <linux/netfilter_bridge/ebtables.h>
13#include <uapi/linux/netfilter_bridge.h>
14#include <linux/module.h>
15
16#define NAT_VALID_HOOKS ((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT) | \
17			 (1 << NF_BR_POST_ROUTING))
18
19static struct ebt_entries initial_chains[] = {
20	{
21		.name	= "PREROUTING",
22		.policy	= EBT_ACCEPT,
23	},
24	{
25		.name	= "OUTPUT",
26		.policy	= EBT_ACCEPT,
27	},
28	{
29		.name	= "POSTROUTING",
30		.policy	= EBT_ACCEPT,
31	}
32};
33
34static struct ebt_replace_kernel initial_table = {
35	.name		= "nat",
36	.valid_hooks	= NAT_VALID_HOOKS,
37	.entries_size	= 3 * sizeof(struct ebt_entries),
38	.hook_entry	= {
39		[NF_BR_PRE_ROUTING]	= &initial_chains[0],
40		[NF_BR_LOCAL_OUT]	= &initial_chains[1],
41		[NF_BR_POST_ROUTING]	= &initial_chains[2],
42	},
43	.entries	= (char *)initial_chains,
44};
45
46static const struct ebt_table frame_nat = {
47	.name		= "nat",
48	.table		= &initial_table,
49	.valid_hooks	= NAT_VALID_HOOKS,
50	.me		= THIS_MODULE,
51};
52
53static const struct nf_hook_ops ebt_ops_nat[] = {
54	{
55		.hook		= ebt_do_table,
56		.pf		= NFPROTO_BRIDGE,
57		.hooknum	= NF_BR_LOCAL_OUT,
58		.priority	= NF_BR_PRI_NAT_DST_OTHER,
59	},
60	{
61		.hook		= ebt_do_table,
62		.pf		= NFPROTO_BRIDGE,
63		.hooknum	= NF_BR_POST_ROUTING,
64		.priority	= NF_BR_PRI_NAT_SRC,
65	},
66	{
67		.hook		= ebt_do_table,
68		.pf		= NFPROTO_BRIDGE,
69		.hooknum	= NF_BR_PRE_ROUTING,
70		.priority	= NF_BR_PRI_NAT_DST_BRIDGED,
71	},
72};
73
74static int frame_nat_table_init(struct net *net)
75{
76	return ebt_register_table(net, &frame_nat, ebt_ops_nat);
77}
78
79static void __net_exit frame_nat_net_pre_exit(struct net *net)
80{
81	ebt_unregister_table_pre_exit(net, "nat");
82}
83
84static void __net_exit frame_nat_net_exit(struct net *net)
85{
86	ebt_unregister_table(net, "nat");
87}
88
89static struct pernet_operations frame_nat_net_ops = {
90	.exit = frame_nat_net_exit,
91	.pre_exit = frame_nat_net_pre_exit,
92};
93
94static int __init ebtable_nat_init(void)
95{
96	int ret = ebt_register_template(&frame_nat, frame_nat_table_init);
97
98	if (ret)
99		return ret;
100
101	ret = register_pernet_subsys(&frame_nat_net_ops);
102	if (ret) {
103		ebt_unregister_template(&frame_nat);
104		return ret;
105	}
106
107	return ret;
108}
109
110static void __exit ebtable_nat_fini(void)
111{
112	unregister_pernet_subsys(&frame_nat_net_ops);
113	ebt_unregister_template(&frame_nat);
114}
115
116module_init(ebtable_nat_init);
117module_exit(ebtable_nat_fini);
118MODULE_LICENSE("GPL");
119MODULE_DESCRIPTION("ebtables legacy stateless nat table");
120