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: 20 nft_set_pktinfo_ipv4(&pkt); 21 break; 22 #endif 23 #ifdef CONFIG_NF_TABLES_IPV6 24 case NFPROTO_IPV6: 25 nft_set_pktinfo_ipv6(&pkt); 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 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 #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 146 #ifdef CONFIG_NF_TABLES_INET 147 MODULE_ALIAS_NFT_CHAIN(1, "nat"); /* NFPROTO_INET */ 148 #endif 149