inet: frags: add a pointer to struct netns_frags
authorEric Dumazet <edumazet@google.com>
Thu, 13 Sep 2018 14:58:34 +0000 (07:58 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Sep 2018 20:43:45 +0000 (22:43 +0200)
In order to simplify the API, add a pointer to struct inet_frags.
This will allow us to make things less complex.

These functions no longer have a struct inet_frags parameter :

inet_frag_destroy(struct inet_frag_queue *q  /*, struct inet_frags *f */)
inet_frag_put(struct inet_frag_queue *q /*, struct inet_frags *f */)
inet_frag_kill(struct inet_frag_queue *q /*, struct inet_frags *f */)
inet_frags_exit_net(struct netns_frags *nf /*, struct inet_frags *f */)
ip6_expire_frag_queue(struct net *net, struct frag_queue *fq)

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 093ba72914b696521e4885756a68a3332782c8de)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
include/net/inet_frag.h
include/net/ipv6.h
net/ieee802154/6lowpan/reassembly.c
net/ipv4/inet_fragment.c
net/ipv4/ip_fragment.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/reassembly.c

index 2ad894e..fd33829 100644 (file)
@@ -10,6 +10,7 @@ struct netns_frags {
        int                     high_thresh;
        int                     low_thresh;
        int                     max_dist;
+       struct inet_frags       *f;
 };
 
 /**
@@ -109,20 +110,20 @@ static inline int inet_frags_init_net(struct netns_frags *nf)
        atomic_set(&nf->mem, 0);
        return 0;
 }
-void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f);
+void inet_frags_exit_net(struct netns_frags *nf);
 
-void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
-void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f);
+void inet_frag_kill(struct inet_frag_queue *q);
+void inet_frag_destroy(struct inet_frag_queue *q);
 struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
                struct inet_frags *f, void *key, unsigned int hash);
 
 void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
                                   const char *prefix);
 
-static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
+static inline void inet_frag_put(struct inet_frag_queue *q)
 {
        if (refcount_dec_and_test(&q->refcnt))
-               inet_frag_destroy(q, f);
+               inet_frag_destroy(q);
 }
 
 static inline bool inet_frag_evicting(struct inet_frag_queue *q)
index f280c61..ff8407b 100644 (file)
@@ -560,8 +560,7 @@ struct frag_queue {
        u8                      ecn;
 };
 
-void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq,
-                          struct inet_frags *frags);
+void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq);
 
 static inline bool ipv6_addr_any(const struct in6_addr *a)
 {
index 9757ce6..9ccb845 100644 (file)
@@ -93,10 +93,10 @@ static void lowpan_frag_expire(unsigned long data)
        if (fq->q.flags & INET_FRAG_COMPLETE)
                goto out;
 
-       inet_frag_kill(&fq->q, &lowpan_frags);
+       inet_frag_kill(&fq->q);
 out:
        spin_unlock(&fq->q.lock);
-       inet_frag_put(&fq->q, &lowpan_frags);
+       inet_frag_put(&fq->q);
 }
 
 static inline struct lowpan_frag_queue *
@@ -229,7 +229,7 @@ static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, struct sk_buff *prev,
        struct sk_buff *fp, *head = fq->q.fragments;
        int sum_truesize;
 
-       inet_frag_kill(&fq->q, &lowpan_frags);
+       inet_frag_kill(&fq->q);
 
        /* Make the one we just received the head. */
        if (prev) {
@@ -437,7 +437,7 @@ int lowpan_frag_rcv(struct sk_buff *skb, u8 frag_type)
                ret = lowpan_frag_queue(fq, skb, frag_type);
                spin_unlock(&fq->q.lock);
 
-               inet_frag_put(&fq->q, &lowpan_frags);
+               inet_frag_put(&fq->q);
                return ret;
        }
 
@@ -585,13 +585,14 @@ static int __net_init lowpan_frags_init_net(struct net *net)
        ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
        ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH;
        ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT;
+       ieee802154_lowpan->frags.f = &lowpan_frags;
 
        res = inet_frags_init_net(&ieee802154_lowpan->frags);
        if (res < 0)
                return res;
        res = lowpan_frags_ns_sysctl_register(net);
        if (res < 0)
-               inet_frags_exit_net(&ieee802154_lowpan->frags, &lowpan_frags);
+               inet_frags_exit_net(&ieee802154_lowpan->frags);
        return res;
 }
 
@@ -601,7 +602,7 @@ static void __net_exit lowpan_frags_exit_net(struct net *net)
                net_ieee802154_lowpan(net);
 
        lowpan_frags_ns_sysctl_unregister(net);
-       inet_frags_exit_net(&ieee802154_lowpan->frags, &lowpan_frags);
+       inet_frags_exit_net(&ieee802154_lowpan->frags);
 }
 
 static struct pernet_operations lowpan_frags_ops = {
index ba4454e..4b44f97 100644 (file)
@@ -219,8 +219,9 @@ void inet_frags_fini(struct inet_frags *f)
 }
 EXPORT_SYMBOL(inet_frags_fini);
 
