]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - 6/sys/netatm/uni/sscf_uni_lower.c
Clone Kip's Xen on stable/6 tree so that I can work on improving FreeBSD/amd64
[FreeBSD/FreeBSD.git] / 6 / sys / netatm / uni / sscf_uni_lower.c
1 /*-
2  * ===================================
3  * HARP  |  Host ATM Research Platform
4  * ===================================
5  *
6  *
7  * This Host ATM Research Platform ("HARP") file (the "Software") is
8  * made available by Network Computing Services, Inc. ("NetworkCS")
9  * "AS IS".  NetworkCS does not provide maintenance, improvements or
10  * support of any kind.
11  *
12  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
13  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
14  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
15  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
16  * In no event shall NetworkCS be responsible for any damages, including
17  * but not limited to consequential damages, arising from or relating to
18  * any use of the Software or related support.
19  *
20  * Copyright 1994-1998 Network Computing Services, Inc.
21  *
22  * Copies of this Software may be made, however, the above copyright
23  * notice must be reproduced on all copies.
24  */
25
26 /*
27  * ATM Forum UNI Support
28  * ---------------------
29  *
30  * SSCF UNI - SSCF_UNI SAP interface processing
31  */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/systm.h>
39 #include <sys/time.h>
40 #include <sys/socket.h>
41 #include <sys/socketvar.h>
42 #include <sys/syslog.h>
43 #include <net/if.h>
44 #include <netatm/port.h>
45 #include <netatm/queue.h>
46 #include <netatm/atm.h>
47 #include <netatm/atm_sys.h>
48 #include <netatm/atm_sap.h>
49 #include <netatm/atm_cm.h>
50 #include <netatm/atm_if.h>
51 #include <netatm/atm_stack.h>
52 #include <netatm/atm_pcb.h>
53 #include <netatm/atm_var.h>
54
55 #include <netatm/uni/uni.h>
56 #include <netatm/uni/sscop.h>
57 #include <netatm/uni/sscf_uni.h>
58 #include <netatm/uni/sscf_uni_var.h>
59
60 #include <vm/uma.h>
61
62 extern uma_zone_t       sscf_uni_zone;
63
64 /*
65  * Local variables
66  */
67 static struct sscop_parms       sscf_uni_sscop_parms = {
68         4096,                           /* sp_maxinfo */
69         4096,                           /* sp_maxuu */
70         4,                              /* sp_maxcc */
71         25,                             /* sp_maxpd */
72         1 * ATM_HZ,                     /* sp_timecc */
73         2 * ATM_HZ,                     /* sp_timekeep */
74         7 * ATM_HZ,                     /* sp_timeresp */
75         1 * ATM_HZ,                     /* sp_timepoll */
76         15 * ATM_HZ,                    /* sp_timeidle */
77         80                              /* sp_rcvwin */
78 };
79
80
81 /*
82  * SSCF_UNI Lower Stack Command Handler
83  * 
84  * This function will receive all of the stack commands issued from the 
85  * layer above SSCF UNI (ie. Q.2931).
86  *
87  * Arguments:
88  *      cmd     stack command code
89  *      tok     session token
90  *      arg1    command specific argument
91  *      arg2    command specific argument
92  *
93  * Returns:
94  *      none
95  *
96  */
97 void
98 sscf_uni_lower(cmd, tok, arg1, arg2)
99         int     cmd;
100         void    *tok;
101         intptr_t        arg1;
102         intptr_t        arg2;
103 {
104         struct univcc   *uvp = (struct univcc *)tok;
105         Atm_connvc      *cvp = uvp->uv_connvc;
106         enum sscop_vers vers;
107         int             err;
108
109         ATM_DEBUG5("sscf_uni_lower: cmd=0x%x, uvp=%p, ustate=%d, arg1=%p, arg2=%p\n",
110                 cmd, uvp, uvp->uv_ustate, (void *)arg1, (void *)arg2);
111
112         switch (cmd) {
113
114         case SSCF_UNI_INIT:
115                 /*
116                  * Validate state
117                  */
118                 if (uvp->uv_ustate != UVU_INST) {
119                         log(LOG_ERR, "sscf_uni_lower: SSCF_INIT in ustate=%d\n",
120                                 uvp->uv_ustate);
121                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
122                         break;
123                 }
124
125                 /*
126                  * Validate UNI version
127                  */
128                 if ((enum uni_vers)arg1 == UNI_VERS_3_0)
129                         vers = SSCOP_VERS_QSAAL;
130                 else if ((enum uni_vers)arg1 == UNI_VERS_3_1)
131                         vers = SSCOP_VERS_Q2110;
132                 else {
133                         sscf_uni_abort(uvp, "sscf_uni: bad version\n");
134                         break;
135                 }
136                 uvp->uv_vers = (enum uni_vers)arg1;
137
138                 /*
139                  * Make ourselves ready and pass on the INIT
140                  */
141                 uvp->uv_ustate = UVU_RELEASED;
142                 uvp->uv_lstate = UVL_IDLE;
143
144                 STACK_CALL(SSCOP_INIT, uvp->uv_lower, uvp->uv_tokl, cvp, 
145                         (int)vers, (int)&sscf_uni_sscop_parms, err);
146                 if (err) {
147                         /*
148                          * Should never happen
149                          */
150                         sscf_uni_abort(uvp, "sscf_uni: INIT failure\n");
151                 }
152                 break;
153
154         case SSCF_UNI_TERM:
155                 /*
156                  * Set termination states
157                  */
158                 uvp->uv_ustate = UVU_TERM;
159                 uvp->uv_lstate = UVL_TERM;
160
161                 /*
162                  * Pass the TERM down the stack
163                  */
164                 STACK_CALL(SSCOP_TERM, uvp->uv_lower, uvp->uv_tokl, cvp,
165                         0, 0, err);
166                 if (err) {
167                         /*
168                          * Should never happen
169                          */
170                         sscf_uni_abort(uvp, "sscf_uni: TERM failure\n");
171                         return;
172                 }
173                 uma_zfree(sscf_uni_zone, uvp);
174                 sscf_uni_vccnt--;
175                 break;
176
177         case SSCF_UNI_ESTABLISH_REQ:
178                 /*
179                  * Validation based on user state
180                  */
181                 switch (uvp->uv_ustate) {
182
183                 case UVU_RELEASED:
184                 case UVU_PRELEASE:
185                         /*
186                          * Establishing a new connection
187                          */
188                         uvp->uv_ustate = UVU_PACTIVE;
189                         uvp->uv_lstate = UVL_OUTCONN;
190                         STACK_CALL(SSCOP_ESTABLISH_REQ, uvp->uv_lower, 
191                                 uvp->uv_tokl, cvp, 
192                                 SSCOP_UU_NULL, SSCOP_BR_YES, err);
193                         if (err) {
194                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
195                                 return;
196                         }
197                         break;
198
199                 case UVU_ACTIVE:
200                         /*
201                          * Resynchronizing a connection
202                          */
203                         uvp->uv_ustate = UVU_PACTIVE;
204                         if (uvp->uv_vers == UNI_VERS_3_0) {
205                                 uvp->uv_lstate = UVL_OUTCONN;
206                                 STACK_CALL(SSCOP_ESTABLISH_REQ, uvp->uv_lower, 
207                                         uvp->uv_tokl, cvp, 
208                                         SSCOP_UU_NULL, SSCOP_BR_YES, err);
209                         } else {
210                                 uvp->uv_lstate = UVL_OUTRESYN;
211                                 STACK_CALL(SSCOP_RESYNC_REQ, uvp->uv_lower, 
212                                         uvp->uv_tokl, cvp, 
213                                         SSCOP_UU_NULL, 0, err);
214                         }
215                         if (err) {
216                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
217                                 return;
218                         }
219                         break;
220
221                 case UVU_TERM:
222                         /* Ignore */
223                         break;
224
225                 case UVU_INST:
226                 case UVU_PACTIVE:
227                 default:
228                         log(LOG_ERR, "sscf_uni_lower: cmd=0x%x, ustate=%d\n",
229                                 cmd, uvp->uv_ustate);
230                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
231                 }
232                 break;
233
234         case SSCF_UNI_RELEASE_REQ:
235                 /*
236                  * Validate re-establishment parameter
237                  */
238                 switch (arg1) {
239
240                 case SSCF_UNI_ESTIND_YES:
241                         uvp->uv_flags &= ~UVF_NOESTIND;
242                         break;
243
244                 case SSCF_UNI_ESTIND_NO:
245                         uvp->uv_flags |= UVF_NOESTIND;
246                         break;
247
248                 default:
249                         sscf_uni_abort(uvp, "sscf_uni: bad estind value\n");
250                         return;
251                 }
252
253                 /*
254                  * Validation based on user state
255                  */
256                 switch (uvp->uv_ustate) {
257
258                 case UVU_RELEASED:
259                         /*
260                          * Releasing a non-existant connection
261                          */
262                         STACK_CALL(SSCF_UNI_RELEASE_CNF, uvp->uv_upper, 
263                                 uvp->uv_toku, cvp, 
264                                 0, 0, err);
265                         if (err) {
266                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
267                                 return;
268                         }
269                         break;
270
271                 case UVU_PACTIVE:
272                 case UVU_ACTIVE:
273                         /*
274                          * Releasing a connection
275                          */
276                         uvp->uv_ustate = UVU_PRELEASE;
277                         uvp->uv_lstate = UVL_OUTDISC;
278                         STACK_CALL(SSCOP_RELEASE_REQ, uvp->uv_lower, 
279                                 uvp->uv_tokl, cvp, 
280                                 SSCOP_UU_NULL, 0, err);
281                         if (err) {
282                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
283                                 return;
284                         }
285                         break;
286
287                 case UVU_TERM:
288                         /* Ignore */
289                         break;
290
291                 case UVU_INST:
292                 case UVU_PRELEASE:
293                 default:
294                         log(LOG_ERR, "sscf_uni_lower: cmd=0x%x, ustate=%d\n",
295                                 cmd, uvp->uv_ustate);
296                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
297                 }
298                 break;
299
300         case SSCF_UNI_DATA_REQ:
301 #ifdef notdef
302                 sscf_uni_pdu_print(uvp, (KBuffer *)arg1, "DATA_REQ");
303 #endif
304
305                 /*
306                  * Validation based on user state
307                  */
308                 switch (uvp->uv_ustate) {
309
310                 case UVU_ACTIVE:
311                         /*
312                          * Send assured data on connection
313                          */
314                         STACK_CALL(SSCOP_DATA_REQ, uvp->uv_lower, 
315                                 uvp->uv_tokl, cvp, 
316                                 arg1, 0, err);
317                         if (err) {
318                                 KB_FREEALL((KBuffer *)arg1);
319                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
320                                 return;
321                         }
322                         break;
323
324                 case UVU_RELEASED:
325                 case UVU_TERM:
326                         /*
327                          * Release supplied buffers and ignore
328                          */
329                         KB_FREEALL((KBuffer *)arg1);
330                         break;
331
332                 case UVU_INST:
333                 case UVU_PACTIVE:
334                 case UVU_PRELEASE:
335                 default:
336                         KB_FREEALL((KBuffer *)arg1);
337                         log(LOG_ERR, "sscf_uni_lower: cmd=0x%x, ustate=%d\n",
338                                 cmd, uvp->uv_ustate);
339                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
340                 }
341                 break;
342
343         case SSCF_UNI_UNITDATA_REQ:
344 #ifdef notdef
345                 sscf_uni_pdu_print(uvp, (KBuffer *)arg1, "UNITDATA_REQ");
346 #endif
347
348                 /*
349                  * Validation based on user state
350                  */
351                 switch (uvp->uv_ustate) {
352
353                 case UVU_RELEASED:
354                 case UVU_PACTIVE:
355                 case UVU_PRELEASE:
356                 case UVU_ACTIVE:
357                         /*
358                          * Send unassured data on connection
359                          */
360                         STACK_CALL(SSCOP_UNITDATA_REQ, uvp->uv_lower, 
361                                 uvp->uv_tokl, cvp, 
362                                 arg1, 0, err);
363                         if (err) {
364                                 KB_FREEALL((KBuffer *)arg1);
365                                 sscf_uni_abort(uvp, "sscf_uni: stack memory\n");
366                                 return;
367                         }
368                         break;
369
370                 case UVU_TERM:
371                         /*
372                          * Release supplied buffers and ignore
373                          */
374                         KB_FREEALL((KBuffer *)arg1);
375                         break;
376
377                 case UVU_INST:
378                 default:
379                         KB_FREEALL((KBuffer *)arg1);
380                         log(LOG_ERR, "sscf_uni_lower: cmd=0x%x, ustate=%d\n",
381                                 cmd, uvp->uv_ustate);
382                         sscf_uni_abort(uvp, "sscf_uni: sequence err\n");
383                 }
384                 break;
385
386         default:
387                 log(LOG_ERR, "sscf_uni_lower: unknown cmd 0x%x, uvp=%p\n",
388                         cmd, uvp);
389         }
390
391         return;
392 }
393