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