blob: 7f4f7d305db8370c32dc0d1dc021473a87a0f3fc [file] [log] [blame]
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -07001/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
dh155122f4b3ec62007-01-19 16:59:38 -08005 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -07007 *
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/*
Anders Persson3e95bd42010-06-17 17:22:09 -070022 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070023 */
24
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070025#include <sys/types.h>
26#include <sys/stat.h>
27#include <sys/stream.h>
28#include <sys/ddi.h>
29#include <sys/sunddi.h>
30#include <sys/priv_names.h>
31
32/*
33 * This file contains generic goo needed to hook the STREAMS modules and
34 * drivers that live under uts/common/inet into the DDI. In order to use it,
35 * each module/driver should #define the symbols below (as appropriate) and
36 * then #include this source file; see the other uts/common/inet/<star>ddi.c
37 * files for examples of this in action.
38 *
39 * The symbols that all modules and drivers must define are:
40 *
41 * INET_NAME The name of the module/driver.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070042 *
43 * The symbols that all modules must define are:
44 *
nordmarkfc80c0d2007-10-11 22:57:36 -070045 * INET_MODSTRTAB The name of the `streamtab' structure for this module.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070046 * INET_MODDESC The one-line description for this module.
47 * INET_MODMTFLAGS The mt-streams(9F) flags for the module.
48 *
49 * The symbols that all drivers must define are:
50 *
nordmarkfc80c0d2007-10-11 22:57:36 -070051 * INET_DEVSTRTAB The name of the `streamtab' structure for this driver.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070052 * INET_DEVDESC The one-line description for this driver.
53 * INET_DEVMTFLAGS The mt-streams(9F) flags for the driver.
54 * INET_DEVMINOR The minor number of the driver (usually 0).
55 *
56 * Drivers that need to masquerade as IP should set INET_DEVMTFLAGS to
nordmarkfc80c0d2007-10-11 22:57:36 -070057 * IP_DEVMTFLAGS and set INET_DEVSTRTAB to ipinfo.
Yu Xiangning0f1702c2008-12-11 20:04:13 -080058 *
59 * The symbols that all socket modules must define are:
60 *
61 * INET_SOCKDESC The one-line description for this socket module
62 * INET_SOCK_PROTO_CREATE_FUNC The function used to create PCBs
63 *
64 * In addition, socket modules that can be converted to TPI must define:
65 *
66 * INET_SOCK_PROTO_FB_FUNC The function used to fallback to TPI
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070067 */
68
nordmarkfc80c0d2007-10-11 22:57:36 -070069#if !defined(INET_NAME)
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070070#error inetddi.c: INET_NAME is not defined!
Yu Xiangning0f1702c2008-12-11 20:04:13 -080071#elif !defined(INET_DEVDESC) && !defined(INET_MODDESC) && \
72 !defined(INET_SOCKDESC)
73#error inetddi.c: at least one of INET_DEVDESC or INET_MODDESC or \
74INET_SOCKDESC must be defined!
nordmarkfc80c0d2007-10-11 22:57:36 -070075#elif defined(INET_DEVDESC) && !defined(INET_DEVSTRTAB)
76#error inetddi.c: INET_DEVDESC is defined but INET_DEVSTRTAB is not!
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070077#elif defined(INET_DEVDESC) && !defined(INET_DEVMTFLAGS)
78#error inetddi.c: INET_DEVDESC is defined but INET_DEVMTFLAGS is not!
79#elif defined(INET_DEVDESC) && !defined(INET_DEVMINOR)
80#error inetddi.c: INET_DEVDESC is defined but INET_DEVMINOR is not!
nordmarkfc80c0d2007-10-11 22:57:36 -070081#elif defined(INET_MODDESC) && !defined(INET_MODSTRTAB)
82#error inetddi.c: INET_MODDESC is defined but INET_MODSTRTAB is not!
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070083#elif defined(INET_MODDESC) && !defined(INET_MODMTFLAGS)
84#error inetddi.c: INET_MODDESC is defined but INET_MODMTFLAGS is not!
Yu Xiangning0f1702c2008-12-11 20:04:13 -080085#elif defined(INET_SOCKDESC) && !defined(SOCKMOD_VERSION)
86#error inetddi.c: INET_SOCKDESC is defined but SOCKMOD_VERSION is not!
87#elif defined(INET_SOCKDESC) && !defined(INET_SOCK_PROTO_CREATE_FUNC)
88#error inetddi.c: INET_SOCKDESC is defined but INET_SOCK_PROTO_CREATE_FUNC \
89is not!
Anders Persson3e95bd42010-06-17 17:22:09 -070090#elif defined(INET_SOCK_PROTO_FB_FUNC) && !defined(INET_SOCK_FALLBACK_DEV_V4)
91#error inetddi.c: INET_SOCK_PROTO_FB_FUNC is defined but \
92INET_SOCK_FALLBACK_DEV_V4 is not!
93#elif defined(INET_SOCK_PROTO_FB_FUNC) && !defined(INET_SOCK_FALLBACK_DEV_V6)
94#error inetddi.c: INET_SOCK_PROTO_FB_FUNC is defined but \
95INET_SOCK_FALLBACK_DEV_V6 is not!
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070096#endif
97
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070098#ifdef INET_DEVDESC
99
nordmarkfc80c0d2007-10-11 22:57:36 -0700100extern struct streamtab INET_DEVSTRTAB;
101
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700102/*
nordmarkfc80c0d2007-10-11 22:57:36 -0700103 * Drivers that actually want to be IP would set INET_DEVSTRTAB to ipinfo.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700104 */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700105
106static dev_info_t *inet_dev_info;
107
108#define INET_DEFAULT_PRIV_MODE 0666
109
110static struct dev_priv {
111 char *driver;
112 int privonly;
113 const char *read_priv;
114 const char *write_priv;
115} netdev_privs[] = {
116 {"icmp", PRIVONLY_DEV, PRIV_NET_ICMPACCESS, PRIV_NET_ICMPACCESS},
117 {"icmp6", PRIVONLY_DEV, PRIV_NET_ICMPACCESS, PRIV_NET_ICMPACCESS},
118 {"ip", PRIVONLY_DEV, PRIV_NET_RAWACCESS, PRIV_NET_RAWACCESS},
119 {"ip6", PRIVONLY_DEV, PRIV_NET_RAWACCESS, PRIV_NET_RAWACCESS},
dh155122f4b3ec62007-01-19 16:59:38 -0800120 {"keysock", PRIVONLY_DEV, PRIV_SYS_IP_CONFIG, PRIV_SYS_IP_CONFIG},
121 {"ipsecah", PRIVONLY_DEV, PRIV_SYS_IP_CONFIG, PRIV_SYS_IP_CONFIG},
122 {"ipsecesp", PRIVONLY_DEV, PRIV_SYS_IP_CONFIG, PRIV_SYS_IP_CONFIG},
123 {"spdsock", PRIVONLY_DEV, PRIV_SYS_IP_CONFIG, PRIV_SYS_IP_CONFIG},
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700124 {NULL, 0, NULL, NULL}
125};
126
127static int
128inet_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
129{
Toomas Soome623c3de2020-01-20 19:01:15 +0200130 size_t i, ndevs;
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700131
132 if (cmd != DDI_ATTACH)
133 return (DDI_FAILURE);
134
135 inet_dev_info = devi;
136
137 ndevs = sizeof (netdev_privs) / sizeof (struct dev_priv);
138 for (i = 0; i < ndevs; i++) {
139 char *drv = netdev_privs[i].driver;
140 if (drv == NULL || strcmp(drv, ddi_driver_name(devi)) == 0)
141 break;
142 }
143
Toomas Soome623c3de2020-01-20 19:01:15 +0200144 /* smatch has no idea what VERIFY does. */
145 if (i == ndevs) {
146 VERIFY(i < ndevs);
147 return (DDI_FAILURE);
148 }
149
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700150 return (ddi_create_priv_minor_node(devi, INET_NAME, S_IFCHR,
151 INET_DEVMINOR, DDI_PSEUDO, netdev_privs[i].privonly,
152 netdev_privs[i].read_priv, netdev_privs[i].write_priv,
153 INET_DEFAULT_PRIV_MODE));
154}
155
156static int
157inet_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
158{
159 if (cmd != DDI_DETACH)
160 return (DDI_FAILURE);
161
162 ASSERT(devi == inet_dev_info);
163
164 ddi_remove_minor_node(devi, NULL);
165 return (DDI_SUCCESS);
166}
167
168
169/* ARGSUSED */
170static int
171inet_info(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
172{
173 int error = DDI_FAILURE;
174
175 switch (cmd) {
176 case DDI_INFO_DEVT2DEVINFO:
177 if (inet_dev_info != NULL) {
178 *result = (void *)inet_dev_info;
179 error = DDI_SUCCESS;
180 }
181 break;
182
183 case DDI_INFO_DEVT2INSTANCE:
184 *result = NULL;
185 error = DDI_SUCCESS;
186 break;
187
188 default:
189 break;
190 }
191
192 return (error);
193}
194
195DDI_DEFINE_STREAM_OPS(inet_devops, nulldev, nulldev, inet_attach, inet_detach,
Sherry Moore19397402008-09-22 16:30:26 -0700196 nulldev, inet_info, INET_DEVMTFLAGS, &INET_DEVSTRTAB,
197 ddi_quiesce_not_supported);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700198
199static struct modldrv modldrv = {
200 &mod_driverops,
201 INET_DEVDESC,
202 &inet_devops
203};
204
205#endif /* INET_DEVDESC */
206
207#ifdef INET_MODDESC
nordmarkfc80c0d2007-10-11 22:57:36 -0700208extern struct streamtab INET_MODSTRTAB;
209
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700210static struct fmodsw fsw = {
211 INET_NAME,
nordmarkfc80c0d2007-10-11 22:57:36 -0700212 &INET_MODSTRTAB,
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700213 INET_MODMTFLAGS
214};
215
216static struct modlstrmod modlstrmod = {
217 &mod_strmodops,
218 INET_MODDESC,
219 &fsw
220};
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800221
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700222#endif /* INET_MODDESC */
223
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800224#ifdef INET_SOCKDESC
225
226#ifdef INET_SOCK_PROTO_FB_FUNC
227static __smod_priv_t smodpriv = {
228 NULL,
229 NULL,
Anders Persson3e95bd42010-06-17 17:22:09 -0700230 INET_SOCK_PROTO_FB_FUNC,
231 INET_SOCK_FALLBACK_DEV_V4,
232 INET_SOCK_FALLBACK_DEV_V6
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800233};
234#endif /* INET_SOCK_PROTO_FB_FUNC */
235
236static struct smod_reg_s smodreg = {
237 SOCKMOD_VERSION,
238 INET_NAME,
239 SOCK_UC_VERSION,
240 SOCK_DC_VERSION,
241 INET_SOCK_PROTO_CREATE_FUNC,
242#ifdef INET_SOCK_PROTO_FB_FUNC
243 &smodpriv
244#else
245 NULL
246#endif /* INET_SOCK_PROTO_FB_FUNC */
247};
248
249static struct modlsockmod modlsockmod = {
250 &mod_sockmodops,
251 INET_SOCKDESC,
252 &smodreg
253};
254#endif /* INET_SOCKDESC */
255
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700256static struct modlinkage modlinkage = {
257 MODREV_1,
258#ifdef INET_DEVDESC
259 &modldrv,
260#endif
261#ifdef INET_MODDESC
262 &modlstrmod,
263#endif
Yu Xiangning0f1702c2008-12-11 20:04:13 -0800264#ifdef INET_SOCKDESC
265 &modlsockmod,
266#endif
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700267 NULL
268};