Skip to contentSkip to conversation

Netfilter: Use a bit in conntrack status to indicate sequence number adjustment

PATCH Applied Rusty Russell 1 participant 1 message Jan 11, 2005

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 2/3 Netfilter: Use a bit in conntrack status to indicate sequence number adjustment

Name: Use a bit in conntrack status to indicate sequence number adjustment
Status: Tested under nfsim

Rather than calling the sequence adjustment code on every connection which has a helper, we can set a status bit on the conntrack when we change the length of a TCP packet, and use that to indicate that we should call the routine.

net/ipv4/netfilter/ip_nat_core.c +1 -3
Index: linux-2.6.10-bk13-Netfilter/net/ipv4/netfilter/ip_nat_core.c
===================================================================
@@ -354,9 +354,7 @@
 	unsigned long statusbit;
 	enum ip_nat_manip_type mtype = HOOK2MANIP(hooknum);
 
-	/* FIXME: use a bit in status for this. */
-	if (ct->helper
-	    && ct->tuplehash[0].tuple.dst.protonum == IPPROTO_TCP
+	if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)
 	    && (hooknum == NF_IP_POST_ROUTING || hooknum == NF_IP_LOCAL_IN)) {
 		DEBUGP("ip_nat_core: adjusting sequence number\n");
 		/* future: put this in a l4-proto specific function,
net/ipv4/netfilter/ip_nat_helper.c +8 -10
Index: linux-2.6.10-bk13-Netfilter/net/ipv4/netfilter/ip_nat_helper.c
===================================================================
@@ -192,11 +192,14 @@
 	tcph->check = tcp_v4_check(tcph, datalen, iph->saddr, iph->daddr,
 				   csum_partial((char *)tcph, datalen, 0));
 
-	adjust_tcp_sequence(ntohl(tcph->seq),
-			    (int)rep_len - (int)match_len,
-			    ct, ctinfo);
-	/* Tell connection tracking about seq change, to expand window */
-	ip_conntrack_tcp_update(*pskb, ct, CTINFO2DIR(ctinfo));
+	if (rep_len != match_len) {
+		set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
+		adjust_tcp_sequence(ntohl(tcph->seq),
+				    (int)rep_len - (int)match_len,
+				    ct, ctinfo);
+		/* Tell TCP window tracking about seq change */
+		ip_conntrack_tcp_update(*pskb, ct, CTINFO2DIR(ctinfo));
+	}
 	return 1;
 }
 			
@@ -363,11 +366,6 @@
 	this_way = &ct->nat.info.seq[dir];
 	other_way = &ct->nat.info.seq[!dir];
 
-	/* No adjustments to make?  Very common case. */
-	if (!this_way->offset_before && !this_way->offset_after
-	    && !other_way->offset_before && !other_way->offset_after)
-		return 1;
-
 	if (!skb_ip_make_writable(pskb, (*pskb)->nh.iph->ihl*4+sizeof(*tcph)))
 		return 0;
 
include/linux/netfilter_ipv4/ip_conntrack.h +4 -0
Index: linux-2.6.10-bk13-Netfilter/include/linux/netfilter_ipv4/ip_conntrack.h
===================================================================
@@ -51,6 +51,10 @@
 
 	/* Both together. */
 	IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
+
+	/* Connection needs TCP sequence adjusted. */
+	IPS_SEQ_ADJUST_BIT = 6,
+	IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
 };
 
 #ifdef __KERNEL__