linux-stable/net/netfilter/nft_chain_nat.c
Florian Westphal db8ab38880 netfilter: nf_tables: merge ipv4 and ipv6 nat chain types
Merge the ipv4 and ipv6 nat chain type. This is the last
missing piece which allows to provide inet family support
for nat in a follow patch.

The kconfig knobs for ipv4/ipv6 nat chain are removed, the
nat chain type will be built unconditionally if NFT_NAT
expression is enabled.

Before:
   text	   data	    bss	    dec	    hex	filename
   1576     896       0    2472     9a8 nft_chain_nat_ipv4.ko
   1697     896       0    2593     a21 nft_chain_nat_ipv6.ko

After:
   text	   data	    bss	    dec	    hex	filename
   1832     896       0    2728     aa8 nft_chain_nat.ko

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2019-03-01 14:36:59 +01:00

108 lines
2.6 KiB
C

// 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, skb);
break;
#endif
#ifdef CONFIG_NF_TABLES_IPV6
case NFPROTO_IPV6:
nft_set_pktinfo_ipv6(&pkt, skb);
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
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
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
}
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