| 1 | /*	$OpenBSD: ip6_var.h,v 1.129 2025/12/31 04:10:00 jsg Exp $	*/ |
| 2 | /*	$KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei 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) 1982, 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 | *	@(#)ip_var.h	8.1 (Berkeley) 6/10/93 |
| 62 | */ |
| 63 | |
| 64 | #ifndef _NETINET6_IP6_VAR_H_ |
| 65 | #define _NETINET6_IP6_VAR_H_ |
| 66 | |
| 67 | struct	ip6stat { |
| 68 | 	u_int64_t ip6s_total;		/* total packets received */ |
| 69 | 	u_int64_t ip6s_tooshort;	/* packet too short */ |
| 70 | 	u_int64_t ip6s_toosmall;	/* not enough data */ |
| 71 | 	u_int64_t ip6s_fragments;	/* fragments received */ |
| 72 | 	u_int64_t ip6s_fragdropped;	/* frags dropped(dups, out of space) */ |
| 73 | 	u_int64_t ip6s_fragtimeout;	/* fragments timed out */ |
| 74 | 	u_int64_t ip6s_fragoverflow;	/* fragments that exceeded limit */ |
| 75 | 	u_int64_t ip6s_forward;		/* packets forwarded */ |
| 76 | 	u_int64_t ip6s_cantforward;	/* packets rcvd for unreachable dest */ |
| 77 | 	u_int64_t ip6s_redirectsent;	/* packets forwarded on same net */ |
| 78 | 	u_int64_t ip6s_delivered;	/* datagrams delivered to upper level*/ |
| 79 | 	u_int64_t ip6s_localout;	/* total ip packets generated here */ |
| 80 | 	u_int64_t ip6s_odropped;	/* lost output due to nobufs, etc. */ |
| 81 | 	u_int64_t ip6s_reassembled;	/* total packets reassembled ok */ |
| 82 | 	u_int64_t ip6s_fragmented;	/* datagrams successfully fragmented */ |
| 83 | 	u_int64_t ip6s_ofragments;	/* output fragments created */ |
| 84 | 	u_int64_t ip6s_cantfrag;	/* don't fragment flag was set, etc. */ |
| 85 | 	u_int64_t ip6s_badoptions;	/* error in option processing */ |
| 86 | 	u_int64_t ip6s_noroute;		/* packets discarded due to no route */ |
| 87 | 	u_int64_t ip6s_badvers;		/* ip6 version != 6 */ |
| 88 | 	u_int64_t ip6s_rawout;		/* total raw ip packets generated */ |
| 89 | 	u_int64_t ip6s_badscope;	/* scope error */ |
| 90 | 	u_int64_t ip6s_notmember;	/* don't join this multicast group */ |
| 91 | 	u_int64_t ip6s_nxthist[256];	/* next header history */ |
| 92 | 	u_int64_t ip6s_m1;		/* one mbuf */ |
| 93 | 	u_int64_t ip6s_m2m[32];		/* two or more mbuf */ |
| 94 | 	u_int64_t ip6s_mext1;		/* one ext mbuf */ |
| 95 | 	u_int64_t ip6s_mext2m;		/* two or more ext mbuf */ |
| 96 | 	u_int64_t ip6s_nogif;		/* no match gif found */ |
| 97 | 	u_int64_t ip6s_toomanyhdr;	/* discarded due to too many headers */ |
| 98 | |
| 99 | 	/* |
| 100 | 	 * statistics for improvement of the source address selection |
| 101 | 	 * algorithm: |
| 102 | 	 * XXX: hardcoded 16 = # of ip6 multicast scope types + 1 |
| 103 | 	 */ |
| 104 | 	/* number of times that address selection fails */ |
| 105 | 	u_int64_t ip6s_sources_none; |
| 106 | 	/* number of times that an address on the outgoing I/F is chosen */ |
| 107 | 	u_int64_t ip6s_sources_sameif[16]; |
| 108 | 	/* number of times that an address on a non-outgoing I/F is chosen */ |
| 109 | 	u_int64_t ip6s_sources_otherif[16]; |
| 110 | 	/* |
| 111 | 	 * number of times that an address that has the same scope |
| 112 | 	 * from the destination is chosen. |
| 113 | 	 */ |
| 114 | 	u_int64_t ip6s_sources_samescope[16]; |
| 115 | 	/* |
| 116 | 	 * number of times that an address that has a different scope |
| 117 | 	 * from the destination is chosen. |
| 118 | 	 */ |
| 119 | 	u_int64_t ip6s_sources_otherscope[16]; |
| 120 | 	/* number of times that an deprecated address is chosen */ |
| 121 | 	u_int64_t ip6s_sources_deprecated[16]; |
| 122 | |
| 123 | 	u_int64_t ip6s_rtcachehit;	/* valid route found in cache */ |
| 124 | 	u_int64_t ip6s_rtcachemiss;	/* route cache with new destination */ |
| 125 | 	u_int64_t ip6s_wrongif;		/* packet received on wrong interface */ |
| 126 | 	u_int64_t ip6s_idropped;	/* lost input due to nobufs, etc. */ |
| 127 | }; |
| 128 | |
| 129 | #ifdef _KERNEL |
| 130 | |
| 131 | /* |
| 132 | * IP6 reassembly queue structure. Each fragment |
| 133 | * being reassembled is attached to one of these structures. |
| 134 | */ |
| 135 | struct	ip6q { |
| 136 | 	TAILQ_ENTRY(ip6q) ip6q_queue; |
| 137 | 	LIST_HEAD(ip6asfrag_list, ip6asfrag) ip6q_asfrag; |
| 138 | 	struct in6_addr	ip6q_src, ip6q_dst; |
| 139 | 	int		ip6q_unfrglen;	/* len of unfragmentable part */ |
| 140 | 	int		ip6q_nfrag;	/* # of fragments */ |
| 141 | 	u_int32_t	ip6q_ident;	/* fragment identification */ |
| 142 | 	u_int8_t	ip6q_nxt;	/* ip6f_nxt in first fragment */ |
| 143 | 	u_int8_t	ip6q_ecn; |
| 144 | 	u_int8_t	ip6q_ttl;	/* time to live in slowtimo units */ |
| 145 | }; |
| 146 | |
| 147 | struct	ip6asfrag { |
| 148 | 	LIST_ENTRY(ip6asfrag) ip6af_list; |
| 149 | 	struct mbuf	*ip6af_m; |
| 150 | 	int		ip6af_offset;	/* offset in ip6af_m to next header */ |
| 151 | 	int		ip6af_frglen;	/* fragmentable part length */ |
| 152 | 	int		ip6af_off;	/* fragment offset */ |
| 153 | 	u_int16_t	ip6af_mff;	/* more fragment bit in frag off */ |
| 154 | }; |
| 155 | |
| 156 | struct	ip6_moptions { |
| 157 | 	LIST_HEAD(, in6_multi_mship) im6o_memberships; |
| 158 | 	unsigned short im6o_ifidx;	/* ifp index for outgoing multicasts */ |
| 159 | 	u_char	im6o_hlim;	/* hoplimit for outgoing multicasts */ |
| 160 | 	u_char	im6o_loop;	/* 1 >= hear sends if a member */ |
| 161 | }; |
| 162 | |
| 163 | /* |
| 164 | * Control options for outgoing packets |
| 165 | */ |
| 166 | |
| 167 | /* Routing header related info */ |
| 168 | struct	ip6po_rhinfo { |
| 169 | 	struct	ip6_rthdr *ip6po_rhi_rthdr; /* Routing header */ |
| 170 | 	struct	route ip6po_rhi_route; /* Route to the 1st hop */ |
| 171 | }; |
| 172 | #define ip6po_rthdr	ip6po_rhinfo.ip6po_rhi_rthdr |
| 173 | #define ip6po_route	ip6po_rhinfo.ip6po_rhi_route |
| 174 | |
| 175 | struct	ip6_pktopts { |
| 176 | 	/* Hoplimit for outgoing packets */ |
| 177 | 	int	ip6po_hlim; |
| 178 | |
| 179 | 	/* Outgoing IF/address information */ |
| 180 | 	struct in6_pktinfo *ip6po_pktinfo; |
| 181 | |
| 182 | 	/* Hop-by-Hop options header */ |
| 183 | 	struct	ip6_hbh *ip6po_hbh; |
| 184 | |
| 185 | 	/* Destination options header (before a routing header) */ |
| 186 | 	struct	ip6_dest *ip6po_dest1; |
| 187 | |
| 188 | 	/* Routing header related info. */ |
| 189 | 	struct	ip6po_rhinfo ip6po_rhinfo; |
| 190 | |
| 191 | 	/* Destination options header (after a routing header) */ |
| 192 | 	struct	ip6_dest *ip6po_dest2; |
| 193 | |
| 194 | 	/* traffic class */ |
| 195 | 	int	ip6po_tclass; |
| 196 | |
| 197 | 	/* fragment vs PMTU discovery policy */ |
| 198 | 	int	ip6po_minmtu; |
| 199 | #define IP6PO_MINMTU_MCASTONLY	-1 /* default: send at min MTU for multicast */ |
| 200 | #define IP6PO_MINMTU_DISABLE	0 /* always perform pmtu disc */ |
| 201 | #define IP6PO_MINMTU_ALL	1 /* always send at min MTU */ |
| 202 | |
| 203 | 	int	ip6po_flags; |
| 204 | #define	IP6PO_DONTFRAG	0x04	/* disable fragmentation (IPV6_DONTFRAG) */ |
| 205 | }; |
| 206 | |
| 207 | #include <sys/percpu.h> |
| 208 | |
| 209 | enum ip6stat_counters { |
| 210 | 	ip6s_total, |
| 211 | 	ip6s_tooshort, |
| 212 | 	ip6s_toosmall, |
| 213 | 	ip6s_fragments, |
| 214 | 	ip6s_fragdropped, |
| 215 | 	ip6s_fragtimeout, |
| 216 | 	ip6s_fragoverflow, |
| 217 | 	ip6s_forward, |
| 218 | 	ip6s_cantforward, |
| 219 | 	ip6s_redirectsent, |
| 220 | 	ip6s_delivered, |
| 221 | 	ip6s_localout, |
| 222 | 	ip6s_odropped, |
| 223 | 	ip6s_reassembled, |
| 224 | 	ip6s_fragmented, |
| 225 | 	ip6s_ofragments, |
| 226 | 	ip6s_cantfrag, |
| 227 | 	ip6s_badoptions, |
| 228 | 	ip6s_noroute, |
| 229 | 	ip6s_badvers, |
| 230 | 	ip6s_rawout, |
| 231 | 	ip6s_badscope, |
| 232 | 	ip6s_notmember, |
| 233 | 	ip6s_nxthist, |
| 234 | 	ip6s_m1 = ip6s_nxthist + 256, |
| 235 | 	ip6s_m2m, |
| 236 | 	ip6s_mext1 = ip6s_m2m + 32, |
| 237 | 	ip6s_mext2m, |
| 238 | 	ip6s_nogif, |
| 239 | 	ip6s_toomanyhdr, |
| 240 | 	ip6s_sources_none, |
| 241 | 	ip6s_sources_sameif, |
| 242 | 	ip6s_sources_otherif = ip6s_sources_sameif + 16, |
| 243 | 	ip6s_sources_samescope = ip6s_sources_otherif + 16, |
| 244 | 	ip6s_sources_otherscope = ip6s_sources_samescope + 16, |
| 245 | 	ip6s_sources_deprecated = ip6s_sources_otherscope + 16, |
| 246 | 	ip6s_rtcachehit = ip6s_sources_deprecated + 16, |
| 247 | 	ip6s_rtcachemiss, |
| 248 | 	ip6s_wrongif, |
| 249 | 	ip6s_idropped, |
| 250 | |
| 251 | 	ip6s_ncounters, |
| 252 | }; |
| 253 | |
| 254 | extern struct cpumem *ip6counters; |
| 255 | |
| 256 | static inline void |
| 257 | ip6stat_inc(enum ip6stat_counters c) |
| 258 | { |
| 259 | 	counters_inc(ip6counters, c); |
| 260 | } |
| 261 | |
| 262 | static inline void |
| 263 | ip6stat_add(enum ip6stat_counters c, uint64_t v) |
| 264 | { |
| 265 | 	counters_add(ip6counters, c, v); |
| 266 | } |
| 267 | |
| 268 | /* flags passed to ip6_output or ip6_forward as last parameter */ |
| 269 | #define IPV6_UNSPECSRC		0x01	/* allow :: as the source address */ |
| 270 | #define IPV6_FORWARDING		0x02	/* most of IPv6 header exists */ |
| 271 | #define IPV6_MINMTU		0x04	/* use minimum MTU (IPV6_USE_MIN_MTU) */ |
| 272 | #define IPV6_REDIRECT		0x08	/* redirected by pf */ |
| 273 | #define IPV6_FORWARDING_IPSEC	0x10	/* only packets processed by IPsec */ |
| 274 | |
| 275 | extern int ip6_mtudisc_timeout;		/* mtu discovery */ |
| 276 | extern struct rttimer_queue icmp6_mtudisc_timeout_q; |
| 277 | |
| 278 | extern int	ip6_defhlim;		/* default hop limit */ |
| 279 | extern int	ip6_defmcasthlim;	/* default multicast hop limit */ |
| 280 | extern int	ip6_forwarding;		/* act as router? */ |
| 281 | extern int	ip6_mforwarding;	/* act as multicast router? */ |
| 282 | extern int	ip6_multipath;		/* use multipath routes */ |
| 283 | extern int	ip6_mcast_pmtu;		/* path MTU discovery for multicast */ |
| 284 | extern int	ip6_neighborgcthresh; /* Threshold # of NDP entries for GC */ |
| 285 | extern int	ip6_maxdynroutes; /* Max # of routes created via redirect */ |
| 286 | |
| 287 | extern struct socket *ip6_mrouter[RT_TABLEID_MAX + 1]; /* multicast routing daemon */ |
| 288 | extern int	ip6_sendredirects;	/* send IP redirects when forwarding? */ |
| 289 | extern int	ip6_maxfragpackets; /* Maximum packets in reassembly queue */ |
| 290 | extern int	ip6_maxfrags;	/* Maximum fragments in reassembly queue */ |
| 291 | extern int	ip6_hdrnestlimit; /* upper limit of # of extension headers */ |
| 292 | extern int	ip6_dad_count;		/* DupAddrDetectionTransmits */ |
| 293 | extern int	ip6_dad_pending;	/* number of currently running DADs */ |
| 294 | |
| 295 | extern const struct pr_usrreqs rip6_usrreqs; |
| 296 | |
| 297 | struct inpcb; |
| 298 | struct ipsec_level; |
| 299 | |
| 300 | int	icmp6_ctloutput(int, struct socket *, int, int, struct mbuf *); |
| 301 | |
| 302 | void	ip6_init(void); |
| 303 | void	ip6intr(void); |
| 304 | int	ip6_input_if(struct mbuf **, int *, int, int, struct ifnet *, |
| 305 | 	 struct netstack *); |
| 306 | int	ip6_ours_enqueue(struct mbuf **, int *, int); |
| 307 | void	ip6_freepcbopts(struct ip6_pktopts *); |
| 308 | void	ip6_freemoptions(struct ip6_moptions *); |
| 309 | int	ip6_unknown_opt(struct mbuf **, u_int8_t *, int); |
| 310 | int	ip6_get_prevhdr(struct mbuf *, int); |
| 311 | int	ip6_nexthdr(struct mbuf *, int, int, int *); |
| 312 | int	ip6_lasthdr(struct mbuf *, int, int, int *); |
| 313 | int	ip6_mforward(struct ip6_hdr *, struct ifnet *, struct mbuf *, int); |
| 314 | int	ip6_process_hopopts(struct mbuf **, u_int8_t *, int, u_int32_t *, |
| 315 | 	 u_int32_t *); |
| 316 | void	ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **); |
| 317 | int	ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t); |
| 318 | |
| 319 | void	ip6_forward(struct mbuf *, struct route *, int); |
| 320 | |
| 321 | void	ip6_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in6 *); |
| 322 | int	ip6_output(struct mbuf *, struct ip6_pktopts *, struct route *, int, |
| 323 | 	 struct ip6_moptions *, const struct ipsec_level *); |
| 324 | int	ip6_fragment(struct mbuf *, struct mbuf_list *, int, u_char, u_long); |
| 325 | int	ip6_ctloutput(int, struct socket *, int, int, struct mbuf *); |
| 326 | int	ip6_raw_ctloutput(int, struct socket *, int, int, struct mbuf *); |
| 327 | void	ip6_initpktopts(struct ip6_pktopts *); |
| 328 | int	ip6_setpktopts(struct mbuf *, struct ip6_pktopts *, |
| 329 | 	 struct ip6_pktopts *, int, int); |
| 330 | void	ip6_clearpktopts(struct ip6_pktopts *, int); |
| 331 | void	ip6_randomid_init(void); |
| 332 | u_int32_t ip6_randomid(void); |
| 333 | void	ip6_send(struct mbuf *); |
| 334 | |
| 335 | int	route6_input(struct mbuf **, int *, int, int, struct netstack *); |
| 336 | |
| 337 | void	frag6_init(void); |
| 338 | int	frag6_input(struct mbuf **, int *, int, int, struct netstack *); |
| 339 | int	frag6_deletefraghdr(struct mbuf *, int); |
| 340 | void	frag6_slowtimo(void); |
| 341 | |
| 342 | void	rip6_init(void); |
| 343 | int	rip6_input(struct mbuf **, int *, int, int, struct netstack *); |
| 344 | void	rip6_ctlinput(int, struct sockaddr *, u_int, void *); |
| 345 | int	rip6_ctloutput(int, struct socket *, int, int, struct mbuf *); |
| 346 | int	rip6_output(struct mbuf *, struct socket *, struct sockaddr *, |
| 347 | 	 struct mbuf *); |
| 348 | int	rip6_attach(struct socket *, int, int); |
| 349 | int	rip6_detach(struct socket *); |
| 350 | int	rip6_bind(struct socket *, struct mbuf *, struct proc *); |
| 351 | int	rip6_connect(struct socket *, struct mbuf *); |
| 352 | int	rip6_disconnect(struct socket *); |
| 353 | int	rip6_shutdown(struct socket *); |
| 354 | int	rip6_send(struct socket *, struct mbuf *, struct mbuf *, |
| 355 | 	 struct mbuf *); |
| 356 | int	rip6_sysctl(int *, u_int, void *, size_t *, void *, size_t); |
| 357 | |
| 358 | int	dest6_input(struct mbuf **, int *, int, int, struct netstack *); |
| 359 | |
| 360 | int	in6_pcbselsrc(const struct in6_addr **, const struct sockaddr_in6 *, |
| 361 | 	 struct inpcb *, struct ip6_pktopts *); |
| 362 | int	in6_selectsrc(const struct in6_addr **, const struct sockaddr_in6 *, |
| 363 | 	 struct ip6_moptions *, unsigned int); |
| 364 | struct rtentry *in6_selectroute(const struct in6_addr *, struct ip6_pktopts *, |
| 365 | 	 struct route *, unsigned int rtableid); |
| 366 | |
| 367 | u_int32_t ip6_randomflowlabel(void); |
| 368 | |
| 369 | #ifdef IPSEC |
| 370 | struct tdb; |
| 371 | int	ip6_output_ipsec_lookup(struct mbuf *, const struct ipsec_level *, |
| 372 | 	 struct tdb **); |
| 373 | int	ip6_output_ipsec_send(struct tdb *, struct mbuf *, struct route *, |
| 374 | 	 u_int, int, int); |
| 375 | #endif /* IPSEC */ |
| 376 | |
| 377 | #endif /* _KERNEL */ |
| 378 | |
| 379 | #endif /* !_NETINET6_IP6_VAR_H_ */ |