xref: /linux/net/bluetooth/bnep/core.c (revision bea06c7c1b83bcd0519b91141999369eae6925bd)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3    BNEP implementation for Linux Bluetooth stack (BlueZ).
4    Copyright (C) 2001-2002 Inventel Systemes
5    Written 2001-2002 by
6 	Clément Moreau <clement.moreau@inventel.fr>
7 	David Libault  <david.libault@inventel.fr>
8 
9    Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
10 
11    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 
20    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
22    SOFTWARE IS DISCLAIMED.
23 */
24 
25 #include <linux/module.h>
26 #include <linux/kthread.h>
27 #include <linux/file.h>
28 #include <linux/etherdevice.h>
29 #include <linux/unaligned.h>
30 
31 #include <net/bluetooth/bluetooth.h>
32 #include <net/bluetooth/l2cap.h>
33 #include <net/bluetooth/hci_core.h>
34 
35 #include "bnep.h"
36 
37 #define VERSION "1.3"
38 
39 static bool compress_src = true;
40 static bool compress_dst = true;
41 
42 static LIST_HEAD(bnep_session_list);
43 static DECLARE_RWSEM(bnep_session_sem);
44 
45 static struct bnep_session *__bnep_get_session(u8 *dst)
46 {
47 	struct bnep_session *s;
48 
49 	BT_DBG("");
50 
51 	list_for_each_entry(s, &bnep_session_list, list)
52 		if (ether_addr_equal(dst, s->eh.h_source))
53 			return s;
54 
55 	return NULL;
56 }
57 
58 static void __bnep_link_session(struct bnep_session *s)
59 {
60 	list_add(&s->list, &bnep_session_list);
61 }
62 
63 static void __bnep_unlink_session(struct bnep_session *s)
64 {
65 	list_del(&s->list);
66 }
67 
68 static int bnep_send(struct bnep_session *s, void *data, size_t len)
69 {
70 	struct socket *sock = s->sock;
71 	struct kvec iv = { data, len };
72 
73 	return kernel_sendmsg(sock, &s->msg, &iv, 1, len);
74 }
75 
76 static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
77 {
78 	struct bnep_control_rsp rsp;
79 	rsp.type = BNEP_CONTROL;
80 	rsp.ctrl = ctrl;
81 	rsp.resp = htons(resp);
82 	return bnep_send(s, &rsp, sizeof(rsp));
83 }
84 
85 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
86 static inline void bnep_set_default_proto_filter(struct bnep_session *s)
87 {
88 	/* (IPv4, ARP)  */
89 	s->proto_filter[0].start = ETH_P_IP;
90 	s->proto_filter[0].end   = ETH_P_ARP;
91 	/* (RARP, AppleTalk) */
92 	s->proto_filter[1].start = ETH_P_RARP;
93 	s->proto_filter[1].end   = ETH_P_AARP;
94 	/* (IPX, IPv6) */
95 	s->proto_filter[2].start = ETH_P_IPX;
96 	s->proto_filter[2].end   = ETH_P_IPV6;
97 }
98 #endif
99 
100 static int bnep_ctrl_set_netfilter(struct bnep_session *s, __be16 *data, int len)
101 {
102 	int n;
103 
104 	if (len < 2)
105 		return -EILSEQ;
106 
107 	n = get_unaligned_be16(data);
108 	data++;
109 	len -= 2;
110 
111 	if (len < n)
112 		return -EILSEQ;
113 
114 	BT_DBG("filter len %d", n);
115 
116 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
117 	n /= 4;
118 	if (n <= BNEP_MAX_PROTO_FILTERS) {
119 		struct bnep_proto_filter *f = s->proto_filter;
120 		int i;
121 
122 		for (i = 0; i < n; i++) {
123 			f[i].start = get_unaligned_be16(data++);
124 			f[i].end   = get_unaligned_be16(data++);
125 
126 			BT_DBG("proto filter start %u end %u",
127 			       f[i].start, f[i].end);
128 		}
129 
130 		if (i < BNEP_MAX_PROTO_FILTERS)
131 			memset(f + i, 0, sizeof(*f));
132 
133 		if (n == 0)
134 			bnep_set_default_proto_filter(s);
135 
136 		bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_SUCCESS);
137 	} else {
138 		bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_LIMIT_REACHED);
139 	}
140 #else
141 	bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
142 #endif
143 	return 0;
144 }
145 
146 static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
147 {
148 	int n;
149 
150 	if (len < 2)
151 		return -EILSEQ;
152 
153 	n = get_unaligned_be16(data);
154 	data += 2;
155 	len -= 2;
156 
157 	if (len < n)
158 		return -EILSEQ;
159 
160 	BT_DBG("filter len %d", n);
161 
162 #ifdef CONFIG_BT_BNEP_MC_FILTER
163 	n /= (ETH_ALEN * 2);
164 
165 	if (n > 0) {
166 		int i;
167 
168 		s->mc_filter = 0;
169 
170 		/* Always send broadcast */
171 		set_bit(bnep_mc_hash(s->dev->broadcast), (ulong *) &s->mc_filter);
172 
173 		/* Add address ranges to the multicast hash */
174 		for (; n > 0; n--) {
175 			u8 a1[6], *a2;
176 
177 			memcpy(a1, data, ETH_ALEN);
178 			data += ETH_ALEN;
179 			a2 = data;
180 			data += ETH_ALEN;
181 
182 			BT_DBG("mc filter %pMR -> %pMR", a1, a2);
183 
184 			/* Iterate from a1 to a2 */
185 			set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter);
186 			while (memcmp(a1, a2, 6) < 0 && s->mc_filter != ~0LL) {
187 				/* Increment a1 */
188 				i = 5;
189 				while (i >= 0 && ++a1[i--] == 0)
190 					;
191 
192 				set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter);
193 			}
194 		}
195 	}
196 
197 	BT_DBG("mc filter hash 0x%llx", s->mc_filter);
198 
199 	bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_SUCCESS);
200 #else
201 	bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
202 #endif
203 	return 0;
204 }
205 
206 static int bnep_rx_control_cmd(struct bnep_session *s, u8 cmd, void *data,
207 			       int len)
208 {
209 	int err = 0;
210 
211 	switch (cmd) {
212 	case BNEP_CMD_NOT_UNDERSTOOD:
213 	case BNEP_SETUP_CONN_RSP:
214 	case BNEP_FILTER_NET_TYPE_RSP:
215 	case BNEP_FILTER_MULTI_ADDR_RSP:
216 		/* Ignore these for now */
217 		break;
218 
219 	case BNEP_FILTER_NET_TYPE_SET:
220 		err = bnep_ctrl_set_netfilter(s, data, len);
221 		break;
222 
223 	case BNEP_FILTER_MULTI_ADDR_SET:
224 		err = bnep_ctrl_set_mcfilter(s, data, len);
225 		break;
226 
227 	case BNEP_SETUP_CONN_REQ:
228 		/* Successful response should be sent only once */
229 		if (test_bit(BNEP_SETUP_RESPONSE, &s->flags) &&
230 		    !test_and_set_bit(BNEP_SETUP_RSP_SENT, &s->flags))
231 			err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP,
232 					    BNEP_SUCCESS);
233 		else
234 			err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP,
235 					    BNEP_CONN_NOT_ALLOWED);
236 		break;
237 
238 	default: {
239 			u8 pkt[3];
240 			pkt[0] = BNEP_CONTROL;
241 			pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
242 			pkt[2] = cmd;
243 			err = bnep_send(s, pkt, sizeof(pkt));
244 		}
245 		break;
246 	}
247 
248 	return err;
249 }
250 
251 static int bnep_rx_control(struct bnep_session *s, void *data, int len)
252 {
253 	if (len < 1)
254 		return -EILSEQ;
255 
256 	return bnep_rx_control_cmd(s, *(u8 *)data, data + 1, len - 1);
257 }
258 
259 static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
260 {
261 	struct bnep_ext_hdr *h;
262 	int err = 0;
263 
264 	do {
265 		h = (void *) skb->data;
266 		if (!skb_pull(skb, sizeof(*h))) {
267 			err = -EILSEQ;
268 			break;
269 		}
270 
271 		BT_DBG("type 0x%x len %u", h->type, h->len);
272 
273 		switch (h->type & BNEP_TYPE_MASK) {
274 		case BNEP_EXT_CONTROL:
275 			bnep_rx_control(s, skb->data, skb->len);
276 			break;
277 
278 		default:
279 			/* Unknown extension, skip it. */
280 			break;
281 		}
282 
283 		if (!skb_pull(skb, h->len)) {
284 			err = -EILSEQ;
285 			break;
286 		}
287 	} while (!err && (h->type & BNEP_EXT_HEADER));
288 
289 	return err;
290 }
291 
292 static u8 __bnep_rx_hlen[] = {
293 	ETH_HLEN,     /* BNEP_GENERAL */
294 	0,            /* BNEP_CONTROL */
295 	2,            /* BNEP_COMPRESSED */
296 	ETH_ALEN + 2, /* BNEP_COMPRESSED_SRC_ONLY */
297 	ETH_ALEN + 2  /* BNEP_COMPRESSED_DST_ONLY */
298 };
299 
300 static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
301 {
302 	struct net_device *dev = s->dev;
303 	struct sk_buff *nskb;
304 	u8 *data;
305 	u8 type, ctrl_type;
306 
307 	dev->stats.rx_bytes += skb->len;
308 
309 	data = skb_pull_data(skb, sizeof(type));
310 	if (!data)
311 		goto badframe;
312 	type = *data;
313 
314 	if ((type & BNEP_TYPE_MASK) >= sizeof(__bnep_rx_hlen))
315 		goto badframe;
316 
317 	if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
318 		data = skb_pull_data(skb, sizeof(ctrl_type));
319 		if (!data)
320 			goto badframe;
321 		ctrl_type = *data;
322 
323 		if (bnep_rx_control_cmd(s, ctrl_type, skb->data, skb->len) < 0) {
324 			dev->stats.tx_errors++;
325 			kfree_skb(skb);
326 			return 0;
327 		}
328 
329 		if (!(type & BNEP_EXT_HEADER)) {
330 			kfree_skb(skb);
331 			return 0;
332 		}
333 
334 		/* Verify and pull ctrl message since it's already processed */
335 		switch (ctrl_type) {
336 		case BNEP_SETUP_CONN_REQ: {
337 			u8 uuid_size;
338 
339 			/* Pull uuid_size and the dst/src service UUIDs. */
340 			data = skb_pull_data(skb, sizeof(uuid_size));
341 			if (!data)
342 				goto badframe;
343 			uuid_size = *data;
344 			if (!skb_pull(skb, uuid_size + uuid_size))
345 				goto badframe;
346 			break;
347 		}
348 		case BNEP_FILTER_MULTI_ADDR_SET:
349 		case BNEP_FILTER_NET_TYPE_SET:
350 			/* Pull: len (2 b), data (len bytes) */
351 			data = skb_pull_data(skb, sizeof(u16));
352 			if (!data)
353 				goto badframe;
354 			if (!skb_pull(skb, get_unaligned_be16(data)))
355 				goto badframe;
356 			break;
357 		default:
358 			kfree_skb(skb);
359 			return 0;
360 		}
361 	} else {
362 		skb_reset_mac_header(skb);
363 
364 		/* Verify and pull out header */
365 		if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK]))
366 			goto badframe;
367 
368 		s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2));
369 	}
370 
371 	if (type & BNEP_EXT_HEADER) {
372 		if (bnep_rx_extension(s, skb) < 0)
373 			goto badframe;
374 	}
375 
376 	/* Strip 802.1p header */
377 	if (ntohs(s->eh.h_proto) == ETH_P_8021Q) {
378 		if (!skb_pull(skb, 4))
379 			goto badframe;
380 		s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2));
381 	}
382 
383 	/* We have to alloc new skb and copy data here :(. Because original skb
384 	 * may not be modified and because of the alignment requirements. */
385 	nskb = alloc_skb(2 + ETH_HLEN + skb->len, GFP_KERNEL);
386 	if (!nskb) {
387 		dev->stats.rx_dropped++;
388 		kfree_skb(skb);
389 		return -ENOMEM;
390 	}
391 	skb_reserve(nskb, 2);
392 
393 	/* Decompress header and construct ether frame */
394 	switch (type & BNEP_TYPE_MASK) {
395 	case BNEP_COMPRESSED:
396 		__skb_put_data(nskb, &s->eh, ETH_HLEN);
397 		break;
398 
399 	case BNEP_COMPRESSED_SRC_ONLY:
400 		__skb_put_data(nskb, s->eh.h_dest, ETH_ALEN);
401 		__skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN);
402 		put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2));
403 		break;
404 
405 	case BNEP_COMPRESSED_DST_ONLY:
406 		__skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN);
407 		__skb_put_data(nskb, s->eh.h_source, ETH_ALEN);
408 		put_unaligned(s->eh.h_proto, (__be16 *)__skb_put(nskb, 2));
409 		break;
410 
411 	case BNEP_GENERAL:
412 		__skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN * 2);
413 		put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2));
414 		break;
415 	}
416 
417 	skb_copy_from_linear_data(skb, __skb_put(nskb, skb->len), skb->len);
418 	kfree_skb(skb);
419 
420 	dev->stats.rx_packets++;
421 	nskb->ip_summed = CHECKSUM_NONE;
422 	nskb->protocol  = eth_type_trans(nskb, dev);
423 	netif_rx(nskb);
424 	return 0;
425 
426 badframe:
427 	dev->stats.rx_errors++;
428 	kfree_skb(skb);
429 	return 0;
430 }
431 
432 static u8 __bnep_tx_types[] = {
433 	BNEP_GENERAL,
434 	BNEP_COMPRESSED_SRC_ONLY,
435 	BNEP_COMPRESSED_DST_ONLY,
436 	BNEP_COMPRESSED
437 };
438 
439 static int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb)
440 {
441 	struct ethhdr *eh = (void *) skb->data;
442 	struct socket *sock = s->sock;
443 	struct kvec iv[3];
444 	int len = 0, il = 0;
445 	u8 type = 0;
446 
447 	BT_DBG("skb %p dev %p type %u", skb, skb->dev, skb->pkt_type);
448 
449 	if (!skb->dev) {
450 		/* Control frame sent by us */
451 		goto send;
452 	}
453 
454 	iv[il++] = (struct kvec) { &type, 1 };
455 	len++;
456 
457 	if (compress_src && ether_addr_equal(eh->h_dest, s->eh.h_source))
458 		type |= 0x01;
459 
460 	if (compress_dst && ether_addr_equal(eh->h_source, s->eh.h_dest))
461 		type |= 0x02;
462 
463 	if (type)
464 		skb_pull(skb, ETH_ALEN * 2);
465 
466 	type = __bnep_tx_types[type];
467 	switch (type) {
468 	case BNEP_COMPRESSED_SRC_ONLY:
469 		iv[il++] = (struct kvec) { eh->h_source, ETH_ALEN };
470 		len += ETH_ALEN;
471 		break;
472 
473 	case BNEP_COMPRESSED_DST_ONLY:
474 		iv[il++] = (struct kvec) { eh->h_dest, ETH_ALEN };
475 		len += ETH_ALEN;
476 		break;
477 	}
478 
479 send:
480 	iv[il++] = (struct kvec) { skb->data, skb->len };
481 	len += skb->len;
482 
483 	/* FIXME: linearize skb */
484 	{
485 		len = kernel_sendmsg(sock, &s->msg, iv, il, len);
486 	}
487 	kfree_skb(skb);
488 
489 	if (len > 0) {
490 		s->dev->stats.tx_bytes += len;
491 		s->dev->stats.tx_packets++;
492 		return 0;
493 	}
494 
495 	return len;
496 }
497 
498 static int bnep_session(void *arg)
499 {
500 	struct bnep_session *s = arg;
501 	struct net_device *dev = s->dev;
502 	struct sock *sk = s->sock->sk;
503 	struct sk_buff *skb;
504 	DEFINE_WAIT_FUNC(wait, woken_wake_function);
505 
506 	BT_DBG("");
507 
508 	set_user_nice(current, -15);
509 
510 	add_wait_queue(sk_sleep(sk), &wait);
511 	while (1) {
512 		if (atomic_read(&s->terminate))
513 			break;
514 		/* RX */
515 		while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
516 			skb_orphan(skb);
517 			if (!skb_linearize(skb))
518 				bnep_rx_frame(s, skb);
519 			else
520 				kfree_skb(skb);
521 		}
522 
523 		if (sk->sk_state != BT_CONNECTED)
524 			break;
525 
526 		/* TX */
527 		while ((skb = skb_dequeue(&sk->sk_write_queue)))
528 			if (bnep_tx_frame(s, skb))
529 				break;
530 		netif_wake_queue(dev);
531 
532 		/*
533 		 * wait_woken() performs the necessary memory barriers
534 		 * for us; see the header comment for this primitive.
535 		 */
536 		wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
537 	}
538 	remove_wait_queue(sk_sleep(sk), &wait);
539 
540 	/* Cleanup session */
541 	down_write(&bnep_session_sem);
542 
543 	/* Delete network device */
544 	unregister_netdev(dev);
545 
546 	/* Wakeup user-space polling for socket errors */
547 	s->sock->sk->sk_err = EUNATCH;
548 
549 	wake_up_interruptible(sk_sleep(s->sock->sk));
550 
551 	/* Release the socket */
552 	fput(s->sock->file);
553 
554 	__bnep_unlink_session(s);
555 
556 	up_write(&bnep_session_sem);
557 	free_netdev(dev);
558 	module_put_and_kthread_exit(0);
559 	return 0;
560 }
561 
562 static struct device *bnep_get_device(struct bnep_session *session)
563 {
564 	struct l2cap_conn *conn = l2cap_pi(session->sock->sk)->chan->conn;
565 
566 	if (!conn || !conn->hcon)
567 		return NULL;
568 
569 	return &conn->hcon->dev;
570 }
571 
572 static const struct device_type bnep_type = {
573 	.name	= "bluetooth",
574 };
575 
576 int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
577 {
578 	u32 valid_flags = BIT(BNEP_SETUP_RESPONSE);
579 	struct net_device *dev;
580 	struct bnep_session *s, *ss;
581 	u8 dst[ETH_ALEN], src[ETH_ALEN];
582 	int err;
583 
584 	BT_DBG("");
585 
586 	if (!l2cap_is_socket(sock))
587 		return -EBADFD;
588 
589 	if (req->flags & ~valid_flags)
590 		return -EINVAL;
591 
592 	baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst);
593 	baswap((void *) src, &l2cap_pi(sock->sk)->chan->src);
594 
595 	/* session struct allocated as private part of net_device */
596 	dev = alloc_netdev(sizeof(struct bnep_session),
597 			   (*req->device) ? req->device : "bnep%d",
598 			   NET_NAME_UNKNOWN,
599 			   bnep_net_setup);
600 	if (!dev)
601 		return -ENOMEM;
602 
603 	down_write(&bnep_session_sem);
604 
605 	ss = __bnep_get_session(dst);
606 	if (ss && ss->state == BT_CONNECTED) {
607 		err = -EEXIST;
608 		goto failed;
609 	}
610 
611 	s = netdev_priv(dev);
612 
613 	/* This is rx header therefore addresses are swapped.
614 	 * ie. eh.h_dest is our local address. */
615 	memcpy(s->eh.h_dest,   &src, ETH_ALEN);
616 	memcpy(s->eh.h_source, &dst, ETH_ALEN);
617 	eth_hw_addr_set(dev, s->eh.h_dest);
618 
619 	s->dev   = dev;
620 	s->sock  = sock;
621 	s->role  = req->role;
622 	s->state = BT_CONNECTED;
623 	s->flags = req->flags;
624 
625 	s->msg.msg_flags = MSG_NOSIGNAL;
626 
627 #ifdef CONFIG_BT_BNEP_MC_FILTER
628 	/* Set default mc filter to not filter out any mc addresses
629 	 * as defined in the BNEP specification (revision 0.95a)
630 	 * http://grouper.ieee.org/groups/802/15/Bluetooth/BNEP.pdf
631 	 */
632 	s->mc_filter = ~0LL;
633 #endif
634 
635 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
636 	/* Set default protocol filter */
637 	bnep_set_default_proto_filter(s);
638 #endif
639 
640 	SET_NETDEV_DEV(dev, bnep_get_device(s));
641 	SET_NETDEV_DEVTYPE(dev, &bnep_type);
642 
643 	err = register_netdev(dev);
644 	if (err)
645 		goto failed;
646 
647 	__bnep_link_session(s);
648 
649 	__module_get(THIS_MODULE);
650 	s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name);
651 	if (IS_ERR(s->task)) {
652 		/* Session thread start failed, gotta cleanup. */
653 		module_put(THIS_MODULE);
654 		unregister_netdev(dev);
655 		__bnep_unlink_session(s);
656 		err = PTR_ERR(s->task);
657 		goto failed;
658 	}
659 
660 	strcpy(req->device, dev->name);
661 	up_write(&bnep_session_sem);
662 	return 0;
663 
664 failed:
665 	up_write(&bnep_session_sem);
666 	free_netdev(dev);
667 	return err;
668 }
669 
670 int bnep_del_connection(struct bnep_conndel_req *req)
671 {
672 	u32 valid_flags = 0;
673 	struct bnep_session *s;
674 	int  err = 0;
675 
676 	BT_DBG("");
677 
678 	if (req->flags & ~valid_flags)
679 		return -EINVAL;
680 
681 	down_read(&bnep_session_sem);
682 
683 	s = __bnep_get_session(req->dst);
684 	if (s) {
685 		atomic_inc(&s->terminate);
686 		wake_up_interruptible(sk_sleep(s->sock->sk));
687 	} else
688 		err = -ENOENT;
689 
690 	up_read(&bnep_session_sem);
691 	return err;
692 }
693 
694 static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
695 {
696 	u32 valid_flags = BIT(BNEP_SETUP_RESPONSE);
697 
698 	memset(ci, 0, sizeof(*ci));
699 	memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
700 	strcpy(ci->device, s->dev->name);
701 	ci->flags = s->flags & valid_flags;
702 	ci->state = s->state;
703 	ci->role  = s->role;
704 }
705 
706 int bnep_get_connlist(struct bnep_connlist_req *req)
707 {
708 	struct bnep_session *s;
709 	int err = 0, n = 0;
710 
711 	down_read(&bnep_session_sem);
712 
713 	list_for_each_entry(s, &bnep_session_list, list) {
714 		struct bnep_conninfo ci;
715 
716 		__bnep_copy_ci(&ci, s);
717 
718 		if (copy_to_user(req->ci, &ci, sizeof(ci))) {
719 			err = -EFAULT;
720 			break;
721 		}
722 
723 		if (++n >= req->cnum)
724 			break;
725 
726 		req->ci++;
727 	}
728 	req->cnum = n;
729 
730 	up_read(&bnep_session_sem);
731 	return err;
732 }
733 
734 int bnep_get_conninfo(struct bnep_conninfo *ci)
735 {
736 	struct bnep_session *s;
737 	int err = 0;
738 
739 	down_read(&bnep_session_sem);
740 
741 	s = __bnep_get_session(ci->dst);
742 	if (s)
743 		__bnep_copy_ci(ci, s);
744 	else
745 		err = -ENOENT;
746 
747 	up_read(&bnep_session_sem);
748 	return err;
749 }
750 
751 static int __init bnep_init(void)
752 {
753 	char flt[50] = "";
754 
755 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
756 	strcat(flt, "protocol ");
757 #endif
758 
759 #ifdef CONFIG_BT_BNEP_MC_FILTER
760 	strcat(flt, "multicast");
761 #endif
762 
763 	BT_INFO("BNEP (Ethernet Emulation) ver %s", VERSION);
764 	if (flt[0])
765 		BT_INFO("BNEP filters: %s", flt);
766 
767 	return bnep_sock_init();
768 }
769 
770 static void __exit bnep_exit(void)
771 {
772 	bnep_sock_cleanup();
773 }
774 
775 module_init(bnep_init);
776 module_exit(bnep_exit);
777 
778 module_param(compress_src, bool, 0644);
779 MODULE_PARM_DESC(compress_src, "Compress sources headers");
780 
781 module_param(compress_dst, bool, 0644);
782 MODULE_PARM_DESC(compress_dst, "Compress destination headers");
783 
784 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
785 MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION);
786 MODULE_VERSION(VERSION);
787 MODULE_LICENSE("GPL");
788 MODULE_ALIAS("bt-proto-4");
789