LCOV - code coverage report
Current view: top level - net/ipv6 - route.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 185 1031 17.9 %
Date: 2014-04-07 Functions: 23 90 25.6 %
Branches: 94 750 12.5 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  *      Linux INET6 implementation
       3                 :            :  *      FIB front-end.
       4                 :            :  *
       5                 :            :  *      Authors:
       6                 :            :  *      Pedro Roque             <roque@di.fc.ul.pt>
       7                 :            :  *
       8                 :            :  *      This program is free software; you can redistribute it and/or
       9                 :            :  *      modify it under the terms of the GNU General Public License
      10                 :            :  *      as published by the Free Software Foundation; either version
      11                 :            :  *      2 of the License, or (at your option) any later version.
      12                 :            :  */
      13                 :            : 
      14                 :            : /*      Changes:
      15                 :            :  *
      16                 :            :  *      YOSHIFUJI Hideaki @USAGI
      17                 :            :  *              reworked default router selection.
      18                 :            :  *              - respect outgoing interface
      19                 :            :  *              - select from (probably) reachable routers (i.e.
      20                 :            :  *              routers in REACHABLE, STALE, DELAY or PROBE states).
      21                 :            :  *              - always select the same router if it is (probably)
      22                 :            :  *              reachable.  otherwise, round-robin the list.
      23                 :            :  *      Ville Nuorvala
      24                 :            :  *              Fixed routing subtrees.
      25                 :            :  */
      26                 :            : 
      27                 :            : #define pr_fmt(fmt) "IPv6: " fmt
      28                 :            : 
      29                 :            : #include <linux/capability.h>
      30                 :            : #include <linux/errno.h>
      31                 :            : #include <linux/export.h>
      32                 :            : #include <linux/types.h>
      33                 :            : #include <linux/times.h>
      34                 :            : #include <linux/socket.h>
      35                 :            : #include <linux/sockios.h>
      36                 :            : #include <linux/net.h>
      37                 :            : #include <linux/route.h>
      38                 :            : #include <linux/netdevice.h>
      39                 :            : #include <linux/in6.h>
      40                 :            : #include <linux/mroute6.h>
      41                 :            : #include <linux/init.h>
      42                 :            : #include <linux/if_arp.h>
      43                 :            : #include <linux/proc_fs.h>
      44                 :            : #include <linux/seq_file.h>
      45                 :            : #include <linux/nsproxy.h>
      46                 :            : #include <linux/slab.h>
      47                 :            : #include <net/net_namespace.h>
      48                 :            : #include <net/snmp.h>
      49                 :            : #include <net/ipv6.h>
      50                 :            : #include <net/ip6_fib.h>
      51                 :            : #include <net/ip6_route.h>
      52                 :            : #include <net/ndisc.h>
      53                 :            : #include <net/addrconf.h>
      54                 :            : #include <net/tcp.h>
      55                 :            : #include <linux/rtnetlink.h>
      56                 :            : #include <net/dst.h>
      57                 :            : #include <net/xfrm.h>
      58                 :            : #include <net/netevent.h>
      59                 :            : #include <net/netlink.h>
      60                 :            : #include <net/nexthop.h>
      61                 :            : 
      62                 :            : #include <asm/uaccess.h>
      63                 :            : 
      64                 :            : #ifdef CONFIG_SYSCTL
      65                 :            : #include <linux/sysctl.h>
      66                 :            : #endif
      67                 :            : 
      68                 :            : enum rt6_nud_state {
      69                 :            :         RT6_NUD_FAIL_HARD = -2,
      70                 :            :         RT6_NUD_FAIL_SOFT = -1,
      71                 :            :         RT6_NUD_SUCCEED = 1
      72                 :            : };
      73                 :            : 
      74                 :            : static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,
      75                 :            :                                     const struct in6_addr *dest);
      76                 :            : static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
      77                 :            : static unsigned int      ip6_default_advmss(const struct dst_entry *dst);
      78                 :            : static unsigned int      ip6_mtu(const struct dst_entry *dst);
      79                 :            : static struct dst_entry *ip6_negative_advice(struct dst_entry *);
      80                 :            : static void             ip6_dst_destroy(struct dst_entry *);
      81                 :            : static void             ip6_dst_ifdown(struct dst_entry *,
      82                 :            :                                        struct net_device *dev, int how);
      83                 :            : static int               ip6_dst_gc(struct dst_ops *ops);
      84                 :            : 
      85                 :            : static int              ip6_pkt_discard(struct sk_buff *skb);
      86                 :            : static int              ip6_pkt_discard_out(struct sk_buff *skb);
      87                 :            : static int              ip6_pkt_prohibit(struct sk_buff *skb);
      88                 :            : static int              ip6_pkt_prohibit_out(struct sk_buff *skb);
      89                 :            : static void             ip6_link_failure(struct sk_buff *skb);
      90                 :            : static void             ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
      91                 :            :                                            struct sk_buff *skb, u32 mtu);
      92                 :            : static void             rt6_do_redirect(struct dst_entry *dst, struct sock *sk,
      93                 :            :                                         struct sk_buff *skb);
      94                 :            : static int rt6_score_route(struct rt6_info *rt, int oif, int strict);
      95                 :            : 
      96                 :            : #ifdef CONFIG_IPV6_ROUTE_INFO
      97                 :            : static struct rt6_info *rt6_add_route_info(struct net *net,
      98                 :            :                                            const struct in6_addr *prefix, int prefixlen,
      99                 :            :                                            const struct in6_addr *gwaddr, int ifindex,
     100                 :            :                                            unsigned int pref);
     101                 :            : static struct rt6_info *rt6_get_route_info(struct net *net,
     102                 :            :                                            const struct in6_addr *prefix, int prefixlen,
     103                 :            :                                            const struct in6_addr *gwaddr, int ifindex);
     104                 :            : #endif
     105                 :            : 
     106                 :          0 : static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
     107                 :            : {
     108                 :            :         struct rt6_info *rt = (struct rt6_info *) dst;
     109                 :        105 :         struct inet_peer *peer;
     110                 :            :         u32 *p = NULL;
     111                 :            : 
     112            [ + ]:        105 :         if (!(rt->dst.flags & DST_HOST))
     113                 :            :                 return NULL;
     114                 :            : 
     115                 :            :         peer = rt6_get_peer_create(rt);
     116         [ +  - ]:        105 :         if (peer) {
     117                 :        105 :                 u32 *old_p = __DST_METRICS_PTR(old);
     118                 :            :                 unsigned long prev, new;
     119                 :            : 
     120                 :        105 :                 p = peer->metrics;
     121         [ +  + ]:        105 :                 if (inet_metrics_new(peer))
     122                 :          5 :                         memcpy(p, old_p, sizeof(u32) * RTAX_MAX);
     123                 :            : 
     124                 :        105 :                 new = (unsigned long) p;
     125                 :        105 :                 prev = cmpxchg(&dst->_metrics, old, new);
     126                 :            : 
     127         [ -  + ]:        105 :                 if (prev != old) {
     128                 :          0 :                         p = __DST_METRICS_PTR(prev);
     129         [ #  # ]:          0 :                         if (prev & DST_METRICS_READ_ONLY)
     130                 :            :                                 p = NULL;
     131                 :            :                 }
     132                 :            :         }
     133                 :        105 :         return p;
     134                 :            : }
     135                 :            : 
     136                 :            : static inline const void *choose_neigh_daddr(struct rt6_info *rt,
     137                 :            :                                              struct sk_buff *skb,
     138                 :            :                                              const void *daddr)
     139                 :            : {
     140                 :          0 :         struct in6_addr *p = &rt->rt6i_gateway;
     141                 :            : 
     142         [ #  # ]:          0 :         if (!ipv6_addr_any(p))
     143                 :            :                 return (const void *) p;
     144         [ #  # ]:          0 :         else if (skb)
     145                 :          0 :                 return &ipv6_hdr(skb)->daddr;
     146                 :            :         return daddr;
     147                 :            : }
     148                 :            : 
     149                 :          0 : static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst,
     150                 :            :                                           struct sk_buff *skb,
     151                 :            :                                           const void *daddr)
     152                 :            : {
     153                 :            :         struct rt6_info *rt = (struct rt6_info *) dst;
     154                 :            :         struct neighbour *n;
     155                 :            : 
     156                 :            :         daddr = choose_neigh_daddr(rt, skb, daddr);
     157                 :          0 :         n = __ipv6_neigh_lookup(dst->dev, daddr);
     158         [ #  # ]:          0 :         if (n)
     159                 :            :                 return n;
     160                 :          0 :         return neigh_create(&nd_tbl, daddr, dst->dev);
     161                 :            : }
     162                 :            : 
     163                 :            : static struct dst_ops ip6_dst_ops_template = {
     164                 :            :         .family                 =       AF_INET6,
     165                 :            :         .protocol               =       cpu_to_be16(ETH_P_IPV6),
     166                 :            :         .gc                     =       ip6_dst_gc,
     167                 :            :         .gc_thresh              =       1024,
     168                 :            :         .check                  =       ip6_dst_check,
     169                 :            :         .default_advmss         =       ip6_default_advmss,
     170                 :            :         .mtu                    =       ip6_mtu,
     171                 :            :         .cow_metrics            =       ipv6_cow_metrics,
     172                 :            :         .destroy                =       ip6_dst_destroy,
     173                 :            :         .ifdown                 =       ip6_dst_ifdown,
     174                 :            :         .negative_advice        =       ip6_negative_advice,
     175                 :            :         .link_failure           =       ip6_link_failure,
     176                 :            :         .update_pmtu            =       ip6_rt_update_pmtu,
     177                 :            :         .redirect               =       rt6_do_redirect,
     178                 :            :         .local_out              =       __ip6_local_out,
     179                 :            :         .neigh_lookup           =       ip6_neigh_lookup,
     180                 :            : };
     181                 :            : 
     182                 :          0 : static unsigned int ip6_blackhole_mtu(const struct dst_entry *dst)
     183                 :            : {
     184                 :            :         unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
     185                 :            : 
     186         [ #  # ]:          0 :         return mtu ? : dst->dev->mtu;
     187                 :            : }
     188                 :            : 
     189                 :          0 : static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk,
     190                 :            :                                          struct sk_buff *skb, u32 mtu)
     191                 :            : {
     192                 :          0 : }
     193                 :            : 
     194                 :          0 : static void ip6_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk,
     195                 :            :                                       struct sk_buff *skb)
     196                 :            : {
     197                 :          0 : }
     198                 :            : 
     199                 :          0 : static u32 *ip6_rt_blackhole_cow_metrics(struct dst_entry *dst,
     200                 :            :                                          unsigned long old)
     201                 :            : {
     202                 :          0 :         return NULL;
     203                 :            : }
     204                 :            : 
     205                 :            : static struct dst_ops ip6_dst_blackhole_ops = {
     206                 :            :         .family                 =       AF_INET6,
     207                 :            :         .protocol               =       cpu_to_be16(ETH_P_IPV6),
     208                 :            :         .destroy                =       ip6_dst_destroy,
     209                 :            :         .check                  =       ip6_dst_check,
     210                 :            :         .mtu                    =       ip6_blackhole_mtu,
     211                 :            :         .default_advmss         =       ip6_default_advmss,
     212                 :            :         .update_pmtu            =       ip6_rt_blackhole_update_pmtu,
     213                 :            :         .redirect               =       ip6_rt_blackhole_redirect,
     214                 :            :         .cow_metrics            =       ip6_rt_blackhole_cow_metrics,
     215                 :            :         .neigh_lookup           =       ip6_neigh_lookup,
     216                 :            : };
     217                 :            : 
     218                 :            : static const u32 ip6_template_metrics[RTAX_MAX] = {
     219                 :            :         [RTAX_HOPLIMIT - 1] = 0,
     220                 :            : };
     221                 :            : 
     222                 :            : static const struct rt6_info ip6_null_entry_template = {
     223                 :            :         .dst = {
     224                 :            :                 .__refcnt       = ATOMIC_INIT(1),
     225                 :            :                 .__use          = 1,
     226                 :            :                 .obsolete       = DST_OBSOLETE_FORCE_CHK,
     227                 :            :                 .error          = -ENETUNREACH,
     228                 :            :                 .input          = ip6_pkt_discard,
     229                 :            :                 .output         = ip6_pkt_discard_out,
     230                 :            :         },
     231                 :            :         .rt6i_flags     = (RTF_REJECT | RTF_NONEXTHOP),
     232                 :            :         .rt6i_protocol  = RTPROT_KERNEL,
     233                 :            :         .rt6i_metric    = ~(u32) 0,
     234                 :            :         .rt6i_ref       = ATOMIC_INIT(1),
     235                 :            : };
     236                 :            : 
     237                 :            : #ifdef CONFIG_IPV6_MULTIPLE_TABLES
     238                 :            : 
     239                 :            : static const struct rt6_info ip6_prohibit_entry_template = {
     240                 :            :         .dst = {
     241                 :            :                 .__refcnt       = ATOMIC_INIT(1),
     242                 :            :                 .__use          = 1,
     243                 :            :                 .obsolete       = DST_OBSOLETE_FORCE_CHK,
     244                 :            :                 .error          = -EACCES,
     245                 :            :                 .input          = ip6_pkt_prohibit,
     246                 :            :                 .output         = ip6_pkt_prohibit_out,
     247                 :            :         },
     248                 :            :         .rt6i_flags     = (RTF_REJECT | RTF_NONEXTHOP),
     249                 :            :         .rt6i_protocol  = RTPROT_KERNEL,
     250                 :            :         .rt6i_metric    = ~(u32) 0,
     251                 :            :         .rt6i_ref       = ATOMIC_INIT(1),
     252                 :            : };
     253                 :            : 
     254                 :            : static const struct rt6_info ip6_blk_hole_entry_template = {
     255                 :            :         .dst = {
     256                 :            :                 .__refcnt       = ATOMIC_INIT(1),
     257                 :            :                 .__use          = 1,
     258                 :            :                 .obsolete       = DST_OBSOLETE_FORCE_CHK,
     259                 :            :                 .error          = -EINVAL,
     260                 :            :                 .input          = dst_discard,
     261                 :            :                 .output         = dst_discard,
     262                 :            :         },
     263                 :            :         .rt6i_flags     = (RTF_REJECT | RTF_NONEXTHOP),
     264                 :            :         .rt6i_protocol  = RTPROT_KERNEL,
     265                 :            :         .rt6i_metric    = ~(u32) 0,
     266                 :            :         .rt6i_ref       = ATOMIC_INIT(1),
     267                 :            : };
     268                 :            : 
     269                 :            : #endif
     270                 :            : 
     271                 :            : /* allocate dst with ip6_dst_ops */
     272                 :            : static inline struct rt6_info *ip6_dst_alloc(struct net *net,
     273                 :            :                                              struct net_device *dev,
     274                 :            :                                              int flags,
     275                 :            :                                              struct fib6_table *table)
     276                 :            : {
     277                 :        105 :         struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
     278                 :            :                                         0, DST_OBSOLETE_FORCE_CHK, flags);
     279                 :            : 
     280   [ #  #  +  -  :        105 :         if (rt) {
             #  #  #  # ]
     281                 :            :                 struct dst_entry *dst = &rt->dst;
     282                 :            : 
     283                 :        105 :                 memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
     284 [ +  - ][ #  # ]:        105 :                 rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers);
     285                 :        105 :                 rt->rt6i_genid = rt_genid_ipv6(net);
     286                 :        105 :                 INIT_LIST_HEAD(&rt->rt6i_siblings);
     287                 :            :         }
     288                 :            :         return rt;
     289                 :            : }
     290                 :            : 
     291                 :          0 : static void ip6_dst_destroy(struct dst_entry *dst)
     292                 :            : {
     293                 :        105 :         struct rt6_info *rt = (struct rt6_info *)dst;
     294                 :        105 :         struct inet6_dev *idev = rt->rt6i_idev;
     295                 :        105 :         struct dst_entry *from = dst->from;
     296                 :            : 
     297         [ -  + ]:        105 :         if (!(rt->dst.flags & DST_HOST))
     298                 :            :                 dst_destroy_metrics_generic(dst);
     299                 :            : 
     300         [ +  - ]:        105 :         if (idev) {
     301                 :        105 :                 rt->rt6i_idev = NULL;
     302                 :            :                 in6_dev_put(idev);
     303                 :            :         }
     304                 :            : 
     305                 :        105 :         dst->from = NULL;
     306                 :        105 :         dst_release(from);
     307                 :            : 
     308         [ +  - ]:        105 :         if (rt6_has_peer(rt)) {
     309                 :            :                 struct inet_peer *peer = rt6_peer_ptr(rt);
     310                 :        105 :                 inet_putpeer(peer);
     311                 :            :         }
     312                 :        105 : }
     313                 :            : 
     314                 :          0 : void rt6_bind_peer(struct rt6_info *rt, int create)
     315                 :            : {
     316                 :            :         struct inet_peer_base *base;
     317                 :            :         struct inet_peer *peer;
     318                 :            : 
     319                 :        105 :         base = inetpeer_base_ptr(rt->_rt6i_peer);
     320         [ +  - ]:        105 :         if (!base)
     321                 :          0 :                 return;
     322                 :            : 
     323                 :            :         peer = inet_getpeer_v6(base, &rt->rt6i_dst.addr, create);
     324         [ +  - ]:        105 :         if (peer) {
     325         [ -  + ]:        105 :                 if (!rt6_set_peer(rt, peer))
     326                 :          0 :                         inet_putpeer(peer);
     327                 :            :         }
     328                 :            : }
     329                 :            : 
     330                 :          0 : static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
     331                 :            :                            int how)
     332                 :            : {
     333                 :            :         struct rt6_info *rt = (struct rt6_info *)dst;
     334                 :          0 :         struct inet6_dev *idev = rt->rt6i_idev;
     335                 :          0 :         struct net_device *loopback_dev =
     336                 :            :                 dev_net(dev)->loopback_dev;
     337                 :            : 
     338         [ #  # ]:          0 :         if (dev != loopback_dev) {
     339 [ #  # ][ #  # ]:          0 :                 if (idev && idev->dev == dev) {
     340                 :            :                         struct inet6_dev *loopback_idev =
     341                 :            :                                 in6_dev_get(loopback_dev);
     342         [ #  # ]:          0 :                         if (loopback_idev) {
     343                 :          0 :                                 rt->rt6i_idev = loopback_idev;
     344                 :            :                                 in6_dev_put(idev);
     345                 :            :                         }
     346                 :            :                 }
     347                 :            :         }
     348                 :          0 : }
     349                 :            : 
     350                 :            : static bool rt6_check_expired(const struct rt6_info *rt)
     351                 :            : {
     352 [ #  # ][ #  # ]:        134 :         if (rt->rt6i_flags & RTF_EXPIRES) {
         [ #  # ][ -  + ]
     353 [ #  # ][ #  # ]:          0 :                 if (time_after(jiffies, rt->dst.expires))
         [ #  # ][ #  # ]
     354                 :            :                         return true;
     355 [ #  # ][ #  # ]:        134 :         } else if (rt->dst.from) {
         [ #  # ][ +  + ]
     356                 :            :                 return rt6_check_expired((struct rt6_info *) rt->dst.from);
     357                 :            :         }
     358                 :            :         return false;
     359                 :            : }
     360                 :            : 
     361                 :            : static bool rt6_need_strict(const struct in6_addr *daddr)
     362                 :            : {
     363                 :        115 :         return ipv6_addr_type(daddr) &
     364                 :            :                 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
     365                 :            : }
     366                 :            : 
     367                 :            : /* Multipath route selection:
     368                 :            :  *   Hash based function using packet header and flowlabel.
     369                 :            :  * Adapted from fib_info_hashfn()
     370                 :            :  */
     371                 :          0 : static int rt6_info_hash_nhsfn(unsigned int candidate_count,
     372                 :            :                                const struct flowi6 *fl6)
     373                 :            : {
     374                 :          0 :         unsigned int val = fl6->flowi6_proto;
     375                 :            : 
     376                 :          0 :         val ^= ipv6_addr_hash(&fl6->daddr);
     377                 :          0 :         val ^= ipv6_addr_hash(&fl6->saddr);
     378                 :            : 
     379                 :            :         /* Work only if this not encapsulated */
     380      [ #  #  # ]:          0 :         switch (fl6->flowi6_proto) {
     381                 :            :         case IPPROTO_UDP:
     382                 :            :         case IPPROTO_TCP:
     383                 :            :         case IPPROTO_SCTP:
     384                 :          0 :                 val ^= (__force u16)fl6->fl6_sport;
     385                 :          0 :                 val ^= (__force u16)fl6->fl6_dport;
     386                 :          0 :                 break;
     387                 :            : 
     388                 :            :         case IPPROTO_ICMPV6:
     389                 :          0 :                 val ^= (__force u16)fl6->fl6_icmp_type;
     390                 :          0 :                 val ^= (__force u16)fl6->fl6_icmp_code;
     391                 :          0 :                 break;
     392                 :            :         }
     393                 :            :         /* RFC6438 recommands to use flowlabel */
     394                 :          0 :         val ^= (__force u32)fl6->flowlabel;
     395                 :            : 
     396                 :            :         /* Perhaps, we need to tune, this function? */
     397                 :          0 :         val = val ^ (val >> 7) ^ (val >> 12);
     398                 :          0 :         return val % candidate_count;
     399                 :            : }
     400                 :            : 
     401                 :          0 : static struct rt6_info *rt6_multipath_select(struct rt6_info *match,
     402                 :            :                                              struct flowi6 *fl6, int oif,
     403                 :            :                                              int strict)
     404                 :            : {
     405                 :            :         struct rt6_info *sibling, *next_sibling;
     406                 :            :         int route_choosen;
     407                 :            : 
     408                 :          0 :         route_choosen = rt6_info_hash_nhsfn(match->rt6i_nsiblings + 1, fl6);
     409                 :            :         /* Don't change the route, if route_choosen == 0
     410                 :            :          * (siblings does not include ourself)
     411                 :            :          */
     412         [ #  # ]:          0 :         if (route_choosen)
     413         [ #  # ]:          0 :                 list_for_each_entry_safe(sibling, next_sibling,
     414                 :            :                                 &match->rt6i_siblings, rt6i_siblings) {
     415                 :          0 :                         route_choosen--;
     416         [ #  # ]:          0 :                         if (route_choosen == 0) {
     417         [ #  # ]:          0 :                                 if (rt6_score_route(sibling, oif, strict) < 0)
     418                 :            :                                         break;
     419                 :            :                                 match = sibling;
     420                 :          0 :                                 break;
     421                 :            :                         }
     422                 :            :                 }
     423                 :          0 :         return match;
     424                 :            : }
     425                 :            : 
     426                 :            : /*
     427                 :            :  *      Route lookup. Any table->tb6_lock is implied.
     428                 :            :  */
     429                 :            : 
     430                 :            : static inline struct rt6_info *rt6_device_match(struct net *net,
     431                 :            :                                                     struct rt6_info *rt,
     432                 :            :                                                     const struct in6_addr *saddr,
     433                 :            :                                                     int oif,
     434                 :            :                                                     int flags)
     435                 :            : {
     436                 :            :         struct rt6_info *local = NULL;
     437                 :            :         struct rt6_info *sprt;
     438                 :            : 
     439 [ #  # ][ #  # ]:          0 :         if (!oif && ipv6_addr_any(saddr))
     440                 :            :                 goto out;
     441                 :            : 
     442         [ #  # ]:          0 :         for (sprt = rt; sprt; sprt = sprt->dst.rt6_next) {
     443                 :          0 :                 struct net_device *dev = sprt->dst.dev;
     444                 :            : 
     445         [ #  # ]:          0 :                 if (oif) {
     446         [ #  # ]:          0 :                         if (dev->ifindex == oif)
     447                 :            :                                 return sprt;
     448         [ #  # ]:          0 :                         if (dev->flags & IFF_LOOPBACK) {
     449 [ #  # ][ #  # ]:          0 :                                 if (!sprt->rt6i_idev ||
     450                 :          0 :                                     sprt->rt6i_idev->dev->ifindex != oif) {
     451 [ #  # ][ #  # ]:          0 :                                         if (flags & RT6_LOOKUP_F_IFACE && oif)
     452                 :          0 :                                                 continue;
     453 [ #  # ][ #  # ]:          0 :                                         if (local && (!oif ||
                 [ #  # ]
     454                 :          0 :                                                       local->rt6i_idev->dev->ifindex == oif))
     455                 :          0 :                                                 continue;
     456                 :            :                                 }
     457                 :            :                                 local = sprt;
     458                 :            :                         }
     459                 :            :                 } else {
     460         [ #  # ]:          0 :                         if (ipv6_chk_addr(net, saddr, dev,
     461                 :            :                                           flags & RT6_LOOKUP_F_IFACE))
     462                 :            :                                 return sprt;
     463                 :            :                 }
     464                 :            :         }
     465                 :            : 
     466         [ #  # ]:          0 :         if (oif) {
     467         [ #  # ]:          0 :                 if (local)
     468                 :            :                         return local;
     469                 :            : 
     470         [ #  # ]:          0 :                 if (flags & RT6_LOOKUP_F_IFACE)
     471                 :          0 :                         return net->ipv6.ip6_null_entry;
     472                 :            :         }
     473                 :            : out:
     474                 :            :         return rt;
     475                 :            : }
     476                 :            : 
     477                 :            : #ifdef CONFIG_IPV6_ROUTER_PREF
     478                 :            : struct __rt6_probe_work {
     479                 :            :         struct work_struct work;
     480                 :            :         struct in6_addr target;
     481                 :            :         struct net_device *dev;
     482                 :            : };
     483                 :            : 
     484                 :            : static void rt6_probe_deferred(struct work_struct *w)
     485                 :            : {
     486                 :            :         struct in6_addr mcaddr;
     487                 :            :         struct __rt6_probe_work *work =
     488                 :            :                 container_of(w, struct __rt6_probe_work, work);
     489                 :            : 
     490                 :            :         addrconf_addr_solict_mult(&work->target, &mcaddr);
     491                 :            :         ndisc_send_ns(work->dev, NULL, &work->target, &mcaddr, NULL);
     492                 :            :         dev_put(work->dev);
     493                 :            :         kfree(w);
     494                 :            : }
     495                 :            : 
     496                 :            : static void rt6_probe(struct rt6_info *rt)
     497                 :            : {
     498                 :            :         struct neighbour *neigh;
     499                 :            :         /*
     500                 :            :          * Okay, this does not seem to be appropriate
     501                 :            :          * for now, however, we need to check if it
     502                 :            :          * is really so; aka Router Reachability Probing.
     503                 :            :          *
     504                 :            :          * Router Reachability Probe MUST be rate-limited
     505                 :            :          * to no more than one per minute.
     506                 :            :          */
     507                 :            :         if (!rt || !(rt->rt6i_flags & RTF_GATEWAY))
     508                 :            :                 return;
     509                 :            :         rcu_read_lock_bh();
     510                 :            :         neigh = __ipv6_neigh_lookup_noref(rt->dst.dev, &rt->rt6i_gateway);
     511                 :            :         if (neigh) {
     512                 :            :                 write_lock(&neigh->lock);
     513                 :            :                 if (neigh->nud_state & NUD_VALID)
     514                 :            :                         goto out;
     515                 :            :         }
     516                 :            : 
     517                 :            :         if (!neigh ||
     518                 :            :             time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) {
     519                 :            :                 struct __rt6_probe_work *work;
     520                 :            : 
     521                 :            :                 work = kmalloc(sizeof(*work), GFP_ATOMIC);
     522                 :            : 
     523                 :            :                 if (neigh && work)
     524                 :            :                         neigh->updated = jiffies;
     525                 :            : 
     526                 :            :                 if (neigh)
     527                 :            :                         write_unlock(&neigh->lock);
     528                 :            : 
     529                 :            :                 if (work) {
     530                 :            :                         INIT_WORK(&work->work, rt6_probe_deferred);
     531                 :            :                         work->target = rt->rt6i_gateway;
     532                 :            :                         dev_hold(rt->dst.dev);
     533                 :            :                         work->dev = rt->dst.dev;
     534                 :            :                         schedule_work(&work->work);
     535                 :            :                 }
     536                 :            :         } else {
     537                 :            : out:
     538                 :            :                 write_unlock(&neigh->lock);
     539                 :            :         }
     540                 :            :         rcu_read_unlock_bh();
     541                 :            : }
     542                 :            : #else
     543                 :            : static inline void rt6_probe(struct rt6_info *rt)
     544                 :            : {
     545                 :            : }
     546                 :            : #endif
     547                 :            : 
     548                 :            : /*
     549                 :            :  * Default Router Selection (RFC 2461 6.3.6)
     550                 :            :  */
     551                 :            : static inline int rt6_check_dev(struct rt6_info *rt, int oif)
     552                 :            : {
     553                 :            :         struct net_device *dev = rt->dst.dev;
     554 [ +  + ][ -  + ]:        122 :         if (!oif || dev->ifindex == oif)
     555                 :            :                 return 2;
     556 [ #  # ][ #  # ]:          0 :         if ((dev->flags & IFF_LOOPBACK) &&
     557         [ #  # ]:          0 :             rt->rt6i_idev && rt->rt6i_idev->dev->ifindex == oif)
     558                 :            :                 return 1;
     559                 :            :         return 0;
     560                 :            : }
     561                 :            : 
     562                 :            : static inline enum rt6_nud_state rt6_check_neigh(struct rt6_info *rt)
     563                 :            : {
     564                 :            :         struct neighbour *neigh;
     565                 :            :         enum rt6_nud_state ret = RT6_NUD_FAIL_HARD;
     566                 :            : 
     567         [ -  + ]:        115 :         if (rt->rt6i_flags & RTF_NONEXTHOP ||
     568                 :            :             !(rt->rt6i_flags & RTF_GATEWAY))
     569                 :            :                 return RT6_NUD_SUCCEED;
     570                 :            : 
     571                 :            :         rcu_read_lock_bh();
     572                 :          0 :         neigh = __ipv6_neigh_lookup_noref(rt->dst.dev, &rt->rt6i_gateway);
     573         [ #  # ]:          0 :         if (neigh) {
     574                 :          0 :                 read_lock(&neigh->lock);
     575         [ #  # ]:          0 :                 if (neigh->nud_state & NUD_VALID)
     576                 :            :                         ret = RT6_NUD_SUCCEED;
     577                 :            : #ifdef CONFIG_IPV6_ROUTER_PREF
     578                 :            :                 else if (!(neigh->nud_state & NUD_FAILED))
     579                 :            :                         ret = RT6_NUD_SUCCEED;
     580                 :            : #endif
     581                 :            :                 read_unlock(&neigh->lock);
     582                 :            :         } else {
     583                 :            :                 ret = IS_ENABLED(CONFIG_IPV6_ROUTER_PREF) ?
     584                 :            :                       RT6_NUD_SUCCEED : RT6_NUD_FAIL_SOFT;
     585                 :            :         }
     586                 :            :         rcu_read_unlock_bh();
     587                 :            : 
     588                 :            :         return ret;
     589                 :            : }
     590                 :            : 
     591                 :          0 : static int rt6_score_route(struct rt6_info *rt, int oif,
     592                 :            :                            int strict)
     593                 :            : {
     594                 :            :         int m;
     595                 :            : 
     596                 :            :         m = rt6_check_dev(rt, oif);
     597 [ -  + ][ #  # ]:        122 :         if (!m && (strict & RT6_LOOKUP_F_IFACE))
     598                 :            :                 return RT6_NUD_FAIL_HARD;
     599                 :            : #ifdef CONFIG_IPV6_ROUTER_PREF
     600                 :            :         m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2;
     601                 :            : #endif
     602         [ +  + ]:        122 :         if (strict & RT6_LOOKUP_F_REACHABLE) {
     603                 :            :                 int n = rt6_check_neigh(rt);
     604         [ +  - ]:        115 :                 if (n < 0)
     605                 :            :                         return n;
     606                 :            :         }
     607                 :        122 :         return m;
     608                 :            : }
     609                 :            : 
     610                 :        122 : static struct rt6_info *find_match(struct rt6_info *rt, int oif, int strict,
     611                 :            :                                    int *mpri, struct rt6_info *match,
     612                 :            :                                    bool *do_rr)
     613                 :            : {
     614                 :            :         int m;
     615                 :            :         bool match_do_rr = false;
     616                 :            : 
     617         [ +  - ]:        122 :         if (rt6_check_expired(rt))
     618                 :            :                 goto out;
     619                 :            : 
     620                 :        122 :         m = rt6_score_route(rt, oif, strict);
     621         [ +  - ]:        122 :         if (m == RT6_NUD_FAIL_SOFT) {
     622                 :            :                 match_do_rr = true;
     623                 :            :                 m = 0; /* lowest valid score */
     624            [ + ]:        122 :         } else if (m < 0) {
     625                 :            :                 goto out;
     626                 :            :         }
     627                 :            : 
     628                 :            :         if (strict & RT6_LOOKUP_F_REACHABLE)
     629                 :            :                 rt6_probe(rt);
     630                 :            : 
     631         [ +  - ]:        244 :         if (m > *mpri) {
     632                 :        122 :                 *do_rr = match_do_rr;
     633                 :        122 :                 *mpri = m;
     634                 :            :                 match = rt;
     635                 :            :         }
     636                 :            : out:
     637                 :          0 :         return match;
     638                 :            : }
     639                 :            : 
     640                 :        122 : static struct rt6_info *find_rr_leaf(struct fib6_node *fn,
     641                 :            :                                      struct rt6_info *rr_head,
     642                 :            :                                      u32 metric, int oif, int strict,
     643                 :            :                                      bool *do_rr)
     644                 :            : {
     645                 :            :         struct rt6_info *rt, *match;
     646                 :        122 :         int mpri = -1;
     647                 :            : 
     648                 :            :         match = NULL;
     649 [ +  + ][ +  - ]:        244 :         for (rt = rr_head; rt && rt->rt6i_metric == metric;
     650                 :        122 :              rt = rt->dst.rt6_next)
     651                 :        122 :                 match = find_match(rt, oif, strict, &mpri, match, do_rr);
     652 [ -  + ][ #  # ]:        122 :         for (rt = fn->leaf; rt && rt != rr_head && rt->rt6i_metric == metric;
     653                 :          0 :              rt = rt->dst.rt6_next)
     654                 :          0 :                 match = find_match(rt, oif, strict, &mpri, match, do_rr);
     655                 :            : 
     656                 :          0 :         return match;
     657                 :            : }
     658                 :            : 
     659                 :          0 : static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict)
     660                 :            : {
     661                 :            :         struct rt6_info *match, *rt0;
     662                 :            :         struct net *net;
     663                 :        122 :         bool do_rr = false;
     664                 :            : 
     665                 :        122 :         rt0 = fn->rr_ptr;
     666         [ +  + ]:        122 :         if (!rt0)
     667                 :          6 :                 fn->rr_ptr = rt0 = fn->leaf;
     668                 :            : 
     669                 :        122 :         match = find_rr_leaf(fn, rt0, rt0->rt6i_metric, oif, strict,
     670                 :            :                              &do_rr);
     671                 :            : 
     672         [ -  + ]:        122 :         if (do_rr) {
     673                 :          0 :                 struct rt6_info *next = rt0->dst.rt6_next;
     674                 :            : 
     675                 :            :                 /* no entries matched; do round-robin */
     676 [ #  # ][ #  # ]:          0 :                 if (!next || next->rt6i_metric != rt0->rt6i_metric)
     677                 :          0 :                         next = fn->leaf;
     678                 :            : 
     679         [ #  # ]:          0 :                 if (next != rt0)
     680                 :          0 :                         fn->rr_ptr = next;
     681                 :            :         }
     682                 :            : 
     683                 :            :         net = dev_net(rt0->dst.dev);
     684         [ -  - ]:        122 :         return match ? match : net->ipv6.ip6_null_entry;
     685                 :            : }
     686                 :            : 
     687                 :            : #ifdef CONFIG_IPV6_ROUTE_INFO
     688                 :            : int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
     689                 :            :                   const struct in6_addr *gwaddr)
     690                 :            : {
     691                 :            :         struct net *net = dev_net(dev);
     692                 :            :         struct route_info *rinfo = (struct route_info *) opt;
     693                 :            :         struct in6_addr prefix_buf, *prefix;
     694                 :            :         unsigned int pref;
     695                 :            :         unsigned long lifetime;
     696                 :            :         struct rt6_info *rt;
     697                 :            : 
     698                 :            :         if (len < sizeof(struct route_info)) {
     699                 :            :                 return -EINVAL;
     700                 :            :         }
     701                 :            : 
     702                 :            :         /* Sanity check for prefix_len and length */
     703                 :            :         if (rinfo->length > 3) {
     704                 :            :                 return -EINVAL;
     705                 :            :         } else if (rinfo->prefix_len > 128) {
     706                 :            :                 return -EINVAL;
     707                 :            :         } else if (rinfo->prefix_len > 64) {
     708                 :            :                 if (rinfo->length < 2) {
     709                 :            :                         return -EINVAL;
     710                 :            :                 }
     711                 :            :         } else if (rinfo->prefix_len > 0) {
     712                 :            :                 if (rinfo->length < 1) {
     713                 :            :                         return -EINVAL;
     714                 :            :                 }
     715                 :            :         }
     716                 :            : 
     717                 :            :         pref = rinfo->route_pref;
     718                 :            :         if (pref == ICMPV6_ROUTER_PREF_INVALID)
     719                 :            :                 return -EINVAL;
     720                 :            : 
     721                 :            :         lifetime = addrconf_timeout_fixup(ntohl(rinfo->lifetime), HZ);
     722                 :            : 
     723                 :            :         if (rinfo->length == 3)
     724                 :            :                 prefix = (struct in6_addr *)rinfo->prefix;
     725                 :            :         else {
     726                 :            :                 /* this function is safe */
     727                 :            :                 ipv6_addr_prefix(&prefix_buf,
     728                 :            :                                  (struct in6_addr *)rinfo->prefix,
     729                 :            :                                  rinfo->prefix_len);
     730                 :            :                 prefix = &prefix_buf;
     731                 :            :         }
     732                 :            : 
     733                 :            :         if (rinfo->prefix_len == 0)
     734                 :            :                 rt = rt6_get_dflt_router(gwaddr, dev);
     735                 :            :         else
     736                 :            :                 rt = rt6_get_route_info(net, prefix, rinfo->prefix_len,
     737                 :            :                                         gwaddr, dev->ifindex);
     738                 :            : 
     739                 :            :         if (rt && !lifetime) {
     740                 :            :                 ip6_del_rt(rt);
     741                 :            :                 rt = NULL;
     742                 :            :         }
     743                 :            : 
     744                 :            :         if (!rt && lifetime)
     745                 :            :                 rt = rt6_add_route_info(net, prefix, rinfo->prefix_len, gwaddr, dev->ifindex,
     746                 :            :                                         pref);
     747                 :            :         else if (rt)
     748                 :            :                 rt->rt6i_flags = RTF_ROUTEINFO |
     749                 :            :                                  (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
     750                 :            : 
     751                 :            :         if (rt) {
     752                 :            :                 if (!addrconf_finite_timeout(lifetime))
     753                 :            :                         rt6_clean_expires(rt);
     754                 :            :                 else
     755                 :            :                         rt6_set_expires(rt, jiffies + HZ * lifetime);
     756                 :            : 
     757                 :            :                 ip6_rt_put(rt);
     758                 :            :         }
     759                 :            :         return 0;
     760                 :            : }
     761                 :            : #endif
     762                 :            : 
     763                 :            : #define BACKTRACK(__net, saddr)                 \
     764                 :            : do { \
     765                 :            :         if (rt == __net->ipv6.ip6_null_entry) {      \
     766                 :            :                 struct fib6_node *pn; \
     767                 :            :                 while (1) { \
     768                 :            :                         if (fn->fn_flags & RTN_TL_ROOT) \
     769                 :            :                                 goto out; \
     770                 :            :                         pn = fn->parent; \
     771                 :            :                         if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) \
     772                 :            :                                 fn = fib6_lookup(FIB6_SUBTREE(pn), NULL, saddr); \
     773                 :            :                         else \
     774                 :            :                                 fn = pn; \
     775                 :            :                         if (fn->fn_flags & RTN_RTINFO) \
     776                 :            :                                 goto restart; \
     777                 :            :                 } \
     778                 :            :         } \
     779                 :            : } while (0)
     780                 :            : 
     781                 :          0 : static struct rt6_info *ip6_pol_route_lookup(struct net *net,
     782                 :            :                                              struct fib6_table *table,
     783                 :            :                                              struct flowi6 *fl6, int flags)
     784                 :            : {
     785                 :            :         struct fib6_node *fn;
     786                 :            :         struct rt6_info *rt;
     787                 :            : 
     788                 :          0 :         read_lock_bh(&table->tb6_lock);
     789                 :          0 :         fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
     790                 :            : restart:
     791                 :          0 :         rt = fn->leaf;
     792                 :          0 :         rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags);
     793 [ #  # ][ #  # ]:          0 :         if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0)
     794                 :          0 :                 rt = rt6_multipath_select(rt, fl6, fl6->flowi6_oif, flags);
     795 [ #  # ][ #  # ]:          0 :         BACKTRACK(net, &fl6->saddr);
                 [ #  # ]
     796                 :            : out:
     797                 :          0 :         dst_use(&rt->dst, jiffies);
     798                 :          0 :         read_unlock_bh(&table->tb6_lock);
     799                 :          0 :         return rt;
     800                 :            : 
     801                 :            : }
     802                 :            : 
     803                 :          0 : struct dst_entry * ip6_route_lookup(struct net *net, struct flowi6 *fl6,
     804                 :            :                                     int flags)
     805                 :            : {
     806                 :          0 :         return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_lookup);
     807                 :            : }
     808                 :            : EXPORT_SYMBOL_GPL(ip6_route_lookup);
     809                 :            : 
     810                 :          0 : struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
     811                 :            :                             const struct in6_addr *saddr, int oif, int strict)
     812                 :            : {
     813                 :          0 :         struct flowi6 fl6 = {
     814                 :            :                 .flowi6_oif = oif,
     815                 :            :                 .daddr = *daddr,
     816                 :            :         };
     817                 :            :         struct dst_entry *dst;
     818                 :          0 :         int flags = strict ? RT6_LOOKUP_F_IFACE : 0;
     819                 :            : 
     820         [ #  # ]:          0 :         if (saddr) {
     821                 :          0 :                 memcpy(&fl6.saddr, saddr, sizeof(*saddr));
     822                 :          0 :                 flags |= RT6_LOOKUP_F_HAS_SADDR;
     823                 :            :         }
     824                 :            : 
     825                 :          0 :         dst = fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_lookup);
     826         [ #  # ]:          0 :         if (dst->error == 0)
     827                 :            :                 return (struct rt6_info *) dst;
     828                 :            : 
     829                 :          0 :         dst_release(dst);
     830                 :            : 
     831                 :          0 :         return NULL;
     832                 :            : }
     833                 :            : 
     834                 :            : EXPORT_SYMBOL(rt6_lookup);
     835                 :            : 
     836                 :            : /* ip6_ins_rt is called with FREE table->tb6_lock.
     837                 :            :    It takes new route entry, the addition fails by any reason the
     838                 :            :    route is freed. In any case, if caller does not hold it, it may
     839                 :            :    be destroyed.
     840                 :            :  */
     841                 :            : 
     842                 :          0 : static int __ip6_ins_rt(struct rt6_info *rt, struct nl_info *info)
     843                 :            : {
     844                 :            :         int err;
     845                 :            :         struct fib6_table *table;
     846                 :            : 
     847                 :        105 :         table = rt->rt6i_table;
     848                 :        105 :         write_lock_bh(&table->tb6_lock);
     849                 :        105 :         err = fib6_add(&table->tb6_root, rt, info);
     850                 :        105 :         write_unlock_bh(&table->tb6_lock);
     851                 :            : 
     852                 :        105 :         return err;
     853                 :            : }
     854                 :            : 
     855                 :          0 : int ip6_ins_rt(struct rt6_info *rt)
     856                 :            : {
     857                 :        105 :         struct nl_info info = {
     858                 :            :                 .nl_net = dev_net(rt->dst.dev),
     859                 :            :         };
     860                 :        105 :         return __ip6_ins_rt(rt, &info);
     861                 :            : }
     862                 :            : 
     863                 :        105 : static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort,
     864                 :            :                                       const struct in6_addr *daddr,
     865                 :            :                                       const struct in6_addr *saddr)
     866                 :            : {
     867                 :            :         struct rt6_info *rt;
     868                 :            : 
     869                 :            :         /*
     870                 :            :          *      Clone the route.
     871                 :            :          */
     872                 :            : 
     873                 :        105 :         rt = ip6_rt_copy(ort, daddr);
     874                 :            : 
     875            [ + ]:        105 :         if (rt) {
     876 [ +  - ][ -  + ]:        210 :                 if (ort->rt6i_dst.plen != 128 &&
     877                 :            :                     ipv6_addr_equal(&ort->rt6i_dst.addr, daddr))
     878                 :          0 :                         rt->rt6i_flags |= RTF_ANYCAST;
     879                 :            : 
     880                 :        105 :                 rt->rt6i_flags |= RTF_CACHE;
     881                 :            : 
     882                 :            : #ifdef CONFIG_IPV6_SUBTREES
     883                 :            :                 if (rt->rt6i_src.plen && saddr) {
     884                 :            :                         rt->rt6i_src.addr = *saddr;
     885                 :            :                         rt->rt6i_src.plen = 128;
     886                 :            :                 }
     887                 :            : #endif
     888                 :            :         }
     889                 :            : 
     890                 :          0 :         return rt;
     891                 :            : }
     892                 :            : 
     893                 :            : static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort,
     894                 :            :                                         const struct in6_addr *daddr)
     895                 :            : {
     896                 :          0 :         struct rt6_info *rt = ip6_rt_copy(ort, daddr);
     897                 :            : 
     898         [ #  # ]:          0 :         if (rt)
     899                 :          0 :                 rt->rt6i_flags |= RTF_CACHE;
     900                 :            :         return rt;
     901                 :            : }
     902                 :            : 
     903                 :        115 : static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif,
     904                 :            :                                       struct flowi6 *fl6, int flags)
     905                 :            : {
     906                 :            :         struct fib6_node *fn;
     907                 :            :         struct rt6_info *rt, *nrt;
     908                 :            :         int strict = 0;
     909                 :            :         int attempts = 3;
     910                 :            :         int err;
     911         [ +  - ]:        115 :         int reachable = net->ipv6.devconf_all->forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
     912                 :            : 
     913                 :        115 :         strict |= flags & RT6_LOOKUP_F_IFACE;
     914                 :            : 
     915                 :            : relookup:
     916                 :        115 :         read_lock_bh(&table->tb6_lock);
     917                 :            : 
     918                 :            : restart_2:
     919                 :        122 :         fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
     920                 :            : 
     921                 :            : restart:
     922                 :        122 :         rt = rt6_select(fn, oif, strict | reachable);
     923         [ -  + ]:        122 :         if (rt->rt6i_nsiblings)
     924                 :          0 :                 rt = rt6_multipath_select(rt, fl6, oif, strict | reachable);
     925 [ +  + ][ -  + ]:        237 :         BACKTRACK(net, &fl6->saddr);
                 [ #  # ]
     926 [ +  - ][ +  + ]:        235 :         if (rt == net->ipv6.ip6_null_entry ||
     927                 :        120 :             rt->rt6i_flags & RTF_CACHE)
     928                 :            :                 goto out;
     929                 :            : 
     930                 :            :         dst_hold(&rt->dst);
     931                 :        108 :         read_unlock_bh(&table->tb6_lock);
     932                 :            : 
     933         [ +  + ]:        108 :         if (!(rt->rt6i_flags & (RTF_NONEXTHOP | RTF_GATEWAY)))
     934                 :        105 :                 nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
     935         [ -  + ]:          3 :         else if (!(rt->dst.flags & DST_HOST))
     936                 :            :                 nrt = rt6_alloc_clone(rt, &fl6->daddr);
     937                 :            :         else
     938                 :            :                 goto out2;
     939                 :            : 
     940                 :            :         ip6_rt_put(rt);
     941         [ -  + ]:        105 :         rt = nrt ? : net->ipv6.ip6_null_entry;
     942                 :            : 
     943                 :            :         dst_hold(&rt->dst);
     944         [ +  - ]:        105 :         if (nrt) {
     945                 :        105 :                 err = ip6_ins_rt(nrt);
     946         [ -  + ]:        105 :                 if (!err)
     947                 :            :                         goto out2;
     948                 :            :         }
     949                 :            : 
     950         [ #  # ]:          0 :         if (--attempts <= 0)
     951                 :            :                 goto out2;
     952                 :            : 
     953                 :            :         /*
     954                 :            :          * Race condition! In the gap, when table->tb6_lock was
     955                 :            :          * released someone could insert this route.  Relookup.
     956                 :            :          */
     957                 :            :         ip6_rt_put(rt);
     958                 :            :         goto relookup;
     959                 :            : 
     960                 :            : out:
     961         [ +  + ]:         14 :         if (reachable) {
     962                 :            :                 reachable = 0;
     963                 :            :                 goto restart_2;
     964                 :            :         }
     965                 :            :         dst_hold(&rt->dst);
     966                 :          7 :         read_unlock_bh(&table->tb6_lock);
     967                 :            : out2:
     968                 :        115 :         rt->dst.lastuse = jiffies;
     969                 :        115 :         rt->dst.__use++;
     970                 :            : 
     971                 :        115 :         return rt;
     972                 :            : }
     973                 :            : 
     974                 :          0 : static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table,
     975                 :            :                                             struct flowi6 *fl6, int flags)
     976                 :            : {
     977                 :        111 :         return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags);
     978                 :            : }
     979                 :            : 
     980                 :        111 : static struct dst_entry *ip6_route_input_lookup(struct net *net,
     981                 :            :                                                 struct net_device *dev,
     982                 :            :                                                 struct flowi6 *fl6, int flags)
     983                 :            : {
     984 [ +  - ][ +  - ]:        111 :         if (rt6_need_strict(&fl6->daddr) && dev->type != ARPHRD_PIMREG)
     985                 :        111 :                 flags |= RT6_LOOKUP_F_IFACE;
     986                 :            : 
     987                 :        111 :         return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_input);
     988                 :            : }
     989                 :            : 
     990                 :          0 : void ip6_route_input(struct sk_buff *skb)
     991                 :            : {
     992                 :            :         const struct ipv6hdr *iph = ipv6_hdr(skb);
     993                 :            :         struct net *net = dev_net(skb->dev);
     994                 :            :         int flags = RT6_LOOKUP_F_HAS_SADDR;
     995                 :        555 :         struct flowi6 fl6 = {
     996                 :        111 :                 .flowi6_iif = skb->dev->ifindex,
     997                 :            :                 .daddr = iph->daddr,
     998                 :            :                 .saddr = iph->saddr,
     999                 :            :                 .flowlabel = ip6_flowinfo(iph),
    1000                 :        111 :                 .flowi6_mark = skb->mark,
    1001                 :        111 :                 .flowi6_proto = iph->nexthdr,
    1002                 :            :         };
    1003                 :            : 
    1004                 :        111 :         skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags));
    1005                 :        111 : }
    1006                 :            : 
    1007                 :          0 : static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
    1008                 :            :                                              struct flowi6 *fl6, int flags)
    1009                 :            : {
    1010                 :          4 :         return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags);
    1011                 :            : }
    1012                 :            : 
    1013                 :          0 : struct dst_entry * ip6_route_output(struct net *net, const struct sock *sk,
    1014                 :            :                                     struct flowi6 *fl6)
    1015                 :            : {
    1016                 :            :         int flags = 0;
    1017                 :            : 
    1018                 :          4 :         fl6->flowi6_iif = LOOPBACK_IFINDEX;
    1019                 :            : 
    1020         [ +  - ]:          8 :         if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr))
           [ +  -  +  + ]
    1021                 :            :                 flags |= RT6_LOOKUP_F_IFACE;
    1022                 :            : 
    1023         [ -  + ]:          4 :         if (!ipv6_addr_any(&fl6->saddr))
    1024                 :          0 :                 flags |= RT6_LOOKUP_F_HAS_SADDR;
    1025         [ +  - ]:          4 :         else if (sk)
    1026                 :          4 :                 flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs);
    1027                 :            : 
    1028                 :          4 :         return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output);
    1029                 :            : }
    1030                 :            : 
    1031                 :            : EXPORT_SYMBOL(ip6_route_output);
    1032                 :            : 
    1033                 :          0 : struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig)
    1034                 :            : {
    1035                 :            :         struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig;
    1036                 :            :         struct dst_entry *new = NULL;
    1037                 :            : 
    1038                 :          0 :         rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, DST_OBSOLETE_NONE, 0);
    1039         [ #  # ]:          0 :         if (rt) {
    1040                 :          0 :                 new = &rt->dst;
    1041                 :            : 
    1042                 :          0 :                 memset(new + 1, 0, sizeof(*rt) - sizeof(*new));
    1043                 :          0 :                 rt6_init_peer(rt, net->ipv6.peers);
    1044                 :            : 
    1045                 :          0 :                 new->__use = 1;
    1046                 :          0 :                 new->input = dst_discard;
    1047                 :          0 :                 new->output = dst_discard;
    1048                 :            : 
    1049         [ #  # ]:          0 :                 if (dst_metrics_read_only(&ort->dst))
    1050                 :          0 :                         new->_metrics = ort->dst._metrics;
    1051                 :            :                 else
    1052                 :            :                         dst_copy_metrics(new, &ort->dst);
    1053                 :          0 :                 rt->rt6i_idev = ort->rt6i_idev;
    1054         [ #  # ]:          0 :                 if (rt->rt6i_idev)
    1055                 :            :                         in6_dev_hold(rt->rt6i_idev);
    1056                 :            : 
    1057                 :          0 :                 rt->rt6i_gateway = ort->rt6i_gateway;
    1058                 :          0 :                 rt->rt6i_flags = ort->rt6i_flags;
    1059                 :          0 :                 rt->rt6i_metric = 0;
    1060                 :            : 
    1061                 :          0 :                 memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
    1062                 :            : #ifdef CONFIG_IPV6_SUBTREES
    1063                 :            :                 memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key));
    1064                 :            : #endif
    1065                 :            : 
    1066                 :            :                 dst_free(new);
    1067                 :            :         }
    1068                 :            : 
    1069                 :          0 :         dst_release(dst_orig);
    1070         [ #  # ]:          0 :         return new ? new : ERR_PTR(-ENOMEM);
    1071                 :            : }
    1072                 :            : 
    1073                 :            : /*
    1074                 :            :  *      Destination cache support functions
    1075                 :            :  */
    1076                 :            : 
    1077                 :          0 : static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
    1078                 :            : {
    1079                 :            :         struct rt6_info *rt;
    1080                 :            : 
    1081                 :            :         rt = (struct rt6_info *) dst;
    1082                 :            : 
    1083                 :            :         /* All IPV6 dsts are created with ->obsolete set to the value
    1084                 :            :          * DST_OBSOLETE_FORCE_CHK which forces validation calls down
    1085                 :            :          * into this function always.
    1086                 :            :          */
    1087         [ #  # ]:          0 :         if (rt->rt6i_genid != rt_genid_ipv6(dev_net(rt->dst.dev)))
    1088                 :            :                 return NULL;
    1089                 :            : 
    1090 [ #  # ][ #  # ]:          0 :         if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie))
    1091                 :            :                 return NULL;
    1092                 :            : 
    1093         [ #  # ]:          0 :         if (rt6_check_expired(rt))
    1094                 :            :                 return NULL;
    1095                 :            : 
    1096                 :          0 :         return dst;
    1097                 :            : }
    1098                 :            : 
    1099                 :          0 : static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
    1100                 :            : {
    1101                 :            :         struct rt6_info *rt = (struct rt6_info *) dst;
    1102                 :            : 
    1103         [ #  # ]:          0 :         if (rt) {
    1104         [ #  # ]:          0 :                 if (rt->rt6i_flags & RTF_CACHE) {
    1105         [ #  # ]:          0 :                         if (rt6_check_expired(rt)) {
    1106                 :          0 :                                 ip6_del_rt(rt);
    1107                 :            :                                 dst = NULL;
    1108                 :            :                         }
    1109                 :            :                 } else {
    1110                 :          0 :                         dst_release(dst);
    1111                 :            :                         dst = NULL;
    1112                 :            :                 }
    1113                 :            :         }
    1114                 :          0 :         return dst;
    1115                 :            : }
    1116                 :            : 
    1117                 :          0 : static void ip6_link_failure(struct sk_buff *skb)
    1118                 :            : {
    1119                 :            :         struct rt6_info *rt;
    1120                 :            : 
    1121                 :          0 :         icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
    1122                 :            : 
    1123                 :            :         rt = (struct rt6_info *) skb_dst(skb);
    1124         [ #  # ]:          0 :         if (rt) {
    1125         [ #  # ]:          0 :                 if (rt->rt6i_flags & RTF_CACHE) {
    1126                 :            :                         dst_hold(&rt->dst);
    1127         [ #  # ]:          0 :                         if (ip6_del_rt(rt))
    1128                 :          0 :                                 dst_free(&rt->dst);
    1129 [ #  # ][ #  # ]:          0 :                 } else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) {
    1130                 :          0 :                         rt->rt6i_node->fn_sernum = -1;
    1131                 :            :                 }
    1132                 :            :         }
    1133                 :          0 : }
    1134                 :            : 
    1135                 :          0 : static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
    1136                 :            :                                struct sk_buff *skb, u32 mtu)
    1137                 :            : {
    1138                 :            :         struct rt6_info *rt6 = (struct rt6_info*)dst;
    1139                 :            : 
    1140                 :            :         dst_confirm(dst);
    1141 [ #  # ][ #  # ]:          0 :         if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) {
    1142                 :            :                 struct net *net = dev_net(dst->dev);
    1143                 :            : 
    1144                 :          0 :                 rt6->rt6i_flags |= RTF_MODIFIED;
    1145         [ #  # ]:          0 :                 if (mtu < IPV6_MIN_MTU) {
    1146                 :            :                         u32 features = dst_metric(dst, RTAX_FEATURES);
    1147                 :            :                         mtu = IPV6_MIN_MTU;
    1148                 :          0 :                         features |= RTAX_FEATURE_ALLFRAG;
    1149                 :            :                         dst_metric_set(dst, RTAX_FEATURES, features);
    1150                 :            :                 }
    1151                 :            :                 dst_metric_set(dst, RTAX_MTU, mtu);
    1152                 :          0 :                 rt6_update_expires(rt6, net->ipv6.sysctl.ip6_rt_mtu_expires);
    1153                 :            :         }
    1154                 :          0 : }
    1155                 :            : 
    1156                 :          0 : void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,
    1157                 :            :                      int oif, u32 mark)
    1158                 :            : {
    1159                 :          0 :         const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data;
    1160                 :            :         struct dst_entry *dst;
    1161                 :            :         struct flowi6 fl6;
    1162                 :            : 
    1163                 :          0 :         memset(&fl6, 0, sizeof(fl6));
    1164                 :          0 :         fl6.flowi6_oif = oif;
    1165                 :          0 :         fl6.flowi6_mark = mark;
    1166                 :          0 :         fl6.daddr = iph->daddr;
    1167                 :          0 :         fl6.saddr = iph->saddr;
    1168                 :          0 :         fl6.flowlabel = ip6_flowinfo(iph);
    1169                 :            : 
    1170                 :          0 :         dst = ip6_route_output(net, NULL, &fl6);
    1171         [ #  # ]:          0 :         if (!dst->error)
    1172         [ #  # ]:          0 :                 ip6_rt_update_pmtu(dst, NULL, skb, ntohl(mtu));
    1173                 :          0 :         dst_release(dst);
    1174                 :          0 : }
    1175                 :            : EXPORT_SYMBOL_GPL(ip6_update_pmtu);
    1176                 :            : 
    1177                 :          0 : void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu)
    1178                 :            : {
    1179                 :          0 :         ip6_update_pmtu(skb, sock_net(sk), mtu,
    1180                 :            :                         sk->sk_bound_dev_if, sk->sk_mark);
    1181                 :          0 : }
    1182                 :            : EXPORT_SYMBOL_GPL(ip6_sk_update_pmtu);
    1183                 :            : 
    1184                 :            : /* Handle redirects */
    1185                 :            : struct ip6rd_flowi {
    1186                 :            :         struct flowi6 fl6;
    1187                 :            :         struct in6_addr gateway;
    1188                 :            : };
    1189                 :            : 
    1190                 :          0 : static struct rt6_info *__ip6_route_redirect(struct net *net,
    1191                 :            :                                              struct fib6_table *table,
    1192                 :            :                                              struct flowi6 *fl6,
    1193                 :            :                                              int flags)
    1194                 :            : {
    1195                 :            :         struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6;
    1196                 :            :         struct rt6_info *rt;
    1197                 :            :         struct fib6_node *fn;
    1198                 :            : 
    1199                 :            :         /* Get the "current" route for this destination and
    1200                 :            :          * check if the redirect has come from approriate router.
    1201                 :            :          *
    1202                 :            :          * RFC 4861 specifies that redirects should only be
    1203                 :            :          * accepted if they come from the nexthop to the target.
    1204                 :            :          * Due to the way the routes are chosen, this notion
    1205                 :            :          * is a bit fuzzy and one might need to check all possible
    1206                 :            :          * routes.
    1207                 :            :          */
    1208                 :            : 
    1209                 :          0 :         read_lock_bh(&table->tb6_lock);
    1210                 :          0 :         fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
    1211                 :            : restart:
    1212         [ #  # ]:          0 :         for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
    1213         [ #  # ]:          0 :                 if (rt6_check_expired(rt))
    1214                 :          0 :                         continue;
    1215         [ #  # ]:          0 :                 if (rt->dst.error)
    1216                 :            :                         break;
    1217         [ #  # ]:          0 :                 if (!(rt->rt6i_flags & RTF_GATEWAY))
    1218                 :          0 :                         continue;
    1219         [ #  # ]:          0 :                 if (fl6->flowi6_oif != rt->dst.dev->ifindex)
    1220                 :          0 :                         continue;
    1221         [ #  # ]:          0 :                 if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway))
    1222                 :          0 :                         continue;
    1223                 :            :                 break;
    1224                 :            :         }
    1225                 :            : 
    1226         [ #  # ]:          0 :         if (!rt)
    1227                 :          0 :                 rt = net->ipv6.ip6_null_entry;
    1228         [ #  # ]:          0 :         else if (rt->dst.error) {
    1229                 :          0 :                 rt = net->ipv6.ip6_null_entry;
    1230                 :          0 :                 goto out;
    1231                 :            :         }
    1232 [ #  # ][ #  # ]:          0 :         BACKTRACK(net, &fl6->saddr);
                 [ #  # ]
    1233                 :            : out:
    1234                 :            :         dst_hold(&rt->dst);
    1235                 :            : 
    1236                 :          0 :         read_unlock_bh(&table->tb6_lock);
    1237                 :            : 
    1238                 :          0 :         return rt;
    1239                 :            : };
    1240                 :            : 
    1241                 :          0 : static struct dst_entry *ip6_route_redirect(struct net *net,
    1242                 :            :                                         const struct flowi6 *fl6,
    1243                 :            :                                         const struct in6_addr *gateway)
    1244                 :            : {
    1245                 :            :         int flags = RT6_LOOKUP_F_HAS_SADDR;
    1246                 :            :         struct ip6rd_flowi rdfl;
    1247                 :            : 
    1248                 :          0 :         rdfl.fl6 = *fl6;
    1249                 :          0 :         rdfl.gateway = *gateway;
    1250                 :            : 
    1251                 :          0 :         return fib6_rule_lookup(net, &rdfl.fl6,
    1252                 :            :                                 flags, __ip6_route_redirect);
    1253                 :            : }
    1254                 :            : 
    1255                 :          0 : void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark)
    1256                 :            : {
    1257                 :          0 :         const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data;
    1258                 :            :         struct dst_entry *dst;
    1259                 :            :         struct flowi6 fl6;
    1260                 :            : 
    1261                 :          0 :         memset(&fl6, 0, sizeof(fl6));
    1262                 :          0 :         fl6.flowi6_oif = oif;
    1263                 :          0 :         fl6.flowi6_mark = mark;
    1264                 :          0 :         fl6.daddr = iph->daddr;
    1265                 :          0 :         fl6.saddr = iph->saddr;
    1266                 :          0 :         fl6.flowlabel = ip6_flowinfo(iph);
    1267                 :            : 
    1268                 :          0 :         dst = ip6_route_redirect(net, &fl6, &ipv6_hdr(skb)->saddr);
    1269                 :          0 :         rt6_do_redirect(dst, NULL, skb);
    1270                 :          0 :         dst_release(dst);
    1271                 :          0 : }
    1272                 :            : EXPORT_SYMBOL_GPL(ip6_redirect);
    1273                 :            : 
    1274                 :          0 : void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif,
    1275                 :            :                             u32 mark)
    1276                 :            : {
    1277                 :            :         const struct ipv6hdr *iph = ipv6_hdr(skb);
    1278                 :            :         const struct rd_msg *msg = (struct rd_msg *)icmp6_hdr(skb);
    1279                 :            :         struct dst_entry *dst;
    1280                 :            :         struct flowi6 fl6;
    1281                 :            : 
    1282                 :          0 :         memset(&fl6, 0, sizeof(fl6));
    1283                 :          0 :         fl6.flowi6_oif = oif;
    1284                 :          0 :         fl6.flowi6_mark = mark;
    1285                 :          0 :         fl6.daddr = msg->dest;
    1286                 :          0 :         fl6.saddr = iph->daddr;
    1287                 :            : 
    1288                 :          0 :         dst = ip6_route_redirect(net, &fl6, &iph->saddr);
    1289                 :          0 :         rt6_do_redirect(dst, NULL, skb);
    1290                 :          0 :         dst_release(dst);
    1291                 :          0 : }
    1292                 :            : 
    1293                 :          0 : void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk)
    1294                 :            : {
    1295                 :          0 :         ip6_redirect(skb, sock_net(sk), sk->sk_bound_dev_if, sk->sk_mark);
    1296                 :          0 : }
    1297                 :            : EXPORT_SYMBOL_GPL(ip6_sk_redirect);
    1298                 :            : 
    1299                 :          0 : static unsigned int ip6_default_advmss(const struct dst_entry *dst)
    1300                 :            : {
    1301                 :            :         struct net_device *dev = dst->dev;
    1302                 :            :         unsigned int mtu = dst_mtu(dst);
    1303                 :            :         struct net *net = dev_net(dev);
    1304                 :            : 
    1305                 :          0 :         mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr);
    1306                 :            : 
    1307         [ #  # ]:          0 :         if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss)
    1308                 :            :                 mtu = net->ipv6.sysctl.ip6_rt_min_advmss;
    1309                 :            : 
    1310                 :            :         /*
    1311                 :            :          * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and
    1312                 :            :          * corresponding MSS is IPV6_MAXPLEN - tcp_header_size.
    1313                 :            :          * IPV6_MAXPLEN is also valid and means: "any MSS,
    1314                 :            :          * rely only on pmtu discovery"
    1315                 :            :          */
    1316         [ #  # ]:          0 :         if (mtu > IPV6_MAXPLEN - sizeof(struct tcphdr))
    1317                 :            :                 mtu = IPV6_MAXPLEN;
    1318                 :          0 :         return mtu;
    1319                 :            : }
    1320                 :            : 
    1321                 :          0 : static unsigned int ip6_mtu(const struct dst_entry *dst)
    1322                 :            : {
    1323                 :            :         struct inet6_dev *idev;
    1324                 :            :         unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
    1325                 :            : 
    1326         [ #  # ]:          0 :         if (mtu)
    1327                 :            :                 return mtu;
    1328                 :            : 
    1329                 :            :         mtu = IPV6_MIN_MTU;
    1330                 :            : 
    1331                 :            :         rcu_read_lock();
    1332                 :          0 :         idev = __in6_dev_get(dst->dev);
    1333         [ #  # ]:          0 :         if (idev)
    1334                 :          0 :                 mtu = idev->cnf.mtu6;
    1335                 :            :         rcu_read_unlock();
    1336                 :            : 
    1337                 :          0 :         return mtu;
    1338                 :            : }
    1339                 :            : 
    1340                 :            : static struct dst_entry *icmp6_dst_gc_list;
    1341                 :            : static DEFINE_SPINLOCK(icmp6_dst_lock);
    1342                 :            : 
    1343                 :          0 : struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
    1344                 :            :                                   struct flowi6 *fl6)
    1345                 :            : {
    1346                 :            :         struct dst_entry *dst;
    1347                 :            :         struct rt6_info *rt;
    1348                 :            :         struct inet6_dev *idev = in6_dev_get(dev);
    1349                 :            :         struct net *net = dev_net(dev);
    1350                 :            : 
    1351         [ #  # ]:          0 :         if (unlikely(!idev))
    1352                 :            :                 return ERR_PTR(-ENODEV);
    1353                 :            : 
    1354                 :            :         rt = ip6_dst_alloc(net, dev, 0, NULL);
    1355         [ #  # ]:          0 :         if (unlikely(!rt)) {
    1356                 :            :                 in6_dev_put(idev);
    1357                 :            :                 dst = ERR_PTR(-ENOMEM);
    1358                 :            :                 goto out;
    1359                 :            :         }
    1360                 :            : 
    1361                 :          0 :         rt->dst.flags |= DST_HOST;
    1362                 :          0 :         rt->dst.output  = ip6_output;
    1363                 :          0 :         atomic_set(&rt->dst.__refcnt, 1);
    1364                 :          0 :         rt->rt6i_gateway  = fl6->daddr;
    1365                 :          0 :         rt->rt6i_dst.addr = fl6->daddr;
    1366                 :          0 :         rt->rt6i_dst.plen = 128;
    1367                 :          0 :         rt->rt6i_idev     = idev;
    1368                 :          0 :         dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 0);
    1369                 :            : 
    1370                 :            :         spin_lock_bh(&icmp6_dst_lock);
    1371                 :          0 :         rt->dst.next = icmp6_dst_gc_list;
    1372                 :          0 :         icmp6_dst_gc_list = &rt->dst;
    1373                 :            :         spin_unlock_bh(&icmp6_dst_lock);
    1374                 :            : 
    1375                 :          0 :         fib6_force_start_gc(net);
    1376                 :            : 
    1377                 :          0 :         dst = xfrm_lookup(net, &rt->dst, flowi6_to_flowi(fl6), NULL, 0);
    1378                 :            : 
    1379                 :            : out:
    1380                 :          0 :         return dst;
    1381                 :            : }
    1382                 :            : 
    1383                 :          0 : int icmp6_dst_gc(void)
    1384                 :            : {
    1385                 :            :         struct dst_entry *dst, **pprev;
    1386                 :            :         int more = 0;
    1387                 :            : 
    1388                 :            :         spin_lock_bh(&icmp6_dst_lock);
    1389                 :            :         pprev = &icmp6_dst_gc_list;
    1390                 :            : 
    1391         [ -  + ]:        110 :         while ((dst = *pprev) != NULL) {
    1392         [ #  # ]:          0 :                 if (!atomic_read(&dst->__refcnt)) {
    1393                 :          0 :                         *pprev = dst->next;
    1394                 :            :                         dst_free(dst);
    1395                 :            :                 } else {
    1396                 :          0 :                         pprev = &dst->next;
    1397                 :          0 :                         ++more;
    1398                 :            :                 }
    1399                 :            :         }
    1400                 :            : 
    1401                 :            :         spin_unlock_bh(&icmp6_dst_lock);
    1402                 :            : 
    1403                 :        110 :         return more;
    1404                 :            : }
    1405                 :            : 
    1406                 :          0 : static void icmp6_clean_all(int (*func)(struct rt6_info *rt, void *arg),
    1407                 :            :                             void *arg)
    1408                 :            : {
    1409                 :            :         struct dst_entry *dst, **pprev;
    1410                 :            : 
    1411                 :            :         spin_lock_bh(&icmp6_dst_lock);
    1412                 :            :         pprev = &icmp6_dst_gc_list;
    1413         [ #  # ]:          0 :         while ((dst = *pprev) != NULL) {
    1414                 :            :                 struct rt6_info *rt = (struct rt6_info *) dst;
    1415         [ #  # ]:          0 :                 if (func(rt, arg)) {
    1416                 :          0 :                         *pprev = dst->next;
    1417                 :            :                         dst_free(dst);
    1418                 :            :                 } else {
    1419                 :          0 :                         pprev = &dst->next;
    1420                 :            :                 }
    1421                 :            :         }
    1422                 :            :         spin_unlock_bh(&icmp6_dst_lock);
    1423                 :          0 : }
    1424                 :            : 
    1425                 :          0 : static int ip6_dst_gc(struct dst_ops *ops)
    1426                 :            : {
    1427                 :          0 :         struct net *net = container_of(ops, struct net, ipv6.ip6_dst_ops);
    1428                 :          0 :         int rt_min_interval = net->ipv6.sysctl.ip6_rt_gc_min_interval;
    1429                 :          0 :         int rt_max_size = net->ipv6.sysctl.ip6_rt_max_size;
    1430                 :          0 :         int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity;
    1431                 :          0 :         int rt_gc_timeout = net->ipv6.sysctl.ip6_rt_gc_timeout;
    1432                 :          0 :         unsigned long rt_last_gc = net->ipv6.ip6_rt_last_gc;
    1433                 :            :         int entries;
    1434                 :            : 
    1435                 :            :         entries = dst_entries_get_fast(ops);
    1436 [ #  # ][ #  # ]:          0 :         if (time_after(rt_last_gc + rt_min_interval, jiffies) &&
    1437                 :            :             entries <= rt_max_size)
    1438                 :            :                 goto out;
    1439                 :            : 
    1440                 :          0 :         net->ipv6.ip6_rt_gc_expire++;
    1441                 :          0 :         fib6_run_gc(net->ipv6.ip6_rt_gc_expire, net, entries > rt_max_size);
    1442                 :            :         entries = dst_entries_get_slow(ops);
    1443         [ #  # ]:          0 :         if (entries < ops->gc_thresh)
    1444                 :          0 :                 net->ipv6.ip6_rt_gc_expire = rt_gc_timeout>>1;
    1445                 :            : out:
    1446                 :          0 :         net->ipv6.ip6_rt_gc_expire -= net->ipv6.ip6_rt_gc_expire>>rt_elasticity;
    1447                 :          0 :         return entries > rt_max_size;
    1448                 :            : }
    1449                 :            : 
    1450                 :            : /*
    1451                 :            :  *
    1452                 :            :  */
    1453                 :            : 
    1454                 :          0 : int ip6_route_add(struct fib6_config *cfg)
    1455                 :            : {
    1456                 :            :         int err;
    1457                 :          0 :         struct net *net = cfg->fc_nlinfo.nl_net;
    1458                 :            :         struct rt6_info *rt = NULL;
    1459                 :            :         struct net_device *dev = NULL;
    1460                 :            :         struct inet6_dev *idev = NULL;
    1461                 :            :         struct fib6_table *table;
    1462                 :            :         int addr_type;
    1463                 :            : 
    1464 [ #  # ][ #  # ]:          0 :         if (cfg->fc_dst_len > 128 || cfg->fc_src_len > 128)
    1465                 :            :                 return -EINVAL;
    1466                 :            : #ifndef CONFIG_IPV6_SUBTREES
    1467         [ #  # ]:          0 :         if (cfg->fc_src_len)
    1468                 :            :                 return -EINVAL;
    1469                 :            : #endif
    1470         [ #  # ]:          0 :         if (cfg->fc_ifindex) {
    1471                 :            :                 err = -ENODEV;
    1472                 :          0 :                 dev = dev_get_by_index(net, cfg->fc_ifindex);
    1473         [ #  # ]:          0 :                 if (!dev)
    1474                 :            :                         goto out;
    1475                 :            :                 idev = in6_dev_get(dev);
    1476         [ #  # ]:          0 :                 if (!idev)
    1477                 :            :                         goto out;
    1478                 :            :         }
    1479                 :            : 
    1480         [ #  # ]:          0 :         if (cfg->fc_metric == 0)
    1481                 :          0 :                 cfg->fc_metric = IP6_RT_PRIO_USER;
    1482                 :            : 
    1483                 :            :         err = -ENOBUFS;
    1484 [ #  # ][ #  # ]:          0 :         if (cfg->fc_nlinfo.nlh &&
    1485                 :          0 :             !(cfg->fc_nlinfo.nlh->nlmsg_flags & NLM_F_CREATE)) {
    1486                 :          0 :                 table = fib6_get_table(net, cfg->fc_table);
    1487         [ #  # ]:          0 :                 if (!table) {
    1488                 :          0 :                         pr_warn("NLM_F_CREATE should be specified when creating new route\n");
    1489                 :          0 :                         table = fib6_new_table(net, cfg->fc_table);
    1490                 :            :                 }
    1491                 :            :         } else {
    1492                 :          0 :                 table = fib6_new_table(net, cfg->fc_table);
    1493                 :            :         }
    1494                 :            : 
    1495         [ #  # ]:          0 :         if (!table)
    1496                 :            :                 goto out;
    1497                 :            : 
    1498                 :            :         rt = ip6_dst_alloc(net, NULL, DST_NOCOUNT, table);
    1499                 :            : 
    1500         [ #  # ]:          0 :         if (!rt) {
    1501                 :            :                 err = -ENOMEM;
    1502                 :            :                 goto out;
    1503                 :            :         }
    1504                 :            : 
    1505         [ #  # ]:          0 :         if (cfg->fc_flags & RTF_EXPIRES)
    1506                 :          0 :                 rt6_set_expires(rt, jiffies +
    1507                 :          0 :                                 clock_t_to_jiffies(cfg->fc_expires));
    1508                 :            :         else
    1509                 :            :                 rt6_clean_expires(rt);
    1510                 :            : 
    1511         [ #  # ]:          0 :         if (cfg->fc_protocol == RTPROT_UNSPEC)
    1512                 :          0 :                 cfg->fc_protocol = RTPROT_BOOT;
    1513                 :          0 :         rt->rt6i_protocol = cfg->fc_protocol;
    1514                 :            : 
    1515                 :          0 :         addr_type = ipv6_addr_type(&cfg->fc_dst);
    1516                 :            : 
    1517         [ #  # ]:          0 :         if (addr_type & IPV6_ADDR_MULTICAST)
    1518                 :          0 :                 rt->dst.input = ip6_mc_input;
    1519         [ #  # ]:          0 :         else if (cfg->fc_flags & RTF_LOCAL)
    1520                 :          0 :                 rt->dst.input = ip6_input;
    1521                 :            :         else
    1522                 :          0 :                 rt->dst.input = ip6_forward;
    1523                 :            : 
    1524                 :          0 :         rt->dst.output = ip6_output;
    1525                 :            : 
    1526                 :          0 :         ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len);
    1527                 :          0 :         rt->rt6i_dst.plen = cfg->fc_dst_len;
    1528         [ #  # ]:          0 :         if (rt->rt6i_dst.plen == 128)
    1529                 :          0 :                rt->dst.flags |= DST_HOST;
    1530                 :            : 
    1531 [ #  # ][ #  # ]:          0 :         if (!(rt->dst.flags & DST_HOST) && cfg->fc_mx) {
    1532                 :            :                 u32 *metrics = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL);
    1533         [ #  # ]:          0 :                 if (!metrics) {
    1534                 :            :                         err = -ENOMEM;
    1535                 :            :                         goto out;
    1536                 :            :                 }
    1537                 :            :                 dst_init_metrics(&rt->dst, metrics, 0);
    1538                 :            :         }
    1539                 :            : #ifdef CONFIG_IPV6_SUBTREES
    1540                 :            :         ipv6_addr_prefix(&rt->rt6i_src.addr, &cfg->fc_src, cfg->fc_src_len);
    1541                 :            :         rt->rt6i_src.plen = cfg->fc_src_len;
    1542                 :            : #endif
    1543                 :            : 
    1544                 :          0 :         rt->rt6i_metric = cfg->fc_metric;
    1545                 :            : 
    1546                 :            :         /* We cannot add true routes via loopback here,
    1547                 :            :            they would result in kernel looping; promote them to reject routes
    1548                 :            :          */
    1549 [ #  # ][ #  # ]:          0 :         if ((cfg->fc_flags & RTF_REJECT) ||
    1550 [ #  # ][ #  # ]:          0 :             (dev && (dev->flags & IFF_LOOPBACK) &&
    1551         [ #  # ]:          0 :              !(addr_type & IPV6_ADDR_LOOPBACK) &&
    1552                 :          0 :              !(cfg->fc_flags & RTF_LOCAL))) {
    1553                 :            :                 /* hold loopback dev/idev if we haven't done so. */
    1554         [ #  # ]:          0 :                 if (dev != net->loopback_dev) {
    1555         [ #  # ]:          0 :                         if (dev) {
    1556                 :            :                                 dev_put(dev);
    1557                 :            :                                 in6_dev_put(idev);
    1558                 :            :                         }
    1559                 :          0 :                         dev = net->loopback_dev;
    1560                 :            :                         dev_hold(dev);
    1561                 :            :                         idev = in6_dev_get(dev);
    1562         [ #  # ]:          0 :                         if (!idev) {
    1563                 :            :                                 err = -ENODEV;
    1564                 :            :                                 goto out;
    1565                 :            :                         }
    1566                 :            :                 }
    1567                 :          0 :                 rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP;
    1568      [ #  #  # ]:          0 :                 switch (cfg->fc_type) {
    1569                 :            :                 case RTN_BLACKHOLE:
    1570                 :          0 :                         rt->dst.error = -EINVAL;
    1571                 :          0 :                         rt->dst.output = dst_discard;
    1572                 :          0 :                         rt->dst.input = dst_discard;
    1573                 :          0 :                         break;
    1574                 :            :                 case RTN_PROHIBIT:
    1575                 :          0 :                         rt->dst.error = -EACCES;
    1576                 :          0 :                         rt->dst.output = ip6_pkt_prohibit_out;
    1577                 :          0 :                         rt->dst.input = ip6_pkt_prohibit;
    1578                 :          0 :                         break;
    1579                 :            :                 case RTN_THROW:
    1580                 :            :                 default:
    1581         [ #  # ]:          0 :                         rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN
    1582                 :            :                                         : -ENETUNREACH;
    1583                 :          0 :                         rt->dst.output = ip6_pkt_discard_out;
    1584                 :          0 :                         rt->dst.input = ip6_pkt_discard;
    1585                 :          0 :                         break;
    1586                 :            :                 }
    1587                 :            :                 goto install_route;
    1588                 :            :         }
    1589                 :            : 
    1590         [ #  # ]:          0 :         if (cfg->fc_flags & RTF_GATEWAY) {
    1591                 :            :                 const struct in6_addr *gw_addr;
    1592                 :            :                 int gwa_type;
    1593                 :            : 
    1594                 :          0 :                 gw_addr = &cfg->fc_gateway;
    1595                 :          0 :                 rt->rt6i_gateway = *gw_addr;
    1596                 :            :                 gwa_type = ipv6_addr_type(gw_addr);
    1597                 :            : 
    1598         [ #  # ]:          0 :                 if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) {
    1599                 :            :                         struct rt6_info *grt;
    1600                 :            : 
    1601                 :            :                         /* IPv6 strictly inhibits using not link-local
    1602                 :            :                            addresses as nexthop address.
    1603                 :            :                            Otherwise, router will not able to send redirects.
    1604                 :            :                            It is very good, but in some (rare!) circumstances
    1605                 :            :                            (SIT, PtP, NBMA NOARP links) it is handy to allow
    1606                 :            :                            some exceptions. --ANK
    1607                 :            :                          */
    1608                 :            :                         err = -EINVAL;
    1609         [ #  # ]:          0 :                         if (!(gwa_type & IPV6_ADDR_UNICAST))
    1610                 :            :                                 goto out;
    1611                 :            : 
    1612                 :          0 :                         grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1);
    1613                 :            : 
    1614                 :            :                         err = -EHOSTUNREACH;
    1615         [ #  # ]:          0 :                         if (!grt)
    1616                 :            :                                 goto out;
    1617         [ #  # ]:          0 :                         if (dev) {
    1618         [ #  # ]:          0 :                                 if (dev != grt->dst.dev) {
    1619                 :            :                                         ip6_rt_put(grt);
    1620                 :            :                                         goto out;
    1621                 :            :                                 }
    1622                 :            :                         } else {
    1623                 :          0 :                                 dev = grt->dst.dev;
    1624                 :          0 :                                 idev = grt->rt6i_idev;
    1625                 :            :                                 dev_hold(dev);
    1626                 :          0 :                                 in6_dev_hold(grt->rt6i_idev);
    1627                 :            :                         }
    1628         [ #  # ]:          0 :                         if (!(grt->rt6i_flags & RTF_GATEWAY))
    1629                 :            :                                 err = 0;
    1630                 :            :                         ip6_rt_put(grt);
    1631                 :            : 
    1632         [ #  # ]:          0 :                         if (err)
    1633                 :            :                                 goto out;
    1634                 :            :                 }
    1635                 :            :                 err = -EINVAL;
    1636 [ #  # ][ #  # ]:          0 :                 if (!dev || (dev->flags & IFF_LOOPBACK))
    1637                 :            :                         goto out;
    1638                 :            :         }
    1639                 :            : 
    1640                 :            :         err = -ENODEV;
    1641         [ #  # ]:          0 :         if (!dev)
    1642                 :            :                 goto out;
    1643                 :            : 
    1644         [ #  # ]:          0 :         if (!ipv6_addr_any(&cfg->fc_prefsrc)) {
    1645         [ #  # ]:          0 :                 if (!ipv6_chk_addr(net, &cfg->fc_prefsrc, dev, 0)) {
    1646                 :            :                         err = -EINVAL;
    1647                 :            :                         goto out;
    1648                 :            :                 }
    1649                 :          0 :                 rt->rt6i_prefsrc.addr = cfg->fc_prefsrc;
    1650                 :          0 :                 rt->rt6i_prefsrc.plen = 128;
    1651                 :            :         } else
    1652                 :          0 :                 rt->rt6i_prefsrc.plen = 0;
    1653                 :            : 
    1654                 :          0 :         rt->rt6i_flags = cfg->fc_flags;
    1655                 :            : 
    1656                 :            : install_route:
    1657         [ #  # ]:          0 :         if (cfg->fc_mx) {
    1658                 :          0 :                 struct nlattr *nla;
    1659                 :            :                 int remaining;
    1660                 :            : 
    1661         [ #  # ]:          0 :                 nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) {
    1662                 :            :                         int type = nla_type(nla);
    1663                 :            : 
    1664         [ #  # ]:          0 :                         if (type) {
    1665         [ #  # ]:          0 :                                 if (type > RTAX_MAX) {
    1666                 :            :                                         err = -EINVAL;
    1667                 :            :                                         goto out;
    1668                 :            :                                 }
    1669                 :            : 
    1670                 :          0 :                                 dst_metric_set(&rt->dst, type, nla_get_u32(nla));
    1671                 :            :                         }
    1672                 :            :                 }
    1673                 :            :         }
    1674                 :            : 
    1675                 :          0 :         rt->dst.dev = dev;
    1676                 :          0 :         rt->rt6i_idev = idev;
    1677                 :          0 :         rt->rt6i_table = table;
    1678                 :            : 
    1679                 :          0 :         cfg->fc_nlinfo.nl_net = dev_net(dev);
    1680                 :            : 
    1681                 :          0 :         return __ip6_ins_rt(rt, &cfg->fc_nlinfo);
    1682                 :            : 
    1683                 :            : out:
    1684         [ #  # ]:          0 :         if (dev)
    1685                 :            :                 dev_put(dev);
    1686         [ #  # ]:          0 :         if (idev)
    1687                 :            :                 in6_dev_put(idev);
    1688         [ #  # ]:          0 :         if (rt)
    1689                 :          0 :                 dst_free(&rt->dst);
    1690                 :          0 :         return err;
    1691                 :            : }
    1692                 :            : 
    1693                 :          0 : static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info)
    1694                 :            : {
    1695                 :            :         int err;
    1696                 :            :         struct fib6_table *table;
    1697                 :            :         struct net *net = dev_net(rt->dst.dev);
    1698                 :            : 
    1699         [ #  # ]:          0 :         if (rt == net->ipv6.ip6_null_entry) {
    1700                 :            :                 err = -ENOENT;
    1701                 :            :                 goto out;
    1702                 :            :         }
    1703                 :            : 
    1704                 :          0 :         table = rt->rt6i_table;
    1705                 :          0 :         write_lock_bh(&table->tb6_lock);
    1706                 :          0 :         err = fib6_del(rt, info);
    1707                 :          0 :         write_unlock_bh(&table->tb6_lock);
    1708                 :            : 
    1709                 :            : out:
    1710                 :            :         ip6_rt_put(rt);
    1711                 :          0 :         return err;
    1712                 :            : }
    1713                 :            : 
    1714                 :          0 : int ip6_del_rt(struct rt6_info *rt)
    1715                 :            : {
    1716                 :          0 :         struct nl_info info = {
    1717                 :            :                 .nl_net = dev_net(rt->dst.dev),
    1718                 :            :         };
    1719                 :          0 :         return __ip6_del_rt(rt, &info);
    1720                 :            : }
    1721                 :            : 
    1722                 :          0 : static int ip6_route_del(struct fib6_config *cfg)
    1723                 :            : {
    1724                 :            :         struct fib6_table *table;
    1725                 :            :         struct fib6_node *fn;
    1726                 :            :         struct rt6_info *rt;
    1727                 :            :         int err = -ESRCH;
    1728                 :            : 
    1729                 :          0 :         table = fib6_get_table(cfg->fc_nlinfo.nl_net, cfg->fc_table);
    1730         [ #  # ]:          0 :         if (!table)
    1731                 :            :                 return err;
    1732                 :            : 
    1733                 :          0 :         read_lock_bh(&table->tb6_lock);
    1734                 :            : 
    1735                 :          0 :         fn = fib6_locate(&table->tb6_root,
    1736                 :          0 :                          &cfg->fc_dst, cfg->fc_dst_len,
    1737                 :          0 :                          &cfg->fc_src, cfg->fc_src_len);
    1738                 :            : 
    1739         [ #  # ]:          0 :         if (fn) {
    1740         [ #  # ]:          0 :                 for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
    1741 [ #  # ][ #  # ]:          0 :                         if (cfg->fc_ifindex &&
    1742         [ #  # ]:          0 :                             (!rt->dst.dev ||
    1743                 :          0 :                              rt->dst.dev->ifindex != cfg->fc_ifindex))
    1744                 :          0 :                                 continue;
    1745 [ #  # ][ #  # ]:          0 :                         if (cfg->fc_flags & RTF_GATEWAY &&
    1746                 :            :                             !ipv6_addr_equal(&cfg->fc_gateway, &rt->rt6i_gateway))
    1747                 :          0 :                                 continue;
    1748 [ #  # ][ #  # ]:          0 :                         if (cfg->fc_metric && cfg->fc_metric != rt->rt6i_metric)
    1749                 :          0 :                                 continue;
    1750                 :            :                         dst_hold(&rt->dst);
    1751                 :          0 :                         read_unlock_bh(&table->tb6_lock);
    1752                 :            : 
    1753                 :          0 :                         return __ip6_del_rt(rt, &cfg->fc_nlinfo);
    1754                 :            :                 }
    1755                 :            :         }
    1756                 :          0 :         read_unlock_bh(&table->tb6_lock);
    1757                 :            : 
    1758                 :          0 :         return err;
    1759                 :            : }
    1760                 :            : 
    1761                 :          0 : static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb)
    1762                 :            : {
    1763                 :          0 :         struct net *net = dev_net(skb->dev);
    1764                 :            :         struct netevent_redirect netevent;
    1765                 :            :         struct rt6_info *rt, *nrt = NULL;
    1766                 :            :         struct ndisc_options ndopts;
    1767                 :            :         struct inet6_dev *in6_dev;
    1768                 :            :         struct neighbour *neigh;
    1769                 :            :         struct rd_msg *msg;
    1770                 :            :         int optlen, on_link;
    1771                 :            :         u8 *lladdr;
    1772                 :            : 
    1773                 :          0 :         optlen = skb_tail_pointer(skb) - skb_transport_header(skb);
    1774                 :          0 :         optlen -= sizeof(*msg);
    1775                 :            : 
    1776         [ #  # ]:          0 :         if (optlen < 0) {
    1777                 :          0 :                 net_dbg_ratelimited("rt6_do_redirect: packet too short\n");
    1778                 :          0 :                 return;
    1779                 :            :         }
    1780                 :            : 
    1781                 :            :         msg = (struct rd_msg *)icmp6_hdr(skb);
    1782                 :            : 
    1783         [ #  # ]:          0 :         if (ipv6_addr_is_multicast(&msg->dest)) {
    1784                 :          0 :                 net_dbg_ratelimited("rt6_do_redirect: destination address is multicast\n");
    1785                 :            :                 return;
    1786                 :            :         }
    1787                 :            : 
    1788                 :            :         on_link = 0;
    1789         [ #  # ]:          0 :         if (ipv6_addr_equal(&msg->dest, &msg->target)) {
    1790                 :            :                 on_link = 1;
    1791         [ #  # ]:          0 :         } else if (ipv6_addr_type(&msg->target) !=
    1792                 :            :                    (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) {
    1793                 :          0 :                 net_dbg_ratelimited("rt6_do_redirect: target address is not link-local unicast\n");
    1794                 :            :                 return;
    1795                 :            :         }
    1796                 :            : 
    1797                 :          0 :         in6_dev = __in6_dev_get(skb->dev);
    1798         [ #  # ]:          0 :         if (!in6_dev)
    1799                 :            :                 return;
    1800 [ #  # ][ #  # ]:          0 :         if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects)
    1801                 :            :                 return;
    1802                 :            : 
    1803                 :            :         /* RFC2461 8.1:
    1804                 :            :          *      The IP source address of the Redirect MUST be the same as the current
    1805                 :            :          *      first-hop router for the specified ICMP Destination Address.
    1806                 :            :          */
    1807                 :            : 
    1808         [ #  # ]:          0 :         if (!ndisc_parse_options(msg->opt, optlen, &ndopts)) {
    1809                 :          0 :                 net_dbg_ratelimited("rt6_redirect: invalid ND options\n");
    1810                 :            :                 return;
    1811                 :            :         }
    1812                 :            : 
    1813                 :            :         lladdr = NULL;
    1814         [ #  # ]:          0 :         if (ndopts.nd_opts_tgt_lladdr) {
    1815                 :          0 :                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr,
    1816                 :            :                                              skb->dev);
    1817         [ #  # ]:          0 :                 if (!lladdr) {
    1818                 :          0 :                         net_dbg_ratelimited("rt6_redirect: invalid link-layer address length\n");
    1819                 :            :                         return;
    1820                 :            :                 }
    1821                 :            :         }
    1822                 :            : 
    1823                 :            :         rt = (struct rt6_info *) dst;
    1824         [ #  # ]:          0 :         if (rt == net->ipv6.ip6_null_entry) {
    1825                 :          0 :                 net_dbg_ratelimited("rt6_redirect: source isn't a valid nexthop for redirect target\n");
    1826                 :            :                 return;
    1827                 :            :         }
    1828                 :            : 
    1829                 :            :         /* Redirect received -> path was valid.
    1830                 :            :          * Look, redirects are sent only in response to data packets,
    1831                 :            :          * so that this nexthop apparently is reachable. --ANK
    1832                 :            :          */
    1833                 :            :         dst_confirm(&rt->dst);
    1834                 :            : 
    1835                 :          0 :         neigh = __neigh_lookup(&nd_tbl, &msg->target, skb->dev, 1);
    1836         [ #  # ]:          0 :         if (!neigh)
    1837                 :            :                 return;
    1838                 :            : 
    1839                 :            :         /*
    1840                 :            :          *      We have finally decided to accept it.
    1841                 :            :          */
    1842                 :            : 
    1843         [ #  # ]:          0 :         neigh_update(neigh, lladdr, NUD_STALE,
    1844                 :            :                      NEIGH_UPDATE_F_WEAK_OVERRIDE|
    1845                 :            :                      NEIGH_UPDATE_F_OVERRIDE|
    1846                 :            :                      (on_link ? 0 : (NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
    1847                 :            :                                      NEIGH_UPDATE_F_ISROUTER))
    1848                 :            :                      );
    1849                 :            : 
    1850                 :          0 :         nrt = ip6_rt_copy(rt, &msg->dest);
    1851         [ #  # ]:          0 :         if (!nrt)
    1852                 :            :                 goto out;
    1853                 :            : 
    1854                 :          0 :         nrt->rt6i_flags = RTF_GATEWAY|RTF_UP|RTF_DYNAMIC|RTF_CACHE;
    1855         [ #  # ]:          0 :         if (on_link)
    1856                 :          0 :                 nrt->rt6i_flags &= ~RTF_GATEWAY;
    1857                 :            : 
    1858                 :          0 :         nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key;
    1859                 :            : 
    1860         [ #  # ]:          0 :         if (ip6_ins_rt(nrt))
    1861                 :            :                 goto out;
    1862                 :            : 
    1863                 :          0 :         netevent.old = &rt->dst;
    1864                 :          0 :         netevent.new = &nrt->dst;
    1865                 :          0 :         netevent.daddr = &msg->dest;
    1866                 :          0 :         netevent.neigh = neigh;
    1867                 :          0 :         call_netevent_notifiers(NETEVENT_REDIRECT, &netevent);
    1868                 :            : 
    1869         [ #  # ]:          0 :         if (rt->rt6i_flags & RTF_CACHE) {
    1870                 :            :                 rt = (struct rt6_info *) dst_clone(&rt->dst);
    1871                 :          0 :                 ip6_del_rt(rt);
    1872                 :            :         }
    1873                 :            : 
    1874                 :            : out:
    1875                 :            :         neigh_release(neigh);
    1876                 :            : }
    1877                 :            : 
    1878                 :            : /*
    1879                 :            :  *      Misc support functions
    1880                 :            :  */
    1881                 :            : 
    1882                 :          0 : static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,
    1883                 :            :                                     const struct in6_addr *dest)
    1884                 :            : {
    1885                 :            :         struct net *net = dev_net(ort->dst.dev);
    1886                 :        105 :         struct rt6_info *rt = ip6_dst_alloc(net, ort->dst.dev, 0,
    1887                 :            :                                             ort->rt6i_table);
    1888                 :            : 
    1889         [ +  - ]:        105 :         if (rt) {
    1890                 :        105 :                 rt->dst.input = ort->dst.input;
    1891                 :        105 :                 rt->dst.output = ort->dst.output;
    1892                 :        105 :                 rt->dst.flags |= DST_HOST;
    1893                 :            : 
    1894                 :        105 :                 rt->rt6i_dst.addr = *dest;
    1895                 :        105 :                 rt->rt6i_dst.plen = 128;
    1896                 :        105 :                 dst_copy_metrics(&rt->dst, &ort->dst);
    1897                 :        105 :                 rt->dst.error = ort->dst.error;
    1898                 :        105 :                 rt->rt6i_idev = ort->rt6i_idev;
    1899         [ +  - ]:        105 :                 if (rt->rt6i_idev)
    1900                 :            :                         in6_dev_hold(rt->rt6i_idev);
    1901                 :        105 :                 rt->dst.lastuse = jiffies;
    1902                 :            : 
    1903         [ -  + ]:        105 :                 if (ort->rt6i_flags & RTF_GATEWAY)
    1904                 :          0 :                         rt->rt6i_gateway = ort->rt6i_gateway;
    1905                 :            :                 else
    1906                 :        105 :                         rt->rt6i_gateway = *dest;
    1907                 :        105 :                 rt->rt6i_flags = ort->rt6i_flags;
    1908                 :            :                 rt6_set_from(rt, ort);
    1909                 :        105 :                 rt->rt6i_metric = 0;
    1910                 :            : 
    1911                 :            : #ifdef CONFIG_IPV6_SUBTREES
    1912                 :            :                 memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key));
    1913                 :            : #endif
    1914                 :        105 :                 memcpy(&rt->rt6i_prefsrc, &ort->rt6i_prefsrc, sizeof(struct rt6key));
    1915                 :        105 :                 rt->rt6i_table = ort->rt6i_table;
    1916                 :            :         }
    1917                 :        105 :         return rt;
    1918                 :            : }
    1919                 :            : 
    1920                 :            : #ifdef CONFIG_IPV6_ROUTE_INFO
    1921                 :            : static struct rt6_info *rt6_get_route_info(struct net *net,
    1922                 :            :                                            const struct in6_addr *prefix, int prefixlen,
    1923                 :            :                                            const struct in6_addr *gwaddr, int ifindex)
    1924                 :            : {
    1925                 :            :         struct fib6_node *fn;
    1926                 :            :         struct rt6_info *rt = NULL;
    1927                 :            :         struct fib6_table *table;
    1928                 :            : 
    1929                 :            :         table = fib6_get_table(net, RT6_TABLE_INFO);
    1930                 :            :         if (!table)
    1931                 :            :                 return NULL;
    1932                 :            : 
    1933                 :            :         read_lock_bh(&table->tb6_lock);
    1934                 :            :         fn = fib6_locate(&table->tb6_root, prefix ,prefixlen, NULL, 0);
    1935                 :            :         if (!fn)
    1936                 :            :                 goto out;
    1937                 :            : 
    1938                 :            :         for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
    1939                 :            :                 if (rt->dst.dev->ifindex != ifindex)
    1940                 :            :                         continue;
    1941                 :            :                 if ((rt->rt6i_flags & (RTF_ROUTEINFO|RTF_GATEWAY)) != (RTF_ROUTEINFO|RTF_GATEWAY))
    1942                 :            :                         continue;
    1943                 :            :                 if (!ipv6_addr_equal(&rt->rt6i_gateway, gwaddr))
    1944                 :            :                         continue;
    1945                 :            :                 dst_hold(&rt->dst);
    1946                 :            :                 break;
    1947                 :            :         }
    1948                 :            : out:
    1949                 :            :         read_unlock_bh(&table->tb6_lock);
    1950                 :            :         return rt;
    1951                 :            : }
    1952                 :            : 
    1953                 :            : static struct rt6_info *rt6_add_route_info(struct net *net,
    1954                 :            :                                            const struct in6_addr *prefix, int prefixlen,
    1955                 :            :                                            const struct in6_addr *gwaddr, int ifindex,
    1956                 :            :                                            unsigned int pref)
    1957                 :            : {
    1958                 :            :         struct fib6_config cfg = {
    1959                 :            :                 .fc_table       = RT6_TABLE_INFO,
    1960                 :            :                 .fc_metric      = IP6_RT_PRIO_USER,
    1961                 :            :                 .fc_ifindex     = ifindex,
    1962                 :            :                 .fc_dst_len     = prefixlen,
    1963                 :            :                 .fc_flags       = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
    1964                 :            :                                   RTF_UP | RTF_PREF(pref),
    1965                 :            :                 .fc_nlinfo.portid = 0,
    1966                 :            :                 .fc_nlinfo.nlh = NULL,
    1967                 :            :                 .fc_nlinfo.nl_net = net,
    1968                 :            :         };
    1969                 :            : 
    1970                 :            :         cfg.fc_dst = *prefix;
    1971                 :            :         cfg.fc_gateway = *gwaddr;
    1972                 :            : 
    1973                 :            :         /* We should treat it as a default route if prefix length is 0. */
    1974                 :            :         if (!prefixlen)
    1975                 :            :                 cfg.fc_flags |= RTF_DEFAULT;
    1976                 :            : 
    1977                 :            :         ip6_route_add(&cfg);
    1978                 :            : 
    1979                 :            :         return rt6_get_route_info(net, prefix, prefixlen, gwaddr, ifindex);
    1980                 :            : }
    1981                 :            : #endif
    1982                 :            : 
    1983                 :          0 : struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_device *dev)
    1984                 :            : {
    1985                 :            :         struct rt6_info *rt;
    1986                 :            :         struct fib6_table *table;
    1987                 :            : 
    1988                 :          0 :         table = fib6_get_table(dev_net(dev), RT6_TABLE_DFLT);
    1989         [ #  # ]:          0 :         if (!table)
    1990                 :            :                 return NULL;
    1991                 :            : 
    1992                 :          0 :         read_lock_bh(&table->tb6_lock);
    1993         [ #  # ]:          0 :         for (rt = table->tb6_root.leaf; rt; rt=rt->dst.rt6_next) {
    1994 [ #  # ][ #  # ]:          0 :                 if (dev == rt->dst.dev &&
    1995         [ #  # ]:          0 :                     ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) &&
    1996                 :            :                     ipv6_addr_equal(&rt->rt6i_gateway, addr))
    1997                 :            :                         break;
    1998                 :            :         }
    1999         [ #  # ]:          0 :         if (rt)
    2000                 :            :                 dst_hold(&rt->dst);
    2001                 :          0 :         read_unlock_bh(&table->tb6_lock);
    2002                 :          0 :         return rt;
    2003                 :            : }
    2004                 :            : 
    2005                 :          0 : struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr,
    2006                 :            :                                      struct net_device *dev,
    2007                 :            :                                      unsigned int pref)
    2008                 :            : {
    2009                 :          0 :         struct fib6_config cfg = {
    2010                 :            :                 .fc_table       = RT6_TABLE_DFLT,
    2011                 :            :                 .fc_metric      = IP6_RT_PRIO_USER,
    2012                 :          0 :                 .fc_ifindex     = dev->ifindex,
    2013                 :            :                 .fc_flags       = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
    2014                 :          0 :                                   RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
    2015                 :            :                 .fc_nlinfo.portid = 0,
    2016                 :            :                 .fc_nlinfo.nlh = NULL,
    2017                 :            :                 .fc_nlinfo.nl_net = dev_net(dev),
    2018                 :            :         };
    2019                 :            : 
    2020                 :          0 :         cfg.fc_gateway = *gwaddr;
    2021                 :            : 
    2022                 :          0 :         ip6_route_add(&cfg);
    2023                 :            : 
    2024                 :          0 :         return rt6_get_dflt_router(gwaddr, dev);
    2025                 :            : }
    2026                 :            : 
    2027                 :          0 : void rt6_purge_dflt_routers(struct net *net)
    2028                 :            : {
    2029                 :            :         struct rt6_info *rt;
    2030                 :            :         struct fib6_table *table;
    2031                 :            : 
    2032                 :            :         /* NOTE: Keep consistent with rt6_get_dflt_router */
    2033                 :          0 :         table = fib6_get_table(net, RT6_TABLE_DFLT);
    2034         [ #  # ]:          0 :         if (!table)
    2035                 :          0 :                 return;
    2036                 :            : 
    2037                 :            : restart:
    2038                 :          0 :         read_lock_bh(&table->tb6_lock);
    2039         [ #  # ]:          0 :         for (rt = table->tb6_root.leaf; rt; rt = rt->dst.rt6_next) {
    2040 [ #  # ][ #  # ]:          0 :                 if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF) &&
    2041         [ #  # ]:          0 :                     (!rt->rt6i_idev || rt->rt6i_idev->cnf.accept_ra != 2)) {
    2042                 :            :                         dst_hold(&rt->dst);
    2043                 :          0 :                         read_unlock_bh(&table->tb6_lock);
    2044                 :          0 :                         ip6_del_rt(rt);
    2045                 :          0 :                         goto restart;
    2046                 :            :                 }
    2047                 :            :         }
    2048                 :          0 :         read_unlock_bh(&table->tb6_lock);
    2049                 :            : }
    2050                 :            : 
    2051                 :          0 : static void rtmsg_to_fib6_config(struct net *net,
    2052                 :            :                                  struct in6_rtmsg *rtmsg,
    2053                 :            :                                  struct fib6_config *cfg)
    2054                 :            : {
    2055                 :          0 :         memset(cfg, 0, sizeof(*cfg));
    2056                 :            : 
    2057                 :          0 :         cfg->fc_table = RT6_TABLE_MAIN;
    2058                 :          0 :         cfg->fc_ifindex = rtmsg->rtmsg_ifindex;
    2059                 :          0 :         cfg->fc_metric = rtmsg->rtmsg_metric;
    2060                 :          0 :         cfg->fc_expires = rtmsg->rtmsg_info;
    2061                 :          0 :         cfg->fc_dst_len = rtmsg->rtmsg_dst_len;
    2062                 :          0 :         cfg->fc_src_len = rtmsg->rtmsg_src_len;
    2063                 :          0 :         cfg->fc_flags = rtmsg->rtmsg_flags;
    2064                 :            : 
    2065                 :          0 :         cfg->fc_nlinfo.nl_net = net;
    2066                 :            : 
    2067                 :          0 :         cfg->fc_dst = rtmsg->rtmsg_dst;
    2068                 :          0 :         cfg->fc_src = rtmsg->rtmsg_src;
    2069                 :          0 :         cfg->fc_gateway = rtmsg->rtmsg_gateway;
    2070                 :          0 : }
    2071                 :            : 
    2072                 :          0 : int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg)
    2073                 :            : {
    2074                 :            :         struct fib6_config cfg;
    2075                 :            :         struct in6_rtmsg rtmsg;
    2076                 :            :         int err;
    2077                 :            : 
    2078         [ #  # ]:          0 :         switch(cmd) {
    2079                 :            :         case SIOCADDRT:         /* Add a route */
    2080                 :            :         case SIOCDELRT:         /* Delete a route */
    2081         [ #  # ]:          0 :                 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
    2082                 :            :                         return -EPERM;
    2083                 :            :                 err = copy_from_user(&rtmsg, arg,
    2084                 :            :                                      sizeof(struct in6_rtmsg));
    2085         [ #  # ]:          0 :                 if (err)
    2086                 :            :                         return -EFAULT;
    2087                 :            : 
    2088                 :          0 :                 rtmsg_to_fib6_config(net, &rtmsg, &cfg);
    2089                 :            : 
    2090                 :          0 :                 rtnl_lock();
    2091      [ #  #  # ]:          0 :                 switch (cmd) {
    2092                 :            :                 case SIOCADDRT:
    2093                 :          0 :                         err = ip6_route_add(&cfg);
    2094                 :          0 :                         break;
    2095                 :            :                 case SIOCDELRT:
    2096                 :          0 :                         err = ip6_route_del(&cfg);
    2097                 :          0 :                         break;
    2098                 :            :                 default:
    2099                 :            :                         err = -EINVAL;
    2100                 :            :                 }
    2101                 :          0 :                 rtnl_unlock();
    2102                 :            : 
    2103                 :          0 :                 return err;
    2104                 :            :         }
    2105                 :            : 
    2106                 :            :         return -EINVAL;
    2107                 :            : }
    2108                 :            : 
    2109                 :            : /*
    2110                 :            :  *      Drop the packet on the floor
    2111                 :            :  */
    2112                 :            : 
    2113                 :          0 : static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes)
    2114                 :            : {
    2115                 :            :         int type;
    2116                 :            :         struct dst_entry *dst = skb_dst(skb);
    2117      [ #  #  # ]:          0 :         switch (ipstats_mib_noroutes) {
    2118                 :            :         case IPSTATS_MIB_INNOROUTES:
    2119                 :          0 :                 type = ipv6_addr_type(&ipv6_hdr(skb)->daddr);
    2120         [ #  # ]:          0 :                 if (type == IPV6_ADDR_ANY) {
    2121         [ #  # ]:          0 :                         IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst),
    2122                 :            :                                       IPSTATS_MIB_INADDRERRORS);
    2123                 :          0 :                         break;
    2124                 :            :                 }
    2125                 :            :                 /* FALLTHROUGH */
    2126                 :            :         case IPSTATS_MIB_OUTNOROUTES:
    2127         [ #  # ]:          0 :                 IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst),
    2128                 :            :                               ipstats_mib_noroutes);
    2129                 :          0 :                 break;
    2130                 :            :         }
    2131                 :          0 :         icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0);
    2132                 :          0 :         kfree_skb(skb);
    2133                 :          0 :         return 0;
    2134                 :            : }
    2135                 :            : 
    2136                 :          0 : static int ip6_pkt_discard(struct sk_buff *skb)
    2137                 :            : {
    2138                 :          0 :         return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES);
    2139                 :            : }
    2140                 :            : 
    2141                 :          0 : static int ip6_pkt_discard_out(struct sk_buff *skb)
    2142                 :            : {
    2143                 :          0 :         skb->dev = skb_dst(skb)->dev;
    2144                 :          0 :         return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES);
    2145                 :            : }
    2146                 :            : 
    2147                 :          0 : static int ip6_pkt_prohibit(struct sk_buff *skb)
    2148                 :            : {
    2149                 :          0 :         return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES);
    2150                 :            : }
    2151                 :            : 
    2152                 :          0 : static int ip6_pkt_prohibit_out(struct sk_buff *skb)
    2153                 :            : {
    2154                 :          0 :         skb->dev = skb_dst(skb)->dev;
    2155                 :          0 :         return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
    2156                 :            : }
    2157                 :            : 
    2158                 :            : /*
    2159                 :            :  *      Allocate a dst for local (unicast / anycast) address.
    2160                 :            :  */
    2161                 :            : 
    2162                 :          0 : struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
    2163                 :            :                                     const struct in6_addr *addr,
    2164                 :            :                                     bool anycast)
    2165                 :            : {
    2166                 :            :         struct net *net = dev_net(idev->dev);
    2167                 :          0 :         struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev,
    2168                 :            :                                             DST_NOCOUNT, NULL);
    2169         [ #  # ]:          0 :         if (!rt)
    2170                 :            :                 return ERR_PTR(-ENOMEM);
    2171                 :            : 
    2172                 :            :         in6_dev_hold(idev);
    2173                 :            : 
    2174                 :          0 :         rt->dst.flags |= DST_HOST;
    2175                 :          0 :         rt->dst.input = ip6_input;
    2176                 :          0 :         rt->dst.output = ip6_output;
    2177                 :          0 :         rt->rt6i_idev = idev;
    2178                 :            : 
    2179                 :          0 :         rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
    2180         [ #  # ]:          0 :         if (anycast)
    2181                 :          0 :                 rt->rt6i_flags |= RTF_ANYCAST;
    2182                 :            :         else
    2183                 :          0 :                 rt->rt6i_flags |= RTF_LOCAL;
    2184                 :            : 
    2185                 :          0 :         rt->rt6i_gateway  = *addr;
    2186                 :          0 :         rt->rt6i_dst.addr = *addr;
    2187                 :          0 :         rt->rt6i_dst.plen = 128;
    2188                 :          0 :         rt->rt6i_table = fib6_get_table(net, RT6_TABLE_LOCAL);
    2189                 :            : 
    2190                 :          0 :         atomic_set(&rt->dst.__refcnt, 1);
    2191                 :            : 
    2192                 :          0 :         return rt;
    2193                 :            : }
    2194                 :            : 
    2195                 :          0 : int ip6_route_get_saddr(struct net *net,
    2196                 :            :                         struct rt6_info *rt,
    2197                 :            :                         const struct in6_addr *daddr,
    2198                 :            :                         unsigned int prefs,
    2199                 :            :                         struct in6_addr *saddr)
    2200                 :            : {
    2201                 :            :         struct inet6_dev *idev = ip6_dst_idev((struct dst_entry*)rt);
    2202                 :            :         int err = 0;
    2203         [ -  + ]:          3 :         if (rt->rt6i_prefsrc.plen)
    2204                 :          0 :                 *saddr = rt->rt6i_prefsrc.addr;
    2205                 :            :         else
    2206         [ +  - ]:          3 :                 err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
    2207                 :            :                                          daddr, prefs, saddr);
    2208                 :          3 :         return err;
    2209                 :            : }
    2210                 :            : 
    2211                 :            : /* remove deleted ip from prefsrc entries */
    2212                 :            : struct arg_dev_net_ip {
    2213                 :            :         struct net_device *dev;
    2214                 :            :         struct net *net;
    2215                 :            :         struct in6_addr *addr;
    2216                 :            : };
    2217                 :            : 
    2218                 :          0 : static int fib6_remove_prefsrc(struct rt6_info *rt, void *arg)
    2219                 :            : {
    2220                 :          0 :         struct net_device *dev = ((struct arg_dev_net_ip *)arg)->dev;
    2221                 :          0 :         struct net *net = ((struct arg_dev_net_ip *)arg)->net;
    2222                 :          0 :         struct in6_addr *addr = ((struct arg_dev_net_ip *)arg)->addr;
    2223                 :            : 
    2224 [ #  # ][ #  # ]:          0 :         if (((void *)rt->dst.dev == dev || !dev) &&
                 [ #  # ]
    2225         [ #  # ]:          0 :             rt != net->ipv6.ip6_null_entry &&
    2226                 :            :             ipv6_addr_equal(addr, &rt->rt6i_prefsrc.addr)) {
    2227                 :            :                 /* remove prefsrc entry */
    2228                 :          0 :                 rt->rt6i_prefsrc.plen = 0;
    2229                 :            :         }
    2230                 :          0 :         return 0;
    2231                 :            : }
    2232                 :            : 
    2233                 :          0 : void rt6_remove_prefsrc(struct inet6_ifaddr *ifp)
    2234                 :            : {
    2235                 :            :         struct net *net = dev_net(ifp->idev->dev);
    2236                 :          0 :         struct arg_dev_net_ip adni = {
    2237                 :          0 :                 .dev = ifp->idev->dev,
    2238                 :            :                 .net = net,
    2239                 :          0 :                 .addr = &ifp->addr,
    2240                 :            :         };
    2241                 :          0 :         fib6_clean_all(net, fib6_remove_prefsrc, 0, &adni);
    2242                 :          0 : }
    2243                 :            : 
    2244                 :            : struct arg_dev_net {
    2245                 :            :         struct net_device *dev;
    2246                 :            :         struct net *net;
    2247                 :            : };
    2248                 :            : 
    2249                 :          0 : static int fib6_ifdown(struct rt6_info *rt, void *arg)
    2250                 :            : {
    2251                 :            :         const struct arg_dev_net *adn = arg;
    2252                 :          0 :         const struct net_device *dev = adn->dev;
    2253                 :            : 
    2254 [ #  # ][ #  # ]:          0 :         if ((rt->dst.dev == dev || !dev) &&
                 [ #  # ]
    2255                 :          0 :             rt != adn->net->ipv6.ip6_null_entry)
    2256                 :            :                 return -1;
    2257                 :            : 
    2258                 :          0 :         return 0;
    2259                 :            : }
    2260                 :            : 
    2261                 :          0 : void rt6_ifdown(struct net *net, struct net_device *dev)
    2262                 :            : {
    2263                 :          0 :         struct arg_dev_net adn = {
    2264                 :            :                 .dev = dev,
    2265                 :            :                 .net = net,
    2266                 :            :         };
    2267                 :            : 
    2268                 :          0 :         fib6_clean_all(net, fib6_ifdown, 0, &adn);
    2269                 :          0 :         icmp6_clean_all(fib6_ifdown, &adn);
    2270                 :          0 : }
    2271                 :            : 
    2272                 :            : struct rt6_mtu_change_arg {
    2273                 :            :         struct net_device *dev;
    2274                 :            :         unsigned int mtu;
    2275                 :            : };
    2276                 :            : 
    2277                 :          0 : static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
    2278                 :            : {
    2279                 :            :         struct rt6_mtu_change_arg *arg = (struct rt6_mtu_change_arg *) p_arg;
    2280                 :            :         struct inet6_dev *idev;
    2281                 :            : 
    2282                 :            :         /* In IPv6 pmtu discovery is not optional,
    2283                 :            :            so that RTAX_MTU lock cannot disable it.
    2284                 :            :            We still use this lock to block changes
    2285                 :            :            caused by addrconf/ndisc.
    2286                 :            :         */
    2287                 :            : 
    2288                 :          0 :         idev = __in6_dev_get(arg->dev);
    2289         [ #  # ]:          0 :         if (!idev)
    2290                 :            :                 return 0;
    2291                 :            : 
    2292                 :            :         /* For administrative MTU increase, there is no way to discover
    2293                 :            :            IPv6 PMTU increase, so PMTU increase should be updated here.
    2294                 :            :            Since RFC 1981 doesn't include administrative MTU increase
    2295                 :            :            update PMTU increase is a MUST. (i.e. jumbo frame)
    2296                 :            :          */
    2297                 :            :         /*
    2298                 :            :            If new MTU is less than route PMTU, this new MTU will be the
    2299                 :            :            lowest MTU in the path, update the route PMTU to reflect PMTU
    2300                 :            :            decreases; if new MTU is greater than route PMTU, and the
    2301                 :            :            old MTU is the lowest MTU in the path, update the route PMTU
    2302                 :            :            to reflect the increase. In this case if the other nodes' MTU
    2303                 :            :            also have the lowest MTU, TOO BIG MESSAGE will be lead to
    2304                 :            :            PMTU discouvery.
    2305                 :            :          */
    2306 [ #  # ][ #  # ]:          0 :         if (rt->dst.dev == arg->dev &&
    2307         [ #  # ]:          0 :             !dst_metric_locked(&rt->dst, RTAX_MTU) &&
    2308         [ #  # ]:          0 :             (dst_mtu(&rt->dst) >= arg->mtu ||
    2309         [ #  # ]:          0 :              (dst_mtu(&rt->dst) < arg->mtu &&
    2310                 :          0 :               dst_mtu(&rt->dst) == idev->cnf.mtu6))) {
    2311                 :          0 :                 dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu);
    2312                 :            :         }
    2313                 :            :         return 0;
    2314                 :            : }
    2315                 :            : 
    2316                 :          0 : void rt6_mtu_change(struct net_device *dev, unsigned int mtu)
    2317                 :            : {
    2318                 :          0 :         struct rt6_mtu_change_arg arg = {
    2319                 :            :                 .dev = dev,
    2320                 :            :                 .mtu = mtu,
    2321                 :            :         };
    2322                 :            : 
    2323                 :          0 :         fib6_clean_all(dev_net(dev), rt6_mtu_change_route, 0, &arg);
    2324                 :          0 : }
    2325                 :            : 
    2326                 :            : static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
    2327                 :            :         [RTA_GATEWAY]           = { .len = sizeof(struct in6_addr) },
    2328                 :            :         [RTA_OIF]               = { .type = NLA_U32 },
    2329                 :            :         [RTA_IIF]               = { .type = NLA_U32 },
    2330                 :            :         [RTA_PRIORITY]          = { .type = NLA_U32 },
    2331                 :            :         [RTA_METRICS]           = { .type = NLA_NESTED },
    2332                 :            :         [RTA_MULTIPATH]         = { .len = sizeof(struct rtnexthop) },
    2333                 :            : };
    2334                 :            : 
    2335                 :          0 : static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
    2336                 :            :                               struct fib6_config *cfg)
    2337                 :            : {
    2338                 :            :         struct rtmsg *rtm;
    2339                 :            :         struct nlattr *tb[RTA_MAX+1];
    2340                 :            :         int err;
    2341                 :            : 
    2342                 :            :         err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
    2343         [ #  # ]:          0 :         if (err < 0)
    2344                 :            :                 goto errout;
    2345                 :            : 
    2346                 :            :         err = -EINVAL;
    2347                 :            :         rtm = nlmsg_data(nlh);
    2348                 :          0 :         memset(cfg, 0, sizeof(*cfg));
    2349                 :            : 
    2350                 :          0 :         cfg->fc_table = rtm->rtm_table;
    2351                 :          0 :         cfg->fc_dst_len = rtm->rtm_dst_len;
    2352                 :          0 :         cfg->fc_src_len = rtm->rtm_src_len;
    2353                 :          0 :         cfg->fc_flags = RTF_UP;
    2354                 :          0 :         cfg->fc_protocol = rtm->rtm_protocol;
    2355                 :          0 :         cfg->fc_type = rtm->rtm_type;
    2356                 :            : 
    2357         [ #  # ]:          0 :         if (rtm->rtm_type == RTN_UNREACHABLE ||
    2358                 :            :             rtm->rtm_type == RTN_BLACKHOLE ||
    2359                 :          0 :             rtm->rtm_type == RTN_PROHIBIT ||
    2360                 :            :             rtm->rtm_type == RTN_THROW)
    2361                 :          0 :                 cfg->fc_flags |= RTF_REJECT;
    2362                 :            : 
    2363         [ #  # ]:          0 :         if (rtm->rtm_type == RTN_LOCAL)
    2364                 :          0 :                 cfg->fc_flags |= RTF_LOCAL;
    2365                 :            : 
    2366                 :          0 :         cfg->fc_nlinfo.portid = NETLINK_CB(skb).portid;
    2367                 :          0 :         cfg->fc_nlinfo.nlh = nlh;
    2368                 :          0 :         cfg->fc_nlinfo.nl_net = sock_net(skb->sk);
    2369                 :            : 
    2370         [ #  # ]:          0 :         if (tb[RTA_GATEWAY]) {
    2371                 :          0 :                 nla_memcpy(&cfg->fc_gateway, tb[RTA_GATEWAY], 16);
    2372                 :          0 :                 cfg->fc_flags |= RTF_GATEWAY;
    2373                 :            :         }
    2374                 :            : 
    2375         [ #  # ]:          0 :         if (tb[RTA_DST]) {
    2376                 :          0 :                 int plen = (rtm->rtm_dst_len + 7) >> 3;
    2377                 :            : 
    2378         [ #  # ]:          0 :                 if (nla_len(tb[RTA_DST]) < plen)
    2379                 :            :                         goto errout;
    2380                 :            : 
    2381                 :          0 :                 nla_memcpy(&cfg->fc_dst, tb[RTA_DST], plen);
    2382                 :            :         }
    2383                 :            : 
    2384         [ #  # ]:          0 :         if (tb[RTA_SRC]) {
    2385                 :          0 :                 int plen = (rtm->rtm_src_len + 7) >> 3;
    2386                 :            : 
    2387         [ #  # ]:          0 :                 if (nla_len(tb[RTA_SRC]) < plen)
    2388                 :            :                         goto errout;
    2389                 :            : 
    2390                 :          0 :                 nla_memcpy(&cfg->fc_src, tb[RTA_SRC], plen);
    2391                 :            :         }
    2392                 :            : 
    2393         [ #  # ]:          0 :         if (tb[RTA_PREFSRC])
    2394                 :          0 :                 nla_memcpy(&cfg->fc_prefsrc, tb[RTA_PREFSRC], 16);
    2395                 :            : 
    2396         [ #  # ]:          0 :         if (tb[RTA_OIF])
    2397                 :          0 :                 cfg->fc_ifindex = nla_get_u32(tb[RTA_OIF]);
    2398                 :            : 
    2399         [ #  # ]:          0 :         if (tb[RTA_PRIORITY])
    2400                 :          0 :                 cfg->fc_metric = nla_get_u32(tb[RTA_PRIORITY]);
    2401                 :            : 
    2402         [ #  # ]:          0 :         if (tb[RTA_METRICS]) {
    2403                 :          0 :                 cfg->fc_mx = nla_data(tb[RTA_METRICS]);
    2404                 :          0 :                 cfg->fc_mx_len = nla_len(tb[RTA_METRICS]);
    2405                 :            :         }
    2406                 :            : 
    2407         [ #  # ]:          0 :         if (tb[RTA_TABLE])
    2408                 :          0 :                 cfg->fc_table = nla_get_u32(tb[RTA_TABLE]);
    2409                 :            : 
    2410         [ #  # ]:          0 :         if (tb[RTA_MULTIPATH]) {
    2411                 :          0 :                 cfg->fc_mp = nla_data(tb[RTA_MULTIPATH]);
    2412                 :          0 :                 cfg->fc_mp_len = nla_len(tb[RTA_MULTIPATH]);
    2413                 :            :         }
    2414                 :            : 
    2415                 :            :         err = 0;
    2416                 :            : errout:
    2417                 :          0 :         return err;
    2418                 :            : }
    2419                 :            : 
    2420                 :          0 : static int ip6_route_multipath(struct fib6_config *cfg, int add)
    2421                 :            : {
    2422                 :            :         struct fib6_config r_cfg;
    2423                 :          0 :         struct rtnexthop *rtnh;
    2424                 :            :         int remaining;
    2425                 :            :         int attrlen;
    2426                 :            :         int err = 0, last_err = 0;
    2427                 :            : 
    2428                 :            : beginning:
    2429                 :          0 :         rtnh = (struct rtnexthop *)cfg->fc_mp;
    2430                 :          0 :         remaining = cfg->fc_mp_len;
    2431                 :            : 
    2432                 :            :         /* Parse a Multipath Entry */
    2433         [ #  # ]:          0 :         while (rtnh_ok(rtnh, remaining)) {
    2434                 :          0 :                 memcpy(&r_cfg, cfg, sizeof(*cfg));
    2435         [ #  # ]:          0 :                 if (rtnh->rtnh_ifindex)
    2436                 :          0 :                         r_cfg.fc_ifindex = rtnh->rtnh_ifindex;
    2437                 :            : 
    2438                 :            :                 attrlen = rtnh_attrlen(rtnh);
    2439         [ #  # ]:          0 :                 if (attrlen > 0) {
    2440                 :          0 :                         struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
    2441                 :            : 
    2442                 :          0 :                         nla = nla_find(attrs, attrlen, RTA_GATEWAY);
    2443         [ #  # ]:          0 :                         if (nla) {
    2444                 :          0 :                                 nla_memcpy(&r_cfg.fc_gateway, nla, 16);
    2445                 :          0 :                                 r_cfg.fc_flags |= RTF_GATEWAY;
    2446                 :            :                         }
    2447                 :            :                 }
    2448         [ #  # ]:          0 :                 err = add ? ip6_route_add(&r_cfg) : ip6_route_del(&r_cfg);
    2449         [ #  # ]:          0 :                 if (err) {
    2450                 :            :                         last_err = err;
    2451                 :            :                         /* If we are trying to remove a route, do not stop the
    2452                 :            :                          * loop when ip6_route_del() fails (because next hop is
    2453                 :            :                          * already gone), we should try to remove all next hops.
    2454                 :            :                          */
    2455         [ #  # ]:          0 :                         if (add) {
    2456                 :            :                                 /* If add fails, we should try to delete all
    2457                 :            :                                  * next hops that have been already added.
    2458                 :            :                                  */
    2459                 :            :                                 add = 0;
    2460                 :            :                                 goto beginning;
    2461                 :            :                         }
    2462                 :            :                 }
    2463                 :            :                 /* Because each route is added like a single route we remove
    2464                 :            :                  * this flag after the first nexthop (if there is a collision,
    2465                 :            :                  * we have already fail to add the first nexthop:
    2466                 :            :                  * fib6_add_rt2node() has reject it).
    2467                 :            :                  */
    2468                 :          0 :                 cfg->fc_nlinfo.nlh->nlmsg_flags &= ~NLM_F_EXCL;
    2469                 :            :                 rtnh = rtnh_next(rtnh, &remaining);
    2470                 :            :         }
    2471                 :            : 
    2472                 :          0 :         return last_err;
    2473                 :            : }
    2474                 :            : 
    2475                 :          0 : static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh)
    2476                 :            : {
    2477                 :            :         struct fib6_config cfg;
    2478                 :            :         int err;
    2479                 :            : 
    2480                 :          0 :         err = rtm_to_fib6_config(skb, nlh, &cfg);
    2481         [ #  # ]:          0 :         if (err < 0)
    2482                 :            :                 return err;
    2483                 :            : 
    2484         [ #  # ]:          0 :         if (cfg.fc_mp)
    2485                 :          0 :                 return ip6_route_multipath(&cfg, 0);
    2486                 :            :         else
    2487                 :          0 :                 return ip6_route_del(&cfg);
    2488                 :            : }
    2489                 :            : 
    2490                 :          0 : static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh)
    2491                 :            : {
    2492                 :            :         struct fib6_config cfg;
    2493                 :            :         int err;
    2494                 :            : 
    2495                 :          0 :         err = rtm_to_fib6_config(skb, nlh, &cfg);
    2496         [ #  # ]:          0 :         if (err < 0)
    2497                 :            :                 return err;
    2498                 :            : 
    2499         [ #  # ]:          0 :         if (cfg.fc_mp)
    2500                 :          0 :                 return ip6_route_multipath(&cfg, 1);
    2501                 :            :         else
    2502                 :          0 :                 return ip6_route_add(&cfg);
    2503                 :            : }
    2504                 :            : 
    2505                 :            : static inline size_t rt6_nlmsg_size(void)
    2506                 :            : {
    2507                 :            :         return NLMSG_ALIGN(sizeof(struct rtmsg))
    2508                 :            :                + nla_total_size(16) /* RTA_SRC */
    2509                 :            :                + nla_total_size(16) /* RTA_DST */
    2510                 :            :                + nla_total_size(16) /* RTA_GATEWAY */
    2511                 :            :                + nla_total_size(16) /* RTA_PREFSRC */
    2512                 :            :                + nla_total_size(4) /* RTA_TABLE */
    2513                 :            :                + nla_total_size(4) /* RTA_IIF */
    2514                 :            :                + nla_total_size(4) /* RTA_OIF */
    2515                 :            :                + nla_total_size(4) /* RTA_PRIORITY */
    2516                 :            :                + RTAX_MAX * nla_total_size(4) /* RTA_METRICS */
    2517                 :            :                + nla_total_size(sizeof(struct rta_cacheinfo));
    2518                 :            : }
    2519                 :            : 
    2520                 :          0 : static int rt6_fill_node(struct net *net,
    2521                 :            :                          struct sk_buff *skb, struct rt6_info *rt,
    2522                 :            :                          struct in6_addr *dst, struct in6_addr *src,
    2523                 :            :                          int iif, int type, u32 portid, u32 seq,
    2524                 :            :                          int prefix, int nowait, unsigned int flags)
    2525                 :            : {
    2526                 :            :         struct rtmsg *rtm;
    2527                 :            :         struct nlmsghdr *nlh;
    2528                 :            :         long expires;
    2529                 :            :         u32 table;
    2530                 :            : 
    2531         [ -  + ]:        210 :         if (prefix) {   /* user wants prefix routes only */
    2532         [ #  # ]:          0 :                 if (!(rt->rt6i_flags & RTF_PREFIX_RT)) {
    2533                 :            :                         /* success since this is not a prefix route */
    2534                 :            :                         return 1;
    2535                 :            :                 }
    2536                 :            :         }
    2537                 :            : 
    2538                 :        210 :         nlh = nlmsg_put(skb, portid, seq, type, sizeof(*rtm), flags);
    2539         [ +  - ]:        210 :         if (!nlh)
    2540                 :            :                 return -EMSGSIZE;
    2541                 :            : 
    2542                 :            :         rtm = nlmsg_data(nlh);
    2543                 :        210 :         rtm->rtm_family = AF_INET6;
    2544                 :        210 :         rtm->rtm_dst_len = rt->rt6i_dst.plen;
    2545                 :        210 :         rtm->rtm_src_len = rt->rt6i_src.plen;
    2546                 :        210 :         rtm->rtm_tos = 0;
    2547         [ +  - ]:        210 :         if (rt->rt6i_table)
    2548                 :        210 :                 table = rt->rt6i_table->tb6_id;
    2549                 :            :         else
    2550                 :            :                 table = RT6_TABLE_UNSPEC;
    2551                 :        210 :         rtm->rtm_table = table;
    2552            [ + ]:        210 :         if (nla_put_u32(skb, RTA_TABLE, table))
    2553                 :            :                 goto nla_put_failure;
    2554         [ -  + ]:        420 :         if (rt->rt6i_flags & RTF_REJECT) {
    2555   [ #  #  #  # ]:          0 :                 switch (rt->dst.error) {
    2556                 :            :                 case -EINVAL:
    2557                 :          0 :                         rtm->rtm_type = RTN_BLACKHOLE;
    2558                 :            :                         break;
    2559                 :            :                 case -EACCES:
    2560                 :          0 :                         rtm->rtm_type = RTN_PROHIBIT;
    2561                 :            :                         break;
    2562                 :            :                 case -EAGAIN:
    2563                 :          0 :                         rtm->rtm_type = RTN_THROW;
    2564                 :            :                         break;
    2565                 :            :                 default:
    2566                 :          0 :                         rtm->rtm_type = RTN_UNREACHABLE;
    2567                 :            :                         break;
    2568                 :            :                 }
    2569                 :            :         }
    2570         [ -  + ]:        210 :         else if (rt->rt6i_flags & RTF_LOCAL)
    2571                 :          0 :                 rtm->rtm_type = RTN_LOCAL;
    2572 [ +  - ][ -  + ]:        210 :         else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK))
    2573                 :          0 :                 rtm->rtm_type = RTN_LOCAL;
    2574                 :            :         else
    2575                 :        210 :                 rtm->rtm_type = RTN_UNICAST;
    2576                 :        210 :         rtm->rtm_flags = 0;
    2577                 :        210 :         rtm->rtm_scope = RT_SCOPE_UNIVERSE;
    2578                 :        210 :         rtm->rtm_protocol = rt->rt6i_protocol;
    2579         [ -  + ]:        210 :         if (rt->rt6i_flags & RTF_DYNAMIC)
    2580                 :          0 :                 rtm->rtm_protocol = RTPROT_REDIRECT;
    2581         [ -  + ]:        210 :         else if (rt->rt6i_flags & RTF_ADDRCONF) {
    2582         [ #  # ]:          0 :                 if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ROUTEINFO))
    2583                 :          0 :                         rtm->rtm_protocol = RTPROT_RA;
    2584                 :            :                 else
    2585                 :          0 :                         rtm->rtm_protocol = RTPROT_KERNEL;
    2586                 :            :         }
    2587                 :            : 
    2588         [ +  - ]:        210 :         if (rt->rt6i_flags & RTF_CACHE)
    2589                 :        210 :                 rtm->rtm_flags |= RTM_F_CLONED;
    2590                 :            : 
    2591         [ -  + ]:        210 :         if (dst) {
    2592         [ #  # ]:          0 :                 if (nla_put(skb, RTA_DST, 16, dst))
    2593                 :            :                         goto nla_put_failure;
    2594                 :          0 :                 rtm->rtm_dst_len = 128;
    2595         [ +  - ]:        210 :         } else if (rtm->rtm_dst_len)
    2596         [ +  - ]:        210 :                 if (nla_put(skb, RTA_DST, 16, &rt->rt6i_dst.addr))
    2597                 :            :                         goto nla_put_failure;
    2598                 :            : #ifdef CONFIG_IPV6_SUBTREES
    2599                 :            :         if (src) {
    2600                 :            :                 if (nla_put(skb, RTA_SRC, 16, src))
    2601                 :            :                         goto nla_put_failure;
    2602                 :            :                 rtm->rtm_src_len = 128;
    2603                 :            :         } else if (rtm->rtm_src_len &&
    2604                 :            :                    nla_put(skb, RTA_SRC, 16, &rt->rt6i_src.addr))
    2605                 :            :                 goto nla_put_failure;
    2606                 :            : #endif
    2607         [ -  + ]:        210 :         if (iif) {
    2608                 :            : #ifdef CONFIG_IPV6_MROUTE
    2609                 :            :                 if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) {
    2610                 :            :                         int err = ip6mr_get_route(net, skb, rtm, nowait);
    2611                 :            :                         if (err <= 0) {
    2612                 :            :                                 if (!nowait) {
    2613                 :            :                                         if (err == 0)
    2614                 :            :                                                 return 0;
    2615                 :            :                                         goto nla_put_failure;
    2616                 :            :                                 } else {
    2617                 :            :                                         if (err == -EMSGSIZE)
    2618                 :            :                                                 goto nla_put_failure;
    2619                 :            :                                 }
    2620                 :            :                         }
    2621                 :            :                 } else
    2622                 :            : #endif
    2623         [ #  # ]:          0 :                         if (nla_put_u32(skb, RTA_IIF, iif))
    2624                 :            :                                 goto nla_put_failure;
    2625         [ -  + ]:        210 :         } else if (dst) {
    2626                 :            :                 struct in6_addr saddr_buf;
    2627   [ #  #  #  # ]:          0 :                 if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0 &&
    2628                 :          0 :                     nla_put(skb, RTA_PREFSRC, 16, &saddr_buf))
    2629                 :            :                         goto nla_put_failure;
    2630                 :            :         }
    2631                 :            : 
    2632         [ #  # ]:          0 :         if (rt->rt6i_prefsrc.plen) {
    2633                 :            :                 struct in6_addr saddr_buf;
    2634                 :          0 :                 saddr_buf = rt->rt6i_prefsrc.addr;
    2635         [ #  # ]:          0 :                 if (nla_put(skb, RTA_PREFSRC, 16, &saddr_buf))
    2636                 :            :                         goto nla_put_failure;
    2637                 :            :         }
    2638                 :            : 
    2639         [ +  - ]:          0 :         if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
    2640                 :            :                 goto nla_put_failure;
    2641                 :            : 
    2642         [ -  + ]:        210 :         if (rt->rt6i_flags & RTF_GATEWAY) {
    2643         [ #  # ]:          0 :                 if (nla_put(skb, RTA_GATEWAY, 16, &rt->rt6i_gateway) < 0)
    2644                 :            :                         goto nla_put_failure;
    2645                 :            :         }
    2646                 :            : 
    2647   [ +  -  +  - ]:        420 :         if (rt->dst.dev &&
    2648                 :        210 :             nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex))
    2649                 :            :                 goto nla_put_failure;
    2650         [ +  - ]:        210 :         if (nla_put_u32(skb, RTA_PRIORITY, rt->rt6i_metric))
    2651                 :            :                 goto nla_put_failure;
    2652                 :            : 
    2653         [ -  + ]:        210 :         expires = (rt->rt6i_flags & RTF_EXPIRES) ? rt->dst.expires - jiffies : 0;
    2654                 :            : 
    2655         [ +  - ]:        210 :         if (rtnl_put_cacheinfo(skb, &rt->dst, 0, expires, rt->dst.error) < 0)
    2656                 :            :                 goto nla_put_failure;
    2657                 :            : 
    2658                 :            :         return nlmsg_end(skb, nlh);
    2659                 :            : 
    2660                 :            : nla_put_failure:
    2661                 :            :         nlmsg_cancel(skb, nlh);
    2662                 :            :         return -EMSGSIZE;
    2663                 :            : }
    2664                 :            : 
    2665                 :          0 : int rt6_dump_route(struct rt6_info *rt, void *p_arg)
    2666                 :            : {
    2667                 :            :         struct rt6_rtnl_dump_arg *arg = (struct rt6_rtnl_dump_arg *) p_arg;
    2668                 :            :         int prefix;
    2669                 :            : 
    2670         [ #  # ]:          0 :         if (nlmsg_len(arg->cb->nlh) >= sizeof(struct rtmsg)) {
    2671                 :            :                 struct rtmsg *rtm = nlmsg_data(arg->cb->nlh);
    2672                 :          0 :                 prefix = (rtm->rtm_flags & RTM_F_PREFIX) != 0;
    2673                 :            :         } else
    2674                 :            :                 prefix = 0;
    2675                 :            : 
    2676                 :          0 :         return rt6_fill_node(arg->net,
    2677                 :            :                      arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
    2678                 :          0 :                      NETLINK_CB(arg->cb->skb).portid, arg->cb->nlh->nlmsg_seq,
    2679                 :            :                      prefix, 0, NLM_F_MULTI);
    2680                 :            : }
    2681                 :            : 
    2682                 :          0 : static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh)
    2683                 :            : {
    2684                 :            :         struct net *net = sock_net(in_skb->sk);
    2685                 :            :         struct nlattr *tb[RTA_MAX+1];
    2686                 :            :         struct rt6_info *rt;
    2687                 :            :         struct sk_buff *skb;
    2688                 :            :         struct rtmsg *rtm;
    2689                 :            :         struct flowi6 fl6;
    2690                 :            :         int err, iif = 0, oif = 0;
    2691                 :            : 
    2692                 :            :         err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
    2693         [ #  # ]:          0 :         if (err < 0)
    2694                 :            :                 goto errout;
    2695                 :            : 
    2696                 :            :         err = -EINVAL;
    2697                 :          0 :         memset(&fl6, 0, sizeof(fl6));
    2698                 :            : 
    2699         [ #  # ]:          0 :         if (tb[RTA_SRC]) {
    2700         [ #  # ]:          0 :                 if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr))
    2701                 :            :                         goto errout;
    2702                 :            : 
    2703                 :          0 :                 fl6.saddr = *(struct in6_addr *)nla_data(tb[RTA_SRC]);
    2704                 :            :         }
    2705                 :            : 
    2706         [ #  # ]:          0 :         if (tb[RTA_DST]) {
    2707         [ #  # ]:          0 :                 if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr))
    2708                 :            :                         goto errout;
    2709                 :            : 
    2710                 :          0 :                 fl6.daddr = *(struct in6_addr *)nla_data(tb[RTA_DST]);
    2711                 :            :         }
    2712                 :            : 
    2713         [ #  # ]:          0 :         if (tb[RTA_IIF])
    2714                 :          0 :                 iif = nla_get_u32(tb[RTA_IIF]);
    2715                 :            : 
    2716         [ #  # ]:          0 :         if (tb[RTA_OIF])
    2717                 :          0 :                 oif = nla_get_u32(tb[RTA_OIF]);
    2718                 :            : 
    2719         [ #  # ]:          0 :         if (iif) {
    2720                 :            :                 struct net_device *dev;
    2721                 :            :                 int flags = 0;
    2722                 :            : 
    2723                 :          0 :                 dev = __dev_get_by_index(net, iif);
    2724         [ #  # ]:          0 :                 if (!dev) {
    2725                 :            :                         err = -ENODEV;
    2726                 :            :                         goto errout;
    2727                 :            :                 }
    2728                 :            : 
    2729                 :          0 :                 fl6.flowi6_iif = iif;
    2730                 :            : 
    2731         [ #  # ]:          0 :                 if (!ipv6_addr_any(&fl6.saddr))
    2732                 :            :                         flags |= RT6_LOOKUP_F_HAS_SADDR;
    2733                 :            : 
    2734                 :          0 :                 rt = (struct rt6_info *)ip6_route_input_lookup(net, dev, &fl6,
    2735                 :            :                                                                flags);
    2736                 :            :         } else {
    2737                 :          0 :                 fl6.flowi6_oif = oif;
    2738                 :            : 
    2739                 :          0 :                 rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6);
    2740                 :            :         }
    2741                 :            : 
    2742                 :            :         skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
    2743         [ #  # ]:          0 :         if (!skb) {
    2744                 :            :                 ip6_rt_put(rt);
    2745                 :            :                 err = -ENOBUFS;
    2746                 :          0 :                 goto errout;
    2747                 :            :         }
    2748                 :            : 
    2749                 :            :         /* Reserve room for dummy headers, this skb can pass
    2750                 :            :            through good chunk of routing engine.
    2751                 :            :          */
    2752                 :            :         skb_reset_mac_header(skb);
    2753                 :            :         skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr));
    2754                 :            : 
    2755                 :          0 :         skb_dst_set(skb, &rt->dst);
    2756                 :            : 
    2757                 :          0 :         err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif,
    2758                 :            :                             RTM_NEWROUTE, NETLINK_CB(in_skb).portid,
    2759                 :            :                             nlh->nlmsg_seq, 0, 0, 0);
    2760         [ #  # ]:          0 :         if (err < 0) {
    2761                 :          0 :                 kfree_skb(skb);
    2762                 :          0 :                 goto errout;
    2763                 :            :         }
    2764                 :            : 
    2765                 :          0 :         err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
    2766                 :            : errout:
    2767                 :          0 :         return err;
    2768                 :            : }
    2769                 :            : 
    2770                 :          0 : void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
    2771                 :            : {
    2772                 :            :         struct sk_buff *skb;
    2773                 :        210 :         struct net *net = info->nl_net;
    2774                 :            :         u32 seq;
    2775                 :            :         int err;
    2776                 :            : 
    2777                 :            :         err = -ENOBUFS;
    2778         [ -  + ]:        210 :         seq = info->nlh ? info->nlh->nlmsg_seq : 0;
    2779                 :            : 
    2780                 :            :         skb = nlmsg_new(rt6_nlmsg_size(), gfp_any());
    2781         [ +  - ]:        210 :         if (!skb)
    2782                 :            :                 goto errout;
    2783                 :            : 
    2784                 :        210 :         err = rt6_fill_node(net, skb, rt, NULL, NULL, 0,
    2785                 :            :                                 event, info->portid, seq, 0, 0, 0);
    2786         [ -  + ]:        210 :         if (err < 0) {
    2787                 :            :                 /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
    2788         [ #  # ]:          0 :                 WARN_ON(err == -EMSGSIZE);
    2789                 :          0 :                 kfree_skb(skb);
    2790                 :          0 :                 goto errout;
    2791                 :            :         }
    2792                 :        210 :         rtnl_notify(skb, net, info->portid, RTNLGRP_IPV6_ROUTE,
    2793                 :            :                     info->nlh, gfp_any());
    2794                 :        210 :         return;
    2795                 :            : errout:
    2796         [ #  # ]:          0 :         if (err < 0)
    2797                 :          0 :                 rtnl_set_sk_err(net, RTNLGRP_IPV6_ROUTE, err);
    2798                 :            : }
    2799                 :            : 
    2800                 :          0 : static int ip6_route_dev_notify(struct notifier_block *this,
    2801                 :            :                                 unsigned long event, void *ptr)
    2802                 :            : {
    2803                 :            :         struct net_device *dev = netdev_notifier_info_to_dev(ptr);
    2804                 :            :         struct net *net = dev_net(dev);
    2805                 :            : 
    2806 [ #  # ][ #  # ]:          0 :         if (event == NETDEV_REGISTER && (dev->flags & IFF_LOOPBACK)) {
    2807                 :          0 :                 net->ipv6.ip6_null_entry->dst.dev = dev;
    2808                 :          0 :                 net->ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(dev);
    2809                 :            : #ifdef CONFIG_IPV6_MULTIPLE_TABLES
    2810                 :            :                 net->ipv6.ip6_prohibit_entry->dst.dev = dev;
    2811                 :            :                 net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
    2812                 :            :                 net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
    2813                 :            :                 net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
    2814                 :            : #endif
    2815                 :            :         }
    2816                 :            : 
    2817                 :          0 :         return NOTIFY_OK;
    2818                 :            : }
    2819                 :            : 
    2820                 :            : /*
    2821                 :            :  *      /proc
    2822                 :            :  */
    2823                 :            : 
    2824                 :            : #ifdef CONFIG_PROC_FS
    2825                 :            : 
    2826                 :            : static const struct file_operations ipv6_route_proc_fops = {
    2827                 :            :         .owner          = THIS_MODULE,
    2828                 :            :         .open           = ipv6_route_open,
    2829                 :            :         .read           = seq_read,
    2830                 :            :         .llseek         = seq_lseek,
    2831                 :            :         .release        = seq_release_net,
    2832                 :            : };
    2833                 :            : 
    2834                 :          0 : static int rt6_stats_seq_show(struct seq_file *seq, void *v)
    2835                 :            : {
    2836                 :          1 :         struct net *net = (struct net *)seq->private;
    2837                 :          1 :         seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
    2838                 :          1 :                    net->ipv6.rt6_stats->fib_nodes,
    2839                 :            :                    net->ipv6.rt6_stats->fib_route_nodes,
    2840                 :            :                    net->ipv6.rt6_stats->fib_rt_alloc,
    2841                 :            :                    net->ipv6.rt6_stats->fib_rt_entries,
    2842                 :            :                    net->ipv6.rt6_stats->fib_rt_cache,
    2843                 :            :                    dst_entries_get_slow(&net->ipv6.ip6_dst_ops),
    2844                 :          1 :                    net->ipv6.rt6_stats->fib_discarded_routes);
    2845                 :            : 
    2846                 :          1 :         return 0;
    2847                 :            : }
    2848                 :            : 
    2849                 :          0 : static int rt6_stats_seq_open(struct inode *inode, struct file *file)
    2850                 :            : {
    2851                 :          1 :         return single_open_net(inode, file, rt6_stats_seq_show);
    2852                 :            : }
    2853                 :            : 
    2854                 :            : static const struct file_operations rt6_stats_seq_fops = {
    2855                 :            :         .owner   = THIS_MODULE,
    2856                 :            :         .open    = rt6_stats_seq_open,
    2857                 :            :         .read    = seq_read,
    2858                 :            :         .llseek  = seq_lseek,
    2859                 :            :         .release = single_release_net,
    2860                 :            : };
    2861                 :            : #endif  /* CONFIG_PROC_FS */
    2862                 :            : 
    2863                 :            : #ifdef CONFIG_SYSCTL
    2864                 :            : 
    2865                 :            : static
    2866                 :          0 : int ipv6_sysctl_rtcache_flush(struct ctl_table *ctl, int write,
    2867                 :            :                               void __user *buffer, size_t *lenp, loff_t *ppos)
    2868                 :            : {
    2869                 :            :         struct net *net;
    2870                 :            :         int delay;
    2871         [ #  # ]:          0 :         if (!write)
    2872                 :            :                 return -EINVAL;
    2873                 :            : 
    2874                 :          0 :         net = (struct net *)ctl->extra1;
    2875                 :          0 :         delay = net->ipv6.sysctl.flush_delay;
    2876                 :          0 :         proc_dointvec(ctl, write, buffer, lenp, ppos);
    2877                 :          0 :         fib6_run_gc(delay <= 0 ? 0 : (unsigned long)delay, net, delay > 0);
    2878                 :          0 :         return 0;
    2879                 :            : }
    2880                 :            : 
    2881                 :            : struct ctl_table ipv6_route_table_template[] = {
    2882                 :            :         {
    2883                 :            :                 .procname       =       "flush",
    2884                 :            :                 .data           =       &init_net.ipv6.sysctl.flush_delay,
    2885                 :            :                 .maxlen         =       sizeof(int),
    2886                 :            :                 .mode           =       0200,
    2887                 :            :                 .proc_handler   =       ipv6_sysctl_rtcache_flush
    2888                 :            :         },
    2889                 :            :         {
    2890                 :            :                 .procname       =       "gc_thresh",
    2891                 :            :                 .data           =       &ip6_dst_ops_template.gc_thresh,
    2892                 :            :                 .maxlen         =       sizeof(int),
    2893                 :            :                 .mode           =       0644,
    2894                 :            :                 .proc_handler   =       proc_dointvec,
    2895                 :            :         },
    2896                 :            :         {
    2897                 :            :                 .procname       =       "max_size",
    2898                 :            :                 .data           =       &init_net.ipv6.sysctl.ip6_rt_max_size,
    2899                 :            :                 .maxlen         =       sizeof(int),
    2900                 :            :                 .mode           =       0644,
    2901                 :            :                 .proc_handler   =       proc_dointvec,
    2902                 :            :         },
    2903                 :            :         {
    2904                 :            :                 .procname       =       "gc_min_interval",
    2905                 :            :                 .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
    2906                 :            :                 .maxlen         =       sizeof(int),
    2907                 :            :                 .mode           =       0644,
    2908                 :            :                 .proc_handler   =       proc_dointvec_jiffies,
    2909                 :            :         },
    2910                 :            :         {
    2911                 :            :                 .procname       =       "gc_timeout",
    2912                 :            :                 .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_timeout,
    2913                 :            :                 .maxlen         =       sizeof(int),
    2914                 :            :                 .mode           =       0644,
    2915                 :            :                 .proc_handler   =       proc_dointvec_jiffies,
    2916                 :            :         },
    2917                 :            :         {
    2918                 :            :                 .procname       =       "gc_interval",
    2919                 :            :                 .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_interval,
    2920                 :            :                 .maxlen         =       sizeof(int),
    2921                 :            :                 .mode           =       0644,
    2922                 :            :                 .proc_handler   =       proc_dointvec_jiffies,
    2923                 :            :         },
    2924                 :            :         {
    2925                 :            :                 .procname       =       "gc_elasticity",
    2926                 :            :                 .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_elasticity,
    2927                 :            :                 .maxlen         =       sizeof(int),
    2928                 :            :                 .mode           =       0644,
    2929                 :            :                 .proc_handler   =       proc_dointvec,
    2930                 :            :         },
    2931                 :            :         {
    2932                 :            :                 .procname       =       "mtu_expires",
    2933                 :            :                 .data           =       &init_net.ipv6.sysctl.ip6_rt_mtu_expires,
    2934                 :            :                 .maxlen         =       sizeof(int),
    2935                 :            :                 .mode           =       0644,
    2936                 :            :                 .proc_handler   =       proc_dointvec_jiffies,
    2937                 :            :         },
    2938                 :            :         {
    2939                 :            :                 .procname       =       "min_adv_mss",
    2940                 :            :                 .data           =       &init_net.ipv6.sysctl.ip6_rt_min_advmss,
    2941                 :            :                 .maxlen         =       sizeof(int),
    2942                 :            :                 .mode           =       0644,
    2943                 :            :                 .proc_handler   =       proc_dointvec,
    2944                 :            :         },
    2945                 :            :         {
    2946                 :            :                 .procname       =       "gc_min_interval_ms",
    2947                 :            :                 .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
    2948                 :            :                 .maxlen         =       sizeof(int),
    2949                 :            :                 .mode           =       0644,
    2950                 :            :                 .proc_handler   =       proc_dointvec_ms_jiffies,
    2951                 :            :         },
    2952                 :            :         { }
    2953                 :            : };
    2954                 :            : 
    2955                 :          0 : struct ctl_table * __net_init ipv6_route_sysctl_init(struct net *net)
    2956                 :            : {
    2957                 :            :         struct ctl_table *table;
    2958                 :            : 
    2959                 :          0 :         table = kmemdup(ipv6_route_table_template,
    2960                 :            :                         sizeof(ipv6_route_table_template),
    2961                 :            :                         GFP_KERNEL);
    2962                 :            : 
    2963         [ #  # ]:          0 :         if (table) {
    2964                 :          0 :                 table[0].data = &net->ipv6.sysctl.flush_delay;
    2965                 :          0 :                 table[0].extra1 = net;
    2966                 :          0 :                 table[1].data = &net->ipv6.ip6_dst_ops.gc_thresh;
    2967                 :          0 :                 table[2].data = &net->ipv6.sysctl.ip6_rt_max_size;
    2968                 :          0 :                 table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval;
    2969                 :          0 :                 table[4].data = &net->ipv6.sysctl.ip6_rt_gc_timeout;
    2970                 :          0 :                 table[5].data = &net->ipv6.sysctl.ip6_rt_gc_interval;
    2971                 :          0 :                 table[6].data = &net->ipv6.sysctl.ip6_rt_gc_elasticity;
    2972                 :          0 :                 table[7].data = &net->ipv6.sysctl.ip6_rt_mtu_expires;
    2973                 :          0 :                 table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss;
    2974                 :          0 :                 table[9].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval;
    2975                 :            : 
    2976                 :            :                 /* Don't export sysctls to unprivileged users */
    2977         [ #  # ]:          0 :                 if (net->user_ns != &init_user_ns)
    2978                 :          0 :                         table[0].procname = NULL;
    2979                 :            :         }
    2980                 :            : 
    2981                 :          0 :         return table;
    2982                 :            : }
    2983                 :            : #endif
    2984                 :            : 
    2985                 :          0 : static int __net_init ip6_route_net_init(struct net *net)
    2986                 :            : {
    2987                 :            :         int ret = -ENOMEM;
    2988                 :            : 
    2989                 :          0 :         memcpy(&net->ipv6.ip6_dst_ops, &ip6_dst_ops_template,
    2990                 :            :                sizeof(net->ipv6.ip6_dst_ops));
    2991                 :            : 
    2992         [ #  # ]:          0 :         if (dst_entries_init(&net->ipv6.ip6_dst_ops) < 0)
    2993                 :            :                 goto out_ip6_dst_ops;
    2994                 :            : 
    2995                 :          0 :         net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template,
    2996                 :            :                                            sizeof(*net->ipv6.ip6_null_entry),
    2997                 :            :                                            GFP_KERNEL);
    2998         [ #  # ]:          0 :         if (!net->ipv6.ip6_null_entry)
    2999                 :            :                 goto out_ip6_dst_entries;
    3000                 :          0 :         net->ipv6.ip6_null_entry->dst.path =
    3001                 :            :                 (struct dst_entry *)net->ipv6.ip6_null_entry;
    3002                 :          0 :         net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops;
    3003                 :          0 :         dst_init_metrics(&net->ipv6.ip6_null_entry->dst,
    3004                 :            :                          ip6_template_metrics, true);
    3005                 :            : 
    3006                 :            : #ifdef CONFIG_IPV6_MULTIPLE_TABLES
    3007                 :            :         net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
    3008                 :            :                                                sizeof(*net->ipv6.ip6_prohibit_entry),
    3009                 :            :                                                GFP_KERNEL);
    3010                 :            :         if (!net->ipv6.ip6_prohibit_entry)
    3011                 :            :                 goto out_ip6_null_entry;
    3012                 :            :         net->ipv6.ip6_prohibit_entry->dst.path =
    3013                 :            :                 (struct dst_entry *)net->ipv6.ip6_prohibit_entry;
    3014                 :            :         net->ipv6.ip6_prohibit_entry->dst.ops = &net->ipv6.ip6_dst_ops;
    3015                 :            :         dst_init_metrics(&net->ipv6.ip6_prohibit_entry->dst,
    3016                 :            :                          ip6_template_metrics, true);
    3017                 :            : 
    3018                 :            :         net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template,
    3019                 :            :                                                sizeof(*net->ipv6.ip6_blk_hole_entry),
    3020                 :            :                                                GFP_KERNEL);
    3021                 :            :         if (!net->ipv6.ip6_blk_hole_entry)
    3022                 :            :                 goto out_ip6_prohibit_entry;
    3023                 :            :         net->ipv6.ip6_blk_hole_entry->dst.path =
    3024                 :            :                 (struct dst_entry *)net->ipv6.ip6_blk_hole_entry;
    3025                 :            :         net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
    3026                 :            :         dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
    3027                 :            :                          ip6_template_metrics, true);
    3028                 :            : #endif
    3029                 :            : 
    3030                 :          0 :         net->ipv6.sysctl.flush_delay = 0;
    3031                 :          0 :         net->ipv6.sysctl.ip6_rt_max_size = 4096;
    3032                 :          0 :         net->ipv6.sysctl.ip6_rt_gc_min_interval = HZ / 2;
    3033                 :          0 :         net->ipv6.sysctl.ip6_rt_gc_timeout = 60*HZ;
    3034                 :          0 :         net->ipv6.sysctl.ip6_rt_gc_interval = 30*HZ;
    3035                 :          0 :         net->ipv6.sysctl.ip6_rt_gc_elasticity = 9;
    3036                 :          0 :         net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ;
    3037                 :          0 :         net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
    3038                 :            : 
    3039                 :          0 :         net->ipv6.ip6_rt_gc_expire = 30*HZ;
    3040                 :            : 
    3041                 :            :         ret = 0;
    3042                 :            : out:
    3043                 :          0 :         return ret;
    3044                 :            : 
    3045                 :            : #ifdef CONFIG_IPV6_MULTIPLE_TABLES
    3046                 :            : out_ip6_prohibit_entry:
    3047                 :            :         kfree(net->ipv6.ip6_prohibit_entry);
    3048                 :            : out_ip6_null_entry:
    3049                 :            :         kfree(net->ipv6.ip6_null_entry);
    3050                 :            : #endif
    3051                 :            : out_ip6_dst_entries:
    3052                 :            :         dst_entries_destroy(&net->ipv6.ip6_dst_ops);
    3053                 :            : out_ip6_dst_ops:
    3054                 :            :         goto out;
    3055                 :            : }
    3056                 :            : 
    3057                 :          0 : static void __net_exit ip6_route_net_exit(struct net *net)
    3058                 :            : {
    3059                 :          0 :         kfree(net->ipv6.ip6_null_entry);
    3060                 :            : #ifdef CONFIG_IPV6_MULTIPLE_TABLES
    3061                 :            :         kfree(net->ipv6.ip6_prohibit_entry);
    3062                 :            :         kfree(net->ipv6.ip6_blk_hole_entry);
    3063                 :            : #endif
    3064                 :            :         dst_entries_destroy(&net->ipv6.ip6_dst_ops);
    3065                 :          0 : }
    3066                 :            : 
    3067                 :          0 : static int __net_init ip6_route_net_init_late(struct net *net)
    3068                 :            : {
    3069                 :            : #ifdef CONFIG_PROC_FS
    3070                 :          0 :         proc_create("ipv6_route", 0, net->proc_net, &ipv6_route_proc_fops);
    3071                 :          0 :         proc_create("rt6_stats", S_IRUGO, net->proc_net, &rt6_stats_seq_fops);
    3072                 :            : #endif
    3073                 :          0 :         return 0;
    3074                 :            : }
    3075                 :            : 
    3076                 :          0 : static void __net_exit ip6_route_net_exit_late(struct net *net)
    3077                 :            : {
    3078                 :            : #ifdef CONFIG_PROC_FS
    3079                 :          0 :         remove_proc_entry("ipv6_route", net->proc_net);
    3080                 :          0 :         remove_proc_entry("rt6_stats", net->proc_net);
    3081                 :            : #endif
    3082                 :          0 : }
    3083                 :            : 
    3084                 :            : static struct pernet_operations ip6_route_net_ops = {
    3085                 :            :         .init = ip6_route_net_init,
    3086                 :            :         .exit = ip6_route_net_exit,
    3087                 :            : };
    3088                 :            : 
    3089                 :          0 : static int __net_init ipv6_inetpeer_init(struct net *net)
    3090                 :            : {
    3091                 :            :         struct inet_peer_base *bp = kmalloc(sizeof(*bp), GFP_KERNEL);
    3092                 :            : 
    3093         [ #  # ]:          0 :         if (!bp)
    3094                 :            :                 return -ENOMEM;
    3095                 :          0 :         inet_peer_base_init(bp);
    3096                 :          0 :         net->ipv6.peers = bp;
    3097                 :          0 :         return 0;
    3098                 :            : }
    3099                 :            : 
    3100                 :          0 : static void __net_exit ipv6_inetpeer_exit(struct net *net)
    3101                 :            : {
    3102                 :          0 :         struct inet_peer_base *bp = net->ipv6.peers;
    3103                 :            : 
    3104                 :          0 :         net->ipv6.peers = NULL;
    3105                 :          0 :         inetpeer_invalidate_tree(bp);
    3106                 :          0 :         kfree(bp);
    3107                 :          0 : }
    3108                 :            : 
    3109                 :            : static struct pernet_operations ipv6_inetpeer_ops = {
    3110                 :            :         .init   =       ipv6_inetpeer_init,
    3111                 :            :         .exit   =       ipv6_inetpeer_exit,
    3112                 :            : };
    3113                 :            : 
    3114                 :            : static struct pernet_operations ip6_route_net_late_ops = {
    3115                 :            :         .init = ip6_route_net_init_late,
    3116                 :            :         .exit = ip6_route_net_exit_late,
    3117                 :            : };
    3118                 :            : 
    3119                 :            : static struct notifier_block ip6_route_dev_notifier = {
    3120                 :            :         .notifier_call = ip6_route_dev_notify,
    3121                 :            :         .priority = 0,
    3122                 :            : };
    3123                 :            : 
    3124                 :          0 : int __init ip6_route_init(void)
    3125                 :            : {
    3126                 :            :         int ret;
    3127                 :            : 
    3128                 :            :         ret = -ENOMEM;
    3129                 :          0 :         ip6_dst_ops_template.kmem_cachep =
    3130                 :          0 :                 kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0,
    3131                 :            :                                   SLAB_HWCACHE_ALIGN, NULL);
    3132         [ #  # ]:          0 :         if (!ip6_dst_ops_template.kmem_cachep)
    3133                 :            :                 goto out;
    3134                 :            : 
    3135                 :            :         ret = dst_entries_init(&ip6_dst_blackhole_ops);
    3136         [ #  # ]:          0 :         if (ret)
    3137                 :            :                 goto out_kmem_cache;
    3138                 :            : 
    3139                 :          0 :         ret = register_pernet_subsys(&ipv6_inetpeer_ops);
    3140         [ #  # ]:          0 :         if (ret)
    3141                 :            :                 goto out_dst_entries;
    3142                 :            : 
    3143                 :          0 :         ret = register_pernet_subsys(&ip6_route_net_ops);
    3144         [ #  # ]:          0 :         if (ret)
    3145                 :            :                 goto out_register_inetpeer;
    3146                 :            : 
    3147                 :          0 :         ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep;
    3148                 :            : 
    3149                 :            :         /* Registering of the loopback is done before this portion of code,
    3150                 :            :          * the loopback reference in rt6_info will not be taken, do it
    3151                 :            :          * manually for init_net */
    3152                 :          0 :         init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev;
    3153                 :          0 :         init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
    3154                 :            :   #ifdef CONFIG_IPV6_MULTIPLE_TABLES
    3155                 :            :         init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev;
    3156                 :            :         init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
    3157                 :            :         init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
    3158                 :            :         init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
    3159                 :            :   #endif
    3160                 :          0 :         ret = fib6_init();
    3161         [ #  # ]:          0 :         if (ret)
    3162                 :            :                 goto out_register_subsys;
    3163                 :            : 
    3164                 :          0 :         ret = xfrm6_init();
    3165         [ #  # ]:          0 :         if (ret)
    3166                 :            :                 goto out_fib6_init;
    3167                 :            : 
    3168                 :            :         ret = fib6_rules_init();
    3169                 :            :         if (ret)
    3170                 :            :                 goto xfrm6_init;
    3171                 :            : 
    3172                 :          0 :         ret = register_pernet_subsys(&ip6_route_net_late_ops);
    3173         [ #  # ]:          0 :         if (ret)
    3174                 :            :                 goto fib6_rules_init;
    3175                 :            : 
    3176                 :            :         ret = -ENOBUFS;
    3177   [ #  #  #  # ]:          0 :         if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, NULL) ||
    3178         [ #  # ]:          0 :             __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, NULL) ||
    3179                 :          0 :             __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, NULL))
    3180                 :            :                 goto out_register_late_subsys;
    3181                 :            : 
    3182                 :          0 :         ret = register_netdevice_notifier(&ip6_route_dev_notifier);
    3183         [ #  # ]:          0 :         if (ret)
    3184                 :            :                 goto out_register_late_subsys;
    3185                 :            : 
    3186                 :            : out:
    3187                 :          0 :         return ret;
    3188                 :            : 
    3189                 :            : out_register_late_subsys:
    3190                 :          0 :         unregister_pernet_subsys(&ip6_route_net_late_ops);
    3191                 :            : fib6_rules_init:
    3192                 :            :         fib6_rules_cleanup();
    3193                 :            : xfrm6_init:
    3194                 :          0 :         xfrm6_fini();
    3195                 :            : out_fib6_init:
    3196                 :          0 :         fib6_gc_cleanup();
    3197                 :            : out_register_subsys:
    3198                 :          0 :         unregister_pernet_subsys(&ip6_route_net_ops);
    3199                 :            : out_register_inetpeer:
    3200                 :          0 :         unregister_pernet_subsys(&ipv6_inetpeer_ops);
    3201                 :            : out_dst_entries:
    3202                 :            :         dst_entries_destroy(&ip6_dst_blackhole_ops);
    3203                 :            : out_kmem_cache:
    3204                 :          0 :         kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep);
    3205                 :          0 :         goto out;
    3206                 :            : }
    3207                 :            : 
    3208                 :          0 : void ip6_route_cleanup(void)
    3209                 :            : {
    3210                 :          0 :         unregister_netdevice_notifier(&ip6_route_dev_notifier);
    3211                 :          0 :         unregister_pernet_subsys(&ip6_route_net_late_ops);
    3212                 :            :         fib6_rules_cleanup();
    3213                 :          0 :         xfrm6_fini();
    3214                 :          0 :         fib6_gc_cleanup();
    3215                 :          0 :         unregister_pernet_subsys(&ipv6_inetpeer_ops);
    3216                 :          0 :         unregister_pernet_subsys(&ip6_route_net_ops);
    3217                 :            :         dst_entries_destroy(&ip6_dst_blackhole_ops);
    3218                 :          0 :         kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep);
    3219                 :          0 : }

Generated by: LCOV version 1.9