~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/lapb/lapb_in.c

Version: ~ [ linux-5.3 ] ~ [ linux-5.2.14 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.72 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.143 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.192 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.192 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.73 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 <linux/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  */
 44 static 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  */
115 static 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  */
191 static 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  */
251 static 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) %5ph\n",
448                          lapb->dev, frame->pf,
449                          skb->data);
450                 lapb_establish_data_link(lapb);
451                 lapb_dbg(0, "(%p) S3 -> S1\n", lapb->dev);
452                 lapb_requeue_frames(lapb);
453                 lapb->state = LAPB_STATE_1;
454                 break;
455 
456         case LAPB_ILLEGAL:
457                 lapb_dbg(1, "(%p) S3 RX ILLEGAL(%d)\n", lapb->dev, frame->pf);
458                 lapb->frmr_data = *frame;
459                 lapb->frmr_type = LAPB_FRMR_W;
460                 lapb_transmit_frmr(lapb);
461                 lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev);
462                 lapb_start_t1timer(lapb);
463                 lapb_stop_t2timer(lapb);
464                 lapb->state   = LAPB_STATE_4;
465                 lapb->n2count = 0;
466                 break;
467         }
468 
469         if (!queued)
470                 kfree_skb(skb);
471 }
472 
473 /*
474  *      State machine for state 4, Frame Reject State.
475  *      The handling of the timer(s) is in file lapb_timer.c.
476  */
477 static void lapb_state4_machine(struct lapb_cb *lapb, struct sk_buff *skb,
478                                 struct lapb_frame *frame)
479 {
480         switch (frame->type) {
481         case LAPB_SABM:
482                 lapb_dbg(1, "(%p) S4 RX SABM(%d)\n", lapb->dev, frame->pf);
483                 if (lapb->mode & LAPB_EXTENDED) {
484                         lapb_dbg(1, "(%p) S4 TX DM(%d)\n",
485                                  lapb->dev, frame->pf);
486                         lapb_send_control(lapb, LAPB_DM, frame->pf,
487                                           LAPB_RESPONSE);
488                 } else {
489                         lapb_dbg(1, "(%p) S4 TX UA(%d)\n",
490                                  lapb->dev, frame->pf);
491                         lapb_dbg(0, "(%p) S4 -> S3\n", lapb->dev);
492                         lapb_send_control(lapb, LAPB_UA, frame->pf,
493                                           LAPB_RESPONSE);
494                         lapb_stop_t1timer(lapb);
495                         lapb_stop_t2timer(lapb);
496                         lapb->state     = LAPB_STATE_3;
497                         lapb->condition = 0x00;
498                         lapb->n2count   = 0;
499                         lapb->vs        = 0;
500                         lapb->vr        = 0;
501                         lapb->va        = 0;
502                         lapb_connect_indication(lapb, LAPB_OK);
503                 }
504                 break;
505 
506         case LAPB_SABME:
507                 lapb_dbg(1, "(%p) S4 RX SABME(%d)\n", lapb->dev, frame->pf);
508                 if (lapb->mode & LAPB_EXTENDED) {
509                         lapb_dbg(1, "(%p) S4 TX UA(%d)\n",
510                                  lapb->dev, frame->pf);
511                         lapb_dbg(0, "(%p) S4 -> S3\n", lapb->dev);
512                         lapb_send_control(lapb, LAPB_UA, frame->pf,
513                                           LAPB_RESPONSE);
514                         lapb_stop_t1timer(lapb);
515                         lapb_stop_t2timer(lapb);
516                         lapb->state     = LAPB_STATE_3;
517                         lapb->condition = 0x00;
518                         lapb->n2count   = 0;
519                         lapb->vs        = 0;
520                         lapb->vr        = 0;
521                         lapb->va        = 0;
522                         lapb_connect_indication(lapb, LAPB_OK);
523                 } else {
524                         lapb_dbg(1, "(%p) S4 TX DM(%d)\n",
525                                  lapb->dev, frame->pf);
526                         lapb_send_control(lapb, LAPB_DM, frame->pf,
527                                           LAPB_RESPONSE);
528                 }
529                 break;
530         }
531 
532         kfree_skb(skb);
533 }
534 
535 /*
536  *      Process an incoming LAPB frame
537  */
538 void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *skb)
539 {
540         struct lapb_frame frame;
541 
542         if (lapb_decode(lapb, skb, &frame) < 0) {
543                 kfree_skb(skb);
544                 return;
545         }
546 
547         switch (lapb->state) {
548         case LAPB_STATE_0:
549                 lapb_state0_machine(lapb, skb, &frame); break;
550         case LAPB_STATE_1:
551                 lapb_state1_machine(lapb, skb, &frame); break;
552         case LAPB_STATE_2:
553                 lapb_state2_machine(lapb, skb, &frame); break;
554         case LAPB_STATE_3:
555                 lapb_state3_machine(lapb, skb, &frame); break;
556         case LAPB_STATE_4:
557                 lapb_state4_machine(lapb, skb, &frame); break;
558         }
559 
560         lapb_kick(lapb);
561 }
562 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp