summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/inet/ip_impl.h
blob: 87086b4c1703b8e6fde630a5ce47cde38f74d192 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 * Copyright 2019 Joyent, Inc.
 */

#ifndef	_INET_IP_IMPL_H
#define	_INET_IP_IMPL_H

/*
 * IP implementation private declarations.  These interfaces are
 * used to build the IP module and are not meant to be accessed
 * by any modules except IP itself.  They are undocumented and are
 * subject to change without notice.
 */

#ifdef	__cplusplus
extern "C" {
#endif

#ifdef _KERNEL

#include <sys/sdt.h>
#include <sys/dld.h>
#include <inet/tunables.h>

#define	IP_MOD_ID		5701

#define	INET_NAME	"ip"

#ifdef	_BIG_ENDIAN
#define	IP_HDR_CSUM_TTL_ADJUST	256
#define	IP_TCP_CSUM_COMP	IPPROTO_TCP
#define	IP_UDP_CSUM_COMP	IPPROTO_UDP
#define	IP_ICMPV6_CSUM_COMP	IPPROTO_ICMPV6
#else
#define	IP_HDR_CSUM_TTL_ADJUST	1
#define	IP_TCP_CSUM_COMP	(IPPROTO_TCP << 8)
#define	IP_UDP_CSUM_COMP	(IPPROTO_UDP << 8)
#define	IP_ICMPV6_CSUM_COMP	(IPPROTO_ICMPV6 << 8)
#endif

#define	TCP_CHECKSUM_OFFSET	16
#define	TCP_CHECKSUM_SIZE	2

#define	UDP_CHECKSUM_OFFSET	6
#define	UDP_CHECKSUM_SIZE	2

#define	ICMPV6_CHECKSUM_OFFSET	2
#define	ICMPV6_CHECKSUM_SIZE	2

#define	IPH_TCPH_CHECKSUMP(ipha, hlen)	\
	((uint16_t *)(((uchar_t *)(ipha)) + ((hlen) + TCP_CHECKSUM_OFFSET)))

#define	IPH_UDPH_CHECKSUMP(ipha, hlen)	\
	((uint16_t *)(((uchar_t *)(ipha)) + ((hlen) + UDP_CHECKSUM_OFFSET)))

#define	IPH_ICMPV6_CHECKSUMP(ipha, hlen)	\
	((uint16_t *)(((uchar_t *)(ipha)) + ((hlen) + ICMPV6_CHECKSUM_OFFSET)))

#define	ILL_HCKSUM_CAPABLE(ill)		\
	(((ill)->ill_capabilities & ILL_CAPAB_HCKSUM) != 0)

/*
 * Macro to adjust a given checksum value depending on any prepended
 * or postpended data on the packet.  It expects the start offset to
 * begin at an even boundary and that the packet consists of at most
 * two mblks.
 */
#define	IP_ADJCKSUM_PARTIAL(cksum_start, mp, mp1, len, adj) {		\
	/*								\
	 * Prepended extraneous data; adjust checksum.			\
	 */								\
	if ((len) > 0)							\
		(adj) = IP_BCSUM_PARTIAL(cksum_start, len, 0);		\
	else								\
		(adj) = 0;						\
	/*								\
	 * len is now the total length of mblk(s)			\
	 */								\
	(len) = MBLKL(mp);						\
	if ((mp1) == NULL)						\
		(mp1) = (mp);						\
	else								\
		(len) += MBLKL(mp1);					\
	/*								\
	 * Postpended extraneous data; adjust checksum.			\
	 */								\
	if (((len) = (DB_CKSUMEND(mp) - len)) > 0) {			\
		uint32_t _pad;						\
									\
		_pad = IP_BCSUM_PARTIAL((mp1)->b_wptr, len, 0);		\
		/*							\
		 * If the postpended extraneous data was odd		\
		 * byte aligned, swap resulting checksum bytes.		\
		 */							\
		if ((uintptr_t)(mp1)->b_wptr & 1)			\
			(adj) += ((_pad << 8) & 0xFFFF) | (_pad >> 8);	\
		else							\
			(adj) += _pad;					\
		(adj) = ((adj) & 0xFFFF) + ((int)(adj) >> 16);		\
	}								\
}

#define	IS_SIMPLE_IPH(ipha)						\
	((ipha)->ipha_version_and_hdr_length == IP_SIMPLE_HDR_VERSION)

