summaryrefslogtreecommitdiffstats
path: root/net/x25
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-05-07 02:55:41 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-05-07 02:55:41 +0000
commitdcec8a13bf565e47942a1751a9cec21bec5648fe (patch)
tree548b69625b18cc2e88c3e68d0923be546c9ebb03 /net/x25
parent2e0f55e79c49509b7ff70ff1a10e1e9e90a3dfd4 (diff)
o Merge with Linux 2.1.99.
o Fix ancient bug in the ELF loader making ldd crash. o Fix ancient bug in the keyboard code for SGI, SNI and Jazz.
Diffstat (limited to 'net/x25')
-rw-r--r--net/x25/af_x25.c12
-rw-r--r--net/x25/x25_in.c28
2 files changed, 25 insertions, 15 deletions
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index a85aeea5f..163960409 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1118,13 +1118,14 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
struct x25_facilities facilities;
if (copy_from_user(&facilities, (void *)arg, sizeof(facilities)))
return -EFAULT;
- if (sk->state != TCP_LISTEN)
+ if (sk->state != TCP_LISTEN && sk->state != TCP_CLOSE)
return -EINVAL;
if (facilities.pacsize_in < X25_PS16 || facilities.pacsize_in > X25_PS4096)
return -EINVAL;
if (facilities.pacsize_out < X25_PS16 || facilities.pacsize_out > X25_PS4096)
return -EINVAL;
- if (sk->protinfo.x25->neighbour->extended) {
+ if (sk->state == TCP_CLOSE || sk->protinfo.x25->neighbour->extended)
+ {
if (facilities.winsize_in < 1 || facilities.winsize_in > 127)
return -EINVAL;
if (facilities.winsize_out < 1 || facilities.winsize_out > 127)
@@ -1188,7 +1189,7 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length, in
cli();
- len += sprintf(buffer, "dest_addr src_addr dev lci st vs vr va t t2 t21 t22 t23 Snd-Q Rcv-Q\n");
+ len += sprintf(buffer, "dest_addr src_addr dev lci st vs vr va t t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
for (s = x25_list; s != NULL; s = s->next) {
if (s->protinfo.x25->neighbour == NULL || (dev = s->protinfo.x25->neighbour->dev) == NULL)
@@ -1196,7 +1197,7 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length, in
else
devname = s->protinfo.x25->neighbour->dev->name;
- len += sprintf(buffer + len, "%-10s %-10s %-5s %3.3X %d %d %d %d %3lu %3lu %3lu %3lu %3lu %5d %5d\n",
+ len += sprintf(buffer + len, "%-10s %-10s %-5s %3.3X %d %d %d %d %3lu %3lu %3lu %3lu %3lu %5d %5d %ld\n",
(s->protinfo.x25->dest_addr.x25_addr[0] == '\0') ? "*" : s->protinfo.x25->dest_addr.x25_addr,
(s->protinfo.x25->source_addr.x25_addr[0] == '\0') ? "*" : s->protinfo.x25->source_addr.x25_addr,
devname,
@@ -1211,7 +1212,8 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length, in
s->protinfo.x25->t22 / HZ,
s->protinfo.x25->t23 / HZ,
atomic_read(&s->wmem_alloc),
- atomic_read(&s->rmem_alloc));
+ atomic_read(&s->rmem_alloc),
+ s->socket != NULL ? s->socket->inode->i_ino : 0L);
pos = begin + len;
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c
index b9a66103c..ae98e95ec 100644
--- a/net/x25/x25_in.c
+++ b/net/x25/x25_in.c
@@ -184,11 +184,6 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
case X25_RR:
case X25_RNR:
- if (frametype == X25_RNR) {
- sk->protinfo.x25->condition |= X25_COND_PEER_RX_BUSY;
- } else {
- sk->protinfo.x25->condition &= ~X25_COND_PEER_RX_BUSY;
- }
if (!x25_validate_nr(sk, nr)) {
x25_clear_queues(sk);
x25_write_internal(sk, X25_RESET_REQUEST);
@@ -201,8 +196,11 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
sk->protinfo.x25->state = X25_STATE_4;
} else {
x25_frames_acked(sk, nr);
- if (frametype == X25_RNR)
- x25_requeue_frames(sk);
+ if (frametype == X25_RNR) {
+ sk->protinfo.x25->condition |= X25_COND_PEER_RX_BUSY;
+ } else {
+ sk->protinfo.x25->condition &= ~X25_COND_PEER_RX_BUSY;
+ }
}
break;
@@ -221,15 +219,25 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
break;
}
x25_frames_acked(sk, nr);
- if (sk->protinfo.x25->condition & X25_COND_OWN_RX_BUSY)
- break;
if (ns == sk->protinfo.x25->vr) {
if (x25_queue_rx_frame(sk, skb, m) == 0) {
sk->protinfo.x25->vr = (sk->protinfo.x25->vr + 1) % modulus;
queued = 1;
} else {
- sk->protinfo.x25->condition |= X25_COND_OWN_RX_BUSY;
+ /* Should never happen */
+ x25_clear_queues(sk);
+ x25_write_internal(sk, X25_RESET_REQUEST);
+ x25_start_t22timer(sk);
+ sk->protinfo.x25->condition = 0x00;
+ sk->protinfo.x25->vs = 0;
+ sk->protinfo.x25->vr = 0;
+ sk->protinfo.x25->va = 0;
+ sk->protinfo.x25->vl = 0;
+ sk->protinfo.x25->state = X25_STATE_4;
+ break;
}
+ if (atomic_read(&sk->rmem_alloc) > (sk->rcvbuf / 2))
+ sk->protinfo.x25->condition |= X25_COND_OWN_RX_BUSY;
}
/*
* If the window is full Ack it immediately, else