llc_c_ev.c (21784B)
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 * llc_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 * llc_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}