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  */
  25 
  26 #ifndef _INET_IP_IMPL_H
  27 #define _INET_IP_IMPL_H
  28 
  29 /*
  30  * IP implementation private declarations.  These interfaces are
  31  * used to build the IP module and are not meant to be accessed
  32  * by any modules except IP itself.  They are undocumented and are
  33  * subject to change without notice.
  34  */
  35 
  36 #ifdef  __cplusplus
  37 extern "C" {
  38 #endif
  39 
  40 #ifdef _KERNEL
  41 
  42 #include <sys/sdt.h>
  43 #include <sys/dld.h>
  44 #include <inet/tunables.h>
  45 
  46 #define IP_MOD_ID               5701
  47 
  48 #define INET_NAME       "ip"
  49 
  50 #ifdef  _BIG_ENDIAN
  51 #define IP_HDR_CSUM_TTL_ADJUST  256
  52 #define IP_TCP_CSUM_COMP        IPPROTO_TCP
  53 #define IP_UDP_CSUM_COMP        IPPROTO_UDP
  54 #define IP_ICMPV6_CSUM_COMP     IPPROTO_ICMPV6
  55 #else
  56 #define IP_HDR_CSUM_TTL_ADJUST  1
  57 #define IP_TCP_CSUM_COMP        (IPPROTO_TCP << 8)
  58 #define IP_UDP_CSUM_COMP        (IPPROTO_UDP << 8)
  59 #define IP_ICMPV6_CSUM_COMP     (IPPROTO_ICMPV6 << 8)
  60 #endif
  61 
  62 #define TCP_CHECKSUM_OFFSET     16
  63 #define TCP_CHECKSUM_SIZE       2
  64 
  65 #define UDP_CHECKSUM_OFFSET     6
  66 #define UDP_CHECKSUM_SIZE       2
  67 
  68 #define ICMPV6_CHECKSUM_OFFSET  2
  69 #define ICMPV6_CHECKSUM_SIZE    2
  70 
  71 #define IPH_TCPH_CHECKSUMP(ipha, hlen)  \
  72         ((uint16_t *)(((uchar_t *)(ipha)) + ((hlen) + TCP_CHECKSUM_OFFSET)))
  73 
  74 #define IPH_UDPH_CHECKSUMP(ipha, hlen)  \
  75         ((uint16_t *)(((uchar_t *)(ipha)) + ((hlen) + UDP_CHECKSUM_OFFSET)))
  76 
  77 #define IPH_ICMPV6_CHECKSUMP(ipha, hlen)        \
  78         ((uint16_t *)(((uchar_t *)(ipha)) + ((hlen) + ICMPV6_CHECKSUM_OFFSET)))
  79 
  80 #define ILL_HCKSUM_CAPABLE(ill)         \
  81         (((ill)->ill_capabilities & ILL_CAPAB_HCKSUM) != 0)
  82 
  83 /*
  84  * Macro to adjust a given checksum value depending on any prepended
  85  * or postpended data on the packet.  It expects the start offset to
  86  * begin at an even boundary and that the packet consists of at most
  87  * two mblks.
  88  */
  89 #define IP_ADJCKSUM_PARTIAL(cksum_start, mp, mp1, len, adj) {           \
  90         /*                                                              \
  91          * Prepended extraneous data; adjust checksum.                  \
  92          */                                                             \
  93         if ((len) > 0)                                                       \
  94                 (adj) = IP_BCSUM_PARTIAL(cksum_start, len, 0);          \
  95         else                                                            \
  96                 (adj) = 0;                                              \
  97         /*                                                              \
  98          * len is now the total length of mblk(s)                       \
  99          */                                                             \
 100         (len) = MBLKL(mp);                                              \
 101         if ((mp1) == NULL)                                              \
 102                 (mp1) = (mp);                                           \
 103         else                                                            \
 104                 (len) += MBLKL(mp1);                                    \
 105         /*                                                              \
 106          * Postpended extraneous data; adjust checksum.                 \
 107          */                                                             \
 108         if (((len) = (DB_CKSUMEND(mp) - len)) > 0) {                 \
 109                 uint32_t _pad;                                          \
 110                                                                         \
 111                 _pad = IP_BCSUM_PARTIAL((mp1)->b_wptr, len, 0);              \
 112                 /*                                                      \
 113                  * If the postpended extraneous data was odd            \
 114                  * byte aligned, swap resulting checksum bytes.         \
 115                  */                                                     \
 116                 if ((uintptr_t)(mp1)->b_wptr & 1)                        \
 117                         (adj) += ((_pad << 8) & 0xFFFF) | (_pad >> 8);  \
 118                 else                                                    \
 119                         (adj) += _pad;                                  \
 120                 (adj) = ((adj) & 0xFFFF) + ((int)(adj) >> 16);                \
 121         }                                                               \
 122 }
 123 
 124 #define IS_SIMPLE_IPH(ipha)                                             \
 125         ((ipha)->ipha_version_and_hdr_length == IP_SIMPLE_HDR_VERSION)
 126 
 127 /*
 128  * Currently supported flags for LSO.
 129  */
 130 #define LSO_BASIC_TCP_IPV4      DLD_LSO_BASIC_TCP_IPV4
 131 #define LSO_BASIC_TCP_IPV6      DLD_LSO_BASIC_TCP_IPV6
 132 
 133 #define ILL_LSO_CAPABLE(ill)                                            \
 134         (((ill)->ill_capabilities & ILL_CAPAB_LSO) != 0)
 135 
 136 #define ILL_LSO_USABLE(ill)                                             \
 137         (ILL_LSO_CAPABLE(ill) &&                                        \
 138         ill->ill_lso_capab != NULL)
 139 
 140 #define ILL_LSO_TCP_IPV4_USABLE(ill)                                    \
 141         (ILL_LSO_USABLE(ill) &&                                         \
 142         ill->ill_lso_capab->ill_lso_flags & LSO_BASIC_TCP_IPV4)
 143 
 144 #define ILL_LSO_TCP_IPV6_USABLE(ill)                                    \
 145         (ILL_LSO_USABLE(ill) &&                                         \
 146         ill->ill_lso_capab->ill_lso_flags & LSO_BASIC_TCP_IPV6)
 147 
 148 #define ILL_ZCOPY_CAPABLE(ill)                                          \
 149         (((ill)->ill_capabilities & ILL_CAPAB_ZEROCOPY) != 0)
 150 
 151 #define ILL_ZCOPY_USABLE(ill)                                           \
 152         (ILL_ZCOPY_CAPABLE(ill) && (ill->ill_zerocopy_capab != NULL) &&      \
 153         (ill->ill_zerocopy_capab->ill_zerocopy_flags != 0))
 154 
 155 
 156 /* Macro that follows definitions of flags for mac_tx() (see mac_client.h) */
 157 #define IP_DROP_ON_NO_DESC      0x01    /* Equivalent to MAC_DROP_ON_NO_DESC */
 158 
 159 #define ILL_DIRECT_CAPABLE(ill)                                         \
 160         (((ill)->ill_capabilities & ILL_CAPAB_DLD_DIRECT) != 0)
 161 
 162 /* This macro is used by the mac layer */
 163 #define MBLK_RX_FANOUT_SLOWPATH(mp, ipha)                               \
 164         (DB_TYPE(mp) != M_DATA || DB_REF(mp) != 1 || !OK_32PTR(ipha) || \
 165         (((uchar_t *)ipha + IP_SIMPLE_HDR_LENGTH) >= (mp)->b_wptr))
 166 
 167 /*
 168  * In non-global zone exclusive IP stacks, data structures such as IRE
 169  * entries pretend that they're in the global zone.  The following
 170  * macro evaluates to the real zoneid instead of a pretend
 171  * GLOBAL_ZONEID.
 172  */
 173 #define IP_REAL_ZONEID(zoneid, ipst)                                    \
 174         (((zoneid) == GLOBAL_ZONEID) ?                                  \
 175             netstackid_to_zoneid((ipst)->ips_netstack->netstack_stackid) : \
 176             (zoneid))
 177 
 178 extern void ill_flow_enable(void *, ip_mac_tx_cookie_t);
 179 extern zoneid_t ip_get_zoneid_v4(ipaddr_t, mblk_t *, ip_recv_attr_t *,
 180     zoneid_t);
 181 extern zoneid_t ip_get_zoneid_v6(in6_addr_t *, mblk_t *, const ill_t *,
 182     ip_recv_attr_t *, zoneid_t);
 183 extern void conn_ire_revalidate(conn_t *, void *);
 184 extern void ip_ire_unbind_walker(ire_t *, void *);
 185 extern void ip_ire_rebind_walker(ire_t *, void *);
 186 
 187 /*
 188  * flag passed in by IP based protocols to get a private ip stream with
 189  * no conn_t. Note this flag has the same value as SO_FALLBACK
 190  */
 191 #define IP_HELPER_STR   SO_FALLBACK
 192 
 193 #define IP_MOD_MINPSZ   1
 194 #define IP_MOD_MAXPSZ   INFPSZ
 195 #define IP_MOD_HIWAT    65536
 196 #define IP_MOD_LOWAT    1024
 197 
 198 #define DEV_IP  "/devices/pseudo/ip@0:ip"
 199 #define DEV_IP6 "/devices/pseudo/ip6@0:ip6"
 200 
 201 #endif  /* _KERNEL */
 202 
 203 #ifdef  __cplusplus
 204 }
 205 #endif
 206 
 207 #endif  /* _INET_IP_IMPL_H */