| 1 | /*	$NetBSD: in6_var.h,v 1.87 2016/09/14 16:17:17 christos Exp $	*/ | 
| 2 | /*	$KAME: in6_var.h,v 1.81 2002/06/08 11:16:51 itojun Exp $	*/ | 
| 3 |  | 
| 4 | /* | 
| 5 |  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | 
| 6 |  * All rights reserved. | 
| 7 |  * | 
| 8 |  * Redistribution and use in source and binary forms, with or without | 
| 9 |  * modification, are permitted provided that the following conditions | 
| 10 |  * are met: | 
| 11 |  * 1. Redistributions of source code must retain the above copyright | 
| 12 |  *    notice, this list of conditions and the following disclaimer. | 
| 13 |  * 2. Redistributions in binary form must reproduce the above copyright | 
| 14 |  *    notice, this list of conditions and the following disclaimer in the | 
| 15 |  *    documentation and/or other materials provided with the distribution. | 
| 16 |  * 3. Neither the name of the project nor the names of its contributors | 
| 17 |  *    may be used to endorse or promote products derived from this software | 
| 18 |  *    without specific prior written permission. | 
| 19 |  * | 
| 20 |  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | 
| 21 |  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
| 22 |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
| 23 |  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | 
| 24 |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
| 25 |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
| 26 |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
| 27 |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
| 28 |  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
| 29 |  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
| 30 |  * SUCH DAMAGE. | 
| 31 |  */ | 
| 32 |  | 
| 33 | /* | 
| 34 |  * Copyright (c) 1985, 1986, 1993 | 
| 35 |  *	The Regents of the University of California.  All rights reserved. | 
| 36 |  * | 
| 37 |  * Redistribution and use in source and binary forms, with or without | 
| 38 |  * modification, are permitted provided that the following conditions | 
| 39 |  * are met: | 
| 40 |  * 1. Redistributions of source code must retain the above copyright | 
| 41 |  *    notice, this list of conditions and the following disclaimer. | 
| 42 |  * 2. Redistributions in binary form must reproduce the above copyright | 
| 43 |  *    notice, this list of conditions and the following disclaimer in the | 
| 44 |  *    documentation and/or other materials provided with the distribution. | 
| 45 |  * 3. Neither the name of the University nor the names of its contributors | 
| 46 |  *    may be used to endorse or promote products derived from this software | 
| 47 |  *    without specific prior written permission. | 
| 48 |  * | 
| 49 |  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 
| 50 |  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
| 51 |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
| 52 |  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 
| 53 |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
| 54 |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
| 55 |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
| 56 |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
| 57 |  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
| 58 |  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
| 59 |  * SUCH DAMAGE. | 
| 60 |  * | 
| 61 |  *	@(#)in_var.h	8.1 (Berkeley) 6/10/93 | 
| 62 |  */ | 
| 63 |  | 
| 64 | #ifndef _NETINET6_IN6_VAR_H_ | 
| 65 | #define _NETINET6_IN6_VAR_H_ | 
| 66 |  | 
| 67 | #include <sys/callout.h> | 
| 68 | #include <sys/ioccom.h> | 
| 69 |  | 
| 70 | /* | 
| 71 |  * Interface address, Internet version.  One of these structures | 
| 72 |  * is allocated for each interface with an Internet address. | 
| 73 |  * The ifaddr structure contains the protocol-independent part | 
| 74 |  * of the structure and is assumed to be first. | 
| 75 |  */ | 
| 76 |  | 
| 77 | /* | 
| 78 |  * pltime/vltime are just for future reference (required to implements 2 | 
| 79 |  * hour rule for hosts).  they should never be modified by nd6_timeout or | 
| 80 |  * anywhere else. | 
| 81 |  *	userland -> kernel: accept pltime/vltime | 
| 82 |  *	kernel -> userland: throw up everything | 
| 83 |  *	in kernel: modify preferred/expire only | 
| 84 |  */ | 
| 85 | struct in6_addrlifetime { | 
| 86 | 	time_t ia6t_expire;	/* valid lifetime expiration time */ | 
| 87 | 	time_t ia6t_preferred;	/* preferred lifetime expiration time */ | 
| 88 | 	u_int32_t ia6t_vltime;	/* valid lifetime */ | 
| 89 | 	u_int32_t ia6t_pltime;	/* prefix lifetime */ | 
| 90 | }; | 
| 91 |  | 
| 92 | struct lltable; | 
| 93 | struct nd_ifinfo; | 
| 94 | struct  { | 
| 95 | 	struct in6_ifstat *; | 
| 96 | 	struct icmp6_ifstat *; | 
| 97 | 	struct nd_ifinfo *; | 
| 98 | 	struct scope6_id *; | 
| 99 | 	int ; | 
| 100 | 	int ; | 
| 101 | 	struct lltable *; | 
| 102 | }; | 
| 103 |  | 
| 104 | LIST_HEAD(in6_multihead, in6_multi); | 
| 105 | struct	in6_ifaddr { | 
| 106 | 	struct	ifaddr ia_ifa;		/* protocol-independent info */ | 
| 107 | #define	ia_ifp		ia_ifa.ifa_ifp | 
| 108 | #define ia_flags	ia_ifa.ifa_flags | 
| 109 | 	struct	sockaddr_in6 ia_addr;	/* interface address */ | 
| 110 | 	struct	sockaddr_in6 ia_net;	/* network number of interface */ | 
| 111 | 	struct	sockaddr_in6 ia_dstaddr; /* space for destination addr */ | 
| 112 | 	struct	sockaddr_in6 ia_prefixmask; /* prefix mask */ | 
| 113 | 	u_int32_t ia_plen;		/* prefix length */ | 
| 114 | 	/* DEPRECATED. Keep it to avoid breaking kvm(3) users */ | 
| 115 | 	struct	in6_ifaddr *ia_next;	/* next in6 list of IP6 addresses */ | 
| 116 | 	struct	in6_multihead ia6_multiaddrs; | 
| 117 | 					/* list of multicast addresses */ | 
| 118 | 	int	ia6_flags; | 
| 119 |  | 
| 120 | 	struct in6_addrlifetime ia6_lifetime; | 
| 121 | 	time_t	ia6_createtime; /* the creation time of this address, which is | 
| 122 | 				 * currently used for temporary addresses only. | 
| 123 | 				 */ | 
| 124 | 	time_t	ia6_updatetime; | 
| 125 |  | 
| 126 | 	/* back pointer to the ND prefix (for autoconfigured addresses only) */ | 
| 127 | 	struct nd_prefix *ia6_ndpr; | 
| 128 |  | 
| 129 | 	/* multicast addresses joined from the kernel */ | 
| 130 | 	LIST_HEAD(, in6_multi_mship) ia6_memberships; | 
| 131 |  | 
| 132 | #ifdef _KERNEL | 
| 133 | 	struct pslist_entry	ia6_pslist_entry; | 
| 134 | #endif | 
| 135 | }; | 
| 136 |  | 
| 137 | #ifdef _KERNEL | 
| 138 | static inline void | 
| 139 | ia6_acquire(struct in6_ifaddr *ia, struct psref *psref) | 
| 140 | { | 
| 141 |  | 
| 142 | 	KASSERT(ia != NULL); | 
| 143 | 	ifa_acquire(&ia->ia_ifa, psref); | 
| 144 | } | 
| 145 |  | 
| 146 | static inline void | 
| 147 | ia6_release(struct in6_ifaddr *ia, struct psref *psref) | 
| 148 | { | 
| 149 |  | 
| 150 | 	if (ia == NULL) | 
| 151 | 		return; | 
| 152 | 	ifa_release(&ia->ia_ifa, psref); | 
| 153 | } | 
| 154 | #endif | 
| 155 |  | 
| 156 | /* control structure to manage address selection policy */ | 
| 157 | struct in6_addrpolicy { | 
| 158 | 	struct sockaddr_in6 addr; /* prefix address */ | 
| 159 | 	struct sockaddr_in6 addrmask; /* prefix mask */ | 
| 160 | 	int preced;		/* precedence */ | 
| 161 | 	int label;		/* matching label */ | 
| 162 | 	u_quad_t use;		/* statistics */ | 
| 163 | }; | 
| 164 |  | 
| 165 | /* | 
| 166 |  * IPv6 interface statistics, as defined in RFC2465 Ipv6IfStatsEntry (p12). | 
| 167 |  */ | 
| 168 | struct in6_ifstat { | 
| 169 | 	u_quad_t ifs6_in_receive;	/* # of total input datagram */ | 
| 170 | 	u_quad_t ifs6_in_hdrerr;	/* # of datagrams with invalid hdr */ | 
| 171 | 	u_quad_t ifs6_in_toobig;	/* # of datagrams exceeded MTU */ | 
| 172 | 	u_quad_t ifs6_in_noroute;	/* # of datagrams with no route */ | 
| 173 | 	u_quad_t ifs6_in_addrerr;	/* # of datagrams with invalid dst */ | 
| 174 | 	u_quad_t ifs6_in_protounknown;	/* # of datagrams with unknown proto */ | 
| 175 | 					/* NOTE: increment on final dst if */ | 
| 176 | 	u_quad_t ifs6_in_truncated;	/* # of truncated datagrams */ | 
| 177 | 	u_quad_t ifs6_in_discard;	/* # of discarded datagrams */ | 
| 178 | 					/* NOTE: fragment timeout is not here */ | 
| 179 | 	u_quad_t ifs6_in_deliver;	/* # of datagrams delivered to ULP */ | 
| 180 | 					/* NOTE: increment on final dst if */ | 
| 181 | 	u_quad_t ifs6_out_forward;	/* # of datagrams forwarded */ | 
| 182 | 					/* NOTE: increment on outgoing if */ | 
| 183 | 	u_quad_t ifs6_out_request;	/* # of outgoing datagrams from ULP */ | 
| 184 | 					/* NOTE: does not include forwrads */ | 
| 185 | 	u_quad_t ifs6_out_discard;	/* # of discarded datagrams */ | 
| 186 | 	u_quad_t ifs6_out_fragok;	/* # of datagrams fragmented */ | 
| 187 | 	u_quad_t ifs6_out_fragfail;	/* # of datagrams failed on fragment */ | 
| 188 | 	u_quad_t ifs6_out_fragcreat;	/* # of fragment datagrams */ | 
| 189 | 					/* NOTE: this is # after fragment */ | 
| 190 | 	u_quad_t ifs6_reass_reqd;	/* # of incoming fragmented packets */ | 
| 191 | 					/* NOTE: increment on final dst if */ | 
| 192 | 	u_quad_t ifs6_reass_ok;		/* # of reassembled packets */ | 
| 193 | 					/* NOTE: this is # after reass */ | 
| 194 | 					/* NOTE: increment on final dst if */ | 
| 195 | 	u_quad_t ifs6_reass_fail;	/* # of reass failures */ | 
| 196 | 					/* NOTE: may not be packet count */ | 
| 197 | 					/* NOTE: increment on final dst if */ | 
| 198 | 	u_quad_t ifs6_in_mcast;		/* # of inbound multicast datagrams */ | 
| 199 | 	u_quad_t ifs6_out_mcast;	/* # of outbound multicast datagrams */ | 
| 200 | }; | 
| 201 |  | 
| 202 | /* | 
| 203 |  * ICMPv6 interface statistics, as defined in RFC2466 Ipv6IfIcmpEntry. | 
| 204 |  * XXX: I'm not sure if this file is the right place for this structure... | 
| 205 |  */ | 
| 206 | struct icmp6_ifstat { | 
| 207 | 	/* | 
| 208 | 	 * Input statistics | 
| 209 | 	 */ | 
| 210 | 	/* ipv6IfIcmpInMsgs, total # of input messages */ | 
| 211 | 	u_quad_t ifs6_in_msg; | 
| 212 | 	/* ipv6IfIcmpInErrors, # of input error messages */ | 
| 213 | 	u_quad_t ifs6_in_error; | 
| 214 | 	/* ipv6IfIcmpInDestUnreachs, # of input dest unreach errors */ | 
| 215 | 	u_quad_t ifs6_in_dstunreach; | 
| 216 | 	/* ipv6IfIcmpInAdminProhibs, # of input administratively prohibited errs */ | 
| 217 | 	u_quad_t ifs6_in_adminprohib; | 
| 218 | 	/* ipv6IfIcmpInTimeExcds, # of input time exceeded errors */ | 
| 219 | 	u_quad_t ifs6_in_timeexceed; | 
| 220 | 	/* ipv6IfIcmpInParmProblems, # of input parameter problem errors */ | 
| 221 | 	u_quad_t ifs6_in_paramprob; | 
| 222 | 	/* ipv6IfIcmpInPktTooBigs, # of input packet too big errors */ | 
| 223 | 	u_quad_t ifs6_in_pkttoobig; | 
| 224 | 	/* ipv6IfIcmpInEchos, # of input echo requests */ | 
| 225 | 	u_quad_t ifs6_in_echo; | 
| 226 | 	/* ipv6IfIcmpInEchoReplies, # of input echo replies */ | 
| 227 | 	u_quad_t ifs6_in_echoreply; | 
| 228 | 	/* ipv6IfIcmpInRouterSolicits, # of input router solicitations */ | 
| 229 | 	u_quad_t ifs6_in_routersolicit; | 
| 230 | 	/* ipv6IfIcmpInRouterAdvertisements, # of input router advertisements */ | 
| 231 | 	u_quad_t ifs6_in_routeradvert; | 
| 232 | 	/* ipv6IfIcmpInNeighborSolicits, # of input neighbor solicitations */ | 
| 233 | 	u_quad_t ifs6_in_neighborsolicit; | 
| 234 | 	/* ipv6IfIcmpInNeighborAdvertisements, # of input neighbor advertisements */ | 
| 235 | 	u_quad_t ifs6_in_neighboradvert; | 
| 236 | 	/* ipv6IfIcmpInRedirects, # of input redirects */ | 
| 237 | 	u_quad_t ifs6_in_redirect; | 
| 238 | 	/* ipv6IfIcmpInGroupMembQueries, # of input MLD queries */ | 
| 239 | 	u_quad_t ifs6_in_mldquery; | 
| 240 | 	/* ipv6IfIcmpInGroupMembResponses, # of input MLD reports */ | 
| 241 | 	u_quad_t ifs6_in_mldreport; | 
| 242 | 	/* ipv6IfIcmpInGroupMembReductions, # of input MLD done */ | 
| 243 | 	u_quad_t ifs6_in_mlddone; | 
| 244 |  | 
| 245 | 	/* | 
| 246 | 	 * Output statistics. We should solve unresolved routing problem... | 
| 247 | 	 */ | 
| 248 | 	/* ipv6IfIcmpOutMsgs, total # of output messages */ | 
| 249 | 	u_quad_t ifs6_out_msg; | 
| 250 | 	/* ipv6IfIcmpOutErrors, # of output error messages */ | 
| 251 | 	u_quad_t ifs6_out_error; | 
| 252 | 	/* ipv6IfIcmpOutDestUnreachs, # of output dest unreach errors */ | 
| 253 | 	u_quad_t ifs6_out_dstunreach; | 
| 254 | 	/* ipv6IfIcmpOutAdminProhibs, # of output administratively prohibited errs */ | 
| 255 | 	u_quad_t ifs6_out_adminprohib; | 
| 256 | 	/* ipv6IfIcmpOutTimeExcds, # of output time exceeded errors */ | 
| 257 | 	u_quad_t ifs6_out_timeexceed; | 
| 258 | 	/* ipv6IfIcmpOutParmProblems, # of output parameter problem errors */ | 
| 259 | 	u_quad_t ifs6_out_paramprob; | 
| 260 | 	/* ipv6IfIcmpOutPktTooBigs, # of output packet too big errors */ | 
| 261 | 	u_quad_t ifs6_out_pkttoobig; | 
| 262 | 	/* ipv6IfIcmpOutEchos, # of output echo requests */ | 
| 263 | 	u_quad_t ifs6_out_echo; | 
| 264 | 	/* ipv6IfIcmpOutEchoReplies, # of output echo replies */ | 
| 265 | 	u_quad_t ifs6_out_echoreply; | 
| 266 | 	/* ipv6IfIcmpOutRouterSolicits, # of output router solicitations */ | 
| 267 | 	u_quad_t ifs6_out_routersolicit; | 
| 268 | 	/* ipv6IfIcmpOutRouterAdvertisements, # of output router advertisements */ | 
| 269 | 	u_quad_t ifs6_out_routeradvert; | 
| 270 | 	/* ipv6IfIcmpOutNeighborSolicits, # of output neighbor solicitations */ | 
| 271 | 	u_quad_t ifs6_out_neighborsolicit; | 
| 272 | 	/* ipv6IfIcmpOutNeighborAdvertisements, # of output neighbor advertisements */ | 
| 273 | 	u_quad_t ifs6_out_neighboradvert; | 
| 274 | 	/* ipv6IfIcmpOutRedirects, # of output redirects */ | 
| 275 | 	u_quad_t ifs6_out_redirect; | 
| 276 | 	/* ipv6IfIcmpOutGroupMembQueries, # of output MLD queries */ | 
| 277 | 	u_quad_t ifs6_out_mldquery; | 
| 278 | 	/* ipv6IfIcmpOutGroupMembResponses, # of output MLD reports */ | 
| 279 | 	u_quad_t ifs6_out_mldreport; | 
| 280 | 	/* ipv6IfIcmpOutGroupMembReductions, # of output MLD done */ | 
| 281 | 	u_quad_t ifs6_out_mlddone; | 
| 282 | }; | 
| 283 |  | 
| 284 | /* | 
| 285 |  * If you make changes that change the size of in6_ifreq, | 
| 286 |  * make sure you fix compat/netinet6/in6_var.h | 
| 287 |  */ | 
| 288 | struct	in6_ifreq { | 
| 289 | 	char	ifr_name[IFNAMSIZ]; | 
| 290 | 	union { | 
| 291 | 		struct	sockaddr_in6 ifru_addr; | 
| 292 | 		struct	sockaddr_in6 ifru_dstaddr; | 
| 293 | 		short	ifru_flags; | 
| 294 | 		int	ifru_flags6; | 
| 295 | 		int	ifru_metric; | 
| 296 | 		void *	ifru_data; | 
| 297 | 		struct in6_addrlifetime ifru_lifetime; | 
| 298 | 		struct in6_ifstat ifru_stat; | 
| 299 | 		struct icmp6_ifstat ifru_icmp6stat; | 
| 300 | 	} ifr_ifru; | 
| 301 | }; | 
| 302 |  | 
| 303 | struct	in6_aliasreq { | 
| 304 | 	char	ifra_name[IFNAMSIZ]; | 
| 305 | 	struct	sockaddr_in6 ifra_addr; | 
| 306 | 	struct	sockaddr_in6 ifra_dstaddr; | 
| 307 | 	struct	sockaddr_in6 ifra_prefixmask; | 
| 308 | 	int	ifra_flags; | 
| 309 | 	struct in6_addrlifetime ifra_lifetime; | 
| 310 | }; | 
| 311 |  | 
| 312 | /* prefix type macro */ | 
| 313 | #define IN6_PREFIX_ND	1 | 
| 314 | #define IN6_PREFIX_RR	2 | 
| 315 |  | 
| 316 | /* | 
| 317 |  * prefix related flags passed between kernel(NDP related part) and | 
| 318 |  * user land command(ifconfig) and daemon(rtadvd). | 
| 319 |  * Note: We originally intended to use prf_ra{} only within in6_prflags{}, but | 
| 320 |  * it was (probably unintentionally) used in nd6.h as well.  Since C++ does | 
| 321 |  * not allow such a reference, prf_ra{} was then moved outside.  In general, | 
| 322 |  * however, this structure should not be used directly. | 
| 323 |  */ | 
| 324 | struct prf_ra { | 
| 325 | 	u_int32_t onlink : 1; | 
| 326 | 	u_int32_t autonomous : 1; | 
| 327 | 	u_int32_t router : 1; | 
| 328 | 	u_int32_t reserved : 5; | 
| 329 | }; | 
| 330 |  | 
| 331 | struct in6_prflags { | 
| 332 | 	struct prf_ra prf_ra; | 
| 333 | 	u_char prf_reserved1; | 
| 334 | 	u_short prf_reserved2; | 
| 335 | 	/* want to put this on 4byte offset */ | 
| 336 | 	struct prf_rr { | 
| 337 | 		u_int32_t decrvalid : 1; | 
| 338 | 		u_int32_t decrprefd : 1; | 
| 339 | 		u_int32_t reserved : 6; | 
| 340 | 	} prf_rr; | 
| 341 | 	u_char prf_reserved3; | 
| 342 | 	u_short prf_reserved4; | 
| 343 | }; | 
| 344 |  | 
| 345 | struct  in6_prefixreq { | 
| 346 | 	char	ipr_name[IFNAMSIZ]; | 
| 347 | 	u_char	ipr_origin; | 
| 348 | 	u_char	ipr_plen; | 
| 349 | 	u_int32_t ipr_vltime; | 
| 350 | 	u_int32_t ipr_pltime; | 
| 351 | 	struct in6_prflags ipr_flags; | 
| 352 | 	struct	sockaddr_in6 ipr_prefix; | 
| 353 | }; | 
| 354 |  | 
| 355 | #define PR_ORIG_RA	0 | 
| 356 | #define PR_ORIG_RR	1 | 
| 357 | #define PR_ORIG_STATIC	2 | 
| 358 | #define PR_ORIG_KERNEL	3 | 
| 359 |  | 
| 360 | #define ipr_raf_onlink		ipr_flags.prf_ra.onlink | 
| 361 | #define ipr_raf_auto		ipr_flags.prf_ra.autonomous | 
| 362 |  | 
| 363 | #define ipr_statef_onlink	ipr_flags.prf_state.onlink | 
| 364 |  | 
| 365 | #define ipr_rrf_decrvalid	ipr_flags.prf_rr.decrvalid | 
| 366 | #define ipr_rrf_decrprefd	ipr_flags.prf_rr.decrprefd | 
| 367 |  | 
| 368 | struct	in6_rrenumreq { | 
| 369 | 	char	irr_name[IFNAMSIZ]; | 
| 370 | 	u_char	irr_origin; | 
| 371 | 	u_char	irr_m_len;	/* match len for matchprefix */ | 
| 372 | 	u_char	irr_m_minlen;	/* minlen for matching prefix */ | 
| 373 | 	u_char	irr_m_maxlen;	/* maxlen for matching prefix */ | 
| 374 | 	u_char	irr_u_uselen;	/* uselen for adding prefix */ | 
| 375 | 	u_char	irr_u_keeplen;	/* keeplen from matching prefix */ | 
| 376 | 	struct irr_raflagmask { | 
| 377 | 		u_int32_t onlink : 1; | 
| 378 | 		u_int32_t autonomous : 1; | 
| 379 | 		u_int32_t reserved : 6; | 
| 380 | 	} irr_raflagmask; | 
| 381 | 	u_int32_t irr_vltime; | 
| 382 | 	u_int32_t irr_pltime; | 
| 383 | 	struct in6_prflags irr_flags; | 
| 384 | 	struct	sockaddr_in6 irr_matchprefix; | 
| 385 | 	struct	sockaddr_in6 irr_useprefix; | 
| 386 | }; | 
| 387 |  | 
| 388 | #define irr_raf_mask_onlink	irr_raflagmask.onlink | 
| 389 | #define irr_raf_mask_auto	irr_raflagmask.autonomous | 
| 390 | #define irr_raf_mask_reserved	irr_raflagmask.reserved | 
| 391 |  | 
| 392 | #define irr_raf_onlink		irr_flags.prf_ra.onlink | 
| 393 | #define irr_raf_auto		irr_flags.prf_ra.autonomous | 
| 394 |  | 
| 395 | #define irr_statef_onlink	irr_flags.prf_state.onlink | 
| 396 |  | 
| 397 | #define irr_rrf			irr_flags.prf_rr | 
| 398 | #define irr_rrf_decrvalid	irr_flags.prf_rr.decrvalid | 
| 399 | #define irr_rrf_decrprefd	irr_flags.prf_rr.decrprefd | 
| 400 |  | 
| 401 | /* | 
| 402 |  * Given a pointer to an in6_ifaddr (ifaddr), | 
| 403 |  * return a pointer to the addr as a sockaddr_in6 | 
| 404 |  */ | 
| 405 | #define IA6_IN6(ia)	(&((ia)->ia_addr.sin6_addr)) | 
| 406 | #define IA6_DSTIN6(ia)	(&((ia)->ia_dstaddr.sin6_addr)) | 
| 407 | #define IA6_MASKIN6(ia)	(&((ia)->ia_prefixmask.sin6_addr)) | 
| 408 | #define IA6_SIN6(ia)	(&((ia)->ia_addr)) | 
| 409 | #define IA6_DSTSIN6(ia)	(&((ia)->ia_dstaddr)) | 
| 410 | #define IFA_IN6(x)	(&((struct sockaddr_in6 *)((x)->ifa_addr))->sin6_addr) | 
| 411 | #define IFA_DSTIN6(x)	(&((struct sockaddr_in6 *)((x)->ifa_dstaddr))->sin6_addr) | 
| 412 |  | 
| 413 | #ifdef _KERNEL | 
| 414 | #define IN6_ARE_MASKED_ADDR_EQUAL(d, a, m)	(	\ | 
| 415 | 	(((d)->s6_addr32[0] ^ (a)->s6_addr32[0]) & (m)->s6_addr32[0]) == 0 && \ | 
| 416 | 	(((d)->s6_addr32[1] ^ (a)->s6_addr32[1]) & (m)->s6_addr32[1]) == 0 && \ | 
| 417 | 	(((d)->s6_addr32[2] ^ (a)->s6_addr32[2]) & (m)->s6_addr32[2]) == 0 && \ | 
| 418 | 	(((d)->s6_addr32[3] ^ (a)->s6_addr32[3]) & (m)->s6_addr32[3]) == 0 ) | 
| 419 | #endif | 
| 420 |  | 
| 421 | #define SIOCSIFADDR_IN6		 _IOW('i', 12, struct in6_ifreq) | 
| 422 | #define SIOCGIFADDR_IN6		_IOWR('i', 33, struct in6_ifreq) | 
| 423 |  | 
| 424 | #ifdef _KERNEL | 
| 425 | /* | 
| 426 |  * SIOCSxxx ioctls should be unused (see comments in in6.c), but | 
| 427 |  * we do not shift numbers for binary compatibility. | 
| 428 |  */ | 
| 429 | #define SIOCSIFDSTADDR_IN6	 _IOW('i', 14, struct in6_ifreq) | 
| 430 | #define SIOCSIFNETMASK_IN6	 _IOW('i', 22, struct in6_ifreq) | 
| 431 | #endif | 
| 432 |  | 
| 433 | #define SIOCGIFDSTADDR_IN6	_IOWR('i', 34, struct in6_ifreq) | 
| 434 | #define SIOCGIFNETMASK_IN6	_IOWR('i', 37, struct in6_ifreq) | 
| 435 |  | 
| 436 | #define SIOCDIFADDR_IN6		 _IOW('i', 25, struct in6_ifreq) | 
| 437 | /* 26 was OSIOCAIFADDR_IN6 */ | 
| 438 |  | 
| 439 | /* 70 was OSIOCSIFPHYADDR_IN6 */ | 
| 440 | #define	SIOCGIFPSRCADDR_IN6	_IOWR('i', 71, struct in6_ifreq) | 
| 441 | #define	SIOCGIFPDSTADDR_IN6	_IOWR('i', 72, struct in6_ifreq) | 
| 442 |  | 
| 443 | #define SIOCGIFAFLAG_IN6	_IOWR('i', 73, struct in6_ifreq) | 
| 444 |  | 
| 445 | #define SIOCGDRLST_IN6		_IOWR('i', 74, struct in6_drlist) | 
| 446 | #define SIOCGPRLST_IN6		_IOWR('i', 75, struct in6_oprlist) | 
| 447 | #ifdef _KERNEL | 
| 448 | #define OSIOCGIFINFO_IN6	_IOWR('i', 76, struct in6_ondireq) | 
| 449 | #endif | 
| 450 | #define SIOCSNDFLUSH_IN6	_IOWR('i', 77, struct in6_ifreq) | 
| 451 | #define SIOCGNBRINFO_IN6	_IOWR('i', 78, struct in6_nbrinfo) | 
| 452 | #define SIOCSPFXFLUSH_IN6	_IOWR('i', 79, struct in6_ifreq) | 
| 453 | #define SIOCSRTRFLUSH_IN6	_IOWR('i', 80, struct in6_ifreq) | 
| 454 | /* 81 was old SIOCGIFALIFETIME_IN6 */ | 
| 455 | #if 0 | 
| 456 | /* withdrawn - do not reuse number 82 */ | 
| 457 | #define SIOCSIFALIFETIME_IN6	_IOWR('i', 82, struct in6_ifreq) | 
| 458 | #endif | 
| 459 | #define SIOCGIFSTAT_IN6		_IOWR('i', 83, struct in6_ifreq) | 
| 460 | #define SIOCGIFSTAT_ICMP6	_IOWR('i', 84, struct in6_ifreq) | 
| 461 |  | 
| 462 | #define SIOCSDEFIFACE_IN6	_IOWR('i', 85, struct in6_ndifreq) | 
| 463 | #define SIOCGDEFIFACE_IN6	_IOWR('i', 86, struct in6_ndifreq) | 
| 464 |  | 
| 465 | #define SIOCSIFINFO_FLAGS	_IOWR('i', 87, struct in6_ndireq) /* XXX */ | 
| 466 |  | 
| 467 | #define SIOCSIFPREFIX_IN6	_IOW('i', 100, struct in6_prefixreq) /* set */ | 
| 468 | #define SIOCGIFPREFIX_IN6	_IOWR('i', 101, struct in6_prefixreq) /* get */ | 
| 469 | #define SIOCDIFPREFIX_IN6	_IOW('i', 102, struct in6_prefixreq) /* del */ | 
| 470 | #define SIOCAIFPREFIX_IN6	_IOW('i', 103, struct in6_rrenumreq) /* add */ | 
| 471 | #define SIOCCIFPREFIX_IN6	_IOW('i', 104, \ | 
| 472 | 				     struct in6_rrenumreq) /* change */ | 
| 473 | #define SIOCSGIFPREFIX_IN6	_IOW('i', 105, \ | 
| 474 | 				     struct in6_rrenumreq) /* set global */ | 
| 475 | #define SIOCGIFALIFETIME_IN6	_IOWR('i', 106, struct in6_ifreq) | 
| 476 | #define SIOCAIFADDR_IN6		_IOW('i', 107, struct in6_aliasreq) | 
| 477 | #define SIOCGIFINFO_IN6		_IOWR('i', 108, struct in6_ndireq) | 
| 478 | #define SIOCSIFINFO_IN6		_IOWR('i', 109, struct in6_ndireq) | 
| 479 | #define SIOCSIFPHYADDR_IN6      _IOW('i', 110, struct in6_aliasreq) | 
| 480 |  | 
| 481 |  | 
| 482 | /* XXX: Someone decided to switch to 'u' here for unknown reasons! */ | 
| 483 | #define SIOCGETSGCNT_IN6	_IOWR('u', 106, \ | 
| 484 | 				      struct sioc_sg_req6) /* get s,g pkt cnt */ | 
| 485 | #define SIOCGETMIFCNT_IN6	_IOWR('u', 107, \ | 
| 486 | 				      struct sioc_mif_req6) /* get pkt cnt per if */ | 
| 487 | #define SIOCAADDRCTL_POLICY	_IOW('u', 108, struct in6_addrpolicy) | 
| 488 | #define SIOCDADDRCTL_POLICY	_IOW('u', 109, struct in6_addrpolicy) | 
| 489 |  | 
| 490 | #define IN6_IFF_ANYCAST		0x01	/* anycast address */ | 
| 491 | #define IN6_IFF_TENTATIVE	0x02	/* tentative address */ | 
| 492 | #define IN6_IFF_DUPLICATED	0x04	/* DAD detected duplicate */ | 
| 493 | #define IN6_IFF_DETACHED	0x08	/* may be detached from the link */ | 
| 494 | #define IN6_IFF_DEPRECATED	0x10	/* deprecated address */ | 
| 495 | #define IN6_IFF_NODAD		0x20	/* don't perform DAD on this address | 
| 496 | 					 * (used only at first SIOC* call) | 
| 497 | 					 */ | 
| 498 | #define IN6_IFF_AUTOCONF	0x40	/* autoconfigurable address. */ | 
| 499 | #define IN6_IFF_TEMPORARY	0x80	/* temporary (anonymous) address. */ | 
| 500 |  | 
| 501 | #define IN6_IFFBITS \ | 
| 502 |     "\020\1ANYCAST\2TENTATIVE\3DUPLICATED\4DETACHED\5DEPRECATED\6NODAD" \ | 
| 503 |     "\7AUTOCONF\10TEMPORARY" | 
| 504 |  | 
| 505 |  | 
| 506 | /* do not input/output */ | 
| 507 | #define IN6_IFF_NOTREADY (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED) | 
| 508 |  | 
| 509 | #ifdef _KERNEL | 
| 510 | #define IN6_ARE_SCOPE_CMP(a,b) ((a)-(b)) | 
| 511 | #define IN6_ARE_SCOPE_EQUAL(a,b) ((a)==(b)) | 
| 512 | #endif | 
| 513 |  | 
| 514 | #ifdef _KERNEL | 
| 515 |  | 
| 516 | #include <sys/mutex.h> | 
| 517 | #include <sys/pserialize.h> | 
| 518 |  | 
| 519 | #include <net/pktqueue.h> | 
| 520 |  | 
| 521 | extern pktqueue_t *ip6_pktq; | 
| 522 |  | 
| 523 | MALLOC_DECLARE(M_IP6OPT); | 
| 524 |  | 
| 525 | extern struct pslist_head	in6_ifaddr_list; | 
| 526 | extern kmutex_t			in6_ifaddr_lock; | 
| 527 |  | 
| 528 | #define IN6_ADDRLIST_ENTRY_INIT(__ia) \ | 
| 529 | 	PSLIST_ENTRY_INIT((__ia), ia6_pslist_entry) | 
| 530 | #define IN6_ADDRLIST_ENTRY_DESTROY(__ia) \ | 
| 531 | 	PSLIST_ENTRY_DESTROY((__ia), ia6_pslist_entry) | 
| 532 | #define IN6_ADDRLIST_READER_EMPTY() \ | 
| 533 | 	(PSLIST_READER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \ | 
| 534 | 	                     ia6_pslist_entry) == NULL) | 
| 535 | #define IN6_ADDRLIST_READER_FIRST() \ | 
| 536 | 	PSLIST_READER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \ | 
| 537 | 	                    ia6_pslist_entry) | 
| 538 | #define IN6_ADDRLIST_READER_NEXT(__ia) \ | 
| 539 | 	PSLIST_READER_NEXT((__ia), struct in6_ifaddr, ia6_pslist_entry) | 
| 540 | #define IN6_ADDRLIST_READER_FOREACH(__ia) \ | 
| 541 | 	PSLIST_READER_FOREACH((__ia), &in6_ifaddr_list, \ | 
| 542 | 	                      struct in6_ifaddr, ia6_pslist_entry) | 
| 543 | #define IN6_ADDRLIST_WRITER_INSERT_HEAD(__ia) \ | 
| 544 | 	PSLIST_WRITER_INSERT_HEAD(&in6_ifaddr_list, (__ia), ia6_pslist_entry) | 
| 545 | #define IN6_ADDRLIST_WRITER_REMOVE(__ia) \ | 
| 546 | 	PSLIST_WRITER_REMOVE((__ia), ia6_pslist_entry) | 
| 547 | #define IN6_ADDRLIST_WRITER_FOREACH(__ia) \ | 
| 548 | 	PSLIST_WRITER_FOREACH((__ia), &in6_ifaddr_list, struct in6_ifaddr, \ | 
| 549 | 	                      ia6_pslist_entry) | 
| 550 | #define IN6_ADDRLIST_WRITER_FIRST() \ | 
| 551 | 	PSLIST_WRITER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \ | 
| 552 | 	                    ia6_pslist_entry) | 
| 553 | #define IN6_ADDRLIST_WRITER_NEXT(__ia) \ | 
| 554 | 	PSLIST_WRITER_NEXT((__ia), struct in6_ifaddr, ia6_pslist_entry) | 
| 555 | #define IN6_ADDRLIST_WRITER_INSERT_AFTER(__ia, __new) \ | 
| 556 | 	PSLIST_WRITER_INSERT_AFTER((__ia), (__new), ia6_pslist_entry) | 
| 557 | #define IN6_ADDRLIST_WRITER_EMPTY() \ | 
| 558 | 	(PSLIST_WRITER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \ | 
| 559 | 	    ia6_pslist_entry) == NULL) | 
| 560 | #define IN6_ADDRLIST_WRITER_INSERT_TAIL(__new)				\ | 
| 561 | 	do {								\ | 
| 562 | 		if (IN6_ADDRLIST_WRITER_EMPTY()) {			\ | 
| 563 | 			IN6_ADDRLIST_WRITER_INSERT_HEAD((__new));	\ | 
| 564 | 		} else {						\ | 
| 565 | 			struct in6_ifaddr *__ia;			\ | 
| 566 | 			IN6_ADDRLIST_WRITER_FOREACH(__ia) {		\ | 
| 567 | 				if (IN6_ADDRLIST_WRITER_NEXT(__ia) == NULL) { \ | 
| 568 | 					IN6_ADDRLIST_WRITER_INSERT_AFTER(__ia,\ | 
| 569 | 					    (__new));			\ | 
| 570 | 					break;				\ | 
| 571 | 				}					\ | 
| 572 | 			}						\ | 
| 573 | 		}							\ | 
| 574 | 	} while (0) | 
| 575 |  | 
| 576 | #define in6_ifstat_inc(ifp, tag) \ | 
| 577 | do {								\ | 
| 578 | 	if (ifp)						\ | 
| 579 | 		((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->in6_ifstat->tag++; \ | 
| 580 | } while (/*CONSTCOND*/ 0) | 
| 581 |  | 
| 582 | extern const struct in6_addr zeroin6_addr; | 
| 583 | extern const u_char inet6ctlerrmap[]; | 
| 584 | extern unsigned long in6_maxmtu; | 
| 585 | extern bool in6_present; | 
| 586 | extern callout_t in6_tmpaddrtimer_ch; | 
| 587 |  | 
| 588 | /* | 
| 589 |  * Macro for finding the internet address structure (in6_ifaddr) corresponding | 
| 590 |  * to a given interface (ifnet structure). | 
| 591 |  */ | 
| 592 | static inline struct in6_ifaddr * | 
| 593 | in6_get_ia_from_ifp(struct ifnet *ifp) | 
| 594 | { | 
| 595 | 	struct ifaddr *ifa; | 
| 596 |  | 
| 597 | 	IFADDR_READER_FOREACH(ifa, ifp) { | 
| 598 | 		if (ifa->ifa_addr->sa_family == AF_INET6) | 
| 599 | 			break; | 
| 600 | 	} | 
| 601 | 	return (struct in6_ifaddr *)ifa; | 
| 602 | } | 
| 603 |  | 
| 604 | static inline struct in6_ifaddr * | 
| 605 | in6_get_ia_from_ifp_psref(struct ifnet *ifp, struct psref *psref) | 
| 606 | { | 
| 607 | 	struct in6_ifaddr *ia; | 
| 608 | 	int s; | 
| 609 |  | 
| 610 | 	s = pserialize_read_enter(); | 
| 611 | 	ia = in6_get_ia_from_ifp(ifp); | 
| 612 | 	if (ia != NULL) | 
| 613 | 		ia6_acquire(ia, psref); | 
| 614 | 	pserialize_read_exit(s); | 
| 615 |  | 
| 616 | 	return ia; | 
| 617 | } | 
| 618 | #endif /* _KERNEL */ | 
| 619 |  | 
| 620 | /* | 
| 621 |  * Multi-cast membership entry.  One for each group/ifp that a PCB | 
| 622 |  * belongs to. | 
| 623 |  */ | 
| 624 | struct in6_multi_mship { | 
| 625 | 	struct	in6_multi *i6mm_maddr;	/* Multicast address pointer */ | 
| 626 | 	LIST_ENTRY(in6_multi_mship) i6mm_chain;  /* multicast options chain */ | 
| 627 | }; | 
| 628 |  | 
| 629 | struct	in6_multi { | 
| 630 | 	LIST_ENTRY(in6_multi) in6m_entry; /* list glue */ | 
| 631 | 	struct	in6_addr in6m_addr;	/* IP6 multicast address */ | 
| 632 | 	struct	ifnet *in6m_ifp;	/* back pointer to ifnet */ | 
| 633 | 	struct	in6_ifaddr *in6m_ia;	/* back pointer to in6_ifaddr */ | 
| 634 | 	u_int	in6m_refcount;		/* # membership claims by sockets */ | 
| 635 | 	u_int	in6m_state;		/* state of the membership */ | 
| 636 | 	int	in6m_timer;		/* delay to send the 1st report */ | 
| 637 | 	struct timeval in6m_timer_expire; /* when the timer expires */ | 
| 638 | 	callout_t in6m_timer_ch; | 
| 639 | }; | 
| 640 |   | 
| 641 | #define IN6M_TIMER_UNDEF -1 | 
| 642 |  | 
| 643 |  | 
| 644 | #ifdef _KERNEL | 
| 645 | /* flags to in6_update_ifa */ | 
| 646 | #define IN6_IFAUPDATE_DADDELAY	0x1 /* first time to configure an address */ | 
| 647 |  | 
| 648 | /* | 
| 649 |  * Structure used by macros below to remember position when stepping through | 
| 650 |  * all of the in6_multi records. | 
| 651 |  */ | 
| 652 | struct	in6_multistep { | 
| 653 | 	struct	in6_ifaddr *i_ia; | 
| 654 | 	struct	in6_multi *i_in6m; | 
| 655 | }; | 
| 656 |  | 
| 657 | /* | 
| 658 |  * Macros for looking up the in6_multi record for a given IP6 multicast | 
| 659 |  * address on a given interface. If no matching record is found, "in6m" | 
| 660 |  * returns NULL. | 
| 661 |  */ | 
| 662 |  | 
| 663 | static inline struct in6_multi * | 
| 664 | in6_lookup_multi(struct in6_addr *addr, struct ifnet *ifp) | 
| 665 | { | 
| 666 | 	struct in6_multi *in6m; | 
| 667 | 	struct in6_ifaddr *ia; | 
| 668 | 	int s; | 
| 669 |  | 
| 670 | 	s = pserialize_read_enter(); | 
| 671 | 	if ((ia = in6_get_ia_from_ifp(ifp)) == NULL) { | 
| 672 | 		pserialize_read_exit(s); | 
| 673 | 	  	return NULL; | 
| 674 | 	} | 
| 675 | 	LIST_FOREACH(in6m, &ia->ia6_multiaddrs, in6m_entry) { | 
| 676 | 		if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, addr)) | 
| 677 | 			break; | 
| 678 | 	} | 
| 679 | 	pserialize_read_exit(s); | 
| 680 | 	return in6m; | 
| 681 | } | 
| 682 |  | 
| 683 | #define IN6_LOOKUP_MULTI(__addr, __ifp, __in6m)			\ | 
| 684 | /* struct in6_addr __addr; */					\ | 
| 685 | /* struct ifnet *__ifp; */					\ | 
| 686 | /* struct in6_multi *__in6m; */					\ | 
| 687 | do {								\ | 
| 688 | 	(__in6m) = in6_lookup_multi(&(__addr), (__ifp));	\ | 
| 689 | } while (/*CONSTCOND*/ 0) | 
| 690 |  | 
| 691 | /* | 
| 692 |  * Macro to step through all of the in6_multi records, one at a time. | 
| 693 |  * The current position is remembered in "step", which the caller must | 
| 694 |  * provide.  IN6_FIRST_MULTI(), below, must be called to initialize "step" | 
| 695 |  * and get the first record.  Both macros return a NULL "in6m" when there | 
| 696 |  * are no remaining records. | 
| 697 |  */ | 
| 698 | static inline struct in6_multi * | 
| 699 | in6_next_multi(struct in6_multistep *step) | 
| 700 | { | 
| 701 | 	struct in6_multi *in6m; | 
| 702 |  | 
| 703 | 	if ((in6m = step->i_in6m) != NULL) { | 
| 704 | 		step->i_in6m = LIST_NEXT(in6m, in6m_entry); | 
| 705 | 		return in6m; | 
| 706 | 	} | 
| 707 | 	while (step->i_ia != NULL) { | 
| 708 | 		in6m = LIST_FIRST(&step->i_ia->ia6_multiaddrs); | 
| 709 | 		/* FIXME NOMPSAFE */ | 
| 710 | 		step->i_ia = IN6_ADDRLIST_READER_NEXT(step->i_ia); | 
| 711 | 		if (in6m != NULL) { | 
| 712 | 			step->i_in6m = LIST_NEXT(in6m, in6m_entry); | 
| 713 | 			break; | 
| 714 | 		} | 
| 715 | 	} | 
| 716 | 	return in6m; | 
| 717 | } | 
| 718 |  | 
| 719 | static inline struct in6_multi * | 
| 720 | in6_first_multi(struct in6_multistep *step) | 
| 721 | {						 | 
| 722 |  | 
| 723 | 	/* FIXME NOMPSAFE */ | 
| 724 | 	step->i_ia = IN6_ADDRLIST_READER_FIRST(); | 
| 725 | 	step->i_in6m = NULL;			 | 
| 726 | 	return in6_next_multi(step);		 | 
| 727 | } | 
| 728 |  | 
| 729 | #define IN6_NEXT_MULTI(__step, __in6m)		\ | 
| 730 | /* struct in6_multistep __step; */		\ | 
| 731 | /* struct in6_multi *__in6m; */			\ | 
| 732 | do {						\ | 
| 733 | 	(__in6m) = in6_next_multi(&(__step));	\ | 
| 734 | } while (/*CONSTCOND*/ 0) | 
| 735 |  | 
| 736 | #define IN6_FIRST_MULTI(__step, __in6m)		\ | 
| 737 | /* struct in6_multistep __step; */		\ | 
| 738 | /* struct in6_multi *__in6m */			\ | 
| 739 | do {						\ | 
| 740 | 	(__in6m) = in6_first_multi(&(__step));	\ | 
| 741 | } while (/*CONSTCOND*/ 0) | 
| 742 |  | 
| 743 |  | 
| 744 | #if 0 | 
| 745 | /* | 
| 746 |  * Macros for looking up the in6_multi_mship record for a given IP6 multicast | 
| 747 |  * address on a given interface. If no matching record is found, "imm" | 
| 748 |  * returns NULL. | 
| 749 |  */ | 
| 750 | static inline struct in6_multi_mship * | 
| 751 | in6_lookup_mship(struct in6_addr *addr, struct ifnet *ifp, | 
| 752 |     struct ip6_moptions *imop) | 
| 753 | { | 
| 754 | 	struct in6_multi_mship *imm; | 
| 755 |  | 
| 756 | 	LIST_FOREACH(imm, &imop->im6o_memberships, i6mm_chain) { | 
| 757 | 		if (imm->i6mm_maddr->in6m_ifp != ifp) | 
| 758 | 		    	continue; | 
| 759 | 		if (IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr, | 
| 760 | 		    addr)) | 
| 761 | 			break; | 
| 762 | 	} | 
| 763 | 	return imm; | 
| 764 | } | 
| 765 |  | 
| 766 | #define IN6_LOOKUP_MSHIP(__addr, __ifp, __imop, __imm)			\ | 
| 767 | /* struct in6_addr __addr; */						\ | 
| 768 | /* struct ifnet *__ifp; */						\ | 
| 769 | /* struct ip6_moptions *__imop */					\ | 
| 770 | /* struct in6_multi_mship *__imm; */					\ | 
| 771 | do {									\ | 
| 772 | 	(__imm) = in6_lookup_mship(&(__addr), (__ifp), (__imop));	\ | 
| 773 | } while (/*CONSTCOND*/ 0) | 
| 774 | #endif | 
| 775 |  | 
| 776 | void	in6_init(void); | 
| 777 |  | 
| 778 | struct	in6_multi *in6_addmulti(struct in6_addr *, struct ifnet *, | 
| 779 | 	int *, int); | 
| 780 | void	in6_delmulti(struct in6_multi *); | 
| 781 | struct in6_multi_mship *in6_joingroup(struct ifnet *, struct in6_addr *, | 
| 782 | 	int *, int); | 
| 783 | int	in6_leavegroup(struct in6_multi_mship *); | 
| 784 | int	in6_mask2len(struct in6_addr *, u_char *); | 
| 785 | int	in6_control(struct socket *, u_long, void *, struct ifnet *); | 
| 786 | int	in6_update_ifa(struct ifnet *, struct in6_aliasreq *, | 
| 787 | 	struct in6_ifaddr *, int); | 
| 788 | void	in6_purgeaddr(struct ifaddr *); | 
| 789 | void	in6_purgeif(struct ifnet *); | 
| 790 | void	in6_savemkludge(struct in6_ifaddr *); | 
| 791 | void	in6_setmaxmtu  (void); | 
| 792 | int	in6_if2idlen  (struct ifnet *); | 
| 793 | void	*in6_domifattach(struct ifnet *); | 
| 794 | void	in6_domifdetach(struct ifnet *, void *); | 
| 795 | void	in6_restoremkludge(struct in6_ifaddr *, struct ifnet *); | 
| 796 | void	in6_ifremlocal(struct ifaddr *); | 
| 797 | void	in6_ifaddlocal(struct ifaddr *); | 
| 798 | void	in6_createmkludge(struct ifnet *); | 
| 799 | void	in6_purgemkludge(struct ifnet *); | 
| 800 | struct in6_ifaddr * | 
| 801 | 	in6ifa_ifpforlinklocal(const struct ifnet *, int); | 
| 802 | struct in6_ifaddr * | 
| 803 | 	in6ifa_ifpforlinklocal_psref(const struct ifnet *, int, struct psref *); | 
| 804 | struct in6_ifaddr * | 
| 805 | 	in6ifa_ifpwithaddr(const struct ifnet *, const struct in6_addr *); | 
| 806 | struct in6_ifaddr * | 
| 807 | 	in6ifa_ifpwithaddr_psref(const struct ifnet *, const struct in6_addr *, | 
| 808 | 	    struct psref *); | 
| 809 | struct in6_ifaddr *in6ifa_ifwithaddr(const struct in6_addr *, uint32_t); | 
| 810 | char	*ip6_sprintf(const struct in6_addr *); | 
| 811 | int	in6_matchlen(struct in6_addr *, struct in6_addr *); | 
| 812 | int	in6_are_prefix_equal(struct in6_addr *, struct in6_addr *, int); | 
| 813 | void	in6_prefixlen2mask(struct in6_addr *, int); | 
| 814 | void	in6_purgeprefix(struct ifnet *); | 
| 815 |  | 
| 816 | int	ip6flow_fastforward(struct mbuf **); /* IPv6 fast forward routine */ | 
| 817 |  | 
| 818 | int in6_src_ioctl(u_long, void *); | 
| 819 | int	in6_is_addr_deprecated(struct sockaddr_in6 *); | 
| 820 | struct in6pcb; | 
| 821 |  | 
| 822 | #define	LLTABLE6(ifp)	(((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->lltable) | 
| 823 |  | 
| 824 | #endif /* _KERNEL */ | 
| 825 |  | 
| 826 | #endif /* !_NETINET6_IN6_VAR_H_ */ | 
| 827 |  |