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