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