Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
[firefly-linux-kernel-4.4.55.git] / net / ipv6 / reassembly.c
index 4ff9af628e72762843cf35c083c6ee1427b57b03..da8a4e301b1b04ec5d8d0d7aa042a328c986e1d9 100644 (file)
@@ -65,36 +65,8 @@ struct ip6frag_skb_cb
 #define FRAG6_CB(skb)  ((struct ip6frag_skb_cb*)((skb)->cb))
 
 
-/*
- *     Equivalent of ipv4 struct ipq
- */
-
-struct frag_queue
-{
-       struct inet_frag_queue  q;
-
-       __be32                  id;             /* fragment id          */
-       u32                     user;
-       struct in6_addr         saddr;
-       struct in6_addr         daddr;
-
-       int                     iif;
-       unsigned int            csum;
-       __u16                   nhoffset;
-};
-
 static struct inet_frags ip6_frags;
 
-int ip6_frag_nqueues(struct net *net)
-{
-       return net->ipv6.frags.nqueues;
-}
-
-int ip6_frag_mem(struct net *net)
-{
-       return atomic_read(&net->ipv6.frags.mem);
-}
-
 static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
                          struct net_device *dev);
 
@@ -159,46 +131,18 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a)
 }
 EXPORT_SYMBOL(ip6_frag_init);
 
-/* Destruction primitives. */
-
-static __inline__ void fq_put(struct frag_queue *fq)
-{
-       inet_frag_put(&fq->q, &ip6_frags);
-}
-
-/* Kill fq entry. It is not destroyed immediately,
- * because caller (and someone more) holds reference count.
- */
-static __inline__ void fq_kill(struct frag_queue *fq)
-{
-       inet_frag_kill(&fq->q, &ip6_frags);
-}
-
-static void ip6_evictor(struct net *net, struct inet6_dev *idev)
+void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq,
+                          struct inet_frags *frags)
 {
-       int evicted;
-
-       evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags);
-       if (evicted)
-               IP6_ADD_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS, evicted);
-}
-
-static void ip6_frag_expire(unsigned long data)
-{
-       struct frag_queue *fq;
        struct net_device *dev = NULL;
-       struct net *net;
-
-       fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
 
        spin_lock(&fq->q.lock);
 
        if (fq->q.last_in & INET_FRAG_COMPLETE)
                goto out;
 
-       fq_kill(fq);
+       inet_frag_kill(&fq->q, frags);
 
-       net = container_of(fq->q.net, struct net, ipv6.frags);
        rcu_read_lock();
        dev = dev_get_by_index_rcu(net, fq->iif);
        if (!dev)
@@ -222,7 +166,19 @@ out_rcu_unlock:
        rcu_read_unlock();
 out:
        spin_unlock(&fq->q.lock);
-       fq_put(fq);
+       inet_frag_put(&fq->q, frags);
+}
+EXPORT_SYMBOL(ip6_expire_frag_queue);
+
+static void ip6_frag_expire(unsigned long data)
+{
+       struct frag_queue *fq;
+       struct net *net;
+
+       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);
 }
 
 static __inline__ struct frag_queue *
@@ -391,7 +347,7 @@ found:
        return -1;
 
 discard_fq:
-       fq_kill(fq);
+       inet_frag_kill(&fq->q, &ip6_frags);
 err:
        IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
                      IPSTATS_MIB_REASMFAILS);
@@ -417,7 +373,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
        unsigned int nhoff;
        int sum_truesize;
 
-       fq_kill(fq);
+       inet_frag_kill(&fq->q, &ip6_frags);
 
        /* Make the one we just received the head. */
        if (prev) {
@@ -550,6 +506,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
        struct frag_queue *fq;
        const struct ipv6hdr *hdr = ipv6_hdr(skb);
        struct net *net = dev_net(skb_dst(skb)->dev);
+       int evicted;
 
        IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS);
 
@@ -574,8 +531,10 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
                return 1;
        }
 
-       if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
-               ip6_evictor(net, ip6_dst_idev(skb_dst(skb)));
+       evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags, false);
+       if (evicted)
+               IP6_ADD_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
+                                IPSTATS_MIB_REASMFAILS, evicted);
 
        fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr);
        if (fq != NULL) {
@@ -586,7 +545,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);
-               fq_put(fq);
+               inet_frag_put(&fq->q, &ip6_frags);
                return ret;
        }