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