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 '') 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 */ 59 static 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 */ 75 static 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); 95 out: 96 return rc; 97 } 98 99 int 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 107 int 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 115 int 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 123 int 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 131 int 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 139 int 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 147 int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb) 148 { 149 return 1; 150 } 151 152 int 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 160 int 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 168 int 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 176 int 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 186 int 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 196 int 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 208 int 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 220 int 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 235 int 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 245 int 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 254 int 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 263 int 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 275 int 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 287 int 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 298 int 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 313 int 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 322 int 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 331 int 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 340 int 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 349 int 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 357 int 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 366 int 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 375 int 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 384 int 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 393 int 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 402 int 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 411 int 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 421 int 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 431 int 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 439 int 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 447 int 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 462 int 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 481 int 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 502 int 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 520 int 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 538 int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb) 539 { 540 return 0; 541 } 542 543 int 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 550 int 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 557 int 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 564 int 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 571 int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb) 572 { 573 return 1; 574 } 575 576 int 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 */ 590 int 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 595 int 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 600 int 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 605 int 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 */ 621 int 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 */ 635 int 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 640 int 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 645 int 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 653 int 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 658 int 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 663 int 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 668 int 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 673 int 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 678 int 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 683 int 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 688 int 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 693 int 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 701 int 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 709 int 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 717 int 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 726 int 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 734 int 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 742 int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, struct sk_buff *skb) 743 { 744 struct llc_conn_state_ev *ev = llc_conn_ev(skb); 745 746 ev->status = LLC_STATUS_RESET_DONE; 747 return 0; 748 } 749
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.