LCOV - code coverage report
Current view: top level - include/net - addrconf.h (source / functions) Hit Total Coverage
Test: combined.info Lines: 41 90 45.6 %
Date: 2022-04-01 14:58:12 Functions: 4 6 66.7 %
Branches: 47 194 24.2 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: GPL-2.0 */
       2                 :            : #ifndef _ADDRCONF_H
       3                 :            : #define _ADDRCONF_H
       4                 :            : 
       5                 :            : #define MAX_RTR_SOLICITATIONS           -1              /* unlimited */
       6                 :            : #define RTR_SOLICITATION_INTERVAL       (4*HZ)
       7                 :            : #define RTR_SOLICITATION_MAX_INTERVAL   (3600*HZ)       /* 1 hour */
       8                 :            : 
       9                 :            : #define MIN_VALID_LIFETIME              (2*3600)        /* 2 hours */
      10                 :            : 
      11                 :            : #define TEMP_VALID_LIFETIME             (7*86400)
      12                 :            : #define TEMP_PREFERRED_LIFETIME         (86400)
      13                 :            : #define REGEN_MAX_RETRY                 (3)
      14                 :            : #define MAX_DESYNC_FACTOR               (600)
      15                 :            : 
      16                 :            : #define ADDR_CHECK_FREQUENCY            (120*HZ)
      17                 :            : 
      18                 :            : #define IPV6_MAX_ADDRESSES              16
      19                 :            : 
      20                 :            : #define ADDRCONF_TIMER_FUZZ_MINUS       (HZ > 50 ? HZ / 50 : 1)
      21                 :            : #define ADDRCONF_TIMER_FUZZ             (HZ / 4)
      22                 :            : #define ADDRCONF_TIMER_FUZZ_MAX         (HZ)
      23                 :            : 
      24                 :            : #define ADDRCONF_NOTIFY_PRIORITY        0
      25                 :            : 
      26                 :            : #include <linux/in.h>
      27                 :            : #include <linux/in6.h>
      28                 :            : 
      29                 :            : struct prefix_info {
      30                 :            :         __u8                    type;
      31                 :            :         __u8                    length;
      32                 :            :         __u8                    prefix_len;
      33                 :            : 
      34                 :            : #if defined(__BIG_ENDIAN_BITFIELD)
      35                 :            :         __u8                    onlink : 1,
      36                 :            :                                 autoconf : 1,
      37                 :            :                                 reserved : 6;
      38                 :            : #elif defined(__LITTLE_ENDIAN_BITFIELD)
      39                 :            :         __u8                    reserved : 6,
      40                 :            :                                 autoconf : 1,
      41                 :            :                                 onlink : 1;
      42                 :            : #else
      43                 :            : #error "Please fix <asm/byteorder.h>"
      44                 :            : #endif
      45                 :            :         __be32                  valid;
      46                 :            :         __be32                  prefered;
      47                 :            :         __be32                  reserved2;
      48                 :            : 
      49                 :            :         struct in6_addr         prefix;
      50                 :            : };
      51                 :            : 
      52                 :            : #include <linux/ipv6.h>
      53                 :            : #include <linux/netdevice.h>
      54                 :            : #include <net/if_inet6.h>
      55                 :            : #include <net/ipv6.h>
      56                 :            : 
      57                 :            : struct in6_validator_info {
      58                 :            :         struct in6_addr         i6vi_addr;
      59                 :            :         struct inet6_dev        *i6vi_dev;
      60                 :            :         struct netlink_ext_ack  *extack;
      61                 :            : };
      62                 :            : 
      63                 :            : struct ifa6_config {
      64                 :            :         const struct in6_addr   *pfx;
      65                 :            :         unsigned int            plen;
      66                 :            : 
      67                 :            :         const struct in6_addr   *peer_pfx;
      68                 :            : 
      69                 :            :         u32                     rt_priority;
      70                 :            :         u32                     ifa_flags;
      71                 :            :         u32                     preferred_lft;
      72                 :            :         u32                     valid_lft;
      73                 :            :         u16                     scope;
      74                 :            : };
      75                 :            : 
      76                 :            : int addrconf_init(void);
      77                 :            : void addrconf_cleanup(void);
      78                 :            : 
      79                 :            : int addrconf_add_ifaddr(struct net *net, void __user *arg);
      80                 :            : int addrconf_del_ifaddr(struct net *net, void __user *arg);
      81                 :            : int addrconf_set_dstaddr(struct net *net, void __user *arg);
      82                 :            : 
      83                 :            : int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
      84                 :            :                   const struct net_device *dev, int strict);
      85                 :            : int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
      86                 :            :                             const struct net_device *dev, bool skip_dev_check,
      87                 :            :                             int strict, u32 banned_flags);
      88                 :            : 
      89                 :            : #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
      90                 :            : int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr);
      91                 :            : #endif
      92                 :            : 
      93                 :            : bool ipv6_chk_custom_prefix(const struct in6_addr *addr,
      94                 :            :                                    const unsigned int prefix_len,
      95                 :            :                                    struct net_device *dev);
      96                 :            : 
      97                 :            : int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev);
      98                 :            : 
      99                 :            : struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
     100                 :            :                                      const struct in6_addr *addr,
     101                 :            :                                      struct net_device *dev, int strict);
     102                 :            : 
     103                 :            : int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
     104                 :            :                        const struct in6_addr *daddr, unsigned int srcprefs,
     105                 :            :                        struct in6_addr *saddr);
     106                 :            : int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
     107                 :            :                       u32 banned_flags);
     108                 :            : int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
     109                 :            :                     u32 banned_flags);
     110                 :            : bool inet_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,
     111                 :            :                           bool match_wildcard);
     112                 :            : bool inet_rcv_saddr_any(const struct sock *sk);
     113                 :            : void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr);
     114                 :            : void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr);
     115                 :            : 
     116                 :            : void addrconf_add_linklocal(struct inet6_dev *idev,
     117                 :            :                             const struct in6_addr *addr, u32 flags);
     118                 :            : 
     119                 :            : int addrconf_prefix_rcv_add_addr(struct net *net, struct net_device *dev,
     120                 :            :                                  const struct prefix_info *pinfo,
     121                 :            :                                  struct inet6_dev *in6_dev,
     122                 :            :                                  const struct in6_addr *addr, int addr_type,
     123                 :            :                                  u32 addr_flags, bool sllao, bool tokenized,
     124                 :            :                                  __u32 valid_lft, u32 prefered_lft);
     125                 :            : 
     126                 :          3 : static inline void addrconf_addr_eui48_base(u8 *eui, const char *const addr)
     127                 :            : {
     128                 :          3 :         memcpy(eui, addr, 3);
     129                 :          3 :         eui[3] = 0xFF;
     130                 :          3 :         eui[4] = 0xFE;
     131                 :          3 :         memcpy(eui + 5, addr + 3, 3);
     132                 :          3 : }
     133                 :            : 
     134                 :            : static inline void addrconf_addr_eui48(u8 *eui, const char *const addr)
     135                 :            : {
     136                 :            :         addrconf_addr_eui48_base(eui, addr);
     137                 :            :         eui[0] ^= 2;
     138                 :            : }
     139                 :            : 
     140                 :          3 : static inline int addrconf_ifid_eui48(u8 *eui, struct net_device *dev)
     141                 :            : {
     142         [ +  - ]:          3 :         if (dev->addr_len != ETH_ALEN)
     143                 :            :                 return -1;
     144                 :            : 
     145                 :            :         /*
     146                 :            :          * The zSeries OSA network cards can be shared among various
     147                 :            :          * OS instances, but the OSA cards have only one MAC address.
     148                 :            :          * This leads to duplicate address conflicts in conjunction
     149                 :            :          * with IPv6 if more than one instance uses the same card.
     150                 :            :          *
     151                 :            :          * The driver for these cards can deliver a unique 16-bit
     152                 :            :          * identifier for each instance sharing the same card.  It is
     153                 :            :          * placed instead of 0xFFFE in the interface identifier.  The
     154                 :            :          * "u" bit of the interface identifier is not inverted in this
     155                 :            :          * case.  Hence the resulting interface identifier has local
     156                 :            :          * scope according to RFC2373.
     157                 :            :          */
     158                 :            : 
     159                 :          3 :         addrconf_addr_eui48_base(eui, dev->dev_addr);
     160                 :            : 
     161         [ -  + ]:          3 :         if (dev->dev_id) {
     162                 :          0 :                 eui[3] = (dev->dev_id >> 8) & 0xFF;
     163                 :          0 :                 eui[4] = dev->dev_id & 0xFF;
     164                 :            :         } else {
     165                 :          3 :                 eui[0] ^= 2;
     166                 :            :         }
     167                 :            : 
     168                 :            :         return 0;
     169                 :            : }
     170                 :            : 
     171                 :         15 : static inline unsigned long addrconf_timeout_fixup(u32 timeout,
     172                 :            :                                                    unsigned int unit)
     173                 :            : {
     174   [ +  -  -  -  :         15 :         if (timeout == 0xffffffff)
          -  +  -  +  -  
                -  -  - ]
     175                 :            :                 return ~0UL;
     176                 :            : 
     177                 :            :         /*
     178                 :            :          * Avoid arithmetic overflow.
     179                 :            :          * Assuming unit is constant and non-zero, this "if" statement
     180                 :            :          * will go away on 64bit archs.
     181                 :            :          */
     182                 :          0 :         if (0xfffffffe > LONG_MAX / unit && timeout > LONG_MAX / unit)
     183                 :            :                 return LONG_MAX / unit;
     184                 :            : 
     185                 :          0 :         return timeout;
     186                 :            : }
     187                 :            : 
     188                 :         15 : static inline int addrconf_finite_timeout(unsigned long timeout)
     189                 :            : {
     190   [ +  -  -  -  :         15 :         return ~timeout;
          -  +  -  +  -  
             -  -  -  -  
                      - ]
     191                 :            : }
     192                 :            : 
     193                 :            : /*
     194                 :            :  *      IPv6 Address Label subsystem (addrlabel.c)
     195                 :            :  */
     196                 :            : int ipv6_addr_label_init(void);
     197                 :            : void ipv6_addr_label_cleanup(void);
     198                 :            : int ipv6_addr_label_rtnl_register(void);
     199                 :            : u32 ipv6_addr_label(struct net *net, const struct in6_addr *addr,
     200                 :            :                     int type, int ifindex);
     201                 :            : 
     202                 :            : /*
     203                 :            :  *      multicast prototypes (mcast.c)
     204                 :            :  */
     205                 :          0 : static inline bool ipv6_mc_may_pull(struct sk_buff *skb,
     206                 :            :                                     unsigned int len)
     207                 :            : {
     208         [ #  # ]:          0 :         if (skb_transport_offset(skb) + ipv6_transport_len(skb) < len)
     209                 :            :                 return false;
     210                 :            : 
     211                 :          0 :         return pskb_may_pull(skb, len);
     212                 :            : }
     213                 :            : 
     214                 :            : int ipv6_sock_mc_join(struct sock *sk, int ifindex,
     215                 :            :                       const struct in6_addr *addr);
     216                 :            : int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
     217                 :            :                       const struct in6_addr *addr);
     218                 :            : void __ipv6_sock_mc_close(struct sock *sk);
     219                 :            : void ipv6_sock_mc_close(struct sock *sk);
     220                 :            : bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
     221                 :            :                     const struct in6_addr *src_addr);
     222                 :            : 
     223                 :            : int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr);
     224                 :            : int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr);
     225                 :            : int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr);
     226                 :            : void ipv6_mc_up(struct inet6_dev *idev);
     227                 :            : void ipv6_mc_down(struct inet6_dev *idev);
     228                 :            : void ipv6_mc_unmap(struct inet6_dev *idev);
     229                 :            : void ipv6_mc_remap(struct inet6_dev *idev);
     230                 :            : void ipv6_mc_init_dev(struct inet6_dev *idev);
     231                 :            : void ipv6_mc_destroy_dev(struct inet6_dev *idev);
     232                 :            : int ipv6_mc_check_icmpv6(struct sk_buff *skb);
     233                 :            : int ipv6_mc_check_mld(struct sk_buff *skb);
     234                 :            : void addrconf_dad_failure(struct sk_buff *skb, struct inet6_ifaddr *ifp);
     235                 :            : 
     236                 :            : bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group,
     237                 :            :                          const struct in6_addr *src_addr);
     238                 :            : 
     239                 :            : void ipv6_mc_dad_complete(struct inet6_dev *idev);
     240                 :            : 
     241                 :            : /*
     242                 :            :  * identify MLD packets for MLD filter exceptions
     243                 :            :  */
     244                 :          0 : static inline bool ipv6_is_mld(struct sk_buff *skb, int nexthdr, int offset)
     245                 :            : {
     246                 :          0 :         struct icmp6hdr *hdr;
     247                 :            : 
     248   [ #  #  #  # ]:          0 :         if (nexthdr != IPPROTO_ICMPV6 ||
     249                 :          0 :             !pskb_network_may_pull(skb, offset + sizeof(struct icmp6hdr)))
     250                 :          0 :                 return false;
     251                 :            : 
     252         [ #  # ]:          0 :         hdr = (struct icmp6hdr *)(skb_network_header(skb) + offset);
     253                 :            : 
     254         [ #  # ]:          0 :         switch (hdr->icmp6_type) {
     255                 :            :         case ICMPV6_MGM_QUERY:
     256                 :            :         case ICMPV6_MGM_REPORT:
     257                 :            :         case ICMPV6_MGM_REDUCTION:
     258                 :            :         case ICMPV6_MLD2_REPORT:
     259                 :            :                 return true;
     260                 :            :         default:
     261                 :          0 :                 break;
     262                 :            :         }
     263                 :          0 :         return false;
     264                 :            : }
     265                 :            : 
     266                 :            : void addrconf_prefix_rcv(struct net_device *dev,
     267                 :            :                          u8 *opt, int len, bool sllao);
     268                 :            : 
     269                 :            : /*
     270                 :            :  *      anycast prototypes (anycast.c)
     271                 :            :  */
     272                 :            : int ipv6_sock_ac_join(struct sock *sk, int ifindex,
     273                 :            :                       const struct in6_addr *addr);
     274                 :            : int ipv6_sock_ac_drop(struct sock *sk, int ifindex,
     275                 :            :                       const struct in6_addr *addr);
     276                 :            : void ipv6_sock_ac_close(struct sock *sk);
     277                 :            : 
     278                 :            : int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr);
     279                 :            : int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr);
     280                 :            : void ipv6_ac_destroy_dev(struct inet6_dev *idev);
     281                 :            : bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
     282                 :            :                          const struct in6_addr *addr);
     283                 :            : bool ipv6_chk_acast_addr_src(struct net *net, struct net_device *dev,
     284                 :            :                              const struct in6_addr *addr);
     285                 :            : int ipv6_anycast_init(void);
     286                 :            : void ipv6_anycast_cleanup(void);
     287                 :            : 
     288                 :            : /* Device notifier */
     289                 :            : int register_inet6addr_notifier(struct notifier_block *nb);
     290                 :            : int unregister_inet6addr_notifier(struct notifier_block *nb);
     291                 :            : int inet6addr_notifier_call_chain(unsigned long val, void *v);
     292                 :            : 
     293                 :            : int register_inet6addr_validator_notifier(struct notifier_block *nb);
     294                 :            : int unregister_inet6addr_validator_notifier(struct notifier_block *nb);
     295                 :            : int inet6addr_validator_notifier_call_chain(unsigned long val, void *v);
     296                 :            : 
     297                 :            : void inet6_netconf_notify_devconf(struct net *net, int event, int type,
     298                 :            :                                   int ifindex, struct ipv6_devconf *devconf);
     299                 :            : 
     300                 :            : /**
     301                 :            :  * __in6_dev_get - get inet6_dev pointer from netdevice
     302                 :            :  * @dev: network device
     303                 :            :  *
     304                 :            :  * Caller must hold rcu_read_lock or RTNL, because this function
     305                 :            :  * does not take a reference on the inet6_dev.
     306                 :            :  */
     307                 :        258 : static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev)
     308                 :            : {
     309   [ -  +  -  -  :        252 :         return rcu_dereference_rtnl(dev->ip6_ptr);
          -  -  +  -  +  
          -  -  -  +  -  
          +  -  -  +  -  
          -  -  +  -  -  
          -  -  +  -  +  
          -  -  -  -  +  
          +  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  -  
          -  -  -  -  -  
             -  -  -  + ]
     310                 :            : }
     311                 :            : 
     312                 :            : /**
     313                 :            :  * __in6_dev_stats_get - get inet6_dev pointer for stats
     314                 :            :  * @dev: network device
     315                 :            :  * @skb: skb for original incoming interface if neeeded
     316                 :            :  *
     317                 :            :  * Caller must hold rcu_read_lock or RTNL, because this function
     318                 :            :  * does not take a reference on the inet6_dev.
     319                 :            :  */
     320                 :          0 : static inline struct inet6_dev *__in6_dev_stats_get(const struct net_device *dev,
     321                 :            :                                                     const struct sk_buff *skb)
     322                 :            : {
     323   [ #  #  #  # ]:          0 :         if (netif_is_l3_master(dev))
     324                 :          0 :                 dev = dev_get_by_index_rcu(dev_net(dev), inet6_iif(skb));
     325   [ #  #  #  # ]:          0 :         return __in6_dev_get(dev);
     326                 :            : }
     327                 :            : 
     328                 :            : /**
     329                 :            :  * __in6_dev_get_safely - get inet6_dev pointer from netdevice
     330                 :            :  * @dev: network device
     331                 :            :  *
     332                 :            :  * This is a safer version of __in6_dev_get
     333                 :            :  */
     334                 :          0 : static inline struct inet6_dev *__in6_dev_get_safely(const struct net_device *dev)
     335                 :            : {
     336   [ #  #  #  # ]:          0 :         if (likely(dev))
     337                 :          0 :                 return rcu_dereference_rtnl(dev->ip6_ptr);
     338                 :            :         else
     339                 :            :                 return NULL;
     340                 :            : }
     341                 :            : 
     342                 :            : /**
     343                 :            :  * in6_dev_get - get inet6_dev pointer from netdevice
     344                 :            :  * @dev: network device
     345                 :            :  *
     346                 :            :  * This version can be used in any context, and takes a reference
     347                 :            :  * on the inet6_dev. Callers must use in6_dev_put() later to
     348                 :            :  * release this reference.
     349                 :            :  */
     350                 :         83 : static inline struct inet6_dev *in6_dev_get(const struct net_device *dev)
     351                 :            : {
     352                 :         83 :         struct inet6_dev *idev;
     353                 :            : 
     354                 :         83 :         rcu_read_lock();
     355   [ +  -  +  +  :         83 :         idev = rcu_dereference(dev->ip6_ptr);
          +  -  -  -  +  
          -  +  -  -  -  
             +  -  -  - ]
     356   [ +  -  +  +  :         83 :         if (idev)
          +  -  -  -  +  
          -  +  -  -  -  
             +  -  -  - ]
     357                 :         80 :                 refcount_inc(&idev->refcnt);
     358                 :         83 :         rcu_read_unlock();
     359   [ +  +  -  +  :         80 :         return idev;
          +  -  -  -  +  
                      - ]
     360                 :            : }
     361                 :            : 
     362                 :          0 : static inline struct neigh_parms *__in6_dev_nd_parms_get_rcu(const struct net_device *dev)
     363                 :            : {
     364         [ #  # ]:          0 :         struct inet6_dev *idev = __in6_dev_get(dev);
     365                 :            : 
     366         [ #  # ]:          0 :         return idev ? idev->nd_parms : NULL;
     367                 :            : }
     368                 :            : 
     369                 :            : void in6_dev_finish_destroy(struct inet6_dev *idev);
     370                 :            : 
     371                 :         64 : static inline void in6_dev_put(struct inet6_dev *idev)
     372                 :            : {
     373         [ -  + ]:         64 :         if (refcount_dec_and_test(&idev->refcnt))
     374                 :          0 :                 in6_dev_finish_destroy(idev);
     375                 :         64 : }
     376                 :            : 
     377                 :          0 : static inline void in6_dev_put_clear(struct inet6_dev **pidev)
     378                 :            : {
     379                 :          0 :         struct inet6_dev *idev = *pidev;
     380                 :            : 
     381         [ #  # ]:          0 :         if (idev) {
     382                 :          0 :                 in6_dev_put(idev);
     383                 :          0 :                 *pidev = NULL;
     384                 :            :         }
     385                 :            : }
     386                 :            : 
     387                 :          0 : static inline void __in6_dev_put(struct inet6_dev *idev)
     388                 :            : {
     389                 :          0 :         refcount_dec(&idev->refcnt);
     390                 :          0 : }
     391                 :            : 
     392                 :         21 : static inline void in6_dev_hold(struct inet6_dev *idev)
     393                 :            : {
     394                 :         21 :         refcount_inc(&idev->refcnt);
     395                 :         12 : }
     396                 :            : 
     397                 :            : /* called with rcu_read_lock held */
     398                 :          6 : static inline bool ip6_ignore_linkdown(const struct net_device *dev)
     399                 :            : {
     400   [ -  -  -  -  :          6 :         const struct inet6_dev *idev = __in6_dev_get(dev);
             -  -  -  + ]
     401                 :            : 
     402   [ -  -  -  -  :          6 :         return !!idev->cnf.ignore_routes_with_linkdown;
             -  -  -  + ]
     403                 :            : }
     404                 :            : 
     405                 :            : void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp);
     406                 :            : 
     407                 :         18 : static inline void in6_ifa_put(struct inet6_ifaddr *ifp)
     408                 :            : {
     409         [ -  + ]:         18 :         if (refcount_dec_and_test(&ifp->refcnt))
     410                 :          0 :                 inet6_ifa_finish_destroy(ifp);
     411                 :         18 : }
     412                 :            : 
     413                 :          0 : static inline void __in6_ifa_put(struct inet6_ifaddr *ifp)
     414                 :            : {
     415                 :          0 :         refcount_dec(&ifp->refcnt);
     416                 :          0 : }
     417                 :            : 
     418                 :         18 : static inline void in6_ifa_hold(struct inet6_ifaddr *ifp)
     419                 :            : {
     420                 :         18 :         refcount_inc(&ifp->refcnt);
     421                 :          0 : }
     422                 :            : 
     423                 :            : 
     424                 :            : /*
     425                 :            :  *      compute link-local solicited-node multicast address
     426                 :            :  */
     427                 :            : 
     428                 :          6 : static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,
     429                 :            :                                              struct in6_addr *solicited)
     430                 :            : {
     431   [ -  +  -  -  :          6 :         ipv6_addr_set(solicited,
                   -  + ]
     432                 :            :                       htonl(0xFF020000), 0,
     433                 :            :                       htonl(0x1),
     434                 :            :                       htonl(0xFF000000) | addr->s6_addr32[3]);
     435                 :            : }
     436                 :            : 
     437                 :          0 : static inline bool ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
     438                 :            : {
     439                 :            : #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
     440                 :          0 :         __be64 *p = (__force __be64 *)addr;
     441         [ #  # ]:          0 :         return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(1))) == 0UL;
     442                 :            : #else
     443                 :            :         return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
     444                 :            :                 addr->s6_addr32[1] | addr->s6_addr32[2] |
     445                 :            :                 (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0;
     446                 :            : #endif
     447                 :            : }
     448                 :            : 
     449                 :            : static inline bool ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
     450                 :            : {
     451                 :            : #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
     452                 :            :         __be64 *p = (__force __be64 *)addr;
     453                 :            :         return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(2))) == 0UL;
     454                 :            : #else
     455                 :            :         return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
     456                 :            :                 addr->s6_addr32[1] | addr->s6_addr32[2] |
     457                 :            :                 (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0;
     458                 :            : #endif
     459                 :            : }
     460                 :            : 
     461                 :          0 : static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
     462                 :            : {
     463         [ #  # ]:          0 :         return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
     464                 :            : }
     465                 :            : 
     466                 :          0 : static inline bool ipv6_addr_is_solict_mult(const struct in6_addr *addr)
     467                 :            : {
     468                 :            : #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
     469                 :          0 :         __be64 *p = (__force __be64 *)addr;
     470                 :          0 :         return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) |
     471         [ #  # ]:          0 :                 ((p[1] ^ cpu_to_be64(0x00000001ff000000UL)) &
     472                 :            :                  cpu_to_be64(0xffffffffff000000UL))) == 0UL;
     473                 :            : #else
     474                 :            :         return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
     475                 :            :                 addr->s6_addr32[1] |
     476                 :            :                 (addr->s6_addr32[2] ^ htonl(0x00000001)) |
     477                 :            :                 (addr->s6_addr[12] ^ 0xff)) == 0;
     478                 :            : #endif
     479                 :            : }
     480                 :            : 
     481                 :            : static inline bool ipv6_addr_is_all_snoopers(const struct in6_addr *addr)
     482                 :            : {
     483                 :            : #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
     484                 :            :         __be64 *p = (__force __be64 *)addr;
     485                 :            : 
     486                 :            :         return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) |
     487                 :            :                 (p[1] ^ cpu_to_be64(0x6a))) == 0UL;
     488                 :            : #else
     489                 :            :         return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
     490                 :            :                 addr->s6_addr32[1] | addr->s6_addr32[2] |
     491                 :            :                 (addr->s6_addr32[3] ^ htonl(0x0000006a))) == 0;
     492                 :            : #endif
     493                 :            : }
     494                 :            : 
     495                 :            : #ifdef CONFIG_PROC_FS
     496                 :            : int if6_proc_init(void);
     497                 :            : void if6_proc_exit(void);
     498                 :            : #endif
     499                 :            : 
     500                 :            : #endif

Generated by: LCOV version 1.14