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