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