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

Generated by: LCOV version 1.14