]> err.no Git - linux-2.6/blobdiff - net/netfilter/nf_conntrack_proto_tcp.c
[NETFILTER]: nf_conntrack: switch rwlock to spinlock
[linux-2.6] / net / netfilter / nf_conntrack_proto_tcp.c
index eb3fe7401466544483d6356dbd28e3da0fca873c..8e22075356654666f7cef2e46889e64ecfe8edef 100644 (file)
@@ -24,6 +24,7 @@
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
+#include <net/netfilter/nf_log.h>
 
 /* Protects conntrack->proto.tcp */
 static DEFINE_RWLOCK(tcp_lock);
@@ -63,32 +64,21 @@ static const char *tcp_conntrack_names[] = {
 #define HOURS * 60 MINS
 #define DAYS * 24 HOURS
 
-static unsigned int nf_ct_tcp_timeout_syn_sent __read_mostly =      2 MINS;
-static unsigned int nf_ct_tcp_timeout_syn_recv __read_mostly =     60 SECS;
-static unsigned int nf_ct_tcp_timeout_established __read_mostly =   5 DAYS;
-static unsigned int nf_ct_tcp_timeout_fin_wait __read_mostly =      2 MINS;
-static unsigned int nf_ct_tcp_timeout_close_wait __read_mostly =   60 SECS;
-static unsigned int nf_ct_tcp_timeout_last_ack __read_mostly =     30 SECS;
-static unsigned int nf_ct_tcp_timeout_time_wait __read_mostly =     2 MINS;
-static unsigned int nf_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. */
 static unsigned int nf_ct_tcp_timeout_max_retrans __read_mostly =   5 MINS;
 
-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, */
-    &nf_ct_tcp_timeout_established,    /* TCP_CONNTRACK_ESTABLISHED, */
-    &nf_ct_tcp_timeout_fin_wait,       /* TCP_CONNTRACK_FIN_WAIT, */
-    &nf_ct_tcp_timeout_close_wait,     /* TCP_CONNTRACK_CLOSE_WAIT, */
-    &nf_ct_tcp_timeout_last_ack,       /* TCP_CONNTRACK_LAST_ACK, */
-    &nf_ct_tcp_timeout_time_wait,      /* TCP_CONNTRACK_TIME_WAIT, */
-    &nf_ct_tcp_timeout_close,          /* TCP_CONNTRACK_CLOSE, */
-    NULL,                              /* TCP_CONNTRACK_LISTEN */
- };
+static unsigned int tcp_timeouts[TCP_CONNTRACK_MAX] __read_mostly = {
+       [TCP_CONNTRACK_SYN_SENT]        = 2 MINS,
+       [TCP_CONNTRACK_SYN_RECV]        = 60 SECS,
+       [TCP_CONNTRACK_ESTABLISHED]     = 5 DAYS,
+       [TCP_CONNTRACK_FIN_WAIT]        = 2 MINS,
+       [TCP_CONNTRACK_CLOSE_WAIT]      = 60 SECS,
+       [TCP_CONNTRACK_LAST_ACK]        = 30 SECS,
+       [TCP_CONNTRACK_TIME_WAIT]       = 2 MINS,
+       [TCP_CONNTRACK_CLOSE]           = 10 SECS,
+};
 
 #define sNO TCP_CONNTRACK_NONE
 #define sSS TCP_CONNTRACK_SYN_SENT
