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                llc_conn_send_pdu(sk, skb);
 376                llc_conn_ac_inc_vs_by_1(sk, skb);
 377        }
 378        return rc;
 379}
 380
 381static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
 382{
 383        int rc;
 384        struct llc_sock *llc = llc_sk(sk);
 385        struct llc_sap *sap = llc->sap;
 386
 387        llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
 388                            llc->daddr.lsap, LLC_PDU_CMD);
 389        llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
 390        rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 391        if (likely(!rc)) {
 392                llc_conn_send_pdu(sk, skb);
 393                llc_conn_ac_inc_vs_by_1(sk, skb);
 394        }
 395        return rc;
 396}
 397
 398int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 399{
 400        int rc;
 401        struct llc_sock *llc = llc_sk(sk);
 402        struct llc_sap *sap = llc->sap;
 403
 404        llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
 405                            llc->daddr.lsap, LLC_PDU_CMD);
 406        llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
 407        rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 408        if (likely(!rc)) {
 409                llc_conn_send_pdu(sk, skb);
 410                llc_conn_ac_inc_vs_by_1(sk, skb);
 411        }
 412        return 0;
 413}
 414
 415int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 416{
 417        struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 418        u8 nr = LLC_I_GET_NR(pdu);
 419
 420        llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
 421        return 0;
 422}
 423
 424int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
 425                                                struct sk_buff *skb)
 426{
 427        u8 nr;
 428        struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 429        int rc = -ENOBUFS;
 430        struct llc_sock *llc = llc_sk(sk);
 431        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
 432
 433        if (nskb) {
 434                struct llc_sap *sap = llc->sap;
 435
 436                llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 437                                    llc->daddr.lsap, LLC_PDU_RSP);
 438                llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
 439                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 440                if (likely(!rc))
 441                        llc_conn_send_pdu(sk, nskb);
 442                else
 443                        kfree_skb(skb);
 444        }
 445        if (rc) {
 446                nr = LLC_I_GET_NR(pdu);
 447                rc = 0;
 448                llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
 449        }
 450        return rc;
 451}
 452
 453int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 454{
 455        struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 456        u8 nr = LLC_I_GET_NR(pdu);
 457
 458        llc_conn_resend_i_pdu_as_rsp(sk, nr, 1);
 459        return 0;
 460}
 461
 462int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
 463{
 464        int rc = -ENOBUFS;
 465        struct llc_sock *llc = llc_sk(sk);
 466        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
 467
 468        if (nskb) {
 469                struct llc_sap *sap = llc->sap;
 470
 471                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 472                                    llc->daddr.lsap, LLC_PDU_CMD);
 473                llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR);
 474                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 475                if (unlikely(rc))
 476                        goto free;
 477                llc_conn_send_pdu(sk, nskb);
 478        }
 479out:
 480        return rc;
 481free:
 482        kfree_skb(nskb);
 483        goto out;
 484}
 485
 486int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 487{
 488        int rc = -ENOBUFS;
 489        struct llc_sock *llc = llc_sk(sk);
 490        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
 491
 492        if (nskb) {
 493                struct llc_sap *sap = llc->sap;
 494
 495                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 496                                    llc->daddr.lsap, LLC_PDU_RSP);
 497                llc_pdu_init_as_rej_rsp(nskb, 1, llc->vR);
 498                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 499                if (unlikely(rc))
 500                        goto free;
 501                llc_conn_send_pdu(sk, nskb);
 502        }
 503out:
 504        return rc;
 505free:
 506        kfree_skb(nskb);
 507        goto out;
 508}
 509
 510int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 511{
 512        int rc = -ENOBUFS;
 513        struct llc_sock *llc = llc_sk(sk);
 514        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
 515
 516        if (nskb) {
 517                struct llc_sap *sap = llc->sap;
 518
 519                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 520                                    llc->daddr.lsap, LLC_PDU_RSP);
 521                llc_pdu_init_as_rej_rsp(nskb, 0, llc->vR);
 522                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 523                if (unlikely(rc))
 524                        goto free;
 525                llc_conn_send_pdu(sk, nskb);
 526        }
 527out:
 528        return rc;
 529free:
 530        kfree_skb(nskb);
 531        goto out;
 532}
 533
 534int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
 535{
 536        int rc = -ENOBUFS;
 537        struct llc_sock *llc = llc_sk(sk);
 538        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
 539
 540        if (nskb) {
 541                struct llc_sap *sap = llc->sap;
 542
 543                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 544                                    llc->daddr.lsap, LLC_PDU_CMD);
 545                llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR);
 546                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 547                if (unlikely(rc))
 548                        goto free;
 549                llc_conn_send_pdu(sk, nskb);
 550        }
 551out:
 552        return rc;
 553free:
 554        kfree_skb(nskb);
 555        goto out;
 556}
 557
 558int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 559{
 560        int rc = -ENOBUFS;
 561        struct llc_sock *llc = llc_sk(sk);
 562        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
 563
 564        if (nskb) {
 565                struct llc_sap *sap = llc->sap;
 566
 567                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 568                                    llc->daddr.lsap, LLC_PDU_RSP);
 569                llc_pdu_init_as_rnr_rsp(nskb, 1, llc->vR);
 570                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 571                if (unlikely(rc))
 572                        goto free;
 573                llc_conn_send_pdu(sk, nskb);
 574        }
 575out:
 576        return rc;
 577free:
 578        kfree_skb(nskb);
 579        goto out;
 580}
 581
 582int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 583{
 584        int rc = -ENOBUFS;
 585        struct llc_sock *llc = llc_sk(sk);
 586        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
 587
 588        if (nskb) {
 589                struct llc_sap *sap = llc->sap;
 590
 591                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 592                                    llc->daddr.lsap, LLC_PDU_RSP);
 593                llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
 594                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 595                if (unlikely(rc))
 596                        goto free;
 597                llc_conn_send_pdu(sk, nskb);
 598        }
 599out:
 600        return rc;
 601free:
 602        kfree_skb(nskb);
 603        goto out;
 604}
 605
 606int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb)
 607{
 608        struct llc_sock *llc = llc_sk(sk);
 609
 610        if (!llc->remote_busy_flag) {
 611                llc->remote_busy_flag = 1;
 612                mod_timer(&llc->busy_state_timer.timer,
 613                         jiffies + llc->busy_state_timer.expire);
 614        }
 615        return 0;
 616}
 617
 618int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 619{
 620        int rc = -ENOBUFS;
 621        struct llc_sock *llc = llc_sk(sk);
 622        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
 623
 624        if (nskb) {
 625                struct llc_sap *sap = llc->sap;
 626
 627                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 628                                    llc->daddr.lsap, LLC_PDU_RSP);
 629                llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
 630                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 631                if (unlikely(rc))
 632                        goto free;
 633                llc_conn_send_pdu(sk, nskb);
 634        }
 635out:
 636        return rc;
 637free:
 638        kfree_skb(nskb);
 639        goto out;
 640}
 641
 642int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
 643{
 644        int rc = -ENOBUFS;
 645        struct llc_sock *llc = llc_sk(sk);
 646        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
 647
 648        if (nskb) {
 649                struct llc_sap *sap = llc->sap;
 650
 651                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 652                                    llc->daddr.lsap, LLC_PDU_CMD);
 653                llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
 654                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 655                if (unlikely(rc))
 656                        goto free;
 657                llc_conn_send_pdu(sk, nskb);
 658        }
 659out:
 660        return rc;
 661free:
 662        kfree_skb(nskb);
 663        goto out;
 664}
 665
 666int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 667{
 668        int rc = -ENOBUFS;
 669        struct llc_sock *llc = llc_sk(sk);
 670        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
 671
 672        if (nskb) {
 673                struct llc_sap *sap = llc->sap;
 674                u8 f_bit = 1;
 675
 676                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 677                                    llc->daddr.lsap, LLC_PDU_RSP);
 678                llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
 679                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 680                if (unlikely(rc))
 681                        goto free;
 682                llc_conn_send_pdu(sk, nskb);
 683        }
 684out:
 685        return rc;
 686free:
 687        kfree_skb(nskb);
 688        goto out;
 689}
 690
 691int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 692{
 693        int rc = -ENOBUFS;
 694        struct llc_sock *llc = llc_sk(sk);
 695        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
 696
 697        if (nskb) {
 698                struct llc_sap *sap = llc->sap;
 699
 700                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 701                                    llc->daddr.lsap, LLC_PDU_RSP);
 702                llc_pdu_init_as_rr_rsp(nskb, 1, llc->vR);
 703                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 704                if (unlikely(rc))
 705                        goto free;
 706                llc_conn_send_pdu(sk, nskb);
 707        }
 708out:
 709        return rc;
 710free:
 711        kfree_skb(nskb);
 712        goto out;
 713}
 714
 715int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 716{
 717        int rc = -ENOBUFS;
 718        struct llc_sock *llc = llc_sk(sk);
 719        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
 720
 721        if (nskb) {
 722                struct llc_sap *sap = llc->sap;
 723
 724                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 725                                    llc->daddr.lsap, LLC_PDU_RSP);
 726                llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
 727                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 728                if (unlikely(rc))
 729                        goto free;
 730                llc_conn_send_pdu(sk, nskb);
 731        }
 732out:
 733        return rc;
 734free:
 735        kfree_skb(nskb);
 736        goto out;
 737}
 738
 739int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 740{
 741        int rc = -ENOBUFS;
 742        struct llc_sock *llc = llc_sk(sk);
 743        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
 744
 745        if (nskb) {
 746                struct llc_sap *sap = llc->sap;
 747
 748                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 749                                    llc->daddr.lsap, LLC_PDU_RSP);
 750                llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
 751                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 752                if (unlikely(rc))
 753                        goto free;
 754                llc_conn_send_pdu(sk, nskb);
 755        }
 756out:
 757        return rc;
 758free:
 759        kfree_skb(nskb);
 760        goto out;
 761}
 762
 763void llc_conn_set_p_flag(struct sock *sk, u8 value)
 764{
 765        int state_changed = llc_sk(sk)->p_flag && !value;
 766
 767        llc_sk(sk)->p_flag = value;
 768
 769        if (state_changed)
 770                sk->sk_state_change(sk);
 771}
 772
 773int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
 774{
 775        int rc = -ENOBUFS;
 776        struct llc_sock *llc = llc_sk(sk);
 777        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
 778
 779        if (nskb) {
 780                struct llc_sap *sap = llc->sap;
 781                u8 *dmac = llc->daddr.mac;
 782
 783                if (llc->dev->flags & IFF_LOOPBACK)
 784                        dmac = llc->dev->dev_addr;
 785                llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 786                                    llc->daddr.lsap, LLC_PDU_CMD);
 787                llc_pdu_init_as_sabme_cmd(nskb, 1);
 788                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac);
 789                if (unlikely(rc))
 790                        goto free;
 791                llc_conn_send_pdu(sk, nskb);
 792                llc_conn_set_p_flag(sk, 1);
 793        }
 794out:
 795        return rc;
 796free:
 797        kfree_skb(nskb);
 798        goto out;
 799}
 800
 801int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
 802{
 803        u8 f_bit;
 804        int rc = -ENOBUFS;
 805        struct llc_sock *llc = llc_sk(sk);
 806        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
 807
 808        llc_pdu_decode_pf_bit(skb, &f_bit);
 809        if (nskb) {
 810                struct llc_sap *sap = llc->sap;
 811
 812                nskb->dev = llc->dev;
 813                llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 814                                    llc->daddr.lsap, LLC_PDU_RSP);
 815                llc_pdu_init_as_ua_rsp(nskb, f_bit);
 816                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 817                if (unlikely(rc))
 818                        goto free;
 819                llc_conn_send_pdu(sk, nskb);
 820        }
 821out:
 822        return rc;
 823free:
 824        kfree_skb(nskb);
 825        goto out;
 826}
 827
 828int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb)
 829{
 830        llc_sk(sk)->s_flag = 0;
 831        return 0;
 832}
 833
 834int llc_conn_ac_set_s_flag_1(struct sock *sk, struct sk_buff *skb)
 835{
 836        llc_sk(sk)->s_flag = 1;
 837        return 0;
 838}
 839
 840int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb)
 841{
 842        struct llc_sock *llc = llc_sk(sk);
 843
 844        llc_conn_set_p_flag(sk, 1);
 845        mod_timer(&llc->pf_cycle_timer.timer,
 846                  jiffies + llc->pf_cycle_timer.expire);
 847        return 0;
 848}
 849
 850/**
 851 *      llc_conn_ac_send_ack_if_needed - check if ack is needed
 852 *      @sk: current connection structure
 853 *      @skb: current event
 854 *
 855 *      Checks number of received PDUs which have not been acknowledged, yet,
 856 *      If number of them reaches to "npta"(Number of PDUs To Acknowledge) then
 857 *      sends an RR response as acknowledgement for them.  Returns 0 for
 858 *      success, 1 otherwise.
 859 */
 860int llc_conn_ac_send_ack_if_needed(struct sock *sk, struct sk_buff *skb)
 861{
 862        u8 pf_bit;
 863        struct llc_sock *llc = llc_sk(sk);
 864
 865        llc_pdu_decode_pf_bit(skb, &pf_bit);
 866        llc->ack_pf |= pf_bit & 1;
 867        if (!llc->ack_must_be_send) {
 868                llc->first_pdu_Ns = llc->vR;
 869                llc->ack_must_be_send = 1;
 870                llc->ack_pf = pf_bit & 1;
 871        }
 872        if (((llc->vR - llc->first_pdu_Ns + 1 + LLC_2_SEQ_NBR_MODULO)
 873                        % LLC_2_SEQ_NBR_MODULO) >= llc->npta) {
 874                llc_conn_ac_send_rr_rsp_f_set_ackpf(sk, skb);
 875                llc->ack_must_be_send   = 0;
 876                llc->ack_pf             = 0;
 877                llc_conn_ac_inc_npta_value(sk, skb);
 878        }
 879        return 0;
 880}
 881
 882/**
 883 *      llc_conn_ac_rst_sendack_flag - resets ack_must_be_send flag
 884 *      @sk: current connection structure
 885 *      @skb: current event
 886 *
 887 *      This action resets ack_must_be_send flag of given connection, this flag
 888 *      indicates if there is any PDU which has not been acknowledged yet.
 889 *      Returns 0 for success, 1 otherwise.
 890 */
 891int llc_conn_ac_rst_sendack_flag(struct sock *sk, struct sk_buff *skb)
 892{
 893        llc_sk(sk)->ack_must_be_send = llc_sk(sk)->ack_pf = 0;
 894        return 0;
 895}
 896
 897/**
 898 *      llc_conn_ac_send_i_rsp_f_set_ackpf - acknowledge received PDUs
 899 *      @sk: current connection structure
 900 *      @skb: current event
 901 *
 902 *      Sends an I response PDU with f-bit set to ack_pf flag as acknowledge to
 903 *      all received PDUs which have not been acknowledged, yet. ack_pf flag is
 904 *      set to one if one PDU with p-bit set to one is received.  Returns 0 for
 905 *      success, 1 otherwise.
 906 */
 907static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
 908                                              struct sk_buff *skb)
 909{
 910        int rc;
 911        struct llc_sock *llc = llc_sk(sk);
 912        struct llc_sap *sap = llc->sap;
 913
 914        llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
 915                            llc->daddr.lsap, LLC_PDU_RSP);
 916        llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
 917        rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 918        if (likely(!rc)) {
 919                llc_conn_send_pdu(sk, skb);
 920                llc_conn_ac_inc_vs_by_1(sk, skb);
 921        }
 922        return rc;
 923}
 924
 925/**
 926 *      llc_conn_ac_send_i_as_ack - sends an I-format PDU to acknowledge rx PDUs
 927 *      @sk: current connection structure.
 928 *      @skb: current event.
 929 *
 930 *      This action sends an I-format PDU as acknowledge to received PDUs which
 931 *      have not been acknowledged, yet, if there is any. By using of this
 932 *      action number of acknowledgements decreases, this technic is called
 933 *      piggy backing. Returns 0 for success, 1 otherwise.
 934 */
 935int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb)
 936{
 937        struct llc_sock *llc = llc_sk(sk);
 938
 939        if (llc->ack_must_be_send) {
 940                llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb);
 941                llc->ack_must_be_send = 0 ;
 942                llc->ack_pf = 0;
 943        } else
 944                llc_conn_ac_send_i_cmd_p_set_0(sk, skb);
 945        return 0;
 946}
 947
 948/**
 949 *      llc_conn_ac_send_rr_rsp_f_set_ackpf - ack all rx PDUs not yet acked
 950 *      @sk: current connection structure.
 951 *      @skb: current event.
 952 *
 953 *      This action sends an RR response with f-bit set to ack_pf flag as
 954 *      acknowledge to all received PDUs which have not been acknowledged, yet,
 955 *      if there is any. ack_pf flag indicates if a PDU has been received with
 956 *      p-bit set to one. Returns 0 for success, 1 otherwise.
 957 */
 958static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
 959                                               struct sk_buff *skb)
 960{
 961        int rc = -ENOBUFS;
 962        struct llc_sock *llc = llc_sk(sk);
 963        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
 964
 965        if (nskb) {
 966                struct llc_sap *sap = llc->sap;
 967
 968                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 969                                    llc->daddr.lsap, LLC_PDU_RSP);
 970                llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR);
 971                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 972                if (unlikely(rc))
 973                        goto free;
 974                llc_conn_send_pdu(sk, nskb);
 975        }
 976out:
 977        return rc;
 978free:
 979        kfree_skb(nskb);
 980        goto out;
 981}
 982
 983/**
 984 *      llc_conn_ac_inc_npta_value - tries to make value of npta greater
 985 *      @sk: current connection structure.
 986 *      @skb: current event.
 987 *
 988 *      After "inc_cntr" times calling of this action, "npta" increase by one.
 989 *      this action tries to make vale of "npta" greater as possible; number of
 990 *      acknowledgements decreases by increasing of "npta". Returns 0 for
 991 *      success, 1 otherwise.
 992 */
 993static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb)
 994{
 995        struct llc_sock *llc = llc_sk(sk);
 996
 997        if (!llc->inc_cntr) {
 998                llc->dec_step = 0;
 999                llc->dec_cntr = llc->inc_cntr = 2;
1000                ++llc->npta;
1001                if (llc->npta > (u8) ~LLC_2_SEQ_NBR_MODULO)
1002                        llc->npta = (u8) ~LLC_2_SEQ_NBR_MODULO;
1003        } else
1004                --llc->inc_cntr;
1005        return 0;
1006}
1007
1008/**
1009 *      llc_conn_ac_adjust_npta_by_rr - decreases "npta" by one
1010 *      @sk: current connection structure.
1011 *      @skb: current event.
1012 *
1013 *      After receiving "dec_cntr" times RR command, this action decreases
1014 *      "npta" by one. Returns 0 for success, 1 otherwise.
1015 */
1016int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct sk_buff *skb)
1017{
1018        struct llc_sock *llc = llc_sk(sk);
1019
1020        if (!llc->connect_step && !llc->remote_busy_flag) {
1021                if (!llc->dec_step) {
1022                        if (!llc->dec_cntr) {
1023                                llc->inc_cntr = llc->dec_cntr = 2;
1024                                if (llc->npta > 0)
1025                                        llc->npta = llc->npta - 1;
1026                        } else
1027                                llc->dec_cntr -=1;
1028                }
1029        } else
1030                llc->connect_step = 0 ;
1031        return 0;
1032}
1033
1034/**
1035 *      llc_conn_ac_adjust_npta_by_rnr - decreases "npta" by one
1036 *      @sk: current connection structure.
1037 *      @skb: current event.
1038 *
1039 *      After receiving "dec_cntr" times RNR command, this action decreases
1040 *      "npta" by one. Returns 0 for success, 1 otherwise.
1041 */
1042int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk, struct sk_buff *skb)
1043{
1044        struct llc_sock *llc = llc_sk(sk);
1045
1046        if (llc->remote_busy_flag)
1047                if (!llc->dec_step) {
1048                        if (!llc->dec_cntr) {
1049                                llc->inc_cntr = llc->dec_cntr = 2;
1050                                if (llc->npta > 0)
1051                                        --llc->npta;
1052                        } else
1053                                --llc->dec_cntr;
1054                }
1055        return 0;
1056}
1057
1058/**
1059 *      llc_conn_ac_dec_tx_win_size - decreases tx window size
1060 *      @sk: current connection structure.
1061 *      @skb: current event.
1062 *
1063 *      After receiving of a REJ command or response, transmit window size is
1064 *      decreased by number of PDUs which are outstanding yet. Returns 0 for
1065 *      success, 1 otherwise.
1066 */
1067int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct sk_buff *skb)
1068{
1069        struct llc_sock *llc = llc_sk(sk);
1070        u8 unacked_pdu = skb_queue_len(&llc->pdu_unack_q);
1071
1072        if (llc->k - unacked_pdu < 1)
1073                llc->k = 1;
1074        else
1075                llc->k -= unacked_pdu;
1076        return 0;
1077}
1078
1079/**
1080 *      llc_conn_ac_inc_tx_win_size - tx window size is inc by 1
1081 *      @sk: current connection structure.
1082 *      @skb: current event.
1083 *
1084 *      After receiving an RR response with f-bit set to one, transmit window
1085 *      size is increased by one. Returns 0 for success, 1 otherwise.
1086 */
1087int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb)
1088{
1089        struct llc_sock *llc = llc_sk(sk);
1090
1091        llc->k += 1;
1092        if (llc->k > (u8) ~LLC_2_SEQ_NBR_MODULO)
1093                llc->k = (u8) ~LLC_2_SEQ_NBR_MODULO;
1094        return 0;
1095}
1096
1097int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb)
1098{
1099        struct llc_sock *llc = llc_sk(sk);
1100
1101        del_timer(&llc->pf_cycle_timer.timer);
1102        del_timer(&llc->ack_timer.timer);
1103        del_timer(&llc->rej_sent_timer.timer);
1104        del_timer(&llc->busy_state_timer.timer);
1105        llc->ack_must_be_send = 0;
1106        llc->ack_pf = 0;
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(unsigned long timeout_data, u8 type)
1322{
1323        struct sock *sk = (struct sock *)timeout_data;
1324        struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
1325
1326        bh_lock_sock(sk);
1327        if (skb) {
1328                struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1329
1330                skb_set_owner_r(skb, sk);
1331                ev->type = type;
1332                llc_process_tmr_ev(sk, skb);
1333        }
1334        bh_unlock_sock(sk);
1335}
1336
1337void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
1338{
1339        llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_P_TMR);
1340}
1341
1342void llc_conn_busy_tmr_cb(unsigned long timeout_data)
1343{
1344        llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_BUSY_TMR);
1345}
1346
1347void llc_conn_ack_tmr_cb(unsigned long timeout_data)
1348{
1349        llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_ACK_TMR);
1350}
1351
1352void llc_conn_rej_tmr_cb(unsigned long timeout_data)
1353{
1354        llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_REJ_TMR);
1355}
1356
1357int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb)
1358{
1359        llc_sk(sk)->X = llc_sk(sk)->vS;
1360        llc_conn_ac_set_vs_nr(sk, skb);
1361        return 0;
1362}
1363
1364int llc_conn_ac_upd_vs(struct sock *sk, struct sk_buff *skb)
1365{
1366        struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1367        u8 nr = PDU_SUPV_GET_Nr(pdu);
1368
1369        if (llc_circular_between(llc_sk(sk)->vS, nr, llc_sk(sk)->X))
1370                llc_conn_ac_set_vs_nr(sk, skb);
1371        return 0;
1372}
1373
1374/*
1375 * Non-standard actions; these not contained in IEEE specification; for
1376 * our own usage
1377 */
1378/**
1379 *      llc_conn_disc - removes connection from SAP list and frees it
1380 *      @sk: closed connection
1381 *      @skb: occurred event
1382 */
1383int llc_conn_disc(struct sock *sk, struct sk_buff *skb)
1384{
1385        /* FIXME: this thing seems to want to die */
1386        return 0;
1387}
1388
1389/**
1390 *      llc_conn_reset - resets connection
1391 *      @sk : reseting connection.
1392 *      @skb: occurred event.
1393 *
1394 *      Stop all timers, empty all queues and reset all flags.
1395 */
1396int llc_conn_reset(struct sock *sk, struct sk_buff *skb)
1397{
1398        llc_sk_reset(sk);
1399        return 0;
1400}
1401
1402/**
1403 *      llc_circular_between - designates that b is between a and c or not
1404 *      @a: lower bound
1405 *      @b: element to see if is between a and b
1406 *      @c: upper bound
1407 *
1408 *      This function designates that b is between a and c or not (for example,
1409 *      0 is between 127 and 1). Returns 1 if b is between a and c, 0
1410 *      otherwise.
1411 */
1412u8 llc_circular_between(u8 a, u8 b, u8 c)
1413{
1414        b = b - a;
1415        c = c - a;
1416        return b <= c;
1417}
1418
1419/**
1420 *      llc_process_tmr_ev - timer backend
1421 *      @sk: active connection
1422 *      @skb: occurred event
1423 *
1424 *      This function is called from timer callback functions. When connection
1425 *      is busy (during sending a data frame) timer expiration event must be
1426 *      queued. Otherwise this event can be sent to connection state machine.
1427 *      Queued events will process by llc_backlog_rcv function after sending
1428 *      data frame.
1429 */
1430static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)
1431{
1432        if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) {
1433                printk(KERN_WARNING "%s: timer called on closed connection\n",
1434                       __func__);
1435                kfree_skb(skb);
1436        } else {
1437                if (!sock_owned_by_user(sk))
1438                        llc_conn_state_process(sk, skb);
1439                else {
1440                        llc_set_backlog_type(skb, LLC_EVENT);
1441                        __sk_add_backlog(sk, skb);
1442                }
1443        }
1444}
1445
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.