summaryrefslogtreecommitdiffstats
path: root/sys/contrib/ngatm/netnatm/saal/sscoppriv.h
blob: e2b055530b1fe826edc194d342105e0ec8118cbd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
/*
 * Copyright (c) 1996-2003
 *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
 * 	All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * Author: Hartmut Brandt <harti@freebsd.org>
 *
 * $Begemot: libunimsg/netnatm/saal/sscoppriv.h,v 1.4 2004/07/08 08:22:17 brandt Exp $
 *
 * Private SSCOP definitions.
 *
 */
#ifdef _KERNEL
#ifdef __FreeBSD__
#include <netgraph/atm/sscop/ng_sscop_cust.h>
#endif
#else	/* !_KERNEL */
#include "sscopcust.h"
#endif

/* Argh. BSDi */
#ifndef _BYTE_ORDER
#ifndef BYTE_ORDER
#error "_BYTE_ORDER not defined"
#endif
#define _BYTE_ORDER	BYTE_ORDER
#define _LITTLE_ENDIAN	LITTLE_ENDIAN
#define	_BIG_ENDIAN	BIG_ENDIAN
#endif

/*
 * PDU trailer
 */
union pdu {
  u_int			sscop_null;
  struct {
#if _BYTE_ORDER == _BIG_ENDIAN
	u_int		pl : 2;		/* pad length */
	u_int		: 1;		/* reserved field */
	u_int		s : 1;		/* source */
	u_int		type : 4;	/* PDU type */
	u_int		ns : 24;	/* sequence number */
#else
	u_int		ns : 24;	/* sequence number */
	u_int		type : 4;	/* PDU type */
	u_int		s : 1;		/* source */
	u_int		: 1;		/* reserved field */
	u_int		pl : 2;		/* pad length */
#endif
  } ss;
};
#define sscop_pl	ss.pl
#define sscop_s		ss.s
#define sscop_type	ss.type
#define sscop_ns	ss.ns

/*
 * seqno list entry format
 */
union seqno {
  u_int			sscop_null;
  struct {
#if _BYTE_ORDER == _BIG_ENDIAN
	u_int		: 8;		/* pad */
	u_int		n : 24;		/* seqno */
#else
	u_int		n : 24;		/* seqno */
	u_int		: 8;		/* pad */
#endif
  } ss;
};
#define sscop_n	ss.n

/*
 * Begin pdu
 */
union bgn {
  u_int			sscop_null;
  struct {
#if _BYTE_ORDER == _BIG_ENDIAN
	u_int	: 24;			/* reserved */
	u_int	bgns : 8;		/* VT_MR */
#else
	u_int	bgns : 8;		/* VT_MR */
	u_int	: 24;			/* reserved */
#endif
  } ss;
};
#define sscop_bgns	ss.bgns

/*
 * pdu types
 */
enum pdu_type {
	PDU_BGN		= 0x1,	/* request initialization */
	PDU_BGAK	= 0x2,	/* request acknowledgement */
	PDU_END		= 0x3,	/* disconnect command */
	PDU_ENDAK	= 0x4,	/* disconnect acknowledgement */
	PDU_RS		= 0x5,	/* resynchronisation command */
	PDU_RSAK	= 0x6,	/* resynchronisation acknowledgement */
	PDU_BGREJ	= 0x7,	/* connection reject */
	PDU_SD		= 0x8,	/* sequenced connection-mode data */
	PDU_ER		= 0x9,	/* recovery command */
	PDU_POLL	= 0xa,	/* xmit state info with req. for recv state */
	PDU_STAT	= 0xb,	/* solicited receiver state info */
	PDU_USTAT	= 0xc,	/* unsolicited receiver state info */
	PDU_UD		= 0xd,	/* unumbered user data */
	PDU_MD		= 0xe,	/* unumbered management data */
	PDU_ERAK	= 0xf,	/* recovery acknowledgement */
};


