File: /usr/src/linux/net/rose/rose_in.c

1     /*
2      *	ROSE release 003
3      *
4      *	This code REQUIRES 2.1.15 or higher/ NET3.038
5      *
6      *	This module:
7      *		This module is free software; you can redistribute it and/or
8      *		modify it under the terms of the GNU General Public License
9      *		as published by the Free Software Foundation; either version
10      *		2 of the License, or (at your option) any later version.
11      *
12      *	Most of this code is based on the SDL diagrams published in the 7th
13      *	ARRL Computer Networking Conference papers. The diagrams have mistakes
14      *	in them, but are mostly correct. Before you modify the code could you
15      *	read the SDL diagrams as the code is not obvious and probably very
16      *	easy to break;
17      *
18      *	History
19      *	ROSE 001	Jonathan(G4KLX)	Cloned from nr_in.c
20      *	ROSE 002	Jonathan(G4KLX)	Return cause and diagnostic codes from Clear Requests.
21      *	ROSE 003	Jonathan(G4KLX)	New timer architecture.
22      *					Removed M bit processing.
23      */
24     
25     #include <linux/errno.h>
26     #include <linux/types.h>
27     #include <linux/socket.h>
28     #include <linux/in.h>
29     #include <linux/kernel.h>
30     #include <linux/sched.h>
31     #include <linux/timer.h>
32     #include <linux/string.h>
33     #include <linux/sockios.h>
34     #include <linux/net.h>
35     #include <net/ax25.h>
36     #include <linux/inet.h>
37     #include <linux/netdevice.h>
38     #include <linux/skbuff.h>
39     #include <net/sock.h>
40     #include <net/ip.h>			/* For ip_rcv */
41     #include <asm/segment.h>
42     #include <asm/system.h>
43     #include <linux/fcntl.h>
44     #include <linux/mm.h>
45     #include <linux/interrupt.h>
46     #include <net/rose.h>
47     
48     /*
49      * State machine for state 1, Awaiting Call Accepted State.
50      * The handling of the timer(s) is in file rose_timer.c.
51      * Handling of state 0 and connection release is in af_rose.c.
52      */
53     static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
54     {
55     	switch (frametype) {
56     
57     		case ROSE_CALL_ACCEPTED:
58     			rose_stop_timer(sk);
59     			rose_start_idletimer(sk);
60     			sk->protinfo.rose->condition = 0x00;
61     			sk->protinfo.rose->vs        = 0;
62     			sk->protinfo.rose->va        = 0;
63     			sk->protinfo.rose->vr        = 0;
64     			sk->protinfo.rose->vl        = 0;
65     			sk->protinfo.rose->state     = ROSE_STATE_3;
66     			sk->state                    = TCP_ESTABLISHED;
67     			if (!sk->dead)
68     				sk->state_change(sk);
69     			break;
70     
71     		case ROSE_CLEAR_REQUEST:
72     			rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
73     			rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
74     			sk->protinfo.rose->neighbour->use--;
75     			break;
76     
77     		default:
78     			break;
79     	}
80     
81     	return 0;
82     }
83     
84     /*
85      * State machine for state 2, Awaiting Clear Confirmation State.
86      * The handling of the timer(s) is in file rose_timer.c
87      * Handling of state 0 and connection release is in af_rose.c.
88      */
89     static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int frametype)
90     {
91     	switch (frametype) {
92     
93     		case ROSE_CLEAR_REQUEST:
94     			rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
95     			rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
96     			sk->protinfo.rose->neighbour->use--;
97     			break;
98     
99     		case ROSE_CLEAR_CONFIRMATION:
100     			rose_disconnect(sk, 0, -1, -1);
101     			sk->protinfo.rose->neighbour->use--;
102     			break;
103     
104     		default:
105     			break;
106     	}
107     
108     	return 0;
109     }
110     
111     /*
112      * State machine for state 3, Connected State.
113      * The handling of the timer(s) is in file rose_timer.c
114      * Handling of state 0 and connection release is in af_rose.c.
115      */
116     static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype, int ns, int nr, int q, int d, int m)
117     {
118     	int queued = 0;
119     
120     	switch (frametype) {
121     
122     		case ROSE_RESET_REQUEST:
123     			rose_stop_timer(sk);
124     			rose_start_idletimer(sk);
125     			rose_write_internal(sk, ROSE_RESET_CONFIRMATION);
126     			sk->protinfo.rose->condition = 0x00;
127     			sk->protinfo.rose->vs        = 0;
128     			sk->protinfo.rose->vr        = 0;
129     			sk->protinfo.rose->va        = 0;
130     			sk->protinfo.rose->vl        = 0;
131     			rose_requeue_frames(sk);
132     			break;
133     
134     		case ROSE_CLEAR_REQUEST:
135     			rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
136     			rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
137     			sk->protinfo.rose->neighbour->use--;
138     			break;
139     
140     		case ROSE_RR:
141     		case ROSE_RNR:
142     			if (!rose_validate_nr(sk, nr)) {
143     				rose_write_internal(sk, ROSE_RESET_REQUEST);
144     				sk->protinfo.rose->condition = 0x00;
145     				sk->protinfo.rose->vs        = 0;
146     				sk->protinfo.rose->vr        = 0;
147     				sk->protinfo.rose->va        = 0;
148     				sk->protinfo.rose->vl        = 0;
149     				sk->protinfo.rose->state     = ROSE_STATE_4;
150     				rose_start_t2timer(sk);
151     				rose_stop_idletimer(sk);
152     			} else {
153     				rose_frames_acked(sk, nr);
154     				if (frametype == ROSE_RNR) {
155     					sk->protinfo.rose->condition |= ROSE_COND_PEER_RX_BUSY;
156     				} else {
157     					sk->protinfo.rose->condition &= ~ROSE_COND_PEER_RX_BUSY;
158     				}
159     			}
160     			break;
161     
162     		case ROSE_DATA:	/* XXX */
163     			sk->protinfo.rose->condition &= ~ROSE_COND_PEER_RX_BUSY;
164     			if (!rose_validate_nr(sk, nr)) {
165     				rose_write_internal(sk, ROSE_RESET_REQUEST);
166     				sk->protinfo.rose->condition = 0x00;
167     				sk->protinfo.rose->vs        = 0;
168     				sk->protinfo.rose->vr        = 0;
169     				sk->protinfo.rose->va        = 0;
170     				sk->protinfo.rose->vl        = 0;
171     				sk->protinfo.rose->state     = ROSE_STATE_4;
172     				rose_start_t2timer(sk);
173     				rose_stop_idletimer(sk);
174     				break;
175     			}
176     			rose_frames_acked(sk, nr);
177     			if (ns == sk->protinfo.rose->vr) {
178     				rose_start_idletimer(sk);
179     				if (sock_queue_rcv_skb(sk, skb) == 0) {
180     					sk->protinfo.rose->vr = (sk->protinfo.rose->vr + 1) % ROSE_MODULUS;
181     					queued = 1;
182     				} else {
183     					/* Should never happen ! */
184     					rose_write_internal(sk, ROSE_RESET_REQUEST);
185     					sk->protinfo.rose->condition = 0x00;
186     					sk->protinfo.rose->vs        = 0;
187     					sk->protinfo.rose->vr        = 0;
188     					sk->protinfo.rose->va        = 0;
189     					sk->protinfo.rose->vl        = 0;
190     					sk->protinfo.rose->state     = ROSE_STATE_4;
191     					rose_start_t2timer(sk);
192     					rose_stop_idletimer(sk);
193     					break;
194     				}
195     				if (atomic_read(&sk->rmem_alloc) > (sk->rcvbuf / 2))
196     					sk->protinfo.rose->condition |= ROSE_COND_OWN_RX_BUSY;
197     			}
198     			/*
199     			 * If the window is full, ack the frame, else start the
200     			 * acknowledge hold back timer.
201     			 */
202     			if (((sk->protinfo.rose->vl + sysctl_rose_window_size) % ROSE_MODULUS) == sk->protinfo.rose->vr) {
203     				sk->protinfo.rose->condition &= ~ROSE_COND_ACK_PENDING;
204     				rose_stop_timer(sk);
205     				rose_enquiry_response(sk);
206     			} else {
207     				sk->protinfo.rose->condition |= ROSE_COND_ACK_PENDING;
208     				rose_start_hbtimer(sk);
209     			}
210     			break;
211     
212     		default:
213     			printk(KERN_WARNING "ROSE: unknown %02X in state 3\n", frametype);
214     			break;
215     	}
216     
217     	return queued;
218     }
219     
220     /*
221      * State machine for state 4, Awaiting Reset Confirmation State.
222      * The handling of the timer(s) is in file rose_timer.c
223      * Handling of state 0 and connection release is in af_rose.c.
224      */
225     static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype)
226     {
227     	switch (frametype) {
228     
229     		case ROSE_RESET_REQUEST:
230     			rose_write_internal(sk, ROSE_RESET_CONFIRMATION);
231     		case ROSE_RESET_CONFIRMATION:
232     			rose_stop_timer(sk);
233     			rose_start_idletimer(sk);
234     			sk->protinfo.rose->condition = 0x00;
235     			sk->protinfo.rose->va        = 0;
236     			sk->protinfo.rose->vr        = 0;
237     			sk->protinfo.rose->vs        = 0;
238     			sk->protinfo.rose->vl        = 0;
239     			sk->protinfo.rose->state     = ROSE_STATE_3;
240     			rose_requeue_frames(sk);
241     			break;
242     
243     		case ROSE_CLEAR_REQUEST:
244     			rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
245     			rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
246     			sk->protinfo.rose->neighbour->use--;
247     			break;
248     
249     		default:
250     			break;
251     	}
252     
253     	return 0;
254     }
255     
256     /*
257      * State machine for state 5, Awaiting Call Acceptance State.
258      * The handling of the timer(s) is in file rose_timer.c
259      * Handling of state 0 and connection release is in af_rose.c.
260      */
261     static int rose_state5_machine(struct sock *sk, struct sk_buff *skb, int frametype)
262     {
263     	if (frametype == ROSE_CLEAR_REQUEST) {
264     		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
265     		rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
266     		sk->protinfo.rose->neighbour->use--;
267     	}
268     
269     	return 0;
270     }
271     
272     /* Higher level upcall for a LAPB frame */
273     int rose_process_rx_frame(struct sock *sk, struct sk_buff *skb)
274     {
275     	int queued = 0, frametype, ns, nr, q, d, m;
276     
277     	if (sk->protinfo.rose->state == ROSE_STATE_0)
278     		return 0;
279     
280     	frametype = rose_decode(skb, &ns, &nr, &q, &d, &m);
281     
282     	switch (sk->protinfo.rose->state) {
283     		case ROSE_STATE_1:
284     			queued = rose_state1_machine(sk, skb, frametype);
285     			break;
286     		case ROSE_STATE_2:
287     			queued = rose_state2_machine(sk, skb, frametype);
288     			break;
289     		case ROSE_STATE_3:
290     			queued = rose_state3_machine(sk, skb, frametype, ns, nr, q, d, m);
291     			break;
292     		case ROSE_STATE_4:
293     			queued = rose_state4_machine(sk, skb, frametype);
294     			break;
295     		case ROSE_STATE_5:
296     			queued = rose_state5_machine(sk, skb, frametype);
297     			break;
298     	}
299     
300     	rose_kick(sk);
301     
302     	return queued;
303     }
304