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