aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2014-09-08 05:11:45 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-09-09 09:51:47 -0400
commit39e90c77637b3892a39f2908aea57539e961c50e (patch)
treeea10ce3b9c648fd5d82db6e3ebcd5425648c4695 /net/bluetooth
parentb2799cec22812f5f1aaaa57133df51876f685d84 (diff)
Bluetooth: 6lowpan: Route packets that are not meant to peer via correct device
Packets that are supposed to be delivered via the peer device need to be checked and sent to correct device. This requires that user has set the routes properly so that the 6lowpan module can then figure out the destination gateway and the correct Bluetooth device. Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Cc: stable@vger.kernel.org # 3.17.x
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/6lowpan.c65
1 files changed, 63 insertions, 2 deletions
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index b229aed3bf9a..0920cb6ed572 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -39,6 +39,7 @@ static struct dentry *lowpan_control_debugfs;
39 39
40struct skb_cb { 40struct skb_cb {
41 struct in6_addr addr; 41 struct in6_addr addr;
42 struct in6_addr gw;
42 struct l2cap_chan *chan; 43 struct l2cap_chan *chan;
43 int status; 44 int status;
44}; 45};
@@ -158,6 +159,54 @@ static inline struct lowpan_peer *peer_lookup_conn(struct lowpan_dev *dev,
158 return NULL; 159 return NULL;
159} 160}
160 161
162static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_dev *dev,
163 struct in6_addr *daddr,
164 struct sk_buff *skb)
165{
166 struct lowpan_peer *peer, *tmp;
167 struct in6_addr *nexthop;
168 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
169 int count = atomic_read(&dev->peer_count);
170
171 BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt);
172
173 /* If we have multiple 6lowpan peers, then check where we should
174 * send the packet. If only one peer exists, then we can send the
175 * packet right away.
176 */
177 if (count == 1)
178 return list_first_entry(&dev->peers, struct lowpan_peer,
179 list);
180
181 if (!rt) {
182 nexthop = &lowpan_cb(skb)->gw;
183
184 if (ipv6_addr_any(nexthop))
185 return NULL;
186 } else {
187 nexthop = rt6_nexthop(rt);
188
189 /* We need to remember the address because it is needed
190 * by bt_xmit() when sending the packet. In bt_xmit(), the
191 * destination routing info is not set.
192 */
193 memcpy(&lowpan_cb(skb)->gw, nexthop, sizeof(struct in6_addr));
194 }
195
196 BT_DBG("gw %pI6c", nexthop);
197
198 list_for_each_entry_safe(peer, tmp, &dev->peers, list) {
199 BT_DBG("dst addr %pMR dst type %d ip %pI6c",
200 &peer->chan->dst, peer->chan->dst_type,
201 &peer->peer_addr);
202
203 if (!ipv6_addr_cmp(&peer->peer_addr, nexthop))
204 return peer;
205 }
206
207 return NULL;
208}
209
161static struct lowpan_peer *lookup_peer(struct l2cap_conn *conn) 210static struct lowpan_peer *lookup_peer(struct l2cap_conn *conn)
162{ 211{
163 struct lowpan_dev *entry, *tmp; 212 struct lowpan_dev *entry, *tmp;
@@ -415,8 +464,18 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev,
415 read_unlock_irqrestore(&devices_lock, flags); 464 read_unlock_irqrestore(&devices_lock, flags);
416 465
417 if (!peer) { 466 if (!peer) {
418 BT_DBG("no such peer %pMR found", &addr); 467 /* The packet might be sent to 6lowpan interface
419 return -ENOENT; 468 * because of routing (either via default route
469 * or user set route) so get peer according to
470 * the destination address.
471 */
472 read_lock_irqsave(&devices_lock, flags);
473 peer = peer_lookup_dst(dev, &hdr->daddr, skb);
474 read_unlock_irqrestore(&devices_lock, flags);
475 if (!peer) {
476 BT_DBG("no such peer %pMR found", &addr);
477 return -ENOENT;
478 }
420 } 479 }
421 480
422 daddr = peer->eui64_addr; 481 daddr = peer->eui64_addr;
@@ -520,6 +579,8 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
520 579
521 read_lock_irqsave(&devices_lock, flags); 580 read_lock_irqsave(&devices_lock, flags);
522 peer = peer_lookup_ba(dev, &addr, addr_type); 581 peer = peer_lookup_ba(dev, &addr, addr_type);
582 if (!peer)
583 peer = peer_lookup_dst(dev, &lowpan_cb(skb)->addr, skb);
523 read_unlock_irqrestore(&devices_lock, flags); 584 read_unlock_irqrestore(&devices_lock, flags);
524 585
525 BT_DBG("xmit %s to %pMR type %d IP %pI6c peer %p", 586 BT_DBG("xmit %s to %pMR type %d IP %pI6c peer %p",