/*
 * Currently supported flags for LSO.
 */
#define	LSO_BASIC_TCP_IPV4	DLD_LSO_BASIC_TCP_IPV4
#define	LSO_BASIC_TCP_IPV6	DLD_LSO_BASIC_TCP_IPV6

#define	ILL_LSO_CAPABLE(ill)						\
	(((ill)->ill_capabilities & ILL_CAPAB_LSO) != 0)

#define	ILL_LSO_USABLE(ill)						\
	(ILL_LSO_CAPABLE(ill) &&					\
	ill->ill_lso_capab != NULL)

#define	ILL_LSO_TCP_IPV4_USABLE(ill)					\
	(ILL_LSO_USABLE(ill) &&						\
	ill->ill_lso_capab->ill_lso_flags & LSO_BASIC_TCP_IPV4)

#define	ILL_LSO_TCP_IPV6_USABLE(ill)					\
	(ILL_LSO_USABLE(ill) &&						\
	ill->ill_lso_capab->ill_lso_flags & LSO_BASIC_TCP_IPV6)

#define	ILL_ZCOPY_CAPABLE(ill)						\
	(((ill)->ill_capabilities & ILL_CAPAB_ZEROCOPY) != 0)

#define	ILL_ZCOPY_USABLE(ill)						\
	(ILL_ZCOPY_CAPABLE(ill) && (ill->ill_zerocopy_capab != NULL) &&	\
	(ill->ill_zerocopy_capab->ill_zerocopy_flags != 0))


/* Macro that follows definitions of flags for mac_tx() (see mac_client.h) */
#define	IP_DROP_ON_NO_DESC	0x01	/* Equivalent to MAC_DROP_ON_NO_DESC */

#define	ILL_DIRECT_CAPABLE(ill)						\
	(((ill)->ill_capabilities & ILL_CAPAB_DLD_DIRECT) != 0)

/*
 * Determine if a mblk needs to take the "slow path", aka OTH
 * softring. There are multiple reasons why a mblk might take the slow
 * path.
 *
 * o The mblk is not a data message.
 *
 * o There is more than one outstanding reference to the mblk.
 *
 * o The IP header is not aligned (we assume alignment in the checksum
 *   routine).
 *
 * o The mblk doesn't contain enough data to populate a simple IP header.
 */
#define	MBLK_RX_FANOUT_SLOWPATH(mp, ipha)				\
	(DB_TYPE(mp) != M_DATA ||					\
	(DB_REF(mp) != 1) ||						\
	!OK_32PTR(ipha) ||						\
	(((uchar_t *)ipha + IP_SIMPLE_HDR_LENGTH) >= (mp)->b_wptr))

/*
 * In non-global zone exclusive IP stacks, data structures such as IRE
 * entries pretend that they're in the global zone.  The following
 * macro evaluates to the real zoneid instead of a pretend
 * GLOBAL_ZONEID.
 */
#define	IP_REAL_ZONEID(zoneid, ipst)					\
	(((zoneid) == GLOBAL_ZONEID) ?					\
	    netstackid_to_zoneid((ipst)->ips_netstack->netstack_stackid) : \
	    (zoneid))

extern void ill_flow_enable(void *, ip_mac_tx_cookie_t);
extern zoneid_t	ip_get_zoneid_v4(ipaddr_t, mblk_t *, ip_recv_attr_t *,
    zoneid_t);
extern zoneid_t	ip_get_zoneid_v6(in6_addr_t *, mblk_t *, const ill_t *,
    ip_recv_attr_t *, zoneid_t);
extern void conn_ire_revalidate(conn_t *, void *);
extern void ip_ire_unbind_walker(ire_t *, void *);
extern void ip_ire_rebind_walker(ire_t *, void *);

/*
 * flag passed in by IP based protocols to get a private ip stream with
 * no conn_t. Note this flag has the same value as SO_FALLBACK
 */
#define	IP_HELPER_STR	SO_FALLBACK

#define	IP_MOD_MINPSZ	1
#define	IP_MOD_MAXPSZ	INFPSZ
#define	IP_MOD_HIWAT	65536
#define	IP_MOD_LOWAT	1024

#define	DEV_IP	"/devices/pseudo/ip@0:ip"
#define	DEV_IP6	"/devices/pseudo/ip6@0:ip6"

#endif	/* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif	/* _INET_IP_IMPL_H */