]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - 6/usr.sbin/atm/scspd/scsp_if.c
Clone Kip's Xen on stable/6 tree so that I can work on improving FreeBSD/amd64
[FreeBSD/FreeBSD.git] / 6 / usr.sbin / atm / scspd / scsp_if.c
1 /*
2  *
3  * ===================================
4  * HARP  |  Host ATM Research Platform
5  * ===================================
6  *
7  *
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.
12  *
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.
20  *
21  * Copyright 1994-1998 Network Computing Services, Inc.
22  *
23  * Copies of this Software may be made, however, the above copyright
24  * notice must be reproduced on all copies.
25  *
26  *      @(#) $FreeBSD$
27  *
28  */
29
30
31 /*
32  * Server Cache Synchronization Protocol (SCSP) Support
33  * ----------------------------------------------------
34  *
35  * Interface to client server protocol
36  *
37  */
38
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/socket.h>
42 #include <net/if.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>
51   
52 #include <errno.h>
53 #include <libatm.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include <syslog.h>
58 #include <unistd.h>
59
60 #include "scsp_msg.h"
61 #include "scsp_if.h"
62 #include "scsp_var.h"
63
64 #ifndef lint
65 __RCSID("@(#) $FreeBSD$");
66 #endif
67
68
69 /*
70  * SCSP client server interface FSM actions
71  */
72 #define SCSP_CIFSM_ACTION_CNT   11
73 int     scsp_client_act_00(Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
74 int     scsp_client_act_01(Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
75 int     scsp_client_act_02(Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
76 int     scsp_client_act_03(Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
77 int     scsp_client_act_04(Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
78 int     scsp_client_act_05(Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
79 int     scsp_client_act_06(Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
80 int     scsp_client_act_07(Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
81 int     scsp_client_act_08(Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
82 int     scsp_client_act_09(Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
83 int     scsp_client_act_10(Scsp_dcs *, Scsp_msg *, Scsp_if_msg *);
84
85 static int (*scsp_action_vector[SCSP_CIFSM_ACTION_CNT])() = {
86         scsp_client_act_00,
87         scsp_client_act_01,
88         scsp_client_act_02,
89         scsp_client_act_03,
90         scsp_client_act_04,
91         scsp_client_act_05,
92         scsp_client_act_06,
93         scsp_client_act_07,
94         scsp_client_act_08,
95         scsp_client_act_09,
96         scsp_client_act_10
97 };
98
99
100 /*
101  * Client server interface FSM state table
102  */
103 static int client_state_table[SCSP_CIFSM_EVENT_CNT][SCSP_CIFSM_STATE_CNT] = {
104         /* 0   1   2   3  */
105         {  1,  3,  3,  3 },     /*  0 */
106         {  2,  5,  5,  5 },     /*  1 */
107         {  0,  4,  0,  0 },     /*  2 */
108         {  0,  6,  6,  1 },     /*  3 */
109         {  1,  0,  7,  7 },     /*  4 */
110         {  7,  7,  7,  7 },     /*  5 */
111         {  1,  1,  8,  8 },     /*  6 */
112         {  0,  0, 10, 10 },     /*  7 */
113         {  0,  0,  1,  1 },     /*  8 */
114         {  0,  0,  9,  9 }      /*  9 */
115 };
116
117
118 /*
119  * SCSP client server interface finite state machine
120  *
121  * Arguments:
122  *      ssp     pointer to server control block
123  *      event   the event which has occurred
124  *      msg     pointer to message from DCS, if there is one
125  *      cmsg    pointer to message from server, if there is one
126  *
127  * Returns:
128  *      0       success
129  *      errno   error encountered
130  *
131  */
132 int
133 scsp_cfsm(dcsp, event, msg, cmsg)
134         Scsp_dcs        *dcsp;
135         int             event;
136         Scsp_msg        *msg;
137         Scsp_if_msg     *cmsg;
138 {
139         int     action, rc, state;
140
141         /*
142          * Select an action from the state table
143          */
144         state = dcsp->sd_client_state;
145         action = client_state_table[event][state];
146         if (scsp_trace_mode & SCSP_TRACE_CFSM) {
147                 scsp_trace("Server I/F FSM: state=%d, event=%d, action=%d\n",
148                                 state, event, action);
149         }
150         if (action >= SCSP_CIFSM_ACTION_CNT || action <= 0) {
151                 scsp_log(LOG_ERR, "Server I/F FSM--invalid action %d; state=%d, event=%d",
152                                 action, dcsp->sd_client_state, event);
153                 exit(1);
154         }
155
156         /*
157          * Perform the selected action
158          */
159         rc = scsp_action_vector[action](dcsp, msg, cmsg);
160
161         return(rc);
162 }
163
164
165 /*
166  * SCSP client server interface finite state machine action 0
167  * Unexpected action -- log an error message
168  *
169  * Arguments:
170  *      dcsp    pointer to DCS control block
171  *      msg     pointer to message from DCS (ignored)
172  *      cmsg    pointer to message from server (ignored)
173  *
174  * Returns:
175  *      EOPNOTSUPP      always returns EOPNOTSUPP
176  *
177  */
178 int
179 scsp_client_act_00(dcsp, msg, cmsg)
180         Scsp_dcs        *dcsp;
181         Scsp_msg        *msg;
182         Scsp_if_msg     *cmsg;
183 {
184         scsp_log(LOG_ERR, "Server I/F FSM error--unexpected action, state=%d",
185                         dcsp->sd_client_state);
186         return(EOPNOTSUPP);
187 }
188
189
190 /*
191  * SCSP client server interface finite state machine action 1
192  *
193  * Ignore an event
194  *
195  * Arguments:
196  *      dcsp    pointer to DCS control block
197  *      msg     pointer to message from DCS
198  *      cmsg    pointer to message from server
199  *
200  * Returns:
201  *      0       always returns 0
202  *
203  */
204 int
205 scsp_client_act_01(dcsp, msg, cmsg)
206         Scsp_dcs        *dcsp;
207         Scsp_msg        *msg;
208         Scsp_if_msg     *cmsg;
209 {
210         return(0);
211 }
212
213
214 /*
215  * SCSP client server interface finite state machine action 2
216  *
217  * CA FSM went to Cache Summarize state--go to Summarize
218  *
219  * Arguments:
220  *      dcsp    pointer to DCS control block
221  *      msg     pointer to message from DCS
222  *      cmsg    pointer to message from server
223  *
224  * Returns:
225  *      0       success
226  *      else    errno describing error
227  *
228  */
229 int
230 scsp_client_act_02(dcsp, msg, cmsg)
231         Scsp_dcs        *dcsp;
232         Scsp_msg        *msg;
233         Scsp_if_msg     *cmsg;
234 {
235         /*
236          * Set the new state
237          */
238         dcsp->sd_client_state = SCSP_CIFSM_SUM;
239
240         return(0);
241 }
242
243
244 /*
245  * SCSP client server interface finite state machine action 3
246  *
247  * CA FSM went down--clean up and go to Null
248  *
249  * Arguments:
250  *      dcsp    pointer to DCS control block
251  *      msg     pointer to message from DCS
252  *      cmsg    pointer to message from server
253  *
254  * Returns:
255  *      0       success
256  *      else    errno describing error
257  *
258  */
259 int
260 scsp_client_act_03(dcsp, msg, cmsg)
261         Scsp_dcs        *dcsp;
262         Scsp_msg        *msg;
263         Scsp_if_msg     *cmsg;
264 {
265         /*
266          * Set the new state
267          */
268         dcsp->sd_client_state = SCSP_CIFSM_NULL;
269
270         return(0);
271 }
272
273
274 /*
275  * SCSP client server interface finite state machine action 4
276  *
277  * CA FSM went to Update Cache state--go to Update state
278  *
279  * Arguments:
280  *      dcsp    pointer to DCS control block
281  *      msg     pointer to message from DCS
282  *      cmsg    pointer to message from server
283  *
284  * Returns:
285  *      0       success
286  *      else    errno describing error
287  *
288  */
289 int
290 scsp_client_act_04(dcsp, msg, cmsg)
291         Scsp_dcs        *dcsp;
292         Scsp_msg        *msg;
293         Scsp_if_msg     *cmsg;
294 {
295         /*
296          * Set the new state
297          */
298         dcsp->sd_client_state = SCSP_CIFSM_UPD;
299
300         return(0);
301 }
302
303
304 /*
305  * SCSP client server interface finite state machine action 5
306  *
307  * The CA FSM went to Cache Summarize state from Summarize,
308  * Update, or Aligned, implying that the CA FSM went down and came
309  * back up--copy the server's cache to the DCSs CSAS list and go to
310  * Summarize state
311  *
312  * Arguments:
313  *      dcsp    pointer to DCS control block
314  *      msg     pointer to message from DCS
315  *      cmsg    pointer to message from server
316  *
317  * Returns:
318  *      0       success
319  *      else    errno describing error
320  *
321  */
322 int
323 scsp_client_act_05(dcsp, msg, cmsg)
324         Scsp_dcs        *dcsp;
325         Scsp_msg        *msg;
326         Scsp_if_msg     *cmsg;
327 {
328         int             i;
329         Scsp_cse        *csep, *ncsep;
330
331         /*
332          * Copy the cache summmary to the CSAS list
333          */
334         for (i = 0; i < SCSP_HASHSZ; i++) {
335                 for (csep = dcsp->sd_server->ss_cache[i]; csep;
336                                 csep = csep->sc_next) {
337                         ncsep = scsp_dup_cse(csep);
338                         LINK2TAIL(ncsep, Scsp_cse, dcsp->sd_ca_csas,
339                                         sc_next);
340                 }
341         }
342
343         /*
344          * Set the new state
345          */
346         dcsp->sd_client_state = SCSP_CIFSM_SUM;
347
348         return(0);
349 }
350
351
352 /*
353  * SCSP client server interface finite state machine action 6
354  *
355  * CA FSM went to Aligned state--go to Aligned
356  *
357  * Arguments:
358  *      dcsp    pointer to DCS control block
359  *      msg     pointer to message from DCS
360  *      cmsg    pointer to message from server
361  *
362  * Returns:
363  *      0       success
364  *      else    errno describing error
365  *
366  */
367 int
368 scsp_client_act_06(dcsp, msg, cmsg)
369         Scsp_dcs        *dcsp;
370         Scsp_msg        *msg;
371         Scsp_if_msg     *cmsg;
372 {
373         /*
374          * Set the new state
375          */
376         dcsp->sd_client_state = SCSP_CIFSM_ALIGN;
377
378         return(0);
379 }
380
381
382 /*
383  * SCSP client server interface finite state machine action 7
384  *
385  * We received a Solicit Rsp or Update Req from the server--pass it
386  * to the CA FSM
387  *
388  * Arguments:
389  *      dcsp    pointer to DCS control block
390  *      msg     pointer to message from DCS
391  *      cmsg    pointer to message from server
392  *
393  * Returns:
394  *      0       success
395  *      else    errno describing error
396  *
397  */
398 int
399 scsp_client_act_07(dcsp, msg, cmsg)
400         Scsp_dcs        *dcsp;
401         Scsp_msg        *msg;
402         Scsp_if_msg     *cmsg;
403 {
404         int             rc;
405         Scsp_csa        *csap;
406         Scsp_atmarp_csa *acp;
407
408         /*
409          * Allocate memory for a CSA record
410          */
411         csap = calloc(1, sizeof(Scsp_csa));
412         if (csap == NULL)
413                 scsp_mem_err("scsp_client_act_07: sizeof(Scsp_csa)");
414         acp = calloc(1, sizeof(Scsp_atmarp_csa));
415         if (acp == NULL)
416                 scsp_mem_err("scsp_client_act_07: sizeof(Scsp_atmarp_csa)");
417
418         /*
419          * Build a CSA record from the server's message
420          */
421         csap->hops = dcsp->sd_hops;
422         csap->null = (cmsg->si_atmarp.sa_state == SCSP_ASTATE_DEL) ||
423                         (cmsg->si_type == SCSP_SOLICIT_RSP &&
424                         cmsg->si_rc != SCSP_RSP_OK);
425         csap->seq = cmsg->si_atmarp.sa_seq;
426         csap->key = cmsg->si_atmarp.sa_key;
427         csap->oid = cmsg->si_atmarp.sa_oid;
428         csap->atmarp_data = acp;
429         acp->sa_state = cmsg->si_atmarp.sa_state;
430         acp->sa_sha = cmsg->si_atmarp.sa_cha;
431         acp->sa_ssa = cmsg->si_atmarp.sa_csa;
432         acp->sa_spa = cmsg->si_atmarp.sa_cpa;
433         acp->sa_tpa = cmsg->si_atmarp.sa_cpa;
434
435         /*
436          * Call the CA FSM
437          */
438         rc = scsp_cafsm(dcsp, SCSP_CAFSM_CACHE_UPD, (void *)csap);
439
440         return(rc);
441 }
442
443
444 /*
445  * SCSP client server interface finite state machine action 8
446  *
447  * Update Rsp from server--pass the update to the CA FSM.
448  *
449  * Arguments:
450  *      dcsp    pointer to DCS control block
451  *      msg     pointer to message from DCS
452  *      cmsg    pointer to message from server
453  *
454  * Returns:
455  *      0       success
456  *      else    errno describing error
457  *
458  */
459 int
460 scsp_client_act_08(dcsp, msg, cmsg)
461         Scsp_dcs        *dcsp;
462         Scsp_msg        *msg;
463         Scsp_if_msg     *cmsg;
464 {
465         int             rc;
466
467         /* 
468          * Pass the response to the CA FSM
469          */
470         switch (dcsp->sd_server->ss_pid) {
471         case SCSP_PROTO_ATMARP:
472                 rc = scsp_cafsm(dcsp, SCSP_CAFSM_CACHE_RSP, cmsg);
473                 break;
474         default:
475                 rc = EPROTONOSUPPORT;
476         }
477
478         return(rc);
479 }
480
481
482 /*
483  * SCSP client server interface finite state machine action 9
484  *
485  * CSU Solicit from DCS--pass Solicit Ind to server
486  *
487  * Arguments:
488  *      dcsp    pointer to DCS control block
489  *      msg     pointer to message from DCS
490  *      cmsg    pointer to message from server
491  *
492  * Returns:
493  *      0       success
494  *      else    errno describing error
495  *
496  */
497 int
498 scsp_client_act_09(dcsp, msg, cmsg)
499         Scsp_dcs        *dcsp;
500         Scsp_msg        *msg;
501         Scsp_if_msg     *cmsg;
502 {
503         int             rc, rrc = 0;
504         Scsp_csa        *csap;
505         Scsp_if_msg     *csip;
506
507         /*
508          * Get memory for a Solicit Ind
509          */
510         csip = calloc(1, sizeof(Scsp_if_msg));
511         if (csip == NULL)
512                 scsp_mem_err("scsp_client_act_09: sizeof(Scsp_if_msg)");
513
514         /*
515          * Loop through list of CSAs
516          */
517         for (csap = msg->sc_csu_msg->csu_csa_rec; csap;
518                         csap = csap->next) {
519                 /*
520                  * Fill out the Solicit Indication
521                  */
522                 bzero(csip, sizeof(Scsp_if_msg));
523                 csip->si_type = SCSP_SOLICIT_IND;
524                 csip->si_proto = dcsp->sd_server->ss_pid;
525                 csip->si_tok = (u_long)dcsp;
526                 csip->si_len = sizeof(Scsp_if_msg_hdr) +
527                                 sizeof(Scsp_sum_msg);
528                 csip->si_sum.ss_hops = csap->hops;
529                 csip->si_sum.ss_null = csap->null;
530                 csip->si_sum.ss_seq = csap->seq;
531                 csip->si_sum.ss_key = csap->key;
532                 csip->si_sum.ss_oid = csap->oid;
533
534                 /*
535                  * Send the Solicit Ind to the server
536                  */
537                 rc = scsp_if_sock_write(dcsp->sd_server->ss_sock, csip);
538                 if (rc) {
539                         rrc = rc;
540                 }
541         }
542         free(csip);
543         return(rrc);
544 }
545
546
547 /*
548  * SCSP client server interface finite state machine action 10
549  *
550  * CSU Request from DCS--pass it to the server as a Cache Update
551  * Indication
552  *
553  * Arguments:
554  *      dcsp    pointer to DCS control block
555  *      msg     pointer to message from DCS
556  *      cmsg    pointer to message from server
557  *
558  * Returns:
559  *      0       success
560  *      else    errno describing error
561  *
562  */
563 int
564 scsp_client_act_10(dcsp, msg, cmsg)
565         Scsp_dcs        *dcsp;
566         Scsp_msg        *msg;
567         Scsp_if_msg     *cmsg;
568 {
569         int             rc, rrc = 0;
570         Scsp_csa        *csap;
571         Scsp_atmarp_csa *acp;
572         Scsp_if_msg     *cuip;
573
574         /*
575          * Get memory for a Cache Update Ind
576          */
577         cuip = malloc(sizeof(Scsp_if_msg));
578         if (cuip == NULL)
579                 scsp_mem_err("scsp_client_act_10: sizeof(Scsp_if_msg)");
580
581         /*
582          * Loop through CSAs in message
583          */
584         for (csap = msg->sc_csu_msg->csu_csa_rec; csap;
585                         csap = csap->next) {
586                 acp = csap->atmarp_data;
587                 if (!acp)
588                         continue;
589
590                 /*
591                  * Fill out the Cache Update Ind
592                  */
593                 bzero(cuip, sizeof(Scsp_if_msg));
594                 cuip->si_type = SCSP_UPDATE_IND;
595                 cuip->si_proto = dcsp->sd_server->ss_pid;
596                 cuip->si_tok = (u_long)dcsp;
597                 switch(dcsp->sd_server->ss_pid) {
598                 case SCSP_PROTO_ATMARP:
599                         cuip->si_len = sizeof(Scsp_if_msg_hdr) +
600                                         sizeof(Scsp_atmarp_msg);
601                         cuip->si_atmarp.sa_state = acp->sa_state;
602                         cuip->si_atmarp.sa_cpa = acp->sa_spa;
603                         cuip->si_atmarp.sa_cha = acp->sa_sha;
604                         cuip->si_atmarp.sa_csa = acp->sa_ssa;
605                         cuip->si_atmarp.sa_key = csap->key;
606                         cuip->si_atmarp.sa_oid = csap->oid;
607                         cuip->si_atmarp.sa_seq = csap->seq;
608                         break;
609                 case SCSP_PROTO_NHRP:
610                         /*
611                          * Not implemented yet
612                          */
613                         break;
614                 }
615
616                 /*
617                  * Send the Cache Update Ind to the server
618                  */
619                 rc = scsp_if_sock_write(dcsp->sd_server->ss_sock, cuip);
620                 if (rc) {
621                         rrc = rc;
622                 }
623         }
624         free(cuip);
625         return(rrc);
626 }