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