xref: /openbmc/linux/net/llc/llc_c_ev.c (revision 8be98d2f2a0a262f8bf8a0bc1fdf522b3c7aab17)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * llc_c_ev.c - Connection component state transition event qualifiers
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * A 'state' consists of a number of possible event matching functions,
51da177e4SLinus Torvalds  * the actions associated with each being executed when that event is
61da177e4SLinus Torvalds  * matched; a 'state machine' accepts events in a serial fashion from an
71da177e4SLinus Torvalds  * event queue. Each event is passed to each successive event matching
81da177e4SLinus Torvalds  * function until a match is made (the event matching function returns
91da177e4SLinus Torvalds  * success, or '0') or the list of event matching functions is exhausted.
101da177e4SLinus Torvalds  * If a match is made, the actions associated with the event are executed
111da177e4SLinus Torvalds  * and the state is changed to that event's transition state. Before some
121da177e4SLinus Torvalds  * events are recognized, even after a match has been made, a certain
131da177e4SLinus Torvalds  * number of 'event qualifier' functions must also be executed. If these
141da177e4SLinus Torvalds  * all execute successfully, then the event is finally executed.
151da177e4SLinus Torvalds  *
161da177e4SLinus Torvalds  * These event functions must return 0 for success, to show a matched
171da177e4SLinus Torvalds  * event, of 1 if the event does not match. Event qualifier functions
181da177e4SLinus Torvalds  * must return a 0 for success or a non-zero for failure. Each function
191da177e4SLinus Torvalds  * is simply responsible for verifying one single thing and returning
201da177e4SLinus Torvalds  * either a success or failure.
211da177e4SLinus Torvalds  *
221da177e4SLinus Torvalds  * All of followed event functions are described in 802.2 LLC Protocol
231da177e4SLinus Torvalds  * standard document except two functions that we added that will explain
241da177e4SLinus Torvalds  * in their comments, at below.
251da177e4SLinus Torvalds  *
261da177e4SLinus Torvalds  * Copyright (c) 1997 by Procom Technology, Inc.
271da177e4SLinus Torvalds  * 		 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
281da177e4SLinus Torvalds  *
291da177e4SLinus Torvalds  * This program can be redistributed or modified under the terms of the
301da177e4SLinus Torvalds  * GNU General Public License as published by the Free Software Foundation.
311da177e4SLinus Torvalds  * This program is distributed without any warranty or implied warranty
321da177e4SLinus Torvalds  * of merchantability or fitness for a particular purpose.
331da177e4SLinus Torvalds  *
341da177e4SLinus Torvalds  * See the GNU General Public License for more details.
351da177e4SLinus Torvalds  */
361da177e4SLinus Torvalds #include <linux/netdevice.h>
371da177e4SLinus Torvalds #include <net/llc_conn.h>
381da177e4SLinus Torvalds #include <net/llc_sap.h>
391da177e4SLinus Torvalds #include <net/sock.h>
4072b1ad4aSArnaldo Carvalho de Melo #include <net/llc_c_ac.h>
411da177e4SLinus Torvalds #include <net/llc_c_ev.h>
421da177e4SLinus Torvalds #include <net/llc_pdu.h>
431da177e4SLinus Torvalds 
441da177e4SLinus Torvalds #if 1
451da177e4SLinus Torvalds #define dprintk(args...) printk(KERN_DEBUG args)
461da177e4SLinus Torvalds #else
471da177e4SLinus Torvalds #define dprintk(args...)
481da177e4SLinus Torvalds #endif
491da177e4SLinus Torvalds 
501da177e4SLinus Torvalds /**
511da177e4SLinus Torvalds  *	llc_util_ns_inside_rx_window - check if sequence number is in rx window
521da177e4SLinus Torvalds  *	@ns: sequence number of received pdu.
531da177e4SLinus Torvalds  *	@vr: sequence number which receiver expects to receive.
541da177e4SLinus Torvalds  *	@rw: receive window size of receiver.
551da177e4SLinus Torvalds  *
561da177e4SLinus Torvalds  *	Checks if sequence number of received PDU is in range of receive
571da177e4SLinus Torvalds  *	window. Returns 0 for success, 1 otherwise
581da177e4SLinus Torvalds  */
llc_util_ns_inside_rx_window(u8 ns,u8 vr,u8 rw)591da177e4SLinus Torvalds static u16 llc_util_ns_inside_rx_window(u8 ns, u8 vr, u8 rw)
601da177e4SLinus Torvalds {
611da177e4SLinus Torvalds 	return !llc_circular_between(vr, ns,
621da177e4SLinus Torvalds 				     (vr + rw - 1) % LLC_2_SEQ_NBR_MODULO);
631da177e4SLinus Torvalds }
641da177e4SLinus Torvalds 
651da177e4SLinus Torvalds /**
661da177e4SLinus Torvalds  *	llc_util_nr_inside_tx_window - check if sequence number is in tx window
671da177e4SLinus Torvalds  *	@sk: current connection.
681da177e4SLinus Torvalds  *	@nr: N(R) of received PDU.
691da177e4SLinus Torvalds  *
701da177e4SLinus Torvalds  *	This routine checks if N(R) of received PDU is in range of transmit
711da177e4SLinus Torvalds  *	window; on the other hand checks if received PDU acknowledges some
721da177e4SLinus Torvalds  *	outstanding PDUs that are in transmit window. Returns 0 for success, 1
731da177e4SLinus Torvalds  *	otherwise.
741da177e4SLinus Torvalds  */
llc_util_nr_inside_tx_window(struct sock * sk,u8 nr)751da177e4SLinus Torvalds static u16 llc_util_nr_inside_tx_window(struct sock *sk, u8 nr)
761da177e4SLinus Torvalds {
771da177e4SLinus Torvalds 	u8 nr1, nr2;
781da177e4SLinus Torvalds 	struct sk_buff *skb;
791da177e4SLinus Torvalds 	struct llc_pdu_sn *pdu;
801da177e4SLinus Torvalds 	struct llc_sock *llc = llc_sk(sk);
811da177e4SLinus Torvalds 	int rc = 0;
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds 	if (llc->dev->flags & IFF_LOOPBACK)
841da177e4SLinus Torvalds 		goto out;
851da177e4SLinus Torvalds 	rc = 1;
86b03efcfbSDavid S. Miller 	if (skb_queue_empty(&llc->pdu_unack_q))
871da177e4SLinus Torvalds 		goto out;
881da177e4SLinus Torvalds 	skb = skb_peek(&llc->pdu_unack_q);
891da177e4SLinus Torvalds 	pdu = llc_pdu_sn_hdr(skb);
901da177e4SLinus Torvalds 	nr1 = LLC_I_GET_NS(pdu);
911da177e4SLinus Torvalds 	skb = skb_peek_tail(&llc->pdu_unack_q);
921da177e4SLinus Torvalds 	pdu = llc_pdu_sn_hdr(skb);
931da177e4SLinus Torvalds 	nr2 = LLC_I_GET_NS(pdu);
941da177e4SLinus Torvalds 	rc = !llc_circular_between(nr1, nr, (nr2 + 1) % LLC_2_SEQ_NBR_MODULO);
951da177e4SLinus Torvalds out:
961da177e4SLinus Torvalds 	return rc;
971da177e4SLinus Torvalds }
981da177e4SLinus Torvalds 
llc_conn_ev_conn_req(struct sock * sk,struct sk_buff * skb)991da177e4SLinus Torvalds int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
1001da177e4SLinus Torvalds {
101b9441fc3SArnaldo Carvalho de Melo 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1021da177e4SLinus Torvalds 
1031da177e4SLinus Torvalds 	return ev->prim == LLC_CONN_PRIM &&
1041da177e4SLinus Torvalds 	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
1051da177e4SLinus Torvalds }
1061da177e4SLinus Torvalds 
llc_conn_ev_data_req(struct sock * sk,struct sk_buff * skb)1071da177e4SLinus Torvalds int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
1081da177e4SLinus Torvalds {
109b9441fc3SArnaldo Carvalho de Melo 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1101da177e4SLinus Torvalds 
1111da177e4SLinus Torvalds 	return ev->prim == LLC_DATA_PRIM &&
1121da177e4SLinus Torvalds 	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
1131da177e4SLinus Torvalds }
1141da177e4SLinus Torvalds 
llc_conn_ev_disc_req(struct sock * sk,struct sk_buff * skb)1151da177e4SLinus Torvalds int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
1161da177e4SLinus Torvalds {
117b9441fc3SArnaldo Carvalho de Melo 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1181da177e4SLinus Torvalds 
1191da177e4SLinus Torvalds 	return ev->prim == LLC_DISC_PRIM &&
1201da177e4SLinus Torvalds 	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
1211da177e4SLinus Torvalds }
1221da177e4SLinus Torvalds 
llc_conn_ev_rst_req(struct sock * sk,struct sk_buff * skb)1231da177e4SLinus Torvalds int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
1241da177e4SLinus Torvalds {
125b9441fc3SArnaldo Carvalho de Melo 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1261da177e4SLinus Torvalds 
1271da177e4SLinus Torvalds 	return ev->prim == LLC_RESET_PRIM &&
1281da177e4SLinus Torvalds 	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
1291da177e4SLinus Torvalds }
1301da177e4SLinus Torvalds 
llc_conn_ev_local_busy_detected(struct sock * sk,struct sk_buff * skb)1311da177e4SLinus Torvalds int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
1321da177e4SLinus Torvalds {
133b9441fc3SArnaldo Carvalho de Melo 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1341da177e4SLinus Torvalds 
1351da177e4SLinus Torvalds 	return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
1361da177e4SLinus Torvalds 	       ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
1371da177e4SLinus Torvalds }
1381da177e4SLinus Torvalds 
llc_conn_ev_local_busy_cleared(struct sock * sk,struct sk_buff * skb)1391da177e4SLinus Torvalds int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
1401da177e4SLinus Torvalds {
141b9441fc3SArnaldo Carvalho de Melo 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1421da177e4SLinus Torvalds 
1431da177e4SLinus Torvalds 	return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
1441da177e4SLinus Torvalds 	       ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
1451da177e4SLinus Torvalds }
1461da177e4SLinus Torvalds 
llc_conn_ev_rx_bad_pdu(struct sock * sk,struct sk_buff * skb)1471da177e4SLinus Torvalds int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb)
1481da177e4SLinus Torvalds {
1491da177e4SLinus Torvalds 	return 1;
1501da177e4SLinus Torvalds }
1511da177e4SLinus Torvalds 
llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock * sk,struct sk_buff * skb)1521da177e4SLinus Torvalds int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
1531da177e4SLinus Torvalds {
154b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
1551da177e4SLinus Torvalds 
1561da177e4SLinus Torvalds 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
1571da177e4SLinus Torvalds 	       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1;
1581da177e4SLinus Torvalds }
1591da177e4SLinus Torvalds 
llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock * sk,struct sk_buff * skb)1601da177e4SLinus Torvalds int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
1611da177e4SLinus Torvalds {
162b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
1631da177e4SLinus Torvalds 
1641da177e4SLinus Torvalds 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
1651da177e4SLinus Torvalds 	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1;
1661da177e4SLinus Torvalds }
1671da177e4SLinus Torvalds 
llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock * sk,struct sk_buff * skb)1681da177e4SLinus Torvalds int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
1691da177e4SLinus Torvalds {
170b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
1711da177e4SLinus Torvalds 
1721da177e4SLinus Torvalds 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
1731da177e4SLinus Torvalds 	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1;
1741da177e4SLinus Torvalds }
1751da177e4SLinus Torvalds 
llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock * sk,struct sk_buff * skb)1761da177e4SLinus Torvalds int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
1771da177e4SLinus Torvalds {
178b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1791da177e4SLinus Torvalds 
1801da177e4SLinus Torvalds 	return llc_conn_space(sk, skb) &&
1811da177e4SLinus Torvalds 	       LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
1821da177e4SLinus Torvalds 	       LLC_I_PF_IS_0(pdu) &&
1831da177e4SLinus Torvalds 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
1841da177e4SLinus Torvalds }
1851da177e4SLinus Torvalds 
llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock * sk,struct sk_buff * skb)1861da177e4SLinus Torvalds int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
1871da177e4SLinus Torvalds {
188b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1891da177e4SLinus Torvalds 
1901da177e4SLinus Torvalds 	return llc_conn_space(sk, skb) &&
1911da177e4SLinus Torvalds 	       LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
1921da177e4SLinus Torvalds 	       LLC_I_PF_IS_1(pdu) &&
1931da177e4SLinus Torvalds 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
1941da177e4SLinus Torvalds }
1951da177e4SLinus Torvalds 
llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock * sk,struct sk_buff * skb)1961da177e4SLinus Torvalds int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
1971da177e4SLinus Torvalds 					      struct sk_buff *skb)
1981da177e4SLinus Torvalds {
199b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
200b9441fc3SArnaldo Carvalho de Melo 	const u8 vr = llc_sk(sk)->vR;
201b9441fc3SArnaldo Carvalho de Melo 	const u8 ns = LLC_I_GET_NS(pdu);
2021da177e4SLinus Torvalds 
2031da177e4SLinus Torvalds 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
2041da177e4SLinus Torvalds 	       LLC_I_PF_IS_0(pdu) && ns != vr &&
2051da177e4SLinus Torvalds 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
2061da177e4SLinus Torvalds }
2071da177e4SLinus Torvalds 
llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock * sk,struct sk_buff * skb)2081da177e4SLinus Torvalds int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
2091da177e4SLinus Torvalds 					      struct sk_buff *skb)
2101da177e4SLinus Torvalds {
211b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
212b9441fc3SArnaldo Carvalho de Melo 	const u8 vr = llc_sk(sk)->vR;
213b9441fc3SArnaldo Carvalho de Melo 	const u8 ns = LLC_I_GET_NS(pdu);
2141da177e4SLinus Torvalds 
2151da177e4SLinus Torvalds 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
2161da177e4SLinus Torvalds 	       LLC_I_PF_IS_1(pdu) && ns != vr &&
2171da177e4SLinus Torvalds 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
2181da177e4SLinus Torvalds }
2191da177e4SLinus Torvalds 
llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock * sk,struct sk_buff * skb)2201da177e4SLinus Torvalds int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
2211da177e4SLinus Torvalds 					     struct sk_buff *skb)
2221da177e4SLinus Torvalds {
223b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb);
224b9441fc3SArnaldo Carvalho de Melo 	const u8 vr = llc_sk(sk)->vR;
225b9441fc3SArnaldo Carvalho de Melo 	const u8 ns = LLC_I_GET_NS(pdu);
226b9441fc3SArnaldo Carvalho de Melo 	const u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
227b9441fc3SArnaldo Carvalho de Melo 		ns != vr &&
2281da177e4SLinus Torvalds 		 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
2291da177e4SLinus Torvalds 	if (!rc)
2301da177e4SLinus Torvalds 		dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
2310dc47877SHarvey Harrison 			__func__, llc_sk(sk)->state, ns, vr);
2321da177e4SLinus Torvalds 	return rc;
2331da177e4SLinus Torvalds }
2341da177e4SLinus Torvalds 
llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock * sk,struct sk_buff * skb)2351da177e4SLinus Torvalds int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
2361da177e4SLinus Torvalds {
237b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
2381da177e4SLinus Torvalds 
2391da177e4SLinus Torvalds 	return llc_conn_space(sk, skb) &&
2401da177e4SLinus Torvalds 	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
2411da177e4SLinus Torvalds 	       LLC_I_PF_IS_0(pdu) &&
2421da177e4SLinus Torvalds 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
2431da177e4SLinus Torvalds }
2441da177e4SLinus Torvalds 
llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock * sk,struct sk_buff * skb)2451da177e4SLinus Torvalds int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
2461da177e4SLinus Torvalds {
247b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
2481da177e4SLinus Torvalds 
2491da177e4SLinus Torvalds 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
2501da177e4SLinus Torvalds 	       LLC_I_PF_IS_1(pdu) &&
2511da177e4SLinus Torvalds 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
2521da177e4SLinus Torvalds }
2531da177e4SLinus Torvalds 
llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock * sk,struct sk_buff * skb)2541da177e4SLinus Torvalds int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
2551da177e4SLinus Torvalds {
256b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
2571da177e4SLinus Torvalds 
2581da177e4SLinus Torvalds 	return llc_conn_space(sk, skb) &&
2591da177e4SLinus Torvalds 	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
2601da177e4SLinus Torvalds 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
2611da177e4SLinus Torvalds }
2621da177e4SLinus Torvalds 
llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock * sk,struct sk_buff * skb)2631da177e4SLinus Torvalds int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
2641da177e4SLinus Torvalds 					      struct sk_buff *skb)
2651da177e4SLinus Torvalds {
266b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
267b9441fc3SArnaldo Carvalho de Melo 	const u8 vr = llc_sk(sk)->vR;
268b9441fc3SArnaldo Carvalho de Melo 	const u8 ns = LLC_I_GET_NS(pdu);
2691da177e4SLinus Torvalds 
2701da177e4SLinus Torvalds 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
2711da177e4SLinus Torvalds 	       LLC_I_PF_IS_0(pdu) && ns != vr &&
2721da177e4SLinus Torvalds 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
2731da177e4SLinus Torvalds }
2741da177e4SLinus Torvalds 
llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock * sk,struct sk_buff * skb)2751da177e4SLinus Torvalds int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
2761da177e4SLinus Torvalds 					      struct sk_buff *skb)
2771da177e4SLinus Torvalds {
278b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
279b9441fc3SArnaldo Carvalho de Melo 	const u8 vr = llc_sk(sk)->vR;
280b9441fc3SArnaldo Carvalho de Melo 	const u8 ns = LLC_I_GET_NS(pdu);
2811da177e4SLinus Torvalds 
2821da177e4SLinus Torvalds 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
2831da177e4SLinus Torvalds 	       LLC_I_PF_IS_1(pdu) && ns != vr &&
2841da177e4SLinus Torvalds 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
2851da177e4SLinus Torvalds }
2861da177e4SLinus Torvalds 
llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock * sk,struct sk_buff * skb)2871da177e4SLinus Torvalds int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
2881da177e4SLinus Torvalds 					      struct sk_buff *skb)
2891da177e4SLinus Torvalds {
290b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
291b9441fc3SArnaldo Carvalho de Melo 	const u8 vr = llc_sk(sk)->vR;
292b9441fc3SArnaldo Carvalho de Melo 	const u8 ns = LLC_I_GET_NS(pdu);
2931da177e4SLinus Torvalds 
2941da177e4SLinus Torvalds 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
2951da177e4SLinus Torvalds 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
2961da177e4SLinus Torvalds }
2971da177e4SLinus Torvalds 
llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock * sk,struct sk_buff * skb)2981da177e4SLinus Torvalds int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
2991da177e4SLinus Torvalds 					     struct sk_buff *skb)
3001da177e4SLinus Torvalds {
301b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
302b9441fc3SArnaldo Carvalho de Melo 	const u8 vr = llc_sk(sk)->vR;
303b9441fc3SArnaldo Carvalho de Melo 	const u8 ns = LLC_I_GET_NS(pdu);
304b9441fc3SArnaldo Carvalho de Melo 	const u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
305b9441fc3SArnaldo Carvalho de Melo 		ns != vr &&
3061da177e4SLinus Torvalds 		 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
3071da177e4SLinus Torvalds 	if (!rc)
3081da177e4SLinus Torvalds 		dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
3090dc47877SHarvey Harrison 			__func__, llc_sk(sk)->state, ns, vr);
3101da177e4SLinus Torvalds 	return rc;
3111da177e4SLinus Torvalds }
3121da177e4SLinus Torvalds 
llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock * sk,struct sk_buff * skb)3131da177e4SLinus Torvalds int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
3141da177e4SLinus Torvalds {
315b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
3161da177e4SLinus Torvalds 
3171da177e4SLinus Torvalds 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
3181da177e4SLinus Torvalds 	       LLC_S_PF_IS_0(pdu) &&
3191da177e4SLinus Torvalds 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
3201da177e4SLinus Torvalds }
3211da177e4SLinus Torvalds 
llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock * sk,struct sk_buff * skb)3221da177e4SLinus Torvalds int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
3231da177e4SLinus Torvalds {
324b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
3251da177e4SLinus Torvalds 
3261da177e4SLinus Torvalds 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
3271da177e4SLinus Torvalds 	       LLC_S_PF_IS_1(pdu) &&
3281da177e4SLinus Torvalds 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
3291da177e4SLinus Torvalds }
3301da177e4SLinus Torvalds 
llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock * sk,struct sk_buff * skb)3311da177e4SLinus Torvalds int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
3321da177e4SLinus Torvalds {
333b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
3341da177e4SLinus Torvalds 
3351da177e4SLinus Torvalds 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
3361da177e4SLinus Torvalds 	       LLC_S_PF_IS_0(pdu) &&
3371da177e4SLinus Torvalds 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
3381da177e4SLinus Torvalds }
3391da177e4SLinus Torvalds 
llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock * sk,struct sk_buff * skb)3401da177e4SLinus Torvalds int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
3411da177e4SLinus Torvalds {
342b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
3431da177e4SLinus Torvalds 
3441da177e4SLinus Torvalds 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
3451da177e4SLinus Torvalds 	       LLC_S_PF_IS_1(pdu) &&
3461da177e4SLinus Torvalds 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
3471da177e4SLinus Torvalds }
3481da177e4SLinus Torvalds 
llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock * sk,struct sk_buff * skb)3491da177e4SLinus Torvalds int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
3501da177e4SLinus Torvalds {
351b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
3521da177e4SLinus Torvalds 
3531da177e4SLinus Torvalds 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
3541da177e4SLinus Torvalds 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
3551da177e4SLinus Torvalds }
3561da177e4SLinus Torvalds 
llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock * sk,struct sk_buff * skb)3571da177e4SLinus Torvalds int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
3581da177e4SLinus Torvalds {
359b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
3601da177e4SLinus Torvalds 
3611da177e4SLinus Torvalds 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
3621da177e4SLinus Torvalds 	       LLC_S_PF_IS_0(pdu) &&
3631da177e4SLinus Torvalds 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
3641da177e4SLinus Torvalds }
3651da177e4SLinus Torvalds 
llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock * sk,struct sk_buff * skb)3661da177e4SLinus Torvalds int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
3671da177e4SLinus Torvalds {
368b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
3691da177e4SLinus Torvalds 
3701da177e4SLinus Torvalds 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
3711da177e4SLinus Torvalds 	       LLC_S_PF_IS_1(pdu) &&
3721da177e4SLinus Torvalds 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
3731da177e4SLinus Torvalds }
3741da177e4SLinus Torvalds 
llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock * sk,struct sk_buff * skb)3751da177e4SLinus Torvalds int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
3761da177e4SLinus Torvalds {
377b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
3781da177e4SLinus Torvalds 
3791da177e4SLinus Torvalds 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
3801da177e4SLinus Torvalds 	       LLC_S_PF_IS_0(pdu) &&
3811da177e4SLinus Torvalds 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
3821da177e4SLinus Torvalds }
3831da177e4SLinus Torvalds 
llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock * sk,struct sk_buff * skb)3841da177e4SLinus Torvalds int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
3851da177e4SLinus Torvalds {
386b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
3871da177e4SLinus Torvalds 
3881da177e4SLinus Torvalds 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
3891da177e4SLinus Torvalds 	       LLC_S_PF_IS_1(pdu) &&
3901da177e4SLinus Torvalds 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
3911da177e4SLinus Torvalds }
3921da177e4SLinus Torvalds 
llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock * sk,struct sk_buff * skb)3931da177e4SLinus Torvalds int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
3941da177e4SLinus Torvalds {
395b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
3961da177e4SLinus Torvalds 
3971da177e4SLinus Torvalds 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
3981da177e4SLinus Torvalds 	       LLC_S_PF_IS_0(pdu) &&
3991da177e4SLinus Torvalds 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
4001da177e4SLinus Torvalds }
4011da177e4SLinus Torvalds 
llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock * sk,struct sk_buff * skb)4021da177e4SLinus Torvalds int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
4031da177e4SLinus Torvalds {
404b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
4051da177e4SLinus Torvalds 
4061da177e4SLinus Torvalds 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
4071da177e4SLinus Torvalds 	       LLC_S_PF_IS_1(pdu) &&
4081da177e4SLinus Torvalds 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
4091da177e4SLinus Torvalds }
4101da177e4SLinus Torvalds 
llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock * sk,struct sk_buff * skb)4111da177e4SLinus Torvalds int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
4121da177e4SLinus Torvalds {
413b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
4141da177e4SLinus Torvalds 
4151da177e4SLinus Torvalds 	return llc_conn_space(sk, skb) &&
4161da177e4SLinus Torvalds 	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
4171da177e4SLinus Torvalds 	       LLC_S_PF_IS_0(pdu) &&
4181da177e4SLinus Torvalds 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
4191da177e4SLinus Torvalds }
4201da177e4SLinus Torvalds 
llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock * sk,struct sk_buff * skb)4211da177e4SLinus Torvalds int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
4221da177e4SLinus Torvalds {
423b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
4241da177e4SLinus Torvalds 
4251da177e4SLinus Torvalds 	return llc_conn_space(sk, skb) &&
4261da177e4SLinus Torvalds 	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
4271da177e4SLinus Torvalds 	       LLC_S_PF_IS_1(pdu) &&
4281da177e4SLinus Torvalds 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
4291da177e4SLinus Torvalds }
4301da177e4SLinus Torvalds 
llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock * sk,struct sk_buff * skb)4311da177e4SLinus Torvalds int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
4321da177e4SLinus Torvalds {
433b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
4341da177e4SLinus Torvalds 
4351da177e4SLinus Torvalds 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
4361da177e4SLinus Torvalds 	       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1;
4371da177e4SLinus Torvalds }
4381da177e4SLinus Torvalds 
llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock * sk,struct sk_buff * skb)4391da177e4SLinus Torvalds int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
4401da177e4SLinus Torvalds {
4411da177e4SLinus Torvalds 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
4421da177e4SLinus Torvalds 
4431da177e4SLinus Torvalds 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
4441da177e4SLinus Torvalds 	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_UA ? 0 : 1;
4451da177e4SLinus Torvalds }
4461da177e4SLinus Torvalds 
llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock * sk,struct sk_buff * skb)4471da177e4SLinus Torvalds int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
4481da177e4SLinus Torvalds {
4491da177e4SLinus Torvalds 	u16 rc = 1;
450b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
4511da177e4SLinus Torvalds 
4521da177e4SLinus Torvalds 	if (LLC_PDU_IS_CMD(pdu)) {
4531da177e4SLinus Torvalds 		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
4541da177e4SLinus Torvalds 			if (LLC_I_PF_IS_1(pdu))
4551da177e4SLinus Torvalds 				rc = 0;
4561da177e4SLinus Torvalds 		} else if (LLC_PDU_TYPE_IS_U(pdu) && LLC_U_PF_IS_1(pdu))
4571da177e4SLinus Torvalds 			rc = 0;
4581da177e4SLinus Torvalds 	}
4591da177e4SLinus Torvalds 	return rc;
4601da177e4SLinus Torvalds }
4611da177e4SLinus Torvalds 
llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock * sk,struct sk_buff * skb)4621da177e4SLinus Torvalds int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
4631da177e4SLinus Torvalds {
4641da177e4SLinus Torvalds 	u16 rc = 1;
465b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
4661da177e4SLinus Torvalds 
4671da177e4SLinus Torvalds 	if (LLC_PDU_IS_CMD(pdu)) {
4681da177e4SLinus Torvalds 		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
4691da177e4SLinus Torvalds 			rc = 0;
4701da177e4SLinus Torvalds 		else if (LLC_PDU_TYPE_IS_U(pdu))
4711da177e4SLinus Torvalds 			switch (LLC_U_PDU_CMD(pdu)) {
4721da177e4SLinus Torvalds 			case LLC_2_PDU_CMD_SABME:
4731da177e4SLinus Torvalds 			case LLC_2_PDU_CMD_DISC:
4741da177e4SLinus Torvalds 				rc = 0;
4751da177e4SLinus Torvalds 				break;
4761da177e4SLinus Torvalds 			}
4771da177e4SLinus Torvalds 	}
4781da177e4SLinus Torvalds 	return rc;
4791da177e4SLinus Torvalds }
4801da177e4SLinus Torvalds 
llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock * sk,struct sk_buff * skb)4811da177e4SLinus Torvalds int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
4821da177e4SLinus Torvalds {
4831da177e4SLinus Torvalds 	u16 rc = 1;
484b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
4851da177e4SLinus Torvalds 
4861da177e4SLinus Torvalds 	if (LLC_PDU_IS_RSP(pdu)) {
4871da177e4SLinus Torvalds 		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
4881da177e4SLinus Torvalds 			rc = 0;
4891da177e4SLinus Torvalds 		else if (LLC_PDU_TYPE_IS_U(pdu))
4901da177e4SLinus Torvalds 			switch (LLC_U_PDU_RSP(pdu)) {
4911da177e4SLinus Torvalds 			case LLC_2_PDU_RSP_UA:
4921da177e4SLinus Torvalds 			case LLC_2_PDU_RSP_DM:
4931da177e4SLinus Torvalds 			case LLC_2_PDU_RSP_FRMR:
4941da177e4SLinus Torvalds 				rc = 0;
4951da177e4SLinus Torvalds 				break;
4961da177e4SLinus Torvalds 			}
4971da177e4SLinus Torvalds 	}
4981da177e4SLinus Torvalds 
4991da177e4SLinus Torvalds 	return rc;
5001da177e4SLinus Torvalds }
5011da177e4SLinus Torvalds 
llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock * sk,struct sk_buff * skb)5021da177e4SLinus Torvalds int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
5031da177e4SLinus Torvalds 					       struct sk_buff *skb)
5041da177e4SLinus Torvalds {
5051da177e4SLinus Torvalds 	u16 rc = 1;
506b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
507b9441fc3SArnaldo Carvalho de Melo 	const u8 vs = llc_sk(sk)->vS;
508b9441fc3SArnaldo Carvalho de Melo 	const u8 nr = LLC_I_GET_NR(pdu);
5091da177e4SLinus Torvalds 
5101da177e4SLinus Torvalds 	if (LLC_PDU_IS_CMD(pdu) &&
5111da177e4SLinus Torvalds 	    (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
5121da177e4SLinus Torvalds 	    nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
5131da177e4SLinus Torvalds 		dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
5140dc47877SHarvey Harrison 			__func__, llc_sk(sk)->state, vs, nr);
5151da177e4SLinus Torvalds 		rc = 0;
5161da177e4SLinus Torvalds 	}
5171da177e4SLinus Torvalds 	return rc;
5181da177e4SLinus Torvalds }
5191da177e4SLinus Torvalds 
llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock * sk,struct sk_buff * skb)5201da177e4SLinus Torvalds int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
5211da177e4SLinus Torvalds 					       struct sk_buff *skb)
5221da177e4SLinus Torvalds {
5231da177e4SLinus Torvalds 	u16 rc = 1;
524b9441fc3SArnaldo Carvalho de Melo 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
525b9441fc3SArnaldo Carvalho de Melo 	const u8 vs = llc_sk(sk)->vS;
526b9441fc3SArnaldo Carvalho de Melo 	const u8 nr = LLC_I_GET_NR(pdu);
5271da177e4SLinus Torvalds 
5281da177e4SLinus Torvalds 	if (LLC_PDU_IS_RSP(pdu) &&
5291da177e4SLinus Torvalds 	    (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
5301da177e4SLinus Torvalds 	    nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
5311da177e4SLinus Torvalds 		rc = 0;
5321da177e4SLinus Torvalds 		dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
5330dc47877SHarvey Harrison 			__func__, llc_sk(sk)->state, vs, nr);
5341da177e4SLinus Torvalds 	}
5351da177e4SLinus Torvalds 	return rc;
5361da177e4SLinus Torvalds }
5371da177e4SLinus Torvalds 
llc_conn_ev_rx_any_frame(struct sock * sk,struct sk_buff * skb)5381da177e4SLinus Torvalds int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb)
5391da177e4SLinus Torvalds {
5401da177e4SLinus Torvalds 	return 0;
5411da177e4SLinus Torvalds }
5421da177e4SLinus Torvalds 
llc_conn_ev_p_tmr_exp(struct sock * sk,struct sk_buff * skb)5431da177e4SLinus Torvalds int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb)
5441da177e4SLinus Torvalds {
545b9441fc3SArnaldo Carvalho de Melo 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
5461da177e4SLinus Torvalds 
5471da177e4SLinus Torvalds 	return ev->type != LLC_CONN_EV_TYPE_P_TMR;
5481da177e4SLinus Torvalds }
5491da177e4SLinus Torvalds 
llc_conn_ev_ack_tmr_exp(struct sock * sk,struct sk_buff * skb)5501da177e4SLinus Torvalds int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb)
5511da177e4SLinus Torvalds {
552b9441fc3SArnaldo Carvalho de Melo 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
5531da177e4SLinus Torvalds 
5541da177e4SLinus Torvalds 	return ev->type != LLC_CONN_EV_TYPE_ACK_TMR;
5551da177e4SLinus Torvalds }
5561da177e4SLinus Torvalds 
llc_conn_ev_rej_tmr_exp(struct sock * sk,struct sk_buff * skb)5571da177e4SLinus Torvalds int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb)
5581da177e4SLinus Torvalds {
559b9441fc3SArnaldo Carvalho de Melo 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
5601da177e4SLinus Torvalds 
5611da177e4SLinus Torvalds 	return ev->type != LLC_CONN_EV_TYPE_REJ_TMR;
5621da177e4SLinus Torvalds }
5631da177e4SLinus Torvalds 
llc_conn_ev_busy_tmr_exp(struct sock * sk,struct sk_buff * skb)5641da177e4SLinus Torvalds int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb)
5651da177e4SLinus Torvalds {
566b9441fc3SArnaldo Carvalho de Melo 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
5671da177e4SLinus Torvalds 
5681da177e4SLinus Torvalds 	return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR;
5691da177e4SLinus Torvalds }
5701da177e4SLinus Torvalds 
llc_conn_ev_init_p_f_cycle(struct sock * sk,struct sk_buff * skb)5711da177e4SLinus Torvalds int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb)
5721da177e4SLinus Torvalds {
5731da177e4SLinus Torvalds 	return 1;
5741da177e4SLinus Torvalds }
5751da177e4SLinus Torvalds 
llc_conn_ev_tx_buffer_full(struct sock * sk,struct sk_buff * skb)5761da177e4SLinus Torvalds int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb)
5771da177e4SLinus Torvalds {
578b9441fc3SArnaldo Carvalho de Melo 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
5791da177e4SLinus Torvalds 
5801da177e4SLinus Torvalds 	return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
5811da177e4SLinus Torvalds 	       ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
5821da177e4SLinus Torvalds }
5831da177e4SLinus Torvalds 
5841da177e4SLinus Torvalds /* Event qualifier functions
5851da177e4SLinus Torvalds  *
5861da177e4SLinus Torvalds  * these functions simply verify the value of a state flag associated with
5871da177e4SLinus Torvalds  * the connection and return either a 0 for success or a non-zero value
5881da177e4SLinus Torvalds  * for not-success; verify the event is the type we expect
5891da177e4SLinus Torvalds  */
llc_conn_ev_qlfy_data_flag_eq_1(struct sock * sk,struct sk_buff * skb)5901da177e4SLinus Torvalds int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, struct sk_buff *skb)
5911da177e4SLinus Torvalds {
5921da177e4SLinus Torvalds 	return llc_sk(sk)->data_flag != 1;
5931da177e4SLinus Torvalds }
5941da177e4SLinus Torvalds 
llc_conn_ev_qlfy_data_flag_eq_0(struct sock * sk,struct sk_buff * skb)5951da177e4SLinus Torvalds int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, struct sk_buff *skb)
5961da177e4SLinus Torvalds {
5971da177e4SLinus Torvalds 	return llc_sk(sk)->data_flag;
5981da177e4SLinus Torvalds }
5991da177e4SLinus Torvalds 
llc_conn_ev_qlfy_data_flag_eq_2(struct sock * sk,struct sk_buff * skb)6001da177e4SLinus Torvalds int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, struct sk_buff *skb)
6011da177e4SLinus Torvalds {
6021da177e4SLinus Torvalds 	return llc_sk(sk)->data_flag != 2;
6031da177e4SLinus Torvalds }
6041da177e4SLinus Torvalds 
llc_conn_ev_qlfy_p_flag_eq_1(struct sock * sk,struct sk_buff * skb)6051da177e4SLinus Torvalds int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb)
6061da177e4SLinus Torvalds {
6071da177e4SLinus Torvalds 	return llc_sk(sk)->p_flag != 1;
6081da177e4SLinus Torvalds }
6091da177e4SLinus Torvalds 
6101da177e4SLinus Torvalds /**
611*26440a63SYang Yingliang  *	llc_conn_ev_qlfy_last_frame_eq_1 - checks if frame is last in tx window
6121da177e4SLinus Torvalds  *	@sk: current connection structure.
6131da177e4SLinus Torvalds  *	@skb: current event.
6141da177e4SLinus Torvalds  *
6151da177e4SLinus Torvalds  *	This function determines when frame which is sent, is last frame of
6161da177e4SLinus Torvalds  *	transmit window, if it is then this function return zero else return
6171da177e4SLinus Torvalds  *	one.  This function is used for sending last frame of transmit window
6181da177e4SLinus Torvalds  *	as I-format command with p-bit set to one. Returns 0 if frame is last
6191da177e4SLinus Torvalds  *	frame, 1 otherwise.
6201da177e4SLinus Torvalds  */
llc_conn_ev_qlfy_last_frame_eq_1(struct sock * sk,struct sk_buff * skb)6211da177e4SLinus Torvalds int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, struct sk_buff *skb)
6221da177e4SLinus Torvalds {
6231da177e4SLinus Torvalds 	return !(skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k);
6241da177e4SLinus Torvalds }
6251da177e4SLinus Torvalds 
6261da177e4SLinus Torvalds /**
627*26440a63SYang Yingliang  *	llc_conn_ev_qlfy_last_frame_eq_0 - checks if frame isn't last in tx window
6281da177e4SLinus Torvalds  *	@sk: current connection structure.
6291da177e4SLinus Torvalds  *	@skb: current event.
6301da177e4SLinus Torvalds  *
6311da177e4SLinus Torvalds  *	This function determines when frame which is sent, isn't last frame of
6321da177e4SLinus Torvalds  *	transmit window, if it isn't then this function return zero else return
6331da177e4SLinus Torvalds  *	one. Returns 0 if frame isn't last frame, 1 otherwise.
6341da177e4SLinus Torvalds  */
llc_conn_ev_qlfy_last_frame_eq_0(struct sock * sk,struct sk_buff * skb)6351da177e4SLinus Torvalds int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, struct sk_buff *skb)
6361da177e4SLinus Torvalds {
6371da177e4SLinus Torvalds 	return skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k;
6381da177e4SLinus Torvalds }
6391da177e4SLinus Torvalds 
llc_conn_ev_qlfy_p_flag_eq_0(struct sock * sk,struct sk_buff * skb)6401da177e4SLinus Torvalds int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb)
6411da177e4SLinus Torvalds {
6421da177e4SLinus Torvalds 	return llc_sk(sk)->p_flag;
6431da177e4SLinus Torvalds }
6441da177e4SLinus Torvalds 
llc_conn_ev_qlfy_p_flag_eq_f(struct sock * sk,struct sk_buff * skb)6451da177e4SLinus Torvalds int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb)
6461da177e4SLinus Torvalds {
6471da177e4SLinus Torvalds 	u8 f_bit;
6481da177e4SLinus Torvalds 
6491da177e4SLinus Torvalds 	llc_pdu_decode_pf_bit(skb, &f_bit);
6501da177e4SLinus Torvalds 	return llc_sk(sk)->p_flag == f_bit ? 0 : 1;
6511da177e4SLinus Torvalds }
6521da177e4SLinus Torvalds 
llc_conn_ev_qlfy_remote_busy_eq_0(struct sock * sk,struct sk_buff * skb)6531da177e4SLinus Torvalds int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, struct sk_buff *skb)
6541da177e4SLinus Torvalds {
6551da177e4SLinus Torvalds 	return llc_sk(sk)->remote_busy_flag;
6561da177e4SLinus Torvalds }
6571da177e4SLinus Torvalds 
llc_conn_ev_qlfy_remote_busy_eq_1(struct sock * sk,struct sk_buff * skb)6581da177e4SLinus Torvalds int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, struct sk_buff *skb)
6591da177e4SLinus Torvalds {
6601da177e4SLinus Torvalds 	return !llc_sk(sk)->remote_busy_flag;
6611da177e4SLinus Torvalds }
6621da177e4SLinus Torvalds 
llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock * sk,struct sk_buff * skb)6631da177e4SLinus Torvalds int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, struct sk_buff *skb)
6641da177e4SLinus Torvalds {
6651da177e4SLinus Torvalds 	return !(llc_sk(sk)->retry_count < llc_sk(sk)->n2);
6661da177e4SLinus Torvalds }
6671da177e4SLinus Torvalds 
llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock * sk,struct sk_buff * skb)6681da177e4SLinus Torvalds int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, struct sk_buff *skb)
6691da177e4SLinus Torvalds {
6701da177e4SLinus Torvalds 	return !(llc_sk(sk)->retry_count >= llc_sk(sk)->n2);
6711da177e4SLinus Torvalds }
6721da177e4SLinus Torvalds 
llc_conn_ev_qlfy_s_flag_eq_1(struct sock * sk,struct sk_buff * skb)6731da177e4SLinus Torvalds int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb)
6741da177e4SLinus Torvalds {
6751da177e4SLinus Torvalds 	return !llc_sk(sk)->s_flag;
6761da177e4SLinus Torvalds }
6771da177e4SLinus Torvalds 
llc_conn_ev_qlfy_s_flag_eq_0(struct sock * sk,struct sk_buff * skb)6781da177e4SLinus Torvalds int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb)
6791da177e4SLinus Torvalds {
6801da177e4SLinus Torvalds 	return llc_sk(sk)->s_flag;
6811da177e4SLinus Torvalds }
6821da177e4SLinus Torvalds 
llc_conn_ev_qlfy_cause_flag_eq_1(struct sock * sk,struct sk_buff * skb)6831da177e4SLinus Torvalds int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, struct sk_buff *skb)
6841da177e4SLinus Torvalds {
6851da177e4SLinus Torvalds 	return !llc_sk(sk)->cause_flag;
6861da177e4SLinus Torvalds }
6871da177e4SLinus Torvalds 
llc_conn_ev_qlfy_cause_flag_eq_0(struct sock * sk,struct sk_buff * skb)6881da177e4SLinus Torvalds int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, struct sk_buff *skb)
6891da177e4SLinus Torvalds {
6901da177e4SLinus Torvalds 	return llc_sk(sk)->cause_flag;
6911da177e4SLinus Torvalds }
6921da177e4SLinus Torvalds 
llc_conn_ev_qlfy_set_status_conn(struct sock * sk,struct sk_buff * skb)6931da177e4SLinus Torvalds int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, struct sk_buff *skb)
6941da177e4SLinus Torvalds {
6951da177e4SLinus Torvalds 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
6961da177e4SLinus Torvalds 
6971da177e4SLinus Torvalds 	ev->status = LLC_STATUS_CONN;
6981da177e4SLinus Torvalds 	return 0;
6991da177e4SLinus Torvalds }
7001da177e4SLinus Torvalds 
llc_conn_ev_qlfy_set_status_disc(struct sock * sk,struct sk_buff * skb)7011da177e4SLinus Torvalds int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, struct sk_buff *skb)
7021da177e4SLinus Torvalds {
7031da177e4SLinus Torvalds 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
7041da177e4SLinus Torvalds 
7051da177e4SLinus Torvalds 	ev->status = LLC_STATUS_DISC;
7061da177e4SLinus Torvalds 	return 0;
7071da177e4SLinus Torvalds }
7081da177e4SLinus Torvalds 
llc_conn_ev_qlfy_set_status_failed(struct sock * sk,struct sk_buff * skb)7091da177e4SLinus Torvalds int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, struct sk_buff *skb)
7101da177e4SLinus Torvalds {
7111da177e4SLinus Torvalds 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
7121da177e4SLinus Torvalds 
7131da177e4SLinus Torvalds 	ev->status = LLC_STATUS_FAILED;
7141da177e4SLinus Torvalds 	return 0;
7151da177e4SLinus Torvalds }
7161da177e4SLinus Torvalds 
llc_conn_ev_qlfy_set_status_remote_busy(struct sock * sk,struct sk_buff * skb)7171da177e4SLinus Torvalds int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
7181da177e4SLinus Torvalds 					    struct sk_buff *skb)
7191da177e4SLinus Torvalds {
7201da177e4SLinus Torvalds 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
7211da177e4SLinus Torvalds 
7221da177e4SLinus Torvalds 	ev->status = LLC_STATUS_REMOTE_BUSY;
7231da177e4SLinus Torvalds 	return 0;
7241da177e4SLinus Torvalds }
7251da177e4SLinus Torvalds 
llc_conn_ev_qlfy_set_status_refuse(struct sock * sk,struct sk_buff * skb)7261da177e4SLinus Torvalds int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, struct sk_buff *skb)
7271da177e4SLinus Torvalds {
7281da177e4SLinus Torvalds 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
7291da177e4SLinus Torvalds 
7301da177e4SLinus Torvalds 	ev->status = LLC_STATUS_REFUSE;
7311da177e4SLinus Torvalds 	return 0;
7321da177e4SLinus Torvalds }
7331da177e4SLinus Torvalds 
llc_conn_ev_qlfy_set_status_conflict(struct sock * sk,struct sk_buff * skb)7341da177e4SLinus Torvalds int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, struct sk_buff *skb)
7351da177e4SLinus Torvalds {
7361da177e4SLinus Torvalds 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
7371da177e4SLinus Torvalds 
7381da177e4SLinus Torvalds 	ev->status = LLC_STATUS_CONFLICT;
7391da177e4SLinus Torvalds 	return 0;
7401da177e4SLinus Torvalds }
7411da177e4SLinus Torvalds 
llc_conn_ev_qlfy_set_status_rst_done(struct sock * sk,struct sk_buff * skb)7421da177e4SLinus Torvalds int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, struct sk_buff *skb)
7431da177e4SLinus Torvalds {
7441da177e4SLinus Torvalds 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
7451da177e4SLinus Torvalds 
7461da177e4SLinus Torvalds 	ev->status = LLC_STATUS_RESET_DONE;
7471da177e4SLinus Torvalds 	return 0;
7481da177e4SLinus Torvalds }
749