blob: 479641a11b5083d1b75c5e5db8b9328206064ca5 [file] [log] [blame]
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -07001/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
rshoaib2caf0dc2006-03-05 18:00:39 -08005 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -07007 *
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 */
rshoaib2caf0dc2006-03-05 18:00:39 -080021
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070022/*
Anders Persson5f1fdc12010-04-26 14:42:41 -070023 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
Robert Mustacchi907c2822021-02-01 13:50:02 +000024 * Copyright 2015 Joyent, Inc.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070025 */
26
27/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
Marcel Telkab4203d72017-06-14 08:51:35 +020028/* All Rights Reserved */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070029
30/*
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
33 * All Rights Reserved
34 *
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
37 * contributors.
38 */
Alexander Eremin19581f82015-06-05 08:00:15 -070039/*
40 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
Andy Fiddamand865fc92020-06-05 14:22:45 +000041 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
Alexander Eremin19581f82015-06-05 08:00:15 -070042 */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070043
44#ifndef _SYS_SOCKETVAR_H
45#define _SYS_SOCKETVAR_H
46
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070047#include <sys/types.h>
48#include <sys/stream.h>
49#include <sys/t_lock.h>
50#include <sys/cred.h>
51#include <sys/vnode.h>
52#include <sys/file.h>
53#include <sys/param.h>
54#include <sys/zone.h>
Yu Xiangning0f1702c2008-12-11 20:04:13 -080055#include <sys/sdt.h>
56#include <sys/modctl.h>
57#include <sys/atomic.h>
58#include <sys/socket.h>
59#include <sys/ksocket.h>
Anders Persson7d64f412009-02-11 15:38:45 -080060#include <sys/kstat.h>
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070061
Scott Rotondod67944f2009-05-21 22:03:24 -070062#ifdef _KERNEL
63#include <sys/vfs_opreg.h>
64#endif
65
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070066#ifdef __cplusplus
67extern "C" {
68#endif
69
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070070/*
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070071 * Internal representation of the address used to represent addresses
72 * in the loopback transport for AF_UNIX. While the sockaddr_un is used
73 * as the sockfs layer address for AF_UNIX the pathnames contained in
74 * these addresses are not unique (due to relative pathnames) thus can not
75 * be used in the transport.
76 *
77 * The transport level address consists of a magic number (used to separate the
78 * name space for specific and implicit binds). For a specific bind
79 * this is followed by a "vnode *" which ensures that all specific binds
80 * have a unique transport level address. For implicit binds the latter
81 * part of the address is a byte string (of the same length as a pointer)
82 * that is assigned by the loopback transport.
83 *
84 * The uniqueness assumes that the loopback transport has a separate namespace
85 * for sockets in order to avoid name conflicts with e.g. TLI use of the
86 * same transport.
87 */
88struct so_ux_addr {
89 void *soua_vp; /* vnode pointer or assigned by tl */
90 uint_t soua_magic; /* See below */
91};
92
93#define SOU_MAGIC_EXPLICIT 0x75787670 /* "uxvp" */
94#define SOU_MAGIC_IMPLICIT 0x616e6f6e /* "anon" */
95
96struct sockaddr_ux {
97 sa_family_t sou_family; /* AF_UNIX */
98 struct so_ux_addr sou_addr;
99};
100
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800101#if defined(_KERNEL) || defined(_KMEMUSER)
102
103#include <sys/socket_proto.h>
104
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700105typedef struct sonodeops sonodeops_t;
masputraff550d02005-10-22 22:50:14 -0700106typedef struct sonode sonode_t;
Robert Mustacchi907c2822021-02-01 13:50:02 +0000107typedef boolean_t (*so_krecv_f)(sonode_t *, mblk_t *, size_t, int, void *);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700108
Anders Perssonbbc000e2009-04-28 12:10:59 -0700109struct sodirect_s;
110
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700111/*
112 * The sonode represents a socket. A sonode never exist in the file system
113 * name space and can not be opened using open() - only the socket, socketpair
114 * and accept calls create sonodes.
115 *
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800116 * The locking of sockfs uses the so_lock mutex plus the SOLOCKED and
117 * SOREADLOCKED flags in so_flag. The mutex protects all the state in the
118 * sonode. It is expected that the underlying transport protocol serializes
119 * socket operations, so sockfs will not normally not single-thread
120 * operations. However, certain sockets, including TPI based ones, can only
121 * handle one control operation at a time. The SOLOCKED flag is used to
122 * single-thread operations from sockfs users to prevent e.g. multiple bind()
123 * calls to operate on the same sonode concurrently. The SOREADLOCKED flag is
124 * used to ensure that only one thread sleeps in kstrgetmsg for a given
125 * sonode. This is needed to ensure atomic operation for things like
126 * MSG_WAITALL.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700127 *
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800128 * The so_fallback_rwlock is used to ensure that for sockets that can
129 * fall back to TPI, the fallback is not initiated until all pending
130 * operations have completed.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700131 *
132 * Note that so_lock is sometimes held across calls that might go to sleep
133 * (kmem_alloc and soallocproto*). This implies that no other lock in
134 * the system should be held when calling into sockfs; from the system call
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800135 * side or from strrput (in case of TPI based sockets). If locks are held
136 * while calling into sockfs the system might hang when running low on memory.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700137 */
138struct sonode {
139 struct vnode *so_vnode; /* vnode associated with this sonode */
140
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000141 sonodeops_t *so_ops; /* operations vector for this sonode */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800142 void *so_priv; /* sonode private data */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700143
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800144 krwlock_t so_fallback_rwlock;
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700145 kmutex_t so_lock; /* protects sonode fields */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800146
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700147 kcondvar_t so_state_cv; /* synchronize state changes */
Anders Persson6a571a22010-01-15 20:20:54 -0800148 kcondvar_t so_single_cv; /* wait due to SOLOCKED */
149 kcondvar_t so_read_cv; /* wait due to SOREADLOCKED */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700150
151 /* These fields are protected by so_lock */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700152
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800153 uint_t so_state; /* internal state flags SS_*, below */
154 uint_t so_mode; /* characteristics on socket. SM_* */
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000155 ushort_t so_flag; /* flags, see below */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800156 int so_count; /* count of opened references */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700157
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800158 sock_connid_t so_proto_connid; /* protocol generation number */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700159
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000160 ushort_t so_error; /* error affecting connection */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800161
162 struct sockparams *so_sockparams; /* vnode or socket module */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700163 /* Needed to recreate the same socket for accept */
164 short so_family;
165 short so_type;
166 short so_protocol;
167 short so_version; /* From so_socket call */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800168
169 /* Accept queue */
170 kmutex_t so_acceptq_lock; /* protects accept queue */
Anders Persson3e95bd42010-06-17 17:22:09 -0700171 list_t so_acceptq_list; /* pending conns */
172 list_t so_acceptq_defer; /* deferred conns */
173 list_node_t so_acceptq_node; /* acceptq list node */
174 unsigned int so_acceptq_len; /* # of conns (both lists) */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800175 unsigned int so_backlog; /* Listen backlog */
176 kcondvar_t so_acceptq_cv; /* wait for new conn. */
Anders Persson3e95bd42010-06-17 17:22:09 -0700177 struct sonode *so_listener; /* parent socket */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700178
179 /* Options */
180 short so_options; /* From socket call, see socket.h */
181 struct linger so_linger; /* SO_LINGER value */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800182#define so_sndbuf so_proto_props.sopp_txhiwat /* SO_SNDBUF value */
183#define so_sndlowat so_proto_props.sopp_txlowat /* tx low water mark */
184#define so_rcvbuf so_proto_props.sopp_rxhiwat /* SO_RCVBUF value */
185#define so_rcvlowat so_proto_props.sopp_rxlowat /* rx low water mark */
186#define so_max_addr_len so_proto_props.sopp_maxaddrlen
187#define so_minpsz so_proto_props.sopp_minpsz
188#define so_maxpsz so_proto_props.sopp_maxpsz
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700189
Yu Xiangninga5adac42008-12-29 13:56:29 +0800190 int so_xpg_rcvbuf; /* SO_RCVBUF value for XPG4 socket */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800191 clock_t so_sndtimeo; /* send timeout */
192 clock_t so_rcvtimeo; /* recv timeout */
193
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700194 mblk_t *so_oobmsg; /* outofline oob data */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800195 ssize_t so_oobmark; /* offset of the oob data */
196
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700197 pid_t so_pgrp; /* pgrp for signals */
198
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700199 cred_t *so_peercred; /* connected socket peer cred */
200 pid_t so_cpid; /* connected socket peer cached pid */
201 zoneid_t so_zoneid; /* opener's zoneid */
202
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800203 struct pollhead so_poll_list; /* common pollhead */
204 short so_pollev; /* events that should be generated */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700205
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800206 /* Receive */
Anders Persson419dcee2009-02-28 20:06:52 -0800207 unsigned int so_rcv_queued; /* # bytes on both rcv lists */
208 mblk_t *so_rcv_q_head; /* processing/copyout rcv queue */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800209 mblk_t *so_rcv_q_last_head;
Anders Persson419dcee2009-02-28 20:06:52 -0800210 mblk_t *so_rcv_head; /* protocol prequeue */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800211 mblk_t *so_rcv_last_head; /* last mblk in b_next chain */
Anders Persson419dcee2009-02-28 20:06:52 -0800212 kcondvar_t so_rcv_cv; /* wait for data */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800213 uint_t so_rcv_wanted; /* # of bytes wanted by app */
214 timeout_id_t so_rcv_timer_tid;
kaisc28749e2005-11-12 18:58:05 -0800215
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800216#define so_rcv_thresh so_proto_props.sopp_rcvthresh
217#define so_rcv_timer_interval so_proto_props.sopp_rcvtimer
218
Anders Persson419dcee2009-02-28 20:06:52 -0800219 kcondvar_t so_snd_cv; /* wait for snd buffers */
Rao Shoaibd36be522008-12-17 13:09:55 -0800220 uint32_t
221 so_snd_qfull: 1, /* Transmit full */
222 so_rcv_wakeup: 1,
223 so_snd_wakeup: 1,
224 so_not_str: 1, /* B_TRUE if not streams based socket */
225 so_pad_to_bit_31: 28;
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800226
227 /* Communication channel with protocol */
228 sock_lower_handle_t so_proto_handle;
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000229 sock_downcalls_t *so_downcalls;
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800230
231 struct sock_proto_props so_proto_props; /* protocol settings */
232 boolean_t so_flowctrld; /* Flow controlled */
233 uint_t so_copyflag; /* Copy related flag */
234 kcondvar_t so_copy_cv; /* Copy cond variable */
235
236 /* kernel sockets */
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000237 ksocket_callbacks_t so_ksock_callbacks;
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800238 void *so_ksock_cb_arg; /* callback argument */
239 kcondvar_t so_closing_cv;
brutus17169042008-05-23 20:14:10 -0700240
Anders Perssonbbc000e2009-04-28 12:10:59 -0700241 /* != NULL for sodirect enabled socket */
242 struct sodirect_s *so_direct;
Anders Persson3e95bd42010-06-17 17:22:09 -0700243
244 /* socket filters */
245 uint_t so_filter_active; /* # of active fil */
246 uint_t so_filter_tx; /* pending tx ops */
247 struct sof_instance *so_filter_top; /* top of stack */
248 struct sof_instance *so_filter_bottom; /* bottom of stack */
249 clock_t so_filter_defertime; /* time when deferred */
Robert Mustacchi907c2822021-02-01 13:50:02 +0000250
251 /* Kernel direct receive callbacks */
252 so_krecv_f so_krecv_cb; /* recv callback */
253 void *so_krecv_arg; /* recv cb arg */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700254};
255
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800256#define SO_HAVE_DATA(so) \
andersf0267582008-12-20 22:46:32 -0800257 /* \
258 * For the (tid == 0) case we must check so_rcv_{q_,}head \
259 * rather than (so_rcv_queued > 0), since the latter does not \
260 * take into account mblks with only control/name information. \
261 */ \
262 ((so)->so_rcv_timer_tid == 0 && ((so)->so_rcv_head != NULL || \
263 (so)->so_rcv_q_head != NULL)) || \
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800264 ((so)->so_state & SS_CANTRCVMORE)
265
266/*
267 * Events handled by the protocol (in case sd_poll is set)
268 */
269#define SO_PROTO_POLLEV (POLLIN|POLLRDNORM|POLLRDBAND)
270
271
272#endif /* _KERNEL || _KMEMUSER */
273
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700274/* flags */
275#define SOMOD 0x0001 /* update socket modification time */
276#define SOACC 0x0002 /* update socket access time */
277
278#define SOLOCKED 0x0010 /* use to serialize open/closes */
279#define SOREADLOCKED 0x0020 /* serialize kstrgetmsg calls */
Anders Persson6a571a22010-01-15 20:20:54 -0800280#define SOCLONE 0x0040 /* child of clone driver */
281#define SOASYNC_UNBIND 0x0080 /* wait for ACK of async unbind */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700282
Rao Shoaibd36be522008-12-17 13:09:55 -0800283#define SOCK_IS_NONSTR(so) ((so)->so_not_str)
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800284
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700285/*
286 * Socket state bits.
287 */
288#define SS_ISCONNECTED 0x00000001 /* socket connected to a peer */
289#define SS_ISCONNECTING 0x00000002 /* in process, connecting to peer */
290#define SS_ISDISCONNECTING 0x00000004 /* in process of disconnecting */
291#define SS_CANTSENDMORE 0x00000008 /* can't send more data to peer */
292
293#define SS_CANTRCVMORE 0x00000010 /* can't receive more data */
294#define SS_ISBOUND 0x00000020 /* socket is bound */
295#define SS_NDELAY 0x00000040 /* FNDELAY non-blocking */
296#define SS_NONBLOCK 0x00000080 /* O_NONBLOCK non-blocking */
297
298#define SS_ASYNC 0x00000100 /* async i/o notify */
299#define SS_ACCEPTCONN 0x00000200 /* listen done */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800300/* unused 0x00000400 */ /* was SS_HASCONNIND */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700301#define SS_SAVEDEOR 0x00000800 /* Saved MSG_EOR rcv side state */
302
303#define SS_RCVATMARK 0x00001000 /* at mark on input */
304#define SS_OOBPEND 0x00002000 /* OOB pending or present - poll */
305#define SS_HAVEOOBDATA 0x00004000 /* OOB data present */
306#define SS_HADOOBDATA 0x00008000 /* OOB data consumed */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800307#define SS_CLOSING 0x00010000 /* in process of closing */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700308
Anders Persson3e95bd42010-06-17 17:22:09 -0700309#define SS_FIL_DEFER 0x00020000 /* filter deferred notification */
310#define SS_FILOP_OK 0x00040000 /* socket can attach filters */
311#define SS_FIL_RCV_FLOWCTRL 0x00080000 /* filter asserted rcv flow ctrl */
312#define SS_FIL_SND_FLOWCTRL 0x00100000 /* filter asserted snd flow ctrl */
Anders Perssone82bc0b2010-08-10 15:52:26 -0700313#define SS_FIL_STOP 0x00200000 /* no more filter actions */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700314
brutus17169042008-05-23 20:14:10 -0700315#define SS_SODIRECT 0x00400000 /* transport supports sodirect */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700316
Anders Persson41174432009-02-12 17:35:05 -0800317#define SS_SENTLASTREADSIG 0x01000000 /* last rx signal has been sent */
318#define SS_SENTLASTWRITESIG 0x02000000 /* last tx signal has been sent */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800319
Anders Persson41174432009-02-12 17:35:05 -0800320#define SS_FALLBACK_DRAIN 0x20000000 /* data was/is being drained */
321#define SS_FALLBACK_PENDING 0x40000000 /* fallback is pending */
322#define SS_FALLBACK_COMP 0x80000000 /* fallback has completed */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800323
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700324
325/* Set of states when the socket can't be rebound */
326#define SS_CANTREBIND (SS_ISCONNECTED|SS_ISCONNECTING|SS_ISDISCONNECTING|\
327 SS_CANTSENDMORE|SS_CANTRCVMORE|SS_ACCEPTCONN)
328
329/*
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800330 * Sockets that can fall back to TPI must ensure that fall back is not
331 * initiated while a thread is using a socket.
332 */
Anders Persson3e95bd42010-06-17 17:22:09 -0700333#define SO_BLOCK_FALLBACK(so, fn) \
334 ASSERT(MUTEX_NOT_HELD(&(so)->so_lock)); \
335 rw_enter(&(so)->so_fallback_rwlock, RW_READER); \
336 if ((so)->so_state & (SS_FALLBACK_COMP|SS_FILOP_OK)) { \
337 if ((so)->so_state & SS_FALLBACK_COMP) { \
338 rw_exit(&(so)->so_fallback_rwlock); \
339 return (fn); \
340 } else { \
341 mutex_enter(&(so)->so_lock); \
342 (so)->so_state &= ~SS_FILOP_OK; \
343 mutex_exit(&(so)->so_lock); \
344 } \
345 }
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800346
347#define SO_UNBLOCK_FALLBACK(so) { \
348 rw_exit(&(so)->so_fallback_rwlock); \
349}
350
Anders Persson3e95bd42010-06-17 17:22:09 -0700351#define SO_SND_FLOWCTRLD(so) \
352 ((so)->so_snd_qfull || (so)->so_state & SS_FIL_SND_FLOWCTRL)
353
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800354/* Poll events */
355#define SO_POLLEV_IN 0x1 /* POLLIN wakeup needed */
356#define SO_POLLEV_ALWAYS 0x2 /* wakeups */
357
358/*
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700359 * Characteristics of sockets. Not changed after the socket is created.
360 */
361#define SM_PRIV 0x001 /* privileged for broadcast, raw... */
362#define SM_ATOMIC 0x002 /* atomic data transmission */
363#define SM_ADDR 0x004 /* addresses given with messages */
364#define SM_CONNREQUIRED 0x008 /* connection required by protocol */
365
366#define SM_FDPASSING 0x010 /* passes file descriptors */
367#define SM_EXDATA 0x020 /* Can handle T_EXDATA_REQ */
368#define SM_OPTDATA 0x040 /* Can handle T_OPTDATA_REQ */
369#define SM_BYTESTREAM 0x080 /* Byte stream - can use M_DATA */
370
371#define SM_ACCEPTOR_ID 0x100 /* so_acceptor_id is valid */
372
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800373#define SM_KERNEL 0x200 /* kernel socket */
374
anders07d13e52008-12-17 18:28:34 -0800375/* The modes below are only for non-streams sockets */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800376#define SM_ACCEPTSUPP 0x400 /* can handle accept() */
anders07d13e52008-12-17 18:28:34 -0800377#define SM_SENDFILESUPP 0x800 /* Private: proto supp sendfile */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800378
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700379/*
380 * Socket versions. Used by the socket library when calling _so_socket().
381 */
382#define SOV_STREAM 0 /* Not a socket - just a stream */
383#define SOV_DEFAULT 1 /* Select based on so_default_version */
384#define SOV_SOCKSTREAM 2 /* Socket plus streams operations */
385#define SOV_SOCKBSD 3 /* Socket with no streams operations */
386#define SOV_XPG4_2 4 /* Xnet socket */
387
388#if defined(_KERNEL) || defined(_KMEMUSER)
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800389
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700390/*
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800391 * sonode create and destroy functions.
392 */
393typedef struct sonode *(*so_create_func_t)(struct sockparams *,
394 int, int, int, int, int, int *, cred_t *);
395typedef void (*so_destroy_func_t)(struct sonode *);
396
397/* STREAM device information */
398typedef struct sdev_info {
399 char *sd_devpath;
400 int sd_devpathlen; /* Is 0 if sp_devpath is a static string */
401 vnode_t *sd_vnode;
402} sdev_info_t;
403
Anders Persson3e95bd42010-06-17 17:22:09 -0700404#define SOCKMOD_VERSION_1 1
405#define SOCKMOD_VERSION 2
406
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800407/* name of the TPI pseudo socket module */
408#define SOTPI_SMOD_NAME "socktpi"
409
410typedef struct __smod_priv_s {
411 so_create_func_t smodp_sock_create_func;
412 so_destroy_func_t smodp_sock_destroy_func;
413 so_proto_fallback_func_t smodp_proto_fallback_func;
Anders Persson3e95bd42010-06-17 17:22:09 -0700414 const char *smodp_fallback_devpath_v4;
415 const char *smodp_fallback_devpath_v6;
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800416} __smod_priv_t;
417
418/*
419 * Socket module register information
420 */
421typedef struct smod_reg_s {
422 int smod_version;
423 char *smod_name;
424 size_t smod_uc_version;
425 size_t smod_dc_version;
426 so_proto_create_func_t smod_proto_create_func;
427
428 /* __smod_priv_data must be NULL */
429 __smod_priv_t *__smod_priv;
430} smod_reg_t;
431
432/*
433 * Socket module information
434 */
435typedef struct smod_info {
436 int smod_version;
437 char *smod_name;
438 uint_t smod_refcnt; /* # of entries */
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000439 size_t smod_uc_version; /* upcall version */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800440 size_t smod_dc_version; /* down call version */
441 so_proto_create_func_t smod_proto_create_func;
442 so_proto_fallback_func_t smod_proto_fallback_func;
Anders Persson3e95bd42010-06-17 17:22:09 -0700443 const char *smod_fallback_devpath_v4;
444 const char *smod_fallback_devpath_v6;
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800445 so_create_func_t smod_sock_create_func;
446 so_destroy_func_t smod_sock_destroy_func;
447 list_node_t smod_node;
448} smod_info_t;
449
Anders Persson7d64f412009-02-11 15:38:45 -0800450typedef struct sockparams_stats {
451 kstat_named_t sps_nfallback; /* # of fallbacks to TPI */
452 kstat_named_t sps_nactive; /* # of active sockets */
453 kstat_named_t sps_ncreate; /* total # of created sockets */
454} sockparams_stats_t;
455
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800456/*
457 * sockparams
458 *
Anders Persson5f1fdc12010-04-26 14:42:41 -0700459 * Used for mapping family/type/protocol to a socket module or STREAMS device
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700460 */
461struct sockparams {
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800462 /*
Anders Persson5f1fdc12010-04-26 14:42:41 -0700463 * The family, type, protocol, sdev_info and smod_name are
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800464 * set when the entry is created, and they will never change
465 * thereafter.
466 */
467 int sp_family;
468 int sp_type;
469 int sp_protocol;
470
471 sdev_info_t sp_sdev_info; /* STREAM device */
472 char *sp_smod_name; /* socket module name */
Anders Persson5f1fdc12010-04-26 14:42:41 -0700473
474 kmutex_t sp_lock; /* lock for refcnt and smod_info */
475 uint64_t sp_refcnt; /* entry reference count */
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800476 smod_info_t *sp_smod_info; /* socket module */
477
Anders Persson7d64f412009-02-11 15:38:45 -0800478 sockparams_stats_t sp_stats;
479 kstat_t *sp_kstat;
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800480
481 /*
482 * The entries below are only modified while holding
Anders Persson3e95bd42010-06-17 17:22:09 -0700483 * sockconf_lock as a writer.
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800484 */
485 int sp_flags; /* see below */
486 list_node_t sp_node;
Anders Persson3e95bd42010-06-17 17:22:09 -0700487
488 list_t sp_auto_filters; /* list of automatic filters */
489 list_t sp_prog_filters; /* list of programmatic filters */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700490};
491
Anders Persson3e95bd42010-06-17 17:22:09 -0700492struct sof_entry;
493
494typedef struct sp_filter {
495 struct sof_entry *spf_filter;
496 list_node_t spf_node;
497} sp_filter_t;
498
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800499
500/*
501 * sockparams flags
502 */
503#define SOCKPARAMS_EPHEMERAL 0x1 /* temp. entry, not on global list */
504
505extern void sockparams_init(void);
506extern struct sockparams *sockparams_hold_ephemeral_bydev(int, int, int,
507 const char *, int, int *);
508extern struct sockparams *sockparams_hold_ephemeral_bymod(int, int, int,
509 const char *, int, int *);
510extern void sockparams_ephemeral_drop_last_ref(struct sockparams *);
511
Anders Persson3e95bd42010-06-17 17:22:09 -0700512extern struct sockparams *sockparams_create(int, int, int, char *, char *, int,
513 int, int, int *);
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000514extern void sockparams_destroy(struct sockparams *);
515extern int sockparams_add(struct sockparams *);
Anders Persson3e95bd42010-06-17 17:22:09 -0700516extern int sockparams_delete(int, int, int);
517extern int sockparams_new_filter(struct sof_entry *);
518extern void sockparams_filter_cleanup(struct sof_entry *);
Alexander Eremin19581f82015-06-05 08:00:15 -0700519extern int sockparams_copyout_socktable(uintptr_t);
Anders Persson3e95bd42010-06-17 17:22:09 -0700520
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800521extern void smod_init(void);
522extern void smod_add(smod_info_t *);
523extern int smod_register(const smod_reg_t *);
524extern int smod_unregister(const char *);
525extern smod_info_t *smod_lookup_byname(const char *);
526
527#define SOCKPARAMS_HAS_DEVICE(sp) \
528 ((sp)->sp_sdev_info.sd_devpath != NULL)
529
530/* Increase the smod_info_t reference count */
531#define SMOD_INC_REF(smodp) { \
532 ASSERT((smodp) != NULL); \
533 DTRACE_PROBE1(smodinfo__inc__ref, struct smod_info *, (smodp)); \
534 atomic_inc_uint(&(smodp)->smod_refcnt); \
535}
536
537/*
538 * Decreace the socket module entry reference count.
539 * When no one mapping to the entry, we try to unload the module from the
540 * kernel. If the module can't unload, just leave the module entry with
541 * a zero refcnt.
542 */
Anders Persson5f1fdc12010-04-26 14:42:41 -0700543#define SMOD_DEC_REF(smodp, modname) { \
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800544 ASSERT((smodp) != NULL); \
545 ASSERT((smodp)->smod_refcnt != 0); \
546 atomic_dec_uint(&(smodp)->smod_refcnt); \
547 /* \
548 * No need to atomically check the return value because the \
549 * socket module framework will verify that no one is using \
550 * the module before unloading. Worst thing that can happen \
551 * here is multiple calls to mod_remove_by_name(), which is OK. \
552 */ \
553 if ((smodp)->smod_refcnt == 0) \
Anders Persson5f1fdc12010-04-26 14:42:41 -0700554 (void) mod_remove_by_name(modname); \
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800555}
556
557/* Increase the reference count */
558#define SOCKPARAMS_INC_REF(sp) { \
559 ASSERT((sp) != NULL); \
560 DTRACE_PROBE1(sockparams__inc__ref, struct sockparams *, (sp)); \
561 mutex_enter(&(sp)->sp_lock); \
562 (sp)->sp_refcnt++; \
563 ASSERT((sp)->sp_refcnt != 0); \
564 mutex_exit(&(sp)->sp_lock); \
565}
566
567/*
568 * Decrease the reference count.
569 *
570 * If the sockparams is ephemeral, then the thread dropping the last ref
571 * count will destroy the entry.
572 */
573#define SOCKPARAMS_DEC_REF(sp) { \
574 ASSERT((sp) != NULL); \
575 DTRACE_PROBE1(sockparams__dec__ref, struct sockparams *, (sp)); \
576 mutex_enter(&(sp)->sp_lock); \
577 ASSERT((sp)->sp_refcnt > 0); \
578 if ((sp)->sp_refcnt == 1) { \
579 if ((sp)->sp_flags & SOCKPARAMS_EPHEMERAL) { \
580 mutex_exit(&(sp)->sp_lock); \
581 sockparams_ephemeral_drop_last_ref((sp)); \
582 } else { \
583 (sp)->sp_refcnt--; \
Anders Persson5f1fdc12010-04-26 14:42:41 -0700584 if ((sp)->sp_smod_info != NULL) { \
585 SMOD_DEC_REF((sp)->sp_smod_info, \
586 (sp)->sp_smod_name); \
587 } \
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800588 (sp)->sp_smod_info = NULL; \
589 mutex_exit(&(sp)->sp_lock); \
590 } \
591 } else { \
592 (sp)->sp_refcnt--; \
593 mutex_exit(&(sp)->sp_lock); \
594 } \
595}
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700596
597/*
598 * Used to traverse the list of AF_UNIX sockets to construct the kstat
Richard Lowebbf21552022-02-26 16:40:47 -0600599 * for netstat(8).
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700600 */
601struct socklist {
602 kmutex_t sl_lock;
603 struct sonode *sl_list;
604};
605
606extern struct socklist socklist;
607/*
608 * ss_full_waits is the number of times the reader thread
609 * waits when the queue is full and ss_empty_waits is the number
610 * of times the consumer thread waits when the queue is empty.
611 * No locks for these as they are just indicators of whether
612 * disk or network or both is slow or fast.
613 */
614struct sendfile_stats {
615 uint32_t ss_file_cached;
616 uint32_t ss_file_not_cached;
617 uint32_t ss_full_waits;
618 uint32_t ss_empty_waits;
619 uint32_t ss_file_segmap;
620};
621
622/*
623 * A single sendfile request is represented by snf_req.
624 */
625typedef struct snf_req {
626 struct snf_req *sr_next;
627 mblk_t *sr_mp_head;
628 mblk_t *sr_mp_tail;
629 kmutex_t sr_lock;
630 kcondvar_t sr_cv;
631 uint_t sr_qlen;
632 int sr_hiwat;
633 int sr_lowat;
634 int sr_operation;
635 struct vnode *sr_vp;
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000636 file_t *sr_fp;
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700637 ssize_t sr_maxpsz;
638 u_offset_t sr_file_off;
639 u_offset_t sr_file_size;
640#define SR_READ_DONE 0x80000000
641 int sr_read_error;
642 int sr_write_error;
643} snf_req_t;
644
645/* A queue of sendfile requests */
646struct sendfile_queue {
647 snf_req_t *snfq_req_head;
648 snf_req_t *snfq_req_tail;
649 kmutex_t snfq_lock;
650 kcondvar_t snfq_cv;
651 int snfq_svc_threads; /* # of service threads */
652 int snfq_idle_cnt; /* # of idling threads */
653 int snfq_max_threads;
654 int snfq_req_cnt; /* Number of requests */
655};
656
657#define READ_OP 1
658#define SNFQ_TIMEOUT (60 * 5 * hz) /* 5 minutes */
659
660/* Socket network operations switch */
661struct sonodeops {
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000662 int (*sop_init)(struct sonode *, struct sonode *, cred_t *,
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700663 int);
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800664 int (*sop_accept)(struct sonode *, int, cred_t *, struct sonode **);
665 int (*sop_bind)(struct sonode *, struct sockaddr *, socklen_t,
666 int, cred_t *);
667 int (*sop_listen)(struct sonode *, int, cred_t *);
Anders Persson3e95bd42010-06-17 17:22:09 -0700668 int (*sop_connect)(struct sonode *, struct sockaddr *,
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800669 socklen_t, int, int, cred_t *);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700670 int (*sop_recvmsg)(struct sonode *, struct msghdr *,
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800671 struct uio *, cred_t *);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700672 int (*sop_sendmsg)(struct sonode *, struct msghdr *,
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800673 struct uio *, cred_t *);
674 int (*sop_sendmblk)(struct sonode *, struct msghdr *, int,
675 cred_t *, mblk_t **);
676 int (*sop_getpeername)(struct sonode *, struct sockaddr *,
677 socklen_t *, boolean_t, cred_t *);
678 int (*sop_getsockname)(struct sonode *, struct sockaddr *,
679 socklen_t *, cred_t *);
680 int (*sop_shutdown)(struct sonode *, int, cred_t *);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700681 int (*sop_getsockopt)(struct sonode *, int, int, void *,
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800682 socklen_t *, int, cred_t *);
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000683 int (*sop_setsockopt)(struct sonode *, int, int, const void *,
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800684 socklen_t, cred_t *);
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000685 int (*sop_ioctl)(struct sonode *, int, intptr_t, int,
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800686 cred_t *, int32_t *);
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000687 int (*sop_poll)(struct sonode *, short, int, short *,
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800688 struct pollhead **);
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000689 int (*sop_close)(struct sonode *, int, cred_t *);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700690};
691
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800692#define SOP_INIT(so, flag, cr, flags) \
693 ((so)->so_ops->sop_init((so), (flag), (cr), (flags)))
694#define SOP_ACCEPT(so, fflag, cr, nsop) \
695 ((so)->so_ops->sop_accept((so), (fflag), (cr), (nsop)))
696#define SOP_BIND(so, name, namelen, flags, cr) \
697 ((so)->so_ops->sop_bind((so), (name), (namelen), (flags), (cr)))
698#define SOP_LISTEN(so, backlog, cr) \
699 ((so)->so_ops->sop_listen((so), (backlog), (cr)))
700#define SOP_CONNECT(so, name, namelen, fflag, flags, cr) \
701 ((so)->so_ops->sop_connect((so), (name), (namelen), (fflag), (flags), \
702 (cr)))
703#define SOP_RECVMSG(so, msg, uiop, cr) \
704 ((so)->so_ops->sop_recvmsg((so), (msg), (uiop), (cr)))
705#define SOP_SENDMSG(so, msg, uiop, cr) \
706 ((so)->so_ops->sop_sendmsg((so), (msg), (uiop), (cr)))
707#define SOP_SENDMBLK(so, msg, size, cr, mpp) \
708 ((so)->so_ops->sop_sendmblk((so), (msg), (size), (cr), (mpp)))
709#define SOP_GETPEERNAME(so, addr, addrlen, accept, cr) \
710 ((so)->so_ops->sop_getpeername((so), (addr), (addrlen), (accept), (cr)))
711#define SOP_GETSOCKNAME(so, addr, addrlen, cr) \
712 ((so)->so_ops->sop_getsockname((so), (addr), (addrlen), (cr)))
713#define SOP_SHUTDOWN(so, how, cr) \
714 ((so)->so_ops->sop_shutdown((so), (how), (cr)))
715#define SOP_GETSOCKOPT(so, level, optionname, optval, optlenp, flags, cr) \
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700716 ((so)->so_ops->sop_getsockopt((so), (level), (optionname), \
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800717 (optval), (optlenp), (flags), (cr)))
718#define SOP_SETSOCKOPT(so, level, optionname, optval, optlen, cr) \
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700719 ((so)->so_ops->sop_setsockopt((so), (level), (optionname), \
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800720 (optval), (optlen), (cr)))
721#define SOP_IOCTL(so, cmd, arg, mode, cr, rvalp) \
722 ((so)->so_ops->sop_ioctl((so), (cmd), (arg), (mode), (cr), (rvalp)))
723#define SOP_POLL(so, events, anyyet, reventsp, phpp) \
724 ((so)->so_ops->sop_poll((so), (events), (anyyet), (reventsp), (phpp)))
725#define SOP_CLOSE(so, flag, cr) \
726 ((so)->so_ops->sop_close((so), (flag), (cr)))
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700727
728#endif /* defined(_KERNEL) || defined(_KMEMUSER) */
729
730#ifdef _KERNEL
731
732#define ISALIGNED_cmsghdr(addr) \
733 (((uintptr_t)(addr) & (_CMSG_HDR_ALIGNMENT - 1)) == 0)
734
735#define ROUNDUP_cmsglen(len) \
736 (((len) + _CMSG_HDR_ALIGNMENT - 1) & ~(_CMSG_HDR_ALIGNMENT - 1))
737
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800738#define IS_NON_STREAM_SOCK(vp) \
739 ((vp)->v_type == VSOCK && (vp)->v_stream == NULL)
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700740/*
nn352489acbbea2006-09-11 22:51:59 -0700741 * Macros that operate on struct cmsghdr.
742 * Used in parsing msg_control.
743 * The CMSG_VALID macro does not assume that the last option buffer is padded.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700744 */
745#define CMSG_NEXT(cmsg) \
746 (struct cmsghdr *)((uintptr_t)(cmsg) + \
747 ROUNDUP_cmsglen((cmsg)->cmsg_len))
nn352489acbbea2006-09-11 22:51:59 -0700748#define CMSG_CONTENT(cmsg) (&((cmsg)[1]))
749#define CMSG_CONTENTLEN(cmsg) ((cmsg)->cmsg_len - sizeof (struct cmsghdr))
750#define CMSG_VALID(cmsg, start, end) \
751 (ISALIGNED_cmsghdr(cmsg) && \
752 ((uintptr_t)(cmsg) >= (uintptr_t)(start)) && \
753 ((uintptr_t)(cmsg) < (uintptr_t)(end)) && \
754 ((ssize_t)(cmsg)->cmsg_len >= sizeof (struct cmsghdr)) && \
755 ((uintptr_t)(cmsg) + (cmsg)->cmsg_len <= (uintptr_t)(end)))
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700756
757/*
758 * Maximum size of any argument that is copied in (addresses, options,
759 * access rights). MUST be at least MAXPATHLEN + 3.
760 * BSD and SunOS 4.X limited this to MLEN or MCLBYTES.
761 */
762#define SO_MAXARGSIZE 8192
763
764/*
765 * Convert between vnode and sonode
766 */
767#define VTOSO(vp) ((struct sonode *)((vp)->v_data))
768#define SOTOV(sp) ((sp)->so_vnode)
769
770/*
771 * Internal flags for sobind()
772 */
773#define _SOBIND_REBIND 0x01 /* Bind to existing local address */
774#define _SOBIND_UNSPEC 0x02 /* Bind to unspecified address */
775#define _SOBIND_LOCK_HELD 0x04 /* so_excl_lock held by caller */
776#define _SOBIND_NOXLATE 0x08 /* No addr translation for AF_UNIX */
777#define _SOBIND_XPG4_2 0x10 /* xpg4.2 semantics */
778#define _SOBIND_SOCKBSD 0x20 /* BSD semantics */
779#define _SOBIND_LISTEN 0x40 /* Make into SS_ACCEPTCONN */
780#define _SOBIND_SOCKETPAIR 0x80 /* Internal flag for so_socketpair() */
781 /* to enable listen with backlog = 1 */
782
783/*
784 * Internal flags for sounbind()
785 */
786#define _SOUNBIND_REBIND 0x01 /* Don't clear fields - will rebind */
787
788/*
789 * Internal flags for soconnect()
790 */
791#define _SOCONNECT_NOXLATE 0x01 /* No addr translation for AF_UNIX */
792#define _SOCONNECT_DID_BIND 0x02 /* Unbind when connect fails */
793#define _SOCONNECT_XPG4_2 0x04 /* xpg4.2 semantics */
794
795/*
796 * Internal flags for sodisconnect()
797 */
798#define _SODISCONNECT_LOCK_HELD 0x01 /* so_excl_lock held by caller */
799
800/*
801 * Internal flags for sotpi_getsockopt().
802 */
803#define _SOGETSOCKOPT_XPG4_2 0x01 /* xpg4.2 semantics */
804
805/*
806 * Internal flags for soallocproto*()
807 */
808#define _ALLOC_NOSLEEP 0 /* Don't sleep for memory */
809#define _ALLOC_INTR 1 /* Sleep until interrupt */
810#define _ALLOC_SLEEP 2 /* Sleep forever */
811
812/*
813 * Internal structure for handling AF_UNIX file descriptor passing
814 */
815struct fdbuf {
816 int fd_size; /* In bytes, for kmem_free */
817 int fd_numfd; /* Number of elements below */
818 char *fd_ebuf; /* Extra buffer to free */
819 int fd_ebuflen;
820 frtn_t fd_frtn;
821 struct file *fd_fds[1]; /* One or more */
822};
823#define FDBUF_HDRSIZE (sizeof (struct fdbuf) - sizeof (struct file *))
824
825/*
826 * Variable that can be patched to set what version of socket socket()
827 * will create.
828 */
829extern int so_default_version;
830
831#ifdef DEBUG
832/* Turn on extra testing capabilities */
833#define SOCK_TEST
834#endif /* DEBUG */
835
836#ifdef DEBUG
837char *pr_state(uint_t, uint_t);
838char *pr_addr(int, struct sockaddr *, t_uscalar_t);
839int so_verify_oobstate(struct sonode *);
840#endif /* DEBUG */
841
842/*
843 * DEBUG macros
844 */
Nick Todd8793b362008-09-18 20:50:09 +0100845#if defined(DEBUG)
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700846#define SOCK_DEBUG
847
848extern int sockdebug;
849extern int sockprinterr;
850
851#define eprint(args) printf args
852#define eprintso(so, args) \
853{ if (sockprinterr && ((so)->so_options & SO_DEBUG)) printf args; }
854#define eprintline(error) \
855{ \
856 if (error != EINTR && (sockprinterr || sockdebug > 0)) \
857 printf("socket error %d: line %d file %s\n", \
858 (error), __LINE__, __FILE__); \
859}
860
861#define eprintsoline(so, error) \
862{ if (sockprinterr && ((so)->so_options & SO_DEBUG)) \
863 printf("socket(%p) error %d: line %d file %s\n", \
Nick Todd8793b362008-09-18 20:50:09 +0100864 (void *)(so), (error), __LINE__, __FILE__); \
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700865}
866#define dprint(level, args) { if (sockdebug > (level)) printf args; }
867#define dprintso(so, level, args) \
868{ if (sockdebug > (level) && ((so)->so_options & SO_DEBUG)) printf args; }
869
Nick Todd8793b362008-09-18 20:50:09 +0100870#else /* define(DEBUG) */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700871
872#define eprint(args) {}
873#define eprintso(so, args) {}
874#define eprintline(error) {}
875#define eprintsoline(so, error) {}
876#define dprint(level, args) {}
877#define dprintso(so, level, args) {}
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700878
Nick Todd8793b362008-09-18 20:50:09 +0100879#endif /* defined(DEBUG) */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700880
881extern struct vfsops sock_vfsops;
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800882extern struct vnodeops *socket_vnodeops;
883extern const struct fs_operation_def socket_vnodeops_template[];
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700884
885extern dev_t sockdev;
886
Anders Persson3e95bd42010-06-17 17:22:09 -0700887extern krwlock_t sockconf_lock;
888
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700889/*
890 * sockfs functions
891 */
892extern int sock_getmsg(vnode_t *, struct strbuf *, struct strbuf *,
893 uchar_t *, int *, int, rval_t *);
894extern int sock_putmsg(vnode_t *, struct strbuf *, struct strbuf *,
895 uchar_t, int, int);
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800896extern int sogetvp(char *, vnode_t **, int);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700897extern int sockinit(int, char *);
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800898extern int solookup(int, int, int, struct sockparams **);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700899extern void so_lock_single(struct sonode *);
900extern void so_unlock_single(struct sonode *, int);
901extern int so_lock_read(struct sonode *, int);
902extern int so_lock_read_intr(struct sonode *, int);
903extern void so_unlock_read(struct sonode *);
904extern void *sogetoff(mblk_t *, t_uscalar_t, t_uscalar_t, uint_t);
905extern void so_getopt_srcaddr(void *, t_uscalar_t,
906 void **, t_uscalar_t *);
907extern int so_getopt_unix_close(void *, t_uscalar_t);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700908extern void fdbuf_free(struct fdbuf *);
909extern mblk_t *fdbuf_allocmsg(int, struct fdbuf *);
910extern int fdbuf_create(void *, int, struct fdbuf **);
911extern void so_closefds(void *, t_uscalar_t, int, int);
Andy Fiddamand865fc92020-06-05 14:22:45 +0000912extern void so_truncatecmsg(void *, t_uscalar_t, uint_t);
913
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700914extern int so_getfdopt(void *, t_uscalar_t, int, void **, int *);
915t_uscalar_t so_optlen(void *, t_uscalar_t, int);
916extern void so_cmsg2opt(void *, t_uscalar_t, int, mblk_t *);
917extern t_uscalar_t
918 so_cmsglen(mblk_t *, void *, t_uscalar_t, int);
919extern int so_opt2cmsg(mblk_t *, void *, t_uscalar_t, int,
920 void *, t_uscalar_t);
921extern void soisconnecting(struct sonode *);
922extern void soisconnected(struct sonode *);
923extern void soisdisconnected(struct sonode *, int);
924extern void socantsendmore(struct sonode *);
925extern void socantrcvmore(struct sonode *);
926extern void soseterror(struct sonode *, int);
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800927extern int sogeterr(struct sonode *, boolean_t);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700928extern int sowaitconnected(struct sonode *, int, int);
929
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700930extern ssize_t soreadfile(file_t *, uchar_t *, u_offset_t, int *, size_t);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700931extern void *sock_kstat_init(zoneid_t);
932extern void sock_kstat_fini(zoneid_t, void *);
tz204579745b2692007-10-11 01:06:36 -0700933extern struct sonode *getsonode(int, int *, file_t **);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700934/*
amwda6c28a2007-10-25 16:34:29 -0700935 * Function wrappers (mostly around the sonode switch) for
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700936 * backward compatibility.
937 */
938extern int soaccept(struct sonode *, int, struct sonode **);
939extern int sobind(struct sonode *, struct sockaddr *, socklen_t,
940 int, int);
941extern int solisten(struct sonode *, int);
Anders Persson3e95bd42010-06-17 17:22:09 -0700942extern int soconnect(struct sonode *, struct sockaddr *, socklen_t,
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700943 int, int);
944extern int sorecvmsg(struct sonode *, struct nmsghdr *, struct uio *);
945extern int sosendmsg(struct sonode *, struct nmsghdr *, struct uio *);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700946extern int soshutdown(struct sonode *, int);
947extern int sogetsockopt(struct sonode *, int, int, void *, socklen_t *,
948 int);
949extern int sosetsockopt(struct sonode *, int, int, const void *,
950 t_uscalar_t);
951
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800952extern struct sonode *socreate(struct sockparams *, int, int, int, int,
953 int *);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700954
955extern int so_copyin(const void *, void *, size_t, int);
956extern int so_copyout(const void *, void *, size_t, int);
957
Robert Mustacchi907c2822021-02-01 13:50:02 +0000958/*
959 * Functions to manipulate the use of direct receive callbacks. This should not
960 * be used outside of sockfs and ksocket. These are generally considered a use
961 * once interface for a socket and will cause all outstanding data on the socket
962 * to be flushed.
963 */
964extern int so_krecv_set(sonode_t *, so_krecv_f, void *);
965extern void so_krecv_unblock(sonode_t *);
966
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700967#endif
968
969/*
970 * Internal structure for obtaining sonode information from the socklist.
971 * These types match those corresponding in the sonode structure.
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000972 * This is not a published interface, and may change at any time. It is
973 * used for passing information back up to the kstat consumers. By converting
974 * kernel addresses to strings, we should be able to pass information from
975 * the kernel to userland regardless of n-bit kernel we are using.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700976 */
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000977
978#define ADRSTRLEN (2 * sizeof (uint64_t) + 1)
979
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700980struct sockinfo {
981 uint_t si_size; /* real length of this struct */
982 short si_family;
983 short si_type;
984 ushort_t si_flag;
985 uint_t si_state;
986 uint_t si_ux_laddr_sou_magic;
987 uint_t si_ux_faddr_sou_magic;
988 t_scalar_t si_serv_type;
989 t_uscalar_t si_laddr_soa_len;
990 t_uscalar_t si_faddr_soa_len;
991 uint16_t si_laddr_family;
992 uint16_t si_faddr_family;
993 char si_laddr_sun_path[MAXPATHLEN + 1]; /* NULL terminated */
994 char si_faddr_sun_path[MAXPATHLEN + 1];
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800995 boolean_t si_faddr_noxlate;
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700996 zoneid_t si_szoneid;
Andy Fiddaman78a2e112019-08-22 14:59:11 +0000997 char si_son_straddr[ADRSTRLEN];
998 char si_lvn_straddr[ADRSTRLEN];
999 char si_fvn_straddr[ADRSTRLEN];
1000 uint64_t si_inode;
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -07001001};
1002
Anders Persson3e95bd42010-06-17 17:22:09 -07001003/*
1004 * Subcodes for sockconf() system call
1005 */
1006#define SOCKCONFIG_ADD_SOCK 0
1007#define SOCKCONFIG_REMOVE_SOCK 1
1008#define SOCKCONFIG_ADD_FILTER 2
1009#define SOCKCONFIG_REMOVE_FILTER 3
Alexander Eremin19581f82015-06-05 08:00:15 -07001010#define SOCKCONFIG_GET_SOCKTABLE 4
Anders Persson3e95bd42010-06-17 17:22:09 -07001011
1012/*
1013 * Data structures for configuring socket filters.
1014 */
1015
1016/*
1017 * Placement hint for automatic filters
1018 */
1019typedef enum {
1020 SOF_HINT_NONE,
1021 SOF_HINT_TOP,
1022 SOF_HINT_BOTTOM,
1023 SOF_HINT_BEFORE,
1024 SOF_HINT_AFTER
1025} sof_hint_t;
1026
1027/*
1028 * Socket tuple. Used by sockconfig_filter_props to list socket
1029 * types of interest.
1030 */
1031typedef struct sof_socktuple {
1032 int sofst_family;
1033 int sofst_type;
1034 int sofst_protocol;
1035} sof_socktuple_t;
1036
1037/*
1038 * Socket filter properties used by sockconfig() system call.
1039 */
1040struct sockconfig_filter_props {
1041 char *sfp_modname;
1042 boolean_t sfp_autoattach;
1043 sof_hint_t sfp_hint;
1044 char *sfp_hintarg;
1045 uint_t sfp_socktuple_cnt;
1046 sof_socktuple_t *sfp_socktuple;
1047};
1048
Alexander Eremin19581f82015-06-05 08:00:15 -07001049/*
1050 * Data structures for the in-kernel socket configuration table.
1051 */
1052typedef struct sockconfig_socktable_entry {
1053 int se_family;
1054 int se_type;
1055 int se_protocol;
1056 int se_refcnt;
1057 int se_flags;
1058 char se_modname[MODMAXNAMELEN];
1059 char se_strdev[MAXPATHLEN];
1060} sockconfig_socktable_entry_t;
1061
1062typedef struct sockconfig_socktable {
1063 uint_t num_of_entries;
1064 sockconfig_socktable_entry_t *st_entries;
1065} sockconfig_socktable_t;
1066
Anders Persson3e95bd42010-06-17 17:22:09 -07001067#ifdef _SYSCALL32
1068
1069typedef struct sof_socktuple32 {
1070 int32_t sofst_family;
1071 int32_t sofst_type;
1072 int32_t sofst_protocol;
1073} sof_socktuple32_t;
1074
1075struct sockconfig_filter_props32 {
1076 caddr32_t sfp_modname;
1077 boolean_t sfp_autoattach;
1078 sof_hint_t sfp_hint;
1079 caddr32_t sfp_hintarg;
1080 uint32_t sfp_socktuple_cnt;
1081 caddr32_t sfp_socktuple;
1082};
1083
Alexander Eremin19581f82015-06-05 08:00:15 -07001084typedef struct sockconfig_socktable32 {
1085 uint_t num_of_entries;
1086 caddr32_t st_entries;
1087} sockconfig_socktable32_t;
1088
Anders Persson3e95bd42010-06-17 17:22:09 -07001089#endif /* _SYSCALL32 */
1090
Yu Xiangning0f1702c2008-12-11 20:04:13 -08001091#define SOCKMOD_PATH "socketmod" /* dir where sockmods are stored */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -07001092
1093#ifdef __cplusplus
1094}
1095#endif
1096
1097#endif /* _SYS_SOCKETVAR_H */