ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / net / llc / llc_c_ev.c
1 /*
2  * llc_c_ev.c - Connection component state transition event qualifiers
3  *
4  * A 'state' consists of a number of possible event matching functions,
5  * the actions associated with each being executed when that event is
6  * matched; a 'state machine' accepts events in a serial fashion from an
7  * event queue. Each event is passed to each successive event matching
8  * function until a match is made (the event matching function returns
9  * success, or '0') or the list of event matching functions is exhausted.
10  * If a match is made, the actions associated with the event are executed
11  * and the state is changed to that event's transition state. Before some
12  * events are recognized, even after a match has been made, a certain
13  * number of 'event qualifier' functions must also be executed. If these
14  * all execute successfully, then the event is finally executed.
15  *
16  * These event functions must return 0 for success, to show a matched
17  * event, of 1 if the event does not match. Event qualifier functions
18  * must return a 0 for success or a non-zero for failure. Each function
19  * is simply responsible for verifying one single thing and returning
20  * either a success or failure.
21  *
22  * All of followed event functions are described in 802.2 LLC Protocol
23  * standard document except two functions that we added that will explain
24  * in their comments, at below.
25  *
26  * Copyright (c) 1997 by Procom Technology, Inc.
27  *               2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
28  *
29  * This program can be redistributed or modified under the terms of the
30  * GNU General Public License as published by the Free Software Foundation.
31  * This program is distributed without any warranty or implied warranty
32  * of merchantability or fitness for a particular purpose.
33  *
34  * See the GNU General Public License for more details.
35  */
36 #include <linux/netdevice.h>
37 #include <net/llc_conn.h>
38 #include <net/llc_sap.h>
39 #include <net/sock.h>
40 #include <net/llc_c_ev.h>
41 #include <net/llc_pdu.h>
42
43 #if 1
44 #define dprintk(args...) printk(KERN_DEBUG args)
45 #else
46 #define dprintk(args...)
47 #endif
48
49 extern u16 llc_circular_between(u8 a, u8 b, u8 c);
50
51 /**
52  *      llc_util_ns_inside_rx_window - check if sequence number is in rx window
53  *      @ns: sequence number of received pdu.
54  *      @vr: sequence number which receiver expects to receive.
55  *      @rw: receive window size of receiver.
56  *
57  *      Checks if sequence number of received PDU is in range of receive
58  *      window. Returns 0 for success, 1 otherwise
59  */
60 static u16 llc_util_ns_inside_rx_window(u8 ns, u8 vr, u8 rw)
61 {
62         return !llc_circular_between(vr, ns,
63                                      (vr + rw - 1) % LLC_2_SEQ_NBR_MODULO);
64 }
65
66 /**
67  *      llc_util_nr_inside_tx_window - check if sequence number is in tx window
68  *      @sk: current connection.
69  *      @nr: N(R) of received PDU.
70  *
71  *      This routine checks if N(R) of received PDU is in range of transmit
72  *      window; on the other hand checks if received PDU acknowledges some
73  *      outstanding PDUs that are in transmit window. Returns 0 for success, 1
74  *      otherwise.
75  */
76 static u16 llc_util_nr_inside_tx_window(struct sock *sk, u8 nr)
77 {
78         u8 nr1, nr2;
79         struct sk_buff *skb;
80         struct llc_pdu_sn *pdu;
81         struct llc_opt *llc = llc_sk(sk);
82         int rc = 0;
83
84         if (llc->dev->flags & IFF_LOOPBACK)
85                 goto out;
86         rc = 1;
87         if (!skb_queue_len(&llc->pdu_unack_q))
88                 goto out;
89         skb = skb_peek(&llc->pdu_unack_q);
90         pdu = llc_pdu_sn_hdr(skb);
91         nr1 = LLC_I_GET_NS(pdu);
92         skb = skb_peek_tail(&llc->pdu_unack_q);
93         pdu = llc_pdu_sn_hdr(skb);
94         nr2 = LLC_I_GET_NS(pdu);
95         rc = !llc_circular_between(nr1, nr, (nr2 + 1) % LLC_2_SEQ_NBR_MODULO);
96 out:
97         return rc;
98 }
99
100 int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
101 {
102         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
103
104         return ev->prim == LLC_CONN_PRIM &&
105                ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
106 }
107
108 int llc_conn_ev_conn_resp(struct sock *sk, struct sk_buff *skb)
109 {
110         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
111
112         return ev->prim == LLC_CONN_PRIM &&
113                ev->prim_type == LLC_PRIM_TYPE_RESP ? 0 : 1;
114 }
115
116 int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
117 {
118         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
119
120         return ev->prim == LLC_DATA_PRIM &&
121                ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
122 }
123
124 int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
125 {
126         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
127
128         return ev->prim == LLC_DISC_PRIM &&
129                ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
130 }
131
132 int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
133 {
134         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
135
136         return ev->prim == LLC_RESET_PRIM &&
137                ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
138 }
139
140 int llc_conn_ev_rst_resp(struct sock *sk, struct sk_buff *skb)
141 {
142         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
143
144         return ev->prim == LLC_RESET_PRIM &&
145                ev->prim_type == LLC_PRIM_TYPE_RESP ? 0 : 1;
146 }
147
148 int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
149 {
150         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
151
152         return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
153                ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
154 }
155
156 int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
157 {
158         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
159
160         return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
161                ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
162 }
163
164 int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb)
165 {
166         return 1;
167 }
168
169 int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
170 {
171         struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
172
173         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
174                LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1;
175 }
176
177 int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
178 {
179         struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
180
181         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
182                LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1;
183 }
184
185 int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
186 {
187         struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
188
189         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
190                LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1;
191 }
192
193 int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
194 {
195         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
196
197         return llc_conn_space(sk, skb) &&
198                LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
199                LLC_I_PF_IS_0(pdu) &&
200                LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
201 }
202
203 int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
204 {
205         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
206
207         return llc_conn_space(sk, skb) &&
208                LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
209                LLC_I_PF_IS_1(pdu) &&
210                LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
211 }
212
213 int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
214                                               struct sk_buff *skb)
215 {
216         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
217         u8 vr = llc_sk(sk)->vR;
218         u8 ns = LLC_I_GET_NS(pdu);
219
220         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
221                LLC_I_PF_IS_0(pdu) && ns != vr &&
222                !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
223 }
224
225 int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
226                                               struct sk_buff *skb)
227 {
228         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
229         u8 vr = llc_sk(sk)->vR;
230         u8 ns = LLC_I_GET_NS(pdu);
231
232         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
233                LLC_I_PF_IS_1(pdu) && ns != vr &&
234                !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
235 }
236
237 int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
238                                              struct sk_buff *skb)
239 {
240         struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb);
241         u8 vr = llc_sk(sk)->vR;
242         u8 ns = LLC_I_GET_NS(pdu);
243         u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
244                  llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
245         if (!rc)
246                 dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
247                         __FUNCTION__, llc_sk(sk)->state, ns, vr);
248         return rc;
249 }
250
251 int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
252 {
253         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
254
255         return llc_conn_space(sk, skb) &&
256                LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
257                LLC_I_PF_IS_0(pdu) &&
258                LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
259 }
260
261 int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
262 {
263         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
264
265         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
266                LLC_I_PF_IS_1(pdu) &&
267                LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
268 }
269
270 int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
271 {
272         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
273
274         return llc_conn_space(sk, skb) &&
275                LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
276                LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
277 }
278
279 int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
280                                               struct sk_buff *skb)
281 {
282         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
283         u8 vr = llc_sk(sk)->vR;
284         u8 ns = LLC_I_GET_NS(pdu);
285
286         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
287                LLC_I_PF_IS_0(pdu) && ns != vr &&
288                !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
289 }
290
291 int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
292                                               struct sk_buff *skb)
293 {
294         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
295         u8 vr = llc_sk(sk)->vR;
296         u8 ns = LLC_I_GET_NS(pdu);
297
298         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
299                LLC_I_PF_IS_1(pdu) && ns != vr &&
300                !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
301 }
302
303 int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
304                                               struct sk_buff *skb)
305 {
306         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
307         u8 vr = llc_sk(sk)->vR;
308         u8 ns = LLC_I_GET_NS(pdu);
309
310         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
311                !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
312 }
313
314 int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
315                                              struct sk_buff *skb)
316 {
317         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
318         u8 vr = llc_sk(sk)->vR;
319         u8 ns = LLC_I_GET_NS(pdu);
320         u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
321                  llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
322         if (!rc)
323                 dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
324                         __FUNCTION__, llc_sk(sk)->state, ns, vr);
325         return rc;
326 }
327
328 int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
329 {
330         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
331
332         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
333                LLC_S_PF_IS_0(pdu) &&
334                LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
335 }
336
337 int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
338 {
339         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
340
341         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
342                LLC_S_PF_IS_1(pdu) &&
343                LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
344 }
345
346 int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
347 {
348         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
349
350         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
351                LLC_S_PF_IS_0(pdu) &&
352                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
353 }
354
355 int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
356 {
357         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
358
359         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
360                LLC_S_PF_IS_1(pdu) &&
361                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
362 }
363
364 int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
365 {
366         struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
367
368         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
369                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
370 }
371
372 int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
373 {
374         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
375
376         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
377                LLC_S_PF_IS_0(pdu) &&
378                LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
379 }
380
381 int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
382 {
383         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
384
385         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
386                LLC_S_PF_IS_1(pdu) &&
387                LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
388 }
389
390 int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
391 {
392         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
393
394         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
395                LLC_S_PF_IS_0(pdu) &&
396                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
397 }
398
399 int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
400 {
401         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
402
403         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
404                LLC_S_PF_IS_1(pdu) &&
405                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
406 }
407
408 int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
409 {
410         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
411
412         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
413                LLC_S_PF_IS_0(pdu) &&
414                LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
415 }
416
417 int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
418 {
419         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
420
421         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
422                LLC_S_PF_IS_1(pdu) &&
423                LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
424 }
425
426 int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
427 {
428         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
429
430         return llc_conn_space(sk, skb) &&
431                LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
432                LLC_S_PF_IS_0(pdu) &&
433                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
434 }
435
436 int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
437 {
438         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
439
440         return llc_conn_space(sk, skb) &&
441                LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
442                LLC_S_PF_IS_1(pdu) &&
443                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
444 }
445
446 int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
447 {
448         struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
449
450         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
451                LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1;
452 }
453
454 int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
455 {
456         struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
457
458         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
459                LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_UA ? 0 : 1;
460 }
461
462 int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
463 {
464         u16 rc = 1;
465         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
466
467         if (LLC_PDU_IS_CMD(pdu)) {
468                 if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
469                         if (LLC_I_PF_IS_1(pdu))
470                                 rc = 0;
471                 } else if (LLC_PDU_TYPE_IS_U(pdu) && LLC_U_PF_IS_1(pdu))
472                         rc = 0;
473         }
474         return rc;
475 }
476
477 int llc_conn_ev_rx_xxx_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
478 {
479         u16 rc = 1;
480         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
481
482         if (LLC_PDU_IS_CMD(pdu)) {
483                 if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
484                         if (LLC_I_PF_IS_0(pdu))
485                                 rc = 0;
486                 } else if (LLC_PDU_TYPE_IS_U(pdu))
487                         switch (LLC_U_PDU_CMD(pdu)) {
488                         case LLC_2_PDU_CMD_SABME:
489                         case LLC_2_PDU_CMD_DISC:
490                                 if (LLC_U_PF_IS_0(pdu))
491                                         rc = 0;
492                                 break;
493                         }
494         }
495         return rc;
496 }
497
498 int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
499 {
500         u16 rc = 1;
501         struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
502
503         if (LLC_PDU_IS_CMD(pdu)) {
504                 if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
505                         rc = 0;
506                 else if (LLC_PDU_TYPE_IS_U(pdu))
507                         switch (LLC_U_PDU_CMD(pdu)) {
508                         case LLC_2_PDU_CMD_SABME:
509                         case LLC_2_PDU_CMD_DISC:
510                                 rc = 0;
511                                 break;
512                         }
513         }
514         return rc;
515 }
516
517 int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
518 {
519         u16 rc = 1;
520         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
521
522         if (LLC_PDU_IS_RSP(pdu)) {
523                 if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
524                         if (LLC_I_PF_IS_1(pdu))
525                                 rc = 0;
526                 } else if (LLC_PDU_TYPE_IS_U(pdu))
527                         switch (LLC_U_PDU_RSP(pdu)) {
528                         case LLC_2_PDU_RSP_UA:
529                         case LLC_2_PDU_RSP_DM:
530                         case LLC_2_PDU_RSP_FRMR:
531                                 if (LLC_U_PF_IS_1(pdu))
532                                         rc = 0;
533                                 break;
534                         }
535         }
536         return rc;
537 }
538
539 int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
540 {
541         u16 rc = 1;
542         struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
543
544         if (LLC_PDU_IS_RSP(pdu)) {
545                 if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
546                         rc = 0;
547                 else if (LLC_PDU_TYPE_IS_U(pdu))
548                         switch (LLC_U_PDU_RSP(pdu)) {
549                         case LLC_2_PDU_RSP_UA:
550                         case LLC_2_PDU_RSP_DM:
551                         case LLC_2_PDU_RSP_FRMR:
552                                 rc = 0;
553                                 break;
554                         }
555         }
556
557         return rc;
558 }
559
560 int llc_conn_ev_rx_xxx_yyy(struct sock *sk, struct sk_buff *skb)
561 {
562         u16 rc = 1;
563         struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
564
565         if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
566                 rc = 0;
567         else if (LLC_PDU_TYPE_IS_U(pdu))
568                 switch (LLC_U_PDU_CMD(pdu)) {
569                 case LLC_2_PDU_CMD_SABME:
570                 case LLC_2_PDU_CMD_DISC:
571                 case LLC_2_PDU_RSP_UA:
572                 case LLC_2_PDU_RSP_DM:
573                 case LLC_2_PDU_RSP_FRMR:
574                         rc = 0;
575                         break;
576                 }
577         return rc;
578 }
579
580 int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
581                                                struct sk_buff *skb)
582 {
583         u16 rc = 1;
584         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
585         u8 vs = llc_sk(sk)->vS;
586         u8 nr = LLC_I_GET_NR(pdu);
587
588         if (LLC_PDU_IS_CMD(pdu) &&
589             (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
590             nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
591                 dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
592                         __FUNCTION__, llc_sk(sk)->state, vs, nr);
593                 rc = 0;
594         }
595         return rc;
596 }
597
598 int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
599                                                struct sk_buff *skb)
600 {
601         u16 rc = 1;
602         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
603         u8 vs = llc_sk(sk)->vS;
604         u8 nr = LLC_I_GET_NR(pdu);
605
606         if (LLC_PDU_IS_RSP(pdu) &&
607             (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
608             nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
609                 rc = 0;
610                 dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
611                         __FUNCTION__, llc_sk(sk)->state, vs, nr);
612         }
613         return rc;
614 }
615
616 int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb)
617 {
618         return 0;
619 }
620
621 int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb)
622 {
623         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
624
625         return ev->type != LLC_CONN_EV_TYPE_P_TMR;
626 }
627
628 int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb)
629 {
630         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
631
632         return ev->type != LLC_CONN_EV_TYPE_ACK_TMR;
633 }
634
635 int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb)
636 {
637         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
638
639         return ev->type != LLC_CONN_EV_TYPE_REJ_TMR;
640 }
641
642 int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb)
643 {
644         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
645
646         return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR;
647 }
648
649 int llc_conn_ev_any_tmr_exp(struct sock *sk, struct sk_buff *skb)
650 {
651         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
652
653         return ev->type == LLC_CONN_EV_TYPE_P_TMR ||
654                ev->type == LLC_CONN_EV_TYPE_ACK_TMR ||
655                ev->type == LLC_CONN_EV_TYPE_REJ_TMR ||
656                ev->type == LLC_CONN_EV_TYPE_BUSY_TMR ? 0 : 1;
657 }
658
659 int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb)
660 {
661         return 1;
662 }
663
664 int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb)
665 {
666         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
667
668         return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
669                ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
670 }
671
672 /* Event qualifier functions
673  *
674  * these functions simply verify the value of a state flag associated with
675  * the connection and return either a 0 for success or a non-zero value
676  * for not-success; verify the event is the type we expect
677  */
678 int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, struct sk_buff *skb)
679 {
680         return llc_sk(sk)->data_flag != 1;
681 }
682
683 int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, struct sk_buff *skb)
684 {
685         return llc_sk(sk)->data_flag;
686 }
687
688 int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, struct sk_buff *skb)
689 {
690         return llc_sk(sk)->data_flag != 2;
691 }
692
693 int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb)
694 {
695         return llc_sk(sk)->p_flag != 1;
696 }
697
698 /**
699  *      conn_ev_qlfy_last_frame_eq_1 - checks if frame is last in tx window
700  *      @sk: current connection structure.
701  *      @skb: current event.
702  *
703  *      This function determines when frame which is sent, is last frame of
704  *      transmit window, if it is then this function return zero else return
705  *      one.  This function is used for sending last frame of transmit window
706  *      as I-format command with p-bit set to one. Returns 0 if frame is last
707  *      frame, 1 otherwise.
708  */
709 int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, struct sk_buff *skb)
710 {
711         return !(skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k);
712 }
713
714 /**
715  *      conn_ev_qlfy_last_frame_eq_0 - checks if frame isn't last in tx window
716  *      @sk: current connection structure.
717  *      @skb: current event.
718  *
719  *      This function determines when frame which is sent, isn't last frame of
720  *      transmit window, if it isn't then this function return zero else return
721  *      one. Returns 0 if frame isn't last frame, 1 otherwise.
722  */
723 int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, struct sk_buff *skb)
724 {
725         return skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k;
726 }
727
728 int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb)
729 {
730         return llc_sk(sk)->p_flag;
731 }
732
733 int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb)
734 {
735         u8 f_bit;
736
737         llc_pdu_decode_pf_bit(skb, &f_bit);
738         return llc_sk(sk)->p_flag == f_bit ? 0 : 1;
739 }
740
741 int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, struct sk_buff *skb)
742 {
743         return llc_sk(sk)->remote_busy_flag;
744 }
745
746 int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, struct sk_buff *skb)
747 {
748         return !llc_sk(sk)->remote_busy_flag;
749 }
750
751 int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, struct sk_buff *skb)
752 {
753         return !(llc_sk(sk)->retry_count < llc_sk(sk)->n2);
754 }
755
756 int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, struct sk_buff *skb)
757 {
758         return !(llc_sk(sk)->retry_count >= llc_sk(sk)->n2);
759 }
760
761 int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb)
762 {
763         return !llc_sk(sk)->s_flag;
764 }
765
766 int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb)
767 {
768         return llc_sk(sk)->s_flag;
769 }
770
771 int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, struct sk_buff *skb)
772 {
773         return !llc_sk(sk)->cause_flag;
774 }
775
776 int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, struct sk_buff *skb)
777 {
778         return llc_sk(sk)->cause_flag;
779 }
780
781 int llc_conn_ev_qlfy_init_p_f_cycle(struct sock *sk, struct sk_buff *skb)
782 {
783         return 0;
784 }
785
786 int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, struct sk_buff *skb)
787 {
788         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
789
790         ev->status = LLC_STATUS_CONN;
791         return 0;
792 }
793
794 int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, struct sk_buff *skb)
795 {
796         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
797
798         ev->status = LLC_STATUS_DISC;
799         return 0;
800 }
801
802 int llc_conn_ev_qlfy_set_status_impossible(struct sock *sk, struct sk_buff *skb)
803 {
804         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
805
806         ev->status = LLC_STATUS_IMPOSSIBLE;
807         return 0;
808 }
809
810 int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, struct sk_buff *skb)
811 {
812         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
813
814         ev->status = LLC_STATUS_FAILED;
815         return 0;
816 }
817
818 int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
819                                             struct sk_buff *skb)
820 {
821         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
822
823         ev->status = LLC_STATUS_REMOTE_BUSY;
824         return 0;
825 }
826
827 int llc_conn_ev_qlfy_set_status_received(struct sock *sk, struct sk_buff *skb)
828 {
829         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
830
831         ev->status = LLC_STATUS_RECEIVED;
832         return 0;
833 }
834
835 int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, struct sk_buff *skb)
836 {
837         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
838
839         ev->status = LLC_STATUS_REFUSE;
840         return 0;
841 }
842
843 int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, struct sk_buff *skb)
844 {
845         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
846
847         ev->status = LLC_STATUS_CONFLICT;
848         return 0;
849 }
850
851 int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, struct sk_buff *skb)
852 {
853         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
854
855         ev->status = LLC_STATUS_RESET_DONE;
856         return 0;
857 }