Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / netproto / atm / uni / sscf_uni_upper.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/sys/netatm/uni/sscf_uni_upper.c,v 1.5 2000/01/17 20:49:50 mks Exp $
27  *
28  */
29
30 /*
31  * ATM Forum UNI Support
32  * ---------------------
33  *
34  * SSCF UNI - SSCOP SAP interface processing
35  *
36  */
37
38 #include <netatm/kern_include.h>
39
40 #include <netatm/uni/uni.h>
41 #include <netatm/uni/sscop.h>
42 #include <netatm/uni/sscf_uni_var.h>
43
44 #ifndef lint
45 __RCSID("@(#) $FreeBSD: src/sys/netatm/uni/sscf_uni_upper.c,v 1.5 2000/01/17 20:49:50 mks Exp $");
46 #endif
47
48
49 /*
50  * SSCF_UNI Upper Stack Command Handler
51  * 
52  * This function will receive all of the stack commands issued from the 
53  * layer below SSCF UNI (ie. SSCOP).
54  *
55  * Arguments:
56  *      cmd     stack command code
57  *      tok     session token
58  *      arg1    command specific argument
59  *      arg2    command specific argument
60  *
61  * Returns:
62  *      none
63  *
64  */
65 void
66 sscf_uni_upper(cmd, tok, arg1, arg2)
67         int     cmd;
68         void    *tok;
69         int     arg1;
70         int     arg2;
71 {
72         struct univcc   *uvp = (struct univcc *)tok;
73         Atm_connvc      *cvp = uvp->uv_connvc;
74         int             err;
75
76         ATM_DEBUG5("sscf_uni_upper: cmd=0x%x, uvp=%p, lstate=%d, arg1=0x%x, arg2=0x%x\n",
77                 cmd, uvp, uvp->uv_lstate, arg1, arg2);
78
79         switch (cmd) {
80
81         case SSCOP_ESTABLISH_IND:
82                 /*
83                  * We don't support SSCOP User-to-User data, so just
84                  * get rid of any supplied to us
85                  */
86                 if (arg1 != SSCOP_UU_NULL)
87                         KB_FREEALL((KBuffer *)arg1);
88
89                 /*
90                  * Validation based on sscop state
91                  */
92                 switch (uvp->uv_lstate) {
93
94                 case UVL_READY:
95                         if (uvp->uv_vers != UNI_VERS_3_0) {
96                                 goto seqerr;
97                         }
98                         goto doestind;
99
100                 case UVL_IDLE:
101                         /*
102                          * Incoming connection establishment request
103                          */
104
105                         /*
106                          * If user doesn't want any more incoming sessions
107                          * accepted, then refuse request
108                          */
109                         if (uvp->uv_flags & UVF_NOESTIND) {
110                                 STACK_CALL(SSCOP_RELEASE_REQ, uvp->uv_lower,
111                                         uvp->uv_tokl, cvp,
112                                         SSCOP_UU_NULL, 0, err);
113                                 if (err) {
114                                         sscf_uni_abort(uvp,
115                                                 "sscf_uni: stack memory\n");
116                                         return;
117                                 }
118                                 break;
119                         }
120
121 doestind:
122                         /*
123                          * Tell sscop we've accepted the new connection
124                          */
125                         uvp->uv_lstate = UVL_READY;
126                         STACK_CALL(SSCOP_ESTABLISH_RSP, uvp->uv_lower, 
127                                 uvp->uv_tokl, cvp, 
128                                 SSCOP_UU_NULL, SSCOP_BR_YES, err);
129                         if (err) {
130                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
131                                 return;
132                         }
133
134                         /*
135                          * Now notify the user of the new connection
136                          */
137                         uvp->uv_ustate = UVU_ACTIVE;
138                         STACK_CALL(SSCF_UNI_ESTABLISH_IND, uvp->uv_upper, 
139                                 uvp->uv_toku, cvp, 
140                                 SSCOP_UU_NULL, 0, err);
141                         if (err) {
142                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
143                                 return;
144                         }
145                         break;
146
147                 case UVL_TERM:
148                         /*
149                          * Ignoring everything
150                          */
151                         break;
152
153                 case UVL_INST:
154                 case UVL_OUTCONN:
155                 case UVL_INCONN:
156                 case UVL_OUTDISC:
157                 case UVL_OUTRESYN:
158                 case UVL_INRESYN:
159                 case UVL_RECOVERY:
160                 default:
161 seqerr:
162                         log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n",
163                                 cmd, uvp->uv_lstate);
164                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
165                 }
166                 break;
167
168         case SSCOP_ESTABLISH_CNF:
169                 /*
170                  * We don't support SSCOP User-to-User data, so just
171                  * get rid of any supplied to us
172                  */
173                 if (arg1 != SSCOP_UU_NULL)
174                         KB_FREEALL((KBuffer *)arg1);
175
176                 /*
177                  * Validation based on sscop state
178                  */
179                 switch (uvp->uv_lstate) {
180
181                 case UVL_OUTCONN:
182                         /*
183                          * Outgoing connection establishment completed
184                          */
185
186                         /*
187                          * Tell the user that the connection is established
188                          */
189                         uvp->uv_ustate = UVU_ACTIVE;
190                         uvp->uv_lstate = UVL_READY;
191                         STACK_CALL(SSCF_UNI_ESTABLISH_CNF, uvp->uv_upper, 
192                                 uvp->uv_toku, cvp, 
193                                 SSCOP_UU_NULL, 0, err);
194                         if (err) {
195                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
196                                 return;
197                         }
198                         break;
199
200                 case UVL_TERM:
201                         /*
202                          * Ignoring everything
203                          */
204                         break;
205
206                 case UVL_INST:
207                 case UVL_IDLE:
208                 case UVL_INCONN:
209                 case UVL_OUTDISC:
210                 case UVL_OUTRESYN:
211                 case UVL_INRESYN:
212                 case UVL_RECOVERY:
213                 case UVL_READY:
214                 default:
215                         log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n",
216                                 cmd, uvp->uv_lstate);
217                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
218                 }
219                 break;
220
221         case SSCOP_RELEASE_IND:
222                 /*
223                  * We don't support SSCOP User-to-User data, so just
224                  * get rid of any supplied to us
225                  */
226                 if (arg1 != SSCOP_UU_NULL)
227                         KB_FREEALL((KBuffer *)arg1);
228
229                 /*
230                  * Validation based on sscop state
231                  */
232                 switch (uvp->uv_lstate) {
233
234                 case UVL_OUTCONN:
235                 case UVL_OUTRESYN:
236                 case UVL_READY:
237                         /*
238                          * Peer requesting connection termination
239                          */
240
241                         /*
242                          * Notify the user that the connection 
243                          * has been terminated
244                          */
245                         uvp->uv_ustate = UVU_RELEASED;
246                         uvp->uv_lstate = UVL_IDLE;
247                         STACK_CALL(SSCF_UNI_RELEASE_IND, uvp->uv_upper, 
248                                 uvp->uv_toku, cvp, 
249                                 SSCOP_UU_NULL, 0, err);
250                         if (err) {
251                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
252                                 return;
253                         }
254                         break;
255
256                 case UVL_TERM:
257                         /*
258                          * Ignoring everything
259                          */
260                         break;
261
262                 case UVL_INST:
263                 case UVL_IDLE:
264                 case UVL_INCONN:
265                 case UVL_OUTDISC:
266                 case UVL_INRESYN:
267                 case UVL_RECOVERY:
268                 default:
269                         log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n",
270                                 cmd, uvp->uv_lstate);
271                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
272                 }
273                 break;
274
275         case SSCOP_RELEASE_CNF:
276                 /*
277                  * Validation based on sscop state
278                  */
279                 switch (uvp->uv_lstate) {
280
281                 case UVL_OUTDISC:
282                         /*
283                          * Peer acknowledging connection termination
284                          */
285
286                         /*
287                          * Notify the user that the connection 
288                          * termination is completed
289                          */
290                         uvp->uv_ustate = UVU_RELEASED;
291                         uvp->uv_lstate = UVL_IDLE;
292                         STACK_CALL(SSCF_UNI_RELEASE_CNF, uvp->uv_upper, 
293                                 uvp->uv_toku, cvp, 
294                                 SSCOP_UU_NULL, 0, err);
295                         if (err) {
296                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
297                                 return;
298                         }
299                         break;
300
301                 case UVL_TERM:
302                         /*
303                          * Ignoring everything
304                          */
305                         break;
306
307                 case UVL_INST:
308                 case UVL_IDLE:
309                 case UVL_OUTCONN:
310                 case UVL_INCONN:
311                 case UVL_OUTRESYN:
312                 case UVL_INRESYN:
313                 case UVL_RECOVERY:
314                 case UVL_READY:
315                 default:
316                         log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n",
317                                 cmd, uvp->uv_lstate);
318                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
319                 }
320                 break;
321
322         case SSCOP_DATA_IND:
323 #ifdef notdef
324                 sscf_uni_pdu_print(uvp, (KBuffer *)arg1, "DATA_IND");
325 #endif
326
327                 /*
328                  * Validation based on sscop state
329                  */
330                 switch (uvp->uv_lstate) {
331
332                 case UVL_READY:
333                         /*
334                          * Incoming assured data from peer
335                          */
336
337                         /*
338                          * Pass the data up to the user
339                          */
340                         STACK_CALL(SSCF_UNI_DATA_IND, uvp->uv_upper, 
341                                 uvp->uv_toku, cvp, 
342                                 arg1, 0, err);
343                         if (err) {
344                                 KB_FREEALL((KBuffer *)arg1);
345                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
346                                 return;
347                         }
348                         break;
349
350                 case UVL_TERM:
351                         /*
352                          * Ignoring everything
353                          */
354                         KB_FREEALL((KBuffer *)arg1);
355                         break;
356
357                 case UVL_INST:
358                 case UVL_IDLE:
359                 case UVL_OUTCONN:
360                 case UVL_INCONN:
361                 case UVL_OUTDISC:
362                 case UVL_OUTRESYN:
363                 case UVL_INRESYN:
364                 case UVL_RECOVERY:
365                 default:
366                         KB_FREEALL((KBuffer *)arg1);
367                         log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n",
368                                 cmd, uvp->uv_lstate);
369                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
370                 }
371                 break;
372
373         case SSCOP_RESYNC_IND:
374                 /*
375                  * We don't support SSCOP User-to-User data, so just
376                  * get rid of any supplied to us
377                  */
378                 if (arg1 != SSCOP_UU_NULL)
379                         KB_FREEALL((KBuffer *)arg1);
380
381                 /*
382                  * Validation based on sscop state
383                  */
384                 switch (uvp->uv_lstate) {
385
386                 case UVL_READY:
387                         /*
388                          * Incoming connection resynchronization request
389                          */
390
391                         /*
392                          * Send resynch acknowledgement to sscop
393                          */
394                         STACK_CALL(SSCOP_RESYNC_RSP, uvp->uv_lower, 
395                                 uvp->uv_tokl, cvp, 
396                                 0, 0, err);
397                         if (err) {
398                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
399                                 return;
400                         }
401
402                         if (uvp->uv_vers != UNI_VERS_3_0) {
403
404                                 /*
405                                  * Notify the user that the connection 
406                                  * has been resynced
407                                  */
408                                 STACK_CALL(SSCF_UNI_ESTABLISH_IND, 
409                                         uvp->uv_upper, uvp->uv_toku, cvp, 
410                                         SSCOP_UU_NULL, 0, err);
411                                 if (err) {
412                                         sscf_uni_abort(uvp, 
413                                                 "sscf_uni: stack memory\n");
414                                         return;
415                                 }
416                         }
417                         break;
418
419                 case UVL_TERM:
420                         /*
421                          * Ignoring everything
422                          */
423                         break;
424
425                 case UVL_INST:
426                 case UVL_IDLE:
427                 case UVL_OUTCONN:
428                 case UVL_INCONN:
429                 case UVL_OUTDISC:
430                 case UVL_OUTRESYN:
431                 case UVL_INRESYN:
432                 case UVL_RECOVERY:
433                 default:
434                         log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n",
435                                 cmd, uvp->uv_lstate);
436                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
437                 }
438                 break;
439
440         case SSCOP_RESYNC_CNF:
441                 /*
442                  * Not supported in version 3.0
443                  */
444                 if (uvp->uv_vers == UNI_VERS_3_0) {
445                         sscf_uni_abort(uvp, 
446                                 "sscf_uni: SSCOP_RESYNC_CNF in 3.0\n");
447                         return;
448                 }
449
450                 /*
451                  * Validation based on sscop state
452                  */
453                 switch (uvp->uv_lstate) {
454
455                 case UVL_OUTRESYN:
456                         /*
457                          * Peer acknowledging connection resynchronization
458                          */
459
460                         /*
461                          * Now notify the user that the connection 
462                          * has been resynced
463                          */
464                         uvp->uv_ustate = UVU_ACTIVE;
465                         uvp->uv_lstate = UVL_READY;
466                         STACK_CALL(SSCF_UNI_ESTABLISH_CNF, uvp->uv_upper, 
467                                 uvp->uv_toku, cvp, 
468                                 SSCOP_UU_NULL, 0, err);
469                         if (err) {
470                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
471                                 return;
472                         }
473                         break;
474
475                 case UVL_TERM:
476                         /*
477                          * Ignoring everything
478                          */
479                         break;
480
481                 case UVL_INST:
482                 case UVL_IDLE:
483                 case UVL_OUTCONN:
484                 case UVL_INCONN:
485                 case UVL_OUTDISC:
486                 case UVL_INRESYN:
487                 case UVL_RECOVERY:
488                 case UVL_READY:
489                 default:
490                         log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n",
491                                 cmd, uvp->uv_lstate);
492                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
493                 }
494                 break;
495
496         case SSCOP_RECOVER_IND:
497                 /*
498                  * Not supported in version 3.0
499                  */
500                 if (uvp->uv_vers == UNI_VERS_3_0) {
501                         sscf_uni_abort(uvp, 
502                                 "sscf_uni: SSCOP_RECOVER_IND in 3.0\n");
503                         return;
504                 }
505
506                 /*
507                  * Validation based on sscop state
508                  */
509                 switch (uvp->uv_lstate) {
510
511                 case UVL_READY:
512                         /*
513                          * Recover connection due to internal problems
514                          */
515
516                         /*
517                          * Send recovery acknowledgement to sscop
518                          */
519                         STACK_CALL(SSCOP_RECOVER_RSP, uvp->uv_lower, 
520                                 uvp->uv_tokl, cvp, 
521                                 0, 0, err);
522                         if (err) {
523                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
524                                 return;
525                         }
526
527                         /*
528                          * Now notify the user that the connection 
529                          * has been recovered
530                          */
531                         STACK_CALL(SSCF_UNI_ESTABLISH_IND, uvp->uv_upper, 
532                                 uvp->uv_toku, cvp, 
533                                 SSCOP_UU_NULL, 0, err);
534                         if (err) {
535                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
536                                 return;
537                         }
538                         break;
539
540                 case UVL_TERM:
541                         /*
542                          * Ignoring everything
543                          */
544                         break;
545
546                 case UVL_INST:
547                 case UVL_IDLE:
548                 case UVL_OUTCONN:
549                 case UVL_INCONN:
550                 case UVL_OUTDISC:
551                 case UVL_OUTRESYN:
552                 case UVL_INRESYN:
553                 case UVL_RECOVERY:
554                 default:
555                         log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n",
556                                 cmd, uvp->uv_lstate);
557                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
558                 }
559                 break;
560
561         case SSCOP_UNITDATA_IND:
562 #ifdef notdef
563                 sscf_uni_pdu_print(uvp, (KBuffer *)arg1, "UNITDATA_IND");
564 #endif
565
566                 /*
567                  * Validation based on sscop state
568                  */
569                 switch (uvp->uv_lstate) {
570
571                 case UVL_IDLE:
572                 case UVL_OUTCONN:
573                 case UVL_INCONN:
574                 case UVL_OUTDISC:
575                 case UVL_OUTRESYN:
576                 case UVL_INRESYN:
577                 case UVL_RECOVERY:
578                 case UVL_READY:
579                         /*
580                          * Incoming unassured data from peer
581                          */
582
583                         /*
584                          * Pass the data up to the user
585                          */
586                         STACK_CALL(SSCF_UNI_UNITDATA_IND, uvp->uv_upper, 
587                                 uvp->uv_toku, cvp, 
588                                 arg1, 0, err);
589                         if (err) {
590                                 KB_FREEALL((KBuffer *)arg1);
591                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
592                                 return;
593                         }
594                         break;
595
596                 case UVL_TERM:
597                         /*
598                          * Ignoring everything
599                          */
600                         KB_FREEALL((KBuffer *)arg1);
601                         break;
602
603                 case UVL_INST:
604                 default:
605                         KB_FREEALL((KBuffer *)arg1);
606                         log(LOG_ERR, "sscf_uni_upper: cmd=0x%x, lstate=%d\n",
607                                 cmd, uvp->uv_lstate);
608                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
609                 }
610                 break;
611
612         case SSCOP_RETRIEVE_IND:
613         case SSCOP_RETRIEVECMP_IND:
614                 /*
615                  * Not supported
616                  */
617         default:
618                 log(LOG_ERR, "sscf_uni_upper: unknown cmd 0x%x, uvp=%p\n",
619                         cmd, uvp);
620         }
621
622         return;
623 }
624