kernel tree reorganization stage 1: Major cvs repository work (not logged as
[dragonfly.git] / sys / netproto / atm / uni / sscop.c
CommitLineData
984263bc
MD
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/sscop.c,v 1.6.2.1 2001/09/30 22:54:35 kris Exp $
d2438d69 27 * @(#) $DragonFly: src/sys/netproto/atm/uni/sscop.c,v 1.4 2003/08/07 21:54:34 dillon Exp $
984263bc
MD
28 */
29
30/*
31 * ATM Forum UNI Support
32 * ---------------------
33 *
34 * Service Specific Connection Oriented Protocol (SSCOP)
35 *
36 */
37
d2438d69 38#include <netproto/atm/kern_include.h>
984263bc 39
1f2de5d4
MD
40#include "sscop.h"
41#include "sscop_misc.h"
42#include "sscop_pdu.h"
43#include "sscop_var.h"
984263bc 44
984263bc
MD
45/*
46 * Global variables
47 */
48int sscop_vccnt = 0;
49
50struct sscop *sscop_head = NULL;
51
52struct sscop_stat sscop_stat = {0};
53
54struct atm_time sscop_timer = {0, 0};
55
56struct sp_info sscop_pool = {
57 "sscop pool", /* si_name */
58 sizeof(struct sscop), /* si_blksiz */
59 5, /* si_blkcnt */
60 100 /* si_maxallow */
61};
62
63
64/*
65 * Local functions
66 */
67static int sscop_inst __P((struct stack_defn **, Atm_connvc *));
68
69
70/*
71 * Local variables
72 */
73static struct stack_defn sscop_service = {
74 NULL,
75 SAP_SSCOP,
76 0,
77 sscop_inst,
78 sscop_lower,
79 sscop_upper,
80 0
81};
82
83static struct t_atm_cause sscop_cause = {
84 T_ATM_ITU_CODING,
85 T_ATM_LOC_USER,
86 T_ATM_CAUSE_TEMPORARY_FAILURE,
87 {0, 0, 0, 0}
88};
89
90static u_char sscop_maa_log[MAA_ERROR_COUNT] = {
91 1, /* A */
92 1, /* B */
93 1, /* C */
94 1, /* D */
95 1, /* E */
96 1, /* F */
97 1, /* G */
98 1, /* H */
99 1, /* I */
100 1, /* J */
101 1, /* K */
102 1, /* L */
103 1, /* M */
104 0, /* N */
105 0, /* O */
106 0, /* P */
107 1, /* Q */
108 1, /* R */
109 1, /* S */
110 1, /* T */
111 1, /* U */
112 0, /* V */
113 0, /* W */
114 0, /* X */
115 1 /* INVAL */
116};
117
118
119/*
120 * Initialize SSCOP processing
121 *
122 * This will be called during module loading. We will register our stack
123 * service and wait for someone to talk to us.
124 *
125 * Arguments:
126 * none
127 *
128 * Returns:
129 * 0 initialization was successful
130 * errno initialization failed - reason indicated
131 *
132 */
133int
134sscop_start()
135{
136 int err = 0;
137
138 /*
139 * Register stack service
140 */
141 if ((err = atm_stack_register(&sscop_service)) != 0)
142 goto done;
143
144 /*
145 * Start up timer
146 */
147 atm_timeout(&sscop_timer, ATM_HZ/SSCOP_HZ, sscop_timeout);
148
149done:
150 return (err);
151}
152
153
154/*
155 * Terminate SSCOP processing
156 *
157 * This will be called just prior to unloading the module from memory. All
158 * signalling instances should have been terminated by now, so we just free
159 * up all of our resources.
160 *
161 * Called at splnet.
162 *
163 * Arguments:
164 * none
165 *
166 * Returns:
167 * 0 termination was successful
168 * errno termination failed - reason indicated
169 *
170 */
171int
172sscop_stop()
173{
174 int err = 0;
175
176 /*
177 * Any connections still exist??
178 */
179 if (sscop_vccnt) {
180
181 /*
182 * Yes, can't stop yet
183 */
184 return (EBUSY);
185 }
186
187 /*
188 * Stop our timer
189 */
190 (void) atm_untimeout(&sscop_timer);
191
192 /*
193 * Deregister the stack service
194 */
195 (void) atm_stack_deregister(&sscop_service);
196
197 /*
198 * Free our storage pools
199 */
200 atm_release_pool(&sscop_pool);
201
202 return (err);
203}
204
205
206/*
207 * SSCOP Stack Instantiation
208 *
209 * Called at splnet.
210 *
211 * Arguments:
212 * ssp pointer to array of stack definition pointers for connection
213 * ssp[0] points to upper layer's stack service definition
214 * ssp[1] points to this layer's stack service definition
215 * ssp[2] points to lower layer's stack service definition
216 * cvp pointer to connection vcc for this stack
217 *
218 * Returns:
219 * 0 instantiation successful
220 * errno instantiation failed - reason indicated
221 *
222 */
223static int
224sscop_inst(ssp, cvp)
225 struct stack_defn **ssp;
226 Atm_connvc *cvp;
227{
228 struct stack_defn *sdp_up = ssp[0],
229 *sdp_me = ssp[1],
230 *sdp_low = ssp[2];
231 struct sscop *sop;
232 int err;
233
234 ATM_DEBUG2("sscop_inst: ssp=%p, cvp=%p\n", ssp, cvp);
235
236 /*
237 * Validate lower SAP
238 */
239 if ((sdp_low->sd_sap & SAP_CLASS_MASK) != SAP_CPCS)
240 return (EINVAL);
241
242 /*
243 * Allocate our control block
244 */
245 sop = (struct sscop *)atm_allocate(&sscop_pool);
246 if (sop == NULL)
247 return (ENOMEM);
248
249 sop->so_state = SOS_INST;
250 sop->so_connvc = cvp;
251 sop->so_toku = sdp_up->sd_toku;
252 sop->so_upper = sdp_up->sd_upper;
253
254 /*
255 * Store my token into service definition
256 */
257 sdp_me->sd_toku = sop;
258
259 /*
260 * Update and save input buffer headroom
261 */
262 HEADIN(cvp, sizeof(struct pdu_hdr), 0);
263 /* sop->so_headin = cvp->cvc_attr.headin; */
264
265 /*
266 * Pass instantiation down the stack
267 */
268 err = sdp_low->sd_inst(ssp + 1, cvp);
269 if (err) {
270 /*
271 * Lower layer instantiation failed, free our resources
272 */
273 atm_free((caddr_t)sop);
274 return (err);
275 }
276
277 /*
278 * Link in connection block
279 */
280 LINK2TAIL(sop, struct sscop, sscop_head, so_next);
281 sscop_vccnt++;
282 sscop_stat.sos_connects++;
283
284 /*
285 * Save and update output buffer headroom
286 */
287 sop->so_headout = cvp->cvc_attr.headout;
288 HEADOUT(cvp, sizeof(struct pdu_hdr), 0);
289
290 /*
291 * Save lower layer's interface info
292 */
293 sop->so_lower = sdp_low->sd_lower;
294 sop->so_tokl = sdp_low->sd_toku;
295
296 /*
297 * Initialize version (until INIT received)
298 */
299 sop->so_vers = SSCOP_VERS_Q2110;
300
301 return (0);
302}
303
304
305/*
306 * Report Management Error
307 *
308 * Called to report an error to the layer management entity.
309 *
310 * Arguments:
311 * sop pointer to sscop control block
312 * code error code
313 *
314 * Returns:
315 * none
316 *
317 */
318void
319sscop_maa_error(sop, code)
320 struct sscop *sop;
321 int code;
322{
323 int i;
324
325 /*
326 * Validate error code
327 */
328 if ((code < MAA_ERROR_MIN) ||
329 (code > MAA_ERROR_MAX))
330 code = MAA_ERROR_INVAL;
331 i = code - MAA_ERROR_MIN;
332
333 /*
334 * Bump statistics counters
335 */
336 sscop_stat.sos_maa_error[i]++;
337
338 /*
339 * Log error message
340 */
341 if (sscop_maa_log[i] != 0) {
342 struct vccb *vcp = sop->so_connvc->cvc_vcc;
343 struct atm_pif *pip = vcp->vc_pif;
344
345 log(LOG_ERR,
346 "sscop_maa_error: intf=%s%d vpi=%d vci=%d code=%c state=%d\n",
347 pip->pif_name, pip->pif_unit,
348 vcp->vc_vpi, vcp->vc_vci, code, sop->so_state);
349 }
350}
351
352
353/*
354 * Abort an SSCOP connection
355 *
356 * Called when an unrecoverable or "should never happen" error occurs.
357 * We log a message, send an END PDU to our peer and request the signalling
358 * manager to abort the connection.
359 *
360 * Arguments:
361 * sop pointer to sscop control block
362 * msg pointer to error message
363 *
364 * Returns:
365 * none
366 *
367 */
368void
369sscop_abort(sop, msg)
370 struct sscop *sop;
371 char *msg;
372{
373 Atm_connvc *cvp = sop->so_connvc;
374
375 /*
376 * Log and count error
377 */
378 log(LOG_ERR, "%s", msg);
379 sscop_stat.sos_aborts++;
380
381 /*
382 * Send an END PDU as a courtesy to peer
383 */
384 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
385
386 /*
387 * Set termination state
388 */
389 sop->so_state = SOS_TERM;
390
391 /*
392 * Flush all of our queues
393 */
394 sscop_xmit_drain(sop);
395 sscop_rcvr_drain(sop);
396
397 /*
398 * Tell Connection Manager to abort this connection
399 */
400 (void) atm_cm_abort(cvp, &sscop_cause);
401}
402