Fri Nov 6 21:33:07 2015 UTC ()
initialize npcb; founds by brainy


(christos)
diff -r1.49 -r1.50 src/sys/netnatm/natm.c

cvs diff -r1.49 -r1.50 src/sys/netnatm/Attic/natm.c (switch to unified diff)

--- src/sys/netnatm/Attic/natm.c 2015/05/02 17:18:04 1.49
+++ src/sys/netnatm/Attic/natm.c 2015/11/06 21:33:07 1.50
@@ -1,547 +1,547 @@ @@ -1,547 +1,547 @@
1/* $NetBSD: natm.c,v 1.49 2015/05/02 17:18:04 rtr Exp $ */ 1/* $NetBSD: natm.c,v 1.50 2015/11/06 21:33:07 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Charles D. Cranor and Washington University. 4 * Copyright (c) 1996 Charles D. Cranor and Washington University.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28/* 28/*
29 * natm.c: native mode ATM access (both aal0 and aal5). 29 * natm.c: native mode ATM access (both aal0 and aal5).
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: natm.c,v 1.49 2015/05/02 17:18:04 rtr Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: natm.c,v 1.50 2015/11/06 21:33:07 christos Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/kmem.h> 36#include <sys/kmem.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/kernel.h> 38#include <sys/kernel.h>
39#include <sys/domain.h> 39#include <sys/domain.h>
40#include <sys/ioctl.h> 40#include <sys/ioctl.h>
41#include <sys/protosw.h> 41#include <sys/protosw.h>
42#include <sys/mbuf.h> 42#include <sys/mbuf.h>
43#include <sys/socket.h> 43#include <sys/socket.h>
44#include <sys/socketvar.h> 44#include <sys/socketvar.h>
45 45
46#include <net/if.h> 46#include <net/if.h>
47#include <net/if_atm.h> 47#include <net/if_atm.h>
48#include <net/netisr.h> 48#include <net/netisr.h>
49#include <net/route.h> 49#include <net/route.h>
50 50
51#include <netinet/in.h> 51#include <netinet/in.h>
52 52
53#include <netnatm/natm.h> 53#include <netnatm/natm.h>
54 54
55u_long natm5_sendspace = 16*1024; 55u_long natm5_sendspace = 16*1024;
56u_long natm5_recvspace = 16*1024; 56u_long natm5_recvspace = 16*1024;
57 57
58u_long natm0_sendspace = 16*1024; 58u_long natm0_sendspace = 16*1024;
59u_long natm0_recvspace = 16*1024; 59u_long natm0_recvspace = 16*1024;
60 60
61static int 61static int
62natm_attach(struct socket *so, int proto) 62natm_attach(struct socket *so, int proto)
63{ 63{
64 int error = 0; 64 int error = 0;
65 struct natmpcb *npcb; 65 struct natmpcb *npcb;
66 66
67 KASSERT(so->so_pcb == NULL); 67 KASSERT(so->so_pcb == NULL);
68 sosetlock(so); 68 sosetlock(so);
69 69
70 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 70 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
71 if (proto == PROTO_NATMAAL5) 71 if (proto == PROTO_NATMAAL5)
72 error = soreserve(so, natm5_sendspace, natm5_recvspace); 72 error = soreserve(so, natm5_sendspace, natm5_recvspace);
73 else 73 else
74 error = soreserve(so, natm0_sendspace, natm0_recvspace); 74 error = soreserve(so, natm0_sendspace, natm0_recvspace);
75 if (error) 75 if (error)
76 return error; 76 return error;
77 } 77 }
78 npcb = npcb_alloc(true); 78 npcb = npcb_alloc(true);
79 npcb->npcb_socket = so; 79 npcb->npcb_socket = so;
80 so->so_pcb = npcb; 80 so->so_pcb = npcb;
81 return error; 81 return error;
82} 82}
83 83
84static void 84static void
85natm_detach(struct socket *so) 85natm_detach(struct socket *so)
86{ 86{
87 struct natmpcb *npcb = (struct natmpcb *)so->so_pcb; 87 struct natmpcb *npcb = (struct natmpcb *)so->so_pcb;
88 88
89 /* 89 /*
90 * we turn on 'drain' *before* we sofree. 90 * we turn on 'drain' *before* we sofree.
91 */ 91 */
92 92
93 npcb_free(npcb, NPCB_DESTROY); /* drain */ 93 npcb_free(npcb, NPCB_DESTROY); /* drain */
94 so->so_pcb = NULL; 94 so->so_pcb = NULL;
95 /* sofree drops the lock */ 95 /* sofree drops the lock */
96 sofree(so); 96 sofree(so);
97 mutex_enter(softnet_lock); 97 mutex_enter(softnet_lock);
98} 98}
99 99
100static int 100static int
101natm_accept(struct socket *so, struct sockaddr *nam) 101natm_accept(struct socket *so, struct sockaddr *nam)
102{ 102{
103 KASSERT(solocked(so)); 103 KASSERT(solocked(so));
104 104
105 return EOPNOTSUPP; 105 return EOPNOTSUPP;
106} 106}
107 107
108static int 108static int
109natm_bind(struct socket *so, struct sockaddr *nam, struct lwp *l) 109natm_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
110{ 110{
111 KASSERT(solocked(so)); 111 KASSERT(solocked(so));
112 112
113 return EOPNOTSUPP; 113 return EOPNOTSUPP;
114} 114}
115 115
116static int 116static int
117natm_listen(struct socket *so, struct lwp *l) 117natm_listen(struct socket *so, struct lwp *l)
118{ 118{
119 KASSERT(solocked(so)); 119 KASSERT(solocked(so));
120 120
121 return EOPNOTSUPP; 121 return EOPNOTSUPP;
122} 122}
123 123
124static int 124static int
125natm_connect(struct socket *so, struct sockaddr *nam, struct lwp *l) 125natm_connect(struct socket *so, struct sockaddr *nam, struct lwp *l)
126{ 126{
127 int error = 0, s2; 127 int error = 0, s2;
128 struct natmpcb *npcb; 128 struct natmpcb *npcb = (struct natmpcb *)so->so_pcb;
129 struct sockaddr_natm *snatm = (struct sockaddr_natm *)nam; 129 struct sockaddr_natm *snatm = (struct sockaddr_natm *)nam;
130 struct atm_pseudoioctl api; 130 struct atm_pseudoioctl api;
131 struct atm_pseudohdr *aph; 131 struct atm_pseudohdr *aph;
132 struct ifnet *ifp; 132 struct ifnet *ifp;
133 int proto = so->so_proto->pr_protocol; 133 int proto = so->so_proto->pr_protocol;
134 134
135 KASSERT(solocked(so)); 135 KASSERT(solocked(so));
136 136
137 /* 137 /*
138 * validate nam and npcb 138 * validate snatm and npcb
139 */ 139 */
140 140
141 if (snatm->snatm_len != sizeof(*snatm) || 141 if (snatm->snatm_len != sizeof(*snatm) ||
142 (npcb->npcb_flags & NPCB_FREE) == 0) 142 (npcb->npcb_flags & NPCB_FREE) == 0)
143 return EINVAL; 143 return EINVAL;
144 if (snatm->snatm_family != AF_NATM) 144 if (snatm->snatm_family != AF_NATM)
145 return EAFNOSUPPORT; 145 return EAFNOSUPPORT;
146 146
147 snatm->snatm_if[IFNAMSIZ-1] = '\0'; /* XXX ensure null termination 147 snatm->snatm_if[IFNAMSIZ-1] = '\0'; /* XXX ensure null termination
148 since ifunit() uses strcmp */ 148 since ifunit() uses strcmp */
149 149
150 /* 150 /*
151 * convert interface string to ifp, validate. 151 * convert interface string to ifp, validate.
152 */ 152 */
153 153
154 ifp = ifunit(snatm->snatm_if); 154 ifp = ifunit(snatm->snatm_if);
155 if (ifp == NULL || (ifp->if_flags & IFF_RUNNING) == 0) { 155 if (ifp == NULL || (ifp->if_flags & IFF_RUNNING) == 0) {
156 return ENXIO; 156 return ENXIO;
157 } 157 }
158 if (ifp->if_output != atm_output) { 158 if (ifp->if_output != atm_output) {
159 return EAFNOSUPPORT; 159 return EAFNOSUPPORT;
160 } 160 }
161 161
162 /* 162 /*
163 * register us with the NATM PCB layer 163 * register us with the NATM PCB layer
164 */ 164 */
165 165
166 if (npcb_add(npcb, ifp, snatm->snatm_vci, snatm->snatm_vpi) != npcb) 166 if (npcb_add(npcb, ifp, snatm->snatm_vci, snatm->snatm_vpi) != npcb)
167 return EADDRINUSE; 167 return EADDRINUSE;
168 168
169 /* 169 /*
170 * enable rx 170 * enable rx
171 */ 171 */
172 172
173 ATM_PH_FLAGS(&api.aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0; 173 ATM_PH_FLAGS(&api.aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0;
174 ATM_PH_VPI(&api.aph) = npcb->npcb_vpi; 174 ATM_PH_VPI(&api.aph) = npcb->npcb_vpi;
175 ATM_PH_SETVCI(&api.aph, npcb->npcb_vci); 175 ATM_PH_SETVCI(&api.aph, npcb->npcb_vci);
176 api.rxhand = npcb; 176 api.rxhand = npcb;
177 s2 = splnet(); 177 s2 = splnet();
178 if (ifp->if_ioctl(ifp, SIOCATMENA, &api) != 0) { 178 if (ifp->if_ioctl(ifp, SIOCATMENA, &api) != 0) {
179 splx(s2); 179 splx(s2);
180 npcb_free(npcb, NPCB_REMOVE); 180 npcb_free(npcb, NPCB_REMOVE);
181 return EIO; 181 return EIO;
182 } 182 }
183 splx(s2); 183 splx(s2);
184 184
185 soisconnected(so); 185 soisconnected(so);
186 return error; 186 return error;
187} 187}
188 188
189static int 189static int
190natm_connect2(struct socket *so, struct socket *so2) 190natm_connect2(struct socket *so, struct socket *so2)
191{ 191{
192 KASSERT(solocked(so)); 192 KASSERT(solocked(so));
193 193
194 return EOPNOTSUPP; 194 return EOPNOTSUPP;
195} 195}
196 196
197static int 197static int
198natm_disconnect(struct socket *so) 198natm_disconnect(struct socket *so)
199{ 199{
200 struct natmpcb *npcb = (struct natmpcb *)so->so_pcb; 200 struct natmpcb *npcb = (struct natmpcb *)so->so_pcb;
201 201
202 KASSERT(solocked(so)); 202 KASSERT(solocked(so));
203 KASSERT(npcb != NULL); 203 KASSERT(npcb != NULL);
204 204
205 if ((npcb->npcb_flags & NPCB_CONNECTED) == 0) { 205 if ((npcb->npcb_flags & NPCB_CONNECTED) == 0) {
206 printf("natm: disconnected check\n"); 206 printf("natm: disconnected check\n");
207 return EIO; 207 return EIO;
208 } 208 }
209 ifp = npcb->npcb_ifp; 209 ifp = npcb->npcb_ifp;
210 210
211 /* 211 /*
212 * disable rx 212 * disable rx
213 */ 213 */
214 ATM_PH_FLAGS(&api.aph) = ATM_PH_AAL5; 214 ATM_PH_FLAGS(&api.aph) = ATM_PH_AAL5;
215 ATM_PH_VPI(&api.aph) = npcb->npcb_vpi; 215 ATM_PH_VPI(&api.aph) = npcb->npcb_vpi;
216 ATM_PH_SETVCI(&api.aph, npcb->npcb_vci); 216 ATM_PH_SETVCI(&api.aph, npcb->npcb_vci);
217 api.rxhand = npcb; 217 api.rxhand = npcb;
218 218
219 s2 = splnet(); 219 s2 = splnet();
220 ifp->if_ioctl(ifp, SIOCATMDIS, &api); 220 ifp->if_ioctl(ifp, SIOCATMDIS, &api);
221 splx(s); 221 splx(s);
222 222
223 npcb_free(npcb, NPCB_REMOVE); 223 npcb_free(npcb, NPCB_REMOVE);
224 soisdisconnected(so); 224 soisdisconnected(so);
225 return 0; 225 return 0;
226} 226}
227 227
228static int 228static int
229natm_shutdown(struct socket *so) 229natm_shutdown(struct socket *so)
230{ 230{
231 int s; 231 int s;
232 232
233 KASSERT(solocked(so)); 233 KASSERT(solocked(so));
234 234
235 s = splsoftnet(); 235 s = splsoftnet();
236 socantsendmore(so); 236 socantsendmore(so);
237 splx(s); 237 splx(s);
238 238
239 return 0; 239 return 0;
240} 240}
241 241
242static int 242static int
243natm_abort(struct socket *so) 243natm_abort(struct socket *so)
244{ 244{
245 KASSERT(solocked(so)); 245 KASSERT(solocked(so));
246 246
247 return EOPNOTSUPP; 247 return EOPNOTSUPP;
248} 248}
249 249
250static int 250static int
251natm_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) 251natm_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
252{ 252{
253 int error = 0, s; 253 int error = 0, s;
254 struct natmpcb *npcb; 254 struct natmpcb *npcb;
255 struct atm_rawioctl ario; 255 struct atm_rawioctl ario;
256 256
257 s = SPLSOFTNET(); 257 s = SPLSOFTNET();
258 258
259 npcb = (struct natmpcb *) so->so_pcb; 259 npcb = (struct natmpcb *) so->so_pcb;
260 260
261 /* 261 /*
262 * raw atm ioctl. comes in as a SIOCRAWATM. we convert it to 262 * raw atm ioctl. comes in as a SIOCRAWATM. we convert it to
263 * SIOCXRAWATM and pass it to the driver. 263 * SIOCXRAWATM and pass it to the driver.
264 */ 264 */
265 if (cmd == SIOCRAWATM) { 265 if (cmd == SIOCRAWATM) {
266 if (npcb->npcb_ifp == NULL) { 266 if (npcb->npcb_ifp == NULL) {
267 error = ENOTCONN; 267 error = ENOTCONN;
268 goto done; 268 goto done;
269 } 269 }
270 ario.npcb = npcb; 270 ario.npcb = npcb;
271 ario.rawvalue = *((int *)nam); 271 ario.rawvalue = *((int *)nam);
272 error = npcb->npcb_ifp->if_ioctl(npcb->npcb_ifp, SIOCXRAWATM, &ario); 272 error = npcb->npcb_ifp->if_ioctl(npcb->npcb_ifp, SIOCXRAWATM, &ario);
273 if (!error) { 273 if (!error) {
274 if (ario.rawvalue) 274 if (ario.rawvalue)
275 npcb->npcb_flags |= NPCB_RAW; 275 npcb->npcb_flags |= NPCB_RAW;
276 else 276 else
277 npcb->npcb_flags &= ~(NPCB_RAW); 277 npcb->npcb_flags &= ~(NPCB_RAW);
278 } 278 }
279 279
280 goto done; 280 goto done;
281 } 281 }
282 282
283 error = EOPNOTSUPP; 283 error = EOPNOTSUPP;
284 284
285done: 285done:
286 splx(s); 286 splx(s);
287 return(error); 287 return(error);
288} 288}
289 289
290static int 290static int
291natm_stat(struct socket *so, struct stat *ub) 291natm_stat(struct socket *so, struct stat *ub)
292{ 292{
293 KASSERT(solocked(so)); 293 KASSERT(solocked(so));
294 294
295 return 0; 295 return 0;
296} 296}
297 297
298static int 298static int
299natm_peeraddr(struct socket *so, struct sockaddr *nam) 299natm_peeraddr(struct socket *so, struct sockaddr *nam)
300{ 300{
301 struct natmpcb *npcb = (struct natmpcb *) so->so_pcb; 301 struct natmpcb *npcb = (struct natmpcb *) so->so_pcb;
302 struct sockaddr_natm *snatm = (struct sockaddr_natm *)nam; 302 struct sockaddr_natm *snatm = (struct sockaddr_natm *)nam;
303 303
304 KASSERT(solocked(so)); 304 KASSERT(solocked(so));
305 KASSERT(pcb != NULL); 305 KASSERT(pcb != NULL);
306 KASSERT(nam != NULL); 306 KASSERT(nam != NULL);
307 307
308 memset(snatm, 0, sizeof(*snatm)); 308 memset(snatm, 0, sizeof(*snatm));
309 snatm->snatm_len = sizeof(*snatm); 309 snatm->snatm_len = sizeof(*snatm);
310 snatm->snatm_family = AF_NATM; 310 snatm->snatm_family = AF_NATM;
311 memcpy(snatm->snatm_if, npcb->npcb_ifp->if_xname, sizeof(snatm->snatm_if)); 311 memcpy(snatm->snatm_if, npcb->npcb_ifp->if_xname, sizeof(snatm->snatm_if));
312 snatm->snatm_vci = npcb->npcb_vci; 312 snatm->snatm_vci = npcb->npcb_vci;
313 snatm->snatm_vpi = npcb->npcb_vpi; 313 snatm->snatm_vpi = npcb->npcb_vpi;
314 return 0; 314 return 0;
315} 315}
316 316
317static int 317static int
318natm_sockaddr(struct socket *so, struct sockaddr *nam) 318natm_sockaddr(struct socket *so, struct sockaddr *nam)
319{ 319{
320 KASSERT(solocked(so)); 320 KASSERT(solocked(so));
321 321
322 return EOPNOTSUPP; 322 return EOPNOTSUPP;
323} 323}
324 324
325static int 325static int
326natm_rcvd(struct socket *so, int flags, struct lwp *l) 326natm_rcvd(struct socket *so, int flags, struct lwp *l)
327{ 327{
328 KASSERT(solocked(so)); 328 KASSERT(solocked(so));
329 329
330 return EOPNOTSUPP; 330 return EOPNOTSUPP;
331} 331}
332 332
333static int 333static int
334natm_recvoob(struct socket *so, struct mbuf *m, int flags) 334natm_recvoob(struct socket *so, struct mbuf *m, int flags)
335{ 335{
336 KASSERT(solocked(so)); 336 KASSERT(solocked(so));
337 337
338 return EOPNOTSUPP; 338 return EOPNOTSUPP;
339} 339}
340 340
341static int 341static int
342natm_send(struct socket *so, struct mbuf *m, struct sockaddr *nam, 342natm_send(struct socket *so, struct mbuf *m, struct sockaddr *nam,
343 struct mbuf *control) 343 struct mbuf *control)
344{ 344{
345 struct natmpcb *npcb = (struct natmpcb *) so->so_pcb; 345 struct natmpcb *npcb = (struct natmpcb *) so->so_pcb;
346 struct atm_pseudohdr *aph; 346 struct atm_pseudohdr *aph;
347 347
348 KASSERT(solocked(so)); 348 KASSERT(solocked(so));
349 KASSERT(pcb != NULL); 349 KASSERT(pcb != NULL);
350 KASSERT(m != NULL); 350 KASSERT(m != NULL);
351 351
352 if (control && control->m_len) { 352 if (control && control->m_len) {
353 m_freem(control); 353 m_freem(control);
354 m_freem(m); 354 m_freem(m);
355 return EINVAL; 355 return EINVAL;
356 } 356 }
357 357
358 /* 358 /*
359 * send the data. we must put an atm_pseudohdr on first 359 * send the data. we must put an atm_pseudohdr on first
360 */ 360 */
361 s = SPLSOFTNET(); 361 s = SPLSOFTNET();
362 M_PREPEND(m, sizeof(*aph), M_WAITOK); 362 M_PREPEND(m, sizeof(*aph), M_WAITOK);
363 if (m == NULL) { 363 if (m == NULL) {
364 error = ENOBUFS; 364 error = ENOBUFS;
365 break; 365 break;
366 } 366 }
367 aph = mtod(m, struct atm_pseudohdr *); 367 aph = mtod(m, struct atm_pseudohdr *);
368 ATM_PH_VPI(aph) = npcb->npcb_vpi; 368 ATM_PH_VPI(aph) = npcb->npcb_vpi;
369 ATM_PH_SETVCI(aph, npcb->npcb_vci); 369 ATM_PH_SETVCI(aph, npcb->npcb_vci);
370 ATM_PH_FLAGS(aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0; 370 ATM_PH_FLAGS(aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0;
371 error = atm_output(npcb->npcb_ifp, m, NULL, NULL); 371 error = atm_output(npcb->npcb_ifp, m, NULL, NULL);
372 splx(s); 372 splx(s);
373 373
374 return error; 374 return error;
375} 375}
376 376
377static int 377static int
378natm_send(struct socket *so, struct mbuf *m, struct mbuf *nam, 378natm_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
379 struct mbuf *control, struct lwp *l) 379 struct mbuf *control, struct lwp *l)
380{ 380{
381 struct natmpcb *npcb = (struct natmpcb *) so->so_pcb; 381 struct natmpcb *npcb = (struct natmpcb *) so->so_pcb;
382 struct atm_pseudohdr *aph; 382 struct atm_pseudohdr *aph;
383 383
384 KASSERT(solocked(so)); 384 KASSERT(solocked(so));
385 KASSERT(pcb != NULL); 385 KASSERT(pcb != NULL);
386 KASSERT(m != NULL); 386 KASSERT(m != NULL);
387 387
388 if (control && control->m_len) { 388 if (control && control->m_len) {
389 m_freem(control); 389 m_freem(control);
390 m_freem(m); 390 m_freem(m);
391 return EINVAL; 391 return EINVAL;
392 } 392 }
393 393
394 /* 394 /*
395 * send the data. we must put an atm_pseudohdr on first 395 * send the data. we must put an atm_pseudohdr on first
396 */ 396 */
397 s = SPLSOFTNET(); 397 s = SPLSOFTNET();
398 M_PREPEND(m, sizeof(*aph), M_WAITOK); 398 M_PREPEND(m, sizeof(*aph), M_WAITOK);
399 if (m == NULL) { 399 if (m == NULL) {
400 error = ENOBUFS; 400 error = ENOBUFS;
401 break; 401 break;
402 } 402 }
403 aph = mtod(m, struct atm_pseudohdr *); 403 aph = mtod(m, struct atm_pseudohdr *);
404 ATM_PH_VPI(aph) = npcb->npcb_vpi; 404 ATM_PH_VPI(aph) = npcb->npcb_vpi;
405 ATM_PH_SETVCI(aph, npcb->npcb_vci); 405 ATM_PH_SETVCI(aph, npcb->npcb_vci);
406 ATM_PH_FLAGS(aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0; 406 ATM_PH_FLAGS(aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0;
407 error = atm_output(npcb->npcb_ifp, m, NULL, NULL); 407 error = atm_output(npcb->npcb_ifp, m, NULL, NULL);
408 splx(s); 408 splx(s);
409 409
410 return error; 410 return error;
411} 411}
412 412
413static int 413static int
414natm_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) 414natm_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
415{ 415{
416 KASSERT(solocked(so)); 416 KASSERT(solocked(so));
417 417
418 return EOPNOTSUPP; 418 return EOPNOTSUPP;
419} 419}
420 420
421static int 421static int
422natm_purgeif(struct socket *so, struct ifnet *ifp) 422natm_purgeif(struct socket *so, struct ifnet *ifp)
423{ 423{
424 424
425 return EOPNOTSUPP; 425 return EOPNOTSUPP;
426} 426}
427 427
428/* 428/*
429 * natmintr: splsoftnet interrupt 429 * natmintr: splsoftnet interrupt
430 * 430 *
431 * note: we expect a socket pointer in rcvif rather than an interface 431 * note: we expect a socket pointer in rcvif rather than an interface
432 * pointer. we can get the interface pointer from the so's PCB if 432 * pointer. we can get the interface pointer from the so's PCB if
433 * we really need it. 433 * we really need it.
434 */ 434 */
435 435
436void 436void
437natmintr(void) 437natmintr(void)
438 438
439{ 439{
440 int s; 440 int s;
441 struct mbuf *m; 441 struct mbuf *m;
442 struct socket *so; 442 struct socket *so;
443 struct natmpcb *npcb; 443 struct natmpcb *npcb;
444 444
445 mutex_enter(softnet_lock); 445 mutex_enter(softnet_lock);
446next: 446next:
447 s = splnet(); 447 s = splnet();
448 IF_DEQUEUE(&natmintrq, m); 448 IF_DEQUEUE(&natmintrq, m);
449 splx(s); 449 splx(s);
450 if (m == NULL) { 450 if (m == NULL) {
451 mutex_exit(softnet_lock); 451 mutex_exit(softnet_lock);
452 return; 452 return;
453 } 453 }
454 454
455#ifdef DIAGNOSTIC 455#ifdef DIAGNOSTIC
456 if ((m->m_flags & M_PKTHDR) == 0) 456 if ((m->m_flags & M_PKTHDR) == 0)
457 panic("natmintr no HDR"); 457 panic("natmintr no HDR");
458#endif 458#endif
459 459
460 npcb = (struct natmpcb *) m->m_pkthdr.rcvif; /* XXX: overloaded */ 460 npcb = (struct natmpcb *) m->m_pkthdr.rcvif; /* XXX: overloaded */
461 so = npcb->npcb_socket; 461 so = npcb->npcb_socket;
462 462
463 s = splnet(); /* could have atm devs @ different levels */ 463 s = splnet(); /* could have atm devs @ different levels */
464 npcb->npcb_inq--; 464 npcb->npcb_inq--;
465 splx(s); 465 splx(s);
466 466
467 if (npcb->npcb_flags & NPCB_DRAIN) { 467 if (npcb->npcb_flags & NPCB_DRAIN) {
468 m_freem(m); 468 m_freem(m);
469 if (npcb->npcb_inq == 0) 469 if (npcb->npcb_inq == 0)
470 kmem_intr_free(npcb, sizeof(*npcb)); 470 kmem_intr_free(npcb, sizeof(*npcb));
471 goto next; 471 goto next;
472 } 472 }
473 473
474 if (npcb->npcb_flags & NPCB_FREE) { 474 if (npcb->npcb_flags & NPCB_FREE) {
475 m_freem(m); /* drop */ 475 m_freem(m); /* drop */
476 goto next; 476 goto next;
477 } 477 }
478 478
479#ifdef NEED_TO_RESTORE_IFP 479#ifdef NEED_TO_RESTORE_IFP
480 m->m_pkthdr.rcvif = npcb->npcb_ifp; 480 m->m_pkthdr.rcvif = npcb->npcb_ifp;
481#else 481#else
482#ifdef DIAGNOSTIC 482#ifdef DIAGNOSTIC
483m->m_pkthdr.rcvif = NULL; /* null it out to be safe */ 483m->m_pkthdr.rcvif = NULL; /* null it out to be safe */
484#endif 484#endif
485#endif 485#endif
486 486
487 if (sbspace(&so->so_rcv) > m->m_pkthdr.len || 487 if (sbspace(&so->so_rcv) > m->m_pkthdr.len ||
488 ((npcb->npcb_flags & NPCB_RAW) != 0 && so->so_rcv.sb_cc < NPCB_RAWCC) ) { 488 ((npcb->npcb_flags & NPCB_RAW) != 0 && so->so_rcv.sb_cc < NPCB_RAWCC) ) {
489#ifdef NATM_STAT 489#ifdef NATM_STAT
490 natm_sookcnt++; 490 natm_sookcnt++;
491 natm_sookbytes += m->m_pkthdr.len; 491 natm_sookbytes += m->m_pkthdr.len;
492#endif 492#endif
493 sbappendrecord(&so->so_rcv, m); 493 sbappendrecord(&so->so_rcv, m);
494 sorwakeup(so); 494 sorwakeup(so);
495 } else { 495 } else {
496#ifdef NATM_STAT 496#ifdef NATM_STAT
497 natm_sodropcnt++; 497 natm_sodropcnt++;
498 natm_sodropbytes += m->m_pkthdr.len; 498 natm_sodropbytes += m->m_pkthdr.len;
499#endif 499#endif
500 m_freem(m); 500 m_freem(m);
501 } 501 }
502 502
503 goto next; 503 goto next;
504} 504}
505 505
506PR_WRAP_USRREQS(natm) 506PR_WRAP_USRREQS(natm)
507#define natm_attach natm_attach_wrapper 507#define natm_attach natm_attach_wrapper
508#define natm_detach natm_detach_wrapper 508#define natm_detach natm_detach_wrapper
509#define natm_accept natm_accept_wrapper 509#define natm_accept natm_accept_wrapper
510#define natm_bind natm_bind_wrapper 510#define natm_bind natm_bind_wrapper
511#define natm_listen natm_listen_wrapper 511#define natm_listen natm_listen_wrapper
512#define natm_connect natm_connect_wrapper 512#define natm_connect natm_connect_wrapper
513#define natm_connect2 natm_connect2_wrapper 513#define natm_connect2 natm_connect2_wrapper
514#define natm_disconnect natm_disconnect_wrapper 514#define natm_disconnect natm_disconnect_wrapper
515#define natm_shutdown natm_shutdown_wrapper 515#define natm_shutdown natm_shutdown_wrapper
516#define natm_abort natm_abort_wrapper 516#define natm_abort natm_abort_wrapper
517#define natm_ioctl natm_ioctl_wrapper 517#define natm_ioctl natm_ioctl_wrapper
518#define natm_stat natm_stat_wrapper 518#define natm_stat natm_stat_wrapper
519#define natm_peeraddr natm_peeraddr_wrapper 519#define natm_peeraddr natm_peeraddr_wrapper
520#define natm_sockaddr natm_sockaddr_wrapper 520#define natm_sockaddr natm_sockaddr_wrapper
521#define natm_rcvd natm_rcvd_wrapper 521#define natm_rcvd natm_rcvd_wrapper
522#define natm_recvoob natm_recvoob_wrapper 522#define natm_recvoob natm_recvoob_wrapper
523#define natm_send natm_send_wrapper 523#define natm_send natm_send_wrapper
524#define natm_sendoob natm_sendoob_wrapper 524#define natm_sendoob natm_sendoob_wrapper
525#define natm_purgeif natm_purgeif_wrapper 525#define natm_purgeif natm_purgeif_wrapper
526 526
527const struct pr_usrreqs natm_usrreqs = { 527const struct pr_usrreqs natm_usrreqs = {
528 .pr_attach = natm_attach, 528 .pr_attach = natm_attach,
529 .pr_detach = natm_detach, 529 .pr_detach = natm_detach,
530 .pr_accept = natm_accept, 530 .pr_accept = natm_accept,
531 .pr_bind = natm_bind, 531 .pr_bind = natm_bind,
532 .pr_listen = natm_listen, 532 .pr_listen = natm_listen,
533 .pr_connect = natm_connect, 533 .pr_connect = natm_connect,
534 .pr_connect2 = natm_connect2, 534 .pr_connect2 = natm_connect2,
535 .pr_disconnect = natm_disconnect, 535 .pr_disconnect = natm_disconnect,
536 .pr_shutdown = natm_shutdown, 536 .pr_shutdown = natm_shutdown,
537 .pr_abort = natm_abort, 537 .pr_abort = natm_abort,
538 .pr_ioctl = natm_ioctl, 538 .pr_ioctl = natm_ioctl,
539 .pr_stat = natm_stat, 539 .pr_stat = natm_stat,
540 .pr_peeraddr = natm_peeraddr, 540 .pr_peeraddr = natm_peeraddr,
541 .pr_sockaddr = natm_sockaddr, 541 .pr_sockaddr = natm_sockaddr,
542 .pr_rcvd = natm_rcvd, 542 .pr_rcvd = natm_rcvd,
543 .pr_recvoob = natm_recvoob, 543 .pr_recvoob = natm_recvoob,
544 .pr_send = natm_send, 544 .pr_send = natm_send,
545 .pr_sendoob = natm_sendoob, 545 .pr_sendoob = natm_sendoob,
546 .pr_purgeif = natm_purgeif, 546 .pr_purgeif = natm_purgeif,
547}; 547};