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