aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/hci_core.h2
-rw-r--r--include/net/netns/ieee802154_6lowpan.h1
-rw-r--r--net/bluetooth/hci_conn.c8
-rw-r--r--net/bluetooth/hci_core.c14
-rw-r--r--net/bluetooth/hci_event.c17
-rw-r--r--net/ieee802154/6lowpan_rtnl.c4
-rw-r--r--net/ieee802154/reassembly.c15
-rw-r--r--net/mac802154/wpan.c6
8 files changed, 47 insertions, 20 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index b5d5af3aa469..6f884e6c731e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -464,6 +464,8 @@ struct hci_conn_params {
464 HCI_AUTO_CONN_ALWAYS, 464 HCI_AUTO_CONN_ALWAYS,
465 HCI_AUTO_CONN_LINK_LOSS, 465 HCI_AUTO_CONN_LINK_LOSS,
466 } auto_connect; 466 } auto_connect;
467
468 struct hci_conn *conn;
467}; 469};
468 470
469extern struct list_head hci_dev_list; 471extern struct list_head hci_dev_list;
diff --git a/include/net/netns/ieee802154_6lowpan.h b/include/net/netns/ieee802154_6lowpan.h
index e2070960bac0..8170f8d7052b 100644
--- a/include/net/netns/ieee802154_6lowpan.h
+++ b/include/net/netns/ieee802154_6lowpan.h
@@ -16,7 +16,6 @@ struct netns_sysctl_lowpan {
16struct netns_ieee802154_lowpan { 16struct netns_ieee802154_lowpan {
17 struct netns_sysctl_lowpan sysctl; 17 struct netns_sysctl_lowpan sysctl;
18 struct netns_frags frags; 18 struct netns_frags frags;
19 int max_dsize;
20}; 19};
21 20
22#endif 21#endif
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index b50dabb3f86a..faff6247ac8f 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -589,6 +589,14 @@ EXPORT_SYMBOL(hci_get_route);
589void hci_le_conn_failed(struct hci_conn *conn, u8 status) 589void hci_le_conn_failed(struct hci_conn *conn, u8 status)
590{ 590{
591 struct hci_dev *hdev = conn->hdev; 591 struct hci_dev *hdev = conn->hdev;
592 struct hci_conn_params *params;
593
594 params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst,
595 conn->dst_type);
596 if (params && params->conn) {
597 hci_conn_drop(params->conn);
598 params->conn = NULL;
599 }
592 600
593 conn->state = BT_CLOSED; 601 conn->state = BT_CLOSED;
594 602
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index c32d361c0cf7..1d9c29a00568 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2536,8 +2536,13 @@ static void hci_pend_le_actions_clear(struct hci_dev *hdev)
2536{ 2536{
2537 struct hci_conn_params *p; 2537 struct hci_conn_params *p;
2538 2538
2539 list_for_each_entry(p, &hdev->le_conn_params, list) 2539 list_for_each_entry(p, &hdev->le_conn_params, list) {
2540 if (p->conn) {
2541 hci_conn_drop(p->conn);
2542 p->conn = NULL;
2543 }
2540 list_del_init(&p->action); 2544 list_del_init(&p->action);
2545 }
2541 2546
2542 BT_DBG("All LE pending actions cleared"); 2547 BT_DBG("All LE pending actions cleared");
2543} 2548}
@@ -2578,8 +2583,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
2578 2583
2579 hci_dev_lock(hdev); 2584 hci_dev_lock(hdev);
2580 hci_inquiry_cache_flush(hdev); 2585 hci_inquiry_cache_flush(hdev);
2581 hci_conn_hash_flush(hdev);
2582 hci_pend_le_actions_clear(hdev); 2586 hci_pend_le_actions_clear(hdev);
2587 hci_conn_hash_flush(hdev);
2583 hci_dev_unlock(hdev); 2588 hci_dev_unlock(hdev);
2584 2589
2585 hci_notify(hdev, HCI_DEV_DOWN); 2590 hci_notify(hdev, HCI_DEV_DOWN);
@@ -3727,6 +3732,9 @@ void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
3727 if (!params) 3732 if (!params)
3728 return; 3733 return;
3729 3734
3735 if (params->conn)
3736 hci_conn_drop(params->conn);
3737
3730 list_del(&params->action); 3738 list_del(&params->action);
3731 list_del(&params->list); 3739 list_del(&params->list);
3732 kfree(params); 3740 kfree(params);
@@ -3757,6 +3765,8 @@ void hci_conn_params_clear_all(struct hci_dev *hdev)
3757 struct hci_conn_params *params, *tmp; 3765 struct hci_conn_params *params, *tmp;
3758 3766
3759 list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 3767 list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
3768 if (params->conn)
3769 hci_conn_drop(params->conn);
3760 list_del(&params->action); 3770 list_del(&params->action);
3761 list_del(&params->list); 3771 list_del(&params->list);
3762 kfree(params); 3772 kfree(params);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index be35598984d9..a6000823f0ff 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -4221,8 +4221,13 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
4221 hci_proto_connect_cfm(conn, ev->status); 4221 hci_proto_connect_cfm(conn, ev->status);
4222 4222
4223 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); 4223 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
4224 if (params) 4224 if (params) {
4225 list_del_init(&params->action); 4225 list_del_init(&params->action);
4226 if (params->conn) {
4227 hci_conn_drop(params->conn);
4228 params->conn = NULL;
4229 }
4230 }
4226 4231
4227unlock: 4232unlock:
4228 hci_update_background_scan(hdev); 4233 hci_update_background_scan(hdev);
@@ -4304,8 +4309,16 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4304 4309
4305 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, 4310 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
4306 HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER); 4311 HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER);
4307 if (!IS_ERR(conn)) 4312 if (!IS_ERR(conn)) {
4313 /* Store the pointer since we don't really have any
4314 * other owner of the object besides the params that
4315 * triggered it. This way we can abort the connection if
4316 * the parameters get removed and keep the reference
4317 * count consistent once the connection is established.
4318 */
4319 params->conn = conn;
4308 return; 4320 return;
4321 }
4309 4322
4310 switch (PTR_ERR(conn)) { 4323 switch (PTR_ERR(conn)) {
4311 case -EBUSY: 4324 case -EBUSY:
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
index 016b77ee88f0..6591d27e53a4 100644
--- a/net/ieee802154/6lowpan_rtnl.c
+++ b/net/ieee802154/6lowpan_rtnl.c
@@ -246,7 +246,7 @@ lowpan_alloc_frag(struct sk_buff *skb, int size,
246 return ERR_PTR(-rc); 246 return ERR_PTR(-rc);
247 } 247 }
248 } else { 248 } else {
249 frag = ERR_PTR(ENOMEM); 249 frag = ERR_PTR(-ENOMEM);
250 } 250 }
251 251
252 return frag; 252 return frag;
@@ -437,7 +437,7 @@ static void lowpan_setup(struct net_device *dev)
437 /* Frame Control + Sequence Number + Address fields + Security Header */ 437 /* Frame Control + Sequence Number + Address fields + Security Header */
438 dev->hard_header_len = 2 + 1 + 20 + 14; 438 dev->hard_header_len = 2 + 1 + 20 + 14;
439 dev->needed_tailroom = 2; /* FCS */ 439 dev->needed_tailroom = 2; /* FCS */
440 dev->mtu = 1281; 440 dev->mtu = IPV6_MIN_MTU;
441 dev->tx_queue_len = 0; 441 dev->tx_queue_len = 0;
442 dev->flags = IFF_BROADCAST | IFF_MULTICAST; 442 dev->flags = IFF_BROADCAST | IFF_MULTICAST;
443 dev->watchdog_timeo = 0; 443 dev->watchdog_timeo = 0;
diff --git a/net/ieee802154/reassembly.c b/net/ieee802154/reassembly.c
index ffec6ce51005..32755cb7e64e 100644
--- a/net/ieee802154/reassembly.c
+++ b/net/ieee802154/reassembly.c
@@ -355,8 +355,6 @@ int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type)
355 struct net *net = dev_net(skb->dev); 355 struct net *net = dev_net(skb->dev);
356 struct lowpan_frag_info *frag_info = lowpan_cb(skb); 356 struct lowpan_frag_info *frag_info = lowpan_cb(skb);
357 struct ieee802154_addr source, dest; 357 struct ieee802154_addr source, dest;
358 struct netns_ieee802154_lowpan *ieee802154_lowpan =
359 net_ieee802154_lowpan(net);
360 int err; 358 int err;
361 359
362 source = mac_cb(skb)->source; 360 source = mac_cb(skb)->source;
@@ -366,8 +364,10 @@ int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type)
366 if (err < 0) 364 if (err < 0)
367 goto err; 365 goto err;
368 366
369 if (frag_info->d_size > ieee802154_lowpan->max_dsize) 367 if (frag_info->d_size > IPV6_MIN_MTU) {
368 net_warn_ratelimited("lowpan_frag_rcv: datagram size exceeds MTU\n");
370 goto err; 369 goto err;
370 }
371 371
372 fq = fq_find(net, frag_info, &source, &dest); 372 fq = fq_find(net, frag_info, &source, &dest);
373 if (fq != NULL) { 373 if (fq != NULL) {
@@ -415,13 +415,6 @@ static struct ctl_table lowpan_frags_ns_ctl_table[] = {
415 .mode = 0644, 415 .mode = 0644,
416 .proc_handler = proc_dointvec_jiffies, 416 .proc_handler = proc_dointvec_jiffies,
417 }, 417 },
418 {
419 .procname = "6lowpanfrag_max_datagram_size",
420 .data = &init_net.ieee802154_lowpan.max_dsize,
421 .maxlen = sizeof(int),
422 .mode = 0644,
423 .proc_handler = proc_dointvec
424 },
425 { } 418 { }
426}; 419};
427 420
@@ -458,7 +451,6 @@ static int __net_init lowpan_frags_ns_sysctl_register(struct net *net)
458 table[1].data = &ieee802154_lowpan->frags.low_thresh; 451 table[1].data = &ieee802154_lowpan->frags.low_thresh;
459 table[1].extra2 = &ieee802154_lowpan->frags.high_thresh; 452 table[1].extra2 = &ieee802154_lowpan->frags.high_thresh;
460 table[2].data = &ieee802154_lowpan->frags.timeout; 453 table[2].data = &ieee802154_lowpan->frags.timeout;
461 table[3].data = &ieee802154_lowpan->max_dsize;
462 454
463 /* Don't export sysctls to unprivileged users */ 455 /* Don't export sysctls to unprivileged users */
464 if (net->user_ns != &init_user_ns) 456 if (net->user_ns != &init_user_ns)
@@ -533,7 +525,6 @@ static int __net_init lowpan_frags_init_net(struct net *net)
533 ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH; 525 ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
534 ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH; 526 ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH;
535 ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT; 527 ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT;
536 ieee802154_lowpan->max_dsize = 0xFFFF;
537 528
538 inet_frags_init_net(&ieee802154_lowpan->frags); 529 inet_frags_init_net(&ieee802154_lowpan->frags);
539 530
diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c
index 3c3069fd6971..547838822d5e 100644
--- a/net/mac802154/wpan.c
+++ b/net/mac802154/wpan.c
@@ -462,7 +462,10 @@ mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb,
462 skb->pkt_type = PACKET_OTHERHOST; 462 skb->pkt_type = PACKET_OTHERHOST;
463 break; 463 break;
464 default: 464 default:
465 break; 465 spin_unlock_bh(&sdata->mib_lock);
466 pr_debug("invalid dest mode\n");
467 kfree_skb(skb);
468 return NET_RX_DROP;
466 } 469 }
467 470
468 spin_unlock_bh(&sdata->mib_lock); 471 spin_unlock_bh(&sdata->mib_lock);
@@ -573,6 +576,7 @@ void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb)
573 ret = mac802154_parse_frame_start(skb, &hdr); 576 ret = mac802154_parse_frame_start(skb, &hdr);
574 if (ret) { 577 if (ret) {
575 pr_debug("got invalid frame\n"); 578 pr_debug("got invalid frame\n");
579 kfree_skb(skb);
576 return; 580 return;
577 } 581 }
578 582