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