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