diff options
author | David S. Miller <davem@davemloft.net> | 2016-04-26 13:15:56 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-04-26 13:15:56 -0400 |
commit | c0b04793076167c8d8aade4c31fe06a4cc45b626 (patch) | |
tree | f00ecf6720c7b4c5c742c0080e80a809cf5abffb /net/bluetooth | |
parent | 9c9f261d6e3b1084816e9e2df794a55df16e7387 (diff) | |
parent | 55441070ca1cbd47ce1ad2959bbf4b47aed9b83b (diff) |
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says:
====================
pull request: bluetooth-next 2016-04-26
Here's another set of Bluetooth & 802.15.4 patches for the 4.7 kernel:
- Cleanups & refactoring of ieee802154 & 6lowpan code
- Security related additions to ieee802154 and mrf24j40 driver
- Memory corruption fix to Bluetooth 6lowpan code
- Race condition fix in vhci driver
- Enhancements to the atusb 802.15.4 driver
Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/6lowpan.c | 93 |
1 files changed, 47 insertions, 46 deletions
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 8a4cc2f7f0db..780089d75915 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c | |||
@@ -68,7 +68,7 @@ struct lowpan_peer { | |||
68 | struct in6_addr peer_addr; | 68 | struct in6_addr peer_addr; |
69 | }; | 69 | }; |
70 | 70 | ||
71 | struct lowpan_dev { | 71 | struct lowpan_btle_dev { |
72 | struct list_head list; | 72 | struct list_head list; |
73 | 73 | ||
74 | struct hci_dev *hdev; | 74 | struct hci_dev *hdev; |
@@ -80,18 +80,21 @@ struct lowpan_dev { | |||
80 | struct delayed_work notify_peers; | 80 | struct delayed_work notify_peers; |
81 | }; | 81 | }; |
82 | 82 | ||
83 | static inline struct lowpan_dev *lowpan_dev(const struct net_device *netdev) | 83 | static inline struct lowpan_btle_dev * |
84 | lowpan_btle_dev(const struct net_device *netdev) | ||
84 | { | 85 | { |
85 | return (struct lowpan_dev *)lowpan_priv(netdev)->priv; | 86 | return (struct lowpan_btle_dev *)lowpan_dev(netdev)->priv; |
86 | } | 87 | } |
87 | 88 | ||
88 | static inline void peer_add(struct lowpan_dev *dev, struct lowpan_peer *peer) | 89 | static inline void peer_add(struct lowpan_btle_dev *dev, |
90 | struct lowpan_peer *peer) | ||
89 | { | 91 | { |
90 | list_add_rcu(&peer->list, &dev->peers); | 92 | list_add_rcu(&peer->list, &dev->peers); |
91 | atomic_inc(&dev->peer_count); | 93 | atomic_inc(&dev->peer_count); |
92 | } | 94 | } |
93 | 95 | ||
94 | static inline bool peer_del(struct lowpan_dev *dev, struct lowpan_peer *peer) | 96 | static inline bool peer_del(struct lowpan_btle_dev *dev, |
97 | struct lowpan_peer *peer) | ||
95 | { | 98 | { |
96 | list_del_rcu(&peer->list); | 99 | list_del_rcu(&peer->list); |
97 | kfree_rcu(peer, rcu); | 100 | kfree_rcu(peer, rcu); |
@@ -106,7 +109,7 @@ static inline bool peer_del(struct lowpan_dev *dev, struct lowpan_peer *peer) | |||
106 | return false; | 109 | return false; |
107 | } | 110 | } |
108 | 111 | ||
109 | static inline struct lowpan_peer *peer_lookup_ba(struct lowpan_dev *dev, | 112 | static inline struct lowpan_peer *peer_lookup_ba(struct lowpan_btle_dev *dev, |
110 | bdaddr_t *ba, __u8 type) | 113 | bdaddr_t *ba, __u8 type) |
111 | { | 114 | { |
112 | struct lowpan_peer *peer; | 115 | struct lowpan_peer *peer; |
@@ -134,8 +137,8 @@ static inline struct lowpan_peer *peer_lookup_ba(struct lowpan_dev *dev, | |||
134 | return NULL; | 137 | return NULL; |
135 | } | 138 | } |
136 | 139 | ||
137 | static inline struct lowpan_peer *__peer_lookup_chan(struct lowpan_dev *dev, | 140 | static inline struct lowpan_peer * |
138 | struct l2cap_chan *chan) | 141 | __peer_lookup_chan(struct lowpan_btle_dev *dev, struct l2cap_chan *chan) |
139 | { | 142 | { |
140 | struct lowpan_peer *peer; | 143 | struct lowpan_peer *peer; |
141 | 144 | ||
@@ -147,8 +150,8 @@ static inline struct lowpan_peer *__peer_lookup_chan(struct lowpan_dev *dev, | |||
147 | return NULL; | 150 | return NULL; |
148 | } | 151 | } |
149 | 152 | ||
150 | static inline struct lowpan_peer *__peer_lookup_conn(struct lowpan_dev *dev, | 153 | static inline struct lowpan_peer * |
151 | struct l2cap_conn *conn) | 154 | __peer_lookup_conn(struct lowpan_btle_dev *dev, struct l2cap_conn *conn) |
152 | { | 155 | { |
153 | struct lowpan_peer *peer; | 156 | struct lowpan_peer *peer; |
154 | 157 | ||
@@ -160,7 +163,7 @@ static inline struct lowpan_peer *__peer_lookup_conn(struct lowpan_dev *dev, | |||
160 | return NULL; | 163 | return NULL; |
161 | } | 164 | } |
162 | 165 | ||
163 | static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_dev *dev, | 166 | static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev, |
164 | struct in6_addr *daddr, | 167 | struct in6_addr *daddr, |
165 | struct sk_buff *skb) | 168 | struct sk_buff *skb) |
166 | { | 169 | { |
@@ -220,7 +223,7 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_dev *dev, | |||
220 | 223 | ||
221 | static struct lowpan_peer *lookup_peer(struct l2cap_conn *conn) | 224 | static struct lowpan_peer *lookup_peer(struct l2cap_conn *conn) |
222 | { | 225 | { |
223 | struct lowpan_dev *entry; | 226 | struct lowpan_btle_dev *entry; |
224 | struct lowpan_peer *peer = NULL; | 227 | struct lowpan_peer *peer = NULL; |
225 | 228 | ||
226 | rcu_read_lock(); | 229 | rcu_read_lock(); |
@@ -236,10 +239,10 @@ static struct lowpan_peer *lookup_peer(struct l2cap_conn *conn) | |||
236 | return peer; | 239 | return peer; |
237 | } | 240 | } |
238 | 241 | ||
239 | static struct lowpan_dev *lookup_dev(struct l2cap_conn *conn) | 242 | static struct lowpan_btle_dev *lookup_dev(struct l2cap_conn *conn) |
240 | { | 243 | { |
241 | struct lowpan_dev *entry; | 244 | struct lowpan_btle_dev *entry; |
242 | struct lowpan_dev *dev = NULL; | 245 | struct lowpan_btle_dev *dev = NULL; |
243 | 246 | ||
244 | rcu_read_lock(); | 247 | rcu_read_lock(); |
245 | 248 | ||
@@ -270,10 +273,10 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, | |||
270 | struct l2cap_chan *chan) | 273 | struct l2cap_chan *chan) |
271 | { | 274 | { |
272 | const u8 *saddr, *daddr; | 275 | const u8 *saddr, *daddr; |
273 | struct lowpan_dev *dev; | 276 | struct lowpan_btle_dev *dev; |
274 | struct lowpan_peer *peer; | 277 | struct lowpan_peer *peer; |
275 | 278 | ||
276 | dev = lowpan_dev(netdev); | 279 | dev = lowpan_btle_dev(netdev); |
277 | 280 | ||
278 | rcu_read_lock(); | 281 | rcu_read_lock(); |
279 | peer = __peer_lookup_chan(dev, chan); | 282 | peer = __peer_lookup_chan(dev, chan); |
@@ -375,7 +378,7 @@ drop: | |||
375 | /* Packet from BT LE device */ | 378 | /* Packet from BT LE device */ |
376 | static int chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) | 379 | static int chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) |
377 | { | 380 | { |
378 | struct lowpan_dev *dev; | 381 | struct lowpan_btle_dev *dev; |
379 | struct lowpan_peer *peer; | 382 | struct lowpan_peer *peer; |
380 | int err; | 383 | int err; |
381 | 384 | ||
@@ -431,15 +434,18 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev, | |||
431 | bdaddr_t *peer_addr, u8 *peer_addr_type) | 434 | bdaddr_t *peer_addr, u8 *peer_addr_type) |
432 | { | 435 | { |
433 | struct in6_addr ipv6_daddr; | 436 | struct in6_addr ipv6_daddr; |
434 | struct lowpan_dev *dev; | 437 | struct ipv6hdr *hdr; |
438 | struct lowpan_btle_dev *dev; | ||
435 | struct lowpan_peer *peer; | 439 | struct lowpan_peer *peer; |
436 | bdaddr_t addr, *any = BDADDR_ANY; | 440 | bdaddr_t addr, *any = BDADDR_ANY; |
437 | u8 *daddr = any->b; | 441 | u8 *daddr = any->b; |
438 | int err, status = 0; | 442 | int err, status = 0; |
439 | 443 | ||
440 | dev = lowpan_dev(netdev); | 444 | hdr = ipv6_hdr(skb); |
445 | |||
446 | dev = lowpan_btle_dev(netdev); | ||
441 | 447 | ||
442 | memcpy(&ipv6_daddr, &lowpan_cb(skb)->addr, sizeof(ipv6_daddr)); | 448 | memcpy(&ipv6_daddr, &hdr->daddr, sizeof(ipv6_daddr)); |
443 | 449 | ||
444 | if (ipv6_addr_is_multicast(&ipv6_daddr)) { | 450 | if (ipv6_addr_is_multicast(&ipv6_daddr)) { |
445 | lowpan_cb(skb)->chan = NULL; | 451 | lowpan_cb(skb)->chan = NULL; |
@@ -489,15 +495,9 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev, | |||
489 | unsigned short type, const void *_daddr, | 495 | unsigned short type, const void *_daddr, |
490 | const void *_saddr, unsigned int len) | 496 | const void *_saddr, unsigned int len) |
491 | { | 497 | { |
492 | struct ipv6hdr *hdr; | ||
493 | |||
494 | if (type != ETH_P_IPV6) | 498 | if (type != ETH_P_IPV6) |
495 | return -EINVAL; | 499 | return -EINVAL; |
496 | 500 | ||
497 | hdr = ipv6_hdr(skb); | ||
498 | |||
499 | memcpy(&lowpan_cb(skb)->addr, &hdr->daddr, sizeof(struct in6_addr)); | ||
500 | |||
501 | return 0; | 501 | return 0; |
502 | } | 502 | } |
503 | 503 | ||
@@ -543,19 +543,19 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb, | |||
543 | static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) | 543 | static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) |
544 | { | 544 | { |
545 | struct sk_buff *local_skb; | 545 | struct sk_buff *local_skb; |
546 | struct lowpan_dev *entry; | 546 | struct lowpan_btle_dev *entry; |
547 | int err = 0; | 547 | int err = 0; |
548 | 548 | ||
549 | rcu_read_lock(); | 549 | rcu_read_lock(); |
550 | 550 | ||
551 | list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { | 551 | list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { |
552 | struct lowpan_peer *pentry; | 552 | struct lowpan_peer *pentry; |
553 | struct lowpan_dev *dev; | 553 | struct lowpan_btle_dev *dev; |
554 | 554 | ||
555 | if (entry->netdev != netdev) | 555 | if (entry->netdev != netdev) |
556 | continue; | 556 | continue; |
557 | 557 | ||
558 | dev = lowpan_dev(entry->netdev); | 558 | dev = lowpan_btle_dev(entry->netdev); |
559 | 559 | ||
560 | list_for_each_entry_rcu(pentry, &dev->peers, list) { | 560 | list_for_each_entry_rcu(pentry, &dev->peers, list) { |
561 | int ret; | 561 | int ret; |
@@ -723,8 +723,8 @@ static void ifdown(struct net_device *netdev) | |||
723 | 723 | ||
724 | static void do_notify_peers(struct work_struct *work) | 724 | static void do_notify_peers(struct work_struct *work) |
725 | { | 725 | { |
726 | struct lowpan_dev *dev = container_of(work, struct lowpan_dev, | 726 | struct lowpan_btle_dev *dev = container_of(work, struct lowpan_btle_dev, |
727 | notify_peers.work); | 727 | notify_peers.work); |
728 | 728 | ||
729 | netdev_notify_peers(dev->netdev); /* send neighbour adv at startup */ | 729 | netdev_notify_peers(dev->netdev); /* send neighbour adv at startup */ |
730 | } | 730 | } |
@@ -766,7 +766,7 @@ static void set_ip_addr_bits(u8 addr_type, u8 *addr) | |||
766 | } | 766 | } |
767 | 767 | ||
768 | static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, | 768 | static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, |
769 | struct lowpan_dev *dev) | 769 | struct lowpan_btle_dev *dev) |
770 | { | 770 | { |
771 | struct lowpan_peer *peer; | 771 | struct lowpan_peer *peer; |
772 | 772 | ||
@@ -803,12 +803,12 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, | |||
803 | return peer->chan; | 803 | return peer->chan; |
804 | } | 804 | } |
805 | 805 | ||
806 | static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev) | 806 | static int setup_netdev(struct l2cap_chan *chan, struct lowpan_btle_dev **dev) |
807 | { | 807 | { |
808 | struct net_device *netdev; | 808 | struct net_device *netdev; |
809 | int err = 0; | 809 | int err = 0; |
810 | 810 | ||
811 | netdev = alloc_netdev(LOWPAN_PRIV_SIZE(sizeof(struct lowpan_dev)), | 811 | netdev = alloc_netdev(LOWPAN_PRIV_SIZE(sizeof(struct lowpan_btle_dev)), |
812 | IFACE_NAME_TEMPLATE, NET_NAME_UNKNOWN, | 812 | IFACE_NAME_TEMPLATE, NET_NAME_UNKNOWN, |
813 | netdev_setup); | 813 | netdev_setup); |
814 | if (!netdev) | 814 | if (!netdev) |
@@ -820,7 +820,7 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev) | |||
820 | SET_NETDEV_DEV(netdev, &chan->conn->hcon->hdev->dev); | 820 | SET_NETDEV_DEV(netdev, &chan->conn->hcon->hdev->dev); |
821 | SET_NETDEV_DEVTYPE(netdev, &bt_type); | 821 | SET_NETDEV_DEVTYPE(netdev, &bt_type); |
822 | 822 | ||
823 | *dev = lowpan_dev(netdev); | 823 | *dev = lowpan_btle_dev(netdev); |
824 | (*dev)->netdev = netdev; | 824 | (*dev)->netdev = netdev; |
825 | (*dev)->hdev = chan->conn->hcon->hdev; | 825 | (*dev)->hdev = chan->conn->hcon->hdev; |
826 | INIT_LIST_HEAD(&(*dev)->peers); | 826 | INIT_LIST_HEAD(&(*dev)->peers); |
@@ -853,7 +853,7 @@ out: | |||
853 | 853 | ||
854 | static inline void chan_ready_cb(struct l2cap_chan *chan) | 854 | static inline void chan_ready_cb(struct l2cap_chan *chan) |
855 | { | 855 | { |
856 | struct lowpan_dev *dev; | 856 | struct lowpan_btle_dev *dev; |
857 | 857 | ||
858 | dev = lookup_dev(chan->conn); | 858 | dev = lookup_dev(chan->conn); |
859 | 859 | ||
@@ -890,8 +890,9 @@ static inline struct l2cap_chan *chan_new_conn_cb(struct l2cap_chan *pchan) | |||
890 | 890 | ||
891 | static void delete_netdev(struct work_struct *work) | 891 | static void delete_netdev(struct work_struct *work) |
892 | { | 892 | { |
893 | struct lowpan_dev *entry = container_of(work, struct lowpan_dev, | 893 | struct lowpan_btle_dev *entry = container_of(work, |
894 | delete_netdev); | 894 | struct lowpan_btle_dev, |
895 | delete_netdev); | ||
895 | 896 | ||
896 | lowpan_unregister_netdev(entry->netdev); | 897 | lowpan_unregister_netdev(entry->netdev); |
897 | 898 | ||
@@ -900,8 +901,8 @@ static void delete_netdev(struct work_struct *work) | |||
900 | 901 | ||
901 | static void chan_close_cb(struct l2cap_chan *chan) | 902 | static void chan_close_cb(struct l2cap_chan *chan) |
902 | { | 903 | { |
903 | struct lowpan_dev *entry; | 904 | struct lowpan_btle_dev *entry; |
904 | struct lowpan_dev *dev = NULL; | 905 | struct lowpan_btle_dev *dev = NULL; |
905 | struct lowpan_peer *peer; | 906 | struct lowpan_peer *peer; |
906 | int err = -ENOENT; | 907 | int err = -ENOENT; |
907 | bool last = false, remove = true; | 908 | bool last = false, remove = true; |
@@ -921,7 +922,7 @@ static void chan_close_cb(struct l2cap_chan *chan) | |||
921 | spin_lock(&devices_lock); | 922 | spin_lock(&devices_lock); |
922 | 923 | ||
923 | list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { | 924 | list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { |
924 | dev = lowpan_dev(entry->netdev); | 925 | dev = lowpan_btle_dev(entry->netdev); |
925 | peer = __peer_lookup_chan(dev, chan); | 926 | peer = __peer_lookup_chan(dev, chan); |
926 | if (peer) { | 927 | if (peer) { |
927 | last = peer_del(dev, peer); | 928 | last = peer_del(dev, peer); |
@@ -1131,7 +1132,7 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type, | |||
1131 | 1132 | ||
1132 | static void disconnect_all_peers(void) | 1133 | static void disconnect_all_peers(void) |
1133 | { | 1134 | { |
1134 | struct lowpan_dev *entry; | 1135 | struct lowpan_btle_dev *entry; |
1135 | struct lowpan_peer *peer, *tmp_peer, *new_peer; | 1136 | struct lowpan_peer *peer, *tmp_peer, *new_peer; |
1136 | struct list_head peers; | 1137 | struct list_head peers; |
1137 | 1138 | ||
@@ -1291,7 +1292,7 @@ static ssize_t lowpan_control_write(struct file *fp, | |||
1291 | 1292 | ||
1292 | static int lowpan_control_show(struct seq_file *f, void *ptr) | 1293 | static int lowpan_control_show(struct seq_file *f, void *ptr) |
1293 | { | 1294 | { |
1294 | struct lowpan_dev *entry; | 1295 | struct lowpan_btle_dev *entry; |
1295 | struct lowpan_peer *peer; | 1296 | struct lowpan_peer *peer; |
1296 | 1297 | ||
1297 | spin_lock(&devices_lock); | 1298 | spin_lock(&devices_lock); |
@@ -1322,7 +1323,7 @@ static const struct file_operations lowpan_control_fops = { | |||
1322 | 1323 | ||
1323 | static void disconnect_devices(void) | 1324 | static void disconnect_devices(void) |
1324 | { | 1325 | { |
1325 | struct lowpan_dev *entry, *tmp, *new_dev; | 1326 | struct lowpan_btle_dev *entry, *tmp, *new_dev; |
1326 | struct list_head devices; | 1327 | struct list_head devices; |
1327 | 1328 | ||
1328 | INIT_LIST_HEAD(&devices); | 1329 | INIT_LIST_HEAD(&devices); |
@@ -1360,7 +1361,7 @@ static int device_event(struct notifier_block *unused, | |||
1360 | unsigned long event, void *ptr) | 1361 | unsigned long event, void *ptr) |
1361 | { | 1362 | { |
1362 | struct net_device *netdev = netdev_notifier_info_to_dev(ptr); | 1363 | struct net_device *netdev = netdev_notifier_info_to_dev(ptr); |
1363 | struct lowpan_dev *entry; | 1364 | struct lowpan_btle_dev *entry; |
1364 | 1365 | ||
1365 | if (netdev->type != ARPHRD_6LOWPAN) | 1366 | if (netdev->type != ARPHRD_6LOWPAN) |
1366 | return NOTIFY_DONE; | 1367 | return NOTIFY_DONE; |