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