.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * X.25 Packet Layer release 002 |
---|
3 | 4 | * |
---|
.. | .. |
---|
6 | 7 | * screw up. It might even work. |
---|
7 | 8 | * |
---|
8 | 9 | * This code REQUIRES 2.1.15 or higher |
---|
9 | | - * |
---|
10 | | - * This module: |
---|
11 | | - * This module is free software; you can redistribute it and/or |
---|
12 | | - * modify it under the terms of the GNU General Public License |
---|
13 | | - * as published by the Free Software Foundation; either version |
---|
14 | | - * 2 of the License, or (at your option) any later version. |
---|
15 | 10 | * |
---|
16 | 11 | * History |
---|
17 | 12 | * X.25 001 Jonathan Naylor Started coding. |
---|
.. | .. |
---|
142 | 137 | sk->sk_state_change(sk); |
---|
143 | 138 | break; |
---|
144 | 139 | } |
---|
| 140 | + case X25_CALL_REQUEST: |
---|
| 141 | + /* call collision */ |
---|
| 142 | + x25->causediag.cause = 0x01; |
---|
| 143 | + x25->causediag.diagnostic = 0x48; |
---|
| 144 | + |
---|
| 145 | + x25_write_internal(sk, X25_CLEAR_REQUEST); |
---|
| 146 | + x25_disconnect(sk, EISCONN, 0x01, 0x48); |
---|
| 147 | + break; |
---|
| 148 | + |
---|
145 | 149 | case X25_CLEAR_REQUEST: |
---|
146 | 150 | if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2)) |
---|
147 | 151 | goto out_clear; |
---|
.. | .. |
---|
345 | 349 | |
---|
346 | 350 | case X25_RESET_REQUEST: |
---|
347 | 351 | x25_write_internal(sk, X25_RESET_CONFIRMATION); |
---|
348 | | - /* fall through */ |
---|
| 352 | + fallthrough; |
---|
349 | 353 | case X25_RESET_CONFIRMATION: { |
---|
350 | 354 | x25_stop_timer(sk); |
---|
351 | 355 | x25->condition = 0x00; |
---|
.. | .. |
---|
378 | 382 | return 0; |
---|
379 | 383 | } |
---|
380 | 384 | |
---|
| 385 | +/* |
---|
| 386 | + * State machine for state 5, Call Accepted / Call Connected pending (X25_ACCPT_APPRV_FLAG). |
---|
| 387 | + * The handling of the timer(s) is in file x25_timer.c |
---|
| 388 | + * Handling of state 0 and connection release is in af_x25.c. |
---|
| 389 | + */ |
---|
| 390 | +static int x25_state5_machine(struct sock *sk, struct sk_buff *skb, int frametype) |
---|
| 391 | +{ |
---|
| 392 | + struct x25_sock *x25 = x25_sk(sk); |
---|
| 393 | + |
---|
| 394 | + switch (frametype) { |
---|
| 395 | + case X25_CLEAR_REQUEST: |
---|
| 396 | + if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2)) { |
---|
| 397 | + x25_write_internal(sk, X25_CLEAR_REQUEST); |
---|
| 398 | + x25->state = X25_STATE_2; |
---|
| 399 | + x25_start_t23timer(sk); |
---|
| 400 | + return 0; |
---|
| 401 | + } |
---|
| 402 | + |
---|
| 403 | + x25_write_internal(sk, X25_CLEAR_CONFIRMATION); |
---|
| 404 | + x25_disconnect(sk, 0, skb->data[3], skb->data[4]); |
---|
| 405 | + break; |
---|
| 406 | + |
---|
| 407 | + default: |
---|
| 408 | + break; |
---|
| 409 | + } |
---|
| 410 | + |
---|
| 411 | + return 0; |
---|
| 412 | +} |
---|
| 413 | + |
---|
381 | 414 | /* Higher level upcall for a LAPB frame */ |
---|
382 | 415 | int x25_process_rx_frame(struct sock *sk, struct sk_buff *skb) |
---|
383 | 416 | { |
---|
.. | .. |
---|
402 | 435 | case X25_STATE_4: |
---|
403 | 436 | queued = x25_state4_machine(sk, skb, frametype); |
---|
404 | 437 | break; |
---|
| 438 | + case X25_STATE_5: |
---|
| 439 | + queued = x25_state5_machine(sk, skb, frametype); |
---|
| 440 | + break; |
---|
405 | 441 | } |
---|
406 | 442 | |
---|
407 | 443 | x25_kick(sk); |
---|