Back to home page

OSCL-LXR

 
 

    


0001 /*
0002    BNEP implementation for Linux Bluetooth stack (BlueZ).
0003    Copyright (C) 2001-2002 Inventel Systemes
0004    Written 2001-2002 by
0005     Clément Moreau <clement.moreau@inventel.fr>
0006     David Libault  <david.libault@inventel.fr>
0007 
0008    Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
0009 
0010    This program is free software; you can redistribute it and/or modify
0011    it under the terms of the GNU General Public License version 2 as
0012    published by the Free Software Foundation;
0013 
0014    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0015    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
0017    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
0018    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
0019    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0020    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0021    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0022 
0023    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
0024    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
0025    SOFTWARE IS DISCLAIMED.
0026 */
0027 
0028 #include <linux/etherdevice.h>
0029 
0030 #include <net/bluetooth/bluetooth.h>
0031 #include <net/bluetooth/hci_core.h>
0032 #include <net/bluetooth/l2cap.h>
0033 
0034 #include "bnep.h"
0035 
0036 #define BNEP_TX_QUEUE_LEN 20
0037 
0038 static int bnep_net_open(struct net_device *dev)
0039 {
0040     netif_start_queue(dev);
0041     return 0;
0042 }
0043 
0044 static int bnep_net_close(struct net_device *dev)
0045 {
0046     netif_stop_queue(dev);
0047     return 0;
0048 }
0049 
0050 static void bnep_net_set_mc_list(struct net_device *dev)
0051 {
0052 #ifdef CONFIG_BT_BNEP_MC_FILTER
0053     struct bnep_session *s = netdev_priv(dev);
0054     struct sock *sk = s->sock->sk;
0055     struct bnep_set_filter_req *r;
0056     struct sk_buff *skb;
0057     int size;
0058 
0059     BT_DBG("%s mc_count %d", dev->name, netdev_mc_count(dev));
0060 
0061     size = sizeof(*r) + (BNEP_MAX_MULTICAST_FILTERS + 1) * ETH_ALEN * 2;
0062     skb  = alloc_skb(size, GFP_ATOMIC);
0063     if (!skb) {
0064         BT_ERR("%s Multicast list allocation failed", dev->name);
0065         return;
0066     }
0067 
0068     r = (void *) skb->data;
0069     __skb_put(skb, sizeof(*r));
0070 
0071     r->type = BNEP_CONTROL;
0072     r->ctrl = BNEP_FILTER_MULTI_ADDR_SET;
0073 
0074     if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
0075         u8 start[ETH_ALEN] = { 0x01 };
0076 
0077         /* Request all addresses */
0078         __skb_put_data(skb, start, ETH_ALEN);
0079         __skb_put_data(skb, dev->broadcast, ETH_ALEN);
0080         r->len = htons(ETH_ALEN * 2);
0081     } else {
0082         struct netdev_hw_addr *ha;
0083         int i, len = skb->len;
0084 
0085         if (dev->flags & IFF_BROADCAST) {
0086             __skb_put_data(skb, dev->broadcast, ETH_ALEN);
0087             __skb_put_data(skb, dev->broadcast, ETH_ALEN);
0088         }
0089 
0090         /* FIXME: We should group addresses here. */
0091 
0092         i = 0;
0093         netdev_for_each_mc_addr(ha, dev) {
0094             if (i == BNEP_MAX_MULTICAST_FILTERS)
0095                 break;
0096             __skb_put_data(skb, ha->addr, ETH_ALEN);
0097             __skb_put_data(skb, ha->addr, ETH_ALEN);
0098 
0099             i++;
0100         }
0101         r->len = htons(skb->len - len);
0102     }
0103 
0104     skb_queue_tail(&sk->sk_write_queue, skb);
0105     wake_up_interruptible(sk_sleep(sk));
0106 #endif
0107 }
0108 
0109 static int bnep_net_set_mac_addr(struct net_device *dev, void *arg)
0110 {
0111     BT_DBG("%s", dev->name);
0112     return 0;
0113 }
0114 
0115 static void bnep_net_timeout(struct net_device *dev, unsigned int txqueue)
0116 {
0117     BT_DBG("net_timeout");
0118     netif_wake_queue(dev);
0119 }
0120 
0121 #ifdef CONFIG_BT_BNEP_MC_FILTER
0122 static int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s)
0123 {
0124     struct ethhdr *eh = (void *) skb->data;
0125 
0126     if ((eh->h_dest[0] & 1) && !test_bit(bnep_mc_hash(eh->h_dest), (ulong *) &s->mc_filter))
0127         return 1;
0128     return 0;
0129 }
0130 #endif
0131 
0132 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
0133 /* Determine ether protocol. Based on eth_type_trans. */
0134 static u16 bnep_net_eth_proto(struct sk_buff *skb)
0135 {
0136     struct ethhdr *eh = (void *) skb->data;
0137     u16 proto = ntohs(eh->h_proto);
0138 
0139     if (proto >= ETH_P_802_3_MIN)
0140         return proto;
0141 
0142     if (get_unaligned((__be16 *) skb->data) == htons(0xFFFF))
0143         return ETH_P_802_3;
0144 
0145     return ETH_P_802_2;
0146 }
0147 
0148 static int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s)
0149 {
0150     u16 proto = bnep_net_eth_proto(skb);
0151     struct bnep_proto_filter *f = s->proto_filter;
0152     int i;
0153 
0154     for (i = 0; i < BNEP_MAX_PROTO_FILTERS && f[i].end; i++) {
0155         if (proto >= f[i].start && proto <= f[i].end)
0156             return 0;
0157     }
0158 
0159     BT_DBG("BNEP: filtered skb %p, proto 0x%.4x", skb, proto);
0160     return 1;
0161 }
0162 #endif
0163 
0164 static netdev_tx_t bnep_net_xmit(struct sk_buff *skb,
0165                  struct net_device *dev)
0166 {
0167     struct bnep_session *s = netdev_priv(dev);
0168     struct sock *sk = s->sock->sk;
0169 
0170     BT_DBG("skb %p, dev %p", skb, dev);
0171 
0172 #ifdef CONFIG_BT_BNEP_MC_FILTER
0173     if (bnep_net_mc_filter(skb, s)) {
0174         kfree_skb(skb);
0175         return NETDEV_TX_OK;
0176     }
0177 #endif
0178 
0179 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
0180     if (bnep_net_proto_filter(skb, s)) {
0181         kfree_skb(skb);
0182         return NETDEV_TX_OK;
0183     }
0184 #endif
0185 
0186     /*
0187      * We cannot send L2CAP packets from here as we are potentially in a bh.
0188      * So we have to queue them and wake up session thread which is sleeping
0189      * on the sk_sleep(sk).
0190      */
0191     netif_trans_update(dev);
0192     skb_queue_tail(&sk->sk_write_queue, skb);
0193     wake_up_interruptible(sk_sleep(sk));
0194 
0195     if (skb_queue_len(&sk->sk_write_queue) >= BNEP_TX_QUEUE_LEN) {
0196         BT_DBG("tx queue is full");
0197 
0198         /* Stop queuing.
0199          * Session thread will do netif_wake_queue() */
0200         netif_stop_queue(dev);
0201     }
0202 
0203     return NETDEV_TX_OK;
0204 }
0205 
0206 static const struct net_device_ops bnep_netdev_ops = {
0207     .ndo_open            = bnep_net_open,
0208     .ndo_stop            = bnep_net_close,
0209     .ndo_start_xmit      = bnep_net_xmit,
0210     .ndo_validate_addr   = eth_validate_addr,
0211     .ndo_set_rx_mode     = bnep_net_set_mc_list,
0212     .ndo_set_mac_address = bnep_net_set_mac_addr,
0213     .ndo_tx_timeout      = bnep_net_timeout,
0214 
0215 };
0216 
0217 void bnep_net_setup(struct net_device *dev)
0218 {
0219 
0220     eth_broadcast_addr(dev->broadcast);
0221     dev->addr_len = ETH_ALEN;
0222 
0223     ether_setup(dev);
0224     dev->min_mtu = 0;
0225     dev->max_mtu = ETH_MAX_MTU;
0226     dev->priv_flags &= ~IFF_TX_SKB_SHARING;
0227     dev->netdev_ops = &bnep_netdev_ops;
0228 
0229     dev->watchdog_timeo  = HZ * 2;
0230 }