mirror of
https://github.com/genesi/linux-legacy.git
synced 2026-05-20 13:57:31 +00:00
[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>
This commit is contained in:
committed by
David S. Miller
parent
d2483ddefd
commit
5b1158e909
@@ -9,29 +9,23 @@
|
||||
#ifndef _NF_CONNTRACK_IPV4_H
|
||||
#define _NF_CONNTRACK_IPV4_H
|
||||
|
||||
#ifdef CONFIG_IP_NF_NAT_NEEDED
|
||||
#include <linux/netfilter_ipv4/ip_nat.h>
|
||||
#ifdef CONFIG_NF_NAT_NEEDED
|
||||
#include <net/netfilter/nf_nat.h>
|
||||
|
||||
/* per conntrack: nat application helper private data */
|
||||
union ip_conntrack_nat_help {
|
||||
union nf_conntrack_nat_help {
|
||||
/* insert nat helper private data here */
|
||||
};
|
||||
|
||||
struct nf_conntrack_ipv4_nat {
|
||||
struct ip_nat_info info;
|
||||
union ip_conntrack_nat_help help;
|
||||
struct nf_conn_nat {
|
||||
struct nf_nat_info info;
|
||||
union nf_conntrack_nat_help help;
|
||||
#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
|
||||
defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
|
||||
int masq_index;
|
||||
#endif
|
||||
};
|
||||
#endif /* CONFIG_IP_NF_NAT_NEEDED */
|
||||
|
||||
struct nf_conntrack_ipv4 {
|
||||
#ifdef CONFIG_IP_NF_NAT_NEEDED
|
||||
struct nf_conntrack_ipv4_nat *nat;
|
||||
#endif
|
||||
};
|
||||
#endif /* CONFIG_NF_NAT_NEEDED */
|
||||
|
||||
/* Returns new sk_buff, or NULL */
|
||||
struct sk_buff *
|
||||
|
||||
@@ -264,8 +264,35 @@ nf_conntrack_unregister_cache(u_int32_t features);
|
||||
|
||||
/* valid combinations:
|
||||
* basic: nf_conn, nf_conn .. nf_conn_help
|
||||
* nat: nf_conn .. nf_conn_nat, nf_conn .. nf_conn_nat, nf_conn help
|
||||
* nat: nf_conn .. nf_conn_nat, nf_conn .. nf_conn_nat .. nf_conn help
|
||||
*/
|
||||
#ifdef CONFIG_NF_NAT_NEEDED
|
||||
static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct)
|
||||
{
|
||||
unsigned int offset = sizeof(struct nf_conn);
|
||||
|
||||
if (!(ct->features & NF_CT_F_NAT))
|
||||
return NULL;
|
||||
|
||||
offset = ALIGN(offset, __alignof__(struct nf_conn_nat));
|
||||
return (struct nf_conn_nat *) ((void *)ct + offset);
|
||||
}
|
||||
|
||||
static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
|
||||
{
|
||||
unsigned int offset = sizeof(struct nf_conn);
|
||||
|
||||
if (!(ct->features & NF_CT_F_HELP))
|
||||
return NULL;
|
||||
if (ct->features & NF_CT_F_NAT) {
|
||||
offset = ALIGN(offset, __alignof__(struct nf_conn_nat));
|
||||
offset += sizeof(struct nf_conn_nat);
|
||||
}
|
||||
|
||||
offset = ALIGN(offset, __alignof__(struct nf_conn_help));
|
||||
return (struct nf_conn_help *) ((void *)ct + offset);
|
||||
}
|
||||
#else /* No NAT */
|
||||
static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
|
||||
{
|
||||
unsigned int offset = sizeof(struct nf_conn);
|
||||
@@ -276,6 +303,6 @@ static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
|
||||
offset = ALIGN(offset, __alignof__(struct nf_conn_help));
|
||||
return (struct nf_conn_help *) ((void *)ct + offset);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NF_NAT_NEEDED */
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _NF_CONNTRACK_H */
|
||||
|
||||
@@ -43,7 +43,7 @@ struct nf_conntrack_expect
|
||||
#ifdef CONFIG_NF_NAT_NEEDED
|
||||
/* This is the original per-proto part, used to map the
|
||||
* expected connection the way the recipient expects. */
|
||||
union nf_conntrack_manip_proto saved_proto;
|
||||
union nf_conntrack_man_proto saved_proto;
|
||||
/* Direction relative to the master connection. */
|
||||
enum ip_conntrack_dir dir;
|
||||
#endif
|
||||
|
||||
77
include/net/netfilter/nf_nat.h
Normal file
77
include/net/netfilter/nf_nat.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#ifndef _NF_NAT_H
|
||||
#define _NF_NAT_H
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <net/netfilter/nf_conntrack_tuple.h>
|
||||
|
||||
#define NF_NAT_MAPPING_TYPE_MAX_NAMELEN 16
|
||||
|
||||
enum nf_nat_manip_type
|
||||
{
|
||||
IP_NAT_MANIP_SRC,
|
||||
IP_NAT_MANIP_DST
|
||||
};
|
||||
|
||||
/* SRC manip occurs POST_ROUTING or LOCAL_IN */
|
||||
#define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING && (hooknum) != NF_IP_LOCAL_IN)
|
||||
|
||||
#define IP_NAT_RANGE_MAP_IPS 1
|
||||
#define IP_NAT_RANGE_PROTO_SPECIFIED 2
|
||||
|
||||
/* NAT sequence number modifications */
|
||||
struct nf_nat_seq {
|
||||
/* position of the last TCP sequence number modification (if any) */
|
||||
u_int32_t correction_pos;
|
||||
|
||||
/* sequence number offset before and after last modification */
|
||||
int16_t offset_before, offset_after;
|
||||
};
|
||||
|
||||
/* Single range specification. */
|
||||
struct nf_nat_range
|
||||
{
|
||||
/* Set to OR of flags above. */
|
||||
unsigned int flags;
|
||||
|
||||
/* Inclusive: network order. */
|
||||
__be32 min_ip, max_ip;
|
||||
|
||||
/* Inclusive: network order */
|
||||
union nf_conntrack_man_proto min, max;
|
||||
};
|
||||
|
||||
/* For backwards compat: don't use in modern code. */
|
||||
struct nf_nat_multi_range_compat
|
||||
{
|
||||
unsigned int rangesize; /* Must be 1. */
|
||||
|
||||
/* hangs off end. */
|
||||
struct nf_nat_range range[1];
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/list.h>
|
||||
|
||||
/* The structure embedded in the conntrack structure. */
|
||||
struct nf_nat_info
|
||||
{
|
||||
struct list_head bysource;
|
||||
struct nf_nat_seq seq[IP_CT_DIR_MAX];
|
||||
};
|
||||
|
||||
struct nf_conn;
|
||||
|
||||
/* Set up the info structure to map into this range. */
|
||||
extern unsigned int nf_nat_setup_info(struct nf_conn *ct,
|
||||
const struct nf_nat_range *range,
|
||||
unsigned int hooknum);
|
||||
|
||||
/* Is this tuple already taken? (not by us)*/
|
||||
extern int nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_conn *ignored_conntrack);
|
||||
|
||||
extern int nf_nat_module_is_loaded;
|
||||
|
||||
#else /* !__KERNEL__: iptables wants this to compile. */
|
||||
#define nf_nat_multi_range nf_nat_multi_range_compat
|
||||
#endif /*__KERNEL__*/
|
||||
#endif
|
||||
27
include/net/netfilter/nf_nat_core.h
Normal file
27
include/net/netfilter/nf_nat_core.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef _NF_NAT_CORE_H
|
||||
#define _NF_NAT_CORE_H
|
||||
#include <linux/list.h>
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
|
||||
/* This header used to share core functionality between the standalone
|
||||
NAT module, and the compatibility layer's use of NAT for masquerading. */
|
||||
|
||||
extern unsigned int nf_nat_packet(struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int hooknum,
|
||||
struct sk_buff **pskb);
|
||||
|
||||
extern int nf_nat_icmp_reply_translation(struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int hooknum,
|
||||
struct sk_buff **pskb);
|
||||
|
||||
static inline int nf_nat_initialized(struct nf_conn *ct,
|
||||
enum nf_nat_manip_type manip)
|
||||
{
|
||||
if (manip == IP_NAT_MANIP_SRC)
|
||||
return test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status);
|
||||
else
|
||||
return test_bit(IPS_DST_NAT_DONE_BIT, &ct->status);
|
||||
}
|
||||
#endif /* _NF_NAT_CORE_H */
|
||||
32
include/net/netfilter/nf_nat_helper.h
Normal file
32
include/net/netfilter/nf_nat_helper.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef _NF_NAT_HELPER_H
|
||||
#define _NF_NAT_HELPER_H
|
||||
/* NAT protocol helper routines. */
|
||||
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
|
||||
struct sk_buff;
|
||||
|
||||
/* These return true or false. */
|
||||
extern int nf_nat_mangle_tcp_packet(struct sk_buff **skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int match_offset,
|
||||
unsigned int match_len,
|
||||
const char *rep_buffer,
|
||||
unsigned int rep_len);
|
||||
extern int nf_nat_mangle_udp_packet(struct sk_buff **skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int match_offset,
|
||||
unsigned int match_len,
|
||||
const char *rep_buffer,
|
||||
unsigned int rep_len);
|
||||
extern int nf_nat_seq_adjust(struct sk_buff **pskb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo);
|
||||
|
||||
/* Setup NAT on this expected conntrack so it follows master, but goes
|
||||
* to port ct->master->saved_proto. */
|
||||
extern void nf_nat_follow_master(struct nf_conn *ct,
|
||||
struct nf_conntrack_expect *this);
|
||||
#endif
|
||||
70
include/net/netfilter/nf_nat_protocol.h
Normal file
70
include/net/netfilter/nf_nat_protocol.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* Header for use in defining a given protocol. */
|
||||
#ifndef _NF_NAT_PROTOCOL_H
|
||||
#define _NF_NAT_PROTOCOL_H
|
||||
#include <net/netfilter/nf_nat.h>
|
||||
#include <linux/netfilter/nfnetlink_conntrack.h>
|
||||
|
||||
struct nf_nat_range;
|
||||
|
||||
struct nf_nat_protocol
|
||||
{
|
||||
/* Protocol name */
|
||||
const char *name;
|
||||
|
||||
/* Protocol number. */
|
||||
unsigned int protonum;
|
||||
|
||||
struct module *me;
|
||||
|
||||
/* Translate a packet to the target according to manip type.
|
||||
Return true if succeeded. */
|
||||
int (*manip_pkt)(struct sk_buff **pskb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype);
|
||||
|
||||
/* Is the manipable part of the tuple between min and max incl? */
|
||||
int (*in_range)(const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const union nf_conntrack_man_proto *min,
|
||||
const union nf_conntrack_man_proto *max);
|
||||
|
||||
/* Alter the per-proto part of the tuple (depending on
|
||||
maniptype), to give a unique tuple in the given range if
|
||||
possible; return false if not. Per-protocol part of tuple
|
||||
is initialized to the incoming packet. */
|
||||
int (*unique_tuple)(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_nat_range *range,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const struct nf_conn *ct);
|
||||
|
||||
int (*range_to_nfattr)(struct sk_buff *skb,
|
||||
const struct nf_nat_range *range);
|
||||
|
||||
int (*nfattr_to_range)(struct nfattr *tb[],
|
||||
struct nf_nat_range *range);
|
||||
};
|
||||
|
||||
/* Protocol registration. */
|
||||
extern int nf_nat_protocol_register(struct nf_nat_protocol *proto);
|
||||
extern void nf_nat_protocol_unregister(struct nf_nat_protocol *proto);
|
||||
|
||||
extern struct nf_nat_protocol *nf_nat_proto_find_get(u_int8_t protocol);
|
||||
extern void nf_nat_proto_put(struct nf_nat_protocol *proto);
|
||||
|
||||
/* Built-in protocols. */
|
||||
extern struct nf_nat_protocol nf_nat_protocol_tcp;
|
||||
extern struct nf_nat_protocol nf_nat_protocol_udp;
|
||||
extern struct nf_nat_protocol nf_nat_protocol_icmp;
|
||||
extern struct nf_nat_protocol nf_nat_unknown_protocol;
|
||||
|
||||
extern int init_protocols(void) __init;
|
||||
extern void cleanup_protocols(void);
|
||||
extern struct nf_nat_protocol *find_nat_proto(u_int16_t protonum);
|
||||
|
||||
extern int nf_nat_port_range_to_nfattr(struct sk_buff *skb,
|
||||
const struct nf_nat_range *range);
|
||||
extern int nf_nat_port_nfattr_to_range(struct nfattr *tb[],
|
||||
struct nf_nat_range *range);
|
||||
|
||||
#endif /*_NF_NAT_PROTO_H*/
|
||||
35
include/net/netfilter/nf_nat_rule.h
Normal file
35
include/net/netfilter/nf_nat_rule.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef _NF_NAT_RULE_H
|
||||
#define _NF_NAT_RULE_H
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
#include <net/netfilter/nf_nat.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
|
||||
/* Compatibility definitions for ipt_FOO modules */
|
||||
#define ip_nat_range nf_nat_range
|
||||
#define ip_conntrack_tuple nf_conntrack_tuple
|
||||
#define ip_conntrack_get nf_ct_get
|
||||
#define ip_conntrack nf_conn
|
||||
#define ip_nat_setup_info nf_nat_setup_info
|
||||
#define ip_nat_multi_range_compat nf_nat_multi_range_compat
|
||||
#define ip_ct_iterate_cleanup nf_ct_iterate_cleanup
|
||||
#define IP_NF_ASSERT NF_CT_ASSERT
|
||||
|
||||
extern int nf_nat_rule_init(void) __init;
|
||||
extern void nf_nat_rule_cleanup(void);
|
||||
extern int nf_nat_rule_find(struct sk_buff **pskb,
|
||||
unsigned int hooknum,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
struct nf_conn *ct,
|
||||
struct nf_nat_info *info);
|
||||
|
||||
extern unsigned int
|
||||
alloc_null_binding(struct nf_conn *ct,
|
||||
struct nf_nat_info *info,
|
||||
unsigned int hooknum);
|
||||
|
||||
extern unsigned int
|
||||
alloc_null_binding_confirmed(struct nf_conn *ct,
|
||||
struct nf_nat_info *info,
|
||||
unsigned int hooknum);
|
||||
#endif /* _NF_NAT_RULE_H */
|
||||
Reference in New Issue
Block a user