Commit | Line | Data |
---|---|---|
db8ab388 FW |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | ||
3 | #include <linux/module.h> | |
4 | #include <linux/netfilter/nf_tables.h> | |
5 | #include <net/netfilter/nf_nat.h> | |
6 | #include <net/netfilter/nf_tables.h> | |
7 | #include <net/netfilter/nf_tables_ipv4.h> | |
8 | #include <net/netfilter/nf_tables_ipv6.h> | |
9 | ||
10 | static unsigned int nft_nat_do_chain(void *priv, struct sk_buff *skb, | |
11 | const struct nf_hook_state *state) | |
12 | { | |
13 | struct nft_pktinfo pkt; | |
14 | ||
15 | nft_set_pktinfo(&pkt, skb, state); | |
16 | ||
17 | switch (state->pf) { | |
18 | #ifdef CONFIG_NF_TABLES_IPV4 | |
19 | case NFPROTO_IPV4: | |
f06ad944 | 20 | nft_set_pktinfo_ipv4(&pkt); |
db8ab388 FW |
21 | break; |
22 | #endif | |
23 | #ifdef CONFIG_NF_TABLES_IPV6 | |
24 | case NFPROTO_IPV6: | |
f06ad944 | 25 | nft_set_pktinfo_ipv6(&pkt); |
db8ab388 FW |
26 | break; |
27 | #endif | |
28 | default: | |
29 | break; | |
30 | } | |
31 | ||
32 | return nft_do_chain(&pkt, priv); | |
33 | } | |
34 | ||
35 | #ifdef CONFIG_NF_TABLES_IPV4 | |
36 | static const struct nft_chain_type nft_chain_nat_ipv4 = { | |
37 | .name = "nat", | |
38 | .type = NFT_CHAIN_T_NAT, | |
39 | .family = NFPROTO_IPV4, | |
40 | .owner = THIS_MODULE, | |
41 | .hook_mask = (1 << NF_INET_PRE_ROUTING) | | |
42 | (1 << NF_INET_POST_ROUTING) | | |
43 | (1 << NF_INET_LOCAL_OUT) | | |
44 | (1 << NF_INET_LOCAL_IN), | |
45 | .hooks = { | |
46 | [NF_INET_PRE_ROUTING] = nft_nat_do_chain, | |
47 | [NF_INET_POST_ROUTING] = nft_nat_do_chain, | |
48 | [NF_INET_LOCAL_OUT] = nft_nat_do_chain, | |
49 | [NF_INET_LOCAL_IN] = nft_nat_do_chain, | |
50 | }, | |
51 | .ops_register = nf_nat_ipv4_register_fn, | |
52 | .ops_unregister = nf_nat_ipv4_unregister_fn, | |
53 | }; | |
54 | #endif | |
55 | ||
56 | #ifdef CONFIG_NF_TABLES_IPV6 | |
57 | static const struct nft_chain_type nft_chain_nat_ipv6 = { | |
58 | .name = "nat", | |
59 | .type = NFT_CHAIN_T_NAT, | |
60 | .family = NFPROTO_IPV6, | |
61 | .owner = THIS_MODULE, | |
62 | .hook_mask = (1 << NF_INET_PRE_ROUTING) | | |
63 | (1 << NF_INET_POST_ROUTING) | | |
64 | (1 << NF_INET_LOCAL_OUT) | | |
65 | (1 << NF_INET_LOCAL_IN), | |
66 | .hooks = { | |
67 | [NF_INET_PRE_ROUTING] = nft_nat_do_chain, | |
68 | [NF_INET_POST_ROUTING] = nft_nat_do_chain, | |
69 | [NF_INET_LOCAL_OUT] = nft_nat_do_chain, | |
70 | [NF_INET_LOCAL_IN] = nft_nat_do_chain, | |
71 | }, | |
72 | .ops_register = nf_nat_ipv6_register_fn, | |
73 | .ops_unregister = nf_nat_ipv6_unregister_fn, | |
74 | }; | |
75 | #endif | |
76 | ||
d164385e FW |
77 | #ifdef CONFIG_NF_TABLES_INET |
78 | static int nft_nat_inet_reg(struct net *net, const struct nf_hook_ops *ops) | |
79 | { | |
80 | return nf_nat_inet_register_fn(net, ops); | |
81 | } | |
82 | ||
83 | static void nft_nat_inet_unreg(struct net *net, const struct nf_hook_ops *ops) | |
84 | { | |
85 | nf_nat_inet_unregister_fn(net, ops); | |
86 | } | |
87 | ||
88 | static const struct nft_chain_type nft_chain_nat_inet = { | |
89 | .name = "nat", | |
90 | .type = NFT_CHAIN_T_NAT, | |
91 | .family = NFPROTO_INET, | |
6a42cefb | 92 | .owner = THIS_MODULE, |
d164385e FW |
93 | .hook_mask = (1 << NF_INET_PRE_ROUTING) | |
94 | (1 << NF_INET_LOCAL_IN) | | |
95 | (1 << NF_INET_LOCAL_OUT) | | |
96 | (1 << NF_INET_POST_ROUTING), | |
97 | .hooks = { | |
98 | [NF_INET_PRE_ROUTING] = nft_nat_do_chain, | |
99 | [NF_INET_LOCAL_IN] = nft_nat_do_chain, | |
100 | [NF_INET_LOCAL_OUT] = nft_nat_do_chain, | |
101 | [NF_INET_POST_ROUTING] = nft_nat_do_chain, | |
102 | }, | |
103 | .ops_register = nft_nat_inet_reg, | |
104 | .ops_unregister = nft_nat_inet_unreg, | |
105 | }; | |
106 | #endif | |
107 | ||
db8ab388 FW |
108 | static int __init nft_chain_nat_init(void) |
109 | { | |
110 | #ifdef CONFIG_NF_TABLES_IPV6 | |
111 | nft_register_chain_type(&nft_chain_nat_ipv6); | |
112 | #endif | |
113 | #ifdef CONFIG_NF_TABLES_IPV4 | |
114 | nft_register_chain_type(&nft_chain_nat_ipv4); | |
115 | #endif | |
d164385e FW |
116 | #ifdef CONFIG_NF_TABLES_INET |
117 | nft_register_chain_type(&nft_chain_nat_inet); | |
118 | #endif | |
db8ab388 FW |
119 | |
120 | return 0; | |
121 | } | |
122 | ||
123 | static void __exit nft_chain_nat_exit(void) | |
124 | { | |
125 | #ifdef CONFIG_NF_TABLES_IPV4 | |
126 | nft_unregister_chain_type(&nft_chain_nat_ipv4); | |
127 | #endif | |
128 | #ifdef CONFIG_NF_TABLES_IPV6 | |
129 | nft_unregister_chain_type(&nft_chain_nat_ipv6); | |
130 | #endif | |
d164385e FW |
131 | #ifdef CONFIG_NF_TABLES_INET |
132 | nft_unregister_chain_type(&nft_chain_nat_inet); | |
133 | #endif | |
db8ab388 FW |
134 | } |
135 | ||
136 | module_init(nft_chain_nat_init); | |
137 | module_exit(nft_chain_nat_exit); | |
138 | ||
139 | MODULE_LICENSE("GPL"); | |
140 | #ifdef CONFIG_NF_TABLES_IPV4 | |
141 | MODULE_ALIAS_NFT_CHAIN(AF_INET, "nat"); | |
142 | #endif | |
143 | #ifdef CONFIG_NF_TABLES_IPV6 | |
144 | MODULE_ALIAS_NFT_CHAIN(AF_INET6, "nat"); | |
145 | #endif | |
b4f1483c PS |
146 | #ifdef CONFIG_NF_TABLES_INET |
147 | MODULE_ALIAS_NFT_CHAIN(1, "nat"); /* NFPROTO_INET */ | |
148 | #endif |