xref: /onnv-gate/usr/src/uts/common/inet/sockmods/sockmod_sdp.c (revision 12644:4f9a0cd40c5f)
18348SEric.Yu@Sun.COM /*
28348SEric.Yu@Sun.COM  * CDDL HEADER START
38348SEric.Yu@Sun.COM  *
48348SEric.Yu@Sun.COM  * The contents of this file are subject to the terms of the
58348SEric.Yu@Sun.COM  * Common Development and Distribution License (the "License").
68348SEric.Yu@Sun.COM  * You may not use this file except in compliance with the License.
78348SEric.Yu@Sun.COM  *
88348SEric.Yu@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98348SEric.Yu@Sun.COM  * or http://www.opensolaris.org/os/licensing.
108348SEric.Yu@Sun.COM  * See the License for the specific language governing permissions
118348SEric.Yu@Sun.COM  * and limitations under the License.
128348SEric.Yu@Sun.COM  *
138348SEric.Yu@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
148348SEric.Yu@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158348SEric.Yu@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
168348SEric.Yu@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
178348SEric.Yu@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
188348SEric.Yu@Sun.COM  *
198348SEric.Yu@Sun.COM  * CDDL HEADER END
208348SEric.Yu@Sun.COM  */
218348SEric.Yu@Sun.COM 
228348SEric.Yu@Sun.COM /*
23*12644SAnders.Persson@Sun.COM  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
248348SEric.Yu@Sun.COM  */
258348SEric.Yu@Sun.COM 
268348SEric.Yu@Sun.COM #include <sys/sysmacros.h>
278348SEric.Yu@Sun.COM #include <sys/strsubr.h>
288348SEric.Yu@Sun.COM #include <sys/socket.h>
298348SEric.Yu@Sun.COM #include <sys/socketvar.h>
308348SEric.Yu@Sun.COM #include <sys/modctl.h>
318348SEric.Yu@Sun.COM #include <sys/cmn_err.h>
328348SEric.Yu@Sun.COM #include <sys/vfs.h>
338348SEric.Yu@Sun.COM #include <inet/sdp_itf.h>
348348SEric.Yu@Sun.COM #include <fs/sockfs/sockcommon.h>
358348SEric.Yu@Sun.COM #include "socksdp.h"
368348SEric.Yu@Sun.COM 
378348SEric.Yu@Sun.COM struct sonode *socksdp_create(struct sockparams *, int, int, int,
388348SEric.Yu@Sun.COM     int, int, int *, cred_t *);
398348SEric.Yu@Sun.COM static void socksdp_destroy(struct sonode *);
408348SEric.Yu@Sun.COM 
418348SEric.Yu@Sun.COM static __smod_priv_t sosdp_priv = {
428348SEric.Yu@Sun.COM 	socksdp_create,
438348SEric.Yu@Sun.COM 	socksdp_destroy,
448348SEric.Yu@Sun.COM 	NULL
458348SEric.Yu@Sun.COM };
468348SEric.Yu@Sun.COM 
478348SEric.Yu@Sun.COM static smod_reg_t sinfo = {
488348SEric.Yu@Sun.COM 	SOCKMOD_VERSION,
498348SEric.Yu@Sun.COM 	"socksdp",
508348SEric.Yu@Sun.COM 	SOCK_UC_VERSION,
518348SEric.Yu@Sun.COM 	SOCK_DC_VERSION,
528348SEric.Yu@Sun.COM 	NULL,
538348SEric.Yu@Sun.COM 	&sosdp_priv
548348SEric.Yu@Sun.COM };
558348SEric.Yu@Sun.COM 
568348SEric.Yu@Sun.COM /*
578348SEric.Yu@Sun.COM  * Module linkage information for the kernel
588348SEric.Yu@Sun.COM  */
598348SEric.Yu@Sun.COM static struct modlsockmod modlsockmod = {
608348SEric.Yu@Sun.COM 	&mod_sockmodops, "SDP socket module", &sinfo
618348SEric.Yu@Sun.COM };
628348SEric.Yu@Sun.COM 
638348SEric.Yu@Sun.COM static struct modlinkage modlinkage = {
648348SEric.Yu@Sun.COM 	MODREV_1,
658348SEric.Yu@Sun.COM 	&modlsockmod,
668348SEric.Yu@Sun.COM 	NULL
678348SEric.Yu@Sun.COM };
688348SEric.Yu@Sun.COM 
698348SEric.Yu@Sun.COM /*
708348SEric.Yu@Sun.COM  * Creates a sdp socket data structure.
718348SEric.Yu@Sun.COM  */
728348SEric.Yu@Sun.COM /* ARGSUSED */
738348SEric.Yu@Sun.COM struct sonode *
socksdp_create(struct sockparams * sp,int family,int type,int protocol,int version,int sflags,int * errorp,cred_t * cr)748348SEric.Yu@Sun.COM socksdp_create(struct sockparams *sp, int family, int type, int protocol,
758348SEric.Yu@Sun.COM 		    int version, int sflags, int *errorp, cred_t *cr)
768348SEric.Yu@Sun.COM {
778348SEric.Yu@Sun.COM 	struct sonode *so;
788348SEric.Yu@Sun.COM 	int kmflags = (sflags & SOCKET_NOSLEEP) ? KM_NOSLEEP : KM_SLEEP;
798348SEric.Yu@Sun.COM 
808348SEric.Yu@Sun.COM 	dprint(4, ("Inside sosdp_create: domain:%d proto:%d type:%d",
818348SEric.Yu@Sun.COM 	    family, protocol, type));
828348SEric.Yu@Sun.COM 
838348SEric.Yu@Sun.COM 	*errorp = 0;
848348SEric.Yu@Sun.COM 	if (is_system_labeled()) {
858348SEric.Yu@Sun.COM 		*errorp = EOPNOTSUPP;
868348SEric.Yu@Sun.COM 		return (NULL);
878348SEric.Yu@Sun.COM 	}
888348SEric.Yu@Sun.COM 
898348SEric.Yu@Sun.COM 	if (version == SOV_STREAM) {
908348SEric.Yu@Sun.COM 		*errorp = EINVAL;
918348SEric.Yu@Sun.COM 		return (NULL);
928348SEric.Yu@Sun.COM 	}
938348SEric.Yu@Sun.COM 
948348SEric.Yu@Sun.COM 	/*
958348SEric.Yu@Sun.COM 	 * We only support one type of SDP socket.  Let sotpi_create()
968348SEric.Yu@Sun.COM 	 * handle all other cases, such as raw socket.
978348SEric.Yu@Sun.COM 	 */
988348SEric.Yu@Sun.COM 	if (!(family == AF_INET || family == AF_INET6) ||
998348SEric.Yu@Sun.COM 	    !(type == SOCK_STREAM)) {
1008348SEric.Yu@Sun.COM 		*errorp = EINVAL;
1018348SEric.Yu@Sun.COM 		return (NULL);
1028348SEric.Yu@Sun.COM 	}
1038348SEric.Yu@Sun.COM 
1048348SEric.Yu@Sun.COM 	so = kmem_cache_alloc(socket_cache, kmflags);
1058348SEric.Yu@Sun.COM 	if (so == NULL) {
1068348SEric.Yu@Sun.COM 		*errorp = ENOMEM;
1078348SEric.Yu@Sun.COM 		return (NULL);
1088348SEric.Yu@Sun.COM 	}
1098348SEric.Yu@Sun.COM 
1108348SEric.Yu@Sun.COM 	sonode_init(so, sp, family, type, protocol, &sosdp_sonodeops);
1118348SEric.Yu@Sun.COM 	so->so_pollev |= SO_POLLEV_ALWAYS;
1128348SEric.Yu@Sun.COM 
1138348SEric.Yu@Sun.COM 	dprint(2, ("sosdp_create: %p domain %d type %d\n", (void *)so, family,
1148348SEric.Yu@Sun.COM 	    type));
1158348SEric.Yu@Sun.COM 
1168348SEric.Yu@Sun.COM 	if (version == SOV_DEFAULT) {
1178348SEric.Yu@Sun.COM 		version = so_default_version;
1188348SEric.Yu@Sun.COM 	}
1198348SEric.Yu@Sun.COM 	so->so_version = (short)version;
1208348SEric.Yu@Sun.COM 
1219059SErik.Nordmark@Sun.COM 	/*
1229059SErik.Nordmark@Sun.COM 	 * set the default values to be INFPSZ
1239059SErik.Nordmark@Sun.COM 	 * if a protocol desires it can change the value later
1249059SErik.Nordmark@Sun.COM 	 */
1259059SErik.Nordmark@Sun.COM 	so->so_proto_props.sopp_rxhiwat = SOCKET_RECVHIWATER;
1269059SErik.Nordmark@Sun.COM 	so->so_proto_props.sopp_rxlowat = SOCKET_RECVLOWATER;
1279059SErik.Nordmark@Sun.COM 	so->so_proto_props.sopp_maxpsz = INFPSZ;
1289059SErik.Nordmark@Sun.COM 	so->so_proto_props.sopp_maxblk = INFPSZ;
1299059SErik.Nordmark@Sun.COM 
1308348SEric.Yu@Sun.COM 	return (so);
1318348SEric.Yu@Sun.COM }
1328348SEric.Yu@Sun.COM 
1338348SEric.Yu@Sun.COM static void
socksdp_destroy(struct sonode * so)1348348SEric.Yu@Sun.COM socksdp_destroy(struct sonode *so)
1358348SEric.Yu@Sun.COM {
1368348SEric.Yu@Sun.COM 	ASSERT(so->so_ops == &sosdp_sonodeops);
1378348SEric.Yu@Sun.COM 
1388348SEric.Yu@Sun.COM 	sosdp_fini(so, CRED());
1398348SEric.Yu@Sun.COM 
1408348SEric.Yu@Sun.COM 	kmem_cache_free(socket_cache, so);
1418348SEric.Yu@Sun.COM }
1428348SEric.Yu@Sun.COM 
1438348SEric.Yu@Sun.COM int
_init(void)1448348SEric.Yu@Sun.COM _init(void)
1458348SEric.Yu@Sun.COM {
1468348SEric.Yu@Sun.COM 	return (mod_install(&modlinkage));
1478348SEric.Yu@Sun.COM }
1488348SEric.Yu@Sun.COM 
1498348SEric.Yu@Sun.COM int
_fini(void)1508348SEric.Yu@Sun.COM _fini(void)
1518348SEric.Yu@Sun.COM {
1528348SEric.Yu@Sun.COM 	return (mod_remove(&modlinkage));
1538348SEric.Yu@Sun.COM }
1548348SEric.Yu@Sun.COM 
1558348SEric.Yu@Sun.COM int
_info(struct modinfo * modinfop)1568348SEric.Yu@Sun.COM _info(struct modinfo *modinfop)
1578348SEric.Yu@Sun.COM {
1588348SEric.Yu@Sun.COM 	return (mod_info(&modlinkage, modinfop));
1598348SEric.Yu@Sun.COM }
160