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