10f1702c5SYu Xiangning /*
20f1702c5SYu Xiangning  * CDDL HEADER START
30f1702c5SYu Xiangning  *
40f1702c5SYu Xiangning  * The contents of this file are subject to the terms of the
50f1702c5SYu Xiangning  * Common Development and Distribution License (the "License").
60f1702c5SYu Xiangning  * You may not use this file except in compliance with the License.
70f1702c5SYu Xiangning  *
80f1702c5SYu Xiangning  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90f1702c5SYu Xiangning  * or http://www.opensolaris.org/os/licensing.
100f1702c5SYu Xiangning  * See the License for the specific language governing permissions
110f1702c5SYu Xiangning  * and limitations under the License.
120f1702c5SYu Xiangning  *
130f1702c5SYu Xiangning  * When distributing Covered Code, include this CDDL HEADER in each
140f1702c5SYu Xiangning  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150f1702c5SYu Xiangning  * If applicable, add the following below this CDDL HEADER, with the
160f1702c5SYu Xiangning  * fields enclosed by brackets "[]" replaced with your own identifying
170f1702c5SYu Xiangning  * information: Portions Copyright [yyyy] [name of copyright owner]
180f1702c5SYu Xiangning  *
190f1702c5SYu Xiangning  * CDDL HEADER END
200f1702c5SYu Xiangning  */
210f1702c5SYu Xiangning /*
223e95bd4aSAnders Persson  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
2378a2e113SAndy Fiddaman  * Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
24*2ad53042SDan McDonald  * Copyright 2020 Joyent, Inc.
250f1702c5SYu Xiangning  */
260f1702c5SYu Xiangning 
270f1702c5SYu Xiangning #ifndef _SYS_SOCKET_PROTO_H_
280f1702c5SYu Xiangning #define	_SYS_SOCKET_PROTO_H_
290f1702c5SYu Xiangning 
300f1702c5SYu Xiangning #ifdef	__cplusplus
310f1702c5SYu Xiangning extern "C" {
320f1702c5SYu Xiangning #endif
330f1702c5SYu Xiangning 
340f1702c5SYu Xiangning #include <sys/socket.h>
3533697085SGordon Ross #include <sys/stream.h>
3678a2e113SAndy Fiddaman #include <sys/vnode.h>
370f1702c5SYu Xiangning 
380f1702c5SYu Xiangning /*
390f1702c5SYu Xiangning  * Generation count
400f1702c5SYu Xiangning  */
410f1702c5SYu Xiangning typedef uint64_t sock_connid_t;
420f1702c5SYu Xiangning 
430f1702c5SYu Xiangning #define	SOCK_CONNID_INIT(id) {	\
440f1702c5SYu Xiangning 	(id) = 0;		\
450f1702c5SYu Xiangning }
460f1702c5SYu Xiangning #define	SOCK_CONNID_BUMP(id)		(++(id))
470f1702c5SYu Xiangning #define	SOCK_CONNID_LT(id1, id2)	((int64_t)((id1)-(id2)) < 0)
480f1702c5SYu Xiangning 
490f1702c5SYu Xiangning /* Socket protocol properties */
500f1702c5SYu Xiangning struct sock_proto_props {
510f1702c5SYu Xiangning 	uint_t sopp_flags;		/* options to set */
520f1702c5SYu Xiangning 	ushort_t sopp_wroff;		/* write offset */
530f1702c5SYu Xiangning 	ssize_t sopp_txhiwat;		/* tx hi water mark */
540f1702c5SYu Xiangning 	ssize_t sopp_txlowat;		/* tx lo water mark */
550f1702c5SYu Xiangning 	ssize_t	sopp_rxhiwat;		/* recv high water mark */
560f1702c5SYu Xiangning 	ssize_t	sopp_rxlowat;		/* recv low water mark */
570f1702c5SYu Xiangning 	ssize_t sopp_maxblk;		/* maximum message block size */
580f1702c5SYu Xiangning 	ssize_t sopp_maxpsz;		/* maximum packet size */
590f1702c5SYu Xiangning 	ssize_t sopp_minpsz;		/* minimum packet size */
600f1702c5SYu Xiangning 	ushort_t sopp_tail;		/* space available at the end */
610f1702c5SYu Xiangning 	uint_t	sopp_zcopyflag;		/* zero copy flag */
620f1702c5SYu Xiangning 	boolean_t sopp_oobinline;	/* OOB inline */
630f1702c5SYu Xiangning 	uint_t sopp_rcvtimer;		/* delayed recv notification (time) */
640f1702c5SYu Xiangning 	uint32_t sopp_rcvthresh;	/* delayed recv notification (bytes) */
650f1702c5SYu Xiangning 	socklen_t sopp_maxaddrlen;	/* maximum size of protocol address */
66081c0aa8SAnders Persson 	boolean_t sopp_loopback;	/* loopback connection */
670f1702c5SYu Xiangning };
680f1702c5SYu Xiangning 
690f1702c5SYu Xiangning /* flags to determine which socket options are set */
700f1702c5SYu Xiangning #define	SOCKOPT_WROFF		0x0001	/* set write offset */
710f1702c5SYu Xiangning #define	SOCKOPT_RCVHIWAT	0x0002	/* set read side high water */
720f1702c5SYu Xiangning #define	SOCKOPT_RCVLOWAT	0x0004	/* set read side high water */
730f1702c5SYu Xiangning #define	SOCKOPT_MAXBLK		0x0008	/* set maximum message block size */
740f1702c5SYu Xiangning #define	SOCKOPT_TAIL		0x0010	/* set the extra allocated space */
750f1702c5SYu Xiangning #define	SOCKOPT_ZCOPY		0x0020	/* set/unset zero copy for sendfile */
760f1702c5SYu Xiangning #define	SOCKOPT_MAXPSZ		0x0040	/* set maxpsz for protocols */
770f1702c5SYu Xiangning #define	SOCKOPT_OOBINLINE	0x0080	/* set oob inline processing */
780f1702c5SYu Xiangning #define	SOCKOPT_RCVTIMER	0x0100
790f1702c5SYu Xiangning #define	SOCKOPT_RCVTHRESH	0x0200
800f1702c5SYu Xiangning #define	SOCKOPT_MAXADDRLEN	0x0400	/* set max address length */
810f1702c5SYu Xiangning #define	SOCKOPT_MINPSZ		0x0800	/* set minpsz for protocols */
82081c0aa8SAnders Persson #define	SOCKOPT_LOOPBACK	0x1000	/* set loopback */
830f1702c5SYu Xiangning 
840f1702c5SYu Xiangning #define	IS_SO_OOB_INLINE(so)	((so)->so_proto_props.sopp_oobinline)
850f1702c5SYu Xiangning 
860f1702c5SYu Xiangning #ifdef _KERNEL
870f1702c5SYu Xiangning 
880f1702c5SYu Xiangning struct T_capability_ack;
890f1702c5SYu Xiangning 
900f1702c5SYu Xiangning typedef struct sock_upcalls_s sock_upcalls_t;
910f1702c5SYu Xiangning typedef struct sock_downcalls_s sock_downcalls_t;
920f1702c5SYu Xiangning 
930f1702c5SYu Xiangning /*
940f1702c5SYu Xiangning  * Upcall and downcall handle for sockfs and transport layer.
950f1702c5SYu Xiangning  */
960f1702c5SYu Xiangning typedef struct __sock_upper_handle *sock_upper_handle_t;
970f1702c5SYu Xiangning typedef struct __sock_lower_handle *sock_lower_handle_t;
980f1702c5SYu Xiangning 
990f1702c5SYu Xiangning struct sock_downcalls_s {
1000f1702c5SYu Xiangning 	void	(*sd_activate)(sock_lower_handle_t, sock_upper_handle_t,
1010f1702c5SYu Xiangning 		    sock_upcalls_t *, int, cred_t *);
1020f1702c5SYu Xiangning 	int	(*sd_accept)(sock_lower_handle_t, sock_lower_handle_t,
1030f1702c5SYu Xiangning 		    sock_upper_handle_t, cred_t *);
1040f1702c5SYu Xiangning 	int	(*sd_bind)(sock_lower_handle_t, struct sockaddr *, socklen_t,
1050f1702c5SYu Xiangning 		    cred_t *);
1060f1702c5SYu Xiangning 	int	(*sd_listen)(sock_lower_handle_t, int, cred_t *);
1070f1702c5SYu Xiangning 	int	(*sd_connect)(sock_lower_handle_t, const struct sockaddr *,
1080f1702c5SYu Xiangning 		    socklen_t, sock_connid_t *, cred_t *);
1090f1702c5SYu Xiangning 	int	(*sd_getpeername)(sock_lower_handle_t, struct sockaddr *,
1100f1702c5SYu Xiangning 		    socklen_t *, cred_t *);
1110f1702c5SYu Xiangning 	int	(*sd_getsockname)(sock_lower_handle_t, struct sockaddr *,
1120f1702c5SYu Xiangning 		    socklen_t *, cred_t *);
1130f1702c5SYu Xiangning 	int	(*sd_getsockopt)(sock_lower_handle_t, int, int, void *,
1140f1702c5SYu Xiangning 		    socklen_t *, cred_t *);
1150f1702c5SYu Xiangning 	int	(*sd_setsockopt)(sock_lower_handle_t, int, int, const void *,
1160f1702c5SYu Xiangning 		    socklen_t, cred_t *);
1170f1702c5SYu Xiangning 	int	(*sd_send)(sock_lower_handle_t, mblk_t *, struct nmsghdr *,
1180f1702c5SYu Xiangning 		    cred_t *);
1190f1702c5SYu Xiangning 	int	(*sd_send_uio)(sock_lower_handle_t, uio_t *, struct nmsghdr *,
1200f1702c5SYu Xiangning 		    cred_t *);
1210f1702c5SYu Xiangning 	int	(*sd_recv_uio)(sock_lower_handle_t, uio_t *, struct nmsghdr *,
1220f1702c5SYu Xiangning 		    cred_t *);
1230f1702c5SYu Xiangning 	short	(*sd_poll)(sock_lower_handle_t, short, int, cred_t *);
1240f1702c5SYu Xiangning 	int	(*sd_shutdown)(sock_lower_handle_t, int, cred_t *);
1250f1702c5SYu Xiangning 	void	(*sd_clr_flowctrl)(sock_lower_handle_t);
1260f1702c5SYu Xiangning 	int	(*sd_ioctl)(sock_lower_handle_t, int, intptr_t, int,
1270f1702c5SYu Xiangning 		    int32_t *, cred_t *);
1280f1702c5SYu Xiangning 	int	(*sd_close)(sock_lower_handle_t, int, cred_t *);
1290f1702c5SYu Xiangning };
1300f1702c5SYu Xiangning 
1310f1702c5SYu Xiangning typedef sock_lower_handle_t (*so_proto_create_func_t)(int, int, int,
1320f1702c5SYu Xiangning     sock_downcalls_t **, uint_t *, int *, int, cred_t *);
1330f1702c5SYu Xiangning 
1343e95bd4aSAnders Persson typedef struct sock_quiesce_arg {
1353e95bd4aSAnders Persson 	mblk_t *soqa_exdata_mp;
1363e95bd4aSAnders Persson 	mblk_t *soqa_urgmark_mp;
1373e95bd4aSAnders Persson } sock_quiesce_arg_t;
1383e95bd4aSAnders Persson typedef mblk_t *(*so_proto_quiesced_cb_t)(sock_upper_handle_t,
1393e95bd4aSAnders Persson     sock_quiesce_arg_t *, struct T_capability_ack *, struct sockaddr *,
1403e95bd4aSAnders Persson     socklen_t, struct sockaddr *, socklen_t, short);
14141174437SAnders Persson typedef int (*so_proto_fallback_func_t)(sock_lower_handle_t, queue_t *,
1423e95bd4aSAnders Persson     boolean_t, so_proto_quiesced_cb_t, sock_quiesce_arg_t *);
1430f1702c5SYu Xiangning 
1440a0e9771SDarren Reed /*
1450a0e9771SDarren Reed  * These functions return EOPNOTSUPP and are intended for the sockfs
1460a0e9771SDarren Reed  * developer that doesn't wish to supply stubs for every function themselves.
1470a0e9771SDarren Reed  */
1480a0e9771SDarren Reed extern int sock_accept_notsupp(sock_lower_handle_t, sock_lower_handle_t,
1490a0e9771SDarren Reed     sock_upper_handle_t, cred_t *);
1500a0e9771SDarren Reed extern int sock_bind_notsupp(sock_lower_handle_t, struct sockaddr *,
1510a0e9771SDarren Reed     socklen_t, cred_t *);
1520a0e9771SDarren Reed extern int sock_listen_notsupp(sock_lower_handle_t, int, cred_t *);
1530a0e9771SDarren Reed extern int sock_connect_notsupp(sock_lower_handle_t,
1540a0e9771SDarren Reed     const struct sockaddr *, socklen_t, sock_connid_t *, cred_t *);
1550a0e9771SDarren Reed extern int sock_getpeername_notsupp(sock_lower_handle_t, struct sockaddr *,
1560a0e9771SDarren Reed     socklen_t *, cred_t *);
1570a0e9771SDarren Reed extern int sock_getsockname_notsupp(sock_lower_handle_t, struct sockaddr *,
1580a0e9771SDarren Reed     socklen_t *, cred_t *);
1590a0e9771SDarren Reed extern int sock_getsockopt_notsupp(sock_lower_handle_t, int, int, void *,
1600a0e9771SDarren Reed     socklen_t *, cred_t *);
1610a0e9771SDarren Reed extern int sock_setsockopt_notsupp(sock_lower_handle_t, int, int,
1620a0e9771SDarren Reed     const void *, socklen_t, cred_t *);
1630a0e9771SDarren Reed extern int sock_send_notsupp(sock_lower_handle_t, mblk_t *,
1640a0e9771SDarren Reed     struct nmsghdr *, cred_t *);
1650a0e9771SDarren Reed extern int sock_send_uio_notsupp(sock_lower_handle_t, uio_t *,
1660a0e9771SDarren Reed     struct nmsghdr *, cred_t *);
1670a0e9771SDarren Reed extern int sock_recv_uio_notsupp(sock_lower_handle_t, uio_t *,
1680a0e9771SDarren Reed     struct nmsghdr *, cred_t *);
1690a0e9771SDarren Reed extern short sock_poll_notsupp(sock_lower_handle_t, short, int, cred_t *);
1700a0e9771SDarren Reed extern int sock_shutdown_notsupp(sock_lower_handle_t, int, cred_t *);
1710a0e9771SDarren Reed extern void sock_clr_flowctrl_notsupp(sock_lower_handle_t);
1720a0e9771SDarren Reed extern int sock_ioctl_notsupp(sock_lower_handle_t, int, intptr_t, int,
1730a0e9771SDarren Reed     int32_t *, cred_t *);
1740a0e9771SDarren Reed extern int sock_close_notsupp(sock_lower_handle_t, int, cred_t *);
1750a0e9771SDarren Reed 
1760f1702c5SYu Xiangning /*
1770f1702c5SYu Xiangning  * Upcalls and related information
1780f1702c5SYu Xiangning  */
1790f1702c5SYu Xiangning 
1800f1702c5SYu Xiangning /*
1810f1702c5SYu Xiangning  * su_opctl() actions
1820f1702c5SYu Xiangning  */
1830f1702c5SYu Xiangning typedef enum sock_opctl_action {
1840f1702c5SYu Xiangning 	SOCK_OPCTL_ENAB_ACCEPT = 0,
1850f1702c5SYu Xiangning 	SOCK_OPCTL_SHUT_SEND,
1860f1702c5SYu Xiangning 	SOCK_OPCTL_SHUT_RECV
1870f1702c5SYu Xiangning } sock_opctl_action_t;
1880f1702c5SYu Xiangning 
1890f1702c5SYu Xiangning struct sock_upcalls_s {
1900f1702c5SYu Xiangning 	sock_upper_handle_t (*su_newconn)(sock_upper_handle_t,
1910f1702c5SYu Xiangning 	    sock_lower_handle_t, sock_downcalls_t *, cred_t *, pid_t,
1920f1702c5SYu Xiangning 	    sock_upcalls_t **);
1930f1702c5SYu Xiangning 	void	(*su_connected)(sock_upper_handle_t, sock_connid_t, cred_t *,
1940f1702c5SYu Xiangning 	    pid_t);
1950f1702c5SYu Xiangning 	int	(*su_disconnected)(sock_upper_handle_t, sock_connid_t, int);
1960f1702c5SYu Xiangning 	void	(*su_opctl)(sock_upper_handle_t, sock_opctl_action_t,
1970f1702c5SYu Xiangning 	    uintptr_t);
1980f1702c5SYu Xiangning 	ssize_t	(*su_recv)(sock_upper_handle_t, mblk_t *, size_t, int,
1990f1702c5SYu Xiangning 		    int *, boolean_t *);
2000f1702c5SYu Xiangning 	void	(*su_set_proto_props)(sock_upper_handle_t,
2010f1702c5SYu Xiangning 		    struct sock_proto_props *);
2020f1702c5SYu Xiangning 	void	(*su_txq_full)(sock_upper_handle_t, boolean_t);
2030f1702c5SYu Xiangning 	void	(*su_signal_oob)(sock_upper_handle_t, ssize_t);
2040f1702c5SYu Xiangning 	void	(*su_zcopy_notify)(sock_upper_handle_t);
2050f1702c5SYu Xiangning 	void	(*su_set_error)(sock_upper_handle_t, int);
206*2ad53042SDan McDonald 	/*
207*2ad53042SDan McDonald 	 * NOTE: This function frees upper handle items. Caller cannot
208*2ad53042SDan McDonald 	 * rely on them after this upcall.
209*2ad53042SDan McDonald 	 */
2103e95bd4aSAnders Persson 	void	(*su_closed)(sock_upper_handle_t);
211*2ad53042SDan McDonald 	/*
212*2ad53042SDan McDonald 	 * NOTE: This function MUST be implemented without using lower-level
213*2ad53042SDan McDonald 	 * downcalls or accesses. This allows callers to ensure su_closed()
214*2ad53042SDan McDonald 	 * upcalls can happen indepdently or concurrently.
215*2ad53042SDan McDonald 	 */
21678a2e113SAndy Fiddaman 	vnode_t *(*su_get_vnode)(sock_upper_handle_t);
2170f1702c5SYu Xiangning };
2180f1702c5SYu Xiangning 
2190f1702c5SYu Xiangning #define	SOCK_UC_VERSION		sizeof (sock_upcalls_t)
2200f1702c5SYu Xiangning #define	SOCK_DC_VERSION		sizeof (sock_downcalls_t)
2210f1702c5SYu Xiangning 
2220f1702c5SYu Xiangning #define	SOCKET_RECVHIWATER	(48 * 1024)
2230f1702c5SYu Xiangning #define	SOCKET_RECVLOWATER	1024
2240f1702c5SYu Xiangning 
2250f1702c5SYu Xiangning #define	SOCKET_NO_RCVTIMER	0
2260f1702c5SYu Xiangning #define	SOCKET_TIMER_INTERVAL	50
2270f1702c5SYu Xiangning 
2280f1702c5SYu Xiangning #endif /* _KERNEL */
2290f1702c5SYu Xiangning 
2300f1702c5SYu Xiangning #ifdef	__cplusplus
2310f1702c5SYu Xiangning }
2320f1702c5SYu Xiangning #endif
2330f1702c5SYu Xiangning 
2340f1702c5SYu Xiangning #endif /* _SYS_SOCKET_PROTO_H_ */
235