xref: /illumos-gate/usr/src/uts/common/inet/ip.h (revision 2514b110)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
55dddb8baSkcpoon  * Common Development and Distribution License (the "License").
65dddb8baSkcpoon  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
215dddb8baSkcpoon 
227c478bd9Sstevel@tonic-gate /*
2359927d31SYuri Pankov  * Copyright (c) 1990 Mentat Inc.
241f19738eSmeem  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
250b905b49SYuri Pankov  * Copyright 2017 Nexenta Systems, Inc.
267199b8e7SDan McDonald  * Copyright 2017 OmniTI Computer Consulting, Inc. All rights reserved.
2742c5ef03SDan McDonald  * Copyright 2019, Joyent, Inc.
28*2514b110SRyan Goodfellow  * Copyright 2022 Oxide Computer Company
297c478bd9Sstevel@tonic-gate  */
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #ifndef	_INET_IP_H
327c478bd9Sstevel@tonic-gate #define	_INET_IP_H
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
357c478bd9Sstevel@tonic-gate extern "C" {
367c478bd9Sstevel@tonic-gate #endif
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h>
397c478bd9Sstevel@tonic-gate #include <sys/types.h>
407c478bd9Sstevel@tonic-gate #include <inet/mib2.h>
417c478bd9Sstevel@tonic-gate #include <inet/nd.h>
427c478bd9Sstevel@tonic-gate #include <sys/atomic.h>
437c478bd9Sstevel@tonic-gate #include <net/if_dl.h>
447c478bd9Sstevel@tonic-gate #include <net/if.h>
457c478bd9Sstevel@tonic-gate #include <netinet/ip.h>
467c478bd9Sstevel@tonic-gate #include <netinet/igmp.h>
47381a2a9aSdr #include <sys/neti.h>
48381a2a9aSdr #include <sys/hook.h>
49381a2a9aSdr #include <sys/hook_event.h>
50381a2a9aSdr #include <sys/hook_impl.h>
51f4b3ec61Sdh #include <inet/ip_stack.h>
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate #ifdef _KERNEL
547c478bd9Sstevel@tonic-gate #include <netinet/ip6.h>
557c478bd9Sstevel@tonic-gate #include <sys/avl.h>
56da14cebeSEric Cheng #include <sys/list.h>
577c478bd9Sstevel@tonic-gate #include <sys/vmem.h>
587c478bd9Sstevel@tonic-gate #include <sys/squeue.h>
5945916cd2Sjpk #include <net/route.h>
607c478bd9Sstevel@tonic-gate #include <sys/systm.h>
61c793af95Ssangeeta #include <net/radix.h>
626a8288c7Scarlsonj #include <sys/modhash.h>
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate #ifdef DEBUG
657c478bd9Sstevel@tonic-gate #define	CONN_DEBUG
667c478bd9Sstevel@tonic-gate #endif
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate #define	IP_DEBUG
697c478bd9Sstevel@tonic-gate /*
707c478bd9Sstevel@tonic-gate  * The mt-streams(9F) flags for the IP module; put here so that other
717c478bd9Sstevel@tonic-gate  * "drivers" that are actually IP (e.g., ICMP, UDP) can use the same set
727c478bd9Sstevel@tonic-gate  * of flags.
737c478bd9Sstevel@tonic-gate  */
747c478bd9Sstevel@tonic-gate #define	IP_DEVMTFLAGS D_MP
75ff550d0eSmasputra #endif	/* _KERNEL */
76ff550d0eSmasputra 
77ff550d0eSmasputra #define	IP_MOD_NAME	"ip"
78ff550d0eSmasputra #define	IP_DEV_NAME	"/dev/ip"
79ff550d0eSmasputra #define	IP6_DEV_NAME	"/dev/ip6"
80ff550d0eSmasputra 
81ff550d0eSmasputra #define	UDP_MOD_NAME	"udp"
82ff550d0eSmasputra #define	UDP_DEV_NAME	"/dev/udp"
83ff550d0eSmasputra #define	UDP6_DEV_NAME	"/dev/udp6"
84ff550d0eSmasputra 
85ff550d0eSmasputra #define	TCP_MOD_NAME	"tcp"
86ff550d0eSmasputra #define	TCP_DEV_NAME	"/dev/tcp"
87ff550d0eSmasputra #define	TCP6_DEV_NAME	"/dev/tcp6"
8877c67f2fSkcpoon 
8977c67f2fSkcpoon #define	SCTP_MOD_NAME	"sctp"
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate #ifndef	_IPADDR_T
927c478bd9Sstevel@tonic-gate #define	_IPADDR_T
937c478bd9Sstevel@tonic-gate typedef uint32_t ipaddr_t;
947c478bd9Sstevel@tonic-gate #endif
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate /* Number of bits in an address */
977c478bd9Sstevel@tonic-gate #define	IP_ABITS		32
98bd670b35SErik Nordmark #define	IPV4_ABITS		IP_ABITS
997c478bd9Sstevel@tonic-gate #define	IPV6_ABITS		128
1007f125a53SRavi Chandra Nallan #define	IP_MAX_HW_LEN	40
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate #define	IP_HOST_MASK		(ipaddr_t)0xffffffffU
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate #define	IP_CSUM(mp, off, sum)		(~ip_cksum(mp, off, sum) & 0xFFFF)
1057c478bd9Sstevel@tonic-gate #define	IP_CSUM_PARTIAL(mp, off, sum)	ip_cksum(mp, off, sum)
1067c478bd9Sstevel@tonic-gate #define	IP_BCSUM_PARTIAL(bp, len, sum)	bcksum(bp, len, sum)
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate #define	ILL_FRAG_HASH_TBL_COUNT	((unsigned int)64)
1097c478bd9Sstevel@tonic-gate #define	ILL_FRAG_HASH_TBL_SIZE	(ILL_FRAG_HASH_TBL_COUNT * sizeof (ipfb_t))
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate #define	IPV4_ADDR_LEN			4
1127c478bd9Sstevel@tonic-gate #define	IP_ADDR_LEN			IPV4_ADDR_LEN
1137c478bd9Sstevel@tonic-gate #define	IP_ARP_PROTO_TYPE		0x0800
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate #define	IPV4_VERSION			4
1167c478bd9Sstevel@tonic-gate #define	IP_VERSION			IPV4_VERSION
1177c478bd9Sstevel@tonic-gate #define	IP_SIMPLE_HDR_LENGTH_IN_WORDS	5
1187c478bd9Sstevel@tonic-gate #define	IP_SIMPLE_HDR_LENGTH		20
1197c478bd9Sstevel@tonic-gate #define	IP_MAX_HDR_LENGTH		60
1207c478bd9Sstevel@tonic-gate 
12145916cd2Sjpk #define	IP_MAX_OPT_LENGTH (IP_MAX_HDR_LENGTH-IP_SIMPLE_HDR_LENGTH)
12245916cd2Sjpk 
1237c478bd9Sstevel@tonic-gate #define	IP_MIN_MTU			(IP_MAX_HDR_LENGTH + 8)	/* 68 bytes */
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate /*
1267c478bd9Sstevel@tonic-gate  * XXX IP_MAXPACKET is defined in <netinet/ip.h> as well. At some point the
1277c478bd9Sstevel@tonic-gate  * 2 files should be cleaned up to remove all redundant definitions.
1287c478bd9Sstevel@tonic-gate  */
1297c478bd9Sstevel@tonic-gate #define	IP_MAXPACKET			65535
1307c478bd9Sstevel@tonic-gate #define	IP_SIMPLE_HDR_VERSION \
1317c478bd9Sstevel@tonic-gate 	((IP_VERSION << 4) | IP_SIMPLE_HDR_LENGTH_IN_WORDS)
1327c478bd9Sstevel@tonic-gate 
13345916cd2Sjpk #define	UDPH_SIZE			8
13445916cd2Sjpk 
1357c478bd9Sstevel@tonic-gate /*
1367c478bd9Sstevel@tonic-gate  * Constants and type definitions to support IP IOCTL commands
1377c478bd9Sstevel@tonic-gate  */
1387c478bd9Sstevel@tonic-gate #define	IP_IOCTL			(('i'<<8)|'p')
1397c478bd9Sstevel@tonic-gate #define	IP_IOC_IRE_DELETE		4
1407c478bd9Sstevel@tonic-gate #define	IP_IOC_IRE_DELETE_NO_REPLY	5
1417c478bd9Sstevel@tonic-gate #define	IP_IOC_RTS_REQUEST		7
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate /* Common definitions used by IP IOCTL data structures */
1447c478bd9Sstevel@tonic-gate typedef struct ipllcmd_s {
1457c478bd9Sstevel@tonic-gate 	uint_t	ipllc_cmd;
1467c478bd9Sstevel@tonic-gate 	uint_t	ipllc_name_offset;
1477c478bd9Sstevel@tonic-gate 	uint_t	ipllc_name_length;
1487c478bd9Sstevel@tonic-gate } ipllc_t;
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate /* IP IRE Delete Command Structure. */
1517c478bd9Sstevel@tonic-gate typedef struct ipid_s {
1527c478bd9Sstevel@tonic-gate 	ipllc_t	ipid_ipllc;
1537c478bd9Sstevel@tonic-gate 	uint_t	ipid_ire_type;
1547c478bd9Sstevel@tonic-gate 	uint_t	ipid_addr_offset;
1557c478bd9Sstevel@tonic-gate 	uint_t	ipid_addr_length;
1567c478bd9Sstevel@tonic-gate 	uint_t	ipid_mask_offset;
1577c478bd9Sstevel@tonic-gate 	uint_t	ipid_mask_length;
1587c478bd9Sstevel@tonic-gate } ipid_t;
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate #define	ipid_cmd		ipid_ipllc.ipllc_cmd
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate #ifdef _KERNEL
1637c478bd9Sstevel@tonic-gate /*
1647c478bd9Sstevel@tonic-gate  * Temporary state for ip options parser.
1657c478bd9Sstevel@tonic-gate  */
1667c478bd9Sstevel@tonic-gate typedef struct ipoptp_s
1677c478bd9Sstevel@tonic-gate {
1687c478bd9Sstevel@tonic-gate 	uint8_t		*ipoptp_next;	/* next option to look at */
1697c478bd9Sstevel@tonic-gate 	uint8_t		*ipoptp_end;	/* end of options */
1707c478bd9Sstevel@tonic-gate 	uint8_t		*ipoptp_cur;	/* start of current option */
1717c478bd9Sstevel@tonic-gate 	uint8_t		ipoptp_len;	/* length of current option */
1727c478bd9Sstevel@tonic-gate 	uint32_t	ipoptp_flags;
1737c478bd9Sstevel@tonic-gate } ipoptp_t;
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate /*
1767c478bd9Sstevel@tonic-gate  * Flag(s) for ipoptp_flags
1777c478bd9Sstevel@tonic-gate  */
1787c478bd9Sstevel@tonic-gate #define	IPOPTP_ERROR	0x00000001
1797c478bd9Sstevel@tonic-gate #endif	/* _KERNEL */
1807c478bd9Sstevel@tonic-gate 
181bbf21555SRichard Lowe /* Controls forwarding of IP packets, set via ipadm(8)/ndd(8) */
1827c478bd9Sstevel@tonic-gate #define	IP_FORWARD_NEVER	0
1837c478bd9Sstevel@tonic-gate #define	IP_FORWARD_ALWAYS	1
1847c478bd9Sstevel@tonic-gate 
1856e91bba0SGirish Moodalbail #define	WE_ARE_FORWARDING(ipst)	((ipst)->ips_ip_forwarding == IP_FORWARD_ALWAYS)
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate #define	IPH_HDR_LENGTH(ipha)						\
1887c478bd9Sstevel@tonic-gate 	((int)(((ipha_t *)ipha)->ipha_version_and_hdr_length & 0xF) << 2)
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate #define	IPH_HDR_VERSION(ipha)						\
1917c478bd9Sstevel@tonic-gate 	((int)(((ipha_t *)ipha)->ipha_version_and_hdr_length) >> 4)
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate #ifdef _KERNEL
1947c478bd9Sstevel@tonic-gate /*
1957c478bd9Sstevel@tonic-gate  * IP reassembly macros.  We hide starting and ending offsets in b_next and
1967c478bd9Sstevel@tonic-gate  * b_prev of messages on the reassembly queue.	The messages are chained using
1977c478bd9Sstevel@tonic-gate  * b_cont.  These macros are used in ip_reassemble() so we don't have to see
1987c478bd9Sstevel@tonic-gate  * the ugly casts and assignments.
1997c478bd9Sstevel@tonic-gate  * Note that the offsets are <= 64k i.e. a uint_t is sufficient to represent
2007c478bd9Sstevel@tonic-gate  * them.
2017c478bd9Sstevel@tonic-gate  */
2027c478bd9Sstevel@tonic-gate #define	IP_REASS_START(mp)		((uint_t)(uintptr_t)((mp)->b_next))
2037c478bd9Sstevel@tonic-gate #define	IP_REASS_SET_START(mp, u)	\
2047c478bd9Sstevel@tonic-gate 	((mp)->b_next = (mblk_t *)(uintptr_t)(u))
2057c478bd9Sstevel@tonic-gate #define	IP_REASS_END(mp)		((uint_t)(uintptr_t)((mp)->b_prev))
2067c478bd9Sstevel@tonic-gate #define	IP_REASS_SET_END(mp, u)		\
2077c478bd9Sstevel@tonic-gate 	((mp)->b_prev = (mblk_t *)(uintptr_t)(u))
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate #define	IP_REASS_COMPLETE	0x1
2107c478bd9Sstevel@tonic-gate #define	IP_REASS_PARTIAL	0x2
2117c478bd9Sstevel@tonic-gate #define	IP_REASS_FAILED		0x4
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate /*
2147c478bd9Sstevel@tonic-gate  * Test to determine whether this is a module instance of IP or a
2157c478bd9Sstevel@tonic-gate  * driver instance of IP.
2167c478bd9Sstevel@tonic-gate  */
2177c478bd9Sstevel@tonic-gate #define	CONN_Q(q)	(WR(q)->q_next == NULL)
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate #define	Q_TO_CONN(q)	((conn_t *)(q)->q_ptr)
2207c478bd9Sstevel@tonic-gate #define	Q_TO_TCP(q)	(Q_TO_CONN((q))->conn_tcp)
221ff550d0eSmasputra #define	Q_TO_UDP(q)	(Q_TO_CONN((q))->conn_udp)
222fc80c0dfSnordmark #define	Q_TO_ICMP(q)	(Q_TO_CONN((q))->conn_icmp)
223fc80c0dfSnordmark #define	Q_TO_RTS(q)	(Q_TO_CONN((q))->conn_rts)
2247c478bd9Sstevel@tonic-gate 
225bd670b35SErik Nordmark #define	CONNP_TO_WQ(connp)	((connp)->conn_wq)
226bd670b35SErik Nordmark #define	CONNP_TO_RQ(connp)	((connp)->conn_rq)
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate #define	GRAB_CONN_LOCK(q)	{				\
2297c478bd9Sstevel@tonic-gate 	if (q != NULL && CONN_Q(q))				\
2307c478bd9Sstevel@tonic-gate 		mutex_enter(&(Q_TO_CONN(q))->conn_lock);	\
2317c478bd9Sstevel@tonic-gate }
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate #define	RELEASE_CONN_LOCK(q)	{				\
2347c478bd9Sstevel@tonic-gate 	if (q != NULL && CONN_Q(q))				\
2357c478bd9Sstevel@tonic-gate 		mutex_exit(&(Q_TO_CONN(q))->conn_lock);		\
2367c478bd9Sstevel@tonic-gate }
2377c478bd9Sstevel@tonic-gate 
238838a4ffaSBrian Ruthven /*
239838a4ffaSBrian Ruthven  * Ref counter macros for ioctls. This provides a guard for TCP to stop
240838a4ffaSBrian Ruthven  * tcp_close from removing the rq/wq whilst an ioctl is still in flight on the
241838a4ffaSBrian Ruthven  * stream. The ioctl could have been queued on e.g. an ipsq. tcp_close will wait
242838a4ffaSBrian Ruthven  * until the ioctlref count is zero before proceeding.
243838a4ffaSBrian Ruthven  * Ideally conn_oper_pending_ill would be used for this purpose. However, in the
244838a4ffaSBrian Ruthven  * case where an ioctl is aborted or interrupted, it can be cleared prematurely.
245838a4ffaSBrian Ruthven  * There are also some race possibilities between ip and the stream head which
246838a4ffaSBrian Ruthven  * can also end up with conn_oper_pending_ill being cleared prematurely. So, to
247838a4ffaSBrian Ruthven  * avoid these situations, we use a dedicated ref counter for ioctls which is
248838a4ffaSBrian Ruthven  * used in addition to and in parallel with the normal conn_ref count.
249838a4ffaSBrian Ruthven  */
250838a4ffaSBrian Ruthven #define	CONN_INC_IOCTLREF_LOCKED(connp)	{			\
251838a4ffaSBrian Ruthven 	ASSERT(MUTEX_HELD(&(connp)->conn_lock));		\
252838a4ffaSBrian Ruthven 	DTRACE_PROBE1(conn__inc__ioctlref, conn_t *, (connp));	\
253838a4ffaSBrian Ruthven 	(connp)->conn_ioctlref++;				\
254838a4ffaSBrian Ruthven 	mutex_exit(&(connp)->conn_lock);			\
255838a4ffaSBrian Ruthven }
256838a4ffaSBrian Ruthven 
257838a4ffaSBrian Ruthven #define	CONN_INC_IOCTLREF(connp)	{			\
258838a4ffaSBrian Ruthven 	mutex_enter(&(connp)->conn_lock);			\
259838a4ffaSBrian Ruthven 	CONN_INC_IOCTLREF_LOCKED(connp);			\
260838a4ffaSBrian Ruthven }
261838a4ffaSBrian Ruthven 
262838a4ffaSBrian Ruthven #define	CONN_DEC_IOCTLREF(connp)	{			\
263838a4ffaSBrian Ruthven 	mutex_enter(&(connp)->conn_lock);			\
264838a4ffaSBrian Ruthven 	DTRACE_PROBE1(conn__dec__ioctlref, conn_t *, (connp));	\
265838a4ffaSBrian Ruthven 	/* Make sure conn_ioctlref will not underflow. */	\
266838a4ffaSBrian Ruthven 	ASSERT((connp)->conn_ioctlref != 0);			\
267838a4ffaSBrian Ruthven 	if ((--(connp)->conn_ioctlref == 0) &&			\
268838a4ffaSBrian Ruthven 	    ((connp)->conn_state_flags & CONN_CLOSING)) {	\
269838a4ffaSBrian Ruthven 		cv_broadcast(&(connp)->conn_cv);		\
270838a4ffaSBrian Ruthven 	}							\
271838a4ffaSBrian Ruthven 	mutex_exit(&(connp)->conn_lock);			\
272838a4ffaSBrian Ruthven }
273838a4ffaSBrian Ruthven 
274838a4ffaSBrian Ruthven 
2757c478bd9Sstevel@tonic-gate /*
2767c478bd9Sstevel@tonic-gate  * Complete the pending operation. Usually an ioctl. Can also
2777c478bd9Sstevel@tonic-gate  * be a bind or option management request that got enqueued
2787c478bd9Sstevel@tonic-gate  * in an ipsq_t. Called on completion of the operation.
2797c478bd9Sstevel@tonic-gate  */
2807c478bd9Sstevel@tonic-gate #define	CONN_OPER_PENDING_DONE(connp)	{			\
2817c478bd9Sstevel@tonic-gate 	mutex_enter(&(connp)->conn_lock);			\
2827c478bd9Sstevel@tonic-gate 	(connp)->conn_oper_pending_ill = NULL;			\
2837c478bd9Sstevel@tonic-gate 	cv_broadcast(&(connp)->conn_refcv);			\
2847c478bd9Sstevel@tonic-gate 	mutex_exit(&(connp)->conn_lock);			\
2857c478bd9Sstevel@tonic-gate 	CONN_DEC_REF(connp);					\
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate /*
2897c478bd9Sstevel@tonic-gate  * Values for squeue switch:
2907c478bd9Sstevel@tonic-gate  */
2917c478bd9Sstevel@tonic-gate #define	IP_SQUEUE_ENTER_NODRAIN	1
2927c478bd9Sstevel@tonic-gate #define	IP_SQUEUE_ENTER	2
293bd670b35SErik Nordmark #define	IP_SQUEUE_FILL 3
2947c478bd9Sstevel@tonic-gate 
295bd670b35SErik Nordmark extern int ip_squeue_flag;
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate /* IP Fragmentation Reassembly Header */
2987c478bd9Sstevel@tonic-gate typedef struct ipf_s {
2997c478bd9Sstevel@tonic-gate 	struct ipf_s	*ipf_hash_next;
3007c478bd9Sstevel@tonic-gate 	struct ipf_s	**ipf_ptphn;	/* Pointer to previous hash next. */
3017c478bd9Sstevel@tonic-gate 	uint32_t	ipf_ident;	/* Ident to match. */
3027c478bd9Sstevel@tonic-gate 	uint8_t		ipf_protocol;	/* Protocol to match. */
3037c478bd9Sstevel@tonic-gate 	uchar_t		ipf_last_frag_seen : 1;	/* Last fragment seen ? */
3047c478bd9Sstevel@tonic-gate 	time_t		ipf_timestamp;	/* Reassembly start time. */
3057c478bd9Sstevel@tonic-gate 	mblk_t		*ipf_mp;	/* mblk we live in. */
3067c478bd9Sstevel@tonic-gate 	mblk_t		*ipf_tail_mp;	/* Frag queue tail pointer. */
3077c478bd9Sstevel@tonic-gate 	int		ipf_hole_cnt;	/* Number of holes (hard-case). */
3087c478bd9Sstevel@tonic-gate 	int		ipf_end;	/* Tail end offset (0 -> hard-case). */
3097c478bd9Sstevel@tonic-gate 	uint_t		ipf_gen;	/* Frag queue generation */
3107c478bd9Sstevel@tonic-gate 	size_t		ipf_count;	/* Count of bytes used by frag */
3117c478bd9Sstevel@tonic-gate 	uint_t		ipf_nf_hdr_len; /* Length of nonfragmented header */
3127c478bd9Sstevel@tonic-gate 	in6_addr_t	ipf_v6src;	/* IPv6 source address */
3137c478bd9Sstevel@tonic-gate 	in6_addr_t	ipf_v6dst;	/* IPv6 dest address */
3147c478bd9Sstevel@tonic-gate 	uint_t		ipf_prev_nexthdr_offset; /* Offset for nexthdr value */
3157c478bd9Sstevel@tonic-gate 	uint8_t		ipf_ecn;	/* ECN info for the fragments */
3167c478bd9Sstevel@tonic-gate 	uint8_t		ipf_num_dups;	/* Number of times dup frags recvd */
317ff550d0eSmasputra 	uint16_t	ipf_checksum_flags; /* Hardware checksum flags */
318ff550d0eSmasputra 	uint32_t	ipf_checksum;	/* Partial checksum of fragment data */
3197c478bd9Sstevel@tonic-gate } ipf_t;
3207c478bd9Sstevel@tonic-gate 
321da14cebeSEric Cheng /*
322da14cebeSEric Cheng  * IPv4 Fragments
323da14cebeSEric Cheng  */
324da14cebeSEric Cheng #define	IS_V4_FRAGMENT(ipha_fragment_offset_and_flags)			\
325da14cebeSEric Cheng 	(((ntohs(ipha_fragment_offset_and_flags) & IPH_OFFSET) != 0) ||	\
326da14cebeSEric Cheng 	((ntohs(ipha_fragment_offset_and_flags) & IPH_MF) != 0))
327da14cebeSEric Cheng 
3287c478bd9Sstevel@tonic-gate #define	ipf_src	V4_PART_OF_V6(ipf_v6src)
3297c478bd9Sstevel@tonic-gate #define	ipf_dst	V4_PART_OF_V6(ipf_v6dst)
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate /* ICMP types */
3347c478bd9Sstevel@tonic-gate #define	ICMP_ECHO_REPLY			0
3357c478bd9Sstevel@tonic-gate #define	ICMP_DEST_UNREACHABLE		3
3367c478bd9Sstevel@tonic-gate #define	ICMP_SOURCE_QUENCH		4
3377c478bd9Sstevel@tonic-gate #define	ICMP_REDIRECT			5
3387c478bd9Sstevel@tonic-gate #define	ICMP_ECHO_REQUEST		8
3397c478bd9Sstevel@tonic-gate #define	ICMP_ROUTER_ADVERTISEMENT	9
3407c478bd9Sstevel@tonic-gate #define	ICMP_ROUTER_SOLICITATION	10
3417c478bd9Sstevel@tonic-gate #define	ICMP_TIME_EXCEEDED		11
3427c478bd9Sstevel@tonic-gate #define	ICMP_PARAM_PROBLEM		12
3437c478bd9Sstevel@tonic-gate #define	ICMP_TIME_STAMP_REQUEST		13
3447c478bd9Sstevel@tonic-gate #define	ICMP_TIME_STAMP_REPLY		14
3457c478bd9Sstevel@tonic-gate #define	ICMP_INFO_REQUEST		15
3467c478bd9Sstevel@tonic-gate #define	ICMP_INFO_REPLY			16
3477c478bd9Sstevel@tonic-gate #define	ICMP_ADDRESS_MASK_REQUEST	17
3487c478bd9Sstevel@tonic-gate #define	ICMP_ADDRESS_MASK_REPLY		18
3497c478bd9Sstevel@tonic-gate 
3502b24ab6bSSebastien Roy /* Evaluates to true if the ICMP type is an ICMP error */
3512b24ab6bSSebastien Roy #define	ICMP_IS_ERROR(type)	(		\
3522b24ab6bSSebastien Roy 	(type) == ICMP_DEST_UNREACHABLE ||	\
3532b24ab6bSSebastien Roy 	(type) == ICMP_SOURCE_QUENCH ||		\
3542b24ab6bSSebastien Roy 	(type) == ICMP_TIME_EXCEEDED ||		\
3552b24ab6bSSebastien Roy 	(type) == ICMP_PARAM_PROBLEM)
3562b24ab6bSSebastien Roy 
3577c478bd9Sstevel@tonic-gate /* ICMP_TIME_EXCEEDED codes */
3587c478bd9Sstevel@tonic-gate #define	ICMP_TTL_EXCEEDED		0
3597c478bd9Sstevel@tonic-gate #define	ICMP_REASSEMBLY_TIME_EXCEEDED	1
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate /* ICMP_DEST_UNREACHABLE codes */
3627c478bd9Sstevel@tonic-gate #define	ICMP_NET_UNREACHABLE		0
3637c478bd9Sstevel@tonic-gate #define	ICMP_HOST_UNREACHABLE		1
3647c478bd9Sstevel@tonic-gate #define	ICMP_PROTOCOL_UNREACHABLE	2
3657c478bd9Sstevel@tonic-gate #define	ICMP_PORT_UNREACHABLE		3
3667c478bd9Sstevel@tonic-gate #define	ICMP_FRAGMENTATION_NEEDED	4
3677c478bd9Sstevel@tonic-gate #define	ICMP_SOURCE_ROUTE_FAILED	5
3687c478bd9Sstevel@tonic-gate #define	ICMP_DEST_NET_UNKNOWN		6
3697c478bd9Sstevel@tonic-gate #define	ICMP_DEST_HOST_UNKNOWN		7
3707c478bd9Sstevel@tonic-gate #define	ICMP_SRC_HOST_ISOLATED		8
3717c478bd9Sstevel@tonic-gate #define	ICMP_DEST_NET_UNREACH_ADMIN	9
3727c478bd9Sstevel@tonic-gate #define	ICMP_DEST_HOST_UNREACH_ADMIN	10
3737c478bd9Sstevel@tonic-gate #define	ICMP_DEST_NET_UNREACH_TOS	11
3747c478bd9Sstevel@tonic-gate #define	ICMP_DEST_HOST_UNREACH_TOS	12
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate /* ICMP Header Structure */
3777c478bd9Sstevel@tonic-gate typedef struct icmph_s {
3787c478bd9Sstevel@tonic-gate 	uint8_t		icmph_type;
3797c478bd9Sstevel@tonic-gate 	uint8_t		icmph_code;
3807c478bd9Sstevel@tonic-gate 	uint16_t	icmph_checksum;
3817c478bd9Sstevel@tonic-gate 	union {
3827c478bd9Sstevel@tonic-gate 		struct { /* ECHO request/response structure */
3837c478bd9Sstevel@tonic-gate 			uint16_t	u_echo_ident;
3847c478bd9Sstevel@tonic-gate 			uint16_t	u_echo_seqnum;
3857c478bd9Sstevel@tonic-gate 		} u_echo;
3867c478bd9Sstevel@tonic-gate 		struct { /* Destination unreachable structure */
3877c478bd9Sstevel@tonic-gate 			uint16_t	u_du_zero;
3887c478bd9Sstevel@tonic-gate 			uint16_t	u_du_mtu;
3897c478bd9Sstevel@tonic-gate 		} u_du;
3907c478bd9Sstevel@tonic-gate 		struct { /* Parameter problem structure */
3917c478bd9Sstevel@tonic-gate 			uint8_t		u_pp_ptr;
3927c478bd9Sstevel@tonic-gate 			uint8_t		u_pp_rsvd[3];
3937c478bd9Sstevel@tonic-gate 		} u_pp;
3947c478bd9Sstevel@tonic-gate 		struct { /* Redirect structure */
3957c478bd9Sstevel@tonic-gate 			ipaddr_t	u_rd_gateway;
3967c478bd9Sstevel@tonic-gate 		} u_rd;
3977c478bd9Sstevel@tonic-gate 	} icmph_u;
3987c478bd9Sstevel@tonic-gate } icmph_t;
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate #define	icmph_echo_ident	icmph_u.u_echo.u_echo_ident
4017c478bd9Sstevel@tonic-gate #define	icmph_echo_seqnum	icmph_u.u_echo.u_echo_seqnum
4027c478bd9Sstevel@tonic-gate #define	icmph_du_zero		icmph_u.u_du.u_du_zero
4037c478bd9Sstevel@tonic-gate #define	icmph_du_mtu		icmph_u.u_du.u_du_mtu
4047c478bd9Sstevel@tonic-gate #define	icmph_pp_ptr		icmph_u.u_pp.u_pp_ptr
4057c478bd9Sstevel@tonic-gate #define	icmph_rd_gateway	icmph_u.u_rd.u_rd_gateway
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate #define	ICMPH_SIZE	8
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate /*
4107c478bd9Sstevel@tonic-gate  * Minimum length of transport layer header included in an ICMP error
4117c478bd9Sstevel@tonic-gate  * message for it to be considered valid.
4127c478bd9Sstevel@tonic-gate  */
4137c478bd9Sstevel@tonic-gate #define	ICMP_MIN_TP_HDR_LEN	8
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate /* Aligned IP header */
4167c478bd9Sstevel@tonic-gate typedef struct ipha_s {
4177c478bd9Sstevel@tonic-gate 	uint8_t		ipha_version_and_hdr_length;
4187c478bd9Sstevel@tonic-gate 	uint8_t		ipha_type_of_service;
4197c478bd9Sstevel@tonic-gate 	uint16_t	ipha_length;
4207c478bd9Sstevel@tonic-gate 	uint16_t	ipha_ident;
4217c478bd9Sstevel@tonic-gate 	uint16_t	ipha_fragment_offset_and_flags;
4227c478bd9Sstevel@tonic-gate 	uint8_t		ipha_ttl;
4237c478bd9Sstevel@tonic-gate 	uint8_t		ipha_protocol;
4247c478bd9Sstevel@tonic-gate 	uint16_t	ipha_hdr_checksum;
4257c478bd9Sstevel@tonic-gate 	ipaddr_t	ipha_src;
4267c478bd9Sstevel@tonic-gate 	ipaddr_t	ipha_dst;
4277c478bd9Sstevel@tonic-gate } ipha_t;
4287c478bd9Sstevel@tonic-gate 
42910e6dadfSbrendan /*
43010e6dadfSbrendan  * IP Flags
43110e6dadfSbrendan  *
43210e6dadfSbrendan  * Some of these constant names are copied for the DTrace IP provider in
43310e6dadfSbrendan  * usr/src/lib/libdtrace/common/{ip.d.in, ip.sed.in}, which should be kept
43410e6dadfSbrendan  * in sync.
43510e6dadfSbrendan  */
4367c478bd9Sstevel@tonic-gate #define	IPH_DF		0x4000	/* Don't fragment */
4377c478bd9Sstevel@tonic-gate #define	IPH_MF		0x2000	/* More fragments to come */
4387c478bd9Sstevel@tonic-gate #define	IPH_OFFSET	0x1FFF	/* Where the offset lives */
439bd670b35SErik Nordmark 
440bd670b35SErik Nordmark /* Byte-order specific values */
441bd670b35SErik Nordmark #ifdef	_BIG_ENDIAN
442bd670b35SErik Nordmark #define	IPH_DF_HTONS	0x4000	/* Don't fragment */
443bd670b35SErik Nordmark #define	IPH_MF_HTONS	0x2000	/* More fragments to come */
444bd670b35SErik Nordmark #define	IPH_OFFSET_HTONS 0x1FFF	/* Where the offset lives */
445bd670b35SErik Nordmark #else
446bd670b35SErik Nordmark #define	IPH_DF_HTONS	0x0040	/* Don't fragment */
447bd670b35SErik Nordmark #define	IPH_MF_HTONS	0x0020	/* More fragments to come */
448bd670b35SErik Nordmark #define	IPH_OFFSET_HTONS 0xFF1F	/* Where the offset lives */
449bd670b35SErik Nordmark #endif
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate /* ECN code points for IPv4 TOS byte and IPv6 traffic class octet. */
4527924222fSmeem #define	IPH_ECN_NECT	0x0	/* Not ECN-Capable Transport */
4537c478bd9Sstevel@tonic-gate #define	IPH_ECN_ECT1	0x1	/* ECN-Capable Transport, ECT(1) */
4547c478bd9Sstevel@tonic-gate #define	IPH_ECN_ECT0	0x2	/* ECN-Capable Transport, ECT(0) */
4557c478bd9Sstevel@tonic-gate #define	IPH_ECN_CE	0x3	/* ECN-Congestion Experienced (CE) */
4567c478bd9Sstevel@tonic-gate 
457e11c3f44Smeem struct ill_s;
458e11c3f44Smeem 
4592b24ab6bSSebastien Roy typedef	void ip_v6intfid_func_t(struct ill_s *, in6_addr_t *);
460bd670b35SErik Nordmark typedef void ip_v6mapinfo_func_t(struct ill_s *, uchar_t *, uchar_t *);
461bd670b35SErik Nordmark typedef void ip_v4mapinfo_func_t(struct ill_s *, uchar_t *, uchar_t *);
462e11c3f44Smeem 
4637c478bd9Sstevel@tonic-gate /* IP Mac info structure */
4647c478bd9Sstevel@tonic-gate typedef struct ip_m_s {
465e11c3f44Smeem 	t_uscalar_t		ip_m_mac_type;	/* From <sys/dlpi.h> */
466e11c3f44Smeem 	int			ip_m_type;	/* From <net/if_types.h> */
4672b24ab6bSSebastien Roy 	t_uscalar_t		ip_m_ipv4sap;
4682b24ab6bSSebastien Roy 	t_uscalar_t		ip_m_ipv6sap;
469bd670b35SErik Nordmark 	ip_v4mapinfo_func_t	*ip_m_v4mapping;
470bd670b35SErik Nordmark 	ip_v6mapinfo_func_t	*ip_m_v6mapping;
471e11c3f44Smeem 	ip_v6intfid_func_t	*ip_m_v6intfid;
4722b24ab6bSSebastien Roy 	ip_v6intfid_func_t	*ip_m_v6destintfid;
4737c478bd9Sstevel@tonic-gate } ip_m_t;
4747c478bd9Sstevel@tonic-gate 
4757c478bd9Sstevel@tonic-gate /*
4767c478bd9Sstevel@tonic-gate  * The following functions attempt to reduce the link layer dependency
4777c478bd9Sstevel@tonic-gate  * of the IP stack. The current set of link specific operations are:
478bd670b35SErik Nordmark  * a. map from IPv4 class D (224.0/4) multicast address range or the
479bd670b35SErik Nordmark  * IPv6 multicast address range (ff00::/8) to the link layer multicast
480