LCOV - code coverage report
Current view: top level - net/ipv6 - ndisc.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 110 688 16.0 %
Date: 2020-09-30 20:25:40 Functions: 11 45 24.4 %
Branches: 37 569 6.5 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-or-later
       2                 :            : /*
       3                 :            :  *      Neighbour Discovery for IPv6
       4                 :            :  *      Linux INET6 implementation
       5                 :            :  *
       6                 :            :  *      Authors:
       7                 :            :  *      Pedro Roque             <roque@di.fc.ul.pt>
       8                 :            :  *      Mike Shaver             <shaver@ingenia.com>
       9                 :            :  */
      10                 :            : 
      11                 :            : /*
      12                 :            :  *      Changes:
      13                 :            :  *
      14                 :            :  *      Alexey I. Froloff               :       RFC6106 (DNSSL) support
      15                 :            :  *      Pierre Ynard                    :       export userland ND options
      16                 :            :  *                                              through netlink (RDNSS support)
      17                 :            :  *      Lars Fenneberg                  :       fixed MTU setting on receipt
      18                 :            :  *                                              of an RA.
      19                 :            :  *      Janos Farkas                    :       kmalloc failure checks
      20                 :            :  *      Alexey Kuznetsov                :       state machine reworked
      21                 :            :  *                                              and moved to net/core.
      22                 :            :  *      Pekka Savola                    :       RFC2461 validation
      23                 :            :  *      YOSHIFUJI Hideaki @USAGI        :       Verify ND options properly
      24                 :            :  */
      25                 :            : 
      26                 :            : #define pr_fmt(fmt) "ICMPv6: " fmt
      27                 :            : 
      28                 :            : #include <linux/module.h>
      29                 :            : #include <linux/errno.h>
      30                 :            : #include <linux/types.h>
      31                 :            : #include <linux/socket.h>
      32                 :            : #include <linux/sockios.h>
      33                 :            : #include <linux/sched.h>
      34                 :            : #include <linux/net.h>
      35                 :            : #include <linux/in6.h>
      36                 :            : #include <linux/route.h>
      37                 :            : #include <linux/init.h>
      38                 :            : #include <linux/rcupdate.h>
      39                 :            : #include <linux/slab.h>
      40                 :            : #ifdef CONFIG_SYSCTL
      41                 :            : #include <linux/sysctl.h>
      42                 :            : #endif
      43                 :            : 
      44                 :            : #include <linux/if_addr.h>
      45                 :            : #include <linux/if_ether.h>
      46                 :            : #include <linux/if_arp.h>
      47                 :            : #include <linux/ipv6.h>
      48                 :            : #include <linux/icmpv6.h>
      49                 :            : #include <linux/jhash.h>
      50                 :            : 
      51                 :            : #include <net/sock.h>
      52                 :            : #include <net/snmp.h>
      53                 :            : 
      54                 :            : #include <net/ipv6.h>
      55                 :            : #include <net/protocol.h>
      56                 :            : #include <net/ndisc.h>
      57                 :            : #include <net/ip6_route.h>
      58                 :            : #include <net/addrconf.h>
      59                 :            : #include <net/icmp.h>
      60                 :            : 
      61                 :            : #include <net/netlink.h>
      62                 :            : #include <linux/rtnetlink.h>
      63                 :            : 
      64                 :            : #include <net/flow.h>
      65                 :            : #include <net/ip6_checksum.h>
      66                 :            : #include <net/inet_common.h>
      67                 :            : #include <linux/proc_fs.h>
      68                 :            : 
      69                 :            : #include <linux/netfilter.h>
      70                 :            : #include <linux/netfilter_ipv6.h>
      71                 :            : 
      72                 :            : static u32 ndisc_hash(const void *pkey,
      73                 :            :                       const struct net_device *dev,
      74                 :            :                       __u32 *hash_rnd);
      75                 :            : static bool ndisc_key_eq(const struct neighbour *neigh, const void *pkey);
      76                 :            : static bool ndisc_allow_add(const struct net_device *dev,
      77                 :            :                             struct netlink_ext_ack *extack);
      78                 :            : static int ndisc_constructor(struct neighbour *neigh);
      79                 :            : static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
      80                 :            : static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb);
      81                 :            : static int pndisc_constructor(struct pneigh_entry *n);
      82                 :            : static void pndisc_destructor(struct pneigh_entry *n);
      83                 :            : static void pndisc_redo(struct sk_buff *skb);
      84                 :            : 
      85                 :            : static const struct neigh_ops ndisc_generic_ops = {
      86                 :            :         .family =               AF_INET6,
      87                 :            :         .solicit =              ndisc_solicit,
      88                 :            :         .error_report =         ndisc_error_report,
      89                 :            :         .output =               neigh_resolve_output,
      90                 :            :         .connected_output =     neigh_connected_output,
      91                 :            : };
      92                 :            : 
      93                 :            : static const struct neigh_ops ndisc_hh_ops = {
      94                 :            :         .family =               AF_INET6,
      95                 :            :         .solicit =              ndisc_solicit,
      96                 :            :         .error_report =         ndisc_error_report,
      97                 :            :         .output =               neigh_resolve_output,
      98                 :            :         .connected_output =     neigh_resolve_output,
      99                 :            : };
     100                 :            : 
     101                 :            : 
     102                 :            : static const struct neigh_ops ndisc_direct_ops = {
     103                 :            :         .family =               AF_INET6,
     104                 :            :         .output =               neigh_direct_output,
     105                 :            :         .connected_output =     neigh_direct_output,
     106                 :            : };
     107                 :            : 
     108                 :            : struct neigh_table nd_tbl = {
     109                 :            :         .family =       AF_INET6,
     110                 :            :         .key_len =      sizeof(struct in6_addr),
     111                 :            :         .protocol =     cpu_to_be16(ETH_P_IPV6),
     112                 :            :         .hash =         ndisc_hash,
     113                 :            :         .key_eq =       ndisc_key_eq,
     114                 :            :         .constructor =  ndisc_constructor,
     115                 :            :         .pconstructor = pndisc_constructor,
     116                 :            :         .pdestructor =  pndisc_destructor,
     117                 :            :         .proxy_redo =   pndisc_redo,
     118                 :            :         .allow_add  =   ndisc_allow_add,
     119                 :            :         .id =           "ndisc_cache",
     120                 :            :         .parms = {
     121                 :            :                 .tbl                    = &nd_tbl,
     122                 :            :                 .reachable_time         = ND_REACHABLE_TIME,
     123                 :            :                 .data = {
     124                 :            :                         [NEIGH_VAR_MCAST_PROBES] = 3,
     125                 :            :                         [NEIGH_VAR_UCAST_PROBES] = 3,
     126                 :            :                         [NEIGH_VAR_RETRANS_TIME] = ND_RETRANS_TIMER,
     127                 :            :                         [NEIGH_VAR_BASE_REACHABLE_TIME] = ND_REACHABLE_TIME,
     128                 :            :                         [NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ,
     129                 :            :                         [NEIGH_VAR_GC_STALETIME] = 60 * HZ,
     130                 :            :                         [NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_MAX,
     131                 :            :                         [NEIGH_VAR_PROXY_QLEN] = 64,
     132                 :            :                         [NEIGH_VAR_ANYCAST_DELAY] = 1 * HZ,
     133                 :            :                         [NEIGH_VAR_PROXY_DELAY] = (8 * HZ) / 10,
     134                 :            :                 },
     135                 :            :         },
     136                 :            :         .gc_interval =    30 * HZ,
     137                 :            :         .gc_thresh1 =    128,
     138                 :            :         .gc_thresh2 =    512,
     139                 :            :         .gc_thresh3 =   1024,
     140                 :            : };
     141                 :            : EXPORT_SYMBOL_GPL(nd_tbl);
     142                 :            : 
     143                 :          0 : void __ndisc_fill_addr_option(struct sk_buff *skb, int type, void *data,
     144                 :            :                               int data_len, int pad)
     145                 :            : {
     146                 :            :         int space = __ndisc_opt_addr_space(data_len, pad);
     147                 :          0 :         u8 *opt = skb_put(skb, space);
     148                 :            : 
     149                 :          0 :         opt[0] = type;
     150                 :          0 :         opt[1] = space>>3;
     151                 :            : 
     152                 :          0 :         memset(opt + 2, 0, pad);
     153                 :          0 :         opt   += pad;
     154                 :          0 :         space -= pad;
     155                 :            : 
     156                 :          0 :         memcpy(opt+2, data, data_len);
     157                 :          0 :         data_len += 2;
     158                 :          0 :         opt += data_len;
     159                 :          0 :         space -= data_len;
     160         [ #  # ]:          0 :         if (space > 0)
     161                 :          0 :                 memset(opt, 0, space);
     162                 :          0 : }
     163                 :            : EXPORT_SYMBOL_GPL(__ndisc_fill_addr_option);
     164                 :            : 
     165                 :          0 : static inline void ndisc_fill_addr_option(struct sk_buff *skb, int type,
     166                 :            :                                           void *data, u8 icmp6_type)
     167                 :            : {
     168                 :          0 :         __ndisc_fill_addr_option(skb, type, data, skb->dev->addr_len,
     169                 :            :                                  ndisc_addr_option_pad(skb->dev->type));
     170                 :          0 :         ndisc_ops_fill_addr_option(skb->dev, skb, icmp6_type);
     171                 :          0 : }
     172                 :            : 
     173                 :          0 : static inline void ndisc_fill_redirect_addr_option(struct sk_buff *skb,
     174                 :            :                                                    void *ha,
     175                 :            :                                                    const u8 *ops_data)
     176                 :            : {
     177                 :          0 :         ndisc_fill_addr_option(skb, ND_OPT_TARGET_LL_ADDR, ha, NDISC_REDIRECT);
     178                 :          0 :         ndisc_ops_fill_redirect_addr_option(skb->dev, skb, ops_data);
     179                 :          0 : }
     180                 :            : 
     181                 :          0 : static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
     182                 :            :                                             struct nd_opt_hdr *end)
     183                 :            : {
     184                 :            :         int type;
     185   [ #  #  #  # ]:          0 :         if (!cur || !end || cur >= end)
     186                 :            :                 return NULL;
     187                 :          0 :         type = cur->nd_opt_type;
     188                 :            :         do {
     189                 :          0 :                 cur = ((void *)cur) + (cur->nd_opt_len << 3);
     190   [ #  #  #  # ]:          0 :         } while (cur < end && cur->nd_opt_type != type);
     191   [ #  #  #  # ]:          0 :         return cur <= end && cur->nd_opt_type == type ? cur : NULL;
     192                 :            : }
     193                 :            : 
     194                 :          0 : static inline int ndisc_is_useropt(const struct net_device *dev,
     195                 :            :                                    struct nd_opt_hdr *opt)
     196                 :            : {
     197                 :          0 :         return opt->nd_opt_type == ND_OPT_RDNSS ||
     198         [ #  # ]:          0 :                 opt->nd_opt_type == ND_OPT_DNSSL ||
     199   [ #  #  #  # ]:          0 :                 opt->nd_opt_type == ND_OPT_CAPTIVE_PORTAL ||
     200                 :            :                 ndisc_ops_is_useropt(dev, opt->nd_opt_type);
     201                 :            : }
     202                 :            : 
     203                 :          0 : static struct nd_opt_hdr *ndisc_next_useropt(const struct net_device *dev,
     204                 :            :                                              struct nd_opt_hdr *cur,
     205                 :            :                                              struct nd_opt_hdr *end)
     206                 :            : {
     207   [ #  #  #  # ]:          0 :         if (!cur || !end || cur >= end)
     208                 :            :                 return NULL;
     209                 :            :         do {
     210                 :          0 :                 cur = ((void *)cur) + (cur->nd_opt_len << 3);
     211   [ #  #  #  # ]:          0 :         } while (cur < end && !ndisc_is_useropt(dev, cur));
     212   [ #  #  #  # ]:          0 :         return cur <= end && ndisc_is_useropt(dev, cur) ? cur : NULL;
     213                 :            : }
     214                 :            : 
     215                 :          0 : struct ndisc_options *ndisc_parse_options(const struct net_device *dev,
     216                 :            :                                           u8 *opt, int opt_len,
     217                 :            :                                           struct ndisc_options *ndopts)
     218                 :            : {
     219                 :            :         struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)opt;
     220                 :            : 
     221   [ #  #  #  # ]:          0 :         if (!nd_opt || opt_len < 0 || !ndopts)
     222                 :            :                 return NULL;
     223                 :          0 :         memset(ndopts, 0, sizeof(*ndopts));
     224         [ #  # ]:          0 :         while (opt_len) {
     225                 :            :                 int l;
     226         [ #  # ]:          0 :                 if (opt_len < sizeof(struct nd_opt_hdr))
     227                 :            :                         return NULL;
     228                 :          0 :                 l = nd_opt->nd_opt_len << 3;
     229         [ #  # ]:          0 :                 if (opt_len < l || l == 0)
     230                 :            :                         return NULL;
     231         [ #  # ]:          0 :                 if (ndisc_ops_parse_options(dev, nd_opt, ndopts))
     232                 :            :                         goto next_opt;
     233   [ #  #  #  # ]:          0 :                 switch (nd_opt->nd_opt_type) {
     234                 :            :                 case ND_OPT_SOURCE_LL_ADDR:
     235                 :            :                 case ND_OPT_TARGET_LL_ADDR:
     236                 :            :                 case ND_OPT_MTU:
     237                 :            :                 case ND_OPT_NONCE:
     238                 :            :                 case ND_OPT_REDIRECT_HDR:
     239         [ #  # ]:          0 :                         if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
     240                 :            :                                 ND_PRINTK(2, warn,
     241                 :            :                                           "%s: duplicated ND6 option found: type=%d\n",
     242                 :            :                                           __func__, nd_opt->nd_opt_type);
     243                 :            :                         } else {
     244                 :          0 :                                 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
     245                 :            :                         }
     246                 :            :                         break;
     247                 :            :                 case ND_OPT_PREFIX_INFO:
     248                 :          0 :                         ndopts->nd_opts_pi_end = nd_opt;
     249         [ #  # ]:          0 :                         if (!ndopts->nd_opt_array[nd_opt->nd_opt_type])
     250                 :          0 :                                 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
     251                 :            :                         break;
     252                 :            : #ifdef CONFIG_IPV6_ROUTE_INFO
     253                 :            :                 case ND_OPT_ROUTE_INFO:
     254                 :          0 :                         ndopts->nd_opts_ri_end = nd_opt;
     255         [ #  # ]:          0 :                         if (!ndopts->nd_opts_ri)
     256                 :          0 :                                 ndopts->nd_opts_ri = nd_opt;
     257                 :            :                         break;
     258                 :            : #endif
     259                 :            :                 default:
     260         [ #  # ]:          0 :                         if (ndisc_is_useropt(dev, nd_opt)) {
     261                 :          0 :                                 ndopts->nd_useropts_end = nd_opt;
     262         [ #  # ]:          0 :                                 if (!ndopts->nd_useropts)
     263                 :          0 :                                         ndopts->nd_useropts = nd_opt;
     264                 :            :                         } else {
     265                 :            :                                 /*
     266                 :            :                                  * Unknown options must be silently ignored,
     267                 :            :                                  * to accommodate future extension to the
     268                 :            :                                  * protocol.
     269                 :            :                                  */
     270                 :            :                                 ND_PRINTK(2, notice,
     271                 :            :                                           "%s: ignored unsupported option; type=%d, len=%d\n",
     272                 :            :                                           __func__,
     273                 :            :                                           nd_opt->nd_opt_type,
     274                 :            :                                           nd_opt->nd_opt_len);
     275                 :            :                         }
     276                 :            :                 }
     277                 :            : next_opt:
     278                 :          0 :                 opt_len -= l;
     279                 :          0 :                 nd_opt = ((void *)nd_opt) + l;
     280                 :            :         }
     281                 :            :         return ndopts;
     282                 :            : }
     283                 :            : 
     284                 :       2866 : int ndisc_mc_map(const struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
     285                 :            : {
     286   [ +  -  -  -  :       2866 :         switch (dev->type) {
                      + ]
     287                 :            :         case ARPHRD_ETHER:
     288                 :            :         case ARPHRD_IEEE802:    /* Not sure. Check it later. --ANK */
     289                 :            :         case ARPHRD_FDDI:
     290                 :            :                 ipv6_eth_mc_map(addr, buf);
     291                 :       2659 :                 return 0;
     292                 :            :         case ARPHRD_ARCNET:
     293                 :            :                 ipv6_arcnet_mc_map(addr, buf);
     294                 :          0 :                 return 0;
     295                 :            :         case ARPHRD_INFINIBAND:
     296                 :          0 :                 ipv6_ib_mc_map(addr, dev->broadcast, buf);
     297                 :          0 :                 return 0;
     298                 :            :         case ARPHRD_IPGRE:
     299                 :          0 :                 return ipv6_ipgre_mc_map(addr, dev->broadcast, buf);
     300                 :            :         default:
     301         [ -  + ]:        207 :                 if (dir) {
     302                 :          0 :                         memcpy(buf, dev->broadcast, dev->addr_len);
     303                 :          0 :                         return 0;
     304                 :            :                 }
     305                 :            :         }
     306                 :            :         return -EINVAL;
     307                 :            : }
     308                 :            : EXPORT_SYMBOL(ndisc_mc_map);
     309                 :            : 
     310                 :       1210 : static u32 ndisc_hash(const void *pkey,
     311                 :            :                       const struct net_device *dev,
     312                 :            :                       __u32 *hash_rnd)
     313                 :            : {
     314                 :       1210 :         return ndisc_hashfn(pkey, dev, hash_rnd);
     315                 :            : }
     316                 :            : 
     317                 :          0 : static bool ndisc_key_eq(const struct neighbour *n, const void *pkey)
     318                 :            : {
     319                 :          0 :         return neigh_key_eq128(n, pkey);
     320                 :            : }
     321                 :            : 
     322                 :       1210 : static int ndisc_constructor(struct neighbour *neigh)
     323                 :            : {
     324                 :       1210 :         struct in6_addr *addr = (struct in6_addr *)&neigh->primary_key;
     325                 :       1210 :         struct net_device *dev = neigh->dev;
     326                 :            :         struct inet6_dev *in6_dev;
     327                 :            :         struct neigh_parms *parms;
     328                 :            :         bool is_multicast = ipv6_addr_is_multicast(addr);
     329                 :            : 
     330                 :            :         in6_dev = in6_dev_get(dev);
     331         [ +  - ]:       1210 :         if (!in6_dev) {
     332                 :            :                 return -EINVAL;
     333                 :            :         }
     334                 :            : 
     335                 :       1210 :         parms = in6_dev->nd_parms;
     336                 :       1210 :         __neigh_parms_put(neigh->parms);
     337                 :       1210 :         neigh->parms = neigh_parms_clone(parms);
     338                 :            : 
     339         [ -  + ]:       1210 :         neigh->type = is_multicast ? RTN_MULTICAST : RTN_UNICAST;
     340         [ -  + ]:       1210 :         if (!dev->header_ops) {
     341                 :          0 :                 neigh->nud_state = NUD_NOARP;
     342                 :          0 :                 neigh->ops = &ndisc_direct_ops;
     343                 :          0 :                 neigh->output = neigh_direct_output;
     344                 :            :         } else {
     345         [ +  - ]:       1210 :                 if (is_multicast) {
     346                 :       1210 :                         neigh->nud_state = NUD_NOARP;
     347                 :       1210 :                         ndisc_mc_map(addr, neigh->ha, dev, 1);
     348         [ #  # ]:          0 :                 } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) {
     349                 :          0 :                         neigh->nud_state = NUD_NOARP;
     350                 :          0 :                         memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
     351         [ #  # ]:          0 :                         if (dev->flags&IFF_LOOPBACK)
     352                 :          0 :                                 neigh->type = RTN_LOCAL;
     353         [ #  # ]:          0 :                 } else if (dev->flags&IFF_POINTOPOINT) {
     354                 :          0 :                         neigh->nud_state = NUD_NOARP;
     355                 :          0 :                         memcpy(neigh->ha, dev->broadcast, dev->addr_len);
     356                 :            :                 }
     357         [ +  - ]:       1210 :                 if (dev->header_ops->cache)
     358                 :       1210 :                         neigh->ops = &ndisc_hh_ops;
     359                 :            :                 else
     360                 :          0 :                         neigh->ops = &ndisc_generic_ops;
     361         [ +  - ]:       1210 :                 if (neigh->nud_state&NUD_VALID)
     362                 :       1210 :                         neigh->output = neigh->ops->connected_output;
     363                 :            :                 else
     364                 :          0 :                         neigh->output = neigh->ops->output;
     365                 :            :         }
     366                 :       1210 :         in6_dev_put(in6_dev);
     367                 :       1210 :         return 0;
     368                 :            : }
     369                 :            : 
     370                 :          0 : static int pndisc_constructor(struct pneigh_entry *n)
     371                 :            : {
     372                 :            :         struct in6_addr *addr = (struct in6_addr *)&n->key;
     373                 :            :         struct in6_addr maddr;
     374                 :          0 :         struct net_device *dev = n->dev;
     375                 :            : 
     376   [ #  #  #  # ]:          0 :         if (!dev || !__in6_dev_get(dev))
     377                 :            :                 return -EINVAL;
     378                 :            :         addrconf_addr_solict_mult(addr, &maddr);
     379                 :          0 :         ipv6_dev_mc_inc(dev, &maddr);
     380                 :          0 :         return 0;
     381                 :            : }
     382                 :            : 
     383                 :          0 : static void pndisc_destructor(struct pneigh_entry *n)
     384                 :            : {
     385                 :            :         struct in6_addr *addr = (struct in6_addr *)&n->key;
     386                 :            :         struct in6_addr maddr;
     387                 :          0 :         struct net_device *dev = n->dev;
     388                 :            : 
     389   [ #  #  #  # ]:          0 :         if (!dev || !__in6_dev_get(dev))
     390                 :          0 :                 return;
     391                 :            :         addrconf_addr_solict_mult(addr, &maddr);
     392                 :          0 :         ipv6_dev_mc_dec(dev, &maddr);
     393                 :            : }
     394                 :            : 
     395                 :            : /* called with rtnl held */
     396                 :          0 : static bool ndisc_allow_add(const struct net_device *dev,
     397                 :            :                             struct netlink_ext_ack *extack)
     398                 :            : {
     399                 :            :         struct inet6_dev *idev = __in6_dev_get(dev);
     400                 :            : 
     401   [ #  #  #  # ]:          0 :         if (!idev || idev->cnf.disable_ipv6) {
     402         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "IPv6 is disabled on this device");
     403                 :            :                 return false;
     404                 :            :         }
     405                 :            : 
     406                 :            :         return true;
     407                 :            : }
     408                 :            : 
     409                 :        392 : static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
     410                 :            :                                        int len)
     411                 :            : {
     412                 :        392 :         int hlen = LL_RESERVED_SPACE(dev);
     413                 :        392 :         int tlen = dev->needed_tailroom;
     414                 :        392 :         struct sock *sk = dev_net(dev)->ipv6.ndisc_sk;
     415                 :            :         struct sk_buff *skb;
     416                 :            : 
     417                 :        392 :         skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC);
     418         [ -  + ]:        392 :         if (!skb) {
     419         [ #  # ]:          0 :                 ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n",
     420                 :            :                           __func__);
     421                 :            :                 return NULL;
     422                 :            :         }
     423                 :            : 
     424                 :        392 :         skb->protocol = htons(ETH_P_IPV6);
     425                 :        392 :         skb->dev = dev;
     426                 :            : 
     427                 :        392 :         skb_reserve(skb, hlen + sizeof(struct ipv6hdr));
     428                 :            :         skb_reset_transport_header(skb);
     429                 :            : 
     430                 :            :         /* Manually assign socket ownership as we avoid calling
     431                 :            :          * sock_alloc_send_pskb() to bypass wmem buffer limits
     432                 :            :          */
     433                 :        392 :         skb_set_owner_w(skb, sk);
     434                 :            : 
     435                 :        392 :         return skb;
     436                 :            : }
     437                 :            : 
     438                 :        392 : static void ip6_nd_hdr(struct sk_buff *skb,
     439                 :            :                        const struct in6_addr *saddr,
     440                 :            :                        const struct in6_addr *daddr,
     441                 :            :                        int hop_limit, int len)
     442                 :            : {
     443                 :            :         struct ipv6hdr *hdr;
     444                 :            :         struct inet6_dev *idev;
     445                 :            :         unsigned tclass;
     446                 :            : 
     447                 :            :         rcu_read_lock();
     448                 :        392 :         idev = __in6_dev_get(skb->dev);
     449         [ +  - ]:        392 :         tclass = idev ? idev->cnf.ndisc_tclass : 0;
     450                 :            :         rcu_read_unlock();
     451                 :            : 
     452                 :        392 :         skb_push(skb, sizeof(*hdr));
     453                 :            :         skb_reset_network_header(skb);
     454                 :            :         hdr = ipv6_hdr(skb);
     455                 :            : 
     456                 :            :         ip6_flow_hdr(hdr, tclass, 0);
     457                 :            : 
     458                 :        392 :         hdr->payload_len = htons(len);
     459                 :        392 :         hdr->nexthdr = IPPROTO_ICMPV6;
     460                 :        392 :         hdr->hop_limit = hop_limit;
     461                 :            : 
     462                 :        392 :         hdr->saddr = *saddr;
     463                 :        392 :         hdr->daddr = *daddr;
     464                 :        392 : }
     465                 :            : 
     466                 :        392 : static void ndisc_send_skb(struct sk_buff *skb,
     467                 :            :                            const struct in6_addr *daddr,
     468                 :            :                            const struct in6_addr *saddr)
     469                 :            : {
     470                 :            :         struct dst_entry *dst = skb_dst(skb);
     471                 :        392 :         struct net *net = dev_net(skb->dev);
     472                 :        392 :         struct sock *sk = net->ipv6.ndisc_sk;
     473                 :            :         struct inet6_dev *idev;
     474                 :            :         int err;
     475                 :            :         struct icmp6hdr *icmp6h = icmp6_hdr(skb);
     476                 :            :         u8 type;
     477                 :            : 
     478                 :        392 :         type = icmp6h->icmp6_type;
     479                 :            : 
     480         [ +  - ]:        392 :         if (!dst) {
     481                 :            :                 struct flowi6 fl6;
     482                 :        392 :                 int oif = skb->dev->ifindex;
     483                 :            : 
     484                 :        392 :                 icmpv6_flow_init(sk, &fl6, type, saddr, daddr, oif);
     485                 :        392 :                 dst = icmp6_dst_alloc(skb->dev, &fl6);
     486         [ -  + ]:        392 :                 if (IS_ERR(dst)) {
     487                 :          0 :                         kfree_skb(skb);
     488                 :        392 :                         return;
     489                 :            :                 }
     490                 :            : 
     491                 :            :                 skb_dst_set(skb, dst);
     492                 :            :         }
     493                 :            : 
     494                 :        784 :         icmp6h->icmp6_cksum = csum_ipv6_magic(saddr, daddr, skb->len,
     495                 :            :                                               IPPROTO_ICMPV6,
     496                 :            :                                               csum_partial(icmp6h,
     497                 :        392 :                                                            skb->len, 0));
     498                 :            : 
     499                 :        392 :         ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, skb->len);
     500                 :            : 
     501                 :            :         rcu_read_lock();
     502                 :        392 :         idev = __in6_dev_get(dst->dev);
     503         [ +  - ]:       3920 :         IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
     504                 :            : 
     505                 :        392 :         err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
     506                 :            :                       net, sk, skb, NULL, dst->dev,
     507                 :            :                       dst_output);
     508         [ +  + ]:        392 :         if (!err) {
     509         [ +  - ]:        758 :                 ICMP6MSGOUT_INC_STATS(net, idev, type);
     510         [ +  - ]:       1137 :                 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
     511                 :            :         }
     512                 :            : 
     513                 :            :         rcu_read_unlock();
     514                 :            : }
     515                 :            : 
     516                 :          0 : void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
     517                 :            :                    const struct in6_addr *solicited_addr,
     518                 :            :                    bool router, bool solicited, bool override, bool inc_opt)
     519                 :            : {
     520                 :            :         struct sk_buff *skb;
     521                 :            :         struct in6_addr tmpaddr;
     522                 :            :         struct inet6_ifaddr *ifp;
     523                 :            :         const struct in6_addr *src_addr;
     524                 :            :         struct nd_msg *msg;
     525                 :            :         int optlen = 0;
     526                 :            : 
     527                 :            :         /* for anycast or proxy, solicited_addr != src_addr */
     528                 :          0 :         ifp = ipv6_get_ifaddr(dev_net(dev), solicited_addr, dev, 1);
     529         [ #  # ]:          0 :         if (ifp) {
     530                 :            :                 src_addr = solicited_addr;
     531         [ #  # ]:          0 :                 if (ifp->flags & IFA_F_OPTIMISTIC)
     532                 :            :                         override = false;
     533                 :          0 :                 inc_opt |= ifp->idev->cnf.force_tllao;
     534                 :          0 :                 in6_ifa_put(ifp);
     535                 :            :         } else {
     536         [ #  # ]:          0 :                 if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
     537                 :          0 :                                        inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
     538                 :            :                                        &tmpaddr))
     539                 :          0 :                         return;
     540                 :            :                 src_addr = &tmpaddr;
     541                 :            :         }
     542                 :            : 
     543         [ #  # ]:          0 :         if (!dev->addr_len)
     544                 :            :                 inc_opt = false;
     545         [ #  # ]:          0 :         if (inc_opt)
     546                 :          0 :                 optlen += ndisc_opt_addr_space(dev,
     547                 :            :                                                NDISC_NEIGHBOUR_ADVERTISEMENT);
     548                 :            : 
     549                 :          0 :         skb = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
     550         [ #  # ]:          0 :         if (!skb)
     551                 :            :                 return;
     552                 :            : 
     553                 :          0 :         msg = skb_put(skb, sizeof(*msg));
     554                 :          0 :         *msg = (struct nd_msg) {
     555                 :            :                 .icmph = {
     556                 :            :                         .icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT,
     557                 :            :                         .icmp6_router = router,
     558                 :            :                         .icmp6_solicited = solicited,
     559                 :            :                         .icmp6_override = override,
     560                 :            :                 },
     561                 :          0 :                 .target = *solicited_addr,
     562                 :            :         };
     563                 :            : 
     564         [ #  # ]:          0 :         if (inc_opt)
     565                 :          0 :                 ndisc_fill_addr_option(skb, ND_OPT_TARGET_LL_ADDR,
     566                 :          0 :                                        dev->dev_addr,
     567                 :            :                                        NDISC_NEIGHBOUR_ADVERTISEMENT);
     568                 :            : 
     569                 :          0 :         ndisc_send_skb(skb, daddr, src_addr);
     570                 :            : }
     571                 :            : 
     572                 :          0 : static void ndisc_send_unsol_na(struct net_device *dev)
     573                 :            : {
     574                 :            :         struct inet6_dev *idev;
     575                 :            :         struct inet6_ifaddr *ifa;
     576                 :            : 
     577                 :            :         idev = in6_dev_get(dev);
     578         [ #  # ]:          0 :         if (!idev)
     579                 :          0 :                 return;
     580                 :            : 
     581                 :          0 :         read_lock_bh(&idev->lock);
     582         [ #  # ]:          0 :         list_for_each_entry(ifa, &idev->addr_list, if_list) {
     583                 :            :                 /* skip tentative addresses until dad completes */
     584         [ #  # ]:          0 :                 if (ifa->flags & IFA_F_TENTATIVE &&
     585                 :            :                     !(ifa->flags & IFA_F_OPTIMISTIC))
     586                 :          0 :                         continue;
     587                 :            : 
     588                 :          0 :                 ndisc_send_na(dev, &in6addr_linklocal_allnodes, &ifa->addr,
     589                 :          0 :                               /*router=*/ !!idev->cnf.forwarding,
     590                 :            :                               /*solicited=*/ false, /*override=*/ true,
     591                 :            :                               /*inc_opt=*/ true);
     592                 :            :         }
     593                 :          0 :         read_unlock_bh(&idev->lock);
     594                 :            : 
     595                 :          0 :         in6_dev_put(idev);
     596                 :            : }
     597                 :            : 
     598                 :        392 : void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
     599                 :            :                    const struct in6_addr *daddr, const struct in6_addr *saddr,
     600                 :            :                    u64 nonce)
     601                 :            : {
     602                 :            :         struct sk_buff *skb;
     603                 :            :         struct in6_addr addr_buf;
     604                 :        392 :         int inc_opt = dev->addr_len;
     605                 :            :         int optlen = 0;
     606                 :            :         struct nd_msg *msg;
     607                 :            : 
     608         [ -  + ]:        392 :         if (!saddr) {
     609         [ #  # ]:          0 :                 if (ipv6_get_lladdr(dev, &addr_buf,
     610                 :            :                                    (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)))
     611                 :          0 :                         return;
     612                 :            :                 saddr = &addr_buf;
     613                 :            :         }
     614                 :            : 
     615         [ +  - ]:        392 :         if (ipv6_addr_any(saddr))
     616                 :            :                 inc_opt = false;
     617         [ -  + ]:        392 :         if (inc_opt)
     618                 :          0 :                 optlen += ndisc_opt_addr_space(dev,
     619                 :            :                                                NDISC_NEIGHBOUR_SOLICITATION);
     620         [ +  - ]:        392 :         if (nonce != 0)
     621                 :        392 :                 optlen += 8;
     622                 :            : 
     623                 :        392 :         skb = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
     624         [ +  - ]:        392 :         if (!skb)
     625                 :            :                 return;
     626                 :            : 
     627                 :        392 :         msg = skb_put(skb, sizeof(*msg));
     628                 :        392 :         *msg = (struct nd_msg) {
     629                 :            :                 .icmph = {
     630                 :            :                         .icmp6_type = NDISC_NEIGHBOUR_SOLICITATION,
     631                 :            :                 },
     632                 :        392 :                 .target = *solicit,
     633                 :            :         };
     634                 :            : 
     635         [ -  + ]:        392 :         if (inc_opt)
     636                 :          0 :                 ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR,
     637                 :          0 :                                        dev->dev_addr,
     638                 :            :                                        NDISC_NEIGHBOUR_SOLICITATION);
     639         [ +  - ]:        392 :         if (nonce != 0) {
     640                 :        392 :                 u8 *opt = skb_put(skb, 8);
     641                 :            : 
     642                 :        392 :                 opt[0] = ND_OPT_NONCE;
     643                 :        392 :                 opt[1] = 8 >> 3;
     644                 :        392 :                 memcpy(opt + 2, &nonce, 6);
     645                 :            :         }
     646                 :            : 
     647                 :        392 :         ndisc_send_skb(skb, daddr, saddr);
     648                 :            : }
     649                 :            : 
     650                 :          0 : void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
     651                 :            :                    const struct in6_addr *daddr)
     652                 :            : {
     653                 :            :         struct sk_buff *skb;
     654                 :            :         struct rs_msg *msg;
     655                 :          0 :         int send_sllao = dev->addr_len;
     656                 :            :         int optlen = 0;
     657                 :            : 
     658                 :            : #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
     659                 :            :         /*
     660                 :            :          * According to section 2.2 of RFC 4429, we must not
     661                 :            :          * send router solicitations with a sllao from
     662                 :            :          * optimistic addresses, but we may send the solicitation
     663                 :            :          * if we don't include the sllao.  So here we check
     664                 :            :          * if our address is optimistic, and if so, we
     665                 :            :          * suppress the inclusion of the sllao.
     666                 :            :          */
     667                 :            :         if (send_sllao) {
     668                 :            :                 struct inet6_ifaddr *ifp = ipv6_get_ifaddr(dev_net(dev), saddr,
     669                 :            :                                                            dev, 1);
     670                 :            :                 if (ifp) {
     671                 :            :                         if (ifp->flags & IFA_F_OPTIMISTIC)  {
     672                 :            :                                 send_sllao = 0;
     673                 :            :                         }
     674                 :            :                         in6_ifa_put(ifp);
     675                 :            :                 } else {
     676                 :            :                         send_sllao = 0;
     677                 :            :                 }
     678                 :            :         }
     679                 :            : #endif
     680         [ #  # ]:          0 :         if (send_sllao)
     681                 :          0 :                 optlen += ndisc_opt_addr_space(dev, NDISC_ROUTER_SOLICITATION);
     682                 :            : 
     683                 :          0 :         skb = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
     684         [ #  # ]:          0 :         if (!skb)
     685                 :          0 :                 return;
     686                 :            : 
     687                 :          0 :         msg = skb_put(skb, sizeof(*msg));
     688                 :          0 :         *msg = (struct rs_msg) {
     689                 :            :                 .icmph = {
     690                 :            :                         .icmp6_type = NDISC_ROUTER_SOLICITATION,
     691                 :            :                 },
     692                 :            :         };
     693                 :            : 
     694         [ #  # ]:          0 :         if (send_sllao)
     695                 :          0 :                 ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR,
     696                 :          0 :                                        dev->dev_addr,
     697                 :            :                                        NDISC_ROUTER_SOLICITATION);
     698                 :            : 
     699                 :          0 :         ndisc_send_skb(skb, daddr, saddr);
     700                 :            : }
     701                 :            : 
     702                 :            : 
     703                 :          0 : static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
     704                 :            : {
     705                 :            :         /*
     706                 :            :          *      "The sender MUST return an ICMP
     707                 :            :          *       destination unreachable"
     708                 :            :          */
     709                 :          0 :         dst_link_failure(skb);
     710                 :          0 :         kfree_skb(skb);
     711                 :          0 : }
     712                 :            : 
     713                 :            : /* Called with locked neigh: either read or both */
     714                 :            : 
     715                 :          0 : static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
     716                 :            : {
     717                 :            :         struct in6_addr *saddr = NULL;
     718                 :            :         struct in6_addr mcaddr;
     719                 :          0 :         struct net_device *dev = neigh->dev;
     720                 :          0 :         struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
     721                 :          0 :         int probes = atomic_read(&neigh->probes);
     722                 :            : 
     723   [ #  #  #  # ]:          0 :         if (skb && ipv6_chk_addr_and_flags(dev_net(dev), &ipv6_hdr(skb)->saddr,
     724                 :            :                                            dev, false, 1,
     725                 :            :                                            IFA_F_TENTATIVE|IFA_F_OPTIMISTIC))
     726                 :          0 :                 saddr = &ipv6_hdr(skb)->saddr;
     727                 :          0 :         probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES);
     728         [ #  # ]:          0 :         if (probes < 0) {
     729                 :            :                 if (!(neigh->nud_state & NUD_VALID)) {
     730                 :            :                         ND_PRINTK(1, dbg,
     731                 :            :                                   "%s: trying to ucast probe in NUD_INVALID: %pI6\n",
     732                 :            :                                   __func__, target);
     733                 :            :                 }
     734                 :          0 :                 ndisc_send_ns(dev, target, target, saddr, 0);
     735         [ #  # ]:          0 :         } else if ((probes -= NEIGH_VAR(neigh->parms, APP_PROBES)) < 0) {
     736                 :          0 :                 neigh_app_ns(neigh);
     737                 :            :         } else {
     738                 :            :                 addrconf_addr_solict_mult(target, &mcaddr);
     739                 :          0 :                 ndisc_send_ns(dev, target, &mcaddr, saddr, 0);
     740                 :            :         }
     741                 :          0 : }
     742                 :            : 
     743                 :          0 : static int pndisc_is_router(const void *pkey,
     744                 :            :                             struct net_device *dev)
     745                 :            : {
     746                 :            :         struct pneigh_entry *n;
     747                 :            :         int ret = -1;
     748                 :            : 
     749                 :          0 :         read_lock_bh(&nd_tbl.lock);
     750                 :          0 :         n = __pneigh_lookup(&nd_tbl, dev_net(dev), pkey, dev);
     751         [ #  # ]:          0 :         if (n)
     752                 :          0 :                 ret = !!(n->flags & NTF_ROUTER);
     753                 :          0 :         read_unlock_bh(&nd_tbl.lock);
     754                 :            : 
     755                 :          0 :         return ret;
     756                 :            : }
     757                 :            : 
     758                 :          0 : void ndisc_update(const struct net_device *dev, struct neighbour *neigh,
     759                 :            :                   const u8 *lladdr, u8 new, u32 flags, u8 icmp6_type,
     760                 :            :                   struct ndisc_options *ndopts)
     761                 :            : {
     762                 :          0 :         neigh_update(neigh, lladdr, new, flags, 0);
     763                 :            :         /* report ndisc ops about neighbour update */
     764                 :            :         ndisc_ops_update(dev, neigh, flags, icmp6_type, ndopts);
     765                 :          0 : }
     766                 :            : 
     767                 :          0 : static void ndisc_recv_ns(struct sk_buff *skb)
     768                 :            : {
     769                 :            :         struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
     770                 :          0 :         const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
     771                 :            :         const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
     772                 :            :         u8 *lladdr = NULL;
     773                 :          0 :         u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) +
     774                 :            :                                     offsetof(struct nd_msg, opt));
     775                 :            :         struct ndisc_options ndopts;
     776                 :          0 :         struct net_device *dev = skb->dev;
     777                 :            :         struct inet6_ifaddr *ifp;
     778                 :            :         struct inet6_dev *idev = NULL;
     779                 :            :         struct neighbour *neigh;
     780                 :          0 :         int dad = ipv6_addr_any(saddr);
     781                 :            :         bool inc;
     782                 :            :         int is_router = -1;
     783                 :          0 :         u64 nonce = 0;
     784                 :            : 
     785         [ #  # ]:          0 :         if (skb->len < sizeof(struct nd_msg)) {
     786                 :            :                 ND_PRINTK(2, warn, "NS: packet too short\n");
     787                 :          0 :                 return;
     788                 :            :         }
     789                 :            : 
     790         [ #  # ]:          0 :         if (ipv6_addr_is_multicast(&msg->target)) {
     791                 :            :                 ND_PRINTK(2, warn, "NS: multicast target address\n");
     792                 :            :                 return;
     793                 :            :         }
     794                 :            : 
     795                 :            :         /*
     796                 :            :          * RFC2461 7.1.1:
     797                 :            :          * DAD has to be destined for solicited node multicast address.
     798                 :            :          */
     799   [ #  #  #  # ]:          0 :         if (dad && !ipv6_addr_is_solict_mult(daddr)) {
     800                 :            :                 ND_PRINTK(2, warn, "NS: bad DAD packet (wrong destination)\n");
     801                 :            :                 return;
     802                 :            :         }
     803                 :            : 
     804         [ #  # ]:          0 :         if (!ndisc_parse_options(dev, msg->opt, ndoptlen, &ndopts)) {
     805                 :            :                 ND_PRINTK(2, warn, "NS: invalid ND options\n");
     806                 :            :                 return;
     807                 :            :         }
     808                 :            : 
     809         [ #  # ]:          0 :         if (ndopts.nd_opts_src_lladdr) {
     810                 :            :                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, dev);
     811         [ #  # ]:          0 :                 if (!lladdr) {
     812                 :            :                         ND_PRINTK(2, warn,
     813                 :            :                                   "NS: invalid link-layer address length\n");
     814                 :            :                         return;
     815                 :            :                 }
     816                 :            : 
     817                 :            :                 /* RFC2461 7.1.1:
     818                 :            :                  *      If the IP source address is the unspecified address,
     819                 :            :                  *      there MUST NOT be source link-layer address option
     820                 :            :                  *      in the message.
     821                 :            :                  */
     822         [ #  # ]:          0 :                 if (dad) {
     823                 :            :                         ND_PRINTK(2, warn,
     824                 :            :                                   "NS: bad DAD packet (link-layer address option)\n");
     825                 :            :                         return;
     826                 :            :                 }
     827                 :            :         }
     828   [ #  #  #  # ]:          0 :         if (ndopts.nd_opts_nonce && ndopts.nd_opts_nonce->nd_opt_len == 1)
     829                 :          0 :                 memcpy(&nonce, (u8 *)(ndopts.nd_opts_nonce + 1), 6);
     830                 :            : 
     831                 :            :         inc = ipv6_addr_is_multicast(daddr);
     832                 :            : 
     833                 :          0 :         ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
     834         [ #  # ]:          0 :         if (ifp) {
     835                 :            : have_ifp:
     836         [ #  # ]:          0 :                 if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) {
     837         [ #  # ]:          0 :                         if (dad) {
     838   [ #  #  #  # ]:          0 :                                 if (nonce != 0 && ifp->dad_nonce == nonce) {
     839                 :            :                                         u8 *np = (u8 *)&nonce;
     840                 :            :                                         /* Matching nonce if looped back */
     841                 :            :                                         ND_PRINTK(2, notice,
     842                 :            :                                                   "%s: IPv6 DAD loopback for address %pI6c nonce %pM ignored\n",
     843                 :            :                                                   ifp->idev->dev->name,
     844                 :            :                                                   &ifp->addr, np);
     845                 :            :                                         goto out;
     846                 :            :                                 }
     847                 :            :                                 /*
     848                 :            :                                  * We are colliding with another node
     849                 :            :                                  * who is doing DAD
     850                 :            :                                  * so fail our DAD process
     851                 :            :                                  */
     852                 :          0 :                                 addrconf_dad_failure(skb, ifp);
     853                 :          0 :                                 return;
     854                 :            :                         } else {
     855                 :            :                                 /*
     856                 :            :                                  * This is not a dad solicitation.
     857                 :            :                                  * If we are an optimistic node,
     858                 :            :                                  * we should respond.
     859                 :            :                                  * Otherwise, we should ignore it.
     860                 :            :                                  */
     861         [ #  # ]:          0 :                                 if (!(ifp->flags & IFA_F_OPTIMISTIC))
     862                 :            :                                         goto out;
     863                 :            :                         }
     864                 :            :                 }
     865                 :            : 
     866                 :          0 :                 idev = ifp->idev;
     867                 :            :         } else {
     868                 :            :                 struct net *net = dev_net(dev);
     869                 :            : 
     870                 :            :                 /* perhaps an address on the master device */
     871         [ #  # ]:          0 :                 if (netif_is_l3_slave(dev)) {
     872                 :            :                         struct net_device *mdev;
     873                 :            : 
     874                 :          0 :                         mdev = netdev_master_upper_dev_get_rcu(dev);
     875         [ #  # ]:          0 :                         if (mdev) {
     876                 :          0 :                                 ifp = ipv6_get_ifaddr(net, &msg->target, mdev, 1);
     877         [ #  # ]:          0 :                                 if (ifp)
     878                 :            :                                         goto have_ifp;
     879                 :            :                         }
     880                 :            :                 }
     881                 :            : 
     882                 :            :                 idev = in6_dev_get(dev);
     883         [ #  # ]:          0 :                 if (!idev) {
     884                 :            :                         /* XXX: count this drop? */
     885                 :            :                         return;
     886                 :            :                 }
     887                 :            : 
     888   [ #  #  #  # ]:          0 :                 if (ipv6_chk_acast_addr(net, dev, &msg->target) ||
     889         [ #  # ]:          0 :                     (idev->cnf.forwarding &&
     890   [ #  #  #  # ]:          0 :                      (net->ipv6.devconf_all->proxy_ndp || idev->cnf.proxy_ndp) &&
     891                 :            :                      (is_router = pndisc_is_router(&msg->target, dev)) >= 0)) {
     892   [ #  #  #  # ]:          0 :                         if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
     893         [ #  # ]:          0 :                             skb->pkt_type != PACKET_HOST &&
     894         [ #  # ]:          0 :                             inc &&
     895                 :          0 :                             NEIGH_VAR(idev->nd_parms, PROXY_DELAY) != 0) {
     896                 :            :                                 /*
     897                 :            :                                  * for anycast or proxy,
     898                 :            :                                  * sender should delay its response
     899                 :            :                                  * by a random time between 0 and
     900                 :            :                                  * MAX_ANYCAST_DELAY_TIME seconds.
     901                 :            :                                  * (RFC2461) -- yoshfuji
     902                 :            :                                  */
     903                 :          0 :                                 struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
     904         [ #  # ]:          0 :                                 if (n)
     905                 :          0 :                                         pneigh_enqueue(&nd_tbl, idev->nd_parms, n);
     906                 :            :                                 goto out;
     907                 :            :                         }
     908                 :            :                 } else
     909                 :            :                         goto out;
     910                 :            :         }
     911                 :            : 
     912         [ #  # ]:          0 :         if (is_router < 0)
     913                 :          0 :                 is_router = idev->cnf.forwarding;
     914                 :            : 
     915         [ #  # ]:          0 :         if (dad) {
     916                 :          0 :                 ndisc_send_na(dev, &in6addr_linklocal_allnodes, &msg->target,
     917                 :            :                               !!is_router, false, (ifp != NULL), true);
     918                 :          0 :                 goto out;
     919                 :            :         }
     920                 :            : 
     921         [ #  # ]:          0 :         if (inc)
     922                 :          0 :                 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_mcast);
     923                 :            :         else
     924                 :          0 :                 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_ucast);
     925                 :            : 
     926                 :            :         /*
     927                 :            :          *      update / create cache entry
     928                 :            :          *      for the source address
     929                 :            :          */
     930   [ #  #  #  # ]:          0 :         neigh = __neigh_lookup(&nd_tbl, saddr, dev,
     931                 :          0 :                                !inc || lladdr || !dev->addr_len);
     932         [ #  # ]:          0 :         if (neigh)
     933                 :          0 :                 ndisc_update(dev, neigh, lladdr, NUD_STALE,
     934                 :            :                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
     935                 :            :                              NEIGH_UPDATE_F_OVERRIDE,
     936                 :            :                              NDISC_NEIGHBOUR_SOLICITATION, &ndopts);
     937   [ #  #  #  # ]:          0 :         if (neigh || !dev->header_ops) {
     938                 :          0 :                 ndisc_send_na(dev, saddr, &msg->target, !!is_router,
     939                 :          0 :                               true, (ifp != NULL && inc), inc);
     940         [ #  # ]:          0 :                 if (neigh)
     941                 :          0 :                         neigh_release(neigh);
     942                 :            :         }
     943                 :            : 
     944                 :            : out:
     945         [ #  # ]:          0 :         if (ifp)
     946                 :          0 :                 in6_ifa_put(ifp);
     947                 :            :         else
     948                 :          0 :                 in6_dev_put(idev);
     949                 :            : }
     950                 :            : 
     951                 :          0 : static void ndisc_recv_na(struct sk_buff *skb)
     952                 :            : {
     953                 :            :         struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
     954                 :          0 :         struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
     955                 :            :         const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
     956                 :            :         u8 *lladdr = NULL;
     957                 :          0 :         u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) +
     958                 :            :                                     offsetof(struct nd_msg, opt));
     959                 :            :         struct ndisc_options ndopts;
     960                 :          0 :         struct net_device *dev = skb->dev;
     961                 :            :         struct inet6_dev *idev = __in6_dev_get(dev);
     962                 :            :         struct inet6_ifaddr *ifp;
     963                 :            :         struct neighbour *neigh;
     964                 :            : 
     965         [ #  # ]:          0 :         if (skb->len < sizeof(struct nd_msg)) {
     966                 :            :                 ND_PRINTK(2, warn, "NA: packet too short\n");
     967                 :          0 :                 return;
     968                 :            :         }
     969                 :            : 
     970         [ #  # ]:          0 :         if (ipv6_addr_is_multicast(&msg->target)) {
     971                 :            :                 ND_PRINTK(2, warn, "NA: target address is multicast\n");
     972                 :            :                 return;
     973                 :            :         }
     974                 :            : 
     975   [ #  #  #  # ]:          0 :         if (ipv6_addr_is_multicast(daddr) &&
     976                 :            :             msg->icmph.icmp6_solicited) {
     977                 :            :                 ND_PRINTK(2, warn, "NA: solicited NA is multicasted\n");
     978                 :            :                 return;
     979                 :            :         }
     980                 :            : 
     981                 :            :         /* For some 802.11 wireless deployments (and possibly other networks),
     982                 :            :          * there will be a NA proxy and unsolicitd packets are attacks
     983                 :            :          * and thus should not be accepted.
     984                 :            :          */
     985   [ #  #  #  #  :          0 :         if (!msg->icmph.icmp6_solicited && idev &&
                   #  # ]
     986                 :          0 :             idev->cnf.drop_unsolicited_na)
     987                 :            :                 return;
     988                 :            : 
     989         [ #  # ]:          0 :         if (!ndisc_parse_options(dev, msg->opt, ndoptlen, &ndopts)) {
     990                 :            :                 ND_PRINTK(2, warn, "NS: invalid ND option\n");
     991                 :            :                 return;
     992                 :            :         }
     993         [ #  # ]:          0 :         if (ndopts.nd_opts_tgt_lladdr) {
     994                 :            :                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, dev);
     995         [ #  # ]:          0 :                 if (!lladdr) {
     996                 :            :                         ND_PRINTK(2, warn,
     997                 :            :                                   "NA: invalid link-layer address length\n");
     998                 :            :                         return;
     999                 :            :                 }
    1000                 :            :         }
    1001                 :          0 :         ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
    1002         [ #  # ]:          0 :         if (ifp) {
    1003         [ #  # ]:          0 :                 if (skb->pkt_type != PACKET_LOOPBACK
    1004         [ #  # ]:          0 :                     && (ifp->flags & IFA_F_TENTATIVE)) {
    1005                 :          0 :                                 addrconf_dad_failure(skb, ifp);
    1006                 :          0 :                                 return;
    1007                 :            :                 }
    1008                 :            :                 /* What should we make now? The advertisement
    1009                 :            :                    is invalid, but ndisc specs say nothing
    1010                 :            :                    about it. It could be misconfiguration, or
    1011                 :            :                    an smart proxy agent tries to help us :-)
    1012                 :            : 
    1013                 :            :                    We should not print the error if NA has been
    1014                 :            :                    received from loopback - it is just our own
    1015                 :            :                    unsolicited advertisement.
    1016                 :            :                  */
    1017         [ #  # ]:          0 :                 if (skb->pkt_type != PACKET_LOOPBACK)
    1018         [ #  # ]:          0 :                         ND_PRINTK(1, warn,
    1019                 :            :                                   "NA: %pM advertised our address %pI6c on %s!\n",
    1020                 :            :                                   eth_hdr(skb)->h_source, &ifp->addr, ifp->idev->dev->name);
    1021                 :          0 :                 in6_ifa_put(ifp);
    1022                 :          0 :                 return;
    1023                 :            :         }
    1024                 :          0 :         neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
    1025                 :            : 
    1026         [ #  # ]:          0 :         if (neigh) {
    1027                 :          0 :                 u8 old_flags = neigh->flags;
    1028                 :            :                 struct net *net = dev_net(dev);
    1029                 :            : 
    1030         [ #  # ]:          0 :                 if (neigh->nud_state & NUD_FAILED)
    1031                 :            :                         goto out;
    1032                 :            : 
    1033                 :            :                 /*
    1034                 :            :                  * Don't update the neighbor cache entry on a proxy NA from
    1035                 :            :                  * ourselves because either the proxied node is off link or it
    1036                 :            :                  * has already sent a NA to us.
    1037                 :            :                  */
    1038   [ #  #  #  #  :          0 :                 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
                   #  # ]
    1039   [ #  #  #  # ]:          0 :                     net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp &&
    1040                 :          0 :                     pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) {
    1041                 :            :                         /* XXX: idev->cnf.proxy_ndp */
    1042                 :            :                         goto out;
    1043                 :            :                 }
    1044                 :            : 
    1045         [ #  # ]:          0 :                 ndisc_update(dev, neigh, lladdr,
    1046                 :          0 :                              msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
    1047                 :            :                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
    1048         [ #  # ]:          0 :                              (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0)|
    1049                 :          0 :                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
    1050         [ #  # ]:          0 :                              (msg->icmph.icmp6_router ? NEIGH_UPDATE_F_ISROUTER : 0),
    1051                 :            :                              NDISC_NEIGHBOUR_ADVERTISEMENT, &ndopts);
    1052                 :            : 
    1053         [ #  # ]:          0 :                 if ((old_flags & ~neigh->flags) & NTF_ROUTER) {
    1054                 :            :                         /*
    1055                 :            :                          * Change: router to host
    1056                 :            :                          */
    1057                 :          0 :                         rt6_clean_tohost(dev_net(dev),  saddr);
    1058                 :            :                 }
    1059                 :            : 
    1060                 :            : out:
    1061                 :          0 :                 neigh_release(neigh);
    1062                 :            :         }
    1063                 :            : }
    1064                 :            : 
    1065                 :          0 : static void ndisc_recv_rs(struct sk_buff *skb)
    1066                 :            : {
    1067                 :            :         struct rs_msg *rs_msg = (struct rs_msg *)skb_transport_header(skb);
    1068                 :          0 :         unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
    1069                 :            :         struct neighbour *neigh;
    1070                 :            :         struct inet6_dev *idev;
    1071                 :          0 :         const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
    1072                 :            :         struct ndisc_options ndopts;
    1073                 :            :         u8 *lladdr = NULL;
    1074                 :            : 
    1075         [ #  # ]:          0 :         if (skb->len < sizeof(*rs_msg))
    1076                 :            :                 return;
    1077                 :            : 
    1078                 :          0 :         idev = __in6_dev_get(skb->dev);
    1079         [ #  # ]:          0 :         if (!idev) {
    1080         [ #  # ]:          0 :                 ND_PRINTK(1, err, "RS: can't find in6 device\n");
    1081                 :            :                 return;
    1082                 :            :         }
    1083                 :            : 
    1084                 :            :         /* Don't accept RS if we're not in router mode */
    1085         [ #  # ]:          0 :         if (!idev->cnf.forwarding)
    1086                 :            :                 goto out;
    1087                 :            : 
    1088                 :            :         /*
    1089                 :            :          * Don't update NCE if src = ::;
    1090                 :            :          * this implies that the source node has no ip address assigned yet.
    1091                 :            :          */
    1092         [ #  # ]:          0 :         if (ipv6_addr_any(saddr))
    1093                 :            :                 goto out;
    1094                 :            : 
    1095                 :            :         /* Parse ND options */
    1096         [ #  # ]:          0 :         if (!ndisc_parse_options(skb->dev, rs_msg->opt, ndoptlen, &ndopts)) {
    1097                 :            :                 ND_PRINTK(2, notice, "NS: invalid ND option, ignored\n");
    1098                 :            :                 goto out;
    1099                 :            :         }
    1100                 :            : 
    1101         [ #  # ]:          0 :         if (ndopts.nd_opts_src_lladdr) {
    1102                 :          0 :                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
    1103                 :            :                                              skb->dev);
    1104         [ #  # ]:          0 :                 if (!lladdr)
    1105                 :            :                         goto out;
    1106                 :            :         }
    1107                 :            : 
    1108                 :          0 :         neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
    1109         [ #  # ]:          0 :         if (neigh) {
    1110                 :          0 :                 ndisc_update(skb->dev, neigh, lladdr, NUD_STALE,
    1111                 :            :                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
    1112                 :            :                              NEIGH_UPDATE_F_OVERRIDE|
    1113                 :            :                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER,
    1114                 :            :                              NDISC_ROUTER_SOLICITATION, &ndopts);
    1115                 :          0 :                 neigh_release(neigh);
    1116                 :            :         }
    1117                 :            : out:
    1118                 :            :         return;
    1119                 :            : }
    1120                 :            : 
    1121                 :          0 : static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
    1122                 :            : {
    1123                 :            :         struct icmp6hdr *icmp6h = (struct icmp6hdr *)skb_transport_header(ra);
    1124                 :            :         struct sk_buff *skb;
    1125                 :            :         struct nlmsghdr *nlh;
    1126                 :            :         struct nduseroptmsg *ndmsg;
    1127                 :          0 :         struct net *net = dev_net(ra->dev);
    1128                 :            :         int err;
    1129                 :          0 :         int base_size = NLMSG_ALIGN(sizeof(struct nduseroptmsg)
    1130                 :            :                                     + (opt->nd_opt_len << 3));
    1131                 :          0 :         size_t msg_size = base_size + nla_total_size(sizeof(struct in6_addr));
    1132                 :            : 
    1133                 :            :         skb = nlmsg_new(msg_size, GFP_ATOMIC);
    1134         [ #  # ]:          0 :         if (!skb) {
    1135                 :            :                 err = -ENOBUFS;
    1136                 :            :                 goto errout;
    1137                 :            :         }
    1138                 :            : 
    1139                 :          0 :         nlh = nlmsg_put(skb, 0, 0, RTM_NEWNDUSEROPT, base_size, 0);
    1140         [ #  # ]:          0 :         if (!nlh) {
    1141                 :            :                 goto nla_put_failure;
    1142                 :            :         }
    1143                 :            : 
    1144                 :            :         ndmsg = nlmsg_data(nlh);
    1145                 :          0 :         ndmsg->nduseropt_family = AF_INET6;
    1146                 :          0 :         ndmsg->nduseropt_ifindex = ra->dev->ifindex;
    1147                 :          0 :         ndmsg->nduseropt_icmp_type = icmp6h->icmp6_type;
    1148                 :          0 :         ndmsg->nduseropt_icmp_code = icmp6h->icmp6_code;
    1149                 :          0 :         ndmsg->nduseropt_opts_len = opt->nd_opt_len << 3;
    1150                 :            : 
    1151                 :          0 :         memcpy(ndmsg + 1, opt, opt->nd_opt_len << 3);
    1152                 :            : 
    1153         [ #  # ]:          0 :         if (nla_put_in6_addr(skb, NDUSEROPT_SRCADDR, &ipv6_hdr(ra)->saddr))
    1154                 :            :                 goto nla_put_failure;
    1155                 :            :         nlmsg_end(skb, nlh);
    1156                 :            : 
    1157                 :          0 :         rtnl_notify(skb, net, 0, RTNLGRP_ND_USEROPT, NULL, GFP_ATOMIC);
    1158                 :          0 :         return;
    1159                 :            : 
    1160                 :            : nla_put_failure:
    1161                 :            :         nlmsg_free(skb);
    1162                 :            :         err = -EMSGSIZE;
    1163                 :            : errout:
    1164                 :          0 :         rtnl_set_sk_err(net, RTNLGRP_ND_USEROPT, err);
    1165                 :            : }
    1166                 :            : 
    1167                 :          0 : static void ndisc_router_discovery(struct sk_buff *skb)
    1168                 :            : {
    1169                 :            :         struct ra_msg *ra_msg = (struct ra_msg *)skb_transport_header(skb);
    1170                 :            :         struct neighbour *neigh = NULL;
    1171                 :            :         struct inet6_dev *in6_dev;
    1172                 :            :         struct fib6_info *rt = NULL;
    1173                 :            :         struct net *net;
    1174                 :            :         int lifetime;
    1175                 :            :         struct ndisc_options ndopts;
    1176                 :            :         int optlen;
    1177                 :            :         unsigned int pref = 0;
    1178                 :            :         __u32 old_if_flags;
    1179                 :            :         bool send_ifinfo_notify = false;
    1180                 :            : 
    1181                 :          0 :         __u8 *opt = (__u8 *)(ra_msg + 1);
    1182                 :            : 
    1183                 :          0 :         optlen = (skb_tail_pointer(skb) - skb_transport_header(skb)) -
    1184                 :            :                 sizeof(struct ra_msg);
    1185                 :            : 
    1186                 :            :         ND_PRINTK(2, info,
    1187                 :            :                   "RA: %s, dev: %s\n",
    1188                 :            :                   __func__, skb->dev->name);
    1189         [ #  # ]:          0 :         if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
    1190                 :            :                 ND_PRINTK(2, warn, "RA: source address is not link-local\n");
    1191                 :          0 :                 return;
    1192                 :            :         }
    1193         [ #  # ]:          0 :         if (optlen < 0) {
    1194                 :            :                 ND_PRINTK(2, warn, "RA: packet too short\n");
    1195                 :            :                 return;
    1196                 :            :         }
    1197                 :            : 
    1198                 :            : #ifdef CONFIG_IPV6_NDISC_NODETYPE
    1199         [ #  # ]:          0 :         if (skb->ndisc_nodetype == NDISC_NODETYPE_HOST) {
    1200                 :            :                 ND_PRINTK(2, warn, "RA: from host or unauthorized router\n");
    1201                 :            :                 return;
    1202                 :            :         }
    1203                 :            : #endif
    1204                 :            : 
    1205                 :            :         /*
    1206                 :            :          *      set the RA_RECV flag in the interface
    1207                 :            :          */
    1208                 :            : 
    1209                 :          0 :         in6_dev = __in6_dev_get(skb->dev);
    1210         [ #  # ]:          0 :         if (!in6_dev) {
    1211         [ #  # ]:          0 :                 ND_PRINTK(0, err, "RA: can't find inet6 device for %s\n",
    1212                 :            :                           skb->dev->name);
    1213                 :            :                 return;
    1214                 :            :         }
    1215                 :            : 
    1216         [ #  # ]:          0 :         if (!ndisc_parse_options(skb->dev, opt, optlen, &ndopts)) {
    1217                 :            :                 ND_PRINTK(2, warn, "RA: invalid ND options\n");
    1218                 :            :                 return;
    1219                 :            :         }
    1220                 :            : 
    1221         [ #  # ]:          0 :         if (!ipv6_accept_ra(in6_dev)) {
    1222                 :            :                 ND_PRINTK(2, info,
    1223                 :            :                           "RA: %s, did not accept ra for dev: %s\n",
    1224                 :            :                           __func__, skb->dev->name);
    1225                 :            :                 goto skip_linkparms;
    1226                 :            :         }
    1227                 :            : 
    1228                 :            : #ifdef CONFIG_IPV6_NDISC_NODETYPE
    1229                 :            :         /* skip link-specific parameters from interior routers */
    1230         [ #  # ]:          0 :         if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) {
    1231                 :            :                 ND_PRINTK(2, info,
    1232                 :            :                           "RA: %s, nodetype is NODEFAULT, dev: %s\n",
    1233                 :            :                           __func__, skb->dev->name);
    1234                 :            :                 goto skip_linkparms;
    1235                 :            :         }
    1236                 :            : #endif
    1237                 :            : 
    1238         [ #  # ]:          0 :         if (in6_dev->if_flags & IF_RS_SENT) {
    1239                 :            :                 /*
    1240                 :            :                  *      flag that an RA was received after an RS was sent
    1241                 :            :                  *      out on this interface.
    1242                 :            :                  */
    1243                 :          0 :                 in6_dev->if_flags |= IF_RA_RCVD;
    1244                 :            :         }
    1245                 :            : 
    1246                 :            :         /*
    1247                 :            :          * Remember the managed/otherconf flags from most recently
    1248                 :            :          * received RA message (RFC 2462) -- yoshfuji
    1249                 :            :          */
    1250                 :          0 :         old_if_flags = in6_dev->if_flags;
    1251                 :          0 :         in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
    1252         [ #  # ]:          0 :                                 IF_RA_OTHERCONF)) |
    1253                 :          0 :                                 (ra_msg->icmph.icmp6_addrconf_managed ?
    1254         [ #  # ]:          0 :                                         IF_RA_MANAGED : 0) |
    1255                 :          0 :                                 (ra_msg->icmph.icmp6_addrconf_other ?
    1256                 :            :                                         IF_RA_OTHERCONF : 0);
    1257                 :            : 
    1258         [ #  # ]:          0 :         if (old_if_flags != in6_dev->if_flags)
    1259                 :            :                 send_ifinfo_notify = true;
    1260                 :            : 
    1261         [ #  # ]:          0 :         if (!in6_dev->cnf.accept_ra_defrtr) {
    1262                 :            :                 ND_PRINTK(2, info,
    1263                 :            :                           "RA: %s, defrtr is false for dev: %s\n",
    1264                 :            :                           __func__, skb->dev->name);
    1265                 :            :                 goto skip_defrtr;
    1266                 :            :         }
    1267                 :            : 
    1268                 :            :         /* Do not accept RA with source-addr found on local machine unless
    1269                 :            :          * accept_ra_from_local is set to true.
    1270                 :            :          */
    1271                 :          0 :         net = dev_net(in6_dev->dev);
    1272   [ #  #  #  # ]:          0 :         if (!in6_dev->cnf.accept_ra_from_local &&
    1273                 :          0 :             ipv6_chk_addr(net, &ipv6_hdr(skb)->saddr, in6_dev->dev, 0)) {
    1274                 :            :                 ND_PRINTK(2, info,
    1275                 :            :                           "RA from local address detected on dev: %s: default router ignored\n",
    1276                 :            :                           skb->dev->name);
    1277                 :            :                 goto skip_defrtr;
    1278                 :            :         }
    1279                 :            : 
    1280                 :          0 :         lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
    1281                 :            : 
    1282                 :            : #ifdef CONFIG_IPV6_ROUTER_PREF
    1283                 :          0 :         pref = ra_msg->icmph.icmp6_router_pref;
    1284                 :            :         /* 10b is handled as if it were 00b (medium) */
    1285   [ #  #  #  # ]:          0 :         if (pref == ICMPV6_ROUTER_PREF_INVALID ||
    1286                 :          0 :             !in6_dev->cnf.accept_ra_rtr_pref)
    1287                 :            :                 pref = ICMPV6_ROUTER_PREF_MEDIUM;
    1288                 :            : #endif
    1289                 :            :         /* routes added from RAs do not use nexthop objects */
    1290                 :          0 :         rt = rt6_get_dflt_router(net, &ipv6_hdr(skb)->saddr, skb->dev);
    1291         [ #  # ]:          0 :         if (rt) {
    1292                 :          0 :                 neigh = ip6_neigh_lookup(&rt->fib6_nh->fib_nh_gw6,
    1293                 :            :                                          rt->fib6_nh->fib_nh_dev, NULL,
    1294                 :          0 :                                           &ipv6_hdr(skb)->saddr);
    1295         [ #  # ]:          0 :                 if (!neigh) {
    1296         [ #  # ]:          0 :                         ND_PRINTK(0, err,
    1297                 :            :                                   "RA: %s got default router without neighbour\n",
    1298                 :            :                                   __func__);
    1299                 :          0 :                         fib6_info_release(rt);
    1300                 :          0 :                         return;
    1301                 :            :                 }
    1302                 :            :         }
    1303         [ #  # ]:          0 :         if (rt && lifetime == 0) {
    1304                 :          0 :                 ip6_del_rt(net, rt);
    1305                 :            :                 rt = NULL;
    1306                 :            :         }
    1307                 :            : 
    1308                 :            :         ND_PRINTK(3, info, "RA: rt: %p  lifetime: %d, for dev: %s\n",
    1309                 :            :                   rt, lifetime, skb->dev->name);
    1310         [ #  # ]:          0 :         if (!rt && lifetime) {
    1311                 :            :                 ND_PRINTK(3, info, "RA: adding default router\n");
    1312                 :            : 
    1313                 :          0 :                 rt = rt6_add_dflt_router(net, &ipv6_hdr(skb)->saddr,
    1314                 :            :                                          skb->dev, pref);
    1315         [ #  # ]:          0 :                 if (!rt) {
    1316         [ #  # ]:          0 :                         ND_PRINTK(0, err,
    1317                 :            :                                   "RA: %s failed to add default route\n",
    1318                 :            :                                   __func__);
    1319                 :            :                         return;
    1320                 :            :                 }
    1321                 :            : 
    1322                 :          0 :                 neigh = ip6_neigh_lookup(&rt->fib6_nh->fib_nh_gw6,
    1323                 :            :                                          rt->fib6_nh->fib_nh_dev, NULL,
    1324                 :          0 :                                           &ipv6_hdr(skb)->saddr);
    1325         [ #  # ]:          0 :                 if (!neigh) {
    1326         [ #  # ]:          0 :                         ND_PRINTK(0, err,
    1327                 :            :                                   "RA: %s got default router without neighbour\n",
    1328                 :            :                                   __func__);
    1329                 :          0 :                         fib6_info_release(rt);
    1330                 :          0 :                         return;
    1331                 :            :                 }
    1332                 :          0 :                 neigh->flags |= NTF_ROUTER;
    1333         [ #  # ]:          0 :         } else if (rt) {
    1334                 :          0 :                 rt->fib6_flags = (rt->fib6_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
    1335                 :            :         }
    1336                 :            : 
    1337         [ #  # ]:          0 :         if (rt)
    1338                 :          0 :                 fib6_set_expires(rt, jiffies + (HZ * lifetime));
    1339   [ #  #  #  # ]:          0 :         if (in6_dev->cnf.accept_ra_min_hop_limit < 256 &&
    1340                 :          0 :             ra_msg->icmph.icmp6_hop_limit) {
    1341         [ #  # ]:          0 :                 if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) {
    1342                 :          0 :                         in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
    1343                 :          0 :                         fib6_metric_set(rt, RTAX_HOPLIMIT,
    1344                 :          0 :                                         ra_msg->icmph.icmp6_hop_limit);
    1345                 :            :                 } else {
    1346                 :            :                         ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than minimum\n");
    1347                 :            :                 }
    1348                 :            :         }
    1349                 :            : 
    1350                 :            : skip_defrtr:
    1351                 :            : 
    1352                 :            :         /*
    1353                 :            :          *      Update Reachable Time and Retrans Timer
    1354                 :            :          */
    1355                 :            : 
    1356         [ #  # ]:          0 :         if (in6_dev->nd_parms) {
    1357                 :          0 :                 unsigned long rtime = ntohl(ra_msg->retrans_timer);
    1358                 :            : 
    1359         [ #  # ]:          0 :                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
    1360                 :          0 :                         rtime = (rtime*HZ)/1000;
    1361         [ #  # ]:          0 :                         if (rtime < HZ/10)
    1362                 :            :                                 rtime = HZ/10;
    1363                 :          0 :                         NEIGH_VAR_SET(in6_dev->nd_parms, RETRANS_TIME, rtime);
    1364                 :          0 :                         in6_dev->tstamp = jiffies;
    1365                 :            :                         send_ifinfo_notify = true;
    1366                 :            :                 }
    1367                 :            : 
    1368                 :          0 :                 rtime = ntohl(ra_msg->reachable_time);
    1369         [ #  # ]:          0 :                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
    1370                 :          0 :                         rtime = (rtime*HZ)/1000;
    1371                 :            : 
    1372         [ #  # ]:          0 :                         if (rtime < HZ/10)
    1373                 :            :                                 rtime = HZ/10;
    1374                 :            : 
    1375         [ #  # ]:          0 :                         if (rtime != NEIGH_VAR(in6_dev->nd_parms, BASE_REACHABLE_TIME)) {
    1376                 :          0 :                                 NEIGH_VAR_SET(in6_dev->nd_parms,
    1377                 :            :                                               BASE_REACHABLE_TIME, rtime);
    1378                 :          0 :                                 NEIGH_VAR_SET(in6_dev->nd_parms,
    1379                 :            :                                               GC_STALETIME, 3 * rtime);
    1380                 :          0 :                                 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
    1381                 :          0 :                                 in6_dev->tstamp = jiffies;
    1382                 :            :                                 send_ifinfo_notify = true;
    1383                 :            :                         }
    1384                 :            :                 }
    1385                 :            :         }
    1386                 :            : 
    1387                 :            :         /*
    1388                 :            :          *      Send a notify if RA changed managed/otherconf flags or timer settings
    1389                 :            :          */
    1390         [ #  # ]:          0 :         if (send_ifinfo_notify)
    1391                 :          0 :                 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
    1392                 :            : 
    1393                 :            : skip_linkparms:
    1394                 :            : 
    1395                 :            :         /*
    1396                 :            :          *      Process options.
    1397                 :            :          */
    1398                 :            : 
    1399         [ #  # ]:          0 :         if (!neigh)
    1400                 :          0 :                 neigh = __neigh_lookup(&nd_tbl, &ipv6_hdr(skb)->saddr,
    1401                 :            :                                        skb->dev, 1);
    1402         [ #  # ]:          0 :         if (neigh) {
    1403                 :            :                 u8 *lladdr = NULL;
    1404         [ #  # ]:          0 :                 if (ndopts.nd_opts_src_lladdr) {
    1405                 :          0 :                         lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
    1406                 :            :                                                      skb->dev);
    1407         [ #  # ]:          0 :                         if (!lladdr) {
    1408                 :            :                                 ND_PRINTK(2, warn,
    1409                 :            :                                           "RA: invalid link-layer address length\n");
    1410                 :            :                                 goto out;
    1411                 :            :                         }
    1412                 :            :                 }
    1413                 :          0 :                 ndisc_update(skb->dev, neigh, lladdr, NUD_STALE,
    1414                 :            :                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
    1415                 :            :                              NEIGH_UPDATE_F_OVERRIDE|
    1416                 :            :                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
    1417                 :            :                              NEIGH_UPDATE_F_ISROUTER,
    1418                 :            :                              NDISC_ROUTER_ADVERTISEMENT, &ndopts);
    1419                 :            :         }
    1420                 :            : 
    1421         [ #  # ]:          0 :         if (!ipv6_accept_ra(in6_dev)) {
    1422                 :            :                 ND_PRINTK(2, info,
    1423                 :            :                           "RA: %s, accept_ra is false for dev: %s\n",
    1424                 :            :                           __func__, skb->dev->name);
    1425                 :            :                 goto out;
    1426                 :            :         }
    1427                 :            : 
    1428                 :            : #ifdef CONFIG_IPV6_ROUTE_INFO
    1429   [ #  #  #  # ]:          0 :         if (!in6_dev->cnf.accept_ra_from_local &&
    1430                 :          0 :             ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr,
    1431                 :            :                           in6_dev->dev, 0)) {
    1432                 :            :                 ND_PRINTK(2, info,
    1433                 :            :                           "RA from local address detected on dev: %s: router info ignored.\n",
    1434                 :            :                           skb->dev->name);
    1435                 :            :                 goto skip_routeinfo;
    1436                 :            :         }
    1437                 :            : 
    1438   [ #  #  #  # ]:          0 :         if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {
    1439                 :            :                 struct nd_opt_hdr *p;
    1440         [ #  # ]:          0 :                 for (p = ndopts.nd_opts_ri;
    1441                 :            :                      p;
    1442                 :          0 :                      p = ndisc_next_option(p, ndopts.nd_opts_ri_end)) {
    1443                 :            :                         struct route_info *ri = (struct route_info *)p;
    1444                 :            : #ifdef CONFIG_IPV6_NDISC_NODETYPE
    1445   [ #  #  #  # ]:          0 :                         if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT &&
    1446                 :          0 :                             ri->prefix_len == 0)
    1447                 :          0 :                                 continue;
    1448                 :            : #endif
    1449   [ #  #  #  # ]:          0 :                         if (ri->prefix_len == 0 &&
    1450                 :          0 :                             !in6_dev->cnf.accept_ra_defrtr)
    1451                 :          0 :                                 continue;
    1452         [ #  # ]:          0 :                         if (ri->prefix_len < in6_dev->cnf.accept_ra_rt_info_min_plen)
    1453                 :          0 :                                 continue;
    1454         [ #  # ]:          0 :                         if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
    1455                 :          0 :                                 continue;
    1456                 :          0 :                         rt6_route_rcv(skb->dev, (u8 *)p, (p->nd_opt_len) << 3,
    1457                 :          0 :                                       &ipv6_hdr(skb)->saddr);
    1458                 :            :                 }
    1459                 :            :         }
    1460                 :            : 
    1461                 :            : skip_routeinfo:
    1462                 :            : #endif
    1463                 :            : 
    1464                 :            : #ifdef CONFIG_IPV6_NDISC_NODETYPE
    1465                 :            :         /* skip link-specific ndopts from interior routers */
    1466         [ #  # ]:          0 :         if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) {
    1467                 :            :                 ND_PRINTK(2, info,
    1468                 :            :                           "RA: %s, nodetype is NODEFAULT (interior routes), dev: %s\n",
    1469                 :            :                           __func__, skb->dev->name);
    1470                 :            :                 goto out;
    1471                 :            :         }
    1472                 :            : #endif
    1473                 :            : 
    1474   [ #  #  #  # ]:          0 :         if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
    1475                 :            :                 struct nd_opt_hdr *p;
    1476         [ #  # ]:          0 :                 for (p = ndopts.nd_opts_pi;
    1477                 :            :                      p;
    1478                 :          0 :                      p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
    1479                 :          0 :                         addrconf_prefix_rcv(skb->dev, (u8 *)p,
    1480                 :          0 :                                             (p->nd_opt_len) << 3,
    1481                 :          0 :                                             ndopts.nd_opts_src_lladdr != NULL);
    1482                 :            :                 }
    1483                 :            :         }
    1484                 :            : 
    1485   [ #  #  #  # ]:          0 :         if (ndopts.nd_opts_mtu && in6_dev->cnf.accept_ra_mtu) {
    1486                 :            :                 __be32 n;
    1487                 :            :                 u32 mtu;
    1488                 :            : 
    1489                 :          0 :                 memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
    1490                 :          0 :                 mtu = ntohl(n);
    1491                 :            : 
    1492   [ #  #  #  # ]:          0 :                 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
    1493                 :            :                         ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
    1494         [ #  # ]:          0 :                 } else if (in6_dev->cnf.mtu6 != mtu) {
    1495                 :          0 :                         in6_dev->cnf.mtu6 = mtu;
    1496                 :          0 :                         fib6_metric_set(rt, RTAX_MTU, mtu);
    1497                 :          0 :                         rt6_mtu_change(skb->dev, mtu);
    1498                 :            :                 }
    1499                 :            :         }
    1500                 :            : 
    1501         [ #  # ]:          0 :         if (ndopts.nd_useropts) {
    1502                 :            :                 struct nd_opt_hdr *p;
    1503         [ #  # ]:          0 :                 for (p = ndopts.nd_useropts;
    1504                 :            :                      p;
    1505                 :          0 :                      p = ndisc_next_useropt(skb->dev, p,
    1506                 :            :                                             ndopts.nd_useropts_end)) {
    1507                 :          0 :                         ndisc_ra_useropt(skb, p);
    1508                 :            :                 }
    1509                 :            :         }
    1510                 :            : 
    1511                 :            :         if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
    1512                 :            :                 ND_PRINTK(2, warn, "RA: invalid RA options\n");
    1513                 :            :         }
    1514                 :            : out:
    1515                 :          0 :         fib6_info_release(rt);
    1516         [ #  # ]:          0 :         if (neigh)
    1517                 :          0 :                 neigh_release(neigh);
    1518                 :            : }
    1519                 :            : 
    1520                 :          0 : static void ndisc_redirect_rcv(struct sk_buff *skb)
    1521                 :            : {
    1522                 :            :         u8 *hdr;
    1523                 :            :         struct ndisc_options ndopts;
    1524                 :            :         struct rd_msg *msg = (struct rd_msg *)skb_transport_header(skb);
    1525                 :          0 :         u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) +
    1526                 :            :                                     offsetof(struct rd_msg, opt));
    1527                 :            : 
    1528                 :            : #ifdef CONFIG_IPV6_NDISC_NODETYPE
    1529         [ #  # ]:          0 :         switch (skb->ndisc_nodetype) {
    1530                 :            :         case NDISC_NODETYPE_HOST:
    1531                 :            :         case NDISC_NODETYPE_NODEFAULT:
    1532                 :            :                 ND_PRINTK(2, warn,
    1533                 :            :                           "Redirect: from host or unauthorized router\n");
    1534                 :          0 :                 return;
    1535                 :            :         }
    1536                 :            : #endif
    1537                 :            : 
    1538         [ #  # ]:          0 :         if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
    1539                 :            :                 ND_PRINTK(2, warn,
    1540                 :            :                           "Redirect: source address is not link-local\n");
    1541                 :            :                 return;
    1542                 :            :         }
    1543                 :            : 
    1544         [ #  # ]:          0 :         if (!ndisc_parse_options(skb->dev, msg->opt, ndoptlen, &ndopts))
    1545                 :            :                 return;
    1546                 :            : 
    1547         [ #  # ]:          0 :         if (!ndopts.nd_opts_rh) {
    1548                 :          0 :                 ip6_redirect_no_header(skb, dev_net(skb->dev),
    1549                 :            :                                         skb->dev->ifindex);
    1550                 :          0 :                 return;
    1551                 :            :         }
    1552                 :            : 
    1553                 :            :         hdr = (u8 *)ndopts.nd_opts_rh;
    1554                 :          0 :         hdr += 8;
    1555         [ #  # ]:          0 :         if (!pskb_pull(skb, hdr - skb_transport_header(skb)))
    1556                 :            :                 return;
    1557                 :            : 
    1558                 :          0 :         icmpv6_notify(skb, NDISC_REDIRECT, 0, 0);
    1559                 :            : }
    1560                 :            : 
    1561                 :          0 : static void ndisc_fill_redirect_hdr_option(struct sk_buff *skb,
    1562                 :            :                                            struct sk_buff *orig_skb,
    1563                 :            :                                            int rd_len)
    1564                 :            : {
    1565                 :          0 :         u8 *opt = skb_put(skb, rd_len);
    1566                 :            : 
    1567                 :          0 :         memset(opt, 0, 8);
    1568                 :          0 :         *(opt++) = ND_OPT_REDIRECT_HDR;
    1569                 :          0 :         *(opt++) = (rd_len >> 3);
    1570                 :          0 :         opt += 6;
    1571                 :            : 
    1572                 :          0 :         skb_copy_bits(orig_skb, skb_network_offset(orig_skb), opt,
    1573                 :            :                       rd_len - 8);
    1574                 :          0 : }
    1575                 :            : 
    1576                 :          0 : void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
    1577                 :            : {
    1578                 :          0 :         struct net_device *dev = skb->dev;
    1579                 :            :         struct net *net = dev_net(dev);
    1580                 :          0 :         struct sock *sk = net->ipv6.ndisc_sk;
    1581                 :            :         int optlen = 0;
    1582                 :            :         struct inet_peer *peer;
    1583                 :            :         struct sk_buff *buff;
    1584                 :            :         struct rd_msg *msg;
    1585                 :            :         struct in6_addr saddr_buf;
    1586                 :            :         struct rt6_info *rt;
    1587                 :            :         struct dst_entry *dst;
    1588                 :            :         struct flowi6 fl6;
    1589                 :            :         int rd_len;
    1590                 :            :         u8 ha_buf[MAX_ADDR_LEN], *ha = NULL,
    1591                 :          0 :            ops_data_buf[NDISC_OPS_REDIRECT_DATA_SPACE], *ops_data = NULL;
    1592                 :            :         bool ret;
    1593                 :            : 
    1594         [ #  # ]:          0 :         if (netif_is_l3_master(skb->dev)) {
    1595                 :          0 :                 dev = __dev_get_by_index(dev_net(skb->dev), IPCB(skb)->iif);
    1596         [ #  # ]:          0 :                 if (!dev)
    1597                 :          0 :                         return;
    1598                 :            :         }
    1599                 :            : 
    1600         [ #  # ]:          0 :         if (ipv6_get_lladdr(dev, &saddr_buf, IFA_F_TENTATIVE)) {
    1601                 :            :                 ND_PRINTK(2, warn, "Redirect: no link-local address on %s\n",
    1602                 :            :                           dev->name);
    1603                 :            :                 return;
    1604                 :            :         }
    1605                 :            : 
    1606   [ #  #  #  # ]:          0 :         if (!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, target) &&
    1607                 :            :             ipv6_addr_type(target) != (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) {
    1608                 :            :                 ND_PRINTK(2, warn,
    1609                 :            :                           "Redirect: target address is not link-local unicast\n");
    1610                 :            :                 return;
    1611                 :            :         }
    1612                 :            : 
    1613                 :          0 :         icmpv6_flow_init(sk, &fl6, NDISC_REDIRECT,
    1614                 :          0 :                          &saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex);
    1615                 :            : 
    1616                 :            :         dst = ip6_route_output(net, NULL, &fl6);
    1617         [ #  # ]:          0 :         if (dst->error) {
    1618                 :          0 :                 dst_release(dst);
    1619                 :          0 :                 return;
    1620                 :            :         }
    1621                 :          0 :         dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
    1622         [ #  # ]:          0 :         if (IS_ERR(dst))
    1623                 :            :                 return;
    1624                 :            : 
    1625                 :            :         rt = (struct rt6_info *) dst;
    1626                 :            : 
    1627         [ #  # ]:          0 :         if (rt->rt6i_flags & RTF_GATEWAY) {
    1628                 :            :                 ND_PRINTK(2, warn,
    1629                 :            :                           "Redirect: destination is not a neighbour\n");
    1630                 :            :                 goto release;
    1631                 :            :         }
    1632                 :          0 :         peer = inet_getpeer_v6(net->ipv6.peers, &ipv6_hdr(skb)->saddr, 1);
    1633                 :          0 :         ret = inet_peer_xrlim_allow(peer, 1*HZ);
    1634         [ #  # ]:          0 :         if (peer)
    1635                 :          0 :                 inet_putpeer(peer);
    1636         [ #  # ]:          0 :         if (!ret)
    1637                 :            :                 goto release;
    1638                 :            : 
    1639         [ #  # ]:          0 :         if (dev->addr_len) {
    1640                 :            :                 struct neighbour *neigh = dst_neigh_lookup(skb_dst(skb), target);
    1641         [ #  # ]:          0 :                 if (!neigh) {
    1642                 :            :                         ND_PRINTK(2, warn,
    1643                 :            :                                   "Redirect: no neigh for target address\n");
    1644                 :            :                         goto release;
    1645                 :            :                 }
    1646                 :            : 
    1647                 :          0 :                 read_lock_bh(&neigh->lock);
    1648         [ #  # ]:          0 :                 if (neigh->nud_state & NUD_VALID) {
    1649                 :          0 :                         memcpy(ha_buf, neigh->ha, dev->addr_len);
    1650                 :          0 :                         read_unlock_bh(&neigh->lock);
    1651                 :            :                         ha = ha_buf;
    1652                 :          0 :                         optlen += ndisc_redirect_opt_addr_space(dev, neigh,
    1653                 :            :                                                                 ops_data_buf,
    1654                 :            :                                                                 &ops_data);
    1655                 :            :                 } else
    1656                 :          0 :                         read_unlock_bh(&neigh->lock);
    1657                 :            : 
    1658                 :          0 :                 neigh_release(neigh);
    1659                 :            :         }
    1660                 :            : 
    1661                 :          0 :         rd_len = min_t(unsigned int,
    1662                 :            :                        IPV6_MIN_MTU - sizeof(struct ipv6hdr) - sizeof(*msg) - optlen,
    1663                 :            :                        skb->len + 8);
    1664                 :          0 :         rd_len &= ~0x7;
    1665                 :          0 :         optlen += rd_len;
    1666                 :            : 
    1667                 :          0 :         buff = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
    1668         [ #  # ]:          0 :         if (!buff)
    1669                 :            :                 goto release;
    1670                 :            : 
    1671                 :          0 :         msg = skb_put(buff, sizeof(*msg));
    1672                 :          0 :         *msg = (struct rd_msg) {
    1673                 :            :                 .icmph = {
    1674                 :            :                         .icmp6_type = NDISC_REDIRECT,
    1675                 :            :                 },
    1676                 :          0 :                 .target = *target,
    1677                 :          0 :                 .dest = ipv6_hdr(skb)->daddr,
    1678                 :            :         };
    1679                 :            : 
    1680                 :            :         /*
    1681                 :            :          *      include target_address option
    1682                 :            :          */
    1683                 :            : 
    1684         [ #  # ]:          0 :         if (ha)
    1685                 :          0 :                 ndisc_fill_redirect_addr_option(buff, ha, ops_data);
    1686                 :            : 
    1687                 :            :         /*
    1688                 :            :          *      build redirect option and copy skb over to the new packet.
    1689                 :            :          */
    1690                 :            : 
    1691         [ #  # ]:          0 :         if (rd_len)
    1692                 :          0 :                 ndisc_fill_redirect_hdr_option(buff, skb, rd_len);
    1693                 :            : 
    1694                 :            :         skb_dst_set(buff, dst);
    1695                 :          0 :         ndisc_send_skb(buff, &ipv6_hdr(skb)->saddr, &saddr_buf);
    1696                 :          0 :         return;
    1697                 :            : 
    1698                 :            : release:
    1699                 :          0 :         dst_release(dst);
    1700                 :            : }
    1701                 :            : 
    1702                 :          0 : static void pndisc_redo(struct sk_buff *skb)
    1703                 :            : {
    1704                 :          0 :         ndisc_recv_ns(skb);
    1705                 :          0 :         kfree_skb(skb);
    1706                 :          0 : }
    1707                 :            : 
    1708                 :          0 : static bool ndisc_suppress_frag_ndisc(struct sk_buff *skb)
    1709                 :            : {
    1710                 :          0 :         struct inet6_dev *idev = __in6_dev_get(skb->dev);
    1711                 :            : 
    1712         [ #  # ]:          0 :         if (!idev)
    1713                 :            :                 return true;
    1714   [ #  #  #  # ]:          0 :         if (IP6CB(skb)->flags & IP6SKB_FRAGMENTED &&
    1715                 :          0 :             idev->cnf.suppress_frag_ndisc) {
    1716         [ #  # ]:          0 :                 net_warn_ratelimited("Received fragmented ndisc packet. Carefully consider disabling suppress_frag_ndisc.\n");
    1717                 :            :                 return true;
    1718                 :            :         }
    1719                 :            :         return false;
    1720                 :            : }
    1721                 :            : 
    1722                 :          0 : int ndisc_rcv(struct sk_buff *skb)
    1723                 :            : {
    1724                 :            :         struct nd_msg *msg;
    1725                 :            : 
    1726         [ #  # ]:          0 :         if (ndisc_suppress_frag_ndisc(skb))
    1727                 :            :                 return 0;
    1728                 :            : 
    1729         [ #  # ]:          0 :         if (skb_linearize(skb))
    1730                 :            :                 return 0;
    1731                 :            : 
    1732                 :            :         msg = (struct nd_msg *)skb_transport_header(skb);
    1733                 :            : 
    1734                 :          0 :         __skb_push(skb, skb->data - skb_transport_header(skb));
    1735                 :            : 
    1736         [ #  # ]:          0 :         if (ipv6_hdr(skb)->hop_limit != 255) {
    1737                 :            :                 ND_PRINTK(2, warn, "NDISC: invalid hop-limit: %d\n",
    1738                 :            :                           ipv6_hdr(skb)->hop_limit);
    1739                 :            :                 return 0;
    1740                 :            :         }
    1741                 :            : 
    1742         [ #  # ]:          0 :         if (msg->icmph.icmp6_code != 0) {
    1743                 :            :                 ND_PRINTK(2, warn, "NDISC: invalid ICMPv6 code: %d\n",
    1744                 :            :                           msg->icmph.icmp6_code);
    1745                 :            :                 return 0;
    1746                 :            :         }
    1747                 :            : 
    1748   [ #  #  #  #  :          0 :         switch (msg->icmph.icmp6_type) {
                   #  # ]
    1749                 :            :         case NDISC_NEIGHBOUR_SOLICITATION:
    1750                 :          0 :                 memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
    1751                 :          0 :                 ndisc_recv_ns(skb);
    1752                 :          0 :                 break;
    1753                 :            : 
    1754                 :            :         case NDISC_NEIGHBOUR_ADVERTISEMENT:
    1755                 :          0 :                 ndisc_recv_na(skb);
    1756                 :          0 :                 break;
    1757                 :            : 
    1758                 :            :         case NDISC_ROUTER_SOLICITATION:
    1759                 :          0 :                 ndisc_recv_rs(skb);
    1760                 :          0 :                 break;
    1761                 :            : 
    1762                 :            :         case NDISC_ROUTER_ADVERTISEMENT:
    1763                 :          0 :                 ndisc_router_discovery(skb);
    1764                 :          0 :                 break;
    1765                 :            : 
    1766                 :            :         case NDISC_REDIRECT:
    1767                 :          0 :                 ndisc_redirect_rcv(skb);
    1768                 :          0 :                 break;
    1769                 :            :         }
    1770                 :            : 
    1771                 :            :         return 0;
    1772                 :            : }
    1773                 :            : 
    1774                 :       2070 : static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
    1775                 :            : {
    1776                 :            :         struct net_device *dev = netdev_notifier_info_to_dev(ptr);
    1777                 :            :         struct netdev_notifier_change_info *change_info;
    1778                 :            :         struct net *net = dev_net(dev);
    1779                 :            :         struct inet6_dev *idev;
    1780                 :            : 
    1781   [ -  +  +  -  :       2070 :         switch (event) {
                   -  + ]
    1782                 :            :         case NETDEV_CHANGEADDR:
    1783                 :          0 :                 neigh_changeaddr(&nd_tbl, dev);
    1784                 :          0 :                 fib6_run_gc(0, net, false);
    1785                 :            :                 /* fallthrough */
    1786                 :            :         case NETDEV_UP:
    1787                 :            :                 idev = in6_dev_get(dev);
    1788         [ +  - ]:        414 :                 if (!idev)
    1789                 :            :                         break;
    1790   [ +  -  -  + ]:        828 :                 if (idev->cnf.ndisc_notify ||
    1791                 :        414 :                     net->ipv6.devconf_all->ndisc_notify)
    1792                 :          0 :                         ndisc_send_unsol_na(dev);
    1793                 :        414 :                 in6_dev_put(idev);
    1794                 :        414 :                 break;
    1795                 :            :         case NETDEV_CHANGE:
    1796                 :            :                 change_info = ptr;
    1797         [ -  + ]:        828 :                 if (change_info->flags_changed & IFF_NOARP)
    1798                 :          0 :                         neigh_changeaddr(&nd_tbl, dev);
    1799         [ +  + ]:        828 :                 if (!netif_carrier_ok(dev))
    1800                 :        207 :                         neigh_carrier_down(&nd_tbl, dev);
    1801                 :            :                 break;
    1802                 :            :         case NETDEV_DOWN:
    1803                 :          0 :                 neigh_ifdown(&nd_tbl, dev);
    1804                 :          0 :                 fib6_run_gc(0, net, false);
    1805                 :          0 :                 break;
    1806                 :            :         case NETDEV_NOTIFY_PEERS:
    1807                 :          0 :                 ndisc_send_unsol_na(dev);
    1808                 :          0 :                 break;
    1809                 :            :         default:
    1810                 :            :                 break;
    1811                 :            :         }
    1812                 :            : 
    1813                 :       2070 :         return NOTIFY_DONE;
    1814                 :            : }
    1815                 :            : 
    1816                 :            : static struct notifier_block ndisc_netdev_notifier = {
    1817                 :            :         .notifier_call = ndisc_netdev_event,
    1818                 :            :         .priority = ADDRCONF_NOTIFY_PRIORITY - 5,
    1819                 :            : };
    1820                 :            : 
    1821                 :            : #ifdef CONFIG_SYSCTL
    1822                 :          0 : static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl,
    1823                 :            :                                          const char *func, const char *dev_name)
    1824                 :            : {
    1825                 :            :         static char warncomm[TASK_COMM_LEN];
    1826                 :            :         static int warned;
    1827   [ #  #  #  # ]:          0 :         if (strcmp(warncomm, current->comm) && warned < 5) {
    1828                 :          0 :                 strcpy(warncomm, current->comm);
    1829                 :          0 :                 pr_warn("process `%s' is using deprecated sysctl (%s) net.ipv6.neigh.%s.%s - use net.ipv6.neigh.%s.%s_ms instead\n",
    1830                 :            :                         warncomm, func,
    1831                 :            :                         dev_name, ctl->procname,
    1832                 :            :                         dev_name, ctl->procname);
    1833                 :          0 :                 warned++;
    1834                 :            :         }
    1835                 :          0 : }
    1836                 :            : 
    1837                 :          0 : int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
    1838                 :            : {
    1839                 :          0 :         struct net_device *dev = ctl->extra1;
    1840                 :            :         struct inet6_dev *idev;
    1841                 :            :         int ret;
    1842                 :            : 
    1843   [ #  #  #  # ]:          0 :         if ((strcmp(ctl->procname, "retrans_time") == 0) ||
    1844                 :          0 :             (strcmp(ctl->procname, "base_reachable_time") == 0))
    1845         [ #  # ]:          0 :                 ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default");
    1846                 :            : 
    1847         [ #  # ]:          0 :         if (strcmp(ctl->procname, "retrans_time") == 0)
    1848                 :          0 :                 ret = neigh_proc_dointvec(ctl, write, buffer, lenp, ppos);
    1849                 :            : 
    1850         [ #  # ]:          0 :         else if (strcmp(ctl->procname, "base_reachable_time") == 0)
    1851                 :          0 :                 ret = neigh_proc_dointvec_jiffies(ctl, write,
    1852                 :            :                                                   buffer, lenp, ppos);
    1853                 :            : 
    1854   [ #  #  #  # ]:          0 :         else if ((strcmp(ctl->procname, "retrans_time_ms") == 0) ||
    1855                 :          0 :                  (strcmp(ctl->procname, "base_reachable_time_ms") == 0))
    1856                 :          0 :                 ret = neigh_proc_dointvec_ms_jiffies(ctl, write,
    1857                 :            :                                                      buffer, lenp, ppos);
    1858                 :            :         else
    1859                 :            :                 ret = -1;
    1860                 :            : 
    1861   [ #  #  #  #  :          0 :         if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) {
                   #  # ]
    1862         [ #  # ]:          0 :                 if (ctl->data == &NEIGH_VAR(idev->nd_parms, BASE_REACHABLE_TIME))
    1863                 :          0 :                         idev->nd_parms->reachable_time =
    1864                 :          0 :                                         neigh_rand_reach_time(NEIGH_VAR(idev->nd_parms, BASE_REACHABLE_TIME));
    1865                 :          0 :                 idev->tstamp = jiffies;
    1866                 :          0 :                 inet6_ifinfo_notify(RTM_NEWLINK, idev);
    1867                 :          0 :                 in6_dev_put(idev);
    1868                 :            :         }
    1869                 :          0 :         return ret;
    1870                 :            : }
    1871                 :            : 
    1872                 :            : 
    1873                 :            : #endif
    1874                 :            : 
    1875                 :        207 : static int __net_init ndisc_net_init(struct net *net)
    1876                 :            : {
    1877                 :            :         struct ipv6_pinfo *np;
    1878                 :            :         struct sock *sk;
    1879                 :            :         int err;
    1880                 :            : 
    1881                 :        207 :         err = inet_ctl_sock_create(&sk, PF_INET6,
    1882                 :            :                                    SOCK_RAW, IPPROTO_ICMPV6, net);
    1883         [ -  + ]:        207 :         if (err < 0) {
    1884         [ #  # ]:          0 :                 ND_PRINTK(0, err,
    1885                 :            :                           "NDISC: Failed to initialize the control socket (err %d)\n",
    1886                 :            :                           err);
    1887                 :          0 :                 return err;
    1888                 :            :         }
    1889                 :            : 
    1890                 :        207 :         net->ipv6.ndisc_sk = sk;
    1891                 :            : 
    1892                 :            :         np = inet6_sk(sk);
    1893                 :        207 :         np->hop_limit = 255;
    1894                 :            :         /* Do not loopback ndisc messages */
    1895                 :        207 :         np->mc_loop = 0;
    1896                 :            : 
    1897                 :        207 :         return 0;
    1898                 :            : }
    1899                 :            : 
    1900                 :          0 : static void __net_exit ndisc_net_exit(struct net *net)
    1901                 :            : {
    1902                 :          0 :         inet_ctl_sock_destroy(net->ipv6.ndisc_sk);
    1903                 :          0 : }
    1904                 :            : 
    1905                 :            : static struct pernet_operations ndisc_net_ops = {
    1906                 :            :         .init = ndisc_net_init,
    1907                 :            :         .exit = ndisc_net_exit,
    1908                 :            : };
    1909                 :            : 
    1910                 :        207 : int __init ndisc_init(void)
    1911                 :            : {
    1912                 :            :         int err;
    1913                 :            : 
    1914                 :        207 :         err = register_pernet_subsys(&ndisc_net_ops);
    1915         [ +  - ]:        207 :         if (err)
    1916                 :            :                 return err;
    1917                 :            :         /*
    1918                 :            :          * Initialize the neighbour table
    1919                 :            :          */
    1920                 :        207 :         neigh_table_init(NEIGH_ND_TABLE, &nd_tbl);
    1921                 :            : 
    1922                 :            : #ifdef CONFIG_SYSCTL
    1923                 :        207 :         err = neigh_sysctl_register(NULL, &nd_tbl.parms,
    1924                 :            :                                     ndisc_ifinfo_sysctl_change);
    1925         [ +  - ]:        207 :         if (err)
    1926                 :            :                 goto out_unregister_pernet;
    1927                 :            : out:
    1928                 :            : #endif
    1929                 :        207 :         return err;
    1930                 :            : 
    1931                 :            : #ifdef CONFIG_SYSCTL
    1932                 :            : out_unregister_pernet:
    1933                 :          0 :         unregister_pernet_subsys(&ndisc_net_ops);
    1934                 :          0 :         goto out;
    1935                 :            : #endif
    1936                 :            : }
    1937                 :            : 
    1938                 :        207 : int __init ndisc_late_init(void)
    1939                 :            : {
    1940                 :        207 :         return register_netdevice_notifier(&ndisc_netdev_notifier);
    1941                 :            : }
    1942                 :            : 
    1943                 :          0 : void ndisc_late_cleanup(void)
    1944                 :            : {
    1945                 :          0 :         unregister_netdevice_notifier(&ndisc_netdev_notifier);
    1946                 :          0 : }
    1947                 :            : 
    1948                 :          0 : void ndisc_cleanup(void)
    1949                 :            : {
    1950                 :            : #ifdef CONFIG_SYSCTL
    1951                 :          0 :         neigh_sysctl_unregister(&nd_tbl.parms);
    1952                 :            : #endif
    1953                 :          0 :         neigh_table_clear(NEIGH_ND_TABLE, &nd_tbl);
    1954                 :          0 :         unregister_pernet_subsys(&ndisc_net_ops);
    1955                 :          0 : }

Generated by: LCOV version 1.14