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 | |