LCOV - code coverage report
Current view: top level - net/ipv6 - ip6_input.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_qemu_modules_combined.info Lines: 83 163 50.9 %
Date: 2020-09-30 20:25:01 Functions: 8 12 66.7 %
Branches: 60 182 33.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-or-later
       2                 :            : /*
       3                 :            :  *      IPv6 input
       4                 :            :  *      Linux INET6 implementation
       5                 :            :  *
       6                 :            :  *      Authors:
       7                 :            :  *      Pedro Roque             <roque@di.fc.ul.pt>
       8                 :            :  *      Ian P. Morris           <I.P.Morris@soton.ac.uk>
       9                 :            :  *
      10                 :            :  *      Based in linux/net/ipv4/ip_input.c
      11                 :            :  */
      12                 :            : /* Changes
      13                 :            :  *
      14                 :            :  *      Mitsuru KANDA @USAGI and
      15                 :            :  *      YOSHIFUJI Hideaki @USAGI: Remove ipv6_parse_exthdrs().
      16                 :            :  */
      17                 :            : 
      18                 :            : #include <linux/errno.h>
      19                 :            : #include <linux/types.h>
      20                 :            : #include <linux/socket.h>
      21                 :            : #include <linux/sockios.h>
      22                 :            : #include <linux/net.h>
      23                 :            : #include <linux/netdevice.h>
      24                 :            : #include <linux/in6.h>
      25                 :            : #include <linux/icmpv6.h>
      26                 :            : #include <linux/mroute6.h>
      27                 :            : #include <linux/slab.h>
      28                 :            : #include <linux/indirect_call_wrapper.h>
      29                 :            : 
      30                 :            : #include <linux/netfilter.h>
      31                 :            : #include <linux/netfilter_ipv6.h>
      32                 :            : 
      33                 :            : #include <net/sock.h>
      34                 :            : #include <net/snmp.h>
      35                 :            : 
      36                 :            : #include <net/ipv6.h>
      37                 :            : #include <net/protocol.h>
      38                 :            : #include <net/transp_v6.h>
      39                 :            : #include <net/rawv6.h>
      40                 :            : #include <net/ndisc.h>
      41                 :            : #include <net/ip6_route.h>
      42                 :            : #include <net/addrconf.h>
      43                 :            : #include <net/xfrm.h>
      44                 :            : #include <net/inet_ecn.h>
      45                 :            : #include <net/dst_metadata.h>
      46                 :            : 
      47                 :            : INDIRECT_CALLABLE_DECLARE(void udp_v6_early_demux(struct sk_buff *));
      48                 :            : INDIRECT_CALLABLE_DECLARE(void tcp_v6_early_demux(struct sk_buff *));
      49                 :       2088 : static void ip6_rcv_finish_core(struct net *net, struct sock *sk,
      50                 :            :                                 struct sk_buff *skb)
      51                 :            : {
      52                 :            :         void (*edemux)(struct sk_buff *skb);
      53                 :            : 
      54   [ +  -  +  +  :       4176 :         if (net->ipv4.sysctl_ip_early_demux && !skb_dst(skb) && skb->sk == NULL) {
                   +  - ]
      55                 :            :                 const struct inet6_protocol *ipprot;
      56                 :            : 
      57                 :        924 :                 ipprot = rcu_dereference(inet6_protos[ipv6_hdr(skb)->nexthdr]);
      58   [ +  -  -  + ]:        924 :                 if (ipprot && (edemux = READ_ONCE(ipprot->early_demux)))
      59                 :          0 :                         INDIRECT_CALL_2(edemux, tcp_v6_early_demux,
      60                 :            :                                         udp_v6_early_demux, skb);
      61                 :            :         }
      62         [ +  + ]:       2088 :         if (!skb_valid_dst(skb))
      63                 :        462 :                 ip6_route_input(skb);
      64                 :       2088 : }
      65                 :            : 
      66                 :       2088 : int ip6_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
      67                 :            : {
      68                 :            :         /* if ingress device is enslaved to an L3 master device pass the
      69                 :            :          * skb to its handler for processing
      70                 :            :          */
      71                 :            :         skb = l3mdev_ip6_rcv(skb);
      72         [ +  - ]:       2088 :         if (!skb)
      73                 :            :                 return NET_RX_SUCCESS;
      74                 :       2088 :         ip6_rcv_finish_core(net, sk, skb);
      75                 :            : 
      76                 :       2088 :         return dst_input(skb);
      77                 :            : }
      78                 :            : 
      79                 :          0 : static void ip6_sublist_rcv_finish(struct list_head *head)
      80                 :            : {
      81                 :            :         struct sk_buff *skb, *next;
      82                 :            : 
      83         [ #  # ]:          0 :         list_for_each_entry_safe(skb, next, head, list) {
      84                 :            :                 skb_list_del_init(skb);
      85                 :            :                 dst_input(skb);
      86                 :            :         }
      87                 :          0 : }
      88                 :            : 
      89                 :          0 : static void ip6_list_rcv_finish(struct net *net, struct sock *sk,
      90                 :            :                                 struct list_head *head)
      91                 :            : {
      92                 :            :         struct dst_entry *curr_dst = NULL;
      93                 :            :         struct sk_buff *skb, *next;
      94                 :            :         struct list_head sublist;
      95                 :            : 
      96                 :            :         INIT_LIST_HEAD(&sublist);
      97         [ #  # ]:          0 :         list_for_each_entry_safe(skb, next, head, list) {
      98                 :            :                 struct dst_entry *dst;
      99                 :            : 
     100                 :            :                 skb_list_del_init(skb);
     101                 :            :                 /* if ingress device is enslaved to an L3 master device pass the
     102                 :            :                  * skb to its handler for processing
     103                 :            :                  */
     104                 :            :                 skb = l3mdev_ip6_rcv(skb);
     105         [ #  # ]:          0 :                 if (!skb)
     106                 :          0 :                         continue;
     107                 :          0 :                 ip6_rcv_finish_core(net, sk, skb);
     108                 :            :                 dst = skb_dst(skb);
     109         [ #  # ]:          0 :                 if (curr_dst != dst) {
     110                 :            :                         /* dispatch old sublist */
     111         [ #  # ]:          0 :                         if (!list_empty(&sublist))
     112                 :          0 :                                 ip6_sublist_rcv_finish(&sublist);
     113                 :            :                         /* start new sublist */
     114                 :            :                         INIT_LIST_HEAD(&sublist);
     115                 :            :                         curr_dst = dst;
     116                 :            :                 }
     117                 :          0 :                 list_add_tail(&skb->list, &sublist);
     118                 :            :         }
     119                 :            :         /* dispatch final sublist */
     120                 :          0 :         ip6_sublist_rcv_finish(&sublist);
     121                 :          0 : }
     122                 :            : 
     123                 :       2088 : static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
     124                 :            :                                     struct net *net)
     125                 :            : {
     126                 :            :         const struct ipv6hdr *hdr;
     127                 :            :         u32 pkt_len;
     128                 :            :         struct inet6_dev *idev;
     129                 :            : 
     130         [ -  + ]:       2088 :         if (skb->pkt_type == PACKET_OTHERHOST) {
     131                 :          0 :                 kfree_skb(skb);
     132                 :          0 :                 return NULL;
     133                 :            :         }
     134                 :            : 
     135                 :            :         rcu_read_lock();
     136                 :            : 
     137                 :       2088 :         idev = __in6_dev_get(skb->dev);
     138                 :            : 
     139         [ +  - ]:      10440 :         __IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_IN, skb->len);
     140                 :            : 
     141   [ +  -  +  - ]:       2088 :         if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
     142         [ -  + ]:       2088 :             !idev || unlikely(idev->cnf.disable_ipv6)) {
     143         [ #  # ]:          0 :                 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
     144                 :            :                 goto drop;
     145                 :            :         }
     146                 :            : 
     147                 :       2088 :         memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm));
     148                 :            : 
     149                 :            :         /*
     150                 :            :          * Store incoming device index. When the packet will
     151                 :            :          * be queued, we cannot refer to skb->dev anymore.
     152                 :            :          *
     153                 :            :          * BTW, when we send a packet for our own local address on a
     154                 :            :          * non-loopback interface (e.g. ethX), it is being delivered
     155                 :            :          * via the loopback interface (lo) here; skb->dev = loopback_dev.
     156                 :            :          * It, however, should be considered as if it is being
     157                 :            :          * arrived via the sending interface (ethX), because of the
     158                 :            :          * nature of scoping architecture. --yoshfuji
     159                 :            :          */
     160         [ +  + ]:       3714 :         IP6CB(skb)->iif = skb_valid_dst(skb) ? ip6_dst_idev(skb_dst(skb))->dev->ifindex : dev->ifindex;
     161                 :            : 
     162         [ +  - ]:       2088 :         if (unlikely(!pskb_may_pull(skb, sizeof(*hdr))))
     163                 :            :                 goto err;
     164                 :            : 
     165                 :            :         hdr = ipv6_hdr(skb);
     166                 :            : 
     167         [ +  - ]:       2088 :         if (hdr->version != 6)
     168                 :            :                 goto err;
     169                 :            : 
     170   [ +  -  -  +  :      14616 :         __IP6_ADD_STATS(net, idev,
                   -  + ]
     171                 :            :                         IPSTATS_MIB_NOECTPKTS +
     172                 :            :                                 (ipv6_get_dsfield(hdr) & INET_ECN_MASK),
     173                 :            :                         max_t(unsigned short, 1, skb_shinfo(skb)->gso_segs));
     174                 :            :         /*
     175                 :            :          * RFC4291 2.5.3
     176                 :            :          * The loopback address must not be used as the source address in IPv6
     177                 :            :          * packets that are sent outside of a single node. [..]
     178                 :            :          * A packet received on an interface with a destination address
     179                 :            :          * of loopback must be dropped.
     180                 :            :          */
     181   [ +  -  -  + ]:       4176 :         if ((ipv6_addr_loopback(&hdr->saddr) ||
     182         [ #  # ]:          0 :              ipv6_addr_loopback(&hdr->daddr)) &&
     183         [ #  # ]:          0 :             !(dev->flags & IFF_LOOPBACK) &&
     184                 :            :             !netif_is_l3_master(dev))
     185                 :            :                 goto err;
     186                 :            : 
     187                 :            :         /* RFC4291 Errata ID: 3480
     188                 :            :          * Interface-Local scope spans only a single interface on a
     189                 :            :          * node and is useful only for loopback transmission of
     190                 :            :          * multicast.  Packets with interface-local scope received
     191                 :            :          * from another node must be discarded.
     192                 :            :          */
     193   [ +  +  +  - ]:       2550 :         if (!(skb->pkt_type == PACKET_LOOPBACK ||
     194         [ +  + ]:        924 :               dev->flags & IFF_LOOPBACK) &&
     195         [ +  - ]:        438 :             ipv6_addr_is_multicast(&hdr->daddr) &&
     196                 :        438 :             IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 1)
     197                 :            :                 goto err;
     198                 :            : 
     199                 :            :         /* If enabled, drop unicast packets that were encapsulated in link-layer
     200                 :            :          * multicast or broadcast to protected against the so-called "hole-196"
     201                 :            :          * attack in 802.11 wireless.
     202                 :            :          */
     203   [ +  +  -  + ]:       2112 :         if (!ipv6_addr_is_multicast(&hdr->daddr) &&
     204                 :         24 :             (skb->pkt_type == PACKET_BROADCAST ||
     205         [ #  # ]:          0 :              skb->pkt_type == PACKET_MULTICAST) &&
     206                 :          0 :             idev->cnf.drop_unicast_in_l2_multicast)
     207                 :            :                 goto err;
     208                 :            : 
     209                 :            :         /* RFC4291 2.7
     210                 :            :          * Nodes must not originate a packet to a multicast address whose scope
     211                 :            :          * field contains the reserved value 0; if such a packet is received, it
     212                 :            :          * must be silently dropped.
     213                 :            :          */
     214   [ +  +  +  - ]:       4152 :         if (ipv6_addr_is_multicast(&hdr->daddr) &&
     215                 :       2064 :             IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 0)
     216                 :            :                 goto err;
     217                 :            : 
     218                 :            :         /*
     219                 :            :          * RFC4291 2.7
     220                 :            :          * Multicast addresses must not be used as source addresses in IPv6
     221                 :            :          * packets or appear in any Routing header.
     222                 :            :          */
     223         [ +  - ]:       2088 :         if (ipv6_addr_is_multicast(&hdr->saddr))
     224                 :            :                 goto err;
     225                 :            : 
     226                 :            :         /* While RFC4291 is not explicit about v4mapped addresses
     227                 :            :          * in IPv6 headers, it seems clear linux dual-stack
     228                 :            :          * model can not deal properly with these.
     229                 :            :          * Security models could be fooled by ::ffff:127.0.0.1 for example.
     230                 :            :          *
     231                 :            :          * https://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful-02
     232                 :            :          */
     233         [ +  - ]:       2088 :         if (ipv6_addr_v4mapped(&hdr->saddr))
     234                 :            :                 goto err;
     235                 :            : 
     236                 :       2088 :         skb->transport_header = skb->network_header + sizeof(*hdr);
     237                 :       2088 :         IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
     238                 :            : 
     239                 :       2088 :         pkt_len = ntohs(hdr->payload_len);
     240                 :            : 
     241                 :            :         /* pkt_len may be zero if Jumbo payload option is present */
     242   [ -  +  #  # ]:       2088 :         if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) {
     243         [ -  + ]:       2088 :                 if (pkt_len + sizeof(struct ipv6hdr) > skb->len) {
     244         [ #  # ]:          0 :                         __IP6_INC_STATS(net,
     245                 :            :                                         idev, IPSTATS_MIB_INTRUNCATEDPKTS);
     246                 :            :                         goto drop;
     247                 :            :                 }
     248         [ -  + ]:       2088 :                 if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) {
     249         [ #  # ]:          0 :                         __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
     250                 :            :                         goto drop;
     251                 :            :                 }
     252                 :            :                 hdr = ipv6_hdr(skb);
     253                 :            :         }
     254                 :            : 
     255         [ -  + ]:       2088 :         if (hdr->nexthdr == NEXTHDR_HOP) {
     256         [ #  # ]:          0 :                 if (ipv6_parse_hopopts(skb) < 0) {
     257         [ #  # ]:          0 :                         __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
     258                 :            :                         rcu_read_unlock();
     259                 :          0 :                         return NULL;
     260                 :            :                 }
     261                 :            :         }
     262                 :            : 
     263                 :            :         rcu_read_unlock();
     264                 :            : 
     265                 :            :         /* Must drop socket now because of tproxy. */
     266                 :       2088 :         skb_orphan(skb);
     267                 :            : 
     268                 :       2088 :         return skb;
     269                 :            : err:
     270         [ #  # ]:          0 :         __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
     271                 :            : drop:
     272                 :            :         rcu_read_unlock();
     273                 :          0 :         kfree_skb(skb);
     274                 :          0 :         return NULL;
     275                 :            : }
     276                 :            : 
     277                 :       2088 : int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
     278                 :            : {
     279                 :       2088 :         struct net *net = dev_net(skb->dev);
     280                 :            : 
     281                 :       2088 :         skb = ip6_rcv_core(skb, dev, net);
     282         [ +  - ]:       2088 :         if (skb == NULL)
     283                 :            :                 return NET_RX_DROP;
     284                 :       2088 :         return NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING,
     285                 :            :                        net, NULL, skb, dev, NULL,
     286                 :            :                        ip6_rcv_finish);
     287                 :            : }
     288                 :            : 
     289                 :          0 : static void ip6_sublist_rcv(struct list_head *head, struct net_device *dev,
     290                 :            :                             struct net *net)
     291                 :            : {
     292                 :          0 :         NF_HOOK_LIST(NFPROTO_IPV6, NF_INET_PRE_ROUTING, net, NULL,
     293                 :            :                      head, dev, NULL, ip6_rcv_finish);
     294                 :          0 :         ip6_list_rcv_finish(net, NULL, head);
     295                 :          0 : }
     296                 :            : 
     297                 :            : /* Receive a list of IPv6 packets */
     298                 :          0 : void ipv6_list_rcv(struct list_head *head, struct packet_type *pt,
     299                 :            :                    struct net_device *orig_dev)
     300                 :            : {
     301                 :            :         struct net_device *curr_dev = NULL;
     302                 :            :         struct net *curr_net = NULL;
     303                 :            :         struct sk_buff *skb, *next;
     304                 :            :         struct list_head sublist;
     305                 :            : 
     306                 :            :         INIT_LIST_HEAD(&sublist);
     307         [ #  # ]:          0 :         list_for_each_entry_safe(skb, next, head, list) {
     308                 :          0 :                 struct net_device *dev = skb->dev;
     309                 :            :                 struct net *net = dev_net(dev);
     310                 :            : 
     311                 :            :                 skb_list_del_init(skb);
     312                 :          0 :                 skb = ip6_rcv_core(skb, dev, net);
     313         [ #  # ]:          0 :                 if (skb == NULL)
     314                 :          0 :                         continue;
     315                 :            : 
     316         [ #  # ]:          0 :                 if (curr_dev != dev || curr_net != net) {
     317                 :            :                         /* dispatch old sublist */
     318         [ #  # ]:          0 :                         if (!list_empty(&sublist))
     319                 :          0 :                                 ip6_sublist_rcv(&sublist, curr_dev, curr_net);
     320                 :            :                         /* start new sublist */
     321                 :            :                         INIT_LIST_HEAD(&sublist);
     322                 :            :                         curr_dev = dev;
     323                 :            :                         curr_net = net;
     324                 :            :                 }
     325                 :          0 :                 list_add_tail(&skb->list, &sublist);
     326                 :            :         }
     327                 :            :         /* dispatch final sublist */
     328                 :          0 :         ip6_sublist_rcv(&sublist, curr_dev, curr_net);
     329                 :          0 : }
     330                 :            : 
     331                 :            : INDIRECT_CALLABLE_DECLARE(int udpv6_rcv(struct sk_buff *));
     332                 :            : INDIRECT_CALLABLE_DECLARE(int tcp_v6_rcv(struct sk_buff *));
     333                 :            : 
     334                 :            : /*
     335                 :            :  *      Deliver the packet to the host
     336                 :            :  */
     337                 :       2088 : void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
     338                 :            :                               bool have_final)
     339                 :            : {
     340                 :            :         const struct inet6_protocol *ipprot;
     341                 :            :         struct inet6_dev *idev;
     342                 :            :         unsigned int nhoff;
     343                 :            :         bool raw;
     344                 :            : 
     345                 :            :         /*
     346                 :            :          *      Parse extension headers
     347                 :            :          */
     348                 :            : 
     349                 :            : resubmit:
     350                 :            :         idev = ip6_dst_idev(skb_dst(skb));
     351                 :       2088 :         nhoff = IP6CB(skb)->nhoff;
     352         [ +  - ]:       2088 :         if (!have_final) {
     353         [ +  - ]:       4176 :                 if (!pskb_pull(skb, skb_transport_offset(skb)))
     354                 :            :                         goto discard;
     355                 :       2088 :                 nexthdr = skb_network_header(skb)[nhoff];
     356                 :            :         }
     357                 :            : 
     358                 :            : resubmit_final:
     359                 :       2088 :         raw = raw6_local_deliver(skb, nexthdr);
     360                 :       4176 :         ipprot = rcu_dereference(inet6_protos[nexthdr]);
     361         [ +  - ]:       2088 :         if (ipprot) {
     362                 :            :                 int ret;
     363                 :            : 
     364         [ -  + ]:       2088 :                 if (have_final) {
     365         [ #  # ]:          0 :                         if (!(ipprot->flags & INET6_PROTO_FINAL)) {
     366                 :            :                                 /* Once we've seen a final protocol don't
     367                 :            :                                  * allow encapsulation on any non-final
     368                 :            :                                  * ones. This allows foo in UDP encapsulation
     369                 :            :                                  * to work.
     370                 :            :                                  */
     371                 :            :                                 goto discard;
     372                 :            :                         }
     373         [ +  - ]:       2088 :                 } else if (ipprot->flags & INET6_PROTO_FINAL) {
     374                 :            :                         const struct ipv6hdr *hdr;
     375                 :            :                         int sdif = inet6_sdif(skb);
     376                 :            :                         struct net_device *dev;
     377                 :            : 
     378                 :            :                         /* Only do this once for first final protocol */
     379                 :            :                         have_final = true;
     380                 :            : 
     381                 :            :                         /* Free reference early: we don't need it any more,
     382                 :            :                            and it may hold ip_conntrack module loaded
     383                 :            :                            indefinitely. */
     384                 :            :                         nf_reset_ct(skb);
     385                 :            : 
     386                 :       2088 :                         skb_postpull_rcsum(skb, skb_network_header(skb),
     387                 :            :                                            skb_network_header_len(skb));
     388                 :            :                         hdr = ipv6_hdr(skb);
     389                 :            : 
     390                 :            :                         /* skb->dev passed may be master dev for vrfs. */
     391         [ -  + ]:       2088 :                         if (sdif) {
     392                 :          0 :                                 dev = dev_get_by_index_rcu(net, sdif);
     393         [ #  # ]:          0 :                                 if (!dev)
     394                 :            :                                         goto discard;
     395                 :            :                         } else {
     396                 :       2088 :                                 dev = skb->dev;
     397                 :            :                         }
     398                 :            : 
     399   [ +  +  -  + ]:       4152 :                         if (ipv6_addr_is_multicast(&hdr->daddr) &&
     400                 :       2064 :                             !ipv6_chk_mcast_addr(dev, &hdr->daddr,
     401         [ #  # ]:          0 :                                                  &hdr->saddr) &&
     402                 :          0 :                             !ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb)))
     403                 :            :                                 goto discard;
     404                 :            :                 }
     405   [ -  +  #  # ]:       2088 :                 if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
     406                 :            :                     !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
     407                 :            :                         goto discard;
     408                 :            : 
     409                 :       2088 :                 ret = INDIRECT_CALL_2(ipprot->handler, tcp_v6_rcv, udpv6_rcv,
     410                 :            :                                       skb);
     411         [ -  + ]:       2088 :                 if (ret > 0) {
     412         [ #  # ]:          0 :                         if (ipprot->flags & INET6_PROTO_FINAL) {
     413                 :            :                                 /* Not an extension header, most likely UDP
     414                 :            :                                  * encapsulation. Use return value as nexthdr
     415                 :            :                                  * protocol not nhoff (which presumably is
     416                 :            :                                  * not set by handler).
     417                 :            :                                  */
     418                 :            :                                 nexthdr = ret;
     419                 :            :                                 goto resubmit_final;
     420                 :            :                         } else {
     421                 :            :                                 goto resubmit;
     422                 :            :                         }
     423         [ +  - ]:       2088 :                 } else if (ret == 0) {
     424         [ +  - ]:      14616 :                         __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDELIVERS);
     425                 :            :                 }
     426                 :            :         } else {
     427         [ #  # ]:          0 :                 if (!raw) {
     428         [ #  # ]:          0 :                         if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
     429         [ #  # ]:          0 :                                 __IP6_INC_STATS(net, idev,
     430                 :            :                                                 IPSTATS_MIB_INUNKNOWNPROTOS);
     431                 :          0 :                                 icmpv6_send(skb, ICMPV6_PARAMPROB,
     432                 :            :                                             ICMPV6_UNK_NEXTHDR, nhoff);
     433                 :            :                         }
     434                 :          0 :                         kfree_skb(skb);
     435                 :            :                 } else {
     436         [ #  # ]:          0 :                         __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDELIVERS);
     437                 :          0 :                         consume_skb(skb);
     438                 :            :                 }
     439                 :            :         }
     440                 :       2088 :         return;
     441                 :            : 
     442                 :            : discard:
     443         [ #  # ]:          0 :         __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
     444                 :          0 :         kfree_skb(skb);
     445                 :            : }
     446                 :            : 
     447                 :       2088 : static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
     448                 :            : {
     449                 :            :         rcu_read_lock();
     450                 :       2088 :         ip6_protocol_deliver_rcu(net, skb, 0, false);
     451                 :            :         rcu_read_unlock();
     452                 :            : 
     453                 :       2088 :         return 0;
     454                 :            : }
     455                 :            : 
     456                 :            : 
     457                 :       2088 : int ip6_input(struct sk_buff *skb)
     458                 :            : {
     459                 :       2088 :         return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_IN,
     460                 :       2088 :                        dev_net(skb->dev), NULL, skb, skb->dev, NULL,
     461                 :            :                        ip6_input_finish);
     462                 :            : }
     463                 :            : EXPORT_SYMBOL_GPL(ip6_input);
     464                 :            : 
     465                 :       2064 : int ip6_mc_input(struct sk_buff *skb)
     466                 :            : {
     467                 :            :         int sdif = inet6_sdif(skb);
     468                 :            :         const struct ipv6hdr *hdr;
     469                 :            :         struct net_device *dev;
     470                 :            :         bool deliver;
     471                 :            : 
     472         [ +  - ]:      16512 :         __IP6_UPD_PO_STATS(dev_net(skb_dst(skb)->dev),
     473                 :            :                          __in6_dev_get_safely(skb->dev), IPSTATS_MIB_INMCAST,
     474                 :            :                          skb->len);
     475                 :            : 
     476                 :            :         /* skb->dev passed may be master dev for vrfs. */
     477         [ -  + ]:       2064 :         if (sdif) {
     478                 :            :                 rcu_read_lock();
     479                 :          0 :                 dev = dev_get_by_index_rcu(dev_net(skb->dev), sdif);
     480         [ #  # ]:          0 :                 if (!dev) {
     481                 :            :                         rcu_read_unlock();
     482                 :          0 :                         kfree_skb(skb);
     483                 :          0 :                         return -ENODEV;
     484                 :            :                 }
     485                 :            :         } else {
     486                 :       2064 :                 dev = skb->dev;
     487                 :            :         }
     488                 :            : 
     489                 :            :         hdr = ipv6_hdr(skb);
     490                 :       2064 :         deliver = ipv6_chk_mcast_addr(dev, &hdr->daddr, NULL);
     491         [ -  + ]:       2064 :         if (sdif)
     492                 :            :                 rcu_read_unlock();
     493                 :            : 
     494                 :            : #ifdef CONFIG_IPV6_MROUTE
     495                 :            :         /*
     496                 :            :          *      IPv6 multicast router mode is now supported ;)
     497                 :            :          */
     498   [ -  +  #  # ]:       4128 :         if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding &&
     499                 :          0 :             !(ipv6_addr_type(&hdr->daddr) &
     500         [ #  # ]:          0 :               (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)) &&
     501                 :          0 :             likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) {
     502                 :            :                 /*
     503                 :            :                  * Okay, we try to forward - split and duplicate
     504                 :            :                  * packets.
     505                 :            :                  */
     506                 :            :                 struct sk_buff *skb2;
     507                 :            :                 struct inet6_skb_parm *opt = IP6CB(skb);
     508                 :            : 
     509                 :            :                 /* Check for MLD */
     510         [ #  # ]:          0 :                 if (unlikely(opt->flags & IP6SKB_ROUTERALERT)) {
     511                 :            :                         /* Check if this is a mld message */
     512                 :          0 :                         u8 nexthdr = hdr->nexthdr;
     513                 :            :                         __be16 frag_off;
     514                 :            :                         int offset;
     515                 :            : 
     516                 :            :                         /* Check if the value of Router Alert
     517                 :            :                          * is for MLD (0x0000).
     518                 :            :                          */
     519         [ #  # ]:          0 :                         if (opt->ra == htons(IPV6_OPT_ROUTERALERT_MLD)) {
     520                 :            :                                 deliver = false;
     521                 :            : 
     522         [ #  # ]:          0 :                                 if (!ipv6_ext_hdr(nexthdr)) {
     523                 :            :                                         /* BUG */
     524                 :            :                                         goto out;
     525                 :            :                                 }
     526                 :          0 :                                 offset = ipv6_skip_exthdr(skb, sizeof(*hdr),
     527                 :            :                                                           &nexthdr, &frag_off);
     528         [ #  # ]:          0 :                                 if (offset < 0)
     529                 :            :                                         goto out;
     530                 :            : 
     531         [ #  # ]:          0 :                                 if (ipv6_is_mld(skb, nexthdr, offset))
     532                 :            :                                         deliver = true;
     533                 :            : 
     534                 :            :                                 goto out;
     535                 :            :                         }
     536                 :            :                         /* unknown RA - process it normally */
     537                 :            :                 }
     538                 :            : 
     539         [ #  # ]:          0 :                 if (deliver)
     540                 :          0 :                         skb2 = skb_clone(skb, GFP_ATOMIC);
     541                 :            :                 else {
     542                 :            :                         skb2 = skb;
     543                 :            :                         skb = NULL;
     544                 :            :                 }
     545                 :            : 
     546         [ #  # ]:          0 :                 if (skb2) {
     547                 :          0 :                         ip6_mr_input(skb2);
     548                 :            :                 }
     549                 :            :         }
     550                 :            : out:
     551                 :            : #endif
     552         [ +  - ]:       2064 :         if (likely(deliver))
     553                 :       2064 :                 ip6_input(skb);
     554                 :            :         else {
     555                 :            :                 /* discard */
     556                 :          0 :                 kfree_skb(skb);
     557                 :            :         }
     558                 :            : 
     559                 :            :         return 0;
     560                 :            : }

Generated by: LCOV version 1.14