1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
  24  * Copyright 2020 Joyent, Inc.
  25  */
  26 
  27 #ifndef _SYS_SOCKET_PROTO_H_
  28 #define _SYS_SOCKET_PROTO_H_
  29 
  30 #ifdef  __cplusplus
  31 extern "C" {
  32 #endif
  33 
  34 #include <sys/socket.h>
  35 #include <sys/stream.h>
  36 #include <sys/vnode.h>
  37 
  38 /*
  39  * Generation count
  40  */
  41 typedef uint64_t sock_connid_t;
  42 
  43 #define SOCK_CONNID_INIT(id) {  \
  44         (id) = 0;               \
  45 }
  46 #define SOCK_CONNID_BUMP(id)            (++(id))
  47 #define SOCK_CONNID_LT(id1, id2)        ((int64_t)((id1)-(id2)) < 0)
  48 
  49 /* Socket protocol properties */
  50 struct sock_proto_props {
  51         uint_t sopp_flags;              /* options to set */
  52         ushort_t sopp_wroff;            /* write offset */
  53         ssize_t sopp_txhiwat;           /* tx hi water mark */
  54         ssize_t sopp_txlowat;           /* tx lo water mark */
  55         ssize_t sopp_rxhiwat;           /* recv high water mark */
  56         ssize_t sopp_rxlowat;           /* recv low water mark */
  57         ssize_t sopp_maxblk;            /* maximum message block size */
  58         ssize_t sopp_maxpsz;            /* maximum packet size */
  59         ssize_t sopp_minpsz;            /* minimum packet size */
  60         ushort_t sopp_tail;             /* space available at the end */
  61         uint_t  sopp_zcopyflag;         /* zero copy flag */
  62         boolean_t sopp_oobinline;       /* OOB inline */
  63         uint_t sopp_rcvtimer;           /* delayed recv notification (time) */
  64         uint32_t sopp_rcvthresh;        /* delayed recv notification (bytes) */
  65         socklen_t sopp_maxaddrlen;      /* maximum size of protocol address */
  66         boolean_t sopp_loopback;        /* loopback connection */
  67 };
  68 
  69 /* flags to determine which socket options are set */
  70 #define SOCKOPT_WROFF           0x0001  /* set write offset */
  71 #define SOCKOPT_RCVHIWAT        0x0002  /* set read side high water */
  72 #define SOCKOPT_RCVLOWAT        0x0004  /* set read side high water */
  73 #define SOCKOPT_MAXBLK          0x0008  /* set maximum message block size */
  74 #define SOCKOPT_TAIL            0x0010  /* set the extra allocated space */
  75 #define SOCKOPT_ZCOPY           0x0020  /* set/unset zero copy for sendfile */
  76 #define SOCKOPT_MAXPSZ          0x0040  /* set maxpsz for protocols */
  77 #define SOCKOPT_OOBINLINE       0x0080  /* set oob inline processing */
  78 #define SOCKOPT_RCVTIMER        0x0100
  79 #define SOCKOPT_RCVTHRESH       0x0200
  80 #define SOCKOPT_MAXADDRLEN      0x0400  /* set max address length */
  81 #define SOCKOPT_MINPSZ          0x0800  /* set minpsz for protocols */
  82 #define SOCKOPT_LOOPBACK        0x1000  /* set loopback */
  83 
  84 #define IS_SO_OOB_INLINE(so)    ((so)->so_proto_props.sopp_oobinline)
  85 
  86 #ifdef _KERNEL
  87 
  88 struct T_capability_ack;
  89 
  90 typedef struct sock_upcalls_s sock_upcalls_t;
  91 typedef struct sock_downcalls_s sock_downcalls_t;
  92 
  93 /*
  94  * Upcall and downcall handle for sockfs and transport layer.
  95  */
  96 typedef struct __sock_upper_handle *sock_upper_handle_t;
  97 typedef struct __sock_lower_handle *sock_lower_handle_t;
  98 
  99 struct sock_downcalls_s {
 100         void    (*sd_activate)(sock_lower_handle_t, sock_upper_handle_t,
 101                     sock_upcalls_t *, int, cred_t *);
 102         int     (*sd_accept)(sock_lower_handle_t, sock_lower_handle_t,
 103                     sock_upper_handle_t, cred_t *);
 104         int     (*sd_bind)(sock_lower_handle_t, struct sockaddr *, socklen_t,
 105                     cred_t *);
 106         int     (*sd_listen)(sock_lower_handle_t, int, cred_t *);
 107         int     (*sd_connect)(sock_lower_handle_t, const struct sockaddr *,
 108                     socklen_t, sock_connid_t *, cred_t *);
 109         int     (*sd_getpeername)(sock_lower_handle_t, struct sockaddr *,
 110                     socklen_t *, cred_t *);
 111         int     (*sd_getsockname)(sock_lower_handle_t, struct sockaddr *,
 112                     socklen_t *, cred_t *);
 113         int     (*sd_getsockopt)(sock_lower_handle_t, int, int, void *,
 114                     socklen_t *, cred_t *);
 115         int     (*sd_setsockopt)(sock_lower_handle_t, int, int, const void *,
 116                     socklen_t, cred_t *);
 117         int     (*sd_send)(sock_lower_handle_t, mblk_t *, struct nmsghdr *,
 118                     cred_t *);
 119         int     (*sd_send_uio)(sock_lower_handle_t, uio_t *, struct nmsghdr *,
 120                     cred_t *);
 121         int     (*sd_recv_uio)(sock_lower_handle_t, uio_t *, struct nmsghdr *,
 122                     cred_t *);
 123         short   (*sd_poll)(sock_lower_handle_t, short, int, cred_t *);
 124         int     (*sd_shutdown)(sock_lower_handle_t, int, cred_t *);
 125         void    (*sd_clr_flowctrl)(sock_lower_handle_t);
 126         int     (*sd_ioctl)(sock_lower_handle_t, int, intptr_t, int,
 127                     int32_t *, cred_t *);
 128         int     (*sd_close)(sock_lower_handle_t, int, cred_t *);
 129 };
 130 
 131 typedef sock_lower_handle_t (*so_proto_create_func_t)(int, int, int,
 132     sock_downcalls_t **, uint_t *, int *, int, cred_t *);
 133 
 134 typedef struct sock_quiesce_arg {
 135         mblk_t *soqa_exdata_mp;
 136         mblk_t *soqa_urgmark_mp;
 137 } sock_quiesce_arg_t;
 138 typedef mblk_t *(*so_proto_quiesced_cb_t)(sock_upper_handle_t,
 139     sock_quiesce_arg_t *, struct T_capability_ack *, struct sockaddr *,
 140     socklen_t, struct sockaddr *, socklen_t, short);
 141 typedef int (*so_proto_fallback_func_t)(sock_lower_handle_t, queue_t *,
 142     boolean_t, so_proto_quiesced_cb_t, sock_quiesce_arg_t *);
 143 
 144 /*
 145  * These functions return EOPNOTSUPP and are intended for the sockfs
 146  * developer that doesn't wish to supply stubs for every function themselves.
 147  */
 148 extern int sock_accept_notsupp(sock_lower_handle_t, sock_lower_handle_t,
 149     sock_upper_handle_t, cred_t *);
 150 extern int sock_bind_notsupp(sock_lower_handle_t, struct sockaddr *,
 151     socklen_t, cred_t *);
 152 extern int sock_listen_notsupp(sock_lower_handle_t, int, cred_t *);
 153 extern int sock_connect_notsupp(sock_lower_handle_t,
 154     const struct sockaddr *, socklen_t, sock_connid_t *, cred_t *);
 155 extern int sock_getpeername_notsupp(sock_lower_handle_t, struct sockaddr *,
 156     socklen_t *, cred_t *);
 157 extern int sock_getsockname_notsupp(sock_lower_handle_t, struct sockaddr *,
 158     socklen_t *, cred_t *);
 159 extern int sock_getsockopt_notsupp(sock_lower_handle_t, int, int, void *,
 160     socklen_t *, cred_t *);
 161 extern int sock_setsockopt_notsupp(sock_lower_handle_t, int, int,
 162     const void *, socklen_t, cred_t *);
 163 extern int sock_send_notsupp(sock_lower_handle_t, mblk_t *,
 164     struct nmsghdr *, cred_t *);
 165 extern int sock_send_uio_notsupp(sock_lower_handle_t, uio_t *,
 166     struct nmsghdr *, cred_t *);
 167 extern int sock_recv_uio_notsupp(sock_lower_handle_t, uio_t *,
 168     struct nmsghdr *, cred_t *);
 169 extern short sock_poll_notsupp(sock_lower_handle_t, short, int, cred_t *);
 170 extern int sock_shutdown_notsupp(sock_lower_handle_t, int, cred_t *);
 171 extern void sock_clr_flowctrl_notsupp(sock_lower_handle_t);
 172 extern int sock_ioctl_notsupp(sock_lower_handle_t, int, intptr_t, int,
 173     int32_t *, cred_t *);
 174 extern int sock_close_notsupp(sock_lower_handle_t, int, cred_t *);
 175 
 176 /*
 177  * Upcalls and related information
 178  */
 179 
 180 /*
 181  * su_opctl() actions
 182  */
 183 typedef enum sock_opctl_action {
 184         SOCK_OPCTL_ENAB_ACCEPT = 0,
 185         SOCK_OPCTL_SHUT_SEND,
 186         SOCK_OPCTL_SHUT_RECV
 187 } sock_opctl_action_t;
 188 
 189 struct sock_upcalls_s {
 190         sock_upper_handle_t (*su_newconn)(sock_upper_handle_t,
 191             sock_lower_handle_t, sock_downcalls_t *, cred_t *, pid_t,
 192             sock_upcalls_t **);
 193         void    (*su_connected)(sock_upper_handle_t, sock_connid_t, cred_t *,
 194             pid_t);
 195         int     (*su_disconnected)(sock_upper_handle_t, sock_connid_t, int);
 196         void    (*su_opctl)(sock_upper_handle_t, sock_opctl_action_t,
 197             uintptr_t);
 198         ssize_t (*su_recv)(sock_upper_handle_t, mblk_t *, size_t, int,
 199                     int *, boolean_t *);
 200         void    (*su_set_proto_props)(sock_upper_handle_t,
 201                     struct sock_proto_props *);
 202         void    (*su_txq_full)(sock_upper_handle_t, boolean_t);
 203         void    (*su_signal_oob)(sock_upper_handle_t, ssize_t);
 204         void    (*su_zcopy_notify)(sock_upper_handle_t);
 205         void    (*su_set_error)(sock_upper_handle_t, int);
 206         /*
 207          * NOTE: This function frees upper handle items. Caller cannot
 208          * rely on them after this upcall.
 209          */
 210         void    (*su_closed)(sock_upper_handle_t);
 211         /*
 212          * NOTE: This function MUST be implemented without using lower-level
 213          * downcalls or accesses. This allows callers to ensure su_closed()
 214          * upcalls can happen indepdently or concurrently.
 215          */
 216         vnode_t *(*su_get_vnode)(sock_upper_handle_t);
 217 };
 218 
 219 #define SOCK_UC_VERSION         sizeof (sock_upcalls_t)
 220 #define SOCK_DC_VERSION         sizeof (sock_downcalls_t)
 221 
 222 #define SOCKET_RECVHIWATER      (48 * 1024)
 223 #define SOCKET_RECVLOWATER      1024
 224 
 225 #define SOCKET_NO_RCVTIMER      0
 226 #define SOCKET_TIMER_INTERVAL   50
 227 
 228 #endif /* _KERNEL */
 229 
 230 #ifdef  __cplusplus
 231 }
 232 #endif
 233 
 234 #endif /* _SYS_SOCKET_PROTO_H_ */