| 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ | 
|---|
| 2 | /* | 
|---|
| 3 | *	inet6 interface/address list definitions | 
|---|
| 4 | *	Linux INET6 implementation | 
|---|
| 5 | * | 
|---|
| 6 | *	Authors: | 
|---|
| 7 | *	Pedro Roque		<roque@di.fc.ul.pt> | 
|---|
| 8 | */ | 
|---|
| 9 |  | 
|---|
| 10 | #ifndef _NET_IF_INET6_H | 
|---|
| 11 | #define _NET_IF_INET6_H | 
|---|
| 12 |  | 
|---|
| 13 | #include <net/snmp.h> | 
|---|
| 14 | #include <linux/ipv6.h> | 
|---|
| 15 | #include <linux/refcount.h> | 
|---|
| 16 |  | 
|---|
| 17 | /* inet6_dev.if_flags */ | 
|---|
| 18 |  | 
|---|
| 19 | #define IF_RA_OTHERCONF	0x80 | 
|---|
| 20 | #define IF_RA_MANAGED	0x40 | 
|---|
| 21 | #define IF_RA_RCVD	0x20 | 
|---|
| 22 | #define IF_RS_SENT	0x10 | 
|---|
| 23 | #define IF_READY	0x80000000 | 
|---|
| 24 |  | 
|---|
| 25 | enum { | 
|---|
| 26 | INET6_IFADDR_STATE_PREDAD, | 
|---|
| 27 | INET6_IFADDR_STATE_DAD, | 
|---|
| 28 | INET6_IFADDR_STATE_POSTDAD, | 
|---|
| 29 | INET6_IFADDR_STATE_ERRDAD, | 
|---|
| 30 | INET6_IFADDR_STATE_DEAD, | 
|---|
| 31 | }; | 
|---|
| 32 |  | 
|---|
| 33 | struct inet6_ifaddr { | 
|---|
| 34 | struct in6_addr		addr; | 
|---|
| 35 | __u32			prefix_len; | 
|---|
| 36 | __u32			rt_priority; | 
|---|
| 37 |  | 
|---|
| 38 | /* In seconds, relative to tstamp. Expiry is at tstamp + HZ * lft. */ | 
|---|
| 39 | __u32			valid_lft; | 
|---|
| 40 | __u32			prefered_lft; | 
|---|
| 41 | refcount_t		refcnt; | 
|---|
| 42 | spinlock_t		lock; | 
|---|
| 43 |  | 
|---|
| 44 | int			state; | 
|---|
| 45 |  | 
|---|
| 46 | __u32			flags; | 
|---|
| 47 | __u8			dad_probes; | 
|---|
| 48 | __u8			stable_privacy_retry; | 
|---|
| 49 |  | 
|---|
| 50 | __u16			scope; | 
|---|
| 51 | __u64			dad_nonce; | 
|---|
| 52 |  | 
|---|
| 53 | unsigned long		cstamp;	/* created timestamp */ | 
|---|
| 54 | unsigned long		tstamp; /* updated timestamp */ | 
|---|
| 55 |  | 
|---|
| 56 | struct delayed_work	dad_work; | 
|---|
| 57 |  | 
|---|
| 58 | struct inet6_dev	*idev; | 
|---|
| 59 | struct fib6_info	*rt; | 
|---|
| 60 |  | 
|---|
| 61 | struct hlist_node	addr_lst; | 
|---|
| 62 | struct list_head	if_list; | 
|---|
| 63 | /* | 
|---|
| 64 | * Used to safely traverse idev->addr_list in process context | 
|---|
| 65 | * if the idev->lock needed to protect idev->addr_list cannot be held. | 
|---|
| 66 | * In that case, add the items to this list temporarily and iterate | 
|---|
| 67 | * without holding idev->lock. | 
|---|
| 68 | * See addrconf_ifdown and dev_forward_change. | 
|---|
| 69 | */ | 
|---|
| 70 | struct list_head	if_list_aux; | 
|---|
| 71 |  | 
|---|
| 72 | struct list_head	tmp_list; | 
|---|
| 73 | struct inet6_ifaddr	*ifpub; | 
|---|
| 74 | int			regen_count; | 
|---|
| 75 |  | 
|---|
| 76 | bool			tokenized; | 
|---|
| 77 |  | 
|---|
| 78 | u8			ifa_proto; | 
|---|
| 79 |  | 
|---|
| 80 | struct rcu_head		rcu; | 
|---|
| 81 | struct in6_addr		peer_addr; | 
|---|
| 82 | }; | 
|---|
| 83 |  | 
|---|
| 84 | struct ip6_sf_socklist { | 
|---|
| 85 | unsigned int		sl_max; | 
|---|
| 86 | unsigned int		sl_count; | 
|---|
| 87 | struct rcu_head		rcu; | 
|---|
| 88 | struct in6_addr		sl_addr[] __counted_by(sl_max); | 
|---|
| 89 | }; | 
|---|
| 90 |  | 
|---|
| 91 | #define IP6_SFBLOCK	10	/* allocate this many at once */ | 
|---|
| 92 |  | 
|---|
| 93 | struct ipv6_mc_socklist { | 
|---|
| 94 | struct in6_addr		addr; | 
|---|
| 95 | int			ifindex; | 
|---|
| 96 | unsigned int		sfmode;		/* MCAST_{INCLUDE,EXCLUDE} */ | 
|---|
| 97 | struct ipv6_mc_socklist __rcu *next; | 
|---|
| 98 | struct ip6_sf_socklist	__rcu *sflist; | 
|---|
| 99 | struct rcu_head		rcu; | 
|---|
| 100 | }; | 
|---|
| 101 |  | 
|---|
| 102 | struct ip6_sf_list { | 
|---|
| 103 | struct ip6_sf_list __rcu *sf_next; | 
|---|
| 104 | struct in6_addr		sf_addr; | 
|---|
| 105 | unsigned long		sf_count[2];	/* include/exclude counts */ | 
|---|
| 106 | unsigned char		sf_gsresp;	/* include in g & s response? */ | 
|---|
| 107 | unsigned char		sf_oldin;	/* change state */ | 
|---|
| 108 | unsigned char		sf_crcount;	/* retrans. left to send */ | 
|---|
| 109 | struct rcu_head		rcu; | 
|---|
| 110 | }; | 
|---|
| 111 |  | 
|---|
| 112 | #define MAF_TIMER_RUNNING	0x01 | 
|---|
| 113 | #define MAF_LAST_REPORTER	0x02 | 
|---|
| 114 | #define MAF_LOADED		0x04 | 
|---|
| 115 | #define MAF_NOREPORT		0x08 | 
|---|
| 116 | #define MAF_GSQUERY		0x10 | 
|---|
| 117 |  | 
|---|
| 118 | struct ifmcaddr6 { | 
|---|
| 119 | struct in6_addr		mca_addr; | 
|---|
| 120 | struct inet6_dev	*idev; | 
|---|
| 121 | struct ifmcaddr6	__rcu *next; | 
|---|
| 122 | struct ip6_sf_list	__rcu *mca_sources; | 
|---|
| 123 | struct ip6_sf_list	__rcu *mca_tomb; | 
|---|
| 124 | unsigned int		mca_sfmode; | 
|---|
| 125 | unsigned char		mca_crcount; | 
|---|
| 126 | unsigned long		mca_sfcount[2]; | 
|---|
| 127 | struct delayed_work	mca_work; | 
|---|
| 128 | unsigned int		mca_flags; | 
|---|
| 129 | int			mca_users; | 
|---|
| 130 | refcount_t		mca_refcnt; | 
|---|
| 131 | unsigned long		mca_cstamp; | 
|---|
| 132 | unsigned long		mca_tstamp; | 
|---|
| 133 | struct rcu_head		rcu; | 
|---|
| 134 | }; | 
|---|
| 135 |  | 
|---|
| 136 | /* Anycast stuff */ | 
|---|
| 137 |  | 
|---|
| 138 | struct ipv6_ac_socklist { | 
|---|
| 139 | struct in6_addr		acl_addr; | 
|---|
| 140 | int			acl_ifindex; | 
|---|
| 141 | struct ipv6_ac_socklist *acl_next; | 
|---|
| 142 | }; | 
|---|
| 143 |  | 
|---|
| 144 | struct ifacaddr6 { | 
|---|
| 145 | struct in6_addr		aca_addr; | 
|---|
| 146 | struct fib6_info	*aca_rt; | 
|---|
| 147 | struct ifacaddr6 __rcu	*aca_next; | 
|---|
| 148 | struct hlist_node	aca_addr_lst; | 
|---|
| 149 | int			aca_users; | 
|---|
| 150 | refcount_t		aca_refcnt; | 
|---|
| 151 | unsigned long		aca_cstamp; | 
|---|
| 152 | unsigned long		aca_tstamp; | 
|---|
| 153 | struct rcu_head		rcu; | 
|---|
| 154 | }; | 
|---|
| 155 |  | 
|---|
| 156 | #define	IFA_HOST	IPV6_ADDR_LOOPBACK | 
|---|
| 157 | #define	IFA_LINK	IPV6_ADDR_LINKLOCAL | 
|---|
| 158 | #define	IFA_SITE	IPV6_ADDR_SITELOCAL | 
|---|
| 159 |  | 
|---|
| 160 | struct ipv6_devstat { | 
|---|
| 161 | struct proc_dir_entry	*proc_dir_entry; | 
|---|
| 162 | DEFINE_SNMP_STAT(struct ipstats_mib, ipv6); | 
|---|
| 163 | DEFINE_SNMP_STAT_ATOMIC(struct icmpv6_mib_device, icmpv6dev); | 
|---|
| 164 | DEFINE_SNMP_STAT_ATOMIC(struct icmpv6msg_mib_device, icmpv6msgdev); | 
|---|
| 165 | }; | 
|---|
| 166 |  | 
|---|
| 167 | struct inet6_dev { | 
|---|
| 168 | struct net_device	*dev; | 
|---|
| 169 | netdevice_tracker	dev_tracker; | 
|---|
| 170 |  | 
|---|
| 171 | struct list_head	addr_list; | 
|---|
| 172 |  | 
|---|
| 173 | struct ifmcaddr6	__rcu *mc_list; | 
|---|
| 174 | struct ifmcaddr6	__rcu *mc_tomb; | 
|---|
| 175 |  | 
|---|
| 176 | unsigned char		mc_qrv;		/* Query Robustness Variable */ | 
|---|
| 177 | unsigned char		mc_gq_running; | 
|---|
| 178 | unsigned char		mc_ifc_count; | 
|---|
| 179 | unsigned char		mc_dad_count; | 
|---|
| 180 |  | 
|---|
| 181 | unsigned long		mc_v1_seen;	/* Max time we stay in MLDv1 mode */ | 
|---|
| 182 | unsigned long		mc_qi;		/* Query Interval */ | 
|---|
| 183 | unsigned long		mc_qri;		/* Query Response Interval */ | 
|---|
| 184 | unsigned long		mc_maxdelay; | 
|---|
| 185 |  | 
|---|
| 186 | struct delayed_work	mc_gq_work;	/* general query work */ | 
|---|
| 187 | struct delayed_work	mc_ifc_work;	/* interface change work */ | 
|---|
| 188 | struct delayed_work	mc_dad_work;	/* dad complete mc work */ | 
|---|
| 189 | struct delayed_work	mc_query_work;	/* mld query work */ | 
|---|
| 190 | struct delayed_work	mc_report_work;	/* mld report work */ | 
|---|
| 191 |  | 
|---|
| 192 | struct sk_buff_head	mc_query_queue;		/* mld query queue */ | 
|---|
| 193 | struct sk_buff_head	mc_report_queue;	/* mld report queue */ | 
|---|
| 194 |  | 
|---|
| 195 | spinlock_t		mc_query_lock;	/* mld query queue lock */ | 
|---|
| 196 | spinlock_t		mc_report_lock;	/* mld query report lock */ | 
|---|
| 197 | struct mutex		mc_lock;	/* mld global lock */ | 
|---|
| 198 |  | 
|---|
| 199 | struct ifacaddr6 __rcu	*ac_list; | 
|---|
| 200 | rwlock_t		lock; | 
|---|
| 201 | refcount_t		refcnt; | 
|---|
| 202 | __u32			if_flags; | 
|---|
| 203 | int			dead; | 
|---|
| 204 |  | 
|---|
| 205 | u32			desync_factor; | 
|---|
| 206 | struct list_head	tempaddr_list; | 
|---|
| 207 |  | 
|---|
| 208 | struct in6_addr		token; | 
|---|
| 209 |  | 
|---|
| 210 | struct neigh_parms	*nd_parms; | 
|---|
| 211 | struct ipv6_devconf	cnf; | 
|---|
| 212 | struct ipv6_devstat	stats; | 
|---|
| 213 |  | 
|---|
| 214 | struct timer_list	rs_timer; | 
|---|
| 215 | __s32			rs_interval;	/* in jiffies */ | 
|---|
| 216 | __u8			rs_probes; | 
|---|
| 217 |  | 
|---|
| 218 | unsigned long		tstamp; /* ipv6InterfaceTable update timestamp */ | 
|---|
| 219 | struct rcu_head		rcu; | 
|---|
| 220 |  | 
|---|
| 221 | unsigned int		ra_mtu; | 
|---|
| 222 | }; | 
|---|
| 223 |  | 
|---|
| 224 | static inline void ipv6_eth_mc_map(const struct in6_addr *addr, char *buf) | 
|---|
| 225 | { | 
|---|
| 226 | /* | 
|---|
| 227 | *	+-------+-------+-------+-------+-------+-------+ | 
|---|
| 228 | *      |   33  |   33  | DST13 | DST14 | DST15 | DST16 | | 
|---|
| 229 | *      +-------+-------+-------+-------+-------+-------+ | 
|---|
| 230 | */ | 
|---|
| 231 |  | 
|---|
| 232 | buf[0]= 0x33; | 
|---|
| 233 | buf[1]= 0x33; | 
|---|
| 234 |  | 
|---|
| 235 | memcpy(to: buf + 2, from: &addr->s6_addr32[3], len: sizeof(__u32)); | 
|---|
| 236 | } | 
|---|
| 237 |  | 
|---|
| 238 | static inline void ipv6_arcnet_mc_map(const struct in6_addr *addr, char *buf) | 
|---|
| 239 | { | 
|---|
| 240 | buf[0] = 0x00; | 
|---|
| 241 | } | 
|---|
| 242 |  | 
|---|
| 243 | static inline void ipv6_ib_mc_map(const struct in6_addr *addr, | 
|---|
| 244 | const unsigned char *broadcast, char *buf) | 
|---|
| 245 | { | 
|---|
| 246 | unsigned char scope = broadcast[5] & 0xF; | 
|---|
| 247 |  | 
|---|
| 248 | buf[0]  = 0;		/* Reserved */ | 
|---|
| 249 | buf[1]  = 0xff;		/* Multicast QPN */ | 
|---|
| 250 | buf[2]  = 0xff; | 
|---|
| 251 | buf[3]  = 0xff; | 
|---|
| 252 | buf[4]  = 0xff; | 
|---|
| 253 | buf[5]  = 0x10 | scope;	/* scope from broadcast address */ | 
|---|
| 254 | buf[6]  = 0x60;		/* IPv6 signature */ | 
|---|
| 255 | buf[7]  = 0x1b; | 
|---|
| 256 | buf[8]  = broadcast[8];	/* P_Key */ | 
|---|
| 257 | buf[9]  = broadcast[9]; | 
|---|
| 258 | memcpy(to: buf + 10, from: addr->s6_addr + 6, len: 10); | 
|---|
| 259 | } | 
|---|
| 260 |  | 
|---|
| 261 | static inline int ipv6_ipgre_mc_map(const struct in6_addr *addr, | 
|---|
| 262 | const unsigned char *broadcast, char *buf) | 
|---|
| 263 | { | 
|---|
| 264 | if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) { | 
|---|
| 265 | memcpy(to: buf, from: broadcast, len: 4); | 
|---|
| 266 | } else { | 
|---|
| 267 | /* v4mapped? */ | 
|---|
| 268 | if ((addr->s6_addr32[0] | addr->s6_addr32[1] | | 
|---|
| 269 | (addr->s6_addr32[2] ^ htonl(0x0000ffff))) != 0) | 
|---|
| 270 | return -EINVAL; | 
|---|
| 271 | memcpy(to: buf, from: &addr->s6_addr32[3], len: 4); | 
|---|
| 272 | } | 
|---|
| 273 | return 0; | 
|---|
| 274 | } | 
|---|
| 275 |  | 
|---|
| 276 | #endif | 
|---|
| 277 |  | 
|---|