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