xref: /illumos-gate/usr/src/uts/common/inet/ip_impl.h (revision 1f8b8a0145321ca42ee324565958ceb82a14ee7a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  * Copyright 2019 Joyent, Inc.
25  * Copyright 2025 Oxide Computer Company
26  */
27 
28 #ifndef	_INET_IP_IMPL_H
29 #define	_INET_IP_IMPL_H
30 
31 /*
32  * IP implementation private declarations.  These interfaces are
33  * used to build the IP module and are not meant to be accessed
34  * by any modules except IP itself.  They are undocumented and are
35  * subject to change without notice.
36  */
37 
38 #ifdef	__cplusplus
39 extern "C" {
40 #endif
41 
42 #ifdef _KERNEL
43 
44 #include <sys/sdt.h>
45 #include <sys/dld.h>
46 #include <inet/tunables.h>
47 
48 #define	IP_MOD_ID		5701
49 
50 #define	INET_NAME	"ip"
51 
52 #ifdef	_BIG_ENDIAN
53 #define	IP_HDR_CSUM_TTL_ADJUST	256
54 #define	IP_TCP_CSUM_COMP	IPPROTO_TCP
55 #define	IP_UDP_CSUM_COMP	IPPROTO_UDP
56 #define	IP_ICMP_CSUM_COMP	IPPROTO_ICMP
57 #define	IP_ICMPV6_CSUM_COMP	IPPROTO_ICMPV6
58 #else
59 #define	IP_HDR_CSUM_TTL_ADJUST	1
60 #define	IP_TCP_CSUM_COMP	(IPPROTO_TCP << 8)
61 #define	IP_UDP_CSUM_COMP	(IPPROTO_UDP << 8)
62 #define	IP_ICMP_CSUM_COMP	(IPPROTO_ICMP << 8)
63 #define	IP_ICMPV6_CSUM_COMP	(IPPROTO_ICMPV6 << 8)
64 #endif
65 
66 #define	TCP_CHECKSUM_OFFSET	16
67 #define	TCP_CHECKSUM_SIZE	2
68 
69 #define	UDP_CHECKSUM_OFFSET	6
70 #define	UDP_CHECKSUM_SIZE	2
71 
72 #define	ICMP_CHECKSUM_OFFSET	2
73 #define	ICMP_CHECKSUM_SIZE	2
74 
75 #define	ICMPV6_CHECKSUM_OFFSET	2
76 #define	ICMPV6_CHECKSUM_SIZE	2
77 
78 #define	SCTP_CHECKSUM_OFFSET	8
79 #define	SCTP_CHECKSUM_SIZE	4
80 
81 #define	IPH_TCPH_CHECKSUMP(ipha, hlen)	\
82 	((uint16_t *)(((uchar_t *)(ipha)) + ((hlen) + TCP_CHECKSUM_OFFSET)))
83 
84 #define	IPH_UDPH_CHECKSUMP(ipha, hlen)	\
85 	((uint16_t *)(((uchar_t *)(ipha)) + ((hlen) + UDP_CHECKSUM_OFFSET)))
86 
87 #define	IPH_ICMPV6_CHECKSUMP(ipha, hlen)	\
88 	((uint16_t *)(((uchar_t *)(ipha)) + ((hlen) + ICMPV6_CHECKSUM_OFFSET)))
89 
90 #define	ILL_HCKSUM_CAPABLE(ill)		\
91 	(((ill)->ill_capabilities & ILL_CAPAB_HCKSUM) != 0)
92 
93 /*
94  * Macro to adjust a given checksum value depending on any prepended
95  * or postpended data on the packet.  It expects the start offset to
96  * begin at an even boundary and that the packet consists of at most
97  * two mblks.
98  */
99 #define	IP_ADJCKSUM_PARTIAL(cksum_start, mp, mp1, len, adj) {		\
100 	/*								\
101 	 * Prepended extraneous data; adjust checksum.			\
102 	 */								\
103 	if ((len) > 0)							\
104 		(adj) = IP_BCSUM_PARTIAL(cksum_start, len, 0);		\
105 	else								\
106 		(adj) = 0;						\
107 	/*								\
108 	 * len is now the total length of mblk(s)			\
109 	 */								\
110 	(len) = MBLKL(mp);						\
111 	if ((mp1) == NULL)						\
112 		(mp1) = (mp);						\
113 	else								\
114 		(len) += MBLKL(mp1);					\
115 	/*								\
116 	 * Postpended extraneous data; adjust checksum.			\
117 	 */								\
118 	if (((len) = (DB_CKSUMEND(mp) - len)) > 0) {			\
119 		uint32_t _pad;						\
120 									\
121 		_pad = IP_BCSUM_PARTIAL((mp1)->b_wptr, len, 0);		\
122 		/*							\
123 		 * If the postpended extraneous data was odd		\
124 		 * byte aligned, swap resulting checksum bytes.		\
125 		 */							\
126 		if ((uintptr_t)(mp1)->b_wptr & 1)			\
127 			(adj) += ((_pad << 8) & 0xFFFF) | (_pad >> 8);	\
128 		else							\
129 			(adj) += _pad;					\
130 		(adj) = ((adj) & 0xFFFF) + ((int)(adj) >> 16);		\
131 	}								\
132 }
133 
134 #define	IS_SIMPLE_IPH(ipha)						\
135 	((ipha)->ipha_version_and_hdr_length == IP_SIMPLE_HDR_VERSION)
136 
137 /*
138  * Currently supported flags for LSO.
139  */
140 #define	LSO_BASIC_TCP_IPV4	DLD_LSO_BASIC_TCP_IPV4
141 #define	LSO_BASIC_TCP_IPV6	DLD_LSO_BASIC_TCP_IPV6
142 
143 #define	ILL_LSO_CAPABLE(ill)						\
144 	(((ill)->ill_capabilities & ILL_CAPAB_LSO) != 0)
145 
146 #define	ILL_LSO_USABLE(ill)						\
147 	(ILL_LSO_CAPABLE(ill) &&					\
148 	ill->ill_lso_capab != NULL)
149 
150 #define	ILL_LSO_TCP_IPV4_USABLE(ill)					\
151 	(ILL_LSO_USABLE(ill) &&						\
152 	ill->ill_lso_capab->ill_lso_flags & LSO_BASIC_TCP_IPV4)
153 
154 #define	ILL_LSO_TCP_IPV6_USABLE(ill)					\
155 	(ILL_LSO_USABLE(ill) &&						\
156 	ill->ill_lso_capab->ill_lso_flags & LSO_BASIC_TCP_IPV6)
157 
158 #define	ILL_ZCOPY_CAPABLE(ill)						\
159 	(((ill)->ill_capabilities & ILL_CAPAB_ZEROCOPY) != 0)
160 
161 #define	ILL_ZCOPY_USABLE(ill)						\
162 	(ILL_ZCOPY_CAPABLE(ill) && (ill->ill_zerocopy_capab != NULL) &&	\
163 	(ill->ill_zerocopy_capab->ill_zerocopy_flags != 0))
164 
165 
166 /* Macro that follows definitions of flags for mac_tx() (see mac_client.h) */
167 #define	IP_DROP_ON_NO_DESC	0x01	/* Equivalent to MAC_DROP_ON_NO_DESC */
168 
169 #define	ILL_DIRECT_CAPABLE(ill)						\
170 	(((ill)->ill_capabilities & ILL_CAPAB_DLD_DIRECT) != 0)
171 
172 /*
173  * Determine if a mblk needs to take the "slow path", aka OTH
174  * softring. There are multiple reasons why a mblk might take the slow
175  * path.
176  *
177  * o The mblk is not a data message.
178  *
179  * o There is more than one outstanding reference to the mblk.
180  *
181  * o The IP header is not aligned (we assume alignment in the checksum
182  *   routine).
183  *
184  * o The mblk doesn't contain enough data to populate a simple IP header.
185  */
186 #define	MBLK_RX_FANOUT_SLOWPATH(mp, ipha)				\
187 	(DB_TYPE(mp) != M_DATA ||					\
188 	(DB_REF(mp) != 1) ||						\
189 	!OK_32PTR(ipha) ||						\
190 	(((uchar_t *)ipha + IP_SIMPLE_HDR_LENGTH) >= (mp)->b_wptr))
191 
192 /*
193  * In non-global zone exclusive IP stacks, data structures such as IRE
194  * entries pretend that they're in the global zone.  The following
195  * macro evaluates to the real zoneid instead of a pretend
196  * GLOBAL_ZONEID.
197  */
198 #define	IP_REAL_ZONEID(zoneid, ipst)					\
199 	(((zoneid) == GLOBAL_ZONEID) ?					\
200 	    netstackid_to_zoneid((ipst)->ips_netstack->netstack_stackid) : \
201 	    (zoneid))
202 
203 extern void ill_flow_enable(void *, ip_mac_tx_cookie_t);
204 extern zoneid_t	ip_get_zoneid_v4(ipaddr_t, mblk_t *, ip_recv_attr_t *,
205     zoneid_t);
206 extern zoneid_t	ip_get_zoneid_v6(in6_addr_t *, mblk_t *, const ill_t *,
207     ip_recv_attr_t *, zoneid_t);
208 extern void conn_ire_revalidate(conn_t *, void *);
209 extern void ip_ire_unbind_walker(ire_t *, void *);
210 extern void ip_ire_rebind_walker(ire_t *, void *);
211 
212 /*
213  * flag passed in by IP based protocols to get a private ip stream with
214  * no conn_t. Note this flag has the same value as SO_FALLBACK
215  */
216 #define	IP_HELPER_STR	SO_FALLBACK
217 
218 #define	IP_MOD_MINPSZ	1
219 #define	IP_MOD_MAXPSZ	INFPSZ
220 #define	IP_MOD_HIWAT	65536
221 #define	IP_MOD_LOWAT	1024
222 
223 #define	DEV_IP	"/devices/pseudo/ip@0:ip"
224 #define	DEV_IP6	"/devices/pseudo/ip6@0:ip6"
225 
226 #endif	/* _KERNEL */
227 
228 #ifdef	__cplusplus
229 }
230 #endif
231 
232 #endif	/* _INET_IP_IMPL_H */
233