nft_chain_nat.c (3717B)
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 10static 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 36static 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 57static 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 78static 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 83static 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 88static 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 108static 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 123static 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 136module_init(nft_chain_nat_init); 137module_exit(nft_chain_nat_exit); 138 139MODULE_LICENSE("GPL"); 140#ifdef CONFIG_NF_TABLES_IPV4 141MODULE_ALIAS_NFT_CHAIN(AF_INET, "nat"); 142#endif 143#ifdef CONFIG_NF_TABLES_IPV6 144MODULE_ALIAS_NFT_CHAIN(AF_INET6, "nat"); 145#endif 146#ifdef CONFIG_NF_TABLES_INET 147MODULE_ALIAS_NFT_CHAIN(1, "nat"); /* NFPROTO_INET */ 148#endif