-void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f)
+void inet_frags_exit_net(struct netns_frags *nf)
 {
+       struct inet_frags *f =nf->f;
        unsigned int seq;
        int i;
 
@@ -264,33 +265,34 @@ __acquires(hb->chain_lock)
        return hb;
 }
 
-static inline void fq_unlink(struct inet_frag_queue *fq, struct inet_frags *f)
+static inline void fq_unlink(struct inet_frag_queue *fq)
 {
        struct inet_frag_bucket *hb;
 
-       hb = get_frag_bucket_locked(fq, f);
+       hb = get_frag_bucket_locked(fq, fq->net->f);
        hlist_del(&fq->list);
        fq->flags |= INET_FRAG_COMPLETE;
        spin_unlock(&hb->chain_lock);
 }
 
-void inet_frag_kill(struct inet_frag_queue *fq, struct inet_frags *f)
+void inet_frag_kill(struct inet_frag_queue *fq)
 {
        if (del_timer(&fq->timer))
                refcount_dec(&fq->refcnt);
 
        if (!(fq->flags & INET_FRAG_COMPLETE)) {
-               fq_unlink(fq, f);
+               fq_unlink(fq);
                refcount_dec(&fq->refcnt);
        }
 }
 EXPORT_SYMBOL(inet_frag_kill);
 
-void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f)
+void inet_frag_destroy(struct inet_frag_queue *q)
 {
        struct sk_buff *fp;
        struct netns_frags *nf;
        unsigned int sum, sum_truesize = 0;
+       struct inet_frags *f;
 
        WARN_ON(!(q->flags & INET_FRAG_COMPLETE));
        WARN_ON(del_timer(&q->timer) != 0);
@@ -298,6 +300,7 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f)
        /* Release all fragment data. */
        fp = q->fragments;
        nf = q->net;
+       f = nf->f;
        while (fp) {
                struct sk_buff *xp = fp->next;
 
@@ -333,7 +336,7 @@ static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf,
                        refcount_inc(&qp->refcnt);
                        spin_unlock(&hb->chain_lock);
                        qp_in->flags |= INET_FRAG_COMPLETE;
-                       inet_frag_put(qp_in, f);
+                       inet_frag_put(qp_in);
                        return qp;
                }
        }
index 916def2..c32718b 100644 (file)
@@ -168,7 +168,7 @@ static void ip4_frag_free(struct inet_frag_queue *q)
 
 static void ipq_put(struct ipq *ipq)
 {
-       inet_frag_put(&ipq->q, &ip4_frags);
+       inet_frag_put(&ipq->q);
 }
 
 /* Kill ipq entry. It is not destroyed immediately,
@@ -176,7 +176,7 @@ static void ipq_put(struct ipq *ipq)
  */
 static void ipq_kill(struct ipq *ipq)
 {
-       inet_frag_kill(&ipq->q, &ip4_frags);
+       inet_frag_kill(&ipq->q);
 }
 
 static bool frag_expire_skip_icmp(u32 user)
@@ -876,20 +876,21 @@ static int __net_init ipv4_frags_init_net(struct net *net)
        net->ipv4.frags.timeout = IP_FRAG_TIME;
 
        net->ipv4.frags.max_dist = 64;
+       net->ipv4.frags.f = &ip4_frags;
 
        res = inet_frags_init_net(&net->ipv4.frags);
        if (res < 0)
                return res;
        res = ip4_frags_ns_ctl_register(net);
        if (res < 0)
-               inet_frags_exit_net(&net->ipv4.frags, &ip4_frags);
+               inet_frags_exit_net(&net->ipv4.frags);
        return res;
 }
 
 static void __net_exit ipv4_frags_exit_net(struct net *net)
 {
        ip4_frags_ns_ctl_unregister(net);
-       inet_frags_exit_net(&net->ipv4.frags, &ip4_frags);
+       inet_frags_exit_net(&net->ipv4.frags);
 }
 
 static struct pernet_operations ip4_frags_ops = {
index afa9ea7..7ea2b44 100644 (file)
@@ -177,7 +177,7 @@ static void nf_ct_frag6_expire(unsigned long data)
        fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
        net = container_of(fq->q.net, struct net, nf_frag.frags);
 
-       ip6_expire_frag_queue(net, fq, &nf_frags);
+       ip6_expire_frag_queue(net, fq);
 }
 
 /* Creation primitives. */
@@ -263,7 +263,7 @@ static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb,
                         * this case. -DaveM
                         */
                        pr_debug("end of fragment not rounded to 8 bytes.\n");
-                       inet_frag_kill(&fq->q, &nf_frags);
+                       inet_frag_kill(&fq->q);
                        return -EPROTO;
                }
                if (end > fq->q.len) {
@@ -356,7 +356,7 @@ found:
        return 0;
 
 discard_fq:
-       inet_frag_kill(&fq->q, &nf_frags);
+       inet_frag_kill(&fq->q);
 err:
        return -EINVAL;
 }
