Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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