Merge branch 'for-4.4/reservations' of git://git.kernel.dk/linux-block
[firefly-linux-kernel-4.4.55.git] / net / netfilter / nf_conntrack_core.c
index c09d6c7198f60d809b36783ca1de43646025c876..3cb3cb831591ef79515b4bde66d5db825a732afb 100644 (file)
@@ -168,6 +168,7 @@ nf_ct_get_tuple(const struct sk_buff *skb,
                unsigned int dataoff,
                u_int16_t l3num,
                u_int8_t protonum,
+               struct net *net,
                struct nf_conntrack_tuple *tuple,
                const struct nf_conntrack_l3proto *l3proto,
                const struct nf_conntrack_l4proto *l4proto)
@@ -181,12 +182,13 @@ nf_ct_get_tuple(const struct sk_buff *skb,
        tuple->dst.protonum = protonum;
        tuple->dst.dir = IP_CT_DIR_ORIGINAL;
 
-       return l4proto->pkt_to_tuple(skb, dataoff, tuple);
+       return l4proto->pkt_to_tuple(skb, dataoff, net, tuple);
 }
 EXPORT_SYMBOL_GPL(nf_ct_get_tuple);
 
 bool nf_ct_get_tuplepr(const struct sk_buff *skb, unsigned int nhoff,
-                      u_int16_t l3num, struct nf_conntrack_tuple *tuple)
+                      u_int16_t l3num,
+                      struct net *net, struct nf_conntrack_tuple *tuple)
 {
        struct nf_conntrack_l3proto *l3proto;
        struct nf_conntrack_l4proto *l4proto;
@@ -205,7 +207,7 @@ bool nf_ct_get_tuplepr(const struct sk_buff *skb, unsigned int nhoff,
 
        l4proto = __nf_ct_l4proto_find(l3num, protonum);
 
-       ret = nf_ct_get_tuple(skb, nhoff, protoff, l3num, protonum, tuple,
+       ret = nf_ct_get_tuple(skb, nhoff, protoff, l3num, protonum, net, tuple,
                              l3proto, l4proto);
 
        rcu_read_unlock();
@@ -938,10 +940,13 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
        }
 
        timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL;
-       if (timeout_ext)
-               timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext);
-       else
+       if (timeout_ext) {
+               timeouts = nf_ct_timeout_data(timeout_ext);
+               if (unlikely(!timeouts))
+                       timeouts = l4proto->get_timeouts(net);
+       } else {
                timeouts = l4proto->get_timeouts(net);
+       }
 
        if (!l4proto->new(ct, skb, dataoff, timeouts)) {
                nf_conntrack_free(ct);
@@ -950,7 +955,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
        }
 
        if (timeout_ext)
-               nf_ct_timeout_ext_add(ct, timeout_ext->timeout, GFP_ATOMIC);
+               nf_ct_timeout_ext_add(ct, rcu_dereference(timeout_ext->timeout),
+                                     GFP_ATOMIC);
 
        nf_ct_acct_ext_add(ct, GFP_ATOMIC);
        nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
@@ -1029,7 +1035,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
        u32 hash;
 
        if (!nf_ct_get_tuple(skb, skb_network_offset(skb),
-                            dataoff, l3num, protonum, &tuple, l3proto,
+                            dataoff, l3num, protonum, net, &tuple, l3proto,
                             l4proto)) {
                pr_debug("resolve_normal_ct: Can't get tuple\n");
                return NULL;