c53b823242684d5715fdb14a9a431c1ecddb63a3
[linux-3.10.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_sock *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_empty(&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         const 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_data_req(struct sock *sk, struct sk_buff *skb)
109 {
110         const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
111
112         return ev->prim == LLC_DATA_PRIM &&
113                ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
114 }
115
116 int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
117 {
118         const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
119
120         return ev->prim == LLC_DISC_PRIM &&
121                ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
122 }
123
124 int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
125 {
126         const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
127
128         return ev->prim == LLC_RESET_PRIM &&
129                ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
130 }
131
132 int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
133 {
134         const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
135
136         return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
137                ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
138 }
139
140 int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
141 {
142         const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
143
144         return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
145                ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
146 }
147
148 int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb)
149 {
150         return 1;
151 }
152
153 int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
154 {
155         const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
156
157         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
158                LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1;
159 }
160
161 int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
162 {
163         const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
164
165         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
166                LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1;
167 }
168
169 int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
170 {
171         const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
172
173         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
174                LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1;
175 }
176
177 int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
178 {
179         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
180
181         return llc_conn_space(sk, skb) &&
182                LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
183                LLC_I_PF_IS_0(pdu) &&
184                LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
185 }
186
187 int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
188 {
189         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
190
191         return llc_conn_space(sk, skb) &&
192                LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
193                LLC_I_PF_IS_1(pdu) &&
194                LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
195 }
196
197 int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
198                                               struct sk_buff *skb)
199 {
200         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
201         const u8 vr = llc_sk(sk)->vR;
202         const u8 ns = LLC_I_GET_NS(pdu);
203
204         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
205                LLC_I_PF_IS_0(pdu) && ns != vr &&
206                !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
207 }
208
209 int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
210                                               struct sk_buff *skb)
211 {
212         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
213         const u8 vr = llc_sk(sk)->vR;
214         const u8 ns = LLC_I_GET_NS(pdu);
215
216         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
217                LLC_I_PF_IS_1(pdu) && ns != vr &&
218                !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
219 }
220
221 int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
222                                              struct sk_buff *skb)
223 {
224         const struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb);
225         const u8 vr = llc_sk(sk)->vR;
226         const u8 ns = LLC_I_GET_NS(pdu);
227         const u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
228                 ns != vr &&
229                  llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
230         if (!rc)
231                 dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
232                         __FUNCTION__, llc_sk(sk)->state, ns, vr);
233         return rc;
234 }
235
236 int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
237 {
238         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
239
240         return llc_conn_space(sk, skb) &&
241                LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
242                LLC_I_PF_IS_0(pdu) &&
243                LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
244 }
245
246 int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
247 {
248         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
249
250         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
251                LLC_I_PF_IS_1(pdu) &&
252                LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
253 }
254
255 int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
256 {
257         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
258
259         return llc_conn_space(sk, skb) &&
260                LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
261                LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
262 }
263
264 int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
265                                               struct sk_buff *skb)
266 {
267         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
268         const u8 vr = llc_sk(sk)->vR;
269         const u8 ns = LLC_I_GET_NS(pdu);
270
271         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
272                LLC_I_PF_IS_0(pdu) && ns != vr &&
273                !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
274 }
275
276 int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
277                                               struct sk_buff *skb)
278 {
279         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
280         const u8 vr = llc_sk(sk)->vR;
281         const u8 ns = LLC_I_GET_NS(pdu);
282
283         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
284                LLC_I_PF_IS_1(pdu) && ns != vr &&
285                !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
286 }
287
288 int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
289                                               struct sk_buff *skb)
290 {
291         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
292         const u8 vr = llc_sk(sk)->vR;
293         const u8 ns = LLC_I_GET_NS(pdu);
294
295         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
296                !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
297 }
298
299 int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
300                                              struct sk_buff *skb)
301 {
302         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
303         const u8 vr = llc_sk(sk)->vR;
304         const u8 ns = LLC_I_GET_NS(pdu);
305         const u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
306                 ns != vr &&
307                  llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
308         if (!rc)
309                 dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
310                         __FUNCTION__, llc_sk(sk)->state, ns, vr);
311         return rc;
312 }
313
314 int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
315 {
316         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
317
318         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
319                LLC_S_PF_IS_0(pdu) &&
320                LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
321 }
322
323 int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
324 {
325         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
326
327         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
328                LLC_S_PF_IS_1(pdu) &&
329                LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
330 }
331
332 int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
333 {
334         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
335
336         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
337                LLC_S_PF_IS_0(pdu) &&
338                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
339 }
340
341 int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
342 {
343         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
344
345         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
346                LLC_S_PF_IS_1(pdu) &&
347                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
348 }
349
350 int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
351 {
352         const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
353
354         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
355                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
356 }
357
358 int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
359 {
360         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
361
362         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
363                LLC_S_PF_IS_0(pdu) &&
364                LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
365 }
366
367 int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
368 {
369         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
370
371         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
372                LLC_S_PF_IS_1(pdu) &&
373                LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
374 }
375
376 int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
377 {
378         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
379
380         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
381                LLC_S_PF_IS_0(pdu) &&
382                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
383 }
384
385 int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
386 {
387         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
388
389         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
390                LLC_S_PF_IS_1(pdu) &&
391                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
392 }
393
394 int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
395 {
396         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
397
398         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
399                LLC_S_PF_IS_0(pdu) &&
400                LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
401 }
402
403 int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
404 {
405         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
406
407         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
408                LLC_S_PF_IS_1(pdu) &&
409                LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
410 }
411
412 int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
413 {
414         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
415
416         return llc_conn_space(sk, skb) &&
417                LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
418                LLC_S_PF_IS_0(pdu) &&
419                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
420 }
421
422 int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
423 {
424         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
425
426         return llc_conn_space(sk, skb) &&
427                LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
428                LLC_S_PF_IS_1(pdu) &&
429                LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
430 }
431
432 int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
433 {
434         const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
435
436         return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
437                LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1;
438 }
439
440 int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
441 {
442         struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
443
444         return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
445                LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_UA ? 0 : 1;
446 }
447
448 int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
449 {
450         u16 rc = 1;
451         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
452
453         if (LLC_PDU_IS_CMD(pdu)) {
454                 if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
455                         if (LLC_I_PF_IS_1(pdu))
456                                 rc = 0;
457                 } else if (LLC_PDU_TYPE_IS_U(pdu) && LLC_U_PF_IS_1(pdu))
458                         rc = 0;
459         }
460         return rc;
461 }
462
463 int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
464 {
465         u16 rc = 1;
466         const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
467
468         if (LLC_PDU_IS_CMD(pdu)) {
469                 if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
470                         rc = 0;
471                 else if (LLC_PDU_TYPE_IS_U(pdu))
472                         switch (LLC_U_PDU_CMD(pdu)) {
473                         case LLC_2_PDU_CMD_SABME:
474                         case LLC_2_PDU_CMD_DISC:
475                                 rc = 0;
476                                 break;
477                         }
478         }
479         return rc;
480 }
481
482 int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
483 {
484         u16 rc = 1;
485         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
486
487         if (LLC_PDU_IS_RSP(pdu)) {
488                 if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
489                         if (LLC_I_PF_IS_1(pdu))
490                                 rc = 0;
491                 } else if (LLC_PDU_TYPE_IS_U(pdu))
492                         switch (LLC_U_PDU_RSP(pdu)) {
493                         case LLC_2_PDU_RSP_UA:
494                         case LLC_2_PDU_RSP_DM:
495                         case LLC_2_PDU_RSP_FRMR:
496                                 if (LLC_U_PF_IS_1(pdu))
497                                         rc = 0;
498                                 break;
499                         }
500         }
501         return rc;
502 }
503
504 int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
505 {
506         u16 rc = 1;
507         const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
508
509         if (LLC_PDU_IS_RSP(pdu)) {
510                 if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
511                         rc = 0;
512                 else if (LLC_PDU_TYPE_IS_U(pdu))
513                         switch (LLC_U_PDU_RSP(pdu)) {
514                         case LLC_2_PDU_RSP_UA:
515                         case LLC_2_PDU_RSP_DM:
516                         case LLC_2_PDU_RSP_FRMR:
517                                 rc = 0;
518                                 break;
519                         }
520         }
521
522         return rc;
523 }
524
525 int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
526                                                struct sk_buff *skb)
527 {
528         u16 rc = 1;
529         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
530         const u8 vs = llc_sk(sk)->vS;
531         const u8 nr = LLC_I_GET_NR(pdu);
532
533         if (LLC_PDU_IS_CMD(pdu) &&
534             (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
535             nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
536                 dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
537                         __FUNCTION__, llc_sk(sk)->state, vs, nr);
538                 rc = 0;
539         }
540         return rc;
541 }
542
543 int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
544                                                struct sk_buff *skb)
545 {
546         u16 rc = 1;
547         const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
548         const u8 vs = llc_sk(sk)->vS;
549         const u8 nr = LLC_I_GET_NR(pdu);
550
551         if (LLC_PDU_IS_RSP(pdu) &&
552             (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
553             nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
554                 rc = 0;
555                 dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
556                         __FUNCTION__, llc_sk(sk)->state, vs, nr);
557         }
558         return rc;
559 }
560
561 int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb)
562 {
563         return 0;
564 }
565
566 int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb)
567 {
568         const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
569
570         return ev->type != LLC_CONN_EV_TYPE_P_TMR;
571 }
572
573 int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb)
574 {
575         const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
576
577         return ev->type != LLC_CONN_EV_TYPE_ACK_TMR;
578 }
579
580 int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb)
581 {
582         const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
583
584         return ev->type != LLC_CONN_EV_TYPE_REJ_TMR;
585 }
586
587 int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb)
588 {
589         const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
590
591         return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR;
592 }
593
594 int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb)
595 {
596         return 1;
597 }
598
599 int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb)
600 {
601         const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
602
603         return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
604                ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
605 }
606
607 /* Event qualifier functions
608  *
609  * these functions simply verify the value of a state flag associated with
610  * the connection and return either a 0 for success or a non-zero value
611  * for not-success; verify the event is the type we expect
612  */
613 int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, struct sk_buff *skb)
614 {
615         return llc_sk(sk)->data_flag != 1;
616 }
617
618 int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, struct sk_buff *skb)
619 {
620         return llc_sk(sk)->data_flag;
621 }
622
623 int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, struct sk_buff *skb)
624 {
625         return llc_sk(sk)->data_flag != 2;
626 }
627
628 int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb)
629 {
630         return llc_sk(sk)->p_flag != 1;
631 }
632
633 /**
634  *      conn_ev_qlfy_last_frame_eq_1 - checks if frame is last in tx window
635  *      @sk: current connection structure.
636  *      @skb: current event.
637  *
638  *      This function determines when frame which is sent, is last frame of
639  *      transmit window, if it is then this function return zero else return
640  *      one.  This function is used for sending last frame of transmit window
641  *      as I-format command with p-bit set to one. Returns 0 if frame is last
642  *      frame, 1 otherwise.
643  */
644 int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, struct sk_buff *skb)
645 {
646         return !(skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k);
647 }
648
649 /**
650  *      conn_ev_qlfy_last_frame_eq_0 - checks if frame isn't last in tx window
651  *      @sk: current connection structure.
652  *      @skb: current event.
653  *
654  *      This function determines when frame which is sent, isn't last frame of
655  *      transmit window, if it isn't then this function return zero else return
656  *      one. Returns 0 if frame isn't last frame, 1 otherwise.
657  */
658 int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, struct sk_buff *skb)
659 {
660         return skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k;
661 }
662
663 int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb)
664 {
665         return llc_sk(sk)->p_flag;
666 }
667
668 int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb)
669 {
670         u8 f_bit;
671
672         llc_pdu_decode_pf_bit(skb, &f_bit);
673         return llc_sk(sk)->p_flag == f_bit ? 0 : 1;
674 }
675
676 int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, struct sk_buff *skb)
677 {
678         return llc_sk(sk)->remote_busy_flag;
679 }
680
681 int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, struct sk_buff *skb)
682 {
683         return !llc_sk(sk)->remote_busy_flag;
684 }
685
686 int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, struct sk_buff *skb)
687 {
688         return !(llc_sk(sk)->retry_count < llc_sk(sk)->n2);
689 }
690
691 int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, struct sk_buff *skb)
692 {
693         return !(llc_sk(sk)->retry_count >= llc_sk(sk)->n2);
694 }
695
696 int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb)
697 {
698         return !llc_sk(sk)->s_flag;
699 }
700
701 int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb)
702 {
703         return llc_sk(sk)->s_flag;
704 }
705
706 int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, struct sk_buff *skb)
707 {
708         return !llc_sk(sk)->cause_flag;
709 }
710
711 int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, struct sk_buff *skb)
712 {
713         return llc_sk(sk)->cause_flag;
714 }
715
716 int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, struct sk_buff *skb)
717 {
718         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
719
720         ev->status = LLC_STATUS_CONN;
721         return 0;
722 }
723
724 int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, struct sk_buff *skb)
725 {
726         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
727
728         ev->status = LLC_STATUS_DISC;
729         return 0;
730 }
731
732 int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, struct sk_buff *skb)
733 {
734         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
735
736         ev->status = LLC_STATUS_FAILED;
737         return 0;
738 }
739
740 int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
741                                             struct sk_buff *skb)
742 {
743         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
744
745         ev->status = LLC_STATUS_REMOTE_BUSY;
746         return 0;
747 }
748
749 int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, struct sk_buff *skb)
750 {
751         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
752
753         ev->status = LLC_STATUS_REFUSE;
754         return 0;
755 }
756
757 int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, struct sk_buff *skb)
758 {
759         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
760
761         ev->status = LLC_STATUS_CONFLICT;
762         return 0;
763 }
764
765 int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, struct sk_buff *skb)
766 {
767         struct llc_conn_state_ev *ev = llc_conn_ev(skb);
768
769         ev->status = LLC_STATUS_RESET_DONE;
770         return 0;
771 }