]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/netfilter/ip_conntrack_proto_tcp.c
[NETFILTER]: add IPv6-capable TCPMSS target
[linux-2.6-omap-h63xx.git] / net / ipv4 / netfilter / ip_conntrack_proto_tcp.c
index c5c2ce5cdeb88205ea3a17dc48d12dea4af3a5c3..c34f48fe547875e5bb48f9552526dd257eb79cfb 100644 (file)
@@ -19,7 +19,6 @@
  * version 2.2
  */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
@@ -49,19 +48,16 @@ static DEFINE_RWLOCK(tcp_lock);
 /* "Be conservative in what you do, 
     be liberal in what you accept from others." 
     If it's non-zero, we mark only out of window RST segments as INVALID. */
-int ip_ct_tcp_be_liberal = 0;
+int ip_ct_tcp_be_liberal __read_mostly = 0;
 
-/* When connection is picked up from the middle, how many packets are required
-   to pass in each direction when we assume we are in sync - if any side uses
-   window scaling, we lost the game. 
-   If it is set to zero, we disable picking up already established 
+/* If it is set to zero, we disable picking up already established
    connections. */
-int ip_ct_tcp_loose = 3;
+int ip_ct_tcp_loose __read_mostly = 1;
 
 /* Max number of the retransmitted packets without receiving an (acceptable) 
    ACK from the destination. If this number is reached, a shorter timer 
    will be started. */
-int ip_ct_tcp_max_retrans = 3;
+int ip_ct_tcp_max_retrans __read_mostly = 3;
 
   /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
      closely.  They're more complex. --RR */
