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