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