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