linux/include/net/addrconf.h
<<
>>
Prefs
   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
  29struct 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/netdevice.h>
  53#include <net/if_inet6.h>
  54#include <net/ipv6.h>
  55
  56struct in6_validator_info {
  57        struct in6_addr         i6vi_addr;
  58        struct inet6_dev        *i6vi_dev;
  59        struct netlink_ext_ack  *extack;
  60};
  61
  62int addrconf_init(void);
  63void addrconf_cleanup(void);
  64
  65int addrconf_add_ifaddr(struct net *net, void __user *arg);
  66int addrconf_del_ifaddr(struct net *net, void __user *arg);
  67int addrconf_set_dstaddr(struct net *net, void __user *arg);
  68
  69int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
  70                  const struct net_device *dev, int strict);
  71int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
  72                            const struct net_device *dev, bool skip_dev_check,
  73                            int strict, u32 banned_flags);
  74
  75#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
  76int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr);
  77#endif
  78
  79bool ipv6_chk_custom_prefix(const struct in6_addr *addr,
  80                                   const unsigned int prefix_len,
  81                                   struct net_device *dev);
  82
  83int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev);
  84
  85struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
  86                                     const struct in6_addr *addr,
  87                                     struct net_device *dev, int strict);
  88
  89int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
  90                       const struct in6_addr *daddr, unsigned int srcprefs,
  91                       struct in6_addr *saddr);
  92int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
  93                      u32 banned_flags);
  94int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
  95                    u32 banned_flags);
  96bool inet_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,
  97                          bool match_wildcard);
  98void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr);
  99void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr);
 100
 101void addrconf_add_linklocal(struct inet6_dev *idev,
 102                            const struct in6_addr *addr, u32 flags);
 103
 104int addrconf_prefix_rcv_add_addr(struct net *net, struct net_device *dev,
 105                                 const struct prefix_info *pinfo,
 106                                 struct inet6_dev *in6_dev,
 107                                 const struct in6_addr *addr, int addr_type,
 108                                 u32 addr_flags, bool sllao, bool tokenized,
 109                                 __u32 valid_lft, u32 prefered_lft);
 110
 111static inline void addrconf_addr_eui48_base(u8 *eui, const char *const addr)
 112{
 113        memcpy(eui, addr, 3);
 114        eui[3] = 0xFF;
 115        eui[4] = 0xFE;
 116        memcpy(eui + 5, addr + 3, 3);
 117}
 118
 119static inline void addrconf_addr_eui48(u8 *eui, const char *const addr)
 120{
 121        addrconf_addr_eui48_base(eui, addr);
 122        eui[0] ^= 2;
 123}
 124
 125static inline int addrconf_ifid_eui48(u8 *eui, struct net_device *dev)
 126{
 127        if (dev->addr_len != ETH_ALEN)
 128                return -1;
 129
 130        /*
 131         * The zSeries OSA network cards can be shared among various
 132         * OS instances, but the OSA cards have only one MAC address.
 133         * This leads to duplicate address conflicts in conjunction
 134         * with IPv6 if more than one instance uses the same card.
 135         *
 136         * The driver for these cards can deliver a unique 16-bit
 137         * identifier for each instance sharing the same card.  It is
 138         * placed instead of 0xFFFE in the interface identifier.  The
 139         * "u" bit of the interface identifier is not inverted in this
 140         * case.  Hence the resulting interface identifier has local
 141         * scope according to RFC2373.
 142         */
 143
 144        addrconf_addr_eui48_base(eui, dev->dev_addr);
 145
 146        if (dev->dev_id) {
 147                eui[3] = (dev->dev_id >> 8) & 0xFF;
 148                eui[4] = dev->dev_id & 0xFF;
 149        } else {
 150                eui[0] ^= 2;
 151        }
 152
 153        return 0;
 154}
 155
 156static inline unsigned long addrconf_timeout_fixup(u32 timeout,
 157                                                   unsigned int unit)
 158{
 159        if (timeout == 0xffffffff)
 160                return ~0UL;
 161
 162        /*
 163         * Avoid arithmetic overflow.
 164         * Assuming unit is constant and non-zero, this "if" statement
 165         * will go away on 64bit archs.
 166         */
 167        if (0xfffffffe > LONG_MAX / unit && timeout > LONG_MAX / unit)
 168                return LONG_MAX / unit;
 169
 170        return timeout;
 171}
 172
 173static inline int addrconf_finite_timeout(unsigned long timeout)
 174{
 175        return ~timeout;
 176}
 177
 178/*
 179 *      IPv6 Address Label subsystem (addrlabel.c)
 180 */
 181int ipv6_addr_label_init(void);
 182void ipv6_addr_label_cleanup(void);
 183int ipv6_addr_label_rtnl_register(void);
 184u32 ipv6_addr_label(struct net *net, const struct in6_addr *addr,
 185                    int type, int ifindex);
 186
 187/*
 188 *      multicast prototypes (mcast.c)
 189 */
 190int ipv6_sock_mc_join(struct sock *sk, int ifindex,
 191                      const struct in6_addr *addr);
 192int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
 193                      const struct in6_addr *addr);
 194void __ipv6_sock_mc_close(struct sock *sk);
 195void ipv6_sock_mc_close(struct sock *sk);
 196bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
 197                    const struct in6_addr *src_addr);
 198
 199int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr);
 200int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr);
 201int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr);
 202void ipv6_mc_up(struct inet6_dev *idev);
 203void ipv6_mc_down(struct inet6_dev *idev);
 204void ipv6_mc_unmap(struct inet6_dev *idev);
 205void ipv6_mc_remap(struct inet6_dev *idev);
 206void ipv6_mc_init_dev(struct inet6_dev *idev);
 207void ipv6_mc_destroy_dev(struct inet6_dev *idev);
 208int ipv6_mc_check_mld(struct sk_buff *skb, struct sk_buff **skb_trimmed);
 209void addrconf_dad_failure(struct sk_buff *skb, struct inet6_ifaddr *ifp);
 210
 211bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group,
 212                         const struct in6_addr *src_addr);
 213
 214void ipv6_mc_dad_complete(struct inet6_dev *idev);
 215
 216/* A stub used by vxlan module. This is ugly, ideally these
 217 * symbols should be built into the core kernel.
 218 */
 219struct ipv6_stub {
 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        int (*ipv6_dst_lookup)(struct net *net, struct sock *sk,
 225                               struct dst_entry **dst, struct flowi6 *fl6);
 226        void (*udpv6_encap_enable)(void);
 227        void (*ndisc_send_na)(struct net_device *dev, const struct in6_addr *daddr,
 228                              const struct in6_addr *solicited_addr,
 229                              bool router, bool solicited, bool override, bool inc_opt);
 230        struct neigh_table *nd_tbl;
 231};
 232extern const struct ipv6_stub *ipv6_stub __read_mostly;
 233
 234/* A stub used by bpf helpers. Similarly ugly as ipv6_stub */
 235struct ipv6_bpf_stub {
 236        int (*inet6_bind)(struct sock *sk, struct sockaddr *uaddr, int addr_len,
 237                          bool force_bind_address_no_port, bool with_lock);
 238};
 239extern const struct ipv6_bpf_stub *ipv6_bpf_stub __read_mostly;
 240
 241/*
 242 * identify MLD packets for MLD filter exceptions
 243 */
 244static inline bool ipv6_is_mld(struct sk_buff *skb, int nexthdr, int offset)
 245{
 246        struct icmp6hdr *hdr;
 247
 248        if (nexthdr != IPPROTO_ICMPV6 ||
 249            !pskb_network_may_pull(skb, offset + sizeof(struct icmp6hdr)))
 250                return false;
 251
 252        hdr = (struct icmp6hdr *)(skb_network_header(skb) + offset);
 253
 254        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                break;
 262        }
 263        return false;
 264}
 265
 266void addrconf_prefix_rcv(struct net_device *dev,
 267                         u8 *opt, int len, bool sllao);
 268
 269/*
 270 *      anycast prototypes (anycast.c)
 271 */
 272int ipv6_sock_ac_join(struct sock *sk, int ifindex,
 273                      const struct in6_addr *addr);
 274int ipv6_sock_ac_drop(struct sock *sk, int ifindex,
 275                      const struct in6_addr *addr);
 276void ipv6_sock_ac_close(struct sock *sk);
 277
 278int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr);
 279int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr);
 280void ipv6_ac_destroy_dev(struct inet6_dev *idev);
 281bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
 282                         const struct in6_addr *addr);
 283bool ipv6_chk_acast_addr_src(struct net *net, struct net_device *dev,
 284                             const struct in6_addr *addr);
 285
 286/* Device notifier */
 287int register_inet6addr_notifier(struct notifier_block *nb);
 288int unregister_inet6addr_notifier(struct notifier_block *nb);
 289int inet6addr_notifier_call_chain(unsigned long val, void *v);
 290
 291int register_inet6addr_validator_notifier(struct notifier_block *nb);
 292int unregister_inet6addr_validator_notifier(struct notifier_block *nb);
 293int inet6addr_validator_notifier_call_chain(unsigned long val, void *v);
 294
 295void inet6_netconf_notify_devconf(struct net *net, int event, int type,
 296                                  int ifindex, struct ipv6_devconf *devconf);
 297
 298/**
 299 * __in6_dev_get - get inet6_dev pointer from netdevice
 300 * @dev: network device
 301 *
 302 * Caller must hold rcu_read_lock or RTNL, because this function
 303 * does not take a reference on the inet6_dev.
 304 */
 305static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev)
 306{
 307        return rcu_dereference_rtnl(dev->ip6_ptr);
 308}
 309
 310/**
 311 * in6_dev_get - get inet6_dev pointer from netdevice
 312 * @dev: network device
 313 *
 314 * This version can be used in any context, and takes a reference
 315 * on the inet6_dev. Callers must use in6_dev_put() later to
 316 * release this reference.
 317 */
 318static inline struct inet6_dev *in6_dev_get(const struct net_device *dev)
 319{
 320        struct inet6_dev *idev;
 321
 322        rcu_read_lock();
 323        idev = rcu_dereference(dev->ip6_ptr);
 324        if (idev)
 325                refcount_inc(&idev->refcnt);
 326        rcu_read_unlock();
 327        return idev;
 328}
 329
 330static inline struct neigh_parms *__in6_dev_nd_parms_get_rcu(const struct net_device *dev)
 331{
 332        struct inet6_dev *idev = __in6_dev_get(dev);
 333
 334        return idev ? idev->nd_parms : NULL;
 335}
 336
 337void in6_dev_finish_destroy(struct inet6_dev *idev);
 338
 339static inline void in6_dev_put(struct inet6_dev *idev)
 340{
 341        if (refcount_dec_and_test(&idev->refcnt))
 342                in6_dev_finish_destroy(idev);
 343}
 344
 345static inline void in6_dev_put_clear(struct inet6_dev **pidev)
 346{
 347        struct inet6_dev *idev = *pidev;
 348
 349        if (idev) {
 350                in6_dev_put(idev);
 351                *pidev = NULL;
 352        }
 353}
 354
 355static inline void __in6_dev_put(struct inet6_dev *idev)
 356{
 357        refcount_dec(&idev->refcnt);
 358}
 359
 360static inline void in6_dev_hold(struct inet6_dev *idev)
 361{
 362        refcount_inc(&idev->refcnt);
 363}
 364
 365void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp);
 366
 367static inline void in6_ifa_put(struct inet6_ifaddr *ifp)
 368{
 369        if (refcount_dec_and_test(&ifp->refcnt))
 370                inet6_ifa_finish_destroy(ifp);
 371}
 372
 373static inline void __in6_ifa_put(struct inet6_ifaddr *ifp)
 374{
 375        refcount_dec(&ifp->refcnt);
 376}
 377
 378static inline void in6_ifa_hold(struct inet6_ifaddr *ifp)
 379{
 380        refcount_inc(&ifp->refcnt);
 381}
 382
 383
 384/*
 385 *      compute link-local solicited-node multicast address
 386 */
 387
 388static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,
 389                                             struct in6_addr *solicited)
 390{
 391        ipv6_addr_set(solicited,
 392                      htonl(0xFF020000), 0,
 393                      htonl(0x1),
 394                      htonl(0xFF000000) | addr->s6_addr32[3]);
 395}
 396
 397static inline bool ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
 398{
 399#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
 400        __be64 *p = (__be64 *)addr;
 401        return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(1))) == 0UL;
 402#else
 403        return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
 404                addr->s6_addr32[1] | addr->s6_addr32[2] |
 405                (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0;
 406#endif
 407}
 408
 409static inline bool ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
 410{
 411#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
 412        __be64 *p = (__be64 *)addr;
 413        return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(2))) == 0UL;
 414#else
 415        return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
 416                addr->s6_addr32[1] | addr->s6_addr32[2] |
 417                (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0;
 418#endif
 419}
 420
 421static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
 422{
 423        return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
 424}
 425
 426static inline bool ipv6_addr_is_solict_mult(const struct in6_addr *addr)
 427{
 428#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
 429        __be64 *p = (__be64 *)addr;
 430        return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) |
 431                ((p[1] ^ cpu_to_be64(0x00000001ff000000UL)) &
 432                 cpu_to_be64(0xffffffffff000000UL))) == 0UL;
 433#else
 434        return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
 435                addr->s6_addr32[1] |
 436                (addr->s6_addr32[2] ^ htonl(0x00000001)) |
 437                (addr->s6_addr[12] ^ 0xff)) == 0;
 438#endif
 439}
 440
 441#ifdef CONFIG_PROC_FS
 442int if6_proc_init(void);
 443void if6_proc_exit(void);
 444#endif
 445
 446#endif
 447