0001
0002 #ifndef _ADDRCONF_H
0003 #define _ADDRCONF_H
0004
0005 #define MAX_RTR_SOLICITATIONS -1
0006 #define RTR_SOLICITATION_INTERVAL (4*HZ)
0007 #define RTR_SOLICITATION_MAX_INTERVAL (3600*HZ)
0008
0009 #define MIN_VALID_LIFETIME (2*3600)
0010
0011 #define TEMP_VALID_LIFETIME (7*86400)
0012 #define TEMP_PREFERRED_LIFETIME (86400)
0013 #define REGEN_MAX_RETRY (3)
0014 #define MAX_DESYNC_FACTOR (600)
0015
0016 #define ADDR_CHECK_FREQUENCY (120*HZ)
0017
0018 #define IPV6_MAX_ADDRESSES 16
0019
0020 #define ADDRCONF_TIMER_FUZZ_MINUS (HZ > 50 ? HZ / 50 : 1)
0021 #define ADDRCONF_TIMER_FUZZ (HZ / 4)
0022 #define ADDRCONF_TIMER_FUZZ_MAX (HZ)
0023
0024 #define ADDRCONF_NOTIFY_PRIORITY 0
0025
0026 #include <linux/in.h>
0027 #include <linux/in6.h>
0028
0029 struct prefix_info {
0030 __u8 type;
0031 __u8 length;
0032 __u8 prefix_len;
0033
0034 #if defined(__BIG_ENDIAN_BITFIELD)
0035 __u8 onlink : 1,
0036 autoconf : 1,
0037 reserved : 6;
0038 #elif defined(__LITTLE_ENDIAN_BITFIELD)
0039 __u8 reserved : 6,
0040 autoconf : 1,
0041 onlink : 1;
0042 #else
0043 #error "Please fix <asm/byteorder.h>"
0044 #endif
0045 __be32 valid;
0046 __be32 prefered;
0047 __be32 reserved2;
0048
0049 struct in6_addr prefix;
0050 };
0051
0052 #include <linux/ipv6.h>
0053 #include <linux/netdevice.h>
0054 #include <net/if_inet6.h>
0055 #include <net/ipv6.h>
0056
0057 struct in6_validator_info {
0058 struct in6_addr i6vi_addr;
0059 struct inet6_dev *i6vi_dev;
0060 struct netlink_ext_ack *extack;
0061 };
0062
0063 struct ifa6_config {
0064 const struct in6_addr *pfx;
0065 unsigned int plen;
0066
0067 u8 ifa_proto;
0068
0069 const struct in6_addr *peer_pfx;
0070
0071 u32 rt_priority;
0072 u32 ifa_flags;
0073 u32 preferred_lft;
0074 u32 valid_lft;
0075 u16 scope;
0076 };
0077
0078 int addrconf_init(void);
0079 void addrconf_cleanup(void);
0080
0081 int addrconf_add_ifaddr(struct net *net, void __user *arg);
0082 int addrconf_del_ifaddr(struct net *net, void __user *arg);
0083 int addrconf_set_dstaddr(struct net *net, void __user *arg);
0084
0085 int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
0086 const struct net_device *dev, int strict);
0087 int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
0088 const struct net_device *dev, bool skip_dev_check,
0089 int strict, u32 banned_flags);
0090
0091 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
0092 int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr);
0093 #endif
0094
0095 int ipv6_chk_rpl_srh_loop(struct net *net, const struct in6_addr *segs,
0096 unsigned char nsegs);
0097
0098 bool ipv6_chk_custom_prefix(const struct in6_addr *addr,
0099 const unsigned int prefix_len,
0100 struct net_device *dev);
0101
0102 int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev);
0103
0104 struct net_device *ipv6_dev_find(struct net *net, const struct in6_addr *addr,
0105 struct net_device *dev);
0106
0107 struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
0108 const struct in6_addr *addr,
0109 struct net_device *dev, int strict);
0110
0111 int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
0112 const struct in6_addr *daddr, unsigned int srcprefs,
0113 struct in6_addr *saddr);
0114 int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
0115 u32 banned_flags);
0116 bool inet_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,
0117 bool match_wildcard);
0118 bool inet_rcv_saddr_any(const struct sock *sk);
0119 void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr);
0120 void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr);
0121
0122 void addrconf_add_linklocal(struct inet6_dev *idev,
0123 const struct in6_addr *addr, u32 flags);
0124
0125 int addrconf_prefix_rcv_add_addr(struct net *net, struct net_device *dev,
0126 const struct prefix_info *pinfo,
0127 struct inet6_dev *in6_dev,
0128 const struct in6_addr *addr, int addr_type,
0129 u32 addr_flags, bool sllao, bool tokenized,
0130 __u32 valid_lft, u32 prefered_lft);
0131
0132 static inline void addrconf_addr_eui48_base(u8 *eui, const char *const addr)
0133 {
0134 memcpy(eui, addr, 3);
0135 eui[3] = 0xFF;
0136 eui[4] = 0xFE;
0137 memcpy(eui + 5, addr + 3, 3);
0138 }
0139
0140 static inline void addrconf_addr_eui48(u8 *eui, const char *const addr)
0141 {
0142 addrconf_addr_eui48_base(eui, addr);
0143 eui[0] ^= 2;
0144 }
0145
0146 static inline int addrconf_ifid_eui48(u8 *eui, struct net_device *dev)
0147 {
0148 if (dev->addr_len != ETH_ALEN)
0149 return -1;
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165 addrconf_addr_eui48_base(eui, dev->dev_addr);
0166
0167 if (dev->dev_id) {
0168 eui[3] = (dev->dev_id >> 8) & 0xFF;
0169 eui[4] = dev->dev_id & 0xFF;
0170 } else {
0171 eui[0] ^= 2;
0172 }
0173
0174 return 0;
0175 }
0176
0177 static inline unsigned long addrconf_timeout_fixup(u32 timeout,
0178 unsigned int unit)
0179 {
0180 if (timeout == 0xffffffff)
0181 return ~0UL;
0182
0183
0184
0185
0186
0187
0188 if (0xfffffffe > LONG_MAX / unit && timeout > LONG_MAX / unit)
0189 return LONG_MAX / unit;
0190
0191 return timeout;
0192 }
0193
0194 static inline int addrconf_finite_timeout(unsigned long timeout)
0195 {
0196 return ~timeout;
0197 }
0198
0199
0200
0201
0202 int ipv6_addr_label_init(void);
0203 void ipv6_addr_label_cleanup(void);
0204 int ipv6_addr_label_rtnl_register(void);
0205 u32 ipv6_addr_label(struct net *net, const struct in6_addr *addr,
0206 int type, int ifindex);
0207
0208
0209
0210
0211 static inline bool ipv6_mc_may_pull(struct sk_buff *skb,
0212 unsigned int len)
0213 {
0214 if (skb_transport_offset(skb) + ipv6_transport_len(skb) < len)
0215 return false;
0216
0217 return pskb_may_pull(skb, len);
0218 }
0219
0220 int ipv6_sock_mc_join(struct sock *sk, int ifindex,
0221 const struct in6_addr *addr);
0222 int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
0223 const struct in6_addr *addr);
0224 void __ipv6_sock_mc_close(struct sock *sk);
0225 void ipv6_sock_mc_close(struct sock *sk);
0226 bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
0227 const struct in6_addr *src_addr);
0228
0229 int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr);
0230 int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr);
0231 int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr);
0232 void ipv6_mc_up(struct inet6_dev *idev);
0233 void ipv6_mc_down(struct inet6_dev *idev);
0234 void ipv6_mc_unmap(struct inet6_dev *idev);
0235 void ipv6_mc_remap(struct inet6_dev *idev);
0236 void ipv6_mc_init_dev(struct inet6_dev *idev);
0237 void ipv6_mc_destroy_dev(struct inet6_dev *idev);
0238 int ipv6_mc_check_mld(struct sk_buff *skb);
0239 void addrconf_dad_failure(struct sk_buff *skb, struct inet6_ifaddr *ifp);
0240
0241 bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group,
0242 const struct in6_addr *src_addr);
0243
0244 void ipv6_mc_dad_complete(struct inet6_dev *idev);
0245
0246
0247
0248
0249 static inline bool ipv6_is_mld(struct sk_buff *skb, int nexthdr, int offset)
0250 {
0251 struct icmp6hdr *hdr;
0252
0253 if (nexthdr != IPPROTO_ICMPV6 ||
0254 !pskb_network_may_pull(skb, offset + sizeof(struct icmp6hdr)))
0255 return false;
0256
0257 hdr = (struct icmp6hdr *)(skb_network_header(skb) + offset);
0258
0259 switch (hdr->icmp6_type) {
0260 case ICMPV6_MGM_QUERY:
0261 case ICMPV6_MGM_REPORT:
0262 case ICMPV6_MGM_REDUCTION:
0263 case ICMPV6_MLD2_REPORT:
0264 return true;
0265 default:
0266 break;
0267 }
0268 return false;
0269 }
0270
0271 void addrconf_prefix_rcv(struct net_device *dev,
0272 u8 *opt, int len, bool sllao);
0273
0274
0275
0276
0277 int ipv6_sock_ac_join(struct sock *sk, int ifindex,
0278 const struct in6_addr *addr);
0279 int ipv6_sock_ac_drop(struct sock *sk, int ifindex,
0280 const struct in6_addr *addr);
0281 void __ipv6_sock_ac_close(struct sock *sk);
0282 void ipv6_sock_ac_close(struct sock *sk);
0283
0284 int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr);
0285 int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr);
0286 void ipv6_ac_destroy_dev(struct inet6_dev *idev);
0287 bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
0288 const struct in6_addr *addr);
0289 bool ipv6_chk_acast_addr_src(struct net *net, struct net_device *dev,
0290 const struct in6_addr *addr);
0291 int ipv6_anycast_init(void);
0292 void ipv6_anycast_cleanup(void);
0293
0294
0295 int register_inet6addr_notifier(struct notifier_block *nb);
0296 int unregister_inet6addr_notifier(struct notifier_block *nb);
0297 int inet6addr_notifier_call_chain(unsigned long val, void *v);
0298
0299 int register_inet6addr_validator_notifier(struct notifier_block *nb);
0300 int unregister_inet6addr_validator_notifier(struct notifier_block *nb);
0301 int inet6addr_validator_notifier_call_chain(unsigned long val, void *v);
0302
0303 void inet6_netconf_notify_devconf(struct net *net, int event, int type,
0304 int ifindex, struct ipv6_devconf *devconf);
0305
0306
0307
0308
0309
0310
0311
0312
0313 static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev)
0314 {
0315 return rcu_dereference_rtnl(dev->ip6_ptr);
0316 }
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326 static inline struct inet6_dev *__in6_dev_stats_get(const struct net_device *dev,
0327 const struct sk_buff *skb)
0328 {
0329 if (netif_is_l3_master(dev))
0330 dev = dev_get_by_index_rcu(dev_net(dev), inet6_iif(skb));
0331 return __in6_dev_get(dev);
0332 }
0333
0334
0335
0336
0337
0338
0339
0340 static inline struct inet6_dev *__in6_dev_get_safely(const struct net_device *dev)
0341 {
0342 if (likely(dev))
0343 return rcu_dereference_rtnl(dev->ip6_ptr);
0344 else
0345 return NULL;
0346 }
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356 static inline struct inet6_dev *in6_dev_get(const struct net_device *dev)
0357 {
0358 struct inet6_dev *idev;
0359
0360 rcu_read_lock();
0361 idev = rcu_dereference(dev->ip6_ptr);
0362 if (idev)
0363 refcount_inc(&idev->refcnt);
0364 rcu_read_unlock();
0365 return idev;
0366 }
0367
0368 static inline struct neigh_parms *__in6_dev_nd_parms_get_rcu(const struct net_device *dev)
0369 {
0370 struct inet6_dev *idev = __in6_dev_get(dev);
0371
0372 return idev ? idev->nd_parms : NULL;
0373 }
0374
0375 void in6_dev_finish_destroy(struct inet6_dev *idev);
0376
0377 static inline void in6_dev_put(struct inet6_dev *idev)
0378 {
0379 if (refcount_dec_and_test(&idev->refcnt))
0380 in6_dev_finish_destroy(idev);
0381 }
0382
0383 static inline void in6_dev_put_clear(struct inet6_dev **pidev)
0384 {
0385 struct inet6_dev *idev = *pidev;
0386
0387 if (idev) {
0388 in6_dev_put(idev);
0389 *pidev = NULL;
0390 }
0391 }
0392
0393 static inline void __in6_dev_put(struct inet6_dev *idev)
0394 {
0395 refcount_dec(&idev->refcnt);
0396 }
0397
0398 static inline void in6_dev_hold(struct inet6_dev *idev)
0399 {
0400 refcount_inc(&idev->refcnt);
0401 }
0402
0403
0404 static inline bool ip6_ignore_linkdown(const struct net_device *dev)
0405 {
0406 const struct inet6_dev *idev = __in6_dev_get(dev);
0407
0408 if (unlikely(!idev))
0409 return true;
0410
0411 return !!idev->cnf.ignore_routes_with_linkdown;
0412 }
0413
0414 void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp);
0415
0416 static inline void in6_ifa_put(struct inet6_ifaddr *ifp)
0417 {
0418 if (refcount_dec_and_test(&ifp->refcnt))
0419 inet6_ifa_finish_destroy(ifp);
0420 }
0421
0422 static inline void __in6_ifa_put(struct inet6_ifaddr *ifp)
0423 {
0424 refcount_dec(&ifp->refcnt);
0425 }
0426
0427 static inline void in6_ifa_hold(struct inet6_ifaddr *ifp)
0428 {
0429 refcount_inc(&ifp->refcnt);
0430 }
0431
0432
0433
0434
0435
0436
0437 static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,
0438 struct in6_addr *solicited)
0439 {
0440 ipv6_addr_set(solicited,
0441 htonl(0xFF020000), 0,
0442 htonl(0x1),
0443 htonl(0xFF000000) | addr->s6_addr32[3]);
0444 }
0445
0446 static inline bool ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
0447 {
0448 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
0449 __be64 *p = (__force __be64 *)addr;
0450 return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(1))) == 0UL;
0451 #else
0452 return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
0453 addr->s6_addr32[1] | addr->s6_addr32[2] |
0454 (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0;
0455 #endif
0456 }
0457
0458 static inline bool ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
0459 {
0460 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
0461 __be64 *p = (__force __be64 *)addr;
0462 return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(2))) == 0UL;
0463 #else
0464 return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
0465 addr->s6_addr32[1] | addr->s6_addr32[2] |
0466 (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0;
0467 #endif
0468 }
0469
0470 static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
0471 {
0472 return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
0473 }
0474
0475 static inline bool ipv6_addr_is_solict_mult(const struct in6_addr *addr)
0476 {
0477 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
0478 __be64 *p = (__force __be64 *)addr;
0479 return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) |
0480 ((p[1] ^ cpu_to_be64(0x00000001ff000000UL)) &
0481 cpu_to_be64(0xffffffffff000000UL))) == 0UL;
0482 #else
0483 return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
0484 addr->s6_addr32[1] |
0485 (addr->s6_addr32[2] ^ htonl(0x00000001)) |
0486 (addr->s6_addr[12] ^ 0xff)) == 0;
0487 #endif
0488 }
0489
0490 static inline bool ipv6_addr_is_all_snoopers(const struct in6_addr *addr)
0491 {
0492 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
0493 __be64 *p = (__force __be64 *)addr;
0494
0495 return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) |
0496 (p[1] ^ cpu_to_be64(0x6a))) == 0UL;
0497 #else
0498 return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
0499 addr->s6_addr32[1] | addr->s6_addr32[2] |
0500 (addr->s6_addr32[3] ^ htonl(0x0000006a))) == 0;
0501 #endif
0502 }
0503
0504 #ifdef CONFIG_PROC_FS
0505 int if6_proc_init(void);
0506 void if6_proc_exit(void);
0507 #endif
0508
0509 #endif