Commit 4c88c4e3 authored by Rusty Russell's avatar Rusty Russell Committed by David S. Miller

[NETFILTER]: Get rid of 'initialized' in nat structure: use conntrack status bits

Fairly simple patch to move the 'initialized' NAT bitfield to bits in
the 'status' word.  This saves the size of a pointer from the
connection tracking structure.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7cfb7fc4
......@@ -55,6 +55,16 @@ enum ip_conntrack_status {
/* Connection needs TCP sequence adjusted. */
IPS_SEQ_ADJUST_BIT = 6,
IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
/* NAT initialization bits. */
IPS_SRC_NAT_DONE_BIT = 7,
IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
IPS_DST_NAT_DONE_BIT = 8,
IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
/* Both together */
IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
};
#ifdef __KERNEL__
......@@ -291,5 +301,12 @@ struct ip_conntrack_stat
#define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++)
static inline int ip_nat_initialized(struct ip_conntrack *conntrack,
enum ip_nat_manip_type manip)
{
if (manip == IP_NAT_MANIP_SRC)
return test_bit(IPS_SRC_NAT_DONE_BIT, &conntrack->status);
return test_bit(IPS_DST_NAT_DONE_BIT, &conntrack->status);
}
#endif /* __KERNEL__ */
#endif /* _IP_CONNTRACK_H */
......@@ -55,9 +55,6 @@ struct ip_nat_multi_range_compat
/* The structure embedded in the conntrack structure. */
struct ip_nat_info
{
/* Set to zero when conntrack created: bitmask of maniptypes */
u_int16_t initialized;
struct list_head bysource;
/* Helper (NULL if none). */
......
......@@ -62,13 +62,11 @@ hash_by_src(const struct ip_conntrack_tuple *tuple)
/* Noone using conntrack by the time this called. */
static void ip_nat_cleanup_conntrack(struct ip_conntrack *conn)
{
struct ip_nat_info *info = &conn->nat.info;
if (!info->initialized)
if (!(conn->status & IPS_NAT_DONE_MASK))
return;
WRITE_LOCK(&ip_nat_lock);
list_del(&info->bysource);
list_del(&conn->nat.info.bysource);
WRITE_UNLOCK(&ip_nat_lock);
}
......@@ -261,14 +259,14 @@ ip_nat_setup_info(struct ip_conntrack *conntrack,
{
struct ip_conntrack_tuple curr_tuple, new_tuple;
struct ip_nat_info *info = &conntrack->nat.info;
int have_to_hash = !info->initialized;
int have_to_hash = !(conntrack->status & IPS_NAT_DONE_MASK);
enum ip_nat_manip_type maniptype = HOOK2MANIP(hooknum);
IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
|| hooknum == NF_IP_POST_ROUTING
|| hooknum == NF_IP_LOCAL_IN
|| hooknum == NF_IP_LOCAL_OUT);
IP_NF_ASSERT(!(info->initialized & (1 << maniptype)));
BUG_ON(ip_nat_initialized(conntrack, maniptype));
/* What we've got will look like inverse of reply. Normally
this is what is in the conntrack, except for prior
......@@ -305,7 +303,11 @@ ip_nat_setup_info(struct ip_conntrack *conntrack,
}
/* It's done. */
info->initialized |= (1 << maniptype);
if (maniptype == IP_NAT_MANIP_DST)
set_bit(IPS_DST_NAT_DONE_BIT, &conntrack->status);
else
set_bit(IPS_SRC_NAT_DONE_BIT, &conntrack->status);
return NF_ACCEPT;
}
......@@ -420,10 +422,11 @@ int icmp_reply_translation(struct sk_buff **pskb,
start talking to each other without our translation, and be
confused... --RR */
if (inside->icmp.type == ICMP_REDIRECT) {
/* Don't care about races here. */
if (ct->nat.info.initialized
!= ((1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST))
|| (ct->status & IPS_NAT_MASK))
/* If NAT isn't finished, assume it and drop. */
if ((ct->status & IPS_NAT_DONE_MASK) != IPS_NAT_DONE_MASK)
return 0;
if (ct->status & IPS_NAT_MASK)
return 0;
}
......@@ -505,9 +508,7 @@ int __init ip_nat_init(void)
ip_conntrack_destroyed = &ip_nat_cleanup_conntrack;
/* Initialize fake conntrack so that NAT will skip it */
ip_conntrack_untracked.nat.info.initialized |=
(1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST);
ip_conntrack_untracked.status |= IPS_NAT_DONE_MASK;
return 0;
}
......
......@@ -411,7 +411,7 @@ void ip_nat_follow_master(struct ip_conntrack *ct,
struct ip_nat_range range;
/* This must be a fresh one. */
BUG_ON(ct->nat.info.initialized);
BUG_ON(ct->status & IPS_NAT_DONE_MASK);
/* Change src to where master sends to */
range.flags = IP_NAT_RANGE_MAP_IPS;
......
......@@ -267,7 +267,7 @@ int ip_nat_rule_find(struct sk_buff **pskb,
ret = ipt_do_table(pskb, hooknum, in, out, &nat_table, NULL);
if (ret == NF_ACCEPT) {
if (!(info->initialized & (1 << HOOK2MANIP(hooknum))))
if (!ip_nat_initialized(ct, HOOK2MANIP(hooknum)))
/* NUL mapping */
ret = alloc_null_binding(ct, info, hooknum);
}
......
......@@ -118,7 +118,7 @@ ip_nat_fn(unsigned int hooknum,
/* Seen it before? This can happen for loopback, retrans,
or local packets.. */
if (!(info->initialized & (1 << maniptype))) {
if (!ip_nat_initialized(ct, maniptype)) {
unsigned int ret;
/* LOCAL_IN hook doesn't have a chain! */
......
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