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#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  19
  20#include <linux/errno.h>
  21#include <linux/types.h>
  22#include <linux/socket.h>
  23#include <linux/in.h>
  24#include <linux/kernel.h>
  25#include <linux/timer.h>
  26#include <linux/string.h>
  27#include <linux/sockios.h>
  28#include <linux/net.h>
  29#include <linux/inet.h>
  30#include <linux/netdevice.h>
  31#include <linux/skbuff.h>
  32#include <linux/slab.h>
  33#include <net/sock.h>
  34#include <asm/uaccess.h>
  35#include <linux/fcntl.h>
  36#include <linux/mm.h>
  37#include <linux/interrupt.h>
  38#include <net/lapb.h>
  39
  40/*
  41 *      State machine for state 0, Disconnected State.
  42 *      The handling of the timer(s) is in file lapb_timer.c.
  43 */
  44static void lapb_state0_machine(struct lapb_cb *lapb, struct sk_buff *skb,
  45                                struct lapb_frame *frame)
  46{
  47        switch (frame->type) {
  48        case LAPB_SABM:
  49                lapb_dbg(1, "(%p) S0 RX SABM(%d)\n", lapb->dev, frame->pf);
  50                if (lapb->mode & LAPB_EXTENDED) {
  51                        lapb_dbg(1, "(%p) S0 TX DM(%d)\n",
  52                                 lapb->dev, frame->pf);
  53                        lapb_send_control(lapb, LAPB_DM, frame->pf,
  54                                          LAPB_RESPONSE);
  55                } else {
  56                        lapb_dbg(1, "(%p) S0 TX UA(%d)\n",
  57                                 lapb->dev, frame->pf);
  58                        lapb_dbg(0, "(%p) S0 -> S3\n", lapb->dev);
  59                        lapb_send_control(lapb, LAPB_UA, frame->pf,
  60                                          LAPB_RESPONSE);
  61                        lapb_stop_t1timer(lapb);
  62                        lapb_stop_t2timer(lapb);
  63                        lapb->state     = LAPB_STATE_3;
  64                        lapb->condition = 0x00;
  65                        lapb->n2count   = 0;
  66                        lapb->vs        = 0;
  67                        lapb->vr        = 0;
  68                        lapb->va        = 0;
  69                        lapb_connect_indication(lapb, LAPB_OK);
  70                }
  71                break;
  72
  73        case LAPB_SABME:
  74                lapb_dbg(1, "(%p) S0 RX SABME(%d)\n", lapb->dev, frame->pf);
  75                if (lapb->mode & LAPB_EXTENDED) {
  76                        lapb_dbg(1, "(%p) S0 TX UA(%d)\n",
  77                                 lapb->dev, frame->pf);
  78                        lapb_dbg(0, "(%p) S0 -> S3\n", lapb->dev);
  79                        lapb_send_control(lapb, LAPB_UA, frame->pf,
  80                                          LAPB_RESPONSE);
  81                        lapb_stop_t1timer(lapb);
  82                        lapb_stop_t2timer(lapb);
  83                        lapb->state     = LAPB_STATE_3;
  84                        lapb->condition = 0x00;
  85                        lapb->n2count   = 0;
  86                        lapb->vs        = 0;
  87                        lapb->vr        = 0;
  88                        lapb->va        = 0;
  89                        lapb_connect_indication(lapb, LAPB_OK);
  90                } else {
  91                        lapb_dbg(1, "(%p) S0 TX DM(%d)\n",
  92                                 lapb->dev, frame->pf);
  93                        lapb_send_control(lapb, LAPB_DM, frame->pf,
  94                                          LAPB_RESPONSE);
  95                }
  96                break;
  97
  98        case LAPB_DISC:
  99                lapb_dbg(1, "(%p) S0 RX DISC(%d)\n", lapb->dev, frame->pf);
 100                lapb_dbg(1, "(%p) S0 TX UA(%d)\n", lapb->dev, frame->pf);
 101                lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
 102                break;
 103
 104        default:
 105                break;
 106        }
 107
 108        kfree_skb(skb);
 109}
 110
 111/*
 112 *      State machine for state 1, Awaiting Connection State.
 113 *      The handling of the timer(s) is in file lapb_timer.c.
 114 */
 115static void lapb_state1_machine(struct lapb_cb *lapb, struct sk_buff *skb,
 116                                struct lapb_frame *frame)
 117{
 118        switch (frame->type) {
 119        case LAPB_SABM:
 120                lapb_dbg(1, "(%p) S1 RX SABM(%d)\n", lapb->dev, frame->pf);
 121                if (lapb->mode & LAPB_EXTENDED) {
 122                        lapb_dbg(1, "(%p) S1 TX DM(%d)\n",
 123                                 lapb->dev, frame->pf);
 124                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 125                                          LAPB_RESPONSE);
 126                } else {
 127                        lapb_dbg(1, "(%p) S1 TX UA(%d)\n",
 128                                 lapb->dev, frame->pf);
 129                        lapb_send_control(lapb, LAPB_UA, frame->pf,
 130                                          LAPB_RESPONSE);
 131                }
 132                break;
 133
 134        case LAPB_SABME:
 135                lapb_dbg(1, "(%p) S1 RX SABME(%d)\n", lapb->dev, frame->pf);
 136                if (lapb->mode & LAPB_EXTENDED) {
 137                        lapb_dbg(1, "(%p) S1 TX UA(%d)\n",
 138                                 lapb->dev, frame->pf);
 139                        lapb_send_control(lapb, LAPB_UA, frame->pf,
 140                                          LAPB_RESPONSE);
 141                } else {
 142                        lapb_dbg(1, "(%p) S1 TX DM(%d)\n",
 143                                 lapb->dev, frame->pf);
 144                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 145                                          LAPB_RESPONSE);
 146                }
 147                break;
 148
 149        case LAPB_DISC:
 150                lapb_dbg(1, "(%p) S1 RX DISC(%d)\n", lapb->dev, frame->pf);
 151                lapb_dbg(1, "(%p) S1 TX DM(%d)\n", lapb->dev, frame->pf);
 152                lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
 153                break;
 154
 155        case LAPB_UA:
 156                lapb_dbg(1, "(%p) S1 RX UA(%d)\n", lapb->dev, frame->pf);
 157                if (frame->pf) {
 158                        lapb_dbg(0, "(%p) S1 -> S3\n", lapb->dev);
 159                        lapb_stop_t1timer(lapb);
 160                        lapb_stop_t2timer(lapb);
 161                        lapb->state     = LAPB_STATE_3;
 162                        lapb->condition = 0x00;
 163                        lapb->n2count   = 0;
 164                        lapb->vs        = 0;
 165                        lapb->vr        = 0;
 166                        lapb->va        = 0;
 167                        lapb_connect_confirmation(lapb, LAPB_OK);
 168                }
 169                break;
 170
 171        case LAPB_DM:
 172                lapb_dbg(1, "(%p) S1 RX DM(%d)\n", lapb->dev, frame->pf);
 173                if (frame->pf) {
 174                        lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev);
 175                        lapb_clear_queues(lapb);
 176                        lapb->state = LAPB_STATE_0;
 177                        lapb_start_t1timer(lapb);
 178                        lapb_stop_t2timer(lapb);
 179                        lapb_disconnect_indication(lapb, LAPB_REFUSED);
 180                }
 181                break;
 182        }
 183
 184        kfree_skb(skb);
 185}
 186
 187/*
 188 *      State machine for state 2, Awaiting Release State.
 189 *      The handling of the timer(s) is in file lapb_timer.c
 190 */
 191static void lapb_state2_machine(struct lapb_cb *lapb, struct sk_buff *skb,
 192                                struct lapb_frame *frame)
 193{
 194        switch (frame->type) {
 195        case LAPB_SABM:
 196        case LAPB_SABME:
 197                lapb_dbg(1, "(%p) S2 RX {SABM,SABME}(%d)\n",
 198                         lapb->dev, frame->pf);
 199                lapb_dbg(1, "(%p) S2 TX DM(%d)\n", lapb->dev, frame->pf);
 200                lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
 201                break;
 202
 203        case LAPB_DISC:
 204                lapb_dbg(1, "(%p) S2 RX DISC(%d)\n", lapb->dev, frame->pf);
 205                lapb_dbg(1, "(%p) S2 TX UA(%d)\n", lapb->dev, frame->pf);
 206                lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
 207                break;
 208
 209        case LAPB_UA:
 210                lapb_dbg(1, "(%p) S2 RX UA(%d)\n", lapb->dev, frame->pf);
 211                if (frame->pf) {
 212                        lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev);
 213                        lapb->state = LAPB_STATE_0;
 214                        lapb_start_t1timer(lapb);
 215                        lapb_stop_t2timer(lapb);
 216                        lapb_disconnect_confirmation(lapb, LAPB_OK);
 217                }
 218                break;
 219
 220        case LAPB_DM:
 221                lapb_dbg(1, "(%p) S2 RX DM(%d)\n", lapb->dev, frame->pf);
 222                if (frame->pf) {
 223                        lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev);
 224                        lapb->state = LAPB_STATE_0;
 225                        lapb_start_t1timer(lapb);
 226                        lapb_stop_t2timer(lapb);
 227                        lapb_disconnect_confirmation(lapb, LAPB_NOTCONNECTED);
 228                }
 229                break;
 230
 231        case LAPB_I:
 232        case LAPB_REJ:
 233        case LAPB_RNR:
 234        case LAPB_RR:
 235                lapb_dbg(1, "(%p) S2 RX {I,REJ,RNR,RR}(%d)\n",
 236                       lapb->dev, frame->pf);
 237                lapb_dbg(1, "(%p) S2 RX DM(%d)\n", lapb->dev, frame->pf);
 238                if (frame->pf)
 239                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 240                                          LAPB_RESPONSE);
 241                break;
 242        }
 243
 244        kfree_skb(skb);
 245}
 246
 247/*
 248 *      State machine for state 3, Connected State.
 249 *      The handling of the timer(s) is in file lapb_timer.c
 250 */
 251static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb,
 252                                struct lapb_frame *frame)
 253{
 254        int queued = 0;
 255        int modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS :
 256                                                     LAPB_SMODULUS;
 257
 258        switch (frame->type) {
 259        case LAPB_SABM:
 260                lapb_dbg(1, "(%p) S3 RX SABM(%d)\n", lapb->dev, frame->pf);
 261                if (lapb->mode & LAPB_EXTENDED) {
 262                        lapb_dbg(1, "(%p) S3 TX DM(%d)\n",
 263                                 lapb->dev, frame->pf);
 264                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 265                                          LAPB_RESPONSE);
 266                } else {
 267                        lapb_dbg(1, "(%p) S3 TX UA(%d)\n",
 268                                 lapb->dev, frame->pf);
 269                        lapb_send_control(lapb, LAPB_UA, frame->pf,
 270                                          LAPB_RESPONSE);
 271                        lapb_stop_t1timer(lapb);
 272                        lapb_stop_t2timer(lapb);
 273                        lapb->condition = 0x00;
 274                        lapb->n2count   = 0;
 275                        lapb->vs        = 0;
 276                        lapb->vr        = 0;
 277                        lapb->va        = 0;
 278                        lapb_requeue_frames(lapb);
 279                }
 280                break;
 281
 282        case LAPB_SABME:
 283                lapb_dbg(1, "(%p) S3 RX SABME(%d)\n", lapb->dev, frame->pf);
 284                if (lapb->mode & LAPB_EXTENDED) {
 285                        lapb_dbg(1, "(%p) S3 TX UA(%d)\n",
 286                                 lapb->dev, frame->pf);
 287                        lapb_send_control(lapb, LAPB_UA, frame->pf,
 288                                          LAPB_RESPONSE);
 289                        lapb_stop_t1timer(lapb);
 290                        lapb_stop_t2timer(lapb);
 291                        lapb->condition = 0x00;
 292                        lapb->n2count   = 0;
 293                        lapb->vs        = 0;
 294                        lapb->vr        = 0;
 295                        lapb->va        = 0;
 296                        lapb_requeue_frames(lapb);
 297                } else {
 298                        lapb_dbg(1, "(%p) S3 TX DM(%d)\n",
 299                                 lapb->dev, frame->pf);
 300                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 301                                          LAPB_RESPONSE);
 302                }
 303                break;
 304
 305        case LAPB_DISC:
 306                lapb_dbg(1, "(%p) S3 RX DISC(%d)\n", lapb->dev, frame->pf);
 307                lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev);
 308                lapb_clear_queues(lapb);
 309                lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
 310                lapb_start_t1timer(lapb);
 311                lapb_stop_t2timer(lapb);
 312                lapb->state = LAPB_STATE_0;
 313                lapb_disconnect_indication(lapb, LAPB_OK);
 314                break;
 315
 316        case LAPB_DM:
 317                lapb_dbg(1, "(%p) S3 RX DM(%d)\n", lapb->dev, frame->pf);
 318                lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev);
 319                lapb_clear_queues(lapb);
 320                lapb->state = LAPB_STATE_0;
 321                lapb_start_t1timer(lapb);
 322                lapb_stop_t2timer(lapb);
 323                lapb_disconnect_indication(lapb, LAPB_NOTCONNECTED);
 324                break;
 325
 326        case LAPB_RNR:
 327                lapb_dbg(1, "(%p) S3 RX RNR(%d) R%d\n",
 328                         lapb->dev, frame->pf, frame->nr);
 329                lapb->condition |= LAPB_PEER_RX_BUSY_CONDITION;
 330                lapb_check_need_response(lapb, frame->cr, frame->pf);
 331                if (lapb_validate_nr(lapb, frame->nr)) {
 332                        lapb_check_iframes_acked(lapb, frame->nr);
 333                } else {
 334                        lapb->frmr_data = *frame;
 335                        lapb->frmr_type = LAPB_FRMR_Z;
 336                        lapb_transmit_frmr(lapb);
 337                        lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev);
 338                        lapb_start_t1timer(lapb);
 339                        lapb_stop_t2timer(lapb);
 340                        lapb->state   = LAPB_STATE_4;
 341                        lapb->n2count = 0;
 342                }
 343                break;
 344
 345        case LAPB_RR:
 346                lapb_dbg(1, "(%p) S3 RX RR(%d) R%d\n",
 347                         lapb->dev, frame->pf, frame->nr);
 348                lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
 349                lapb_check_need_response(lapb, frame->cr, frame->pf);
 350                if (lapb_validate_nr(lapb, frame->nr)) {
 351                        lapb_check_iframes_acked(lapb, frame->nr);
 352                } else {
 353                        lapb->frmr_data = *frame;
 354                        lapb->frmr_type = LAPB_FRMR_Z;
 355                        lapb_transmit_frmr(lapb);
 356                        lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev);
 357                        lapb_start_t1timer(lapb);
 358                        lapb_stop_t2timer(lapb);
 359                        lapb->state   = LAPB_STATE_4;
 360                        lapb->n2count = 0;
 361                }
 362                break;
 363
 364        case LAPB_REJ:
 365                lapb_dbg(1, "(%p) S3 RX REJ(%d) R%d\n",
 366                         lapb->dev, frame->pf, frame->nr);
 367                lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
 368                lapb_check_need_response(lapb, frame->cr, frame->pf);
 369                if (lapb_validate_nr(lapb, frame->nr)) {
 370                        lapb_frames_acked(lapb, frame->nr);
 371                        lapb_stop_t1timer(lapb);
 372                        lapb->n2count = 0;
 373                        lapb_requeue_frames(lapb);
 374                } else {
 375                        lapb->frmr_data = *frame;
 376                        lapb->frmr_type = LAPB_FRMR_Z;
 377                        lapb_transmit_frmr(lapb);
 378                        lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev);
 379                        lapb_start_t1timer(lapb);
 380                        lapb_stop_t2timer(lapb);
 381                        lapb->state   = LAPB_STATE_4;
 382                        lapb->n2count = 0;
 383                }
 384                break;
 385
 386        case LAPB_I:
 387                lapb_dbg(1, "(%p) S3 RX I(%d) S%d R%d\n",
 388                         lapb->dev, frame->pf, frame->ns, frame->nr);
 389                if (!lapb_validate_nr(lapb, frame->nr)) {
 390                        lapb->frmr_data = *frame;
 391                        lapb->frmr_type = LAPB_FRMR_Z;
 392                        lapb_transmit_frmr(lapb);
 393                        lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev);
 394                        lapb_start_t1timer(lapb);
 395                        lapb_stop_t2timer(lapb);
 396                        lapb->state   = LAPB_STATE_4;
 397                        lapb->n2count = 0;
 398                        break;
 399                }
 400                if (lapb->condition & LAPB_PEER_RX_BUSY_CONDITION)
 401                        lapb_frames_acked(lapb, frame->nr);
 402                else
 403                        lapb_check_iframes_acked(lapb, frame->nr);
 404
 405                if (frame->ns == lapb->vr) {
 406                        int cn;
 407                        cn = lapb_data_indication(lapb, skb);
 408                        queued = 1;
 409                        /*
 410                         * If upper layer has dropped the frame, we
 411                         * basically ignore any further protocol
 412                         * processing. This will cause the peer
 413                         * to re-transmit the frame later like
 414                         * a frame lost on the wire.
 415                         */
 416                        if (cn == NET_RX_DROP) {
 417                                pr_debug("rx congestion\n");
 418                                break;
 419                        }
 420                        lapb->vr = (lapb->vr + 1) % modulus;
 421                        lapb->condition &= ~LAPB_REJECT_CONDITION;
 422                        if (frame->pf)
 423                                lapb_enquiry_response(lapb);
 424                        else {
 425                                if (!(lapb->condition &
 426                                      LAPB_ACK_PENDING_CONDITION)) {
 427                                        lapb->condition |= LAPB_ACK_PENDING_CONDITION;
 428                                        lapb_start_t2timer(lapb);
 429                                }
 430                        }
 431                } else {
 432                        if (lapb->condition & LAPB_REJECT_CONDITION) {
 433                                if (frame->pf)
 434                                        lapb_enquiry_response(lapb);
 435                        } else {
 436                                lapb_dbg(1, "(%p) S3 TX REJ(%d) R%d\n",
 437                                         lapb->dev, frame->pf, lapb->vr);
 438                                lapb->condition |= LAPB_REJECT_CONDITION;
 439                                lapb_send_control(lapb, LAPB_REJ, frame->pf,
 440                                                  LAPB_RESPONSE);
 441                                lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
 442                        }
 443                }
 444                break;
 445
 446        case LAPB_FRMR:
 447                lapb_dbg(1, "(%p) S3 RX FRMR(%d) %02X %02X %02X %02X %02X\n",
 448                         lapb->dev, frame->pf,
 449                         skb->data[0], skb->data[1], skb->data[2],
 450                         skb->data[3], skb->data[4]);
 451                lapb_establish_data_link(lapb);
 452                lapb_dbg(0, "(%p) S3 -> S1\n", lapb->dev);
 453                lapb_requeue_frames(lapb);
 454                lapb->state = LAPB_STATE_1;
 455                break;
 456
 457        case LAPB_ILLEGAL:
 458                lapb_dbg(1, "(%p) S3 RX ILLEGAL(%d)\n", lapb->dev, frame->pf);
 459                lapb->frmr_data = *frame;
 460                lapb->frmr_type = LAPB_FRMR_W;
 461                lapb_transmit_frmr(lapb);
 462                lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev);
 463                lapb_start_t1timer(lapb);
 464                lapb_stop_t2timer(lapb);
 465                lapb->state   = LAPB_STATE_4;
 466                lapb->n2count = 0;
 467                break;
 468        }
 469
 470        if (!queued)
 471                kfree_skb(skb);
 472}
 473
 474/*
 475 *      State machine for state 4, Frame Reject State.
 476 *      The handling of the timer(s) is in file lapb_timer.c.
 477 */
 478static void lapb_state4_machine(struct lapb_cb *lapb, struct sk_buff *skb,
 479                                struct lapb_frame *frame)
 480{
 481        switch (frame->type) {
 482        case LAPB_SABM:
 483                lapb_dbg(1, "(%p) S4 RX SABM(%d)\n", lapb->dev, frame->pf);
 484                if (lapb->mode & LAPB_EXTENDED) {
 485                        lapb_dbg(1, "(%p) S4 TX DM(%d)\n",
 486                                 lapb->dev, frame->pf);
 487                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 488                                          LAPB_RESPONSE);
 489                } else {
 490                        lapb_dbg(1, "(%p) S4 TX UA(%d)\n",
 491                                 lapb->dev, frame->pf);
 492                        lapb_dbg(0, "(%p) S4 -> S3\n", lapb->dev);
 493                        lapb_send_control(lapb, LAPB_UA, frame->pf,
 494                                          LAPB_RESPONSE);
 495                        lapb_stop_t1timer(lapb);
 496                        lapb_stop_t2timer(lapb);
 497                        lapb->state     = LAPB_STATE_3;
 498                        lapb->condition = 0x00;
 499                        lapb->n2count   = 0;
 500                        lapb->vs        = 0;
 501                        lapb->vr        = 0;
 502                        lapb->va        = 0;
 503                        lapb_connect_indication(lapb, LAPB_OK);
 504                }
 505                break;
 506
 507        case LAPB_SABME:
 508                lapb_dbg(1, "(%p) S4 RX SABME(%d)\n", lapb->dev, frame->pf);
 509                if (lapb->mode & LAPB_EXTENDED) {
 510                        lapb_dbg(1, "(%p) S4 TX UA(%d)\n",
 511                                 lapb->dev, frame->pf);
 512                        lapb_dbg(0, "(%p) S4 -> S3\n", lapb->dev);
 513                        lapb_send_control(lapb, LAPB_UA, frame->pf,
 514                                          LAPB_RESPONSE);
 515                        lapb_stop_t1timer(lapb);
 516                        lapb_stop_t2timer(lapb);
 517                        lapb->state     = LAPB_STATE_3;
 518                        lapb->condition = 0x00;
 519                        lapb->n2count   = 0;
 520                        lapb->vs        = 0;
 521                        lapb->vr        = 0;
 522                        lapb->va        = 0;
 523                        lapb_connect_indication(lapb, LAPB_OK);
 524                } else {
 525                        lapb_dbg(1, "(%p) S4 TX DM(%d)\n",
 526                                 lapb->dev, frame->pf);
 527                        lapb_send_control(lapb, LAPB_DM, frame->pf,
 528                                          LAPB_RESPONSE);
 529                }
 530                break;
 531        }
 532
 533        kfree_skb(skb);
 534}
 535
 536/*
 537 *      Process an incoming LAPB frame
 538 */
 539void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *skb)
 540{
 541        struct lapb_frame frame;
 542
 543        if (lapb_decode(lapb, skb, &frame) < 0) {
 544                kfree_skb(skb);
 545                return;
 546        }
 547
 548        switch (lapb->state) {
 549        case LAPB_STATE_0:
 550                lapb_state0_machine(lapb, skb, &frame); break;
 551        case LAPB_STATE_1:
 552                lapb_state1_machine(lapb, skb, &frame); break;
 553        case LAPB_STATE_2:
 554                lapb_state2_machine(lapb, skb, &frame); break;
 555        case LAPB_STATE_3:
 556                lapb_state3_machine(lapb, skb, &frame); break;
 557        case LAPB_STATE_4:
 558                lapb_state4_machine(lapb, skb, &frame); break;
 559        }
 560
 561        lapb_kick(lapb);
 562}
 563
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.