@@ -148,7 +138,7 @@ enum tcp_bit_set {
  *     if they are invalid
  *     or we do not support the request (simultaneous open)
  */
-static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
+static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
        {
 /* ORIGINAL */
 /*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI   */
@@ -783,9 +773,7 @@ static int tcp_error(struct sk_buff *skb,
         * because the checksum is assumed to be correct.
         */
        /* FIXME: Source route IP option packets --RR */
-       if (nf_conntrack_checksum &&
-           ((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
-            (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING)) &&
+       if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
            nf_checksum(skb, hooknum, dataoff, IPPROTO_TCP, pf)) {
                if (LOG_INVALID(IPPROTO_TCP))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
@@ -831,6 +819,22 @@ static int tcp_packet(struct nf_conn *conntrack,
        tuple = &conntrack->tuplehash[dir].tuple;
 
        switch (new_state) {
+       case TCP_CONNTRACK_SYN_SENT:
+               if (old_state < TCP_CONNTRACK_TIME_WAIT)
+                       break;
+               if ((conntrack->proto.tcp.seen[!dir].flags &
+                       IP_CT_TCP_FLAG_CLOSE_INIT)
+                   || (conntrack->proto.tcp.last_dir == dir
+                       && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
+                       /* Attempt to reopen a closed/aborted connection.
+                        * Delete this connection and look up again. */
+                       write_unlock_bh(&tcp_lock);
+                       if (del_timer(&conntrack->timeout))
+                               conntrack->timeout.function((unsigned long)
+                                                           conntrack);
+                       return -NF_REPEAT;
+               }
+               /* Fall through */
        case TCP_CONNTRACK_IGNORE:
                /* Ignored packets:
                 *
@@ -879,27 +883,6 @@ static int tcp_packet(struct nf_conn *conntrack,
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                  "nf_ct_tcp: invalid state ");
                return -NF_ACCEPT;
-       case TCP_CONNTRACK_SYN_SENT:
-               if (old_state < TCP_CONNTRACK_TIME_WAIT)
-                       break;
-               if ((conntrack->proto.tcp.seen[dir].flags &
-                       IP_CT_TCP_FLAG_CLOSE_INIT)
-                   || after(ntohl(th->seq),
-                            conntrack->proto.tcp.seen[dir].td_end)) {
-                       /* Attempt to reopen a closed connection.
-                       * Delete this connection and look up again. */
-                       write_unlock_bh(&tcp_lock);
-                       if (del_timer(&conntrack->timeout))
-                               conntrack->timeout.function((unsigned long)
-                                                           conntrack);
-                       return -NF_REPEAT;
-               } else {
-                       write_unlock_bh(&tcp_lock);
-                       if (LOG_INVALID(IPPROTO_TCP))
-                               nf_log_packet(pf, 0, skb, NULL, NULL,
-                                             NULL, "nf_ct_tcp: invalid SYN");
-                       return -NF_ACCEPT;
-               }
        case TCP_CONNTRACK_CLOSE:
                if (index == TCP_RST_SET
                    && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
@@ -932,6 +915,7 @@ static int tcp_packet(struct nf_conn *conntrack,
      in_window:
        /* From now on we have got in-window packets */
        conntrack->proto.tcp.last_index = index;
+       conntrack->proto.tcp.last_dir = dir;
 
        pr_debug("tcp_conntracks: ");
        NF_CT_DUMP_TUPLE(tuple);
@@ -946,8 +930,8 @@ static int tcp_packet(struct nf_conn *conntrack,
                || new_state == TCP_CONNTRACK_CLOSE))
                conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
        timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans
-                 && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
-                 ? nf_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];
+                 && tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
+                 ? nf_ct_tcp_timeout_max_retrans : tcp_timeouts[new_state];
        write_unlock_bh(&tcp_lock);
 
        nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
@@ -1067,93 +1051,94 @@ static int tcp_new(struct nf_conn *conntrack,
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nfnetlink_conntrack.h>
 
-static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
+static int tcp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
                         const struct nf_conn *ct)
 {
-       struct nfattr *nest_parms;
+       struct nlattr *nest_parms;
        struct nf_ct_tcp_flags tmp = {};
 
        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);
+       nest_parms = nla_nest_start(skb, CTA_PROTOINFO_TCP | NLA_F_NESTED);
+       if (!nest_parms)
+               goto nla_put_failure;
 
-       NFA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, sizeof(u_int8_t),
-               &ct->proto.tcp.seen[0].td_scale);
+       NLA_PUT_U8(skb, CTA_PROTOINFO_TCP_STATE, ct->proto.tcp.state);
 
-       NFA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY, sizeof(u_int8_t),
-               &ct->proto.tcp.seen[1].td_scale);
+       NLA_PUT_U8(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
+                  ct->proto.tcp.seen[0].td_scale);
+
+       NLA_PUT_U8(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY,
+                  ct->proto.tcp.seen[1].td_scale);
 
        tmp.flags = ct->proto.tcp.seen[0].flags;
-       NFA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
+       NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
                sizeof(struct nf_ct_tcp_flags), &tmp);
 
        tmp.flags = ct->proto.tcp.seen[1].flags;
-       NFA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY,
+       NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY,
                sizeof(struct nf_ct_tcp_flags), &tmp);
        read_unlock_bh(&tcp_lock);
 
-       NFA_NEST_END(skb, nest_parms);
+       nla_nest_end(skb, nest_parms);
 
        return 0;
 
-nfattr_failure:
+nla_put_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),
-       [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1] = sizeof(u_int8_t),
-       [CTA_PROTOINFO_TCP_WSCALE_REPLY-1]    = sizeof(u_int8_t),
-       [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]  = sizeof(struct nf_ct_tcp_flags),
-       [CTA_PROTOINFO_TCP_FLAGS_REPLY-1]     = sizeof(struct nf_ct_tcp_flags)
+static const struct nla_policy tcp_nla_policy[CTA_PROTOINFO_TCP_MAX+1] = {
+       [CTA_PROTOINFO_TCP_STATE]           = { .type = NLA_U8 },
+       [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] = { .type = NLA_U8 },
+       [CTA_PROTOINFO_TCP_WSCALE_REPLY]    = { .type = NLA_U8 },
+       [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]  = { .len = sizeof(struct nf_ct_tcp_flags) },
+       [CTA_PROTOINFO_TCP_FLAGS_REPLY]     = { .len =  sizeof(struct nf_ct_tcp_flags) },
 };
 
-static int nfattr_to_tcp(struct nfattr *cda[], struct nf_conn *ct)
+static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
 {
-       struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
-       struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
+       struct nlattr *pattr = cda[CTA_PROTOINFO_TCP];
+       struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1];
+       int err;
 
        /* updates could not contain anything about the private
         * protocol info, in that case skip the parsing */
-       if (!attr)
+       if (!pattr)
                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;
+       err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, pattr, tcp_nla_policy);
+       if (err < 0)
+               return err;
 
-       if (!tb[CTA_PROTOINFO_TCP_STATE-1])
+       if (!tb[CTA_PROTOINFO_TCP_STATE])
                return -EINVAL;
 
        write_lock_bh(&tcp_lock);
-       ct->proto.tcp.state =
-               *(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]);
+       ct->proto.tcp.state = nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]);
 
