linux/net/lapb/lapb_in.c
<<
>>
Prefs
   1/*
   2 *      LAPB release 002
   3 *
   4 *      This code REQUIRES 2.1.15 or higher/ NET3.038
   5 *
   6 *      This module:
   7 *              This module is free software; you can redistribute it and/or
   8 *              modify it under the terms of the GNU General Public License
   9 *              as published by the Free Software Foundation; either version
  10 *              2 of the License, or (at your option) any later version.
  11 *
  12 *      History
  13 *      LAPB 001        Jonathan Naulor Started Coding
  14 *      LAPB 002        Jonathan Naylor New timer architecture.
  15 *      2000-10-29      Henner Eisen    lapb_data_indication() return status.
  16 */
  17
  18#include <linux/errno.h>
  19#include <linux/types.h>
  20#include <linux/socket.h>
  21#include <linux/in.h>
  22#include <linux/kernel.h>
  23#include <linux/timer.h>
  24#include <linux/string.h>
  25#include <linux/sockios.h>
  26#include <linux/net.h>
  27#include <linux/inet.h>
  28#include <linux/netdevice.h>
  29#include <linux/skbuff.h>
  30#include <linux/slab.h>
  31#include <net/sock.h>
  32#include <asm/uaccess.h>
  33#include <asm/system.h>
  34#include <linux/fcntl.h>
  35#include <linux/mm.h>
  36#include <linux/interrupt.h>
  37#include <net/lapb.h>
  38
  39/*
  40 *      State machine for state 0, Disconnected State.
  41 *      The handling of the timer(s) is in file lapb_timer.c.
  42 */
  43static void lapb_state0_machine(struct lapb_cb *lapb, struct sk_buff *skb,
  44                                struct lapb_frame *frame)
  45{
  46        switch (frame->type) {
  47        case LAPB_SABM:
  48#if LAPB_DEBUG > 1
  49                printk(KERN_DEBUG "lapb: (%p) S0 RX SABM(%d)\n",
  50                       lapb->dev, frame->pf);
  51#endif
  52                if (lapb->mode & LAPB_EXTENDED) {
  53#if LAPB_DEBUG > 1
  54                        printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)\n",
  55                               lapb->dev, frame->pf);
  56#endif
  57                        lapb_send_control(lapb, LAPB_DM, frame->pf,
  58                                          LAPB_RESPONSE);
  59                } else {
  60#if LAPB_DEBUG > 1
  61                        printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n",
  62                               lapb->dev, frame->pf);
  63#endif
  64#if LAPB_DEBUG > 0
  65                        printk(KERN_DEBUG "lapb: (%p) S0 -> S3\n", lapb->dev);
  66#endif
  67                        lapb_send_control(lapb, LAPB_UA, frame->pf,
  68                                          LAPB_RESPONSE);
  69                        lapb_stop_t1timer(lapb);
  70                        lapb_stop_t2timer(lapb);
  71                        lapb->state     = LAPB_STATE_3;
  72                        lapb->condition = 0x00;
  73                        lapb->n2count   = 0;
  74                        lapb->vs        = 0;
  75                        lapb->vr        = 0;
  76                        lapb->va        = 0;
  77                        lapb_connect_indication(lapb, LAPB_OK);
  78                }
  79                break;
  80
  81        case LAPB_SABME:
  82#if LAPB_DEBUG > 1
  83                printk(KERN_DEBUG "lapb: (%p) S0 RX SABME(%d)\n",
  84                       lapb->dev, frame->pf);
  85#endif
  86                if (lapb->mode & LAPB_EXTENDED) {
  87#if LAPB_DEBUG > 1
  88                        printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n",
  89                               lapb->dev, frame->pf);
  90#endif
  91#if LAPB_DEBUG > 0
  92                        printk(KERN_DEBUG "lapb: (%p) S0 -> S3\n", lapb->dev);
  93#endif
  94                        lapb_send_control(lapb, LAPB_UA, frame->pf,
  95                                          LAPB_RESPONSE);
  96                        lapb_stop_t1timer(lapb);
  97                        lapb_stop_t2timer(lapb);
  98                        lapb->state     = LAPB_STATE_3;
  99                        lapb->condition = 0x00;
 100                        lapb->n2count   = 0;
 101                        lapb->vs        = 0;
 102                        lapb->vr        = 0;
 103                        lapb->va        = 0;
 104                        lapb_connect_indication(lapb, LAPB_OK);
 105                } else {
 106#if LAPB_DEBUG > 1
 107                        printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)\n",
 108                               lapb->dev, frame->pf);
 109#endif
 110                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 111                                          LAPB_RESPONSE);
 112                }
 113                break;
 114
 115        case LAPB_DISC:
 116#if LAPB_DEBUG > 1
 117                printk(KERN_DEBUG "lapb: (%p) S0 RX DISC(%d)\n",
 118                       lapb->dev, frame->pf);
 119                printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n",
 120                       lapb->dev, frame->pf);
 121#endif
 122                lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
 123                break;
 124
 125        default:
 126                break;
 127        }
 128
 129        kfree_skb(skb);
 130}
 131
 132/*
 133 *      State machine for state 1, Awaiting Connection State.
 134 *      The handling of the timer(s) is in file lapb_timer.c.
 135 */
 136static void lapb_state1_machine(struct lapb_cb *lapb, struct sk_buff *skb,
 137                                struct lapb_frame *frame)
 138{
 139        switch (frame->type) {
 140        case LAPB_SABM:
 141#if LAPB_DEBUG > 1
 142                printk(KERN_DEBUG "lapb: (%p) S1 RX SABM(%d)\n",
 143                       lapb->dev, frame->pf);
 144#endif
 145                if (lapb->mode & LAPB_EXTENDED) {
 146#if LAPB_DEBUG > 1
 147                        printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n",
 148                               lapb->dev, frame->pf);
 149#endif
 150                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 151                                          LAPB_RESPONSE);
 152                } else {
 153#if LAPB_DEBUG > 1
 154                        printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)\n",
 155                               lapb->dev, frame->pf);
 156#endif
 157                        lapb_send_control(lapb, LAPB_UA, frame->pf,
 158                                          LAPB_RESPONSE);
 159                }
 160                break;
 161
 162        case LAPB_SABME:
 163#if LAPB_DEBUG > 1
 164                printk(KERN_DEBUG "lapb: (%p) S1 RX SABME(%d)\n",
 165                       lapb->dev, frame->pf);
 166#endif
 167                if (lapb->mode & LAPB_EXTENDED) {
 168#if LAPB_DEBUG > 1
 169                        printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)\n",
 170                               lapb->dev, frame->pf);
 171#endif
 172                        lapb_send_control(lapb, LAPB_UA, frame->pf,
 173                                          LAPB_RESPONSE);
 174                } else {
 175#if LAPB_DEBUG > 1
 176                        printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n",
 177                               lapb->dev, frame->pf);
 178#endif
 179                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 180                                          LAPB_RESPONSE);
 181                }
 182                break;
 183
 184        case LAPB_DISC:
 185#if LAPB_DEBUG > 1
 186                printk(KERN_DEBUG "lapb: (%p) S1 RX DISC(%d)\n",
 187                       lapb->dev, frame->pf);
 188                printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n",
 189                       lapb->dev, frame->pf);
 190#endif
 191                lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
 192                break;
 193
 194        case LAPB_UA:
 195#if LAPB_DEBUG > 1
 196                printk(KERN_DEBUG "lapb: (%p) S1 RX UA(%d)\n",
 197                       lapb->dev, frame->pf);
 198#endif
 199                if (frame->pf) {
 200#if LAPB_DEBUG > 0
 201                        printk(KERN_DEBUG "lapb: (%p) S1 -> S3\n", lapb->dev);
 202#endif
 203                        lapb_stop_t1timer(lapb);
 204                        lapb_stop_t2timer(lapb);
 205                        lapb->state     = LAPB_STATE_3;
 206                        lapb->condition = 0x00;
 207                        lapb->n2count   = 0;
 208                        lapb->vs        = 0;
 209                        lapb->vr        = 0;
 210                        lapb->va        = 0;
 211                        lapb_connect_confirmation(lapb, LAPB_OK);
 212                }
 213                break;
 214
 215        case LAPB_DM:
 216#if LAPB_DEBUG > 1
 217                printk(KERN_DEBUG "lapb: (%p) S1 RX DM(%d)\n",
 218                       lapb->dev, frame->pf);
 219#endif
 220                if (frame->pf) {
 221#if LAPB_DEBUG > 0
 222                        printk(KERN_DEBUG "lapb: (%p) S1 -> S0\n", lapb->dev);
 223#endif
 224                        lapb_clear_queues(lapb);
 225                        lapb->state = LAPB_STATE_0;
 226                        lapb_start_t1timer(lapb);
 227                        lapb_stop_t2timer(lapb);
 228                        lapb_disconnect_indication(lapb, LAPB_REFUSED);
 229                }
 230                break;
 231        }
 232
 233        kfree_skb(skb);
 234}
 235
 236/*
 237 *      State machine for state 2, Awaiting Release State.
 238 *      The handling of the timer(s) is in file lapb_timer.c
 239 */
 240static void lapb_state2_machine(struct lapb_cb *lapb, struct sk_buff *skb,
 241                                struct lapb_frame *frame)
 242{
 243        switch (frame->type) {
 244        case LAPB_SABM:
 245        case LAPB_SABME:
 246#if LAPB_DEBUG > 1
 247                printk(KERN_DEBUG "lapb: (%p) S2 RX {SABM,SABME}(%d)\n",
 248                       lapb->dev, frame->pf);
 249                printk(KERN_DEBUG "lapb: (%p) S2 TX DM(%d)\n",
 250                       lapb->dev, frame->pf);
 251#endif
 252                lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
 253                break;
 254
 255        case LAPB_DISC:
 256#if LAPB_DEBUG > 1
 257                printk(KERN_DEBUG "lapb: (%p) S2 RX DISC(%d)\n",
 258                       lapb->dev, frame->pf);
 259                printk(KERN_DEBUG "lapb: (%p) S2 TX UA(%d)\n",
 260                       lapb->dev, frame->pf);
 261#endif
 262                lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
 263                break;
 264
 265        case LAPB_UA:
 266#if LAPB_DEBUG > 1
 267                printk(KERN_DEBUG "lapb: (%p) S2 RX UA(%d)\n",
 268                       lapb->dev, frame->pf);
 269#endif
 270                if (frame->pf) {
 271#if LAPB_DEBUG > 0
 272                        printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n", lapb->dev);
 273#endif
 274                        lapb->state = LAPB_STATE_0;
 275                        lapb_start_t1timer(lapb);
 276                        lapb_stop_t2timer(lapb);
 277                        lapb_disconnect_confirmation(lapb, LAPB_OK);
 278                }
 279                break;
 280
 281        case LAPB_DM:
 282#if LAPB_DEBUG > 1
 283                printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)\n",
 284                       lapb->dev, frame->pf);
 285#endif
 286                if (frame->pf) {
 287#if LAPB_DEBUG > 0
 288                        printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n", lapb->dev);
 289#endif
 290                        lapb->state = LAPB_STATE_0;
 291                        lapb_start_t1timer(lapb);
 292                        lapb_stop_t2timer(lapb);
 293                        lapb_disconnect_confirmation(lapb, LAPB_NOTCONNECTED);
 294                }
 295                break;
 296
 297        case LAPB_I:
 298        case LAPB_REJ:
 299        case LAPB_RNR:
 300        case LAPB_RR:
 301#if LAPB_DEBUG > 1
 302                printk(KERN_DEBUG "lapb: (%p) S2 RX {I,REJ,RNR,RR}(%d)\n",
 303                       lapb->dev, frame->pf);
 304                printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)\n",
 305                       lapb->dev, frame->pf);
 306#endif
 307                if (frame->pf)
 308                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 309                                          LAPB_RESPONSE);
 310                break;
 311        }
 312
 313        kfree_skb(skb);
 314}
 315
 316/*
 317 *      State machine for state 3, Connected State.
 318 *      The handling of the timer(s) is in file lapb_timer.c
 319 */
 320static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb,
 321                                struct lapb_frame *frame)
 322{
 323        int queued = 0;
 324        int modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS :
 325                                                     LAPB_SMODULUS;
 326
 327        switch (frame->type) {
 328        case LAPB_SABM:
 329#if LAPB_DEBUG > 1
 330                printk(KERN_DEBUG "lapb: (%p) S3 RX SABM(%d)\n",
 331                       lapb->dev, frame->pf);
 332#endif
 333                if (lapb->mode & LAPB_EXTENDED) {
 334#if LAPB_DEBUG > 1
 335                        printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)\n",
 336                               lapb->dev, frame->pf);
 337#endif
 338                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 339                                          LAPB_RESPONSE);
 340                } else {
 341#if LAPB_DEBUG > 1
 342                        printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)\n",
 343                               lapb->dev, frame->pf);
 344#endif
 345                        lapb_send_control(lapb, LAPB_UA, frame->pf,
 346                                          LAPB_RESPONSE);
 347                        lapb_stop_t1timer(lapb);
 348                        lapb_stop_t2timer(lapb);
 349                        lapb->condition = 0x00;
 350                        lapb->n2count   = 0;
 351                        lapb->vs        = 0;
 352                        lapb->vr        = 0;
 353                        lapb->va        = 0;
 354                        lapb_requeue_frames(lapb);
 355                }
 356                break;
 357
 358        case LAPB_SABME:
 359#if LAPB_DEBUG > 1
 360                printk(KERN_DEBUG "lapb: (%p) S3 RX SABME(%d)\n",
 361                       lapb->dev, frame->pf);
 362#endif
 363                if (lapb->mode & LAPB_EXTENDED) {
 364#if LAPB_DEBUG > 1
 365                        printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)\n",
 366                               lapb->dev, frame->pf);
 367#endif
 368                        lapb_send_control(lapb, LAPB_UA, frame->pf,
 369                                          LAPB_RESPONSE);
 370                        lapb_stop_t1timer(lapb);
 371                        lapb_stop_t2timer(lapb);
 372                        lapb->condition = 0x00;
 373                        lapb->n2count   = 0;
 374                        lapb->vs        = 0;
 375                        lapb->vr        = 0;
 376                        lapb->va        = 0;
 377                        lapb_requeue_frames(lapb);
 378                } else {
 379#if LAPB_DEBUG > 1
 380                        printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)\n",
 381                               lapb->dev, frame->pf);
 382#endif
 383                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 384                                          LAPB_RESPONSE);
 385                }
 386                break;
 387
 388        case LAPB_DISC:
 389#if LAPB_DEBUG > 1
 390                printk(KERN_DEBUG "lapb: (%p) S3 RX DISC(%d)\n",
 391                       lapb->dev, frame->pf);
 392#endif
 393#if LAPB_DEBUG > 0
 394                printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->dev);
 395#endif
 396                lapb_clear_queues(lapb);
 397                lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
 398                lapb_start_t1timer(lapb);
 399                lapb_stop_t2timer(lapb);
 400                lapb->state = LAPB_STATE_0;
 401                lapb_disconnect_indication(lapb, LAPB_OK);
 402                break;
 403
 404        case LAPB_DM:
 405#if LAPB_DEBUG > 1
 406                printk(KERN_DEBUG "lapb: (%p) S3 RX DM(%d)\n",
 407                       lapb->dev, frame->pf);
 408#endif
 409#if LAPB_DEBUG > 0
 410                printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->dev);
 411#endif
 412                lapb_clear_queues(lapb);
 413                lapb->state = LAPB_STATE_0;
 414                lapb_start_t1timer(lapb);
 415                lapb_stop_t2timer(lapb);
 416                lapb_disconnect_indication(lapb, LAPB_NOTCONNECTED);
 417                break;
 418
 419        case LAPB_RNR:
 420#if LAPB_DEBUG > 1
 421                printk(KERN_DEBUG "lapb: (%p) S3 RX RNR(%d) R%d\n",
 422                       lapb->dev, frame->pf, frame->nr);
 423#endif
 424                lapb->condition |= LAPB_PEER_RX_BUSY_CONDITION;
 425                lapb_check_need_response(lapb, frame->cr, frame->pf);
 426                if (lapb_validate_nr(lapb, frame->nr)) {
 427                        lapb_check_iframes_acked(lapb, frame->nr);
 428                } else {
 429                        lapb->frmr_data = *frame;
 430                        lapb->frmr_type = LAPB_FRMR_Z;
 431                        lapb_transmit_frmr(lapb);
 432#if LAPB_DEBUG > 0
 433                        printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev);
 434#endif
 435                        lapb_start_t1timer(lapb);
 436                        lapb_stop_t2timer(lapb);
 437                        lapb->state   = LAPB_STATE_4;
 438                        lapb->n2count = 0;
 439                }
 440                break;
 441
 442        case LAPB_RR:
 443#if LAPB_DEBUG > 1
 444                printk(KERN_DEBUG "lapb: (%p) S3 RX RR(%d) R%d\n",
 445                       lapb->dev, frame->pf, frame->nr);
 446#endif
 447                lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
 448                lapb_check_need_response(lapb, frame->cr, frame->pf);
 449                if (lapb_validate_nr(lapb, frame->nr)) {
 450                        lapb_check_iframes_acked(lapb, frame->nr);
 451                } else {
 452                        lapb->frmr_data = *frame;
 453                        lapb->frmr_type = LAPB_FRMR_Z;
 454                        lapb_transmit_frmr(lapb);
 455#if LAPB_DEBUG > 0
 456                        printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev);
 457#endif
 458                        lapb_start_t1timer(lapb);
 459                        lapb_stop_t2timer(lapb);
 460                        lapb->state   = LAPB_STATE_4;
 461                        lapb->n2count = 0;
 462                }
 463                break;
 464
 465        case LAPB_REJ:
 466#if LAPB_DEBUG > 1
 467                printk(KERN_DEBUG "lapb: (%p) S3 RX REJ(%d) R%d\n",
 468                       lapb->dev, frame->pf, frame->nr);
 469#endif
 470                lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
 471                lapb_check_need_response(lapb, frame->cr, frame->pf);
 472                if (lapb_validate_nr(lapb, frame->nr)) {
 473                        lapb_frames_acked(lapb, frame->nr);
 474                        lapb_stop_t1timer(lapb);
 475                        lapb->n2count = 0;
 476                        lapb_requeue_frames(lapb);
 477                } else {
 478                        lapb->frmr_data = *frame;
 479                        lapb->frmr_type = LAPB_FRMR_Z;
 480                        lapb_transmit_frmr(lapb);
 481#if LAPB_DEBUG > 0
 482                        printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev);
 483#endif
 484                        lapb_start_t1timer(lapb);
 485                        lapb_stop_t2timer(lapb);
 486                        lapb->state   = LAPB_STATE_4;
 487                        lapb->n2count = 0;
 488                }
 489                break;
 490
 491        case LAPB_I:
 492#if LAPB_DEBUG > 1
 493                printk(KERN_DEBUG "lapb: (%p) S3 RX I(%d) S%d R%d\n",
 494                       lapb->dev, frame->pf, frame->ns, frame->nr);
 495#endif
 496                if (!lapb_validate_nr(lapb, frame->nr)) {
 497                        lapb->frmr_data = *frame;
 498                        lapb->frmr_type = LAPB_FRMR_Z;
 499                        lapb_transmit_frmr(lapb);
 500#if LAPB_DEBUG > 0
 501                        printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev);
 502#endif
 503                        lapb_start_t1timer(lapb);
 504                        lapb_stop_t2timer(lapb);
 505                        lapb->state   = LAPB_STATE_4;
 506                        lapb->n2count = 0;
 507                        break;
 508                }
 509                if (lapb->condition & LAPB_PEER_RX_BUSY_CONDITION)
 510                        lapb_frames_acked(lapb, frame->nr);
 511                else
 512                        lapb_check_iframes_acked(lapb, frame->nr);
 513
 514                if (frame->ns == lapb->vr) {
 515                        int cn;
 516                        cn = lapb_data_indication(lapb, skb);
 517                        queued = 1;
 518                        /*
 519                         * If upper layer has dropped the frame, we
 520                         * basically ignore any further protocol
 521                         * processing. This will cause the peer
 522                         * to re-transmit the frame later like
 523                         * a frame lost on the wire.
 524                         */
 525                        if (cn == NET_RX_DROP) {
 526                                printk(KERN_DEBUG "LAPB: rx congestion\n");
 527                                break;
 528                        }
 529                        lapb->vr = (lapb->vr + 1) % modulus;
 530                        lapb->condition &= ~LAPB_REJECT_CONDITION;
 531                        if (frame->pf)
 532                                lapb_enquiry_response(lapb);
 533                        else {
 534                                if (!(lapb->condition &
 535                                      LAPB_ACK_PENDING_CONDITION)) {
 536                                        lapb->condition |= LAPB_ACK_PENDING_CONDITION;
 537                                        lapb_start_t2timer(lapb);
 538                                }
 539                        }
 540                } else {
 541                        if (lapb->condition & LAPB_REJECT_CONDITION) {
 542                                if (frame->pf)
 543                                        lapb_enquiry_response(lapb);
 544                        } else {
 545#if LAPB_DEBUG > 1
 546                                printk(KERN_DEBUG
 547                                       "lapb: (%p) S3 TX REJ(%d) R%d\n",
 548                                       lapb->dev, frame->pf, lapb->vr);
 549#endif
 550                                lapb->condition |= LAPB_REJECT_CONDITION;
 551                                lapb_send_control(lapb, LAPB_REJ, frame->pf,
 552                                                  LAPB_RESPONSE);
 553                                lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
 554                        }
 555                }
 556                break;
 557
 558        case LAPB_FRMR:
 559#if LAPB_DEBUG > 1
 560                printk(KERN_DEBUG "lapb: (%p) S3 RX FRMR(%d) %02X "
 561                       "%02X %02X %02X %02X\n", lapb->dev, frame->pf,
 562                       skb->data[0], skb->data[1], skb->data[2],
 563                       skb->data[3], skb->data[4]);
 564#endif
 565                lapb_establish_data_link(lapb);
 566#if LAPB_DEBUG > 0
 567                printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n", lapb->dev);
 568#endif
 569                lapb_requeue_frames(lapb);
 570                lapb->state = LAPB_STATE_1;
 571                break;
 572
 573        case LAPB_ILLEGAL:
 574#if LAPB_DEBUG > 1
 575                printk(KERN_DEBUG "lapb: (%p) S3 RX ILLEGAL(%d)\n",
 576                       lapb->dev, frame->pf);
 577#endif
 578                lapb->frmr_data = *frame;
 579                lapb->frmr_type = LAPB_FRMR_W;
 580                lapb_transmit_frmr(lapb);
 581#if LAPB_DEBUG > 0
 582                printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev);
 583#endif
 584                lapb_start_t1timer(lapb);
 585                lapb_stop_t2timer(lapb);
 586                lapb->state   = LAPB_STATE_4;
 587                lapb->n2count = 0;
 588                break;
 589        }
 590
 591        if (!queued)
 592                kfree_skb(skb);
 593}
 594
 595/*
 596 *      State machine for state 4, Frame Reject State.
 597 *      The handling of the timer(s) is in file lapb_timer.c.
 598 */
 599static void lapb_state4_machine(struct lapb_cb *lapb, struct sk_buff *skb,
 600                                struct lapb_frame *frame)
 601{
 602        switch (frame->type) {
 603        case LAPB_SABM:
 604#if LAPB_DEBUG > 1
 605                printk(KERN_DEBUG "lapb: (%p) S4 RX SABM(%d)\n",
 606                       lapb->dev, frame->pf);
 607#endif
 608                if (lapb->mode & LAPB_EXTENDED) {
 609#if LAPB_DEBUG > 1
 610                        printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n",
 611                               lapb->dev, frame->pf);
 612#endif
 613                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 614                                          LAPB_RESPONSE);
 615                } else {
 616#if LAPB_DEBUG > 1
 617                        printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n",
 618                               lapb->dev, frame->pf);
 619#endif
 620#if LAPB_DEBUG > 0
 621                        printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->dev);
 622#endif
 623                        lapb_send_control(lapb, LAPB_UA, frame->pf,
 624                                          LAPB_RESPONSE);
 625                        lapb_stop_t1timer(lapb);
 626                        lapb_stop_t2timer(lapb);
 627                        lapb->state     = LAPB_STATE_3;
 628                        lapb->condition = 0x00;
 629                        lapb->n2count   = 0;
 630                        lapb->vs        = 0;
 631                        lapb->vr        = 0;
 632                        lapb->va        = 0;
 633                        lapb_connect_indication(lapb, LAPB_OK);
 634                }
 635                break;
 636
 637        case LAPB_SABME:
 638#if LAPB_DEBUG > 1
 639                printk(KERN_DEBUG "lapb: (%p) S4 RX SABME(%d)\n",
 640                       lapb->dev, frame->pf);
 641#endif
 642                if (lapb->mode & LAPB_EXTENDED) {
 643#if LAPB_DEBUG > 1
 644                        printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n",
 645                               lapb->dev, frame->pf);
 646#endif
 647#if LAPB_DEBUG > 0
 648                        printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->dev);
 649#endif
 650                        lapb_send_control(lapb, LAPB_UA, frame->pf,
 651                                          LAPB_RESPONSE);
 652                        lapb_stop_t1timer(lapb);
 653                        lapb_stop_t2timer(lapb);
 654                        lapb->state     = LAPB_STATE_3;
 655                        lapb->condition = 0x00;
 656                        lapb->n2count   = 0;
 657                        lapb->vs        = 0;
 658                        lapb->vr        = 0;
 659                        lapb->va        = 0;
 660                        lapb_connect_indication(lapb, LAPB_OK);
 661                } else {
 662#if LAPB_DEBUG > 1
 663                        printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n",
 664                               lapb->dev, frame->pf);
 665#endif
 666                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 667                                          LAPB_RESPONSE);
 668                }
 669                break;
 670        }
 671
 672        kfree_skb(skb);
 673}
 674
 675/*
 676 *      Process an incoming LAPB frame
 677 */
 678void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *skb)
 679{
 680        struct lapb_frame frame;
 681
 682        if (lapb_decode(lapb, skb, &frame) < 0) {
 683                kfree_skb(skb);
 684                return;
 685        }
 686
 687        switch (lapb->state) {
 688        case LAPB_STATE_0:
 689                lapb_state0_machine(lapb, skb, &frame); break;
 690        case LAPB_STATE_1:
 691                lapb_state1_machine(lapb, skb, &frame); break;
 692        case LAPB_STATE_2:
 693                lapb_state2_machine(lapb, skb, &frame); break;
 694        case LAPB_STATE_3:
 695                lapb_state3_machine(lapb, skb, &frame); break;
 696        case LAPB_STATE_4:
 697                lapb_state4_machine(lapb, skb, &frame); break;
 698        }
 699
 700        lapb_kick(lapb);
 701}
 702
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.