Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  IPv6 input
0004  *  Linux INET6 implementation
0005  *
0006  *  Authors:
0007  *  Pedro Roque     <roque@di.fc.ul.pt>
0008  *  Ian P. Morris       <I.P.Morris@soton.ac.uk>
0009  *
0010  *  Based in linux/net/ipv4/ip_input.c
0011  */
0012 /* Changes
0013  *
0014  *  Mitsuru KANDA @USAGI and
0015  *  YOSHIFUJI Hideaki @USAGI: Remove ipv6_parse_exthdrs().
0016  */
0017 
0018 #include <linux/errno.h>
0019 #include <linux/types.h>
0020 #include <linux/socket.h>
0021 #include <linux/sockios.h>
0022 #include <linux/net.h>
0023 #include <linux/netdevice.h>
0024 #include <linux/in6.h>
0025 #include <linux/icmpv6.h>
0026 #include <linux/mroute6.h>
0027 #include <linux/slab.h>
0028 #include <linux/indirect_call_wrapper.h>
0029 
0030 #include <linux/netfilter.h>
0031 #include <linux/netfilter_ipv6.h>
0032 
0033 #include <net/sock.h>
0034 #include <net/snmp.h>
0035 #include <net/udp.h>
0036 
0037 #include <net/ipv6.h>
0038 #include <net/protocol.h>
0039 #include <net/transp_v6.h>
0040 #include <net/rawv6.h>
0041 #include <net/ndisc.h>
0042 #include <net/ip6_route.h>
0043 #include <net/addrconf.h>
0044 #include <net/xfrm.h>
0045 #include <net/inet_ecn.h>
0046 #include <net/dst_metadata.h>
0047 
0048 static void ip6_rcv_finish_core(struct net *net, struct sock *sk,
0049                 struct sk_buff *skb)
0050 {
0051     if (READ_ONCE(net->ipv4.sysctl_ip_early_demux) &&
0052         !skb_dst(skb) && !skb->sk) {
0053         switch (ipv6_hdr(skb)->nexthdr) {
0054         case IPPROTO_TCP:
0055             if (READ_ONCE(net->ipv4.sysctl_tcp_early_demux))
0056                 tcp_v6_early_demux(skb);
0057             break;
0058         case IPPROTO_UDP:
0059             if (READ_ONCE(net->ipv4.sysctl_udp_early_demux))
0060                 udp_v6_early_demux(skb);
0061             break;
0062         }
0063     }
0064 
0065     if (!skb_valid_dst(skb))
0066         ip6_route_input(skb);
0067 }
0068 
0069 int ip6_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
0070 {
0071     /* if ingress device is enslaved to an L3 master device pass the
0072      * skb to its handler for processing
0073      */
0074     skb = l3mdev_ip6_rcv(skb);
0075     if (!skb)
0076         return NET_RX_SUCCESS;
0077     ip6_rcv_finish_core(net, sk, skb);
0078 
0079     return dst_input(skb);
0080 }
0081 
0082 static void ip6_sublist_rcv_finish(struct list_head *head)
0083 {
0084     struct sk_buff *skb, *next;
0085 
0086     list_for_each_entry_safe(skb, next, head, list) {
0087         skb_list_del_init(skb);
0088         dst_input(skb);
0089     }
0090 }
0091 
0092 static bool ip6_can_use_hint(const struct sk_buff *skb,
0093                  const struct sk_buff *hint)
0094 {
0095     return hint && !skb_dst(skb) &&
0096            ipv6_addr_equal(&ipv6_hdr(hint)->daddr, &ipv6_hdr(skb)->daddr);
0097 }
0098 
0099 static struct sk_buff *ip6_extract_route_hint(const struct net *net,
0100                           struct sk_buff *skb)
0101 {
0102     if (fib6_routes_require_src(net) || fib6_has_custom_rules(net))
0103         return NULL;
0104 
0105     return skb;
0106 }
0107 
0108 static void ip6_list_rcv_finish(struct net *net, struct sock *sk,
0109                 struct list_head *head)
0110 {
0111     struct sk_buff *skb, *next, *hint = NULL;
0112     struct dst_entry *curr_dst = NULL;
0113     struct list_head sublist;
0114 
0115     INIT_LIST_HEAD(&sublist);
0116     list_for_each_entry_safe(skb, next, head, list) {
0117         struct dst_entry *dst;
0118 
0119         skb_list_del_init(skb);
0120         /* if ingress device is enslaved to an L3 master device pass the
0121          * skb to its handler for processing
0122          */
0123         skb = l3mdev_ip6_rcv(skb);
0124         if (!skb)
0125             continue;
0126 
0127         if (ip6_can_use_hint(skb, hint))
0128             skb_dst_copy(skb, hint);
0129         else
0130             ip6_rcv_finish_core(net, sk, skb);
0131         dst = skb_dst(skb);
0132         if (curr_dst != dst) {
0133             hint = ip6_extract_route_hint(net, skb);
0134 
0135             /* dispatch old sublist */
0136             if (!list_empty(&sublist))
0137                 ip6_sublist_rcv_finish(&sublist);
0138             /* start new sublist */
0139             INIT_LIST_HEAD(&sublist);
0140             curr_dst = dst;
0141         }
0142         list_add_tail(&skb->list, &sublist);
0143     }
0144     /* dispatch final sublist */
0145     ip6_sublist_rcv_finish(&sublist);
0146 }
0147 
0148 static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
0149                     struct net *net)
0150 {
0151     enum skb_drop_reason reason;
0152     const struct ipv6hdr *hdr;
0153     u32 pkt_len;
0154     struct inet6_dev *idev;
0155 
0156     if (skb->pkt_type == PACKET_OTHERHOST) {
0157         dev_core_stats_rx_otherhost_dropped_inc(skb->dev);
0158         kfree_skb_reason(skb, SKB_DROP_REASON_OTHERHOST);
0159         return NULL;
0160     }
0161 
0162     rcu_read_lock();
0163 
0164     idev = __in6_dev_get(skb->dev);
0165 
0166     __IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_IN, skb->len);
0167 
0168     SKB_DR_SET(reason, NOT_SPECIFIED);
0169     if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
0170         !idev || unlikely(idev->cnf.disable_ipv6)) {
0171         __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
0172         if (idev && unlikely(idev->cnf.disable_ipv6))
0173             SKB_DR_SET(reason, IPV6DISABLED);
0174         goto drop;
0175     }
0176 
0177     memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm));
0178 
0179     /*
0180      * Store incoming device index. When the packet will
0181      * be queued, we cannot refer to skb->dev anymore.
0182      *
0183      * BTW, when we send a packet for our own local address on a
0184      * non-loopback interface (e.g. ethX), it is being delivered
0185      * via the loopback interface (lo) here; skb->dev = loopback_dev.
0186      * It, however, should be considered as if it is being
0187      * arrived via the sending interface (ethX), because of the
0188      * nature of scoping architecture. --yoshfuji
0189      */
0190     IP6CB(skb)->iif = skb_valid_dst(skb) ? ip6_dst_idev(skb_dst(skb))->dev->ifindex : dev->ifindex;
0191 
0192     if (unlikely(!pskb_may_pull(skb, sizeof(*hdr))))
0193         goto err;
0194 
0195     hdr = ipv6_hdr(skb);
0196 
0197     if (hdr->version != 6) {
0198         SKB_DR_SET(reason, UNHANDLED_PROTO);
0199         goto err;
0200     }
0201 
0202     __IP6_ADD_STATS(net, idev,
0203             IPSTATS_MIB_NOECTPKTS +
0204                 (ipv6_get_dsfield(hdr) & INET_ECN_MASK),
0205             max_t(unsigned short, 1, skb_shinfo(skb)->gso_segs));
0206     /*
0207      * RFC4291 2.5.3
0208      * The loopback address must not be used as the source address in IPv6
0209      * packets that are sent outside of a single node. [..]
0210      * A packet received on an interface with a destination address
0211      * of loopback must be dropped.
0212      */
0213     if ((ipv6_addr_loopback(&hdr->saddr) ||
0214          ipv6_addr_loopback(&hdr->daddr)) &&
0215         !(dev->flags & IFF_LOOPBACK) &&
0216         !netif_is_l3_master(dev))
0217         goto err;
0218 
0219     /* RFC4291 Errata ID: 3480
0220      * Interface-Local scope spans only a single interface on a
0221      * node and is useful only for loopback transmission of
0222      * multicast.  Packets with interface-local scope received
0223      * from another node must be discarded.
0224      */
0225     if (!(skb->pkt_type == PACKET_LOOPBACK ||
0226           dev->flags & IFF_LOOPBACK) &&
0227         ipv6_addr_is_multicast(&hdr->daddr) &&
0228         IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 1)
0229         goto err;
0230 
0231     /* If enabled, drop unicast packets that were encapsulated in link-layer
0232      * multicast or broadcast to protected against the so-called "hole-196"
0233      * attack in 802.11 wireless.
0234      */
0235     if (!ipv6_addr_is_multicast(&hdr->daddr) &&
0236         (skb->pkt_type == PACKET_BROADCAST ||
0237          skb->pkt_type == PACKET_MULTICAST) &&
0238         idev->cnf.drop_unicast_in_l2_multicast) {
0239         SKB_DR_SET(reason, UNICAST_IN_L2_MULTICAST);
0240         goto err;
0241     }
0242 
0243     /* RFC4291 2.7
0244      * Nodes must not originate a packet to a multicast address whose scope
0245      * field contains the reserved value 0; if such a packet is received, it
0246      * must be silently dropped.
0247      */
0248     if (ipv6_addr_is_multicast(&hdr->daddr) &&
0249         IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 0)
0250         goto err;
0251 
0252     /*
0253      * RFC4291 2.7
0254      * Multicast addresses must not be used as source addresses in IPv6
0255      * packets or appear in any Routing header.
0256      */
0257     if (ipv6_addr_is_multicast(&hdr->saddr))
0258         goto err;
0259 
0260     skb->transport_header = skb->network_header + sizeof(*hdr);
0261     IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
0262 
0263     pkt_len = ntohs(hdr->payload_len);
0264 
0265     /* pkt_len may be zero if Jumbo payload option is present */
0266     if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) {
0267         if (pkt_len + sizeof(struct ipv6hdr) > skb->len) {
0268             __IP6_INC_STATS(net,
0269                     idev, IPSTATS_MIB_INTRUNCATEDPKTS);
0270             SKB_DR_SET(reason, PKT_TOO_SMALL);
0271             goto drop;
0272         }
0273         if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
0274             goto err;
0275         hdr = ipv6_hdr(skb);
0276     }
0277 
0278     if (hdr->nexthdr == NEXTHDR_HOP) {
0279         if (ipv6_parse_hopopts(skb) < 0) {
0280             __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
0281             rcu_read_unlock();
0282             return NULL;
0283         }
0284     }
0285 
0286     rcu_read_unlock();
0287 
0288     /* Must drop socket now because of tproxy. */
0289     if (!skb_sk_is_prefetched(skb))
0290         skb_orphan(skb);
0291 
0292     return skb;
0293 err:
0294     __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
0295     SKB_DR_OR(reason, IP_INHDR);
0296 drop:
0297     rcu_read_unlock();
0298     kfree_skb_reason(skb, reason);
0299     return NULL;
0300 }
0301 
0302 int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
0303 {
0304     struct net *net = dev_net(skb->dev);
0305 
0306     skb = ip6_rcv_core(skb, dev, net);
0307     if (skb == NULL)
0308         return NET_RX_DROP;
0309     return NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING,
0310                net, NULL, skb, dev, NULL,
0311                ip6_rcv_finish);
0312 }
0313 
0314 static void ip6_sublist_rcv(struct list_head *head, struct net_device *dev,
0315                 struct net *net)
0316 {
0317     NF_HOOK_LIST(NFPROTO_IPV6, NF_INET_PRE_ROUTING, net, NULL,
0318              head, dev, NULL, ip6_rcv_finish);
0319     ip6_list_rcv_finish(net, NULL, head);
0320 }
0321 
0322 /* Receive a list of IPv6 packets */
0323 void ipv6_list_rcv(struct list_head *head, struct packet_type *pt,
0324            struct net_device *orig_dev)
0325 {
0326     struct net_device *curr_dev = NULL;
0327     struct net *curr_net = NULL;
0328     struct sk_buff *skb, *next;
0329     struct list_head sublist;
0330 
0331     INIT_LIST_HEAD(&sublist);
0332     list_for_each_entry_safe(skb, next, head, list) {
0333         struct net_device *dev = skb->dev;
0334         struct net *net = dev_net(dev);
0335 
0336         skb_list_del_init(skb);
0337         skb = ip6_rcv_core(skb, dev, net);
0338         if (skb == NULL)
0339             continue;
0340 
0341         if (curr_dev != dev || curr_net != net) {
0342             /* dispatch old sublist */
0343             if (!list_empty(&sublist))
0344                 ip6_sublist_rcv(&sublist, curr_dev, curr_net);
0345             /* start new sublist */
0346             INIT_LIST_HEAD(&sublist);
0347             curr_dev = dev;
0348             curr_net = net;
0349         }
0350         list_add_tail(&skb->list, &sublist);
0351     }
0352     /* dispatch final sublist */
0353     if (!list_empty(&sublist))
0354         ip6_sublist_rcv(&sublist, curr_dev, curr_net);
0355 }
0356 
0357 INDIRECT_CALLABLE_DECLARE(int tcp_v6_rcv(struct sk_buff *));
0358 
0359 /*
0360  *  Deliver the packet to the host
0361  */
0362 void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
0363                   bool have_final)
0364 {
0365     const struct inet6_protocol *ipprot;
0366     struct inet6_dev *idev;
0367     unsigned int nhoff;
0368     SKB_DR(reason);
0369     bool raw;
0370 
0371     /*
0372      *  Parse extension headers
0373      */
0374 
0375 resubmit:
0376     idev = ip6_dst_idev(skb_dst(skb));
0377     nhoff = IP6CB(skb)->nhoff;
0378     if (!have_final) {
0379         if (!pskb_pull(skb, skb_transport_offset(skb)))
0380             goto discard;
0381         nexthdr = skb_network_header(skb)[nhoff];
0382     }
0383 
0384 resubmit_final:
0385     raw = raw6_local_deliver(skb, nexthdr);
0386     ipprot = rcu_dereference(inet6_protos[nexthdr]);
0387     if (ipprot) {
0388         int ret;
0389 
0390         if (have_final) {
0391             if (!(ipprot->flags & INET6_PROTO_FINAL)) {
0392                 /* Once we've seen a final protocol don't
0393                  * allow encapsulation on any non-final
0394                  * ones. This allows foo in UDP encapsulation
0395                  * to work.
0396                  */
0397                 goto discard;
0398             }
0399         } else if (ipprot->flags & INET6_PROTO_FINAL) {
0400             const struct ipv6hdr *hdr;
0401             int sdif = inet6_sdif(skb);
0402             struct net_device *dev;
0403 
0404             /* Only do this once for first final protocol */
0405             have_final = true;
0406 
0407             /* Free reference early: we don't need it any more,
0408                and it may hold ip_conntrack module loaded
0409                indefinitely. */
0410             nf_reset_ct(skb);
0411 
0412             skb_postpull_rcsum(skb, skb_network_header(skb),
0413                        skb_network_header_len(skb));
0414             hdr = ipv6_hdr(skb);
0415 
0416             /* skb->dev passed may be master dev for vrfs. */
0417             if (sdif) {
0418                 dev = dev_get_by_index_rcu(net, sdif);
0419                 if (!dev)
0420                     goto discard;
0421             } else {
0422                 dev = skb->dev;
0423             }
0424 
0425             if (ipv6_addr_is_multicast(&hdr->daddr) &&
0426                 !ipv6_chk_mcast_addr(dev, &hdr->daddr,
0427                          &hdr->saddr) &&
0428                 !ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb))) {
0429                 SKB_DR_SET(reason, IP_INADDRERRORS);
0430                 goto discard;
0431             }
0432         }
0433         if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
0434             !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
0435             SKB_DR_SET(reason, XFRM_POLICY);
0436             goto discard;
0437         }
0438 
0439         ret = INDIRECT_CALL_2(ipprot->handler, tcp_v6_rcv, udpv6_rcv,
0440                       skb);
0441         if (ret > 0) {
0442             if (ipprot->flags & INET6_PROTO_FINAL) {
0443                 /* Not an extension header, most likely UDP
0444                  * encapsulation. Use return value as nexthdr
0445                  * protocol not nhoff (which presumably is
0446                  * not set by handler).
0447                  */
0448                 nexthdr = ret;
0449                 goto resubmit_final;
0450             } else {
0451                 goto resubmit;
0452             }
0453         } else if (ret == 0) {
0454             __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDELIVERS);
0455         }
0456     } else {
0457         if (!raw) {
0458             if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
0459                 __IP6_INC_STATS(net, idev,
0460                         IPSTATS_MIB_INUNKNOWNPROTOS);
0461                 icmpv6_send(skb, ICMPV6_PARAMPROB,
0462                         ICMPV6_UNK_NEXTHDR, nhoff);
0463                 SKB_DR_SET(reason, IP_NOPROTO);
0464             } else {
0465                 SKB_DR_SET(reason, XFRM_POLICY);
0466             }
0467             kfree_skb_reason(skb, reason);
0468         } else {
0469             __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDELIVERS);
0470             consume_skb(skb);
0471         }
0472     }
0473     return;
0474 
0475 discard:
0476     __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
0477     kfree_skb_reason(skb, reason);
0478 }
0479 
0480 static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
0481 {
0482     skb_clear_delivery_time(skb);
0483     rcu_read_lock();
0484     ip6_protocol_deliver_rcu(net, skb, 0, false);
0485     rcu_read_unlock();
0486 
0487     return 0;
0488 }
0489 
0490 
0491 int ip6_input(struct sk_buff *skb)
0492 {
0493     return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_IN,
0494                dev_net(skb->dev), NULL, skb, skb->dev, NULL,
0495                ip6_input_finish);
0496 }
0497 EXPORT_SYMBOL_GPL(ip6_input);
0498 
0499 int ip6_mc_input(struct sk_buff *skb)
0500 {
0501     int sdif = inet6_sdif(skb);
0502     const struct ipv6hdr *hdr;
0503     struct net_device *dev;
0504     bool deliver;
0505 
0506     __IP6_UPD_PO_STATS(dev_net(skb_dst(skb)->dev),
0507              __in6_dev_get_safely(skb->dev), IPSTATS_MIB_INMCAST,
0508              skb->len);
0509 
0510     /* skb->dev passed may be master dev for vrfs. */
0511     if (sdif) {
0512         rcu_read_lock();
0513         dev = dev_get_by_index_rcu(dev_net(skb->dev), sdif);
0514         if (!dev) {
0515             rcu_read_unlock();
0516             kfree_skb(skb);
0517             return -ENODEV;
0518         }
0519     } else {
0520         dev = skb->dev;
0521     }
0522 
0523     hdr = ipv6_hdr(skb);
0524     deliver = ipv6_chk_mcast_addr(dev, &hdr->daddr, NULL);
0525     if (sdif)
0526         rcu_read_unlock();
0527 
0528 #ifdef CONFIG_IPV6_MROUTE
0529     /*
0530      *      IPv6 multicast router mode is now supported ;)
0531      */
0532     if (atomic_read(&dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding) &&
0533         !(ipv6_addr_type(&hdr->daddr) &
0534           (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)) &&
0535         likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) {
0536         /*
0537          * Okay, we try to forward - split and duplicate
0538          * packets.
0539          */
0540         struct sk_buff *skb2;
0541         struct inet6_skb_parm *opt = IP6CB(skb);
0542 
0543         /* Check for MLD */
0544         if (unlikely(opt->flags & IP6SKB_ROUTERALERT)) {
0545             /* Check if this is a mld message */
0546             u8 nexthdr = hdr->nexthdr;
0547             __be16 frag_off;
0548             int offset;
0549 
0550             /* Check if the value of Router Alert
0551              * is for MLD (0x0000).
0552              */
0553             if (opt->ra == htons(IPV6_OPT_ROUTERALERT_MLD)) {
0554                 deliver = false;
0555 
0556                 if (!ipv6_ext_hdr(nexthdr)) {
0557                     /* BUG */
0558                     goto out;
0559                 }
0560                 offset = ipv6_skip_exthdr(skb, sizeof(*hdr),
0561                               &nexthdr, &frag_off);
0562                 if (offset < 0)
0563                     goto out;
0564 
0565                 if (ipv6_is_mld(skb, nexthdr, offset))
0566                     deliver = true;
0567 
0568                 goto out;
0569             }
0570             /* unknown RA - process it normally */
0571         }
0572 
0573         if (deliver)
0574             skb2 = skb_clone(skb, GFP_ATOMIC);
0575         else {
0576             skb2 = skb;
0577             skb = NULL;
0578         }
0579 
0580         if (skb2) {
0581             ip6_mr_input(skb2);
0582         }
0583     }
0584 out:
0585 #endif
0586     if (likely(deliver))
0587         ip6_input(skb);
0588     else {
0589         /* discard */
0590         kfree_skb(skb);
0591     }
0592 
0593     return 0;
0594 }