diff options
author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2006-12-03 01:07:13 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-12-03 01:07:13 -0500 |
commit | 5b1158e909ecbe1a052203e0d8df15633f829930 (patch) | |
tree | 1d29320fd6184b982b1a8a83e7e1e9f25537d3ff /include/net | |
parent | d2483ddefd38b06053cdce7206382ca61f6282b1 (diff) |
[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 <kadlec@blackhole.kfki.hu>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/netfilter/ipv4/nf_conntrack_ipv4.h | 20 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack.h | 29 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack_expect.h | 2 | ||||
-rw-r--r-- | include/net/netfilter/nf_nat.h | 77 | ||||
-rw-r--r-- | include/net/netfilter/nf_nat_core.h | 27 | ||||
-rw-r--r-- | include/net/netfilter/nf_nat_helper.h | 32 | ||||
-rw-r--r-- | include/net/netfilter/nf_nat_protocol.h | 70 | ||||
-rw-r--r-- | include/net/netfilter/nf_nat_rule.h | 35 |
8 files changed, 277 insertions, 15 deletions
diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h index 34b453a81a63..a1c57ee0a4fa 100644 --- a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h +++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h | |||
@@ -9,29 +9,23 @@ | |||
9 | #ifndef _NF_CONNTRACK_IPV4_H | 9 | #ifndef _NF_CONNTRACK_IPV4_H |
10 | #define _NF_CONNTRACK_IPV4_H | 10 | #define _NF_CONNTRACK_IPV4_H |
11 | 11 | ||
12 | #ifdef CONFIG_IP_NF_NAT_NEEDED | 12 | #ifdef CONFIG_NF_NAT_NEEDED |
13 | #include <linux/netfilter_ipv4/ip_nat.h> | 13 | #include <net/netfilter/nf_nat.h> |
14 | 14 | ||
15 | /* per conntrack: nat application helper private data */ | 15 | /* per conntrack: nat application helper private data */ |
16 | union ip_conntrack_nat_help { | 16 | union nf_conntrack_nat_help { |
17 | /* insert nat helper private data here */ | 17 | /* insert nat helper private data here */ |
18 | }; | 18 | }; |
19 | 19 | ||
20 | struct nf_conntrack_ipv4_nat { | 20 | struct nf_conn_nat { |
21 | struct ip_nat_info info; | 21 | struct nf_nat_info info; |
22 | union ip_conntrack_nat_help help; | 22 | union nf_conntrack_nat_help help; |
23 | #if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \ | 23 | #if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \ |
24 | defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE) | 24 | defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE) |
25 | int masq_index; | 25 | int masq_index; |
26 | #endif | 26 | #endif |
27 | }; | 27 | }; |
28 | #endif /* CONFIG_IP_NF_NAT_NEEDED */ | 28 | #endif /* CONFIG_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 | }; | ||
35 | 29 | ||
36 | /* Returns new sk_buff, or NULL */ | 30 | /* Returns new sk_buff, or NULL */ |
37 | struct sk_buff * | 31 | struct sk_buff * |
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index b4beb8c799e5..9948af068688 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h | |||
@@ -264,18 +264,45 @@ nf_conntrack_unregister_cache(u_int32_t features); | |||
264 | 264 | ||
265 | /* valid combinations: | 265 | /* valid combinations: |
266 | * basic: nf_conn, nf_conn .. nf_conn_help | 266 | * 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 |
268 | */ | 268 | */ |
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 | |||
269 | static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct) | 281 | static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct) |
270 | { | 282 | { |
271 | unsigned int offset = sizeof(struct nf_conn); | 283 | unsigned int offset = sizeof(struct nf_conn); |
272 | 284 | ||
273 | if (!(ct->features & NF_CT_F_HELP)) | 285 | if (!(ct->features & NF_CT_F_HELP)) |
274 | return NULL; | 286 | 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 | } | ||
275 | 291 | ||
276 | offset = ALIGN(offset, __alignof__(struct nf_conn_help)); | 292 | offset = ALIGN(offset, __alignof__(struct nf_conn_help)); |
277 | return (struct nf_conn_help *) ((void *)ct + offset); | 293 | return (struct nf_conn_help *) ((void *)ct + offset); |
278 | } | 294 | } |
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; | ||
279 | 302 | ||
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 */ | ||
280 | #endif /* __KERNEL__ */ | 307 | #endif /* __KERNEL__ */ |
281 | #endif /* _NF_CONNTRACK_H */ | 308 | #endif /* _NF_CONNTRACK_H */ |
diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 5d853e826d1d..b969c430b36a 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h | |||
@@ -43,7 +43,7 @@ struct nf_conntrack_expect | |||
43 | #ifdef CONFIG_NF_NAT_NEEDED | 43 | #ifdef CONFIG_NF_NAT_NEEDED |
44 | /* This is the original per-proto part, used to map the | 44 | /* This is the original per-proto part, used to map the |
45 | * expected connection the way the recipient expects. */ | 45 | * expected connection the way the recipient expects. */ |
46 | union nf_conntrack_manip_proto saved_proto; | 46 | union nf_conntrack_man_proto saved_proto; |
47 | /* Direction relative to the master connection. */ | 47 | /* Direction relative to the master connection. */ |
48 | enum ip_conntrack_dir dir; | 48 | enum ip_conntrack_dir dir; |
49 | #endif | 49 | #endif |
diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h new file mode 100644 index 000000000000..61c62068ca6b --- /dev/null +++ b/include/net/netfilter/nf_nat.h | |||
@@ -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 | ||
diff --git a/include/net/netfilter/nf_nat_core.h b/include/net/netfilter/nf_nat_core.h new file mode 100644 index 000000000000..9778ffa93440 --- /dev/null +++ b/include/net/netfilter/nf_nat_core.h | |||
@@ -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 */ | ||
diff --git a/include/net/netfilter/nf_nat_helper.h b/include/net/netfilter/nf_nat_helper.h new file mode 100644 index 000000000000..ec98ecf95fc8 --- /dev/null +++ b/include/net/netfilter/nf_nat_helper.h | |||
@@ -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 | ||
diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h new file mode 100644 index 000000000000..a9ec5ef61468 --- /dev/null +++ b/include/net/netfilter/nf_nat_protocol.h | |||
@@ -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*/ | ||
diff --git a/include/net/netfilter/nf_nat_rule.h b/include/net/netfilter/nf_nat_rule.h new file mode 100644 index 000000000000..f191c672bcc6 --- /dev/null +++ b/include/net/netfilter/nf_nat_rule.h | |||
@@ -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 */ | ||