Deleted Added
full compact
ccpriv.h (131826) ccpriv.h (146539)
1/*
2 * Copyright (c) 2003-2004
3 * Hartmut Brandt
4 * All rights reserved.
5 *
6 * Author: Harti Brandt <harti@freebsd.org>
7 *
8 * Redistribution of this software and documentation and use in source and
9 * binary forms, with or without modification, are permitted provided that
10 * the following conditions are met:
11 *
12 * 1. Redistributions of source code or documentation must retain the above
13 * copyright notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE AUTHOR
19 * AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 * THE AUTHOR OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
25 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
1/*
2 * Copyright (c) 2003-2004
3 * Hartmut Brandt
4 * All rights reserved.
5 *
6 * Author: Harti Brandt <harti@freebsd.org>
7 *
8 * Redistribution of this software and documentation and use in source and
9 * binary forms, with or without modification, are permitted provided that
10 * the following conditions are met:
11 *
12 * 1. Redistributions of source code or documentation must retain the above
13 * copyright notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE AUTHOR
19 * AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 * THE AUTHOR OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
25 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * $FreeBSD: vendor-sys/ngatm/dist/sys/contrib/ngatm/netnatm/api/ccpriv.h 131826 2004-07-08 16:39:03Z harti $
30 * $Begemot: libunimsg/netnatm/api/ccpriv.h,v 1.2 2005/05/23 11:49:17 brandt_h Exp $
31 *
32 * ATM API as defined per af-saa-0108
33 *
34 * Private declarations.
35 */
36#ifdef _KERNEL
37#ifdef __FreeBSD__
38#include <netgraph/atm/ccatm/ng_ccatm_cust.h>
39#endif
40#else /* !_KERNEL */
41#include "cccust.h"
42#endif
43
44struct ccuser;
45struct ccconn;
46struct ccaddr;
47struct ccport;
48struct ccdata;
49struct ccsig;
50struct ccparty;
51
52LIST_HEAD(ccuser_list, ccuser);
53LIST_HEAD(ccconn_list, ccconn);
54TAILQ_HEAD(ccaddr_list, ccaddr);
55TAILQ_HEAD(ccport_list, ccport);
56TAILQ_HEAD(ccsig_list, ccsig);
57LIST_HEAD(ccparty_list, ccparty);
58
59/*
60 * Private node data.
61 */
62struct ccdata {
63 struct ccuser_list user_list; /* instance list */
64 struct ccport_list port_list; /* list of ports */
65 struct ccconn_list orphaned_conns; /* list of connections */
66 struct ccsig_list sigs; /* current signals */
67 struct ccsig_list def_sigs; /* deferred signals */
68 struct ccsig_list free_sigs; /* free signals */
69
70 const struct cc_funcs *funcs;
71 uint32_t cookie; /* cookie generator */
72 u_int log; /* logging flags */
73};
74
75/* retrieve info on local ports */
76struct atm_port_list *cc_get_local_port_info(struct ccdata *,
77 u_int, size_t *);
78
79/* log */
80#ifdef CCATM_DEBUG
81#if defined(__GNUC__) && __GNUC__ < 3
82#define cc_log(CC, FMT, ARGS...) do { \
83 (CC)->funcs->log("%s (data=%p): " FMT, __FUNCTION__, \
84 (CC) , ## ARGS); \
85 } while (0)
86#else
87#define cc_log(CC, FMT, ...) do { \
88 (CC)->funcs->log("%s (data=%p): " FMT, __func__, \
89 (CC), __VA_ARGS__); \
90 } while (0)
91#endif
92#else
93#if defined(__GNUC__) && __GNUC__ < 3
94#define cc_log(CC, FMT, ARGS...) do { } while (0)
95#else
96#define cc_log(CC, FMT, ...) do { } while (0)
97#endif
98#endif
99
100/*
101 * structure to remember cookies for outstanding requests
102 * we also remember the request itself but don't use it.
103 */
104struct ccreq {
105 TAILQ_ENTRY(ccreq) link;
106 uint32_t cookie;
107 uint32_t req;
108 struct ccconn *conn;
109};
110TAILQ_HEAD(ccreq_list, ccreq);
111
112/*
113 * Port data. Each port has one UNI stack below.
114 * The port number is in param.port. The number is assigned when the
115 * hook to the uni is connected. This hook has the name 'uni<port>'.
116 */
117struct ccport {
118 void *uarg; /* hook to UNI protocol */
119 struct ccdata *cc; /* back pointer to node */
120 enum {
121 CCPORT_STOPPED, /* halted */
122 CCPORT_RUNNING, /* ok */
123 } admin; /* admin status */
124 struct ccconn_list conn_list; /* list of connections */
125 struct ccaddr_list addr_list; /* list of network addresses */
126 struct atm_port_info param; /* parameters */
127
128 /* list of outstanding requests */
129 struct ccreq_list cookies;
130
131 TAILQ_ENTRY(ccport) node_link;
132};
133
134#ifdef CCATM_DEBUG
135#if defined(__GNUC__) && __GNUC__ < 3
136#define cc_port_log(P, FMT, ARGS...) do { \
137 (P)->cc->funcs->log("%s (port=%p/%u): " FMT, __FUNCTION__, \
138 (P), (P)->param.port , ## ARGS); \
139 } while (0)
140#else
141#define cc_port_log(P, FMT, ...) do { \
142 (P)->cc->funcs->log("%s (port=%p/%u): " FMT, __func__, \
143 (P), (P)->param.port, __VA_ARGS__); \
144 } while (0)
145#endif
146#else
147#if defined(__GNUC__) && __GNUC__ < 3
148#define cc_port_log(P, FMT, ARGS...) do { } while (0)
149#else
150#define cc_port_log(P, FMT, ...) do { } while (0)
151#endif
152#endif
153
154#define CONN_STATES \
155 DEF(CONN_NULL) /* C0 */ \
156 DEF(CONN_OUT_PREPARING) /* C1 */ \
157 DEF(CONN_OUT_WAIT_CREATE) /* C2 */ \
158 DEF(CONN_OUT_WAIT_OK) /* C3 */ \
159 DEF(CONN_OUT_WAIT_CONF) /* C4 */ \
160 \
161 DEF(CONN_ACTIVE) /* C5 */ \
162 \
163 DEF(CONN_IN_PREPARING) /* C10 */ \
164 DEF(CONN_IN_WAITING) /* C21 */ \
165 DEF(CONN_IN_ARRIVED) /* C11 */ \
166 DEF(CONN_IN_WAIT_ACCEPT_OK) /* C12 */ \
167 DEF(CONN_IN_WAIT_COMPL) /* C13 */ \
168 \
169 DEF(CONN_REJ_WAIT_OK) /* C14 */ \
170 DEF(CONN_REL_IN_WAIT_OK) /* C15 */ \
171 DEF(CONN_REL_WAIT_OK) /* C20 */ \
172 \
173 DEF(CONN_AB_WAIT_REQ_OK) /* C33 */ \
174 DEF(CONN_AB_WAIT_RESP_OK) /* C34 */ \
175 DEF(CONN_AB_FLUSH_IND) /* C35 */ \
176 DEF(CONN_OUT_WAIT_DESTROY) /* C37 */
177
178enum conn_state {
179#define DEF(N) N,
180 CONN_STATES
181#undef DEF
182};
183
184#define CONN_SIGS \
185 DEF(CONNECT_OUTGOING) /* U */ \
186 DEF(ARRIVAL) /* U */ \
187 DEF(RELEASE) /* U */ \
188 DEF(REJECT) /* U */ \
189 DEF(ACCEPT) /* U newuser */ \
190 DEF(ADD_PARTY) /* U ident */ \
191 DEF(DROP_PARTY) /* U ident */ \
192 DEF(USER_ABORT) /* U */ \
193 \
194 DEF(CREATED) /* P msg */ \
195 DEF(DESTROYED) /* P */ \
196 DEF(SETUP_CONFIRM) /* P msg */ \
197 DEF(SETUP_IND) /* P msg */ \
198 DEF(SETUP_COMPL) /* P msg */ \
199 DEF(PROC_IND) /* P msg */ \
200 DEF(ALERTING_IND) /* P msg */ \
201 DEF(REL_CONF) /* P msg */ \
202 DEF(REL_IND) /* P msg */ \
203 DEF(PARTY_CREATED) /* P msg */ \
204 DEF(PARTY_DESTROYED) /* P msg */ \
205 DEF(PARTY_ALERTING_IND) /* P msg */ \
206 DEF(PARTY_ADD_ACK_IND) /* P msg */ \
207 DEF(PARTY_ADD_REJ_IND) /* P msg */ \
208 DEF(DROP_PARTY_IND) /* P msg */ \
209 DEF(DROP_PARTY_ACK_IND) /* P msg */ \
210 \
211 DEF(OK) /* P msg */ \
212 DEF(ERROR) /* P msg */
213
214enum conn_sig {
215#define DEF(NAME) CONN_SIG_##NAME,
216CONN_SIGS
217#undef DEF
218};
219extern const char *const cc_conn_sigtab[];
220
221/*
222 * This describes a connection and must be in sync with the UNI
223 * stack.
224 */
225struct ccconn {
226 enum conn_state state; /* API state of the connection */
227 struct ccdata *cc; /* owner node */
228 struct ccport *port; /* the port we belong to */
229 struct ccuser *user; /* user instance we belong to */
230 TAILQ_ENTRY(ccconn) connq_link; /* queue of the owner */
231 LIST_ENTRY(ccconn) port_link; /* link in list of port */
232 struct uni_cref cref;
233 uint8_t reason;
234 struct ccuser *acceptor;
235
236 /* attributes */
237 uint32_t blli_selector;
238 struct uni_ie_blli blli[UNI_NUM_IE_BLLI];
239
240 struct uni_ie_bearer bearer;
241 struct uni_ie_traffic traffic;
242 struct uni_ie_qos qos;
243 struct uni_ie_exqos exqos;
244 struct uni_ie_called called;
245 struct uni_ie_calledsub calledsub;
246 struct uni_ie_aal aal;
247 struct uni_ie_epref epref;
248 struct uni_ie_conned conned;
249 struct uni_ie_connedsub connedsub;
250 struct uni_ie_eetd eetd;
251 struct uni_ie_abrsetup abrsetup;
252 struct uni_ie_abradd abradd;
253 struct uni_ie_mdcr mdcr;
254
255 struct uni_ie_calling calling;
256 struct uni_ie_callingsub callingsub;
257 struct uni_ie_connid connid;
258 struct uni_ie_tns tns[UNI_NUM_IE_TNS];
259 struct uni_ie_atraffic atraffic;
260 struct uni_ie_mintraffic mintraffic;
261 struct uni_ie_cscope cscope;
262 struct uni_ie_bhli bhli;
263
264 /* bit mask of written attributes in A6 */
265 u_int dirty_attr;
266
267 struct uni_ie_cause cause[2];
268
269 struct ccparty_list parties;
270};
271
272/* dirty attribute mask values */
273enum {
274 CCDIRTY_AAL = 0x0001,
275 CCDIRTY_BLLI = 0x0002,
276 CCDIRTY_CONNID = 0x0004,
277 CCDIRTY_NOTIFY = 0x0008, /* XXX */
278 CCDIRTY_EETD = 0x0010,
279 CCDIRTY_GIT = 0x0020, /* XXX */
280 CCDIRTY_UU = 0x0040, /* XXX */
281 CCDIRTY_TRAFFIC = 0x0080,
282 CCDIRTY_EXQOS = 0x0100,
283 CCDIRTY_ABRSETUP = 0x0200,
284 CCDIRTY_ABRADD = 0x0400,
285};
286
287/* set conn to new state */
288void cc_conn_set_state(struct ccconn *, enum conn_state);
289
290/* return string for state */
291const char *cc_conn_state2str(u_int);
292
293/* connect connection to user */
294void cc_connect_to_user(struct ccconn *, struct ccuser *);
295
296/* disconnect from the user */
297void cc_disconnect_from_user(struct ccconn *);
298
299/* abort the connection */
300void cc_conn_abort(struct ccconn *, int);
301
302/* destroy a connection */
303void cc_conn_destroy(struct ccconn *);
304
305/* create a connection */
306struct ccconn *cc_conn_create(struct ccdata *);
307
308/* assign to port */
309void cc_conn_ins_port(struct ccconn *, struct ccport *);
310
311/* remove from port */
312void cc_conn_rem_port(struct ccconn *);
313
314/* dispatch a connection to a user or reject it */
315void cc_conn_dispatch(struct ccconn *);
316
317/* disconnect from acceptor */
318void cc_conn_reset_acceptor(struct ccconn *);
319
320/* log on a connection */
321#ifdef CCATM_DEBUG
322#if defined(__GNUC__) && __GNUC__ < 3
323#define cc_conn_log(C, FMT, ARGS...) do { \
324 (C)->cc->funcs->log("%s (conn=%p): " FMT, __FUNCTION__, \
325 (C) , ## ARGS); \
326 } while (0)
327#else
328#define cc_conn_log(C, FMT, ...) do { \
329 (C)->cc->funcs->log("%s (conn=%p): " FMT, __func__, \
330 (C), __VA_ARGS__); \
331 } while (0)
332#endif
333#else
334#if defined(__GNUC__) && __GNUC__ < 3
335#define cc_conn_log(C, FMT, ARGS...) do { } while (0)
336#else
337#define cc_conn_log(C, FMT, ...) do { } while (0)
338#endif
339#endif
340
341/* handle signal to connection */
342void cc_conn_sig_handle(struct ccconn *, enum conn_sig, void *arg, u_int iarg);
343
344/*
345 * Mp connection parties
346 */
347#define PARTY_STATES \
348 DEF(NULL) /* 0 created */ \
349 DEF(ACTIVE) /* 1 active */ \
350 DEF(ADD_WAIT_CREATE) /* 2 wait for PARTY_CREATE */ \
351 DEF(ADD_WAIT_OK) /* 3 wait for OK for ADD.request */ \
352 DEF(ADD_WAIT_ACK) /* 4 wait for ADD.ack/rej */ \
353 DEF(DROP_WAIT_OK) /* 5 wait for OK for DROP.request */ \
354 DEF(DROP_WAIT_ACK) /* 6 wait for DROP.ack */ \
355 DEF(WAIT_DESTROY) /* 7 wait for destroy */ \
356 DEF(WAIT_SETUP_COMPL) /* 8 wait for setup.complete */ \
357 DEF(WAIT_DROP_ACK_OK) /* 9 wait for OK for DROP_ACK.request */\
358 DEF(WAIT_SETUP_CONF) /* 10 wait for setup.confirm */ \
359 DEF(ADD_DROP_WAIT_OK) /* 11 wait for ok to DROP.request */ \
360 DEF(ADD_DROPACK_WAIT_OK)/* 12 wait for ok to DROP_ACK.req */
361
362enum party_state {
363#define DEF(N) PARTY_##N,
364PARTY_STATES
365#undef DEF
366};
367
368struct ccparty {
369 struct ccconn *conn; /* owner */
370 LIST_ENTRY(ccparty) link;
371 enum party_state state;
372 struct uni_ie_called called;
373 struct uni_ie_epref epref;
374};
375
376/* set party to new state */
377void cc_party_set_state(struct ccparty *, enum party_state);
378
379/* return string for state */
380const char *cc_party_state2str(u_int);
381
382/* create new party */
383struct ccparty *cc_party_create(struct ccconn *, u_int ident, u_int flag);
384
385/* log on a party */
386#ifdef CCATM_DEBUG
387#if defined(__GNUC__) && __GNUC__ < 3
388#define cc_party_log(P, FMT, ARGS...) do { \
389 (P)->conn->cc->funcs->log("%s (conn=%p, party=%p): " FMT, \
390 __FUNCTION__, (P)->conn, (P) , ## ARGS); \
391 } while (0)
392#else
393#define cc_party_log(P, FMT, ...) do { \
394 (P)->conn->cc->funcs->log("%s (conn=%p, party=%p): " FMT, \
395 __func__, (P)->conn, (P), __VA_ARGS__); \
396 } while (0)
397#endif
398#else
399#if defined(__GNUC__) && __GNUC__ < 3
400#define cc_party_log(P, FMT, ARGS...) do { } while (0)
401#else
402#define cc_party_log(P, FMT, ...) do { } while (0)
403#endif
404#endif
405
406/*
407 * This is kind of a user socket, i.e. the entity managed towards the
408 * upper layer.
409 */
410#define USER_STATES \
411 DEF(USER_NULL) /* U0 none */ \
412 DEF(USER_OUT_PREPARING) /* U1 process set/query requests */ \
413 DEF(USER_OUT_WAIT_OK) /* U2 wait for OK to setup */ \
414 DEF(USER_OUT_WAIT_CONF) /* U3 wait for SETUP.confirm */ \
415 DEF(USER_ACTIVE) /* U4 A8-9-10/U10 */ \
416 DEF(USER_REL_WAIT) /* U5 wait for release to compl */ \
417 DEF(USER_IN_PREPARING) /* U6 set SAP */ \
418 DEF(USER_IN_WAITING) /* U7 wait and dispatch */ \
419 DEF(USER_IN_ARRIVED) /* U8 waiting for rej/acc */ \
420 DEF(USER_IN_WAIT_REJ) /* U9 wait for rejecting */ \
421 DEF(USER_IN_WAIT_ACC) /* U10 wait for accepting */ \
422 DEF(USER_IN_ACCEPTING) /* U11 wait for SETUP_complete */ \
423 DEF(USER_REL_WAIT_SCOMP)/* U12 wait for SETUP_complete */ \
424 DEF(USER_REL_WAIT_SCONF)/* U13 wait for SETUP.confirm */ \
425 DEF(USER_REL_WAIT_CONF) /* U14 wait for confirm */ \
426 DEF(USER_REL_WAIT_CONN) /* U15 wait for CONN_OK */
427
428enum user_state {
429#define DEF(N) N,
430USER_STATES
431#undef DEF
432};
433
434#define USER_SIGS \
435 DEF(PREPARE_OUTGOING) /* U */ \
436 DEF(CONNECT_OUTGOING) /* U msg */ \
437 DEF(PREPARE_INCOMING) /* U msg */ \
438 DEF(WAIT_ON_INCOMING) /* U msg */ \
439 DEF(REJECT_INCOMING) /* U msg */ \
440 DEF(ACCEPT_INCOMING) /* U msg */ \
441 DEF(CALL_RELEASE) /* U msg */ \
442 DEF(ADD_PARTY) /* U msg */ \
443 DEF(DROP_PARTY) /* U msg */ \
444 DEF(QUERY_ATTR) /* U msg */ \
445 DEF(QUERY_ATTR_X) /* U msg */ \
446 DEF(SET_ATTR) /* U msg */ \
447 DEF(SET_ATTR_X) /* U msg */ \
448 DEF(QUERY_STATE) /* U */ \
449 DEF(GET_LOCAL_PORT_INFO) /* U msg */ \
450 DEF(ABORT_CONNECTION) /* U msg */ \
451 \
452 DEF(CONNECT_OUTGOING_OK) /* */ \
453 DEF(CONNECT_OUTGOING_ERR) /* reason */ \
454 DEF(SETUP_CONFIRM) /* */ \
455 DEF(SETUP_IND) /* */ \
456 DEF(REJECT_OK) /* */ \
457 DEF(REJECT_ERR) /* reason */ \
458 DEF(ACCEPT_OK) /* */ \
459 DEF(ACCEPT_ERR) /* reason */ \
460 DEF(ACCEPTING) /* */ \
461 DEF(SETUP_COMPL) /* */ \
462 DEF(RELEASE_CONFIRM) /* */ \
463 DEF(RELEASE_ERR) /* reason */ \
464 DEF(ADD_PARTY_ERR) /* reason */ \
465 DEF(ADD_PARTY_OK) /* */ \
466 DEF(ADD_PARTY_ACK) /* leaf-ident */ \
467 DEF(ADD_PARTY_REJ) /* leaf-ident */ \
468 DEF(DROP_PARTY_ERR) /* reason */ \
469 DEF(DROP_PARTY_OK) /* */ \
470 DEF(DROP_PARTY_IND) /* leaf-ident */ \
471
472
473enum user_sig {
474#define DEF(NAME) USER_SIG_##NAME,
475USER_SIGS
476#undef DEF
477};
478extern const char *const cc_user_sigtab[];
479
480struct ccuser {
481 LIST_ENTRY(ccuser) node_link; /* link in list of node */
482 enum user_state state; /* type of this instance */
483 struct ccdata *cc; /* the node */
484 void *uarg; /* the hook (if any) */
485 char name[ATM_EPNAMSIZ];
486 enum {
487 USER_P2P,
488 USER_ROOT,
489 USER_LEAF
490 } config; /* configuration */
491
492 struct uni_sap *sap; /* listening SAP */
493 u_int queue_max; /* maximum queue size */
494 u_int queue_act; /* actual queue size */
495 TAILQ_HEAD(,ccconn) connq; /* pending connections */
496 struct ccconn *accepted;
497 struct uni_ie_cause cause[2]; /* cause from connection */
498 u_int aborted;
499};
500
501/* set user to new state */
502void cc_user_set_state(struct ccuser *, enum user_state);
503
504/* return string for state */
505const char *cc_user_state2str(u_int);
506
507/* log on a user */
508#ifdef CCATM_DEBUG
509#if defined(__GNUC__) && __GNUC__ < 3
510#define cc_user_log(U, FMT, ARGS...) do { \
511 (U)->cc->funcs->log("%s (user=%p): " FMT, __FUNCTION__, \
512 (U) , ## ARGS); \
513 } while (0)
514#else
515#define cc_user_log(U, FMT, ...) do { \
516 (U)->cc->funcs->log("%s (user=%p): " FMT, __func__, \
517 (U), __VA_ARGS__); \
518 } while (0)
519#endif
520#else
521#if defined(__GNUC__) && __GNUC__ < 3
522#define cc_user_log(U, FMT, ARGS...) do { } while (0)
523#else
524#define cc_user_log(U, FMT, ...) do { } while (0)
525#endif
526#endif
527
528/* Handle a signal to this user */
529void cc_user_sig_handle(struct ccuser *, enum user_sig, void *, u_int);
530
531/*
532 * Addresses
533 */
534struct ccaddr {
535 TAILQ_ENTRY(ccaddr) port_link;
536 struct uni_addr addr;
537};
538
539/* signal to connection */
540int cc_conn_sig(struct ccconn *, enum conn_sig, void *arg);
541
542/* signal with message to connection */
543int cc_conn_sig_msg(struct ccconn *, enum conn_sig, struct uni_msg *);
544int cc_conn_sig_msg_nodef(struct ccconn *, enum conn_sig, struct uni_msg *);
545
546/* response signal to connection */
547int cc_conn_resp(struct ccconn *, enum conn_sig, u_int, u_int, u_int);
548
549/* flush all signals to a given connection */
550void cc_conn_sig_flush(struct ccconn *);
551
552/* Queue a signal to this user */
553int cc_user_sig(struct ccuser *, enum user_sig, void *, u_int);
554
555/* Queue a signal with message to this user */
556int cc_user_sig_msg(struct ccuser *, enum user_sig, struct uni_msg *);
557
558/* Flush all signals to a given user */
559void cc_user_sig_flush(struct ccuser *);
560
561/* flush all signals */
562void cc_sig_flush_all(struct ccdata *);
31 *
32 * ATM API as defined per af-saa-0108
33 *
34 * Private declarations.
35 */
36#ifdef _KERNEL
37#ifdef __FreeBSD__
38#include <netgraph/atm/ccatm/ng_ccatm_cust.h>
39#endif
40#else /* !_KERNEL */
41#include "cccust.h"
42#endif
43
44struct ccuser;
45struct ccconn;
46struct ccaddr;
47struct ccport;
48struct ccdata;
49struct ccsig;
50struct ccparty;
51
52LIST_HEAD(ccuser_list, ccuser);
53LIST_HEAD(ccconn_list, ccconn);
54TAILQ_HEAD(ccaddr_list, ccaddr);
55TAILQ_HEAD(ccport_list, ccport);
56TAILQ_HEAD(ccsig_list, ccsig);
57LIST_HEAD(ccparty_list, ccparty);
58
59/*
60 * Private node data.
61 */
62struct ccdata {
63 struct ccuser_list user_list; /* instance list */
64 struct ccport_list port_list; /* list of ports */
65 struct ccconn_list orphaned_conns; /* list of connections */
66 struct ccsig_list sigs; /* current signals */
67 struct ccsig_list def_sigs; /* deferred signals */
68 struct ccsig_list free_sigs; /* free signals */
69
70 const struct cc_funcs *funcs;
71 uint32_t cookie; /* cookie generator */
72 u_int log; /* logging flags */
73};
74
75/* retrieve info on local ports */
76struct atm_port_list *cc_get_local_port_info(struct ccdata *,
77 u_int, size_t *);
78
79/* log */
80#ifdef CCATM_DEBUG
81#if defined(__GNUC__) && __GNUC__ < 3
82#define cc_log(CC, FMT, ARGS...) do { \
83 (CC)->funcs->log("%s (data=%p): " FMT, __FUNCTION__, \
84 (CC) , ## ARGS); \
85 } while (0)
86#else
87#define cc_log(CC, FMT, ...) do { \
88 (CC)->funcs->log("%s (data=%p): " FMT, __func__, \
89 (CC), __VA_ARGS__); \
90 } while (0)
91#endif
92#else
93#if defined(__GNUC__) && __GNUC__ < 3
94#define cc_log(CC, FMT, ARGS...) do { } while (0)
95#else
96#define cc_log(CC, FMT, ...) do { } while (0)
97#endif
98#endif
99
100/*
101 * structure to remember cookies for outstanding requests
102 * we also remember the request itself but don't use it.
103 */
104struct ccreq {
105 TAILQ_ENTRY(ccreq) link;
106 uint32_t cookie;
107 uint32_t req;
108 struct ccconn *conn;
109};
110TAILQ_HEAD(ccreq_list, ccreq);
111
112/*
113 * Port data. Each port has one UNI stack below.
114 * The port number is in param.port. The number is assigned when the
115 * hook to the uni is connected. This hook has the name 'uni<port>'.
116 */
117struct ccport {
118 void *uarg; /* hook to UNI protocol */
119 struct ccdata *cc; /* back pointer to node */
120 enum {
121 CCPORT_STOPPED, /* halted */
122 CCPORT_RUNNING, /* ok */
123 } admin; /* admin status */
124 struct ccconn_list conn_list; /* list of connections */
125 struct ccaddr_list addr_list; /* list of network addresses */
126 struct atm_port_info param; /* parameters */
127
128 /* list of outstanding requests */
129 struct ccreq_list cookies;
130
131 TAILQ_ENTRY(ccport) node_link;
132};
133
134#ifdef CCATM_DEBUG
135#if defined(__GNUC__) && __GNUC__ < 3
136#define cc_port_log(P, FMT, ARGS...) do { \
137 (P)->cc->funcs->log("%s (port=%p/%u): " FMT, __FUNCTION__, \
138 (P), (P)->param.port , ## ARGS); \
139 } while (0)
140#else
141#define cc_port_log(P, FMT, ...) do { \
142 (P)->cc->funcs->log("%s (port=%p/%u): " FMT, __func__, \
143 (P), (P)->param.port, __VA_ARGS__); \
144 } while (0)
145#endif
146#else
147#if defined(__GNUC__) && __GNUC__ < 3
148#define cc_port_log(P, FMT, ARGS...) do { } while (0)
149#else
150#define cc_port_log(P, FMT, ...) do { } while (0)
151#endif
152#endif
153
154#define CONN_STATES \
155 DEF(CONN_NULL) /* C0 */ \
156 DEF(CONN_OUT_PREPARING) /* C1 */ \
157 DEF(CONN_OUT_WAIT_CREATE) /* C2 */ \
158 DEF(CONN_OUT_WAIT_OK) /* C3 */ \
159 DEF(CONN_OUT_WAIT_CONF) /* C4 */ \
160 \
161 DEF(CONN_ACTIVE) /* C5 */ \
162 \
163 DEF(CONN_IN_PREPARING) /* C10 */ \
164 DEF(CONN_IN_WAITING) /* C21 */ \
165 DEF(CONN_IN_ARRIVED) /* C11 */ \
166 DEF(CONN_IN_WAIT_ACCEPT_OK) /* C12 */ \
167 DEF(CONN_IN_WAIT_COMPL) /* C13 */ \
168 \
169 DEF(CONN_REJ_WAIT_OK) /* C14 */ \
170 DEF(CONN_REL_IN_WAIT_OK) /* C15 */ \
171 DEF(CONN_REL_WAIT_OK) /* C20 */ \
172 \
173 DEF(CONN_AB_WAIT_REQ_OK) /* C33 */ \
174 DEF(CONN_AB_WAIT_RESP_OK) /* C34 */ \
175 DEF(CONN_AB_FLUSH_IND) /* C35 */ \
176 DEF(CONN_OUT_WAIT_DESTROY) /* C37 */
177
178enum conn_state {
179#define DEF(N) N,
180 CONN_STATES
181#undef DEF
182};
183
184#define CONN_SIGS \
185 DEF(CONNECT_OUTGOING) /* U */ \
186 DEF(ARRIVAL) /* U */ \
187 DEF(RELEASE) /* U */ \
188 DEF(REJECT) /* U */ \
189 DEF(ACCEPT) /* U newuser */ \
190 DEF(ADD_PARTY) /* U ident */ \
191 DEF(DROP_PARTY) /* U ident */ \
192 DEF(USER_ABORT) /* U */ \
193 \
194 DEF(CREATED) /* P msg */ \
195 DEF(DESTROYED) /* P */ \
196 DEF(SETUP_CONFIRM) /* P msg */ \
197 DEF(SETUP_IND) /* P msg */ \
198 DEF(SETUP_COMPL) /* P msg */ \
199 DEF(PROC_IND) /* P msg */ \
200 DEF(ALERTING_IND) /* P msg */ \
201 DEF(REL_CONF) /* P msg */ \
202 DEF(REL_IND) /* P msg */ \
203 DEF(PARTY_CREATED) /* P msg */ \
204 DEF(PARTY_DESTROYED) /* P msg */ \
205 DEF(PARTY_ALERTING_IND) /* P msg */ \
206 DEF(PARTY_ADD_ACK_IND) /* P msg */ \
207 DEF(PARTY_ADD_REJ_IND) /* P msg */ \
208 DEF(DROP_PARTY_IND) /* P msg */ \
209 DEF(DROP_PARTY_ACK_IND) /* P msg */ \
210 \
211 DEF(OK) /* P msg */ \
212 DEF(ERROR) /* P msg */
213
214enum conn_sig {
215#define DEF(NAME) CONN_SIG_##NAME,
216CONN_SIGS
217#undef DEF
218};
219extern const char *const cc_conn_sigtab[];
220
221/*
222 * This describes a connection and must be in sync with the UNI
223 * stack.
224 */
225struct ccconn {
226 enum conn_state state; /* API state of the connection */
227 struct ccdata *cc; /* owner node */
228 struct ccport *port; /* the port we belong to */
229 struct ccuser *user; /* user instance we belong to */
230 TAILQ_ENTRY(ccconn) connq_link; /* queue of the owner */
231 LIST_ENTRY(ccconn) port_link; /* link in list of port */
232 struct uni_cref cref;
233 uint8_t reason;
234 struct ccuser *acceptor;
235
236 /* attributes */
237 uint32_t blli_selector;
238 struct uni_ie_blli blli[UNI_NUM_IE_BLLI];
239
240 struct uni_ie_bearer bearer;
241 struct uni_ie_traffic traffic;
242 struct uni_ie_qos qos;
243 struct uni_ie_exqos exqos;
244 struct uni_ie_called called;
245 struct uni_ie_calledsub calledsub;
246 struct uni_ie_aal aal;
247 struct uni_ie_epref epref;
248 struct uni_ie_conned conned;
249 struct uni_ie_connedsub connedsub;
250 struct uni_ie_eetd eetd;
251 struct uni_ie_abrsetup abrsetup;
252 struct uni_ie_abradd abradd;
253 struct uni_ie_mdcr mdcr;
254
255 struct uni_ie_calling calling;
256 struct uni_ie_callingsub callingsub;
257 struct uni_ie_connid connid;
258 struct uni_ie_tns tns[UNI_NUM_IE_TNS];
259 struct uni_ie_atraffic atraffic;
260 struct uni_ie_mintraffic mintraffic;
261 struct uni_ie_cscope cscope;
262 struct uni_ie_bhli bhli;
263
264 /* bit mask of written attributes in A6 */
265 u_int dirty_attr;
266
267 struct uni_ie_cause cause[2];
268
269 struct ccparty_list parties;
270};
271
272/* dirty attribute mask values */
273enum {
274 CCDIRTY_AAL = 0x0001,
275 CCDIRTY_BLLI = 0x0002,
276 CCDIRTY_CONNID = 0x0004,
277 CCDIRTY_NOTIFY = 0x0008, /* XXX */
278 CCDIRTY_EETD = 0x0010,
279 CCDIRTY_GIT = 0x0020, /* XXX */
280 CCDIRTY_UU = 0x0040, /* XXX */
281 CCDIRTY_TRAFFIC = 0x0080,
282 CCDIRTY_EXQOS = 0x0100,
283 CCDIRTY_ABRSETUP = 0x0200,
284 CCDIRTY_ABRADD = 0x0400,
285};
286
287/* set conn to new state */
288void cc_conn_set_state(struct ccconn *, enum conn_state);
289
290/* return string for state */
291const char *cc_conn_state2str(u_int);
292
293/* connect connection to user */
294void cc_connect_to_user(struct ccconn *, struct ccuser *);
295
296/* disconnect from the user */
297void cc_disconnect_from_user(struct ccconn *);
298
299/* abort the connection */
300void cc_conn_abort(struct ccconn *, int);
301
302/* destroy a connection */
303void cc_conn_destroy(struct ccconn *);
304
305/* create a connection */
306struct ccconn *cc_conn_create(struct ccdata *);
307
308/* assign to port */
309void cc_conn_ins_port(struct ccconn *, struct ccport *);
310
311/* remove from port */
312void cc_conn_rem_port(struct ccconn *);
313
314/* dispatch a connection to a user or reject it */
315void cc_conn_dispatch(struct ccconn *);
316
317/* disconnect from acceptor */
318void cc_conn_reset_acceptor(struct ccconn *);
319
320/* log on a connection */
321#ifdef CCATM_DEBUG
322#if defined(__GNUC__) && __GNUC__ < 3
323#define cc_conn_log(C, FMT, ARGS...) do { \
324 (C)->cc->funcs->log("%s (conn=%p): " FMT, __FUNCTION__, \
325 (C) , ## ARGS); \
326 } while (0)
327#else
328#define cc_conn_log(C, FMT, ...) do { \
329 (C)->cc->funcs->log("%s (conn=%p): " FMT, __func__, \
330 (C), __VA_ARGS__); \
331 } while (0)
332#endif
333#else
334#if defined(__GNUC__) && __GNUC__ < 3
335#define cc_conn_log(C, FMT, ARGS...) do { } while (0)
336#else
337#define cc_conn_log(C, FMT, ...) do { } while (0)
338#endif
339#endif
340
341/* handle signal to connection */
342void cc_conn_sig_handle(struct ccconn *, enum conn_sig, void *arg, u_int iarg);
343
344/*
345 * Mp connection parties
346 */
347#define PARTY_STATES \
348 DEF(NULL) /* 0 created */ \
349 DEF(ACTIVE) /* 1 active */ \
350 DEF(ADD_WAIT_CREATE) /* 2 wait for PARTY_CREATE */ \
351 DEF(ADD_WAIT_OK) /* 3 wait for OK for ADD.request */ \
352 DEF(ADD_WAIT_ACK) /* 4 wait for ADD.ack/rej */ \
353 DEF(DROP_WAIT_OK) /* 5 wait for OK for DROP.request */ \
354 DEF(DROP_WAIT_ACK) /* 6 wait for DROP.ack */ \
355 DEF(WAIT_DESTROY) /* 7 wait for destroy */ \
356 DEF(WAIT_SETUP_COMPL) /* 8 wait for setup.complete */ \
357 DEF(WAIT_DROP_ACK_OK) /* 9 wait for OK for DROP_ACK.request */\
358 DEF(WAIT_SETUP_CONF) /* 10 wait for setup.confirm */ \
359 DEF(ADD_DROP_WAIT_OK) /* 11 wait for ok to DROP.request */ \
360 DEF(ADD_DROPACK_WAIT_OK)/* 12 wait for ok to DROP_ACK.req */
361
362enum party_state {
363#define DEF(N) PARTY_##N,
364PARTY_STATES
365#undef DEF
366};
367
368struct ccparty {
369 struct ccconn *conn; /* owner */
370 LIST_ENTRY(ccparty) link;
371 enum party_state state;
372 struct uni_ie_called called;
373 struct uni_ie_epref epref;
374};
375
376/* set party to new state */
377void cc_party_set_state(struct ccparty *, enum party_state);
378
379/* return string for state */
380const char *cc_party_state2str(u_int);
381
382/* create new party */
383struct ccparty *cc_party_create(struct ccconn *, u_int ident, u_int flag);
384
385/* log on a party */
386#ifdef CCATM_DEBUG
387#if defined(__GNUC__) && __GNUC__ < 3
388#define cc_party_log(P, FMT, ARGS...) do { \
389 (P)->conn->cc->funcs->log("%s (conn=%p, party=%p): " FMT, \
390 __FUNCTION__, (P)->conn, (P) , ## ARGS); \
391 } while (0)
392#else
393#define cc_party_log(P, FMT, ...) do { \
394 (P)->conn->cc->funcs->log("%s (conn=%p, party=%p): " FMT, \
395 __func__, (P)->conn, (P), __VA_ARGS__); \
396 } while (0)
397#endif
398#else
399#if defined(__GNUC__) && __GNUC__ < 3
400#define cc_party_log(P, FMT, ARGS...) do { } while (0)
401#else
402#define cc_party_log(P, FMT, ...) do { } while (0)
403#endif
404#endif
405
406/*
407 * This is kind of a user socket, i.e. the entity managed towards the
408 * upper layer.
409 */
410#define USER_STATES \
411 DEF(USER_NULL) /* U0 none */ \
412 DEF(USER_OUT_PREPARING) /* U1 process set/query requests */ \
413 DEF(USER_OUT_WAIT_OK) /* U2 wait for OK to setup */ \
414 DEF(USER_OUT_WAIT_CONF) /* U3 wait for SETUP.confirm */ \
415 DEF(USER_ACTIVE) /* U4 A8-9-10/U10 */ \
416 DEF(USER_REL_WAIT) /* U5 wait for release to compl */ \
417 DEF(USER_IN_PREPARING) /* U6 set SAP */ \
418 DEF(USER_IN_WAITING) /* U7 wait and dispatch */ \
419 DEF(USER_IN_ARRIVED) /* U8 waiting for rej/acc */ \
420 DEF(USER_IN_WAIT_REJ) /* U9 wait for rejecting */ \
421 DEF(USER_IN_WAIT_ACC) /* U10 wait for accepting */ \
422 DEF(USER_IN_ACCEPTING) /* U11 wait for SETUP_complete */ \
423 DEF(USER_REL_WAIT_SCOMP)/* U12 wait for SETUP_complete */ \
424 DEF(USER_REL_WAIT_SCONF)/* U13 wait for SETUP.confirm */ \
425 DEF(USER_REL_WAIT_CONF) /* U14 wait for confirm */ \
426 DEF(USER_REL_WAIT_CONN) /* U15 wait for CONN_OK */
427
428enum user_state {
429#define DEF(N) N,
430USER_STATES
431#undef DEF
432};
433
434#define USER_SIGS \
435 DEF(PREPARE_OUTGOING) /* U */ \
436 DEF(CONNECT_OUTGOING) /* U msg */ \
437 DEF(PREPARE_INCOMING) /* U msg */ \
438 DEF(WAIT_ON_INCOMING) /* U msg */ \
439 DEF(REJECT_INCOMING) /* U msg */ \
440 DEF(ACCEPT_INCOMING) /* U msg */ \
441 DEF(CALL_RELEASE) /* U msg */ \
442 DEF(ADD_PARTY) /* U msg */ \
443 DEF(DROP_PARTY) /* U msg */ \
444 DEF(QUERY_ATTR) /* U msg */ \
445 DEF(QUERY_ATTR_X) /* U msg */ \
446 DEF(SET_ATTR) /* U msg */ \
447 DEF(SET_ATTR_X) /* U msg */ \
448 DEF(QUERY_STATE) /* U */ \
449 DEF(GET_LOCAL_PORT_INFO) /* U msg */ \
450 DEF(ABORT_CONNECTION) /* U msg */ \
451 \
452 DEF(CONNECT_OUTGOING_OK) /* */ \
453 DEF(CONNECT_OUTGOING_ERR) /* reason */ \
454 DEF(SETUP_CONFIRM) /* */ \
455 DEF(SETUP_IND) /* */ \
456 DEF(REJECT_OK) /* */ \
457 DEF(REJECT_ERR) /* reason */ \
458 DEF(ACCEPT_OK) /* */ \
459 DEF(ACCEPT_ERR) /* reason */ \
460 DEF(ACCEPTING) /* */ \
461 DEF(SETUP_COMPL) /* */ \
462 DEF(RELEASE_CONFIRM) /* */ \
463 DEF(RELEASE_ERR) /* reason */ \
464 DEF(ADD_PARTY_ERR) /* reason */ \
465 DEF(ADD_PARTY_OK) /* */ \
466 DEF(ADD_PARTY_ACK) /* leaf-ident */ \
467 DEF(ADD_PARTY_REJ) /* leaf-ident */ \
468 DEF(DROP_PARTY_ERR) /* reason */ \
469 DEF(DROP_PARTY_OK) /* */ \
470 DEF(DROP_PARTY_IND) /* leaf-ident */ \
471
472
473enum user_sig {
474#define DEF(NAME) USER_SIG_##NAME,
475USER_SIGS
476#undef DEF
477};
478extern const char *const cc_user_sigtab[];
479
480struct ccuser {
481 LIST_ENTRY(ccuser) node_link; /* link in list of node */
482 enum user_state state; /* type of this instance */
483 struct ccdata *cc; /* the node */
484 void *uarg; /* the hook (if any) */
485 char name[ATM_EPNAMSIZ];
486 enum {
487 USER_P2P,
488 USER_ROOT,
489 USER_LEAF
490 } config; /* configuration */
491
492 struct uni_sap *sap; /* listening SAP */
493 u_int queue_max; /* maximum queue size */
494 u_int queue_act; /* actual queue size */
495 TAILQ_HEAD(,ccconn) connq; /* pending connections */
496 struct ccconn *accepted;
497 struct uni_ie_cause cause[2]; /* cause from connection */
498 u_int aborted;
499};
500
501/* set user to new state */
502void cc_user_set_state(struct ccuser *, enum user_state);
503
504/* return string for state */
505const char *cc_user_state2str(u_int);
506
507/* log on a user */
508#ifdef CCATM_DEBUG
509#if defined(__GNUC__) && __GNUC__ < 3
510#define cc_user_log(U, FMT, ARGS...) do { \
511 (U)->cc->funcs->log("%s (user=%p): " FMT, __FUNCTION__, \
512 (U) , ## ARGS); \
513 } while (0)
514#else
515#define cc_user_log(U, FMT, ...) do { \
516 (U)->cc->funcs->log("%s (user=%p): " FMT, __func__, \
517 (U), __VA_ARGS__); \
518 } while (0)
519#endif
520#else
521#if defined(__GNUC__) && __GNUC__ < 3
522#define cc_user_log(U, FMT, ARGS...) do { } while (0)
523#else
524#define cc_user_log(U, FMT, ...) do { } while (0)
525#endif
526#endif
527
528/* Handle a signal to this user */
529void cc_user_sig_handle(struct ccuser *, enum user_sig, void *, u_int);
530
531/*
532 * Addresses
533 */
534struct ccaddr {
535 TAILQ_ENTRY(ccaddr) port_link;
536 struct uni_addr addr;
537};
538
539/* signal to connection */
540int cc_conn_sig(struct ccconn *, enum conn_sig, void *arg);
541
542/* signal with message to connection */
543int cc_conn_sig_msg(struct ccconn *, enum conn_sig, struct uni_msg *);
544int cc_conn_sig_msg_nodef(struct ccconn *, enum conn_sig, struct uni_msg *);
545
546/* response signal to connection */
547int cc_conn_resp(struct ccconn *, enum conn_sig, u_int, u_int, u_int);
548
549/* flush all signals to a given connection */
550void cc_conn_sig_flush(struct ccconn *);
551
552/* Queue a signal to this user */
553int cc_user_sig(struct ccuser *, enum user_sig, void *, u_int);
554
555/* Queue a signal with message to this user */
556int cc_user_sig_msg(struct ccuser *, enum user_sig, struct uni_msg *);
557
558/* Flush all signals to a given user */
559void cc_user_sig_flush(struct ccuser *);
560
561/* flush all signals */
562void cc_sig_flush_all(struct ccdata *);