[NETFILTER]: Fix timeout sysctls on big-endian 64bit architectures
[linux-2.6.git] / net / ipv4 / netfilter / ip_conntrack_proto_sctp.c
index ff8c34a..be602e8 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
+#include <linux/interrupt.h>
 #include <linux/netfilter.h>
 #include <linux/module.h>
 #include <linux/in.h>
@@ -26,7 +27,6 @@
 
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
 
 #if 0
 #define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
@@ -35,7 +35,7 @@
 #endif
 
 /* Protects conntrack->proto.sctp */
-static DECLARE_RWLOCK(sctp_lock);
+static DEFINE_RWLOCK(sctp_lock);
 
 /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
    closely.  They're more complex. --RR 
@@ -58,15 +58,15 @@ static const char *sctp_conntrack_names[] = {
 #define HOURS * 60 MINS
 #define DAYS  * 24 HOURS
 
-static unsigned long ip_ct_sctp_timeout_closed            =  10 SECS;
-static unsigned long ip_ct_sctp_timeout_cookie_wait       =   3 SECS;
-static unsigned long ip_ct_sctp_timeout_cookie_echoed     =   3 SECS;
-static unsigned long ip_ct_sctp_timeout_established       =   5 DAYS;
-static unsigned long ip_ct_sctp_timeout_shutdown_sent     = 300 SECS / 1000;
-static unsigned long ip_ct_sctp_timeout_shutdown_recd     = 300 SECS / 1000;
-static unsigned long ip_ct_sctp_timeout_shutdown_ack_sent =   3 SECS;
+static unsigned int ip_ct_sctp_timeout_closed            =  10 SECS;
+static unsigned int ip_ct_sctp_timeout_cookie_wait       =   3 SECS;
+static unsigned int ip_ct_sctp_timeout_cookie_echoed     =   3 SECS;
+static unsigned int ip_ct_sctp_timeout_established       =   5 DAYS;
+static unsigned int ip_ct_sctp_timeout_shutdown_sent     = 300 SECS / 1000;
+static unsigned int ip_ct_sctp_timeout_shutdown_recd     = 300 SECS / 1000;
+static unsigned int ip_ct_sctp_timeout_shutdown_ack_sent =   3 SECS;
 
-static unsigned long * sctp_timeouts[]
+static const unsigned int * sctp_timeouts[]
 = { NULL,                                  /* SCTP_CONNTRACK_NONE  */
     &ip_ct_sctp_timeout_closed,                   /* SCTP_CONNTRACK_CLOSED */
     &ip_ct_sctp_timeout_cookie_wait,       /* SCTP_CONNTRACK_COOKIE_WAIT */
@@ -119,7 +119,7 @@ cookie echoed to closed.
 */
 
 /* SCTP conntrack state transitions */
-static enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
+static const enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
        {
 /*     ORIGINAL        */
 /*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
@@ -199,9 +199,9 @@ static int sctp_print_conntrack(struct seq_file *s,
        DEBUGP(__FUNCTION__);
        DEBUGP("\n");
 
-       READ_LOCK(&sctp_lock);
+       read_lock_bh(&sctp_lock);
        state = conntrack->proto.sctp.state;
-       READ_UNLOCK(&sctp_lock);
+       read_unlock_bh(&sctp_lock);
 
        return seq_printf(s, "%s ", sctp_conntrack_names[state]);
 }
@@ -343,13 +343,13 @@ static int sctp_packet(struct ip_conntrack *conntrack,
 
        oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX;
        for_each_sctp_chunk (skb, sch, _sch, offset, count) {
-               WRITE_LOCK(&sctp_lock);
+               write_lock_bh(&sctp_lock);
 
                /* Special cases of Verification tag check (Sec 8.5.1) */
                if (sch->type == SCTP_CID_INIT) {
                        /* Sec 8.5.1 (A) */
                        if (sh->vtag != 0) {
-                               WRITE_UNLOCK(&sctp_lock);
+                               write_unlock_bh(&sctp_lock);
                                return -1;
                        }
                } else if (sch->type == SCTP_CID_ABORT) {
@@ -357,7 +357,7 @@ static int sctp_packet(struct ip_conntrack *conntrack,
                        if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
                                && !(sh->vtag == conntrack->proto.sctp.vtag
                                                        [1 - CTINFO2DIR(ctinfo)])) {
-                               WRITE_UNLOCK(&sctp_lock);
+                               write_unlock_bh(&sctp_lock);
                                return -1;
                        }
                } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
@@ -366,13 +366,13 @@ static int sctp_packet(struct ip_conntrack *conntrack,
                                && !(sh->vtag == conntrack->proto.sctp.vtag
                                                        [1 - CTINFO2DIR(ctinfo)] 
                                        && (sch->flags & 1))) {
-                               WRITE_UNLOCK(&sctp_lock);
+                               write_unlock_bh(&sctp_lock);
                                return -1;
                        }
                } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
                        /* Sec 8.5.1 (D) */
                        if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
-                               WRITE_UNLOCK(&sctp_lock);
+                               write_unlock_bh(&sctp_lock);
                                return -1;
                        }
                }
@@ -384,7 +384,7 @@ static int sctp_packet(struct ip_conntrack *conntrack,
                if (newconntrack == SCTP_CONNTRACK_MAX) {
                        DEBUGP("ip_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n",
                               CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
-                       WRITE_UNLOCK(&sctp_lock);
+                       write_unlock_bh(&sctp_lock);
                        return -1;
                }
 
@@ -396,7 +396,7 @@ static int sctp_packet(struct ip_conntrack *conntrack,
                        ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
                                                sizeof(_inithdr), &_inithdr);
                        if (ih == NULL) {
-                                       WRITE_UNLOCK(&sctp_lock);
+                                       write_unlock_bh(&sctp_lock);
                                        return -1;
                        }
                        DEBUGP("Setting vtag %x for dir %d\n", 
@@ -405,7 +405,9 @@ static int sctp_packet(struct ip_conntrack *conntrack,
                }
 
                conntrack->proto.sctp.state = newconntrack;
-               WRITE_UNLOCK(&sctp_lock);
+               if (oldsctpstate != newconntrack)
+                       ip_conntrack_event_cache(IPCT_PROTOINFO, skb);
+               write_unlock_bh(&sctp_lock);
        }
 
        ip_ct_refresh_acct(conntrack, ctinfo, skb, *sctp_timeouts[newconntrack]);
@@ -415,6 +417,7 @@ static int sctp_packet(struct ip_conntrack *conntrack,
                && newconntrack == SCTP_CONNTRACK_ESTABLISHED) {
                DEBUGP("Setting assured bit\n");
                set_bit(IPS_ASSURED_BIT, &conntrack->status);
+               ip_conntrack_event_cache(IPCT_STATUS, skb);
        }
 
        return NF_ACCEPT;
@@ -504,7 +507,12 @@ static struct ip_conntrack_protocol ip_conntrack_protocol_sctp = {
        .packet          = sctp_packet, 
        .new             = sctp_new, 
        .destroy         = NULL, 
-       .me              = THIS_MODULE 
+       .me              = THIS_MODULE,
+#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
+    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
+       .tuple_to_nfattr = ip_ct_port_tuple_to_nfattr,
+       .nfattr_to_tuple = ip_ct_port_nfattr_to_tuple,
+#endif
 };
 
 #ifdef CONFIG_SYSCTL