LCOV - code coverage report
Current view: top level - include/net - addrconf.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1 0.0 %
Date: 2023-08-24 13:40:31 Functions: 0 0 -

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

Generated by: LCOV version 1.14