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