Skip to content

Commit 5b1158e

Browse files
Jozsef Kadlecsikdavem330
authored andcommitted
[NETFILTER]: Add NAT support for nf_conntrack
Add NAT support for nf_conntrack. Joint work of Jozsef Kadlecsik, Yasuyuki Kozakai, Martin Josefsson and myself. Signed-off-by: Jozsef Kadlecsik <[email protected]> Signed-off-by: Patrick McHardy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d2483dd commit 5b1158e

29 files changed

+2667
-59
lines changed

include/linux/netfilter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
357357
static inline void
358358
nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family)
359359
{
360-
#ifdef CONFIG_IP_NF_NAT_NEEDED
360+
#if defined(CONFIG_IP_NF_NAT_NEEDED) || defined(CONFIG_NF_NAT_NEEDED)
361361
void (*decodefn)(struct sk_buff *, struct flowi *);
362362

363363
if (family == AF_INET && (decodefn = ip_nat_decode_session) != NULL)

include/net/netfilter/ipv4/nf_conntrack_ipv4.h

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,23 @@
99
#ifndef _NF_CONNTRACK_IPV4_H
1010
#define _NF_CONNTRACK_IPV4_H
1111

12-
#ifdef CONFIG_IP_NF_NAT_NEEDED
13-
#include <linux/netfilter_ipv4/ip_nat.h>
12+
#ifdef CONFIG_NF_NAT_NEEDED
13+
#include <net/netfilter/nf_nat.h>
1414

1515
/* per conntrack: nat application helper private data */
16-
union ip_conntrack_nat_help {
16+
union nf_conntrack_nat_help {
1717
/* insert nat helper private data here */
1818
};
1919

20-
struct nf_conntrack_ipv4_nat {
21-
struct ip_nat_info info;
22-
union ip_conntrack_nat_help help;
20+
struct nf_conn_nat {
21+
struct nf_nat_info info;
22+
union nf_conntrack_nat_help help;
2323
#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
2424
defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
2525
int masq_index;
2626
#endif
2727
};
28-
#endif /* CONFIG_IP_NF_NAT_NEEDED */
29-
30-
struct nf_conntrack_ipv4 {
31-
#ifdef CONFIG_IP_NF_NAT_NEEDED
32-
struct nf_conntrack_ipv4_nat *nat;
33-
#endif
34-
};
28+
#endif /* CONFIG_NF_NAT_NEEDED */
3529

3630
/* Returns new sk_buff, or NULL */
3731
struct sk_buff *

include/net/netfilter/nf_conntrack.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,18 +264,45 @@ nf_conntrack_unregister_cache(u_int32_t features);
264264

265265
/* valid combinations:
266266
* basic: nf_conn, nf_conn .. nf_conn_help
267-
* nat: nf_conn .. nf_conn_nat, nf_conn .. nf_conn_nat, nf_conn help
267+
* nat: nf_conn .. nf_conn_nat, nf_conn .. nf_conn_nat .. nf_conn help
268268
*/
269+
#ifdef CONFIG_NF_NAT_NEEDED
270+
static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct)
271+
{
272+
unsigned int offset = sizeof(struct nf_conn);
273+
274+
if (!(ct->features & NF_CT_F_NAT))
275+
return NULL;
276+
277+
offset = ALIGN(offset, __alignof__(struct nf_conn_nat));
278+
return (struct nf_conn_nat *) ((void *)ct + offset);
279+
}
280+
269281
static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
270282
{
271283
unsigned int offset = sizeof(struct nf_conn);
272284

273285
if (!(ct->features & NF_CT_F_HELP))
274286
return NULL;
287+
if (ct->features & NF_CT_F_NAT) {
288+
offset = ALIGN(offset, __alignof__(struct nf_conn_nat));
289+
offset += sizeof(struct nf_conn_nat);
290+
}
275291

276292
offset = ALIGN(offset, __alignof__(struct nf_conn_help));
277293
return (struct nf_conn_help *) ((void *)ct + offset);
278294
}
295+
#else /* No NAT */
296+
static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
297+
{
298+
unsigned int offset = sizeof(struct nf_conn);
299+
300+
if (!(ct->features & NF_CT_F_HELP))
301+
return NULL;
279302

303+
offset = ALIGN(offset, __alignof__(struct nf_conn_help));
304+
return (struct nf_conn_help *) ((void *)ct + offset);
305+
}
306+
#endif /* CONFIG_NF_NAT_NEEDED */
280307
#endif /* __KERNEL__ */
281308
#endif /* _NF_CONNTRACK_H */

include/net/netfilter/nf_conntrack_expect.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct nf_conntrack_expect
4343
#ifdef CONFIG_NF_NAT_NEEDED
4444
/* This is the original per-proto part, used to map the
4545
* expected connection the way the recipient expects. */
46-
union nf_conntrack_manip_proto saved_proto;
46+
union nf_conntrack_man_proto saved_proto;
4747
/* Direction relative to the master connection. */
4848
enum ip_conntrack_dir dir;
4949
#endif

include/net/netfilter/nf_nat.h

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#ifndef _NF_NAT_H
2+
#define _NF_NAT_H
3+
#include <linux/netfilter_ipv4.h>
4+
#include <net/netfilter/nf_conntrack_tuple.h>
5+
6+
#define NF_NAT_MAPPING_TYPE_MAX_NAMELEN 16
7+
8+
enum nf_nat_manip_type
9+
{
10+
IP_NAT_MANIP_SRC,
11+
IP_NAT_MANIP_DST
12+
};
13+
14+
/* SRC manip occurs POST_ROUTING or LOCAL_IN */
15+
#define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING && (hooknum) != NF_IP_LOCAL_IN)
16+
17+
#define IP_NAT_RANGE_MAP_IPS 1
18+
#define IP_NAT_RANGE_PROTO_SPECIFIED 2
19+
20+
/* NAT sequence number modifications */
21+
struct nf_nat_seq {
22+
/* position of the last TCP sequence number modification (if any) */
23+
u_int32_t correction_pos;
24+
25+
/* sequence number offset before and after last modification */
26+
int16_t offset_before, offset_after;
27+
};
28+
29+
/* Single range specification. */
30+
struct nf_nat_range
31+
{
32+
/* Set to OR of flags above. */
33+
unsigned int flags;
34+
35+
/* Inclusive: network order. */
36+
__be32 min_ip, max_ip;
37+
38+
/* Inclusive: network order */
39+
union nf_conntrack_man_proto min, max;
40+
};
41+
42+
/* For backwards compat: don't use in modern code. */
43+
struct nf_nat_multi_range_compat
44+
{
45+
unsigned int rangesize; /* Must be 1. */
46+
47+
/* hangs off end. */
48+
struct nf_nat_range range[1];
49+
};
50+
51+
#ifdef __KERNEL__
52+
#include <linux/list.h>
53+
54+
/* The structure embedded in the conntrack structure. */
55+
struct nf_nat_info
56+
{
57+
struct list_head bysource;
58+
struct nf_nat_seq seq[IP_CT_DIR_MAX];
59+
};
60+
61+
struct nf_conn;
62+
63+
/* Set up the info structure to map into this range. */
64+
extern unsigned int nf_nat_setup_info(struct nf_conn *ct,
65+
const struct nf_nat_range *range,
66+
unsigned int hooknum);
67+
68+
/* Is this tuple already taken? (not by us)*/
69+
extern int nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple,
70+
const struct nf_conn *ignored_conntrack);
71+
72+
extern int nf_nat_module_is_loaded;
73+
74+
#else /* !__KERNEL__: iptables wants this to compile. */
75+
#define nf_nat_multi_range nf_nat_multi_range_compat
76+
#endif /*__KERNEL__*/
77+
#endif
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#ifndef _NF_NAT_CORE_H
2+
#define _NF_NAT_CORE_H
3+
#include <linux/list.h>
4+
#include <net/netfilter/nf_conntrack.h>
5+
6+
/* This header used to share core functionality between the standalone
7+
NAT module, and the compatibility layer's use of NAT for masquerading. */
8+
9+
extern unsigned int nf_nat_packet(struct nf_conn *ct,
10+
enum ip_conntrack_info ctinfo,
11+
unsigned int hooknum,
12+
struct sk_buff **pskb);
13+
14+
extern int nf_nat_icmp_reply_translation(struct nf_conn *ct,
15+
enum ip_conntrack_info ctinfo,
16+
unsigned int hooknum,
17+
struct sk_buff **pskb);
18+
19+
static inline int nf_nat_initialized(struct nf_conn *ct,
20+
enum nf_nat_manip_type manip)
21+
{
22+
if (manip == IP_NAT_MANIP_SRC)
23+
return test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status);
24+
else
25+
return test_bit(IPS_DST_NAT_DONE_BIT, &ct->status);
26+
}
27+
#endif /* _NF_NAT_CORE_H */
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#ifndef _NF_NAT_HELPER_H
2+
#define _NF_NAT_HELPER_H
3+
/* NAT protocol helper routines. */
4+
5+
#include <net/netfilter/nf_conntrack.h>
6+
7+
struct sk_buff;
8+
9+
/* These return true or false. */
10+
extern int nf_nat_mangle_tcp_packet(struct sk_buff **skb,
11+
struct nf_conn *ct,
12+
enum ip_conntrack_info ctinfo,
13+
unsigned int match_offset,
14+
unsigned int match_len,
15+
const char *rep_buffer,
16+
unsigned int rep_len);
17+
extern int nf_nat_mangle_udp_packet(struct sk_buff **skb,
18+
struct nf_conn *ct,
19+
enum ip_conntrack_info ctinfo,
20+
unsigned int match_offset,
21+
unsigned int match_len,
22+
const char *rep_buffer,
23+
unsigned int rep_len);
24+
extern int nf_nat_seq_adjust(struct sk_buff **pskb,
25+
struct nf_conn *ct,
26+
enum ip_conntrack_info ctinfo);
27+
28+
/* Setup NAT on this expected conntrack so it follows master, but goes
29+
* to port ct->master->saved_proto. */
30+
extern void nf_nat_follow_master(struct nf_conn *ct,
31+
struct nf_conntrack_expect *this);
32+
#endif
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* Header for use in defining a given protocol. */
2+
#ifndef _NF_NAT_PROTOCOL_H
3+
#define _NF_NAT_PROTOCOL_H
4+
#include <net/netfilter/nf_nat.h>
5+
#include <linux/netfilter/nfnetlink_conntrack.h>
6+
7+
struct nf_nat_range;
8+
9+
struct nf_nat_protocol
10+
{
11+
/* Protocol name */
12+
const char *name;
13+
14+
/* Protocol number. */
15+
unsigned int protonum;
16+
17+
struct module *me;
18+
19+
/* Translate a packet to the target according to manip type.
20+
Return true if succeeded. */
21+
int (*manip_pkt)(struct sk_buff **pskb,
22+
unsigned int iphdroff,
23+
const struct nf_conntrack_tuple *tuple,
24+
enum nf_nat_manip_type maniptype);
25+
26+
/* Is the manipable part of the tuple between min and max incl? */
27+
int (*in_range)(const struct nf_conntrack_tuple *tuple,
28+
enum nf_nat_manip_type maniptype,
29+
const union nf_conntrack_man_proto *min,
30+
const union nf_conntrack_man_proto *max);
31+
32+
/* Alter the per-proto part of the tuple (depending on
33+
maniptype), to give a unique tuple in the given range if
34+
possible; return false if not. Per-protocol part of tuple
35+
is initialized to the incoming packet. */
36+
int (*unique_tuple)(struct nf_conntrack_tuple *tuple,
37+
const struct nf_nat_range *range,
38+
enum nf_nat_manip_type maniptype,
39+
const struct nf_conn *ct);
40+
41+
int (*range_to_nfattr)(struct sk_buff *skb,
42+
const struct nf_nat_range *range);
43+
44+
int (*nfattr_to_range)(struct nfattr *tb[],
45+
struct nf_nat_range *range);
46+
};
47+
48+
/* Protocol registration. */
49+
extern int nf_nat_protocol_register(struct nf_nat_protocol *proto);
50+
extern void nf_nat_protocol_unregister(struct nf_nat_protocol *proto);
51+
52+
extern struct nf_nat_protocol *nf_nat_proto_find_get(u_int8_t protocol);
53+
extern void nf_nat_proto_put(struct nf_nat_protocol *proto);
54+
55+
/* Built-in protocols. */
56+
extern struct nf_nat_protocol nf_nat_protocol_tcp;
57+
extern struct nf_nat_protocol nf_nat_protocol_udp;
58+
extern struct nf_nat_protocol nf_nat_protocol_icmp;
59+
extern struct nf_nat_protocol nf_nat_unknown_protocol;
60+
61+
extern int init_protocols(void) __init;
62+
extern void cleanup_protocols(void);
63+
extern struct nf_nat_protocol *find_nat_proto(u_int16_t protonum);
64+
65+
extern int nf_nat_port_range_to_nfattr(struct sk_buff *skb,
66+
const struct nf_nat_range *range);
67+
extern int nf_nat_port_nfattr_to_range(struct nfattr *tb[],
68+
struct nf_nat_range *range);
69+
70+
#endif /*_NF_NAT_PROTO_H*/
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#ifndef _NF_NAT_RULE_H
2+
#define _NF_NAT_RULE_H
3+
#include <net/netfilter/nf_conntrack.h>
4+
#include <net/netfilter/nf_nat.h>
5+
#include <linux/netfilter_ipv4/ip_tables.h>
6+
7+
/* Compatibility definitions for ipt_FOO modules */
8+
#define ip_nat_range nf_nat_range
9+
#define ip_conntrack_tuple nf_conntrack_tuple
10+
#define ip_conntrack_get nf_ct_get
11+
#define ip_conntrack nf_conn
12+
#define ip_nat_setup_info nf_nat_setup_info
13+
#define ip_nat_multi_range_compat nf_nat_multi_range_compat
14+
#define ip_ct_iterate_cleanup nf_ct_iterate_cleanup
15+
#define IP_NF_ASSERT NF_CT_ASSERT
16+
17+
extern int nf_nat_rule_init(void) __init;
18+
extern void nf_nat_rule_cleanup(void);
19+
extern int nf_nat_rule_find(struct sk_buff **pskb,
20+
unsigned int hooknum,
21+
const struct net_device *in,
22+
const struct net_device *out,
23+
struct nf_conn *ct,
24+
struct nf_nat_info *info);
25+
26+
extern unsigned int
27+
alloc_null_binding(struct nf_conn *ct,
28+
struct nf_nat_info *info,
29+
unsigned int hooknum);
30+
31+
extern unsigned int
32+
alloc_null_binding_confirmed(struct nf_conn *ct,
33+
struct nf_nat_info *info,
34+
unsigned int hooknum);
35+
#endif /* _NF_NAT_RULE_H */

0 commit comments

Comments
 (0)