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