xref: /openbmc/linux/net/x25/af_x25.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1*1da177e4SLinus Torvalds /*
2*1da177e4SLinus Torvalds  *	X.25 Packet Layer release 002
3*1da177e4SLinus Torvalds  *
4*1da177e4SLinus Torvalds  *	This is ALPHA test software. This code may break your machine,
5*1da177e4SLinus Torvalds  *	randomly fail to work with new releases, misbehave and/or generally
6*1da177e4SLinus Torvalds  *	screw up. It might even work.
7*1da177e4SLinus Torvalds  *
8*1da177e4SLinus Torvalds  *	This code REQUIRES 2.1.15 or higher
9*1da177e4SLinus Torvalds  *
10*1da177e4SLinus Torvalds  *	This module:
11*1da177e4SLinus Torvalds  *		This module is free software; you can redistribute it and/or
12*1da177e4SLinus Torvalds  *		modify it under the terms of the GNU General Public License
13*1da177e4SLinus Torvalds  *		as published by the Free Software Foundation; either version
14*1da177e4SLinus Torvalds  *		2 of the License, or (at your option) any later version.
15*1da177e4SLinus Torvalds  *
16*1da177e4SLinus Torvalds  *	History
17*1da177e4SLinus Torvalds  *	X.25 001	Jonathan Naylor	Started coding.
18*1da177e4SLinus Torvalds  *	X.25 002	Jonathan Naylor	Centralised disconnect handling.
19*1da177e4SLinus Torvalds  *					New timer architecture.
20*1da177e4SLinus Torvalds  *	2000-03-11	Henner Eisen	MSG_EOR handling more POSIX compliant.
21*1da177e4SLinus Torvalds  *	2000-03-22	Daniela Squassoni Allowed disabling/enabling of
22*1da177e4SLinus Torvalds  *					  facilities negotiation and increased
23*1da177e4SLinus Torvalds  *					  the throughput upper limit.
24*1da177e4SLinus Torvalds  *	2000-08-27	Arnaldo C. Melo s/suser/capable/ + micro cleanups
25*1da177e4SLinus Torvalds  *	2000-09-04	Henner Eisen	Set sock->state in x25_accept().
26*1da177e4SLinus Torvalds  *					Fixed x25_output() related skb leakage.
27*1da177e4SLinus Torvalds  *	2000-10-02	Henner Eisen	Made x25_kick() single threaded per socket.
28*1da177e4SLinus Torvalds  *	2000-10-27	Henner Eisen    MSG_DONTWAIT for fragment allocation.
29*1da177e4SLinus Torvalds  *	2000-11-14	Henner Eisen    Closing datalink from NETDEV_GOING_DOWN
30*1da177e4SLinus Torvalds  *	2002-10-06	Arnaldo C. Melo Get rid of cli/sti, move proc stuff to
31*1da177e4SLinus Torvalds  *					x25_proc.c, using seq_file
32*1da177e4SLinus Torvalds  */
33*1da177e4SLinus Torvalds 
34*1da177e4SLinus Torvalds #include <linux/config.h>
35*1da177e4SLinus Torvalds #include <linux/module.h>
36*1da177e4SLinus Torvalds #include <linux/errno.h>
37*1da177e4SLinus Torvalds #include <linux/kernel.h>
38*1da177e4SLinus Torvalds #include <linux/sched.h>
39*1da177e4SLinus Torvalds #include <linux/timer.h>
40*1da177e4SLinus Torvalds #include <linux/string.h>
41*1da177e4SLinus Torvalds #include <linux/net.h>
42*1da177e4SLinus Torvalds #include <linux/netdevice.h>
43*1da177e4SLinus Torvalds #include <linux/if_arp.h>
44*1da177e4SLinus Torvalds #include <linux/skbuff.h>
45*1da177e4SLinus Torvalds #include <net/sock.h>
46*1da177e4SLinus Torvalds #include <net/tcp.h>
47*1da177e4SLinus Torvalds #include <asm/uaccess.h>
48*1da177e4SLinus Torvalds #include <linux/fcntl.h>
49*1da177e4SLinus Torvalds #include <linux/termios.h>	/* For TIOCINQ/OUTQ */
50*1da177e4SLinus Torvalds #include <linux/notifier.h>
51*1da177e4SLinus Torvalds #include <linux/init.h>
52*1da177e4SLinus Torvalds #include <net/x25.h>
53*1da177e4SLinus Torvalds 
54*1da177e4SLinus Torvalds int sysctl_x25_restart_request_timeout = X25_DEFAULT_T20;
55*1da177e4SLinus Torvalds int sysctl_x25_call_request_timeout    = X25_DEFAULT_T21;
56*1da177e4SLinus Torvalds int sysctl_x25_reset_request_timeout   = X25_DEFAULT_T22;
57*1da177e4SLinus Torvalds int sysctl_x25_clear_request_timeout   = X25_DEFAULT_T23;
58*1da177e4SLinus Torvalds int sysctl_x25_ack_holdback_timeout    = X25_DEFAULT_T2;
59*1da177e4SLinus Torvalds 
60*1da177e4SLinus Torvalds HLIST_HEAD(x25_list);
61*1da177e4SLinus Torvalds DEFINE_RWLOCK(x25_list_lock);
62*1da177e4SLinus Torvalds 
63*1da177e4SLinus Torvalds static struct proto_ops x25_proto_ops;
64*1da177e4SLinus Torvalds 
65*1da177e4SLinus Torvalds static struct x25_address null_x25_address = {"               "};
66*1da177e4SLinus Torvalds 
67*1da177e4SLinus Torvalds int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
68*1da177e4SLinus Torvalds 		  struct x25_address *calling_addr)
69*1da177e4SLinus Torvalds {
70*1da177e4SLinus Torvalds 	int called_len, calling_len;
71*1da177e4SLinus Torvalds 	char *called, *calling;
72*1da177e4SLinus Torvalds 	int i;
73*1da177e4SLinus Torvalds 
74*1da177e4SLinus Torvalds 	called_len  = (*p >> 0) & 0x0F;
75*1da177e4SLinus Torvalds 	calling_len = (*p >> 4) & 0x0F;
76*1da177e4SLinus Torvalds 
77*1da177e4SLinus Torvalds 	called  = called_addr->x25_addr;
78*1da177e4SLinus Torvalds 	calling = calling_addr->x25_addr;
79*1da177e4SLinus Torvalds 	p++;
80*1da177e4SLinus Torvalds 
81*1da177e4SLinus Torvalds 	for (i = 0; i < (called_len + calling_len); i++) {
82*1da177e4SLinus Torvalds 		if (i < called_len) {
83*1da177e4SLinus Torvalds 			if (i % 2 != 0) {
84*1da177e4SLinus Torvalds 				*called++ = ((*p >> 0) & 0x0F) + '0';
85*1da177e4SLinus Torvalds 				p++;
86*1da177e4SLinus Torvalds 			} else {
87*1da177e4SLinus Torvalds 				*called++ = ((*p >> 4) & 0x0F) + '0';
88*1da177e4SLinus Torvalds 			}
89*1da177e4SLinus Torvalds 		} else {
90*1da177e4SLinus Torvalds 			if (i % 2 != 0) {
91*1da177e4SLinus Torvalds 				*calling++ = ((*p >> 0) & 0x0F) + '0';
92*1da177e4SLinus Torvalds 				p++;
93*1da177e4SLinus Torvalds 			} else {
94*1da177e4SLinus Torvalds 				*calling++ = ((*p >> 4) & 0x0F) + '0';
95*1da177e4SLinus Torvalds 			}
96*1da177e4SLinus Torvalds 		}
97*1da177e4SLinus Torvalds 	}
98*1da177e4SLinus Torvalds 
99*1da177e4SLinus Torvalds 	*called = *calling = '\0';
100*1da177e4SLinus Torvalds 
101*1da177e4SLinus Torvalds 	return 1 + (called_len + calling_len + 1) / 2;
102*1da177e4SLinus Torvalds }
103*1da177e4SLinus Torvalds 
104*1da177e4SLinus Torvalds int x25_addr_aton(unsigned char *p, struct x25_address *called_addr,
105*1da177e4SLinus Torvalds 		  struct x25_address *calling_addr)
106*1da177e4SLinus Torvalds {
107*1da177e4SLinus Torvalds 	unsigned int called_len, calling_len;
108*1da177e4SLinus Torvalds 	char *called, *calling;
109*1da177e4SLinus Torvalds 	int i;
110*1da177e4SLinus Torvalds 
111*1da177e4SLinus Torvalds 	called  = called_addr->x25_addr;
112*1da177e4SLinus Torvalds 	calling = calling_addr->x25_addr;
113*1da177e4SLinus Torvalds 
114*1da177e4SLinus Torvalds 	called_len  = strlen(called);
115*1da177e4SLinus Torvalds 	calling_len = strlen(calling);
116*1da177e4SLinus Torvalds 
117*1da177e4SLinus Torvalds 	*p++ = (calling_len << 4) | (called_len << 0);
118*1da177e4SLinus Torvalds 
119*1da177e4SLinus Torvalds 	for (i = 0; i < (called_len + calling_len); i++) {
120*1da177e4SLinus Torvalds 		if (i < called_len) {
121*1da177e4SLinus Torvalds 			if (i % 2 != 0) {
122*1da177e4SLinus Torvalds 				*p |= (*called++ - '0') << 0;
123*1da177e4SLinus Torvalds 				p++;
124*1da177e4SLinus Torvalds 			} else {
125*1da177e4SLinus Torvalds 				*p = 0x00;
126*1da177e4SLinus Torvalds 				*p |= (*called++ - '0') << 4;
127*1da177e4SLinus Torvalds 			}
128*1da177e4SLinus Torvalds 		} else {
129*1da177e4SLinus Torvalds 			if (i % 2 != 0) {
130*1da177e4SLinus Torvalds 				*p |= (*calling++ - '0') << 0;
131*1da177e4SLinus Torvalds 				p++;
132*1da177e4SLinus Torvalds 			} else {
133*1da177e4SLinus Torvalds 				*p = 0x00;
134*1da177e4SLinus Torvalds 				*p |= (*calling++ - '0') << 4;
135*1da177e4SLinus Torvalds 			}
136*1da177e4SLinus Torvalds 		}
137*1da177e4SLinus Torvalds 	}
138*1da177e4SLinus Torvalds 
139*1da177e4SLinus Torvalds 	return 1 + (called_len + calling_len + 1) / 2;
140*1da177e4SLinus Torvalds }
141*1da177e4SLinus Torvalds 
142*1da177e4SLinus Torvalds /*
143*1da177e4SLinus Torvalds  *	Socket removal during an interrupt is now safe.
144*1da177e4SLinus Torvalds  */
145*1da177e4SLinus Torvalds static void x25_remove_socket(struct sock *sk)
146*1da177e4SLinus Torvalds {
147*1da177e4SLinus Torvalds 	write_lock_bh(&x25_list_lock);
148*1da177e4SLinus Torvalds 	sk_del_node_init(sk);
149*1da177e4SLinus Torvalds 	write_unlock_bh(&x25_list_lock);
150*1da177e4SLinus Torvalds }
151*1da177e4SLinus Torvalds 
152*1da177e4SLinus Torvalds /*
153*1da177e4SLinus Torvalds  *	Kill all bound sockets on a dropped device.
154*1da177e4SLinus Torvalds  */
155*1da177e4SLinus Torvalds static void x25_kill_by_device(struct net_device *dev)
156*1da177e4SLinus Torvalds {
157*1da177e4SLinus Torvalds 	struct sock *s;
158*1da177e4SLinus Torvalds 	struct hlist_node *node;
159*1da177e4SLinus Torvalds 
160*1da177e4SLinus Torvalds 	write_lock_bh(&x25_list_lock);
161*1da177e4SLinus Torvalds 
162*1da177e4SLinus Torvalds 	sk_for_each(s, node, &x25_list)
163*1da177e4SLinus Torvalds 		if (x25_sk(s)->neighbour && x25_sk(s)->neighbour->dev == dev)
164*1da177e4SLinus Torvalds 			x25_disconnect(s, ENETUNREACH, 0, 0);
165*1da177e4SLinus Torvalds 
166*1da177e4SLinus Torvalds 	write_unlock_bh(&x25_list_lock);
167*1da177e4SLinus Torvalds }
168*1da177e4SLinus Torvalds 
169*1da177e4SLinus Torvalds /*
170*1da177e4SLinus Torvalds  *	Handle device status changes.
171*1da177e4SLinus Torvalds  */
172*1da177e4SLinus Torvalds static int x25_device_event(struct notifier_block *this, unsigned long event,
173*1da177e4SLinus Torvalds 			    void *ptr)
174*1da177e4SLinus Torvalds {
175*1da177e4SLinus Torvalds 	struct net_device *dev = ptr;
176*1da177e4SLinus Torvalds 	struct x25_neigh *nb;
177*1da177e4SLinus Torvalds 
178*1da177e4SLinus Torvalds 	if (dev->type == ARPHRD_X25
179*1da177e4SLinus Torvalds #if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
180*1da177e4SLinus Torvalds 	 || dev->type == ARPHRD_ETHER
181*1da177e4SLinus Torvalds #endif
182*1da177e4SLinus Torvalds 	 ) {
183*1da177e4SLinus Torvalds 		switch (event) {
184*1da177e4SLinus Torvalds 			case NETDEV_UP:
185*1da177e4SLinus Torvalds 				x25_link_device_up(dev);
186*1da177e4SLinus Torvalds 				break;
187*1da177e4SLinus Torvalds 			case NETDEV_GOING_DOWN:
188*1da177e4SLinus Torvalds 				nb = x25_get_neigh(dev);
189*1da177e4SLinus Torvalds 				if (nb) {
190*1da177e4SLinus Torvalds 					x25_terminate_link(nb);
191*1da177e4SLinus Torvalds 					x25_neigh_put(nb);
192*1da177e4SLinus Torvalds 				}
193*1da177e4SLinus Torvalds 				break;
194*1da177e4SLinus Torvalds 			case NETDEV_DOWN:
195*1da177e4SLinus Torvalds 				x25_kill_by_device(dev);
196*1da177e4SLinus Torvalds 				x25_route_device_down(dev);
197*1da177e4SLinus Torvalds 				x25_link_device_down(dev);
198*1da177e4SLinus Torvalds 				break;
199*1da177e4SLinus Torvalds 		}
200*1da177e4SLinus Torvalds 	}
201*1da177e4SLinus Torvalds 
202*1da177e4SLinus Torvalds 	return NOTIFY_DONE;
203*1da177e4SLinus Torvalds }
204*1da177e4SLinus Torvalds 
205*1da177e4SLinus Torvalds /*
206*1da177e4SLinus Torvalds  *	Add a socket to the bound sockets list.
207*1da177e4SLinus Torvalds  */
208*1da177e4SLinus Torvalds static void x25_insert_socket(struct sock *sk)
209*1da177e4SLinus Torvalds {
210*1da177e4SLinus Torvalds 	write_lock_bh(&x25_list_lock);
211*1da177e4SLinus Torvalds 	sk_add_node(sk, &x25_list);
212*1da177e4SLinus Torvalds 	write_unlock_bh(&x25_list_lock);
213*1da177e4SLinus Torvalds }
214*1da177e4SLinus Torvalds 
215*1da177e4SLinus Torvalds /*
216*1da177e4SLinus Torvalds  *	Find a socket that wants to accept the Call Request we just
217*1da177e4SLinus Torvalds  *	received. Check the full list for an address/cud match.
218*1da177e4SLinus Torvalds  *	If no cuds match return the next_best thing, an address match.
219*1da177e4SLinus Torvalds  *	Note: if a listening socket has cud set it must only get calls
220*1da177e4SLinus Torvalds  *	with matching cud.
221*1da177e4SLinus Torvalds  */
222*1da177e4SLinus Torvalds static struct sock *x25_find_listener(struct x25_address *addr, struct x25_calluserdata *calluserdata)
223*1da177e4SLinus Torvalds {
224*1da177e4SLinus Torvalds 	struct sock *s;
225*1da177e4SLinus Torvalds 	struct sock *next_best;
226*1da177e4SLinus Torvalds 	struct hlist_node *node;
227*1da177e4SLinus Torvalds 
228*1da177e4SLinus Torvalds 	read_lock_bh(&x25_list_lock);
229*1da177e4SLinus Torvalds 	next_best = NULL;
230*1da177e4SLinus Torvalds 
231*1da177e4SLinus Torvalds 	sk_for_each(s, node, &x25_list)
232*1da177e4SLinus Torvalds 		if ((!strcmp(addr->x25_addr,
233*1da177e4SLinus Torvalds 			     x25_sk(s)->source_addr.x25_addr) ||
234*1da177e4SLinus Torvalds 		     !strcmp(addr->x25_addr,
235*1da177e4SLinus Torvalds 			     null_x25_address.x25_addr)) &&
236*1da177e4SLinus Torvalds 		     s->sk_state == TCP_LISTEN) {
237*1da177e4SLinus Torvalds 
238*1da177e4SLinus Torvalds 			/*
239*1da177e4SLinus Torvalds 			 * Found a listening socket, now check the incoming
240*1da177e4SLinus Torvalds 			 * call user data vs this sockets call user data
241*1da177e4SLinus Torvalds 			 */
242*1da177e4SLinus Torvalds 			if (x25_check_calluserdata(&x25_sk(s)->calluserdata, calluserdata)) {
243*1da177e4SLinus Torvalds 				sock_hold(s);
244*1da177e4SLinus Torvalds 				goto found;
245*1da177e4SLinus Torvalds 			}
246*1da177e4SLinus Torvalds 			if (x25_sk(s)->calluserdata.cudlength == 0) {
247*1da177e4SLinus Torvalds 				next_best = s;
248*1da177e4SLinus Torvalds 			}
249*1da177e4SLinus Torvalds 		}
250*1da177e4SLinus Torvalds 	if (next_best) {
251*1da177e4SLinus Torvalds 		s = next_best;
252*1da177e4SLinus Torvalds 		sock_hold(s);
253*1da177e4SLinus Torvalds 		goto found;
254*1da177e4SLinus Torvalds 	}
255*1da177e4SLinus Torvalds 	s = NULL;
256*1da177e4SLinus Torvalds found:
257*1da177e4SLinus Torvalds 	read_unlock_bh(&x25_list_lock);
258*1da177e4SLinus Torvalds 	return s;
259*1da177e4SLinus Torvalds }
260*1da177e4SLinus Torvalds 
261*1da177e4SLinus Torvalds /*
262*1da177e4SLinus Torvalds  *	Find a connected X.25 socket given my LCI and neighbour.
263*1da177e4SLinus Torvalds  */
264*1da177e4SLinus Torvalds static struct sock *__x25_find_socket(unsigned int lci, struct x25_neigh *nb)
265*1da177e4SLinus Torvalds {
266*1da177e4SLinus Torvalds 	struct sock *s;
267*1da177e4SLinus Torvalds 	struct hlist_node *node;
268*1da177e4SLinus Torvalds 
269*1da177e4SLinus Torvalds 	sk_for_each(s, node, &x25_list)
270*1da177e4SLinus Torvalds 		if (x25_sk(s)->lci == lci && x25_sk(s)->neighbour == nb) {
271*1da177e4SLinus Torvalds 			sock_hold(s);
272*1da177e4SLinus Torvalds 			goto found;
273*1da177e4SLinus Torvalds 		}
274*1da177e4SLinus Torvalds 	s = NULL;
275*1da177e4SLinus Torvalds found:
276*1da177e4SLinus Torvalds 	return s;
277*1da177e4SLinus Torvalds }
278*1da177e4SLinus Torvalds 
279*1da177e4SLinus Torvalds struct sock *x25_find_socket(unsigned int lci, struct x25_neigh *nb)
280*1da177e4SLinus Torvalds {
281*1da177e4SLinus Torvalds 	struct sock *s;
282*1da177e4SLinus Torvalds 
283*1da177e4SLinus Torvalds 	read_lock_bh(&x25_list_lock);
284*1da177e4SLinus Torvalds 	s = __x25_find_socket(lci, nb);
285*1da177e4SLinus Torvalds 	read_unlock_bh(&x25_list_lock);
286*1da177e4SLinus Torvalds 	return s;
287*1da177e4SLinus Torvalds }
288*1da177e4SLinus Torvalds 
289*1da177e4SLinus Torvalds /*
290*1da177e4SLinus Torvalds  *	Find a unique LCI for a given device.
291*1da177e4SLinus Torvalds  */
292*1da177e4SLinus Torvalds static unsigned int x25_new_lci(struct x25_neigh *nb)
293*1da177e4SLinus Torvalds {
294*1da177e4SLinus Torvalds 	unsigned int lci = 1;
295*1da177e4SLinus Torvalds 	struct sock *sk;
296*1da177e4SLinus Torvalds 
297*1da177e4SLinus Torvalds 	read_lock_bh(&x25_list_lock);
298*1da177e4SLinus Torvalds 
299*1da177e4SLinus Torvalds 	while ((sk = __x25_find_socket(lci, nb)) != NULL) {
300*1da177e4SLinus Torvalds 		sock_put(sk);
301*1da177e4SLinus Torvalds 		if (++lci == 4096) {
302*1da177e4SLinus Torvalds 			lci = 0;
303*1da177e4SLinus Torvalds 			break;
304*1da177e4SLinus Torvalds 		}
305*1da177e4SLinus Torvalds 	}
306*1da177e4SLinus Torvalds 
307*1da177e4SLinus Torvalds 	read_unlock_bh(&x25_list_lock);
308*1da177e4SLinus Torvalds 	return lci;
309*1da177e4SLinus Torvalds }
310*1da177e4SLinus Torvalds 
311*1da177e4SLinus Torvalds /*
312*1da177e4SLinus Torvalds  *	Deferred destroy.
313*1da177e4SLinus Torvalds  */
314*1da177e4SLinus Torvalds void x25_destroy_socket(struct sock *);
315*1da177e4SLinus Torvalds 
316*1da177e4SLinus Torvalds /*
317*1da177e4SLinus Torvalds  *	handler for deferred kills.
318*1da177e4SLinus Torvalds  */
319*1da177e4SLinus Torvalds static void x25_destroy_timer(unsigned long data)
320*1da177e4SLinus Torvalds {
321*1da177e4SLinus Torvalds 	x25_destroy_socket((struct sock *)data);
322*1da177e4SLinus Torvalds }
323*1da177e4SLinus Torvalds 
324*1da177e4SLinus Torvalds /*
325*1da177e4SLinus Torvalds  *	This is called from user mode and the timers. Thus it protects itself
326*1da177e4SLinus Torvalds  *	against interrupt users but doesn't worry about being called during
327*1da177e4SLinus Torvalds  *	work. Once it is removed from the queue no interrupt or bottom half
328*1da177e4SLinus Torvalds  *	will touch it and we are (fairly 8-) ) safe.
329*1da177e4SLinus Torvalds  *	Not static as it's used by the timer
330*1da177e4SLinus Torvalds  */
331*1da177e4SLinus Torvalds void x25_destroy_socket(struct sock *sk)
332*1da177e4SLinus Torvalds {
333*1da177e4SLinus Torvalds 	struct sk_buff *skb;
334*1da177e4SLinus Torvalds 
335*1da177e4SLinus Torvalds 	sock_hold(sk);
336*1da177e4SLinus Torvalds 	lock_sock(sk);
337*1da177e4SLinus Torvalds 	x25_stop_heartbeat(sk);
338*1da177e4SLinus Torvalds 	x25_stop_timer(sk);
339*1da177e4SLinus Torvalds 
340*1da177e4SLinus Torvalds 	x25_remove_socket(sk);
341*1da177e4SLinus Torvalds 	x25_clear_queues(sk);		/* Flush the queues */
342*1da177e4SLinus Torvalds 
343*1da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
344*1da177e4SLinus Torvalds 		if (skb->sk != sk) {		/* A pending connection */
345*1da177e4SLinus Torvalds 			/*
346*1da177e4SLinus Torvalds 			 * Queue the unaccepted socket for death
347*1da177e4SLinus Torvalds 			 */
348*1da177e4SLinus Torvalds 			sock_set_flag(skb->sk, SOCK_DEAD);
349*1da177e4SLinus Torvalds 			x25_start_heartbeat(skb->sk);
350*1da177e4SLinus Torvalds 			x25_sk(skb->sk)->state = X25_STATE_0;
351*1da177e4SLinus Torvalds 		}
352*1da177e4SLinus Torvalds 
353*1da177e4SLinus Torvalds 		kfree_skb(skb);
354*1da177e4SLinus Torvalds 	}
355*1da177e4SLinus Torvalds 
356*1da177e4SLinus Torvalds 	if (atomic_read(&sk->sk_wmem_alloc) ||
357*1da177e4SLinus Torvalds 	    atomic_read(&sk->sk_rmem_alloc)) {
358*1da177e4SLinus Torvalds 		/* Defer: outstanding buffers */
359*1da177e4SLinus Torvalds 		sk->sk_timer.expires  = jiffies + 10 * HZ;
360*1da177e4SLinus Torvalds 		sk->sk_timer.function = x25_destroy_timer;
361*1da177e4SLinus Torvalds 		sk->sk_timer.data = (unsigned long)sk;
362*1da177e4SLinus Torvalds 		add_timer(&sk->sk_timer);
363*1da177e4SLinus Torvalds 	} else {
364*1da177e4SLinus Torvalds 		/* drop last reference so sock_put will free */
365*1da177e4SLinus Torvalds 		__sock_put(sk);
366*1da177e4SLinus Torvalds 	}
367*1da177e4SLinus Torvalds 
368*1da177e4SLinus Torvalds 	release_sock(sk);
369*1da177e4SLinus Torvalds 	sock_put(sk);
370*1da177e4SLinus Torvalds }
371*1da177e4SLinus Torvalds 
372*1da177e4SLinus Torvalds /*
373*1da177e4SLinus Torvalds  *	Handling for system calls applied via the various interfaces to a
374*1da177e4SLinus Torvalds  *	X.25 socket object.
375*1da177e4SLinus Torvalds  */
376*1da177e4SLinus Torvalds 
377*1da177e4SLinus Torvalds static int x25_setsockopt(struct socket *sock, int level, int optname,
378*1da177e4SLinus Torvalds 			  char __user *optval, int optlen)
379*1da177e4SLinus Torvalds {
380*1da177e4SLinus Torvalds 	int opt;
381*1da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
382*1da177e4SLinus Torvalds 	int rc = -ENOPROTOOPT;
383*1da177e4SLinus Torvalds 
384*1da177e4SLinus Torvalds 	if (level != SOL_X25 || optname != X25_QBITINCL)
385*1da177e4SLinus Torvalds 		goto out;
386*1da177e4SLinus Torvalds 
387*1da177e4SLinus Torvalds 	rc = -EINVAL;
388*1da177e4SLinus Torvalds 	if (optlen < sizeof(int))
389*1da177e4SLinus Torvalds 		goto out;
390*1da177e4SLinus Torvalds 
391*1da177e4SLinus Torvalds 	rc = -EFAULT;
392*1da177e4SLinus Torvalds 	if (get_user(opt, (int __user *)optval))
393*1da177e4SLinus Torvalds 		goto out;
394*1da177e4SLinus Torvalds 
395*1da177e4SLinus Torvalds 	x25_sk(sk)->qbitincl = !!opt;
396*1da177e4SLinus Torvalds 	rc = 0;
397*1da177e4SLinus Torvalds out:
398*1da177e4SLinus Torvalds 	return rc;
399*1da177e4SLinus Torvalds }
400*1da177e4SLinus Torvalds 
401*1da177e4SLinus Torvalds static int x25_getsockopt(struct socket *sock, int level, int optname,
402*1da177e4SLinus Torvalds 			  char __user *optval, int __user *optlen)
403*1da177e4SLinus Torvalds {
404*1da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
405*1da177e4SLinus Torvalds 	int val, len, rc = -ENOPROTOOPT;
406*1da177e4SLinus Torvalds 
407*1da177e4SLinus Torvalds 	if (level != SOL_X25 || optname != X25_QBITINCL)
408*1da177e4SLinus Torvalds 		goto out;
409*1da177e4SLinus Torvalds 
410*1da177e4SLinus Torvalds 	rc = -EFAULT;
411*1da177e4SLinus Torvalds 	if (get_user(len, optlen))
412*1da177e4SLinus Torvalds 		goto out;
413*1da177e4SLinus Torvalds 
414*1da177e4SLinus Torvalds 	len = min_t(unsigned int, len, sizeof(int));
415*1da177e4SLinus Torvalds 
416*1da177e4SLinus Torvalds 	rc = -EINVAL;
417*1da177e4SLinus Torvalds 	if (len < 0)
418*1da177e4SLinus Torvalds 		goto out;
419*1da177e4SLinus Torvalds 
420*1da177e4SLinus Torvalds 	rc = -EFAULT;
421*1da177e4SLinus Torvalds 	if (put_user(len, optlen))
422*1da177e4SLinus Torvalds 		goto out;
423*1da177e4SLinus Torvalds 
424*1da177e4SLinus Torvalds 	val = x25_sk(sk)->qbitincl;
425*1da177e4SLinus Torvalds 	rc = copy_to_user(optval, &val, len) ? -EFAULT : 0;
426*1da177e4SLinus Torvalds out:
427*1da177e4SLinus Torvalds 	return rc;
428*1da177e4SLinus Torvalds }
429*1da177e4SLinus Torvalds 
430*1da177e4SLinus Torvalds static int x25_listen(struct socket *sock, int backlog)
431*1da177e4SLinus Torvalds {
432*1da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
433*1da177e4SLinus Torvalds 	int rc = -EOPNOTSUPP;
434*1da177e4SLinus Torvalds 
435*1da177e4SLinus Torvalds 	if (sk->sk_state != TCP_LISTEN) {
436*1da177e4SLinus Torvalds 		memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN);
437*1da177e4SLinus Torvalds 		sk->sk_max_ack_backlog = backlog;
438*1da177e4SLinus Torvalds 		sk->sk_state           = TCP_LISTEN;
439*1da177e4SLinus Torvalds 		rc = 0;
440*1da177e4SLinus Torvalds 	}
441*1da177e4SLinus Torvalds 
442*1da177e4SLinus Torvalds 	return rc;
443*1da177e4SLinus Torvalds }
444*1da177e4SLinus Torvalds 
445*1da177e4SLinus Torvalds static struct proto x25_proto = {
446*1da177e4SLinus Torvalds 	.name	  = "X25",
447*1da177e4SLinus Torvalds 	.owner	  = THIS_MODULE,
448*1da177e4SLinus Torvalds 	.obj_size = sizeof(struct x25_sock),
449*1da177e4SLinus Torvalds };
450*1da177e4SLinus Torvalds 
451*1da177e4SLinus Torvalds static struct sock *x25_alloc_socket(void)
452*1da177e4SLinus Torvalds {
453*1da177e4SLinus Torvalds 	struct x25_sock *x25;
454*1da177e4SLinus Torvalds 	struct sock *sk = sk_alloc(AF_X25, GFP_ATOMIC, &x25_proto, 1);
455*1da177e4SLinus Torvalds 
456*1da177e4SLinus Torvalds 	if (!sk)
457*1da177e4SLinus Torvalds 		goto out;
458*1da177e4SLinus Torvalds 
459*1da177e4SLinus Torvalds 	sock_init_data(NULL, sk);
460*1da177e4SLinus Torvalds 
461*1da177e4SLinus Torvalds 	x25 = x25_sk(sk);
462*1da177e4SLinus Torvalds 	skb_queue_head_init(&x25->ack_queue);
463*1da177e4SLinus Torvalds 	skb_queue_head_init(&x25->fragment_queue);
464*1da177e4SLinus Torvalds 	skb_queue_head_init(&x25->interrupt_in_queue);
465*1da177e4SLinus Torvalds 	skb_queue_head_init(&x25->interrupt_out_queue);
466*1da177e4SLinus Torvalds out:
467*1da177e4SLinus Torvalds 	return sk;
468*1da177e4SLinus Torvalds }
469*1da177e4SLinus Torvalds 
470*1da177e4SLinus Torvalds void x25_init_timers(struct sock *sk);
471*1da177e4SLinus Torvalds 
472*1da177e4SLinus Torvalds static int x25_create(struct socket *sock, int protocol)
473*1da177e4SLinus Torvalds {
474*1da177e4SLinus Torvalds 	struct sock *sk;
475*1da177e4SLinus Torvalds 	struct x25_sock *x25;
476*1da177e4SLinus Torvalds 	int rc = -ESOCKTNOSUPPORT;
477*1da177e4SLinus Torvalds 
478*1da177e4SLinus Torvalds 	if (sock->type != SOCK_SEQPACKET || protocol)
479*1da177e4SLinus Torvalds 		goto out;
480*1da177e4SLinus Torvalds 
481*1da177e4SLinus Torvalds 	rc = -ENOMEM;
482*1da177e4SLinus Torvalds 	if ((sk = x25_alloc_socket()) == NULL)
483*1da177e4SLinus Torvalds 		goto out;
484*1da177e4SLinus Torvalds 
485*1da177e4SLinus Torvalds 	x25 = x25_sk(sk);
486*1da177e4SLinus Torvalds 
487*1da177e4SLinus Torvalds 	sock_init_data(sock, sk);
488*1da177e4SLinus Torvalds 
489*1da177e4SLinus Torvalds 	x25_init_timers(sk);
490*1da177e4SLinus Torvalds 
491*1da177e4SLinus Torvalds 	sock->ops    = &x25_proto_ops;
492*1da177e4SLinus Torvalds 	sk->sk_protocol = protocol;
493*1da177e4SLinus Torvalds 	sk->sk_backlog_rcv = x25_backlog_rcv;
494*1da177e4SLinus Torvalds 
495*1da177e4SLinus Torvalds 	x25->t21   = sysctl_x25_call_request_timeout;
496*1da177e4SLinus Torvalds 	x25->t22   = sysctl_x25_reset_request_timeout;
497*1da177e4SLinus Torvalds 	x25->t23   = sysctl_x25_clear_request_timeout;
498*1da177e4SLinus Torvalds 	x25->t2    = sysctl_x25_ack_holdback_timeout;
499*1da177e4SLinus Torvalds 	x25->state = X25_STATE_0;
500*1da177e4SLinus Torvalds 
501*1da177e4SLinus Torvalds 	x25->facilities.winsize_in  = X25_DEFAULT_WINDOW_SIZE;
502*1da177e4SLinus Torvalds 	x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
503*1da177e4SLinus Torvalds 	x25->facilities.pacsize_in  = X25_DEFAULT_PACKET_SIZE;
504*1da177e4SLinus Torvalds 	x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
505*1da177e4SLinus Torvalds 	x25->facilities.throughput  = X25_DEFAULT_THROUGHPUT;
506*1da177e4SLinus Torvalds 	x25->facilities.reverse     = X25_DEFAULT_REVERSE;
507*1da177e4SLinus Torvalds 	rc = 0;
508*1da177e4SLinus Torvalds out:
509*1da177e4SLinus Torvalds 	return rc;
510*1da177e4SLinus Torvalds }
511*1da177e4SLinus Torvalds 
512*1da177e4SLinus Torvalds static struct sock *x25_make_new(struct sock *osk)
513*1da177e4SLinus Torvalds {
514*1da177e4SLinus Torvalds 	struct sock *sk = NULL;
515*1da177e4SLinus Torvalds 	struct x25_sock *x25, *ox25;
516*1da177e4SLinus Torvalds 
517*1da177e4SLinus Torvalds 	if (osk->sk_type != SOCK_SEQPACKET)
518*1da177e4SLinus Torvalds 		goto out;
519*1da177e4SLinus Torvalds 
520*1da177e4SLinus Torvalds 	if ((sk = x25_alloc_socket()) == NULL)
521*1da177e4SLinus Torvalds 		goto out;
522*1da177e4SLinus Torvalds 
523*1da177e4SLinus Torvalds 	x25 = x25_sk(sk);
524*1da177e4SLinus Torvalds 
525*1da177e4SLinus Torvalds 	sk->sk_type        = osk->sk_type;
526*1da177e4SLinus Torvalds 	sk->sk_socket      = osk->sk_socket;
527*1da177e4SLinus Torvalds 	sk->sk_priority    = osk->sk_priority;
528*1da177e4SLinus Torvalds 	sk->sk_protocol    = osk->sk_protocol;
529*1da177e4SLinus Torvalds 	sk->sk_rcvbuf      = osk->sk_rcvbuf;
530*1da177e4SLinus Torvalds 	sk->sk_sndbuf      = osk->sk_sndbuf;
531*1da177e4SLinus Torvalds 	sk->sk_state       = TCP_ESTABLISHED;
532*1da177e4SLinus Torvalds 	sk->sk_sleep       = osk->sk_sleep;
533*1da177e4SLinus Torvalds 	sk->sk_backlog_rcv = osk->sk_backlog_rcv;
534*1da177e4SLinus Torvalds 
535*1da177e4SLinus Torvalds 	if (sock_flag(osk, SOCK_ZAPPED))
536*1da177e4SLinus Torvalds 		sock_set_flag(sk, SOCK_ZAPPED);
537*1da177e4SLinus Torvalds 
538*1da177e4SLinus Torvalds 	if (sock_flag(osk, SOCK_DBG))
539*1da177e4SLinus Torvalds 		sock_set_flag(sk, SOCK_DBG);
540*1da177e4SLinus Torvalds 
541*1da177e4SLinus Torvalds 	ox25 = x25_sk(osk);
542*1da177e4SLinus Torvalds 	x25->t21        = ox25->t21;
543*1da177e4SLinus Torvalds 	x25->t22        = ox25->t22;
544*1da177e4SLinus Torvalds 	x25->t23        = ox25->t23;
545*1da177e4SLinus Torvalds 	x25->t2         = ox25->t2;
546*1da177e4SLinus Torvalds 	x25->facilities = ox25->facilities;
547*1da177e4SLinus Torvalds 	x25->qbitincl   = ox25->qbitincl;
548*1da177e4SLinus Torvalds 
549*1da177e4SLinus Torvalds 	x25_init_timers(sk);
550*1da177e4SLinus Torvalds out:
551*1da177e4SLinus Torvalds 	return sk;
552*1da177e4SLinus Torvalds }
553*1da177e4SLinus Torvalds 
554*1da177e4SLinus Torvalds static int x25_release(struct socket *sock)
555*1da177e4SLinus Torvalds {
556*1da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
557*1da177e4SLinus Torvalds 	struct x25_sock *x25;
558*1da177e4SLinus Torvalds 
559*1da177e4SLinus Torvalds 	if (!sk)
560*1da177e4SLinus Torvalds 		goto out;
561*1da177e4SLinus Torvalds 
562*1da177e4SLinus Torvalds 	x25 = x25_sk(sk);
563*1da177e4SLinus Torvalds 
564*1da177e4SLinus Torvalds 	switch (x25->state) {
565*1da177e4SLinus Torvalds 
566*1da177e4SLinus Torvalds 		case X25_STATE_0:
567*1da177e4SLinus Torvalds 		case X25_STATE_2:
568*1da177e4SLinus Torvalds 			x25_disconnect(sk, 0, 0, 0);
569*1da177e4SLinus Torvalds 			x25_destroy_socket(sk);
570*1da177e4SLinus Torvalds 			goto out;
571*1da177e4SLinus Torvalds 
572*1da177e4SLinus Torvalds 		case X25_STATE_1:
573*1da177e4SLinus Torvalds 		case X25_STATE_3:
574*1da177e4SLinus Torvalds 		case X25_STATE_4:
575*1da177e4SLinus Torvalds 			x25_clear_queues(sk);
576*1da177e4SLinus Torvalds 			x25_write_internal(sk, X25_CLEAR_REQUEST);
577*1da177e4SLinus Torvalds 			x25_start_t23timer(sk);
578*1da177e4SLinus Torvalds 			x25->state = X25_STATE_2;
579*1da177e4SLinus Torvalds 			sk->sk_state	= TCP_CLOSE;
580*1da177e4SLinus Torvalds 			sk->sk_shutdown	|= SEND_SHUTDOWN;
581*1da177e4SLinus Torvalds 			sk->sk_state_change(sk);
582*1da177e4SLinus Torvalds 			sock_set_flag(sk, SOCK_DEAD);
583*1da177e4SLinus Torvalds 			sock_set_flag(sk, SOCK_DESTROY);
584*1da177e4SLinus Torvalds 			break;
585*1da177e4SLinus Torvalds 	}
586*1da177e4SLinus Torvalds 
587*1da177e4SLinus Torvalds 	sock->sk	= NULL;
588*1da177e4SLinus Torvalds 	sk->sk_socket	= NULL;	/* Not used, but we should do this */
589*1da177e4SLinus Torvalds out:
590*1da177e4SLinus Torvalds 	return 0;
591*1da177e4SLinus Torvalds }
592*1da177e4SLinus Torvalds 
593*1da177e4SLinus Torvalds static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
594*1da177e4SLinus Torvalds {
595*1da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
596*1da177e4SLinus Torvalds 	struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr;
597*1da177e4SLinus Torvalds 
598*1da177e4SLinus Torvalds 	if (!sock_flag(sk, SOCK_ZAPPED) ||
599*1da177e4SLinus Torvalds 	    addr_len != sizeof(struct sockaddr_x25) ||
600*1da177e4SLinus Torvalds 	    addr->sx25_family != AF_X25)
601*1da177e4SLinus Torvalds 		return -EINVAL;
602*1da177e4SLinus Torvalds 
603*1da177e4SLinus Torvalds 	x25_sk(sk)->source_addr = addr->sx25_addr;
604*1da177e4SLinus Torvalds 	x25_insert_socket(sk);
605*1da177e4SLinus Torvalds 	sock_reset_flag(sk, SOCK_ZAPPED);
606*1da177e4SLinus Torvalds 	SOCK_DEBUG(sk, "x25_bind: socket is bound\n");
607*1da177e4SLinus Torvalds 
608*1da177e4SLinus Torvalds 	return 0;
609*1da177e4SLinus Torvalds }
610*1da177e4SLinus Torvalds 
611*1da177e4SLinus Torvalds static int x25_wait_for_connection_establishment(struct sock *sk)
612*1da177e4SLinus Torvalds {
613*1da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
614*1da177e4SLinus Torvalds         int rc;
615*1da177e4SLinus Torvalds 
616*1da177e4SLinus Torvalds 	add_wait_queue_exclusive(sk->sk_sleep, &wait);
617*1da177e4SLinus Torvalds 	for (;;) {
618*1da177e4SLinus Torvalds 		__set_current_state(TASK_INTERRUPTIBLE);
619*1da177e4SLinus Torvalds 		rc = -ERESTARTSYS;
620*1da177e4SLinus Torvalds 		if (signal_pending(current))
621*1da177e4SLinus Torvalds 			break;
622*1da177e4SLinus Torvalds 		rc = sock_error(sk);
623*1da177e4SLinus Torvalds 		if (rc) {
624*1da177e4SLinus Torvalds 			sk->sk_socket->state = SS_UNCONNECTED;
625*1da177e4SLinus Torvalds 			break;
626*1da177e4SLinus Torvalds 		}
627*1da177e4SLinus Torvalds 		rc = 0;
628*1da177e4SLinus Torvalds 		if (sk->sk_state != TCP_ESTABLISHED) {
629*1da177e4SLinus Torvalds 			release_sock(sk);
630*1da177e4SLinus Torvalds 			schedule();
631*1da177e4SLinus Torvalds 			lock_sock(sk);
632*1da177e4SLinus Torvalds 		} else
633*1da177e4SLinus Torvalds 			break;
634*1da177e4SLinus Torvalds 	}
635*1da177e4SLinus Torvalds 	__set_current_state(TASK_RUNNING);
636*1da177e4SLinus Torvalds 	remove_wait_queue(sk->sk_sleep, &wait);
637*1da177e4SLinus Torvalds 	return rc;
638*1da177e4SLinus Torvalds }
639*1da177e4SLinus Torvalds 
640*1da177e4SLinus Torvalds static int x25_connect(struct socket *sock, struct sockaddr *uaddr,
641*1da177e4SLinus Torvalds 		       int addr_len, int flags)
642*1da177e4SLinus Torvalds {
643*1da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
644*1da177e4SLinus Torvalds 	struct x25_sock *x25 = x25_sk(sk);
645*1da177e4SLinus Torvalds 	struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr;
646*1da177e4SLinus Torvalds 	struct x25_route *rt;
647*1da177e4SLinus Torvalds 	int rc = 0;
648*1da177e4SLinus Torvalds 
649*1da177e4SLinus Torvalds 	lock_sock(sk);
650*1da177e4SLinus Torvalds 	if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
651*1da177e4SLinus Torvalds 		sock->state = SS_CONNECTED;
652*1da177e4SLinus Torvalds 		goto out; /* Connect completed during a ERESTARTSYS event */
653*1da177e4SLinus Torvalds 	}
654*1da177e4SLinus Torvalds 
655*1da177e4SLinus Torvalds 	rc = -ECONNREFUSED;
656*1da177e4SLinus Torvalds 	if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) {
657*1da177e4SLinus Torvalds 		sock->state = SS_UNCONNECTED;
658*1da177e4SLinus Torvalds 		goto out;
659*1da177e4SLinus Torvalds 	}
660*1da177e4SLinus Torvalds 
661*1da177e4SLinus Torvalds 	rc = -EISCONN;	/* No reconnect on a seqpacket socket */
662*1da177e4SLinus Torvalds 	if (sk->sk_state == TCP_ESTABLISHED)
663*1da177e4SLinus Torvalds 		goto out;
664*1da177e4SLinus Torvalds 
665*1da177e4SLinus Torvalds 	sk->sk_state   = TCP_CLOSE;
666*1da177e4SLinus Torvalds 	sock->state = SS_UNCONNECTED;
667*1da177e4SLinus Torvalds 
668*1da177e4SLinus Torvalds 	rc = -EINVAL;
669*1da177e4SLinus Torvalds 	if (addr_len != sizeof(struct sockaddr_x25) ||
670*1da177e4SLinus Torvalds 	    addr->sx25_family != AF_X25)
671*1da177e4SLinus Torvalds 		goto out;
672*1da177e4SLinus Torvalds 
673*1da177e4SLinus Torvalds 	rc = -ENETUNREACH;
674*1da177e4SLinus Torvalds 	rt = x25_get_route(&addr->sx25_addr);
675*1da177e4SLinus Torvalds 	if (!rt)
676*1da177e4SLinus Torvalds 		goto out;
677*1da177e4SLinus Torvalds 
678*1da177e4SLinus Torvalds 	x25->neighbour = x25_get_neigh(rt->dev);
679*1da177e4SLinus Torvalds 	if (!x25->neighbour)
680*1da177e4SLinus Torvalds 		goto out_put_route;
681*1da177e4SLinus Torvalds 
682*1da177e4SLinus Torvalds 	x25_limit_facilities(&x25->facilities, x25->neighbour);
683*1da177e4SLinus Torvalds 
684*1da177e4SLinus Torvalds 	x25->lci = x25_new_lci(x25->neighbour);
685*1da177e4SLinus Torvalds 	if (!x25->lci)
686*1da177e4SLinus Torvalds 		goto out_put_neigh;
687*1da177e4SLinus Torvalds 
688*1da177e4SLinus Torvalds 	rc = -EINVAL;
689*1da177e4SLinus Torvalds 	if (sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */
690*1da177e4SLinus Torvalds 		goto out_put_neigh;
691*1da177e4SLinus Torvalds 
692*1da177e4SLinus Torvalds 	if (!strcmp(x25->source_addr.x25_addr, null_x25_address.x25_addr))
693*1da177e4SLinus Torvalds 		memset(&x25->source_addr, '\0', X25_ADDR_LEN);
694*1da177e4SLinus Torvalds 
695*1da177e4SLinus Torvalds 	x25->dest_addr = addr->sx25_addr;
696*1da177e4SLinus Torvalds 
697*1da177e4SLinus Torvalds 	/* Move to connecting socket, start sending Connect Requests */
698*1da177e4SLinus Torvalds 	sock->state   = SS_CONNECTING;
699*1da177e4SLinus Torvalds 	sk->sk_state  = TCP_SYN_SENT;
700*1da177e4SLinus Torvalds 
701*1da177e4SLinus Torvalds 	x25->state = X25_STATE_1;
702*1da177e4SLinus Torvalds 
703*1da177e4SLinus Torvalds 	x25_write_internal(sk, X25_CALL_REQUEST);
704*1da177e4SLinus Torvalds 
705*1da177e4SLinus Torvalds 	x25_start_heartbeat(sk);
706*1da177e4SLinus Torvalds 	x25_start_t21timer(sk);
707*1da177e4SLinus Torvalds 
708*1da177e4SLinus Torvalds 	/* Now the loop */
709*1da177e4SLinus Torvalds 	rc = -EINPROGRESS;
710*1da177e4SLinus Torvalds 	if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
711*1da177e4SLinus Torvalds 		goto out_put_neigh;
712*1da177e4SLinus Torvalds 
713*1da177e4SLinus Torvalds 	rc = x25_wait_for_connection_establishment(sk);
714*1da177e4SLinus Torvalds 	if (rc)
715*1da177e4SLinus Torvalds 		goto out_put_neigh;
716*1da177e4SLinus Torvalds 
717*1da177e4SLinus Torvalds 	sock->state = SS_CONNECTED;
718*1da177e4SLinus Torvalds 	rc = 0;
719*1da177e4SLinus Torvalds out_put_neigh:
720*1da177e4SLinus Torvalds 	if (rc)
721*1da177e4SLinus Torvalds 		x25_neigh_put(x25->neighbour);
722*1da177e4SLinus Torvalds out_put_route:
723*1da177e4SLinus Torvalds 	x25_route_put(rt);
724*1da177e4SLinus Torvalds out:
725*1da177e4SLinus Torvalds 	release_sock(sk);
726*1da177e4SLinus Torvalds 	return rc;
727*1da177e4SLinus Torvalds }
728*1da177e4SLinus Torvalds 
729*1da177e4SLinus Torvalds static int x25_wait_for_data(struct sock *sk, int timeout)
730*1da177e4SLinus Torvalds {
731*1da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
732*1da177e4SLinus Torvalds 	int rc = 0;
733*1da177e4SLinus Torvalds 
734*1da177e4SLinus Torvalds 	add_wait_queue_exclusive(sk->sk_sleep, &wait);
735*1da177e4SLinus Torvalds 	for (;;) {
736*1da177e4SLinus Torvalds 		__set_current_state(TASK_INTERRUPTIBLE);
737*1da177e4SLinus Torvalds 		if (sk->sk_shutdown & RCV_SHUTDOWN)
738*1da177e4SLinus Torvalds 			break;
739*1da177e4SLinus Torvalds 		rc = -ERESTARTSYS;
740*1da177e4SLinus Torvalds 		if (signal_pending(current))
741*1da177e4SLinus Torvalds 			break;
742*1da177e4SLinus Torvalds 		rc = -EAGAIN;
743*1da177e4SLinus Torvalds 		if (!timeout)
744*1da177e4SLinus Torvalds 			break;
745*1da177e4SLinus Torvalds 		rc = 0;
746*1da177e4SLinus Torvalds 		if (skb_queue_empty(&sk->sk_receive_queue)) {
747*1da177e4SLinus Torvalds 			release_sock(sk);
748*1da177e4SLinus Torvalds 			timeout = schedule_timeout(timeout);
749*1da177e4SLinus Torvalds 			lock_sock(sk);
750*1da177e4SLinus Torvalds 		} else
751*1da177e4SLinus Torvalds 			break;
752*1da177e4SLinus Torvalds 	}
753*1da177e4SLinus Torvalds 	__set_current_state(TASK_RUNNING);
754*1da177e4SLinus Torvalds 	remove_wait_queue(sk->sk_sleep, &wait);
755*1da177e4SLinus Torvalds 	return rc;
756*1da177e4SLinus Torvalds }
757*1da177e4SLinus Torvalds 
758*1da177e4SLinus Torvalds static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
759*1da177e4SLinus Torvalds {
760*1da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
761*1da177e4SLinus Torvalds 	struct sock *newsk;
762*1da177e4SLinus Torvalds 	struct sk_buff *skb;
763*1da177e4SLinus Torvalds 	int rc = -EINVAL;
764*1da177e4SLinus Torvalds 
765*1da177e4SLinus Torvalds 	if (!sk || sk->sk_state != TCP_LISTEN)
766*1da177e4SLinus Torvalds 		goto out;
767*1da177e4SLinus Torvalds 
768*1da177e4SLinus Torvalds 	rc = -EOPNOTSUPP;
769*1da177e4SLinus Torvalds 	if (sk->sk_type != SOCK_SEQPACKET)
770*1da177e4SLinus Torvalds 		goto out;
771*1da177e4SLinus Torvalds 
772*1da177e4SLinus Torvalds 	lock_sock(sk);
773*1da177e4SLinus Torvalds 	rc = x25_wait_for_data(sk, sk->sk_rcvtimeo);
774*1da177e4SLinus Torvalds 	if (rc)
775*1da177e4SLinus Torvalds 		goto out2;
776*1da177e4SLinus Torvalds 	skb = skb_dequeue(&sk->sk_receive_queue);
777*1da177e4SLinus Torvalds 	rc = -EINVAL;
778*1da177e4SLinus Torvalds 	if (!skb->sk)
779*1da177e4SLinus Torvalds 		goto out2;
780*1da177e4SLinus Torvalds 	newsk		 = skb->sk;
781*1da177e4SLinus Torvalds 	newsk->sk_socket = newsock;
782*1da177e4SLinus Torvalds 	newsk->sk_sleep  = &newsock->wait;
783*1da177e4SLinus Torvalds 
784*1da177e4SLinus Torvalds 	/* Now attach up the new socket */
785*1da177e4SLinus Torvalds 	skb->sk = NULL;
786*1da177e4SLinus Torvalds 	kfree_skb(skb);
787*1da177e4SLinus Torvalds 	sk->sk_ack_backlog--;
788*1da177e4SLinus Torvalds 	newsock->sk    = newsk;
789*1da177e4SLinus Torvalds 	newsock->state = SS_CONNECTED;
790*1da177e4SLinus Torvalds 	rc = 0;
791*1da177e4SLinus Torvalds out2:
792*1da177e4SLinus Torvalds 	release_sock(sk);
793*1da177e4SLinus Torvalds out:
794*1da177e4SLinus Torvalds 	return rc;
795*1da177e4SLinus Torvalds }
796*1da177e4SLinus Torvalds 
797*1da177e4SLinus Torvalds static int x25_getname(struct socket *sock, struct sockaddr *uaddr,
798*1da177e4SLinus Torvalds 		       int *uaddr_len, int peer)
799*1da177e4SLinus Torvalds {
800*1da177e4SLinus Torvalds 	struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr;
801*1da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
802*1da177e4SLinus Torvalds 	struct x25_sock *x25 = x25_sk(sk);
803*1da177e4SLinus Torvalds 
804*1da177e4SLinus Torvalds 	if (peer) {
805*1da177e4SLinus Torvalds 		if (sk->sk_state != TCP_ESTABLISHED)
806*1da177e4SLinus Torvalds 			return -ENOTCONN;
807*1da177e4SLinus Torvalds 		sx25->sx25_addr = x25->dest_addr;
808*1da177e4SLinus Torvalds 	} else
809*1da177e4SLinus Torvalds 		sx25->sx25_addr = x25->source_addr;
810*1da177e4SLinus Torvalds 
811*1da177e4SLinus Torvalds 	sx25->sx25_family = AF_X25;
812*1da177e4SLinus Torvalds 	*uaddr_len = sizeof(*sx25);
813*1da177e4SLinus Torvalds 
814*1da177e4SLinus Torvalds 	return 0;
815*1da177e4SLinus Torvalds }
816*1da177e4SLinus Torvalds 
817*1da177e4SLinus Torvalds int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
818*1da177e4SLinus Torvalds 			unsigned int lci)
819*1da177e4SLinus Torvalds {
820*1da177e4SLinus Torvalds 	struct sock *sk;
821*1da177e4SLinus Torvalds 	struct sock *make;
822*1da177e4SLinus Torvalds 	struct x25_sock *makex25;
823*1da177e4SLinus Torvalds 	struct x25_address source_addr, dest_addr;
824*1da177e4SLinus Torvalds 	struct x25_facilities facilities;
825*1da177e4SLinus Torvalds 	struct x25_calluserdata calluserdata;
826*1da177e4SLinus Torvalds 	int len, rc;
827*1da177e4SLinus Torvalds 
828*1da177e4SLinus Torvalds 	/*
829*1da177e4SLinus Torvalds 	 *	Remove the LCI and frame type.
830*1da177e4SLinus Torvalds 	 */
831*1da177e4SLinus Torvalds 	skb_pull(skb, X25_STD_MIN_LEN);
832*1da177e4SLinus Torvalds 
833*1da177e4SLinus Torvalds 	/*
834*1da177e4SLinus Torvalds 	 *	Extract the X.25 addresses and convert them to ASCII strings,
835*1da177e4SLinus Torvalds 	 *	and remove them.
836*1da177e4SLinus Torvalds 	 */
837*1da177e4SLinus Torvalds 	skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
838*1da177e4SLinus Torvalds 
839*1da177e4SLinus Torvalds 	/*
840*1da177e4SLinus Torvalds 	 *	Get the length of the facilities, skip past them for the moment
841*1da177e4SLinus Torvalds 	 *	get the call user data because this is needed to determine
842*1da177e4SLinus Torvalds 	 *	the correct listener
843*1da177e4SLinus Torvalds 	 */
844*1da177e4SLinus Torvalds 	len = skb->data[0] + 1;
845*1da177e4SLinus Torvalds 	skb_pull(skb,len);
846*1da177e4SLinus Torvalds 
847*1da177e4SLinus Torvalds 	/*
848*1da177e4SLinus Torvalds 	 *	Incoming Call User Data.
849*1da177e4SLinus Torvalds 	 */
850*1da177e4SLinus Torvalds 	if (skb->len >= 0) {
851*1da177e4SLinus Torvalds 		memcpy(calluserdata.cuddata, skb->data, skb->len);
852*1da177e4SLinus Torvalds 		calluserdata.cudlength = skb->len;
853*1da177e4SLinus Torvalds 	}
854*1da177e4SLinus Torvalds 
855*1da177e4SLinus Torvalds 	skb_push(skb,len);
856*1da177e4SLinus Torvalds 
857*1da177e4SLinus Torvalds 	/*
858*1da177e4SLinus Torvalds 	 *	Find a listener for the particular address/cud pair.
859*1da177e4SLinus Torvalds 	 */
860*1da177e4SLinus Torvalds 	sk = x25_find_listener(&source_addr,&calluserdata);
861*1da177e4SLinus Torvalds 
862*1da177e4SLinus Torvalds 	/*
863*1da177e4SLinus Torvalds 	 *	We can't accept the Call Request.
864*1da177e4SLinus Torvalds 	 */
865*1da177e4SLinus Torvalds 	if (sk == NULL || sk_acceptq_is_full(sk))
866*1da177e4SLinus Torvalds 		goto out_clear_request;
867*1da177e4SLinus Torvalds 
868*1da177e4SLinus Torvalds 	/*
869*1da177e4SLinus Torvalds 	 *	Try to reach a compromise on the requested facilities.
870*1da177e4SLinus Torvalds 	 */
871*1da177e4SLinus Torvalds 	if ((len = x25_negotiate_facilities(skb, sk, &facilities)) == -1)
872*1da177e4SLinus Torvalds 		goto out_sock_put;
873*1da177e4SLinus Torvalds 
874*1da177e4SLinus Torvalds 	/*
875*1da177e4SLinus Torvalds 	 * current neighbour/link might impose additional limits
876*1da177e4SLinus Torvalds 	 * on certain facilties
877*1da177e4SLinus Torvalds 	 */
878*1da177e4SLinus Torvalds 
879*1da177e4SLinus Torvalds 	x25_limit_facilities(&facilities, nb);
880*1da177e4SLinus Torvalds 
881*1da177e4SLinus Torvalds 	/*
882*1da177e4SLinus Torvalds 	 *	Try to create a new socket.
883*1da177e4SLinus Torvalds 	 */
884*1da177e4SLinus Torvalds 	make = x25_make_new(sk);
885*1da177e4SLinus Torvalds 	if (!make)
886*1da177e4SLinus Torvalds 		goto out_sock_put;
887*1da177e4SLinus Torvalds 
888*1da177e4SLinus Torvalds 	/*
889*1da177e4SLinus Torvalds 	 *	Remove the facilities
890*1da177e4SLinus Torvalds 	 */
891*1da177e4SLinus Torvalds 	skb_pull(skb, len);
892*1da177e4SLinus Torvalds 
893*1da177e4SLinus Torvalds 	skb->sk     = make;
894*1da177e4SLinus Torvalds 	make->sk_state = TCP_ESTABLISHED;
895*1da177e4SLinus Torvalds 
896*1da177e4SLinus Torvalds 	makex25 = x25_sk(make);
897*1da177e4SLinus Torvalds 	makex25->lci           = lci;
898*1da177e4SLinus Torvalds 	makex25->dest_addr     = dest_addr;
899*1da177e4SLinus Torvalds 	makex25->source_addr   = source_addr;
900*1da177e4SLinus Torvalds 	makex25->neighbour     = nb;
901*1da177e4SLinus Torvalds 	makex25->facilities    = facilities;
902*1da177e4SLinus Torvalds 	makex25->vc_facil_mask = x25_sk(sk)->vc_facil_mask;
903*1da177e4SLinus Torvalds 	makex25->calluserdata  = calluserdata;
904*1da177e4SLinus Torvalds 
905*1da177e4SLinus Torvalds 	x25_write_internal(make, X25_CALL_ACCEPTED);
906*1da177e4SLinus Torvalds 
907*1da177e4SLinus Torvalds 	makex25->state = X25_STATE_3;
908*1da177e4SLinus Torvalds 
909*1da177e4SLinus Torvalds 	sk->sk_ack_backlog++;
910*1da177e4SLinus Torvalds 
911*1da177e4SLinus Torvalds 	x25_insert_socket(make);
912*1da177e4SLinus Torvalds 
913*1da177e4SLinus Torvalds 	skb_queue_head(&sk->sk_receive_queue, skb);
914*1da177e4SLinus Torvalds 
915*1da177e4SLinus Torvalds 	x25_start_heartbeat(make);
916*1da177e4SLinus Torvalds 
917*1da177e4SLinus Torvalds 	if (!sock_flag(sk, SOCK_DEAD))
918*1da177e4SLinus Torvalds 		sk->sk_data_ready(sk, skb->len);
919*1da177e4SLinus Torvalds 	rc = 1;
920*1da177e4SLinus Torvalds 	sock_put(sk);
921*1da177e4SLinus Torvalds out:
922*1da177e4SLinus Torvalds 	return rc;
923*1da177e4SLinus Torvalds out_sock_put:
924*1da177e4SLinus Torvalds 	sock_put(sk);
925*1da177e4SLinus Torvalds out_clear_request:
926*1da177e4SLinus Torvalds 	rc = 0;
927*1da177e4SLinus Torvalds 	x25_transmit_clear_request(nb, lci, 0x01);
928*1da177e4SLinus Torvalds 	goto out;
929*1da177e4SLinus Torvalds }
930*1da177e4SLinus Torvalds 
931*1da177e4SLinus Torvalds static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
932*1da177e4SLinus Torvalds 		       struct msghdr *msg, size_t len)
933*1da177e4SLinus Torvalds {
934*1da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
935*1da177e4SLinus Torvalds 	struct x25_sock *x25 = x25_sk(sk);
936*1da177e4SLinus Torvalds 	struct sockaddr_x25 *usx25 = (struct sockaddr_x25 *)msg->msg_name;
937*1da177e4SLinus Torvalds 	struct sockaddr_x25 sx25;
938*1da177e4SLinus Torvalds 	struct sk_buff *skb;
939*1da177e4SLinus Torvalds 	unsigned char *asmptr;
940*1da177e4SLinus Torvalds 	int noblock = msg->msg_flags & MSG_DONTWAIT;
941*1da177e4SLinus Torvalds 	size_t size;
942*1da177e4SLinus Torvalds 	int qbit = 0, rc = -EINVAL;
943*1da177e4SLinus Torvalds 
944*1da177e4SLinus Torvalds 	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR|MSG_CMSG_COMPAT))
945*1da177e4SLinus Torvalds 		goto out;
946*1da177e4SLinus Torvalds 
947*1da177e4SLinus Torvalds 	/* we currently don't support segmented records at the user interface */
948*1da177e4SLinus Torvalds 	if (!(msg->msg_flags & (MSG_EOR|MSG_OOB)))
949*1da177e4SLinus Torvalds 		goto out;
950*1da177e4SLinus Torvalds 
951*1da177e4SLinus Torvalds 	rc = -EADDRNOTAVAIL;
952*1da177e4SLinus Torvalds 	if (sock_flag(sk, SOCK_ZAPPED))
953*1da177e4SLinus Torvalds 		goto out;
954*1da177e4SLinus Torvalds 
955*1da177e4SLinus Torvalds 	rc = -EPIPE;
956*1da177e4SLinus Torvalds 	if (sk->sk_shutdown & SEND_SHUTDOWN) {
957*1da177e4SLinus Torvalds 		send_sig(SIGPIPE, current, 0);
958*1da177e4SLinus Torvalds 		goto out;
959*1da177e4SLinus Torvalds 	}
960*1da177e4SLinus Torvalds 
961*1da177e4SLinus Torvalds 	rc = -ENETUNREACH;
962*1da177e4SLinus Torvalds 	if (!x25->neighbour)
963*1da177e4SLinus Torvalds 		goto out;
964*1da177e4SLinus Torvalds 
965*1da177e4SLinus Torvalds 	if (usx25) {
966*1da177e4SLinus Torvalds 		rc = -EINVAL;
967*1da177e4SLinus Torvalds 		if (msg->msg_namelen < sizeof(sx25))
968*1da177e4SLinus Torvalds 			goto out;
969*1da177e4SLinus Torvalds 		memcpy(&sx25, usx25, sizeof(sx25));
970*1da177e4SLinus Torvalds 		rc = -EISCONN;
971*1da177e4SLinus Torvalds 		if (strcmp(x25->dest_addr.x25_addr, sx25.sx25_addr.x25_addr))
972*1da177e4SLinus Torvalds 			goto out;
973*1da177e4SLinus Torvalds 		rc = -EINVAL;
974*1da177e4SLinus Torvalds 		if (sx25.sx25_family != AF_X25)
975*1da177e4SLinus Torvalds 			goto out;
976*1da177e4SLinus Torvalds 	} else {
977*1da177e4SLinus Torvalds 		/*
978*1da177e4SLinus Torvalds 		 *	FIXME 1003.1g - if the socket is like this because
979*1da177e4SLinus Torvalds 		 *	it has become closed (not started closed) we ought
980*1da177e4SLinus Torvalds 		 *	to SIGPIPE, EPIPE;
981*1da177e4SLinus Torvalds 		 */
982*1da177e4SLinus Torvalds 		rc = -ENOTCONN;
983*1da177e4SLinus Torvalds 		if (sk->sk_state != TCP_ESTABLISHED)
984*1da177e4SLinus Torvalds 			goto out;
985*1da177e4SLinus Torvalds 
986*1da177e4SLinus Torvalds 		sx25.sx25_family = AF_X25;
987*1da177e4SLinus Torvalds 		sx25.sx25_addr   = x25->dest_addr;
988*1da177e4SLinus Torvalds 	}
989*1da177e4SLinus Torvalds 
990*1da177e4SLinus Torvalds 	SOCK_DEBUG(sk, "x25_sendmsg: sendto: Addresses built.\n");
991*1da177e4SLinus Torvalds 
992*1da177e4SLinus Torvalds 	/* Build a packet */
993*1da177e4SLinus Torvalds 	SOCK_DEBUG(sk, "x25_sendmsg: sendto: building packet.\n");
994*1da177e4SLinus Torvalds 
995*1da177e4SLinus Torvalds 	if ((msg->msg_flags & MSG_OOB) && len > 32)
996*1da177e4SLinus Torvalds 		len = 32;
997*1da177e4SLinus Torvalds 
998*1da177e4SLinus Torvalds 	size = len + X25_MAX_L2_LEN + X25_EXT_MIN_LEN;
999*1da177e4SLinus Torvalds 
1000*1da177e4SLinus Torvalds 	skb = sock_alloc_send_skb(sk, size, noblock, &rc);
1001*1da177e4SLinus Torvalds 	if (!skb)
1002*1da177e4SLinus Torvalds 		goto out;
1003*1da177e4SLinus Torvalds 	X25_SKB_CB(skb)->flags = msg->msg_flags;
1004*1da177e4SLinus Torvalds 
1005*1da177e4SLinus Torvalds 	skb_reserve(skb, X25_MAX_L2_LEN + X25_EXT_MIN_LEN);
1006*1da177e4SLinus Torvalds 
1007*1da177e4SLinus Torvalds 	/*
1008*1da177e4SLinus Torvalds 	 *	Put the data on the end
1009*1da177e4SLinus Torvalds 	 */
1010*1da177e4SLinus Torvalds 	SOCK_DEBUG(sk, "x25_sendmsg: Copying user data\n");
1011*1da177e4SLinus Torvalds 
1012*1da177e4SLinus Torvalds 	asmptr = skb->h.raw = skb_put(skb, len);
1013*1da177e4SLinus Torvalds 
1014*1da177e4SLinus Torvalds 	rc = memcpy_fromiovec(asmptr, msg->msg_iov, len);
1015*1da177e4SLinus Torvalds 	if (rc)
1016*1da177e4SLinus Torvalds 		goto out_kfree_skb;
1017*1da177e4SLinus Torvalds 
1018*1da177e4SLinus Torvalds 	/*
1019*1da177e4SLinus Torvalds 	 *	If the Q BIT Include socket option is in force, the first
1020*1da177e4SLinus Torvalds 	 *	byte of the user data is the logical value of the Q Bit.
1021*1da177e4SLinus Torvalds 	 */
1022*1da177e4SLinus Torvalds 	if (x25->qbitincl) {
1023*1da177e4SLinus Torvalds 		qbit = skb->data[0];
1024*1da177e4SLinus Torvalds 		skb_pull(skb, 1);
1025*1da177e4SLinus Torvalds 	}
1026*1da177e4SLinus Torvalds 
1027*1da177e4SLinus Torvalds 	/*
1028*1da177e4SLinus Torvalds 	 *	Push down the X.25 header
1029*1da177e4SLinus Torvalds 	 */
1030*1da177e4SLinus Torvalds 	SOCK_DEBUG(sk, "x25_sendmsg: Building X.25 Header.\n");
1031*1da177e4SLinus Torvalds 
1032*1da177e4SLinus Torvalds 	if (msg->msg_flags & MSG_OOB) {
1033*1da177e4SLinus Torvalds 		if (x25->neighbour->extended) {
1034*1da177e4SLinus Torvalds 			asmptr    = skb_push(skb, X25_STD_MIN_LEN);
1035*1da177e4SLinus Torvalds 			*asmptr++ = ((x25->lci >> 8) & 0x0F) | X25_GFI_EXTSEQ;
1036*1da177e4SLinus Torvalds 			*asmptr++ = (x25->lci >> 0) & 0xFF;
1037*1da177e4SLinus Torvalds 			*asmptr++ = X25_INTERRUPT;
1038*1da177e4SLinus Torvalds 		} else {
1039*1da177e4SLinus Torvalds 			asmptr    = skb_push(skb, X25_STD_MIN_LEN);
1040*1da177e4SLinus Torvalds 			*asmptr++ = ((x25->lci >> 8) & 0x0F) | X25_GFI_STDSEQ;
1041*1da177e4SLinus Torvalds 			*asmptr++ = (x25->lci >> 0) & 0xFF;
1042*1da177e4SLinus Torvalds 			*asmptr++ = X25_INTERRUPT;
1043*1da177e4SLinus Torvalds 		}
1044*1da177e4SLinus Torvalds 	} else {
1045*1da177e4SLinus Torvalds 		if (x25->neighbour->extended) {
1046*1da177e4SLinus Torvalds 			/* Build an Extended X.25 header */
1047*1da177e4SLinus Torvalds 			asmptr    = skb_push(skb, X25_EXT_MIN_LEN);
1048*1da177e4SLinus Torvalds 			*asmptr++ = ((x25->lci >> 8) & 0x0F) | X25_GFI_EXTSEQ;
1049*1da177e4SLinus Torvalds 			*asmptr++ = (x25->lci >> 0) & 0xFF;
1050*1da177e4SLinus Torvalds 			*asmptr++ = X25_DATA;
1051*1da177e4SLinus Torvalds 			*asmptr++ = X25_DATA;
1052*1da177e4SLinus Torvalds 		} else {
1053*1da177e4SLinus Torvalds 			/* Build an Standard X.25 header */
1054*1da177e4SLinus Torvalds 			asmptr    = skb_push(skb, X25_STD_MIN_LEN);
1055*1da177e4SLinus Torvalds 			*asmptr++ = ((x25->lci >> 8) & 0x0F) | X25_GFI_STDSEQ;
1056*1da177e4SLinus Torvalds 			*asmptr++ = (x25->lci >> 0) & 0xFF;
1057*1da177e4SLinus Torvalds 			*asmptr++ = X25_DATA;
1058*1da177e4SLinus Torvalds 		}
1059*1da177e4SLinus Torvalds 
1060*1da177e4SLinus Torvalds 		if (qbit)
1061*1da177e4SLinus Torvalds 			skb->data[0] |= X25_Q_BIT;
1062*1da177e4SLinus Torvalds 	}
1063*1da177e4SLinus Torvalds 
1064*1da177e4SLinus Torvalds 	SOCK_DEBUG(sk, "x25_sendmsg: Built header.\n");
1065*1da177e4SLinus Torvalds 	SOCK_DEBUG(sk, "x25_sendmsg: Transmitting buffer\n");
1066*1da177e4SLinus Torvalds 
1067*1da177e4SLinus Torvalds 	rc = -ENOTCONN;
1068*1da177e4SLinus Torvalds 	if (sk->sk_state != TCP_ESTABLISHED)
1069*1da177e4SLinus Torvalds 		goto out_kfree_skb;
1070*1da177e4SLinus Torvalds 
1071*1da177e4SLinus Torvalds 	if (msg->msg_flags & MSG_OOB)
1072*1da177e4SLinus Torvalds 		skb_queue_tail(&x25->interrupt_out_queue, skb);
1073*1da177e4SLinus Torvalds 	else {
1074*1da177e4SLinus Torvalds 	        len = x25_output(sk, skb);
1075*1da177e4SLinus Torvalds 		if (len < 0)
1076*1da177e4SLinus Torvalds 			kfree_skb(skb);
1077*1da177e4SLinus Torvalds 		else if (x25->qbitincl)
1078*1da177e4SLinus Torvalds 			len++;
1079*1da177e4SLinus Torvalds 	}
1080*1da177e4SLinus Torvalds 
1081*1da177e4SLinus Torvalds 	/*
1082*1da177e4SLinus Torvalds 	 * lock_sock() is currently only used to serialize this x25_kick()
1083*1da177e4SLinus Torvalds 	 * against input-driven x25_kick() calls. It currently only blocks
1084*1da177e4SLinus Torvalds 	 * incoming packets for this socket and does not protect against
1085*1da177e4SLinus Torvalds 	 * any other socket state changes and is not called from anywhere
1086*1da177e4SLinus Torvalds 	 * else. As x25_kick() cannot block and as long as all socket
1087*1da177e4SLinus Torvalds 	 * operations are BKL-wrapped, we don't need take to care about
1088*1da177e4SLinus Torvalds 	 * purging the backlog queue in x25_release().
1089*1da177e4SLinus Torvalds 	 *
1090*1da177e4SLinus Torvalds 	 * Using lock_sock() to protect all socket operations entirely
1091*1da177e4SLinus Torvalds 	 * (and making the whole x25 stack SMP aware) unfortunately would
1092*1da177e4SLinus Torvalds 	 * require major changes to {send,recv}msg and skb allocation methods.
1093*1da177e4SLinus Torvalds 	 * -> 2.5 ;)
1094*1da177e4SLinus Torvalds 	 */
1095*1da177e4SLinus Torvalds 	lock_sock(sk);
1096*1da177e4SLinus Torvalds 	x25_kick(sk);
1097*1da177e4SLinus Torvalds 	release_sock(sk);
1098*1da177e4SLinus Torvalds 	rc = len;
1099*1da177e4SLinus Torvalds out:
1100*1da177e4SLinus Torvalds 	return rc;
1101*1da177e4SLinus Torvalds out_kfree_skb:
1102*1da177e4SLinus Torvalds 	kfree_skb(skb);
1103*1da177e4SLinus Torvalds 	goto out;
1104*1da177e4SLinus Torvalds }
1105*1da177e4SLinus Torvalds 
1106*1da177e4SLinus Torvalds 
1107*1da177e4SLinus Torvalds static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
1108*1da177e4SLinus Torvalds 		       struct msghdr *msg, size_t size,
1109*1da177e4SLinus Torvalds 		       int flags)
1110*1da177e4SLinus Torvalds {
1111*1da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
1112*1da177e4SLinus Torvalds 	struct x25_sock *x25 = x25_sk(sk);
1113*1da177e4SLinus Torvalds 	struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)msg->msg_name;
1114*1da177e4SLinus Torvalds 	size_t copied;
1115*1da177e4SLinus Torvalds 	int qbit;
1116*1da177e4SLinus Torvalds 	struct sk_buff *skb;
1117*1da177e4SLinus Torvalds 	unsigned char *asmptr;
1118*1da177e4SLinus Torvalds 	int rc = -ENOTCONN;
1119*1da177e4SLinus Torvalds 
1120*1da177e4SLinus Torvalds 	/*
1121*1da177e4SLinus Torvalds 	 * This works for seqpacket too. The receiver has ordered the queue for
1122*1da177e4SLinus Torvalds 	 * us! We do one quick check first though
1123*1da177e4SLinus Torvalds 	 */
1124*1da177e4SLinus Torvalds 	if (sk->sk_state != TCP_ESTABLISHED)
1125*1da177e4SLinus Torvalds 		goto out;
1126*1da177e4SLinus Torvalds 
1127*1da177e4SLinus Torvalds 	if (flags & MSG_OOB) {
1128*1da177e4SLinus Torvalds 		rc = -EINVAL;
1129*1da177e4SLinus Torvalds 		if (sock_flag(sk, SOCK_URGINLINE) ||
1130*1da177e4SLinus Torvalds 		    !skb_peek(&x25->interrupt_in_queue))
1131*1da177e4SLinus Torvalds 			goto out;
1132*1da177e4SLinus Torvalds 
1133*1da177e4SLinus Torvalds 		skb = skb_dequeue(&x25->interrupt_in_queue);
1134*1da177e4SLinus Torvalds 
1135*1da177e4SLinus Torvalds 		skb_pull(skb, X25_STD_MIN_LEN);
1136*1da177e4SLinus Torvalds 
1137*1da177e4SLinus Torvalds 		/*
1138*1da177e4SLinus Torvalds 		 *	No Q bit information on Interrupt data.
1139*1da177e4SLinus Torvalds 		 */
1140*1da177e4SLinus Torvalds 		if (x25->qbitincl) {
1141*1da177e4SLinus Torvalds 			asmptr  = skb_push(skb, 1);
1142*1da177e4SLinus Torvalds 			*asmptr = 0x00;
1143*1da177e4SLinus Torvalds 		}
1144*1da177e4SLinus Torvalds 
1145*1da177e4SLinus Torvalds 		msg->msg_flags |= MSG_OOB;
1146*1da177e4SLinus Torvalds 	} else {
1147*1da177e4SLinus Torvalds 		/* Now we can treat all alike */
1148*1da177e4SLinus Torvalds 		skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
1149*1da177e4SLinus Torvalds 					flags & MSG_DONTWAIT, &rc);
1150*1da177e4SLinus Torvalds 		if (!skb)
1151*1da177e4SLinus Torvalds 			goto out;
1152*1da177e4SLinus Torvalds 
1153*1da177e4SLinus Torvalds 		qbit = (skb->data[0] & X25_Q_BIT) == X25_Q_BIT;
1154*1da177e4SLinus Torvalds 
1155*1da177e4SLinus Torvalds 		skb_pull(skb, x25->neighbour->extended ?
1156*1da177e4SLinus Torvalds 				X25_EXT_MIN_LEN : X25_STD_MIN_LEN);
1157*1da177e4SLinus Torvalds 
1158*1da177e4SLinus Torvalds 		if (x25->qbitincl) {
1159*1da177e4SLinus Torvalds 			asmptr  = skb_push(skb, 1);
1160*1da177e4SLinus Torvalds 			*asmptr = qbit;
1161*1da177e4SLinus Torvalds 		}
1162*1da177e4SLinus Torvalds 	}
1163*1da177e4SLinus Torvalds 
1164*1da177e4SLinus Torvalds 	skb->h.raw = skb->data;
1165*1da177e4SLinus Torvalds 
1166*1da177e4SLinus Torvalds 	copied = skb->len;
1167*1da177e4SLinus Torvalds 
1168*1da177e4SLinus Torvalds 	if (copied > size) {
1169*1da177e4SLinus Torvalds 		copied = size;
1170*1da177e4SLinus Torvalds 		msg->msg_flags |= MSG_TRUNC;
1171*1da177e4SLinus Torvalds 	}
1172*1da177e4SLinus Torvalds 
1173*1da177e4SLinus Torvalds 	/* Currently, each datagram always contains a complete record */
1174*1da177e4SLinus Torvalds 	msg->msg_flags |= MSG_EOR;
1175*1da177e4SLinus Torvalds 
1176*1da177e4SLinus Torvalds 	rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
1177*1da177e4SLinus Torvalds 	if (rc)
1178*1da177e4SLinus Torvalds 		goto out_free_dgram;
1179*1da177e4SLinus Torvalds 
1180*1da177e4SLinus Torvalds 	if (sx25) {
1181*1da177e4SLinus Torvalds 		sx25->sx25_family = AF_X25;
1182*1da177e4SLinus Torvalds 		sx25->sx25_addr   = x25->dest_addr;
1183*1da177e4SLinus Torvalds 	}
1184*1da177e4SLinus Torvalds 
1185*1da177e4SLinus Torvalds 	msg->msg_namelen = sizeof(struct sockaddr_x25);
1186*1da177e4SLinus Torvalds 
1187*1da177e4SLinus Torvalds 	lock_sock(sk);
1188*1da177e4SLinus Torvalds 	x25_check_rbuf(sk);
1189*1da177e4SLinus Torvalds 	release_sock(sk);
1190*1da177e4SLinus Torvalds 	rc = copied;
1191*1da177e4SLinus Torvalds out_free_dgram:
1192*1da177e4SLinus Torvalds 	skb_free_datagram(sk, skb);
1193*1da177e4SLinus Torvalds out:
1194*1da177e4SLinus Torvalds 	return rc;
1195*1da177e4SLinus Torvalds }
1196*1da177e4SLinus Torvalds 
1197*1da177e4SLinus Torvalds 
1198*1da177e4SLinus Torvalds static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1199*1da177e4SLinus Torvalds {
1200*1da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
1201*1da177e4SLinus Torvalds 	struct x25_sock *x25 = x25_sk(sk);
1202*1da177e4SLinus Torvalds 	void __user *argp = (void __user *)arg;
1203*1da177e4SLinus Torvalds 	int rc;
1204*1da177e4SLinus Torvalds 
1205*1da177e4SLinus Torvalds 	switch (cmd) {
1206*1da177e4SLinus Torvalds 		case TIOCOUTQ: {
1207*1da177e4SLinus Torvalds 			int amount = sk->sk_sndbuf -
1208*1da177e4SLinus Torvalds 				     atomic_read(&sk->sk_wmem_alloc);
1209*1da177e4SLinus Torvalds 			if (amount < 0)
1210*1da177e4SLinus Torvalds 				amount = 0;
1211*1da177e4SLinus Torvalds 			rc = put_user(amount, (unsigned int __user *)argp);
1212*1da177e4SLinus Torvalds 			break;
1213*1da177e4SLinus Torvalds 		}
1214*1da177e4SLinus Torvalds 
1215*1da177e4SLinus Torvalds 		case TIOCINQ: {
1216*1da177e4SLinus Torvalds 			struct sk_buff *skb;
1217*1da177e4SLinus Torvalds 			int amount = 0;
1218*1da177e4SLinus Torvalds 			/*
1219*1da177e4SLinus Torvalds 			 * These two are safe on a single CPU system as
1220*1da177e4SLinus Torvalds 			 * only user tasks fiddle here
1221*1da177e4SLinus Torvalds 			 */
1222*1da177e4SLinus Torvalds 			if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
1223*1da177e4SLinus Torvalds 				amount = skb->len;
1224*1da177e4SLinus Torvalds 			rc = put_user(amount, (unsigned int __user *)argp);
1225*1da177e4SLinus Torvalds 			break;
1226*1da177e4SLinus Torvalds 		}
1227*1da177e4SLinus Torvalds 
1228*1da177e4SLinus Torvalds 		case SIOCGSTAMP:
1229*1da177e4SLinus Torvalds 			rc = -EINVAL;
1230*1da177e4SLinus Torvalds 			if (sk)
1231*1da177e4SLinus Torvalds 				rc = sock_get_timestamp(sk,
1232*1da177e4SLinus Torvalds 						(struct timeval __user *)argp);
1233*1da177e4SLinus Torvalds 			break;
1234*1da177e4SLinus Torvalds 		case SIOCGIFADDR:
1235*1da177e4SLinus Torvalds 		case SIOCSIFADDR:
1236*1da177e4SLinus Torvalds 		case SIOCGIFDSTADDR:
1237*1da177e4SLinus Torvalds 		case SIOCSIFDSTADDR:
1238*1da177e4SLinus Torvalds 		case SIOCGIFBRDADDR:
1239*1da177e4SLinus Torvalds 		case SIOCSIFBRDADDR:
1240*1da177e4SLinus Torvalds 		case SIOCGIFNETMASK:
1241*1da177e4SLinus Torvalds 		case SIOCSIFNETMASK:
1242*1da177e4SLinus Torvalds 		case SIOCGIFMETRIC:
1243*1da177e4SLinus Torvalds 		case SIOCSIFMETRIC:
1244*1da177e4SLinus Torvalds 			rc = -EINVAL;
1245*1da177e4SLinus Torvalds 			break;
1246*1da177e4SLinus Torvalds 		case SIOCADDRT:
1247*1da177e4SLinus Torvalds 		case SIOCDELRT:
1248*1da177e4SLinus Torvalds 			rc = -EPERM;
1249*1da177e4SLinus Torvalds 			if (!capable(CAP_NET_ADMIN))
1250*1da177e4SLinus Torvalds 				break;
1251*1da177e4SLinus Torvalds 			rc = x25_route_ioctl(cmd, argp);
1252*1da177e4SLinus Torvalds 			break;
1253*1da177e4SLinus Torvalds 		case SIOCX25GSUBSCRIP:
1254*1da177e4SLinus Torvalds 			rc = x25_subscr_ioctl(cmd, argp);
1255*1da177e4SLinus Torvalds 			break;
1256*1da177e4SLinus Torvalds 		case SIOCX25SSUBSCRIP:
1257*1da177e4SLinus Torvalds 			rc = -EPERM;
1258*1da177e4SLinus Torvalds 			if (!capable(CAP_NET_ADMIN))
1259*1da177e4SLinus Torvalds 				break;
1260*1da177e4SLinus Torvalds 			rc = x25_subscr_ioctl(cmd, argp);
1261*1da177e4SLinus Torvalds 			break;
1262*1da177e4SLinus Torvalds 		case SIOCX25GFACILITIES: {
1263*1da177e4SLinus Torvalds 			struct x25_facilities fac = x25->facilities;
1264*1da177e4SLinus Torvalds 			rc = copy_to_user(argp, &fac,
1265*1da177e4SLinus Torvalds 					  sizeof(fac)) ? -EFAULT : 0;
1266*1da177e4SLinus Torvalds 			break;
1267*1da177e4SLinus Torvalds 		}
1268*1da177e4SLinus Torvalds 
1269*1da177e4SLinus Torvalds 		case SIOCX25SFACILITIES: {
1270*1da177e4SLinus Torvalds 			struct x25_facilities facilities;
1271*1da177e4SLinus Torvalds 			rc = -EFAULT;
1272*1da177e4SLinus Torvalds 			if (copy_from_user(&facilities, argp,
1273*1da177e4SLinus Torvalds 					   sizeof(facilities)))
1274*1da177e4SLinus Torvalds 				break;
1275*1da177e4SLinus Torvalds 			rc = -EINVAL;
1276*1da177e4SLinus Torvalds 			if (sk->sk_state != TCP_LISTEN &&
1277*1da177e4SLinus Torvalds 			    sk->sk_state != TCP_CLOSE)
1278*1da177e4SLinus Torvalds 				break;
1279*1da177e4SLinus Torvalds 			if (facilities.pacsize_in < X25_PS16 ||
1280*1da177e4SLinus Torvalds 			    facilities.pacsize_in > X25_PS4096)
1281*1da177e4SLinus Torvalds 				break;
1282*1da177e4SLinus Torvalds 			if (facilities.pacsize_out < X25_PS16 ||
1283*1da177e4SLinus Torvalds 			    facilities.pacsize_out > X25_PS4096)
1284*1da177e4SLinus Torvalds 				break;
1285*1da177e4SLinus Torvalds 			if (facilities.winsize_in < 1 ||
1286*1da177e4SLinus Torvalds 			    facilities.winsize_in > 127)
1287*1da177e4SLinus Torvalds 				break;
1288*1da177e4SLinus Torvalds 			if (facilities.throughput < 0x03 ||
1289*1da177e4SLinus Torvalds 			    facilities.throughput > 0xDD)
1290*1da177e4SLinus Torvalds 				break;
1291*1da177e4SLinus Torvalds 			if (facilities.reverse && facilities.reverse != 1)
1292*1da177e4SLinus Torvalds 				break;
1293*1da177e4SLinus Torvalds 			x25->facilities = facilities;
1294*1da177e4SLinus Torvalds 			rc = 0;
1295*1da177e4SLinus Torvalds 			break;
1296*1da177e4SLinus Torvalds 		}
1297*1da177e4SLinus Torvalds 
1298*1da177e4SLinus Torvalds 		case SIOCX25GCALLUSERDATA: {
1299*1da177e4SLinus Torvalds 			struct x25_calluserdata cud = x25->calluserdata;
1300*1da177e4SLinus Torvalds 			rc = copy_to_user(argp, &cud,
1301*1da177e4SLinus Torvalds 					  sizeof(cud)) ? -EFAULT : 0;
1302*1da177e4SLinus Torvalds 			break;
1303*1da177e4SLinus Torvalds 		}
1304*1da177e4SLinus Torvalds 
1305*1da177e4SLinus Torvalds 		case SIOCX25SCALLUSERDATA: {
1306*1da177e4SLinus Torvalds 			struct x25_calluserdata calluserdata;
1307*1da177e4SLinus Torvalds 
1308*1da177e4SLinus Torvalds 			rc = -EFAULT;
1309*1da177e4SLinus Torvalds 			if (copy_from_user(&calluserdata, argp,
1310*1da177e4SLinus Torvalds 					   sizeof(calluserdata)))
1311*1da177e4SLinus Torvalds 				break;
1312*1da177e4SLinus Torvalds 			rc = -EINVAL;
1313*1da177e4SLinus Torvalds 			if (calluserdata.cudlength > X25_MAX_CUD_LEN)
1314*1da177e4SLinus Torvalds 				break;
1315*1da177e4SLinus Torvalds 			x25->calluserdata = calluserdata;
1316*1da177e4SLinus Torvalds 			rc = 0;
1317*1da177e4SLinus Torvalds 			break;
1318*1da177e4SLinus Torvalds 		}
1319*1da177e4SLinus Torvalds 
1320*1da177e4SLinus Torvalds 		case SIOCX25GCAUSEDIAG: {
1321*1da177e4SLinus Torvalds 			struct x25_causediag causediag;
1322*1da177e4SLinus Torvalds 			causediag = x25->causediag;
1323*1da177e4SLinus Torvalds 			rc = copy_to_user(argp, &causediag,
1324*1da177e4SLinus Torvalds 					  sizeof(causediag)) ? -EFAULT : 0;
1325*1da177e4SLinus Torvalds 			break;
1326*1da177e4SLinus Torvalds 		}
1327*1da177e4SLinus Torvalds 
1328*1da177e4SLinus Torvalds  		default:
1329*1da177e4SLinus Torvalds 			rc = dev_ioctl(cmd, argp);
1330*1da177e4SLinus Torvalds 			break;
1331*1da177e4SLinus Torvalds 	}
1332*1da177e4SLinus Torvalds 
1333*1da177e4SLinus Torvalds 	return rc;
1334*1da177e4SLinus Torvalds }
1335*1da177e4SLinus Torvalds 
1336*1da177e4SLinus Torvalds static struct net_proto_family x25_family_ops = {
1337*1da177e4SLinus Torvalds 	.family =	AF_X25,
1338*1da177e4SLinus Torvalds 	.create =	x25_create,
1339*1da177e4SLinus Torvalds 	.owner	=	THIS_MODULE,
1340*1da177e4SLinus Torvalds };
1341*1da177e4SLinus Torvalds 
1342*1da177e4SLinus Torvalds static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
1343*1da177e4SLinus Torvalds 	.family =	AF_X25,
1344*1da177e4SLinus Torvalds 	.owner =	THIS_MODULE,
1345*1da177e4SLinus Torvalds 	.release =	x25_release,
1346*1da177e4SLinus Torvalds 	.bind =		x25_bind,
1347*1da177e4SLinus Torvalds 	.connect =	x25_connect,
1348*1da177e4SLinus Torvalds 	.socketpair =	sock_no_socketpair,
1349*1da177e4SLinus Torvalds 	.accept =	x25_accept,
1350*1da177e4SLinus Torvalds 	.getname =	x25_getname,
1351*1da177e4SLinus Torvalds 	.poll =		datagram_poll,
1352*1da177e4SLinus Torvalds 	.ioctl =	x25_ioctl,
1353*1da177e4SLinus Torvalds 	.listen =	x25_listen,
1354*1da177e4SLinus Torvalds 	.shutdown =	sock_no_shutdown,
1355*1da177e4SLinus Torvalds 	.setsockopt =	x25_setsockopt,
1356*1da177e4SLinus Torvalds 	.getsockopt =	x25_getsockopt,
1357*1da177e4SLinus Torvalds 	.sendmsg =	x25_sendmsg,
1358*1da177e4SLinus Torvalds 	.recvmsg =	x25_recvmsg,
1359*1da177e4SLinus Torvalds 	.mmap =		sock_no_mmap,
1360*1da177e4SLinus Torvalds 	.sendpage =	sock_no_sendpage,
1361*1da177e4SLinus Torvalds };
1362*1da177e4SLinus Torvalds 
1363*1da177e4SLinus Torvalds #include <linux/smp_lock.h>
1364*1da177e4SLinus Torvalds SOCKOPS_WRAP(x25_proto, AF_X25);
1365*1da177e4SLinus Torvalds 
1366*1da177e4SLinus Torvalds static struct packet_type x25_packet_type = {
1367*1da177e4SLinus Torvalds 	.type =	__constant_htons(ETH_P_X25),
1368*1da177e4SLinus Torvalds 	.func =	x25_lapb_receive_frame,
1369*1da177e4SLinus Torvalds };
1370*1da177e4SLinus Torvalds 
1371*1da177e4SLinus Torvalds static struct notifier_block x25_dev_notifier = {
1372*1da177e4SLinus Torvalds 	.notifier_call = x25_device_event,
1373*1da177e4SLinus Torvalds };
1374*1da177e4SLinus Torvalds 
1375*1da177e4SLinus Torvalds void x25_kill_by_neigh(struct x25_neigh *nb)
1376*1da177e4SLinus Torvalds {
1377*1da177e4SLinus Torvalds 	struct sock *s;
1378*1da177e4SLinus Torvalds 	struct hlist_node *node;
1379*1da177e4SLinus Torvalds 
1380*1da177e4SLinus Torvalds 	write_lock_bh(&x25_list_lock);
1381*1da177e4SLinus Torvalds 
1382*1da177e4SLinus Torvalds 	sk_for_each(s, node, &x25_list)
1383*1da177e4SLinus Torvalds 		if (x25_sk(s)->neighbour == nb)
1384*1da177e4SLinus Torvalds 			x25_disconnect(s, ENETUNREACH, 0, 0);
1385*1da177e4SLinus Torvalds 
1386*1da177e4SLinus Torvalds 	write_unlock_bh(&x25_list_lock);
1387*1da177e4SLinus Torvalds }
1388*1da177e4SLinus Torvalds 
1389*1da177e4SLinus Torvalds static int __init x25_init(void)
1390*1da177e4SLinus Torvalds {
1391*1da177e4SLinus Torvalds 	int rc = proto_register(&x25_proto, 0);
1392*1da177e4SLinus Torvalds 
1393*1da177e4SLinus Torvalds 	if (rc != 0)
1394*1da177e4SLinus Torvalds 		goto out;
1395*1da177e4SLinus Torvalds 
1396*1da177e4SLinus Torvalds 	sock_register(&x25_family_ops);
1397*1da177e4SLinus Torvalds 
1398*1da177e4SLinus Torvalds 	dev_add_pack(&x25_packet_type);
1399*1da177e4SLinus Torvalds 
1400*1da177e4SLinus Torvalds 	register_netdevice_notifier(&x25_dev_notifier);
1401*1da177e4SLinus Torvalds 
1402*1da177e4SLinus Torvalds 	printk(KERN_INFO "X.25 for Linux. Version 0.2 for Linux 2.1.15\n");
1403*1da177e4SLinus Torvalds 
1404*1da177e4SLinus Torvalds #ifdef CONFIG_SYSCTL
1405*1da177e4SLinus Torvalds 	x25_register_sysctl();
1406*1da177e4SLinus Torvalds #endif
1407*1da177e4SLinus Torvalds 	x25_proc_init();
1408*1da177e4SLinus Torvalds out:
1409*1da177e4SLinus Torvalds 	return rc;
1410*1da177e4SLinus Torvalds }
1411*1da177e4SLinus Torvalds module_init(x25_init);
1412*1da177e4SLinus Torvalds 
1413*1da177e4SLinus Torvalds static void __exit x25_exit(void)
1414*1da177e4SLinus Torvalds {
1415*1da177e4SLinus Torvalds 	x25_proc_exit();
1416*1da177e4SLinus Torvalds 	x25_link_free();
1417*1da177e4SLinus Torvalds 	x25_route_free();
1418*1da177e4SLinus Torvalds 
1419*1da177e4SLinus Torvalds #ifdef CONFIG_SYSCTL
1420*1da177e4SLinus Torvalds 	x25_unregister_sysctl();
1421*1da177e4SLinus Torvalds #endif
1422*1da177e4SLinus Torvalds 
1423*1da177e4SLinus Torvalds 	unregister_netdevice_notifier(&x25_dev_notifier);
1424*1da177e4SLinus Torvalds 
1425*1da177e4SLinus Torvalds 	dev_remove_pack(&x25_packet_type);
1426*1da177e4SLinus Torvalds 
1427*1da177e4SLinus Torvalds 	sock_unregister(AF_X25);
1428*1da177e4SLinus Torvalds 	proto_unregister(&x25_proto);
1429*1da177e4SLinus Torvalds }
1430*1da177e4SLinus Torvalds module_exit(x25_exit);
1431*1da177e4SLinus Torvalds 
1432*1da177e4SLinus Torvalds MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
1433*1da177e4SLinus Torvalds MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol");
1434*1da177e4SLinus Torvalds MODULE_LICENSE("GPL");
1435*1da177e4SLinus Torvalds MODULE_ALIAS_NETPROTO(PF_X25);
1436