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