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: &pkt, skb, state); |
16 | |
17 | switch (state->pf) { |
18 | #ifdef CONFIG_NF_TABLES_IPV4 |
19 | case NFPROTO_IPV4: |
20 | nft_set_pktinfo_ipv4(pkt: &pkt); |
21 | break; |
22 | #endif |
23 | #ifdef CONFIG_NF_TABLES_IPV6 |
24 | case NFPROTO_IPV6: |
25 | nft_set_pktinfo_ipv6(pkt: &pkt); |
26 | break; |
27 | #endif |
28 | default: |
29 | break; |
30 | } |
31 | |
32 | return nft_do_chain(pkt: &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 | |
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, |
92 | .owner = THIS_MODULE, |
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 | |
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 |
116 | #ifdef CONFIG_NF_TABLES_INET |
117 | nft_register_chain_type(&nft_chain_nat_inet); |
118 | #endif |
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 |
131 | #ifdef CONFIG_NF_TABLES_INET |
132 | nft_unregister_chain_type(&nft_chain_nat_inet); |
133 | #endif |
134 | } |
135 | |
136 | module_init(nft_chain_nat_init); |
137 | module_exit(nft_chain_nat_exit); |
138 | |
139 | MODULE_LICENSE("GPL" ); |
140 | MODULE_DESCRIPTION("nftables network address translation support" ); |
141 | #ifdef CONFIG_NF_TABLES_IPV4 |
142 | MODULE_ALIAS_NFT_CHAIN(AF_INET, "nat" ); |
143 | #endif |
144 | #ifdef CONFIG_NF_TABLES_IPV6 |
145 | MODULE_ALIAS_NFT_CHAIN(AF_INET6, "nat" ); |
146 | #endif |
147 | #ifdef CONFIG_NF_TABLES_INET |
148 | MODULE_ALIAS_NFT_CHAIN(1, "nat" ); /* NFPROTO_INET */ |
149 | #endif |
150 | |