1 /* 2 * llc_c_ac.c - actions performed during connection state transition. 3 * 4 * Description: 5 * Functions in this module are implementation of connection component actions 6 * Details of actions can be found in IEEE-802.2 standard document. 7 * All functions have one connection and one event as input argument. All of 8 * them return 0 On success and 1 otherwise. 9 * 10 * Copyright (c) 1997 by Procom Technology, Inc. 11 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> 12 * 13 * This program can be redistributed or modified under the terms of the 14 * GNU General Public License as published by the Free Software Foundation. 15 * This program is distributed without any warranty or implied warranty 16 * of merchantability or fitness for a particular purpose. 17 * 18 * See the GNU General Public License for more details. 19 */ 20 #include <linux/netdevice.h> 21 #include <net/llc_conn.h> 22 #include <net/llc_sap.h> 23 #include <net/sock.h> 24 #include <net/llc_c_ev.h> 25 #include <net/llc_c_ac.h> 26 #include <net/llc_c_st.h> 27 #include <net/llc_pdu.h> 28 #include <net/llc.h> 29 30 31 static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb); 32 static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb); 33 static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *ev); 34 35 static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb); 36 37 static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk, 38 struct sk_buff *skb); 39 40 static int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb); 41 42 #define INCORRECT 0 43 44 int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb) 45 { 46 struct llc_sock *llc = llc_sk(sk); 47 48 if (llc->remote_busy_flag) { 49 u8 nr; 50 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 51 52 llc->remote_busy_flag = 0; 53 del_timer(&llc->busy_state_timer.timer); 54 nr = LLC_I_GET_NR(pdu); 55 llc_conn_resend_i_pdu_as_cmd(sk, nr, 0); 56 } 57 return 0; 58 } 59 60 int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb) 61 { 62 struct llc_conn_state_ev *ev = llc_conn_ev(skb); 63 64 ev->ind_prim = LLC_CONN_PRIM; 65 return 0; 66 } 67 68 int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb) 69 { 70 struct llc_conn_state_ev *ev = llc_conn_ev(skb); 71 72 ev->cfm_prim = LLC_CONN_PRIM; 73 return 0; 74 } 75 76 static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *skb) 77 { 78 struct llc_conn_state_ev *ev = llc_conn_ev(skb); 79 80 ev->cfm_prim = LLC_DATA_PRIM; 81 return 0; 82 } 83 84 int llc_conn_ac_data_ind(struct sock *sk, struct sk_buff *skb) 85 { 86 llc_conn_rtn_pdu(sk, skb); 87 return 0; 88 } 89 90 int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb) 91 { 92 struct llc_conn_state_ev *ev = llc_conn_ev(skb); 93 u8 reason = 0; 94 int rc = 0; 95 96 if (ev->type == LLC_CONN_EV_TYPE_PDU) { 97 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); 98 99 if (LLC_PDU_IS_RSP(pdu) && 100 LLC_PDU_TYPE_IS_U(pdu) && 101 LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM) 102 reason = LLC_DISC_REASON_RX_DM_RSP_PDU; 103 else if (LLC_PDU_IS_CMD(pdu) && 104 LLC_PDU_TYPE_IS_U(pdu) && 105 LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC) 106 reason = LLC_DISC_REASON_RX_DISC_CMD_PDU; 107 } else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR) 108 reason = LLC_DISC_REASON_ACK_TMR_EXP; 109 else 110 rc = -EINVAL; 111 if (!rc) { 112 ev->reason = reason; 113 ev->ind_prim = LLC_DISC_PRIM; 114 } 115 return rc; 116 } 117 118 int llc_conn_ac_disc_confirm(struct sock *sk, struct sk_buff *skb) 119 { 120 struct llc_conn_state_ev *ev = llc_conn_ev(skb); 121 122 ev->reason = ev->status; 123 ev->cfm_prim = LLC_DISC_PRIM; 124 return 0; 125 } 126 127 int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb) 128 { 129 u8 reason = 0; 130 int rc = 1; 131 struct llc_conn_state_ev *ev = llc_conn_ev(skb); 132 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); 133 struct llc_sock *llc = llc_sk(sk); 134 135 switch (ev->type) { 136 case LLC_CONN_EV_TYPE_PDU: 137 if (LLC_PDU_IS_RSP(pdu) && 138 LLC_PDU_TYPE_IS_U(pdu) && 139 LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR) { 140 reason = LLC_RESET_REASON_LOCAL; 141 rc = 0; 142 } else if (LLC_PDU_IS_CMD(pdu) && 143 LLC_PDU_TYPE_IS_U(pdu) && 144 LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME) { 145 reason = LLC_RESET_REASON_REMOTE; 146 rc = 0; 147 } 148 break; 149 case LLC_CONN_EV_TYPE_ACK_TMR: 150 case LLC_CONN_EV_TYPE_P_TMR: 151 case LLC_CONN_EV_TYPE_REJ_TMR: 152 case LLC_CONN_EV_TYPE_BUSY_TMR: 153 if (llc->retry_count > llc->n2) { 154 reason = LLC_RESET_REASON_LOCAL; 155 rc = 0; 156 } 157 break; 158 } 159 if (!rc) { 160 ev->reason = reason; 161 ev->ind_prim = LLC_RESET_PRIM; 162 } 163 return rc; 164 } 165 166 int llc_conn_ac_rst_confirm(struct sock *sk, struct sk_buff *skb) 167 { 168 struct llc_conn_state_ev *ev = llc_conn_ev(skb); 169 170 ev->reason = 0; 171 ev->cfm_prim = LLC_RESET_PRIM; 172 return 0; 173 } 174 175 int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk, 176 struct sk_buff *skb) 177 { 178 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 179 180 if (LLC_PDU_IS_RSP(pdu) && 181 LLC_PDU_TYPE_IS_I(pdu) && 182 LLC_I_PF_IS_1(pdu) && llc_sk(sk)->ack_pf) 183 llc_conn_ac_clear_remote_busy(sk, skb); 184 return 0; 185 } 186 187 int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk, 188 struct sk_buff *skb) 189 { 190 struct llc_sock *llc = llc_sk(sk); 191 192 if (llc->data_flag == 2) 193 del_timer(&llc->rej_sent_timer.timer); 194 return 0; 195 } 196 197 int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) 198 { 199 int rc = -ENOBUFS; 200 struct llc_sock *llc = llc_sk(sk); 201 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 202 203 if (nskb) { 204 struct llc_sap *sap = llc->sap; 205 206 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, 207 llc->daddr.lsap, LLC_PDU_CMD); 208 llc_pdu_init_as_disc_cmd(nskb, 1); 209 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 210 if (unlikely(rc)) 211 goto free; 212 llc_conn_send_pdu(sk, nskb); 213 llc_conn_ac_set_p_flag_1(sk, skb); 214 } 215 out: 216 return rc; 217 free: 218 kfree_skb(nskb); 219 goto out; 220 } 221 222 int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) 223 { 224 int rc = -ENOBUFS; 225 struct llc_sock *llc = llc_sk(sk); 226 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 227 228 if (nskb) { 229 struct llc_sap *sap = llc->sap; 230 u8 f_bit; 231 232 llc_pdu_decode_pf_bit(skb, &f_bit); 233 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, 234 llc->daddr.lsap, LLC_PDU_RSP); 235 llc_pdu_init_as_dm_rsp(nskb, f_bit); 236 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 237 if (unlikely(rc)) 238 goto free; 239 llc_conn_send_pdu(sk, nskb); 240 } 241 out: 242 return rc; 243 free: 244 kfree_skb(nskb); 245 goto out; 246 } 247 248 int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) 249 { 250 int rc = -ENOBUFS; 251 struct llc_sock *llc = llc_sk(sk); 252 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 253 254 if (nskb) { 255 struct llc_sap *sap = llc->sap; 256 257 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, 258 llc->daddr.lsap, LLC_PDU_RSP); 259 llc_pdu_init_as_dm_rsp(nskb, 1); 260 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 261 if (unlikely(rc)) 262 goto free; 263 llc_conn_send_pdu(sk, nskb); 264 } 265 out: 266 return rc; 267 free: 268 kfree_skb(nskb); 269 goto out; 270 } 271 272 int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb) 273 { 274 u8 f_bit; 275 int rc = -ENOBUFS; 276 struct sk_buff *nskb; 277 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 278 struct llc_sock *llc = llc_sk(sk); 279 280 llc->rx_pdu_hdr = *((u32 *)pdu); 281 if (LLC_PDU_IS_CMD(pdu)) 282 llc_pdu_decode_pf_bit(skb, &f_bit); 283 else 284 f_bit = 0; 285 nskb = llc_alloc_frame(sk, llc->dev); 286 if (nskb) { 287 struct llc_sap *sap = llc->sap; 288 289 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, 290 llc->daddr.lsap, LLC_PDU_RSP); 291 llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS, 292 llc->vR, INCORRECT); 293 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 294 if (unlikely(rc)) 295 goto free; 296 llc_conn_send_pdu(sk, nskb); 297 } 298 out: 299 return rc; 300 free: 301 kfree_skb(nskb); 302 goto out; 303 } 304 305 int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb) 306 { 307 int rc = -ENOBUFS; 308 struct llc_sock *llc = llc_sk(sk); 309 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 310 311 if (nskb) { 312 struct llc_sap *sap = llc->sap; 313 struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)&llc->rx_pdu_hdr; 314 315 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, 316 llc->daddr.lsap, LLC_PDU_RSP); 317 llc_pdu_init_as_frmr_rsp(nskb, pdu, 0, llc->vS, 318 llc->vR, INCORRECT); 319 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 320 if (unlikely(rc)) 321 goto free; 322 llc_conn_send_pdu(sk, nskb); 323 } 324 out: 325 return rc; 326 free: 327 kfree_skb(nskb); 328 goto out; 329 } 330 331 int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) 332 { 333 u8 f_bit; 334 int rc = -ENOBUFS; 335 struct sk_buff *nskb; 336 struct llc_sock *llc = llc_sk(sk); 337 338 llc_pdu_decode_pf_bit(skb, &f_bit); 339 nskb = llc_alloc_frame(sk, llc->dev); 340 if (nskb) { 341 struct llc_sap *sap = llc->sap; 342 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 343 344 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, 345 llc->daddr.lsap, LLC_PDU_RSP); 346 llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS, 347 llc->vR, INCORRECT); 348 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 349 if (unlikely(rc)) 350 goto free; 351 llc_conn_send_pdu(sk, nskb); 352 } 353 out: 354 return rc; 355 free: 356 kfree_skb(nskb); 357 goto out; 358 } 359 360 int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) 361 { 362 int rc; 363 struct llc_sock *llc = llc_sk(sk); 364 struct llc_sap *sap = llc->sap; 365 366 llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap, 367 llc->daddr.lsap, LLC_PDU_CMD); 368 llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR); 369 rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); 370 if (likely(!rc)) { 371 llc_conn_send_pdu(sk, skb); 372 llc_conn_ac_inc_vs_by_1(sk, skb); 373 } 374 return rc; 375 } 376 377 static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb) 378 { 379 int rc; 380 struct llc_sock *llc = llc_sk(sk); 381 struct llc_sap *sap = llc->sap; 382 383 llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap, 384 llc->daddr.lsap, LLC_PDU_CMD); 385 llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR); 386 rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); 387 if (likely(!rc)) { 388 llc_conn_send_pdu(sk, skb); 389 llc_conn_ac_inc_vs_by_1(sk, skb); 390 } 391 return rc; 392 } 393 394 int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) 395 { 396 int rc; 397 struct llc_sock *llc = llc_sk(sk); 398 struct llc_sap *sap = llc->sap; 399 400 llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap, 401 llc->daddr.lsap, LLC_PDU_CMD); 402 llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR); 403 rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); 404 if (likely(!rc)) { 405 llc_conn_send_pdu(sk, skb); 406 llc_conn_ac_inc_vs_by_1(sk, skb); 407 } 408 return 0; 409 } 410 411 int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) 412 { 413 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 414 u8 nr = LLC_I_GET_NR(pdu); 415 416 llc_conn_resend_i_pdu_as_cmd(sk, nr, 0); 417 return 0; 418 } 419 420 int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk, 421 struct sk_buff *skb) 422 { 423 u8 nr; 424 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 425 int rc = -ENOBUFS; 426 struct llc_sock *llc = llc_sk(sk); 427 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 428 429 if (nskb) { 430 struct llc_sap *sap = llc->sap; 431 432 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, 433 llc->daddr.lsap, LLC_PDU_RSP); 434 llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR); 435 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 436 if (likely(!rc)) 437 llc_conn_send_pdu(sk, nskb); 438 else 439 kfree_skb(skb); 440 } 441 if (rc) { 442 nr = LLC_I_GET_NR(pdu); 443 rc = 0; 444 llc_conn_resend_i_pdu_as_cmd(sk, nr, 0); 445 } 446 return rc; 447 } 448 449 int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) 450 { 451 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 452 u8 nr = LLC_I_GET_NR(pdu); 453 454 llc_conn_resend_i_pdu_as_rsp(sk, nr, 1); 455 return 0; 456 } 457 458 int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) 459 { 460 int rc = -ENOBUFS; 461 struct llc_sock *llc = llc_sk(sk); 462 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 463 464 if (nskb) { 465 struct llc_sap *sap = llc->sap; 466 467 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, 468 llc->daddr.lsap, LLC_PDU_CMD); 469 llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR); 470 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 471 if (unlikely(rc)) 472 goto free; 473 llc_conn_send_pdu(sk, nskb); 474 } 475 out: 476 return rc; 477 free: 478 kfree_skb(nskb); 479 goto out; 480 } 481 482 int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) 483 { 484 int rc = -ENOBUFS; 485 struct llc_sock *llc = llc_sk(sk); 486 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 487 488 if (nskb) { 489 struct llc_sap *sap = llc->sap; 490 491 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, 492 llc->daddr.lsap, LLC_PDU_RSP); 493 llc_pdu_init_as_rej_rsp(nskb, 1, llc->vR); 494 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 495 if (unlikely(rc)) 496 goto free; 497 llc_conn_send_pdu(sk, nskb); 498 } 499 out: 500 return rc; 501 free: 502 kfree_skb(nskb); 503 goto out; 504 } 505 506 int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) 507 { 508 int rc = -ENOBUFS; 509 struct llc_sock *llc = llc_sk(sk); 510 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 511 512 if (nskb) { 513 struct llc_sap *sap = llc->sap; 514 515 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, 516 llc->daddr.lsap, LLC_PDU_RSP); 517 llc_pdu_init_as_rej_rsp(nskb, 0, llc->vR); 518 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 519 if (unlikely(rc)) 520 goto free; 521 llc_conn_send_pdu(sk, nskb); 522 } 523 out: 524 return rc; 525 free: 526 kfree_skb(nskb); 527 goto out; 528 } 529 530 int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) 531 { 532 int rc = -ENOBUFS; 533 struct llc_sock *llc = llc_sk(sk); 534 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 535 536 if (nskb) { 537 struct llc_sap *sap = llc->sap; 538 539 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, 540 llc->daddr.lsap, LLC_PDU_CMD); 541 llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR); 542 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 543 if (unlikely(rc)) 544 goto free; 545 llc_conn_send_pdu(sk, nskb); 546 } 547 out: 548 return rc; 549 free: 550 kfree_skb(nskb); 551 goto out; 552 } 553 554 int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) 555 { 556 int rc = -ENOBUFS; 557 struct llc_sock *llc = llc_sk(sk); 558 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 559 560 if (nskb) { 561 struct llc_sap *sap = llc->sap; 562 563 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, 564 llc->daddr.lsap, LLC_PDU_RSP); 565 llc_pdu_init_as_rnr_rsp(nskb, 1, llc->vR); 566 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 567 if (unlikely(rc)) 568 goto free; 569 llc_conn_send_pdu(sk, nskb); 570 } 571 out: 572 return rc; 573 free: 574 kfree_skb(nskb); 575 goto out; 576 } 577 578 int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) 579 { 580 int rc = -ENOBUFS; 581 struct llc_sock *llc = llc_sk(sk); 582 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 583 584 if (nskb) { 585 struct llc_sap *sap = llc->sap; 586 587 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, 588 llc->daddr.lsap, LLC_PDU_RSP); 589 llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR); 590 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 591 if (unlikely(rc)) 592 goto free; 593 llc_conn_send_pdu(sk, nskb); 594 } 595 out: 596 return rc; 597 free: 598 kfree_skb(nskb); 599 goto out; 600 } 601 602 int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb) 603 { 604 struct llc_sock *llc = llc_sk(sk); 605 606 if (!llc->remote_busy_flag) { 607 llc->remote_busy_flag = 1; 608 mod_timer(&llc->busy_state_timer.timer, 609 jiffies + llc->busy_state_timer.expire); 610 } 611 return 0; 612 } 613 614 int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) 615 { 616 int rc = -ENOBUFS; 617 struct llc_sock *llc = llc_sk(sk); 618 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 619 620 if (nskb) { 621 struct llc_sap *sap = llc->sap; 622 623 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, 624 llc->daddr.lsap, LLC_PDU_RSP); 625 llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR); 626 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 627 if (unlikely(rc)) 628 goto free; 629 llc_conn_send_pdu(sk, nskb); 630 } 631 out: 632 return rc; 633 free: 634 kfree_skb(nskb); 635 goto out; 636 } 637 638 int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) 639 { 640 int rc = -ENOBUFS; 641 struct llc_sock *llc = llc_sk(sk); 642 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 643 644 if (nskb) { 645 struct llc_sap *sap = llc->sap; 646 647 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, 648 llc->daddr.lsap, LLC_PDU_CMD); 649 llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR); 650 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 651 if (unlikely(rc)) 652 goto free; 653 llc_conn_send_pdu(sk, nskb); 654 } 655 out: 656 return rc; 657 free: 658 kfree_skb(nskb); 659 goto out; 660 } 661 662 int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) 663 { 664 int rc = -ENOBUFS; 665 struct llc_sock *llc = llc_sk(sk); 666 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 667 668 if (nskb) { 669 struct llc_sap *sap = llc->sap; 670 u8 f_bit = 1; 671 672 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, 673 llc->daddr.lsap, LLC_PDU_RSP); 674 llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR); 675 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 676 if (unlikely(rc)) 677 goto free; 678 llc_conn_send_pdu(sk, nskb); 679 } 680 out: 681 return rc; 682 free: 683 kfree_skb(nskb); 684 goto out; 685 } 686 687 int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) 688 { 689 int rc = -ENOBUFS; 690 struct llc_sock *llc = llc_sk(sk); 691 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 692 693 if (nskb) { 694 struct llc_sap *sap = llc->sap; 695 696 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, 697 llc->daddr.lsap, LLC_PDU_RSP); 698 llc_pdu_init_as_rr_rsp(nskb, 1, llc->vR); 699 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 700 if (unlikely(rc)) 701 goto free; 702 llc_conn_send_pdu(sk, nskb); 703 } 704 out: 705 return rc; 706 free: 707 kfree_skb(nskb); 708 goto out; 709 } 710 711 int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) 712 { 713 int rc = -ENOBUFS; 714 struct llc_sock *llc = llc_sk(sk); 715 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 716 717 if (nskb) { 718 struct llc_sap *sap = llc->sap; 719 720 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, 721 llc->daddr.lsap, LLC_PDU_RSP); 722 llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR); 723 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 724 if (unlikely(rc)) 725 goto free; 726 llc_conn_send_pdu(sk, nskb); 727 } 728 out: 729 return rc; 730 free: 731 kfree_skb(nskb); 732 goto out; 733 } 734 735 int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) 736 { 737 int rc = -ENOBUFS; 738 struct llc_sock *llc = llc_sk(sk); 739 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 740 741 if (nskb) { 742 struct llc_sap *sap = llc->sap; 743 744 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, 745 llc->daddr.lsap, LLC_PDU_RSP); 746 llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR); 747 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 748 if (unlikely(rc)) 749 goto free; 750 llc_conn_send_pdu(sk, nskb); 751 } 752 out: 753 return rc; 754 free: 755 kfree_skb(nskb); 756 goto out; 757 } 758 759 void llc_conn_set_p_flag(struct sock *sk, u8 value) 760 { 761 int state_changed = llc_sk(sk)->p_flag && !value; 762 763 llc_sk(sk)->p_flag = value; 764 765 if (state_changed) 766 sk->sk_state_change(sk); 767 } 768 769 int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) 770 { 771 int rc = -ENOBUFS; 772 struct llc_sock *llc = llc_sk(sk); 773 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 774 775 if (nskb) { 776 struct llc_sap *sap = llc->sap; 777 u8 *dmac = llc->daddr.mac; 778 779 if (llc->dev->flags & IFF_LOOPBACK) 780 dmac = llc->dev->dev_addr; 781 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, 782 llc->daddr.lsap, LLC_PDU_CMD); 783 llc_pdu_init_as_sabme_cmd(nskb, 1); 784 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac); 785 if (unlikely(rc)) 786 goto free; 787 llc_conn_send_pdu(sk, nskb); 788 llc_conn_set_p_flag(sk, 1); 789 } 790 out: 791 return rc; 792 free: 793 kfree_skb(nskb); 794 goto out; 795 } 796 797 int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) 798 { 799 u8 f_bit; 800 int rc = -ENOBUFS; 801 struct llc_sock *llc = llc_sk(sk); 802 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 803 804 llc_pdu_decode_pf_bit(skb, &f_bit); 805 if (nskb) { 806 struct llc_sap *sap = llc->sap; 807 808 nskb->dev = llc->dev; 809 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, 810 llc->daddr.lsap, LLC_PDU_RSP); 811 llc_pdu_init_as_ua_rsp(nskb, f_bit); 812 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 813 if (unlikely(rc)) 814 goto free; 815 llc_conn_send_pdu(sk, nskb); 816 } 817 out: 818 return rc; 819 free: 820 kfree_skb(nskb); 821 goto out; 822 } 823 824 int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb) 825 { 826 llc_sk(sk)->s_flag = 0; 827 return 0; 828 } 829 830 int llc_conn_ac_set_s_flag_1(struct sock *sk, struct sk_buff *skb) 831 { 832 llc_sk(sk)->s_flag = 1; 833 return 0; 834 } 835 836 int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb) 837 { 838 struct llc_sock *llc = llc_sk(sk); 839 840 llc_conn_set_p_flag(sk, 1); 841 mod_timer(&llc->pf_cycle_timer.timer, 842 jiffies + llc->pf_cycle_timer.expire); 843 return 0; 844 } 845 846 /** 847 * llc_conn_ac_send_ack_if_needed - check if ack is needed 848 * @sk: current connection structure 849 * @skb: current event 850 * 851 * Checks number of received PDUs which have not been acknowledged, yet, 852 * If number of them reaches to "npta"(Number of PDUs To Acknowledge) then 853 * sends an RR response as acknowledgement for them. Returns 0 for 854 * success, 1 otherwise. 855 */ 856 int llc_conn_ac_send_ack_if_needed(struct sock *sk, struct sk_buff *skb) 857 { 858 u8 pf_bit; 859 struct llc_sock *llc = llc_sk(sk); 860 861 llc_pdu_decode_pf_bit(skb, &pf_bit); 862 llc->ack_pf |= pf_bit & 1; 863 if (!llc->ack_must_be_send) { 864 llc->first_pdu_Ns = llc->vR; 865 llc->ack_must_be_send = 1; 866 llc->ack_pf = pf_bit & 1; 867 } 868 if (((llc->vR - llc->first_pdu_Ns + 1 + LLC_2_SEQ_NBR_MODULO) 869 % LLC_2_SEQ_NBR_MODULO) >= llc->npta) { 870 llc_conn_ac_send_rr_rsp_f_set_ackpf(sk, skb); 871 llc->ack_must_be_send = 0; 872 llc->ack_pf = 0; 873 llc_conn_ac_inc_npta_value(sk, skb); 874 } 875 return 0; 876 } 877 878 /** 879 * llc_conn_ac_rst_sendack_flag - resets ack_must_be_send flag 880 * @sk: current connection structure 881 * @skb: current event 882 * 883 * This action resets ack_must_be_send flag of given connection, this flag 884 * indicates if there is any PDU which has not been acknowledged yet. 885 * Returns 0 for success, 1 otherwise. 886 */ 887 int llc_conn_ac_rst_sendack_flag(struct sock *sk, struct sk_buff *skb) 888 { 889 llc_sk(sk)->ack_must_be_send = llc_sk(sk)->ack_pf = 0; 890 return 0; 891 } 892 893 /** 894 * llc_conn_ac_send_i_rsp_f_set_ackpf - acknowledge received PDUs 895 * @sk: current connection structure 896 * @skb: current event 897 * 898 * Sends an I response PDU with f-bit set to ack_pf flag as acknowledge to 899 * all received PDUs which have not been acknowledged, yet. ack_pf flag is 900 * set to one if one PDU with p-bit set to one is received. Returns 0 for 901 * success, 1 otherwise. 902 */ 903 static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk, 904 struct sk_buff *skb) 905 { 906 int rc; 907 struct llc_sock *llc = llc_sk(sk); 908 struct llc_sap *sap = llc->sap; 909 910 llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap, 911 llc->daddr.lsap, LLC_PDU_RSP); 912 llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR); 913 rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); 914 if (likely(!rc)) { 915 llc_conn_send_pdu(sk, skb); 916 llc_conn_ac_inc_vs_by_1(sk, skb); 917 } 918 return rc; 919 } 920 921 /** 922 * llc_conn_ac_send_i_as_ack - sends an I-format PDU to acknowledge rx PDUs 923 * @sk: current connection structure. 924 * @skb: current event. 925 * 926 * This action sends an I-format PDU as acknowledge to received PDUs which 927 * have not been acknowledged, yet, if there is any. By using of this 928 * action number of acknowledgements decreases, this technic is called 929 * piggy backing. Returns 0 for success, 1 otherwise. 930 */ 931 int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb) 932 { 933 struct llc_sock *llc = llc_sk(sk); 934 935 if (llc->ack_must_be_send) { 936 llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb); 937 llc->ack_must_be_send = 0 ; 938 llc->ack_pf = 0; 939 } else 940 llc_conn_ac_send_i_cmd_p_set_0(sk, skb); 941 return 0; 942 } 943 944 /** 945 * llc_conn_ac_send_rr_rsp_f_set_ackpf - ack all rx PDUs not yet acked 946 * @sk: current connection structure. 947 * @skb: current event. 948 * 949 * This action sends an RR response with f-bit set to ack_pf flag as 950 * acknowledge to all received PDUs which have not been acknowledged, yet, 951 * if there is any. ack_pf flag indicates if a PDU has been received with 952 * p-bit set to one. Returns 0 for success, 1 otherwise. 953 */ 954 static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk, 955 struct sk_buff *skb) 956 { 957 int rc = -ENOBUFS; 958 struct llc_sock *llc = llc_sk(sk); 959 struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); 960 961 if (nskb) { 962 struct llc_sap *sap = llc->sap; 963 964 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, 965 llc->daddr.lsap, LLC_PDU_RSP); 966 llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR); 967 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); 968 if (unlikely(rc)) 969 goto free; 970 llc_conn_send_pdu(sk, nskb); 971 } 972 out: 973 return rc; 974 free: 975 kfree_skb(nskb); 976 goto out; 977 } 978 979 /** 980 * llc_conn_ac_inc_npta_value - tries to make value of npta greater 981 * @sk: current connection structure. 982 * @skb: current event. 983 * 984 * After "inc_cntr" times calling of this action, "npta" increase by one. 985 * this action tries to make vale of "npta" greater as possible; number of 986 * acknowledgements decreases by increasing of "npta". Returns 0 for 987 * success, 1 otherwise. 988 */ 989 static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb) 990 { 991 struct llc_sock *llc = llc_sk(sk); 992 993 if (!llc->inc_cntr) { 994 llc->dec_step = 0; 995 llc->dec_cntr = llc->inc_cntr = 2; 996 ++llc->npta; 997 if (llc->npta > (u8) ~LLC_2_SEQ_NBR_MODULO) 998 llc->npta = (u8) ~LLC_2_SEQ_NBR_MODULO; 999 } else 1000 --llc->inc_cntr; 1001 return 0; 1002 } 1003 1004 /** 1005 * llc_conn_ac_adjust_npta_by_rr - decreases "npta" by one 1006 * @sk: current connection structure. 1007 * @skb: current event. 1008 * 1009 * After receiving "dec_cntr" times RR command, this action decreases 1010 * "npta" by one. Returns 0 for success, 1 otherwise. 1011 */ 1012 int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct sk_buff *skb) 1013 { 1014 struct llc_sock *llc = llc_sk(sk); 1015 1016 if (!llc->connect_step && !llc->remote_busy_flag) { 1017 if (!llc->dec_step) { 1018 if (!llc->dec_cntr) { 1019 llc->inc_cntr = llc->dec_cntr = 2; 1020 if (llc->npta > 0) 1021 llc->npta = llc->npta - 1; 1022 } else 1023 llc->dec_cntr -=1; 1024 } 1025 } else 1026 llc->connect_step = 0 ; 1027 return 0; 1028 } 1029 1030 /** 1031 * llc_conn_ac_adjust_npta_by_rnr - decreases "npta" by one 1032 * @sk: current connection structure. 1033 * @skb: current event. 1034 * 1035 * After receiving "dec_cntr" times RNR command, this action decreases 1036 * "npta" by one. Returns 0 for success, 1 otherwise. 1037 */ 1038 int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk, struct sk_buff *skb) 1039 { 1040 struct llc_sock *llc = llc_sk(sk); 1041 1042 if (llc->remote_busy_flag) 1043 if (!llc->dec_step) { 1044 if (!llc->dec_cntr) { 1045 llc->inc_cntr = llc->dec_cntr = 2; 1046 if (llc->npta > 0) 1047 --llc->npta; 1048 } else 1049 --llc->dec_cntr; 1050 } 1051 return 0; 1052 } 1053 1054 /** 1055 * llc_conn_ac_dec_tx_win_size - decreases tx window size 1056 * @sk: current connection structure. 1057 * @skb: current event. 1058 * 1059 * After receiving of a REJ command or response, transmit window size is 1060 * decreased by number of PDUs which are outstanding yet. Returns 0 for 1061 * success, 1 otherwise. 1062 */ 1063 int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct sk_buff *skb) 1064 { 1065 struct llc_sock *llc = llc_sk(sk); 1066 u8 unacked_pdu = skb_queue_len(&llc->pdu_unack_q); 1067 1068 if (llc->k - unacked_pdu < 1) 1069 llc->k = 1; 1070 else 1071 llc->k -= unacked_pdu; 1072 return 0; 1073 } 1074 1075 /** 1076 * llc_conn_ac_inc_tx_win_size - tx window size is inc by 1 1077 * @sk: current connection structure. 1078 * @skb: current event. 1079 * 1080 * After receiving an RR response with f-bit set to one, transmit window 1081 * size is increased by one. Returns 0 for success, 1 otherwise. 1082 */ 1083 int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb) 1084 { 1085 struct llc_sock *llc = llc_sk(sk); 1086 1087 llc->k += 1; 1088 if (llc->k > (u8) ~LLC_2_SEQ_NBR_MODULO) 1089 llc->k = (u8) ~LLC_2_SEQ_NBR_MODULO; 1090 return 0; 1091 } 1092 1093 int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb) 1094 { 1095 struct llc_sock *llc = llc_sk(sk); 1096 1097 del_timer(&llc->pf_cycle_timer.timer); 1098 del_timer(&llc->ack_timer.timer); 1099 del_timer(&llc->rej_sent_timer.timer); 1100 del_timer(&llc->busy_state_timer.timer); 1101 llc->ack_must_be_send = 0; 1102 llc->ack_pf = 0; 1103 return 0; 1104 } 1105 1106 int llc_conn_ac_stop_other_timers(struct sock *sk, struct sk_buff *skb) 1107 { 1108 struct llc_sock *llc = llc_sk(sk); 1109 1110 del_timer(&llc->rej_sent_timer.timer); 1111 del_timer(&llc->pf_cycle_timer.timer); 1112 del_timer(&llc->busy_state_timer.timer); 1113 llc->ack_must_be_send = 0; 1114 llc->ack_pf = 0; 1115 return 0; 1116 } 1117 1118 int llc_conn_ac_start_ack_timer(struct sock *sk, struct sk_buff *skb) 1119 { 1120 struct llc_sock *llc = llc_sk(sk); 1121 1122 mod_timer(&llc->ack_timer.timer, jiffies + llc->ack_timer.expire); 1123 return 0; 1124 } 1125 1126 int llc_conn_ac_start_rej_timer(struct sock *sk, struct sk_buff *skb) 1127 { 1128 struct llc_sock *llc = llc_sk(sk); 1129 1130 mod_timer(&llc->rej_sent_timer.timer, 1131 jiffies + llc->rej_sent_timer.expire); 1132 return 0; 1133 } 1134 1135 int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk, 1136 struct sk_buff *skb) 1137 { 1138 struct llc_sock *llc = llc_sk(sk); 1139 1140 if (!timer_pending(&llc->ack_timer.timer)) 1141 mod_timer(&llc->ack_timer.timer, 1142 jiffies + llc->ack_timer.expire); 1143 return 0; 1144 } 1145 1146 int llc_conn_ac_stop_ack_timer(struct sock *sk, struct sk_buff *skb) 1147 { 1148 del_timer(&llc_sk(sk)->ack_timer.timer); 1149 return 0; 1150 } 1151 1152 int llc_conn_ac_stop_p_timer(struct sock *sk, struct sk_buff *skb) 1153 { 1154 struct llc_sock *llc = llc_sk(sk); 1155 1156 del_timer(&llc->pf_cycle_timer.timer); 1157 llc_conn_set_p_flag(sk, 0); 1158 return 0; 1159 } 1160 1161 int llc_conn_ac_stop_rej_timer(struct sock *sk, struct sk_buff *skb) 1162 { 1163 del_timer(&llc_sk(sk)->rej_sent_timer.timer); 1164 return 0; 1165 } 1166 1167 int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb) 1168 { 1169 int acked; 1170 u16 unacked = 0; 1171 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 1172 struct llc_sock *llc = llc_sk(sk); 1173 1174 llc->last_nr = PDU_SUPV_GET_Nr(pdu); 1175 acked = llc_conn_remove_acked_pdus(sk, llc->last_nr, &unacked); 1176 /* On loopback we don't queue I frames in unack_pdu_q queue. */ 1177 if (acked > 0 || (llc->dev->flags & IFF_LOOPBACK)) { 1178 llc->retry_count = 0; 1179 del_timer(&llc->ack_timer.timer); 1180 if (llc->failed_data_req) { 1181 /* already, we did not accept data from upper layer 1182 * (tx_window full or unacceptable state). Now, we 1183 * can send data and must inform to upper layer. 1184 */ 1185 llc->failed_data_req = 0; 1186 llc_conn_ac_data_confirm(sk, skb); 1187 } 1188 if (unacked) 1189 mod_timer(&llc->ack_timer.timer, 1190 jiffies + llc->ack_timer.expire); 1191 } else if (llc->failed_data_req) { 1192 u8 f_bit; 1193 1194 llc_pdu_decode_pf_bit(skb, &f_bit); 1195 if (f_bit == 1) { 1196 llc->failed_data_req = 0; 1197 llc_conn_ac_data_confirm(sk, skb); 1198 } 1199 } 1200 return 0; 1201 } 1202 1203 int llc_conn_ac_upd_p_flag(struct sock *sk, struct sk_buff *skb) 1204 { 1205 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 1206 1207 if (LLC_PDU_IS_RSP(pdu)) { 1208 u8 f_bit; 1209 1210 llc_pdu_decode_pf_bit(skb, &f_bit); 1211 if (f_bit) { 1212 llc_conn_set_p_flag(sk, 0); 1213 llc_conn_ac_stop_p_timer(sk, skb); 1214 } 1215 } 1216 return 0; 1217 } 1218 1219 int llc_conn_ac_set_data_flag_2(struct sock *sk, struct sk_buff *skb) 1220 { 1221 llc_sk(sk)->data_flag = 2; 1222 return 0; 1223 } 1224 1225 int llc_conn_ac_set_data_flag_0(struct sock *sk, struct sk_buff *skb) 1226 { 1227 llc_sk(sk)->data_flag = 0; 1228 return 0; 1229 } 1230 1231 int llc_conn_ac_set_data_flag_1(struct sock *sk, struct sk_buff *skb) 1232 { 1233 llc_sk(sk)->data_flag = 1; 1234 return 0; 1235 } 1236 1237 int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock *sk, 1238 struct sk_buff *skb) 1239 { 1240 if (!llc_sk(sk)->data_flag) 1241 llc_sk(sk)->data_flag = 1; 1242 return 0; 1243 } 1244 1245 int llc_conn_ac_set_p_flag_0(struct sock *sk, struct sk_buff *skb) 1246 { 1247 llc_conn_set_p_flag(sk, 0); 1248 return 0; 1249 } 1250 1251 static int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb) 1252 { 1253 llc_conn_set_p_flag(sk, 1); 1254 return 0; 1255 } 1256 1257 int llc_conn_ac_set_remote_busy_0(struct sock *sk, struct sk_buff *skb) 1258 { 1259 llc_sk(sk)->remote_busy_flag = 0; 1260 return 0; 1261 } 1262 1263 int llc_conn_ac_set_cause_flag_0(struct sock *sk, struct sk_buff *skb) 1264 { 1265 llc_sk(sk)->cause_flag = 0; 1266 return 0; 1267 } 1268 1269 int llc_conn_ac_set_cause_flag_1(struct sock *sk, struct sk_buff *skb) 1270 { 1271 llc_sk(sk)->cause_flag = 1; 1272 return 0; 1273 } 1274 1275 int llc_conn_ac_set_retry_cnt_0(struct sock *sk, struct sk_buff *skb) 1276 { 1277 llc_sk(sk)->retry_count = 0; 1278 return 0; 1279 } 1280 1281 int llc_conn_ac_inc_retry_cnt_by_1(struct sock *sk, struct sk_buff *skb) 1282 { 1283 llc_sk(sk)->retry_count++; 1284 return 0; 1285 } 1286 1287 int llc_conn_ac_set_vr_0(struct sock *sk, struct sk_buff *skb) 1288 { 1289 llc_sk(sk)->vR = 0; 1290 return 0; 1291 } 1292 1293 int llc_conn_ac_inc_vr_by_1(struct sock *sk, struct sk_buff *skb) 1294 { 1295 llc_sk(sk)->vR = PDU_GET_NEXT_Vr(llc_sk(sk)->vR); 1296 return 0; 1297 } 1298 1299 int llc_conn_ac_set_vs_0(struct sock *sk, struct sk_buff *skb) 1300 { 1301 llc_sk(sk)->vS = 0; 1302 return 0; 1303 } 1304 1305 int llc_conn_ac_set_vs_nr(struct sock *sk, struct sk_buff *skb) 1306 { 1307 llc_sk(sk)->vS = llc_sk(sk)->last_nr; 1308 return 0; 1309 } 1310 1311 static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb) 1312 { 1313 llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % LLC_2_SEQ_NBR_MODULO; 1314 return 0; 1315 } 1316 1317 static void llc_conn_tmr_common_cb(unsigned long timeout_data, u8 type) 1318 { 1319 struct sock *sk = (struct sock *)timeout_data; 1320 struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); 1321 1322 bh_lock_sock(sk); 1323 if (skb) { 1324 struct llc_conn_state_ev *ev = llc_conn_ev(skb); 1325 1326 skb_set_owner_r(skb, sk); 1327 ev->type = type; 1328 llc_process_tmr_ev(sk, skb); 1329 } 1330 bh_unlock_sock(sk); 1331 } 1332 1333 void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data) 1334 { 1335 llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_P_TMR); 1336 } 1337 1338 void llc_conn_busy_tmr_cb(unsigned long timeout_data) 1339 { 1340 llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_BUSY_TMR); 1341 } 1342 1343 void llc_conn_ack_tmr_cb(unsigned long timeout_data) 1344 { 1345 llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_ACK_TMR); 1346 } 1347 1348 void llc_conn_rej_tmr_cb(unsigned long timeout_data) 1349 { 1350 llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_REJ_TMR); 1351 } 1352 1353 int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb) 1354 { 1355 llc_sk(sk)->X = llc_sk(sk)->vS; 1356 llc_conn_ac_set_vs_nr(sk, skb); 1357 return 0; 1358 } 1359 1360 int llc_conn_ac_upd_vs(struct sock *sk, struct sk_buff *skb) 1361 { 1362 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 1363 u8 nr = PDU_SUPV_GET_Nr(pdu); 1364 1365 if (llc_circular_between(llc_sk(sk)->vS, nr, llc_sk(sk)->X)) 1366 llc_conn_ac_set_vs_nr(sk, skb); 1367 return 0; 1368 } 1369 1370 /* 1371 * Non-standard actions; these not contained in IEEE specification; for 1372 * our own usage 1373 */ 1374 /** 1375 * llc_conn_disc - removes connection from SAP list and frees it 1376 * @sk: closed connection 1377 * @skb: occurred event 1378 */ 1379 int llc_conn_disc(struct sock *sk, struct sk_buff *skb) 1380 { 1381 /* FIXME: this thing seems to want to die */ 1382 return 0; 1383 } 1384 1385 /** 1386 * llc_conn_reset - resets connection 1387 * @sk : reseting connection. 1388 * @skb: occurred event. 1389 * 1390 * Stop all timers, empty all queues and reset all flags. 1391 */ 1392 int llc_conn_reset(struct sock *sk, struct sk_buff *skb) 1393 { 1394 llc_sk_reset(sk); 1395 return 0; 1396 } 1397 1398 /** 1399 * llc_circular_between - designates that b is between a and c or not 1400 * @a: lower bound 1401 * @b: element to see if is between a and b 1402 * @c: upper bound 1403 * 1404 * This function designates that b is between a and c or not (for example, 1405 * 0 is between 127 and 1). Returns 1 if b is between a and c, 0 1406 * otherwise. 1407 */ 1408 u8 llc_circular_between(u8 a, u8 b, u8 c) 1409 { 1410 b = b - a; 1411 c = c - a; 1412 return b <= c; 1413 } 1414 1415 /** 1416 * llc_process_tmr_ev - timer backend 1417 * @sk: active connection 1418 * @skb: occurred event 1419 * 1420 * This function is called from timer callback functions. When connection 1421 * is busy (during sending a data frame) timer expiration event must be 1422 * queued. Otherwise this event can be sent to connection state machine. 1423 * Queued events will process by llc_backlog_rcv function after sending 1424 * data frame. 1425 */ 1426 static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb) 1427 { 1428 if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) { 1429 printk(KERN_WARNING "%s: timer called on closed connection\n", 1430 __FUNCTION__); 1431 kfree_skb(skb); 1432 } else { 1433 if (!sock_owned_by_user(sk)) 1434 llc_conn_state_process(sk, skb); 1435 else { 1436 llc_set_backlog_type(skb, LLC_EVENT); 1437 sk_add_backlog(sk, skb); 1438 } 1439 } 1440 } 1441