ex_dscp.c revision 535096c2bb10e7c765411fcb939b54c081ba4e07
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER START
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The contents of this file are subject to the terms of the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Common Development and Distribution License (the "License").
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You may not use this file except in compliance with the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * See the License for the specific language governing permissions
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * and limitations under the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * When distributing Covered Code, include this CDDL HEADER in each
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * If applicable, add the following below this CDDL HEADER, with the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * fields enclosed by brackets "[]" replaced with your own identifying
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * information: Portions Copyright [yyyy] [name of copyright owner]
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER END
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Use is subject to license terms.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#pragma ident "%Z%%M% %I% %E% SMI"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * FMA Event Transport Module Transport Layer API implementation.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Library for establishing connections and transporting FMA events between
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * ETMs (event-transport modules) in separate fault domains.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The transport for this library is internet socket based and uses the DSCP
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * client services library (libdscp).
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * On the SP, there is one DSCP interface for every domain.
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Each domain has one and only one DSCP interface to the SP.
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * The DSCP interface is created when the domain powers-on. On the SP,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * a sysevent will be generated when the DSCP interface is up. On the domain,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * the DSCP interface should be up when ETM loads.
d338766d6376ee721b7f1778e12bf79a112bd778jruttexs_hdl_t *Exh_head = NULL; /* Head of ex_hdl_t list */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Protects linked list of ex_hdl_t */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * * * * * * * * * * * * * *
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Module specific routines
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * * * * * * * * * * * * * *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Allocate and initialize a transport instance handle.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return hdl pointer for success, NULL for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int (*cb_func)(fmd_hdl_t *hdl, etm_xport_conn_t conn, etm_cb_flag_t flag,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_endpt_id = fmd_hdl_strdup(hdl, endpoint_id, FMD_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (hp);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Translate endpoint_id string to int.
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Return the domain ID via "dom_id".
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Return 0 for success, nonzero for failure
d338766d6376ee721b7f1778e12bf79a112bd778jruttexs_get_id(fmd_hdl_t *hdl, char *endpoint_id, int *dom_id)
d338766d6376ee721b7f1778e12bf79a112bd778jrutt /* Remote endpoint is the SP */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return (0);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((ptr = strstr(endpoint_id, EXS_DOMAIN_PREFIX)) == NULL) {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return (1);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_error(hdl, "xport - no integer found in %s\n",
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return (1);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Prepare the client connection.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return 0 for success, nonzero for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Find the DSCP address for the remote endpoint */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_error(hp->h_hdl, "xport - dscpAddr on client socket "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((hp->h_client.c_sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_error(hp->h_hdl, "xport - client socket create failed "
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return (2);
535096c2bb10e7c765411fcb939b54c081ba4e07jrutt if (setsockopt(hp->h_client.c_sd, SOL_SOCKET, SO_REUSEADDR,
535096c2bb10e7c765411fcb939b54c081ba4e07jrutt fmd_hdl_error(hp->h_hdl, "xport - set REUSEADDR failed on "
535096c2bb10e7c765411fcb939b54c081ba4e07jrutt return (3);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Bind the socket to the local IP address of the DSCP link */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_error(hp->h_hdl, "xport - dscpBind on client socket "
535096c2bb10e7c765411fcb939b54c081ba4e07jrutt return (4);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Set IPsec security policy for this socket */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((rv = dscpSecure(hp->h_dom, hp->h_client.c_sd)) != DSCP_OK) {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_error(hp->h_hdl, "xport - dscpSecure on client socket "
535096c2bb10e7c765411fcb939b54c081ba4e07jrutt return (5);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Prepare to accept a connection.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return 0 for success, nonzero for failure.
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((hp->h_accept.c_sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_error(hp->h_hdl, "xport - accept socket create failed "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if (setsockopt(hp->h_accept.c_sd, SOL_SOCKET, SO_REUSEADDR,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_error(hp->h_hdl, "xport - set REUSEADDR failed for %s",
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return (2);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Bind the socket to the local IP address of the DSCP link */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_error(hp->h_hdl, "xport - dscpBind on accept socket "
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return (3);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Activate IPsec security policy for this socket */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((rv = dscpSecure(hp->h_dom, hp->h_accept.c_sd)) != DSCP_OK) {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_error(hp->h_hdl, "xport - dscpSecure on accept socket "
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return (4);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((listen(hp->h_accept.c_sd, EXS_NUM_SOCKS)) == -1) {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_debug(hp->h_hdl, "xport - listen on accept socket "
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return (5);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt (void) fcntl(hp->h_accept.c_sd, F_SETFL, flags | O_NONBLOCK);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Notify ETM that incoming data is available on server connection.
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if (hp->h_cb_func(hp->h_hdl, &hp->h_server, ETM_CBFLAG_RECV,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt /* Any non-zero return means to close the connection */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Accept a new incoming connection.
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((new_sd = accept(hp->h_accept.c_sd, (struct sockaddr *)&new_saddr,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt /* Translate saddr to domain id */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((rv = dscpIdent((struct sockaddr *)&new_saddr, (int)new_len,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_debug(hp->h_hdl, "xport - domain id (%d) does "
d338766d6376ee721b7f1778e12bf79a112bd778jrutt /* Authenticate this connection request */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((rv = dscpAuth(dom, (struct sockaddr *)&new_saddr,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt /* Set the socket to be non-blocking */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Server function/thread. There is one thread per endpoint.
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Accepts incoming connections and notifies ETM of incoming data.
d338766d6376ee721b7f1778e12bf79a112bd778jrutt continue; /* loop around and check h_quit */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_debug(hp->h_hdl, "xport - poll hangup/err for "
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_debug(hp->h_hdl, "xport - poll hangup/err for "
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_debug(hp->h_hdl, "xport - exiting server thread for %s",
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * * * * * * * * * * * * * * * * * * * * * * * * * * *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * ETM-to-Transport API Connection Management routines
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * * * * * * * * * * * * * * * * * * * * * * * * * * *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Initialize and setup any transport infrastructure before any connections
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * are opened.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return etm_xport_hdl_t for success, NULL for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int (*cb_func)(fmd_hdl_t *hdl, etm_xport_conn_t conn, etm_cb_flag_t flag,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt /* Check for a duplicate endpoint_id on the list */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt hp = exs_hdl_alloc(hdl, endpoint_id, cb_func, cb_func_arg, dom);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Add this transport instance handle to the list */
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt /* A server thread is created for every endpoint */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Teardown any transport infrastructure after all connections are closed.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return 0 for success, or nonzero for failure.
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_abort(hdl, "xport - fini failed, tlhdl %p not on list",
d338766d6376ee721b7f1778e12bf79a112bd778jrutt /* Socket descr for h_accept and h_server are closed in exs_server */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Open a connection with the given endpoint,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return etm_xport_conn_t for success, NULL and set errno for failure.
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt /* Set the socket to be non-blocking */
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt (void) fcntl(hp->h_client.c_sd, F_SETFL, flags | O_NONBLOCK);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_error(hdl, "xport - failed server connect : %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - connected client socket for %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Close a connection from either endpoint.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return zero for success, nonzero for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*ARGSUSED*/
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0); /* Connection already closed */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * * * * * * * * * * * * * * * * * *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * ETM-to-Transport API I/O routines
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * * * * * * * * * * * * * * * * * *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Try to read byte_cnt bytes from the connection into the given buffer.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return how many bytes actually read for success, negative value for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_xport_read(fmd_hdl_t *hdl, etm_xport_conn_t conn, hrtime_t timeout,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (-EBADF);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 0)) < 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else if (len == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (-1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Try to write byte_cnt bytes to the connection from the given buffer.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return how many bytes actually written for success, negative value
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_xport_write(fmd_hdl_t *hdl, etm_xport_conn_t conn, hrtime_t timeout,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - write socket %d is closed\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (-EBADF);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 0)) < 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (-1);