10f1702c5SYu Xiangning /*
20f1702c5SYu Xiangning  * CDDL HEADER START
30f1702c5SYu Xiangning  *
40f1702c5SYu Xiangning  * The contents of this file are subject to the terms of the
50f1702c5SYu Xiangning  * Common Development and Distribution License (the "License").
60f1702c5SYu Xiangning  * You may not use this file except in compliance with the License.
70f1702c5SYu Xiangning  *
80f1702c5SYu Xiangning  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90f1702c5SYu Xiangning  * or http://www.opensolaris.org/os/licensing.
100f1702c5SYu Xiangning  * See the License for the specific language governing permissions
110f1702c5SYu Xiangning  * and limitations under the License.
120f1702c5SYu Xiangning  *
130f1702c5SYu Xiangning  * When distributing Covered Code, include this CDDL HEADER in each
140f1702c5SYu Xiangning  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150f1702c5SYu Xiangning  * If applicable, add the following below this CDDL HEADER, with the
160f1702c5SYu Xiangning  * fields enclosed by brackets "[]" replaced with your own identifying
170f1702c5SYu Xiangning  * information: Portions Copyright [yyyy] [name of copyright owner]
180f1702c5SYu Xiangning  *
190f1702c5SYu Xiangning  * CDDL HEADER END
200f1702c5SYu Xiangning  */
210f1702c5SYu Xiangning 
220f1702c5SYu Xiangning /*
23*dd49f125SAnders Persson  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
240f1702c5SYu Xiangning  */
250f1702c5SYu Xiangning 
260f1702c5SYu Xiangning #include <sys/sysmacros.h>
270f1702c5SYu Xiangning #include <sys/strsubr.h>
280f1702c5SYu Xiangning #include <sys/socket.h>
290f1702c5SYu Xiangning #include <sys/socketvar.h>
300f1702c5SYu Xiangning #include <sys/modctl.h>
310f1702c5SYu Xiangning #include <sys/cmn_err.h>
320f1702c5SYu Xiangning #include <sys/vfs.h>
330f1702c5SYu Xiangning #include <inet/sdp_itf.h>
340f1702c5SYu Xiangning #include <fs/sockfs/sockcommon.h>
350f1702c5SYu Xiangning #include "socksdp.h"
360f1702c5SYu Xiangning 
370f1702c5SYu Xiangning struct sonode *socksdp_create(struct sockparams *, int, int, int,
380f1702c5SYu Xiangning     int, int, int *, cred_t *);
390f1702c5SYu Xiangning static void socksdp_destroy(struct sonode *);
400f1702c5SYu Xiangning 
410f1702c5SYu Xiangning static __smod_priv_t sosdp_priv = {
420f1702c5SYu Xiangning 	socksdp_create,
430f1702c5SYu Xiangning 	socksdp_destroy,
440f1702c5SYu Xiangning 	NULL
450f1702c5SYu Xiangning };
460f1702c5SYu Xiangning 
470f1702c5SYu Xiangning static smod_reg_t sinfo = {
480f1702c5SYu Xiangning 	SOCKMOD_VERSION,
490f1702c5SYu Xiangning 	"socksdp",
500f1702c5SYu Xiangning 	SOCK_UC_VERSION,
510f1702c5SYu Xiangning 	SOCK_DC_VERSION,
520f1702c5SYu Xiangning 	NULL,
530f1702c5SYu Xiangning 	&sosdp_priv
540f1702c5SYu Xiangning };
550f1702c5SYu Xiangning 
560f1702c5SYu Xiangning /*
570f1702c5SYu Xiangning  * Module linkage information for the kernel
580f1702c5SYu Xiangning  */
590f1702c5SYu Xiangning static struct modlsockmod modlsockmod = {
600f1702c5SYu Xiangning 	&mod_sockmodops, "SDP socket module", &sinfo
610f1702c5SYu Xiangning };
620f1702c5SYu Xiangning 
630f1702c5SYu Xiangning static struct modlinkage modlinkage = {
640f1702c5SYu Xiangning 	MODREV_1,
650f1702c5SYu Xiangning 	&modlsockmod,
660f1702c5SYu Xiangning 	NULL
670f1702c5SYu Xiangning };
680f1702c5SYu Xiangning 
690f1702c5SYu Xiangning /*
700f1702c5SYu Xiangning  * Creates a sdp socket data structure.
710f1702c5SYu Xiangning  */
720f1702c5SYu Xiangning /* ARGSUSED */
730f1702c5SYu Xiangning struct sonode *
socksdp_create(struct sockparams * sp,int family,int type,int protocol,int version,int sflags,int * errorp,cred_t * cr)740f1702c5SYu Xiangning socksdp_create(struct sockparams *sp, int family, int type, int protocol,
750f1702c5SYu Xiangning 		    int version, int sflags, int *errorp, cred_t *cr)
760f1702c5SYu Xiangning {
770f1702c5SYu Xiangning 	struct sonode *so;
780f1702c5SYu Xiangning 	int kmflags = (sflags & SOCKET_NOSLEEP) ? KM_NOSLEEP : KM_SLEEP;
790f1702c5SYu Xiangning 
800f1702c5SYu Xiangning 	dprint(4, ("Inside sosdp_create: domain:%d proto:%d type:%d",
810f1702c5SYu Xiangning 	    family, protocol, type));
820f1702c5SYu Xiangning 
830f1702c5SYu Xiangning 	*errorp = 0;
840f1702c5SYu Xiangning 	if (is_system_labeled()) {
850f1702c5SYu Xiangning 		*errorp = EOPNOTSUPP;
860f1702c5SYu Xiangning 		return (NULL);
870f1702c5SYu Xiangning 	}
880f1702c5SYu Xiangning 
890f1702c5SYu Xiangning 	if (version == SOV_STREAM) {
900f1702c5SYu Xiangning 		*errorp = EINVAL;
910f1702c5SYu Xiangning 		return (NULL);
920f1702c5SYu Xiangning 	}
930f1702c5SYu Xiangning 
940f1702c5SYu Xiangning 	/*
950f1702c5SYu Xiangning 	 * We only support one type of SDP socket.  Let sotpi_create()
960f1702c5SYu Xiangning 	 * handle all other cases, such as raw socket.
970f1702c5SYu Xiangning 	 */
980f1702c5SYu Xiangning 	if (!(family == AF_INET || family == AF_INET6) ||
990f1702c5SYu Xiangning 	    !(type == SOCK_STREAM)) {
1000f1702c5SYu Xiangning 		*errorp = EINVAL;
1010f1702c5SYu Xiangning 		return (NULL);
1020f1702c5SYu Xiangning 	}
1030f1702c5SYu Xiangning 
1040f1702c5SYu Xiangning 	so = kmem_cache_alloc(socket_cache, kmflags);
1050f1702c5SYu Xiangning 	if (so == NULL) {
1060f1702c5SYu Xiangning 		*errorp = ENOMEM;
1070f1702c5SYu Xiangning 		return (NULL);
1080f1702c5SYu Xiangning 	}
1090f1702c5SYu Xiangning 
1100f1702c5SYu Xiangning 	sonode_init(so, sp, family, type, protocol, &sosdp_sonodeops);
1110f1702c5SYu Xiangning 	so->so_pollev |= SO_POLLEV_ALWAYS;
1120f1702c5SYu Xiangning 
1130f1702c5SYu Xiangning 	dprint(2, ("sosdp_create: %p domain %d type %d\n", (void *)so, family,
1140f1702c5SYu Xiangning 	    type));
1150f1702c5SYu Xiangning 
1160f1702c5SYu Xiangning 	if (version == SOV_DEFAULT) {
1170f1702c5SYu Xiangning 		version = so_default_version;
1180f1702c5SYu Xiangning 	}
1190f1702c5SYu Xiangning 	so->so_version = (short)version;
1200f1702c5SYu Xiangning 
121d496d3f8SErik Nordmark 	/*
122d496d3f8SErik Nordmark 	 * set the default values to be INFPSZ
123d496d3f8SErik Nordmark 	 * if a protocol desires it can change the value later
124d496d3f8SErik Nordmark 	 */
125d496d3f8SErik Nordmark 	so->so_proto_props.sopp_rxhiwat = SOCKET_RECVHIWATER;
126d496d3f8SErik Nordmark 	so->so_proto_props.sopp_rxlowat = SOCKET_RECVLOWATER;
127d496d3f8SErik Nordmark 	so->so_proto_props.sopp_maxpsz = INFPSZ;
128d496d3f8SErik Nordmark 	so->so_proto_props.sopp_maxblk = INFPSZ;
129d496d3f8SErik Nordmark 
1300f1702c5SYu Xiangning 	return (so);
1310f1702c5SYu Xiangning }
1320f1702c5SYu Xiangning 
1330f1702c5SYu Xiangning static void
socksdp_destroy(struct sonode * so)1340f1702c5SYu Xiangning socksdp_destroy(struct sonode *so)
1350f1702c5SYu Xiangning {
1360f1702c5SYu Xiangning 	ASSERT(so->so_ops == &sosdp_sonodeops);
1370f1702c5SYu Xiangning 
1380f1702c5SYu Xiangning 	sosdp_fini(so, CRED());
1390f1702c5SYu Xiangning 
1400f1702c5SYu Xiangning 	kmem_cache_free(socket_cache, so);
1410f1702c5SYu Xiangning }
1420f1702c5SYu Xiangning 
1430f1702c5SYu Xiangning int
_init(void)1440f1702c5SYu Xiangning _init(void)
1450f1702c5SYu Xiangning {
1460f1702c5SYu Xiangning 	return (mod_install(&modlinkage));
1470f1702c5SYu Xiangning }
1480f1702c5SYu Xiangning 
1490f1702c5SYu Xiangning int
_fini(void)1500f1702c5SYu Xiangning _fini(void)
1510f1702c5SYu Xiangning {
1520f1702c5SYu Xiangning 	return (mod_remove(&modlinkage));
1530f1702c5SYu Xiangning }
1540f1702c5SYu Xiangning 
1550f1702c5SYu Xiangning int
_info(struct modinfo * modinfop)1560f1702c5SYu Xiangning _info(struct modinfo *modinfop)
1570f1702c5SYu Xiangning {
1580f1702c5SYu Xiangning 	return (mod_info(&modlinkage, modinfop));
1590f1702c5SYu Xiangning }
160