sockparams.c revision 22238f73378cc4cb6fd470f00810959bdd55aff6
* Socket parameter (struct sockparams) entries represent the socket types * available on the system. * SOCKPARAMS_EPHEMERAL: A temporary sockparams entry that will be deleted * as soon as its' ref count drops to zero. In addition, ephemeral entries will * never be hooked onto the global sockparams list. Ephemeral entries are * created when application requests to create a socket using an application * supplied device path, or when a socket is falling back to TPI. * The lock order is splist_lock -> sp_lock. * The lock order is sp_ephem_lock -> sp_lock. * Global sockparams list (populated via soconfig(1M)). * List of ephemeral sockparams. * sockparams_create(int family, int type, int protocol, char *modname, * char *devpath, int devpathlen, int flags, int kmflags, int *errorp) * Create a new sockparams entry. * family, type, protocol: specifies the socket type * modname: Name of the module associated with the socket type. The * module can be NULL if a device path is given, in which * case the TPI module is used. * devpath: Path to the STREAMS device. May be NULL for non-STREAMS * based transports, or those transports that do not provide * the capability to fallback to STREAMS. * devpathlen: Length of the devpath string. The argument can be 0, * indicating that devpath was allocated statically, and should * not be freed when the sockparams entry is destroyed. * flags : SOCKPARAMS_EPHEMERAL is the only flag that is allowed. * errorp : Value-return argument, set when an error occurs. * On success a new sockparams entry is returned, and *errorp is set * to 0. On failure NULL is returned and *errorp is set to indicate the * type of error that occured. * devpath and modname are freed upon failure. /* either a module or device must be given */ /* Set up the device entry. */ * Initialize the STREAMS device aspect of the sockparams entry. dprint(0, (
"sockparams_sdev_init: vp %s failed with %d\n",
* sockparams_destroy(struct sockparams *sp) * Releases all the resources associated with the sockparams entry, * and frees the sockparams entry. * sp: the sockparams entry to destroy. * The sp_lock of the entry can not be held. * Clean up the STREAMS device part of the sockparams entry. * if the entry does not have a STREAMS device, then there * Look for a matching sockparams entry on the given list. * The caller must hold the associated list lock. * sockparams_hold_ephemeral() * Returns an ephemeral sockparams entry of the requested family, type and * protocol. The entry is returned held, and the caller is responsible for * dropping the reference using SOCKPARAMS_DEC_REF() once done. * All ephemeral entries are on list (sp_ephem_list). If there is an * entry on the list that match the search criteria, then a reference is * placed on that entry. Otherwise, a new entry is created and inserted * in the list. The entry is removed from the list when the last reference * The tpi flag is used to determine whether name refers to a device or * First look for an existing entry * Time to load the socket module. * The sockparams entry was created, now try to add it * to the list. We need to hold the lock as a WRITER. * Someone has requested a matching entry, so just * place a hold on it and release the entry we alloc'ed. * Called when the last socket using the ephemeral entry is dropping * its' reference. To maintain lock order we must drop the sockparams * lock before calling this function. As a result, a new reference * might be placed on the entry, in which case there is nothing to * do. However, if ref count goes to zero, we delete the entry. * sockparams_add(struct sockparams *sp) * Tries to add the given sockparams entry to the global list. * sp: the sockparms entry to add * On success 0, but if an entry already exists, then EEXIST * The caller can not be holding splist_lock. * sockparams_delete(int family, int type, int protocol) * Marks the sockparams entry for a specific family, type and protocol * for deletion. The entry is removed from the list and destroyed * if no one is holding a reference to it. * family, type, protocol: the socket type that should be removed. * On success 0, otherwise ENXIO. * Caller can not be holding splist_lock or the sp_lock of * If no one is holding a reference to the entry, then * we go ahead and remove it from the list and then /* Delete the sockparams entry. */ * soconfig(int family, int type, int protocol, * char *devpath, int devpathlen, char *module) * Add or delete an entry to the sockparams table. * When devpath and module both are NULL, it will delete an entry. * family, type, protocol: the tuple in question * devpath: STREAMS device path. Can be NULL for module based sockets. * module : Name of the socket module. Can be NULL for STREAMS * devpathlen: length of the devpath string, or 0 if devpath * was statically allocated. * This routine assumes that the caller has kmem_alloced * devpath (if devpathlen > 0) and module for this routine to dprint(0, (
"soconfig(%d,%d,%d,%s,%d,%s)\n",
* both socket module and STEAMS device. * sockparams_create frees mod name and devpath upon failure. * solookup(int family, int type, int protocol, struct sockparams **spp) * Lookup an entry in the sockparams list based on the triple. The returned * entry either exactly match the given tuple, or it is the 'default' entry * for the given <family, type>. A default entry is on with a protocol * family, type, protocol: tuple to search for * spp: Value-return argument * If an entry is found, 0 is returned and *spp is set to point to the * entry. In case an entry is not found, *spp is set to NULL, and an * error code is returned. The errors are (in decreasing precedence): * EAFNOSUPPORT - address family not in list * EPROTONOSUPPORT - address family supported but not protocol. * EPROTOTYPE - address family and protocol supported but not socket type. * TODO: should use ddi_modopen()/ddi_modclose() * Search the sockparams list for an appropiate entry. * Hopefully we find an entry that match the exact family, * type and protocol specified by the user, in which case * we return that entry. However, we also keep track of * the default entry for a specific family and type, the * entry of which would have a protocol value of 0. /* Determine correct error code */ * We put a hold on the entry early on, so if the * sockmod is not loaded, and we have to exit * splist_lock to call modload(), we know that the * sockparams entry wont go away. That way we don't * have to look up the entry once we come back from * We put a hold on the sockparams entry * earlier, hoping everything would work out. * That obviously did not happen, so release * We should probably mark the sockparams as * "bad", and redo the lookup skipping the * "bad" entries. I.e., sp->sp_mod_state |= BAD, * Alright, we have a valid sockparams entry.