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

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

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

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

kernel.org | git.kernel.org | LWN.net | Project Home | 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.

sflogo.php