diff options
author | Robert Watson <rwatson@FreeBSD.org> | 2008-05-25 22:11:40 +0000 |
---|---|---|
committer | Robert Watson <rwatson@FreeBSD.org> | 2008-05-25 22:11:40 +0000 |
commit | e4372ceba044f2b6dbde2fabf95ce2717135d47c (patch) | |
tree | afe56b8f23cfc7884850445d064a110b6ac85c9e /usr.sbin/atm/scspd/scsp_cafsm.c | |
parent | 727acbb41bf75aacfdc3a5555c918ab308317b9b (diff) |
Remove netatm from HEAD as it is not MPSAFE and relies on the now removed
NET_NEEDS_GIANT. netatm has been disconnected from the build for ten
months in HEAD/RELENG_7. Specifics:
- netatm include files
- netatm command line management tools
- libatm
- ATM parts in rescue and sysinstall
- sample configuration files and documents
- kernel support as a module or in NOTES
- netgraph wrapper nodes for netatm
- ctags data for netatm.
- netatm-specific device drivers.
MFC after: 3 weeks
Reviewed by: bz
Discussed with: bms, bz, harti
Notes
Notes:
svn path=/head/; revision=179308
Diffstat (limited to 'usr.sbin/atm/scspd/scsp_cafsm.c')
-rw-r--r-- | usr.sbin/atm/scspd/scsp_cafsm.c | 1439 |
1 files changed, 0 insertions, 1439 deletions
diff --git a/usr.sbin/atm/scspd/scsp_cafsm.c b/usr.sbin/atm/scspd/scsp_cafsm.c deleted file mode 100644 index 05a1e244a9ce..000000000000 --- a/usr.sbin/atm/scspd/scsp_cafsm.c +++ /dev/null @@ -1,1439 +0,0 @@ -/* - * - * =================================== - * 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. - * - * @(#) $FreeBSD$ - * - */ - - -/* - * Server Cache Synchronization Protocol (SCSP) Support - * ---------------------------------------------------- - * - * Cache Alignment finite state machine - * - */ - -#include <sys/types.h> -#include <sys/param.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 <errno.h> -#include <libatm.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> - -#include "scsp_msg.h" -#include "scsp_if.h" -#include "scsp_var.h" - -#ifndef lint -__RCSID("@(#) $FreeBSD$"); -#endif - - -/* - * CA FSM actions - */ -#define CA_ACTION_CNT 20 -int scsp_ca_act_00(Scsp_dcs *, void *); -int scsp_ca_act_01(Scsp_dcs *, void *); -int scsp_ca_act_02(Scsp_dcs *, void *); -int scsp_ca_act_03(Scsp_dcs *, void *); -int scsp_ca_act_04(Scsp_dcs *, void *); -int scsp_ca_act_05(Scsp_dcs *, void *); -int scsp_ca_act_06(Scsp_dcs *, void *); -int scsp_ca_act_07(Scsp_dcs *, void *); -int scsp_ca_act_08(Scsp_dcs *, void *); -int scsp_ca_act_09(Scsp_dcs *, void *); -int scsp_ca_act_10(Scsp_dcs *, void *); -int scsp_ca_act_11(Scsp_dcs *, void *); -int scsp_ca_act_12(Scsp_dcs *, void *); -int scsp_ca_act_13(Scsp_dcs *, void *); -int scsp_ca_act_14(Scsp_dcs *, void *); -int scsp_ca_act_15(Scsp_dcs *, void *); -int scsp_ca_act_16(Scsp_dcs *, void *); -int scsp_ca_act_17(Scsp_dcs *, void *); -int scsp_ca_act_18(Scsp_dcs *, void *); -int scsp_ca_act_19(Scsp_dcs *, void *); - -static int (*scsp_ca_act_vec[CA_ACTION_CNT])() = { - scsp_ca_act_00, - scsp_ca_act_01, - scsp_ca_act_02, - scsp_ca_act_03, - scsp_ca_act_04, - scsp_ca_act_05, - scsp_ca_act_06, - scsp_ca_act_07, - scsp_ca_act_08, - scsp_ca_act_09, - scsp_ca_act_10, - scsp_ca_act_11, - scsp_ca_act_12, - scsp_ca_act_13, - scsp_ca_act_14, - scsp_ca_act_15, - scsp_ca_act_16, - scsp_ca_act_17, - scsp_ca_act_18, - scsp_ca_act_19 -}; - -/* - * CA FSM state table - */ -static int ca_state_table[SCSP_CAFSM_EVENT_CNT][SCSP_CAFSM_STATE_CNT] = { - /* 0 1 2 3 4 5 */ - { 1, 1, 1, 1, 1, 1 }, /* 0 */ - { 2, 2, 2, 2, 2, 2 }, /* 1 */ - { 0, 3, 4, 5, 15, 15 }, /* 2 */ - { 0, 17, 17, 17, 7, 7 }, /* 3 */ - { 0, 17, 17, 17, 8, 8 }, /* 4 */ - { 0, 17, 17, 17, 10, 10 }, /* 5 */ - { 0, 6, 6, 0, 9, 9 }, /* 6 */ - { 0, 0, 0, 0, 12, 12 }, /* 7 */ - { 0, 0, 0, 0, 13, 13 }, /* 8 */ - { 18, 14, 14, 14, 11, 11 }, /* 9 */ - { 0, 19, 0, 0, 16, 16 }, /* 10 */ -}; - - -/* - * Cache Alignment finite state machine - * - * Arguments: - * dcsp pointer to a DCS control block for the neighbor - * event the event which has occurred - * p pointer to further parameter, if there is one - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_cafsm(dcsp, event, p) - Scsp_dcs *dcsp; - int event; - void *p; -{ - int action, rc, state; - - /* - * Select an action from the state table - */ - state = dcsp->sd_ca_state; - action = ca_state_table[event][state]; - if (scsp_trace_mode & SCSP_TRACE_CAFSM) { - scsp_trace("CAFSM: state=%d, event=%d, action=%d\n", - state, event, action); - } - if (action >= CA_ACTION_CNT || action < 0) { - scsp_log(LOG_ERR, "CA FSM--invalid action state=%d, event=%d, action=%d", - state, event, action); - abort(); - } - - /* - * Perform the selected action - */ - rc = scsp_ca_act_vec[action](dcsp, p); - - return(rc); -} - - -/* - * CA finite state machine action 0 - * Unexpected action -- log an error message and go to Master/Slave - * Negotiation. The unexpected action is probably from a protocol - * error. - * - * Arguments: - * dcsp pointer to DCS control block - * p ignored - * - * Returns: - * EOPNOTSUPP always returns EOPNOTSUPP - * - */ -int -scsp_ca_act_00(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int rc; - - /* - * Log an error message - */ - scsp_log(LOG_ERR, "CA FSM error--unexpected action, state=%d", - dcsp->sd_ca_state); - - /* - * Set the new state - */ - dcsp->sd_ca_state = SCSP_CAFSM_NEG; - - /* - * Clear out the DCS block - */ - scsp_dcs_cleanup(dcsp); - - /* - * Notify the client I/F FSM - */ - rc = scsp_cfsm(dcsp, SCSP_CIFSM_CA_DOWN, (Scsp_msg *)0, - (Scsp_if_msg *)0); - - return(rc); -} - - -/* - * CA finite state machine action 1 - * Hello FSM has reached Bidirectional state -- go to Master/Slave - * Negotiation state, make a copy of the client's cache, send first CA - * message. - * - * Arguments: - * dcsp pointer to DCS control block - * p ignored - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_01(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int i, rc; - Scsp_cse *csep, *dupp; - - /* - * Set the new state - */ - dcsp->sd_ca_state = SCSP_CAFSM_NEG; - - /* - * Make a copy of client's cache entries for cache alignment - */ - for (i = 0; i < SCSP_HASHSZ; i++) { - for (csep = dcsp->sd_server->ss_cache[i]; - csep; csep = csep->sc_next) { - dupp = scsp_dup_cse(csep); - LINK2TAIL(dupp, Scsp_cse, dcsp->sd_ca_csas, - sc_next); - } - } - - /* - * Select an initial sequence number - */ - dcsp->sd_ca_seq = (int)time((time_t *)0); - - /* - * Send a CA message - */ - rc = scsp_send_ca(dcsp); - if (rc == 0) { - HARP_TIMER(&dcsp->sd_ca_rexmt_t, dcsp->sd_ca_rexmt_int, - scsp_ca_retran_timeout); - } - - return(rc); -} - - -/* - * CA finite state machine action 2 - * Hello FSM has gone down -- go to Down state - * - * Arguments: - * dcsp pointer to DCS control block - * p ignored - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_02(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int rc; - - /* - * Set the new state - */ - dcsp->sd_ca_state = SCSP_CAFSM_DOWN; - - /* - * Clear out the DCS block - */ - scsp_dcs_cleanup(dcsp); - - /* - * Notify the client I/F FSM - */ - rc = scsp_cfsm(dcsp, SCSP_CIFSM_CA_DOWN, (Scsp_msg *)0, - (Scsp_if_msg *)0); - - return(rc); -} - - -/* - * CA finite state machine action 3 - * CA message received -- select Cache Summarize Master or Slave state - * - * Arguments: - * dcsp pointer to DCS control block - * p pointer to received message - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_03(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int rc = 0; - Scsp_msg *msg = (Scsp_msg *)p; - - /* - * Check for slave role for LS - */ - if (msg->sc_ca->ca_m && - msg->sc_ca->ca_i && - msg->sc_ca->ca_o && - msg->sc_ca->ca_mcp.rec_cnt == 0 && - scsp_cmp_id(&msg->sc_ca->ca_mcp.sid, - &msg->sc_ca->ca_mcp.rid) > 0) { - - /* - * Stop the retransmit timer - */ - HARP_CANCEL(&dcsp->sd_ca_rexmt_t); - - /* - * Set the new state - */ - dcsp->sd_ca_state = SCSP_CAFSM_SLAVE; - (void)scsp_cfsm(dcsp, SCSP_CIFSM_CA_SUMM, - (Scsp_msg *)0, (Scsp_if_msg *)0); - - /* - * Save the master's sequence number - */ - dcsp->sd_ca_seq = msg->sc_ca->ca_seq; - - /* - * Send a CA message - */ - rc = scsp_send_ca(dcsp); - } else - /* - * Check for master role for LS - */ - if (!msg->sc_ca->ca_m && - !msg->sc_ca->ca_i && - scsp_cmp_id(&msg->sc_ca->ca_mcp.sid, - &msg->sc_ca->ca_mcp.rid) < 0) { - /* - * Stop the retransmit timer - */ - HARP_CANCEL(&dcsp->sd_ca_rexmt_t); - - /* - * Set the new state - */ - dcsp->sd_ca_state = SCSP_CAFSM_MASTER; - rc = scsp_cfsm(dcsp, SCSP_CIFSM_CA_SUMM, - (Scsp_msg *)0, (Scsp_if_msg *)0); - - /* - * Process the CA message - */ - scsp_process_ca(dcsp, msg->sc_ca); - - /* - * Increment the sequence number - */ - dcsp->sd_ca_seq++; - - /* - * Send a CA in reply - */ - rc = scsp_send_ca(dcsp); - if (rc == 0) { - HARP_TIMER(&dcsp->sd_ca_rexmt_t, - dcsp->sd_ca_rexmt_int, - scsp_ca_retran_timeout); - } - } else { - /* - * Ignore the message, go to Master/Slave Negotiation - */ - dcsp->sd_ca_state = SCSP_CAFSM_NEG; - } - - return(rc); -} - - -/* - * CA finite state machine action 4 - * CA message received while in Cache Summarize Master state -- process - * CA message - * - * Arguments: - * dcsp pointer to DCS control block - * p pointer to received message - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_04(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int rc = 0; - Scsp_msg *msg = (Scsp_msg *)p; - - /* - * If the other side thinks he's the master, or if the - * initialization bit is set, or if the message is out - * of sequence, go back to Master/Slave Negotiation state - */ - if (msg->sc_ca->ca_m || msg->sc_ca->ca_i || - msg->sc_ca->ca_seq < dcsp->sd_ca_seq - 1 || - msg->sc_ca->ca_seq > dcsp->sd_ca_seq) { - HARP_CANCEL(&dcsp->sd_ca_rexmt_t); - dcsp->sd_ca_state = SCSP_CAFSM_NEG; - scsp_dcs_cleanup(dcsp); - return(scsp_ca_act_01(dcsp, (Scsp_msg *)0)); - } - - /* - * Ignore any duplicate messages - */ - if (msg->sc_ca->ca_seq == dcsp->sd_ca_seq - 1) { - return(0); - } - - /* - * Stop the retransmission timer - */ - HARP_CANCEL(&dcsp->sd_ca_rexmt_t); - - /* - * Process the CA message - */ - scsp_process_ca(dcsp, msg->sc_ca); - - /* - * Increment the CA sequence number - */ - dcsp->sd_ca_seq++; - - /* - * If we have no more CSAS records to send and the slave sent - * a message with the 'O' bit off, we're done with Summarize - * state - */ - if (!dcsp->sd_ca_csas && !msg->sc_ca->ca_o) { - /* - * Free any CA message saved for retransmission - */ - if (dcsp->sd_ca_rexmt_msg) { - scsp_free_msg(dcsp->sd_ca_rexmt_msg); - dcsp->sd_ca_rexmt_msg = (Scsp_msg *)0; - } - - /* - * If the CRL is empty, we go directly to Aligned state; - * otherwise, we go to Update Cache and send a CSUS - */ - if (!dcsp->sd_crl) { - /* - * Go to Aligned state - */ - dcsp->sd_ca_state = SCSP_CAFSM_ALIGNED; - rc = scsp_cfsm(dcsp, SCSP_CIFSM_CA_ALIGN, - (Scsp_msg *)0, - (Scsp_if_msg *)0); - } else { - /* - * Go to Cache Update state - */ - dcsp->sd_ca_state = SCSP_CAFSM_UPDATE; - (void)scsp_cfsm(dcsp, SCSP_CIFSM_CA_UPD, - (Scsp_msg *)0, - (Scsp_if_msg *)0); - rc = scsp_send_csus(dcsp); - } - } else { - /* - * There are more CSAS records to be exchanged-- - * continue the cache exchange - */ - rc = scsp_send_ca(dcsp); - } - - return(rc); -} - - -/* - * CA finite state machine action 5 - * CA message received while in Cache Summarize Slave state -- process - * CA message - * - * Arguments: - * dcsp pointer to DCS control block - * p pointer to received message - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_05(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int rc = 0; - Scsp_msg *msg = (Scsp_msg *)p; - - /* - * If the other side thinks we're the master, or if the - * initialization bit is set, or if the message is out - * of sequence, go back to Master/Slave Negotiation state - */ - if (!msg->sc_ca->ca_m || msg->sc_ca->ca_i || - msg->sc_ca->ca_seq < dcsp->sd_ca_seq || - msg->sc_ca->ca_seq > dcsp->sd_ca_seq + 1) { - HARP_CANCEL(&dcsp->sd_ca_rexmt_t); - dcsp->sd_ca_state = SCSP_CAFSM_NEG; - scsp_dcs_cleanup(dcsp); - return(scsp_ca_act_01(dcsp, (Scsp_msg *)0)); - } - - /* - * If this is a duplicate, retransmit the last message - */ - if (msg->sc_ca->ca_seq == dcsp->sd_ca_seq) { - if (dcsp->sd_ca_rexmt_msg) { - rc = scsp_send_msg(dcsp, dcsp->sd_ca_rexmt_msg); - if (rc == 0) { - HARP_TIMER(&dcsp->sd_ca_rexmt_t, - dcsp->sd_ca_rexmt_int, - scsp_ca_retran_timeout); - } - } - return(rc); - } - - /* - * Free the last CA message - */ - if (dcsp->sd_ca_rexmt_msg) { - scsp_free_msg(dcsp->sd_ca_rexmt_msg); - dcsp->sd_ca_rexmt_msg = (Scsp_msg *)0; - } - - /* - * Process the CA message - */ - scsp_process_ca(dcsp, msg->sc_ca); - - /* - * Increment the CA sequence number - */ - dcsp->sd_ca_seq++; - - /* - * Answer the CA message - */ - rc = scsp_send_ca(dcsp); - if (rc) - return(rc); - - /* - * If we're done sending CSAS records and the other side is, - * too, we're done with Summarize state - */ - if (!dcsp->sd_ca_csas && !msg->sc_ca->ca_o) { - /* - * If the CRL is empty, we go directly to Aligned state; - * otherwise, we go to Update Cache and send a CSUS - */ - if (!dcsp->sd_crl) { - /* - * Go to Aligned state - */ - dcsp->sd_ca_state = SCSP_CAFSM_ALIGNED; - rc = scsp_cfsm(dcsp, SCSP_CIFSM_CA_ALIGN, - (Scsp_msg *)0, - (Scsp_if_msg *)0); - } else { - /* - * Go to Cache Update state - */ - dcsp->sd_ca_state = SCSP_CAFSM_UPDATE; - HARP_CANCEL(&dcsp->sd_ca_rexmt_t); - HARP_TIMER(&dcsp->sd_ca_rexmt_t, - dcsp->sd_ca_rexmt_int, - scsp_ca_retran_timeout); - (void)scsp_cfsm(dcsp, SCSP_CIFSM_CA_UPD, - (Scsp_msg *)0, - (Scsp_if_msg *)0); - rc = scsp_send_csus(dcsp); - } - } - - return(rc); -} - - -/* - * CA finite state machine action 6 - * Retransmit timer expired -- retransmit last CA message - * - * Arguments: - * dcsp pointer to DCS control block - * p ignored - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_06(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int rc; - - /* - * Resend the CA message - */ - rc = scsp_send_msg(dcsp, dcsp->sd_ca_rexmt_msg); - - /* - * Restart the retransmit timer - */ - if (rc == 0) { - HARP_TIMER(&dcsp->sd_ca_rexmt_t, dcsp->sd_ca_rexmt_int, - scsp_ca_retran_timeout); - } - - return(rc); -} - - -/* - * CA finite state machine action 7 - * CSU Solicit received -- send it to the client interface FSM - * - * Arguments: - * dcsp pointer to DCS control block - * p pointer to received message - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_07(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int rc; - Scsp_msg *msg = (Scsp_msg *)p; - - /* - * Cancel the CA retransmit timer and free any CA message - * saved for retransmission - */ - if (dcsp->sd_ca_rexmt_msg) { - HARP_CANCEL(&dcsp->sd_ca_rexmt_t); - scsp_free_msg(dcsp->sd_ca_rexmt_msg); - dcsp->sd_ca_rexmt_msg = (Scsp_msg *)0; - } - - /* - * Pass the CSUS to the client interface FSM - */ - rc = scsp_cfsm(dcsp, SCSP_CIFSM_CSU_SOL, msg, - (Scsp_if_msg *)0); - - return(rc); -} - - -/* - * CA finite state machine action 8 - * CSU Request received -- pass it to the client interface FSM - * - * Arguments: - * dcsp pointer to DCS control block - * p pointer to received message - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_08(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int rc; - Scsp_msg *msg = (Scsp_msg *)p; - Scsp_csa *csap; - - /* - * Check whether this messages answers a CSUS - */ - scsp_csus_ack(dcsp, msg); - - /* - * If all CSAs requestd in CSUS messages have been - * received, the cache is aligned, so go to Aligned State - */ - if (!dcsp->sd_csus_rexmt_msg && !dcsp->sd_crl && - dcsp->sd_ca_state != SCSP_CAFSM_ALIGNED) { - dcsp->sd_ca_state = SCSP_CAFSM_ALIGNED; - rc = scsp_cfsm(dcsp, SCSP_CIFSM_CA_ALIGN, - (Scsp_msg *)0, (Scsp_if_msg *)0); - } - - /* - * Pass the CSU Req to the client interface FSM - */ - rc = scsp_cfsm(dcsp, SCSP_CIFSM_CSU_REQ, msg, - (Scsp_if_msg *)0); - - /* - * Move the CSA chain from the message to the list of - * requests that need acknowledgements - */ - for (csap = msg->sc_csu_msg->csu_csa_rec; csap; - csap = csap->next) { - LINK2TAIL(csap, Scsp_csa, dcsp->sd_csu_ack_pend, next); - } - msg->sc_csu_msg->csu_csa_rec = (Scsp_csa *)0; - - return(rc); -} - - -/* - * CA finite state machine action 9 - * CA Retransmit timer expired in Update Cache or Aligned state--free - * the saved CA message - * - * Arguments: - * dcsp pointer to DCS control block - * p ignored - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_09(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - /* - * Free any CA message saved for retransmission - */ - if (dcsp->sd_ca_rexmt_msg) { - scsp_free_msg(dcsp->sd_ca_rexmt_msg); - dcsp->sd_ca_rexmt_msg = (Scsp_msg *)0; - } - - return(0); -} - - -/* - * CA finite state machine action 10 - * CSU Reply received -- Process the message - * - * Arguments: - * dcsp pointer to DCS control block - * p pointer to received message - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_10(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int rc = 0; - Scsp_msg *msg = (Scsp_msg *)p; - Scsp_csu_rexmt *rxp, *next_rxp; - Scsp_csa *csap, *next_csap, *mcp; - - /* - * Dequeue acknowledged CSAs. For each CSAS in the received - * message, find the corresponding CSA on the CSU Request - * retransmit queue. Remove the CSA from the queue; if this - * results in the retransmit queue entry being empty, delete - * the entry. If the DCS has a newer CSA, send a CSUS to - * request it. - * - * Caution--potentially confusing lack of indentation ahead. - */ - for (mcp = msg->sc_csu_msg->csu_csa_rec; mcp; - mcp = mcp->next) { - for (rxp = dcsp->sd_csu_rexmt; rxp; rxp = next_rxp) { - next_rxp = rxp->sr_next; - for (csap = rxp->sr_csa; csap; csap = next_csap) { - next_csap = csap->next; - if (scsp_cmp_key(&csap->key, &mcp->key) || - scsp_cmp_id(&csap->oid, &mcp->oid)) - continue; - /* - * Found a CSA whose key and ID are equal to - * those in the CSU Reply - */ - if (csap->seq == mcp->seq) { - /* - * The queued seq no is equal to the - * received seq no--the CSA is acknowledged - */ - UNLINK(csap, Scsp_csa, rxp->sr_csa, next); - SCSP_FREE_CSA(csap); - } else if (csap->seq < mcp->seq) { - /* - * Queued seq no is less than received. - * We must dequeue the CSA and send a - * CSUS to request the more-up-to-date - * cache entry. - */ - UNLINK(mcp, Scsp_csa, - msg->sc_csu_msg->csu_csa_rec, - next); - LINK2TAIL(mcp, Scsp_csa, dcsp->sd_crl, next); - UNLINK(csap, Scsp_csa, rxp->sr_csa, next); - SCSP_FREE_CSA(csap); - if (!dcsp->sd_csus_rexmt_msg) { - rc = scsp_send_csus(dcsp); - if (rc) { - return(rc); - } - } - } - /* - * Queued seq no is greater than - * received. Ignore the received CSAS. - */ - - /* - * If the retransmission block is empty, stop the - * timer and free it - */ - if (!rxp->sr_csa) { - HARP_CANCEL(&rxp->sr_t); - UNLINK(rxp, Scsp_csu_rexmt, - dcsp->sd_csu_rexmt, sr_next); - free(rxp); - } - - break; - } /* for (csap = ... */ - } /* for (rxp = ... */ - } /* for (mcp = ... */ - - return(rc); -} - - -/* - * CA finite state machine action 11 - * Updated cache entry -- update the summary cache and send a - * CSU Request - * - * Arguments: - * dcsp pointer to DCS control block - * p pointer to CSA describing new cache entry - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_11(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int rc, state; - Scsp_csa *csap = (Scsp_csa *)p; - Scsp_cse *csep; - - /* - * Get the state of the CSA - */ - switch(dcsp->sd_server->ss_pid) { - case SCSP_PROTO_ATMARP: - state = csap->atmarp_data->sa_state; - break; - default: - SCSP_FREE_CSA(csap); - return(EINVAL); - } - - if (state < SCSP_ASTATE_NEW || state > SCSP_ASTATE_DEL) { - SCSP_FREE_CSA(csap); - return(EINVAL); - } - - /* - * Look up the cache summary entry for the CSA - */ - SCSP_LOOKUP(dcsp->sd_server, &csap->key, csep); - - /* - * Process ATMARP entries - */ - if (dcsp->sd_server->ss_pid == SCSP_PROTO_ATMARP) { - switch(state) { - case SCSP_ASTATE_NEW: - case SCSP_ASTATE_UPD: - /* - * Add the entry if we don't have it already - */ - if (!csep) { - csep = calloc(1, sizeof(Scsp_cse)); - if (csep == NULL) - scsp_mem_err("scsp_ca_act_11: sizeof(Scsp_cse)"); - - csep->sc_key = csap->key; - SCSP_ADD(dcsp->sd_server, csep); - } - - /* - * Update the cache summary entry - */ - csep->sc_seq = csap->seq; - csep->sc_oid = csap->oid; - break; - case SCSP_ASTATE_DEL: - /* - * Delete any entry, but don't send the - * delete to the DCS - */ - if (csep) { - SCSP_DELETE(dcsp->sd_server, csep); - free(csep); - } - - SCSP_FREE_CSA(csap); - return(0); - } - } - - /* - * Send the CSA in a CSU Request - */ - csap->trans_ct = 0; - rc = scsp_send_csu_req(dcsp, csap); - - return(rc); -} - - -/* - * CA finite state machine action 12 - * CSUS retransmit timer expired--send a CSUS with any pending CSA - * records - * - * Arguments: - * dcsp pointer to DCS control block - * p ignored - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_12(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int rc; - - rc = scsp_send_csus(dcsp); - - return(rc); -} - - -/* - * CA finite state machine action 13 - * CSU retransmit timer fired in Update or Aligned state-- - * retransmit CSU Req - * - * Arguments: - * dcsp pointer to DCS control block - * p pointer to retransmission block whose timer fired - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_13(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int rc = 0; - Scsp_csu_rexmt *rxp = (Scsp_csu_rexmt *)p; - Scsp_csa *csap, *csap1, *next_csap; - - /* - * Unlink and free the retransmit request block - */ - csap = rxp->sr_csa; - UNLINK(rxp, Scsp_csu_rexmt, dcsp->sd_csu_rexmt, sr_next); - free(rxp); - - /* - * Increment the transmission count for the CSAs in the request - */ - for (csap1 = csap; csap1; csap1 = next_csap) { - next_csap = csap1->next; - csap1->trans_ct++; - if (csap1->trans_ct >= dcsp->sd_csu_rexmt_max) { - /* - * We've already sent this as many times as - * the limit allows. Drop this CSA. - */ - UNLINK(csap1, Scsp_csa, csap, next); - SCSP_FREE_CSA(csap1); - } - } - - /* - * Send another CSU Request with the CSA list, if it isn't - * empty now - */ - if (csap) { - rc = scsp_send_csu_req(dcsp, csap); - } - - return(rc); -} - - -/* - * CA finite state machine action 14 - * Updated cache entry in Master/Slave Negotiation, Master, or - * Slave state--add entry to cache and CSA list - * - * Arguments: - * dcsp pointer to DCS control block - * p pointer to new cache summary entry - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_14(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - Scsp_csa *csap = (Scsp_csa *)p; - Scsp_cse *csep, *csep1; - - /* - * Check to see whether we already have this - */ - SCSP_LOOKUP(dcsp->sd_server, &csap->key, csep); - - /* - * If we don't already have it and it's not being deleted, - * build a new cache summary entry - */ - if (!csep && !csap->null) { - /* - * Get memory for a new entry - */ - csep = calloc(1, sizeof(Scsp_cse)); - if (csep == NULL) - scsp_mem_err("scsp_ca_act_14: sizeof(Scsp_cse)"); - - /* - * Fill out the new cache entry - */ - csep->sc_seq = csap->seq; - csep->sc_key = csap->key; - csep->sc_oid = csap->oid; - - /* - * Duplicate the new cache entry - */ - csep1 = scsp_dup_cse(csep); - - /* - * Add entry to the summary cache and the CSAS list - */ - SCSP_ADD(dcsp->sd_server, csep); - LINK2TAIL(csep1, Scsp_cse, dcsp->sd_ca_csas, sc_next); - } else { - /* - * We already have the entry. Find it on the CSAS - * list. - */ - for (csep1 = dcsp->sd_ca_csas; csep1; - csep1 = csep1->sc_next) { - if (scsp_cmp_key(&csep->sc_key, - &csep1->sc_key) == 0) - break; - } - - /* - * Update or delete the entry - */ - if (csap->null) { - /* - * The null flag is set--delete the entry - */ - SCSP_DELETE(dcsp->sd_server, csep); - free(csep); - if (csep1) { - UNLINK(csep1, Scsp_cse, - dcsp->sd_ca_csas, - sc_next); - free(csep1); - } - } else { - /* - * Update the entry - */ - csep->sc_seq = csap->seq; - csep->sc_oid = csap->oid; - if (!csep1) { - csep1 = scsp_dup_cse(csep); - LINK2TAIL(csep1, Scsp_cse, - dcsp->sd_ca_csas, sc_next); - } else { - csep1->sc_seq = csap->seq; - csep1->sc_oid = csap->oid; - } - } - } - - return(0); -} - - -/* - * CA finite state machine action 15 - * CA message received in Update Cache state--if we have a saved CA - * message, retransmit it; otherwise, go to Master/Slave Negotiation - * state - * - * Arguments: - * dcsp pointer to DCS control block - * p ignored - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_15(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int rc; - Scsp_msg *msg = (Scsp_msg *)p; - - /* - * If we don't have a saved CA message, or the sequence no. in - * the received message isn't right, fall back to Master/Slave - * Negotiation state - */ - if (!dcsp->sd_ca_rexmt_msg || - msg->sc_ca->ca_seq != dcsp->sd_ca_seq) { - dcsp->sd_ca_state = SCSP_CAFSM_NEG; - scsp_dcs_cleanup(dcsp); - rc = scsp_ca_act_01(dcsp, (Scsp_msg *)0); - } else { - /* - * Retransmit the saved CA message and reset the - * CA timer - */ - rc = scsp_send_msg(dcsp, dcsp->sd_ca_rexmt_msg); - if (rc == 0) { - HARP_CANCEL(&dcsp->sd_ca_rexmt_t); - HARP_TIMER(&dcsp->sd_ca_rexmt_t, - dcsp->sd_ca_rexmt_int, - scsp_ca_retran_timeout); - } - } - - return(rc); -} - - -/* - * CA finite state machine action 16 - * Update Response received from client in Update Cache or Aligned - * state. Move the acknowledged CSA to the acknowledged queue. If - * the list of CSAs pending acknowledgement is empty, send a CSU - * Reply. - * - * Arguments: - * dcsp pointer to DCS control block - * p pointer to message from client - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_16(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - int found, rc = 0; - Scsp_if_msg *cmsg = (Scsp_if_msg *)p; - Scsp_csa *csap; - - /* - * Find the acknowledged CSA - */ - for (csap = dcsp->sd_csu_ack_pend, found = 0; csap && !found; - csap = csap->next) { - switch (dcsp->sd_server->ss_pid) { - case SCSP_PROTO_ATMARP: - found = ((scsp_cmp_key(&csap->key, - &cmsg->si_atmarp.sa_key) == 0) && - (scsp_cmp_id(&csap->oid, - &cmsg->si_atmarp.sa_oid) == 0)); - break; - default: - /* - * Protocol not implemented - */ - return(EPROTONOSUPPORT); - } - if (found) - break; - } - - if (!found) { - if (scsp_trace_mode & SCSP_TRACE_CAFSM) { - scsp_trace("scsp_ca_act_16: can't find CSA entry for Update Response\n"); - } - return(0); - } - - if (cmsg->si_rc == SCSP_RSP_OK) { - /* - * The server accepted the cache entry - */ - - /* - * Update SCSP's cache - */ - scsp_update_cache(dcsp, csap); - - /* - * Send this CSA to any other DCSs in the server group - */ - rc = scsp_propagate_csa(dcsp, csap); - } - - /* - * Move the CSA from the ACK pending queue to the - * acknowledged queue - */ - UNLINK(csap, Scsp_csa, dcsp->sd_csu_ack_pend, next); - LINK2TAIL(csap, Scsp_csa, dcsp->sd_csu_ack, next); - if (!dcsp->sd_csu_ack_pend) { - /* - * ACK pending list is empty--send a CSU Reply - */ - csap = dcsp->sd_csu_ack; - dcsp->sd_csu_ack = (Scsp_csa *)0; - rc = scsp_send_csu_reply(dcsp, csap); - } - - return(rc); -} - - -/* - * CA finite state machine action 17 - * Ignore an event. - * - * Arguments: - * dcsp pointer to DCS control block - * p ignored - * - * Returns: - * always returns 0 - * - */ -int -scsp_ca_act_17(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - return(0); -} - - -/* - * CA finite state machine action 18 - * Updated cache entry in Down state--add entry to summary cache - * - * Arguments: - * dcsp pointer to DCS control block - * p pointer to new cache summary entry - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_18(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - Scsp_csa *csap = (Scsp_csa *)p; - - /* - * Update the cache as appropriate - */ - scsp_update_cache(dcsp, csap); - - return(0); -} - - -/* - * CA finite state machine action 19 - * Update Response received from client in Master/Slave Negotiation - * state. Update the cache as appropriate. - * - * Arguments: - * dcsp pointer to DCS control block - * p pointer to message from client - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -scsp_ca_act_19(dcsp, p) - Scsp_dcs *dcsp; - void *p; -{ - Scsp_if_msg *cmsg = (Scsp_if_msg *)p; - Scsp_csa *csap; - - /* - * Ignore the message if the client rejected the update - */ - if (cmsg->si_rc != SCSP_RSP_OK) { - return(0); - } - - /* - * Create a CSAS from the client's update - */ - csap = calloc(1, sizeof(Scsp_csa)); - if (csap == NULL) - scsp_mem_err("scsp_ca_act_19: sizeof(Scsp_csa)"); - csap->hops = 1; - switch (dcsp->sd_server->ss_pid) { - case SCSP_PROTO_ATMARP: - csap->null = cmsg->si_atmarp.sa_state == - SCSP_ASTATE_DEL; - csap->seq = cmsg->si_atmarp.sa_seq; - csap->key = cmsg->si_atmarp.sa_key; - csap->oid = cmsg->si_atmarp.sa_oid; - break; - default: - return(EINVAL); - } - - /* - * Update SCSP's cache - */ - scsp_update_cache(dcsp, csap); - - return(0); -} |