Commit df3856a0 authored by Ralf Bächle's avatar Ralf Bächle

More reformatting of switch statements.

parent f7c8ad70
...@@ -334,38 +334,38 @@ static int nr_setsockopt(struct socket *sock, int level, int optname, ...@@ -334,38 +334,38 @@ static int nr_setsockopt(struct socket *sock, int level, int optname,
return -EFAULT; return -EFAULT;
switch (optname) { switch (optname) {
case NETROM_T1: case NETROM_T1:
if (opt < 1) if (opt < 1)
return -EINVAL; return -EINVAL;
nr->t1 = opt * HZ; nr->t1 = opt * HZ;
return 0; return 0;
case NETROM_T2: case NETROM_T2:
if (opt < 1) if (opt < 1)
return -EINVAL; return -EINVAL;
nr->t2 = opt * HZ; nr->t2 = opt * HZ;
return 0; return 0;
case NETROM_N2: case NETROM_N2:
if (opt < 1 || opt > 31) if (opt < 1 || opt > 31)
return -EINVAL; return -EINVAL;
nr->n2 = opt; nr->n2 = opt;
return 0; return 0;
case NETROM_T4: case NETROM_T4:
if (opt < 1) if (opt < 1)
return -EINVAL; return -EINVAL;
nr->t4 = opt * HZ; nr->t4 = opt * HZ;
return 0; return 0;
case NETROM_IDLE: case NETROM_IDLE:
if (opt < 0) if (opt < 0)
return -EINVAL; return -EINVAL;
nr->idle = opt * 60 * HZ; nr->idle = opt * 60 * HZ;
return 0; return 0;
default: default:
return -ENOPROTOOPT; return -ENOPROTOOPT;
} }
} }
...@@ -387,28 +387,28 @@ static int nr_getsockopt(struct socket *sock, int level, int optname, ...@@ -387,28 +387,28 @@ static int nr_getsockopt(struct socket *sock, int level, int optname,
return -EINVAL; return -EINVAL;
switch (optname) { switch (optname) {
case NETROM_T1: case NETROM_T1:
val = nr->t1 / HZ; val = nr->t1 / HZ;
break; break;
case NETROM_T2: case NETROM_T2:
val = nr->t2 / HZ; val = nr->t2 / HZ;
break; break;
case NETROM_N2: case NETROM_N2:
val = nr->n2; val = nr->n2;
break; break;
case NETROM_T4: case NETROM_T4:
val = nr->t4 / HZ; val = nr->t4 / HZ;
break; break;
case NETROM_IDLE: case NETROM_IDLE:
val = nr->idle / (60 * HZ); val = nr->idle / (60 * HZ);
break; break;
default: default:
return -ENOPROTOOPT; return -ENOPROTOOPT;
} }
len = min_t(unsigned int, len, sizeof(int)); len = min_t(unsigned int, len, sizeof(int));
...@@ -533,34 +533,33 @@ static int nr_release(struct socket *sock) ...@@ -533,34 +533,33 @@ static int nr_release(struct socket *sock)
nr = nr_sk(sk); nr = nr_sk(sk);
switch (nr->state) { switch (nr->state) {
case NR_STATE_0:
case NR_STATE_0: case NR_STATE_1:
case NR_STATE_1: case NR_STATE_2:
case NR_STATE_2: nr_disconnect(sk, 0);
nr_disconnect(sk, 0); nr_destroy_socket(sk);
nr_destroy_socket(sk); break;
break;
case NR_STATE_3:
case NR_STATE_3: nr_clear_queues(sk);
nr_clear_queues(sk); nr->n2count = 0;
nr->n2count = 0; nr_write_internal(sk, NR_DISCREQ);
nr_write_internal(sk, NR_DISCREQ); nr_start_t1timer(sk);
nr_start_t1timer(sk); nr_stop_t2timer(sk);
nr_stop_t2timer(sk); nr_stop_t4timer(sk);
nr_stop_t4timer(sk); nr_stop_idletimer(sk);
nr_stop_idletimer(sk); nr->state = NR_STATE_2;
nr->state = NR_STATE_2; sk->state = TCP_CLOSE;
sk->state = TCP_CLOSE; sk->shutdown |= SEND_SHUTDOWN;
sk->shutdown |= SEND_SHUTDOWN; sk->state_change(sk);
sk->state_change(sk); sk->dead = 1;
sk->dead = 1; sk->destroy = 1;
sk->destroy = 1; sk->socket = NULL;
sk->socket = NULL; break;
break;
default:
default: sk->socket = NULL;
sk->socket = NULL; break;
break;
} }
sock->sk = NULL; sock->sk = NULL;
...@@ -1113,54 +1112,53 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -1113,54 +1112,53 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
switch (cmd) { switch (cmd) {
case TIOCOUTQ: { case TIOCOUTQ: {
long amount; long amount;
amount = sk->sndbuf - atomic_read(&sk->wmem_alloc); amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
if (amount < 0) if (amount < 0)
amount = 0; amount = 0;
return put_user(amount, (int *)arg); return put_user(amount, (int *)arg);
} }
case TIOCINQ: { case TIOCINQ: {
struct sk_buff *skb; struct sk_buff *skb;
long amount = 0L; long amount = 0L;
/* These two are safe on a single CPU system as only user tasks fiddle here */ /* These two are safe on a single CPU system as only user tasks fiddle here */
if ((skb = skb_peek(&sk->receive_queue)) != NULL) if ((skb = skb_peek(&sk->receive_queue)) != NULL)
amount = skb->len; amount = skb->len;
return put_user(amount, (int *)arg); return put_user(amount, (int *)arg);
} }
case SIOCGSTAMP: case SIOCGSTAMP:
if (sk != NULL) { if (sk != NULL) {
if (sk->stamp.tv_sec == 0) if (sk->stamp.tv_sec == 0)
return -ENOENT; return -ENOENT;
return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0; return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0;
} }
return -EINVAL; return -EINVAL;
case SIOCGIFADDR: case SIOCGIFADDR:
case SIOCSIFADDR: case SIOCSIFADDR:
case SIOCGIFDSTADDR: case SIOCGIFDSTADDR:
case SIOCSIFDSTADDR: case SIOCSIFDSTADDR:
case SIOCGIFBRDADDR: case SIOCGIFBRDADDR:
case SIOCSIFBRDADDR: case SIOCSIFBRDADDR:
case SIOCGIFNETMASK: case SIOCGIFNETMASK:
case SIOCSIFNETMASK: case SIOCSIFNETMASK:
case SIOCGIFMETRIC: case SIOCGIFMETRIC:
case SIOCSIFMETRIC: case SIOCSIFMETRIC:
return -EINVAL; return -EINVAL;
case SIOCADDRT: case SIOCADDRT:
case SIOCDELRT: case SIOCDELRT:
case SIOCNRDECOBS: case SIOCNRDECOBS:
if (!capable(CAP_NET_ADMIN)) return -EPERM; if (!capable(CAP_NET_ADMIN)) return -EPERM;
return nr_rt_ioctl(cmd, (void *)arg); return nr_rt_ioctl(cmd, (void *)arg);
default: default:
return dev_ioctl(cmd, (void *)arg); return dev_ioctl(cmd, (void *)arg);
} }
/*NOTREACHED*/
return 0; return 0;
} }
......
...@@ -71,36 +71,36 @@ static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more) ...@@ -71,36 +71,36 @@ static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
* The handling of the timer(s) is in file nr_timer.c. * The handling of the timer(s) is in file nr_timer.c.
* Handling of state 0 and connection release is in netrom.c. * Handling of state 0 and connection release is in netrom.c.
*/ */
static int nr_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype) static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
int frametype)
{ {
switch (frametype) { switch (frametype) {
case NR_CONNACK: {
nr_cb *nr = nr_sk(sk);
nr_stop_t1timer(sk);
nr_start_idletimer(sk);
nr->your_index = skb->data[17];
nr->your_id = skb->data[18];
nr->vs = 0;
nr->va = 0;
nr->vr = 0;
nr->vl = 0;
nr->state = NR_STATE_3;
nr->n2count = 0;
nr->window = skb->data[20];
sk->state = TCP_ESTABLISHED;
if (!sk->dead)
sk->state_change(sk);
break;
}
case NR_CONNACK: { case NR_CONNACK | NR_CHOKE_FLAG:
nr_cb *nr = nr_sk(sk); nr_disconnect(sk, ECONNREFUSED);
break;
nr_stop_t1timer(sk);
nr_start_idletimer(sk);
nr->your_index = skb->data[17];
nr->your_id = skb->data[18];
nr->vs = 0;
nr->va = 0;
nr->vr = 0;
nr->vl = 0;
nr->state = NR_STATE_3;
nr->n2count = 0;
nr->window = skb->data[20];
sk->state = TCP_ESTABLISHED;
if (!sk->dead)
sk->state_change(sk);
break;
}
case NR_CONNACK | NR_CHOKE_FLAG:
nr_disconnect(sk, ECONNREFUSED);
break;
default: default:
break; break;
} }
return 0; return 0;
...@@ -111,23 +111,23 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype ...@@ -111,23 +111,23 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype
* The handling of the timer(s) is in file nr_timer.c * The handling of the timer(s) is in file nr_timer.c
* Handling of state 0 and connection release is in netrom.c. * Handling of state 0 and connection release is in netrom.c.
*/ */
static int nr_state2_machine(struct sock *sk, struct sk_buff *skb, int frametype) static int nr_state2_machine(struct sock *sk, struct sk_buff *skb,
int frametype)
{ {
switch (frametype) { switch (frametype) {
case NR_CONNACK | NR_CHOKE_FLAG:
nr_disconnect(sk, ECONNRESET);
break;
case NR_CONNACK | NR_CHOKE_FLAG: case NR_DISCREQ:
nr_disconnect(sk, ECONNRESET); nr_write_internal(sk, NR_DISCACK);
break;
case NR_DISCREQ:
nr_write_internal(sk, NR_DISCACK);
case NR_DISCACK: case NR_DISCACK:
nr_disconnect(sk, 0); nr_disconnect(sk, 0);
break; break;
default: default:
break; break;
} }
return 0; return 0;
...@@ -151,35 +151,62 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype ...@@ -151,35 +151,62 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
ns = skb->data[17]; ns = skb->data[17];
switch (frametype) { switch (frametype) {
case NR_CONNREQ:
case NR_CONNREQ: nr_write_internal(sk, NR_CONNACK);
nr_write_internal(sk, NR_CONNACK); break;
break;
case NR_DISCREQ:
case NR_DISCREQ: nr_write_internal(sk, NR_DISCACK);
nr_write_internal(sk, NR_DISCACK); nr_disconnect(sk, 0);
nr_disconnect(sk, 0); break;
break;
case NR_CONNACK | NR_CHOKE_FLAG:
case NR_CONNACK | NR_CHOKE_FLAG: case NR_DISCACK:
case NR_DISCACK: nr_disconnect(sk, ECONNRESET);
nr_disconnect(sk, ECONNRESET); break;
case NR_INFOACK:
case NR_INFOACK | NR_CHOKE_FLAG:
case NR_INFOACK | NR_NAK_FLAG:
case NR_INFOACK | NR_NAK_FLAG | NR_CHOKE_FLAG:
if (frametype & NR_CHOKE_FLAG) {
nrom->condition |= NR_COND_PEER_RX_BUSY;
nr_start_t4timer(sk);
} else {
nrom->condition &= ~NR_COND_PEER_RX_BUSY;
nr_stop_t4timer(sk);
}
if (!nr_validate_nr(sk, nr)) {
break; break;
}
case NR_INFOACK: if (frametype & NR_NAK_FLAG) {
case NR_INFOACK | NR_CHOKE_FLAG: nr_frames_acked(sk, nr);
case NR_INFOACK | NR_NAK_FLAG: nr_send_nak_frame(sk);
case NR_INFOACK | NR_NAK_FLAG | NR_CHOKE_FLAG: } else {
if (frametype & NR_CHOKE_FLAG) { if (nrom->condition & NR_COND_PEER_RX_BUSY) {
nrom->condition |= NR_COND_PEER_RX_BUSY; nr_frames_acked(sk, nr);
nr_start_t4timer(sk);
} else { } else {
nrom->condition &= ~NR_COND_PEER_RX_BUSY; nr_check_iframes_acked(sk, nr);
nr_stop_t4timer(sk);
}
if (!nr_validate_nr(sk, nr)) {
break;
} }
}
break;
case NR_INFO:
case NR_INFO | NR_NAK_FLAG:
case NR_INFO | NR_CHOKE_FLAG:
case NR_INFO | NR_MORE_FLAG:
case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG:
case NR_INFO | NR_CHOKE_FLAG | NR_MORE_FLAG:
case NR_INFO | NR_NAK_FLAG | NR_MORE_FLAG:
case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG | NR_MORE_FLAG:
if (frametype & NR_CHOKE_FLAG) {
nrom->condition |= NR_COND_PEER_RX_BUSY;
nr_start_t4timer(sk);
} else {
nrom->condition &= ~NR_COND_PEER_RX_BUSY;
nr_stop_t4timer(sk);
}
if (nr_validate_nr(sk, nr)) {
if (frametype & NR_NAK_FLAG) { if (frametype & NR_NAK_FLAG) {
nr_frames_acked(sk, nr); nr_frames_acked(sk, nr);
nr_send_nak_frame(sk); nr_send_nak_frame(sk);
...@@ -190,76 +217,48 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype ...@@ -190,76 +217,48 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
nr_check_iframes_acked(sk, nr); nr_check_iframes_acked(sk, nr);
} }
} }
}
queued = 1;
skb_queue_head(&nrom->reseq_queue, skb);
if (nrom->condition & NR_COND_OWN_RX_BUSY)
break; break;
skb_queue_head_init(&temp_queue);
case NR_INFO: do {
case NR_INFO | NR_NAK_FLAG: save_vr = nrom->vr;
case NR_INFO | NR_CHOKE_FLAG: while ((skbn = skb_dequeue(&nrom->reseq_queue)) != NULL) {
case NR_INFO | NR_MORE_FLAG: ns = skbn->data[17];
case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG: if (ns == nrom->vr) {
case NR_INFO | NR_CHOKE_FLAG | NR_MORE_FLAG: if (nr_queue_rx_frame(sk, skbn, frametype & NR_MORE_FLAG) == 0) {
case NR_INFO | NR_NAK_FLAG | NR_MORE_FLAG: nrom->vr = (nrom->vr + 1) % NR_MODULUS;
case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG | NR_MORE_FLAG:
if (frametype & NR_CHOKE_FLAG) {
nrom->condition |= NR_COND_PEER_RX_BUSY;
nr_start_t4timer(sk);
} else {
nrom->condition &= ~NR_COND_PEER_RX_BUSY;
nr_stop_t4timer(sk);
}
if (nr_validate_nr(sk, nr)) {
if (frametype & NR_NAK_FLAG) {
nr_frames_acked(sk, nr);
nr_send_nak_frame(sk);
} else {
if (nrom->condition & NR_COND_PEER_RX_BUSY) {
nr_frames_acked(sk, nr);
} else { } else {
nr_check_iframes_acked(sk, nr); nrom->condition |= NR_COND_OWN_RX_BUSY;
}
}
}
queued = 1;
skb_queue_head(&nrom->reseq_queue, skb);
if (nrom->condition & NR_COND_OWN_RX_BUSY)
break;
skb_queue_head_init(&temp_queue);
do {
save_vr = nrom->vr;
while ((skbn = skb_dequeue(&nrom->reseq_queue)) != NULL) {
ns = skbn->data[17];
if (ns == nrom->vr) {
if (nr_queue_rx_frame(sk, skbn, frametype & NR_MORE_FLAG) == 0) {
nrom->vr = (nrom->vr + 1) % NR_MODULUS;
} else {
nrom->condition |= NR_COND_OWN_RX_BUSY;
skb_queue_tail(&temp_queue, skbn);
}
} else if (nr_in_rx_window(sk, ns)) {
skb_queue_tail(&temp_queue, skbn); skb_queue_tail(&temp_queue, skbn);
} else {
kfree_skb(skbn);
} }
} } else if (nr_in_rx_window(sk, ns)) {
while ((skbn = skb_dequeue(&temp_queue)) != NULL) { skb_queue_tail(&temp_queue, skbn);
skb_queue_tail(&nrom->reseq_queue, skbn); } else {
} kfree_skb(skbn);
} while (save_vr != nrom->vr);
/*
* Window is full, ack it immediately.
*/
if (((nrom->vl + nrom->window) % NR_MODULUS) == nrom->vr) {
nr_enquiry_response(sk);
} else {
if (!(nrom->condition & NR_COND_ACK_PENDING)) {
nrom->condition |= NR_COND_ACK_PENDING;
nr_start_t2timer(sk);
} }
} }
break; while ((skbn = skb_dequeue(&temp_queue)) != NULL) {
skb_queue_tail(&nrom->reseq_queue, skbn);
}
} while (save_vr != nrom->vr);
/*
* Window is full, ack it immediately.
*/
if (((nrom->vl + nrom->window) % NR_MODULUS) == nrom->vr) {
nr_enquiry_response(sk);
} else {
if (!(nrom->condition & NR_COND_ACK_PENDING)) {
nrom->condition |= NR_COND_ACK_PENDING;
nr_start_t2timer(sk);
}
}
break;
default: default:
break; break;
} }
return queued; return queued;
...@@ -277,15 +276,15 @@ int nr_process_rx_frame(struct sock *sk, struct sk_buff *skb) ...@@ -277,15 +276,15 @@ int nr_process_rx_frame(struct sock *sk, struct sk_buff *skb)
frametype = skb->data[19]; frametype = skb->data[19];
switch (nr->state) { switch (nr->state) {
case NR_STATE_1: case NR_STATE_1:
queued = nr_state1_machine(sk, skb, frametype); queued = nr_state1_machine(sk, skb, frametype);
break; break;
case NR_STATE_2: case NR_STATE_2:
queued = nr_state2_machine(sk, skb, frametype); queued = nr_state2_machine(sk, skb, frametype);
break; break;
case NR_STATE_3: case NR_STATE_3:
queued = nr_state3_machine(sk, skb, frametype); queued = nr_state3_machine(sk, skb, frametype);
break; break;
} }
nr_kick(sk); nr_kick(sk);
......
...@@ -191,40 +191,49 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2 ...@@ -191,40 +191,49 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
/* Now re-sort the routes in quality order */ /* Now re-sort the routes in quality order */
switch (nr_node->count) { switch (nr_node->count) {
case 3: case 3:
if (nr_node->routes[1].quality > nr_node->routes[0].quality) { if (nr_node->routes[1].quality > nr_node->routes[0].quality) {
switch (nr_node->which) { switch (nr_node->which) {
case 0: nr_node->which = 1; break; case 0: nr_node->which = 1; break;
case 1: nr_node->which = 0; break; case 1: nr_node->which = 0; break;
default: break; default: break;
}
nr_route = nr_node->routes[0];
nr_node->routes[0] = nr_node->routes[1];
nr_node->routes[1] = nr_route;
} }
if (nr_node->routes[2].quality > nr_node->routes[1].quality) { nr_route = nr_node->routes[0];
switch (nr_node->which) { nr_node->routes[0] = nr_node->routes[1];
case 1: nr_node->which = 2; break; nr_node->routes[1] = nr_route;
case 2: nr_node->which = 1; break; }
default: break; if (nr_node->routes[2].quality > nr_node->routes[1].quality) {
} switch (nr_node->which) {
nr_route = nr_node->routes[1]; case 1: nr_node->which = 2;
nr_node->routes[1] = nr_node->routes[2]; break;
nr_node->routes[2] = nr_route;
case 2: nr_node->which = 1;
break;
default:
break;
} }
case 2: nr_route = nr_node->routes[1];
if (nr_node->routes[1].quality > nr_node->routes[0].quality) { nr_node->routes[1] = nr_node->routes[2];
switch (nr_node->which) { nr_node->routes[2] = nr_route;
case 0: nr_node->which = 1; break; }
case 1: nr_node->which = 0; break; case 2:
default: break; if (nr_node->routes[1].quality > nr_node->routes[0].quality) {
} switch (nr_node->which) {
nr_route = nr_node->routes[0]; case 0: nr_node->which = 1;
nr_node->routes[0] = nr_node->routes[1]; break;
nr_node->routes[1] = nr_route;
case 1: nr_node->which = 0;
break;
default: break;
} }
case 1: nr_route = nr_node->routes[0];
break; nr_node->routes[0] = nr_node->routes[1];
nr_node->routes[1] = nr_route;
}
case 1:
break;
} }
for (i = 0; i < nr_node->count; i++) { for (i = 0; i < nr_node->count; i++) {
...@@ -332,12 +341,12 @@ static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct n ...@@ -332,12 +341,12 @@ static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct n
nr_remove_node(nr_node); nr_remove_node(nr_node);
} else { } else {
switch (i) { switch (i) {
case 0: case 0:
nr_node->routes[0] = nr_node->routes[1]; nr_node->routes[0] = nr_node->routes[1];
case 1: case 1:
nr_node->routes[1] = nr_node->routes[2]; nr_node->routes[1] = nr_node->routes[2];
case 2: case 2:
break; break;
} }
} }
...@@ -435,7 +444,6 @@ static int nr_dec_obs(void) ...@@ -435,7 +444,6 @@ static int nr_dec_obs(void)
for (i = 0; i < s->count; i++) { for (i = 0; i < s->count; i++) {
switch (s->routes[i].obs_count) { switch (s->routes[i].obs_count) {
case 0: /* A locked entry */ case 0: /* A locked entry */
break; break;
...@@ -498,12 +506,12 @@ void nr_rt_device_down(struct net_device *dev) ...@@ -498,12 +506,12 @@ void nr_rt_device_down(struct net_device *dev)
t->count--; t->count--;
switch (i) { switch (i) {
case 0: case 0:
t->routes[0] = t->routes[1]; t->routes[0] = t->routes[1];
case 1: case 1:
t->routes[1] = t->routes[2]; t->routes[1] = t->routes[2];
case 2: case 2:
break; break;
} }
} }
} }
...@@ -600,51 +608,50 @@ int nr_rt_ioctl(unsigned int cmd, void *arg) ...@@ -600,51 +608,50 @@ int nr_rt_ioctl(unsigned int cmd, void *arg)
struct net_device *dev; struct net_device *dev;
switch (cmd) { switch (cmd) {
case SIOCADDRT:
if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
return -EFAULT;
if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
return -EINVAL;
if (nr_route.ndigis < 0 || nr_route.ndigis > AX25_MAX_DIGIS)
return -EINVAL;
switch (nr_route.type) {
case NETROM_NODE:
return nr_add_node(&nr_route.callsign,
nr_route.mnemonic,
&nr_route.neighbour,
nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters),
dev, nr_route.quality,
nr_route.obs_count);
case NETROM_NEIGH:
return nr_add_neigh(&nr_route.callsign,
nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters),
dev, nr_route.quality);
default:
return -EINVAL;
}
case SIOCADDRT: case SIOCDELRT:
if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct))) if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
return -EFAULT; return -EFAULT;
if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL) if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
return -EINVAL; return -EINVAL;
if (nr_route.ndigis < 0 || nr_route.ndigis > AX25_MAX_DIGIS) switch (nr_route.type) {
return -EINVAL; case NETROM_NODE:
switch (nr_route.type) { return nr_del_node(&nr_route.callsign,
case NETROM_NODE: &nr_route.neighbour, dev);
return nr_add_node(&nr_route.callsign, case NETROM_NEIGH:
nr_route.mnemonic, return nr_del_neigh(&nr_route.callsign,
&nr_route.neighbour, dev, nr_route.quality);
nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters),
dev, nr_route.quality,
nr_route.obs_count);
case NETROM_NEIGH:
return nr_add_neigh(&nr_route.callsign,
nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters),
dev, nr_route.quality);
default:
return -EINVAL;
}
case SIOCDELRT:
if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
return -EFAULT;
if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
return -EINVAL;
switch (nr_route.type) {
case NETROM_NODE:
return nr_del_node(&nr_route.callsign,
&nr_route.neighbour, dev);
case NETROM_NEIGH:
return nr_del_neigh(&nr_route.callsign,
dev, nr_route.quality);
default:
return -EINVAL;
}
case SIOCNRDECOBS:
return nr_dec_obs();
default: default:
return -EINVAL; return -EINVAL;
}
case SIOCNRDECOBS:
return nr_dec_obs();
default:
return -EINVAL;
} }
return 0; return 0;
......
...@@ -130,19 +130,19 @@ void nr_write_internal(struct sock *sk, int frametype) ...@@ -130,19 +130,19 @@ void nr_write_internal(struct sock *sk, int frametype)
len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN + NR_TRANSPORT_LEN; len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN + NR_TRANSPORT_LEN;
switch (frametype & 0x0F) { switch (frametype & 0x0F) {
case NR_CONNREQ: case NR_CONNREQ:
len += 17; len += 17;
break; break;
case NR_CONNACK: case NR_CONNACK:
len += (nr->bpqext) ? 2 : 1; len += (nr->bpqext) ? 2 : 1;
break; break;
case NR_DISCREQ: case NR_DISCREQ:
case NR_DISCACK: case NR_DISCACK:
case NR_INFOACK: case NR_INFOACK:
break; break;
default: default:
printk(KERN_ERR "NET/ROM: nr_write_internal - invalid frame type %d\n", frametype); printk(KERN_ERR "NET/ROM: nr_write_internal - invalid frame type %d\n", frametype);
return; return;
} }
if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL) if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
...@@ -156,55 +156,54 @@ void nr_write_internal(struct sock *sk, int frametype) ...@@ -156,55 +156,54 @@ void nr_write_internal(struct sock *sk, int frametype)
dptr = skb_put(skb, skb_tailroom(skb)); dptr = skb_put(skb, skb_tailroom(skb));
switch (frametype & 0x0F) { switch (frametype & 0x0F) {
case NR_CONNREQ:
timeout = nr->t1 / HZ;
*dptr++ = nr->my_index;
*dptr++ = nr->my_id;
*dptr++ = 0;
*dptr++ = 0;
*dptr++ = frametype;
*dptr++ = nr->window;
memcpy(dptr, &nr->user_addr, AX25_ADDR_LEN);
dptr[6] &= ~AX25_CBIT;
dptr[6] &= ~AX25_EBIT;
dptr[6] |= AX25_SSSID_SPARE;
dptr += AX25_ADDR_LEN;
memcpy(dptr, &nr->source_addr, AX25_ADDR_LEN);
dptr[6] &= ~AX25_CBIT;
dptr[6] &= ~AX25_EBIT;
dptr[6] |= AX25_SSSID_SPARE;
dptr += AX25_ADDR_LEN;
*dptr++ = timeout % 256;
*dptr++ = timeout / 256;
break;
case NR_CONNACK:
*dptr++ = nr->your_index;
*dptr++ = nr->your_id;
*dptr++ = nr->my_index;
*dptr++ = nr->my_id;
*dptr++ = frametype;
*dptr++ = nr->window;
if (nr->bpqext) *dptr++ = sysctl_netrom_network_ttl_initialiser;
break;
case NR_DISCREQ:
case NR_DISCACK:
*dptr++ = nr->your_index;
*dptr++ = nr->your_id;
*dptr++ = 0;
*dptr++ = 0;
*dptr++ = frametype;
break;
case NR_CONNREQ: case NR_INFOACK:
timeout = nr->t1 / HZ; *dptr++ = nr->your_index;
*dptr++ = nr->my_index; *dptr++ = nr->your_id;
*dptr++ = nr->my_id; *dptr++ = 0;
*dptr++ = 0; *dptr++ = nr->vr;
*dptr++ = 0; *dptr++ = frametype;
*dptr++ = frametype; break;
*dptr++ = nr->window;
memcpy(dptr, &nr->user_addr, AX25_ADDR_LEN);
dptr[6] &= ~AX25_CBIT;
dptr[6] &= ~AX25_EBIT;
dptr[6] |= AX25_SSSID_SPARE;
dptr += AX25_ADDR_LEN;
memcpy(dptr, &nr->source_addr, AX25_ADDR_LEN);
dptr[6] &= ~AX25_CBIT;
dptr[6] &= ~AX25_EBIT;
dptr[6] |= AX25_SSSID_SPARE;
dptr += AX25_ADDR_LEN;
*dptr++ = timeout % 256;
*dptr++ = timeout / 256;
break;
case NR_CONNACK:
*dptr++ = nr->your_index;
*dptr++ = nr->your_id;
*dptr++ = nr->my_index;
*dptr++ = nr->my_id;
*dptr++ = frametype;
*dptr++ = nr->window;
if (nr->bpqext) *dptr++ = sysctl_netrom_network_ttl_initialiser;
break;
case NR_DISCREQ:
case NR_DISCACK:
*dptr++ = nr->your_index;
*dptr++ = nr->your_id;
*dptr++ = 0;
*dptr++ = 0;
*dptr++ = frametype;
break;
case NR_INFOACK:
*dptr++ = nr->your_index;
*dptr++ = nr->your_id;
*dptr++ = 0;
*dptr++ = nr->vr;
*dptr++ = frametype;
break;
} }
nr_transmit_buffer(sk, skb); nr_transmit_buffer(sk, skb);
......
...@@ -136,29 +136,28 @@ static void nr_heartbeat_expiry(unsigned long param) ...@@ -136,29 +136,28 @@ static void nr_heartbeat_expiry(unsigned long param)
nr_cb *nr = nr_sk(sk); nr_cb *nr = nr_sk(sk);
switch (nr->state) { switch (nr->state) {
case NR_STATE_0:
case NR_STATE_0: /* Magic here: If we listen() and a new link dies before it
/* Magic here: If we listen() and a new link dies before it is accepted() it isn't 'dead' so doesn't get removed. */
is accepted() it isn't 'dead' so doesn't get removed. */ if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) {
if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) { nr_destroy_socket(sk);
nr_destroy_socket(sk); return;
return; }
} break;
break;
case NR_STATE_3:
case NR_STATE_3: /*
/* * Check for the state of the receive buffer.
* Check for the state of the receive buffer. */
*/ if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) &&
if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) && (nr->condition & NR_COND_OWN_RX_BUSY)) {
(nr->condition & NR_COND_OWN_RX_BUSY)) { nr->condition &= ~NR_COND_OWN_RX_BUSY;
nr->condition &= ~NR_COND_OWN_RX_BUSY; nr->condition &= ~NR_COND_ACK_PENDING;
nr->condition &= ~NR_COND_ACK_PENDING; nr->vl = nr->vr;
nr->vl = nr->vr; nr_write_internal(sk, NR_INFOACK);
nr_write_internal(sk, NR_INFOACK);
break;
}
break; break;
}
break;
} }
nr_start_heartbeat(sk); nr_start_heartbeat(sk);
...@@ -213,36 +212,35 @@ static void nr_t1timer_expiry(unsigned long param) ...@@ -213,36 +212,35 @@ static void nr_t1timer_expiry(unsigned long param)
nr_cb *nr = nr_sk(sk); nr_cb *nr = nr_sk(sk);
switch (nr->state) { switch (nr->state) {
case NR_STATE_1:
case NR_STATE_1: if (nr->n2count == nr->n2) {
if (nr->n2count == nr->n2) { nr_disconnect(sk, ETIMEDOUT);
nr_disconnect(sk, ETIMEDOUT); return;
return; } else {
} else { nr->n2count++;
nr->n2count++; nr_write_internal(sk, NR_CONNREQ);
nr_write_internal(sk, NR_CONNREQ); }
} break;
break;
case NR_STATE_2:
case NR_STATE_2: if (nr->n2count == nr->n2) {
if (nr->n2count == nr->n2) { nr_disconnect(sk, ETIMEDOUT);
nr_disconnect(sk, ETIMEDOUT); return;
return; } else {
} else { nr->n2count++;
nr->n2count++; nr_write_internal(sk, NR_DISCREQ);
nr_write_internal(sk, NR_DISCREQ); }
} break;
break;
case NR_STATE_3:
case NR_STATE_3: if (nr->n2count == nr->n2) {
if (nr->n2count == nr->n2) { nr_disconnect(sk, ETIMEDOUT);
nr_disconnect(sk, ETIMEDOUT); return;
return; } else {
} else { nr->n2count++;
nr->n2count++; nr_requeue_frames(sk);
nr_requeue_frames(sk); }
} break;
break;
} }
nr_start_t1timer(sk); nr_start_t1timer(sk);
......
...@@ -413,46 +413,46 @@ static int rose_setsockopt(struct socket *sock, int level, int optname, ...@@ -413,46 +413,46 @@ static int rose_setsockopt(struct socket *sock, int level, int optname,
return -EFAULT; return -EFAULT;
switch (optname) { switch (optname) {
case ROSE_DEFER: case ROSE_DEFER:
rose->defer = opt ? 1 : 0; rose->defer = opt ? 1 : 0;
return 0; return 0;
case ROSE_T1: case ROSE_T1:
if (opt < 1) if (opt < 1)
return -EINVAL; return -EINVAL;
rose->t1 = opt * HZ; rose->t1 = opt * HZ;
return 0; return 0;
case ROSE_T2: case ROSE_T2:
if (opt < 1) if (opt < 1)
return -EINVAL; return -EINVAL;
rose->t2 = opt * HZ; rose->t2 = opt * HZ;
return 0; return 0;
case ROSE_T3: case ROSE_T3:
if (opt < 1) if (opt < 1)
return -EINVAL; return -EINVAL;
rose->t3 = opt * HZ; rose->t3 = opt * HZ;
return 0; return 0;
case ROSE_HOLDBACK: case ROSE_HOLDBACK:
if (opt < 1) if (opt < 1)
return -EINVAL; return -EINVAL;
rose->hb = opt * HZ; rose->hb = opt * HZ;
return 0; return 0;
case ROSE_IDLE: case ROSE_IDLE:
if (opt < 0) if (opt < 0)
return -EINVAL; return -EINVAL;
rose->idle = opt * 60 * HZ; rose->idle = opt * 60 * HZ;
return 0; return 0;
case ROSE_QBITINCL: case ROSE_QBITINCL:
rose->qbitincl = opt ? 1 : 0; rose->qbitincl = opt ? 1 : 0;
return 0; return 0;
default: default:
return -ENOPROTOOPT; return -ENOPROTOOPT;
} }
} }
...@@ -474,36 +474,36 @@ static int rose_getsockopt(struct socket *sock, int level, int optname, ...@@ -474,36 +474,36 @@ static int rose_getsockopt(struct socket *sock, int level, int optname,
return -EINVAL; return -EINVAL;
switch (optname) { switch (optname) {
case ROSE_DEFER: case ROSE_DEFER:
val = rose->defer; val = rose->defer;
break; break;
case ROSE_T1: case ROSE_T1:
val = rose->t1 / HZ; val = rose->t1 / HZ;
break; break;
case ROSE_T2: case ROSE_T2:
val = rose->t2 / HZ; val = rose->t2 / HZ;
break; break;
case ROSE_T3: case ROSE_T3:
val = rose->t3 / HZ; val = rose->t3 / HZ;
break; break;
case ROSE_HOLDBACK: case ROSE_HOLDBACK:
val = rose->hb / HZ; val = rose->hb / HZ;
break; break;
case ROSE_IDLE: case ROSE_IDLE:
val = rose->idle / (60 * HZ); val = rose->idle / (60 * HZ);
break; break;
case ROSE_QBITINCL: case ROSE_QBITINCL:
val = rose->qbitincl; val = rose->qbitincl;
break; break;
default: default:
return -ENOPROTOOPT; return -ENOPROTOOPT;
} }
len = min_t(unsigned int, len, sizeof(int)); len = min_t(unsigned int, len, sizeof(int));
...@@ -629,36 +629,35 @@ static int rose_release(struct socket *sock) ...@@ -629,36 +629,35 @@ static int rose_release(struct socket *sock)
rose = rose_sk(sk); rose = rose_sk(sk);
switch (rose->state) { switch (rose->state) {
case ROSE_STATE_0:
rose_disconnect(sk, 0, -1, -1);
rose_destroy_socket(sk);
break;
case ROSE_STATE_0: case ROSE_STATE_2:
rose_disconnect(sk, 0, -1, -1); rose->neighbour->use--;
rose_destroy_socket(sk); rose_disconnect(sk, 0, -1, -1);
break; rose_destroy_socket(sk);
break;
case ROSE_STATE_2:
rose->neighbour->use--;
rose_disconnect(sk, 0, -1, -1);
rose_destroy_socket(sk);
break;
case ROSE_STATE_1: case ROSE_STATE_1:
case ROSE_STATE_3: case ROSE_STATE_3:
case ROSE_STATE_4: case ROSE_STATE_4:
case ROSE_STATE_5: case ROSE_STATE_5:
rose_clear_queues(sk); rose_clear_queues(sk);
rose_stop_idletimer(sk); rose_stop_idletimer(sk);
rose_write_internal(sk, ROSE_CLEAR_REQUEST); rose_write_internal(sk, ROSE_CLEAR_REQUEST);
rose_start_t3timer(sk); rose_start_t3timer(sk);
rose->state = ROSE_STATE_2; rose->state = ROSE_STATE_2;
sk->state = TCP_CLOSE; sk->state = TCP_CLOSE;
sk->shutdown |= SEND_SHUTDOWN; sk->shutdown |= SEND_SHUTDOWN;
sk->state_change(sk); sk->state_change(sk);
sk->dead = 1; sk->dead = 1;
sk->destroy = 1; sk->destroy = 1;
break; break;
default: default:
break; break;
} }
sock->sk = NULL; sock->sk = NULL;
...@@ -1268,96 +1267,96 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -1268,96 +1267,96 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
rose_cb *rose = rose_sk(sk); rose_cb *rose = rose_sk(sk);
switch (cmd) { switch (cmd) {
case TIOCOUTQ: { case TIOCOUTQ: {
long amount; long amount;
amount = sk->sndbuf - atomic_read(&sk->wmem_alloc); amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
if (amount < 0) if (amount < 0)
amount = 0; amount = 0;
return put_user(amount, (unsigned int *)arg); return put_user(amount, (unsigned int *)arg);
} }
case TIOCINQ: { case TIOCINQ: {
struct sk_buff *skb; struct sk_buff *skb;
long amount = 0L; long amount = 0L;
/* These two are safe on a single CPU system as only user tasks fiddle here */ /* These two are safe on a single CPU system as only user tasks fiddle here */
if ((skb = skb_peek(&sk->receive_queue)) != NULL) if ((skb = skb_peek(&sk->receive_queue)) != NULL)
amount = skb->len; amount = skb->len;
return put_user(amount, (unsigned int *)arg); return put_user(amount, (unsigned int *)arg);
}
case SIOCGSTAMP:
if (sk != NULL) {
if (sk->stamp.tv_sec == 0)
return -ENOENT;
return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0;
} }
return -EINVAL;
case SIOCGSTAMP: case SIOCGIFADDR:
if (sk != NULL) { case SIOCSIFADDR:
if (sk->stamp.tv_sec == 0) case SIOCGIFDSTADDR:
return -ENOENT; case SIOCSIFDSTADDR:
return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0; case SIOCGIFBRDADDR:
} case SIOCSIFBRDADDR:
return -EINVAL; case SIOCGIFNETMASK:
case SIOCSIFNETMASK:
case SIOCGIFMETRIC:
case SIOCSIFMETRIC:
return -EINVAL;
case SIOCGIFADDR: case SIOCADDRT:
case SIOCSIFADDR: case SIOCDELRT:
case SIOCGIFDSTADDR: case SIOCRSCLRRT:
case SIOCSIFDSTADDR: if (!capable(CAP_NET_ADMIN))
case SIOCGIFBRDADDR: return -EPERM;
case SIOCSIFBRDADDR: return rose_rt_ioctl(cmd, (void *)arg);
case SIOCGIFNETMASK:
case SIOCSIFNETMASK: case SIOCRSGCAUSE: {
case SIOCGIFMETRIC: struct rose_cause_struct rose_cause;
case SIOCSIFMETRIC: rose_cause.cause = rose->cause;
return -EINVAL; rose_cause.diagnostic = rose->diagnostic;
return copy_to_user((void *)arg, &rose_cause, sizeof(struct rose_cause_struct)) ? -EFAULT : 0;
}
case SIOCADDRT: case SIOCRSSCAUSE: {
case SIOCDELRT: struct rose_cause_struct rose_cause;
case SIOCRSCLRRT: if (copy_from_user(&rose_cause, (void *)arg, sizeof(struct rose_cause_struct)))
if (!capable(CAP_NET_ADMIN)) return -EPERM; return -EFAULT;
return rose_rt_ioctl(cmd, (void *)arg); rose->cause = rose_cause.cause;
rose->diagnostic = rose_cause.diagnostic;
case SIOCRSGCAUSE: { return 0;
struct rose_cause_struct rose_cause; }
rose_cause.cause = rose->cause;
rose_cause.diagnostic = rose->diagnostic;
return copy_to_user((void *)arg, &rose_cause, sizeof(struct rose_cause_struct)) ? -EFAULT : 0;
}
case SIOCRSSCAUSE: { case SIOCRSSL2CALL:
struct rose_cause_struct rose_cause; if (!capable(CAP_NET_ADMIN)) return -EPERM;
if (copy_from_user(&rose_cause, (void *)arg, sizeof(struct rose_cause_struct))) if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
return -EFAULT; ax25_listen_release(&rose_callsign, NULL);
rose->cause = rose_cause.cause; if (copy_from_user(&rose_callsign, (void *)arg, sizeof(ax25_address)))
rose->diagnostic = rose_cause.diagnostic; return -EFAULT;
return 0; if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
} ax25_listen_register(&rose_callsign, NULL);
return 0;
case SIOCRSSL2CALL: case SIOCRSGL2CALL:
if (!capable(CAP_NET_ADMIN)) return -EPERM; return copy_to_user((void *)arg, &rose_callsign, sizeof(ax25_address)) ? -EFAULT : 0;
if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
ax25_listen_release(&rose_callsign, NULL); case SIOCRSACCEPT:
if (copy_from_user(&rose_callsign, (void *)arg, sizeof(ax25_address))) if (rose->state == ROSE_STATE_5) {
return -EFAULT; rose_write_internal(sk, ROSE_CALL_ACCEPTED);
if (ax25cmp(&rose_callsign, &null_ax25_address) != 0) rose_start_idletimer(sk);
ax25_listen_register(&rose_callsign, NULL); rose->condition = 0x00;
return 0; rose->vs = 0;
rose->va = 0;
case SIOCRSGL2CALL: rose->vr = 0;
return copy_to_user((void *)arg, &rose_callsign, sizeof(ax25_address)) ? -EFAULT : 0; rose->vl = 0;
rose->state = ROSE_STATE_3;
case SIOCRSACCEPT: }
if (rose->state == ROSE_STATE_5) { return 0;
rose_write_internal(sk, ROSE_CALL_ACCEPTED);
rose_start_idletimer(sk);
rose->condition = 0x00;
rose->vs = 0;
rose->va = 0;
rose->vr = 0;
rose->vl = 0;
rose->state = ROSE_STATE_3;
}
return 0;
default: default:
return dev_ioctl(cmd, (void *)arg); return dev_ioctl(cmd, (void *)arg);
} }
/*NOTREACHED*/
return 0; return 0;
} }
......
...@@ -44,29 +44,28 @@ static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int framety ...@@ -44,29 +44,28 @@ static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int framety
rose_cb *rose = rose_sk(sk); rose_cb *rose = rose_sk(sk);
switch (frametype) { switch (frametype) {
case ROSE_CALL_ACCEPTED:
rose_stop_timer(sk);
rose_start_idletimer(sk);
rose->condition = 0x00;
rose->vs = 0;
rose->va = 0;
rose->vr = 0;
rose->vl = 0;
rose->state = ROSE_STATE_3;
sk->state = TCP_ESTABLISHED;
if (!sk->dead)
sk->state_change(sk);
break;
case ROSE_CLEAR_REQUEST:
rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
rose->neighbour->use--;
break;
case ROSE_CALL_ACCEPTED: default:
rose_stop_timer(sk); break;
rose_start_idletimer(sk);
rose->condition = 0x00;
rose->vs = 0;
rose->va = 0;
rose->vr = 0;
rose->vl = 0;
rose->state = ROSE_STATE_3;
sk->state = TCP_ESTABLISHED;
if (!sk->dead)
sk->state_change(sk);
break;
case ROSE_CLEAR_REQUEST:
rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
rose->neighbour->use--;
break;
default:
break;
} }
return 0; return 0;
...@@ -82,20 +81,19 @@ static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int framety ...@@ -82,20 +81,19 @@ static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int framety
rose_cb *rose = rose_sk(sk); rose_cb *rose = rose_sk(sk);
switch (frametype) { switch (frametype) {
case ROSE_CLEAR_REQUEST:
rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
rose->neighbour->use--;
break;
case ROSE_CLEAR_REQUEST: case ROSE_CLEAR_CONFIRMATION:
rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); rose_disconnect(sk, 0, -1, -1);
rose_disconnect(sk, 0, skb->data[3], skb->data[4]); rose->neighbour->use--;
rose->neighbour->use--; break;
break;
case ROSE_CLEAR_CONFIRMATION:
rose_disconnect(sk, 0, -1, -1);
rose->neighbour->use--;
break;
default: default:
break; break;
} }
return 0; return 0;
...@@ -112,50 +110,68 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety ...@@ -112,50 +110,68 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
int queued = 0; int queued = 0;
switch (frametype) { switch (frametype) {
case ROSE_RESET_REQUEST:
rose_stop_timer(sk);
rose_start_idletimer(sk);
rose_write_internal(sk, ROSE_RESET_CONFIRMATION);
rose->condition = 0x00;
rose->vs = 0;
rose->vr = 0;
rose->va = 0;
rose->vl = 0;
rose_requeue_frames(sk);
break;
case ROSE_CLEAR_REQUEST:
rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
rose->neighbour->use--;
break;
case ROSE_RESET_REQUEST: case ROSE_RR:
rose_stop_timer(sk); case ROSE_RNR:
rose_start_idletimer(sk); if (!rose_validate_nr(sk, nr)) {
rose_write_internal(sk, ROSE_RESET_CONFIRMATION); rose_write_internal(sk, ROSE_RESET_REQUEST);
rose->condition = 0x00; rose->condition = 0x00;
rose->vs = 0; rose->vs = 0;
rose->vr = 0; rose->vr = 0;
rose->va = 0; rose->va = 0;
rose->vl = 0; rose->vl = 0;
rose_requeue_frames(sk); rose->state = ROSE_STATE_4;
break; rose_start_t2timer(sk);
rose_stop_idletimer(sk);
case ROSE_CLEAR_REQUEST: } else {
rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); rose_frames_acked(sk, nr);
rose_disconnect(sk, 0, skb->data[3], skb->data[4]); if (frametype == ROSE_RNR) {
rose->neighbour->use--; rose->condition |= ROSE_COND_PEER_RX_BUSY;
break;
case ROSE_RR:
case ROSE_RNR:
if (!rose_validate_nr(sk, nr)) {
rose_write_internal(sk, ROSE_RESET_REQUEST);
rose->condition = 0x00;
rose->vs = 0;
rose->vr = 0;
rose->va = 0;
rose->vl = 0;
rose->state = ROSE_STATE_4;
rose_start_t2timer(sk);
rose_stop_idletimer(sk);
} else { } else {
rose_frames_acked(sk, nr); rose->condition &= ~ROSE_COND_PEER_RX_BUSY;
if (frametype == ROSE_RNR) {
rose->condition |= ROSE_COND_PEER_RX_BUSY;
} else {
rose->condition &= ~ROSE_COND_PEER_RX_BUSY;
}
} }
break; }
break;
case ROSE_DATA: /* XXX */ case ROSE_DATA: /* XXX */
rose->condition &= ~ROSE_COND_PEER_RX_BUSY; rose->condition &= ~ROSE_COND_PEER_RX_BUSY;
if (!rose_validate_nr(sk, nr)) { if (!rose_validate_nr(sk, nr)) {
rose_write_internal(sk, ROSE_RESET_REQUEST);
rose->condition = 0x00;
rose->vs = 0;
rose->vr = 0;
rose->va = 0;
rose->vl = 0;
rose->state = ROSE_STATE_4;
rose_start_t2timer(sk);
rose_stop_idletimer(sk);
break;
}
rose_frames_acked(sk, nr);
if (ns == rose->vr) {
rose_start_idletimer(sk);
if (sock_queue_rcv_skb(sk, skb) == 0) {
rose->vr = (rose->vr + 1) % ROSE_MODULUS;
queued = 1;
} else {
/* Should never happen ! */
rose_write_internal(sk, ROSE_RESET_REQUEST); rose_write_internal(sk, ROSE_RESET_REQUEST);
rose->condition = 0x00; rose->condition = 0x00;
rose->vs = 0; rose->vs = 0;
...@@ -167,45 +183,26 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety ...@@ -167,45 +183,26 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
rose_stop_idletimer(sk); rose_stop_idletimer(sk);
break; break;
} }
rose_frames_acked(sk, nr); if (atomic_read(&sk->rmem_alloc) > (sk->rcvbuf / 2))
if (ns == rose->vr) { rose->condition |= ROSE_COND_OWN_RX_BUSY;
rose_start_idletimer(sk); }
if (sock_queue_rcv_skb(sk, skb) == 0) { /*
rose->vr = (rose->vr + 1) % ROSE_MODULUS; * If the window is full, ack the frame, else start the
queued = 1; * acknowledge hold back timer.
} else { */
/* Should never happen ! */ if (((rose->vl + sysctl_rose_window_size) % ROSE_MODULUS) == rose->vr) {
rose_write_internal(sk, ROSE_RESET_REQUEST); rose->condition &= ~ROSE_COND_ACK_PENDING;
rose->condition = 0x00; rose_stop_timer(sk);
rose->vs = 0; rose_enquiry_response(sk);
rose->vr = 0; } else {
rose->va = 0; rose->condition |= ROSE_COND_ACK_PENDING;
rose->vl = 0; rose_start_hbtimer(sk);
rose->state = ROSE_STATE_4; }
rose_start_t2timer(sk); break;
rose_stop_idletimer(sk);
break; default:
} printk(KERN_WARNING "ROSE: unknown %02X in state 3\n", frametype);
if (atomic_read(&sk->rmem_alloc) > (sk->rcvbuf / 2)) break;
rose->condition |= ROSE_COND_OWN_RX_BUSY;
}
/*
* If the window is full, ack the frame, else start the
* acknowledge hold back timer.
*/
if (((rose->vl + sysctl_rose_window_size) % ROSE_MODULUS) == rose->vr) {
rose->condition &= ~ROSE_COND_ACK_PENDING;
rose_stop_timer(sk);
rose_enquiry_response(sk);
} else {
rose->condition |= ROSE_COND_ACK_PENDING;
rose_start_hbtimer(sk);
}
break;
default:
printk(KERN_WARNING "ROSE: unknown %02X in state 3\n", frametype);
break;
} }
return queued; return queued;
...@@ -221,29 +218,28 @@ static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int framety ...@@ -221,29 +218,28 @@ static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int framety
rose_cb *rose = rose_sk(sk); rose_cb *rose = rose_sk(sk);
switch (frametype) { switch (frametype) {
case ROSE_RESET_REQUEST:
rose_write_internal(sk, ROSE_RESET_CONFIRMATION);
case ROSE_RESET_CONFIRMATION:
rose_stop_timer(sk);
rose_start_idletimer(sk);
rose->condition = 0x00;
rose->va = 0;
rose->vr = 0;
rose->vs = 0;
rose->vl = 0;
rose->state = ROSE_STATE_3;
rose_requeue_frames(sk);
break;
case ROSE_CLEAR_REQUEST:
rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
rose->neighbour->use--;
break;
case ROSE_RESET_REQUEST: default:
rose_write_internal(sk, ROSE_RESET_CONFIRMATION); break;
case ROSE_RESET_CONFIRMATION:
rose_stop_timer(sk);
rose_start_idletimer(sk);
rose->condition = 0x00;
rose->va = 0;
rose->vr = 0;
rose->vs = 0;
rose->vl = 0;
rose->state = ROSE_STATE_3;
rose_requeue_frames(sk);
break;
case ROSE_CLEAR_REQUEST:
rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
rose->neighbour->use--;
break;
default:
break;
} }
return 0; return 0;
...@@ -277,21 +273,21 @@ int rose_process_rx_frame(struct sock *sk, struct sk_buff *skb) ...@@ -277,21 +273,21 @@ int rose_process_rx_frame(struct sock *sk, struct sk_buff *skb)
frametype = rose_decode(skb, &ns, &nr, &q, &d, &m); frametype = rose_decode(skb, &ns, &nr, &q, &d, &m);
switch (rose->state) { switch (rose->state) {
case ROSE_STATE_1: case ROSE_STATE_1:
queued = rose_state1_machine(sk, skb, frametype); queued = rose_state1_machine(sk, skb, frametype);
break; break;
case ROSE_STATE_2: case ROSE_STATE_2:
queued = rose_state2_machine(sk, skb, frametype); queued = rose_state2_machine(sk, skb, frametype);
break; break;
case ROSE_STATE_3: case ROSE_STATE_3:
queued = rose_state3_machine(sk, skb, frametype, ns, nr, q, d, m); queued = rose_state3_machine(sk, skb, frametype, ns, nr, q, d, m);
break; break;
case ROSE_STATE_4: case ROSE_STATE_4:
queued = rose_state4_machine(sk, skb, frametype); queued = rose_state4_machine(sk, skb, frametype);
break; break;
case ROSE_STATE_5: case ROSE_STATE_5:
queued = rose_state5_machine(sk, skb, frametype); queued = rose_state5_machine(sk, skb, frametype);
break; break;
} }
rose_kick(sk); rose_kick(sk);
......
...@@ -134,25 +134,25 @@ void rose_link_rx_restart(struct sk_buff *skb, struct rose_neigh *neigh, unsigne ...@@ -134,25 +134,25 @@ void rose_link_rx_restart(struct sk_buff *skb, struct rose_neigh *neigh, unsigne
struct sk_buff *skbn; struct sk_buff *skbn;
switch (frametype) { switch (frametype) {
case ROSE_RESTART_REQUEST: case ROSE_RESTART_REQUEST:
rose_stop_t0timer(neigh); rose_stop_t0timer(neigh);
neigh->restarted = 1; neigh->restarted = 1;
neigh->dce_mode = (skb->data[3] == ROSE_DTE_ORIGINATED); neigh->dce_mode = (skb->data[3] == ROSE_DTE_ORIGINATED);
rose_transmit_restart_confirmation(neigh); rose_transmit_restart_confirmation(neigh);
break; break;
case ROSE_RESTART_CONFIRMATION: case ROSE_RESTART_CONFIRMATION:
rose_stop_t0timer(neigh); rose_stop_t0timer(neigh);
neigh->restarted = 1; neigh->restarted = 1;
break; break;
case ROSE_DIAGNOSTIC: case ROSE_DIAGNOSTIC:
printk(KERN_WARNING "ROSE: received diagnostic #%d - %02X %02X %02X\n", skb->data[3], skb->data[4], skb->data[5], skb->data[6]); printk(KERN_WARNING "ROSE: received diagnostic #%d - %02X %02X %02X\n", skb->data[3], skb->data[4], skb->data[5], skb->data[6]);
break; break;
default: default:
printk(KERN_WARNING "ROSE: received unknown %02X with LCI 000\n", frametype); printk(KERN_WARNING "ROSE: received unknown %02X with LCI 000\n", frametype);
break; break;
} }
if (neigh->restarted) { if (neigh->restarted) {
......
This diff is collapsed.
...@@ -131,30 +131,29 @@ static void rose_heartbeat_expiry(unsigned long param) ...@@ -131,30 +131,29 @@ static void rose_heartbeat_expiry(unsigned long param)
rose_cb *rose = rose_sk(sk); rose_cb *rose = rose_sk(sk);
switch (rose->state) { switch (rose->state) {
case ROSE_STATE_0:
case ROSE_STATE_0: /* Magic here: If we listen() and a new link dies before it
/* Magic here: If we listen() and a new link dies before it is accepted() it isn't 'dead' so doesn't get removed. */
is accepted() it isn't 'dead' so doesn't get removed. */ if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) {
if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) { rose_destroy_socket(sk);
rose_destroy_socket(sk); return;
return; }
} break;
break;
case ROSE_STATE_3:
case ROSE_STATE_3: /*
/* * Check for the state of the receive buffer.
* Check for the state of the receive buffer. */
*/ if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) &&
if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) && (rose->condition & ROSE_COND_OWN_RX_BUSY)) {
(rose->condition & ROSE_COND_OWN_RX_BUSY)) { rose->condition &= ~ROSE_COND_OWN_RX_BUSY;
rose->condition &= ~ROSE_COND_OWN_RX_BUSY; rose->condition &= ~ROSE_COND_ACK_PENDING;
rose->condition &= ~ROSE_COND_ACK_PENDING; rose->vl = rose->vr;
rose->vl = rose->vr; rose_write_internal(sk, ROSE_RR);
rose_write_internal(sk, ROSE_RR); rose_stop_timer(sk); /* HB */
rose_stop_timer(sk); /* HB */
break;
}
break; break;
}
break;
} }
rose_start_heartbeat(sk); rose_start_heartbeat(sk);
...@@ -166,25 +165,24 @@ static void rose_timer_expiry(unsigned long param) ...@@ -166,25 +165,24 @@ static void rose_timer_expiry(unsigned long param)
rose_cb *rose = rose_sk(sk); rose_cb *rose = rose_sk(sk);
switch (rose->state) { switch (rose->state) {
case ROSE_STATE_1: /* T1 */
case ROSE_STATE_1: /* T1 */ case ROSE_STATE_4: /* T2 */
case ROSE_STATE_4: /* T2 */ rose_write_internal(sk, ROSE_CLEAR_REQUEST);
rose_write_internal(sk, ROSE_CLEAR_REQUEST); rose->state = ROSE_STATE_2;
rose->state = ROSE_STATE_2; rose_start_t3timer(sk);
rose_start_t3timer(sk); break;
break;
case ROSE_STATE_2: /* T3 */
case ROSE_STATE_2: /* T3 */ rose->neighbour->use--;
rose->neighbour->use--; rose_disconnect(sk, ETIMEDOUT, -1, -1);
rose_disconnect(sk, ETIMEDOUT, -1, -1); break;
break;
case ROSE_STATE_3: /* HB */
case ROSE_STATE_3: /* HB */ if (rose->condition & ROSE_COND_ACK_PENDING) {
if (rose->condition & ROSE_COND_ACK_PENDING) { rose->condition &= ~ROSE_COND_ACK_PENDING;
rose->condition &= ~ROSE_COND_ACK_PENDING; rose_enquiry_response(sk);
rose_enquiry_response(sk); }
} break;
break;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment