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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _UDP_IMPL_H 27 #define _UDP_IMPL_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 /* 32 * UDP 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/int_types.h> 45 46 #include <netinet/in.h> 47 #include <netinet/ip6.h> 48 49 #include <inet/common.h> 50 #include <inet/ip.h> 51 52 #define UDP_MOD_ID 5607 53 54 /* udp_mode. UDP_MT_HOT and UDP_SQUEUE are stable modes. Rest are transient */ 55 typedef enum { 56 UDP_MT_HOT = 0, /* UDP endpoint is MT HOT */ 57 UDP_MT_QUEUED = 1, /* Messages enqueued in udp_mphead */ 58 UDP_QUEUED_SQUEUE = 2, /* Messages enqueued in conn_sqp */ 59 UDP_SQUEUE = 3 /* Single threaded using squeues */ 60 } udp_mode_t; 61 62 /* Internal udp control structure, one per open stream */ 63 typedef struct udp_s { 64 uint32_t udp_state; /* TPI state */ 65 in_port_t udp_port; /* Port bound to this stream */ 66 in_port_t udp_dstport; /* Connected port */ 67 in6_addr_t udp_v6src; /* Source address of this stream */ 68 in6_addr_t udp_bound_v6src; /* Explicitly bound address */ 69 in6_addr_t udp_v6dst; /* Connected destination */ 70 uint32_t udp_flowinfo; /* Connected flow id and tclass */ 71 uint32_t udp_max_hdr_len; /* For write offset in stream head */ 72 sa_family_t udp_family; /* Family from socket() call */ 73 /* 74 * IP format that packets transmitted from this struct should use. 75 * Value can be IP4_VERSION or IPV6_VERSION. 76 */ 77 ushort_t udp_ipversion; 78 uint32_t udp_ip_snd_options_len; /* Len of IPv4 options */ 79 uchar_t *udp_ip_snd_options; /* Ptr to IPv4 options */ 80 uint32_t udp_ip_rcv_options_len; /* Len of IPv4 options recvd */ 81 uchar_t *udp_ip_rcv_options; /* Ptr to IPv4 options recvd */ 82 uchar_t udp_multicast_ttl; /* IP*_MULTICAST_TTL/HOPS */ 83 ipaddr_t udp_multicast_if_addr; /* IP_MULTICAST_IF option */ 84 uint_t udp_multicast_if_index; /* IPV6_MULTICAST_IF option */ 85 int udp_bound_if; /* IP*_BOUND_IF option */ 86 int udp_xmit_if; /* IP_XMIT_IF option */ 87 conn_t *udp_connp; 88 uint32_t 89 udp_debug : 1, /* SO_DEBUG "socket" option. */ 90 udp_dontroute : 1, /* SO_DONTROUTE "socket" option. */ 91 udp_broadcast : 1, /* SO_BROADCAST "socket" option. */ 92 udp_useloopback : 1, /* SO_USELOOPBACK "socket" option */ 93 94 udp_reuseaddr : 1, /* SO_REUSEADDR "socket" option. */ 95 udp_dgram_errind : 1, /* SO_DGRAM_ERRIND option */ 96 udp_recvdstaddr : 1, /* IP_RECVDSTADDR option */ 97 udp_recvopts : 1, /* IP_RECVOPTS option */ 98 99 udp_discon_pending : 1, /* T_DISCON_REQ in progress */ 100 udp_unspec_source : 1, /* IP*_UNSPEC_SRC option */ 101 udp_ipv6_recvpktinfo : 1, /* IPV6_RECVPKTINFO option */ 102 udp_ipv6_recvhoplimit : 1, /* IPV6_RECVHOPLIMIT option */ 103 104 udp_ipv6_recvhopopts : 1, /* IPV6_RECVHOPOPTS option */ 105 udp_ipv6_recvdstopts : 1, /* IPV6_RECVDSTOPTS option */ 106 udp_ipv6_recvrthdr : 1, /* IPV6_RECVRTHDR option */ 107 udp_ipv6_recvtclass : 1, /* IPV6_RECVTCLASS */ 108 109 udp_ipv6_recvpathmtu : 1, /* IPV6_RECVPATHMTU */ 110 udp_anon_priv_bind : 1, 111 udp_exclbind : 1, /* ``exclusive'' binding */ 112 udp_recvif : 1, /* IP_RECVIF option */ 113 114 udp_recvslla : 1, /* IP_RECVSLLA option */ 115 udp_recvttl : 1, /* IP_RECVTTL option */ 116 udp_recvucred : 1, /* IP_RECVUCRED option */ 117 udp_old_ipv6_recvdstopts : 1, /* old form of IPV6_DSTOPTS */ 118 119 udp_ipv6_recvrthdrdstopts : 1, /* IPV6_RECVRTHDRDSTOPTS */ 120 udp_rcvhdr : 1, /* UDP_RCVHDR option */ 121 udp_issocket : 1, /* socket mode */ 122 udp_direct_sockfs : 1, /* direct calls to/from sockfs */ 123 124 udp_timestamp : 1, /* SO_TIMESTAMP "socket" option */ 125 udp_pad_to_bit_31 : 3; 126 127 uint8_t udp_type_of_service; /* IP_TOS option */ 128 uint8_t udp_ttl; /* TTL or hoplimit */ 129 130 ip6_pkt_t udp_sticky_ipp; /* Sticky options */ 131 uint8_t *udp_sticky_hdrs; /* Prebuilt IPv6 hdrs */ 132 uint_t udp_sticky_hdrs_len; /* Incl. ip6h and any ip6i */ 133 struct udp_s *udp_bind_hash; /* Bind hash chain */ 134 struct udp_s **udp_ptpbhn; /* Pointer to previous bind hash next. */ 135 udp_mode_t udp_mode; /* Current mode of operation */ 136 mblk_t *udp_mphead; /* Head of the queued operations */ 137 mblk_t *udp_mptail; /* Tail of the queued operations */ 138 uint_t udp_mpcount; /* Number of messages in the queue */ 139 uint_t udp_reader_count; /* Number of reader threads */ 140 uint_t udp_squeue_count; /* Number of messages in conn_sqp */ 141 142 kmutex_t udp_drain_lock; /* lock for udp_rcv_list */ 143 boolean_t udp_drain_qfull; /* drain queue is full */ 144 mblk_t *udp_rcv_list_head; /* b_next chain of mblks */ 145 mblk_t *udp_rcv_list_tail; /* last mblk in chain */ 146 uint_t udp_rcv_cnt; /* total data in rcv_list */ 147 uint_t udp_rcv_msgcnt; /* total messages in rcv_list */ 148 size_t udp_rcv_hiwat; /* receive high watermark */ 149 } udp_t; 150 151 /* UDP Protocol header */ 152 /* UDP Protocol header aligned */ 153 typedef struct udpahdr_s { 154 in_port_t uha_src_port; /* Source port */ 155 in_port_t uha_dst_port; /* Destination port */ 156 uint16_t uha_length; /* UDP length */ 157 uint16_t uha_checksum; /* UDP checksum */ 158 } udpha_t; 159 #define UDPH_SIZE 8 160 161 /* Named Dispatch Parameter Management Structure */ 162 typedef struct udpparam_s { 163 uint32_t udp_param_min; 164 uint32_t udp_param_max; 165 uint32_t udp_param_value; 166 char *udp_param_name; 167 } udpparam_t; 168 169 extern udpparam_t udp_param_arr[]; 170 171 #define udp_wroff_extra udp_param_arr[0].udp_param_value 172 #define udp_ipv4_ttl udp_param_arr[1].udp_param_value 173 #define udp_ipv6_hoplimit udp_param_arr[2].udp_param_value 174 #define udp_smallest_nonpriv_port udp_param_arr[3].udp_param_value 175 #define udp_do_checksum udp_param_arr[4].udp_param_value 176 #define udp_smallest_anon_port udp_param_arr[5].udp_param_value 177 #define udp_largest_anon_port udp_param_arr[6].udp_param_value 178 #define udp_xmit_hiwat udp_param_arr[7].udp_param_value 179 #define udp_xmit_lowat udp_param_arr[8].udp_param_value 180 #define udp_recv_hiwat udp_param_arr[9].udp_param_value 181 #define udp_max_buf udp_param_arr[10].udp_param_value 182 #define udp_ndd_get_info_interval udp_param_arr[11].udp_param_value 183 184 /* Kstats */ 185 typedef struct { /* Class "net" kstats */ 186 kstat_named_t udp_ip_send; 187 kstat_named_t udp_ip_ire_send; 188 kstat_named_t udp_ire_null; 189 kstat_named_t udp_drain; 190 kstat_named_t udp_sock_fallback; 191 kstat_named_t udp_rrw_busy; 192 kstat_named_t udp_rrw_msgcnt; 193 kstat_named_t udp_out_sw_cksum; 194 kstat_named_t udp_out_sw_cksum_bytes; 195 kstat_named_t udp_out_opt; 196 kstat_named_t udp_out_err_notconn; 197 kstat_named_t udp_out_err_output; 198 kstat_named_t udp_out_err_tudr; 199 kstat_named_t udp_in_pktinfo; 200 kstat_named_t udp_in_recvdstaddr; 201 kstat_named_t udp_in_recvopts; 202 kstat_named_t udp_in_recvif; 203 kstat_named_t udp_in_recvslla; 204 kstat_named_t udp_in_recvucred; 205 kstat_named_t udp_in_recvttl; 206 kstat_named_t udp_in_recvhopopts; 207 kstat_named_t udp_in_recvhoplimit; 208 kstat_named_t udp_in_recvdstopts; 209 kstat_named_t udp_in_recvrtdstopts; 210 kstat_named_t udp_in_recvrthdr; 211 kstat_named_t udp_in_recvpktinfo; 212 kstat_named_t udp_in_recvtclass; 213 kstat_named_t udp_in_timestamp; 214 #ifdef DEBUG 215 kstat_named_t udp_data_conn; 216 kstat_named_t udp_data_notconn; 217 #endif 218 } udp_stat_t; 219 220 extern udp_stat_t udp_statistics; 221 222 #define UDP_STAT(x) (udp_statistics.x.value.ui64++) 223 #define UDP_STAT_UPDATE(x, n) (udp_statistics.x.value.ui64 += (n)) 224 #ifdef DEBUG 225 #define UDP_DBGSTAT(x) UDP_STAT(x) 226 #else 227 #define UDP_DBGSTAT(x) 228 #endif /* DEBUG */ 229 230 extern major_t UDP6_MAJ; 231 232 extern int udp_opt_default(queue_t *, t_scalar_t, t_scalar_t, uchar_t *); 233 extern int udp_opt_get(queue_t *, t_scalar_t, t_scalar_t, uchar_t *); 234 extern int udp_opt_set(queue_t *, uint_t, int, int, uint_t, uchar_t *, 235 uint_t *, uchar_t *, void *, cred_t *, mblk_t *); 236 extern int udp_snmp_get(queue_t *, mblk_t *); 237 extern int udp_snmp_set(queue_t *, t_scalar_t, t_scalar_t, uchar_t *, int); 238 extern void udp_close_free(conn_t *); 239 extern void udp_quiesce_conn(conn_t *); 240 extern void udp_ddi_init(void); 241 extern void udp_ddi_destroy(void); 242 extern void udp_resume_bind(conn_t *, mblk_t *); 243 extern void udp_conn_recv(conn_t *, mblk_t *); 244 extern boolean_t udp_compute_checksum(void); 245 extern void udp_wput_data(queue_t *, mblk_t *, struct sockaddr *, 246 socklen_t); 247 248 #endif /* _KERNEL */ 249 250 #ifdef __cplusplus 251 } 252 #endif 253 254 #endif /* _UDP_IMPL_H */ 255