/*
 * These are all signals, that are used by SSCOP. Don't change the order or
 * number without also changing the associated tables.
 */
enum sscop_sigtype {
	/* received PDU's */
	SIG_BGN,		/* request initialization */
	SIG_BGAK,		/* request acknowledgement */
	SIG_END,		/* disconnect command */
	SIG_ENDAK,		/* disconnect acknowledgement */
	SIG_RS,			/* resynchronisation command */
	SIG_RSAK,		/* resynchronisation acknowledgement */
	SIG_BGREJ,		/* connection reject */
	SIG_SD,			/* sequenced connection-mode data */
	SIG_ER,			/* recovery command */
	SIG_POLL,		/* xmitter state info with req for recv state */
	SIG_STAT,		/* solicited receiver state info */
	SIG_USTAT,		/* unsolicited receiver state info */
	SIG_UD,			/* unumbered user data */
	SIG_MD,			/* unumbered management data */
	SIG_ERAK,		/* recovery acknoledgement */

	/* timer expiry */
	SIG_T_CC,		/* CC timer */
	SIG_T_POLL,		/* POLL timer */
	SIG_T_KA,		/* KEEP ALIVE timer */
	SIG_T_NR,		/* NO RESPONSE timer */
	SIG_T_IDLE,		/* IDLE timer */

	/* user originated signals */
	SIG_PDU_Q,		/* PDU enqueued pseudosignal */
	SIG_USER_DATA,		/* user data request */
	SIG_ESTAB_REQ,		/* establish connection request */
	SIG_ESTAB_RESP,		/* establish connection response */
	SIG_RELEASE_REQ,	/* release connection request */
	SIG_RECOVER,		/* automatic recover response */
	SIG_SYNC_REQ,		/* resynchronisation request */
	SIG_SYNC_RESP,		/* resynchronisation response */
	SIG_UDATA,		/* UDATA request */
	SIG_MDATA,		/* MDATA request */
	SIG_UPDU_Q,		/* UDATA PDU enqueued pseudosignal */
	SIG_MPDU_Q,		/* MDATA PDU enqueued pseudosignal */
	SIG_RETRIEVE,		/* RETRIEVE */

	/* number of signals */
	SIG_NUM
};

/*
 * This is a message as contained in a sscop message queue. It holds a pointer
 * to the real message.
 */
struct sscop_msg {
	sscop_msgq_link_t link;
	u_int		seqno;		/* seq no */
	u_int		poll_seqno;	/* poll seqno (for messages in xmit buffer) */
	u_int		rexmit;		/* in retransmission queue? */
	struct SSCOP_MBUF_T *m;		/* the message */
};

/*
 * This structure is used to hold signals in the signal queue
 */
struct sscop_sig {
	sscop_sigq_link_t link;		/* next signal */
	enum sscop_sigtype sig;		/* THE signal */
	struct sscop_msg *msg;		/* signal argument (message) */
};

/*
 * This structure holds the entire sscop state
 */
struct sscop {
	enum sscop_state state;	/* current state */
	const struct sscop_funcs *funcs;

	/* send state */
	u_int	vt_s;		/* seqno for next pdu first time transmitted */
	u_int	vt_ps;		/* current poll seqno */
	u_int	vt_a;		/* next expected in-sequence sd pdu */
	u_int	vt_pa;		/* poll seqno of next stat pdu */
	u_int	vt_ms;		/* maximum allowed send sd seqno */
	u_int	vt_pd;		/* poll data state */
	u_int	vt_cc;		/* connection control state */
	u_int	vt_sq;		/* transmitter connection sequence */

	/* receive state */
	u_int	vr_r;		/* receive state */
	u_int	vr_h;		/* highes expected state */
	u_int	vr_mr;		/* maximum acceptable */
	u_int	vr_sq;		/* receiver connection state */

