1 | /* $NetBSD: in6_var.h,v 1.100 2018/05/29 04:38:29 ozaki-r 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 | /* DEPRECATED. Keep it to avoid breaking kvm(3) users */ |
117 | struct in6_multihead _ia6_multiaddrs; |
118 | /* list of multicast addresses */ |
119 | int ia6_flags; |
120 | |
121 | struct in6_addrlifetime ia6_lifetime; |
122 | time_t ia6_createtime; /* the creation time of this address, which is |
123 | * currently used for temporary addresses only. |
124 | */ |
125 | time_t ia6_updatetime; |
126 | |
127 | /* back pointer to the ND prefix (for autoconfigured addresses only) */ |
128 | struct nd_prefix *ia6_ndpr; |
129 | |
130 | /* multicast addresses joined from the kernel */ |
131 | LIST_HEAD(, in6_multi_mship) ia6_memberships; |
132 | |
133 | #ifdef _KERNEL |
134 | struct pslist_entry ia6_pslist_entry; |
135 | #endif |
136 | }; |
137 | |
138 | #ifdef _KERNEL |
139 | static __inline void |
140 | ia6_acquire(struct in6_ifaddr *ia, struct psref *psref) |
141 | { |
142 | |
143 | KASSERT(ia != NULL); |
144 | ifa_acquire(&ia->ia_ifa, psref); |
145 | } |
146 | |
147 | static __inline void |
148 | ia6_release(struct in6_ifaddr *ia, struct psref *psref) |
149 | { |
150 | |
151 | if (ia == NULL) |
152 | return; |
153 | ifa_release(&ia->ia_ifa, psref); |
154 | } |
155 | #endif |
156 | |
157 | /* control structure to manage address selection policy */ |
158 | struct in6_addrpolicy { |
159 | struct sockaddr_in6 addr; /* prefix address */ |
160 | struct sockaddr_in6 addrmask; /* prefix mask */ |
161 | int preced; /* precedence */ |
162 | int label; /* matching label */ |
163 | u_quad_t use; /* statistics */ |
164 | }; |
165 | |
166 | /* |
167 | * IPv6 interface statistics, as defined in RFC2465 Ipv6IfStatsEntry (p12). |
168 | */ |
169 | struct in6_ifstat { |
170 | u_quad_t ifs6_in_receive; /* # of total input datagram */ |
171 | u_quad_t ifs6_in_hdrerr; /* # of datagrams with invalid hdr */ |
172 | u_quad_t ifs6_in_toobig; /* # of datagrams exceeded MTU */ |
173 | u_quad_t ifs6_in_noroute; /* # of datagrams with no route */ |
174 | u_quad_t ifs6_in_addrerr; /* # of datagrams with invalid dst */ |
175 | u_quad_t ifs6_in_protounknown; /* # of datagrams with unknown proto */ |
176 | /* NOTE: increment on final dst if */ |
177 | u_quad_t ifs6_in_truncated; /* # of truncated datagrams */ |
178 | u_quad_t ifs6_in_discard; /* # of discarded datagrams */ |
179 | /* NOTE: fragment timeout is not here */ |
180 | u_quad_t ifs6_in_deliver; /* # of datagrams delivered to ULP */ |
181 | /* NOTE: increment on final dst if */ |
182 | u_quad_t ifs6_out_forward; /* # of datagrams forwarded */ |
183 | /* NOTE: increment on outgoing if */ |
184 | u_quad_t ifs6_out_request; /* # of outgoing datagrams from ULP */ |
185 | /* NOTE: does not include forwrads */ |
186 | u_quad_t ifs6_out_discard; /* # of discarded datagrams */ |
187 | u_quad_t ifs6_out_fragok; /* # of datagrams fragmented */ |
188 | u_quad_t ifs6_out_fragfail; /* # of datagrams failed on fragment */ |
189 | u_quad_t ifs6_out_fragcreat; /* # of fragment datagrams */ |
190 | /* NOTE: this is # after fragment */ |
191 | u_quad_t ifs6_reass_reqd; /* # of incoming fragmented packets */ |
192 | /* NOTE: increment on final dst if */ |
193 | u_quad_t ifs6_reass_ok; /* # of reassembled packets */ |
194 | /* NOTE: this is # after reass */ |
195 | /* NOTE: increment on final dst if */ |
196 | u_quad_t ifs6_reass_fail; /* # of reass failures */ |
197 | /* NOTE: may not be packet count */ |
198 | /* NOTE: increment on final dst if */ |
199 | u_quad_t ifs6_in_mcast; /* # of inbound multicast datagrams */ |
200 | u_quad_t ifs6_out_mcast; /* # of outbound multicast datagrams */ |
201 | }; |
202 | |
203 | /* |
204 | * ICMPv6 interface statistics, as defined in RFC2466 Ipv6IfIcmpEntry. |
205 | * XXX: I'm not sure if this file is the right place for this structure... |
206 | */ |
207 | struct icmp6_ifstat { |
208 | /* |
209 | * Input statistics |
210 | */ |
211 | /* ipv6IfIcmpInMsgs, total # of input messages */ |
212 | u_quad_t ifs6_in_msg; |
213 | /* ipv6IfIcmpInErrors, # of input error messages */ |
214 | u_quad_t ifs6_in_error; |
215 | /* ipv6IfIcmpInDestUnreachs, # of input dest unreach errors */ |
216 | u_quad_t ifs6_in_dstunreach; |
217 | /* ipv6IfIcmpInAdminProhibs, # of input administratively prohibited errs */ |
218 | u_quad_t ifs6_in_adminprohib; |
219 | /* ipv6IfIcmpInTimeExcds, # of input time exceeded errors */ |
220 | u_quad_t ifs6_in_timeexceed; |
221 | /* ipv6IfIcmpInParmProblems, # of input parameter problem errors */ |
222 | u_quad_t ifs6_in_paramprob; |
223 | /* ipv6IfIcmpInPktTooBigs, # of input packet too big errors */ |
224 | u_quad_t ifs6_in_pkttoobig; |
225 | /* ipv6IfIcmpInEchos, # of input echo requests */ |
226 | u_quad_t ifs6_in_echo; |
227 | /* ipv6IfIcmpInEchoReplies, # of input echo replies */ |
228 | u_quad_t ifs6_in_echoreply; |
229 | /* ipv6IfIcmpInRouterSolicits, # of input router solicitations */ |
230 | u_quad_t ifs6_in_routersolicit; |
231 | /* ipv6IfIcmpInRouterAdvertisements, # of input router advertisements */ |
232 | u_quad_t ifs6_in_routeradvert; |
233 | /* ipv6IfIcmpInNeighborSolicits, # of input neighbor solicitations */ |
234 | u_quad_t ifs6_in_neighborsolicit; |
235 | /* ipv6IfIcmpInNeighborAdvertisements, # of input neighbor advertisements */ |
236 | u_quad_t ifs6_in_neighboradvert; |
237 | /* ipv6IfIcmpInRedirects, # of input redirects */ |
238 | u_quad_t ifs6_in_redirect; |
239 | /* ipv6IfIcmpInGroupMembQueries, # of input MLD queries */ |
240 | u_quad_t ifs6_in_mldquery; |
241 | /* ipv6IfIcmpInGroupMembResponses, # of input MLD reports */ |
242 | u_quad_t ifs6_in_mldreport; |
243 | /* ipv6IfIcmpInGroupMembReductions, # of input MLD done */ |
244 | u_quad_t ifs6_in_mlddone; |
245 | |
246 | /* |
247 | * Output statistics. We should solve unresolved routing problem... |
248 | */ |
249 | /* ipv6IfIcmpOutMsgs, total # of output messages */ |
250 | u_quad_t ifs6_out_msg; |
251 | /* ipv6IfIcmpOutErrors, # of output error messages */ |
252 | u_quad_t ifs6_out_error; |
253 | /* ipv6IfIcmpOutDestUnreachs, # of output dest unreach errors */ |
254 | u_quad_t ifs6_out_dstunreach; |
255 | /* ipv6IfIcmpOutAdminProhibs, # of output administratively prohibited errs */ |
256 | u_quad_t ifs6_out_adminprohib; |
257 | /* ipv6IfIcmpOutTimeExcds, # of output time exceeded errors */ |
258 | u_quad_t ifs6_out_timeexceed; |
259 | /* ipv6IfIcmpOutParmProblems, # of output parameter problem errors */ |
260 | u_quad_t ifs6_out_paramprob; |
261 | /* ipv6IfIcmpOutPktTooBigs, # of output packet too big errors */ |
262 | u_quad_t ifs6_out_pkttoobig; |
263 | /* ipv6IfIcmpOutEchos, # of output echo requests */ |
264 | u_quad_t ifs6_out_echo; |
265 | /* ipv6IfIcmpOutEchoReplies, # of output echo replies */ |
266 | u_quad_t ifs6_out_echoreply; |
267 | /* ipv6IfIcmpOutRouterSolicits, # of output router solicitations */ |
268 | u_quad_t ifs6_out_routersolicit; |
269 | /* ipv6IfIcmpOutRouterAdvertisements, # of output router advertisements */ |
270 | u_quad_t ifs6_out_routeradvert; |
271 | /* ipv6IfIcmpOutNeighborSolicits, # of output neighbor solicitations */ |
272 | u_quad_t ifs6_out_neighborsolicit; |
273 | /* ipv6IfIcmpOutNeighborAdvertisements, # of output neighbor advertisements */ |
274 | u_quad_t ifs6_out_neighboradvert; |
275 | /* ipv6IfIcmpOutRedirects, # of output redirects */ |
276 | u_quad_t ifs6_out_redirect; |
277 | /* ipv6IfIcmpOutGroupMembQueries, # of output MLD queries */ |
278 | u_quad_t ifs6_out_mldquery; |
279 | /* ipv6IfIcmpOutGroupMembResponses, # of output MLD reports */ |
280 | u_quad_t ifs6_out_mldreport; |
281 | /* ipv6IfIcmpOutGroupMembReductions, # of output MLD done */ |
282 | u_quad_t ifs6_out_mlddone; |
283 | }; |
284 | |
285 | /* |
286 | * If you make changes that change the size of in6_ifreq, |
287 | * make sure you fix compat/netinet6/in6_var.h |
288 | */ |
289 | struct in6_ifreq { |
290 | char ifr_name[IFNAMSIZ]; |
291 | union { |
292 | struct sockaddr_in6 ifru_addr; |
293 | struct sockaddr_in6 ifru_dstaddr; |
294 | short ifru_flags; |
295 | int ifru_flags6; |
296 | int ifru_metric; |
297 | void * ifru_data; |
298 | struct in6_addrlifetime ifru_lifetime; |
299 | struct in6_ifstat ifru_stat; |
300 | struct icmp6_ifstat ifru_icmp6stat; |
301 | } ifr_ifru; |
302 | }; |
303 | |
304 | struct in6_aliasreq { |
305 | char ifra_name[IFNAMSIZ]; |
306 | struct sockaddr_in6 ifra_addr; |
307 | struct sockaddr_in6 ifra_dstaddr; |
308 | struct sockaddr_in6 ifra_prefixmask; |
309 | int ifra_flags; |
310 | struct in6_addrlifetime ifra_lifetime; |
311 | }; |
312 | |
313 | /* prefix type macro */ |
314 | #define IN6_PREFIX_ND 1 |
315 | #define IN6_PREFIX_RR 2 |
316 | |
317 | /* |
318 | * prefix related flags passed between kernel(NDP related part) and |
319 | * user land command(ifconfig) and daemon(rtadvd). |
320 | * Note: We originally intended to use prf_ra{} only within in6_prflags{}, but |
321 | * it was (probably unintentionally) used in nd6.h as well. Since C++ does |
322 | * not allow such a reference, prf_ra{} was then moved outside. In general, |
323 | * however, this structure should not be used directly. |
324 | */ |
325 | struct prf_ra { |
326 | u_int32_t onlink : 1; |
327 | u_int32_t autonomous : 1; |
328 | u_int32_t router : 1; |
329 | u_int32_t reserved : 5; |
330 | }; |
331 | |
332 | struct in6_prflags { |
333 | struct prf_ra prf_ra; |
334 | u_char prf_reserved1; |
335 | u_short prf_reserved2; |
336 | /* want to put this on 4byte offset */ |
337 | struct prf_rr { |
338 | u_int32_t decrvalid : 1; |
339 | u_int32_t decrprefd : 1; |
340 | u_int32_t reserved : 6; |
341 | } prf_rr; |
342 | u_char prf_reserved3; |
343 | u_short prf_reserved4; |
344 | }; |
345 | |
346 | struct in6_prefixreq { |
347 | char ipr_name[IFNAMSIZ]; |
348 | u_char ipr_origin; |
349 | u_char ipr_plen; |
350 | u_int32_t ipr_vltime; |
351 | u_int32_t ipr_pltime; |
352 | struct in6_prflags ipr_flags; |
353 | struct sockaddr_in6 ipr_prefix; |
354 | }; |
355 | |
356 | #define PR_ORIG_RA 0 |
357 | #define PR_ORIG_RR 1 |
358 | #define PR_ORIG_STATIC 2 |
359 | #define PR_ORIG_KERNEL 3 |
360 | |
361 | #define ipr_raf_onlink ipr_flags.prf_ra.onlink |
362 | #define ipr_raf_auto ipr_flags.prf_ra.autonomous |
363 | |
364 | #define ipr_statef_onlink ipr_flags.prf_state.onlink |
365 | |
366 | #define ipr_rrf_decrvalid ipr_flags.prf_rr.decrvalid |
367 | #define ipr_rrf_decrprefd ipr_flags.prf_rr.decrprefd |
368 | |
369 | struct in6_rrenumreq { |
370 | char irr_name[IFNAMSIZ]; |
371 | u_char irr_origin; |
372 | u_char irr_m_len; /* match len for matchprefix */ |
373 | u_char irr_m_minlen; /* minlen for matching prefix */ |
374 | u_char irr_m_maxlen; /* maxlen for matching prefix */ |
375 | u_char irr_u_uselen; /* uselen for adding prefix */ |
376 | u_char irr_u_keeplen; /* keeplen from matching prefix */ |
377 | struct irr_raflagmask { |
378 | u_int32_t onlink : 1; |
379 | u_int32_t autonomous : 1; |
380 | u_int32_t reserved : 6; |
381 | } irr_raflagmask; |
382 | u_int32_t irr_vltime; |
383 | u_int32_t irr_pltime; |
384 | struct in6_prflags irr_flags; |
385 | struct sockaddr_in6 irr_matchprefix; |
386 | struct sockaddr_in6 irr_useprefix; |
387 | }; |
388 | |
389 | #define irr_raf_mask_onlink irr_raflagmask.onlink |
390 | #define irr_raf_mask_auto irr_raflagmask.autonomous |
391 | #define irr_raf_mask_reserved irr_raflagmask.reserved |
392 | |
393 | #define irr_raf_onlink irr_flags.prf_ra.onlink |
394 | #define irr_raf_auto irr_flags.prf_ra.autonomous |
395 | |
396 | #define irr_statef_onlink irr_flags.prf_state.onlink |
397 | |
398 | #define irr_rrf irr_flags.prf_rr |
399 | #define irr_rrf_decrvalid irr_flags.prf_rr.decrvalid |
400 | #define irr_rrf_decrprefd irr_flags.prf_rr.decrprefd |
401 | |
402 | /* |
403 | * Given a pointer to an in6_ifaddr (ifaddr), |
404 | * return a pointer to the addr as a sockaddr_in6 |
405 | */ |
406 | #define IA6_IN6(ia) (&((ia)->ia_addr.sin6_addr)) |
407 | #define IA6_DSTIN6(ia) (&((ia)->ia_dstaddr.sin6_addr)) |
408 | #define IA6_MASKIN6(ia) (&((ia)->ia_prefixmask.sin6_addr)) |
409 | #define IA6_SIN6(ia) (&((ia)->ia_addr)) |
410 | #define IA6_DSTSIN6(ia) (&((ia)->ia_dstaddr)) |
411 | #define IFA_IN6(x) (&((struct sockaddr_in6 *)((x)->ifa_addr))->sin6_addr) |
412 | #define IFA_DSTIN6(x) (&((struct sockaddr_in6 *)((x)->ifa_dstaddr))->sin6_addr) |
413 | |
414 | #ifdef _KERNEL |
415 | #define IN6_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \ |
416 | (((d)->s6_addr32[0] ^ (a)->s6_addr32[0]) & (m)->s6_addr32[0]) == 0 && \ |
417 | (((d)->s6_addr32[1] ^ (a)->s6_addr32[1]) & (m)->s6_addr32[1]) == 0 && \ |
418 | (((d)->s6_addr32[2] ^ (a)->s6_addr32[2]) & (m)->s6_addr32[2]) == 0 && \ |
419 | (((d)->s6_addr32[3] ^ (a)->s6_addr32[3]) & (m)->s6_addr32[3]) == 0 ) |
420 | #endif |
421 | |
422 | #define SIOCSIFADDR_IN6 _IOW('i', 12, struct in6_ifreq) |
423 | #define SIOCGIFADDR_IN6 _IOWR('i', 33, struct in6_ifreq) |
424 | |
425 | #ifdef _KERNEL |
426 | /* |
427 | * SIOCSxxx ioctls should be unused (see comments in in6.c), but |
428 | * we do not shift numbers for binary compatibility. |
429 | */ |
430 | #define SIOCSIFDSTADDR_IN6 _IOW('i', 14, struct in6_ifreq) |
431 | #define SIOCSIFNETMASK_IN6 _IOW('i', 22, struct in6_ifreq) |
432 | #endif |
433 | |
434 | #define SIOCGIFDSTADDR_IN6 _IOWR('i', 34, struct in6_ifreq) |
435 | #define SIOCGIFNETMASK_IN6 _IOWR('i', 37, struct in6_ifreq) |
436 | |
437 | #define SIOCDIFADDR_IN6 _IOW('i', 25, struct in6_ifreq) |
438 | /* 26 was OSIOCAIFADDR_IN6 */ |
439 | |
440 | /* 70 was OSIOCSIFPHYADDR_IN6 */ |
441 | #define SIOCGIFPSRCADDR_IN6 _IOWR('i', 71, struct in6_ifreq) |
442 | #define SIOCGIFPDSTADDR_IN6 _IOWR('i', 72, struct in6_ifreq) |
443 | |
444 | #define SIOCGIFAFLAG_IN6 _IOWR('i', 73, struct in6_ifreq) |
445 | |
446 | #define SIOCGDRLST_IN6 _IOWR('i', 74, struct in6_drlist) |
447 | #define SIOCGPRLST_IN6 _IOWR('i', 75, struct in6_oprlist) |
448 | #ifdef _KERNEL |
449 | #define OSIOCGIFINFO_IN6 _IOWR('i', 76, struct in6_ondireq) |
450 | #endif |
451 | #define SIOCSNDFLUSH_IN6 _IOWR('i', 77, struct in6_ifreq) |
452 | #define SIOCGNBRINFO_IN6 _IOWR('i', 78, struct in6_nbrinfo) |
453 | #define SIOCSPFXFLUSH_IN6 _IOWR('i', 79, struct in6_ifreq) |
454 | #define SIOCSRTRFLUSH_IN6 _IOWR('i', 80, struct in6_ifreq) |
455 | /* 81 was old SIOCGIFALIFETIME_IN6 */ |
456 | #if 0 |
457 | /* withdrawn - do not reuse number 82 */ |
458 | #define SIOCSIFALIFETIME_IN6 _IOWR('i', 82, struct in6_ifreq) |
459 | #endif |
460 | #define SIOCGIFSTAT_IN6 _IOWR('i', 83, struct in6_ifreq) |
461 | #define SIOCGIFSTAT_ICMP6 _IOWR('i', 84, struct in6_ifreq) |
462 | |
463 | #define SIOCSDEFIFACE_IN6 _IOWR('i', 85, struct in6_ndifreq) |
464 | #define SIOCGDEFIFACE_IN6 _IOWR('i', 86, struct in6_ndifreq) |
465 | |
466 | #define SIOCSIFINFO_FLAGS _IOWR('i', 87, struct in6_ndireq) /* XXX */ |
467 | |
468 | #define SIOCSIFPREFIX_IN6 _IOW('i', 100, struct in6_prefixreq) /* set */ |
469 | #define SIOCGIFPREFIX_IN6 _IOWR('i', 101, struct in6_prefixreq) /* get */ |
470 | #define SIOCDIFPREFIX_IN6 _IOW('i', 102, struct in6_prefixreq) /* del */ |
471 | #define SIOCAIFPREFIX_IN6 _IOW('i', 103, struct in6_rrenumreq) /* add */ |
472 | #define SIOCCIFPREFIX_IN6 _IOW('i', 104, \ |
473 | struct in6_rrenumreq) /* change */ |
474 | #define SIOCSGIFPREFIX_IN6 _IOW('i', 105, \ |
475 | struct in6_rrenumreq) /* set global */ |
476 | #define SIOCGIFALIFETIME_IN6 _IOWR('i', 106, struct in6_ifreq) |
477 | #define SIOCAIFADDR_IN6 _IOW('i', 107, struct in6_aliasreq) |
478 | #define SIOCGIFINFO_IN6 _IOWR('i', 108, struct in6_ndireq) |
479 | #define SIOCSIFINFO_IN6 _IOWR('i', 109, struct in6_ndireq) |
480 | #define SIOCSIFPHYADDR_IN6 _IOW('i', 110, struct in6_aliasreq) |
481 | |
482 | |
483 | /* XXX: Someone decided to switch to 'u' here for unknown reasons! */ |
484 | #define SIOCGETSGCNT_IN6 _IOWR('u', 106, \ |
485 | struct sioc_sg_req6) /* get s,g pkt cnt */ |
486 | #define SIOCGETMIFCNT_IN6 _IOWR('u', 107, \ |
487 | struct sioc_mif_req6) /* get pkt cnt per if */ |
488 | #define SIOCAADDRCTL_POLICY _IOW('u', 108, struct in6_addrpolicy) |
489 | #define SIOCDADDRCTL_POLICY _IOW('u', 109, struct in6_addrpolicy) |
490 | |
491 | #define IN6_IFF_ANYCAST 0x01 /* anycast address */ |
492 | #define IN6_IFF_TENTATIVE 0x02 /* tentative address */ |
493 | #define IN6_IFF_DUPLICATED 0x04 /* DAD detected duplicate */ |
494 | #define IN6_IFF_DETACHED 0x08 /* may be detached from the link */ |
495 | #define IN6_IFF_DEPRECATED 0x10 /* deprecated address */ |
496 | #define IN6_IFF_NODAD 0x20 /* don't perform DAD on this address |
497 | * (used only at first SIOC* call) |
498 | */ |
499 | #define IN6_IFF_AUTOCONF 0x40 /* autoconfigurable address. */ |
500 | #define IN6_IFF_TEMPORARY 0x80 /* temporary (anonymous) address. */ |
501 | |
502 | #define IN6_IFFBITS \ |
503 | "\020\1ANYCAST\2TENTATIVE\3DUPLICATED\4DETACHED\5DEPRECATED\6NODAD" \ |
504 | "\7AUTOCONF\10TEMPORARY" |
505 | |
506 | |
507 | /* do not input/output */ |
508 | #define IN6_IFF_NOTREADY (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED) |
509 | |
510 | #ifdef _KERNEL |
511 | #define IN6_ARE_SCOPE_CMP(a,b) ((a)-(b)) |
512 | #define IN6_ARE_SCOPE_EQUAL(a,b) ((a)==(b)) |
513 | #endif |
514 | |
515 | #ifdef _KERNEL |
516 | |
517 | #include <sys/mutex.h> |
518 | #include <sys/pserialize.h> |
519 | |
520 | #include <net/pktqueue.h> |
521 | |
522 | extern pktqueue_t *ip6_pktq; |
523 | |
524 | MALLOC_DECLARE(M_IP6OPT); |
525 | |
526 | extern struct pslist_head in6_ifaddr_list; |
527 | extern kmutex_t in6_ifaddr_lock; |
528 | |
529 | #define IN6_ADDRLIST_ENTRY_INIT(__ia) \ |
530 | PSLIST_ENTRY_INIT((__ia), ia6_pslist_entry) |
531 | #define IN6_ADDRLIST_ENTRY_DESTROY(__ia) \ |
532 | PSLIST_ENTRY_DESTROY((__ia), ia6_pslist_entry) |
533 | #define IN6_ADDRLIST_READER_EMPTY() \ |
534 | (PSLIST_READER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \ |
535 | ia6_pslist_entry) == NULL) |
536 | #define IN6_ADDRLIST_READER_FIRST() \ |
537 | PSLIST_READER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \ |
538 | ia6_pslist_entry) |
539 | #define IN6_ADDRLIST_READER_NEXT(__ia) \ |
540 | PSLIST_READER_NEXT((__ia), struct in6_ifaddr, ia6_pslist_entry) |
541 | #define IN6_ADDRLIST_READER_FOREACH(__ia) \ |
542 | PSLIST_READER_FOREACH((__ia), &in6_ifaddr_list, \ |
543 | struct in6_ifaddr, ia6_pslist_entry) |
544 | #define IN6_ADDRLIST_WRITER_INSERT_HEAD(__ia) \ |
545 | PSLIST_WRITER_INSERT_HEAD(&in6_ifaddr_list, (__ia), ia6_pslist_entry) |
546 | #define IN6_ADDRLIST_WRITER_REMOVE(__ia) \ |
547 | PSLIST_WRITER_REMOVE((__ia), ia6_pslist_entry) |
548 | #define IN6_ADDRLIST_WRITER_FOREACH(__ia) \ |
549 | PSLIST_WRITER_FOREACH((__ia), &in6_ifaddr_list, struct in6_ifaddr, \ |
550 | ia6_pslist_entry) |
551 | #define IN6_ADDRLIST_WRITER_FIRST() \ |
552 | PSLIST_WRITER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \ |
553 | ia6_pslist_entry) |
554 | #define IN6_ADDRLIST_WRITER_NEXT(__ia) \ |
555 | PSLIST_WRITER_NEXT((__ia), struct in6_ifaddr, ia6_pslist_entry) |
556 | #define IN6_ADDRLIST_WRITER_INSERT_AFTER(__ia, __new) \ |
557 | PSLIST_WRITER_INSERT_AFTER((__ia), (__new), ia6_pslist_entry) |
558 | #define IN6_ADDRLIST_WRITER_EMPTY() \ |
559 | (PSLIST_WRITER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \ |
560 | ia6_pslist_entry) == NULL) |
561 | #define IN6_ADDRLIST_WRITER_INSERT_TAIL(__new) \ |
562 | do { \ |
563 | if (IN6_ADDRLIST_WRITER_EMPTY()) { \ |
564 | IN6_ADDRLIST_WRITER_INSERT_HEAD((__new)); \ |
565 | } else { \ |
566 | struct in6_ifaddr *__ia; \ |
567 | IN6_ADDRLIST_WRITER_FOREACH(__ia) { \ |
568 | if (IN6_ADDRLIST_WRITER_NEXT(__ia) == NULL) { \ |
569 | IN6_ADDRLIST_WRITER_INSERT_AFTER(__ia,\ |
570 | (__new)); \ |
571 | break; \ |
572 | } \ |
573 | } \ |
574 | } \ |
575 | } while (0) |
576 | |
577 | #define in6_ifstat_inc(ifp, tag) \ |
578 | do { \ |
579 | if (ifp) \ |
580 | ((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->in6_ifstat->tag++; \ |
581 | } while (/*CONSTCOND*/ 0) |
582 | |
583 | extern const struct in6_addr zeroin6_addr; |
584 | extern const u_char inet6ctlerrmap[]; |
585 | extern unsigned long in6_maxmtu; |
586 | extern bool in6_present; |
587 | extern callout_t in6_tmpaddrtimer_ch; |
588 | |
589 | /* |
590 | * Macro for finding the internet address structure (in6_ifaddr) corresponding |
591 | * to a given interface (ifnet structure). |
592 | */ |
593 | static __inline struct in6_ifaddr * |
594 | in6_get_ia_from_ifp(struct ifnet *ifp) |
595 | { |
596 | struct ifaddr *ifa; |
597 | |
598 | IFADDR_READER_FOREACH(ifa, ifp) { |
599 | if (ifa->ifa_addr->sa_family == AF_INET6) |
600 | break; |
601 | } |
602 | return (struct in6_ifaddr *)ifa; |
603 | } |
604 | |
605 | static __inline struct in6_ifaddr * |
606 | in6_get_ia_from_ifp_psref(struct ifnet *ifp, struct psref *psref) |
607 | { |
608 | struct in6_ifaddr *ia; |
609 | int s; |
610 | |
611 | s = pserialize_read_enter(); |
612 | ia = in6_get_ia_from_ifp(ifp); |
613 | if (ia != NULL) |
614 | ia6_acquire(ia, psref); |
615 | pserialize_read_exit(s); |
616 | |
617 | return ia; |
618 | } |
619 | #endif /* _KERNEL */ |
620 | |
621 | /* |
622 | * Multi-cast membership entry. One for each group/ifp that a PCB |
623 | * belongs to. |
624 | */ |
625 | struct in6_multi_mship { |
626 | struct in6_multi *i6mm_maddr; /* Multicast address pointer */ |
627 | LIST_ENTRY(in6_multi_mship) i6mm_chain; /* multicast options chain */ |
628 | }; |
629 | |
630 | struct in6_multi { |
631 | LIST_ENTRY(in6_multi) in6m_entry; /* list glue */ |
632 | struct in6_addr in6m_addr; /* IP6 multicast address */ |
633 | struct ifnet *in6m_ifp; /* back pointer to ifnet */ |
634 | /* DEPRECATED. Keep it to avoid breaking kvm(3) users */ |
635 | struct in6_ifaddr *_in6m_ia; /* back pointer to in6_ifaddr */ |
636 | u_int in6m_refcount; /* # membership claims by sockets */ |
637 | u_int in6m_state; /* state of the membership */ |
638 | int in6m_timer; /* delay to send the 1st report */ |
639 | struct timeval in6m_timer_expire; /* when the timer expires */ |
640 | callout_t in6m_timer_ch; |
641 | }; |
642 | |
643 | #define IN6M_TIMER_UNDEF -1 |
644 | |
645 | |
646 | #ifdef _KERNEL |
647 | /* flags to in6_update_ifa */ |
648 | #define IN6_IFAUPDATE_DADDELAY 0x1 /* first time to configure an address */ |
649 | |
650 | #if 0 |
651 | /* |
652 | * Macros for looking up the in6_multi_mship record for a given IP6 multicast |
653 | * address on a given interface. If no matching record is found, "imm" |
654 | * returns NULL. |
655 | */ |
656 | static __inline struct in6_multi_mship * |
657 | in6_lookup_mship(struct in6_addr *addr, struct ifnet *ifp, |
658 | struct ip6_moptions *imop) |
659 | { |
660 | struct in6_multi_mship *imm; |
661 | |
662 | LIST_FOREACH(imm, &imop->im6o_memberships, i6mm_chain) { |
663 | if (imm->i6mm_maddr->in6m_ifp != ifp) |
664 | continue; |
665 | if (IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr, |
666 | addr)) |
667 | break; |
668 | } |
669 | return imm; |
670 | } |
671 | |
672 | #define IN6_LOOKUP_MSHIP(__addr, __ifp, __imop, __imm) \ |
673 | /* struct in6_addr __addr; */ \ |
674 | /* struct ifnet *__ifp; */ \ |
675 | /* struct ip6_moptions *__imop */ \ |
676 | /* struct in6_multi_mship *__imm; */ \ |
677 | do { \ |
678 | (__imm) = in6_lookup_mship(&(__addr), (__ifp), (__imop)); \ |
679 | } while (/*CONSTCOND*/ 0) |
680 | #endif |
681 | |
682 | void in6_init(void); |
683 | |
684 | void in6_multi_lock(int); |
685 | void in6_multi_unlock(void); |
686 | bool in6_multi_locked(int); |
687 | struct in6_multi * |
688 | in6_lookup_multi(const struct in6_addr *, const struct ifnet *); |
689 | bool in6_multi_group(const struct in6_addr *, const struct ifnet *); |
690 | void in6_purge_multi(struct ifnet *); |
691 | struct in6_multi *in6_addmulti(struct in6_addr *, struct ifnet *, |
692 | int *, int); |
693 | void in6_delmulti(struct in6_multi *); |
694 | void in6_delmulti_locked(struct in6_multi *); |
695 | void in6_lookup_and_delete_multi(const struct in6_addr *, |
696 | const struct ifnet *); |
697 | struct in6_multi_mship *in6_joingroup(struct ifnet *, struct in6_addr *, |
698 | int *, int); |
699 | int in6_leavegroup(struct in6_multi_mship *); |
700 | int in6_mask2len(struct in6_addr *, u_char *); |
701 | int in6_control(struct socket *, u_long, void *, struct ifnet *); |
702 | int in6_update_ifa(struct ifnet *, struct in6_aliasreq *, int); |
703 | void in6_purgeaddr(struct ifaddr *); |
704 | void in6_purgeif(struct ifnet *); |
705 | void in6_setmaxmtu (void); |
706 | int in6_if2idlen (struct ifnet *); |
707 | void *in6_domifattach(struct ifnet *); |
708 | void in6_domifdetach(struct ifnet *, void *); |
709 | void in6_ifremlocal(struct ifaddr *); |
710 | void in6_ifaddlocal(struct ifaddr *); |
711 | struct in6_ifaddr * |
712 | in6ifa_ifpforlinklocal(const struct ifnet *, int); |
713 | struct in6_ifaddr * |
714 | in6ifa_ifpforlinklocal_psref(const struct ifnet *, int, struct psref *); |
715 | struct in6_ifaddr * |
716 | in6ifa_ifpwithaddr(const struct ifnet *, const struct in6_addr *); |
717 | struct in6_ifaddr * |
718 | in6ifa_ifpwithaddr_psref(const struct ifnet *, const struct in6_addr *, |
719 | struct psref *); |
720 | struct in6_ifaddr *in6ifa_ifwithaddr(const struct in6_addr *, uint32_t); |
721 | int in6_matchlen(struct in6_addr *, struct in6_addr *); |
722 | int in6_are_prefix_equal(struct in6_addr *, struct in6_addr *, int); |
723 | void in6_prefixlen2mask(struct in6_addr *, int); |
724 | void in6_purgeprefix(struct ifnet *); |
725 | void in6_purge_mcast_references(struct in6_multi *); |
726 | |
727 | int ip6flow_fastforward(struct mbuf **); /* IPv6 fast forward routine */ |
728 | |
729 | int in6_src_ioctl(u_long, void *); |
730 | int in6_is_addr_deprecated(struct sockaddr_in6 *); |
731 | struct in6pcb; |
732 | |
733 | #define LLTABLE6(ifp) (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->lltable) |
734 | |
735 | void in6_sysctl_multicast_setup(struct sysctllog **); |
736 | |
737 | #endif /* _KERNEL */ |
738 | |
739 | #endif /* !_NETINET6_IN6_VAR_H_ */ |
740 | |