3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/usr.sbin/atm/scspd/scsp_if.c,v 1.3 1999/08/28 01:15:33 peter Exp $
27 * @(#) $DragonFly: src/usr.sbin/atm/scspd/scsp_if.c,v 1.3 2003/11/03 19:31:35 eirikn Exp $
32 * Server Cache Synchronization Protocol (SCSP) Support
33 * ----------------------------------------------------
35 * Interface to client server protocol
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <netatm/port.h>
45 #include <netatm/queue.h>
46 #include <netatm/atm.h>
47 #include <netatm/atm_if.h>
48 #include <netatm/atm_sap.h>
49 #include <netatm/atm_sys.h>
50 #include <netatm/atm_ioctl.h>
65 * SCSP client server interface FSM actions
67 #define SCSP_CIFSM_ACTION_CNT 11
68 int scsp_client_act_00
69 (Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
70 int scsp_client_act_01
71 (Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
72 int scsp_client_act_02
73 (Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
74 int scsp_client_act_03
75 (Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
76 int scsp_client_act_04
77 (Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
78 int scsp_client_act_05
79 (Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
80 int scsp_client_act_06
81 (Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
82 int scsp_client_act_07
83 (Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
84 int scsp_client_act_08
85 (Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
86 int scsp_client_act_09
87 (Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
88 int scsp_client_act_10
89 (Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
91 static int (*scsp_action_vector[SCSP_CIFSM_ACTION_CNT])() = {
107 * Client server interface FSM state table
109 static int client_state_table[SCSP_CIFSM_EVENT_CNT][SCSP_CIFSM_STATE_CNT] = {
111 { 1, 3, 3, 3 }, /* 0 */
112 { 2, 5, 5, 5 }, /* 1 */
113 { 0, 4, 0, 0 }, /* 2 */
114 { 0, 6, 6, 1 }, /* 3 */
115 { 1, 0, 7, 7 }, /* 4 */
116 { 7, 7, 7, 7 }, /* 5 */
117 { 1, 1, 8, 8 }, /* 6 */
118 { 0, 0, 10, 10 }, /* 7 */
119 { 0, 0, 1, 1 }, /* 8 */
120 { 0, 0, 9, 9 } /* 9 */
125 * SCSP client server interface finite state machine
128 * ssp pointer to server control block
129 * event the event which has occurred
130 * msg pointer to message from DCS, if there is one
131 * cmsg pointer to message from server, if there is one
135 * errno error encountered
139 scsp_cfsm(dcsp, event, msg, cmsg)
145 int action, rc, state;
148 * Select an action from the state table
150 state = dcsp->sd_client_state;
151 action = client_state_table[event][state];
152 if (scsp_trace_mode & SCSP_TRACE_CFSM) {
153 scsp_trace("Server I/F FSM: state=%d, event=%d, action=%d\n",
154 state, event, action);
156 if (action >= SCSP_CIFSM_ACTION_CNT || action <= 0) {
157 scsp_log(LOG_ERR, "Server I/F FSM--invalid action %d; state=%d, event=%d",
158 action, dcsp->sd_client_state, event);
163 * Perform the selected action
165 rc = scsp_action_vector[action](dcsp, msg, cmsg);
172 * SCSP client server interface finite state machine action 0
173 * Unexpected action -- log an error message
176 * dcsp pointer to DCS control block
177 * msg pointer to message from DCS (ignored)
178 * cmsg pointer to message from server (ignored)
181 * EOPNOTSUPP always returns EOPNOTSUPP
185 scsp_client_act_00(dcsp, msg, cmsg)
190 scsp_log(LOG_ERR, "Server I/F FSM error--unexpected action, state=%d",
191 dcsp->sd_client_state);
197 * SCSP client server interface finite state machine action 1
202 * dcsp pointer to DCS control block
203 * msg pointer to message from DCS
204 * cmsg pointer to message from server
211 scsp_client_act_01(dcsp, msg, cmsg)
221 * SCSP client server interface finite state machine action 2
223 * CA FSM went to Cache Summarize state--go to Summarize
226 * dcsp pointer to DCS control block
227 * msg pointer to message from DCS
228 * cmsg pointer to message from server
232 * else errno describing error
236 scsp_client_act_02(dcsp, msg, cmsg)
244 dcsp->sd_client_state = SCSP_CIFSM_SUM;
251 * SCSP client server interface finite state machine action 3
253 * CA FSM went down--clean up and go to Null
256 * dcsp pointer to DCS control block
257 * msg pointer to message from DCS
258 * cmsg pointer to message from server
262 * else errno describing error
266 scsp_client_act_03(dcsp, msg, cmsg)
274 dcsp->sd_client_state = SCSP_CIFSM_NULL;
281 * SCSP client server interface finite state machine action 4
283 * CA FSM went to Update Cache state--go to Update state
286 * dcsp pointer to DCS control block
287 * msg pointer to message from DCS
288 * cmsg pointer to message from server
292 * else errno describing error
296 scsp_client_act_04(dcsp, msg, cmsg)
304 dcsp->sd_client_state = SCSP_CIFSM_UPD;
311 * SCSP client server interface finite state machine action 5
313 * The CA FSM went to Cache Summarize state from Summarize,
314 * Update, or Aligned, implying that the CA FSM went down and came
315 * back up--copy the server's cache to the DCSs CSAS list and go to
319 * dcsp pointer to DCS control block
320 * msg pointer to message from DCS
321 * cmsg pointer to message from server
325 * else errno describing error
329 scsp_client_act_05(dcsp, msg, cmsg)
335 Scsp_cse *csep, *ncsep;
338 * Copy the cache summmary to the CSAS list
340 for (i = 0; i < SCSP_HASHSZ; i++) {
341 for (csep = dcsp->sd_server->ss_cache[i]; csep;
342 csep = csep->sc_next) {
343 ncsep = scsp_dup_cse(csep);
344 LINK2TAIL(ncsep, Scsp_cse, dcsp->sd_ca_csas,
352 dcsp->sd_client_state = SCSP_CIFSM_SUM;
359 * SCSP client server interface finite state machine action 6
361 * CA FSM went to Aligned state--go to Aligned
364 * dcsp pointer to DCS control block
365 * msg pointer to message from DCS
366 * cmsg pointer to message from server
370 * else errno describing error
374 scsp_client_act_06(dcsp, msg, cmsg)
382 dcsp->sd_client_state = SCSP_CIFSM_ALIGN;
389 * SCSP client server interface finite state machine action 7
391 * We received a Solicit Rsp or Update Req from the server--pass it
395 * dcsp pointer to DCS control block
396 * msg pointer to message from DCS
397 * cmsg pointer to message from server
401 * else errno describing error
405 scsp_client_act_07(dcsp, msg, cmsg)
412 Scsp_atmarp_csa *acp;
415 * Allocate memory for a CSA record
417 csap = (Scsp_csa *)UM_ALLOC(sizeof(Scsp_csa));
419 scsp_mem_err("scsp_client_act_07: sizeof(Scsp_csa)");
421 acp = (Scsp_atmarp_csa *)UM_ALLOC(sizeof(Scsp_atmarp_csa));
423 scsp_mem_err("scsp_client_act_07: sizeof(Scsp_atmarp_csa)");
425 UM_ZERO(csap, sizeof(Scsp_csa));
426 UM_ZERO(acp, sizeof(Scsp_atmarp_csa));
429 * Build a CSA record from the server's message
431 csap->hops = dcsp->sd_hops;
432 csap->null = (cmsg->si_atmarp.sa_state == SCSP_ASTATE_DEL) ||
433 (cmsg->si_type == SCSP_SOLICIT_RSP &&
434 cmsg->si_rc != SCSP_RSP_OK);
435 csap->seq = cmsg->si_atmarp.sa_seq;
436 csap->key = cmsg->si_atmarp.sa_key;
437 csap->oid = cmsg->si_atmarp.sa_oid;
438 csap->atmarp_data = acp;
439 acp->sa_state = cmsg->si_atmarp.sa_state;
440 acp->sa_sha = cmsg->si_atmarp.sa_cha;
441 acp->sa_ssa = cmsg->si_atmarp.sa_csa;
442 acp->sa_spa = cmsg->si_atmarp.sa_cpa;
443 acp->sa_tpa = cmsg->si_atmarp.sa_cpa;
448 rc = scsp_cafsm(dcsp, SCSP_CAFSM_CACHE_UPD, (void *)csap);
455 * SCSP client server interface finite state machine action 8
457 * Update Rsp from server--pass the update to the CA FSM.
460 * dcsp pointer to DCS control block
461 * msg pointer to message from DCS
462 * cmsg pointer to message from server
466 * else errno describing error
470 scsp_client_act_08(dcsp, msg, cmsg)
478 * Pass the response to the CA FSM
480 switch (dcsp->sd_server->ss_pid) {
481 case SCSP_PROTO_ATMARP:
482 rc = scsp_cafsm(dcsp, SCSP_CAFSM_CACHE_RSP, cmsg);
485 rc = EPROTONOSUPPORT;
493 * SCSP client server interface finite state machine action 9
495 * CSU Solicit from DCS--pass Solicit Ind to server
498 * dcsp pointer to DCS control block
499 * msg pointer to message from DCS
500 * cmsg pointer to message from server
504 * else errno describing error
508 scsp_client_act_09(dcsp, msg, cmsg)
518 * Get memory for a Solicit Ind
520 csip = (Scsp_if_msg *)UM_ALLOC(sizeof(Scsp_if_msg));
522 scsp_mem_err("scsp_client_act_09: sizeof(Scsp_if_msg)");
526 * Loop through list of CSAs
528 for (csap = msg->sc_csu_msg->csu_csa_rec; csap;
531 * Fill out the Solicit Indication
533 UM_ZERO(csip, sizeof(Scsp_if_msg));
534 csip->si_type = SCSP_SOLICIT_IND;
535 csip->si_proto = dcsp->sd_server->ss_pid;
536 csip->si_tok = (u_long)dcsp;
537 csip->si_len = sizeof(Scsp_if_msg_hdr) +
538 sizeof(Scsp_sum_msg);
539 csip->si_sum.ss_hops = csap->hops;
540 csip->si_sum.ss_null = csap->null;
541 csip->si_sum.ss_seq = csap->seq;
542 csip->si_sum.ss_key = csap->key;
543 csip->si_sum.ss_oid = csap->oid;
546 * Send the Solicit Ind to the server
548 rc = scsp_if_sock_write(dcsp->sd_server->ss_sock, csip);
560 * SCSP client server interface finite state machine action 10
562 * CSU Request from DCS--pass it to the server as a Cache Update
566 * dcsp pointer to DCS control block
567 * msg pointer to message from DCS
568 * cmsg pointer to message from server
572 * else errno describing error
576 scsp_client_act_10(dcsp, msg, cmsg)
583 Scsp_atmarp_csa *acp;
587 * Get memory for a Cache Update Ind
589 cuip = (Scsp_if_msg *)UM_ALLOC(sizeof(Scsp_if_msg));
591 scsp_mem_err("scsp_client_act_10: sizeof(Scsp_if_msg)");
595 * Loop through CSAs in message
597 for (csap = msg->sc_csu_msg->csu_csa_rec; csap;
599 acp = csap->atmarp_data;
604 * Fill out the Cache Update Ind
606 UM_ZERO(cuip, sizeof(Scsp_if_msg));
607 cuip->si_type = SCSP_UPDATE_IND;
608 cuip->si_proto = dcsp->sd_server->ss_pid;
609 cuip->si_tok = (u_long)dcsp;
610 switch(dcsp->sd_server->ss_pid) {
611 case SCSP_PROTO_ATMARP:
612 cuip->si_len = sizeof(Scsp_if_msg_hdr) +
613 sizeof(Scsp_atmarp_msg);
614 cuip->si_atmarp.sa_state = acp->sa_state;
615 cuip->si_atmarp.sa_cpa = acp->sa_spa;
616 cuip->si_atmarp.sa_cha = acp->sa_sha;
617 cuip->si_atmarp.sa_csa = acp->sa_ssa;
618 cuip->si_atmarp.sa_key = csap->key;
619 cuip->si_atmarp.sa_oid = csap->oid;
620 cuip->si_atmarp.sa_seq = csap->seq;
622 case SCSP_PROTO_NHRP:
624 * Not implemented yet
630 * Send the Cache Update Ind to the server
632 rc = scsp_if_sock_write(dcsp->sd_server->ss_sock, cuip);