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 /*
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25 /*
26 * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
27 * Copyright 2015 Joyent, Inc.
28 */
29
30 #include <sys/types.h>
31 #include <sys/param.h>
32 #include <sys/signal.h>
33 #include <sys/cmn_err.h>
34
35 #include <sys/stropts.h>
36 #include <sys/socket.h>
37 #include <sys/socketvar.h>
38 #include <sys/sockio.h>
39 #include <sys/strsubr.h>
40 #include <sys/strsun.h>
41 #include <sys/atomic.h>
42 #include <sys/tihdr.h>
43
44 #include <fs/sockfs/sockcommon.h>
45 #include <fs/sockfs/sockfilter_impl.h>
46 #include <fs/sockfs/socktpi.h>
47 #include <fs/sockfs/sodirect.h>
2275 int
2276 so_tpi_fallback(struct sonode *so, struct cred *cr)
2277 {
2278 int error;
2279 queue_t *q;
2280 struct sockparams *sp;
2281 struct sockparams *newsp = NULL;
2282 so_proto_fallback_func_t fbfunc;
2283 const char *devpath;
2284 boolean_t direct;
2285 struct sonode *nso;
2286 sock_quiesce_arg_t arg = { NULL, NULL };
2287 #ifdef DEBUG
2288 struct sonode origso;
2289 #endif
2290 error = 0;
2291 sp = so->so_sockparams;
2292 fbfunc = sp->sp_smod_info->smod_proto_fallback_func;
2293
2294 /*
2295 * Cannot fallback if the socket has active filters or a krecv callback.
2296 */
2297 if (so->so_filter_active > 0 || so->so_krecv_cb != NULL)
2298 return (EINVAL);
2299
2300 switch (so->so_family) {
2301 case AF_INET:
2302 devpath = sp->sp_smod_info->smod_fallback_devpath_v4;
2303 break;
2304 case AF_INET6:
2305 devpath = sp->sp_smod_info->smod_fallback_devpath_v6;
2306 break;
2307 default:
2308 return (EINVAL);
2309 }
2310
2311 /*
2312 * Fallback can only happen if the socket module has a TPI device
2313 * and fallback function.
2314 */
2315 if (devpath == NULL || fbfunc == NULL)
2316 return (EINVAL);
2317
2454 VN_RELE(SOTOV(so));
2455 out:
2456 so_end_fallback(so);
2457
2458 if (error != 0) {
2459 #ifdef DEBUG
2460 so_integrity_check(so, &origso);
2461 #endif
2462 zcmn_err(getzoneid(), CE_WARN,
2463 "Failed to convert socket to TPI (err=%d). Pid = %d\n",
2464 error, curproc->p_pid);
2465 if (newsp != NULL)
2466 SOCKPARAMS_DEC_REF(newsp);
2467 }
2468 if (arg.soqa_exdata_mp != NULL)
2469 freemsg(arg.soqa_exdata_mp);
2470 if (arg.soqa_urgmark_mp != NULL)
2471 freemsg(arg.soqa_urgmark_mp);
2472
2473 return (error);
2474 }
2475
2476 int
2477 so_krecv_set(sonode_t *so, so_krecv_f cb, void *arg)
2478 {
2479 int ret;
2480
2481 if (cb == NULL && arg != NULL)
2482 return (EINVAL);
2483
2484 SO_BLOCK_FALLBACK(so, so_krecv_set(so, cb, arg));
2485
2486 mutex_enter(&so->so_lock);
2487 if (so->so_state & SS_FALLBACK_COMP) {
2488 mutex_exit(&so->so_lock);
2489 SO_UNBLOCK_FALLBACK(so);
2490 return (ENOTSUP);
2491 }
2492
2493 ret = so_lock_read(so, 0);
2494 VERIFY(ret == 0);
2495 /*
2496 * Other consumers may actually care about getting extant data delivered
2497 * to them, when they come along, they should figure out the best API
2498 * for that.
2499 */
2500 so_rcv_flush(so);
2501
2502 so->so_krecv_cb = cb;
2503 so->so_krecv_arg = arg;
2504
2505 so_unlock_read(so);
2506 mutex_exit(&so->so_lock);
2507 SO_UNBLOCK_FALLBACK(so);
2508
2509 return (0);
2510 }
2511
2512 void
2513 so_krecv_unblock(sonode_t *so)
2514 {
2515 mutex_enter(&so->so_lock);
2516 VERIFY(so->so_krecv_cb != NULL);
2517
2518 so->so_rcv_queued = 0;
2519 (void) so_check_flow_control(so);
2520 mutex_exit(&so->so_lock);
2521 }
|
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 /*
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25 /*
26 * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
27 */
28
29 #include <sys/types.h>
30 #include <sys/param.h>
31 #include <sys/signal.h>
32 #include <sys/cmn_err.h>
33
34 #include <sys/stropts.h>
35 #include <sys/socket.h>
36 #include <sys/socketvar.h>
37 #include <sys/sockio.h>
38 #include <sys/strsubr.h>
39 #include <sys/strsun.h>
40 #include <sys/atomic.h>
41 #include <sys/tihdr.h>
42
43 #include <fs/sockfs/sockcommon.h>
44 #include <fs/sockfs/sockfilter_impl.h>
45 #include <fs/sockfs/socktpi.h>
46 #include <fs/sockfs/sodirect.h>
2274 int
2275 so_tpi_fallback(struct sonode *so, struct cred *cr)
2276 {
2277 int error;
2278 queue_t *q;
2279 struct sockparams *sp;
2280 struct sockparams *newsp = NULL;
2281 so_proto_fallback_func_t fbfunc;
2282 const char *devpath;
2283 boolean_t direct;
2284 struct sonode *nso;
2285 sock_quiesce_arg_t arg = { NULL, NULL };
2286 #ifdef DEBUG
2287 struct sonode origso;
2288 #endif
2289 error = 0;
2290 sp = so->so_sockparams;
2291 fbfunc = sp->sp_smod_info->smod_proto_fallback_func;
2292
2293 /*
2294 * Cannot fallback if the socket has active filters
2295 */
2296 if (so->so_filter_active > 0)
2297 return (EINVAL);
2298
2299 switch (so->so_family) {
2300 case AF_INET:
2301 devpath = sp->sp_smod_info->smod_fallback_devpath_v4;
2302 break;
2303 case AF_INET6:
2304 devpath = sp->sp_smod_info->smod_fallback_devpath_v6;
2305 break;
2306 default:
2307 return (EINVAL);
2308 }
2309
2310 /*
2311 * Fallback can only happen if the socket module has a TPI device
2312 * and fallback function.
2313 */
2314 if (devpath == NULL || fbfunc == NULL)
2315 return (EINVAL);
2316
2453 VN_RELE(SOTOV(so));
2454 out:
2455 so_end_fallback(so);
2456
2457 if (error != 0) {
2458 #ifdef DEBUG
2459 so_integrity_check(so, &origso);
2460 #endif
2461 zcmn_err(getzoneid(), CE_WARN,
2462 "Failed to convert socket to TPI (err=%d). Pid = %d\n",
2463 error, curproc->p_pid);
2464 if (newsp != NULL)
2465 SOCKPARAMS_DEC_REF(newsp);
2466 }
2467 if (arg.soqa_exdata_mp != NULL)
2468 freemsg(arg.soqa_exdata_mp);
2469 if (arg.soqa_urgmark_mp != NULL)
2470 freemsg(arg.soqa_urgmark_mp);
2471
2472 return (error);
2473 }
|