]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - net/netfilter/nf_conntrack_core.c
skbuff: add and use skb_nfct helper
[mirror_ubuntu-artful-kernel.git] / net / netfilter / nf_conntrack_core.c
index 0f87e5d21be7161f6d885fd3ab40f1e752e68a66..78aebf0ee6e37c84e41426030a45ff82047857e7 100644 (file)
@@ -686,8 +686,11 @@ static int nf_ct_resolve_clash(struct net *net, struct sk_buff *skb,
            !nfct_nat(ct) &&
            !nf_ct_is_dying(ct) &&
            atomic_inc_not_zero(&ct->ct_general.use)) {
-               nf_ct_acct_merge(ct, ctinfo, (struct nf_conn *)skb->nfct);
-               nf_conntrack_put(skb->nfct);
+               enum ip_conntrack_info oldinfo;
+               struct nf_conn *loser_ct = nf_ct_get(skb, &oldinfo);
+
+               nf_ct_acct_merge(ct, ctinfo, loser_ct);
+               nf_conntrack_put(&loser_ct->ct_general);
                /* Assign conntrack already in hashes to this skbuff. Don't
                 * modify skb->nfctinfo to ensure consistent stateful filtering.
                 */
@@ -783,7 +786,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
        /* set conntrack timestamp, if enabled. */
        tstamp = nf_conn_tstamp_find(ct);
        if (tstamp) {
-               if (skb->tstamp.tv64 == 0)
+               if (skb->tstamp == 0)
                        __net_timestamp(skb);
 
                tstamp->start = ktime_to_ns(skb->tstamp);
@@ -1288,7 +1291,7 @@ unsigned int
 nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
                struct sk_buff *skb)
 {
-       struct nf_conn *ct, *tmpl = NULL;
+       struct nf_conn *ct, *tmpl;
        enum ip_conntrack_info ctinfo;
        struct nf_conntrack_l3proto *l3proto;
        struct nf_conntrack_l4proto *l4proto;
@@ -1298,9 +1301,9 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
        int set_reply = 0;
        int ret;
 
-       if (skb->nfct) {
+       tmpl = nf_ct_get(skb, &ctinfo);
+       if (tmpl) {
                /* Previously seen (loopback or untracked)?  Ignore. */
-               tmpl = (struct nf_conn *)skb->nfct;
                if (!nf_ct_is_template(tmpl)) {
                        NF_CT_STAT_INC_ATOMIC(net, ignore);
                        return NF_ACCEPT;
@@ -1326,8 +1329,7 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
         * inverse of the return code tells to the netfilter
         * core what to do with the packet. */
        if (l4proto->error != NULL) {
-               ret = l4proto->error(net, tmpl, skb, dataoff, &ctinfo,
-                                    pf, hooknum);
+               ret = l4proto->error(net, tmpl, skb, dataoff, pf, hooknum);
                if (ret <= 0) {
                        NF_CT_STAT_INC_ATOMIC(net, error);
                        NF_CT_STAT_INC_ATOMIC(net, invalid);
@@ -1338,7 +1340,7 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
                if (skb->nfct)
                        goto out;
        }
-
+repeat:
        ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum,
                               l3proto, l4proto, &set_reply, &ctinfo);
        if (!ct) {
@@ -1355,7 +1357,7 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
                goto out;
        }
 
-       NF_CT_ASSERT(skb->nfct);
+       NF_CT_ASSERT(skb_nfct(skb));
 
        /* Decide what timeout policy we want to apply to this flow. */
        timeouts = nf_ct_timeout_lookup(net, ct, l4proto);
@@ -1365,11 +1367,17 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
                /* Invalid: inverse of the return code tells
                 * the netfilter core what to do */
                pr_debug("nf_conntrack_in: Can't track with proto module\n");
-               nf_conntrack_put(skb->nfct);
+               nf_conntrack_put(&ct->ct_general);
                skb->nfct = NULL;
                NF_CT_STAT_INC_ATOMIC(net, invalid);
                if (ret == -NF_DROP)
                        NF_CT_STAT_INC_ATOMIC(net, drop);
+               /* Special case: TCP tracker reports an attempt to reopen a
+                * closed/aborted connection. We have to go back and create a
+                * fresh conntrack.
+                */
+               if (ret == -NF_REPEAT)
+                       goto repeat;
                ret = -ret;
                goto out;
        }
@@ -1377,15 +1385,8 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
        if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
                nf_conntrack_event_cache(IPCT_REPLY, ct);
 out:
-       if (tmpl) {
-               /* Special case: we have to repeat this hook, assign the
-                * template again to this packet. We assume that this packet
-                * has no conntrack assigned. This is used by nf_ct_tcp. */
-               if (ret == NF_REPEAT)
-                       skb->nfct = (struct nf_conntrack *)tmpl;
-               else
-                       nf_ct_put(tmpl);
-       }
+       if (tmpl)
+               nf_ct_put(tmpl);
 
        return ret;
 }
@@ -1527,7 +1528,7 @@ static void nf_conntrack_attach(struct sk_buff *nskb, const struct sk_buff *skb)
        /* Attach to new skbuff, and increment count */
        nskb->nfct = &ct->ct_general;
        nskb->nfctinfo = ctinfo;
-       nf_conntrack_get(nskb->nfct);
+       nf_conntrack_get(skb_nfct(nskb));
 }
 
 /* Bring out ya dead! */