diff options
Diffstat (limited to 'usr.sbin/atm/scspd/scsp_if.c')
-rw-r--r-- | usr.sbin/atm/scspd/scsp_if.c | 655 |
1 files changed, 655 insertions, 0 deletions
diff --git a/usr.sbin/atm/scspd/scsp_if.c b/usr.sbin/atm/scspd/scsp_if.c new file mode 100644 index 000000000000..19309908e513 --- /dev/null +++ b/usr.sbin/atm/scspd/scsp_if.c @@ -0,0 +1,655 @@ +/* + * + * =================================== + * HARP | Host ATM Research Platform + * =================================== + * + * + * This Host ATM Research Platform ("HARP") file (the "Software") is + * made available by Network Computing Services, Inc. ("NetworkCS") + * "AS IS". NetworkCS does not provide maintenance, improvements or + * support of any kind. + * + * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED, + * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE + * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE. + * In no event shall NetworkCS be responsible for any damages, including + * but not limited to consequential damages, arising from or relating to + * any use of the Software or related support. + * + * Copyright 1994-1998 Network Computing Services, Inc. + * + * Copies of this Software may be made, however, the above copyright + * notice must be reproduced on all copies. + * + * @(#) $Id: scsp_if.c,v 1.5 1998/08/13 20:11:14 johnc Exp $ + * + */ + + +/* + * Server Cache Synchronization Protocol (SCSP) Support + * ---------------------------------------------------- + * + * Interface to client server protocol + * + */ + + +#ifndef lint +static char *RCSid = "@(#) $Id: scsp_if.c,v 1.5 1998/08/13 20:11:14 johnc Exp $"; +#endif + +#include <sys/types.h> +#include <sys/param.h> + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <syslog.h> +#include <sys/socket.h> +#include <net/if.h> +#include <netinet/in.h> +#include <netatm/port.h> +#include <netatm/queue.h> +#include <netatm/atm.h> +#include <netatm/atm_if.h> +#include <netatm/atm_sap.h> +#include <netatm/atm_sys.h> +#include <netatm/atm_ioctl.h> + +#include <libatm.h> +#include "scsp_msg.h" +#include "scsp_if.h" +#include "scsp_var.h" + + +/* + * SCSP client server interface FSM actions + */ +#define SCSP_CIFSM_ACTION_CNT 11 +int scsp_client_act_00 + __P((Scsp_dcs *, Scsp_msg *, Scsp_if_msg *)); +int scsp_client_act_01 + __P((Scsp_dcs *, Scsp_msg *, Scsp_if_msg *)); +int scsp_client_act_02 + __P((Scsp_dcs *, Scsp_msg *, Scsp_if_msg *)); +int scsp_client_act_03 + __P((Scsp_dcs *, Scsp_msg *, Scsp_if_msg *)); +int scsp_client_act_04 + __P((Scsp_dcs *, Scsp_msg *, Scsp_if_msg *)); +int scsp_client_act_05 + __P((Scsp_dcs *, Scsp_msg *, Scsp_if_msg *)); +int scsp_client_act_06 + __P((Scsp_dcs *, Scsp_msg *, Scsp_if_msg *)); +int scsp_client_act_07 + __P((Scsp_dcs *, Scsp_msg *, Scsp_if_msg *)); +int scsp_client_act_08 + __P((Scsp_dcs *, Scsp_msg *, Scsp_if_msg *)); +int scsp_client_act_09 + __P((Scsp_dcs *, Scsp_msg *, Scsp_if_msg *)); +int scsp_client_act_10 + __P((Scsp_dcs *, Scsp_msg *, Scsp_if_msg *)); + +static int (*scsp_action_vector[SCSP_CIFSM_ACTION_CNT])() = { + scsp_client_act_00, + scsp_client_act_01, + scsp_client_act_02, + scsp_client_act_03, + scsp_client_act_04, + scsp_client_act_05, + scsp_client_act_06, + scsp_client_act_07, + scsp_client_act_08, + scsp_client_act_09, + scsp_client_act_10 +}; + + +/* + * Client server interface FSM state table + */ +static int client_state_table[SCSP_CIFSM_EVENT_CNT][SCSP_CIFSM_STATE_CNT] = { + /* 0 1 2 3 */ + { 1, 3, 3, 3 }, /* 0 */ + { 2, 5, 5, 5 }, /* 1 */ + { 0, 4, 0, 0 }, /* 2 */ + { 0, 6, 6, 1 }, /* 3 */ + { 1, 0, 7, 7 }, /* 4 */ + { 7, 7, 7, 7 }, /* 5 */ + { 1, 1, 8, 8 }, /* 6 */ + { 0, 0, 10, 10 }, /* 7 */ + { 0, 0, 1, 1 }, /* 8 */ + { 0, 0, 9, 9 } /* 9 */ +}; + + +/* + * SCSP client server interface finite state machine + * + * Arguments: + * ssp pointer to server control block + * event the event which has occurred + * msg pointer to message from DCS, if there is one + * cmsg pointer to message from server, if there is one + * + * Returns: + * 0 success + * errno error encountered + * + */ +int +scsp_cfsm(dcsp, event, msg, cmsg) + Scsp_dcs *dcsp; + int event; + Scsp_msg *msg; + Scsp_if_msg *cmsg; +{ + int action, rc, state; + + /* + * Select an action from the state table + */ + state = dcsp->sd_client_state; + action = client_state_table[event][state]; + if (scsp_trace_mode & SCSP_TRACE_CFSM) { + scsp_trace("Server I/F FSM: state=%d, event=%d, action=%d\n", + state, event, action); + } + if (action >= SCSP_CIFSM_ACTION_CNT || action <= 0) { + scsp_log(LOG_ERR, "Server I/F FSM--invalid action %d; state=%d, event=%d", + action, dcsp->sd_client_state, event); + exit(1); + } + + /* + * Perform the selected action + */ + rc = scsp_action_vector[action](dcsp, msg, cmsg); + + return(rc); +} + + +/* + * SCSP client server interface finite state machine action 0 + * Unexpected action -- log an error message + * + * Arguments: + * dcsp pointer to DCS control block + * msg pointer to message from DCS (ignored) + * cmsg pointer to message from server (ignored) + * + * Returns: + * EOPNOTSUPP always returns EOPNOTSUPP + * + */ +int +scsp_client_act_00(dcsp, msg, cmsg) + Scsp_dcs *dcsp; + Scsp_msg *msg; + Scsp_if_msg *cmsg; +{ + scsp_log(LOG_ERR, "Server I/F FSM error--unexpected action, state=%d", + dcsp->sd_client_state); + return(EOPNOTSUPP); +} + + +/* + * SCSP client server interface finite state machine action 1 + * + * Ignore an event + * + * Arguments: + * dcsp pointer to DCS control block + * msg pointer to message from DCS + * cmsg pointer to message from server + * + * Returns: + * 0 always returns 0 + * + */ +int +scsp_client_act_01(dcsp, msg, cmsg) + Scsp_dcs *dcsp; + Scsp_msg *msg; + Scsp_if_msg *cmsg; +{ + return(0); +} + + +/* + * SCSP client server interface finite state machine action 2 + * + * CA FSM went to Cache Summarize state--go to Summarize + * + * Arguments: + * dcsp pointer to DCS control block + * msg pointer to message from DCS + * cmsg pointer to message from server + * + * Returns: + * 0 success + * else errno describing error + * + */ +int +scsp_client_act_02(dcsp, msg, cmsg) + Scsp_dcs *dcsp; + Scsp_msg *msg; + Scsp_if_msg *cmsg; +{ + /* + * Set the new state + */ + dcsp->sd_client_state = SCSP_CIFSM_SUM; + + return(0); +} + + +/* + * SCSP client server interface finite state machine action 3 + * + * CA FSM went down--clean up and go to Null + * + * Arguments: + * dcsp pointer to DCS control block + * msg pointer to message from DCS + * cmsg pointer to message from server + * + * Returns: + * 0 success + * else errno describing error + * + */ +int +scsp_client_act_03(dcsp, msg, cmsg) + Scsp_dcs *dcsp; + Scsp_msg *msg; + Scsp_if_msg *cmsg; +{ + /* + * Set the new state + */ + dcsp->sd_client_state = SCSP_CIFSM_NULL; + + return(0); +} + + +/* + * SCSP client server interface finite state machine action 4 + * + * CA FSM went to Update Cache state--go to Update state + * + * Arguments: + * dcsp pointer to DCS control block + * msg pointer to message from DCS + * cmsg pointer to message from server + * + * Returns: + * 0 success + * else errno describing error + * + */ +int +scsp_client_act_04(dcsp, msg, cmsg) + Scsp_dcs *dcsp; + Scsp_msg *msg; + Scsp_if_msg *cmsg; +{ + /* + * Set the new state + */ + dcsp->sd_client_state = SCSP_CIFSM_UPD; + + return(0); +} + + +/* + * SCSP client server interface finite state machine action 5 + * + * The CA FSM went to Cache Summarize state from Summarize, + * Update, or Aligned, implying that the CA FSM went down and came + * back up--copy the server's cache to the DCSs CSAS list and go to + * Summarize state + * + * Arguments: + * dcsp pointer to DCS control block + * msg pointer to message from DCS + * cmsg pointer to message from server + * + * Returns: + * 0 success + * else errno describing error + * + */ +int +scsp_client_act_05(dcsp, msg, cmsg) + Scsp_dcs *dcsp; + Scsp_msg *msg; + Scsp_if_msg *cmsg; +{ + int i, rc; + Scsp_cse *csep, *ncsep; + + /* + * Copy the cache summmary to the CSAS list + */ + for (i = 0; i < SCSP_HASHSZ; i++) { + for (csep = dcsp->sd_server->ss_cache[i]; csep; + csep = csep->sc_next) { + ncsep = scsp_dup_cse(csep); + LINK2TAIL(ncsep, Scsp_cse, dcsp->sd_ca_csas, + sc_next); + } + } + + /* + * Set the new state + */ + dcsp->sd_client_state = SCSP_CIFSM_SUM; + + return(0); + +act_05_fail: + for (csep = dcsp->sd_ca_csas; csep; csep = ncsep) { + ncsep = csep->sc_next; + UNLINK(csep, Scsp_cse, dcsp->sd_ca_csas, sc_next); + UM_FREE(csep); + } + + dcsp->sd_client_state = SCSP_CIFSM_NULL; + + return(rc); +} + + +/* + * SCSP client server interface finite state machine action 6 + * + * CA FSM went to Aligned state--go to Aligned + * + * Arguments: + * dcsp pointer to DCS control block + * msg pointer to message from DCS + * cmsg pointer to message from server + * + * Returns: + * 0 success + * else errno describing error + * + */ +int +scsp_client_act_06(dcsp, msg, cmsg) + Scsp_dcs *dcsp; + Scsp_msg *msg; + Scsp_if_msg *cmsg; +{ + /* + * Set the new state + */ + dcsp->sd_client_state = SCSP_CIFSM_ALIGN; + + return(0); +} + + +/* + * SCSP client server interface finite state machine action 7 + * + * We received a Solicit Rsp or Update Req from the server--pass it + * to the CA FSM + * + * Arguments: + * dcsp pointer to DCS control block + * msg pointer to message from DCS + * cmsg pointer to message from server + * + * Returns: + * 0 success + * else errno describing error + * + */ +int +scsp_client_act_07(dcsp, msg, cmsg) + Scsp_dcs *dcsp; + Scsp_msg *msg; + Scsp_if_msg *cmsg; +{ + int rc; + Scsp_csa *csap; + Scsp_atmarp_csa *acp; + + /* + * Allocate memory for a CSA record + */ + csap = (Scsp_csa *)UM_ALLOC(sizeof(Scsp_csa)); + if (!csap) { + scsp_mem_err("scsp_client_act_07: sizeof(Scsp_csa)"); + } + acp = (Scsp_atmarp_csa *)UM_ALLOC(sizeof(Scsp_atmarp_csa)); + if (!acp) { + scsp_mem_err("scsp_client_act_07: sizeof(Scsp_atmarp_csa)"); + } + UM_ZERO(csap, sizeof(Scsp_csa)); + UM_ZERO(acp, sizeof(Scsp_atmarp_csa)); + + /* + * Build a CSA record from the server's message + */ + csap->hops = dcsp->sd_hops; + csap->null = (cmsg->si_atmarp.sa_state == SCSP_ASTATE_DEL) || + (cmsg->si_type == SCSP_SOLICIT_RSP && + cmsg->si_rc != SCSP_RSP_OK); + csap->seq = cmsg->si_atmarp.sa_seq; + csap->key = cmsg->si_atmarp.sa_key; + csap->oid = cmsg->si_atmarp.sa_oid; + csap->atmarp_data = acp; + acp->sa_state = cmsg->si_atmarp.sa_state; + acp->sa_sha = cmsg->si_atmarp.sa_cha; + acp->sa_ssa = cmsg->si_atmarp.sa_csa; + acp->sa_spa = cmsg->si_atmarp.sa_cpa; + acp->sa_tpa = cmsg->si_atmarp.sa_cpa; + + /* + * Call the CA FSM + */ + rc = scsp_cafsm(dcsp, SCSP_CAFSM_CACHE_UPD, (void *)csap); + + return(rc); +} + + +/* + * SCSP client server interface finite state machine action 8 + * + * Update Rsp from server--pass the update to the CA FSM. + * + * Arguments: + * dcsp pointer to DCS control block + * msg pointer to message from DCS + * cmsg pointer to message from server + * + * Returns: + * 0 success + * else errno describing error + * + */ +int +scsp_client_act_08(dcsp, msg, cmsg) + Scsp_dcs *dcsp; + Scsp_msg *msg; + Scsp_if_msg *cmsg; +{ + int rc; + + /* + * Pass the response to the CA FSM + */ + switch (dcsp->sd_server->ss_pid) { + case SCSP_PROTO_ATMARP: + rc = scsp_cafsm(dcsp, SCSP_CAFSM_CACHE_RSP, cmsg); + break; + default: + rc = EPROTONOSUPPORT; + } + + return(rc); +} + + +/* + * SCSP client server interface finite state machine action 9 + * + * CSU Solicit from DCS--pass Solicit Ind to server + * + * Arguments: + * dcsp pointer to DCS control block + * msg pointer to message from DCS + * cmsg pointer to message from server + * + * Returns: + * 0 success + * else errno describing error + * + */ +int +scsp_client_act_09(dcsp, msg, cmsg) + Scsp_dcs *dcsp; + Scsp_msg *msg; + Scsp_if_msg *cmsg; +{ + int rc, rrc = 0; + Scsp_csa *csap; + Scsp_if_msg *csip; + + /* + * Get memory for a Solicit Ind + */ + csip = (Scsp_if_msg *)UM_ALLOC(sizeof(Scsp_if_msg)); + if (!csip) { + scsp_mem_err("scsp_client_act_09: sizeof(Scsp_if_msg)"); + } + + /* + * Loop through list of CSAs + */ + for (csap = msg->sc_csu_msg->csu_csa_rec; csap; + csap = csap->next) { + /* + * Fill out the Solicit Indication + */ + UM_ZERO(csip, sizeof(Scsp_if_msg)); + csip->si_type = SCSP_SOLICIT_IND; + csip->si_proto = dcsp->sd_server->ss_pid; + csip->si_tok = (u_long)dcsp; + csip->si_len = sizeof(Scsp_if_msg_hdr) + + sizeof(Scsp_sum_msg); + csip->si_sum.ss_hops = csap->hops; + csip->si_sum.ss_null = csap->null; + csip->si_sum.ss_seq = csap->seq; + csip->si_sum.ss_key = csap->key; + csip->si_sum.ss_oid = csap->oid; + + /* + * Send the Solicit Ind to the server + */ + rc = scsp_if_sock_write(dcsp->sd_server->ss_sock, csip); + if (rc) { + rrc = rc; + } + } + + UM_FREE(csip); + return(rrc); +} + + +/* + * SCSP client server interface finite state machine action 10 + * + * CSU Request from DCS--pass it to the server as a Cache Update + * Indication + * + * Arguments: + * dcsp pointer to DCS control block + * msg pointer to message from DCS + * cmsg pointer to message from server + * + * Returns: + * 0 success + * else errno describing error + * + */ +int +scsp_client_act_10(dcsp, msg, cmsg) + Scsp_dcs *dcsp; + Scsp_msg *msg; + Scsp_if_msg *cmsg; +{ + int rc, rrc = 0; + Scsp_csa *csap; + Scsp_atmarp_csa *acp; + Scsp_if_msg *cuip; + + /* + * Get memory for a Cache Update Ind + */ + cuip = (Scsp_if_msg *)UM_ALLOC(sizeof(Scsp_if_msg)); + if (!cuip) { + scsp_mem_err("scsp_client_act_10: sizeof(Scsp_if_msg)"); + } + + /* + * Loop through CSAs in message + */ + for (csap = msg->sc_csu_msg->csu_csa_rec; csap; + csap = csap->next) { + acp = csap->atmarp_data; + if (!acp) + continue; + + /* + * Fill out the Cache Update Ind + */ + UM_ZERO(cuip, sizeof(Scsp_if_msg)); + cuip->si_type = SCSP_UPDATE_IND; + cuip->si_proto = dcsp->sd_server->ss_pid; + cuip->si_tok = (u_long)dcsp; + switch(dcsp->sd_server->ss_pid) { + case SCSP_PROTO_ATMARP: + cuip->si_len = sizeof(Scsp_if_msg_hdr) + + sizeof(Scsp_atmarp_msg); + cuip->si_atmarp.sa_state = acp->sa_state; + cuip->si_atmarp.sa_cpa = acp->sa_spa; + cuip->si_atmarp.sa_cha = acp->sa_sha; + cuip->si_atmarp.sa_csa = acp->sa_ssa; + cuip->si_atmarp.sa_key = csap->key; + cuip->si_atmarp.sa_oid = csap->oid; + cuip->si_atmarp.sa_seq = csap->seq; + break; + case SCSP_PROTO_NHRP: + /* + * Not implemented yet + */ + break; + } + + /* + * Send the Cache Update Ind to the server + */ + rc = scsp_if_sock_write(dcsp->sd_server->ss_sock, cuip); + if (rc) { + rrc = rc; + } + } + + UM_FREE(cuip); + return(rrc); +} |