xref: /titanic_41/usr/src/uts/common/inet/nca/ncaddi.c (revision 5e2c3ae0c70f6eb4a42ae670882aabac983cb5f1)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
25  */
26 
27 #include <sys/types.h>
28 #include <sys/conf.h>
29 #include <sys/modctl.h>
30 #include <sys/stream.h>
31 #include <sys/strsubr.h>
32 #include <sys/strsun.h>
33 #include <sys/zone.h>
34 #include <inet/common.h>
35 #include <inet/led.h>
36 #include <inet/nd.h>
37 #include <netinet/in.h>
38 
39 #include "ncaconf.h"
40 
41 extern caddr_t	nca_g_nd;	/* Head of 'named dispatch' variable list */
42 
43 #define	INET_NAME	"nca"
44 #define	INET_MODSTRTAB	ncainfo
45 #define	INET_DEVSTRTAB	ncainfo
46 #define	INET_MODDESC	"NCA STREAMS module 1.6"
47 #define	INET_DEVDESC	"NCA STREAMS driver 1.6"
48 #define	INET_DEVMINOR	0
49 #define	INET_DEVMTFLAGS	D_MP
50 #define	INET_MODMTFLAGS	D_MP
51 
52 #include "../inetddi.c"
53 
54 /*ARGSUSED*/
55 static int
56 nca_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
57 {
58 	/* Reopen supported */
59 	if (q->q_ptr != NULL)
60 		return (0);
61 
62 	/*
63 	 * NCA is not supported in non-global zones; we enforce this restriction
64 	 * here.
65 	 */
66 	if (credp != NULL && crgetzoneid(credp) != GLOBAL_ZONEID) {
67 		return (ENOTSUP);
68 	}
69 
70 	if (! (sflag & MODOPEN)) {
71 		/* Device instance */
72 		RD(q)->q_ptr = (void *)B_TRUE;
73 		WR(q)->q_ptr = (void *)B_TRUE;
74 	} else {
75 		/* Modopen just pass through */
76 		RD(q)->q_ptr = (void *)B_FALSE;
77 		WR(q)->q_ptr = (void *)B_FALSE;
78 	}
79 	qprocson(q);
80 	return (0);
81 }
82 
83 static int
84 nca_close(queue_t *q)
85 {
86 	qprocsoff(q);
87 	RD(q)->q_ptr = NULL;
88 	WR(q)->q_ptr = NULL;
89 	return (0);
90 }
91 
92 static void
93 nca_rput(queue_t *q, mblk_t *mp)
94 {
95 	/* Passthrough */
96 	putnext(q, mp);
97 }
98 
99 static void
100 nca_wput(queue_t *q, mblk_t *mp)
101 {
102 	struct iocblk	*iocp;
103 
104 	if (! (boolean_t)q->q_ptr) {
105 		iocp = (struct iocblk *)mp->b_rptr;
106 		if (DB_TYPE(mp) == M_IOCTL && iocp->ioc_cmd == NCA_SET_IF) {
107 			miocnak(q, mp, 0, ENOTSUP);
108 			return;
109 		}
110 		/* Module, passthrough */
111 		putnext(q, mp);
112 		return;
113 	}
114 
115 	switch (DB_TYPE(mp)) {
116 	case M_IOCTL:
117 		iocp = (struct iocblk *)mp->b_rptr;
118 		switch (iocp->ioc_cmd) {
119 		case ND_SET:
120 		case ND_GET:
121 			if (! nd_getset(q, nca_g_nd, mp)) {
122 				miocnak(q, mp, 0, ENOENT);
123 				return;
124 			}
125 			qreply(q, mp);
126 			break;
127 		default:
128 			miocnak(q, mp, 0, ENOTSUP);
129 			break;
130 		}
131 		break;
132 	default:
133 		freemsg(mp);
134 		break;
135 	}
136 }
137 
138 static struct module_info info = {
139 	0, "nca", 1, INFPSZ, 65536, 1024
140 };
141 
142 static struct qinit rinit = {
143 	(pfi_t)nca_rput, NULL, nca_open, nca_close, NULL, &info
144 };
145 
146 static struct qinit winit = {
147 	(pfi_t)nca_wput, NULL, nca_open, nca_close, NULL, &info
148 };
149 
150 struct streamtab ncainfo = {
151 	&rinit, &winit
152 };
153 
154 int
155 _init(void)
156 {
157 	return (mod_install(&modlinkage));
158 }
159 
160 int
161 _fini(void)
162 {
163 	return (EBUSY);
164 }
165 
166 int
167 _info(struct modinfo *modinfop)
168 {
169 	return (mod_info(&modlinkage, modinfop));
170 }
171