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 /*
  23  * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  27 /*        All Rights Reserved   */
  28 
  29 /*
  30  * University Copyright- Copyright (c) 1982, 1986, 1988
  31  * The Regents of the University of California
  32  * All Rights Reserved
  33  *
  34  * University Acknowledgment- Portions of this document are derived from
  35  * software developed by the University of California, Berkeley, and its
  36  * contributors.
  37  */
  38 /*
  39  * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
  40  */
  41 
  42 #ifndef _SYS_SOCKETVAR_H
  43 #define _SYS_SOCKETVAR_H
  44 
  45 #include <sys/types.h>
  46 #include <sys/stream.h>
  47 #include <sys/t_lock.h>
  48 #include <sys/cred.h>
  49 #include <sys/vnode.h>
  50 #include <sys/file.h>
  51 #include <sys/param.h>
  52 #include <sys/zone.h>
  53 #include <sys/sdt.h>
  54 #include <sys/modctl.h>
  55 #include <sys/atomic.h>
  56 #include <sys/socket.h>
  57 #include <sys/ksocket.h>
  58 #include <sys/kstat.h>
  59 
  60 #ifdef _KERNEL
  61 #include <sys/vfs_opreg.h>
  62 #endif
  63 
  64 #ifdef  __cplusplus
  65 extern "C" {
  66 #endif
  67 
  68 /*
  69  * Internal representation of the address used to represent addresses
  70  * in the loopback transport for AF_UNIX. While the sockaddr_un is used
  71  * as the sockfs layer address for AF_UNIX the pathnames contained in
  72  * these addresses are not unique (due to relative pathnames) thus can not
  73  * be used in the transport.
  74  *
  75  * The transport level address consists of a magic number (used to separate the
  76  * name space for specific and implicit binds). For a specific bind
  77  * this is followed by a "vnode *" which ensures that all specific binds
  78  * have a unique transport level address. For implicit binds the latter
  79  * part of the address is a byte string (of the same length as a pointer)
  80  * that is assigned by the loopback transport.
  81  *
  82  * The uniqueness assumes that the loopback transport has a separate namespace
  83  * for sockets in order to avoid name conflicts with e.g. TLI use of the
  84  * same transport.
  85  */
  86 struct so_ux_addr {
  87         void    *soua_vp;       /* vnode pointer or assigned by tl */
  88         uint_t  soua_magic;     /* See below */
  89 };
  90 
  91 #define SOU_MAGIC_EXPLICIT      0x75787670      /* "uxvp" */
  92 #define SOU_MAGIC_IMPLICIT      0x616e6f6e      /* "anon" */
  93 
  94 struct sockaddr_ux {
  95         sa_family_t             sou_family;     /* AF_UNIX */
  96         struct so_ux_addr       sou_addr;
  97 };
  98 
  99 #if defined(_KERNEL) || defined(_KMEMUSER)
 100 
 101 #include <sys/socket_proto.h>
 102 
 103 typedef struct sonodeops sonodeops_t;
 104 typedef struct sonode sonode_t;
 105 
 106 struct sodirect_s;
 107 
 108 /*
 109  * The sonode represents a socket. A sonode never exist in the file system
 110  * name space and can not be opened using open() - only the socket, socketpair
 111  * and accept calls create sonodes.
 112  *
 113  * The locking of sockfs uses the so_lock mutex plus the SOLOCKED and
 114  * SOREADLOCKED flags in so_flag. The mutex protects all the state in the
 115  * sonode. It is expected that the underlying transport protocol serializes
 116  * socket operations, so sockfs will not normally not single-thread
 117  * operations. However, certain sockets, including TPI based ones, can only
 118  * handle one control operation at a time. The SOLOCKED flag is used to
 119  * single-thread operations from sockfs users to prevent e.g. multiple bind()
 120  * calls to operate on the same sonode concurrently. The SOREADLOCKED flag is
 121  * used to ensure that only one thread sleeps in kstrgetmsg for a given
 122  * sonode. This is needed to ensure atomic operation for things like
 123  * MSG_WAITALL.
 124  *
 125  * The so_fallback_rwlock is used to ensure that for sockets that can
 126  * fall back to TPI, the fallback is not initiated until all pending
 127  * operations have completed.
 128  *
 129  * Note that so_lock is sometimes held across calls that might go to sleep
 130  * (kmem_alloc and soallocproto*). This implies that no other lock in
 131  * the system should be held when calling into sockfs; from the system call
 132  * side or from strrput (in case of TPI based sockets). If locks are held
 133  * while calling into sockfs the system might hang when running low on memory.
 134  */
 135 struct sonode {
 136         struct  vnode   *so_vnode;      /* vnode associated with this sonode */
 137 
 138         sonodeops_t     *so_ops;        /* operations vector for this sonode */
 139         void            *so_priv;       /* sonode private data */
 140 
 141         krwlock_t       so_fallback_rwlock;
 142         kmutex_t        so_lock;        /* protects sonode fields */
 143 
 144         kcondvar_t      so_state_cv;    /* synchronize state changes */
 145         kcondvar_t      so_single_cv;   /* wait due to SOLOCKED */
 146         kcondvar_t      so_read_cv;     /* wait due to SOREADLOCKED */
 147 
 148         /* These fields are protected by so_lock */
 149 
 150         uint_t          so_state;       /* internal state flags SS_*, below */
 151         uint_t          so_mode;        /* characteristics on socket. SM_* */
 152         ushort_t        so_flag;        /* flags, see below */
 153         int             so_count;       /* count of opened references */
 154 
 155         sock_connid_t   so_proto_connid; /* protocol generation number */
 156 
 157         ushort_t        so_error;       /* error affecting connection */
 158 
 159         struct sockparams *so_sockparams;       /* vnode or socket module */
 160         /* Needed to recreate the same socket for accept */
 161         short   so_family;
 162         short   so_type;
 163         short   so_protocol;
 164         short   so_version;             /* From so_socket call */
 165 
 166         /* Accept queue */
 167         kmutex_t        so_acceptq_lock;        /* protects accept queue */
 168         list_t          so_acceptq_list;        /* pending conns */
 169         list_t          so_acceptq_defer;       /* deferred conns */
 170         list_node_t     so_acceptq_node;        /* acceptq list node */
 171         unsigned int    so_acceptq_len;         /* # of conns (both lists) */
 172         unsigned int    so_backlog;             /* Listen backlog */
 173         kcondvar_t      so_acceptq_cv;          /* wait for new conn. */
 174         struct sonode   *so_listener;           /* parent socket */
 175 
 176         /* Options */
 177         short   so_options;             /* From socket call, see socket.h */
 178         struct linger   so_linger;      /* SO_LINGER value */
 179 #define so_sndbuf       so_proto_props.sopp_txhiwat     /* SO_SNDBUF value */
 180 #define so_sndlowat     so_proto_props.sopp_txlowat     /* tx low water mark */
 181 #define so_rcvbuf       so_proto_props.sopp_rxhiwat     /* SO_RCVBUF value */
 182 #define so_rcvlowat     so_proto_props.sopp_rxlowat     /* rx low water mark */
 183 #define so_max_addr_len so_proto_props.sopp_maxaddrlen
 184 #define so_minpsz       so_proto_props.sopp_minpsz
 185 #define so_maxpsz       so_proto_props.sopp_maxpsz
 186 
 187         int     so_xpg_rcvbuf;          /* SO_RCVBUF value for XPG4 socket */
 188         clock_t so_sndtimeo;            /* send timeout */
 189         clock_t so_rcvtimeo;            /* recv timeout */
 190 
 191         mblk_t  *so_oobmsg;             /* outofline oob data */
 192         ssize_t so_oobmark;             /* offset of the oob data */
 193 
 194         pid_t   so_pgrp;                /* pgrp for signals */
 195 
 196         cred_t          *so_peercred;   /* connected socket peer cred */
 197         pid_t           so_cpid;        /* connected socket peer cached pid */
 198         zoneid_t        so_zoneid;      /* opener's zoneid */
 199 
 200         struct pollhead so_poll_list;   /* common pollhead */
 201         short           so_pollev;      /* events that should be generated */
 202 
 203         /* Receive */
 204         unsigned int    so_rcv_queued;  /* # bytes on both rcv lists */
 205         mblk_t          *so_rcv_q_head; /* processing/copyout rcv queue */
 206         mblk_t          *so_rcv_q_last_head;
 207         mblk_t          *so_rcv_head;   /* protocol prequeue */
 208         mblk_t          *so_rcv_last_head;      /* last mblk in b_next chain */
 209         kcondvar_t      so_rcv_cv;      /* wait for data */
 210         uint_t          so_rcv_wanted;  /* # of bytes wanted by app */
 211         timeout_id_t    so_rcv_timer_tid;
 212 
 213 #define so_rcv_thresh   so_proto_props.sopp_rcvthresh
 214 #define so_rcv_timer_interval so_proto_props.sopp_rcvtimer
 215 
 216         kcondvar_t      so_snd_cv;      /* wait for snd buffers */
 217         uint32_t
 218                 so_snd_qfull: 1,        /* Transmit full */
 219                 so_rcv_wakeup: 1,
 220                 so_snd_wakeup: 1,
 221                 so_not_str: 1,  /* B_TRUE if not streams based socket */
 222                 so_pad_to_bit_31: 28;
 223 
 224         /* Communication channel with protocol */
 225         sock_lower_handle_t     so_proto_handle;
 226         sock_downcalls_t        *so_downcalls;
 227 
 228         struct sock_proto_props so_proto_props; /* protocol settings */
 229         boolean_t               so_flowctrld;   /* Flow controlled */
 230         uint_t                  so_copyflag;    /* Copy related flag */
 231         kcondvar_t              so_copy_cv;     /* Copy cond variable */
 232 
 233         /* kernel sockets */
 234         ksocket_callbacks_t     so_ksock_callbacks;
 235         void                    *so_ksock_cb_arg;       /* callback argument */
 236         kcondvar_t              so_closing_cv;
 237 
 238         /* != NULL for sodirect enabled socket */
 239         struct sodirect_s       *so_direct;
 240 
 241         /* socket filters */
 242         uint_t                  so_filter_active;       /* # of active fil */
 243         uint_t                  so_filter_tx;           /* pending tx ops */
 244         struct sof_instance     *so_filter_top;         /* top of stack */
 245         struct sof_instance     *so_filter_bottom;      /* bottom of stack */
 246         clock_t                 so_filter_defertime;    /* time when deferred */
 247 };
 248 
 249 #define SO_HAVE_DATA(so)                                                \
 250         /*                                                              \
 251          * For the (tid == 0) case we must check so_rcv_{q_,}head       \
 252          * rather than (so_rcv_queued > 0), since the latter does not        \
 253          * take into account mblks with only control/name information.  \
 254          */                                                             \
 255         ((so)->so_rcv_timer_tid == 0 && ((so)->so_rcv_head != NULL ||     \
 256         (so)->so_rcv_q_head != NULL)) ||                             \
 257         ((so)->so_state & SS_CANTRCVMORE)
 258 
 259 /*
 260  * Events handled by the protocol (in case sd_poll is set)
 261  */
 262 #define SO_PROTO_POLLEV         (POLLIN|POLLRDNORM|POLLRDBAND)
 263 
 264 
 265 #endif /* _KERNEL || _KMEMUSER */
 266 
 267 /* flags */
 268 #define SOMOD           0x0001          /* update socket modification time */
 269 #define SOACC           0x0002          /* update socket access time */
 270 
 271 #define SOLOCKED        0x0010          /* use to serialize open/closes */
 272 #define SOREADLOCKED    0x0020          /* serialize kstrgetmsg calls */
 273 #define SOCLONE         0x0040          /* child of clone driver */
 274 #define SOASYNC_UNBIND  0x0080          /* wait for ACK of async unbind */
 275 
 276 #define SOCK_IS_NONSTR(so)      ((so)->so_not_str)
 277 
 278 /*
 279  * Socket state bits.
 280  */
 281 #define SS_ISCONNECTED          0x00000001 /* socket connected to a peer */
 282 #define SS_ISCONNECTING         0x00000002 /* in process, connecting to peer */
 283 #define SS_ISDISCONNECTING      0x00000004 /* in process of disconnecting */
 284 #define SS_CANTSENDMORE         0x00000008 /* can't send more data to peer */
 285 
 286 #define SS_CANTRCVMORE          0x00000010 /* can't receive more data */
 287 #define SS_ISBOUND              0x00000020 /* socket is bound */
 288 #define SS_NDELAY               0x00000040 /* FNDELAY non-blocking */
 289 #define SS_NONBLOCK             0x00000080 /* O_NONBLOCK non-blocking */
 290 
 291 #define SS_ASYNC                0x00000100 /* async i/o notify */
 292 #define SS_ACCEPTCONN           0x00000200 /* listen done */
 293 /*      unused                  0x00000400 */   /* was SS_HASCONNIND */
 294 #define SS_SAVEDEOR             0x00000800 /* Saved MSG_EOR rcv side state */
 295 
 296 #define SS_RCVATMARK            0x00001000 /* at mark on input */
 297 #define SS_OOBPEND              0x00002000 /* OOB pending or present - poll */
 298 #define SS_HAVEOOBDATA          0x00004000 /* OOB data present */
 299 #define SS_HADOOBDATA           0x00008000 /* OOB data consumed */
 300 
 301 #define SS_CLOSING              0x00010000 /* in process of closing */
 302 #define SS_FIL_DEFER            0x00020000 /* filter deferred notification */
 303 #define SS_FILOP_OK             0x00040000 /* socket can attach filters */
 304 #define SS_FIL_RCV_FLOWCTRL     0x00080000 /* filter asserted rcv flow ctrl */
 305 
 306 #define SS_FIL_SND_FLOWCTRL     0x00100000 /* filter asserted snd flow ctrl */
 307 #define SS_FIL_STOP             0x00200000 /* no more filter actions */
 308 #define SS_SODIRECT             0x00400000 /* transport supports sodirect */
 309 #define SS_FILOP_UNSF           0x00800000 /* block attaching unsafe filters */
 310 
 311 #define SS_SENTLASTREADSIG      0x01000000 /* last rx signal has been sent */
 312 #define SS_SENTLASTWRITESIG     0x02000000 /* last tx signal has been sent */
 313 
 314 #define SS_FALLBACK_DRAIN       0x20000000 /* data was/is being drained */
 315 #define SS_FALLBACK_PENDING     0x40000000 /* fallback is pending */
 316 #define SS_FALLBACK_COMP        0x80000000 /* fallback has completed */
 317 
 318 
 319 /* Set of states when the socket can't be rebound */
 320 #define SS_CANTREBIND   (SS_ISCONNECTED|SS_ISCONNECTING|SS_ISDISCONNECTING|\
 321                             SS_CANTSENDMORE|SS_CANTRCVMORE|SS_ACCEPTCONN)
 322 
 323 /*
 324  * Sockets that can fall back to TPI must ensure that fall back is not
 325  * initiated while a thread is using a socket. Otherwise this disables all
 326  * future filter attachment.
 327  */
 328 #define SO_BLOCK_FALLBACK(so, fn)                               \
 329         ASSERT(MUTEX_NOT_HELD(&(so)->so_lock));                  \
 330         rw_enter(&(so)->so_fallback_rwlock, RW_READER);          \
 331         if ((so)->so_state & (SS_FALLBACK_COMP|SS_FILOP_OK)) {   \
 332                 if ((so)->so_state & SS_FALLBACK_COMP) { \
 333                         rw_exit(&(so)->so_fallback_rwlock);      \
 334                         return (fn);                            \
 335                 } else {                                        \
 336                         mutex_enter(&(so)->so_lock);             \
 337                         (so)->so_state &= ~SS_FILOP_OK;          \
 338                         mutex_exit(&(so)->so_lock);              \
 339                 }                                               \
 340         }
 341 
 342 /*
 343  * Sockets that can fall back to TPI must ensure that fall back is not
 344  * initiated while a thread is using a socket. Otherwise this disables all
 345  * future unsafe filter attachment. Safe filters can still attach after
 346  * we execute the function in which this macro is used.
 347  */
 348 #define SO_BLOCK_FALLBACK_SAFE(so, fn)                          \
 349         ASSERT(MUTEX_NOT_HELD(&(so)->so_lock));                  \
 350         rw_enter(&(so)->so_fallback_rwlock, RW_READER);          \
 351         if ((so)->so_state & SS_FALLBACK_COMP) {         \
 352                 rw_exit(&(so)->so_fallback_rwlock);              \
 353                 return (fn);                                    \
 354         } else if (((so)->so_state & SS_FILOP_UNSF) == 0) {      \
 355                 mutex_enter(&(so)->so_lock);                     \
 356                 (so)->so_state |= SS_FILOP_UNSF;             \
 357                 mutex_exit(&(so)->so_lock);                      \
 358         }
 359 
 360 #define SO_UNBLOCK_FALLBACK(so) {                       \
 361         rw_exit(&(so)->so_fallback_rwlock);              \
 362 }
 363 
 364 #define SO_SND_FLOWCTRLD(so)    \
 365         ((so)->so_snd_qfull || (so)->so_state & SS_FIL_SND_FLOWCTRL)
 366 
 367 /* Poll events */
 368 #define SO_POLLEV_IN            0x1     /* POLLIN wakeup needed */
 369 #define SO_POLLEV_ALWAYS        0x2     /* wakeups */
 370 
 371 /*
 372  * Characteristics of sockets. Not changed after the socket is created.
 373  */
 374 #define SM_PRIV                 0x001   /* privileged for broadcast, raw... */
 375 #define SM_ATOMIC               0x002   /* atomic data transmission */
 376 #define SM_ADDR                 0x004   /* addresses given with messages */
 377 #define SM_CONNREQUIRED         0x008   /* connection required by protocol */
 378 
 379 #define SM_FDPASSING            0x010   /* passes file descriptors */
 380 #define SM_EXDATA               0x020   /* Can handle T_EXDATA_REQ */
 381 #define SM_OPTDATA              0x040   /* Can handle T_OPTDATA_REQ */
 382 #define SM_BYTESTREAM           0x080   /* Byte stream - can use M_DATA */
 383 
 384 #define SM_ACCEPTOR_ID          0x100   /* so_acceptor_id is valid */
 385 
 386 #define SM_KERNEL               0x200   /* kernel socket */
 387 
 388 /* The modes below are only for non-streams sockets */
 389 #define SM_ACCEPTSUPP           0x400   /* can handle accept() */
 390 #define SM_SENDFILESUPP         0x800   /* Private: proto supp sendfile  */
 391 #define SM_DEFERERR             0x1000  /* Private: defer so_error delivery */
 392 
 393 /*
 394  * Socket versions. Used by the socket library when calling _so_socket().
 395  */
 396 #define SOV_STREAM      0       /* Not a socket - just a stream */
 397 #define SOV_DEFAULT     1       /* Select based on so_default_version */
 398 #define SOV_SOCKSTREAM  2       /* Socket plus streams operations */
 399 #define SOV_SOCKBSD     3       /* Socket with no streams operations */
 400 #define SOV_XPG4_2      4       /* Xnet socket */
 401 
 402 #if defined(_KERNEL) || defined(_KMEMUSER)
 403 
 404 /*
 405  * sonode create and destroy functions.
 406  */
 407 typedef struct sonode *(*so_create_func_t)(struct sockparams *,
 408     int, int, int, int, int, int *, cred_t *);
 409 typedef void (*so_destroy_func_t)(struct sonode *);
 410 
 411 /* STREAM device information */
 412 typedef struct sdev_info {
 413         char    *sd_devpath;
 414         int     sd_devpathlen; /* Is 0 if sp_devpath is a static string */
 415         vnode_t *sd_vnode;
 416 } sdev_info_t;
 417 
 418 #define SOCKMOD_VERSION_1       1
 419 #define SOCKMOD_VERSION         2
 420 
 421 /* name of the TPI pseudo socket module */
 422 #define SOTPI_SMOD_NAME         "socktpi"
 423 
 424 typedef struct __smod_priv_s {
 425         so_create_func_t        smodp_sock_create_func;
 426         so_destroy_func_t       smodp_sock_destroy_func;
 427         so_proto_fallback_func_t smodp_proto_fallback_func;
 428         const char              *smodp_fallback_devpath_v4;
 429         const char              *smodp_fallback_devpath_v6;
 430 } __smod_priv_t;
 431 
 432 /*
 433  * Socket module register information
 434  */
 435 typedef struct smod_reg_s {
 436         int             smod_version;
 437         char            *smod_name;
 438         size_t          smod_uc_version;
 439         size_t          smod_dc_version;
 440         so_proto_create_func_t  smod_proto_create_func;
 441 
 442         /* __smod_priv_data must be NULL */
 443         __smod_priv_t   *__smod_priv;
 444 } smod_reg_t;
 445 
 446 /*
 447  * Socket module information
 448  */
 449 typedef struct smod_info {
 450         int             smod_version;
 451         char            *smod_name;
 452         uint_t          smod_refcnt;            /* # of entries */
 453         size_t          smod_uc_version;        /* upcall version */
 454         size_t          smod_dc_version;        /* down call version */
 455         so_proto_create_func_t  smod_proto_create_func;
 456         so_proto_fallback_func_t smod_proto_fallback_func;
 457         const char              *smod_fallback_devpath_v4;
 458         const char              *smod_fallback_devpath_v6;
 459         so_create_func_t        smod_sock_create_func;
 460         so_destroy_func_t       smod_sock_destroy_func;
 461         list_node_t     smod_node;
 462 } smod_info_t;
 463 
 464 typedef struct sockparams_stats {
 465         kstat_named_t   sps_nfallback;  /* # of fallbacks to TPI */
 466         kstat_named_t   sps_nactive;    /* # of active sockets */
 467         kstat_named_t   sps_ncreate;    /* total # of created sockets */
 468 } sockparams_stats_t;
 469 
 470 /*
 471  * sockparams
 472  *
 473  * Used for mapping family/type/protocol to a socket module or STREAMS device
 474  */
 475 struct sockparams {
 476         /*
 477          * The family, type, protocol, sdev_info and smod_name are
 478          * set when the entry is created, and they will never change
 479          * thereafter.
 480          */
 481         int             sp_family;
 482         int             sp_type;
 483         int             sp_protocol;
 484 
 485         sdev_info_t     sp_sdev_info;   /* STREAM device */
 486         char            *sp_smod_name;  /* socket module name */
 487 
 488         kmutex_t        sp_lock;        /* lock for refcnt and smod_info */
 489         uint64_t        sp_refcnt;      /* entry reference count */
 490         smod_info_t     *sp_smod_info;  /* socket module */
 491 
 492         sockparams_stats_t sp_stats;
 493         kstat_t         *sp_kstat;
 494 
 495         /*
 496          * The entries below are only modified while holding
 497          * sockconf_lock as a writer.
 498          */
 499         int             sp_flags;       /* see below */
 500         list_node_t     sp_node;
 501 
 502         list_t          sp_auto_filters; /* list of automatic filters */
 503         list_t          sp_prog_filters; /* list of programmatic filters */
 504 };
 505 
 506 struct sof_entry;
 507 
 508 typedef struct sp_filter {
 509         struct sof_entry *spf_filter;
 510         list_node_t     spf_node;
 511 } sp_filter_t;
 512 
 513 
 514 /*
 515  * sockparams flags
 516  */
 517 #define SOCKPARAMS_EPHEMERAL    0x1     /* temp. entry, not on global list */
 518 
 519 extern void sockparams_init(void);
 520 extern struct sockparams *sockparams_hold_ephemeral_bydev(int, int, int,
 521     const char *, int, int *);
 522 extern struct sockparams *sockparams_hold_ephemeral_bymod(int, int, int,
 523     const char *, int, int *);
 524 extern void sockparams_ephemeral_drop_last_ref(struct sockparams *);
 525 
 526 extern struct sockparams *sockparams_create(int, int, int, char *, char *, int,
 527     int, int, int *);
 528 extern void     sockparams_destroy(struct sockparams *);
 529 extern int      sockparams_add(struct sockparams *);
 530 extern int      sockparams_delete(int, int, int);
 531 extern int      sockparams_new_filter(struct sof_entry *);
 532 extern void     sockparams_filter_cleanup(struct sof_entry *);
 533 extern int      sockparams_copyout_socktable(uintptr_t);
 534 
 535 extern void smod_init(void);
 536 extern void smod_add(smod_info_t *);
 537 extern int smod_register(const smod_reg_t *);
 538 extern int smod_unregister(const char *);
 539 extern smod_info_t *smod_lookup_byname(const char *);
 540 
 541 #define SOCKPARAMS_HAS_DEVICE(sp)                                       \
 542         ((sp)->sp_sdev_info.sd_devpath != NULL)
 543 
 544 /* Increase the smod_info_t reference count */
 545 #define SMOD_INC_REF(smodp) {                                           \
 546         ASSERT((smodp) != NULL);                                        \
 547         DTRACE_PROBE1(smodinfo__inc__ref, struct smod_info *, (smodp)); \
 548         atomic_inc_uint(&(smodp)->smod_refcnt);                          \
 549 }
 550 
 551 /*
 552  * Decreace the socket module entry reference count.
 553  * When no one mapping to the entry, we try to unload the module from the
 554  * kernel. If the module can't unload, just leave the module entry with
 555  * a zero refcnt.
 556  */
 557 #define SMOD_DEC_REF(smodp, modname) {                                  \
 558         ASSERT((smodp) != NULL);                                        \
 559         ASSERT((smodp)->smod_refcnt != 0);                           \
 560         atomic_dec_uint(&(smodp)->smod_refcnt);                          \
 561         /*                                                              \
 562          * No need to atomically check the return value because the     \
 563          * socket module framework will verify that no one is using     \
 564          * the module before unloading. Worst thing that can happen     \
 565          * here is multiple calls to mod_remove_by_name(), which is OK. \
 566          */                                                             \
 567         if ((smodp)->smod_refcnt == 0)                                       \
 568                 (void) mod_remove_by_name(modname);                     \
 569 }
 570 
 571 /* Increase the reference count */
 572 #define SOCKPARAMS_INC_REF(sp) {                                        \
 573         ASSERT((sp) != NULL);                                           \
 574         DTRACE_PROBE1(sockparams__inc__ref, struct sockparams *, (sp)); \
 575         mutex_enter(&(sp)->sp_lock);                                     \
 576         (sp)->sp_refcnt++;                                           \
 577         ASSERT((sp)->sp_refcnt != 0);                                        \
 578         mutex_exit(&(sp)->sp_lock);                                      \
 579 }
 580 
 581 /*
 582  * Decrease the reference count.
 583  *
 584  * If the sockparams is ephemeral, then the thread dropping the last ref
 585  * count will destroy the entry.
 586  */
 587 #define SOCKPARAMS_DEC_REF(sp) {                                        \
 588         ASSERT((sp) != NULL);                                           \
 589         DTRACE_PROBE1(sockparams__dec__ref, struct sockparams *, (sp)); \
 590         mutex_enter(&(sp)->sp_lock);                                     \
 591         ASSERT((sp)->sp_refcnt > 0);                                      \
 592         if ((sp)->sp_refcnt == 1) {                                  \
 593                 if ((sp)->sp_flags & SOCKPARAMS_EPHEMERAL) {             \
 594                         mutex_exit(&(sp)->sp_lock);                      \
 595                         sockparams_ephemeral_drop_last_ref((sp));       \
 596                 } else {                                                \
 597                         (sp)->sp_refcnt--;                           \
 598                         if ((sp)->sp_smod_info != NULL) {            \
 599                                 SMOD_DEC_REF((sp)->sp_smod_info,     \
 600                                     (sp)->sp_smod_name);             \
 601                         }                                               \
 602                         (sp)->sp_smod_info = NULL;                   \
 603                         mutex_exit(&(sp)->sp_lock);                      \
 604                 }                                                       \
 605         } else {                                                        \
 606                 (sp)->sp_refcnt--;                                   \
 607                 mutex_exit(&(sp)->sp_lock);                              \
 608         }                                                               \
 609 }
 610 
 611 /*
 612  * Used to traverse the list of AF_UNIX sockets to construct the kstat
 613  * for netstat(1m).
 614  */
 615 struct socklist {
 616         kmutex_t        sl_lock;
 617         struct sonode   *sl_list;
 618 };
 619 
 620 extern struct socklist socklist;
 621 /*
 622  * ss_full_waits is the number of times the reader thread
 623  * waits when the queue is full and ss_empty_waits is the number
 624  * of times the consumer thread waits when the queue is empty.
 625  * No locks for these as they are just indicators of whether
 626  * disk or network or both is slow or fast.
 627  */
 628 struct sendfile_stats {
 629         uint32_t ss_file_cached;
 630         uint32_t ss_file_not_cached;
 631         uint32_t ss_full_waits;
 632         uint32_t ss_empty_waits;
 633         uint32_t ss_file_segmap;
 634 };
 635 
 636 /*
 637  * A single sendfile request is represented by snf_req.
 638  */
 639 typedef struct snf_req {
 640         struct snf_req  *sr_next;
 641         mblk_t          *sr_mp_head;
 642         mblk_t          *sr_mp_tail;
 643         kmutex_t        sr_lock;
 644         kcondvar_t      sr_cv;
 645         uint_t          sr_qlen;
 646         int             sr_hiwat;
 647         int             sr_lowat;
 648         int             sr_operation;
 649         struct vnode    *sr_vp;
 650         file_t          *sr_fp;
 651         ssize_t         sr_maxpsz;
 652         u_offset_t      sr_file_off;
 653         u_offset_t      sr_file_size;
 654 #define SR_READ_DONE    0x80000000
 655         int             sr_read_error;
 656         int             sr_write_error;
 657 } snf_req_t;
 658 
 659 /* A queue of sendfile requests */
 660 struct sendfile_queue {
 661         snf_req_t       *snfq_req_head;
 662         snf_req_t       *snfq_req_tail;
 663         kmutex_t        snfq_lock;
 664         kcondvar_t      snfq_cv;
 665         int             snfq_svc_threads;       /* # of service threads */
 666         int             snfq_idle_cnt;          /* # of idling threads */
 667         int             snfq_max_threads;
 668         int             snfq_req_cnt;           /* Number of requests */
 669 };
 670 
 671 #define READ_OP                 1
 672 #define SNFQ_TIMEOUT            (60 * 5 * hz)   /* 5 minutes */
 673 
 674 /* Socket network operations switch */
 675 struct sonodeops {
 676         int     (*sop_init)(struct sonode *, struct sonode *, cred_t *,
 677                     int);
 678         int     (*sop_accept)(struct sonode *, int, cred_t *, struct sonode **);
 679         int     (*sop_bind)(struct sonode *, struct sockaddr *, socklen_t,
 680                     int, cred_t *);
 681         int     (*sop_listen)(struct sonode *, int, cred_t *);
 682         int     (*sop_connect)(struct sonode *, struct sockaddr *,
 683                     socklen_t, int, int, cred_t *);
 684         int     (*sop_recvmsg)(struct sonode *, struct msghdr *,
 685                     struct uio *, cred_t *);
 686         int     (*sop_sendmsg)(struct sonode *, struct msghdr *,
 687                     struct uio *, cred_t *);
 688         int     (*sop_sendmblk)(struct sonode *, struct msghdr *, int,
 689                     cred_t *, mblk_t **);
 690         int     (*sop_getpeername)(struct sonode *, struct sockaddr *,
 691                     socklen_t *, boolean_t, cred_t *);
 692         int     (*sop_getsockname)(struct sonode *, struct sockaddr *,
 693                     socklen_t *, cred_t *);
 694         int     (*sop_shutdown)(struct sonode *, int, cred_t *);
 695         int     (*sop_getsockopt)(struct sonode *, int, int, void *,
 696                     socklen_t *, int, cred_t *);
 697         int     (*sop_setsockopt)(struct sonode *, int, int, const void *,
 698                     socklen_t, cred_t *);
 699         int     (*sop_ioctl)(struct sonode *, int, intptr_t, int,
 700                     cred_t *, int32_t *);
 701         int     (*sop_poll)(struct sonode *, short, int, short *,
 702                     struct pollhead **);
 703         int     (*sop_close)(struct sonode *, int, cred_t *);
 704 };
 705 
 706 #define SOP_INIT(so, flag, cr, flags)   \
 707         ((so)->so_ops->sop_init((so), (flag), (cr), (flags)))
 708 #define SOP_ACCEPT(so, fflag, cr, nsop) \
 709         ((so)->so_ops->sop_accept((so), (fflag), (cr), (nsop)))
 710 #define SOP_BIND(so, name, namelen, flags, cr)  \
 711         ((so)->so_ops->sop_bind((so), (name), (namelen), (flags), (cr)))
 712 #define SOP_LISTEN(so, backlog, cr)     \
 713         ((so)->so_ops->sop_listen((so), (backlog), (cr)))
 714 #define SOP_CONNECT(so, name, namelen, fflag, flags, cr)        \
 715         ((so)->so_ops->sop_connect((so), (name), (namelen), (fflag), (flags), \
 716         (cr)))
 717 #define SOP_RECVMSG(so, msg, uiop, cr)  \
 718         ((so)->so_ops->sop_recvmsg((so), (msg), (uiop), (cr)))
 719 #define SOP_SENDMSG(so, msg, uiop, cr)  \
 720         ((so)->so_ops->sop_sendmsg((so), (msg), (uiop), (cr)))
 721 #define SOP_SENDMBLK(so, msg, size, cr, mpp)    \
 722         ((so)->so_ops->sop_sendmblk((so), (msg), (size), (cr), (mpp)))
 723 #define SOP_GETPEERNAME(so, addr, addrlen, accept, cr)  \
 724         ((so)->so_ops->sop_getpeername((so), (addr), (addrlen), (accept), (cr)))
 725 #define SOP_GETSOCKNAME(so, addr, addrlen, cr)  \
 726         ((so)->so_ops->sop_getsockname((so), (addr), (addrlen), (cr)))
 727 #define SOP_SHUTDOWN(so, how, cr)       \
 728         ((so)->so_ops->sop_shutdown((so), (how), (cr)))
 729 #define SOP_GETSOCKOPT(so, level, optionname, optval, optlenp, flags, cr) \
 730         ((so)->so_ops->sop_getsockopt((so), (level), (optionname),        \
 731             (optval), (optlenp), (flags), (cr)))
 732 #define SOP_SETSOCKOPT(so, level, optionname, optval, optlen, cr)       \
 733         ((so)->so_ops->sop_setsockopt((so), (level), (optionname),        \
 734             (optval), (optlen), (cr)))
 735 #define SOP_IOCTL(so, cmd, arg, mode, cr, rvalp)        \
 736         ((so)->so_ops->sop_ioctl((so), (cmd), (arg), (mode), (cr), (rvalp)))
 737 #define SOP_POLL(so, events, anyyet, reventsp, phpp) \
 738         ((so)->so_ops->sop_poll((so), (events), (anyyet), (reventsp), (phpp)))
 739 #define SOP_CLOSE(so, flag, cr) \
 740         ((so)->so_ops->sop_close((so), (flag), (cr)))
 741 
 742 #endif /* defined(_KERNEL) || defined(_KMEMUSER) */
 743 
 744 #ifdef _KERNEL
 745 
 746 #define ISALIGNED_cmsghdr(addr) \
 747                 (((uintptr_t)(addr) & (_CMSG_HDR_ALIGNMENT - 1)) == 0)
 748 
 749 #define ROUNDUP_cmsglen(len) \
 750         (((len) + _CMSG_HDR_ALIGNMENT - 1) & ~(_CMSG_HDR_ALIGNMENT - 1))
 751 
 752 #define IS_NON_STREAM_SOCK(vp) \
 753         ((vp)->v_type == VSOCK && (vp)->v_stream == NULL)
 754 /*
 755  * Macros that operate on struct cmsghdr.
 756  * Used in parsing msg_control.
 757  * The CMSG_VALID macro does not assume that the last option buffer is padded.
 758  */
 759 #define CMSG_NEXT(cmsg)                                         \
 760         (struct cmsghdr *)((uintptr_t)(cmsg) +                  \
 761             ROUNDUP_cmsglen((cmsg)->cmsg_len))
 762 #define CMSG_CONTENT(cmsg)      (&((cmsg)[1]))
 763 #define CMSG_CONTENTLEN(cmsg)   ((cmsg)->cmsg_len - sizeof (struct cmsghdr))
 764 #define CMSG_VALID(cmsg, start, end)                                    \
 765         (ISALIGNED_cmsghdr(cmsg) &&                                     \
 766         ((uintptr_t)(cmsg) >= (uintptr_t)(start)) &&                 \
 767         ((uintptr_t)(cmsg) < (uintptr_t)(end)) &&                    \
 768         ((ssize_t)(cmsg)->cmsg_len >= sizeof (struct cmsghdr)) && \
 769         ((uintptr_t)(cmsg) + (cmsg)->cmsg_len <= (uintptr_t)(end)))
 770 
 771 /*
 772  * Maximum size of any argument that is copied in (addresses, options,
 773  * access rights). MUST be at least MAXPATHLEN + 3.
 774  * BSD and SunOS 4.X limited this to MLEN or MCLBYTES.
 775  */
 776 #define SO_MAXARGSIZE   8192
 777 
 778 /*
 779  * Convert between vnode and sonode
 780  */
 781 #define VTOSO(vp)       ((struct sonode *)((vp)->v_data))
 782 #define SOTOV(sp)       ((sp)->so_vnode)
 783 
 784 /*
 785  * Internal flags for sobind()
 786  */
 787 #define _SOBIND_REBIND          0x01    /* Bind to existing local address */
 788 #define _SOBIND_UNSPEC          0x02    /* Bind to unspecified address */
 789 #define _SOBIND_LOCK_HELD       0x04    /* so_excl_lock held by caller */
 790 #define _SOBIND_NOXLATE         0x08    /* No addr translation for AF_UNIX */
 791 #define _SOBIND_XPG4_2          0x10    /* xpg4.2 semantics */
 792 #define _SOBIND_SOCKBSD         0x20    /* BSD semantics */
 793 #define _SOBIND_LISTEN          0x40    /* Make into SS_ACCEPTCONN */
 794 #define _SOBIND_SOCKETPAIR      0x80    /* Internal flag for so_socketpair() */
 795                                         /* to enable listen with backlog = 1 */
 796 
 797 /*
 798  * Internal flags for sounbind()
 799  */
 800 #define _SOUNBIND_REBIND        0x01    /* Don't clear fields - will rebind */
 801 
 802 /*
 803  * Internal flags for soconnect()
 804  */
 805 #define _SOCONNECT_NOXLATE      0x01    /* No addr translation for AF_UNIX */
 806 #define _SOCONNECT_DID_BIND     0x02    /* Unbind when connect fails */
 807 #define _SOCONNECT_XPG4_2       0x04    /* xpg4.2 semantics */
 808 
 809 /*
 810  * Internal flags for sodisconnect()
 811  */
 812 #define _SODISCONNECT_LOCK_HELD 0x01    /* so_excl_lock held by caller */
 813 
 814 /*
 815  * Internal flags for sotpi_getsockopt().
 816  */
 817 #define _SOGETSOCKOPT_XPG4_2    0x01    /* xpg4.2 semantics */
 818 
 819 /*
 820  * Internal flags for soallocproto*()
 821  */
 822 #define _ALLOC_NOSLEEP          0       /* Don't sleep for memory */
 823 #define _ALLOC_INTR             1       /* Sleep until interrupt */
 824 #define _ALLOC_SLEEP            2       /* Sleep forever */
 825 
 826 /*
 827  * Internal structure for handling AF_UNIX file descriptor passing
 828  */
 829 struct fdbuf {
 830         int             fd_size;        /* In bytes, for kmem_free */
 831         int             fd_numfd;       /* Number of elements below */
 832         char            *fd_ebuf;       /* Extra buffer to free  */
 833         int             fd_ebuflen;
 834         frtn_t          fd_frtn;
 835         struct file     *fd_fds[1];     /* One or more */
 836 };
 837 #define FDBUF_HDRSIZE   (sizeof (struct fdbuf) - sizeof (struct file *))
 838 
 839 /*
 840  * Variable that can be patched to set what version of socket socket()
 841  * will create.
 842  */
 843 extern int so_default_version;
 844 
 845 #ifdef DEBUG
 846 /* Turn on extra testing capabilities */
 847 #define SOCK_TEST
 848 #endif /* DEBUG */
 849 
 850 #ifdef DEBUG
 851 char    *pr_state(uint_t, uint_t);
 852 char    *pr_addr(int, struct sockaddr *, t_uscalar_t);
 853 int     so_verify_oobstate(struct sonode *);
 854 #endif /* DEBUG */
 855 
 856 /*
 857  * DEBUG macros
 858  */
 859 #if defined(DEBUG)
 860 #define SOCK_DEBUG
 861 
 862 extern int sockdebug;
 863 extern int sockprinterr;
 864 
 865 #define eprint(args)    printf args
 866 #define eprintso(so, args) \
 867 { if (sockprinterr && ((so)->so_options & SO_DEBUG)) printf args; }
 868 #define eprintline(error)                                       \
 869 {                                                               \
 870         if (error != EINTR && (sockprinterr || sockdebug > 0))       \
 871                 printf("socket error %d: line %d file %s\n",    \
 872                         (error), __LINE__, __FILE__);           \
 873 }
 874 
 875 #define eprintsoline(so, error)                                 \
 876 { if (sockprinterr && ((so)->so_options & SO_DEBUG))             \
 877         printf("socket(%p) error %d: line %d file %s\n",        \
 878                 (void *)(so), (error), __LINE__, __FILE__);     \
 879 }
 880 #define dprint(level, args)     { if (sockdebug > (level)) printf args; }
 881 #define dprintso(so, level, args) \
 882 { if (sockdebug > (level) && ((so)->so_options & SO_DEBUG)) printf args; }
 883 
 884 #else /* define(DEBUG) */
 885 
 886 #define eprint(args)            {}
 887 #define eprintso(so, args)      {}
 888 #define eprintline(error)       {}
 889 #define eprintsoline(so, error) {}
 890 #define dprint(level, args)     {}
 891 #define dprintso(so, level, args) {}
 892 
 893 #endif /* defined(DEBUG) */
 894 
 895 extern struct vfsops                    sock_vfsops;
 896 extern struct vnodeops                  *socket_vnodeops;
 897 extern const struct fs_operation_def    socket_vnodeops_template[];
 898 
 899 extern dev_t                            sockdev;
 900 
 901 extern krwlock_t                        sockconf_lock;
 902 
 903 /*
 904  * sockfs functions
 905  */
 906 extern int      sock_getmsg(vnode_t *, struct strbuf *, struct strbuf *,
 907                         uchar_t *, int *, int, rval_t *);
 908 extern int      sock_putmsg(vnode_t *, struct strbuf *, struct strbuf *,
 909                         uchar_t, int, int);
 910 extern int      sogetvp(char *, vnode_t **, int);
 911 extern int      sockinit(int, char *);
 912 extern int      solookup(int, int, int, struct sockparams **);
 913 extern void     so_lock_single(struct sonode *);
 914 extern void     so_unlock_single(struct sonode *, int);
 915 extern int      so_lock_read(struct sonode *, int);
 916 extern int      so_lock_read_intr(struct sonode *, int);
 917 extern void     so_unlock_read(struct sonode *);
 918 extern void     *sogetoff(mblk_t *, t_uscalar_t, t_uscalar_t, uint_t);
 919 extern void     so_getopt_srcaddr(void *, t_uscalar_t,
 920                         void **, t_uscalar_t *);
 921 extern int      so_getopt_unix_close(void *, t_uscalar_t);
 922 extern void     fdbuf_free(struct fdbuf *);
 923 extern mblk_t   *fdbuf_allocmsg(int, struct fdbuf *);
 924 extern int      fdbuf_create(void *, int, struct fdbuf **);
 925 extern void     so_closefds(void *, t_uscalar_t, int, int);
 926 extern int      so_getfdopt(void *, t_uscalar_t, int, void **, int *);
 927 t_uscalar_t     so_optlen(void *, t_uscalar_t, int);
 928 extern void     so_cmsg2opt(void *, t_uscalar_t, int, mblk_t *);
 929 extern t_uscalar_t
 930                 so_cmsglen(mblk_t *, void *, t_uscalar_t, int);
 931 extern int      so_opt2cmsg(mblk_t *, void *, t_uscalar_t, int,
 932                         void *, t_uscalar_t);
 933 extern void     soisconnecting(struct sonode *);
 934 extern void     soisconnected(struct sonode *);
 935 extern void     soisdisconnected(struct sonode *, int);
 936 extern void     socantsendmore(struct sonode *);
 937 extern void     socantrcvmore(struct sonode *);
 938 extern void     soseterror(struct sonode *, int);
 939 extern int      sogeterr(struct sonode *, boolean_t);
 940 extern int      sowaitconnected(struct sonode *, int, int);
 941 
 942 extern ssize_t  soreadfile(file_t *, uchar_t *, u_offset_t, int *, size_t);
 943 extern void     *sock_kstat_init(zoneid_t);
 944 extern void     sock_kstat_fini(zoneid_t, void *);
 945 extern struct sonode *getsonode(int, int *, file_t **);
 946 /*
 947  * Function wrappers (mostly around the sonode switch) for
 948  * backward compatibility.
 949  */
 950 extern int      soaccept(struct sonode *, int, struct sonode **);
 951 extern int      sobind(struct sonode *, struct sockaddr *, socklen_t,
 952                     int, int);
 953 extern int      solisten(struct sonode *, int);
 954 extern int      soconnect(struct sonode *, struct sockaddr *, socklen_t,
 955                     int, int);
 956 extern int      sorecvmsg(struct sonode *, struct nmsghdr *, struct uio *);
 957 extern int      sosendmsg(struct sonode *, struct nmsghdr *, struct uio *);
 958 extern int      soshutdown(struct sonode *, int);
 959 extern int      sogetsockopt(struct sonode *, int, int, void *, socklen_t *,
 960                     int);
 961 extern int      sosetsockopt(struct sonode *, int, int, const void *,
 962                     t_uscalar_t);
 963 
 964 extern struct sonode    *socreate(struct sockparams *, int, int, int, int,
 965                             int *);
 966 
 967 extern int      so_copyin(const void *, void *, size_t, int);
 968 extern int      so_copyout(const void *, void *, size_t, int);
 969 
 970 #endif
 971 
 972 /*
 973  * Internal structure for obtaining sonode information from the socklist.
 974  * These types match those corresponding in the sonode structure.
 975  * This is not a published interface, and may change at any time.
 976  */
 977 struct sockinfo {
 978         uint_t          si_size;                /* real length of this struct */
 979         short           si_family;
 980         short           si_type;
 981         ushort_t        si_flag;
 982         uint_t          si_state;
 983         uint_t          si_ux_laddr_sou_magic;
 984         uint_t          si_ux_faddr_sou_magic;
 985         t_scalar_t      si_serv_type;
 986         t_uscalar_t     si_laddr_soa_len;
 987         t_uscalar_t     si_faddr_soa_len;
 988         uint16_t        si_laddr_family;
 989         uint16_t        si_faddr_family;
 990         char            si_laddr_sun_path[MAXPATHLEN + 1]; /* NULL terminated */
 991         char            si_faddr_sun_path[MAXPATHLEN + 1];
 992         boolean_t       si_faddr_noxlate;
 993         zoneid_t        si_szoneid;
 994 };
 995 
 996 /*
 997  * Subcodes for sockconf() system call
 998  */
 999 #define SOCKCONFIG_ADD_SOCK             0