-       if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]) {
+       if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) {
                struct nf_ct_tcp_flags *attr =
-                       NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]);
+                       nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]);
                ct->proto.tcp.seen[0].flags &= ~attr->mask;
                ct->proto.tcp.seen[0].flags |= attr->flags & attr->mask;
        }
 
-       if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]) {
+       if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]) {
                struct nf_ct_tcp_flags *attr =
-                       NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]);
+                       nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]);
                ct->proto.tcp.seen[1].flags &= ~attr->mask;
                ct->proto.tcp.seen[1].flags |= attr->flags & attr->mask;
        }
 
-       if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1] &&
-           tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1] &&
+       if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] &&
+           tb[CTA_PROTOINFO_TCP_WSCALE_REPLY] &&
            ct->proto.tcp.seen[0].flags & IP_CT_TCP_FLAG_WINDOW_SCALE &&
            ct->proto.tcp.seen[1].flags & IP_CT_TCP_FLAG_WINDOW_SCALE) {
-               ct->proto.tcp.seen[0].td_scale = *(u_int8_t *)
-                       NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1]);
-               ct->proto.tcp.seen[1].td_scale = *(u_int8_t *)
-                       NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1]);
+               ct->proto.tcp.seen[0].td_scale =
+                       nla_get_u8(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]);
+               ct->proto.tcp.seen[1].td_scale =
+                       nla_get_u8(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]);
        }
        write_unlock_bh(&tcp_lock);
 
