diff options
author | phk <phk@FreeBSD.org> | 1998-09-15 08:23:17 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1998-09-15 08:23:17 +0000 |
commit | c3dd1fa899d435ea4bf79897f646a93cb80c94ac (patch) | |
tree | 98dfbc96e3c6aa7ff1f322855f6484c4e609819d /usr.sbin/atm/scspd/scsp_if.c | |
parent | 9ed6892f4808d56de443849229e151f8f7ad43b0 (diff) | |
download | FreeBSD-src-c3dd1fa899d435ea4bf79897f646a93cb80c94ac.zip FreeBSD-src-c3dd1fa899d435ea4bf79897f646a93cb80c94ac.tar.gz |
Add new files for HARP3
Host ATM Research Platform (HARP), Network Computing Services, Inc.
This software was developed with the support of the Defense Advanced
Research Projects Agency (DARPA).
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 0000000..1930990 --- /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); +} |