@@ -84,19 +80,19 @@ static const char *tcp_conntrack_names[] = {
 #define HOURS * 60 MINS
 #define DAYS * 24 HOURS
 
-unsigned int ip_ct_tcp_timeout_syn_sent =      2 MINS;
-unsigned int ip_ct_tcp_timeout_syn_recv =     60 SECS;
-unsigned int ip_ct_tcp_timeout_established =   5 DAYS;
-unsigned int ip_ct_tcp_timeout_fin_wait =      2 MINS;
-unsigned int ip_ct_tcp_timeout_close_wait =   60 SECS;
-unsigned int ip_ct_tcp_timeout_last_ack =     30 SECS;
-unsigned int ip_ct_tcp_timeout_time_wait =     2 MINS;
-unsigned int ip_ct_tcp_timeout_close =        10 SECS;
+unsigned int ip_ct_tcp_timeout_syn_sent __read_mostly =      2 MINS;
+unsigned int ip_ct_tcp_timeout_syn_recv __read_mostly =     60 SECS;
+unsigned int ip_ct_tcp_timeout_established __read_mostly =   5 DAYS;
+unsigned int ip_ct_tcp_timeout_fin_wait __read_mostly =      2 MINS;
+unsigned int ip_ct_tcp_timeout_close_wait __read_mostly =   60 SECS;
+unsigned int ip_ct_tcp_timeout_last_ack __read_mostly =     30 SECS;
+unsigned int ip_ct_tcp_timeout_time_wait __read_mostly =     2 MINS;
+unsigned int ip_ct_tcp_timeout_close __read_mostly =        10 SECS;
 
 /* RFC1122 says the R2 limit should be at least 100 seconds.
    Linux uses 15 packets as limit, which corresponds 
    to ~13-30min depending on RTO. */
-unsigned int ip_ct_tcp_timeout_max_retrans =     5 MINS;
+unsigned int ip_ct_tcp_timeout_max_retrans __read_mostly =   5 MINS;
  
 static const unsigned int * tcp_timeouts[]
 = { NULL,                              /*      TCP_CONNTRACK_NONE */
@@ -520,8 +516,8 @@ static void tcp_sack(const struct sk_buff *skb,
 
        /* Fast path for timestamp-only option */
        if (length == TCPOLEN_TSTAMP_ALIGNED*4
-           && *(__u32 *)ptr ==
-               __constant_ntohl((TCPOPT_NOP << 24) 
+           && *(__be32 *)ptr ==
+               __constant_htonl((TCPOPT_NOP << 24)
                                 | (TCPOPT_NOP << 16)
                                 | (TCPOPT_TIMESTAMP << 8)
                                 | TCPOLEN_TIMESTAMP))
@@ -552,7 +548,7 @@ static void tcp_sack(const struct sk_buff *skb,
                                for (i = 0;
                                     i < (opsize - TCPOLEN_SACK_BASE);
                                     i += TCPOLEN_SACK_PERBLOCK) {
-                                       tmp = ntohl(*((u_int32_t *)(ptr+i)+1));
+                                       tmp = ntohl(*((__be32 *)(ptr+i)+1));
                                        
                                        if (after(tmp, *sack))
                                                *sack = tmp;
@@ -695,11 +691,10 @@ static int tcp_in_window(struct ip_ct_tcp *state,
                before(sack, receiver->td_end + 1),
                after(ack, receiver->td_end - MAXACKWINDOW(sender)));
        
-       if (sender->loose || receiver->loose ||
-           (before(seq, sender->td_maxend + 1) &&
-            after(end, sender->td_end - receiver->td_maxwin - 1) &&
-            before(sack, receiver->td_end + 1) &&
-            after(ack, receiver->td_end - MAXACKWINDOW(sender)))) {
+       if (before(seq, sender->td_maxend + 1) &&
+           after(end, sender->td_end - receiver->td_maxwin - 1) &&
+           before(sack, receiver->td_end + 1) &&
+           after(ack, receiver->td_end - MAXACKWINDOW(sender))) {
                /*
                 * Take into account window scaling (RFC 1323).
                 */
@@ -732,25 +727,25 @@ static int tcp_in_window(struct ip_ct_tcp *state,
                        if (state->last_dir == dir
                            && state->last_seq == seq
                            && state->last_ack == ack
-                           && state->last_end == end)
+                           && state->last_end == end
+                           && state->last_win == win)
                                state->retrans++;
                        else {
                                state->last_dir = dir;
                                state->last_seq = seq;
                                state->last_ack = ack;
                                state->last_end = end;
+                               state->last_win = win;
                                state->retrans = 0;
                        }
                }
-               /*
-                * Close the window of disabled window tracking :-)
-                */
-               if (sender->loose)
-                       sender->loose--;
-               
                res = 1;
        } else {
-               if (LOG_INVALID(IPPROTO_TCP))
+               res = 0;
+               if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
+                   ip_ct_tcp_be_liberal)
+                       res = 1;
+               if (!res && LOG_INVALID(IPPROTO_TCP))
                        nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
                        "ip_ct_tcp: %s ",
                        before(seq, sender->td_maxend + 1) ?
@@ -761,8 +756,6 @@ static int tcp_in_window(struct ip_ct_tcp *state,
                        : "ACK is over the upper bound (ACKed data not seen yet)"
                        : "SEQ is under the lower bound (already ACKed data retransmitted)"
                        : "SEQ is over the upper bound (over the window of the receiver)");
-
-               res = ip_ct_tcp_be_liberal;
        }
   
        DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
@@ -866,8 +859,7 @@ static int tcp_error(struct sk_buff *skb,
   
        /* Checksum invalid? Ignore.
         * We skip checking packets on the outgoing path
-        * because the semantic of CHECKSUM_HW is different there 
-        * and moreover root might send raw packets.
+        * because it is assumed to be correct.
         */
        /* FIXME: Source route IP option packets --RR */
        if (ip_conntrack_checksum && hooknum == NF_IP_PRE_ROUTING &&
@@ -1105,8 +1097,6 @@ static int tcp_new(struct ip_conntrack *conntrack,
 
                tcp_options(skb, iph, th, &conntrack->proto.tcp.seen[0]);
                conntrack->proto.tcp.seen[1].flags = 0;
-               conntrack->proto.tcp.seen[0].loose = 
-               conntrack->proto.tcp.seen[1].loose = 0;
        } else if (ip_ct_tcp_loose == 0) {
                /* Don't try to pick up connections. */
                return 0;
@@ -1127,11 +1117,11 @@ static int tcp_new(struct ip_conntrack *conntrack,
                        conntrack->proto.tcp.seen[0].td_maxwin;
                conntrack->proto.tcp.seen[0].td_scale = 0;
 
-               /* We assume SACK. Should we assume window scaling too? */
+               /* We assume SACK and liberal window checking to handle
+                * window scaling */
                conntrack->proto.tcp.seen[0].flags =
-               conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM;
-               conntrack->proto.tcp.seen[0].loose = 
-               conntrack->proto.tcp.seen[1].loose = ip_ct_tcp_loose;
+               conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM |
+                                                    IP_CT_TCP_FLAG_BE_LIBERAL;
        }
     
        conntrack->proto.tcp.seen[1].td_end = 0;