Commit 6220ce1e authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[NETFILTER]: kill struct ip_nat_hash, saves two pointers per conntrack

The back-pointer is not needed when using list.h macros.
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 789575b2
...@@ -80,15 +80,6 @@ struct ip_nat_info_manip ...@@ -80,15 +80,6 @@ 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
{ {
...@@ -100,7 +91,7 @@ struct ip_nat_info ...@@ -100,7 +91,7 @@ struct ip_nat_info
/* 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;
......
...@@ -77,9 +77,6 @@ static void ip_nat_cleanup_conntrack(struct ip_conntrack *conn) ...@@ -77,9 +77,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 +87,8 @@ static void ip_nat_cleanup_conntrack(struct ip_conntrack *conn) ...@@ -90,8 +87,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);
} }
...@@ -171,20 +168,18 @@ in_range(const struct ip_conntrack_tuple *tuple, ...@@ -171,20 +168,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 +188,13 @@ find_appropriate_src(const struct ip_conntrack_tuple *tuple, ...@@ -193,14 +188,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 +220,17 @@ do_extra_mangle(u_int32_t var_ip, u_int32_t *other_ipp) ...@@ -226,19 +220,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 +239,14 @@ static inline unsigned int ...@@ -247,13 +239,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;
} }
...@@ -640,12 +633,10 @@ ip_nat_setup_info(struct ip_conntrack *conntrack, ...@@ -640,12 +633,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 +660,9 @@ void replace_in_hashes(struct ip_conntrack *conntrack, ...@@ -669,14 +660,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 +683,9 @@ void place_in_hashes(struct ip_conntrack *conntrack, ...@@ -697,14 +683,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. */
......
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