LCOV - code coverage report
Current view: top level - net/netfilter - utils.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 108 0.0 %
Date: 2022-03-28 16:04:14 Functions: 0 9 0.0 %
Branches: 0 74 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : #include <linux/kernel.h>
       3                 :            : #include <linux/netfilter.h>
       4                 :            : #include <linux/netfilter_ipv4.h>
       5                 :            : #include <linux/netfilter_ipv6.h>
       6                 :            : #include <net/netfilter/nf_queue.h>
       7                 :            : #include <net/ip6_checksum.h>
       8                 :            : 
       9                 :            : #ifdef CONFIG_INET
      10                 :          0 : __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
      11                 :            :                        unsigned int dataoff, u8 protocol)
      12                 :            : {
      13      [ #  #  # ]:          0 :         const struct iphdr *iph = ip_hdr(skb);
      14                 :          0 :         __sum16 csum = 0;
      15                 :            : 
      16      [ #  #  # ]:          0 :         switch (skb->ip_summed) {
      17                 :          0 :         case CHECKSUM_COMPLETE:
      18         [ #  # ]:          0 :                 if (hook != NF_INET_PRE_ROUTING && hook != NF_INET_LOCAL_IN)
      19                 :            :                         break;
      20   [ #  #  #  # ]:          0 :                 if ((protocol != IPPROTO_TCP && protocol != IPPROTO_UDP &&
      21   [ #  #  #  # ]:          0 :                     !csum_fold(skb->csum)) ||
      22                 :          0 :                     !csum_tcpudp_magic(iph->saddr, iph->daddr,
      23         [ #  # ]:          0 :                                        skb->len - dataoff, protocol,
      24                 :            :                                        skb->csum)) {
      25                 :          0 :                         skb->ip_summed = CHECKSUM_UNNECESSARY;
      26                 :          0 :                         break;
      27                 :            :                 }
      28                 :            :                 /* fall through */
      29                 :            :         case CHECKSUM_NONE:
      30         [ #  # ]:          0 :                 if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP)
      31                 :          0 :                         skb->csum = 0;
      32                 :            :                 else
      33                 :          0 :                         skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
      34                 :          0 :                                                        skb->len - dataoff,
      35                 :            :                                                        protocol, 0);
      36                 :          0 :                 csum = __skb_checksum_complete(skb);
      37                 :            :         }
      38                 :          0 :         return csum;
      39                 :            : }
      40                 :            : EXPORT_SYMBOL(nf_ip_checksum);
      41                 :            : #endif
      42                 :            : 
      43                 :          0 : static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook,
      44                 :            :                                       unsigned int dataoff, unsigned int len,
      45                 :            :                                       u8 protocol)
      46                 :            : {
      47      [ #  #  # ]:          0 :         const struct iphdr *iph = ip_hdr(skb);
      48                 :          0 :         __sum16 csum = 0;
      49                 :            : 
      50      [ #  #  # ]:          0 :         switch (skb->ip_summed) {
      51                 :          0 :         case CHECKSUM_COMPLETE:
      52         [ #  # ]:          0 :                 if (len == skb->len - dataoff)
      53                 :          0 :                         return nf_ip_checksum(skb, hook, dataoff, protocol);
      54                 :            :                 /* fall through */
      55                 :            :         case CHECKSUM_NONE:
      56                 :          0 :                 skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, protocol,
      57                 :          0 :                                                skb->len - dataoff, 0);
      58                 :          0 :                 skb->ip_summed = CHECKSUM_NONE;
      59                 :          0 :                 return __skb_checksum_complete_head(skb, dataoff + len);
      60                 :            :         }
      61                 :            :         return csum;
      62                 :            : }
      63                 :            : 
      64                 :          0 : __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
      65                 :            :                         unsigned int dataoff, u8 protocol)
      66                 :            : {
      67      [ #  #  # ]:          0 :         const struct ipv6hdr *ip6h = ipv6_hdr(skb);
      68                 :          0 :         __sum16 csum = 0;
      69                 :            : 
      70      [ #  #  # ]:          0 :         switch (skb->ip_summed) {
      71                 :          0 :         case CHECKSUM_COMPLETE:
      72         [ #  # ]:          0 :                 if (hook != NF_INET_PRE_ROUTING && hook != NF_INET_LOCAL_IN)
      73                 :            :                         break;
      74         [ #  # ]:          0 :                 if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
      75                 :          0 :                                      skb->len - dataoff, protocol,
      76                 :            :                                      csum_sub(skb->csum,
      77                 :            :                                               skb_checksum(skb, 0,
      78                 :            :                                                            dataoff, 0)))) {
      79                 :          0 :                         skb->ip_summed = CHECKSUM_UNNECESSARY;
      80                 :          0 :                         break;
      81                 :            :                 }
      82                 :            :                 /* fall through */
      83                 :            :         case CHECKSUM_NONE:
      84                 :          0 :                 skb->csum = ~csum_unfold(
      85                 :          0 :                                 csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
      86                 :          0 :                                              skb->len - dataoff,
      87                 :            :                                              protocol,
      88                 :            :                                              csum_sub(0,
      89                 :            :                                                       skb_checksum(skb, 0,
      90                 :            :                                                                    dataoff, 0))));
      91                 :          0 :                 csum = __skb_checksum_complete(skb);
      92                 :            :         }
      93                 :          0 :         return csum;
      94                 :            : }
      95                 :            : EXPORT_SYMBOL(nf_ip6_checksum);
      96                 :            : 
      97                 :          0 : static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook,
      98                 :            :                                        unsigned int dataoff, unsigned int len,
      99                 :            :                                        u8 protocol)
     100                 :            : {
     101      [ #  #  # ]:          0 :         const struct ipv6hdr *ip6h = ipv6_hdr(skb);
     102                 :          0 :         __wsum hsum;
     103                 :          0 :         __sum16 csum = 0;
     104                 :            : 
     105      [ #  #  # ]:          0 :         switch (skb->ip_summed) {
     106                 :          0 :         case CHECKSUM_COMPLETE:
     107         [ #  # ]:          0 :                 if (len == skb->len - dataoff)
     108                 :          0 :                         return nf_ip6_checksum(skb, hook, dataoff, protocol);
     109                 :            :                 /* fall through */
     110                 :            :         case CHECKSUM_NONE:
     111                 :          0 :                 hsum = skb_checksum(skb, 0, dataoff, 0);
     112                 :          0 :                 skb->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr,
     113                 :            :                                                          &ip6h->daddr,
     114                 :          0 :                                                          skb->len - dataoff,
     115                 :            :                                                          protocol,
     116                 :            :                                                          csum_sub(0, hsum)));
     117                 :          0 :                 skb->ip_summed = CHECKSUM_NONE;
     118                 :          0 :                 return __skb_checksum_complete_head(skb, dataoff + len);
     119                 :            :         }
     120                 :            :         return csum;
     121                 :            : };
     122                 :            : 
     123                 :          0 : __sum16 nf_checksum(struct sk_buff *skb, unsigned int hook,
     124                 :            :                     unsigned int dataoff, u8 protocol,
     125                 :            :                     unsigned short family)
     126                 :            : {
     127                 :          0 :         __sum16 csum = 0;
     128                 :            : 
     129      [ #  #  # ]:          0 :         switch (family) {
     130                 :          0 :         case AF_INET:
     131                 :          0 :                 csum = nf_ip_checksum(skb, hook, dataoff, protocol);
     132                 :          0 :                 break;
     133                 :          0 :         case AF_INET6:
     134                 :          0 :                 csum = nf_ip6_checksum(skb, hook, dataoff, protocol);
     135                 :          0 :                 break;
     136                 :            :         }
     137                 :            : 
     138                 :          0 :         return csum;
     139                 :            : }
     140                 :            : EXPORT_SYMBOL_GPL(nf_checksum);
     141                 :            : 
     142                 :          0 : __sum16 nf_checksum_partial(struct sk_buff *skb, unsigned int hook,
     143                 :            :                             unsigned int dataoff, unsigned int len,
     144                 :            :                             u8 protocol, unsigned short family)
     145                 :            : {
     146                 :          0 :         __sum16 csum = 0;
     147                 :            : 
     148      [ #  #  # ]:          0 :         switch (family) {
     149                 :          0 :         case AF_INET:
     150                 :          0 :                 csum = nf_ip_checksum_partial(skb, hook, dataoff, len,
     151                 :            :                                               protocol);
     152                 :          0 :                 break;
     153                 :          0 :         case AF_INET6:
     154                 :          0 :                 csum = nf_ip6_checksum_partial(skb, hook, dataoff, len,
     155                 :            :                                                protocol);
     156                 :          0 :                 break;
     157                 :            :         }
     158                 :            : 
     159                 :          0 :         return csum;
     160                 :            : }
     161                 :            : EXPORT_SYMBOL_GPL(nf_checksum_partial);
     162                 :            : 
     163                 :          0 : int nf_route(struct net *net, struct dst_entry **dst, struct flowi *fl,
     164                 :            :              bool strict, unsigned short family)
     165                 :            : {
     166                 :          0 :         const struct nf_ipv6_ops *v6ops __maybe_unused;
     167                 :          0 :         int ret = 0;
     168                 :            : 
     169      [ #  #  # ]:          0 :         switch (family) {
     170                 :          0 :         case AF_INET:
     171                 :          0 :                 ret = nf_ip_route(net, dst, fl, strict);
     172                 :          0 :                 break;
     173                 :          0 :         case AF_INET6:
     174                 :          0 :                 ret = nf_ip6_route(net, dst, fl, strict);
     175                 :          0 :                 break;
     176                 :            :         }
     177                 :            : 
     178                 :          0 :         return ret;
     179                 :            : }
     180                 :            : EXPORT_SYMBOL_GPL(nf_route);
     181                 :            : 
     182                 :          0 : static int nf_ip_reroute(struct sk_buff *skb, const struct nf_queue_entry *entry)
     183                 :            : {
     184                 :            : #ifdef CONFIG_INET
     185                 :          0 :         const struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry);
     186                 :            : 
     187         [ #  # ]:          0 :         if (entry->state.hook == NF_INET_LOCAL_OUT) {
     188         [ #  # ]:          0 :                 const struct iphdr *iph = ip_hdr(skb);
     189                 :            : 
     190         [ #  # ]:          0 :                 if (!(iph->tos == rt_info->tos &&
     191         [ #  # ]:          0 :                       skb->mark == rt_info->mark &&
     192         [ #  # ]:          0 :                       iph->daddr == rt_info->daddr &&
     193         [ #  # ]:          0 :                       iph->saddr == rt_info->saddr))
     194                 :          0 :                         return ip_route_me_harder(entry->state.net, skb,
     195                 :            :                                                   RTN_UNSPEC);
     196                 :            :         }
     197                 :            : #endif
     198                 :            :         return 0;
     199                 :            : }
     200                 :            : 
     201                 :          0 : int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry)
     202                 :            : {
     203                 :          0 :         const struct nf_ipv6_ops *v6ops;
     204                 :          0 :         int ret = 0;
     205                 :            : 
     206      [ #  #  # ]:          0 :         switch (entry->state.pf) {
     207                 :          0 :         case AF_INET:
     208                 :          0 :                 ret = nf_ip_reroute(skb, entry);
     209                 :          0 :                 break;
     210                 :            :         case AF_INET6:
     211         [ #  # ]:          0 :                 v6ops = rcu_dereference(nf_ipv6_ops);
     212         [ #  # ]:          0 :                 if (v6ops)
     213                 :          0 :                         ret = v6ops->reroute(skb, entry);
     214                 :            :                 break;
     215                 :            :         }
     216                 :          0 :         return ret;
     217                 :            : }

Generated by: LCOV version 1.14