af_llc.c revision 5a770c0262262e96979fe05d5c2fa1d1f409dbdc
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 - automatically bind a socket to a sap
235 *	@sock: socket to bind
236 *	@addr: address to connect to
237 *
238 * 	Used by llc_ui_connect and llc_ui_sendmsg when the user hasn't
239 * 	specifically used llc_ui_bind to bind to an specific address/sap
240 *
241 *	Returns: 0 upon success, negative otherwise.
242 */
243static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
244{
245	struct sock *sk = sock->sk;
246	struct llc_sock *llc = llc_sk(sk);
247	struct llc_sap *sap;
248	int rc = -EINVAL;
249
250	if (!sock_flag(sk, SOCK_ZAPPED))
251		goto out;
252	rc = -ENODEV;
253	llc->dev = dev_getfirstbyhwtype(addr->sllc_arphrd);
254	if (!llc->dev)
255		goto out;
256	rc = -EUSERS;
257	llc->laddr.lsap = llc_ui_autoport();
258	if (!llc->laddr.lsap)
259		goto out;
260	rc = -EBUSY; /* some other network layer is using the sap */
261	sap = llc_sap_open(llc->laddr.lsap, NULL);
262	if (!sap)
263		goto out;
264	memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN);
265	memcpy(&llc->addr, addr, sizeof(llc->addr));
266	/* assign new connection to its SAP */
267	llc_sap_add_socket(sap, sk);
268	sock_reset_flag(sk, SOCK_ZAPPED);
269	rc = 0;
270out:
271	return rc;
272}
273
274/**
275 *	llc_ui_bind - bind a socket to a specific address.
276 *	@sock: Socket to bind an address to.
277 *	@uaddr: Address the user wants the socket bound to.
278 *	@addrlen: Length of the uaddr structure.
279 *
280 *	Bind a socket to a specific address. For llc a user is able to bind to
281 *	a specific sap only or mac + sap.
282 *	If the user desires to bind to a specific mac + sap, it is possible to
283 *	have multiple sap connections via multiple macs.
284 *	Bind and autobind for that matter must enforce the correct sap usage
285 *	otherwise all hell will break loose.
286 *	Returns: 0 upon success, negative otherwise.
287 */
288static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
289{
290	struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
291	struct sock *sk = sock->sk;
292	struct llc_sock *llc = llc_sk(sk);
293	struct llc_sap *sap;
294	int rc = -EINVAL;
295
296	dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_sap);
297	if (!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr))
298		goto out;
299	rc = -EAFNOSUPPORT;
300	if (addr->sllc_family != AF_LLC)
301		goto out;
302	if (!addr->sllc_sap) {
303		rc = -EUSERS;
304		addr->sllc_sap = llc_ui_autoport();
305		if (!addr->sllc_sap)
306			goto out;
307	}
308	sap = llc_sap_find(addr->sllc_sap);
309	if (!sap) {
310		sap = llc_sap_open(addr->sllc_sap, NULL);
311		rc = -EBUSY; /* some other network layer is using the sap */
312		if (!sap)
313			goto out;
314	} else {
315		struct llc_addr laddr, daddr;
316		struct sock *ask;
317
318		memset(&laddr, 0, sizeof(laddr));
319		memset(&daddr, 0, sizeof(daddr));
320		/*
321		 * FIXME: check if the the address is multicast,
322		 * 	  only SOCK_DGRAM can do this.
323		 */
324		memcpy(laddr.mac, addr->sllc_mac, IFHWADDRLEN);
325		laddr.lsap = addr->sllc_sap;
326		rc = -EADDRINUSE; /* mac + sap clash. */
327		ask = llc_lookup_established(sap, &daddr, &laddr);
328		if (ask) {
329			sock_put(ask);
330			goto out;
331		}
332	}
333	llc->laddr.lsap = addr->sllc_sap;
334	memcpy(llc->laddr.mac, addr->sllc_mac, IFHWADDRLEN);
335	memcpy(&llc->addr, addr, sizeof(llc->addr));
336	/* assign new connection to its SAP */
337	llc_sap_add_socket(sap, sk);
338	sock_reset_flag(sk, SOCK_ZAPPED);
339	rc = 0;
340out:
341	return rc;
342}
343
344/**
345 *	llc_ui_shutdown - shutdown a connect llc2 socket.
346 *	@sock: Socket to shutdown.
347 *	@how: What part of the socket to shutdown.
348 *
349 *	Shutdown a connected llc2 socket. Currently this function only supports
350 *	shutting down both sends and receives (2), we could probably make this
351 *	function such that a user can shutdown only half the connection but not
352 *	right now.
353 *	Returns: 0 upon success, negative otherwise.
354 */
355static int llc_ui_shutdown(struct socket *sock, int how)
356{
357	struct sock *sk = sock->sk;
358	int rc = -ENOTCONN;
359
360	lock_sock(sk);
361	if (sk->sk_state != TCP_ESTABLISHED)
362		goto out;
363	rc = -EINVAL;
364	if (how != 2)
365		goto out;
366	rc = llc_send_disc(sk);
367	if (!rc)
368		rc = llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo);
369	/* Wake up anyone sleeping in poll */
370	sk->sk_state_change(sk);
371out:
372	release_sock(sk);
373	return rc;
374}
375
376/**
377 *	llc_ui_connect - Connect to a remote llc2 mac + sap.
378 *	@sock: Socket which will be connected to the remote destination.
379 *	@uaddr: Remote and possibly the local address of the new connection.
380 *	@addrlen: Size of uaddr structure.
381 *	@flags: Operational flags specified by the user.
382 *
383 *	Connect to a remote llc2 mac + sap. The caller must specify the
384 *	destination mac and address to connect to. If the user hasn't previously
385 *	called bind(2) with a smac the address of the first interface of the
386 *	specified arp type will be used.
387 *	This function will autobind if user did not previously call bind.
388 *	Returns: 0 upon success, negative otherwise.
389 */
390static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
391			  int addrlen, int flags)
392{
393	struct sock *sk = sock->sk;
394	struct llc_sock *llc = llc_sk(sk);
395	struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
396	int rc = -EINVAL;
397
398	lock_sock(sk);
399	if (addrlen != sizeof(*addr))
400		goto out;
401	rc = -EAFNOSUPPORT;
402	if (addr->sllc_family != AF_LLC)
403		goto out;
404	/* bind connection to sap if user hasn't done it. */
405	if (sock_flag(sk, SOCK_ZAPPED)) {
406		/* bind to sap with null dev, exclusive */
407		rc = llc_ui_autobind(sock, addr);
408		if (rc)
409			goto out;
410		llc->daddr.lsap = addr->sllc_sap;
411		memcpy(llc->daddr.mac, addr->sllc_mac, IFHWADDRLEN);
412	}
413	if (sk->sk_type != SOCK_STREAM)
414		goto out;
415	rc = -EALREADY;
416	if (sock->state == SS_CONNECTING)
417		goto out;
418	sock->state = SS_CONNECTING;
419	sk->sk_state   = TCP_SYN_SENT;
420	llc->link   = llc_ui_next_link_no(llc->sap->laddr.lsap);
421	rc = llc_establish_connection(sk, llc->dev->dev_addr,
422				      addr->sllc_mac, addr->sllc_sap);
423	if (rc) {
424		dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__);
425		sock->state  = SS_UNCONNECTED;
426		sk->sk_state = TCP_CLOSE;
427		goto out;
428	}
429	rc = llc_ui_wait_for_conn(sk, sk->sk_rcvtimeo);
430	if (rc)
431		dprintk("%s: llc_ui_wait_for_conn failed=%d\n", __FUNCTION__, rc);
432out:
433	release_sock(sk);
434	return rc;
435}
436
437/**
438 *	llc_ui_listen - allow a normal socket to accept incoming connections
439 *	@sock: Socket to allow incoming connections on.
440 *	@backlog: Number of connections to queue.
441 *
442 *	Allow a normal socket to accept incoming connections.
443 *	Returns 0 upon success, negative otherwise.
444 */
445static int llc_ui_listen(struct socket *sock, int backlog)
446{
447	struct sock *sk = sock->sk;
448	int rc = -EINVAL;
449
450	lock_sock(sk);
451	if (sock->state != SS_UNCONNECTED)
452		goto out;
453	rc = -EOPNOTSUPP;
454	if (sk->sk_type != SOCK_STREAM)
455		goto out;
456	rc = -EAGAIN;
457	if (sock_flag(sk, SOCK_ZAPPED))
458		goto out;
459	rc = 0;
460	if (!(unsigned)backlog)	/* BSDism */
461		backlog = 1;
462	sk->sk_max_ack_backlog = backlog;
463	if (sk->sk_state != TCP_LISTEN) {
464		sk->sk_ack_backlog = 0;
465		sk->sk_state	   = TCP_LISTEN;
466	}
467	sk->sk_socket->flags |= __SO_ACCEPTCON;
468out:
469	release_sock(sk);
470	return rc;
471}
472
473static int llc_ui_wait_for_disc(struct sock *sk, int timeout)
474{
475	DECLARE_WAITQUEUE(wait, current);
476	int rc;
477
478	add_wait_queue_exclusive(sk->sk_sleep, &wait);
479	for (;;) {
480		__set_current_state(TASK_INTERRUPTIBLE);
481		rc = 0;
482		if (sk->sk_state != TCP_CLOSE) {
483			release_sock(sk);
484			timeout = schedule_timeout(timeout);
485			lock_sock(sk);
486		} else
487			break;
488		rc = -ERESTARTSYS;
489		if (signal_pending(current))
490			break;
491		rc = -EAGAIN;
492		if (!timeout)
493			break;
494	}
495	__set_current_state(TASK_RUNNING);
496	remove_wait_queue(sk->sk_sleep, &wait);
497	return rc;
498}
499
500static int llc_ui_wait_for_conn(struct sock *sk, int timeout)
501{
502	DECLARE_WAITQUEUE(wait, current);
503	int rc;
504
505	add_wait_queue_exclusive(sk->sk_sleep, &wait);
506	for (;;) {
507		__set_current_state(TASK_INTERRUPTIBLE);
508		rc = -EAGAIN;
509		if (sk->sk_state == TCP_CLOSE)
510			break;
511		rc = 0;
512		if (sk->sk_state != TCP_ESTABLISHED) {
513			release_sock(sk);
514			timeout = schedule_timeout(timeout);
515			lock_sock(sk);
516		} else
517			break;
518		rc = -ERESTARTSYS;
519		if (signal_pending(current))
520			break;
521		rc = -EAGAIN;
522		if (!timeout)
523			break;
524	}
525	__set_current_state(TASK_RUNNING);
526	remove_wait_queue(sk->sk_sleep, &wait);
527	return rc;
528}
529
530static int llc_ui_wait_for_data(struct sock *sk, int timeout)
531{
532	DECLARE_WAITQUEUE(wait, current);
533	int rc = 0;
534
535	add_wait_queue_exclusive(sk->sk_sleep, &wait);
536	for (;;) {
537		__set_current_state(TASK_INTERRUPTIBLE);
538		if (sk->sk_shutdown & RCV_SHUTDOWN)
539			break;
540		/*
541		 * Well, if we have backlog, try to process it now.
542		 */
543                if (sk->sk_backlog.tail) {
544			release_sock(sk);
545			lock_sock(sk);
546		}
547		rc = 0;
548		if (skb_queue_empty(&sk->sk_receive_queue)) {
549			release_sock(sk);
550			timeout = schedule_timeout(timeout);
551			lock_sock(sk);
552		} else
553			break;
554		rc = -ERESTARTSYS;
555		if (signal_pending(current))
556			break;
557		rc = -EAGAIN;
558		if (!timeout)
559			break;
560	}
561	__set_current_state(TASK_RUNNING);
562	remove_wait_queue(sk->sk_sleep, &wait);
563	return rc;
564}
565
566static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout)
567{
568	DECLARE_WAITQUEUE(wait, current);
569	struct llc_sock *llc = llc_sk(sk);
570	int rc;
571
572	add_wait_queue_exclusive(sk->sk_sleep, &wait);
573	for (;;) {
574		dprintk("%s: looping...\n", __FUNCTION__);
575		__set_current_state(TASK_INTERRUPTIBLE);
576		rc = -ENOTCONN;
577		if (sk->sk_shutdown & RCV_SHUTDOWN)
578			break;
579		rc = 0;
580		if (llc_data_accept_state(llc->state) || llc->p_flag) {
581			release_sock(sk);
582			timeout = schedule_timeout(timeout);
583			lock_sock(sk);
584		} else
585			break;
586		rc = -ERESTARTSYS;
587		if (signal_pending(current))
588			break;
589		rc = -EAGAIN;
590		if (!timeout)
591			break;
592	}
593	__set_current_state(TASK_RUNNING);
594	remove_wait_queue(sk->sk_sleep, &wait);
595	return rc;
596}
597
598/**
599 *	llc_ui_accept - accept a new incoming connection.
600 *	@sock: Socket which connections arrive on.
601 *	@newsock: Socket to move incoming connection to.
602 *	@flags: User specified operational flags.
603 *
604 *	Accept a new incoming connection.
605 *	Returns 0 upon success, negative otherwise.
606 */
607static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
608{
609	struct sock *sk = sock->sk, *newsk;
610	struct llc_sock *llc, *newllc;
611	struct sk_buff *skb;
612	int rc = -EOPNOTSUPP;
613
614	dprintk("%s: accepting on %02X\n", __FUNCTION__,
615	        llc_sk(sk)->laddr.lsap);
616	lock_sock(sk);
617	if (sk->sk_type != SOCK_STREAM)
618		goto out;
619	rc = -EINVAL;
620	if (sock->state != SS_UNCONNECTED || sk->sk_state != TCP_LISTEN)
621		goto out;
622	/* wait for a connection to arrive. */
623	rc = llc_ui_wait_for_data(sk, sk->sk_rcvtimeo);
624	if (rc)
625		goto out;
626	dprintk("%s: got a new connection on %02X\n", __FUNCTION__,
627	        llc_sk(sk)->laddr.lsap);
628	skb = skb_dequeue(&sk->sk_receive_queue);
629	rc = -EINVAL;
630	if (!skb->sk)
631		goto frees;
632	rc = 0;
633	newsk = skb->sk;
634	/* attach connection to a new socket. */
635	llc_ui_sk_init(newsock, newsk);
636	sock_reset_flag(newsk, SOCK_ZAPPED);
637	newsk->sk_state		= TCP_ESTABLISHED;
638	newsock->state		= SS_CONNECTED;
639	llc			= llc_sk(sk);
640	newllc			= llc_sk(newsk);
641	memcpy(&newllc->addr, &llc->addr, sizeof(newllc->addr));
642	newllc->link = llc_ui_next_link_no(newllc->laddr.lsap);
643
644	/* put original socket back into a clean listen state. */
645	sk->sk_state = TCP_LISTEN;
646	sk->sk_ack_backlog--;
647	skb->sk = NULL;
648	dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__,
649		llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap);
650frees:
651	kfree_skb(skb);
652out:
653	release_sock(sk);
654	return rc;
655}
656
657/**
658 *	llc_ui_recvmsg - copy received data to the socket user.
659 *	@sock: Socket to copy data from.
660 *	@msg: Various user space related information.
661 *	@size: Size of user buffer.
662 *	@flags: User specified flags.
663 *
664 *	Copy received data to the socket user.
665 *	Returns non-negative upon success, negative otherwise.
666 */
667static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
668			  struct msghdr *msg, size_t size, int flags)
669{
670	struct sock *sk = sock->sk;
671	struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name;
672	struct sk_buff *skb;
673	size_t copied = 0;
674	int rc = -ENOMEM, timeout;
675	int noblock = flags & MSG_DONTWAIT;
676
677	dprintk("%s: receiving in %02X from %02X\n", __FUNCTION__,
678		llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
679	lock_sock(sk);
680	timeout = sock_rcvtimeo(sk, noblock);
681	rc = llc_ui_wait_for_data(sk, timeout);
682	if (rc) {
683		dprintk("%s: llc_ui_wait_for_data failed recv "
684			"in %02X from %02X\n", __FUNCTION__,
685			llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
686		goto out;
687	}
688	skb = skb_dequeue(&sk->sk_receive_queue);
689	if (!skb) /* shutdown */
690		goto out;
691	copied = skb->len;
692	if (copied > size)
693		copied = size;
694	rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
695	if (rc)
696		goto dgram_free;
697	if (skb->len > copied) {
698		skb_pull(skb, copied);
699		skb_queue_head(&sk->sk_receive_queue, skb);
700	}
701	if (uaddr)
702		memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));
703	msg->msg_namelen = sizeof(*uaddr);
704	if (!skb->next) {
705dgram_free:
706		kfree_skb(skb);
707	}
708out:
709	release_sock(sk);
710	return rc ? : copied;
711}
712
713/**
714 *	llc_ui_sendmsg - Transmit data provided by the socket user.
715 *	@sock: Socket to transmit data from.
716 *	@msg: Various user related information.
717 *	@len: Length of data to transmit.
718 *
719 *	Transmit data provided by the socket user.
720 *	Returns non-negative upon success, negative otherwise.
721 */
722static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
723			  struct msghdr *msg, size_t len)
724{
725	struct sock *sk = sock->sk;
726	struct llc_sock *llc = llc_sk(sk);
727	struct sockaddr_llc *addr = (struct sockaddr_llc *)msg->msg_name;
728	int flags = msg->msg_flags;
729	int noblock = flags & MSG_DONTWAIT;
730	struct sk_buff *skb;
731	size_t size = 0;
732	int rc = -EINVAL, copied = 0, hdrlen;
733
734	dprintk("%s: sending from %02X to %02X\n", __FUNCTION__,
735		llc->laddr.lsap, llc->daddr.lsap);
736	lock_sock(sk);
737	if (addr) {
738		if (msg->msg_namelen < sizeof(*addr))
739			goto release;
740	} else {
741		if (llc_ui_addr_null(&llc->addr))
742			goto release;
743		addr = &llc->addr;
744	}
745	/* must bind connection to sap if user hasn't done it. */
746	if (sock_flag(sk, SOCK_ZAPPED)) {
747		/* bind to sap with null dev, exclusive. */
748		rc = llc_ui_autobind(sock, addr);
749		if (rc)
750			goto release;
751	}
752	hdrlen = llc->dev->hard_header_len + llc_ui_header_len(sk, addr);
753	size = hdrlen + len;
754	if (size > llc->dev->mtu)
755		size = llc->dev->mtu;
756	copied = size - hdrlen;
757	release_sock(sk);
758	skb = sock_alloc_send_skb(sk, size, noblock, &rc);
759	lock_sock(sk);
760	if (!skb)
761		goto release;
762	skb->sk	      = sk;
763	skb->dev      = llc->dev;
764	skb->protocol = llc_proto_type(addr->sllc_arphrd);
765	skb_reserve(skb, hdrlen);
766	rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied);
767	if (rc)
768		goto out;
769	if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) {
770		llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_mac,
771					  addr->sllc_sap);
772		goto out;
773	}
774	if (addr->sllc_test) {
775		llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_mac,
776					    addr->sllc_sap);
777		goto out;
778	}
779	if (addr->sllc_xid) {
780		llc_build_and_send_xid_pkt(llc->sap, skb, addr->sllc_mac,
781					   addr->sllc_sap);
782		goto out;
783	}
784	rc = -ENOPROTOOPT;
785	if (!(sk->sk_type == SOCK_STREAM && !addr->sllc_ua))
786		goto out;
787	rc = llc_ui_send_data(sk, skb, noblock);
788	if (rc)
789		dprintk("%s: llc_ui_send_data failed: %d\n", __FUNCTION__, rc);
790out:
791	if (rc)
792		kfree_skb(skb);
793release:
794	if (rc)
795		dprintk("%s: failed sending from %02X to %02X: %d\n",
796			__FUNCTION__, llc->laddr.lsap, llc->daddr.lsap, rc);
797	release_sock(sk);
798	return rc ? : copied;
799}
800
801/**
802 *	llc_ui_getname - return the address info of a socket
803 *	@sock: Socket to get address of.
804 *	@uaddr: Address structure to return information.
805 *	@uaddrlen: Length of address structure.
806 *	@peer: Does user want local or remote address information.
807 *
808 *	Return the address information of a socket.
809 */
810static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
811			  int *uaddrlen, int peer)
812{
813	struct sockaddr_llc sllc;
814	struct sock *sk = sock->sk;
815	struct llc_sock *llc = llc_sk(sk);
816	int rc = 0;
817
818	lock_sock(sk);
819	if (sock_flag(sk, SOCK_ZAPPED))
820		goto out;
821	*uaddrlen = sizeof(sllc);
822	memset(uaddr, 0, *uaddrlen);
823	if (peer) {
824		rc = -ENOTCONN;
825		if (sk->sk_state != TCP_ESTABLISHED)
826			goto out;
827		if(llc->dev)
828			sllc.sllc_arphrd = llc->dev->type;
829		sllc.sllc_sap = llc->daddr.lsap;
830		memcpy(&sllc.sllc_mac, &llc->daddr.mac, IFHWADDRLEN);
831	} else {
832		rc = -EINVAL;
833		if (!llc->sap)
834			goto out;
835		sllc.sllc_sap = llc->sap->laddr.lsap;
836
837		if (llc->dev) {
838			sllc.sllc_arphrd = llc->dev->type;
839			memcpy(&sllc.sllc_mac, &llc->dev->dev_addr,
840			       IFHWADDRLEN);
841		}
842	}
843	rc = 0;
844	sllc.sllc_family = AF_LLC;
845	memcpy(uaddr, &sllc, sizeof(sllc));
846out:
847	release_sock(sk);
848	return rc;
849}
850
851/**
852 *	llc_ui_ioctl - io controls for PF_LLC
853 *	@sock: Socket to get/set info
854 *	@cmd: command
855 *	@arg: optional argument for cmd
856 *
857 *	get/set info on llc sockets
858 */
859static int llc_ui_ioctl(struct socket *sock, unsigned int cmd,
860			unsigned long arg)
861{
862	return dev_ioctl(cmd, (void __user *)arg);
863}
864
865/**
866 *	llc_ui_setsockopt - set various connection specific parameters.
867 *	@sock: Socket to set options on.
868 *	@level: Socket level user is requesting operations on.
869 *	@optname: Operation name.
870 *	@optval User provided operation data.
871 *	@optlen: Length of optval.
872 *
873 *	Set various connection specific parameters.
874 */
875static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
876			     char __user *optval, int optlen)
877{
878	struct sock *sk = sock->sk;
879	struct llc_sock *llc = llc_sk(sk);
880	int rc = -EINVAL, opt;
881
882	lock_sock(sk);
883	if (level != SOL_LLC || optlen != sizeof(int))
884		goto out;
885	rc = get_user(opt, (int __user *)optval);
886	if (rc)
887		goto out;
888	rc = -EINVAL;
889	switch (optname) {
890	case LLC_OPT_RETRY:
891		if (opt > LLC_OPT_MAX_RETRY)
892			goto out;
893		llc->n2 = opt;
894		break;
895	case LLC_OPT_SIZE:
896		if (opt > LLC_OPT_MAX_SIZE)
897			goto out;
898		llc->n1 = opt;
899		break;
900	case LLC_OPT_ACK_TMR_EXP:
901		if (opt > LLC_OPT_MAX_ACK_TMR_EXP)
902			goto out;
903		llc->ack_timer.expire = opt;
904		break;
905	case LLC_OPT_P_TMR_EXP:
906		if (opt > LLC_OPT_MAX_P_TMR_EXP)
907			goto out;
908		llc->pf_cycle_timer.expire = opt;
909		break;
910	case LLC_OPT_REJ_TMR_EXP:
911		if (opt > LLC_OPT_MAX_REJ_TMR_EXP)
912			goto out;
913		llc->rej_sent_timer.expire = opt;
914		break;
915	case LLC_OPT_BUSY_TMR_EXP:
916		if (opt > LLC_OPT_MAX_BUSY_TMR_EXP)
917			goto out;
918		llc->busy_state_timer.expire = opt;
919		break;
920	case LLC_OPT_TX_WIN:
921		if (opt > LLC_OPT_MAX_WIN)
922			goto out;
923		llc->k = opt;
924		break;
925	case LLC_OPT_RX_WIN:
926		if (opt > LLC_OPT_MAX_WIN)
927			goto out;
928		llc->rw = opt;
929		break;
930	default:
931		rc = -ENOPROTOOPT;
932		goto out;
933	}
934	rc = 0;
935out:
936	release_sock(sk);
937	return rc;
938}
939
940/**
941 *	llc_ui_getsockopt - get connection specific socket info
942 *	@sock: Socket to get information from.
943 *	@level: Socket level user is requesting operations on.
944 *	@optname: Operation name.
945 *	@optval: Variable to return operation data in.
946 *	@optlen: Length of optval.
947 *
948 *	Get connection specific socket information.
949 */
950static int llc_ui_getsockopt(struct socket *sock, int level, int optname,
951			     char __user *optval, int __user *optlen)
952{
953	struct sock *sk = sock->sk;
954	struct llc_sock *llc = llc_sk(sk);
955	int val = 0, len = 0, rc = -EINVAL;
956
957	lock_sock(sk);
958	if (level != SOL_LLC)
959		goto out;
960	rc = get_user(len, optlen);
961	if (rc)
962		goto out;
963	rc = -EINVAL;
964	if (len != sizeof(int))
965		goto out;
966	switch (optname) {
967	case LLC_OPT_RETRY:
968		val = llc->n2;				break;
969	case LLC_OPT_SIZE:
970		val = llc->n1;				break;
971	case LLC_OPT_ACK_TMR_EXP:
972		val = llc->ack_timer.expire;		break;
973	case LLC_OPT_P_TMR_EXP:
974		val = llc->pf_cycle_timer.expire;	break;
975	case LLC_OPT_REJ_TMR_EXP:
976		val = llc->rej_sent_timer.expire;	break;
977	case LLC_OPT_BUSY_TMR_EXP:
978		val = llc->busy_state_timer.expire;	break;
979	case LLC_OPT_TX_WIN:
980		val = llc->k;				break;
981	case LLC_OPT_RX_WIN:
982		val = llc->rw;				break;
983	default:
984		rc = -ENOPROTOOPT;
985		goto out;
986	}
987	rc = 0;
988	if (put_user(len, optlen) || copy_to_user(optval, &val, len))
989		rc = -EFAULT;
990out:
991	release_sock(sk);
992	return rc;
993}
994
995static struct net_proto_family llc_ui_family_ops = {
996	.family = PF_LLC,
997	.create = llc_ui_create,
998	.owner	= THIS_MODULE,
999};
1000
1001static struct proto_ops llc_ui_ops = {
1002	.family	     = PF_LLC,
1003	.owner       = THIS_MODULE,
1004	.release     = llc_ui_release,
1005	.bind	     = llc_ui_bind,
1006	.connect     = llc_ui_connect,
1007	.socketpair  = sock_no_socketpair,
1008	.accept      = llc_ui_accept,
1009	.getname     = llc_ui_getname,
1010	.poll	     = datagram_poll,
1011	.ioctl       = llc_ui_ioctl,
1012	.listen      = llc_ui_listen,
1013	.shutdown    = llc_ui_shutdown,
1014	.setsockopt  = llc_ui_setsockopt,
1015	.getsockopt  = llc_ui_getsockopt,
1016	.sendmsg     = llc_ui_sendmsg,
1017	.recvmsg     = llc_ui_recvmsg,
1018	.mmap	     = sock_no_mmap,
1019	.sendpage    = sock_no_sendpage,
1020};
1021
1022extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
1023extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
1024
1025static int __init llc2_init(void)
1026{
1027	int rc = proto_register(&llc_proto, 0);
1028
1029	if (rc != 0)
1030		goto out;
1031
1032	llc_build_offset_table();
1033	llc_station_init();
1034	llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
1035	rc = llc_proc_init();
1036	if (rc != 0)
1037		goto out_unregister_llc_proto;
1038	sock_register(&llc_ui_family_ops);
1039	llc_add_pack(LLC_DEST_SAP, llc_sap_handler);
1040	llc_add_pack(LLC_DEST_CONN, llc_conn_handler);
1041out:
1042	return rc;
1043out_unregister_llc_proto:
1044	proto_unregister(&llc_proto);
1045	goto out;
1046}
1047
1048static void __exit llc2_exit(void)
1049{
1050	llc_station_exit();
1051	llc_remove_pack(LLC_DEST_SAP);
1052	llc_remove_pack(LLC_DEST_CONN);
1053	sock_unregister(PF_LLC);
1054	llc_proc_exit();
1055	proto_unregister(&llc_proto);
1056}
1057
1058module_init(llc2_init);
1059module_exit(llc2_exit);
1060
1061MODULE_LICENSE("GPL");
1062MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
1063MODULE_DESCRIPTION("IEEE 802.2 PF_LLC support");
1064MODULE_ALIAS_NETPROTO(PF_LLC);
1065