af_llc.c revision 774ccb4f64020dad40d38efa63685220e1f245cc
1/*
2 * af_llc.c - LLC User Interface SAPs
3 * Description:
4 *   Functions in this module are implementation of socket based llc
5 *   communications for the Linux operating system. Support of llc class
6 *   one and class two is provided via SOCK_DGRAM and SOCK_STREAM
7 *   respectively.
8 *
9 *   An llc2 connection is (mac + sap), only one llc2 sap connection
10 *   is allowed per mac. Though one sap may have multiple mac + sap
11 *   connections.
12 *
13 * Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
14 *		 2002-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
15 *
16 * This program can be redistributed or modified under the terms of the
17 * GNU General Public License as published by the Free Software Foundation.
18 * This program is distributed without any warranty or implied warranty
19 * of merchantability or fitness for a particular purpose.
20 *
21 * See the GNU General Public License for more details.
22 */
23#include <linux/config.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/rtnetlink.h>
27#include <linux/init.h>
28#include <net/llc.h>
29#include <net/llc_sap.h>
30#include <net/llc_pdu.h>
31#include <net/llc_conn.h>
32#include <net/tcp_states.h>
33
34/* remember: uninitialized global data is zeroed because its in .bss */
35static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
36static u16 llc_ui_sap_link_no_max[256];
37static struct sockaddr_llc llc_ui_addrnull;
38static struct proto_ops llc_ui_ops;
39
40static int llc_ui_wait_for_conn(struct sock *sk, int timeout);
41static int llc_ui_wait_for_disc(struct sock *sk, int timeout);
42static int llc_ui_wait_for_data(struct sock *sk, int timeout);
43static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout);
44
45#if 0
46#define dprintk(args...) printk(KERN_DEBUG args)
47#else
48#define dprintk(args...)
49#endif
50
51/**
52 *	llc_ui_next_link_no - return the next unused link number for a sap
53 *	@sap: Address of sap to get link number from.
54 *
55 *	Return the next unused link number for a given sap.
56 */
57static __inline__ u16 llc_ui_next_link_no(int sap)
58{
59	return llc_ui_sap_link_no_max[sap]++;
60}
61
62/**
63 *	llc_proto_type - return eth protocol for ARP header type
64 *	@arphrd: ARP header type.
65 *
66 *	Given an ARP header type return the corresponding ethernet protocol.
67 */
68static __inline__ u16 llc_proto_type(u16 arphrd)
69{
70	return arphrd == ARPHRD_IEEE802_TR ?
71		         htons(ETH_P_TR_802_2) : htons(ETH_P_802_2);
72}
73
74/**
75 *	llc_ui_addr_null - determines if a address structure is null
76 *	@addr: Address to test if null.
77 */
78static __inline__ u8 llc_ui_addr_null(struct sockaddr_llc *addr)
79{
80	return !memcmp(addr, &llc_ui_addrnull, sizeof(*addr));
81}
82
83/**
84 *	llc_ui_header_len - return length of llc header based on operation
85 *	@sk: Socket which contains a valid llc socket type.
86 *	@addr: Complete sockaddr_llc structure received from the user.
87 *
88 *	Provide the length of the llc header depending on what kind of
89 *	operation the user would like to perform and the type of socket.
90 *	Returns the correct llc header length.
91 */
92static __inline__ u8 llc_ui_header_len(struct sock *sk,
93				       struct sockaddr_llc *addr)
94{
95	u8 rc = LLC_PDU_LEN_U;
96
97	if (addr->sllc_test || addr->sllc_xid)
98		rc = LLC_PDU_LEN_U;
99	else if (sk->sk_type == SOCK_STREAM)
100		rc = LLC_PDU_LEN_I;
101	return rc;
102}
103
104/**
105 *	llc_ui_send_data - send data via reliable llc2 connection
106 *	@sk: Connection the socket is using.
107 *	@skb: Data the user wishes to send.
108 *	@addr: Source and destination fields provided by the user.
109 *	@noblock: can we block waiting for data?
110 *
111 *	Send data via reliable llc2 connection.
112 *	Returns 0 upon success, non-zero if action did not succeed.
113 */
114static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, int noblock)
115{
116	struct llc_sock* llc = llc_sk(sk);
117	int rc = 0;
118
119	if (llc_data_accept_state(llc->state) || llc->p_flag) {
120		int timeout = sock_sndtimeo(sk, noblock);
121
122		rc = llc_ui_wait_for_busy_core(sk, timeout);
123	}
124	if (!rc)
125		rc = llc_build_and_send_pkt(sk, skb);
126	return rc;
127}
128
129static void llc_ui_sk_init(struct socket *sock, struct sock *sk)
130{
131	sk->sk_type	= sock->type;
132	sk->sk_sleep	= &sock->wait;
133	sk->sk_socket	= sock;
134	sock->sk	= sk;
135	sock->ops	= &llc_ui_ops;
136}
137
138static struct proto llc_proto = {
139	.name	  = "DDP",
140	.owner	  = THIS_MODULE,
141	.obj_size = sizeof(struct llc_sock),
142};
143
144/**
145 *	llc_ui_create - alloc and init a new llc_ui socket
146 *	@sock: Socket to initialize and attach allocated sk to.
147 *	@protocol: Unused.
148 *
149 *	Allocate and initialize a new llc_ui socket, validate the user wants a
150 *	socket type we have available.
151 *	Returns 0 upon success, negative upon failure.
152 */
153static int llc_ui_create(struct socket *sock, int protocol)
154{
155	struct sock *sk;
156	int rc = -ESOCKTNOSUPPORT;
157
158	if (sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM) {
159		rc = -ENOMEM;
160		sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto);
161		if (sk) {
162			rc = 0;
163			llc_ui_sk_init(sock, sk);
164		}
165	}
166	return rc;
167}
168
169/**
170 *	llc_ui_release - shutdown socket
171 *	@sock: Socket to release.
172 *
173 *	Shutdown and deallocate an existing socket.
174 */
175static int llc_ui_release(struct socket *sock)
176{
177	struct sock *sk = sock->sk;
178	struct llc_sock *llc;
179
180	if (!sk)
181		goto out;
182	sock_hold(sk);
183	lock_sock(sk);
184	llc = llc_sk(sk);
185	dprintk("%s: closing local(%02X) remote(%02X)\n", __FUNCTION__,
186		llc->laddr.lsap, llc->daddr.lsap);
187	if (!llc_send_disc(sk))
188		llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo);
189	if (!sock_flag(sk, SOCK_ZAPPED))
190		llc_sap_remove_socket(llc->sap, sk);
191	release_sock(sk);
192	if (llc->sap && hlist_empty(&llc->sap->sk_list.list)) {
193		llc_release_sockets(llc->sap);
194		llc_sap_close(llc->sap);
195	}
196	if (llc->dev)
197		dev_put(llc->dev);
198	sock_put(sk);
199	llc_sk_free(sk);
200out:
201	return 0;
202}
203
204/**
205 *	llc_ui_autoport - provide dynamically allocate SAP number
206 *
207 *	Provide the caller with a dynamically allocated SAP number according
208 *	to the rules that are set in this function. Returns: 0, upon failure,
209 *	SAP number otherwise.
210 */
211static int llc_ui_autoport(void)
212{
213	struct llc_sap *sap;
214	int i, tries = 0;
215
216	while (tries < LLC_SAP_DYN_TRIES) {
217		for (i = llc_ui_sap_last_autoport;
218		     i < LLC_SAP_DYN_STOP; i += 2) {
219			sap = llc_sap_find(i);
220			if (!sap) {
221				llc_ui_sap_last_autoport = i + 2;
222				goto out;
223			}
224		}
225		llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
226		tries++;
227	}
228	i = 0;
229out:
230	return i;
231}
232
233/**
234 *	llc_ui_autobind - Bind a socket to a specific address.
235 *	@sk: Socket to bind an address to.
236 *	@addr: Address the user wants the socket bound to.
237 *
238 *	Bind a socket to a specific address. For llc a user is able to bind to
239 *	a specific sap only or mac + sap. If the user only specifies a sap and
240 *	a null dmac (all zeros) the user is attempting to bind to an entire
241 *	sap. This will stop anyone else on the local system from using that
242 *	sap.  If someone else has a mac + sap open the bind to null + sap will
243 *	fail.
244 *	If the user desires to bind to a specific mac + sap, it is possible to
245 *	have multiple sap connections via multiple macs.
246 *	Bind and autobind for that matter must enforce the correct sap usage
247 *	otherwise all hell will break loose.
248 *	Returns: 0 upon success, negative otherwise.
249 */
250static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
251{
252	struct sock *sk = sock->sk;
253	struct llc_sock *llc = llc_sk(sk);
254	struct llc_sap *sap;
255	int rc = -EINVAL;
256
257	if (!sock_flag(sk, SOCK_ZAPPED))
258		goto out;
259	rc = -ENODEV;
260	llc->dev = dev_getfirstbyhwtype(addr->sllc_arphrd);
261	if (!llc->dev)
262		goto out;
263	rc = -EUSERS;
264	llc->laddr.lsap = llc_ui_autoport();
265	if (!llc->laddr.lsap)
266		goto out;
267	rc = -EBUSY; /* some other network layer is using the sap */
268	sap = llc_sap_open(llc->laddr.lsap, NULL);
269	if (!sap)
270		goto out;
271	memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN);
272	memcpy(&llc->addr, addr, sizeof(llc->addr));
273	/* assign new connection to its SAP */
274	llc_sap_add_socket(sap, sk);
275	sock_reset_flag(sk, SOCK_ZAPPED);
276	rc = 0;
277out:
278	return rc;
279}
280
281/**
282 *	llc_ui_bind - bind a socket to a specific address.
283 *	@sock: Socket to bind an address to.
284 *	@uaddr: Address the user wants the socket bound to.
285 *	@addrlen: Length of the uaddr structure.
286 *
287 *	Bind a socket to a specific address. For llc a user is able to bind to
288 *	a specific sap only or mac + sap. If the user only specifies a sap and
289 *	a null dmac (all zeros) the user is attempting to bind to an entire
290 *	sap. This will stop anyone else on the local system from using that
291 *	sap. If someone else has a mac + sap open the bind to null + sap will
292 *	fail.
293 *	If the user desires to bind to a specific mac + sap, it is possible to
294 *	have multiple sap connections via multiple macs.
295 *	Bind and autobind for that matter must enforce the correct sap usage
296 *	otherwise all hell will break loose.
297 *	Returns: 0 upon success, negative otherwise.
298 */
299static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
300{
301	struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
302	struct sock *sk = sock->sk;
303	struct llc_sock *llc = llc_sk(sk);
304	struct llc_sap *sap;
305	int rc = -EINVAL;
306
307	dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_sap);
308	if (!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr))
309		goto out;
310	rc = -EAFNOSUPPORT;
311	if (addr->sllc_family != AF_LLC)
312		goto out;
313	if (!addr->sllc_sap) {
314		rc = -EUSERS;
315		addr->sllc_sap = llc_ui_autoport();
316		if (!addr->sllc_sap)
317			goto out;
318	}
319	sap = llc_sap_find(addr->sllc_sap);
320	if (!sap) {
321		sap = llc_sap_open(addr->sllc_sap, NULL);
322		rc = -EBUSY; /* some other network layer is using the sap */
323		if (!sap)
324			goto out;
325	} else {
326		struct llc_addr laddr, daddr;
327		struct sock *ask;
328
329		memset(&laddr, 0, sizeof(laddr));
330		memset(&daddr, 0, sizeof(daddr));
331		/*
332		 * FIXME: check if the the address is multicast,
333		 * 	  only SOCK_DGRAM can do this.
334		 */
335		memcpy(laddr.mac, addr->sllc_mac, IFHWADDRLEN);
336		laddr.lsap = addr->sllc_sap;
337		rc = -EADDRINUSE; /* mac + sap clash. */
338		ask = llc_lookup_established(sap, &daddr, &laddr);
339		if (ask) {
340			sock_put(ask);
341			goto out;
342		}
343	}
344	llc->laddr.lsap = addr->sllc_sap;
345	memcpy(llc->laddr.mac, addr->sllc_mac, IFHWADDRLEN);
346	memcpy(&llc->addr, addr, sizeof(llc->addr));
347	/* assign new connection to its SAP */
348	llc_sap_add_socket(sap, sk);
349	sock_reset_flag(sk, SOCK_ZAPPED);
350	rc = 0;
351out:
352	return rc;
353}
354
355/**
356 *	llc_ui_shutdown - shutdown a connect llc2 socket.
357 *	@sock: Socket to shutdown.
358 *	@how: What part of the socket to shutdown.
359 *
360 *	Shutdown a connected llc2 socket. Currently this function only supports
361 *	shutting down both sends and receives (2), we could probably make this
362 *	function such that a user can shutdown only half the connection but not
363 *	right now.
364 *	Returns: 0 upon success, negative otherwise.
365 */
366static int llc_ui_shutdown(struct socket *sock, int how)
367{
368	struct sock *sk = sock->sk;
369	int rc = -ENOTCONN;
370
371	lock_sock(sk);
372	if (sk->sk_state != TCP_ESTABLISHED)
373		goto out;
374	rc = -EINVAL;
375	if (how != 2)
376		goto out;
377	rc = llc_send_disc(sk);
378	if (!rc)
379		rc = llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo);
380	/* Wake up anyone sleeping in poll */
381	sk->sk_state_change(sk);
382out:
383	release_sock(sk);
384	return rc;
385}
386
387/**
388 *	llc_ui_connect - Connect to a remote llc2 mac + sap.
389 *	@sock: Socket which will be connected to the remote destination.
390 *	@uaddr: Remote and possibly the local address of the new connection.
391 *	@addrlen: Size of uaddr structure.
392 *	@flags: Operational flags specified by the user.
393 *
394 *	Connect to a remote llc2 mac + sap. The caller must specify the
395 *	destination mac and address to connect to. If the user hasn't previously
396 *	called bind(2) with a smac the address of the first interface of the
397 *	specified arp type will be used.
398 *	This function will autobind if user did not previously call bind.
399 *	Returns: 0 upon success, negative otherwise.
400 */
401static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
402			  int addrlen, int flags)
403{
404	struct sock *sk = sock->sk;
405	struct llc_sock *llc = llc_sk(sk);
406	struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
407	int rc = -EINVAL;
408
409	lock_sock(sk);
410	if (addrlen != sizeof(*addr))
411		goto out;
412	rc = -EAFNOSUPPORT;
413	if (addr->sllc_family != AF_LLC)
414		goto out;
415	/* bind connection to sap if user hasn't done it. */
416	if (sock_flag(sk, SOCK_ZAPPED)) {
417		/* bind to sap with null dev, exclusive */
418		rc = llc_ui_autobind(sock, addr);
419		if (rc)
420			goto out;
421		llc->daddr.lsap = addr->sllc_sap;
422		memcpy(llc->daddr.mac, addr->sllc_mac, IFHWADDRLEN);
423	}
424	if (sk->sk_type != SOCK_STREAM)
425		goto out;
426	rc = -EALREADY;
427	if (sock->state == SS_CONNECTING)
428		goto out;
429	sock->state = SS_CONNECTING;
430	sk->sk_state   = TCP_SYN_SENT;
431	llc->link   = llc_ui_next_link_no(llc->sap->laddr.lsap);
432	rc = llc_establish_connection(sk, llc->dev->dev_addr,
433				      addr->sllc_mac, addr->sllc_sap);
434	if (rc) {
435		dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__);
436		sock->state  = SS_UNCONNECTED;
437		sk->sk_state = TCP_CLOSE;
438		goto out;
439	}
440	rc = llc_ui_wait_for_conn(sk, sk->sk_rcvtimeo);
441	if (rc)
442		dprintk("%s: llc_ui_wait_for_conn failed=%d\n", __FUNCTION__, rc);
443out:
444	release_sock(sk);
445	return rc;
446}
447
448/**
449 *	llc_ui_listen - allow a normal socket to accept incoming connections
450 *	@sock: Socket to allow incoming connections on.
451 *	@backlog: Number of connections to queue.
452 *
453 *	Allow a normal socket to accept incoming connections.
454 *	Returns 0 upon success, negative otherwise.
455 */
456static int llc_ui_listen(struct socket *sock, int backlog)
457{
458	struct sock *sk = sock->sk;
459	int rc = -EINVAL;
460
461	lock_sock(sk);
462	if (sock->state != SS_UNCONNECTED)
463		goto out;
464	rc = -EOPNOTSUPP;
465	if (sk->sk_type != SOCK_STREAM)
466		goto out;
467	rc = -EAGAIN;
468	if (sock_flag(sk, SOCK_ZAPPED))
469		goto out;
470	rc = 0;
471	if (!(unsigned)backlog)	/* BSDism */
472		backlog = 1;
473	sk->sk_max_ack_backlog = backlog;
474	if (sk->sk_state != TCP_LISTEN) {
475		sk->sk_ack_backlog = 0;
476		sk->sk_state	   = TCP_LISTEN;
477	}
478	sk->sk_socket->flags |= __SO_ACCEPTCON;
479out:
480	release_sock(sk);
481	return rc;
482}
483
484static int llc_ui_wait_for_disc(struct sock *sk, int timeout)
485{
486	DECLARE_WAITQUEUE(wait, current);
487	int rc;
488
489	add_wait_queue_exclusive(sk->sk_sleep, &wait);
490	for (;;) {
491		__set_current_state(TASK_INTERRUPTIBLE);
492		rc = 0;
493		if (sk->sk_state != TCP_CLOSE) {
494			release_sock(sk);
495			timeout = schedule_timeout(timeout);
496			lock_sock(sk);
497		} else
498			break;
499		rc = -ERESTARTSYS;
500		if (signal_pending(current))
501			break;
502		rc = -EAGAIN;
503		if (!timeout)
504			break;
505	}
506	__set_current_state(TASK_RUNNING);
507	remove_wait_queue(sk->sk_sleep, &wait);
508	return rc;
509}
510
511static int llc_ui_wait_for_conn(struct sock *sk, int timeout)
512{
513	DECLARE_WAITQUEUE(wait, current);
514	int rc;
515
516	add_wait_queue_exclusive(sk->sk_sleep, &wait);
517	for (;;) {
518		__set_current_state(TASK_INTERRUPTIBLE);
519		rc = -EAGAIN;
520		if (sk->sk_state == TCP_CLOSE)
521			break;
522		rc = 0;
523		if (sk->sk_state != TCP_ESTABLISHED) {
524			release_sock(sk);
525			timeout = schedule_timeout(timeout);
526			lock_sock(sk);
527		} else
528			break;
529		rc = -ERESTARTSYS;
530		if (signal_pending(current))
531			break;
532		rc = -EAGAIN;
533		if (!timeout)
534			break;
535	}
536	__set_current_state(TASK_RUNNING);
537	remove_wait_queue(sk->sk_sleep, &wait);
538	return rc;
539}
540
541static int llc_ui_wait_for_data(struct sock *sk, int timeout)
542{
543	DECLARE_WAITQUEUE(wait, current);
544	int rc = 0;
545
546	add_wait_queue_exclusive(sk->sk_sleep, &wait);
547	for (;;) {
548		__set_current_state(TASK_INTERRUPTIBLE);
549		if (sk->sk_shutdown & RCV_SHUTDOWN)
550			break;
551		/*
552		 * Well, if we have backlog, try to process it now.
553		 */
554                if (sk->sk_backlog.tail) {
555			release_sock(sk);
556			lock_sock(sk);
557		}
558		rc = 0;
559		if (skb_queue_empty(&sk->sk_receive_queue)) {
560			release_sock(sk);
561			timeout = schedule_timeout(timeout);
562			lock_sock(sk);
563		} else
564			break;
565		rc = -ERESTARTSYS;
566		if (signal_pending(current))
567			break;
568		rc = -EAGAIN;
569		if (!timeout)
570			break;
571	}
572	__set_current_state(TASK_RUNNING);
573	remove_wait_queue(sk->sk_sleep, &wait);
574	return rc;
575}
576
577static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout)
578{
579	DECLARE_WAITQUEUE(wait, current);
580	struct llc_sock *llc = llc_sk(sk);
581	int rc;
582
583	add_wait_queue_exclusive(sk->sk_sleep, &wait);
584	for (;;) {
585		dprintk("%s: looping...\n", __FUNCTION__);
586		__set_current_state(TASK_INTERRUPTIBLE);
587		rc = -ENOTCONN;
588		if (sk->sk_shutdown & RCV_SHUTDOWN)
589			break;
590		rc = 0;
591		if (llc_data_accept_state(llc->state) || llc->p_flag) {
592			release_sock(sk);
593			timeout = schedule_timeout(timeout);
594			lock_sock(sk);
595		} else
596			break;
597		rc = -ERESTARTSYS;
598		if (signal_pending(current))
599			break;
600		rc = -EAGAIN;
601		if (!timeout)
602			break;
603	}
604	__set_current_state(TASK_RUNNING);
605	remove_wait_queue(sk->sk_sleep, &wait);
606	return rc;
607}
608
609/**
610 *	llc_ui_accept - accept a new incoming connection.
611 *	@sock: Socket which connections arrive on.
612 *	@newsock: Socket to move incoming connection to.
613 *	@flags: User specified operational flags.
614 *
615 *	Accept a new incoming connection.
616 *	Returns 0 upon success, negative otherwise.
617 */
618static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
619{
620	struct sock *sk = sock->sk, *newsk;
621	struct llc_sock *llc, *newllc;
622	struct sk_buff *skb;
623	int rc = -EOPNOTSUPP;
624
625	dprintk("%s: accepting on %02X\n", __FUNCTION__,
626	        llc_sk(sk)->laddr.lsap);
627	lock_sock(sk);
628	if (sk->sk_type != SOCK_STREAM)
629		goto out;
630	rc = -EINVAL;
631	if (sock->state != SS_UNCONNECTED || sk->sk_state != TCP_LISTEN)
632		goto out;
633	/* wait for a connection to arrive. */
634	rc = llc_ui_wait_for_data(sk, sk->sk_rcvtimeo);
635	if (rc)
636		goto out;
637	dprintk("%s: got a new connection on %02X\n", __FUNCTION__,
638	        llc_sk(sk)->laddr.lsap);
639	skb = skb_dequeue(&sk->sk_receive_queue);
640	rc = -EINVAL;
641	if (!skb->sk)
642		goto frees;
643	rc = 0;
644	newsk = skb->sk;
645	/* attach connection to a new socket. */
646	llc_ui_sk_init(newsock, newsk);
647	sock_reset_flag(newsk, SOCK_ZAPPED);
648	newsk->sk_state		= TCP_ESTABLISHED;
649	newsock->state		= SS_CONNECTED;
650	llc			= llc_sk(sk);
651	newllc			= llc_sk(newsk);
652	memcpy(&newllc->addr, &llc->addr, sizeof(newllc->addr));
653	newllc->link = llc_ui_next_link_no(newllc->laddr.lsap);
654
655	/* put original socket back into a clean listen state. */
656	sk->sk_state = TCP_LISTEN;
657	sk->sk_ack_backlog--;
658	skb->sk = NULL;
659	dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__,
660		llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap);
661frees:
662	kfree_skb(skb);
663out:
664	release_sock(sk);
665	return rc;
666}
667
668/**
669 *	llc_ui_recvmsg - copy received data to the socket user.
670 *	@sock: Socket to copy data from.
671 *	@msg: Various user space related information.
672 *	@size: Size of user buffer.
673 *	@flags: User specified flags.
674 *
675 *	Copy received data to the socket user.
676 *	Returns non-negative upon success, negative otherwise.
677 */
678static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
679			  struct msghdr *msg, size_t size, int flags)
680{
681	struct sock *sk = sock->sk;
682	struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name;
683	struct sk_buff *skb;
684	size_t copied = 0;
685	int rc = -ENOMEM, timeout;
686	int noblock = flags & MSG_DONTWAIT;
687
688	dprintk("%s: receiving in %02X from %02X\n", __FUNCTION__,
689		llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
690	lock_sock(sk);
691	timeout = sock_rcvtimeo(sk, noblock);
692	rc = llc_ui_wait_for_data(sk, timeout);
693	if (rc) {
694		dprintk("%s: llc_ui_wait_for_data failed recv "
695			"in %02X from %02X\n", __FUNCTION__,
696			llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
697		goto out;
698	}
699	skb = skb_dequeue(&sk->sk_receive_queue);
700	if (!skb) /* shutdown */
701		goto out;
702	copied = skb->len;
703	if (copied > size)
704		copied = size;
705	rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
706	if (rc)
707		goto dgram_free;
708	if (skb->len > copied) {
709		skb_pull(skb, copied);
710		skb_queue_head(&sk->sk_receive_queue, skb);
711	}
712	if (uaddr)
713		memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));
714	msg->msg_namelen = sizeof(*uaddr);
715	if (!skb->next) {
716dgram_free:
717		kfree_skb(skb);
718	}
719out:
720	release_sock(sk);
721	return rc ? : copied;
722}
723
724/**
725 *	llc_ui_sendmsg - Transmit data provided by the socket user.
726 *	@sock: Socket to transmit data from.
727 *	@msg: Various user related information.
728 *	@len: Length of data to transmit.
729 *
730 *	Transmit data provided by the socket user.
731 *	Returns non-negative upon success, negative otherwise.
732 */
733static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
734			  struct msghdr *msg, size_t len)
735{
736	struct sock *sk = sock->sk;
737	struct llc_sock *llc = llc_sk(sk);
738	struct sockaddr_llc *addr = (struct sockaddr_llc *)msg->msg_name;
739	int flags = msg->msg_flags;
740	int noblock = flags & MSG_DONTWAIT;
741	struct sk_buff *skb;
742	size_t size = 0;
743	int rc = -EINVAL, copied = 0, hdrlen;
744
745	dprintk("%s: sending from %02X to %02X\n", __FUNCTION__,
746		llc->laddr.lsap, llc->daddr.lsap);
747	lock_sock(sk);
748	if (addr) {
749		if (msg->msg_namelen < sizeof(*addr))
750			goto release;
751	} else {
752		if (llc_ui_addr_null(&llc->addr))
753			goto release;
754		addr = &llc->addr;
755	}
756	/* must bind connection to sap if user hasn't done it. */
757	if (sock_flag(sk, SOCK_ZAPPED)) {
758		/* bind to sap with null dev, exclusive. */
759		rc = llc_ui_autobind(sock, addr);
760		if (rc)
761			goto release;
762	}
763	hdrlen = llc->dev->hard_header_len + llc_ui_header_len(sk, addr);
764	size = hdrlen + len;
765	if (size > llc->dev->mtu)
766		size = llc->dev->mtu;
767	copied = size - hdrlen;
768	release_sock(sk);
769	skb = sock_alloc_send_skb(sk, size, noblock, &rc);
770	lock_sock(sk);
771	if (!skb)
772		goto release;
773	skb->sk	      = sk;
774	skb->dev      = llc->dev;
775	skb->protocol = llc_proto_type(addr->sllc_arphrd);
776	skb_reserve(skb, hdrlen);
777	rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied);
778	if (rc)
779		goto out;
780	if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) {
781		llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_mac,
782					  addr->sllc_sap);
783		goto out;
784	}
785	if (addr->sllc_test) {
786		llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_mac,
787					    addr->sllc_sap);
788		goto out;
789	}
790	if (addr->sllc_xid) {
791		llc_build_and_send_xid_pkt(llc->sap, skb, addr->sllc_mac,
792					   addr->sllc_sap);
793		goto out;
794	}
795	rc = -ENOPROTOOPT;
796	if (!(sk->sk_type == SOCK_STREAM && !addr->sllc_ua))
797		goto out;
798	rc = llc_ui_send_data(sk, skb, noblock);
799	if (rc)
800		dprintk("%s: llc_ui_send_data failed: %d\n", __FUNCTION__, rc);
801out:
802	if (rc)
803		kfree_skb(skb);
804release:
805	if (rc)
806		dprintk("%s: failed sending from %02X to %02X: %d\n",
807			__FUNCTION__, llc->laddr.lsap, llc->daddr.lsap, rc);
808	release_sock(sk);
809	return rc ? : copied;
810}
811
812/**
813 *	llc_ui_getname - return the address info of a socket
814 *	@sock: Socket to get address of.
815 *	@uaddr: Address structure to return information.
816 *	@uaddrlen: Length of address structure.
817 *	@peer: Does user want local or remote address information.
818 *
819 *	Return the address information of a socket.
820 */
821static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
822			  int *uaddrlen, int peer)
823{
824	struct sockaddr_llc sllc;
825	struct sock *sk = sock->sk;
826	struct llc_sock *llc = llc_sk(sk);
827	int rc = 0;
828
829	lock_sock(sk);
830	if (sock_flag(sk, SOCK_ZAPPED))
831		goto out;
832	*uaddrlen = sizeof(sllc);
833	memset(uaddr, 0, *uaddrlen);
834	if (peer) {
835		rc = -ENOTCONN;
836		if (sk->sk_state != TCP_ESTABLISHED)
837			goto out;
838		if(llc->dev)
839			sllc.sllc_arphrd = llc->dev->type;
840		sllc.sllc_sap = llc->daddr.lsap;
841		memcpy(&sllc.sllc_mac, &llc->daddr.mac, IFHWADDRLEN);
842	} else {
843		rc = -EINVAL;
844		if (!llc->sap)
845			goto out;
846		sllc.sllc_sap = llc->sap->laddr.lsap;
847
848		if (llc->dev) {
849			sllc.sllc_arphrd = llc->dev->type;
850			memcpy(&sllc.sllc_mac, &llc->dev->dev_addr,
851			       IFHWADDRLEN);
852		}
853	}
854	rc = 0;
855	sllc.sllc_family = AF_LLC;
856	memcpy(uaddr, &sllc, sizeof(sllc));
857out:
858	release_sock(sk);
859	return rc;
860}
861
862/**
863 *	llc_ui_ioctl - io controls for PF_LLC
864 *	@sock: Socket to get/set info
865 *	@cmd: command
866 *	@arg: optional argument for cmd
867 *
868 *	get/set info on llc sockets
869 */
870static int llc_ui_ioctl(struct socket *sock, unsigned int cmd,
871			unsigned long arg)
872{
873	return dev_ioctl(cmd, (void __user *)arg);
874}
875
876/**
877 *	llc_ui_setsockopt - set various connection specific parameters.
878 *	@sock: Socket to set options on.
879 *	@level: Socket level user is requesting operations on.
880 *	@optname: Operation name.
881 *	@optval User provided operation data.
882 *	@optlen: Length of optval.
883 *
884 *	Set various connection specific parameters.
885 */
886static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
887			     char __user *optval, int optlen)
888{
889	struct sock *sk = sock->sk;
890	struct llc_sock *llc = llc_sk(sk);
891	int rc = -EINVAL, opt;
892
893	lock_sock(sk);
894	if (level != SOL_LLC || optlen != sizeof(int))
895		goto out;
896	rc = get_user(opt, (int __user *)optval);
897	if (rc)
898		goto out;
899	rc = -EINVAL;
900	switch (optname) {
901	case LLC_OPT_RETRY:
902		if (opt > LLC_OPT_MAX_RETRY)
903			goto out;
904		llc->n2 = opt;
905		break;
906	case LLC_OPT_SIZE:
907		if (opt > LLC_OPT_MAX_SIZE)
908			goto out;
909		llc->n1 = opt;
910		break;
911	case LLC_OPT_ACK_TMR_EXP:
912		if (opt > LLC_OPT_MAX_ACK_TMR_EXP)
913			goto out;
914		llc->ack_timer.expire = opt;
915		break;
916	case LLC_OPT_P_TMR_EXP:
917		if (opt > LLC_OPT_MAX_P_TMR_EXP)
918			goto out;
919		llc->pf_cycle_timer.expire = opt;
920		break;
921	case LLC_OPT_REJ_TMR_EXP:
922		if (opt > LLC_OPT_MAX_REJ_TMR_EXP)
923			goto out;
924		llc->rej_sent_timer.expire = opt;
925		break;
926	case LLC_OPT_BUSY_TMR_EXP:
927		if (opt > LLC_OPT_MAX_BUSY_TMR_EXP)
928			goto out;
929		llc->busy_state_timer.expire = opt;
930		break;
931	case LLC_OPT_TX_WIN:
932		if (opt > LLC_OPT_MAX_WIN)
933			goto out;
934		llc->k = opt;
935		break;
936	case LLC_OPT_RX_WIN:
937		if (opt > LLC_OPT_MAX_WIN)
938			goto out;
939		llc->rw = opt;
940		break;
941	default:
942		rc = -ENOPROTOOPT;
943		goto out;
944	}
945	rc = 0;
946out:
947	release_sock(sk);
948	return rc;
949}
950
951/**
952 *	llc_ui_getsockopt - get connection specific socket info
953 *	@sock: Socket to get information from.
954 *	@level: Socket level user is requesting operations on.
955 *	@optname: Operation name.
956 *	@optval: Variable to return operation data in.
957 *	@optlen: Length of optval.
958 *
959 *	Get connection specific socket information.
960 */
961static int llc_ui_getsockopt(struct socket *sock, int level, int optname,
962			     char __user *optval, int __user *optlen)
963{
964	struct sock *sk = sock->sk;
965	struct llc_sock *llc = llc_sk(sk);
966	int val = 0, len = 0, rc = -EINVAL;
967
968	lock_sock(sk);
969	if (level != SOL_LLC)
970		goto out;
971	rc = get_user(len, optlen);
972	if (rc)
973		goto out;
974	rc = -EINVAL;
975	if (len != sizeof(int))
976		goto out;
977	switch (optname) {
978	case LLC_OPT_RETRY:
979		val = llc->n2;				break;
980	case LLC_OPT_SIZE:
981		val = llc->n1;				break;
982	case LLC_OPT_ACK_TMR_EXP:
983		val = llc->ack_timer.expire;		break;
984	case LLC_OPT_P_TMR_EXP:
985		val = llc->pf_cycle_timer.expire;	break;
986	case LLC_OPT_REJ_TMR_EXP:
987		val = llc->rej_sent_timer.expire;	break;
988	case LLC_OPT_BUSY_TMR_EXP:
989		val = llc->busy_state_timer.expire;	break;
990	case LLC_OPT_TX_WIN:
991		val = llc->k;				break;
992	case LLC_OPT_RX_WIN:
993		val = llc->rw;				break;
994	default:
995		rc = -ENOPROTOOPT;
996		goto out;
997	}
998	rc = 0;
999	if (put_user(len, optlen) || copy_to_user(optval, &val, len))
1000		rc = -EFAULT;
1001out:
1002	release_sock(sk);
1003	return rc;
1004}
1005
1006static struct net_proto_family llc_ui_family_ops = {
1007	.family = PF_LLC,
1008	.create = llc_ui_create,
1009	.owner	= THIS_MODULE,
1010};
1011
1012static struct proto_ops llc_ui_ops = {
1013	.family	     = PF_LLC,
1014	.owner       = THIS_MODULE,
1015	.release     = llc_ui_release,
1016	.bind	     = llc_ui_bind,
1017	.connect     = llc_ui_connect,
1018	.socketpair  = sock_no_socketpair,
1019	.accept      = llc_ui_accept,
1020	.getname     = llc_ui_getname,
1021	.poll	     = datagram_poll,
1022	.ioctl       = llc_ui_ioctl,
1023	.listen      = llc_ui_listen,
1024	.shutdown    = llc_ui_shutdown,
1025	.setsockopt  = llc_ui_setsockopt,
1026	.getsockopt  = llc_ui_getsockopt,
1027	.sendmsg     = llc_ui_sendmsg,
1028	.recvmsg     = llc_ui_recvmsg,
1029	.mmap	     = sock_no_mmap,
1030	.sendpage    = sock_no_sendpage,
1031};
1032
1033extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
1034extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
1035
1036static int __init llc2_init(void)
1037{
1038	int rc = proto_register(&llc_proto, 0);
1039
1040	if (rc != 0)
1041		goto out;
1042
1043	llc_build_offset_table();
1044	llc_station_init();
1045	llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
1046	rc = llc_proc_init();
1047	if (rc != 0)
1048		goto out_unregister_llc_proto;
1049	sock_register(&llc_ui_family_ops);
1050	llc_add_pack(LLC_DEST_SAP, llc_sap_handler);
1051	llc_add_pack(LLC_DEST_CONN, llc_conn_handler);
1052out:
1053	return rc;
1054out_unregister_llc_proto:
1055	proto_unregister(&llc_proto);
1056	goto out;
1057}
1058
1059static void __exit llc2_exit(void)
1060{
1061	llc_station_exit();
1062	llc_remove_pack(LLC_DEST_SAP);
1063	llc_remove_pack(LLC_DEST_CONN);
1064	sock_unregister(PF_LLC);
1065	llc_proc_exit();
1066	proto_unregister(&llc_proto);
1067}
1068
1069module_init(llc2_init);
1070module_exit(llc2_exit);
1071
1072MODULE_LICENSE("GPL");
1073MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
1074MODULE_DESCRIPTION("IEEE 802.2 PF_LLC support");
1075MODULE_ALIAS_NETPROTO(PF_LLC);
1076