Remove __P macros from src/usr.bin and src/usr.sbin.
[dragonfly.git] / 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: 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 $
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 /*
65  * SCSP client server interface FSM actions
66  */
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 *);
90
91 static int (*scsp_action_vector[SCSP_CIFSM_ACTION_CNT])() = {
92         scsp_client_act_00,
93         scsp_client_act_01,
94         scsp_client_act_02,
95         scsp_client_act_03,
96         scsp_client_act_04,
97         scsp_client_act_05,
98         scsp_client_act_06,
99         scsp_client_act_07,
100         scsp_client_act_08,
101         scsp_client_act_09,
102         scsp_client_act_10
103 };
104
105
106 /*
107  * Client server interface FSM state table
108  */
109 static int client_state_table[SCSP_CIFSM_EVENT_CNT][SCSP_CIFSM_STATE_CNT] = {
110         /* 0   1   2   3  */
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 */
121 };
122
123
124 /*
125  * SCSP client server interface finite state machine
126  *
127  * Arguments:
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
132  *
133  * Returns:
134  *      0       success
135  *      errno   error encountered
136  *
137  */
138 int
139 scsp_cfsm(dcsp, event, msg, cmsg)
140         Scsp_dcs        *dcsp;
141         int             event;
142         Scsp_msg        *msg;
143         Scsp_if_msg     *cmsg;
144 {
145         int     action, rc, state;
146
147         /*
148          * Select an action from the state table
149          */
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);
155         }
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);
159                 exit(1);
160         }
161
162         /*
163          * Perform the selected action
164          */
165         rc = scsp_action_vector[action](dcsp, msg, cmsg);
166
167         return(rc);
168 }
169
170
171 /*
172  * SCSP client server interface finite state machine action 0
173  * Unexpected action -- log an error message
174  *
175  * Arguments:
176  *      dcsp    pointer to DCS control block
177  *      msg     pointer to message from DCS (ignored)
178  *      cmsg    pointer to message from server (ignored)
179  *
180  * Returns:
181  *      EOPNOTSUPP      always returns EOPNOTSUPP
182  *
183  */
184 int
185 scsp_client_act_00(dcsp, msg, cmsg)
186         Scsp_dcs        *dcsp;
187         Scsp_msg        *msg;
188         Scsp_if_msg     *cmsg;
189 {
190         scsp_log(LOG_ERR, "Server I/F FSM error--unexpected action, state=%d",
191                         dcsp->sd_client_state);
192         return(EOPNOTSUPP);
193 }
194
195
196 /*
197  * SCSP client server interface finite state machine action 1
198  *
199  * Ignore an event
200  *
201  * Arguments:
202  *      dcsp    pointer to DCS control block
203  *      msg     pointer to message from DCS
204  *      cmsg    pointer to message from server
205  *
206  * Returns:
207  *      0       always returns 0
208  *
209  */
210 int
211 scsp_client_act_01(dcsp, msg, cmsg)
212         Scsp_dcs        *dcsp;
213         Scsp_msg        *msg;
214         Scsp_if_msg     *cmsg;
215 {
216         return(0);
217 }
218
219
220 /*
221  * SCSP client server interface finite state machine action 2
222  *
223  * CA FSM went to Cache Summarize state--go to Summarize
224  *
225  * Arguments:
226  *      dcsp    pointer to DCS control block
227  *      msg     pointer to message from DCS
228  *      cmsg    pointer to message from server
229  *
230  * Returns:
231  *      0       success
232  *      else    errno describing error
233  *
234  */
235 int
236 scsp_client_act_02(dcsp, msg, cmsg)
237         Scsp_dcs        *dcsp;
238         Scsp_msg        *msg;
239         Scsp_if_msg     *cmsg;
240 {
241         /*
242          * Set the new state
243          */
244         dcsp->sd_client_state = SCSP_CIFSM_SUM;
245
246         return(0);
247 }
248
249
250 /*
251  * SCSP client server interface finite state machine action 3
252  *
253  * CA FSM went down--clean up and go to Null
254  *
255  * Arguments:
256  *      dcsp    pointer to DCS control block
257  *      msg     pointer to message from DCS
258  *      cmsg    pointer to message from server
259  *
260  * Returns:
261  *      0       success
262  *      else    errno describing error
263  *
264  */
265 int
266 scsp_client_act_03(dcsp, msg, cmsg)
267         Scsp_dcs        *dcsp;
268         Scsp_msg        *msg;
269         Scsp_if_msg     *cmsg;
270 {
271         /*
272          * Set the new state
273          */
274         dcsp->sd_client_state = SCSP_CIFSM_NULL;
275
276         return(0);
277 }
278
279
280 /*
281  * SCSP client server interface finite state machine action 4
282  *
283  * CA FSM went to Update Cache state--go to Update state
284  *
285  * Arguments:
286  *      dcsp    pointer to DCS control block
287  *      msg     pointer to message from DCS
288  *      cmsg    pointer to message from server
289  *
290  * Returns:
291  *      0       success
292  *      else    errno describing error
293  *
294  */
295 int
296 scsp_client_act_04(dcsp, msg, cmsg)
297         Scsp_dcs        *dcsp;
298         Scsp_msg        *msg;
299         Scsp_if_msg     *cmsg;
300 {
301         /*
302          * Set the new state
303          */
304         dcsp->sd_client_state = SCSP_CIFSM_UPD;
305
306         return(0);
307 }
308
309
310 /*
311  * SCSP client server interface finite state machine action 5
312  *
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
316  * Summarize state
317  *
318  * Arguments:
319  *      dcsp    pointer to DCS control block
320  *      msg     pointer to message from DCS
321  *      cmsg    pointer to message from server
322  *
323  * Returns:
324  *      0       success
325  *      else    errno describing error
326  *
327  */
328 int
329 scsp_client_act_05(dcsp, msg, cmsg)
330         Scsp_dcs        *dcsp;
331         Scsp_msg        *msg;
332         Scsp_if_msg     *cmsg;
333 {
334         int             i;
335         Scsp_cse        *csep, *ncsep;
336
337         /*
338          * Copy the cache summmary to the CSAS list
339          */
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,
345                                         sc_next);
346                 }
347         }
348
349         /*
350          * Set the new state
351          */
352         dcsp->sd_client_state = SCSP_CIFSM_SUM;
353
354         return(0);
355 }
356
357
358 /*
359  * SCSP client server interface finite state machine action 6
360  *
361  * CA FSM went to Aligned state--go to Aligned
362  *
363  * Arguments:
364  *      dcsp    pointer to DCS control block
365  *      msg     pointer to message from DCS
366  *      cmsg    pointer to message from server
367  *
368  * Returns:
369  *      0       success
370  *      else    errno describing error
371  *
372  */
373 int
374 scsp_client_act_06(dcsp, msg, cmsg)
375         Scsp_dcs        *dcsp;
376         Scsp_msg        *msg;
377         Scsp_if_msg     *cmsg;
378 {
379         /*
380          * Set the new state
381          */
382         dcsp->sd_client_state = SCSP_CIFSM_ALIGN;
383
384         return(0);
385 }
386
387
388 /*
389  * SCSP client server interface finite state machine action 7
390  *
391  * We received a Solicit Rsp or Update Req from the server--pass it
392  * to the CA FSM
393  *
394  * Arguments:
395  *      dcsp    pointer to DCS control block
396  *      msg     pointer to message from DCS
397  *      cmsg    pointer to message from server
398  *
399  * Returns:
400  *      0       success
401  *      else    errno describing error
402  *
403  */
404 int
405 scsp_client_act_07(dcsp, msg, cmsg)
406         Scsp_dcs        *dcsp;
407         Scsp_msg        *msg;
408         Scsp_if_msg     *cmsg;
409 {
410         int             rc;
411         Scsp_csa        *csap;
412         Scsp_atmarp_csa *acp;
413
414         /*
415          * Allocate memory for a CSA record
416          */
417         csap = (Scsp_csa *)UM_ALLOC(sizeof(Scsp_csa));
418         if (!csap) {
419                 scsp_mem_err("scsp_client_act_07: sizeof(Scsp_csa)");
420         }
421         acp = (Scsp_atmarp_csa *)UM_ALLOC(sizeof(Scsp_atmarp_csa));
422         if (!acp) {
423                 scsp_mem_err("scsp_client_act_07: sizeof(Scsp_atmarp_csa)");
424         }
425         UM_ZERO(csap, sizeof(Scsp_csa));
426         UM_ZERO(acp, sizeof(Scsp_atmarp_csa));
427
428         /*
429          * Build a CSA record from the server's message
430          */
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;
444
445         /*
446          * Call the CA FSM
447          */
448         rc = scsp_cafsm(dcsp, SCSP_CAFSM_CACHE_UPD, (void *)csap);
449
450         return(rc);
451 }
452
453
454 /*
455  * SCSP client server interface finite state machine action 8
456  *
457  * Update Rsp from server--pass the update to the CA FSM.
458  *
459  * Arguments:
460  *      dcsp    pointer to DCS control block
461  *      msg     pointer to message from DCS
462  *      cmsg    pointer to message from server
463  *
464  * Returns:
465  *      0       success
466  *      else    errno describing error
467  *
468  */
469 int
470 scsp_client_act_08(dcsp, msg, cmsg)
471         Scsp_dcs        *dcsp;
472         Scsp_msg        *msg;
473         Scsp_if_msg     *cmsg;
474 {
475         int             rc;
476
477         /* 
478          * Pass the response to the CA FSM
479          */
480         switch (dcsp->sd_server->ss_pid) {
481         case SCSP_PROTO_ATMARP:
482                 rc = scsp_cafsm(dcsp, SCSP_CAFSM_CACHE_RSP, cmsg);
483                 break;
484         default:
485                 rc = EPROTONOSUPPORT;
486         }
487
488         return(rc);
489 }
490
491
492 /*
493  * SCSP client server interface finite state machine action 9
494  *
495  * CSU Solicit from DCS--pass Solicit Ind to server
496  *
497  * Arguments:
498  *      dcsp    pointer to DCS control block
499  *      msg     pointer to message from DCS
500  *      cmsg    pointer to message from server
501  *
502  * Returns:
503  *      0       success
504  *      else    errno describing error
505  *
506  */
507 int
508 scsp_client_act_09(dcsp, msg, cmsg)
509         Scsp_dcs        *dcsp;
510         Scsp_msg        *msg;
511         Scsp_if_msg     *cmsg;
512 {
513         int             rc, rrc = 0;
514         Scsp_csa        *csap;
515         Scsp_if_msg     *csip;
516
517         /*
518          * Get memory for a Solicit Ind
519          */
520         csip = (Scsp_if_msg *)UM_ALLOC(sizeof(Scsp_if_msg));
521         if (!csip) {
522                 scsp_mem_err("scsp_client_act_09: sizeof(Scsp_if_msg)");
523         }
524
525         /*
526          * Loop through list of CSAs
527          */
528         for (csap = msg->sc_csu_msg->csu_csa_rec; csap;
529                         csap = csap->next) {
530                 /*
531                  * Fill out the Solicit Indication
532                  */
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;
544
545                 /*
546                  * Send the Solicit Ind to the server
547                  */
548                 rc = scsp_if_sock_write(dcsp->sd_server->ss_sock, csip);
549                 if (rc) {
550                         rrc = rc;
551                 }
552         }
553
554         UM_FREE(csip);
555         return(rrc);
556 }
557
558
559 /*
560  * SCSP client server interface finite state machine action 10
561  *
562  * CSU Request from DCS--pass it to the server as a Cache Update
563  * Indication
564  *
565  * Arguments:
566  *      dcsp    pointer to DCS control block
567  *      msg     pointer to message from DCS
568  *      cmsg    pointer to message from server
569  *
570  * Returns:
571  *      0       success
572  *      else    errno describing error
573  *
574  */
575 int
576 scsp_client_act_10(dcsp, msg, cmsg)
577         Scsp_dcs        *dcsp;
578         Scsp_msg        *msg;
579         Scsp_if_msg     *cmsg;
580 {
581         int             rc, rrc = 0;
582         Scsp_csa        *csap;
583         Scsp_atmarp_csa *acp;
584         Scsp_if_msg     *cuip;
585
586         /*
587          * Get memory for a Cache Update Ind
588          */
589         cuip = (Scsp_if_msg *)UM_ALLOC(sizeof(Scsp_if_msg));
590         if (!cuip) {
591                 scsp_mem_err("scsp_client_act_10: sizeof(Scsp_if_msg)");
592         }
593
594         /*
595          * Loop through CSAs in message
596          */
597         for (csap = msg->sc_csu_msg->csu_csa_rec; csap;
598                         csap = csap->next) {
599                 acp = csap->atmarp_data;
600                 if (!acp)
601                         continue;
602
603                 /*
604                  * Fill out the Cache Update Ind
605                  */
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;
621                         break;
622                 case SCSP_PROTO_NHRP:
623                         /*
624                          * Not implemented yet
625                          */
626                         break;
627                 }
628
629                 /*
630                  * Send the Cache Update Ind to the server
631                  */
632                 rc = scsp_if_sock_write(dcsp->sd_server->ss_sock, cuip);
633                 if (rc) {
634                         rrc = rc;
635                 }
636         }
637
638         UM_FREE(cuip);
639         return(rrc);
640 }