	/* timers */
	sscop_timer_t t_cc;	/* timer_CC */
	sscop_timer_t t_nr;	/* timer_NO_RESPONSE */
	sscop_timer_t t_ka;	/* timer KEEP_ALIVE */
	sscop_timer_t t_poll;	/* timer_POLL */
	sscop_timer_t t_idle;	/* idle timer */

	/* maximum values */
	u_int	maxj;		/* maximum uu-info */
	u_int	maxk;		/* maximum info */
	u_int	maxcc;		/* maximum number of bgn, end, er and rs */
	u_int	maxpd;		/* maximum value of vt_pd */
	u_int	maxstat;	/* maximum length of list */
	u_int	timercc;	/* connection control timer */
	u_int	timerka;	/* keep alive timer */
	u_int	timernr;	/* no response timer */
	u_int	timerpoll;	/* polling */
	u_int	timeridle;	/* idle timer */
	u_int	robustness;	/* atmf/97-0216 robustness enhancement */
	u_int	poll_after_rex;	/* optional POLL after re-transmission */
	u_int	mr;		/* initial window */

	/*
	 * buffers and queues.
	 * All expect the xq hold SD PDUs.
	 */
	sscop_msgq_head_t xq;	/* xmit queue (input from user before xmit) */
	sscop_msgq_head_t uxq;	/* UD xmit queue */
	sscop_msgq_head_t mxq;	/* MD xmit queue */
	sscop_msgq_head_t xbuf;	/* transmission buffer (SD PDUs transmitted) */
	int	rxq;		/* number of PDUs in retransmission queue */
	sscop_msgq_head_t rbuf;	/* receive buffer (SD PDUs) */
	int	last_end_src;	/* source field from last xmitted end pdu */
	int	clear_buffers;	/* flag */
	int	credit;		/* send window not closed */
	u_int	ll_busy;	/* lower layer busy */
	u_int	rs_mr;		/* N(MR) in last RS PDU */
	u_int	rs_sq;		/* N(SQ) in last RS PDU */
	struct SSCOP_MBUF_T *uu_bgn;	/* last UU data */
	struct SSCOP_MBUF_T *uu_bgak;	/*  ... */
	struct SSCOP_MBUF_T *uu_bgrej;	/*  ... */
	struct SSCOP_MBUF_T *uu_end;	/*  ... */
	struct SSCOP_MBUF_T *uu_rs;	/*  ... */

	/* signal queues */
	sscop_sigq_head_t	sigs;		/* saved signals */
	sscop_sigq_head_t	saved_sigs;	/* saved signals */
	int	in_sig;		/* in signal handler */

	/* debugging */
	u_int		debug;

	/* AA interface */
	void		*aarg;
};


/*
 * Default values for SSCOP
 */
enum {
	MAXK		= 4096,
	MAXMAXK		= 65528,
	MAXJ		= 4096,
	MAXMAXJ		= 65524,
	MAXCC		= 4,
	MAXSTAT		= 67,
	MAXPD		= 25,
	MAXMR		= 128,		/* ??? */
	TIMERCC		= 1000,
	TIMERKA		= 2000,
	TIMERNR		= 7000,
	TIMERPOLL	= 750,
	TIMERIDLE	= 15000,
};

/*
 * Sequence number arithmetic
 */
#define SEQNO_DIFF(A,B)  (((A) < (B)) ? ((A) + (1<<24) - (B)) : ((A) - (B)))

/*
 * Debugging
 */
#ifdef SSCOP_DEBUG
#define VERBOSE(S,M,F)	if ((S)->debug & (M)) (S)->funcs->verbose F
#define VERBERR(S,M,F)	if ((S)->debug & (M)) (S)->funcs->verbose F
#define ISVERBOSE(S,M)	((S)->debug & (M))
#else
#define VERBOSE(S,M,F)
#define VERBERR(S,M,F)
#define ISVERBOSE(S,M)	(0)
#endif
OpenPOWER on IntegriCloud