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