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 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 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