hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
kernel/net/bluetooth/6lowpan.c
....@@ -1,14 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 Copyright (c) 2013-2014 Intel Corp.
34
4
- This program is free software; you can redistribute it and/or modify
5
- it under the terms of the GNU General Public License version 2 and
6
- only version 2 as published by the Free Software Foundation.
7
-
8
- This program is distributed in the hope that it will be useful,
9
- but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- GNU General Public License for more details.
125 */
136
147 #include <linux/if_arp.h>
....@@ -168,24 +161,13 @@
168161 struct in6_addr *daddr,
169162 struct sk_buff *skb)
170163 {
171
- struct lowpan_peer *peer;
172
- struct in6_addr *nexthop;
173164 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
174165 int count = atomic_read(&dev->peer_count);
166
+ const struct in6_addr *nexthop;
167
+ struct lowpan_peer *peer;
168
+ struct neighbour *neigh;
175169
176170 BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt);
177
-
178
- /* If we have multiple 6lowpan peers, then check where we should
179
- * send the packet. If only one peer exists, then we can send the
180
- * packet right away.
181
- */
182
- if (count == 1) {
183
- rcu_read_lock();
184
- peer = list_first_or_null_rcu(&dev->peers, struct lowpan_peer,
185
- list);
186
- rcu_read_unlock();
187
- return peer;
188
- }
189171
190172 if (!rt) {
191173 if (ipv6_addr_any(&lowpan_cb(skb)->gw)) {
....@@ -221,6 +203,20 @@
221203 rcu_read_unlock();
222204 return peer;
223205 }
206
+ }
207
+
208
+ /* use the neighbour cache for matching addresses assigned by SLAAC
209
+ */
210
+ neigh = __ipv6_neigh_lookup(dev->netdev, nexthop);
211
+ if (neigh) {
212
+ list_for_each_entry_rcu(peer, &dev->peers, list) {
213
+ if (!memcmp(neigh->ha, peer->lladdr, ETH_ALEN)) {
214
+ neigh_release(neigh);
215
+ rcu_read_unlock();
216
+ return peer;
217
+ }
218
+ }
219
+ neigh_release(neigh);
224220 }
225221
226222 rcu_read_unlock();
....@@ -474,7 +470,7 @@
474470 iv.iov_len = skb->len;
475471
476472 memset(&msg, 0, sizeof(msg));
477
- iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &iv, 1, skb->len);
473
+ iov_iter_kvec(&msg.msg_iter, WRITE, &iv, 1, skb->len);
478474
479475 err = l2cap_chan_send(chan, &msg, skb->len);
480476 if (err > 0) {
....@@ -588,7 +584,7 @@
588584 .ndo_start_xmit = bt_xmit,
589585 };
590586
591
-static struct header_ops header_ops = {
587
+static const struct header_ops header_ops = {
592588 .create = header_create,
593589 };
594590
....@@ -614,7 +610,7 @@
614610 int err;
615611
616612 rtnl_lock();
617
- err = dev_open(netdev);
613
+ err = dev_open(netdev, NULL);
618614 if (err < 0)
619615 BT_INFO("iface %s cannot be opened (%d)", netdev->name, err);
620616 rtnl_unlock();
....@@ -1014,6 +1010,7 @@
10141010 hci_dev_lock(hdev);
10151011 hcon = hci_conn_hash_lookup_le(hdev, addr, *addr_type);
10161012 hci_dev_unlock(hdev);
1013
+ hci_dev_put(hdev);
10171014
10181015 if (!hcon)
10191016 return -ENOENT;
....@@ -1117,8 +1114,8 @@
11171114 return 0;
11181115 }
11191116
1120
-DEFINE_SIMPLE_ATTRIBUTE(lowpan_enable_fops, lowpan_enable_get,
1121
- lowpan_enable_set, "%llu\n");
1117
+DEFINE_DEBUGFS_ATTRIBUTE(lowpan_enable_fops, lowpan_enable_get,
1118
+ lowpan_enable_set, "%llu\n");
11221119
11231120 static ssize_t lowpan_control_write(struct file *fp,
11241121 const char __user *user_buffer,
....@@ -1289,9 +1286,10 @@
12891286
12901287 static int __init bt_6lowpan_init(void)
12911288 {
1292
- lowpan_enable_debugfs = debugfs_create_file("6lowpan_enable", 0644,
1293
- bt_debugfs, NULL,
1294
- &lowpan_enable_fops);
1289
+ lowpan_enable_debugfs = debugfs_create_file_unsafe("6lowpan_enable",
1290
+ 0644, bt_debugfs,
1291
+ NULL,
1292
+ &lowpan_enable_fops);
12951293 lowpan_control_debugfs = debugfs_create_file("6lowpan_control", 0644,
12961294 bt_debugfs, NULL,
12971295 &lowpan_control_fops);