@@ -1166,71 +1151,62 @@ static unsigned int tcp_sysctl_table_users;
 static struct ctl_table_header *tcp_sysctl_header;
 static struct ctl_table tcp_sysctl_table[] = {
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
                .procname       = "nf_conntrack_tcp_timeout_syn_sent",
-               .data           = &nf_ct_tcp_timeout_syn_sent,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
                .procname       = "nf_conntrack_tcp_timeout_syn_recv",
-               .data           = &nf_ct_tcp_timeout_syn_recv,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
                .procname       = "nf_conntrack_tcp_timeout_established",
-               .data           = &nf_ct_tcp_timeout_established,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
                .procname       = "nf_conntrack_tcp_timeout_fin_wait",
-               .data           = &nf_ct_tcp_timeout_fin_wait,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
                .procname       = "nf_conntrack_tcp_timeout_close_wait",
-               .data           = &nf_ct_tcp_timeout_close_wait,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
                .procname       = "nf_conntrack_tcp_timeout_last_ack",
-               .data           = &nf_ct_tcp_timeout_last_ack,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
                .procname       = "nf_conntrack_tcp_timeout_time_wait",
-               .data           = &nf_ct_tcp_timeout_time_wait,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
                .procname       = "nf_conntrack_tcp_timeout_close",
-               .data           = &nf_ct_tcp_timeout_close,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_CLOSE],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
                .procname       = "nf_conntrack_tcp_timeout_max_retrans",
                .data           = &nf_ct_tcp_timeout_max_retrans,
                .maxlen         = sizeof(unsigned int),
@@ -1269,71 +1245,62 @@ static struct ctl_table tcp_sysctl_table[] = {
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 static struct ctl_table tcp_compat_sysctl_table[] = {
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
                .procname       = "ip_conntrack_tcp_timeout_syn_sent",
-               .data           = &nf_ct_tcp_timeout_syn_sent,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
                .procname       = "ip_conntrack_tcp_timeout_syn_recv",
-               .data           = &nf_ct_tcp_timeout_syn_recv,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
                .procname       = "ip_conntrack_tcp_timeout_established",
-               .data           = &nf_ct_tcp_timeout_established,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
                .procname       = "ip_conntrack_tcp_timeout_fin_wait",
-               .data           = &nf_ct_tcp_timeout_fin_wait,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
                .procname       = "ip_conntrack_tcp_timeout_close_wait",
-               .data           = &nf_ct_tcp_timeout_close_wait,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
                .procname       = "ip_conntrack_tcp_timeout_last_ack",
-               .data           = &nf_ct_tcp_timeout_last_ack,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
                .procname       = "ip_conntrack_tcp_timeout_time_wait",
-               .data           = &nf_ct_tcp_timeout_time_wait,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
                .procname       = "ip_conntrack_tcp_timeout_close",
-               .data           = &nf_ct_tcp_timeout_close,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_CLOSE],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
                .procname       = "ip_conntrack_tcp_timeout_max_retrans",
                .data           = &nf_ct_tcp_timeout_max_retrans,
                .maxlen         = sizeof(unsigned int),
@@ -1384,10 +1351,11 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
        .new                    = tcp_new,
        .error                  = tcp_error,
 #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,
+       .to_nlattr              = tcp_to_nlattr,
+       .from_nlattr            = nlattr_to_tcp,
+       .tuple_to_nlattr        = nf_ct_port_tuple_to_nlattr,
+       .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
+       .nla_policy             = nf_ct_port_nla_policy,
 #endif
 #ifdef CONFIG_SYSCTL
        .ctl_table_users        = &tcp_sysctl_table_users,
@@ -1413,10 +1381,11 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly =
        .new                    = tcp_new,
        .error                  = tcp_error,
 #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,
+       .to_nlattr              = tcp_to_nlattr,
+       .from_nlattr            = nlattr_to_tcp,
+       .tuple_to_nlattr        = nf_ct_port_tuple_to_nlattr,
+       .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
+       .nla_policy             = nf_ct_port_nla_policy,
 #endif
 #ifdef CONFIG_SYSCTL
        .ctl_table_users        = &tcp_sysctl_table_users,