@@ -378,7 +378,7 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct sk_buff *prev,  struct net_devic
        int    payload_len;
        u8 ecn;
 
-       inet_frag_kill(&fq->q, &nf_frags);
+       inet_frag_kill(&fq->q);
 
        WARN_ON(head == NULL);
        WARN_ON(NFCT_FRAG6_CB(head)->offset != 0);
@@ -623,7 +623,7 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
 
 out_unlock:
        spin_unlock_bh(&fq->q.lock);
-       inet_frag_put(&fq->q, &nf_frags);
+       inet_frag_put(&fq->q);
        return ret;
 }
 EXPORT_SYMBOL_GPL(nf_ct_frag6_gather);
@@ -635,19 +635,21 @@ static int nf_ct_net_init(struct net *net)
        net->nf_frag.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
        net->nf_frag.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
        net->nf_frag.frags.timeout = IPV6_FRAG_TIMEOUT;
+       net->nf_frag.frags.f = &nf_frags;
+
        res = inet_frags_init_net(&net->nf_frag.frags);
        if (res < 0)
                return res;
        res = nf_ct_frag6_sysctl_register(net);
        if (res < 0)
-               inet_frags_exit_net(&net->nf_frag.frags, &nf_frags);
+               inet_frags_exit_net(&net->nf_frag.frags);
        return res;
 }
 
 static void nf_ct_net_exit(struct net *net)
 {
        nf_ct_frags6_sysctl_unregister(net);
-       inet_frags_exit_net(&net->nf_frag.frags, &nf_frags);
+       inet_frags_exit_net(&net->nf_frag.frags);
 }
 
 static struct pernet_operations nf_ct_net_ops = {
index 38bf38a..26f737c 100644 (file)
@@ -128,8 +128,7 @@ void ip6_frag_init(struct inet_frag_queue *q, const void *a)
 }
 EXPORT_SYMBOL(ip6_frag_init);
 
-void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq,
-                          struct inet_frags *frags)
+void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq)
 {
        struct net_device *dev = NULL;
 
@@ -138,7 +137,7 @@ void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq,
        if (fq->q.flags & INET_FRAG_COMPLETE)
                goto out;
 
-       inet_frag_kill(&fq->q, frags);
+       inet_frag_kill(&fq->q);
 
        rcu_read_lock();
        dev = dev_get_by_index_rcu(net, fq->iif);
@@ -166,7 +165,7 @@ out_rcu_unlock:
        rcu_read_unlock();
 out:
        spin_unlock(&fq->q.lock);
-       inet_frag_put(&fq->q, frags);
+       inet_frag_put(&fq->q);
 }
 EXPORT_SYMBOL(ip6_expire_frag_queue);
 
@@ -178,7 +177,7 @@ static void ip6_frag_expire(unsigned long data)
        fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
        net = container_of(fq->q.net, struct net, ipv6.frags);
 
-       ip6_expire_frag_queue(net, fq, &ip6_frags);
+       ip6_expire_frag_queue(net, fq);
 }
 
 static struct frag_queue *
@@ -363,7 +362,7 @@ found:
        return -1;
 
 discard_fq:
-       inet_frag_kill(&fq->q, &ip6_frags);
+       inet_frag_kill(&fq->q);
 err:
        __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
                        IPSTATS_MIB_REASMFAILS);
@@ -390,7 +389,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
        int sum_truesize;
        u8 ecn;
 
-       inet_frag_kill(&fq->q, &ip6_frags);
+       inet_frag_kill(&fq->q);
 
        ecn = ip_frag_ecn_table[fq->ecn];
        if (unlikely(ecn == 0xff))
@@ -568,7 +567,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
                ret = ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff);
 
                spin_unlock(&fq->q.lock);
-               inet_frag_put(&fq->q, &ip6_frags);
+               inet_frag_put(&fq->q);
                return ret;
        }
 
@@ -719,6 +718,7 @@ static int __net_init ipv6_frags_init_net(struct net *net)
        net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
        net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
        net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;
+       net->ipv6.frags.f = &ip6_frags;
 
        res = inet_frags_init_net(&net->ipv6.frags);
        if (res < 0)
@@ -726,14 +726,14 @@ static int __net_init ipv6_frags_init_net(struct net *net)
 
        res = ip6_frags_ns_sysctl_register(net);
        if (res < 0)
-               inet_frags_exit_net(&net->ipv6.frags, &ip6_frags);
+               inet_frags_exit_net(&net->ipv6.frags);
        return res;
 }
 
 static void __net_exit ipv6_frags_exit_net(struct net *net)
 {
        ip6_frags_ns_sysctl_unregister(net);
-       inet_frags_exit_net(&net->ipv6.frags, &ip6_frags);
+       inet_frags_exit_net(&net->ipv6.frags);
 }
 
 static struct pernet_operations ip6_frags_ops = {