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 2007 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 #include <sys/netstack.h> 46 47 #include <netinet/in.h> 48 #include <netinet/ip6.h> 49 50 #include <inet/common.h> 51 #include <inet/ip.h> 52 #include <inet/optcom.h> 53 54 #define UDP_MOD_ID 5607 55 56 /* udp_mode. UDP_MT_HOT and UDP_SQUEUE are stable modes. Rest are transient */ 57 typedef enum { 58 UDP_MT_HOT = 0, /* UDP endpoint is MT HOT */ 59 UDP_MT_QUEUED = 1, /* Messages enqueued in udp_mphead */ 60 UDP_QUEUED_SQUEUE = 2, /* Messages enqueued in conn_sqp */ 61 UDP_SQUEUE = 3 /* Single threaded using squeues */ 62 } udp_mode_t; 63 64 /* 65 * Bind hash list size and hash function. It has to be a power of 2 for 66 * hashing. 67 */ 68 #define UDP_BIND_FANOUT_SIZE 512 69 #define UDP_BIND_HASH(lport, size) \ 70 ((ntohs((uint16_t)lport)) & (size - 1)) 71 72 /* UDP bind fanout hash structure. */ 73 typedef struct udp_fanout_s { 74 struct udp_s *uf_udp; 75 kmutex_t uf_lock; 76 #if defined(_LP64) || defined(_I32LPx) 77 char uf_pad[48]; 78 #else 79 char uf_pad[56]; 80 #endif 81 } udp_fanout_t; 82 83 84 /* Kstats */ 85 typedef struct udp_stat { /* Class "net" kstats */ 86 kstat_named_t udp_ip_send; 87 kstat_named_t udp_ip_ire_send; 88 kstat_named_t udp_ire_null; 89 kstat_named_t udp_drain; 90 kstat_named_t udp_sock_fallback; 91 kstat_named_t udp_rrw_busy; 92 kstat_named_t udp_rrw_msgcnt; 93 kstat_named_t udp_out_sw_cksum; 94 kstat_named_t udp_out_sw_cksum_bytes; 95 kstat_named_t udp_out_opt; 96 kstat_named_t udp_out_err_notconn; 97 kstat_named_t udp_out_err_output; 98 kstat_named_t udp_out_err_tudr; 99 kstat_named_t udp_in_pktinfo; 100 kstat_named_t udp_in_recvdstaddr; 101 kstat_named_t udp_in_recvopts; 102 kstat_named_t udp_in_recvif; 103 kstat_named_t udp_in_recvslla; 104 kstat_named_t udp_in_recvucred; 105 kstat_named_t udp_in_recvttl; 106 kstat_named_t udp_in_recvhopopts; 107 kstat_named_t udp_in_recvhoplimit; 108 kstat_named_t udp_in_recvdstopts; 109 kstat_named_t udp_in_recvrtdstopts; 110 kstat_named_t udp_in_recvrthdr; 111 kstat_named_t udp_in_recvpktinfo; 112 kstat_named_t udp_in_recvtclass; 113 kstat_named_t udp_in_timestamp; 114 kstat_named_t udp_ip_recvpktinfo; 115 #ifdef DEBUG 116 kstat_named_t udp_data_conn; 117 kstat_named_t udp_data_notconn; 118 #endif 119 120 } udp_stat_t; 121 122 /* Named Dispatch Parameter Management Structure */ 123 typedef struct udpparam_s { 124 uint32_t udp_param_min; 125 uint32_t udp_param_max; 126 uint32_t udp_param_value; 127 char *udp_param_name; 128 } udpparam_t; 129 130 #define UDP_NUM_EPRIV_PORTS 64 131 132 /* 133 * UDP stack instances 134 */ 135 struct udp_stack { 136 netstack_t *us_netstack; /* Common netstack */ 137 138 uint_t us_bind_fanout_size; 139 udp_fanout_t *us_bind_fanout; 140 141 int us_num_epriv_ports; 142 in_port_t us_epriv_ports[UDP_NUM_EPRIV_PORTS]; 143 144 /* Hint not protected by any lock */ 145 in_port_t us_next_port_to_try; 146 147 IDP us_nd; /* Points to table of UDP ND variables. */ 148 udpparam_t *us_param_arr; /* ndd variable table */ 149 150 kstat_t *us_mibkp; /* kstats exporting mib data */ 151 kstat_t *us_kstat; 152 udp_stat_t us_statistics; 153 154 mib2_udp_t us_udp_mib; /* SNMP fixed size info */ 155 156 /* 157 * This controls the rate some ndd info report functions can be used 158 * by non-priviledged users. It stores the last time such info is 159 * requested. When those report functions are called again, this 160 * is checked with the current time and compare with the ndd param 161 * udp_ndd_get_info_interval. 162 */ 163 clock_t us_last_ndd_get_info_time; 164 165 /* 166 * The smallest anonymous port in the priviledged port range which UDP 167 * looks for free port. Use in the option UDP_ANONPRIVBIND. 168 */ 169 in_port_t us_min_anonpriv_port; 170 171 }; 172 typedef struct udp_stack udp_stack_t; 173 174 /* Internal udp control structure, one per open stream */ 175 typedef struct udp_s { 176 uint32_t udp_state; /* TPI state */ 177 in_port_t udp_port; /* Port bound to this stream */ 178 in_port_t udp_dstport; /* Connected port */ 179 in6_addr_t udp_v6src; /* Source address of this stream */ 180 in6_addr_t udp_bound_v6src; /* Explicitly bound address */ 181 in6_addr_t udp_v6dst; /* Connected destination */ 182 uint32_t udp_flowinfo; /* Connected flow id and tclass */ 183 uint32_t udp_max_hdr_len; /* For write offset in stream head */ 184 sa_family_t udp_family; /* Family from socket() call */ 185 /* 186 * IP format that packets transmitted from this struct should use. 187 * Value can be IP4_VERSION or IPV6_VERSION. 188 */ 189 ushort_t udp_ipversion; 190 uint32_t udp_ip_snd_options_len; /* Len of IPv4 options */ 191 uchar_t *udp_ip_snd_options; /* Ptr to IPv4 options */ 192 uint32_t udp_ip_rcv_options_len; /* Len of IPv4 options recvd */ 193 uchar_t *udp_ip_rcv_options; /* Ptr to IPv4 options recvd */ 194 uchar_t udp_multicast_ttl; /* IP*_MULTICAST_TTL/HOPS */ 195 ipaddr_t udp_multicast_if_addr; /* IP_MULTICAST_IF option */ 196 uint_t udp_multicast_if_index; /* IPV6_MULTICAST_IF option */ 197 int udp_bound_if; /* IP*_BOUND_IF option */ 198 int udp_xmit_if; /* IP_XMIT_IF option */ 199 conn_t *udp_connp; 200 uint32_t 201 udp_debug : 1, /* SO_DEBUG "socket" option. */ 202 udp_dontroute : 1, /* SO_DONTROUTE "socket" option. */ 203 udp_broadcast : 1, /* SO_BROADCAST "socket" option. */ 204 udp_useloopback : 1, /* SO_USELOOPBACK "socket" option */ 205 206 udp_reuseaddr : 1, /* SO_REUSEADDR "socket" option. */ 207 udp_dgram_errind : 1, /* SO_DGRAM_ERRIND option */ 208 udp_recvdstaddr : 1, /* IP_RECVDSTADDR option */ 209 udp_recvopts : 1, /* IP_RECVOPTS option */ 210 211 udp_discon_pending : 1, /* T_DISCON_REQ in progress */ 212 udp_unspec_source : 1, /* IP*_UNSPEC_SRC option */ 213 udp_ip_recvpktinfo : 1, /* IPV[4,6]_RECVPKTINFO option */ 214 udp_ipv6_recvhoplimit : 1, /* IPV6_RECVHOPLIMIT option */ 215 216 udp_ipv6_recvhopopts : 1, /* IPV6_RECVHOPOPTS option */ 217 udp_ipv6_recvdstopts : 1, /* IPV6_RECVDSTOPTS option */ 218 udp_ipv6_recvrthdr : 1, /* IPV6_RECVRTHDR option */ 219 udp_ipv6_recvtclass : 1, /* IPV6_RECVTCLASS */ 220 221 udp_ipv6_recvpathmtu : 1, /* IPV6_RECVPATHMTU */ 222 udp_anon_priv_bind : 1, 223 udp_exclbind : 1, /* ``exclusive'' binding */ 224 udp_recvif : 1, /* IP_RECVIF option */ 225 226 udp_recvslla : 1, /* IP_RECVSLLA option */ 227 udp_recvttl : 1, /* IP_RECVTTL option */ 228 udp_recvucred : 1, /* IP_RECVUCRED option */ 229 udp_old_ipv6_recvdstopts : 1, /* old form of IPV6_DSTOPTS */ 230 231 udp_ipv6_recvrthdrdstopts : 1, /* IPV6_RECVRTHDRDSTOPTS */ 232 udp_rcvhdr : 1, /* UDP_RCVHDR option */ 233 udp_issocket : 1, /* socket mode */ 234 udp_direct_sockfs : 1, /* direct calls to/from sockfs */ 235 236 udp_timestamp : 1, /* SO_TIMESTAMP "socket" option */ 237 udp_anon_mlp : 1, /* SO_ANON_MLP */ 238 udp_mac_exempt : 1, /* SO_MAC_EXEMPT */ 239 udp_pad_to_bit_31 : 1; 240 241 uint8_t udp_type_of_service; /* IP_TOS option */ 242 uint8_t udp_ttl; /* TTL or hoplimit */ 243 244 ip6_pkt_t udp_sticky_ipp; /* Sticky options */ 245 uint8_t *udp_sticky_hdrs; /* Prebuilt IPv6 hdrs */ 246 uint_t udp_sticky_hdrs_len; /* Incl. ip6h and any ip6i */ 247 struct udp_s *udp_bind_hash; /* Bind hash chain */ 248 struct udp_s **udp_ptpbhn; /* Pointer to previous bind hash next. */ 249 udp_mode_t udp_mode; /* Current mode of operation */ 250 mblk_t *udp_mphead; /* Head of the queued operations */ 251 mblk_t *udp_mptail; /* Tail of the queued operations */ 252 uint_t udp_mpcount; /* Number of messages in the queue */ 253 uint_t udp_reader_count; /* Number of reader threads */ 254 uint_t udp_squeue_count; /* Number of messages in conn_sqp */ 255 256 kmutex_t udp_drain_lock; /* lock for udp_rcv_list */ 257 boolean_t udp_drain_qfull; /* drain queue is full */ 258 mblk_t *udp_rcv_list_head; /* b_next chain of mblks */ 259 mblk_t *udp_rcv_list_tail; /* last mblk in chain */ 260 uint_t udp_rcv_cnt; /* total data in rcv_list */ 261 uint_t udp_rcv_msgcnt; /* total messages in rcv_list */ 262 size_t udp_rcv_hiwat; /* receive high watermark */ 263 uint_t udp_label_len; /* length of security label */ 264 uint_t udp_label_len_v6; /* len of v6 security label */ 265 in6_addr_t udp_v6lastdst; /* most recent destination */ 266 267 uint64_t udp_open_time; /* time when this was opened */ 268 pid_t udp_open_pid; /* process id when this was opened */ 269 udp_stack_t *udp_us; /* Stack instance for zone */ 270 } udp_t; 271 #define udp_mib udp_us->us_udp_mib 272 273 /* UDP Protocol header */ 274 /* UDP Protocol header aligned */ 275 typedef struct udpahdr_s { 276 in_port_t uha_src_port; /* Source port */ 277 in_port_t uha_dst_port; /* Destination port */ 278 uint16_t uha_length; /* UDP length */ 279 uint16_t uha_checksum; /* UDP checksum */ 280 } udpha_t; 281 282 #define us_wroff_extra us_param_arr[0].udp_param_value 283 #define us_ipv4_ttl us_param_arr[1].udp_param_value 284 #define us_ipv6_hoplimit us_param_arr[2].udp_param_value 285 #define us_smallest_nonpriv_port us_param_arr[3].udp_param_value 286 #define us_do_checksum us_param_arr[4].udp_param_value 287 #define us_smallest_anon_port us_param_arr[5].udp_param_value 288 #define us_largest_anon_port us_param_arr[6].udp_param_value 289 #define us_xmit_hiwat us_param_arr[7].udp_param_value 290 #define us_xmit_lowat us_param_arr[8].udp_param_value 291 #define us_recv_hiwat us_param_arr[9].udp_param_value 292 #define us_max_buf us_param_arr[10].udp_param_value 293 #define us_ndd_get_info_interval us_param_arr[11].udp_param_value 294 295 296 #define UDP_STAT(us, x) ((us)->us_statistics.x.value.ui64++) 297 #define UDP_STAT_UPDATE(us, x, n) \ 298 ((us)->us_statistics.x.value.ui64 += (n)) 299 300 #ifdef DEBUG 301 #define UDP_DBGSTAT(us, x) UDP_STAT(us, x) 302 #else 303 #define UDP_DBGSTAT(us, x) 304 #endif /* DEBUG */ 305 306 extern major_t UDP6_MAJ; 307 308 extern int udp_opt_default(queue_t *, t_scalar_t, t_scalar_t, uchar_t *); 309 extern int udp_opt_get(queue_t *, t_scalar_t, t_scalar_t, uchar_t *); 310 extern int udp_opt_set(queue_t *, uint_t, int, int, uint_t, uchar_t *, 311 uint_t *, uchar_t *, void *, cred_t *, mblk_t *); 312 extern int udp_snmp_get(queue_t *, mblk_t *); 313 extern int udp_snmp_set(queue_t *, t_scalar_t, t_scalar_t, uchar_t *, int); 314 extern void udp_close_free(conn_t *); 315 extern void udp_quiesce_conn(conn_t *); 316 extern void udp_ddi_init(void); 317 extern void udp_ddi_destroy(void); 318 extern void udp_resume_bind(conn_t *, mblk_t *); 319 extern void udp_conn_recv(conn_t *, mblk_t *); 320 extern boolean_t udp_compute_checksum(netstack_t *); 321 extern void udp_wput_data(queue_t *, mblk_t *, struct sockaddr *, 322 socklen_t); 323 324 extern int udp_opt_default(queue_t *q, t_scalar_t level, t_scalar_t name, 325 uchar_t *ptr); 326 extern int udp_opt_get(queue_t *q, t_scalar_t level, t_scalar_t name, 327 uchar_t *ptr); 328 extern int udp_opt_set(queue_t *q, uint_t optset_context, 329 int level, int name, uint_t inlen, uchar_t *invalp, uint_t *outlenp, 330 uchar_t *outvalp, void *thisdg_attrs, cred_t *cr, mblk_t *mblk); 331 332 /* 333 * Object to represent database of options to search passed to 334 * {sock,tpi}optcom_req() interface routine to take care of option 335 * management and associated methods. 336 */ 337 extern optdb_obj_t udp_opt_obj; 338 extern uint_t udp_max_optsize; 339 340 #endif /* _KERNEL */ 341 342 #ifdef __cplusplus 343 } 344 #endif 345 346 #endif /* _UDP_IMPL_H */ 347