freebsd-dev/usr.sbin/atm/scspd/scsp_if.c
Poul-Henning Kamp 1820df7a2d 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).
1998-09-15 08:23:17 +00:00

656 lines
14 KiB
C

/*
*
* ===================================
* 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);
}