Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * llc_c_ev.c - Connection component state transition event qualifiers
0003  *
0004  * A 'state' consists of a number of possible event matching functions,
0005  * the actions associated with each being executed when that event is
0006  * matched; a 'state machine' accepts events in a serial fashion from an
0007  * event queue. Each event is passed to each successive event matching
0008  * function until a match is made (the event matching function returns
0009  * success, or '0') or the list of event matching functions is exhausted.
0010  * If a match is made, the actions associated with the event are executed
0011  * and the state is changed to that event's transition state. Before some
0012  * events are recognized, even after a match has been made, a certain
0013  * number of 'event qualifier' functions must also be executed. If these
0014  * all execute successfully, then the event is finally executed.
0015  *
0016  * These event functions must return 0 for success, to show a matched
0017  * event, of 1 if the event does not match. Event qualifier functions
0018  * must return a 0 for success or a non-zero for failure. Each function
0019  * is simply responsible for verifying one single thing and returning
0020  * either a success or failure.
0021  *
0022  * All of followed event functions are described in 802.2 LLC Protocol
0023  * standard document except two functions that we added that will explain
0024  * in their comments, at below.
0025  *
0026  * Copyright (c) 1997 by Procom Technology, Inc.
0027  *       2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
0028  *
0029  * This program can be redistributed or modified under the terms of the
0030  * GNU General Public License as published by the Free Software Foundation.
0031  * This program is distributed without any warranty or implied warranty
0032  * of merchantability or fitness for a particular purpose.
0033  *
0034  * See the GNU General Public License for more details.
0035  */
0036 #include <linux/netdevice.h>
0037 #include <net/llc_conn.h>
0038 #include <net/llc_sap.h>
0039 #include <net/sock.h>
0040 #include <net/llc_c_ac.h>
0041 #include <net/llc_c_ev.h>
0042 #include <net/llc_pdu.h>
0043 
0044 #if 1
0045 #define dprintk(args...) printk(KERN_DEBUG args)
0046 #else
0047 #define dprintk(args...)
0048 #endif
0049 
0050 /**
0051  *  llc_util_ns_inside_rx_window - check if sequence number is in rx window
0052  *  @ns: sequence number of received pdu.
0053  *  @vr: sequence number which receiver expects to receive.
0054  *  @rw: receive window size of receiver.
0055  *
0056  *  Checks if sequence number of received PDU is in range of receive
0057  *  window. Returns 0 for success, 1 otherwise
0058  */
0059 static u16 llc_util_ns_inside_rx_window(u8 ns, u8 vr, u8 rw)
0060 {
0061     return !llc_circular_between(vr, ns,
0062                      (vr + rw - 1) % LLC_2_SEQ_NBR_MODULO);
0063 }
0064 
0065 /**
0066  *  llc_util_nr_inside_tx_window - check if sequence number is in tx window
0067  *  @sk: current connection.
0068  *  @nr: N(R) of received PDU.
0069  *
0070  *  This routine checks if N(R) of received PDU is in range of transmit
0071  *  window; on the other hand checks if received PDU acknowledges some
0072  *  outstanding PDUs that are in transmit window. Returns 0 for success, 1
0073  *  otherwise.
0074  */
0075 static u16 llc_util_nr_inside_tx_window(struct sock *sk, u8 nr)
0076 {
0077     u8 nr1, nr2;
0078     struct sk_buff *skb;
0079     struct llc_pdu_sn *pdu;
0080     struct llc_sock *llc = llc_sk(sk);
0081     int rc = 0;
0082 
0083     if (llc->dev->flags & IFF_LOOPBACK)
0084         goto out;
0085     rc = 1;
0086     if (skb_queue_empty(&llc->pdu_unack_q))
0087         goto out;
0088     skb = skb_peek(&llc->pdu_unack_q);
0089     pdu = llc_pdu_sn_hdr(skb);
0090     nr1 = LLC_I_GET_NS(pdu);
0091     skb = skb_peek_tail(&llc->pdu_unack_q);
0092     pdu = llc_pdu_sn_hdr(skb);
0093     nr2 = LLC_I_GET_NS(pdu);
0094     rc = !llc_circular_between(nr1, nr, (nr2 + 1) % LLC_2_SEQ_NBR_MODULO);
0095 out:
0096     return rc;
0097 }
0098 
0099 int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
0100 {
0101     const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0102 
0103     return ev->prim == LLC_CONN_PRIM &&
0104            ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
0105 }
0106 
0107 int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
0108 {
0109     const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0110 
0111     return ev->prim == LLC_DATA_PRIM &&
0112            ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
0113 }
0114 
0115 int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
0116 {
0117     const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0118 
0119     return ev->prim == LLC_DISC_PRIM &&
0120            ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
0121 }
0122 
0123 int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
0124 {
0125     const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0126 
0127     return ev->prim == LLC_RESET_PRIM &&
0128            ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
0129 }
0130 
0131 int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
0132 {
0133     const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0134 
0135     return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
0136            ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
0137 }
0138 
0139 int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
0140 {
0141     const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0142 
0143     return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
0144            ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
0145 }
0146 
0147 int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb)
0148 {
0149     return 1;
0150 }
0151 
0152 int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
0153 {
0154     const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
0155 
0156     return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
0157            LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1;
0158 }
0159 
0160 int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
0161 {
0162     const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
0163 
0164     return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
0165            LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1;
0166 }
0167 
0168 int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
0169 {
0170     const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
0171 
0172     return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
0173            LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1;
0174 }
0175 
0176 int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
0177 {
0178     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0179 
0180     return llc_conn_space(sk, skb) &&
0181            LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
0182            LLC_I_PF_IS_0(pdu) &&
0183            LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
0184 }
0185 
0186 int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
0187 {
0188     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0189 
0190     return llc_conn_space(sk, skb) &&
0191            LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
0192            LLC_I_PF_IS_1(pdu) &&
0193            LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
0194 }
0195 
0196 int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
0197                           struct sk_buff *skb)
0198 {
0199     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0200     const u8 vr = llc_sk(sk)->vR;
0201     const u8 ns = LLC_I_GET_NS(pdu);
0202 
0203     return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
0204            LLC_I_PF_IS_0(pdu) && ns != vr &&
0205            !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
0206 }
0207 
0208 int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
0209                           struct sk_buff *skb)
0210 {
0211     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0212     const u8 vr = llc_sk(sk)->vR;
0213     const u8 ns = LLC_I_GET_NS(pdu);
0214 
0215     return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
0216            LLC_I_PF_IS_1(pdu) && ns != vr &&
0217            !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
0218 }
0219 
0220 int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
0221                          struct sk_buff *skb)
0222 {
0223     const struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb);
0224     const u8 vr = llc_sk(sk)->vR;
0225     const u8 ns = LLC_I_GET_NS(pdu);
0226     const u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
0227         ns != vr &&
0228          llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
0229     if (!rc)
0230         dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
0231             __func__, llc_sk(sk)->state, ns, vr);
0232     return rc;
0233 }
0234 
0235 int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
0236 {
0237     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0238 
0239     return llc_conn_space(sk, skb) &&
0240            LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
0241            LLC_I_PF_IS_0(pdu) &&
0242            LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
0243 }
0244 
0245 int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
0246 {
0247     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0248 
0249     return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
0250            LLC_I_PF_IS_1(pdu) &&
0251            LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
0252 }
0253 
0254 int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
0255 {
0256     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0257 
0258     return llc_conn_space(sk, skb) &&
0259            LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
0260            LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
0261 }
0262 
0263 int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
0264                           struct sk_buff *skb)
0265 {
0266     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0267     const u8 vr = llc_sk(sk)->vR;
0268     const u8 ns = LLC_I_GET_NS(pdu);
0269 
0270     return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
0271            LLC_I_PF_IS_0(pdu) && ns != vr &&
0272            !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
0273 }
0274 
0275 int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
0276                           struct sk_buff *skb)
0277 {
0278     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0279     const u8 vr = llc_sk(sk)->vR;
0280     const u8 ns = LLC_I_GET_NS(pdu);
0281 
0282     return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
0283            LLC_I_PF_IS_1(pdu) && ns != vr &&
0284            !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
0285 }
0286 
0287 int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
0288                           struct sk_buff *skb)
0289 {
0290     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0291     const u8 vr = llc_sk(sk)->vR;
0292     const u8 ns = LLC_I_GET_NS(pdu);
0293 
0294     return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
0295            !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
0296 }
0297 
0298 int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
0299                          struct sk_buff *skb)
0300 {
0301     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0302     const u8 vr = llc_sk(sk)->vR;
0303     const u8 ns = LLC_I_GET_NS(pdu);
0304     const u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
0305         ns != vr &&
0306          llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
0307     if (!rc)
0308         dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
0309             __func__, llc_sk(sk)->state, ns, vr);
0310     return rc;
0311 }
0312 
0313 int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
0314 {
0315     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0316 
0317     return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
0318            LLC_S_PF_IS_0(pdu) &&
0319            LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
0320 }
0321 
0322 int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
0323 {
0324     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0325 
0326     return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
0327            LLC_S_PF_IS_1(pdu) &&
0328            LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
0329 }
0330 
0331 int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
0332 {
0333     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0334 
0335     return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
0336            LLC_S_PF_IS_0(pdu) &&
0337            LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
0338 }
0339 
0340 int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
0341 {
0342     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0343 
0344     return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
0345            LLC_S_PF_IS_1(pdu) &&
0346            LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
0347 }
0348 
0349 int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
0350 {
0351     const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
0352 
0353     return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
0354            LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
0355 }
0356 
0357 int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
0358 {
0359     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0360 
0361     return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
0362            LLC_S_PF_IS_0(pdu) &&
0363            LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
0364 }
0365 
0366 int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
0367 {
0368     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0369 
0370     return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
0371            LLC_S_PF_IS_1(pdu) &&
0372            LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
0373 }
0374 
0375 int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
0376 {
0377     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0378 
0379     return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
0380            LLC_S_PF_IS_0(pdu) &&
0381            LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
0382 }
0383 
0384 int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
0385 {
0386     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0387 
0388     return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
0389            LLC_S_PF_IS_1(pdu) &&
0390            LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
0391 }
0392 
0393 int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
0394 {
0395     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0396 
0397     return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
0398            LLC_S_PF_IS_0(pdu) &&
0399            LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
0400 }
0401 
0402 int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
0403 {
0404     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0405 
0406     return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
0407            LLC_S_PF_IS_1(pdu) &&
0408            LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
0409 }
0410 
0411 int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
0412 {
0413     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0414 
0415     return llc_conn_space(sk, skb) &&
0416            LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
0417            LLC_S_PF_IS_0(pdu) &&
0418            LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
0419 }
0420 
0421 int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
0422 {
0423     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0424 
0425     return llc_conn_space(sk, skb) &&
0426            LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
0427            LLC_S_PF_IS_1(pdu) &&
0428            LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
0429 }
0430 
0431 int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
0432 {
0433     const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
0434 
0435     return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
0436            LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1;
0437 }
0438 
0439 int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
0440 {
0441     struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
0442 
0443     return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
0444            LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_UA ? 0 : 1;
0445 }
0446 
0447 int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
0448 {
0449     u16 rc = 1;
0450     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0451 
0452     if (LLC_PDU_IS_CMD(pdu)) {
0453         if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
0454             if (LLC_I_PF_IS_1(pdu))
0455                 rc = 0;
0456         } else if (LLC_PDU_TYPE_IS_U(pdu) && LLC_U_PF_IS_1(pdu))
0457             rc = 0;
0458     }
0459     return rc;
0460 }
0461 
0462 int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
0463 {
0464     u16 rc = 1;
0465     const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
0466 
0467     if (LLC_PDU_IS_CMD(pdu)) {
0468         if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
0469             rc = 0;
0470         else if (LLC_PDU_TYPE_IS_U(pdu))
0471             switch (LLC_U_PDU_CMD(pdu)) {
0472             case LLC_2_PDU_CMD_SABME:
0473             case LLC_2_PDU_CMD_DISC:
0474                 rc = 0;
0475                 break;
0476             }
0477     }
0478     return rc;
0479 }
0480 
0481 int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
0482 {
0483     u16 rc = 1;
0484     const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
0485 
0486     if (LLC_PDU_IS_RSP(pdu)) {
0487         if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
0488             rc = 0;
0489         else if (LLC_PDU_TYPE_IS_U(pdu))
0490             switch (LLC_U_PDU_RSP(pdu)) {
0491             case LLC_2_PDU_RSP_UA:
0492             case LLC_2_PDU_RSP_DM:
0493             case LLC_2_PDU_RSP_FRMR:
0494                 rc = 0;
0495                 break;
0496             }
0497     }
0498 
0499     return rc;
0500 }
0501 
0502 int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
0503                            struct sk_buff *skb)
0504 {
0505     u16 rc = 1;
0506     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0507     const u8 vs = llc_sk(sk)->vS;
0508     const u8 nr = LLC_I_GET_NR(pdu);
0509 
0510     if (LLC_PDU_IS_CMD(pdu) &&
0511         (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
0512         nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
0513         dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
0514             __func__, llc_sk(sk)->state, vs, nr);
0515         rc = 0;
0516     }
0517     return rc;
0518 }
0519 
0520 int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
0521                            struct sk_buff *skb)
0522 {
0523     u16 rc = 1;
0524     const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0525     const u8 vs = llc_sk(sk)->vS;
0526     const u8 nr = LLC_I_GET_NR(pdu);
0527 
0528     if (LLC_PDU_IS_RSP(pdu) &&
0529         (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
0530         nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
0531         rc = 0;
0532         dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
0533             __func__, llc_sk(sk)->state, vs, nr);
0534     }
0535     return rc;
0536 }
0537 
0538 int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb)
0539 {
0540     return 0;
0541 }
0542 
0543 int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb)
0544 {
0545     const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0546 
0547     return ev->type != LLC_CONN_EV_TYPE_P_TMR;
0548 }
0549 
0550 int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb)
0551 {
0552     const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0553 
0554     return ev->type != LLC_CONN_EV_TYPE_ACK_TMR;
0555 }
0556 
0557 int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb)
0558 {
0559     const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0560 
0561     return ev->type != LLC_CONN_EV_TYPE_REJ_TMR;
0562 }
0563 
0564 int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb)
0565 {
0566     const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0567 
0568     return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR;
0569 }
0570 
0571 int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb)
0572 {
0573     return 1;
0574 }
0575 
0576 int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb)
0577 {
0578     const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0579 
0580     return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
0581            ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
0582 }
0583 
0584 /* Event qualifier functions
0585  *
0586  * these functions simply verify the value of a state flag associated with
0587  * the connection and return either a 0 for success or a non-zero value
0588  * for not-success; verify the event is the type we expect
0589  */
0590 int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, struct sk_buff *skb)
0591 {
0592     return llc_sk(sk)->data_flag != 1;
0593 }
0594 
0595 int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, struct sk_buff *skb)
0596 {
0597     return llc_sk(sk)->data_flag;
0598 }
0599 
0600 int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, struct sk_buff *skb)
0601 {
0602     return llc_sk(sk)->data_flag != 2;
0603 }
0604 
0605 int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb)
0606 {
0607     return llc_sk(sk)->p_flag != 1;
0608 }
0609 
0610 /**
0611  *  llc_conn_ev_qlfy_last_frame_eq_1 - checks if frame is last in tx window
0612  *  @sk: current connection structure.
0613  *  @skb: current event.
0614  *
0615  *  This function determines when frame which is sent, is last frame of
0616  *  transmit window, if it is then this function return zero else return
0617  *  one.  This function is used for sending last frame of transmit window
0618  *  as I-format command with p-bit set to one. Returns 0 if frame is last
0619  *  frame, 1 otherwise.
0620  */
0621 int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, struct sk_buff *skb)
0622 {
0623     return !(skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k);
0624 }
0625 
0626 /**
0627  *  llc_conn_ev_qlfy_last_frame_eq_0 - checks if frame isn't last in tx window
0628  *  @sk: current connection structure.
0629  *  @skb: current event.
0630  *
0631  *  This function determines when frame which is sent, isn't last frame of
0632  *  transmit window, if it isn't then this function return zero else return
0633  *  one. Returns 0 if frame isn't last frame, 1 otherwise.
0634  */
0635 int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, struct sk_buff *skb)
0636 {
0637     return skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k;
0638 }
0639 
0640 int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb)
0641 {
0642     return llc_sk(sk)->p_flag;
0643 }
0644 
0645 int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb)
0646 {
0647     u8 f_bit;
0648 
0649     llc_pdu_decode_pf_bit(skb, &f_bit);
0650     return llc_sk(sk)->p_flag == f_bit ? 0 : 1;
0651 }
0652 
0653 int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, struct sk_buff *skb)
0654 {
0655     return llc_sk(sk)->remote_busy_flag;
0656 }
0657 
0658 int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, struct sk_buff *skb)
0659 {
0660     return !llc_sk(sk)->remote_busy_flag;
0661 }
0662 
0663 int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, struct sk_buff *skb)
0664 {
0665     return !(llc_sk(sk)->retry_count < llc_sk(sk)->n2);
0666 }
0667 
0668 int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, struct sk_buff *skb)
0669 {
0670     return !(llc_sk(sk)->retry_count >= llc_sk(sk)->n2);
0671 }
0672 
0673 int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb)
0674 {
0675     return !llc_sk(sk)->s_flag;
0676 }
0677 
0678 int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb)
0679 {
0680     return llc_sk(sk)->s_flag;
0681 }
0682 
0683 int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, struct sk_buff *skb)
0684 {
0685     return !llc_sk(sk)->cause_flag;
0686 }
0687 
0688 int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, struct sk_buff *skb)
0689 {
0690     return llc_sk(sk)->cause_flag;
0691 }
0692 
0693 int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, struct sk_buff *skb)
0694 {
0695     struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0696 
0697     ev->status = LLC_STATUS_CONN;
0698     return 0;
0699 }
0700 
0701 int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, struct sk_buff *skb)
0702 {
0703     struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0704 
0705     ev->status = LLC_STATUS_DISC;
0706     return 0;
0707 }
0708 
0709 int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, struct sk_buff *skb)
0710 {
0711     struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0712 
0713     ev->status = LLC_STATUS_FAILED;
0714     return 0;
0715 }
0716 
0717 int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
0718                         struct sk_buff *skb)
0719 {
0720     struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0721 
0722     ev->status = LLC_STATUS_REMOTE_BUSY;
0723     return 0;
0724 }
0725 
0726 int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, struct sk_buff *skb)
0727 {
0728     struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0729 
0730     ev->status = LLC_STATUS_REFUSE;
0731     return 0;
0732 }
0733 
0734 int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, struct sk_buff *skb)
0735 {
0736     struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0737 
0738     ev->status = LLC_STATUS_CONFLICT;
0739     return 0;
0740 }
0741 
0742 int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, struct sk_buff *skb)
0743 {
0744     struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0745 
0746     ev->status = LLC_STATUS_RESET_DONE;
0747     return 0;
0748 }