1000 #define SOCKCONFIG_REMOVE_SOCK          1
1001 #define SOCKCONFIG_ADD_FILTER           2
1002 #define SOCKCONFIG_REMOVE_FILTER        3
1003 #define SOCKCONFIG_GET_SOCKTABLE        4
1004 
1005 /*
1006  * Data structures for configuring socket filters.
1007  */
1008 
1009 /*
1010  * Placement hint for automatic filters
1011  */
1012 typedef enum {
1013         SOF_HINT_NONE,
1014         SOF_HINT_TOP,
1015         SOF_HINT_BOTTOM,
1016         SOF_HINT_BEFORE,
1017         SOF_HINT_AFTER
1018 } sof_hint_t;
1019 
1020 /*
1021  * Socket tuple. Used by sockconfig_filter_props to list socket
1022  * types of interest.
1023  */
1024 typedef struct sof_socktuple {
1025         int     sofst_family;
1026         int     sofst_type;
1027         int     sofst_protocol;
1028 } sof_socktuple_t;
1029 
1030 /*
1031  * Socket filter properties used by sockconfig() system call.
1032  */
1033 struct sockconfig_filter_props {
1034         char            *sfp_modname;
1035         boolean_t       sfp_autoattach;
1036         sof_hint_t      sfp_hint;
1037         char            *sfp_hintarg;
1038         uint_t          sfp_socktuple_cnt;
1039         sof_socktuple_t *sfp_socktuple;
1040 };
1041 
1042 /*
1043  * Data structures for the in-kernel socket configuration table.
1044  */
1045 typedef struct sockconfig_socktable_entry {
1046         int             se_family;
1047         int             se_type;
1048         int             se_protocol;
1049         int             se_refcnt;
1050         int             se_flags;
1051         char            se_modname[MODMAXNAMELEN];
1052         char            se_strdev[MAXPATHLEN];
1053 } sockconfig_socktable_entry_t;
1054 
1055 typedef struct sockconfig_socktable {
1056         uint_t          num_of_entries;
1057         sockconfig_socktable_entry_t *st_entries;
1058 } sockconfig_socktable_t;
1059 
1060 #ifdef  _SYSCALL32
1061 
1062 typedef struct sof_socktuple32 {
1063         int32_t sofst_family;
1064         int32_t sofst_type;
1065         int32_t sofst_protocol;
1066 } sof_socktuple32_t;
1067 
1068 struct sockconfig_filter_props32 {
1069         caddr32_t       sfp_modname;
1070         boolean_t       sfp_autoattach;
1071         sof_hint_t      sfp_hint;
1072         caddr32_t       sfp_hintarg;
1073         uint32_t        sfp_socktuple_cnt;
1074         caddr32_t       sfp_socktuple;
1075 };
1076 
1077 typedef struct sockconfig_socktable32 {
1078         uint_t          num_of_entries;
1079         caddr32_t       st_entries;
1080 } sockconfig_socktable32_t;
1081 
1082 #endif  /* _SYSCALL32 */
1083 
1084 #define SOCKMOD_PATH    "socketmod"     /* dir where sockmods are stored */
1085 
1086 #ifdef  __cplusplus
1087 }
1088 #endif
1089 
1090 #endif  /* _SYS_SOCKETVAR_H */