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.4 2003/11/15 20:33:43 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(Scsp_dcs
*dcsp
, int event
, Scsp_msg
*msg
, Scsp_if_msg
*cmsg
)
141 int action
, rc
, state
;
144 * Select an action from the state table
146 state
= dcsp
->sd_client_state
;
147 action
= client_state_table
[event
][state
];
148 if (scsp_trace_mode
& SCSP_TRACE_CFSM
) {
149 scsp_trace("Server I/F FSM: state=%d, event=%d, action=%d\n",
150 state
, event
, action
);
152 if (action
>= SCSP_CIFSM_ACTION_CNT
|| action
<= 0) {
153 scsp_log(LOG_ERR
, "Server I/F FSM--invalid action %d; state=%d, event=%d",
154 action
, dcsp
->sd_client_state
, event
);
159 * Perform the selected action
161 rc
= scsp_action_vector
[action
](dcsp
, msg
, cmsg
);
168 * SCSP client server interface finite state machine action 0
169 * Unexpected action -- log an error message
172 * dcsp pointer to DCS control block
173 * msg pointer to message from DCS (ignored)
174 * cmsg pointer to message from server (ignored)
177 * EOPNOTSUPP always returns EOPNOTSUPP
181 scsp_client_act_00(Scsp_dcs
*dcsp
, Scsp_msg
*msg
, Scsp_if_msg
*cmsg
)
183 scsp_log(LOG_ERR
, "Server I/F FSM error--unexpected action, state=%d",
184 dcsp
->sd_client_state
);
190 * SCSP client server interface finite state machine action 1
195 * dcsp pointer to DCS control block
196 * msg pointer to message from DCS
197 * cmsg pointer to message from server
204 scsp_client_act_01(Scsp_dcs
*dcsp
, Scsp_msg
*msg
, Scsp_if_msg
*cmsg
)
211 * SCSP client server interface finite state machine action 2
213 * CA FSM went to Cache Summarize state--go to Summarize
216 * dcsp pointer to DCS control block
217 * msg pointer to message from DCS
218 * cmsg pointer to message from server
222 * else errno describing error
226 scsp_client_act_02(Scsp_dcs
*dcsp
, Scsp_msg
*msg
, Scsp_if_msg
*cmsg
)
231 dcsp
->sd_client_state
= SCSP_CIFSM_SUM
;
238 * SCSP client server interface finite state machine action 3
240 * CA FSM went down--clean up and go to Null
243 * dcsp pointer to DCS control block
244 * msg pointer to message from DCS
245 * cmsg pointer to message from server
249 * else errno describing error
253 scsp_client_act_03(Scsp_dcs
*dcsp
, Scsp_msg
*msg
, Scsp_if_msg
*cmsg
)
258 dcsp
->sd_client_state
= SCSP_CIFSM_NULL
;
265 * SCSP client server interface finite state machine action 4
267 * CA FSM went to Update Cache state--go to Update state
270 * dcsp pointer to DCS control block
271 * msg pointer to message from DCS
272 * cmsg pointer to message from server
276 * else errno describing error
280 scsp_client_act_04(Scsp_dcs
*dcsp
, Scsp_msg
*msg
, Scsp_if_msg
*cmsg
)
285 dcsp
->sd_client_state
= SCSP_CIFSM_UPD
;
292 * SCSP client server interface finite state machine action 5
294 * The CA FSM went to Cache Summarize state from Summarize,
295 * Update, or Aligned, implying that the CA FSM went down and came
296 * back up--copy the server's cache to the DCSs CSAS list and go to
300 * dcsp pointer to DCS control block
301 * msg pointer to message from DCS
302 * cmsg pointer to message from server
306 * else errno describing error
310 scsp_client_act_05(Scsp_dcs
*dcsp
, Scsp_msg
*msg
, Scsp_if_msg
*cmsg
)
313 Scsp_cse
*csep
, *ncsep
;
316 * Copy the cache summmary to the CSAS list
318 for (i
= 0; i
< SCSP_HASHSZ
; i
++) {
319 for (csep
= dcsp
->sd_server
->ss_cache
[i
]; csep
;
320 csep
= csep
->sc_next
) {
321 ncsep
= scsp_dup_cse(csep
);
322 LINK2TAIL(ncsep
, Scsp_cse
, dcsp
->sd_ca_csas
,
330 dcsp
->sd_client_state
= SCSP_CIFSM_SUM
;
337 * SCSP client server interface finite state machine action 6
339 * CA FSM went to Aligned state--go to Aligned
342 * dcsp pointer to DCS control block
343 * msg pointer to message from DCS
344 * cmsg pointer to message from server
348 * else errno describing error
352 scsp_client_act_06(Scsp_dcs
*dcsp
, Scsp_msg
*msg
, Scsp_if_msg
*cmsg
)
357 dcsp
->sd_client_state
= SCSP_CIFSM_ALIGN
;
364 * SCSP client server interface finite state machine action 7
366 * We received a Solicit Rsp or Update Req from the server--pass it
370 * dcsp pointer to DCS control block
371 * msg pointer to message from DCS
372 * cmsg pointer to message from server
376 * else errno describing error
380 scsp_client_act_07(Scsp_dcs
*dcsp
, Scsp_msg
*msg
, Scsp_if_msg
*cmsg
)
384 Scsp_atmarp_csa
*acp
;
387 * Allocate memory for a CSA record
389 csap
= (Scsp_csa
*)UM_ALLOC(sizeof(Scsp_csa
));
391 scsp_mem_err("scsp_client_act_07: sizeof(Scsp_csa)");
393 acp
= (Scsp_atmarp_csa
*)UM_ALLOC(sizeof(Scsp_atmarp_csa
));
395 scsp_mem_err("scsp_client_act_07: sizeof(Scsp_atmarp_csa)");
397 UM_ZERO(csap
, sizeof(Scsp_csa
));
398 UM_ZERO(acp
, sizeof(Scsp_atmarp_csa
));
401 * Build a CSA record from the server's message
403 csap
->hops
= dcsp
->sd_hops
;
404 csap
->null
= (cmsg
->si_atmarp
.sa_state
== SCSP_ASTATE_DEL
) ||
405 (cmsg
->si_type
== SCSP_SOLICIT_RSP
&&
406 cmsg
->si_rc
!= SCSP_RSP_OK
);
407 csap
->seq
= cmsg
->si_atmarp
.sa_seq
;
408 csap
->key
= cmsg
->si_atmarp
.sa_key
;
409 csap
->oid
= cmsg
->si_atmarp
.sa_oid
;
410 csap
->atmarp_data
= acp
;
411 acp
->sa_state
= cmsg
->si_atmarp
.sa_state
;
412 acp
->sa_sha
= cmsg
->si_atmarp
.sa_cha
;
413 acp
->sa_ssa
= cmsg
->si_atmarp
.sa_csa
;
414 acp
->sa_spa
= cmsg
->si_atmarp
.sa_cpa
;
415 acp
->sa_tpa
= cmsg
->si_atmarp
.sa_cpa
;
420 rc
= scsp_cafsm(dcsp
, SCSP_CAFSM_CACHE_UPD
, (void *)csap
);
427 * SCSP client server interface finite state machine action 8
429 * Update Rsp from server--pass the update to the CA FSM.
432 * dcsp pointer to DCS control block
433 * msg pointer to message from DCS
434 * cmsg pointer to message from server
438 * else errno describing error
442 scsp_client_act_08(Scsp_dcs
*dcsp
, Scsp_msg
*msg
, Scsp_if_msg
*cmsg
)
447 * Pass the response to the CA FSM
449 switch (dcsp
->sd_server
->ss_pid
) {
450 case SCSP_PROTO_ATMARP
:
451 rc
= scsp_cafsm(dcsp
, SCSP_CAFSM_CACHE_RSP
, cmsg
);
454 rc
= EPROTONOSUPPORT
;
462 * SCSP client server interface finite state machine action 9
464 * CSU Solicit from DCS--pass Solicit Ind to server
467 * dcsp pointer to DCS control block
468 * msg pointer to message from DCS
469 * cmsg pointer to message from server
473 * else errno describing error
477 scsp_client_act_09(Scsp_dcs
*dcsp
, Scsp_msg
*msg
, Scsp_if_msg
*cmsg
)
484 * Get memory for a Solicit Ind
486 csip
= (Scsp_if_msg
*)UM_ALLOC(sizeof(Scsp_if_msg
));
488 scsp_mem_err("scsp_client_act_09: sizeof(Scsp_if_msg)");
492 * Loop through list of CSAs
494 for (csap
= msg
->sc_csu_msg
->csu_csa_rec
; csap
;
497 * Fill out the Solicit Indication
499 UM_ZERO(csip
, sizeof(Scsp_if_msg
));
500 csip
->si_type
= SCSP_SOLICIT_IND
;
501 csip
->si_proto
= dcsp
->sd_server
->ss_pid
;
502 csip
->si_tok
= (u_long
)dcsp
;
503 csip
->si_len
= sizeof(Scsp_if_msg_hdr
) +
504 sizeof(Scsp_sum_msg
);
505 csip
->si_sum
.ss_hops
= csap
->hops
;
506 csip
->si_sum
.ss_null
= csap
->null
;
507 csip
->si_sum
.ss_seq
= csap
->seq
;
508 csip
->si_sum
.ss_key
= csap
->key
;
509 csip
->si_sum
.ss_oid
= csap
->oid
;
512 * Send the Solicit Ind to the server
514 rc
= scsp_if_sock_write(dcsp
->sd_server
->ss_sock
, csip
);
526 * SCSP client server interface finite state machine action 10
528 * CSU Request from DCS--pass it to the server as a Cache Update
532 * dcsp pointer to DCS control block
533 * msg pointer to message from DCS
534 * cmsg pointer to message from server
538 * else errno describing error
542 scsp_client_act_10(Scsp_dcs
*dcsp
, Scsp_msg
*msg
, Scsp_if_msg
*cmsg
)
546 Scsp_atmarp_csa
*acp
;
550 * Get memory for a Cache Update Ind
552 cuip
= (Scsp_if_msg
*)UM_ALLOC(sizeof(Scsp_if_msg
));
554 scsp_mem_err("scsp_client_act_10: sizeof(Scsp_if_msg)");
558 * Loop through CSAs in message
560 for (csap
= msg
->sc_csu_msg
->csu_csa_rec
; csap
;
562 acp
= csap
->atmarp_data
;
567 * Fill out the Cache Update Ind
569 UM_ZERO(cuip
, sizeof(Scsp_if_msg
));
570 cuip
->si_type
= SCSP_UPDATE_IND
;
571 cuip
->si_proto
= dcsp
->sd_server
->ss_pid
;
572 cuip
->si_tok
= (u_long
)dcsp
;
573 switch(dcsp
->sd_server
->ss_pid
) {
574 case SCSP_PROTO_ATMARP
:
575 cuip
->si_len
= sizeof(Scsp_if_msg_hdr
) +
576 sizeof(Scsp_atmarp_msg
);
577 cuip
->si_atmarp
.sa_state
= acp
->sa_state
;
578 cuip
->si_atmarp
.sa_cpa
= acp
->sa_spa
;
579 cuip
->si_atmarp
.sa_cha
= acp
->sa_sha
;
580 cuip
->si_atmarp
.sa_csa
= acp
->sa_ssa
;
581 cuip
->si_atmarp
.sa_key
= csap
->key
;
582 cuip
->si_atmarp
.sa_oid
= csap
->oid
;
583 cuip
->si_atmarp
.sa_seq
= csap
->seq
;
585 case SCSP_PROTO_NHRP
:
587 * Not implemented yet
593 * Send the Cache Update Ind to the server
595 rc
= scsp_if_sock_write(dcsp
->sd_server
->ss_sock
, cuip
);