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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
24 * Copyright 2020 Joyent, Inc.
25 */
26
27 /*
28 * IP PACKET CLASSIFIER
29 *
30 * The IP packet classifier provides mapping between IP packets and persistent
31 * connection state for connection-oriented protocols. It also provides
32 * interface for managing connection states.
33 *
34 * The connection state is kept in conn_t data structure and contains, among
35 * other things:
36 *
37 * o local/remote address and ports
38 * o Transport protocol
39 * o squeue for the connection (for TCP only)
40 * o reference counter
41 * o Connection state
42 * o hash table linkage
43 * o interface/ire information
44 * o credentials
2715
2716 ASSERT(MUTEX_HELD(&connp->conn_lock));
2717 last = connp->conn_trace_last;
2718 last++;
2719 if (last == CONN_TRACE_MAX)
2720 last = 0;
2721
2722 ctb = &connp->conn_trace_buf[last];
2723 ctb->ctb_depth = getpcstack(ctb->ctb_stack, CONN_STACK_DEPTH);
2724 connp->conn_trace_last = last;
2725 return (1);
2726 }
2727 #endif
2728
2729 mib2_socketInfoEntry_t *
2730 conn_get_socket_info(conn_t *connp, mib2_socketInfoEntry_t *sie)
2731 {
2732 vnode_t *vn = NULL;
2733 vattr_t attr;
2734 uint64_t flags = 0;
2735
2736 /*
2737 * If the connection is closing, it is not safe to make an upcall or
2738 * access the stream associated with the connection.
2739 * The callers of this function have a reference on connp itself
2740 * so, as long as it is not closing, it's safe to continue.
2741 */
2742 mutex_enter(&connp->conn_lock);
2743
2744 if ((connp->conn_state_flags & CONN_CLOSING)) {
2745 mutex_exit(&connp->conn_lock);
2746 return (NULL);
2747 }
2748
2749 /*
2750 * Continue to hold conn_lock because we don't want to race with an
2751 * in-progress close, which will have set-to-NULL (and destroyed
2752 * upper_handle, aka sonode (and vnode)) BEFORE setting CONN_CLOSING.
2753 */
2754
2755 if (connp->conn_upper_handle != NULL) {
2756 vn = (*connp->conn_upcalls->su_get_vnode)
2757 (connp->conn_upper_handle);
2758 } else if (!IPCL_IS_NONSTR(connp) && connp->conn_rq != NULL) {
2759 vn = STREAM(connp->conn_rq)->sd_pvnode;
2760 if (vn != NULL)
2761 VN_HOLD(vn);
2762 flags |= MIB2_SOCKINFO_STREAM;
2763 }
2764
2765 mutex_exit(&connp->conn_lock);
2766
2767 if (vn == NULL || VOP_GETATTR(vn, &attr, 0, CRED(), NULL) != 0) {
2768 if (vn != NULL)
2769 VN_RELE(vn);
2770 return (NULL);
2771 }
2772
2773 VN_RELE(vn);
2774
2775 bzero(sie, sizeof (*sie));
2776
2777 sie->sie_flags = flags;
|
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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
24 * Copyright 2022 Joyent, Inc.
25 */
26
27 /*
28 * IP PACKET CLASSIFIER
29 *
30 * The IP packet classifier provides mapping between IP packets and persistent
31 * connection state for connection-oriented protocols. It also provides
32 * interface for managing connection states.
33 *
34 * The connection state is kept in conn_t data structure and contains, among
35 * other things:
36 *
37 * o local/remote address and ports
38 * o Transport protocol
39 * o squeue for the connection (for TCP only)
40 * o reference counter
41 * o Connection state
42 * o hash table linkage
43 * o interface/ire information
44 * o credentials
2715
2716 ASSERT(MUTEX_HELD(&connp->conn_lock));
2717 last = connp->conn_trace_last;
2718 last++;
2719 if (last == CONN_TRACE_MAX)
2720 last = 0;
2721
2722 ctb = &connp->conn_trace_buf[last];
2723 ctb->ctb_depth = getpcstack(ctb->ctb_stack, CONN_STACK_DEPTH);
2724 connp->conn_trace_last = last;
2725 return (1);
2726 }
2727 #endif
2728
2729 mib2_socketInfoEntry_t *
2730 conn_get_socket_info(conn_t *connp, mib2_socketInfoEntry_t *sie)
2731 {
2732 vnode_t *vn = NULL;
2733 vattr_t attr;
2734 uint64_t flags = 0;
2735 sock_upcalls_t *upcalls;
2736 sock_upper_handle_t upper_handle;
2737
2738 /*
2739 * If the connection is closing, it is not safe to make an upcall or
2740 * access the stream associated with the connection.
2741 * The callers of this function have a reference on connp itself
2742 * so, as long as it is not closing, it's safe to continue.
2743 */
2744 mutex_enter(&connp->conn_lock);
2745
2746 if ((connp->conn_state_flags & CONN_CLOSING)) {
2747 mutex_exit(&connp->conn_lock);
2748 return (NULL);
2749 }
2750
2751 /*
2752 * Continue to hold conn_lock because we don't want to race with an
2753 * in-progress close, which will have set-to-NULL (and destroyed
2754 * upper_handle, aka sonode (and vnode)) BEFORE setting CONN_CLOSING.
2755 *
2756 * There is still a race with an in-progress OPEN, however, where
2757 * conn_upper_handle and conn_upcalls are being assigned (in multiple
2758 * codepaths) WITHOUT conn_lock being held. We address that race
2759 * HERE, however, given that both are going from NULL to non-NULL,
2760 * if we lose the race, we don't get any data for the in-progress-OPEN
2761 * socket.
2762 */
2763
2764 upcalls = connp->conn_upcalls;
2765 upper_handle = connp->conn_upper_handle;
2766 /* Check BOTH for non-NULL before attempting an upcall. */
2767 if (upper_handle != NULL && upcalls != NULL) {
2768 /* su_get_vnode() returns one with VN_HOLD() already done. */
2769 vn = upcalls->su_get_vnode(upper_handle);
2770 } else if (!IPCL_IS_NONSTR(connp) && connp->conn_rq != NULL) {
2771 vn = STREAM(connp->conn_rq)->sd_pvnode;
2772 if (vn != NULL)
2773 VN_HOLD(vn);
2774 flags |= MIB2_SOCKINFO_STREAM;
2775 }
2776
2777 mutex_exit(&connp->conn_lock);
2778
2779 if (vn == NULL || VOP_GETATTR(vn, &attr, 0, CRED(), NULL) != 0) {
2780 if (vn != NULL)
2781 VN_RELE(vn);
2782 return (NULL);
2783 }
2784
2785 VN_RELE(vn);
2786
2787 bzero(sie, sizeof (*sie));
2788
2789 sie->sie_flags = flags;
|