11/*
22 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
33 * Copyright (c) 2012 Pablo Neira Ayuso <pablo@netfilter.org>
4+ * Copyright (c) 2012 Intel Corporation
45 *
56 * This program is free software; you can redistribute it and/or modify
67 * it under the terms of the GNU General Public License version 2 as
1415#include <linux/list.h>
1516#include <linux/skbuff.h>
1617#include <linux/ip.h>
17- #include <linux/netlink.h>
1818#include <linux/netfilter.h>
1919#include <linux/netfilter_ipv4.h>
20- #include <linux/netfilter/nfnetlink.h>
2120#include <linux/netfilter/nf_tables.h>
2221#include <net/netfilter/nf_conntrack.h>
2322#include <net/netfilter/nf_nat.h>
2726#include <net/netfilter/nf_nat_l3proto.h>
2827#include <net/ip.h>
2928
30- struct nft_nat {
31- enum nft_registers sreg_addr_min :8 ;
32- enum nft_registers sreg_addr_max :8 ;
33- enum nft_registers sreg_proto_min :8 ;
34- enum nft_registers sreg_proto_max :8 ;
35- enum nf_nat_manip_type type ;
36- };
37-
38- static void nft_nat_eval (const struct nft_expr * expr ,
39- struct nft_data data [NFT_REG_MAX + 1 ],
40- const struct nft_pktinfo * pkt )
41- {
42- const struct nft_nat * priv = nft_expr_priv (expr );
43- enum ip_conntrack_info ctinfo ;
44- struct nf_conn * ct = nf_ct_get (pkt -> skb , & ctinfo );
45- struct nf_nat_range range ;
46-
47- memset (& range , 0 , sizeof (range ));
48- if (priv -> sreg_addr_min ) {
49- range .min_addr .ip = data [priv -> sreg_addr_min ].data [0 ];
50- range .max_addr .ip = data [priv -> sreg_addr_max ].data [0 ];
51- range .flags |= NF_NAT_RANGE_MAP_IPS ;
52- }
53-
54- if (priv -> sreg_proto_min ) {
55- range .min_proto .all = data [priv -> sreg_proto_min ].data [0 ];
56- range .max_proto .all = data [priv -> sreg_proto_max ].data [0 ];
57- range .flags |= NF_NAT_RANGE_PROTO_SPECIFIED ;
58- }
59-
60- data [NFT_REG_VERDICT ].verdict =
61- nf_nat_setup_info (ct , & range , priv -> type );
62- }
63-
64- static const struct nla_policy nft_nat_policy [NFTA_NAT_MAX + 1 ] = {
65- [NFTA_NAT_ADDR_MIN ] = { .type = NLA_U32 },
66- [NFTA_NAT_ADDR_MAX ] = { .type = NLA_U32 },
67- [NFTA_NAT_PROTO_MIN ] = { .type = NLA_U32 },
68- [NFTA_NAT_PROTO_MAX ] = { .type = NLA_U32 },
69- [NFTA_NAT_TYPE ] = { .type = NLA_U32 },
70- };
71-
72- static int nft_nat_init (const struct nft_ctx * ctx , const struct nft_expr * expr ,
73- const struct nlattr * const tb [])
74- {
75- struct nft_nat * priv = nft_expr_priv (expr );
76- int err ;
77-
78- if (tb [NFTA_NAT_TYPE ] == NULL )
79- return - EINVAL ;
80-
81- switch (ntohl (nla_get_be32 (tb [NFTA_NAT_TYPE ]))) {
82- case NFT_NAT_SNAT :
83- priv -> type = NF_NAT_MANIP_SRC ;
84- break ;
85- case NFT_NAT_DNAT :
86- priv -> type = NF_NAT_MANIP_DST ;
87- break ;
88- default :
89- return - EINVAL ;
90- }
91-
92- if (tb [NFTA_NAT_ADDR_MIN ]) {
93- priv -> sreg_addr_min = ntohl (nla_get_be32 (tb [NFTA_NAT_ADDR_MIN ]));
94- err = nft_validate_input_register (priv -> sreg_addr_min );
95- if (err < 0 )
96- return err ;
97- }
98-
99- if (tb [NFTA_NAT_ADDR_MAX ]) {
100- priv -> sreg_addr_max = ntohl (nla_get_be32 (tb [NFTA_NAT_ADDR_MAX ]));
101- err = nft_validate_input_register (priv -> sreg_addr_max );
102- if (err < 0 )
103- return err ;
104- } else
105- priv -> sreg_addr_max = priv -> sreg_addr_min ;
106-
107- if (tb [NFTA_NAT_PROTO_MIN ]) {
108- priv -> sreg_proto_min = ntohl (nla_get_be32 (tb [NFTA_NAT_PROTO_MIN ]));
109- err = nft_validate_input_register (priv -> sreg_proto_min );
110- if (err < 0 )
111- return err ;
112- }
113-
114- if (tb [NFTA_NAT_PROTO_MAX ]) {
115- priv -> sreg_proto_max = ntohl (nla_get_be32 (tb [NFTA_NAT_PROTO_MAX ]));
116- err = nft_validate_input_register (priv -> sreg_proto_max );
117- if (err < 0 )
118- return err ;
119- } else
120- priv -> sreg_proto_max = priv -> sreg_proto_min ;
121-
122- return 0 ;
123- }
124-
125- static int nft_nat_dump (struct sk_buff * skb , const struct nft_expr * expr )
126- {
127- const struct nft_nat * priv = nft_expr_priv (expr );
128-
129- switch (priv -> type ) {
130- case NF_NAT_MANIP_SRC :
131- if (nla_put_be32 (skb , NFTA_NAT_TYPE , htonl (NFT_NAT_SNAT )))
132- goto nla_put_failure ;
133- break ;
134- case NF_NAT_MANIP_DST :
135- if (nla_put_be32 (skb , NFTA_NAT_TYPE , htonl (NFT_NAT_DNAT )))
136- goto nla_put_failure ;
137- break ;
138- }
139-
140- if (nla_put_be32 (skb , NFTA_NAT_ADDR_MIN , htonl (priv -> sreg_addr_min )))
141- goto nla_put_failure ;
142- if (nla_put_be32 (skb , NFTA_NAT_ADDR_MAX , htonl (priv -> sreg_addr_max )))
143- goto nla_put_failure ;
144- if (nla_put_be32 (skb , NFTA_NAT_PROTO_MIN , htonl (priv -> sreg_proto_min )))
145- goto nla_put_failure ;
146- if (nla_put_be32 (skb , NFTA_NAT_PROTO_MAX , htonl (priv -> sreg_proto_max )))
147- goto nla_put_failure ;
148- return 0 ;
149-
150- nla_put_failure :
151- return -1 ;
152- }
153-
154- static struct nft_expr_type nft_nat_type ;
155- static const struct nft_expr_ops nft_nat_ops = {
156- .type = & nft_nat_type ,
157- .size = NFT_EXPR_SIZE (sizeof (struct nft_nat )),
158- .eval = nft_nat_eval ,
159- .init = nft_nat_init ,
160- .dump = nft_nat_dump ,
161- };
162-
163- static struct nft_expr_type nft_nat_type __read_mostly = {
164- .name = "nat" ,
165- .ops = & nft_nat_ops ,
166- .policy = nft_nat_policy ,
167- .maxattr = NFTA_NAT_MAX ,
168- .owner = THIS_MODULE ,
169- };
170-
17129/*
17230 * NAT chains
17331 */
@@ -306,7 +164,7 @@ static unsigned int nf_nat_output(const struct nf_hook_ops *ops,
306164 return ret ;
307165}
308166
309- struct nf_chain_type nft_chain_nat_ipv4 = {
167+ static struct nf_chain_type nft_chain_nat_ipv4 = {
310168 .family = NFPROTO_IPV4 ,
311169 .name = "nat" ,
312170 .type = NFT_CHAIN_T_NAT ,
@@ -331,20 +189,11 @@ static int __init nft_chain_nat_init(void)
331189 if (err < 0 )
332190 return err ;
333191
334- err = nft_register_expr (& nft_nat_type );
335- if (err < 0 )
336- goto err ;
337-
338192 return 0 ;
339-
340- err :
341- nft_unregister_chain_type (& nft_chain_nat_ipv4 );
342- return err ;
343193}
344194
345195static void __exit nft_chain_nat_exit (void )
346196{
347- nft_unregister_expr (& nft_nat_type );
348197 nft_unregister_chain_type (& nft_chain_nat_ipv4 );
349198}
350199
@@ -354,4 +203,3 @@ module_exit(nft_chain_nat_exit);
354203MODULE_LICENSE ("GPL" );
355204MODULE_AUTHOR ("Patrick McHardy <kaber@trash.net>" );
356205MODULE_ALIAS_NFT_CHAIN (AF_INET , "nat" );
357- MODULE_ALIAS_NFT_EXPR ("nat" );
0 commit comments