[NETFILTER]: Fix timeout sysctls on big-endian 64bit architectures
[linux-2.6.git] / net / netfilter / nf_conntrack_proto_tcp.c
index 6035633..df99138 100644 (file)
@@ -93,21 +93,21 @@ static const char *tcp_conntrack_names[] = {
 #define HOURS * 60 MINS
 #define DAYS * 24 HOURS
 
-unsigned long nf_ct_tcp_timeout_syn_sent =      2 MINS;
-unsigned long nf_ct_tcp_timeout_syn_recv =     60 SECS;
-unsigned long nf_ct_tcp_timeout_established =   5 DAYS;
-unsigned long nf_ct_tcp_timeout_fin_wait =      2 MINS;
-unsigned long nf_ct_tcp_timeout_close_wait =   60 SECS;
-unsigned long nf_ct_tcp_timeout_last_ack =     30 SECS;
-unsigned long nf_ct_tcp_timeout_time_wait =     2 MINS;
-unsigned long nf_ct_tcp_timeout_close =        10 SECS;
+unsigned int nf_ct_tcp_timeout_syn_sent =      2 MINS;
+unsigned int nf_ct_tcp_timeout_syn_recv =     60 SECS;
+unsigned int nf_ct_tcp_timeout_established =   5 DAYS;
+unsigned int nf_ct_tcp_timeout_fin_wait =      2 MINS;
+unsigned int nf_ct_tcp_timeout_close_wait =   60 SECS;
+unsigned int nf_ct_tcp_timeout_last_ack =     30 SECS;
+unsigned int nf_ct_tcp_timeout_time_wait =     2 MINS;
+unsigned int nf_ct_tcp_timeout_close =        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 long nf_ct_tcp_timeout_max_retrans =     5 MINS;
+unsigned int nf_ct_tcp_timeout_max_retrans =     5 MINS;
  
-static unsigned long * tcp_timeouts[]
+static unsigned int * tcp_timeouts[]
 = { NULL,                              /* TCP_CONNTRACK_NONE */
     &nf_ct_tcp_timeout_syn_sent,       /* TCP_CONNTRACK_SYN_SENT, */
     &nf_ct_tcp_timeout_syn_recv,       /* TCP_CONNTRACK_SYN_RECV, */
@@ -988,7 +988,7 @@ static int tcp_packet(struct nf_conn *conntrack,
                        || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
                            && conntrack->proto.tcp.last_index == TCP_ACK_SET))
                    && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
-                       /* RST sent to invalid SYN or ACK we had let trough
+                       /* RST sent to invalid SYN or ACK we had let through
                         * at a) and c) above:
                         *
                         * a) SYN was in window then
@@ -999,7 +999,7 @@ static int tcp_packet(struct nf_conn *conntrack,
                         * segments we ignored. */
                        goto in_window;
                }
-               /* Just fall trough */
+               /* Just fall through */
        default:
                /* Keep compilers happy. */
                break;
@@ -1147,6 +1147,63 @@ static int tcp_new(struct nf_conn *conntrack,
                receiver->td_scale);
        return 1;
 }
+
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+
+static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
+                        const struct nf_conn *ct)
+{
+       struct nfattr *nest_parms;
+       
+       read_lock_bh(&tcp_lock);
+       nest_parms = NFA_NEST(skb, CTA_PROTOINFO_TCP);
+       NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t),
+               &ct->proto.tcp.state);
+       read_unlock_bh(&tcp_lock);
+
+       NFA_NEST_END(skb, nest_parms);
+
+       return 0;
+
+nfattr_failure:
+       read_unlock_bh(&tcp_lock);
+       return -1;
+}
+
+static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = {
+       [CTA_PROTOINFO_TCP_STATE-1]     = sizeof(u_int8_t),
+};
+
+static int nfattr_to_tcp(struct nfattr *cda[], struct nf_conn *ct)
+{
+       struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
+       struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
+
+       /* updates could not contain anything about the private
+        * protocol info, in that case skip the parsing */
+       if (!attr)
+               return 0;
+
+        nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);
+
+       if (nfattr_bad_size(tb, CTA_PROTOINFO_TCP_MAX, cta_min_tcp))
+               return -EINVAL;
+
+       if (!tb[CTA_PROTOINFO_TCP_STATE-1])
+               return -EINVAL;
+
+       write_lock_bh(&tcp_lock);
+       ct->proto.tcp.state = 
+               *(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]);
+       write_unlock_bh(&tcp_lock);
+
+       return 0;
+}
+#endif
   
 struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 =
 {
@@ -1160,6 +1217,13 @@ struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 =
        .packet                 = tcp_packet,
        .new                    = tcp_new,
        .error                  = tcp_error4,
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+       .to_nfattr              = tcp_to_nfattr,
+       .from_nfattr            = nfattr_to_tcp,
+       .tuple_to_nfattr        = nf_ct_port_tuple_to_nfattr,
+       .nfattr_to_tuple        = nf_ct_port_nfattr_to_tuple,
+#endif
 };
 
 struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 =
@@ -1174,6 +1238,13 @@ struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 =
        .packet                 = tcp_packet,
        .new                    = tcp_new,
        .error                  = tcp_error6,
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+       .to_nfattr              = tcp_to_nfattr,
+       .from_nfattr            = nfattr_to_tcp,
+       .tuple_to_nfattr        = nf_ct_port_tuple_to_nfattr,
+       .nfattr_to_tuple        = nf_ct_port_nfattr_to_tuple,
+#endif
 };
 
 EXPORT_SYMBOL(nf_conntrack_protocol_tcp4);