Commit e068209a authored by David S. Miller's avatar David S. Miller

Merge nuts.davemloft.net:/disk1/BK/nf-work-2.6

into nuts.davemloft.net:/disk1/BK/nf-2.6
parents 6caaa717 480a73d5
...@@ -178,7 +178,7 @@ extern inline struct ip6t_target * ...@@ -178,7 +178,7 @@ extern inline struct ip6t_target *
ip6t_find_target_lock(const char *name, int *error, struct semaphore *mutex); ip6t_find_target_lock(const char *name, int *error, struct semaphore *mutex);
extern inline struct arpt_target * extern inline struct arpt_target *
arpt_find_target_lock(const char *name, int *error, struct semaphore *mutex); arpt_find_target_lock(const char *name, int *error, struct semaphore *mutex);
extern void (*ip_ct_attach)(struct sk_buff *, struct nf_ct_info *); extern void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *);
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
extern void nf_dump_skb(int pf, struct sk_buff *skb); extern void nf_dump_skb(int pf, struct sk_buff *skb);
......
...@@ -172,9 +172,6 @@ struct ip_conntrack ...@@ -172,9 +172,6 @@ struct ip_conntrack
plus 1 for any connection(s) we are `master' for */ plus 1 for any connection(s) we are `master' for */
struct nf_conntrack ct_general; struct nf_conntrack ct_general;
/* These are my tuples; original and reply */
struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
/* Have we seen traffic both ways yet? (bitset) */ /* Have we seen traffic both ways yet? (bitset) */
unsigned long status; unsigned long status;
...@@ -199,12 +196,7 @@ struct ip_conntrack ...@@ -199,12 +196,7 @@ struct ip_conntrack
/* Helper, if any. */ /* Helper, if any. */
struct ip_conntrack_helper *helper; struct ip_conntrack_helper *helper;
/* Our various nf_ct_info structs specify *what* relation this
packet has to the conntrack */
struct nf_ct_info infos[IP_CT_NUMBER];
/* Storage reserved for other modules: */ /* Storage reserved for other modules: */
union ip_conntrack_proto proto; union ip_conntrack_proto proto;
union ip_conntrack_help help; union ip_conntrack_help help;
...@@ -220,6 +212,9 @@ struct ip_conntrack ...@@ -220,6 +212,9 @@ struct ip_conntrack
} nat; } nat;
#endif /* CONFIG_IP_NF_NAT_NEEDED */ #endif /* CONFIG_IP_NF_NAT_NEEDED */
/* Traversed often, so hopefully in different cacheline to top */
/* These are my tuples; original and reply */
struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
}; };
/* get master conntrack via master expectation */ /* get master conntrack via master expectation */
...@@ -238,8 +233,12 @@ ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple, ...@@ -238,8 +233,12 @@ ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple,
const struct ip_conntrack *ignored_conntrack); const struct ip_conntrack *ignored_conntrack);
/* Return conntrack_info and tuple hash for given skb. */ /* Return conntrack_info and tuple hash for given skb. */
extern struct ip_conntrack * static inline struct ip_conntrack *
ip_conntrack_get(struct sk_buff *skb, enum ip_conntrack_info *ctinfo); ip_conntrack_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
{
*ctinfo = skb->nfctinfo;
return (struct ip_conntrack *)skb->nfct;
}
/* decrement reference count on a conntrack */ /* decrement reference count on a conntrack */
extern inline void ip_conntrack_put(struct ip_conntrack *ct); extern inline void ip_conntrack_put(struct ip_conntrack *ct);
...@@ -306,12 +305,13 @@ struct ip_conntrack_stat ...@@ -306,12 +305,13 @@ struct ip_conntrack_stat
unsigned int insert_failed; unsigned int insert_failed;
unsigned int drop; unsigned int drop;
unsigned int early_drop; unsigned int early_drop;
unsigned int icmp_error; unsigned int error;
unsigned int expect_new; unsigned int expect_new;
unsigned int expect_create; unsigned int expect_create;
unsigned int expect_delete; unsigned int expect_delete;
}; };
#define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++)
/* eg. PROVIDES_CONNTRACK(ftp); */ /* eg. PROVIDES_CONNTRACK(ftp); */
#define PROVIDES_CONNTRACK(name) \ #define PROVIDES_CONNTRACK(name) \
......
...@@ -16,10 +16,6 @@ extern int ip_conntrack_init(void); ...@@ -16,10 +16,6 @@ extern int ip_conntrack_init(void);
extern void ip_conntrack_cleanup(void); extern void ip_conntrack_cleanup(void);
struct ip_conntrack_protocol; struct ip_conntrack_protocol;
extern struct ip_conntrack_protocol *ip_ct_find_proto(u_int8_t protocol);
/* Like above, but you already have conntrack read lock. */
extern struct ip_conntrack_protocol *__ip_ct_find_proto(u_int8_t protocol);
extern struct list_head protocol_list;
extern int extern int
ip_ct_get_tuple(const struct iphdr *iph, ip_ct_get_tuple(const struct iphdr *iph,
...@@ -38,14 +34,14 @@ struct ip_conntrack_tuple_hash * ...@@ -38,14 +34,14 @@ struct ip_conntrack_tuple_hash *
ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple, ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple,
const struct ip_conntrack *ignored_conntrack); const struct ip_conntrack *ignored_conntrack);
extern int __ip_conntrack_confirm(struct nf_ct_info *nfct); extern int __ip_conntrack_confirm(struct sk_buff *skb);
/* Confirm a connection: returns NF_DROP if packet must be dropped. */ /* Confirm a connection: returns NF_DROP if packet must be dropped. */
static inline int ip_conntrack_confirm(struct sk_buff *skb) static inline int ip_conntrack_confirm(struct sk_buff *skb)
{ {
if (skb->nfct if (skb->nfct
&& !is_confirmed((struct ip_conntrack *)skb->nfct->master)) && !is_confirmed((struct ip_conntrack *)skb->nfct))
return __ip_conntrack_confirm(skb->nfct); return __ip_conntrack_confirm(skb);
return NF_ACCEPT; return NF_ACCEPT;
} }
......
...@@ -7,9 +7,6 @@ struct seq_file; ...@@ -7,9 +7,6 @@ struct seq_file;
struct ip_conntrack_protocol struct ip_conntrack_protocol
{ {
/* Next pointer. */
struct list_head list;
/* Protocol number. */ /* Protocol number. */
u_int8_t proto; u_int8_t proto;
...@@ -58,14 +55,23 @@ struct ip_conntrack_protocol ...@@ -58,14 +55,23 @@ struct ip_conntrack_protocol
struct module *me; struct module *me;
}; };
#define MAX_IP_CT_PROTO 256
extern struct ip_conntrack_protocol *ip_ct_protos[MAX_IP_CT_PROTO];
/* Protocol registration. */ /* Protocol registration. */
extern int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto); extern int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto);
extern void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto); extern void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto);
static inline struct ip_conntrack_protocol *ip_ct_find_proto(u_int8_t protocol)
{
return ip_ct_protos[protocol];
}
/* Existing built-in protocols */ /* Existing built-in protocols */
extern struct ip_conntrack_protocol ip_conntrack_protocol_tcp; extern struct ip_conntrack_protocol ip_conntrack_protocol_tcp;
extern struct ip_conntrack_protocol ip_conntrack_protocol_udp; extern struct ip_conntrack_protocol ip_conntrack_protocol_udp;
extern struct ip_conntrack_protocol ip_conntrack_protocol_icmp; extern struct ip_conntrack_protocol ip_conntrack_protocol_icmp;
extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
extern int ip_conntrack_protocol_tcp_init(void); extern int ip_conntrack_protocol_tcp_init(void);
/* Log invalid packets */ /* Log invalid packets */
......
...@@ -80,27 +80,18 @@ struct ip_nat_info_manip ...@@ -80,27 +80,18 @@ struct ip_nat_info_manip
/* Protects NAT hash tables, and NAT-private part of conntracks. */ /* Protects NAT hash tables, and NAT-private part of conntracks. */
DECLARE_RWLOCK_EXTERN(ip_nat_lock); DECLARE_RWLOCK_EXTERN(ip_nat_lock);
/* Hashes for by-source and IP/protocol. */
struct ip_nat_hash
{
struct list_head list;
/* conntrack we're embedded in: NULL if not in hash. */
struct ip_conntrack *conntrack;
};
/* The structure embedded in the conntrack structure. */ /* The structure embedded in the conntrack structure. */
struct ip_nat_info struct ip_nat_info
{ {
/* Set to zero when conntrack created: bitmask of maniptypes */ /* Set to zero when conntrack created: bitmask of maniptypes */
int initialized; u_int16_t initialized;
unsigned int num_manips; u_int16_t num_manips;
/* Manipulations to be done on this conntrack. */ /* Manipulations to be done on this conntrack. */
struct ip_nat_info_manip manips[IP_NAT_MAX_MANIPS]; struct ip_nat_info_manip manips[IP_NAT_MAX_MANIPS];
struct ip_nat_hash bysource, byipsproto; struct list_head bysource, byipsproto;
/* Helper (NULL if none). */ /* Helper (NULL if none). */
struct ip_nat_helper *helper; struct ip_nat_helper *helper;
......
...@@ -14,8 +14,6 @@ extern unsigned int do_bindings(struct ip_conntrack *ct, ...@@ -14,8 +14,6 @@ extern unsigned int do_bindings(struct ip_conntrack *ct,
unsigned int hooknum, unsigned int hooknum,
struct sk_buff **pskb); struct sk_buff **pskb);
extern struct list_head protos;
extern int icmp_reply_translation(struct sk_buff **pskb, extern int icmp_reply_translation(struct sk_buff **pskb,
struct ip_conntrack *conntrack, struct ip_conntrack *conntrack,
unsigned int hooknum, unsigned int hooknum,
...@@ -26,8 +24,4 @@ extern void replace_in_hashes(struct ip_conntrack *conntrack, ...@@ -26,8 +24,4 @@ extern void replace_in_hashes(struct ip_conntrack *conntrack,
extern void place_in_hashes(struct ip_conntrack *conntrack, extern void place_in_hashes(struct ip_conntrack *conntrack,
struct ip_nat_info *info); struct ip_nat_info *info);
/* Built-in protocols. */
extern struct ip_nat_protocol ip_nat_protocol_tcp;
extern struct ip_nat_protocol ip_nat_protocol_udp;
extern struct ip_nat_protocol ip_nat_protocol_icmp;
#endif /* _IP_NAT_CORE_H */ #endif /* _IP_NAT_CORE_H */
...@@ -9,8 +9,6 @@ struct ip_nat_range; ...@@ -9,8 +9,6 @@ struct ip_nat_range;
struct ip_nat_protocol struct ip_nat_protocol
{ {
struct list_head list;
/* Protocol name */ /* Protocol name */
const char *name; const char *name;
...@@ -47,10 +45,24 @@ struct ip_nat_protocol ...@@ -47,10 +45,24 @@ struct ip_nat_protocol
const struct ip_nat_range *range); const struct ip_nat_range *range);
}; };
#define MAX_IP_NAT_PROTO 256
extern struct ip_nat_protocol *ip_nat_protos[MAX_IP_NAT_PROTO];
/* Protocol registration. */ /* Protocol registration. */
extern int ip_nat_protocol_register(struct ip_nat_protocol *proto); extern int ip_nat_protocol_register(struct ip_nat_protocol *proto);
extern void ip_nat_protocol_unregister(struct ip_nat_protocol *proto); extern void ip_nat_protocol_unregister(struct ip_nat_protocol *proto);
static inline struct ip_nat_protocol *ip_nat_find_proto(u_int8_t protocol)
{
return ip_nat_protos[protocol];
}
/* Built-in protocols. */
extern struct ip_nat_protocol ip_nat_protocol_tcp;
extern struct ip_nat_protocol ip_nat_protocol_udp;
extern struct ip_nat_protocol ip_nat_protocol_icmp;
extern struct ip_nat_protocol ip_nat_unknown_protocol;
extern int init_protocols(void) __init; extern int init_protocols(void) __init;
extern void cleanup_protocols(void); extern void cleanup_protocols(void);
extern struct ip_nat_protocol *find_nat_proto(u_int16_t protonum); extern struct ip_nat_protocol *find_nat_proto(u_int16_t protonum);
......
#ifndef _IPT_COMMENT_H
#define _IPT_COMMENT_H
#define IPT_MAX_COMMENT_LEN 256
struct ipt_comment_info {
unsigned char comment[IPT_MAX_COMMENT_LEN];
};
#endif /* _IPT_COMMENT_H */
...@@ -97,10 +97,6 @@ struct nf_conntrack { ...@@ -97,10 +97,6 @@ struct nf_conntrack {
void (*destroy)(struct nf_conntrack *); void (*destroy)(struct nf_conntrack *);
}; };
struct nf_ct_info {
struct nf_conntrack *master;
};
#ifdef CONFIG_BRIDGE_NETFILTER #ifdef CONFIG_BRIDGE_NETFILTER
struct nf_bridge_info { struct nf_bridge_info {
atomic_t use; atomic_t use;
...@@ -186,6 +182,7 @@ struct skb_shared_info { ...@@ -186,6 +182,7 @@ struct skb_shared_info {
* @nfmark: Can be used for communication between hooks * @nfmark: Can be used for communication between hooks
* @nfcache: Cache info * @nfcache: Cache info
* @nfct: Associated connection, if any * @nfct: Associated connection, if any
* @nfctinfo: Relationship of this skb to the connection
* @nf_debug: Netfilter debugging * @nf_debug: Netfilter debugging
* @nf_bridge: Saved data about a bridged frame - see br_netfilter.c * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
* @private: Data which is private to the HIPPI implementation * @private: Data which is private to the HIPPI implementation
...@@ -253,7 +250,8 @@ struct sk_buff { ...@@ -253,7 +250,8 @@ struct sk_buff {
#ifdef CONFIG_NETFILTER #ifdef CONFIG_NETFILTER
unsigned long nfmark; unsigned long nfmark;
__u32 nfcache; __u32 nfcache;
struct nf_ct_info *nfct; struct nf_conntrack *nfct;
__u32 nfctinfo;
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
unsigned int nf_debug; unsigned int nf_debug;
#endif #endif
...@@ -1141,15 +1139,15 @@ extern int skb_iter_next(const struct sk_buff *skb, struct skb_iter *i); ...@@ -1141,15 +1139,15 @@ extern int skb_iter_next(const struct sk_buff *skb, struct skb_iter *i);
extern void skb_iter_abort(const struct sk_buff *skb, struct skb_iter *i); extern void skb_iter_abort(const struct sk_buff *skb, struct skb_iter *i);
#ifdef CONFIG_NETFILTER #ifdef CONFIG_NETFILTER
static inline void nf_conntrack_put(struct nf_ct_info *nfct) static inline void nf_conntrack_put(struct nf_conntrack *nfct)
{ {
if (nfct && atomic_dec_and_test(&nfct->master->use)) if (nfct && atomic_dec_and_test(&nfct->use))
nfct->master->destroy(nfct->master); nfct->destroy(nfct);
} }
static inline void nf_conntrack_get(struct nf_ct_info *nfct) static inline void nf_conntrack_get(struct nf_conntrack *nfct)
{ {
if (nfct) if (nfct)
atomic_inc(&nfct->master->use); atomic_inc(&nfct->use);
} }
static inline void nf_reset(struct sk_buff *skb) static inline void nf_reset(struct sk_buff *skb)
{ {
......
...@@ -424,6 +424,7 @@ enum ...@@ -424,6 +424,7 @@ enum
NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24, NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25, NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26, NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
NET_IPV4_NF_CONNTRACK_COUNT=27,
}; };
/* /proc/sys/net/ipv6 */ /* /proc/sys/net/ipv6 */
......
...@@ -806,7 +806,7 @@ EXPORT_SYMBOL(nf_log_packet); ...@@ -806,7 +806,7 @@ EXPORT_SYMBOL(nf_log_packet);
tracking in use: without this, connection may not be in hash table, tracking in use: without this, connection may not be in hash table,
and hence manufactured ICMP or RST packets will not be associated and hence manufactured ICMP or RST packets will not be associated
with it. */ with it. */
void (*ip_ct_attach)(struct sk_buff *, struct nf_ct_info *); void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *);
void __init netfilter_init(void) void __init netfilter_init(void)
{ {
......
...@@ -311,6 +311,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) ...@@ -311,6 +311,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
C(nfcache); C(nfcache);
C(nfct); C(nfct);
nf_conntrack_get(skb->nfct); nf_conntrack_get(skb->nfct);
C(nfctinfo);
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
C(nf_debug); C(nf_debug);
#endif #endif
...@@ -377,6 +378,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) ...@@ -377,6 +378,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->nfcache = old->nfcache; new->nfcache = old->nfcache;
new->nfct = old->nfct; new->nfct = old->nfct;
nf_conntrack_get(old->nfct); nf_conntrack_get(old->nfct);
new->nfctinfo = old->nfctinfo;
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
new->nf_debug = old->nf_debug; new->nf_debug = old->nf_debug;
#endif #endif
......
...@@ -422,6 +422,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) ...@@ -422,6 +422,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
nf_conntrack_put(to->nfct); nf_conntrack_put(to->nfct);
to->nfct = from->nfct; to->nfct = from->nfct;
nf_conntrack_get(to->nfct); nf_conntrack_get(to->nfct);
to->nfctinfo = from->nfctinfo;
#ifdef CONFIG_BRIDGE_NETFILTER #ifdef CONFIG_BRIDGE_NETFILTER
nf_bridge_put(to->nf_bridge); nf_bridge_put(to->nf_bridge);
to->nf_bridge = from->nf_bridge; to->nf_bridge = from->nf_bridge;
......
...@@ -332,6 +332,16 @@ config IP_NF_MATCH_SCTP ...@@ -332,6 +332,16 @@ config IP_NF_MATCH_SCTP
If you want to compile it as a module, say M here and read If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'. Documentation/modules.txt. If unsure, say `N'.
config IP_NF_MATCH_COMMENT
tristate 'comment match support'
depends on IP_NF_IPTABLES
help
This option adds a `comment' dummy-match, which allows you to put
comments in your iptables ruleset.
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
# `filter', generic and specific targets # `filter', generic and specific targets
config IP_NF_FILTER config IP_NF_FILTER
tristate "Packet filtering" tristate "Packet filtering"
......
...@@ -50,28 +50,23 @@ obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o ...@@ -50,28 +50,23 @@ obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o
obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o
obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o
# targets # targets
obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
......
...@@ -66,7 +66,7 @@ EXPORT_SYMBOL(ip_conntrack_count); ...@@ -66,7 +66,7 @@ EXPORT_SYMBOL(ip_conntrack_count);
void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack) = NULL; void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack) = NULL;
LIST_HEAD(ip_conntrack_expect_list); LIST_HEAD(ip_conntrack_expect_list);
LIST_HEAD(protocol_list); struct ip_conntrack_protocol *ip_ct_protos[MAX_IP_CT_PROTO];
static LIST_HEAD(helpers); static LIST_HEAD(helpers);
unsigned int ip_conntrack_htable_size = 0; unsigned int ip_conntrack_htable_size = 0;
int ip_conntrack_max; int ip_conntrack_max;
...@@ -77,45 +77,11 @@ struct ip_conntrack ip_conntrack_untracked; ...@@ -77,45 +77,11 @@ struct ip_conntrack ip_conntrack_untracked;
DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat); DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
static inline int proto_cmpfn(const struct ip_conntrack_protocol *curr,
u_int8_t protocol)
{
return protocol == curr->proto;
}
struct ip_conntrack_protocol *__ip_ct_find_proto(u_int8_t protocol)
{
struct ip_conntrack_protocol *p;
MUST_BE_READ_LOCKED(&ip_conntrack_lock);
p = LIST_FIND(&protocol_list, proto_cmpfn,
struct ip_conntrack_protocol *, protocol);
if (!p)
p = &ip_conntrack_generic_protocol;
return p;
}
struct ip_conntrack_protocol *ip_ct_find_proto(u_int8_t protocol)
{
struct ip_conntrack_protocol *p;
READ_LOCK(&ip_conntrack_lock);
p = __ip_ct_find_proto(protocol);
READ_UNLOCK(&ip_conntrack_lock);
return p;
}
inline void inline void
ip_conntrack_put(struct ip_conntrack *ct) ip_conntrack_put(struct ip_conntrack *ct)
{ {
IP_NF_ASSERT(ct); IP_NF_ASSERT(ct);
IP_NF_ASSERT(ct->infos[0].master); nf_conntrack_put(&ct->ct_general);
/* nf_conntrack_put wants to go via an info struct, so feed it
one at random. */
nf_conntrack_put(&ct->infos[0]);
} }
static int ip_conntrack_hash_rnd_initted; static int ip_conntrack_hash_rnd_initted;
...@@ -185,7 +151,7 @@ destroy_expect(struct ip_conntrack_expect *exp) ...@@ -185,7 +151,7 @@ destroy_expect(struct ip_conntrack_expect *exp)
IP_NF_ASSERT(!timer_pending(&exp->timeout)); IP_NF_ASSERT(!timer_pending(&exp->timeout));
kmem_cache_free(ip_conntrack_expect_cachep, exp); kmem_cache_free(ip_conntrack_expect_cachep, exp);
__get_cpu_var(ip_conntrack_stat).expect_delete++; CONNTRACK_STAT_INC(expect_delete);
} }
inline void ip_conntrack_expect_put(struct ip_conntrack_expect *exp) inline void ip_conntrack_expect_put(struct ip_conntrack_expect *exp)
...@@ -354,14 +320,14 @@ destroy_conntrack(struct nf_conntrack *nfct) ...@@ -354,14 +320,14 @@ destroy_conntrack(struct nf_conntrack *nfct)
DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct); DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct);
kmem_cache_free(ip_conntrack_cachep, ct); kmem_cache_free(ip_conntrack_cachep, ct);
atomic_dec(&ip_conntrack_count); atomic_dec(&ip_conntrack_count);
__get_cpu_var(ip_conntrack_stat).delete++; CONNTRACK_STAT_INC(delete);
} }
static void death_by_timeout(unsigned long ul_conntrack) static void death_by_timeout(unsigned long ul_conntrack)
{ {
struct ip_conntrack *ct = (void *)ul_conntrack; struct ip_conntrack *ct = (void *)ul_conntrack;
__get_cpu_var(ip_conntrack_stat).delete_list++; CONNTRACK_STAT_INC(delete_list);
WRITE_LOCK(&ip_conntrack_lock); WRITE_LOCK(&ip_conntrack_lock);
clean_from_lists(ct); clean_from_lists(ct);
...@@ -416,36 +382,15 @@ ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple, ...@@ -416,36 +382,15 @@ ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple,
return h; return h;
} }
static inline struct ip_conntrack * /* Confirm a connection given skb; places it in hash table */
__ip_conntrack_get(struct nf_ct_info *nfct, enum ip_conntrack_info *ctinfo)
{
struct ip_conntrack *ct
= (struct ip_conntrack *)nfct->master;
/* ctinfo is the index of the nfct inside the conntrack */
*ctinfo = nfct - ct->infos;
IP_NF_ASSERT(*ctinfo >= 0 && *ctinfo < IP_CT_NUMBER);
return ct;
}
/* Return conntrack and conntrack_info given skb->nfct->master */
struct ip_conntrack *
ip_conntrack_get(struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
{
if (skb->nfct)
return __ip_conntrack_get(skb->nfct, ctinfo);
return NULL;
}
/* Confirm a connection given skb->nfct; places it in hash table */
int int
__ip_conntrack_confirm(struct nf_ct_info *nfct) __ip_conntrack_confirm(struct sk_buff *skb)
{ {
unsigned int hash, repl_hash; unsigned int hash, repl_hash;
struct ip_conntrack *ct; struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo; enum ip_conntrack_info ctinfo;
ct = __ip_conntrack_get(nfct, &ctinfo); ct = ip_conntrack_get(skb, &ctinfo);
/* ipt_REJECT uses ip_conntrack_attach to attach related /* ipt_REJECT uses ip_conntrack_attach to attach related
ICMP/TCP RST packets in other direction. Actual packet ICMP/TCP RST packets in other direction. Actual packet
...@@ -491,12 +436,12 @@ __ip_conntrack_confirm(struct nf_ct_info *nfct) ...@@ -491,12 +436,12 @@ __ip_conntrack_confirm(struct nf_ct_info *nfct)
atomic_inc(&ct->ct_general.use); atomic_inc(&ct->ct_general.use);
set_bit(IPS_CONFIRMED_BIT, &ct->status); set_bit(IPS_CONFIRMED_BIT, &ct->status);
WRITE_UNLOCK(&ip_conntrack_lock); WRITE_UNLOCK(&ip_conntrack_lock);
__get_cpu_var(ip_conntrack_stat).insert++; CONNTRACK_STAT_INC(insert);
return NF_ACCEPT; return NF_ACCEPT;
} }
WRITE_UNLOCK(&ip_conntrack_lock); WRITE_UNLOCK(&ip_conntrack_lock);
__get_cpu_var(ip_conntrack_stat).insert_failed++; CONNTRACK_STAT_INC(insert_failed);
return NF_DROP; return NF_DROP;
} }
...@@ -540,7 +485,7 @@ static int early_drop(struct list_head *chain) ...@@ -540,7 +485,7 @@ static int early_drop(struct list_head *chain)
if (del_timer(&h->ctrack->timeout)) { if (del_timer(&h->ctrack->timeout)) {
death_by_timeout((unsigned long)h->ctrack); death_by_timeout((unsigned long)h->ctrack);
dropped = 1; dropped = 1;
__get_cpu_var(ip_conntrack_stat).early_drop++; CONNTRACK_STAT_INC(early_drop);
} }
ip_conntrack_put(h->ctrack); ip_conntrack_put(h->ctrack);
return dropped; return dropped;
...@@ -570,8 +515,6 @@ init_conntrack(const struct ip_conntrack_tuple *tuple, ...@@ -570,8 +515,6 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
struct ip_conntrack_tuple repl_tuple; struct ip_conntrack_tuple repl_tuple;
size_t hash; size_t hash;
struct ip_conntrack_expect *expected; struct ip_conntrack_expect *expected;
int i;
static unsigned int drop_next;
if (!ip_conntrack_hash_rnd_initted) { if (!ip_conntrack_hash_rnd_initted) {
get_random_bytes(&ip_conntrack_hash_rnd, 4); get_random_bytes(&ip_conntrack_hash_rnd, 4);
...@@ -580,15 +523,10 @@ init_conntrack(const struct ip_conntrack_tuple *tuple, ...@@ -580,15 +523,10 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
hash = hash_conntrack(tuple); hash = hash_conntrack(tuple);
if (ip_conntrack_max && if (ip_conntrack_max
atomic_read(&ip_conntrack_count) >= ip_conntrack_max) { && atomic_read(&ip_conntrack_count) >= ip_conntrack_max) {
/* Try dropping from random chain, or else from the /* Try dropping from this hash chain. */
chain about to put into (in case they're trying to if (!early_drop(&ip_conntrack_hash[hash])) {
bomb one hash chain). */
unsigned int next = (drop_next++)%ip_conntrack_htable_size;
if (!early_drop(&ip_conntrack_hash[next])
&& !early_drop(&ip_conntrack_hash[hash])) {
if (net_ratelimit()) if (net_ratelimit())
printk(KERN_WARNING printk(KERN_WARNING
"ip_conntrack: table full, dropping" "ip_conntrack: table full, dropping"
...@@ -615,9 +553,6 @@ init_conntrack(const struct ip_conntrack_tuple *tuple, ...@@ -615,9 +553,6 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
conntrack->tuplehash[IP_CT_DIR_ORIGINAL].ctrack = conntrack; conntrack->tuplehash[IP_CT_DIR_ORIGINAL].ctrack = conntrack;
conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = repl_tuple; conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = repl_tuple;
conntrack->tuplehash[IP_CT_DIR_REPLY].ctrack = conntrack; conntrack->tuplehash[IP_CT_DIR_REPLY].ctrack = conntrack;
for (i=0; i < IP_CT_NUMBER; i++)
conntrack->infos[i].master = &conntrack->ct_general;
if (!protocol->new(conntrack, skb)) { if (!protocol->new(conntrack, skb)) {
kmem_cache_free(ip_conntrack_cachep, conntrack); kmem_cache_free(ip_conntrack_cachep, conntrack);
return NULL; return NULL;
...@@ -655,13 +590,13 @@ init_conntrack(const struct ip_conntrack_tuple *tuple, ...@@ -655,13 +590,13 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
conntrack, expected); conntrack, expected);
/* Welcome, Mr. Bond. We've been expecting you... */ /* Welcome, Mr. Bond. We've been expecting you... */
IP_NF_ASSERT(master_ct(conntrack)); IP_NF_ASSERT(expected->expectant);
__set_bit(IPS_EXPECTED_BIT, &conntrack->status); __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
conntrack->master = expected; conntrack->master = expected;
expected->sibling = conntrack; expected->sibling = conntrack;
LIST_DELETE(&ip_conntrack_expect_list, expected); LIST_DELETE(&ip_conntrack_expect_list, expected);
expected->expectant->expecting--; expected->expectant->expecting--;
nf_conntrack_get(&master_ct(conntrack)->infos[0]); nf_conntrack_get(&master_ct(conntrack)->ct_general);
/* this is a braindead... --pablo */ /* this is a braindead... --pablo */
atomic_inc(&ip_conntrack_count); atomic_inc(&ip_conntrack_count);
...@@ -670,13 +605,13 @@ init_conntrack(const struct ip_conntrack_tuple *tuple, ...@@ -670,13 +605,13 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
if (expected->expectfn) if (expected->expectfn)
expected->expectfn(conntrack); expected->expectfn(conntrack);
__get_cpu_var(ip_conntrack_stat).expect_new++; CONNTRACK_STAT_INC(expect_new);
goto ret; goto ret;
} else { } else {
conntrack->helper = ip_ct_find_helper(&repl_tuple); conntrack->helper = ip_ct_find_helper(&repl_tuple);
__get_cpu_var(ip_conntrack_stat).new++; CONNTRACK_STAT_INC(new);
} }
end: atomic_inc(&ip_conntrack_count); end: atomic_inc(&ip_conntrack_count);
...@@ -734,7 +669,8 @@ resolve_normal_ct(struct sk_buff *skb, ...@@ -734,7 +669,8 @@ resolve_normal_ct(struct sk_buff *skb,
} }
*set_reply = 0; *set_reply = 0;
} }
skb->nfct = &h->ctrack->infos[*ctinfo]; skb->nfct = &h->ctrack->ct_general;
skb->nfctinfo = *ctinfo;
return h->ctrack; return h->ctrack;
} }
...@@ -780,7 +716,7 @@ unsigned int ip_conntrack_in(unsigned int hooknum, ...@@ -780,7 +716,7 @@ unsigned int ip_conntrack_in(unsigned int hooknum,
/* Previously seen (loopback or untracked)? Ignore. */ /* Previously seen (loopback or untracked)? Ignore. */
if ((*pskb)->nfct) { if ((*pskb)->nfct) {
__get_cpu_var(ip_conntrack_stat).ignore++; CONNTRACK_STAT_INC(ignore);
return NF_ACCEPT; return NF_ACCEPT;
} }
...@@ -791,19 +727,20 @@ unsigned int ip_conntrack_in(unsigned int hooknum, ...@@ -791,19 +727,20 @@ unsigned int ip_conntrack_in(unsigned int hooknum,
* core what to do with the packet. */ * core what to do with the packet. */
if (proto->error != NULL if (proto->error != NULL
&& (ret = proto->error(*pskb, &ctinfo, hooknum)) <= 0) { && (ret = proto->error(*pskb, &ctinfo, hooknum)) <= 0) {
__get_cpu_var(ip_conntrack_stat).icmp_error++; CONNTRACK_STAT_INC(error);
CONNTRACK_STAT_INC(invalid);
return -ret; return -ret;
} }
if (!(ct = resolve_normal_ct(*pskb, proto,&set_reply,hooknum,&ctinfo))) { if (!(ct = resolve_normal_ct(*pskb, proto,&set_reply,hooknum,&ctinfo))) {
/* Not valid part of a connection */ /* Not valid part of a connection */
__get_cpu_var(ip_conntrack_stat).invalid++; CONNTRACK_STAT_INC(invalid);
return NF_ACCEPT; return NF_ACCEPT;
} }
if (IS_ERR(ct)) { if (IS_ERR(ct)) {
/* Too stressed to deal. */ /* Too stressed to deal. */
__get_cpu_var(ip_conntrack_stat).drop++; CONNTRACK_STAT_INC(drop);
return NF_DROP; return NF_DROP;
} }
...@@ -815,7 +752,7 @@ unsigned int ip_conntrack_in(unsigned int hooknum, ...@@ -815,7 +752,7 @@ unsigned int ip_conntrack_in(unsigned int hooknum,
* the netfilter core what to do*/ * the netfilter core what to do*/
nf_conntrack_put((*pskb)->nfct); nf_conntrack_put((*pskb)->nfct);
(*pskb)->nfct = NULL; (*pskb)->nfct = NULL;
__get_cpu_var(ip_conntrack_stat).invalid++; CONNTRACK_STAT_INC(invalid);
return -ret; return -ret;
} }
...@@ -823,7 +760,7 @@ unsigned int ip_conntrack_in(unsigned int hooknum, ...@@ -823,7 +760,7 @@ unsigned int ip_conntrack_in(unsigned int hooknum,
ret = ct->helper->help(*pskb, ct, ctinfo); ret = ct->helper->help(*pskb, ct, ctinfo);
if (ret == -1) { if (ret == -1) {
/* Invalid */ /* Invalid */
__get_cpu_var(ip_conntrack_stat).invalid++; CONNTRACK_STAT_INC(invalid);
nf_conntrack_put((*pskb)->nfct); nf_conntrack_put((*pskb)->nfct);
(*pskb)->nfct = NULL; (*pskb)->nfct = NULL;
return NF_ACCEPT; return NF_ACCEPT;
...@@ -1027,7 +964,7 @@ out: ip_conntrack_expect_insert(expect, related_to); ...@@ -1027,7 +964,7 @@ out: ip_conntrack_expect_insert(expect, related_to);
WRITE_UNLOCK(&ip_conntrack_lock); WRITE_UNLOCK(&ip_conntrack_lock);
__get_cpu_var(ip_conntrack_stat).expect_create++; CONNTRACK_STAT_INC(expect_create);
return ret; return ret;
} }
...@@ -1219,23 +1156,23 @@ ip_ct_gather_frags(struct sk_buff *skb) ...@@ -1219,23 +1156,23 @@ ip_ct_gather_frags(struct sk_buff *skb)
} }
/* Used by ipt_REJECT. */ /* Used by ipt_REJECT. */
static void ip_conntrack_attach(struct sk_buff *nskb, struct nf_ct_info *nfct) static void ip_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
{ {
struct ip_conntrack *ct; struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo; enum ip_conntrack_info ctinfo;
ct = __ip_conntrack_get(nfct, &ctinfo); /* This ICMP is in reverse direction to the packet which caused it */
ct = ip_conntrack_get(skb, &ctinfo);
/* This ICMP is in reverse direction to the packet which
caused it */
if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
ctinfo = IP_CT_RELATED + IP_CT_IS_REPLY; ctinfo = IP_CT_RELATED + IP_CT_IS_REPLY;
else else
ctinfo = IP_CT_RELATED; ctinfo = IP_CT_RELATED;
/* Attach new skbuff, and increment count */ /* Attach to new skbuff, and increment count */
nskb->nfct = &ct->infos[ctinfo]; nskb->nfct = &ct->ct_general;
atomic_inc(&ct->ct_general.use); nskb->nfctinfo = ctinfo;
nf_conntrack_get(nskb->nfct);
} }
static inline int static inline int
...@@ -1430,10 +1367,12 @@ int __init ip_conntrack_init(void) ...@@ -1430,10 +1367,12 @@ int __init ip_conntrack_init(void)
/* Don't NEED lock here, but good form anyway. */ /* Don't NEED lock here, but good form anyway. */
WRITE_LOCK(&ip_conntrack_lock); WRITE_LOCK(&ip_conntrack_lock);
for (i = 0; i < MAX_IP_CT_PROTO; i++)
ip_ct_protos[i] = &ip_conntrack_generic_protocol;
/* Sew in builtin protocols. */ /* Sew in builtin protocols. */
list_append(&protocol_list, &ip_conntrack_protocol_tcp); ip_ct_protos[IPPROTO_TCP] = &ip_conntrack_protocol_tcp;
list_append(&protocol_list, &ip_conntrack_protocol_udp); ip_ct_protos[IPPROTO_UDP] = &ip_conntrack_protocol_udp;
list_append(&protocol_list, &ip_conntrack_protocol_icmp); ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp;
WRITE_UNLOCK(&ip_conntrack_lock); WRITE_UNLOCK(&ip_conntrack_lock);
for (i = 0; i < ip_conntrack_htable_size; i++) for (i = 0; i < ip_conntrack_htable_size; i++)
...@@ -1447,11 +1386,6 @@ int __init ip_conntrack_init(void) ...@@ -1447,11 +1386,6 @@ int __init ip_conntrack_init(void)
atomic_set(&ip_conntrack_untracked.ct_general.use, 1); atomic_set(&ip_conntrack_untracked.ct_general.use, 1);
/* - and look it like as a confirmed connection */ /* - and look it like as a confirmed connection */
set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status); set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status);
/* - and prepare the ctinfo field for REJECT & NAT. */
ip_conntrack_untracked.infos[IP_CT_NEW].master =
ip_conntrack_untracked.infos[IP_CT_RELATED].master =
ip_conntrack_untracked.infos[IP_CT_RELATED + IP_CT_IS_REPLY].master =
&ip_conntrack_untracked.ct_general;
return ret; return ret;
......
...@@ -195,7 +195,8 @@ icmp_error_message(struct sk_buff *skb, ...@@ -195,7 +195,8 @@ icmp_error_message(struct sk_buff *skb,
} }
/* Update skb to refer to this connection */ /* Update skb to refer to this connection */
skb->nfct = &h->ctrack->infos[*ctinfo]; skb->nfct = &h->ctrack->ct_general;
skb->nfctinfo = *ctinfo;
return -NF_ACCEPT; return -NF_ACCEPT;
} }
......
...@@ -430,16 +430,16 @@ static int sctp_new(struct ip_conntrack *conntrack, ...@@ -430,16 +430,16 @@ static int sctp_new(struct ip_conntrack *conntrack,
DEBUGP("\n"); DEBUGP("\n");
if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &sctph, sizeof(sctph)) != 0) if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &sctph, sizeof(sctph)) != 0)
return -1; return 0;
if (do_basic_checks(conntrack, skb, map) != 0) if (do_basic_checks(conntrack, skb, map) != 0)
return -1; return 0;
/* If an OOTB packet has any of these chunks discard (Sec 8.4) */ /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
if ((test_bit (SCTP_CID_ABORT, (void *)map)) if ((test_bit (SCTP_CID_ABORT, (void *)map))
|| (test_bit (SCTP_CID_SHUTDOWN_COMPLETE, (void *)map)) || (test_bit (SCTP_CID_SHUTDOWN_COMPLETE, (void *)map))
|| (test_bit (SCTP_CID_COOKIE_ACK, (void *)map))) { || (test_bit (SCTP_CID_COOKIE_ACK, (void *)map))) {
return -1; return 0;
} }
newconntrack = SCTP_CONNTRACK_MAX; newconntrack = SCTP_CONNTRACK_MAX;
...@@ -461,7 +461,7 @@ static int sctp_new(struct ip_conntrack *conntrack, ...@@ -461,7 +461,7 @@ static int sctp_new(struct ip_conntrack *conntrack,
if (skb_copy_bits(skb, offset + sizeof (sctp_chunkhdr_t), if (skb_copy_bits(skb, offset + sizeof (sctp_chunkhdr_t),
&inithdr, sizeof(inithdr)) != 0) { &inithdr, sizeof(inithdr)) != 0) {
return -1; return 0;
} }
DEBUGP("Setting vtag %x for new conn\n", DEBUGP("Setting vtag %x for new conn\n",
...@@ -471,7 +471,7 @@ static int sctp_new(struct ip_conntrack *conntrack, ...@@ -471,7 +471,7 @@ static int sctp_new(struct ip_conntrack *conntrack,
inithdr.init_tag; inithdr.init_tag;
} else { } else {
/* Sec 8.5.1 (A) */ /* Sec 8.5.1 (A) */
return -1; return 0;
} }
} }
/* If it is a shutdown ack OOTB packet, we expect a return /* If it is a shutdown ack OOTB packet, we expect a return
...@@ -496,7 +496,6 @@ static int sctp_exp_matches_pkt(struct ip_conntrack_expect *exp, ...@@ -496,7 +496,6 @@ static int sctp_exp_matches_pkt(struct ip_conntrack_expect *exp,
} }
struct ip_conntrack_protocol ip_conntrack_protocol_sctp = { struct ip_conntrack_protocol ip_conntrack_protocol_sctp = {
.list = { NULL, NULL },
.proto = IPPROTO_SCTP, .proto = IPPROTO_SCTP,
.name = "sctp", .name = "sctp",
.pkt_to_tuple = sctp_pkt_to_tuple, .pkt_to_tuple = sctp_pkt_to_tuple,
......
...@@ -112,7 +112,7 @@ static int ct_seq_real_show(const struct ip_conntrack_tuple_hash *hash, ...@@ -112,7 +112,7 @@ static int ct_seq_real_show(const struct ip_conntrack_tuple_hash *hash,
if (DIRECTION(hash)) if (DIRECTION(hash))
return 0; return 0;
proto = __ip_ct_find_proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL] proto = ip_ct_find_proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
.tuple.dst.protonum); .tuple.dst.protonum);
IP_NF_ASSERT(proto); IP_NF_ASSERT(proto);
...@@ -242,7 +242,7 @@ static int exp_seq_show(struct seq_file *s, void *v) ...@@ -242,7 +242,7 @@ static int exp_seq_show(struct seq_file *s, void *v)
expect->tuple.dst.protonum); expect->tuple.dst.protonum);
print_tuple(s, &expect->tuple, print_tuple(s, &expect->tuple,
__ip_ct_find_proto(expect->tuple.dst.protonum)); ip_ct_find_proto(expect->tuple.dst.protonum));
return seq_putc(s, '\n'); return seq_putc(s, '\n');
} }
...@@ -317,7 +317,7 @@ static int ct_cpu_seq_show(struct seq_file *seq, void *v) ...@@ -317,7 +317,7 @@ static int ct_cpu_seq_show(struct seq_file *seq, void *v)
st->insert_failed, st->insert_failed,
st->drop, st->drop,
st->early_drop, st->early_drop,
st->icmp_error, st->error,
st->expect_new, st->expect_new,
st->expect_create, st->expect_create,
...@@ -515,6 +515,14 @@ static ctl_table ip_ct_sysctl_table[] = { ...@@ -515,6 +515,14 @@ static ctl_table ip_ct_sysctl_table[] = {
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec, .proc_handler = &proc_dointvec,
}, },
{
.ctl_name = NET_IPV4_NF_CONNTRACK_COUNT,
.procname = "ip_conntrack_count",
.data = &ip_conntrack_count,
.maxlen = sizeof(int),
.mode = 0444,
.proc_handler = &proc_dointvec,
},
{ {
.ctl_name = NET_IPV4_NF_CONNTRACK_BUCKETS, .ctl_name = NET_IPV4_NF_CONNTRACK_BUCKETS,
.procname = "ip_conntrack_buckets", .procname = "ip_conntrack_buckets",
...@@ -816,19 +824,13 @@ static int init_or_cleanup(int init) ...@@ -816,19 +824,13 @@ static int init_or_cleanup(int init)
int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto)
{ {
int ret = 0; int ret = 0;
struct list_head *i;
WRITE_LOCK(&ip_conntrack_lock); WRITE_LOCK(&ip_conntrack_lock);
list_for_each(i, &protocol_list) { if (ip_ct_protos[proto->proto] != &ip_conntrack_generic_protocol) {
if (((struct ip_conntrack_protocol *)i)->proto ret = -EBUSY;
== proto->proto) { goto out;
ret = -EBUSY;
goto out;
}
} }
ip_ct_protos[proto->proto] = proto;
list_prepend(&protocol_list, proto);
out: out:
WRITE_UNLOCK(&ip_conntrack_lock); WRITE_UNLOCK(&ip_conntrack_lock);
return ret; return ret;
...@@ -837,10 +839,7 @@ int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) ...@@ -837,10 +839,7 @@ int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto)
void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto) void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto)
{ {
WRITE_LOCK(&ip_conntrack_lock); WRITE_LOCK(&ip_conntrack_lock);
ip_ct_protos[proto->proto] = &ip_conntrack_generic_protocol;
/* ip_ct_find_proto() returns proto_generic in case there is no protocol
* helper. So this should be enough - HW */
LIST_DELETE(&protocol_list, proto);
WRITE_UNLOCK(&ip_conntrack_lock); WRITE_UNLOCK(&ip_conntrack_lock);
/* Somebody could be still looking at the proto in bh. */ /* Somebody could be still looking at the proto in bh. */
...@@ -880,8 +879,8 @@ EXPORT_SYMBOL(ip_conntrack_helper_register); ...@@ -880,8 +879,8 @@ EXPORT_SYMBOL(ip_conntrack_helper_register);
EXPORT_SYMBOL(ip_conntrack_helper_unregister); EXPORT_SYMBOL(ip_conntrack_helper_unregister);
EXPORT_SYMBOL(ip_ct_selective_cleanup); EXPORT_SYMBOL(ip_ct_selective_cleanup);
EXPORT_SYMBOL(ip_ct_refresh_acct); EXPORT_SYMBOL(ip_ct_refresh_acct);
EXPORT_SYMBOL(ip_ct_protos);
EXPORT_SYMBOL(ip_ct_find_proto); EXPORT_SYMBOL(ip_ct_find_proto);
EXPORT_SYMBOL(__ip_ct_find_proto);
EXPORT_SYMBOL(ip_ct_find_helper); EXPORT_SYMBOL(ip_ct_find_helper);
EXPORT_SYMBOL(ip_conntrack_expect_alloc); EXPORT_SYMBOL(ip_conntrack_expect_alloc);
EXPORT_SYMBOL(ip_conntrack_expect_related); EXPORT_SYMBOL(ip_conntrack_expect_related);
......
...@@ -146,7 +146,7 @@ check_for_demasq(struct sk_buff **pskb) ...@@ -146,7 +146,7 @@ check_for_demasq(struct sk_buff **pskb)
case IPPROTO_ICMP: case IPPROTO_ICMP:
/* ICMP errors. */ /* ICMP errors. */
protocol->error(*pskb, &ctinfo, NF_IP_PRE_ROUTING); protocol->error(*pskb, &ctinfo, NF_IP_PRE_ROUTING);
ct = (struct ip_conntrack *)(*pskb)->nfct->master; ct = (struct ip_conntrack *)(*pskb)->nfct;
if (ct) { if (ct) {
/* We only do SNAT in the compatibility layer. /* We only do SNAT in the compatibility layer.
So we can manipulate ICMP errors from So we can manipulate ICMP errors from
...@@ -187,7 +187,7 @@ check_for_demasq(struct sk_buff **pskb) ...@@ -187,7 +187,7 @@ check_for_demasq(struct sk_buff **pskb)
NULL, NULL, NULL); NULL, NULL, NULL);
/* Put back the reference gained from find_get */ /* Put back the reference gained from find_get */
nf_conntrack_put(&h->ctrack->infos[0]); nf_conntrack_put(&h->ctrack->ct_general);
if (ret == NF_ACCEPT) { if (ret == NF_ACCEPT) {
struct ip_conntrack *ct; struct ip_conntrack *ct;
ct = ip_conntrack_get(*pskb, &ctinfo); ct = ip_conntrack_get(*pskb, &ctinfo);
...@@ -206,7 +206,7 @@ check_for_demasq(struct sk_buff **pskb) ...@@ -206,7 +206,7 @@ check_for_demasq(struct sk_buff **pskb)
} else { } else {
if (h) if (h)
/* Put back the reference gained from find_get */ /* Put back the reference gained from find_get */
nf_conntrack_put(&h->ctrack->infos[0]); nf_conntrack_put(&h->ctrack->ct_general);
ret = NF_ACCEPT; ret = NF_ACCEPT;
} }
......
...@@ -48,9 +48,8 @@ static unsigned int ip_nat_htable_size; ...@@ -48,9 +48,8 @@ static unsigned int ip_nat_htable_size;
static struct list_head *bysource; static struct list_head *bysource;
static struct list_head *byipsproto; static struct list_head *byipsproto;
LIST_HEAD(protos); struct ip_nat_protocol *ip_nat_protos[MAX_IP_NAT_PROTO];
extern struct ip_nat_protocol unknown_nat_protocol;
/* We keep extra hashes for each conntrack, for fast searching. */ /* We keep extra hashes for each conntrack, for fast searching. */
static inline size_t static inline size_t
...@@ -77,9 +76,6 @@ static void ip_nat_cleanup_conntrack(struct ip_conntrack *conn) ...@@ -77,9 +76,6 @@ static void ip_nat_cleanup_conntrack(struct ip_conntrack *conn)
if (!info->initialized) if (!info->initialized)
return; return;
IP_NF_ASSERT(info->bysource.conntrack);
IP_NF_ASSERT(info->byipsproto.conntrack);
hs = hash_by_src(&conn->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src, hs = hash_by_src(&conn->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src,
conn->tuplehash[IP_CT_DIR_ORIGINAL] conn->tuplehash[IP_CT_DIR_ORIGINAL]
.tuple.dst.protonum); .tuple.dst.protonum);
...@@ -90,8 +86,8 @@ static void ip_nat_cleanup_conntrack(struct ip_conntrack *conn) ...@@ -90,8 +86,8 @@ static void ip_nat_cleanup_conntrack(struct ip_conntrack *conn)
.tuple.dst.protonum); .tuple.dst.protonum);
WRITE_LOCK(&ip_nat_lock); WRITE_LOCK(&ip_nat_lock);
LIST_DELETE(&bysource[hs], &info->bysource); list_del(&info->bysource);
LIST_DELETE(&byipsproto[hp], &info->byipsproto); list_del(&info->byipsproto);
WRITE_UNLOCK(&ip_nat_lock); WRITE_UNLOCK(&ip_nat_lock);
} }
...@@ -106,23 +102,6 @@ ip_nat_cheat_check(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck) ...@@ -106,23 +102,6 @@ ip_nat_cheat_check(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
oldcheck^0xFFFF)); oldcheck^0xFFFF));
} }
static inline int cmp_proto(const struct ip_nat_protocol *i, int proto)
{
return i->protonum == proto;
}
struct ip_nat_protocol *
find_nat_proto(u_int16_t protonum)
{
struct ip_nat_protocol *i;
MUST_BE_READ_LOCKED(&ip_nat_lock);
i = LIST_FIND(&protos, cmp_proto, struct ip_nat_protocol *, protonum);
if (!i)
i = &unknown_nat_protocol;
return i;
}
/* Is this tuple already taken? (not by us) */ /* Is this tuple already taken? (not by us) */
int int
ip_nat_used_tuple(const struct ip_conntrack_tuple *tuple, ip_nat_used_tuple(const struct ip_conntrack_tuple *tuple,
...@@ -145,7 +124,7 @@ in_range(const struct ip_conntrack_tuple *tuple, ...@@ -145,7 +124,7 @@ in_range(const struct ip_conntrack_tuple *tuple,
const struct ip_conntrack_manip *manip, const struct ip_conntrack_manip *manip,
const struct ip_nat_multi_range *mr) const struct ip_nat_multi_range *mr)
{ {
struct ip_nat_protocol *proto = find_nat_proto(tuple->dst.protonum); struct ip_nat_protocol *proto = ip_nat_find_proto(tuple->dst.protonum);
unsigned int i; unsigned int i;
struct ip_conntrack_tuple newtuple = { *manip, tuple->dst }; struct ip_conntrack_tuple newtuple = { *manip, tuple->dst };
...@@ -171,20 +150,18 @@ in_range(const struct ip_conntrack_tuple *tuple, ...@@ -171,20 +150,18 @@ in_range(const struct ip_conntrack_tuple *tuple,
} }
static inline int static inline int
src_cmp(const struct ip_nat_hash *i, src_cmp(const struct ip_conntrack *ct,
const struct ip_conntrack_tuple *tuple, const struct ip_conntrack_tuple *tuple,
const struct ip_nat_multi_range *mr) const struct ip_nat_multi_range *mr)
{ {
return (i->conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum return (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum
== tuple->dst.protonum == tuple->dst.protonum
&& i->conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip && ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip
== tuple->src.ip == tuple->src.ip
&& i->conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.all && ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.all
== tuple->src.u.all == tuple->src.u.all
&& in_range(tuple, && in_range(tuple,
&i->conntrack->tuplehash[IP_CT_DIR_ORIGINAL] &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src, mr));
.tuple.src,
mr));
} }
/* Only called for SRC manip */ /* Only called for SRC manip */
...@@ -193,14 +170,13 @@ find_appropriate_src(const struct ip_conntrack_tuple *tuple, ...@@ -193,14 +170,13 @@ find_appropriate_src(const struct ip_conntrack_tuple *tuple,
const struct ip_nat_multi_range *mr) const struct ip_nat_multi_range *mr)
{ {
unsigned int h = hash_by_src(&tuple->src, tuple->dst.protonum); unsigned int h = hash_by_src(&tuple->src, tuple->dst.protonum);
struct ip_nat_hash *i; struct ip_conntrack *ct;
MUST_BE_READ_LOCKED(&ip_nat_lock); MUST_BE_READ_LOCKED(&ip_nat_lock);
i = LIST_FIND(&bysource[h], src_cmp, struct ip_nat_hash *, tuple, mr); list_for_each_entry(ct, &bysource[h], nat.info.bysource)
if (i) if (src_cmp(ct, tuple, mr))
return &i->conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src; return &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src;
else return NULL;
return NULL;
} }
#ifdef CONFIG_IP_NF_NAT_LOCAL #ifdef CONFIG_IP_NF_NAT_LOCAL
...@@ -226,19 +202,17 @@ do_extra_mangle(u_int32_t var_ip, u_int32_t *other_ipp) ...@@ -226,19 +202,17 @@ do_extra_mangle(u_int32_t var_ip, u_int32_t *other_ipp)
#endif #endif
/* Simple way to iterate through all. */ /* Simple way to iterate through all. */
static inline int fake_cmp(const struct ip_nat_hash *i, static inline int fake_cmp(const struct ip_conntrack *ct,
u_int32_t src, u_int32_t dst, u_int16_t protonum, u_int32_t src, u_int32_t dst, u_int16_t protonum,
unsigned int *score, unsigned int *score, const struct ip_conntrack *ct2)
const struct ip_conntrack *conntrack)
{ {
/* Compare backwards: we're dealing with OUTGOING tuples, and /* Compare backwards: we're dealing with OUTGOING tuples, and
inside the conntrack is the REPLY tuple. Don't count this inside the conntrack is the REPLY tuple. Don't count this
conntrack. */ conntrack. */
if (i->conntrack != conntrack if (ct != ct2
&& i->conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip == dst && ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip == dst
&& i->conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip == src && ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip == src
&& (i->conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum && (ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum == protonum))
== protonum))
(*score)++; (*score)++;
return 0; return 0;
} }
...@@ -247,13 +221,14 @@ static inline unsigned int ...@@ -247,13 +221,14 @@ static inline unsigned int
count_maps(u_int32_t src, u_int32_t dst, u_int16_t protonum, count_maps(u_int32_t src, u_int32_t dst, u_int16_t protonum,
const struct ip_conntrack *conntrack) const struct ip_conntrack *conntrack)
{ {
struct ip_conntrack *ct;
unsigned int score = 0; unsigned int score = 0;
unsigned int h; unsigned int h;
MUST_BE_READ_LOCKED(&ip_nat_lock); MUST_BE_READ_LOCKED(&ip_nat_lock);
h = hash_by_ipsproto(src, dst, protonum); h = hash_by_ipsproto(src, dst, protonum);
LIST_FIND(&byipsproto[h], fake_cmp, struct ip_nat_hash *, list_for_each_entry(ct, &byipsproto[h], nat.info.byipsproto)
src, dst, protonum, &score, conntrack); fake_cmp(ct, src, dst, protonum, &score, conntrack);
return score; return score;
} }
...@@ -401,7 +376,7 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple, ...@@ -401,7 +376,7 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple,
unsigned int hooknum) unsigned int hooknum)
{ {
struct ip_nat_protocol *proto struct ip_nat_protocol *proto
= find_nat_proto(orig_tuple->dst.protonum); = ip_nat_find_proto(orig_tuple->dst.protonum);
struct ip_nat_range *rptr; struct ip_nat_range *rptr;
unsigned int i; unsigned int i;
int ret; int ret;
...@@ -640,12 +615,10 @@ ip_nat_setup_info(struct ip_conntrack *conntrack, ...@@ -640,12 +615,10 @@ ip_nat_setup_info(struct ip_conntrack *conntrack,
/* It's done. */ /* It's done. */
info->initialized |= (1 << HOOK2MANIP(hooknum)); info->initialized |= (1 << HOOK2MANIP(hooknum));
if (in_hashes) { if (in_hashes)
IP_NF_ASSERT(info->bysource.conntrack);
replace_in_hashes(conntrack, info); replace_in_hashes(conntrack, info);
} else { else
place_in_hashes(conntrack, info); place_in_hashes(conntrack, info);
}
return NF_ACCEPT; return NF_ACCEPT;
} }
...@@ -669,14 +642,9 @@ void replace_in_hashes(struct ip_conntrack *conntrack, ...@@ -669,14 +642,9 @@ void replace_in_hashes(struct ip_conntrack *conntrack,
conntrack->tuplehash[IP_CT_DIR_REPLY] conntrack->tuplehash[IP_CT_DIR_REPLY]
.tuple.dst.protonum); .tuple.dst.protonum);
IP_NF_ASSERT(info->bysource.conntrack == conntrack);
MUST_BE_WRITE_LOCKED(&ip_nat_lock); MUST_BE_WRITE_LOCKED(&ip_nat_lock);
list_move(&info->bysource, &bysource[srchash]);
list_del(&info->bysource.list); list_move(&info->byipsproto, &byipsproto[ipsprotohash]);
list_del(&info->byipsproto.list);
list_prepend(&bysource[srchash], &info->bysource);
list_prepend(&byipsproto[ipsprotohash], &info->byipsproto);
} }
void place_in_hashes(struct ip_conntrack *conntrack, void place_in_hashes(struct ip_conntrack *conntrack,
...@@ -697,14 +665,9 @@ void place_in_hashes(struct ip_conntrack *conntrack, ...@@ -697,14 +665,9 @@ void place_in_hashes(struct ip_conntrack *conntrack,
conntrack->tuplehash[IP_CT_DIR_REPLY] conntrack->tuplehash[IP_CT_DIR_REPLY]
.tuple.dst.protonum); .tuple.dst.protonum);
IP_NF_ASSERT(!info->bysource.conntrack);
MUST_BE_WRITE_LOCKED(&ip_nat_lock); MUST_BE_WRITE_LOCKED(&ip_nat_lock);
info->byipsproto.conntrack = conntrack; list_add(&info->bysource, &bysource[srchash]);
info->bysource.conntrack = conntrack; list_add(&info->byipsproto, &byipsproto[ipsprotohash]);
list_prepend(&bysource[srchash], &info->bysource);
list_prepend(&byipsproto[ipsprotohash], &info->byipsproto);
} }
/* Returns true if succeeded. */ /* Returns true if succeeded. */
...@@ -724,9 +687,8 @@ manip_pkt(u_int16_t proto, ...@@ -724,9 +687,8 @@ manip_pkt(u_int16_t proto,
iph = (void *)(*pskb)->data + iphdroff; iph = (void *)(*pskb)->data + iphdroff;
/* Manipulate protcol part. */ /* Manipulate protcol part. */
if (!find_nat_proto(proto)->manip_pkt(pskb, if (!ip_nat_find_proto(proto)->manip_pkt(pskb, iphdroff + iph->ihl*4,
iphdroff + iph->ihl*4, manip, maniptype))
manip, maniptype))
return 0; return 0;
iph = (void *)(*pskb)->data + iphdroff; iph = (void *)(*pskb)->data + iphdroff;
...@@ -750,7 +712,7 @@ static inline int exp_for_packet(struct ip_conntrack_expect *exp, ...@@ -750,7 +712,7 @@ static inline int exp_for_packet(struct ip_conntrack_expect *exp,
int ret = 1; int ret = 1;
MUST_BE_READ_LOCKED(&ip_conntrack_lock); MUST_BE_READ_LOCKED(&ip_conntrack_lock);
proto = __ip_ct_find_proto(skb->nh.iph->protocol); proto = ip_ct_find_proto(skb->nh.iph->protocol);
if (proto->exp_matches_pkt) if (proto->exp_matches_pkt)
ret = proto->exp_matches_pkt(exp, skb); ret = proto->exp_matches_pkt(exp, skb);
...@@ -890,12 +852,8 @@ icmp_reply_translation(struct sk_buff **pskb, ...@@ -890,12 +852,8 @@ icmp_reply_translation(struct sk_buff **pskb,
} }
/* Must be RELATED */ /* Must be RELATED */
IP_NF_ASSERT((*pskb)->nfct IP_NF_ASSERT((*pskb)->nfctinfo == IP_CT_RELATED ||
- ((struct ip_conntrack *)(*pskb)->nfct->master)->infos (*pskb)->nfctinfo == IP_CT_RELATED+IP_CT_IS_REPLY);
== IP_CT_RELATED
|| (*pskb)->nfct
- ((struct ip_conntrack *)(*pskb)->nfct->master)->infos
== IP_CT_RELATED+IP_CT_IS_REPLY);
/* Redirects on non-null nats must be dropped, else they'll /* Redirects on non-null nats must be dropped, else they'll
start talking to each other without our translation, and be start talking to each other without our translation, and be
...@@ -995,9 +953,11 @@ int __init ip_nat_init(void) ...@@ -995,9 +953,11 @@ int __init ip_nat_init(void)
/* Sew in builtin protocols. */ /* Sew in builtin protocols. */
WRITE_LOCK(&ip_nat_lock); WRITE_LOCK(&ip_nat_lock);
list_append(&protos, &ip_nat_protocol_tcp); for (i = 0; i < MAX_IP_NAT_PROTO; i++)
list_append(&protos, &ip_nat_protocol_udp); ip_nat_protos[i] = &ip_nat_unknown_protocol;
list_append(&protos, &ip_nat_protocol_icmp); ip_nat_protos[IPPROTO_TCP] = &ip_nat_protocol_tcp;
ip_nat_protos[IPPROTO_UDP] = &ip_nat_protocol_udp;
ip_nat_protos[IPPROTO_ICMP] = &ip_nat_protocol_icmp;
WRITE_UNLOCK(&ip_nat_lock); WRITE_UNLOCK(&ip_nat_lock);
for (i = 0; i < ip_nat_htable_size; i++) { for (i = 0; i < ip_nat_htable_size; i++) {
......
...@@ -104,7 +104,7 @@ icmp_print_range(char *buffer, const struct ip_nat_range *range) ...@@ -104,7 +104,7 @@ icmp_print_range(char *buffer, const struct ip_nat_range *range)
} }
struct ip_nat_protocol ip_nat_protocol_icmp struct ip_nat_protocol ip_nat_protocol_icmp
= { { NULL, NULL }, "ICMP", IPPROTO_ICMP, = { "ICMP", IPPROTO_ICMP,
icmp_manip_pkt, icmp_manip_pkt,
icmp_in_range, icmp_in_range,
icmp_unique_tuple, icmp_unique_tuple,
......
...@@ -162,7 +162,7 @@ tcp_print_range(char *buffer, const struct ip_nat_range *range) ...@@ -162,7 +162,7 @@ tcp_print_range(char *buffer, const struct ip_nat_range *range)
} }
struct ip_nat_protocol ip_nat_protocol_tcp struct ip_nat_protocol ip_nat_protocol_tcp
= { { NULL, NULL }, "TCP", IPPROTO_TCP, = { "TCP", IPPROTO_TCP,
tcp_manip_pkt, tcp_manip_pkt,
tcp_in_range, tcp_in_range,
tcp_unique_tuple, tcp_unique_tuple,
......
...@@ -148,7 +148,7 @@ udp_print_range(char *buffer, const struct ip_nat_range *range) ...@@ -148,7 +148,7 @@ udp_print_range(char *buffer, const struct ip_nat_range *range)
} }
struct ip_nat_protocol ip_nat_protocol_udp struct ip_nat_protocol ip_nat_protocol_udp
= { { NULL, NULL }, "UDP", IPPROTO_UDP, = { "UDP", IPPROTO_UDP,
udp_manip_pkt, udp_manip_pkt,
udp_in_range, udp_in_range,
udp_unique_tuple, udp_unique_tuple,
......
...@@ -60,8 +60,8 @@ unknown_print_range(char *buffer, const struct ip_nat_range *range) ...@@ -60,8 +60,8 @@ unknown_print_range(char *buffer, const struct ip_nat_range *range)
return 0; return 0;
} }
struct ip_nat_protocol unknown_nat_protocol = { struct ip_nat_protocol ip_nat_unknown_protocol = {
{ NULL, NULL }, "unknown", 0, "unknown", 0,
unknown_manip_pkt, unknown_manip_pkt,
unknown_in_range, unknown_in_range,
unknown_unique_tuple, unknown_unique_tuple,
......
...@@ -283,18 +283,13 @@ static struct nf_hook_ops ip_nat_local_in_ops = { ...@@ -283,18 +283,13 @@ static struct nf_hook_ops ip_nat_local_in_ops = {
int ip_nat_protocol_register(struct ip_nat_protocol *proto) int ip_nat_protocol_register(struct ip_nat_protocol *proto)
{ {
int ret = 0; int ret = 0;
struct list_head *i;
WRITE_LOCK(&ip_nat_lock); WRITE_LOCK(&ip_nat_lock);
list_for_each(i, &protos) { if (ip_nat_protos[proto->protonum] != &ip_nat_unknown_protocol) {
if (((struct ip_nat_protocol *)i)->protonum ret = -EBUSY;
== proto->protonum) { goto out;
ret = -EBUSY;
goto out;
}
} }
ip_nat_protos[proto->protonum] = proto;
list_prepend(&protos, proto);
out: out:
WRITE_UNLOCK(&ip_nat_lock); WRITE_UNLOCK(&ip_nat_lock);
return ret; return ret;
...@@ -304,7 +299,7 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto) ...@@ -304,7 +299,7 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto)
void ip_nat_protocol_unregister(struct ip_nat_protocol *proto) void ip_nat_protocol_unregister(struct ip_nat_protocol *proto)
{ {
WRITE_LOCK(&ip_nat_lock); WRITE_LOCK(&ip_nat_lock);
LIST_DELETE(&protos, proto); ip_nat_protos[proto->protonum] = &ip_nat_unknown_protocol;
WRITE_UNLOCK(&ip_nat_lock); WRITE_UNLOCK(&ip_nat_lock);
/* Someone could be still looking at the proto in a bh. */ /* Someone could be still looking at the proto in a bh. */
......
...@@ -23,7 +23,8 @@ target(struct sk_buff **pskb, ...@@ -23,7 +23,8 @@ target(struct sk_buff **pskb,
If there is a real ct entry correspondig to this packet, If there is a real ct entry correspondig to this packet,
it'll hang aroun till timing out. We don't deal with it it'll hang aroun till timing out. We don't deal with it
for performance reasons. JK */ for performance reasons. JK */
(*pskb)->nfct = &ip_conntrack_untracked.infos[IP_CT_NEW]; (*pskb)->nfct = &ip_conntrack_untracked.ct_general;
(*pskb)->nfctinfo = IP_CT_NEW;
nf_conntrack_get((*pskb)->nfct); nf_conntrack_get((*pskb)->nfct);
return IPT_CONTINUE; return IPT_CONTINUE;
......
...@@ -41,14 +41,14 @@ MODULE_DESCRIPTION("iptables REJECT target module"); ...@@ -41,14 +41,14 @@ MODULE_DESCRIPTION("iptables REJECT target module");
/* If the original packet is part of a connection, but the connection /* If the original packet is part of a connection, but the connection
is not confirmed, our manufactured reply will not be associated is not confirmed, our manufactured reply will not be associated
with it, so we need to do this manually. */ with it, so we need to do this manually. */
static void connection_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct) static void connection_attach(struct sk_buff *new_skb, struct sk_buff *skb)
{ {
void (*attach)(struct sk_buff *, struct nf_ct_info *); void (*attach)(struct sk_buff *, struct sk_buff *);
/* Avoid module unload race with ip_ct_attach being NULLed out */ /* Avoid module unload race with ip_ct_attach being NULLed out */
if (nfct && (attach = ip_ct_attach) != NULL) { if (skb->nfct && (attach = ip_ct_attach) != NULL) {
mb(); /* Just to be sure: must be read before executing this */ mb(); /* Just to be sure: must be read before executing this */
attach(new_skb, nfct); attach(new_skb, skb);
} }
} }
...@@ -209,7 +209,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) ...@@ -209,7 +209,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
if (nskb->len > dst_pmtu(nskb->dst)) if (nskb->len > dst_pmtu(nskb->dst))
goto free_nskb; goto free_nskb;
connection_attach(nskb, oldskb->nfct); connection_attach(nskb, oldskb);
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev, NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
ip_finish_output); ip_finish_output);
...@@ -360,7 +360,7 @@ static void send_unreach(struct sk_buff *skb_in, int code) ...@@ -360,7 +360,7 @@ static void send_unreach(struct sk_buff *skb_in, int code)
icmph->checksum = ip_compute_csum((unsigned char *)icmph, icmph->checksum = ip_compute_csum((unsigned char *)icmph,
length - sizeof(struct iphdr)); length - sizeof(struct iphdr));
connection_attach(nskb, skb_in->nfct); connection_attach(nskb, skb_in);
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev, NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
ip_finish_output); ip_finish_output);
......
/*
* Implements a dummy match to allow attaching comments to rules
*
* 2003-05-13 Brad Fisher (brad@info-link.net)
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_comment.h>
MODULE_AUTHOR("Brad Fisher <brad@info-link.net>");
MODULE_DESCRIPTION("iptables comment match module");
MODULE_LICENSE("GPL");
static int
match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
int *hotdrop)
{
/* We always match */
return 1;
}
static int
checkentry(const char *tablename,
const struct ipt_ip *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
/* Check the size */
if (matchsize != IPT_ALIGN(sizeof(struct ipt_comment_info)))
return 0;
return 1;
}
static struct ipt_match comment_match = {
.name = "comment",
.match = match,
.checkentry = checkentry,
.me = THIS_MODULE
};
static int __init init(void)
{
return ipt_register_match(&comment_match);
}
static void __exit fini(void)
{
ipt_unregister_match(&comment_match);
}
module_init(init);
module_exit(fini);
...@@ -35,7 +35,7 @@ match(const struct sk_buff *skb, ...@@ -35,7 +35,7 @@ match(const struct sk_buff *skb,
#define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW]) if (ct == &ip_conntrack_untracked)
statebit = IPT_CONNTRACK_STATE_UNTRACKED; statebit = IPT_CONNTRACK_STATE_UNTRACKED;
else if (ct) else if (ct)
statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
......
...@@ -30,9 +30,9 @@ match(const struct sk_buff *skb, ...@@ -30,9 +30,9 @@ match(const struct sk_buff *skb,
enum ip_conntrack_info ctinfo; enum ip_conntrack_info ctinfo;
unsigned int statebit; unsigned int statebit;
if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW]) if (skb->nfct == &ip_conntrack_untracked.ct_general)
statebit = IPT_STATE_UNTRACKED; statebit = IPT_STATE_UNTRACKED;
else if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo)) else if (!ip_conntrack_get(skb, &ctinfo))
statebit = IPT_STATE_INVALID; statebit = IPT_STATE_INVALID;
else else
statebit = IPT_STATE_BIT(ctinfo); statebit = IPT_STATE_BIT(ctinfo);
......
...@@ -477,6 +477,7 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) ...@@ -477,6 +477,7 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
/* Connection association is same as pre-frag packet */ /* Connection association is same as pre-frag packet */
to->nfct = from->nfct; to->nfct = from->nfct;
nf_conntrack_get(to->nfct); nf_conntrack_get(to->nfct);
to->nfctinfo = from->nfctinfo;
#ifdef CONFIG_BRIDGE_NETFILTER #ifdef CONFIG_BRIDGE_NETFILTER
nf_bridge_put(to->nf_bridge); nf_bridge_put(to->nf_bridge);
to->nf_bridge = from->nf_bridge; to->nf_bridge = from->nf_bridge;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment