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