xref: /onnv-gate/usr/src/uts/common/fs/sockfs/socktpi.h (revision 12644:4f9a0cd40c5f)
18348SEric.Yu@Sun.COM /*
28348SEric.Yu@Sun.COM  * CDDL HEADER START
38348SEric.Yu@Sun.COM  *
48348SEric.Yu@Sun.COM  * The contents of this file are subject to the terms of the
58348SEric.Yu@Sun.COM  * Common Development and Distribution License (the "License").
68348SEric.Yu@Sun.COM  * You may not use this file except in compliance with the License.
78348SEric.Yu@Sun.COM  *
88348SEric.Yu@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98348SEric.Yu@Sun.COM  * or http://www.opensolaris.org/os/licensing.
108348SEric.Yu@Sun.COM  * See the License for the specific language governing permissions
118348SEric.Yu@Sun.COM  * and limitations under the License.
128348SEric.Yu@Sun.COM  *
138348SEric.Yu@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
148348SEric.Yu@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158348SEric.Yu@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
168348SEric.Yu@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
178348SEric.Yu@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
188348SEric.Yu@Sun.COM  *
198348SEric.Yu@Sun.COM  * CDDL HEADER END
208348SEric.Yu@Sun.COM  */
218348SEric.Yu@Sun.COM 
228348SEric.Yu@Sun.COM /*
23*12643SAnders.Persson@Sun.COM  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
248348SEric.Yu@Sun.COM  */
258348SEric.Yu@Sun.COM 
268348SEric.Yu@Sun.COM #ifndef _SOCKFS_SOCKTPI_H
278348SEric.Yu@Sun.COM #define	_SOCKFS_SOCKTPI_H
288348SEric.Yu@Sun.COM 
298348SEric.Yu@Sun.COM #ifdef	__cplusplus
308348SEric.Yu@Sun.COM extern "C" {
318348SEric.Yu@Sun.COM #endif
328348SEric.Yu@Sun.COM 
338348SEric.Yu@Sun.COM /*
348348SEric.Yu@Sun.COM  * Internal representation used for addresses.
358348SEric.Yu@Sun.COM  */
368348SEric.Yu@Sun.COM struct soaddr {
378348SEric.Yu@Sun.COM 	struct sockaddr	*soa_sa;	/* Actual address */
388348SEric.Yu@Sun.COM 	t_uscalar_t	soa_len;	/* Length in bytes for kmem_free */
398348SEric.Yu@Sun.COM 	t_uscalar_t	soa_maxlen;	/* Allocated length */
408348SEric.Yu@Sun.COM };
418348SEric.Yu@Sun.COM /* Maximum size address for transports that have ADDR_size == 1 */
428348SEric.Yu@Sun.COM #define	SOA_DEFSIZE	128
438348SEric.Yu@Sun.COM 
448348SEric.Yu@Sun.COM struct sonode;
458348SEric.Yu@Sun.COM 
468348SEric.Yu@Sun.COM /*
478348SEric.Yu@Sun.COM  * TPI Sockets
488348SEric.Yu@Sun.COM  * ======================
498348SEric.Yu@Sun.COM  *
508348SEric.Yu@Sun.COM  * A TPI socket can be created by the TPI socket module, or as a
518348SEric.Yu@Sun.COM  * result of fallback. In either case, the TPI related information is
528348SEric.Yu@Sun.COM  * stored in a sotpi_info_t. Sockets that are TPI based from the
538348SEric.Yu@Sun.COM  * beginning will use a sotpi_sonode_t, but fallback case the
548348SEric.Yu@Sun.COM  * sotpi_info_t will be allocated when needed. However, the so_priv
558348SEric.Yu@Sun.COM  * field in the sonode will always point to the sotpi_info_t, and the
568348SEric.Yu@Sun.COM  * structure should only be accessed via so_priv. Use SOTOTPI().
578348SEric.Yu@Sun.COM  *
588348SEric.Yu@Sun.COM  * A TPI socket always corresponds to a VCHR stream representing the
598348SEric.Yu@Sun.COM  * transport provider (e.g. /dev/tcp). This information is retrieved
608348SEric.Yu@Sun.COM  * from the kernel socket configuration table and accessible via
618348SEric.Yu@Sun.COM  * so_sockparams->sp_sdev_info.  sockfs uses this to perform
628348SEric.Yu@Sun.COM  * VOP_ACCESS checks before allowing an open of the transport
638348SEric.Yu@Sun.COM  * provider.
648348SEric.Yu@Sun.COM  *
658348SEric.Yu@Sun.COM  * AF_UNIX Sockets
668348SEric.Yu@Sun.COM  * -------------------------
678348SEric.Yu@Sun.COM  *
688348SEric.Yu@Sun.COM  * When an AF_UNIX socket is bound to a pathname the sockfs creates a
698348SEric.Yu@Sun.COM  * VSOCK vnode in the underlying file system. However, the vnodeops
708348SEric.Yu@Sun.COM  * etc in this VNODE remain those of the underlying file system.
718348SEric.Yu@Sun.COM  * Sockfs uses the v_stream pointer in the underlying file system
728348SEric.Yu@Sun.COM  * VSOCK node to find the sonode bound to the pathname. The bound
738348SEric.Yu@Sun.COM  * pathname vnode is accessed through sti_ux_vp.
748348SEric.Yu@Sun.COM  *
758348SEric.Yu@Sun.COM  * Out of Band Data Handling
768348SEric.Yu@Sun.COM  * -------------------------
778348SEric.Yu@Sun.COM  *
788348SEric.Yu@Sun.COM  * The counts (sti_oobcnt and sti_oobsigcnt) track the number of
798348SEric.Yu@Sun.COM  * urgent indicates that are (logically) queued on the stream head
808348SEric.Yu@Sun.COM  * read queue. The urgent data is queued on the stream head
818348SEric.Yu@Sun.COM  * as follows.
828348SEric.Yu@Sun.COM  *
838348SEric.Yu@Sun.COM  * In the normal case the SIGURG is not generated until
848348SEric.Yu@Sun.COM  * the T_EXDATA_IND arrives at the stream head. However, transports
858348SEric.Yu@Sun.COM  * that have an early indication that urgent data is pending
868348SEric.Yu@Sun.COM  * (e.g. TCP receiving a "new" urgent pointer value) can send up
878348SEric.Yu@Sun.COM  * an M_PCPROTO/SIGURG message to generate the signal early.
888348SEric.Yu@Sun.COM  *
898348SEric.Yu@Sun.COM  * The mark is indicated by either:
908348SEric.Yu@Sun.COM  *  - a T_EXDATA_IND (with no M_DATA b_cont) with MSGMARK set.
918348SEric.Yu@Sun.COM  *    When this message is consumed by sorecvmsg the socket layer
928348SEric.Yu@Sun.COM  *    sets SS_RCVATMARK until data has been consumed past the mark.
938348SEric.Yu@Sun.COM  *  - a message with MSGMARKNEXT set (indicating that the
948348SEric.Yu@Sun.COM  *    first byte of the next message constitutes the mark). When
958348SEric.Yu@Sun.COM  *    the last byte of the MSGMARKNEXT message is consumed in
968348SEric.Yu@Sun.COM  *    the stream head the stream head sets STRATMARK. This flag
978348SEric.Yu@Sun.COM  *    is cleared when at least one byte is read. (Note that
988348SEric.Yu@Sun.COM  *    the MSGMARKNEXT messages can be of zero length when there
998348SEric.Yu@Sun.COM  *    is no previous data to which the marknext can be attached.)
1008348SEric.Yu@Sun.COM  *
1018348SEric.Yu@Sun.COM  * While the T_EXDATA_IND method is the common case which is used
1028348SEric.Yu@Sun.COM  * with all TPI transports, the MSGMARKNEXT method is needed to
1038348SEric.Yu@Sun.COM  * indicate the mark when e.g. the TCP urgent byte has not been
1048348SEric.Yu@Sun.COM  * received yet but the TCP urgent pointer has made TCP generate
1058348SEric.Yu@Sun.COM  * the M_PCSIG/SIGURG.
1068348SEric.Yu@Sun.COM  *
1078348SEric.Yu@Sun.COM  * The signal (the M_PCSIG carrying the SIGURG) and the mark
1088348SEric.Yu@Sun.COM  * indication can not be delivered as a single message, since
1098348SEric.Yu@Sun.COM  * the signal should be delivered as high priority and any mark
1108348SEric.Yu@Sun.COM  * indication must flow with the data. This implies that immediately
1118348SEric.Yu@Sun.COM  * when the SIGURG has been delivered if the stream head queue is
1128348SEric.Yu@Sun.COM  * empty it is impossible to determine if this will be the position
1138348SEric.Yu@Sun.COM  * of the mark. This race condition is resolved by using MSGNOTMARKNEXT
1148348SEric.Yu@Sun.COM  * messages and the STRNOTATMARK flag in the stream head. The
1158348SEric.Yu@Sun.COM  * SIOCATMARK code calls the stream head to wait for either a
1168348SEric.Yu@Sun.COM  * non-empty queue or one of the STR*ATMARK flags being set.
1178348SEric.Yu@Sun.COM  * This implies that any transport that is sending M_PCSIG(SIGURG)
1188348SEric.Yu@Sun.COM  * should send the appropriate MSGNOTMARKNEXT message (which can be
1198348SEric.Yu@Sun.COM  * zero length) after sending an M_PCSIG to prevent SIOCATMARK
1208348SEric.Yu@Sun.COM  * from sleeping unnecessarily.
1218348SEric.Yu@Sun.COM  */
1228348SEric.Yu@Sun.COM 
1238348SEric.Yu@Sun.COM #define	SOTPI_INFO_MAGIC	0x12345678
1248348SEric.Yu@Sun.COM 
1258348SEric.Yu@Sun.COM /*
1268348SEric.Yu@Sun.COM  * Information used by TPI/STREAMS sockets
1278348SEric.Yu@Sun.COM  */
1288348SEric.Yu@Sun.COM typedef struct sotpi_info {
1298348SEric.Yu@Sun.COM 	/*
1308348SEric.Yu@Sun.COM 	 * These fields are initialized once.
1318348SEric.Yu@Sun.COM 	 */
1328348SEric.Yu@Sun.COM 	uint32_t	sti_magic;	/* always set to SOTPI_INFO_MAGIC */
1338348SEric.Yu@Sun.COM 	dev_t		sti_dev;	/* device the sonode represents */
1348348SEric.Yu@Sun.COM 
1358348SEric.Yu@Sun.COM 	struct sockparams *sti_orig_sp;	/* in case of fallback; the orig sp */
1368348SEric.Yu@Sun.COM 
1378348SEric.Yu@Sun.COM 	kmutex_t	sti_plumb_lock;	/* serializes plumbs, and the related */
1388348SEric.Yu@Sun.COM 					/* so_pushcnt */
1398348SEric.Yu@Sun.COM 	short		sti_pushcnt;	/* Number of modules above "sockmod" */
1408348SEric.Yu@Sun.COM 
1418348SEric.Yu@Sun.COM 	kcondvar_t	sti_ack_cv;	/* wait for TPI acks */
1428348SEric.Yu@Sun.COM 
1438348SEric.Yu@Sun.COM 	uint8_t
1448348SEric.Yu@Sun.COM 		sti_laddr_valid : 1,	/* sti_laddr valid for user */
1458348SEric.Yu@Sun.COM 		sti_faddr_valid : 1,	/* sti_faddr valid for user */
1468348SEric.Yu@Sun.COM 		sti_faddr_noxlate : 1,	/* No xlation of faddr for AF_UNIX */
1478348SEric.Yu@Sun.COM 
1488348SEric.Yu@Sun.COM 		sti_direct : 1,		/* transport is directly below */
1498348SEric.Yu@Sun.COM 
1508348SEric.Yu@Sun.COM 		sti_pad_to_bit7 : 4;
1518348SEric.Yu@Sun.COM 
1528348SEric.Yu@Sun.COM 	mblk_t	*sti_ack_mp;		/* TPI ack received from below */
1538348SEric.Yu@Sun.COM 	mblk_t	*sti_unbind_mp;		/* Preallocated T_UNBIND_REQ message */
1548348SEric.Yu@Sun.COM 
1558348SEric.Yu@Sun.COM 	time_t  sti_atime;		/* time of last access */
1568348SEric.Yu@Sun.COM 	time_t  sti_mtime;		/* time of last modification */
1578348SEric.Yu@Sun.COM 	time_t  sti_ctime;		/* time of last attributes change */
1588348SEric.Yu@Sun.COM 
1598348SEric.Yu@Sun.COM 	ushort_t sti_delayed_error;	/* From T_uderror_ind */
1608348SEric.Yu@Sun.COM 	mblk_t	*sti_eaddr_mp;		/* for so_delayed_error */
1618348SEric.Yu@Sun.COM 					/* put here for delayed processing  */
1628348SEric.Yu@Sun.COM 
1638348SEric.Yu@Sun.COM 	mblk_t	*sti_conn_ind_head;	/* b_next list of T_CONN_IND */
1648348SEric.Yu@Sun.COM 	mblk_t	*sti_conn_ind_tail;
1658348SEric.Yu@Sun.COM 
1668348SEric.Yu@Sun.COM 	uint_t	sti_oobsigcnt;		/* Number of SIGURG generated */
1678348SEric.Yu@Sun.COM 	uint_t	sti_oobcnt;		/* Number of T_EXDATA_IND queued */
1688348SEric.Yu@Sun.COM 
1698348SEric.Yu@Sun.COM 	/* From T_info_ack */
1708348SEric.Yu@Sun.COM 	t_uscalar_t	sti_tsdu_size;
1718348SEric.Yu@Sun.COM 	t_uscalar_t	sti_etsdu_size;
1728348SEric.Yu@Sun.COM 	t_scalar_t	sti_addr_size;
1738348SEric.Yu@Sun.COM 	t_uscalar_t	sti_opt_size;
1748348SEric.Yu@Sun.COM 	t_uscalar_t	sti_tidu_size;
1758348SEric.Yu@Sun.COM 	t_scalar_t	sti_serv_type;
1768348SEric.Yu@Sun.COM 
1778348SEric.Yu@Sun.COM 	/* From T_capability_ack */
1788348SEric.Yu@Sun.COM 	t_uscalar_t	sti_acceptor_id;
1798348SEric.Yu@Sun.COM 
1808348SEric.Yu@Sun.COM 	/* Internal provider information */
1818348SEric.Yu@Sun.COM 	struct tpi_provinfo	*sti_provinfo;
1828348SEric.Yu@Sun.COM 
1838348SEric.Yu@Sun.COM 	/*
1848348SEric.Yu@Sun.COM 	 * The local and remote addresses have multiple purposes
1858348SEric.Yu@Sun.COM 	 * but one of the key reasons for their existence and careful
1868348SEric.Yu@Sun.COM 	 * tracking in sockfs is to support getsockname and getpeername
1878348SEric.Yu@Sun.COM 	 * when the transport does not handle the TI_GET*NAME ioctls
1888348SEric.Yu@Sun.COM 	 * and caching when it does (signalled by valid bits in so_state).
1898348SEric.Yu@Sun.COM 	 * When all transports support the new TPI (with T_ADDR_REQ)
1908348SEric.Yu@Sun.COM 	 * we can revisit this code.
1918348SEric.Yu@Sun.COM 	 *
1928348SEric.Yu@Sun.COM 	 * The other usage of sti_faddr is to keep the "connected to"
1938348SEric.Yu@Sun.COM 	 * address for datagram sockets.
1948348SEric.Yu@Sun.COM 	 *
1958348SEric.Yu@Sun.COM 	 * Finally, for AF_UNIX both local and remote addresses are used
1968348SEric.Yu@Sun.COM 	 * to record the sockaddr_un since we use a separate namespace
1978348SEric.Yu@Sun.COM 	 * in the loopback transport.
1988348SEric.Yu@Sun.COM 	 */
1998348SEric.Yu@Sun.COM 	struct soaddr sti_laddr;	/* Local address */
2008348SEric.Yu@Sun.COM 	struct soaddr sti_faddr;	/* Peer address */
2018348SEric.Yu@Sun.COM #define	sti_laddr_sa		sti_laddr.soa_sa
2028348SEric.Yu@Sun.COM #define	sti_faddr_sa		sti_faddr.soa_sa
2038348SEric.Yu@Sun.COM #define	sti_laddr_len		sti_laddr.soa_len
2048348SEric.Yu@Sun.COM #define	sti_faddr_len		sti_faddr.soa_len
2058348SEric.Yu@Sun.COM #define	sti_laddr_maxlen	sti_laddr.soa_maxlen
2068348SEric.Yu@Sun.COM #define	sti_faddr_maxlen	sti_faddr.soa_maxlen
2078348SEric.Yu@Sun.COM 
2088348SEric.Yu@Sun.COM 	/*
2098348SEric.Yu@Sun.COM 	 * For AF_UNIX sockets:
2108348SEric.Yu@Sun.COM 	 *
2118348SEric.Yu@Sun.COM 	 * sti_ux_laddr/faddr records the internal addresses used with the
2128348SEric.Yu@Sun.COM 	 * transport. sti_ux_vp and v_stream->sd_vnode form the
2138348SEric.Yu@Sun.COM 	 * cross-linkage between the underlying fs vnode corresponding
2148348SEric.Yu@Sun.COM 	 * to the bound sockaddr_un and the socket node.
2158348SEric.Yu@Sun.COM 	 */
2168348SEric.Yu@Sun.COM 	struct so_ux_addr sti_ux_laddr; /* laddr bound with the transport */
2178348SEric.Yu@Sun.COM 	struct so_ux_addr sti_ux_faddr; /* temporary peer address */
2188348SEric.Yu@Sun.COM 	struct vnode	*sti_ux_bound_vp; /* bound AF_UNIX file system vnode */
2198348SEric.Yu@Sun.COM 	struct sonode	*sti_next_so; 	/* next sonode on socklist	*/
2208348SEric.Yu@Sun.COM 	struct sonode	*sti_prev_so;	/* previous sonode on socklist	*/
2218348SEric.Yu@Sun.COM 	mblk_t	*sti_discon_ind_mp;	/* T_DISCON_IND received from below */
2228348SEric.Yu@Sun.COM 
2238348SEric.Yu@Sun.COM 	/*
2248348SEric.Yu@Sun.COM 	 * For NL7C sockets:
2258348SEric.Yu@Sun.COM 	 *
2268348SEric.Yu@Sun.COM 	 * sti_nl7c_flags	the NL7C state of URL processing.
2278348SEric.Yu@Sun.COM 	 *
2288348SEric.Yu@Sun.COM 	 * sti_nl7c_rcv_mp	mblk_t chain of already received data to be
2298348SEric.Yu@Sun.COM 	 *			passed up to the app after NL7C gives up on
2308348SEric.Yu@Sun.COM 	 *			a socket.
2318348SEric.Yu@Sun.COM 	 *
2328348SEric.Yu@Sun.COM 	 * sti_nl7c_rcv_rval	returned rval for last mblk_t from above.
2338348SEric.Yu@Sun.COM 	 *
2348348SEric.Yu@Sun.COM 	 * sti_nl7c_uri		the URI currently being processed.
2358348SEric.Yu@Sun.COM 	 *
2368348SEric.Yu@Sun.COM 	 * sti_nl7c_rtime	URI request gethrestime_sec().
2378348SEric.Yu@Sun.COM 	 *
2388348SEric.Yu@Sun.COM 	 * sti_nl7c_addr	pointer returned by nl7c_addr_lookup().
2398348SEric.Yu@Sun.COM 	 */
2408348SEric.Yu@Sun.COM 	uint64_t	sti_nl7c_flags;
2418348SEric.Yu@Sun.COM 	mblk_t		*sti_nl7c_rcv_mp;
2428348SEric.Yu@Sun.COM 	int64_t		sti_nl7c_rcv_rval;
2438348SEric.Yu@Sun.COM 	void		*sti_nl7c_uri;
2448348SEric.Yu@Sun.COM 	time_t		sti_nl7c_rtime;
2458348SEric.Yu@Sun.COM 	void		*sti_nl7c_addr;
2468348SEric.Yu@Sun.COM } sotpi_info_t;
2478348SEric.Yu@Sun.COM 
2488348SEric.Yu@Sun.COM struct T_capability_ack;
2498348SEric.Yu@Sun.COM 
2508348SEric.Yu@Sun.COM extern sonodeops_t sotpi_sonodeops;
2518348SEric.Yu@Sun.COM 
2528348SEric.Yu@Sun.COM extern int	socktpi_init(void);
2538963SAnders.Persson@Sun.COM extern int	sotpi_convert_sonode(struct sonode *, struct sockparams *,
2548963SAnders.Persson@Sun.COM 		    boolean_t *, queue_t **, struct cred *);
2558963SAnders.Persson@Sun.COM extern void	sotpi_revert_sonode(struct sonode *, struct cred *);
2568348SEric.Yu@Sun.COM extern void	sotpi_update_state(struct sonode *, struct T_capability_ack *,
2578348SEric.Yu@Sun.COM 		    struct sockaddr *, socklen_t, struct sockaddr *, socklen_t,
2588348SEric.Yu@Sun.COM 		    short);
2598348SEric.Yu@Sun.COM 
2608348SEric.Yu@Sun.COM extern sotpi_info_t 	*sotpi_sototpi(struct sonode *);
2618348SEric.Yu@Sun.COM #ifdef DEBUG
2628348SEric.Yu@Sun.COM #define	SOTOTPI(so)	(sotpi_sototpi(so))
2638348SEric.Yu@Sun.COM #else
2648348SEric.Yu@Sun.COM #define	SOTOTPI(so)	((sotpi_info_t *)(so)->so_priv)
2658348SEric.Yu@Sun.COM #endif
2668348SEric.Yu@Sun.COM 
2678348SEric.Yu@Sun.COM /* for consumers outside sockfs */
2688348SEric.Yu@Sun.COM #define	_SOTOTPI(so)	((sotpi_info_t *)(so)->so_priv)
2698348SEric.Yu@Sun.COM 
2708348SEric.Yu@Sun.COM #ifdef	__cplusplus
2718348SEric.Yu@Sun.COM }
2728348SEric.Yu@Sun.COM #endif
2738348SEric.Yu@Sun.COM 
2748348SEric.Yu@Sun.COM #endif /* _SOCKFS_SOCKTPI_H */
275