linux/net/llc/llc_c_ac.c
<<
>>
Prefs
   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                       __func__);
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