LCOV - code coverage report
Current view: top level - include/net - ndisc.h (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_qemu_modules_combined.info Lines: 20 52 38.5 %
Date: 2020-09-30 20:25:01 Functions: 3 8 37.5 %
Branches: 12 72 16.7 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: GPL-2.0 */
       2                 :            : #ifndef _NDISC_H
       3                 :            : #define _NDISC_H
       4                 :            : 
       5                 :            : #include <net/ipv6_stubs.h>
       6                 :            : 
       7                 :            : /*
       8                 :            :  *      ICMP codes for neighbour discovery messages
       9                 :            :  */
      10                 :            : 
      11                 :            : #define NDISC_ROUTER_SOLICITATION       133
      12                 :            : #define NDISC_ROUTER_ADVERTISEMENT      134
      13                 :            : #define NDISC_NEIGHBOUR_SOLICITATION    135
      14                 :            : #define NDISC_NEIGHBOUR_ADVERTISEMENT   136
      15                 :            : #define NDISC_REDIRECT                  137
      16                 :            : 
      17                 :            : /*
      18                 :            :  * Router type: cross-layer information from link-layer to
      19                 :            :  * IPv6 layer reported by certain link types (e.g., RFC4214).
      20                 :            :  */
      21                 :            : #define NDISC_NODETYPE_UNSPEC           0       /* unspecified (default) */
      22                 :            : #define NDISC_NODETYPE_HOST             1       /* host or unauthorized router */
      23                 :            : #define NDISC_NODETYPE_NODEFAULT        2       /* non-default router */
      24                 :            : #define NDISC_NODETYPE_DEFAULT          3       /* default router */
      25                 :            : 
      26                 :            : /*
      27                 :            :  *      ndisc options
      28                 :            :  */
      29                 :            : 
      30                 :            : enum {
      31                 :            :         __ND_OPT_PREFIX_INFO_END = 0,
      32                 :            :         ND_OPT_SOURCE_LL_ADDR = 1,      /* RFC2461 */
      33                 :            :         ND_OPT_TARGET_LL_ADDR = 2,      /* RFC2461 */
      34                 :            :         ND_OPT_PREFIX_INFO = 3,         /* RFC2461 */
      35                 :            :         ND_OPT_REDIRECT_HDR = 4,        /* RFC2461 */
      36                 :            :         ND_OPT_MTU = 5,                 /* RFC2461 */
      37                 :            :         ND_OPT_NONCE = 14,              /* RFC7527 */
      38                 :            :         __ND_OPT_ARRAY_MAX,
      39                 :            :         ND_OPT_ROUTE_INFO = 24,         /* RFC4191 */
      40                 :            :         ND_OPT_RDNSS = 25,              /* RFC5006 */
      41                 :            :         ND_OPT_DNSSL = 31,              /* RFC6106 */
      42                 :            :         ND_OPT_6CO = 34,                /* RFC6775 */
      43                 :            :         ND_OPT_CAPTIVE_PORTAL = 37,     /* RFC7710 */
      44                 :            :         __ND_OPT_MAX
      45                 :            : };
      46                 :            : 
      47                 :            : #define MAX_RTR_SOLICITATION_DELAY      HZ
      48                 :            : 
      49                 :            : #define ND_REACHABLE_TIME               (30*HZ)
      50                 :            : #define ND_RETRANS_TIMER                HZ
      51                 :            : 
      52                 :            : #include <linux/compiler.h>
      53                 :            : #include <linux/icmpv6.h>
      54                 :            : #include <linux/in6.h>
      55                 :            : #include <linux/types.h>
      56                 :            : #include <linux/if_arp.h>
      57                 :            : #include <linux/netdevice.h>
      58                 :            : #include <linux/hash.h>
      59                 :            : 
      60                 :            : #include <net/neighbour.h>
      61                 :            : 
      62                 :            : /* Set to 3 to get tracing... */
      63                 :            : #define ND_DEBUG 1
      64                 :            : 
      65                 :            : #define ND_PRINTK(val, level, fmt, ...)                         \
      66                 :            : do {                                                            \
      67                 :            :         if (val <= ND_DEBUG)                                 \
      68                 :            :                 net_##level##_ratelimited(fmt, ##__VA_ARGS__);  \
      69                 :            : } while (0)
      70                 :            : 
      71                 :            : struct ctl_table;
      72                 :            : struct inet6_dev;
      73                 :            : struct net_device;
      74                 :            : struct net_proto_family;
      75                 :            : struct sk_buff;
      76                 :            : struct prefix_info;
      77                 :            : 
      78                 :            : extern struct neigh_table nd_tbl;
      79                 :            : 
      80                 :            : struct nd_msg {
      81                 :            :         struct icmp6hdr icmph;
      82                 :            :         struct in6_addr target;
      83                 :            :         __u8            opt[0];
      84                 :            : };
      85                 :            : 
      86                 :            : struct rs_msg {
      87                 :            :         struct icmp6hdr icmph;
      88                 :            :         __u8            opt[0];
      89                 :            : };
      90                 :            : 
      91                 :            : struct ra_msg {
      92                 :            :         struct icmp6hdr         icmph;
      93                 :            :         __be32                  reachable_time;
      94                 :            :         __be32                  retrans_timer;
      95                 :            : };
      96                 :            : 
      97                 :            : struct rd_msg {
      98                 :            :         struct icmp6hdr icmph;
      99                 :            :         struct in6_addr target;
     100                 :            :         struct in6_addr dest;
     101                 :            :         __u8            opt[0];
     102                 :            : };
     103                 :            : 
     104                 :            : struct nd_opt_hdr {
     105                 :            :         __u8            nd_opt_type;
     106                 :            :         __u8            nd_opt_len;
     107                 :            : } __packed;
     108                 :            : 
     109                 :            : /* ND options */
     110                 :            : struct ndisc_options {
     111                 :            :         struct nd_opt_hdr *nd_opt_array[__ND_OPT_ARRAY_MAX];
     112                 :            : #ifdef CONFIG_IPV6_ROUTE_INFO
     113                 :            :         struct nd_opt_hdr *nd_opts_ri;
     114                 :            :         struct nd_opt_hdr *nd_opts_ri_end;
     115                 :            : #endif
     116                 :            :         struct nd_opt_hdr *nd_useropts;
     117                 :            :         struct nd_opt_hdr *nd_useropts_end;
     118                 :            : #if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN)
     119                 :            :         struct nd_opt_hdr *nd_802154_opt_array[ND_OPT_TARGET_LL_ADDR + 1];
     120                 :            : #endif
     121                 :            : };
     122                 :            : 
     123                 :            : #define nd_opts_src_lladdr              nd_opt_array[ND_OPT_SOURCE_LL_ADDR]
     124                 :            : #define nd_opts_tgt_lladdr              nd_opt_array[ND_OPT_TARGET_LL_ADDR]
     125                 :            : #define nd_opts_pi                      nd_opt_array[ND_OPT_PREFIX_INFO]
     126                 :            : #define nd_opts_pi_end                  nd_opt_array[__ND_OPT_PREFIX_INFO_END]
     127                 :            : #define nd_opts_rh                      nd_opt_array[ND_OPT_REDIRECT_HDR]
     128                 :            : #define nd_opts_mtu                     nd_opt_array[ND_OPT_MTU]
     129                 :            : #define nd_opts_nonce                   nd_opt_array[ND_OPT_NONCE]
     130                 :            : #define nd_802154_opts_src_lladdr       nd_802154_opt_array[ND_OPT_SOURCE_LL_ADDR]
     131                 :            : #define nd_802154_opts_tgt_lladdr       nd_802154_opt_array[ND_OPT_TARGET_LL_ADDR]
     132                 :            : 
     133                 :            : #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
     134                 :            : 
     135                 :            : struct ndisc_options *ndisc_parse_options(const struct net_device *dev,
     136                 :            :                                           u8 *opt, int opt_len,
     137                 :            :                                           struct ndisc_options *ndopts);
     138                 :            : 
     139                 :            : void __ndisc_fill_addr_option(struct sk_buff *skb, int type, void *data,
     140                 :            :                               int data_len, int pad);
     141                 :            : 
     142                 :            : #define NDISC_OPS_REDIRECT_DATA_SPACE   2
     143                 :            : 
     144                 :            : /*
     145                 :            :  * This structure defines the hooks for IPv6 neighbour discovery.
     146                 :            :  * The following hooks can be defined; unless noted otherwise, they are
     147                 :            :  * optional and can be filled with a null pointer.
     148                 :            :  *
     149                 :            :  * int (*is_useropt)(u8 nd_opt_type):
     150                 :            :  *     This function is called when IPv6 decide RA userspace options. if
     151                 :            :  *     this function returns 1 then the option given by nd_opt_type will
     152                 :            :  *     be handled as userspace option additional to the IPv6 options.
     153                 :            :  *
     154                 :            :  * int (*parse_options)(const struct net_device *dev,
     155                 :            :  *                      struct nd_opt_hdr *nd_opt,
     156                 :            :  *                      struct ndisc_options *ndopts):
     157                 :            :  *     This function is called while parsing ndisc ops and put each position
     158                 :            :  *     as pointer into ndopts. If this function return unequal 0, then this
     159                 :            :  *     function took care about the ndisc option, if 0 then the IPv6 ndisc
     160                 :            :  *     option parser will take care about that option.
     161                 :            :  *
     162                 :            :  * void (*update)(const struct net_device *dev, struct neighbour *n,
     163                 :            :  *                u32 flags, u8 icmp6_type,
     164                 :            :  *                const struct ndisc_options *ndopts):
     165                 :            :  *     This function is called when IPv6 ndisc updates the neighbour cache
     166                 :            :  *     entry. Additional options which can be updated may be previously
     167                 :            :  *     parsed by parse_opts callback and accessible over ndopts parameter.
     168                 :            :  *
     169                 :            :  * int (*opt_addr_space)(const struct net_device *dev, u8 icmp6_type,
     170                 :            :  *                       struct neighbour *neigh, u8 *ha_buf,
     171                 :            :  *                       u8 **ha):
     172                 :            :  *     This function is called when the necessary option space will be
     173                 :            :  *     calculated before allocating a skb. The parameters neigh, ha_buf
     174                 :            :  *     abd ha are available on NDISC_REDIRECT messages only.
     175                 :            :  *
     176                 :            :  * void (*fill_addr_option)(const struct net_device *dev,
     177                 :            :  *                          struct sk_buff *skb, u8 icmp6_type,
     178                 :            :  *                          const u8 *ha):
     179                 :            :  *     This function is called when the skb will finally fill the option
     180                 :            :  *     fields inside skb. NOTE: this callback should fill the option
     181                 :            :  *     fields to the skb which are previously indicated by opt_space
     182                 :            :  *     parameter. That means the decision to add such option should
     183                 :            :  *     not lost between these two callbacks, e.g. protected by interface
     184                 :            :  *     up state.
     185                 :            :  *
     186                 :            :  * void (*prefix_rcv_add_addr)(struct net *net, struct net_device *dev,
     187                 :            :  *                             const struct prefix_info *pinfo,
     188                 :            :  *                             struct inet6_dev *in6_dev,
     189                 :            :  *                             struct in6_addr *addr,
     190                 :            :  *                             int addr_type, u32 addr_flags,
     191                 :            :  *                             bool sllao, bool tokenized,
     192                 :            :  *                             __u32 valid_lft, u32 prefered_lft,
     193                 :            :  *                             bool dev_addr_generated):
     194                 :            :  *     This function is called when a RA messages is received with valid
     195                 :            :  *     PIO option fields and an IPv6 address will be added to the interface
     196                 :            :  *     for autoconfiguration. The parameter dev_addr_generated reports about
     197                 :            :  *     if the address was based on dev->dev_addr or not. This can be used
     198                 :            :  *     to add a second address if link-layer operates with two link layer
     199                 :            :  *     addresses. E.g. 802.15.4 6LoWPAN.
     200                 :            :  */
     201                 :            : struct ndisc_ops {
     202                 :            :         int     (*is_useropt)(u8 nd_opt_type);
     203                 :            :         int     (*parse_options)(const struct net_device *dev,
     204                 :            :                                  struct nd_opt_hdr *nd_opt,
     205                 :            :                                  struct ndisc_options *ndopts);
     206                 :            :         void    (*update)(const struct net_device *dev, struct neighbour *n,
     207                 :            :                           u32 flags, u8 icmp6_type,
     208                 :            :                           const struct ndisc_options *ndopts);
     209                 :            :         int     (*opt_addr_space)(const struct net_device *dev, u8 icmp6_type,
     210                 :            :                                   struct neighbour *neigh, u8 *ha_buf,
     211                 :            :                                   u8 **ha);
     212                 :            :         void    (*fill_addr_option)(const struct net_device *dev,
     213                 :            :                                     struct sk_buff *skb, u8 icmp6_type,
     214                 :            :                                     const u8 *ha);
     215                 :            :         void    (*prefix_rcv_add_addr)(struct net *net, struct net_device *dev,
     216                 :            :                                        const struct prefix_info *pinfo,
     217                 :            :                                        struct inet6_dev *in6_dev,
     218                 :            :                                        struct in6_addr *addr,
     219                 :            :                                        int addr_type, u32 addr_flags,
     220                 :            :                                        bool sllao, bool tokenized,
     221                 :            :                                        __u32 valid_lft, u32 prefered_lft,
     222                 :            :                                        bool dev_addr_generated);
     223                 :            : };
     224                 :            : 
     225                 :            : #if IS_ENABLED(CONFIG_IPV6)
     226                 :            : static inline int ndisc_ops_is_useropt(const struct net_device *dev,
     227                 :            :                                        u8 nd_opt_type)
     228                 :            : {
     229   [ #  #  #  # ]:          0 :         if (dev->ndisc_ops && dev->ndisc_ops->is_useropt)
     230                 :          0 :                 return dev->ndisc_ops->is_useropt(nd_opt_type);
     231                 :            :         else
     232                 :            :                 return 0;
     233                 :            : }
     234                 :            : 
     235                 :            : static inline int ndisc_ops_parse_options(const struct net_device *dev,
     236                 :            :                                           struct nd_opt_hdr *nd_opt,
     237                 :            :                                           struct ndisc_options *ndopts)
     238                 :            : {
     239   [ -  +  #  # ]:       2126 :         if (dev->ndisc_ops && dev->ndisc_ops->parse_options)
     240                 :          0 :                 return dev->ndisc_ops->parse_options(dev, nd_opt, ndopts);
     241                 :            :         else
     242                 :            :                 return 0;
     243                 :            : }
     244                 :            : 
     245                 :            : static inline void ndisc_ops_update(const struct net_device *dev,
     246                 :            :                                           struct neighbour *n, u32 flags,
     247                 :            :                                           u8 icmp6_type,
     248                 :            :                                           const struct ndisc_options *ndopts)
     249                 :            : {
     250   [ -  +  #  # ]:        446 :         if (dev->ndisc_ops && dev->ndisc_ops->update)
     251                 :          0 :                 dev->ndisc_ops->update(dev, n, flags, icmp6_type, ndopts);
     252                 :            : }
     253                 :            : 
     254                 :         12 : static inline int ndisc_ops_opt_addr_space(const struct net_device *dev,
     255                 :            :                                            u8 icmp6_type)
     256                 :            : {
     257   [ -  +  #  #  :         12 :         if (dev->ndisc_ops && dev->ndisc_ops->opt_addr_space &&
                   #  # ]
     258                 :            :             icmp6_type != NDISC_REDIRECT)
     259                 :          0 :                 return dev->ndisc_ops->opt_addr_space(dev, icmp6_type, NULL,
     260                 :            :                                                       NULL, NULL);
     261                 :            :         else
     262                 :            :                 return 0;
     263                 :            : }
     264                 :            : 
     265                 :            : static inline int ndisc_ops_redirect_opt_addr_space(const struct net_device *dev,
     266                 :            :                                                     struct neighbour *neigh,
     267                 :            :                                                     u8 *ha_buf, u8 **ha)
     268                 :            : {
     269   [ #  #  #  # ]:          0 :         if (dev->ndisc_ops && dev->ndisc_ops->opt_addr_space)
     270                 :          0 :                 return dev->ndisc_ops->opt_addr_space(dev, NDISC_REDIRECT,
     271                 :            :                                                       neigh, ha_buf, ha);
     272                 :            :         else
     273                 :            :                 return 0;
     274                 :            : }
     275                 :            : 
     276                 :            : static inline void ndisc_ops_fill_addr_option(const struct net_device *dev,
     277                 :            :                                               struct sk_buff *skb,
     278                 :            :                                               u8 icmp6_type)
     279                 :            : {
     280   [ -  +  #  #  :         12 :         if (dev->ndisc_ops && dev->ndisc_ops->fill_addr_option &&
                   #  # ]
     281                 :            :             icmp6_type != NDISC_REDIRECT)
     282                 :          0 :                 dev->ndisc_ops->fill_addr_option(dev, skb, icmp6_type, NULL);
     283                 :            : }
     284                 :            : 
     285                 :            : static inline void ndisc_ops_fill_redirect_addr_option(const struct net_device *dev,
     286                 :            :                                                        struct sk_buff *skb,
     287                 :            :                                                        const u8 *ha)
     288                 :            : {
     289   [ #  #  #  # ]:          0 :         if (dev->ndisc_ops && dev->ndisc_ops->fill_addr_option)
     290                 :          0 :                 dev->ndisc_ops->fill_addr_option(dev, skb, NDISC_REDIRECT, ha);
     291                 :            : }
     292                 :            : 
     293                 :            : static inline void ndisc_ops_prefix_rcv_add_addr(struct net *net,
     294                 :            :                                                  struct net_device *dev,
     295                 :            :                                                  const struct prefix_info *pinfo,
     296                 :            :                                                  struct inet6_dev *in6_dev,
     297                 :            :                                                  struct in6_addr *addr,
     298                 :            :                                                  int addr_type, u32 addr_flags,
     299                 :            :                                                  bool sllao, bool tokenized,
     300                 :            :                                                  __u32 valid_lft,
     301                 :            :                                                  u32 prefered_lft,
     302                 :            :                                                  bool dev_addr_generated)
     303                 :            : {
     304   [ #  #  #  # ]:          0 :         if (dev->ndisc_ops && dev->ndisc_ops->prefix_rcv_add_addr)
     305                 :          0 :                 dev->ndisc_ops->prefix_rcv_add_addr(net, dev, pinfo, in6_dev,
     306                 :            :                                                     addr, addr_type,
     307                 :            :                                                     addr_flags, sllao,
     308                 :            :                                                     tokenized, valid_lft,
     309                 :            :                                                     prefered_lft,
     310                 :            :                                                     dev_addr_generated);
     311                 :            : }
     312                 :            : #endif
     313                 :            : 
     314                 :            : /*
     315                 :            :  * Return the padding between the option length and the start of the
     316                 :            :  * link addr.  Currently only IP-over-InfiniBand needs this, although
     317                 :            :  * if RFC 3831 IPv6-over-Fibre Channel is ever implemented it may
     318                 :            :  * also need a pad of 2.
     319                 :            :  */
     320                 :            : static inline int ndisc_addr_option_pad(unsigned short type)
     321                 :            : {
     322   [ +  -  #  #  :       1716 :         switch (type) {
          +  -  +  -  +  
             -  #  #  +  
                      - ]
     323                 :            :         case ARPHRD_INFINIBAND: return 2;
     324                 :            :         default:                return 0;
     325                 :            :         }
     326                 :            : }
     327                 :            : 
     328                 :            : static inline int __ndisc_opt_addr_space(unsigned char addr_len, int pad)
     329                 :            : {
     330                 :       1716 :         return NDISC_OPT_SPACE(addr_len + pad);
     331                 :            : }
     332                 :            : 
     333                 :            : #if IS_ENABLED(CONFIG_IPV6)
     334                 :         12 : static inline int ndisc_opt_addr_space(struct net_device *dev, u8 icmp6_type)
     335                 :            : {
     336                 :         24 :         return __ndisc_opt_addr_space(dev->addr_len,
     337                 :            :                                       ndisc_addr_option_pad(dev->type)) +
     338                 :         12 :                 ndisc_ops_opt_addr_space(dev, icmp6_type);
     339                 :            : }
     340                 :            : 
     341                 :          0 : static inline int ndisc_redirect_opt_addr_space(struct net_device *dev,
     342                 :            :                                                 struct neighbour *neigh,
     343                 :            :                                                 u8 *ops_data_buf,
     344                 :            :                                                 u8 **ops_data)
     345                 :            : {
     346                 :          0 :         return __ndisc_opt_addr_space(dev->addr_len,
     347                 :            :                                       ndisc_addr_option_pad(dev->type)) +
     348                 :            :                 ndisc_ops_redirect_opt_addr_space(dev, neigh, ops_data_buf,
     349                 :            :                                                   ops_data);
     350                 :            : }
     351                 :            : #endif
     352                 :            : 
     353                 :            : static inline u8 *__ndisc_opt_addr_data(struct nd_opt_hdr *p,
     354                 :            :                                         unsigned char addr_len, int prepad)
     355                 :            : {
     356                 :            :         u8 *lladdr = (u8 *)(p + 1);
     357                 :       1692 :         int lladdrlen = p->nd_opt_len << 3;
     358   [ +  -  #  #  :       1692 :         if (lladdrlen != __ndisc_opt_addr_space(addr_len, prepad))
             +  -  +  - ]
     359                 :            :                 return NULL;
     360                 :       1692 :         return lladdr + prepad;
     361                 :            : }
     362                 :            : 
     363                 :            : static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
     364                 :            :                                       struct net_device *dev)
     365                 :            : {
     366                 :       1692 :         return __ndisc_opt_addr_data(p, dev->addr_len,
     367                 :            :                                      ndisc_addr_option_pad(dev->type));
     368                 :            : }
     369                 :            : 
     370                 :       6034 : static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, __u32 *hash_rnd)
     371                 :            : {
     372                 :            :         const u32 *p32 = pkey;
     373                 :            : 
     374                 :      36376 :         return (((p32[0] ^ hash32_ptr(dev)) * hash_rnd[0]) +
     375                 :       9094 :                 (p32[1] * hash_rnd[1]) +
     376                 :       9094 :                 (p32[2] * hash_rnd[2]) +
     377                 :       9094 :                 (p32[3] * hash_rnd[3]));
     378                 :            : }
     379                 :            : 
     380                 :            : static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey)
     381                 :            : {
     382                 :       6034 :         return ___neigh_lookup_noref(&nd_tbl, neigh_key_eq128, ndisc_hashfn, pkey, dev);
     383                 :            : }
     384                 :            : 
     385                 :            : static inline
     386                 :            : struct neighbour *__ipv6_neigh_lookup_noref_stub(struct net_device *dev,
     387                 :            :                                                  const void *pkey)
     388                 :            : {
     389                 :          0 :         return ___neigh_lookup_noref(ipv6_stub->nd_tbl, neigh_key_eq128,
     390                 :            :                                      ndisc_hashfn, pkey, dev);
     391                 :            : }
     392                 :            : 
     393                 :          0 : static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, const void *pkey)
     394                 :            : {
     395                 :            :         struct neighbour *n;
     396                 :            : 
     397                 :            :         rcu_read_lock_bh();
     398                 :            :         n = __ipv6_neigh_lookup_noref(dev, pkey);
     399   [ #  #  #  # ]:          0 :         if (n && !refcount_inc_not_zero(&n->refcnt))
     400                 :            :                 n = NULL;
     401                 :            :         rcu_read_unlock_bh();
     402                 :            : 
     403                 :          0 :         return n;
     404                 :            : }
     405                 :            : 
     406                 :          0 : static inline void __ipv6_confirm_neigh(struct net_device *dev,
     407                 :            :                                         const void *pkey)
     408                 :            : {
     409                 :            :         struct neighbour *n;
     410                 :            : 
     411                 :            :         rcu_read_lock_bh();
     412                 :            :         n = __ipv6_neigh_lookup_noref(dev, pkey);
     413         [ #  # ]:          0 :         if (n) {
     414                 :          0 :                 unsigned long now = jiffies;
     415                 :            : 
     416                 :            :                 /* avoid dirtying neighbour */
     417         [ #  # ]:          0 :                 if (READ_ONCE(n->confirmed) != now)
     418                 :            :                         WRITE_ONCE(n->confirmed, now);
     419                 :            :         }
     420                 :            :         rcu_read_unlock_bh();
     421                 :          0 : }
     422                 :            : 
     423                 :          0 : static inline void __ipv6_confirm_neigh_stub(struct net_device *dev,
     424                 :            :                                              const void *pkey)
     425                 :            : {
     426                 :            :         struct neighbour *n;
     427                 :            : 
     428                 :            :         rcu_read_lock_bh();
     429                 :            :         n = __ipv6_neigh_lookup_noref_stub(dev, pkey);
     430         [ #  # ]:          0 :         if (n) {
     431                 :          0 :                 unsigned long now = jiffies;
     432                 :            : 
     433                 :            :                 /* avoid dirtying neighbour */
     434         [ #  # ]:          0 :                 if (READ_ONCE(n->confirmed) != now)
     435                 :            :                         WRITE_ONCE(n->confirmed, now);
     436                 :            :         }
     437                 :            :         rcu_read_unlock_bh();
     438                 :          0 : }
     439                 :            : 
     440                 :            : /* uses ipv6_stub and is meant for use outside of IPv6 core */
     441                 :          0 : static inline struct neighbour *ip_neigh_gw6(struct net_device *dev,
     442                 :            :                                              const void *addr)
     443                 :            : {
     444                 :            :         struct neighbour *neigh;
     445                 :            : 
     446                 :            :         neigh = __ipv6_neigh_lookup_noref_stub(dev, addr);
     447         [ #  # ]:          0 :         if (unlikely(!neigh))
     448                 :          0 :                 neigh = __neigh_create(ipv6_stub->nd_tbl, addr, dev, false);
     449                 :            : 
     450                 :          0 :         return neigh;
     451                 :            : }
     452                 :            : 
     453                 :            : int ndisc_init(void);
     454                 :            : int ndisc_late_init(void);
     455                 :            : 
     456                 :            : void ndisc_late_cleanup(void);
     457                 :            : void ndisc_cleanup(void);
     458                 :            : 
     459                 :            : int ndisc_rcv(struct sk_buff *skb);
     460                 :            : 
     461                 :            : void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
     462                 :            :                    const struct in6_addr *daddr, const struct in6_addr *saddr,
     463                 :            :                    u64 nonce);
     464                 :            : 
     465                 :            : void ndisc_send_rs(struct net_device *dev,
     466                 :            :                    const struct in6_addr *saddr, const struct in6_addr *daddr);
     467                 :            : void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
     468                 :            :                    const struct in6_addr *solicited_addr,
     469                 :            :                    bool router, bool solicited, bool override, bool inc_opt);
     470                 :            : 
     471                 :            : void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target);
     472                 :            : 
     473                 :            : int ndisc_mc_map(const struct in6_addr *addr, char *buf, struct net_device *dev,
     474                 :            :                  int dir);
     475                 :            : 
     476                 :            : void ndisc_update(const struct net_device *dev, struct neighbour *neigh,
     477                 :            :                   const u8 *lladdr, u8 new, u32 flags, u8 icmp6_type,
     478                 :            :                   struct ndisc_options *ndopts);
     479                 :            : 
     480                 :            : /*
     481                 :            :  *      IGMP
     482                 :            :  */
     483                 :            : int igmp6_init(void);
     484                 :            : int igmp6_late_init(void);
     485                 :            : 
     486                 :            : void igmp6_cleanup(void);
     487                 :            : void igmp6_late_cleanup(void);
     488                 :            : 
     489                 :            : int igmp6_event_query(struct sk_buff *skb);
     490                 :            : 
     491                 :            : int igmp6_event_report(struct sk_buff *skb);
     492                 :            : 
     493                 :            : 
     494                 :            : #ifdef CONFIG_SYSCTL
     495                 :            : int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write,
     496                 :            :                                void __user *buffer, size_t *lenp, loff_t *ppos);
     497                 :            : int ndisc_ifinfo_sysctl_strategy(struct ctl_table *ctl,
     498                 :            :                                  void __user *oldval, size_t __user *oldlenp,
     499                 :            :                                  void __user *newval, size_t newlen);
     500                 :            : #endif
     501                 :            : 
     502                 :            : void inet6_ifinfo_notify(int event, struct inet6_dev *idev);
     503                 :            : 
     504                 :            : #endif

Generated by: LCOV version 1.14