xref: /onnv-gate/usr/src/uts/common/inet/tcp/tcp_cluster.c (revision 11754:251da8f4caaa)
1*11754SKacheong.Poon@Sun.COM /*
2*11754SKacheong.Poon@Sun.COM  * CDDL HEADER START
3*11754SKacheong.Poon@Sun.COM  *
4*11754SKacheong.Poon@Sun.COM  * The contents of this file are subject to the terms of the
5*11754SKacheong.Poon@Sun.COM  * Common Development and Distribution License (the "License").
6*11754SKacheong.Poon@Sun.COM  * You may not use this file except in compliance with the License.
7*11754SKacheong.Poon@Sun.COM  *
8*11754SKacheong.Poon@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*11754SKacheong.Poon@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*11754SKacheong.Poon@Sun.COM  * See the License for the specific language governing permissions
11*11754SKacheong.Poon@Sun.COM  * and limitations under the License.
12*11754SKacheong.Poon@Sun.COM  *
13*11754SKacheong.Poon@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*11754SKacheong.Poon@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*11754SKacheong.Poon@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*11754SKacheong.Poon@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*11754SKacheong.Poon@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*11754SKacheong.Poon@Sun.COM  *
19*11754SKacheong.Poon@Sun.COM  * CDDL HEADER END
20*11754SKacheong.Poon@Sun.COM  */
21*11754SKacheong.Poon@Sun.COM 
22*11754SKacheong.Poon@Sun.COM /*
23*11754SKacheong.Poon@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24*11754SKacheong.Poon@Sun.COM  * Use is subject to license terms.
25*11754SKacheong.Poon@Sun.COM  */
26*11754SKacheong.Poon@Sun.COM 
27*11754SKacheong.Poon@Sun.COM /* This file contains Solaris Cluster related TCP hooks and functions. */
28*11754SKacheong.Poon@Sun.COM 
29*11754SKacheong.Poon@Sun.COM #include <inet/tcp.h>
30*11754SKacheong.Poon@Sun.COM #include <inet/tcp_impl.h>
31*11754SKacheong.Poon@Sun.COM #include <inet/tcp_cluster.h>
32*11754SKacheong.Poon@Sun.COM 
33*11754SKacheong.Poon@Sun.COM static int cl_tcp_walk_list_stack(int (*callback)(cl_tcp_info_t *, void *),
34*11754SKacheong.Poon@Sun.COM     void *arg, tcp_stack_t *tcps);
35*11754SKacheong.Poon@Sun.COM 
36*11754SKacheong.Poon@Sun.COM /*
37*11754SKacheong.Poon@Sun.COM  * Hook functions to enable cluster networking
38*11754SKacheong.Poon@Sun.COM  * On non-clustered systems these vectors must always be NULL.
39*11754SKacheong.Poon@Sun.COM  */
40*11754SKacheong.Poon@Sun.COM void (*cl_inet_listen)(netstackid_t stack_id, uint8_t protocol,
41*11754SKacheong.Poon@Sun.COM 			    sa_family_t addr_family, uint8_t *laddrp,
42*11754SKacheong.Poon@Sun.COM 			    in_port_t lport, void *args) = NULL;
43*11754SKacheong.Poon@Sun.COM void (*cl_inet_unlisten)(netstackid_t stack_id, uint8_t protocol,
44*11754SKacheong.Poon@Sun.COM 			    sa_family_t addr_family, uint8_t *laddrp,
45*11754SKacheong.Poon@Sun.COM 			    in_port_t lport, void *args) = NULL;
46*11754SKacheong.Poon@Sun.COM 
47*11754SKacheong.Poon@Sun.COM int (*cl_inet_connect2)(netstackid_t stack_id, uint8_t protocol,
48*11754SKacheong.Poon@Sun.COM 			    boolean_t is_outgoing,
49*11754SKacheong.Poon@Sun.COM 			    sa_family_t addr_family,
50*11754SKacheong.Poon@Sun.COM 			    uint8_t *laddrp, in_port_t lport,
51*11754SKacheong.Poon@Sun.COM 			    uint8_t *faddrp, in_port_t fport,
52*11754SKacheong.Poon@Sun.COM 			    void *args) = NULL;
53*11754SKacheong.Poon@Sun.COM void (*cl_inet_disconnect)(netstackid_t stack_id, uint8_t protocol,
54*11754SKacheong.Poon@Sun.COM 			    sa_family_t addr_family, uint8_t *laddrp,
55*11754SKacheong.Poon@Sun.COM 			    in_port_t lport, uint8_t *faddrp,
56*11754SKacheong.Poon@Sun.COM 			    in_port_t fport, void *args) = NULL;
57*11754SKacheong.Poon@Sun.COM 
58*11754SKacheong.Poon@Sun.COM /*
59*11754SKacheong.Poon@Sun.COM  * Exported routine for extracting active tcp connection status.
60*11754SKacheong.Poon@Sun.COM  *
61*11754SKacheong.Poon@Sun.COM  * This is used by the Solaris Cluster Networking software to
62*11754SKacheong.Poon@Sun.COM  * gather a list of connections that need to be forwarded to
63*11754SKacheong.Poon@Sun.COM  * specific nodes in the cluster when configuration changes occur.
64*11754SKacheong.Poon@Sun.COM  *
65*11754SKacheong.Poon@Sun.COM  * The callback is invoked for each tcp_t structure from all netstacks,
66*11754SKacheong.Poon@Sun.COM  * if 'stack_id' is less than 0. Otherwise, only for tcp_t structures
67*11754SKacheong.Poon@Sun.COM  * from the netstack with the specified stack_id. Returning
68*11754SKacheong.Poon@Sun.COM  * non-zero from the callback routine terminates the search.
69*11754SKacheong.Poon@Sun.COM  */
70*11754SKacheong.Poon@Sun.COM int
cl_tcp_walk_list(netstackid_t stack_id,int (* cl_callback)(cl_tcp_info_t *,void *),void * arg)71*11754SKacheong.Poon@Sun.COM cl_tcp_walk_list(netstackid_t stack_id,
72*11754SKacheong.Poon@Sun.COM     int (*cl_callback)(cl_tcp_info_t *, void *), void *arg)
73*11754SKacheong.Poon@Sun.COM {
74*11754SKacheong.Poon@Sun.COM 	netstack_handle_t nh;
75*11754SKacheong.Poon@Sun.COM 	netstack_t *ns;
76*11754SKacheong.Poon@Sun.COM 	int ret = 0;
77*11754SKacheong.Poon@Sun.COM 
78*11754SKacheong.Poon@Sun.COM 	if (stack_id >= 0) {
79*11754SKacheong.Poon@Sun.COM 		if ((ns = netstack_find_by_stackid(stack_id)) == NULL)
80*11754SKacheong.Poon@Sun.COM 			return (EINVAL);
81*11754SKacheong.Poon@Sun.COM 
82*11754SKacheong.Poon@Sun.COM 		ret = cl_tcp_walk_list_stack(cl_callback, arg,
83*11754SKacheong.Poon@Sun.COM 		    ns->netstack_tcp);
84*11754SKacheong.Poon@Sun.COM 		netstack_rele(ns);
85*11754SKacheong.Poon@Sun.COM 		return (ret);
86*11754SKacheong.Poon@Sun.COM 	}
87*11754SKacheong.Poon@Sun.COM 
88*11754SKacheong.Poon@Sun.COM 	netstack_next_init(&nh);
89*11754SKacheong.Poon@Sun.COM 	while ((ns = netstack_next(&nh)) != NULL) {
90*11754SKacheong.Poon@Sun.COM 		ret = cl_tcp_walk_list_stack(cl_callback, arg,
91*11754SKacheong.Poon@Sun.COM 		    ns->netstack_tcp);
92*11754SKacheong.Poon@Sun.COM 		netstack_rele(ns);
93*11754SKacheong.Poon@Sun.COM 	}
94*11754SKacheong.Poon@Sun.COM 	netstack_next_fini(&nh);
95*11754SKacheong.Poon@Sun.COM 	return (ret);
96*11754SKacheong.Poon@Sun.COM }
97*11754SKacheong.Poon@Sun.COM 
98*11754SKacheong.Poon@Sun.COM static int
cl_tcp_walk_list_stack(int (* callback)(cl_tcp_info_t *,void *),void * arg,tcp_stack_t * tcps)99*11754SKacheong.Poon@Sun.COM cl_tcp_walk_list_stack(int (*callback)(cl_tcp_info_t *, void *), void *arg,
100*11754SKacheong.Poon@Sun.COM     tcp_stack_t *tcps)
101*11754SKacheong.Poon@Sun.COM {
102*11754SKacheong.Poon@Sun.COM 	tcp_t *tcp;
103*11754SKacheong.Poon@Sun.COM 	cl_tcp_info_t	cl_tcpi;
104*11754SKacheong.Poon@Sun.COM 	connf_t	*connfp;
105*11754SKacheong.Poon@Sun.COM 	conn_t	*connp;
106*11754SKacheong.Poon@Sun.COM 	int	i;
107*11754SKacheong.Poon@Sun.COM 	ip_stack_t	*ipst = tcps->tcps_netstack->netstack_ip;
108*11754SKacheong.Poon@Sun.COM 
109*11754SKacheong.Poon@Sun.COM 	ASSERT(callback != NULL);
110*11754SKacheong.Poon@Sun.COM 
111*11754SKacheong.Poon@Sun.COM 	for (i = 0; i < CONN_G_HASH_SIZE; i++) {
112*11754SKacheong.Poon@Sun.COM 		connfp = &ipst->ips_ipcl_globalhash_fanout[i];
113*11754SKacheong.Poon@Sun.COM 		connp = NULL;
114*11754SKacheong.Poon@Sun.COM 
115*11754SKacheong.Poon@Sun.COM 		while ((connp =
116*11754SKacheong.Poon@Sun.COM 		    ipcl_get_next_conn(connfp, connp, IPCL_TCPCONN)) != NULL) {
117*11754SKacheong.Poon@Sun.COM 
118*11754SKacheong.Poon@Sun.COM 			tcp = connp->conn_tcp;
119*11754SKacheong.Poon@Sun.COM 			cl_tcpi.cl_tcpi_version = CL_TCPI_V1;
120*11754SKacheong.Poon@Sun.COM 			cl_tcpi.cl_tcpi_ipversion = connp->conn_ipversion;
121*11754SKacheong.Poon@Sun.COM 			cl_tcpi.cl_tcpi_state = tcp->tcp_state;
122*11754SKacheong.Poon@Sun.COM 			cl_tcpi.cl_tcpi_lport = connp->conn_lport;
123*11754SKacheong.Poon@Sun.COM 			cl_tcpi.cl_tcpi_fport = connp->conn_fport;
124*11754SKacheong.Poon@Sun.COM 			cl_tcpi.cl_tcpi_laddr_v6 = connp->conn_laddr_v6;
125*11754SKacheong.Poon@Sun.COM 			cl_tcpi.cl_tcpi_faddr_v6 = connp->conn_faddr_v6;
126*11754SKacheong.Poon@Sun.COM 
127*11754SKacheong.Poon@Sun.COM 			/*
128*11754SKacheong.Poon@Sun.COM 			 * If the callback returns non-zero
129*11754SKacheong.Poon@Sun.COM 			 * we terminate the traversal.
130*11754SKacheong.Poon@Sun.COM 			 */
131*11754SKacheong.Poon@Sun.COM 			if ((*callback)(&cl_tcpi, arg) != 0) {
132*11754SKacheong.Poon@Sun.COM 				CONN_DEC_REF(tcp->tcp_connp);
133*11754SKacheong.Poon@Sun.COM 				return (1);
134*11754SKacheong.Poon@Sun.COM 			}
135*11754SKacheong.Poon@Sun.COM 		}
136*11754SKacheong.Poon@Sun.COM 	}
137*11754SKacheong.Poon@Sun.COM 
138*11754SKacheong.Poon@Sun.COM 	return (0);
139*11754SKacheong.Poon@Sun.COM }
140