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