mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 14:14:24 +08:00
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>
This commit is contained in:
parent
65cb139862
commit
f8fc57e8d7
@ -62,7 +62,8 @@ enum {
|
||||
X25_STATE_1, /* Awaiting Call Accepted */
|
||||
X25_STATE_2, /* Awaiting Clear Confirmation */
|
||||
X25_STATE_3, /* Data Transfer */
|
||||
X25_STATE_4 /* Awaiting Reset Confirmation */
|
||||
X25_STATE_4, /* Awaiting Reset Confirmation */
|
||||
X25_STATE_5 /* Call Accepted / Call Connected pending */
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -659,6 +659,12 @@ static int x25_release(struct socket *sock)
|
||||
sock_set_flag(sk, SOCK_DEAD);
|
||||
sock_set_flag(sk, SOCK_DESTROY);
|
||||
break;
|
||||
|
||||
case X25_STATE_5:
|
||||
x25_write_internal(sk, X25_CLEAR_REQUEST);
|
||||
x25_disconnect(sk, 0, 0, 0);
|
||||
__x25_destroy_socket(sk);
|
||||
goto out;
|
||||
}
|
||||
|
||||
sock_orphan(sk);
|
||||
@ -1054,6 +1060,8 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
|
||||
if (test_bit(X25_ACCPT_APPRV_FLAG, &makex25->flags)) {
|
||||
x25_write_internal(make, X25_CALL_ACCEPTED);
|
||||
makex25->state = X25_STATE_3;
|
||||
} else {
|
||||
makex25->state = X25_STATE_5;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -382,6 +382,35 @@ out_clear:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* State machine for state 5, Call Accepted / Call Connected pending (X25_ACCPT_APPRV_FLAG).
|
||||
* The handling of the timer(s) is in file x25_timer.c
|
||||
* Handling of state 0 and connection release is in af_x25.c.
|
||||
*/
|
||||
static int x25_state5_machine(struct sock *sk, struct sk_buff *skb, int frametype)
|
||||
{
|
||||
struct x25_sock *x25 = x25_sk(sk);
|
||||
|
||||
switch (frametype) {
|
||||
case X25_CLEAR_REQUEST:
|
||||
if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2)) {
|
||||
x25_write_internal(sk, X25_CLEAR_REQUEST);
|
||||
x25->state = X25_STATE_2;
|
||||
x25_start_t23timer(sk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
|
||||
x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Higher level upcall for a LAPB frame */
|
||||
int x25_process_rx_frame(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
@ -406,6 +435,9 @@ int x25_process_rx_frame(struct sock *sk, struct sk_buff *skb)
|
||||
case X25_STATE_4:
|
||||
queued = x25_state4_machine(sk, skb, frametype);
|
||||
break;
|
||||
case X25_STATE_5:
|
||||
queued = x25_state5_machine(sk, skb, frametype);
|
||||
break;
|
||||
}
|
||||
|
||||
x25_kick(sk);
|
||||
|
Loading…
Reference in New Issue
Block a user