LCOV - code coverage report
Current view: top level - include/net - ipv6_frag.h (source / functions) Hit Total Coverage
Test: Real Lines: 0 28 0.0 %
Date: 2020-10-17 15:46:43 Functions: 0 5 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: GPL-2.0 */
       2                 :            : #ifndef _IPV6_FRAG_H
       3                 :            : #define _IPV6_FRAG_H
       4                 :            : #include <linux/kernel.h>
       5                 :            : #include <net/addrconf.h>
       6                 :            : #include <net/ipv6.h>
       7                 :            : #include <net/inet_frag.h>
       8                 :            : 
       9                 :            : enum ip6_defrag_users {
      10                 :            :         IP6_DEFRAG_LOCAL_DELIVER,
      11                 :            :         IP6_DEFRAG_CONNTRACK_IN,
      12                 :            :         __IP6_DEFRAG_CONNTRACK_IN       = IP6_DEFRAG_CONNTRACK_IN + USHRT_MAX,
      13                 :            :         IP6_DEFRAG_CONNTRACK_OUT,
      14                 :            :         __IP6_DEFRAG_CONNTRACK_OUT      = IP6_DEFRAG_CONNTRACK_OUT + USHRT_MAX,
      15                 :            :         IP6_DEFRAG_CONNTRACK_BRIDGE_IN,
      16                 :            :         __IP6_DEFRAG_CONNTRACK_BRIDGE_IN = IP6_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX,
      17                 :            : };
      18                 :            : 
      19                 :            : /*
      20                 :            :  *      Equivalent of ipv4 struct ip
      21                 :            :  */
      22                 :            : struct frag_queue {
      23                 :            :         struct inet_frag_queue  q;
      24                 :            : 
      25                 :            :         int                     iif;
      26                 :            :         __u16                   nhoffset;
      27                 :            :         u8                      ecn;
      28                 :            : };
      29                 :            : 
      30                 :            : #if IS_ENABLED(CONFIG_IPV6)
      31                 :          0 : static inline void ip6frag_init(struct inet_frag_queue *q, const void *a)
      32                 :            : {
      33                 :            :         struct frag_queue *fq = container_of(q, struct frag_queue, q);
      34                 :            :         const struct frag_v6_compare_key *key = a;
      35                 :            : 
      36                 :          0 :         q->key.v6 = *key;
      37                 :          0 :         fq->ecn = 0;
      38                 :          0 : }
      39                 :            : 
      40                 :          0 : static inline u32 ip6frag_key_hashfn(const void *data, u32 len, u32 seed)
      41                 :            : {
      42                 :          0 :         return jhash2(data,
      43                 :            :                       sizeof(struct frag_v6_compare_key) / sizeof(u32), seed);
      44                 :            : }
      45                 :            : 
      46                 :          0 : static inline u32 ip6frag_obj_hashfn(const void *data, u32 len, u32 seed)
      47                 :            : {
      48                 :            :         const struct inet_frag_queue *fq = data;
      49                 :            : 
      50                 :          0 :         return jhash2((const u32 *)&fq->key.v6,
      51                 :            :                       sizeof(struct frag_v6_compare_key) / sizeof(u32), seed);
      52                 :            : }
      53                 :            : 
      54                 :            : static inline int
      55                 :          0 : ip6frag_obj_cmpfn(struct rhashtable_compare_arg *arg, const void *ptr)
      56                 :            : {
      57                 :          0 :         const struct frag_v6_compare_key *key = arg->key;
      58                 :            :         const struct inet_frag_queue *fq = ptr;
      59                 :            : 
      60                 :          0 :         return !!memcmp(&fq->key, key, sizeof(*key));
      61                 :            : }
      62                 :            : 
      63                 :            : static inline void
      64                 :          0 : ip6frag_expire_frag_queue(struct net *net, struct frag_queue *fq)
      65                 :            : {
      66                 :            :         struct net_device *dev = NULL;
      67                 :            :         struct sk_buff *head;
      68                 :            : 
      69                 :            :         rcu_read_lock();
      70                 :          0 :         if (fq->q.fqdir->dead)
      71                 :            :                 goto out_rcu_unlock;
      72                 :            :         spin_lock(&fq->q.lock);
      73                 :            : 
      74                 :          0 :         if (fq->q.flags & INET_FRAG_COMPLETE)
      75                 :            :                 goto out;
      76                 :            : 
      77                 :          0 :         inet_frag_kill(&fq->q);
      78                 :            : 
      79                 :          0 :         dev = dev_get_by_index_rcu(net, fq->iif);
      80                 :          0 :         if (!dev)
      81                 :            :                 goto out;
      82                 :            : 
      83                 :          0 :         __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
      84                 :          0 :         __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT);
      85                 :            : 
      86                 :            :         /* Don't send error if the first segment did not arrive. */
      87                 :          0 :         if (!(fq->q.flags & INET_FRAG_FIRST_IN))
      88                 :            :                 goto out;
      89                 :            : 
      90                 :            :         /* sk_buff::dev and sk_buff::rbnode are unionized. So we
      91                 :            :          * pull the head out of the tree in order to be able to
      92                 :            :          * deal with head->dev.
      93                 :            :          */
      94                 :          0 :         head = inet_frag_pull_head(&fq->q);
      95                 :          0 :         if (!head)
      96                 :            :                 goto out;
      97                 :            : 
      98                 :          0 :         head->dev = dev;
      99                 :            :         spin_unlock(&fq->q.lock);
     100                 :            : 
     101                 :          0 :         icmpv6_send(head, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0);
     102                 :          0 :         kfree_skb(head);
     103                 :          0 :         goto out_rcu_unlock;
     104                 :            : 
     105                 :            : out:
     106                 :            :         spin_unlock(&fq->q.lock);
     107                 :            : out_rcu_unlock:
     108                 :            :         rcu_read_unlock();
     109                 :          0 :         inet_frag_put(&fq->q);
     110                 :          0 : }
     111                 :            : #endif
     112                 :            : #endif
    

Generated by: LCOV version 1.14