Netfilter: Get rid of initialized in nat structure: use conntrack status bits
Subsystems (2)
PATCH 3/3 Netfilter: Get rid of initialized in nat structure: use conntrack status bits
Name: Get rid of initialized in nat structure: use conntrack status bits
Status: Tested under nfsim
Signed-off-by Rusty Russell <[email protected]>
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.
net/ipv4/netfilter/ip_nat_core.c +16 -15
@@ -62,13 +62,11 @@/* 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 @@ {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 @@ }/* 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 @@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 ; }
@@ -503,11 +506,9 @@/* FIXME: Man, this is a hack. <SIGH> */ IP_NF_ASSERT (ip_conntrack_destroyed ==NULL ); 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 ); +/* Initialize fake conntrack so that NAT will skip it */ + ip_conntrack_untracked.status |=IPS_NAT_DONE_MASK ;return 0 ; }
net/ipv4/netfilter/ip_nat_helper.c +1 -1
@@ -411,7 +411,7 @@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 ;
net/ipv4/netfilter/ip_nat_rule.c +1 -1
@@ -287,7 +287,7 @@ 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); }
include/linux/netfilter_ipv4/ip_nat.h +0 -3
@@ -55,9 +55,6 @@/* 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). */
include/linux/netfilter_ipv4/ip_conntrack.h +17 -0
@@ -55,6 +55,16 @@/* 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 @@#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 */
net/ipv4/netfilter/ip_nat_standalone.c +1 -1
@@ -118,7 +118,7 @@/* 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! */