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