Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/x25: add new state X25_STATE_5

This is needed, because if the flag X25_ACCPT_APPRV_FLAG is not set on a
socket (manual call confirmation) and the channel is cleared by remote
before the manual call confirmation was sent, this situation needs to
be handled.

Signed-off-by: Martin Schiller <ms@dev.tdt.de>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Martin Schiller and committed by
David S. Miller
f8fc57e8 65cb1398

+42 -1
+2 -1
include/net/x25.h
··· 62 62 X25_STATE_1, /* Awaiting Call Accepted */ 63 63 X25_STATE_2, /* Awaiting Clear Confirmation */ 64 64 X25_STATE_3, /* Data Transfer */ 65 - X25_STATE_4 /* Awaiting Reset Confirmation */ 65 + X25_STATE_4, /* Awaiting Reset Confirmation */ 66 + X25_STATE_5 /* Call Accepted / Call Connected pending */ 66 67 }; 67 68 68 69 enum {
+8
net/x25/af_x25.c
··· 659 659 sock_set_flag(sk, SOCK_DEAD); 660 660 sock_set_flag(sk, SOCK_DESTROY); 661 661 break; 662 + 663 + case X25_STATE_5: 664 + x25_write_internal(sk, X25_CLEAR_REQUEST); 665 + x25_disconnect(sk, 0, 0, 0); 666 + __x25_destroy_socket(sk); 667 + goto out; 662 668 } 663 669 664 670 sock_orphan(sk); ··· 1060 1054 if (test_bit(X25_ACCPT_APPRV_FLAG, &makex25->flags)) { 1061 1055 x25_write_internal(make, X25_CALL_ACCEPTED); 1062 1056 makex25->state = X25_STATE_3; 1057 + } else { 1058 + makex25->state = X25_STATE_5; 1063 1059 } 1064 1060 1065 1061 /*
+32
net/x25/x25_in.c
··· 382 382 return 0; 383 383 } 384 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 + 385 414 /* Higher level upcall for a LAPB frame */ 386 415 int x25_process_rx_frame(struct sock *sk, struct sk_buff *skb) 387 416 { ··· 434 405 break; 435 406 case X25_STATE_4: 436 407 queued = x25_state4_machine(sk, skb, frametype); 408 + break; 409 + case X25_STATE_5: 410 + queued = x25_state5_machine(sk, skb, frametype); 437 411 break; 438 412 } 439 413