Commit 7cfb7fc4 authored by Rusty Russell's avatar Rusty Russell Committed by David S. Miller

[NETFILTER]: Use a bit in conntrack status to indicate sequence number adjustment

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.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f97bf1b1
......@@ -51,6 +51,10 @@ enum ip_conntrack_status {
/* 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__
......
......@@ -354,9 +354,7 @@ unsigned int nat_packet(struct ip_conntrack *ct,
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,
......
......@@ -192,11 +192,14 @@ ip_nat_mangle_tcp_packet(struct sk_buff **pskb,
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 @@ ip_nat_seq_adjust(struct sk_buff **pskb,
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;
......
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