.. | .. |
---|
45 | 45 | #define LE_FLOWCTL_MAX_CREDITS 65535 |
---|
46 | 46 | |
---|
47 | 47 | bool disable_ertm; |
---|
| 48 | +bool enable_ecred; |
---|
48 | 49 | |
---|
49 | 50 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD; |
---|
50 | 51 | |
---|
51 | 52 | static LIST_HEAD(chan_list); |
---|
52 | 53 | static DEFINE_RWLOCK(chan_list_lock); |
---|
53 | | - |
---|
54 | | -static u16 le_max_credits = L2CAP_LE_MAX_CREDITS; |
---|
55 | | -static u16 le_default_mps = L2CAP_LE_DEFAULT_MPS; |
---|
56 | 54 | |
---|
57 | 55 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, |
---|
58 | 56 | u8 code, u8 ident, u16 dlen, void *data); |
---|
.. | .. |
---|
63 | 61 | |
---|
64 | 62 | static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, |
---|
65 | 63 | struct sk_buff_head *skbs, u8 event); |
---|
| 64 | +static void l2cap_retrans_timeout(struct work_struct *work); |
---|
| 65 | +static void l2cap_monitor_timeout(struct work_struct *work); |
---|
| 66 | +static void l2cap_ack_timeout(struct work_struct *work); |
---|
66 | 67 | |
---|
67 | 68 | static inline u8 bdaddr_type(u8 link_type, u8 bdaddr_type) |
---|
68 | 69 | { |
---|
.. | .. |
---|
113 | 114 | } |
---|
114 | 115 | |
---|
115 | 116 | /* Find channel with given SCID. |
---|
116 | | - * Returns locked channel. */ |
---|
| 117 | + * Returns a reference locked channel. |
---|
| 118 | + */ |
---|
117 | 119 | static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, |
---|
118 | 120 | u16 cid) |
---|
119 | 121 | { |
---|
.. | .. |
---|
121 | 123 | |
---|
122 | 124 | mutex_lock(&conn->chan_lock); |
---|
123 | 125 | c = __l2cap_get_chan_by_scid(conn, cid); |
---|
124 | | - if (c) |
---|
125 | | - l2cap_chan_lock(c); |
---|
| 126 | + if (c) { |
---|
| 127 | + /* Only lock if chan reference is not 0 */ |
---|
| 128 | + c = l2cap_chan_hold_unless_zero(c); |
---|
| 129 | + if (c) |
---|
| 130 | + l2cap_chan_lock(c); |
---|
| 131 | + } |
---|
126 | 132 | mutex_unlock(&conn->chan_lock); |
---|
127 | 133 | |
---|
128 | 134 | return c; |
---|
129 | 135 | } |
---|
130 | 136 | |
---|
131 | 137 | /* Find channel with given DCID. |
---|
132 | | - * Returns locked channel. |
---|
| 138 | + * Returns a reference locked channel. |
---|
133 | 139 | */ |
---|
134 | 140 | static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn, |
---|
135 | 141 | u16 cid) |
---|
.. | .. |
---|
138 | 144 | |
---|
139 | 145 | mutex_lock(&conn->chan_lock); |
---|
140 | 146 | c = __l2cap_get_chan_by_dcid(conn, cid); |
---|
141 | | - if (c) |
---|
142 | | - l2cap_chan_lock(c); |
---|
| 147 | + if (c) { |
---|
| 148 | + /* Only lock if chan reference is not 0 */ |
---|
| 149 | + c = l2cap_chan_hold_unless_zero(c); |
---|
| 150 | + if (c) |
---|
| 151 | + l2cap_chan_lock(c); |
---|
| 152 | + } |
---|
143 | 153 | mutex_unlock(&conn->chan_lock); |
---|
144 | 154 | |
---|
145 | 155 | return c; |
---|
.. | .. |
---|
164 | 174 | |
---|
165 | 175 | mutex_lock(&conn->chan_lock); |
---|
166 | 176 | c = __l2cap_get_chan_by_ident(conn, ident); |
---|
167 | | - if (c) |
---|
168 | | - l2cap_chan_lock(c); |
---|
| 177 | + if (c) { |
---|
| 178 | + /* Only lock if chan reference is not 0 */ |
---|
| 179 | + c = l2cap_chan_hold_unless_zero(c); |
---|
| 180 | + if (c) |
---|
| 181 | + l2cap_chan_lock(c); |
---|
| 182 | + } |
---|
169 | 183 | mutex_unlock(&conn->chan_lock); |
---|
170 | 184 | |
---|
171 | 185 | return c; |
---|
172 | 186 | } |
---|
173 | 187 | |
---|
174 | | -static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src) |
---|
| 188 | +static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src, |
---|
| 189 | + u8 src_type) |
---|
175 | 190 | { |
---|
176 | 191 | struct l2cap_chan *c; |
---|
177 | 192 | |
---|
178 | 193 | list_for_each_entry(c, &chan_list, global_l) { |
---|
| 194 | + if (src_type == BDADDR_BREDR && c->src_type != BDADDR_BREDR) |
---|
| 195 | + continue; |
---|
| 196 | + |
---|
| 197 | + if (src_type != BDADDR_BREDR && c->src_type == BDADDR_BREDR) |
---|
| 198 | + continue; |
---|
| 199 | + |
---|
179 | 200 | if (c->sport == psm && !bacmp(&c->src, src)) |
---|
180 | 201 | return c; |
---|
181 | 202 | } |
---|
.. | .. |
---|
188 | 209 | |
---|
189 | 210 | write_lock(&chan_list_lock); |
---|
190 | 211 | |
---|
191 | | - if (psm && __l2cap_global_chan_by_addr(psm, src)) { |
---|
| 212 | + if (psm && __l2cap_global_chan_by_addr(psm, src, chan->src_type)) { |
---|
192 | 213 | err = -EADDRINUSE; |
---|
193 | 214 | goto done; |
---|
194 | 215 | } |
---|
.. | .. |
---|
212 | 233 | |
---|
213 | 234 | err = -EINVAL; |
---|
214 | 235 | for (p = start; p <= end; p += incr) |
---|
215 | | - if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) { |
---|
| 236 | + if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src, |
---|
| 237 | + chan->src_type)) { |
---|
216 | 238 | chan->psm = cpu_to_le16(p); |
---|
217 | 239 | chan->sport = cpu_to_le16(p); |
---|
218 | 240 | err = 0; |
---|
.. | .. |
---|
457 | 479 | write_unlock(&chan_list_lock); |
---|
458 | 480 | |
---|
459 | 481 | INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout); |
---|
| 482 | + INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout); |
---|
| 483 | + INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout); |
---|
| 484 | + INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout); |
---|
460 | 485 | |
---|
461 | 486 | chan->state = BT_OPEN; |
---|
462 | 487 | |
---|
.. | .. |
---|
491 | 516 | kref_get(&c->kref); |
---|
492 | 517 | } |
---|
493 | 518 | |
---|
| 519 | +struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c) |
---|
| 520 | +{ |
---|
| 521 | + BT_DBG("chan %p orig refcnt %u", c, kref_read(&c->kref)); |
---|
| 522 | + |
---|
| 523 | + if (!kref_get_unless_zero(&c->kref)) |
---|
| 524 | + return NULL; |
---|
| 525 | + |
---|
| 526 | + return c; |
---|
| 527 | +} |
---|
| 528 | + |
---|
494 | 529 | void l2cap_chan_put(struct l2cap_chan *c) |
---|
495 | 530 | { |
---|
496 | 531 | BT_DBG("chan %p orig refcnt %d", c, kref_read(&c->kref)); |
---|
.. | .. |
---|
520 | 555 | } |
---|
521 | 556 | EXPORT_SYMBOL_GPL(l2cap_chan_set_defaults); |
---|
522 | 557 | |
---|
523 | | -static void l2cap_le_flowctl_init(struct l2cap_chan *chan) |
---|
| 558 | +static void l2cap_le_flowctl_init(struct l2cap_chan *chan, u16 tx_credits) |
---|
524 | 559 | { |
---|
525 | 560 | chan->sdu = NULL; |
---|
526 | 561 | chan->sdu_last_frag = NULL; |
---|
527 | 562 | chan->sdu_len = 0; |
---|
528 | | - chan->tx_credits = 0; |
---|
529 | | - chan->rx_credits = le_max_credits; |
---|
530 | | - chan->mps = min_t(u16, chan->imtu, le_default_mps); |
---|
| 563 | + chan->tx_credits = tx_credits; |
---|
| 564 | + /* Derive MPS from connection MTU to stop HCI fragmentation */ |
---|
| 565 | + chan->mps = min_t(u16, chan->imtu, chan->conn->mtu - L2CAP_HDR_SIZE); |
---|
| 566 | + /* Give enough credits for a full packet */ |
---|
| 567 | + chan->rx_credits = (chan->imtu / chan->mps) + 1; |
---|
531 | 568 | |
---|
532 | 569 | skb_queue_head_init(&chan->tx_q); |
---|
| 570 | +} |
---|
| 571 | + |
---|
| 572 | +static void l2cap_ecred_init(struct l2cap_chan *chan, u16 tx_credits) |
---|
| 573 | +{ |
---|
| 574 | + l2cap_le_flowctl_init(chan, tx_credits); |
---|
| 575 | + |
---|
| 576 | + /* L2CAP implementations shall support a minimum MPS of 64 octets */ |
---|
| 577 | + if (chan->mps < L2CAP_ECRED_MIN_MPS) { |
---|
| 578 | + chan->mps = L2CAP_ECRED_MIN_MPS; |
---|
| 579 | + chan->rx_credits = (chan->imtu / chan->mps) + 1; |
---|
| 580 | + } |
---|
533 | 581 | } |
---|
534 | 582 | |
---|
535 | 583 | void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) |
---|
.. | .. |
---|
638 | 686 | break; |
---|
639 | 687 | |
---|
640 | 688 | case L2CAP_MODE_LE_FLOWCTL: |
---|
| 689 | + case L2CAP_MODE_EXT_FLOWCTL: |
---|
641 | 690 | skb_queue_purge(&chan->tx_q); |
---|
642 | 691 | break; |
---|
643 | 692 | |
---|
.. | .. |
---|
650 | 699 | |
---|
651 | 700 | l2cap_seq_list_free(&chan->srej_list); |
---|
652 | 701 | l2cap_seq_list_free(&chan->retrans_list); |
---|
653 | | - |
---|
654 | | - /* fall through */ |
---|
| 702 | + fallthrough; |
---|
655 | 703 | |
---|
656 | 704 | case L2CAP_MODE_STREAMING: |
---|
657 | 705 | skb_queue_purge(&chan->tx_q); |
---|
.. | .. |
---|
661 | 709 | return; |
---|
662 | 710 | } |
---|
663 | 711 | EXPORT_SYMBOL_GPL(l2cap_chan_del); |
---|
| 712 | + |
---|
| 713 | +static void __l2cap_chan_list_id(struct l2cap_conn *conn, u16 id, |
---|
| 714 | + l2cap_chan_func_t func, void *data) |
---|
| 715 | +{ |
---|
| 716 | + struct l2cap_chan *chan, *l; |
---|
| 717 | + |
---|
| 718 | + list_for_each_entry_safe(chan, l, &conn->chan_l, list) { |
---|
| 719 | + if (chan->ident == id) |
---|
| 720 | + func(chan, data); |
---|
| 721 | + } |
---|
| 722 | +} |
---|
| 723 | + |
---|
| 724 | +static void __l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func, |
---|
| 725 | + void *data) |
---|
| 726 | +{ |
---|
| 727 | + struct l2cap_chan *chan; |
---|
| 728 | + |
---|
| 729 | + list_for_each_entry(chan, &conn->chan_l, list) { |
---|
| 730 | + func(chan, data); |
---|
| 731 | + } |
---|
| 732 | +} |
---|
| 733 | + |
---|
| 734 | +void l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func, |
---|
| 735 | + void *data) |
---|
| 736 | +{ |
---|
| 737 | + if (!conn) |
---|
| 738 | + return; |
---|
| 739 | + |
---|
| 740 | + mutex_lock(&conn->chan_lock); |
---|
| 741 | + __l2cap_chan_list(conn, func, data); |
---|
| 742 | + mutex_unlock(&conn->chan_lock); |
---|
| 743 | +} |
---|
| 744 | + |
---|
| 745 | +EXPORT_SYMBOL_GPL(l2cap_chan_list); |
---|
664 | 746 | |
---|
665 | 747 | static void l2cap_conn_update_id_addr(struct work_struct *work) |
---|
666 | 748 | { |
---|
.. | .. |
---|
688 | 770 | u16 result; |
---|
689 | 771 | |
---|
690 | 772 | if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) |
---|
691 | | - result = L2CAP_CR_AUTHORIZATION; |
---|
| 773 | + result = L2CAP_CR_LE_AUTHORIZATION; |
---|
692 | 774 | else |
---|
693 | | - result = L2CAP_CR_BAD_PSM; |
---|
| 775 | + result = L2CAP_CR_LE_BAD_PSM; |
---|
694 | 776 | |
---|
695 | 777 | l2cap_state_change(chan, BT_DISCONN); |
---|
696 | 778 | |
---|
.. | .. |
---|
702 | 784 | |
---|
703 | 785 | l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), |
---|
704 | 786 | &rsp); |
---|
| 787 | +} |
---|
| 788 | + |
---|
| 789 | +static void l2cap_chan_ecred_connect_reject(struct l2cap_chan *chan) |
---|
| 790 | +{ |
---|
| 791 | + l2cap_state_change(chan, BT_DISCONN); |
---|
| 792 | + |
---|
| 793 | + __l2cap_ecred_conn_rsp_defer(chan); |
---|
705 | 794 | } |
---|
706 | 795 | |
---|
707 | 796 | static void l2cap_chan_connect_reject(struct l2cap_chan *chan) |
---|
.. | .. |
---|
749 | 838 | if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) { |
---|
750 | 839 | if (conn->hcon->type == ACL_LINK) |
---|
751 | 840 | l2cap_chan_connect_reject(chan); |
---|
752 | | - else if (conn->hcon->type == LE_LINK) |
---|
753 | | - l2cap_chan_le_connect_reject(chan); |
---|
| 841 | + else if (conn->hcon->type == LE_LINK) { |
---|
| 842 | + switch (chan->mode) { |
---|
| 843 | + case L2CAP_MODE_LE_FLOWCTL: |
---|
| 844 | + l2cap_chan_le_connect_reject(chan); |
---|
| 845 | + break; |
---|
| 846 | + case L2CAP_MODE_EXT_FLOWCTL: |
---|
| 847 | + l2cap_chan_ecred_connect_reject(chan); |
---|
| 848 | + return; |
---|
| 849 | + } |
---|
| 850 | + } |
---|
754 | 851 | } |
---|
755 | 852 | |
---|
756 | 853 | l2cap_chan_del(chan, reason); |
---|
.. | .. |
---|
804 | 901 | else |
---|
805 | 902 | return HCI_AT_NO_BONDING; |
---|
806 | 903 | } |
---|
807 | | - /* fall through */ |
---|
| 904 | + fallthrough; |
---|
| 905 | + |
---|
808 | 906 | default: |
---|
809 | 907 | switch (chan->sec_level) { |
---|
810 | 908 | case BT_SECURITY_HIGH: |
---|
.. | .. |
---|
1273 | 1371 | chan->conf_state = 0; |
---|
1274 | 1372 | __clear_chan_timer(chan); |
---|
1275 | 1373 | |
---|
1276 | | - if (chan->mode == L2CAP_MODE_LE_FLOWCTL && !chan->tx_credits) |
---|
1277 | | - chan->ops->suspend(chan); |
---|
| 1374 | + switch (chan->mode) { |
---|
| 1375 | + case L2CAP_MODE_LE_FLOWCTL: |
---|
| 1376 | + case L2CAP_MODE_EXT_FLOWCTL: |
---|
| 1377 | + if (!chan->tx_credits) |
---|
| 1378 | + chan->ops->suspend(chan); |
---|
| 1379 | + break; |
---|
| 1380 | + } |
---|
1278 | 1381 | |
---|
1279 | 1382 | chan->state = BT_CONNECTED; |
---|
1280 | 1383 | |
---|
.. | .. |
---|
1289 | 1392 | if (test_and_set_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags)) |
---|
1290 | 1393 | return; |
---|
1291 | 1394 | |
---|
| 1395 | + if (!chan->imtu) |
---|
| 1396 | + chan->imtu = chan->conn->mtu; |
---|
| 1397 | + |
---|
| 1398 | + l2cap_le_flowctl_init(chan, 0); |
---|
| 1399 | + |
---|
1292 | 1400 | req.psm = chan->psm; |
---|
1293 | 1401 | req.scid = cpu_to_le16(chan->scid); |
---|
1294 | 1402 | req.mtu = cpu_to_le16(chan->imtu); |
---|
.. | .. |
---|
1299 | 1407 | |
---|
1300 | 1408 | l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_REQ, |
---|
1301 | 1409 | sizeof(req), &req); |
---|
| 1410 | +} |
---|
| 1411 | + |
---|
| 1412 | +struct l2cap_ecred_conn_data { |
---|
| 1413 | + struct { |
---|
| 1414 | + struct l2cap_ecred_conn_req req; |
---|
| 1415 | + __le16 scid[5]; |
---|
| 1416 | + } __packed pdu; |
---|
| 1417 | + struct l2cap_chan *chan; |
---|
| 1418 | + struct pid *pid; |
---|
| 1419 | + int count; |
---|
| 1420 | +}; |
---|
| 1421 | + |
---|
| 1422 | +static void l2cap_ecred_defer_connect(struct l2cap_chan *chan, void *data) |
---|
| 1423 | +{ |
---|
| 1424 | + struct l2cap_ecred_conn_data *conn = data; |
---|
| 1425 | + struct pid *pid; |
---|
| 1426 | + |
---|
| 1427 | + if (chan == conn->chan) |
---|
| 1428 | + return; |
---|
| 1429 | + |
---|
| 1430 | + if (!test_and_clear_bit(FLAG_DEFER_SETUP, &chan->flags)) |
---|
| 1431 | + return; |
---|
| 1432 | + |
---|
| 1433 | + pid = chan->ops->get_peer_pid(chan); |
---|
| 1434 | + |
---|
| 1435 | + /* Only add deferred channels with the same PID/PSM */ |
---|
| 1436 | + if (conn->pid != pid || chan->psm != conn->chan->psm || chan->ident || |
---|
| 1437 | + chan->mode != L2CAP_MODE_EXT_FLOWCTL || chan->state != BT_CONNECT) |
---|
| 1438 | + return; |
---|
| 1439 | + |
---|
| 1440 | + if (test_and_set_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags)) |
---|
| 1441 | + return; |
---|
| 1442 | + |
---|
| 1443 | + l2cap_ecred_init(chan, 0); |
---|
| 1444 | + |
---|
| 1445 | + /* Set the same ident so we can match on the rsp */ |
---|
| 1446 | + chan->ident = conn->chan->ident; |
---|
| 1447 | + |
---|
| 1448 | + /* Include all channels deferred */ |
---|
| 1449 | + conn->pdu.scid[conn->count] = cpu_to_le16(chan->scid); |
---|
| 1450 | + |
---|
| 1451 | + conn->count++; |
---|
| 1452 | +} |
---|
| 1453 | + |
---|
| 1454 | +static void l2cap_ecred_connect(struct l2cap_chan *chan) |
---|
| 1455 | +{ |
---|
| 1456 | + struct l2cap_conn *conn = chan->conn; |
---|
| 1457 | + struct l2cap_ecred_conn_data data; |
---|
| 1458 | + |
---|
| 1459 | + if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) |
---|
| 1460 | + return; |
---|
| 1461 | + |
---|
| 1462 | + if (test_and_set_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags)) |
---|
| 1463 | + return; |
---|
| 1464 | + |
---|
| 1465 | + l2cap_ecred_init(chan, 0); |
---|
| 1466 | + |
---|
| 1467 | + memset(&data, 0, sizeof(data)); |
---|
| 1468 | + data.pdu.req.psm = chan->psm; |
---|
| 1469 | + data.pdu.req.mtu = cpu_to_le16(chan->imtu); |
---|
| 1470 | + data.pdu.req.mps = cpu_to_le16(chan->mps); |
---|
| 1471 | + data.pdu.req.credits = cpu_to_le16(chan->rx_credits); |
---|
| 1472 | + data.pdu.scid[0] = cpu_to_le16(chan->scid); |
---|
| 1473 | + |
---|
| 1474 | + chan->ident = l2cap_get_ident(conn); |
---|
| 1475 | + data.pid = chan->ops->get_peer_pid(chan); |
---|
| 1476 | + |
---|
| 1477 | + data.count = 1; |
---|
| 1478 | + data.chan = chan; |
---|
| 1479 | + data.pid = chan->ops->get_peer_pid(chan); |
---|
| 1480 | + |
---|
| 1481 | + __l2cap_chan_list(conn, l2cap_ecred_defer_connect, &data); |
---|
| 1482 | + |
---|
| 1483 | + l2cap_send_cmd(conn, chan->ident, L2CAP_ECRED_CONN_REQ, |
---|
| 1484 | + sizeof(data.pdu.req) + data.count * sizeof(__le16), |
---|
| 1485 | + &data.pdu); |
---|
1302 | 1486 | } |
---|
1303 | 1487 | |
---|
1304 | 1488 | static void l2cap_le_start(struct l2cap_chan *chan) |
---|
.. | .. |
---|
1313 | 1497 | return; |
---|
1314 | 1498 | } |
---|
1315 | 1499 | |
---|
1316 | | - if (chan->state == BT_CONNECT) |
---|
1317 | | - l2cap_le_connect(chan); |
---|
| 1500 | + if (chan->state == BT_CONNECT) { |
---|
| 1501 | + if (chan->mode == L2CAP_MODE_EXT_FLOWCTL) |
---|
| 1502 | + l2cap_ecred_connect(chan); |
---|
| 1503 | + else |
---|
| 1504 | + l2cap_le_connect(chan); |
---|
| 1505 | + } |
---|
1318 | 1506 | } |
---|
1319 | 1507 | |
---|
1320 | 1508 | static void l2cap_start_connection(struct l2cap_chan *chan) |
---|
.. | .. |
---|
1359 | 1547 | * actually encrypted before enforcing a key size. |
---|
1360 | 1548 | */ |
---|
1361 | 1549 | return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) || |
---|
1362 | | - hcon->enc_key_size >= HCI_MIN_ENC_KEY_SIZE); |
---|
| 1550 | + hcon->enc_key_size >= hcon->hdev->min_enc_key_size); |
---|
1363 | 1551 | } |
---|
1364 | 1552 | |
---|
1365 | 1553 | static void l2cap_do_start(struct l2cap_chan *chan) |
---|
.. | .. |
---|
1526 | 1714 | if (hcon->out) |
---|
1527 | 1715 | smp_conn_security(hcon, hcon->pending_sec_level); |
---|
1528 | 1716 | |
---|
1529 | | - /* For LE slave connections, make sure the connection interval |
---|
1530 | | - * is in the range of the minium and maximum interval that has |
---|
| 1717 | + /* For LE peripheral connections, make sure the connection interval |
---|
| 1718 | + * is in the range of the minimum and maximum interval that has |
---|
1531 | 1719 | * been configured for this connection. If not, then trigger |
---|
1532 | 1720 | * the connection update procedure. |
---|
1533 | 1721 | */ |
---|
.. | .. |
---|
1781 | 1969 | bdaddr_t *dst, |
---|
1782 | 1970 | u8 link_type) |
---|
1783 | 1971 | { |
---|
1784 | | - struct l2cap_chan *c, *c1 = NULL; |
---|
| 1972 | + struct l2cap_chan *c, *tmp, *c1 = NULL; |
---|
1785 | 1973 | |
---|
1786 | 1974 | read_lock(&chan_list_lock); |
---|
1787 | 1975 | |
---|
1788 | | - list_for_each_entry(c, &chan_list, global_l) { |
---|
| 1976 | + list_for_each_entry_safe(c, tmp, &chan_list, global_l) { |
---|
1789 | 1977 | if (state && c->state != state) |
---|
1790 | 1978 | continue; |
---|
1791 | 1979 | |
---|
.. | .. |
---|
1795 | 1983 | if (link_type == LE_LINK && c->src_type == BDADDR_BREDR) |
---|
1796 | 1984 | continue; |
---|
1797 | 1985 | |
---|
1798 | | - if (c->psm == psm) { |
---|
| 1986 | + if (c->chan_type != L2CAP_CHAN_FIXED && c->psm == psm) { |
---|
1799 | 1987 | int src_match, dst_match; |
---|
1800 | 1988 | int src_any, dst_any; |
---|
1801 | 1989 | |
---|
.. | .. |
---|
1803 | 1991 | src_match = !bacmp(&c->src, src); |
---|
1804 | 1992 | dst_match = !bacmp(&c->dst, dst); |
---|
1805 | 1993 | if (src_match && dst_match) { |
---|
1806 | | - l2cap_chan_hold(c); |
---|
| 1994 | + if (!l2cap_chan_hold_unless_zero(c)) |
---|
| 1995 | + continue; |
---|
| 1996 | + |
---|
1807 | 1997 | read_unlock(&chan_list_lock); |
---|
1808 | 1998 | return c; |
---|
1809 | 1999 | } |
---|
.. | .. |
---|
1818 | 2008 | } |
---|
1819 | 2009 | |
---|
1820 | 2010 | if (c1) |
---|
1821 | | - l2cap_chan_hold(c1); |
---|
| 2011 | + c1 = l2cap_chan_hold_unless_zero(c1); |
---|
1822 | 2012 | |
---|
1823 | 2013 | read_unlock(&chan_list_lock); |
---|
1824 | 2014 | |
---|
.. | .. |
---|
2486 | 2676 | if (IS_ERR(skb)) |
---|
2487 | 2677 | return PTR_ERR(skb); |
---|
2488 | 2678 | |
---|
2489 | | - /* Channel lock is released before requesting new skb and then |
---|
2490 | | - * reacquired thus we need to recheck channel state. |
---|
2491 | | - */ |
---|
2492 | | - if (chan->state != BT_CONNECTED) { |
---|
2493 | | - kfree_skb(skb); |
---|
2494 | | - return -ENOTCONN; |
---|
2495 | | - } |
---|
2496 | | - |
---|
2497 | 2679 | l2cap_do_send(chan, skb); |
---|
2498 | 2680 | return len; |
---|
2499 | 2681 | } |
---|
2500 | 2682 | |
---|
2501 | 2683 | switch (chan->mode) { |
---|
2502 | 2684 | case L2CAP_MODE_LE_FLOWCTL: |
---|
| 2685 | + case L2CAP_MODE_EXT_FLOWCTL: |
---|
2503 | 2686 | /* Check outgoing MTU */ |
---|
2504 | 2687 | if (len > chan->omtu) |
---|
2505 | 2688 | return -EMSGSIZE; |
---|
.. | .. |
---|
2537 | 2720 | if (IS_ERR(skb)) |
---|
2538 | 2721 | return PTR_ERR(skb); |
---|
2539 | 2722 | |
---|
2540 | | - /* Channel lock is released before requesting new skb and then |
---|
2541 | | - * reacquired thus we need to recheck channel state. |
---|
2542 | | - */ |
---|
2543 | | - if (chan->state != BT_CONNECTED) { |
---|
2544 | | - kfree_skb(skb); |
---|
2545 | | - return -ENOTCONN; |
---|
2546 | | - } |
---|
2547 | | - |
---|
2548 | 2723 | l2cap_do_send(chan, skb); |
---|
2549 | 2724 | err = len; |
---|
2550 | 2725 | break; |
---|
.. | .. |
---|
2564 | 2739 | * allocation. |
---|
2565 | 2740 | */ |
---|
2566 | 2741 | err = l2cap_segment_sdu(chan, &seg_queue, msg, len); |
---|
2567 | | - |
---|
2568 | | - /* The channel could have been closed while segmenting, |
---|
2569 | | - * check that it is still connected. |
---|
2570 | | - */ |
---|
2571 | | - if (chan->state != BT_CONNECTED) { |
---|
2572 | | - __skb_queue_purge(&seg_queue); |
---|
2573 | | - err = -ENOTCONN; |
---|
2574 | | - } |
---|
2575 | 2742 | |
---|
2576 | 2743 | if (err) |
---|
2577 | 2744 | break; |
---|
.. | .. |
---|
2825 | 2992 | break; |
---|
2826 | 2993 | case L2CAP_EV_RECV_REQSEQ_AND_FBIT: |
---|
2827 | 2994 | l2cap_process_reqseq(chan, control->reqseq); |
---|
2828 | | - |
---|
2829 | | - /* Fall through */ |
---|
| 2995 | + fallthrough; |
---|
2830 | 2996 | |
---|
2831 | 2997 | case L2CAP_EV_RECV_FBIT: |
---|
2832 | 2998 | if (control && control->final) { |
---|
.. | .. |
---|
3129 | 3295 | chan->rx_state = L2CAP_RX_STATE_RECV; |
---|
3130 | 3296 | chan->tx_state = L2CAP_TX_STATE_XMIT; |
---|
3131 | 3297 | |
---|
3132 | | - INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout); |
---|
3133 | | - INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout); |
---|
3134 | | - INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout); |
---|
3135 | | - |
---|
3136 | 3298 | skb_queue_head_init(&chan->srej_q); |
---|
3137 | 3299 | |
---|
3138 | 3300 | err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win); |
---|
.. | .. |
---|
3153 | 3315 | case L2CAP_MODE_ERTM: |
---|
3154 | 3316 | if (l2cap_mode_supported(mode, remote_feat_mask)) |
---|
3155 | 3317 | return mode; |
---|
3156 | | - /* fall through */ |
---|
| 3318 | + fallthrough; |
---|
3157 | 3319 | default: |
---|
3158 | 3320 | return L2CAP_MODE_BASIC; |
---|
3159 | 3321 | } |
---|
.. | .. |
---|
3224 | 3386 | chan->ack_win = chan->tx_win; |
---|
3225 | 3387 | } |
---|
3226 | 3388 | |
---|
| 3389 | +static void l2cap_mtu_auto(struct l2cap_chan *chan) |
---|
| 3390 | +{ |
---|
| 3391 | + struct hci_conn *conn = chan->conn->hcon; |
---|
| 3392 | + |
---|
| 3393 | + chan->imtu = L2CAP_DEFAULT_MIN_MTU; |
---|
| 3394 | + |
---|
| 3395 | + /* The 2-DH1 packet has between 2 and 56 information bytes |
---|
| 3396 | + * (including the 2-byte payload header) |
---|
| 3397 | + */ |
---|
| 3398 | + if (!(conn->pkt_type & HCI_2DH1)) |
---|
| 3399 | + chan->imtu = 54; |
---|
| 3400 | + |
---|
| 3401 | + /* The 3-DH1 packet has between 2 and 85 information bytes |
---|
| 3402 | + * (including the 2-byte payload header) |
---|
| 3403 | + */ |
---|
| 3404 | + if (!(conn->pkt_type & HCI_3DH1)) |
---|
| 3405 | + chan->imtu = 83; |
---|
| 3406 | + |
---|
| 3407 | + /* The 2-DH3 packet has between 2 and 369 information bytes |
---|
| 3408 | + * (including the 2-byte payload header) |
---|
| 3409 | + */ |
---|
| 3410 | + if (!(conn->pkt_type & HCI_2DH3)) |
---|
| 3411 | + chan->imtu = 367; |
---|
| 3412 | + |
---|
| 3413 | + /* The 3-DH3 packet has between 2 and 554 information bytes |
---|
| 3414 | + * (including the 2-byte payload header) |
---|
| 3415 | + */ |
---|
| 3416 | + if (!(conn->pkt_type & HCI_3DH3)) |
---|
| 3417 | + chan->imtu = 552; |
---|
| 3418 | + |
---|
| 3419 | + /* The 2-DH5 packet has between 2 and 681 information bytes |
---|
| 3420 | + * (including the 2-byte payload header) |
---|
| 3421 | + */ |
---|
| 3422 | + if (!(conn->pkt_type & HCI_2DH5)) |
---|
| 3423 | + chan->imtu = 679; |
---|
| 3424 | + |
---|
| 3425 | + /* The 3-DH5 packet has between 2 and 1023 information bytes |
---|
| 3426 | + * (including the 2-byte payload header) |
---|
| 3427 | + */ |
---|
| 3428 | + if (!(conn->pkt_type & HCI_3DH5)) |
---|
| 3429 | + chan->imtu = 1021; |
---|
| 3430 | +} |
---|
| 3431 | + |
---|
3227 | 3432 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size) |
---|
3228 | 3433 | { |
---|
3229 | 3434 | struct l2cap_conf_req *req = data; |
---|
.. | .. |
---|
3246 | 3451 | if (__l2cap_efs_supported(chan->conn)) |
---|
3247 | 3452 | set_bit(FLAG_EFS_ENABLE, &chan->flags); |
---|
3248 | 3453 | |
---|
3249 | | - /* fall through */ |
---|
| 3454 | + fallthrough; |
---|
3250 | 3455 | default: |
---|
3251 | 3456 | chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask); |
---|
3252 | 3457 | break; |
---|
3253 | 3458 | } |
---|
3254 | 3459 | |
---|
3255 | 3460 | done: |
---|
3256 | | - if (chan->imtu != L2CAP_DEFAULT_MTU) |
---|
3257 | | - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr); |
---|
| 3461 | + if (chan->imtu != L2CAP_DEFAULT_MTU) { |
---|
| 3462 | + if (!chan->imtu) |
---|
| 3463 | + l2cap_mtu_auto(chan); |
---|
| 3464 | + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, |
---|
| 3465 | + endptr - ptr); |
---|
| 3466 | + } |
---|
3258 | 3467 | |
---|
3259 | 3468 | switch (chan->mode) { |
---|
3260 | 3469 | case L2CAP_MODE_BASIC: |
---|
.. | .. |
---|
3524 | 3733 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
---|
3525 | 3734 | sizeof(rfc), (unsigned long) &rfc, endptr - ptr); |
---|
3526 | 3735 | |
---|
3527 | | - if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { |
---|
| 3736 | + if (remote_efs && |
---|
| 3737 | + test_bit(FLAG_EFS_ENABLE, &chan->flags)) { |
---|
3528 | 3738 | chan->remote_id = efs.id; |
---|
3529 | 3739 | chan->remote_stype = efs.stype; |
---|
3530 | 3740 | chan->remote_msdu = le16_to_cpu(efs.msdu); |
---|
.. | .. |
---|
3715 | 3925 | rsp.mtu = cpu_to_le16(chan->imtu); |
---|
3716 | 3926 | rsp.mps = cpu_to_le16(chan->mps); |
---|
3717 | 3927 | rsp.credits = cpu_to_le16(chan->rx_credits); |
---|
3718 | | - rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); |
---|
| 3928 | + rsp.result = cpu_to_le16(L2CAP_CR_LE_SUCCESS); |
---|
3719 | 3929 | |
---|
3720 | 3930 | l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), |
---|
3721 | 3931 | &rsp); |
---|
| 3932 | +} |
---|
| 3933 | + |
---|
| 3934 | +static void l2cap_ecred_list_defer(struct l2cap_chan *chan, void *data) |
---|
| 3935 | +{ |
---|
| 3936 | + int *result = data; |
---|
| 3937 | + |
---|
| 3938 | + if (*result || test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags)) |
---|
| 3939 | + return; |
---|
| 3940 | + |
---|
| 3941 | + switch (chan->state) { |
---|
| 3942 | + case BT_CONNECT2: |
---|
| 3943 | + /* If channel still pending accept add to result */ |
---|
| 3944 | + (*result)++; |
---|
| 3945 | + return; |
---|
| 3946 | + case BT_CONNECTED: |
---|
| 3947 | + return; |
---|
| 3948 | + default: |
---|
| 3949 | + /* If not connected or pending accept it has been refused */ |
---|
| 3950 | + *result = -ECONNREFUSED; |
---|
| 3951 | + return; |
---|
| 3952 | + } |
---|
| 3953 | +} |
---|
| 3954 | + |
---|
| 3955 | +struct l2cap_ecred_rsp_data { |
---|
| 3956 | + struct { |
---|
| 3957 | + struct l2cap_ecred_conn_rsp rsp; |
---|
| 3958 | + __le16 scid[L2CAP_ECRED_MAX_CID]; |
---|
| 3959 | + } __packed pdu; |
---|
| 3960 | + int count; |
---|
| 3961 | +}; |
---|
| 3962 | + |
---|
| 3963 | +static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data) |
---|
| 3964 | +{ |
---|
| 3965 | + struct l2cap_ecred_rsp_data *rsp = data; |
---|
| 3966 | + |
---|
| 3967 | + if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags)) |
---|
| 3968 | + return; |
---|
| 3969 | + |
---|
| 3970 | + /* Reset ident so only one response is sent */ |
---|
| 3971 | + chan->ident = 0; |
---|
| 3972 | + |
---|
| 3973 | + /* Include all channels pending with the same ident */ |
---|
| 3974 | + if (!rsp->pdu.rsp.result) |
---|
| 3975 | + rsp->pdu.rsp.dcid[rsp->count++] = cpu_to_le16(chan->scid); |
---|
| 3976 | + else |
---|
| 3977 | + l2cap_chan_del(chan, ECONNRESET); |
---|
| 3978 | +} |
---|
| 3979 | + |
---|
| 3980 | +void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan) |
---|
| 3981 | +{ |
---|
| 3982 | + struct l2cap_conn *conn = chan->conn; |
---|
| 3983 | + struct l2cap_ecred_rsp_data data; |
---|
| 3984 | + u16 id = chan->ident; |
---|
| 3985 | + int result = 0; |
---|
| 3986 | + |
---|
| 3987 | + if (!id) |
---|
| 3988 | + return; |
---|
| 3989 | + |
---|
| 3990 | + BT_DBG("chan %p id %d", chan, id); |
---|
| 3991 | + |
---|
| 3992 | + memset(&data, 0, sizeof(data)); |
---|
| 3993 | + |
---|
| 3994 | + data.pdu.rsp.mtu = cpu_to_le16(chan->imtu); |
---|
| 3995 | + data.pdu.rsp.mps = cpu_to_le16(chan->mps); |
---|
| 3996 | + data.pdu.rsp.credits = cpu_to_le16(chan->rx_credits); |
---|
| 3997 | + data.pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_SUCCESS); |
---|
| 3998 | + |
---|
| 3999 | + /* Verify that all channels are ready */ |
---|
| 4000 | + __l2cap_chan_list_id(conn, id, l2cap_ecred_list_defer, &result); |
---|
| 4001 | + |
---|
| 4002 | + if (result > 0) |
---|
| 4003 | + return; |
---|
| 4004 | + |
---|
| 4005 | + if (result < 0) |
---|
| 4006 | + data.pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_AUTHORIZATION); |
---|
| 4007 | + |
---|
| 4008 | + /* Build response */ |
---|
| 4009 | + __l2cap_chan_list_id(conn, id, l2cap_ecred_rsp_defer, &data); |
---|
| 4010 | + |
---|
| 4011 | + l2cap_send_cmd(conn, id, L2CAP_ECRED_CONN_RSP, |
---|
| 4012 | + sizeof(data.pdu.rsp) + (data.count * sizeof(__le16)), |
---|
| 4013 | + &data.pdu); |
---|
3722 | 4014 | } |
---|
3723 | 4015 | |
---|
3724 | 4016 | void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) |
---|
.. | .. |
---|
3866 | 4158 | |
---|
3867 | 4159 | result = L2CAP_CR_NO_MEM; |
---|
3868 | 4160 | |
---|
3869 | | - /* Check if we already have channel with that dcid */ |
---|
3870 | | - if (__l2cap_get_chan_by_dcid(conn, scid)) |
---|
| 4161 | + /* Check for valid dynamic CID range (as per Erratum 3253) */ |
---|
| 4162 | + if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_DYN_END) { |
---|
| 4163 | + result = L2CAP_CR_INVALID_SCID; |
---|
3871 | 4164 | goto response; |
---|
| 4165 | + } |
---|
| 4166 | + |
---|
| 4167 | + /* Check if we already have channel with that dcid */ |
---|
| 4168 | + if (__l2cap_get_chan_by_dcid(conn, scid)) { |
---|
| 4169 | + result = L2CAP_CR_SCID_IN_USE; |
---|
| 4170 | + goto response; |
---|
| 4171 | + } |
---|
3872 | 4172 | |
---|
3873 | 4173 | chan = pchan->ops->new_connection(pchan); |
---|
3874 | 4174 | if (!chan) |
---|
.. | .. |
---|
4003 | 4303 | result = __le16_to_cpu(rsp->result); |
---|
4004 | 4304 | status = __le16_to_cpu(rsp->status); |
---|
4005 | 4305 | |
---|
| 4306 | + if (result == L2CAP_CR_SUCCESS && (dcid < L2CAP_CID_DYN_START || |
---|
| 4307 | + dcid > L2CAP_CID_DYN_END)) |
---|
| 4308 | + return -EPROTO; |
---|
| 4309 | + |
---|
4006 | 4310 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", |
---|
4007 | 4311 | dcid, scid, result, status); |
---|
4008 | 4312 | |
---|
.. | .. |
---|
4022 | 4326 | } |
---|
4023 | 4327 | } |
---|
4024 | 4328 | |
---|
| 4329 | + chan = l2cap_chan_hold_unless_zero(chan); |
---|
| 4330 | + if (!chan) { |
---|
| 4331 | + err = -EBADSLT; |
---|
| 4332 | + goto unlock; |
---|
| 4333 | + } |
---|
| 4334 | + |
---|
4025 | 4335 | err = 0; |
---|
4026 | 4336 | |
---|
4027 | 4337 | l2cap_chan_lock(chan); |
---|
4028 | 4338 | |
---|
4029 | 4339 | switch (result) { |
---|
4030 | 4340 | case L2CAP_CR_SUCCESS: |
---|
| 4341 | + if (__l2cap_get_chan_by_dcid(conn, dcid)) { |
---|
| 4342 | + err = -EBADSLT; |
---|
| 4343 | + break; |
---|
| 4344 | + } |
---|
| 4345 | + |
---|
4031 | 4346 | l2cap_state_change(chan, BT_CONFIG); |
---|
4032 | 4347 | chan->ident = 0; |
---|
4033 | 4348 | chan->dcid = dcid; |
---|
.. | .. |
---|
4051 | 4366 | } |
---|
4052 | 4367 | |
---|
4053 | 4368 | l2cap_chan_unlock(chan); |
---|
| 4369 | + l2cap_chan_put(chan); |
---|
4054 | 4370 | |
---|
4055 | 4371 | unlock: |
---|
4056 | 4372 | mutex_unlock(&conn->chan_lock); |
---|
.. | .. |
---|
4158 | 4474 | |
---|
4159 | 4475 | chan->ident = cmd->ident; |
---|
4160 | 4476 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp); |
---|
4161 | | - chan->num_conf_rsp++; |
---|
| 4477 | + if (chan->num_conf_rsp < L2CAP_CONF_MAX_CONF_RSP) |
---|
| 4478 | + chan->num_conf_rsp++; |
---|
4162 | 4479 | |
---|
4163 | 4480 | /* Reset config buffer. */ |
---|
4164 | 4481 | chan->conf_len = 0; |
---|
.. | .. |
---|
4204 | 4521 | |
---|
4205 | 4522 | unlock: |
---|
4206 | 4523 | l2cap_chan_unlock(chan); |
---|
| 4524 | + l2cap_chan_put(chan); |
---|
4207 | 4525 | return err; |
---|
4208 | 4526 | } |
---|
4209 | 4527 | |
---|
.. | .. |
---|
4287 | 4605 | goto done; |
---|
4288 | 4606 | break; |
---|
4289 | 4607 | } |
---|
| 4608 | + fallthrough; |
---|
4290 | 4609 | |
---|
4291 | 4610 | default: |
---|
4292 | 4611 | l2cap_chan_set_err(chan, ECONNRESET); |
---|
.. | .. |
---|
4316 | 4635 | |
---|
4317 | 4636 | done: |
---|
4318 | 4637 | l2cap_chan_unlock(chan); |
---|
| 4638 | + l2cap_chan_put(chan); |
---|
4319 | 4639 | return err; |
---|
4320 | 4640 | } |
---|
4321 | 4641 | |
---|
.. | .. |
---|
4336 | 4656 | |
---|
4337 | 4657 | BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid); |
---|
4338 | 4658 | |
---|
4339 | | - mutex_lock(&conn->chan_lock); |
---|
4340 | | - |
---|
4341 | | - chan = __l2cap_get_chan_by_scid(conn, dcid); |
---|
| 4659 | + chan = l2cap_get_chan_by_scid(conn, dcid); |
---|
4342 | 4660 | if (!chan) { |
---|
4343 | | - mutex_unlock(&conn->chan_lock); |
---|
4344 | 4661 | cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid); |
---|
4345 | 4662 | return 0; |
---|
4346 | 4663 | } |
---|
4347 | | - |
---|
4348 | | - l2cap_chan_hold(chan); |
---|
4349 | | - l2cap_chan_lock(chan); |
---|
4350 | 4664 | |
---|
4351 | 4665 | rsp.dcid = cpu_to_le16(chan->scid); |
---|
4352 | 4666 | rsp.scid = cpu_to_le16(chan->dcid); |
---|
.. | .. |
---|
4354 | 4668 | |
---|
4355 | 4669 | chan->ops->set_shutdown(chan); |
---|
4356 | 4670 | |
---|
| 4671 | + l2cap_chan_unlock(chan); |
---|
| 4672 | + mutex_lock(&conn->chan_lock); |
---|
| 4673 | + l2cap_chan_lock(chan); |
---|
4357 | 4674 | l2cap_chan_del(chan, ECONNRESET); |
---|
| 4675 | + mutex_unlock(&conn->chan_lock); |
---|
4358 | 4676 | |
---|
4359 | 4677 | chan->ops->close(chan); |
---|
4360 | 4678 | |
---|
4361 | 4679 | l2cap_chan_unlock(chan); |
---|
4362 | 4680 | l2cap_chan_put(chan); |
---|
4363 | | - |
---|
4364 | | - mutex_unlock(&conn->chan_lock); |
---|
4365 | 4681 | |
---|
4366 | 4682 | return 0; |
---|
4367 | 4683 | } |
---|
.. | .. |
---|
4382 | 4698 | |
---|
4383 | 4699 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid); |
---|
4384 | 4700 | |
---|
4385 | | - mutex_lock(&conn->chan_lock); |
---|
4386 | | - |
---|
4387 | | - chan = __l2cap_get_chan_by_scid(conn, scid); |
---|
| 4701 | + chan = l2cap_get_chan_by_scid(conn, scid); |
---|
4388 | 4702 | if (!chan) { |
---|
4389 | | - mutex_unlock(&conn->chan_lock); |
---|
4390 | 4703 | return 0; |
---|
4391 | 4704 | } |
---|
4392 | | - |
---|
4393 | | - l2cap_chan_hold(chan); |
---|
4394 | | - l2cap_chan_lock(chan); |
---|
4395 | 4705 | |
---|
4396 | 4706 | if (chan->state != BT_DISCONN) { |
---|
4397 | 4707 | l2cap_chan_unlock(chan); |
---|
4398 | 4708 | l2cap_chan_put(chan); |
---|
4399 | | - mutex_unlock(&conn->chan_lock); |
---|
4400 | 4709 | return 0; |
---|
4401 | 4710 | } |
---|
4402 | 4711 | |
---|
| 4712 | + l2cap_chan_unlock(chan); |
---|
| 4713 | + mutex_lock(&conn->chan_lock); |
---|
| 4714 | + l2cap_chan_lock(chan); |
---|
4403 | 4715 | l2cap_chan_del(chan, 0); |
---|
| 4716 | + mutex_unlock(&conn->chan_lock); |
---|
4404 | 4717 | |
---|
4405 | 4718 | chan->ops->close(chan); |
---|
4406 | 4719 | |
---|
4407 | 4720 | l2cap_chan_unlock(chan); |
---|
4408 | 4721 | l2cap_chan_put(chan); |
---|
4409 | | - |
---|
4410 | | - mutex_unlock(&conn->chan_lock); |
---|
4411 | 4722 | |
---|
4412 | 4723 | return 0; |
---|
4413 | 4724 | } |
---|
.. | .. |
---|
5022 | 5333 | chan->move_role = L2CAP_MOVE_ROLE_RESPONDER; |
---|
5023 | 5334 | l2cap_move_setup(chan); |
---|
5024 | 5335 | chan->move_id = req->dest_amp_id; |
---|
5025 | | - icid = chan->dcid; |
---|
5026 | 5336 | |
---|
5027 | 5337 | if (req->dest_amp_id == AMP_ID_BREDR) { |
---|
5028 | 5338 | /* Moving to BR/EDR */ |
---|
.. | .. |
---|
5044 | 5354 | l2cap_send_move_chan_rsp(chan, result); |
---|
5045 | 5355 | |
---|
5046 | 5356 | l2cap_chan_unlock(chan); |
---|
| 5357 | + l2cap_chan_put(chan); |
---|
5047 | 5358 | |
---|
5048 | 5359 | return 0; |
---|
5049 | 5360 | } |
---|
.. | .. |
---|
5136 | 5447 | } |
---|
5137 | 5448 | |
---|
5138 | 5449 | l2cap_chan_unlock(chan); |
---|
| 5450 | + l2cap_chan_put(chan); |
---|
5139 | 5451 | } |
---|
5140 | 5452 | |
---|
5141 | 5453 | static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid, |
---|
.. | .. |
---|
5165 | 5477 | l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); |
---|
5166 | 5478 | |
---|
5167 | 5479 | l2cap_chan_unlock(chan); |
---|
| 5480 | + l2cap_chan_put(chan); |
---|
5168 | 5481 | } |
---|
5169 | 5482 | |
---|
5170 | 5483 | static int l2cap_move_channel_rsp(struct l2cap_conn *conn, |
---|
.. | .. |
---|
5228 | 5541 | l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid); |
---|
5229 | 5542 | |
---|
5230 | 5543 | l2cap_chan_unlock(chan); |
---|
| 5544 | + l2cap_chan_put(chan); |
---|
5231 | 5545 | |
---|
5232 | 5546 | return 0; |
---|
5233 | 5547 | } |
---|
.. | .. |
---|
5263 | 5577 | } |
---|
5264 | 5578 | |
---|
5265 | 5579 | l2cap_chan_unlock(chan); |
---|
| 5580 | + l2cap_chan_put(chan); |
---|
5266 | 5581 | |
---|
5267 | 5582 | return 0; |
---|
5268 | 5583 | } |
---|
.. | .. |
---|
5336 | 5651 | credits = __le16_to_cpu(rsp->credits); |
---|
5337 | 5652 | result = __le16_to_cpu(rsp->result); |
---|
5338 | 5653 | |
---|
5339 | | - if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23 || |
---|
| 5654 | + if (result == L2CAP_CR_LE_SUCCESS && (mtu < 23 || mps < 23 || |
---|
5340 | 5655 | dcid < L2CAP_CID_DYN_START || |
---|
5341 | 5656 | dcid > L2CAP_CID_LE_DYN_END)) |
---|
5342 | 5657 | return -EPROTO; |
---|
.. | .. |
---|
5357 | 5672 | l2cap_chan_lock(chan); |
---|
5358 | 5673 | |
---|
5359 | 5674 | switch (result) { |
---|
5360 | | - case L2CAP_CR_SUCCESS: |
---|
| 5675 | + case L2CAP_CR_LE_SUCCESS: |
---|
5361 | 5676 | if (__l2cap_get_chan_by_dcid(conn, dcid)) { |
---|
5362 | 5677 | err = -EBADSLT; |
---|
5363 | 5678 | break; |
---|
.. | .. |
---|
5371 | 5686 | l2cap_chan_ready(chan); |
---|
5372 | 5687 | break; |
---|
5373 | 5688 | |
---|
5374 | | - case L2CAP_CR_AUTHENTICATION: |
---|
5375 | | - case L2CAP_CR_ENCRYPTION: |
---|
| 5689 | + case L2CAP_CR_LE_AUTHENTICATION: |
---|
| 5690 | + case L2CAP_CR_LE_ENCRYPTION: |
---|
5376 | 5691 | /* If we already have MITM protection we can't do |
---|
5377 | 5692 | * anything. |
---|
5378 | 5693 | */ |
---|
.. | .. |
---|
5511 | 5826 | BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm), |
---|
5512 | 5827 | scid, mtu, mps); |
---|
5513 | 5828 | |
---|
| 5829 | + /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A |
---|
| 5830 | + * page 1059: |
---|
| 5831 | + * |
---|
| 5832 | + * Valid range: 0x0001-0x00ff |
---|
| 5833 | + * |
---|
| 5834 | + * Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges |
---|
| 5835 | + */ |
---|
| 5836 | + if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) { |
---|
| 5837 | + result = L2CAP_CR_LE_BAD_PSM; |
---|
| 5838 | + chan = NULL; |
---|
| 5839 | + goto response; |
---|
| 5840 | + } |
---|
| 5841 | + |
---|
5514 | 5842 | /* Check if we have socket listening on psm */ |
---|
5515 | 5843 | pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src, |
---|
5516 | 5844 | &conn->hcon->dst, LE_LINK); |
---|
5517 | 5845 | if (!pchan) { |
---|
5518 | | - result = L2CAP_CR_BAD_PSM; |
---|
| 5846 | + result = L2CAP_CR_LE_BAD_PSM; |
---|
5519 | 5847 | chan = NULL; |
---|
5520 | 5848 | goto response; |
---|
5521 | 5849 | } |
---|
.. | .. |
---|
5525 | 5853 | |
---|
5526 | 5854 | if (!smp_sufficient_security(conn->hcon, pchan->sec_level, |
---|
5527 | 5855 | SMP_ALLOW_STK)) { |
---|
5528 | | - result = L2CAP_CR_AUTHENTICATION; |
---|
| 5856 | + result = L2CAP_CR_LE_AUTHENTICATION; |
---|
5529 | 5857 | chan = NULL; |
---|
5530 | 5858 | goto response_unlock; |
---|
5531 | 5859 | } |
---|
5532 | 5860 | |
---|
5533 | 5861 | /* Check for valid dynamic CID range */ |
---|
5534 | 5862 | if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) { |
---|
5535 | | - result = L2CAP_CR_INVALID_SCID; |
---|
| 5863 | + result = L2CAP_CR_LE_INVALID_SCID; |
---|
5536 | 5864 | chan = NULL; |
---|
5537 | 5865 | goto response_unlock; |
---|
5538 | 5866 | } |
---|
5539 | 5867 | |
---|
5540 | 5868 | /* Check if we already have channel with that dcid */ |
---|
5541 | 5869 | if (__l2cap_get_chan_by_dcid(conn, scid)) { |
---|
5542 | | - result = L2CAP_CR_SCID_IN_USE; |
---|
| 5870 | + result = L2CAP_CR_LE_SCID_IN_USE; |
---|
5543 | 5871 | chan = NULL; |
---|
5544 | 5872 | goto response_unlock; |
---|
5545 | 5873 | } |
---|
5546 | 5874 | |
---|
5547 | 5875 | chan = pchan->ops->new_connection(pchan); |
---|
5548 | 5876 | if (!chan) { |
---|
5549 | | - result = L2CAP_CR_NO_MEM; |
---|
| 5877 | + result = L2CAP_CR_LE_NO_MEM; |
---|
5550 | 5878 | goto response_unlock; |
---|
5551 | 5879 | } |
---|
5552 | | - |
---|
5553 | | - l2cap_le_flowctl_init(chan); |
---|
5554 | 5880 | |
---|
5555 | 5881 | bacpy(&chan->src, &conn->hcon->src); |
---|
5556 | 5882 | bacpy(&chan->dst, &conn->hcon->dst); |
---|
.. | .. |
---|
5560 | 5886 | chan->dcid = scid; |
---|
5561 | 5887 | chan->omtu = mtu; |
---|
5562 | 5888 | chan->remote_mps = mps; |
---|
5563 | | - chan->tx_credits = __le16_to_cpu(req->credits); |
---|
5564 | 5889 | |
---|
5565 | 5890 | __l2cap_chan_add(conn, chan); |
---|
| 5891 | + |
---|
| 5892 | + l2cap_le_flowctl_init(chan, __le16_to_cpu(req->credits)); |
---|
| 5893 | + |
---|
5566 | 5894 | dcid = chan->scid; |
---|
5567 | 5895 | credits = chan->rx_credits; |
---|
5568 | 5896 | |
---|
.. | .. |
---|
5581 | 5909 | chan->ops->defer(chan); |
---|
5582 | 5910 | } else { |
---|
5583 | 5911 | l2cap_chan_ready(chan); |
---|
5584 | | - result = L2CAP_CR_SUCCESS; |
---|
| 5912 | + result = L2CAP_CR_LE_SUCCESS; |
---|
5585 | 5913 | } |
---|
5586 | 5914 | |
---|
5587 | 5915 | response_unlock: |
---|
.. | .. |
---|
5635 | 5963 | if (credits > max_credits) { |
---|
5636 | 5964 | BT_ERR("LE credits overflow"); |
---|
5637 | 5965 | l2cap_send_disconn_req(chan, ECONNRESET); |
---|
5638 | | - l2cap_chan_unlock(chan); |
---|
5639 | 5966 | |
---|
5640 | 5967 | /* Return 0 so that we don't trigger an unnecessary |
---|
5641 | 5968 | * command reject packet. |
---|
5642 | 5969 | */ |
---|
5643 | | - return 0; |
---|
| 5970 | + goto unlock; |
---|
5644 | 5971 | } |
---|
5645 | 5972 | |
---|
5646 | 5973 | chan->tx_credits += credits; |
---|
.. | .. |
---|
5651 | 5978 | if (chan->tx_credits) |
---|
5652 | 5979 | chan->ops->resume(chan); |
---|
5653 | 5980 | |
---|
| 5981 | +unlock: |
---|
5654 | 5982 | l2cap_chan_unlock(chan); |
---|
| 5983 | + l2cap_chan_put(chan); |
---|
| 5984 | + |
---|
| 5985 | + return 0; |
---|
| 5986 | +} |
---|
| 5987 | + |
---|
| 5988 | +static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, |
---|
| 5989 | + struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
---|
| 5990 | + u8 *data) |
---|
| 5991 | +{ |
---|
| 5992 | + struct l2cap_ecred_conn_req *req = (void *) data; |
---|
| 5993 | + struct { |
---|
| 5994 | + struct l2cap_ecred_conn_rsp rsp; |
---|
| 5995 | + __le16 dcid[L2CAP_ECRED_MAX_CID]; |
---|
| 5996 | + } __packed pdu; |
---|
| 5997 | + struct l2cap_chan *chan, *pchan; |
---|
| 5998 | + u16 mtu, mps; |
---|
| 5999 | + __le16 psm; |
---|
| 6000 | + u8 result, len = 0; |
---|
| 6001 | + int i, num_scid; |
---|
| 6002 | + bool defer = false; |
---|
| 6003 | + |
---|
| 6004 | + if (!enable_ecred) |
---|
| 6005 | + return -EINVAL; |
---|
| 6006 | + |
---|
| 6007 | + if (cmd_len < sizeof(*req) || (cmd_len - sizeof(*req)) % sizeof(u16)) { |
---|
| 6008 | + result = L2CAP_CR_LE_INVALID_PARAMS; |
---|
| 6009 | + goto response; |
---|
| 6010 | + } |
---|
| 6011 | + |
---|
| 6012 | + cmd_len -= sizeof(*req); |
---|
| 6013 | + num_scid = cmd_len / sizeof(u16); |
---|
| 6014 | + |
---|
| 6015 | + if (num_scid > ARRAY_SIZE(pdu.dcid)) { |
---|
| 6016 | + result = L2CAP_CR_LE_INVALID_PARAMS; |
---|
| 6017 | + goto response; |
---|
| 6018 | + } |
---|
| 6019 | + |
---|
| 6020 | + mtu = __le16_to_cpu(req->mtu); |
---|
| 6021 | + mps = __le16_to_cpu(req->mps); |
---|
| 6022 | + |
---|
| 6023 | + if (mtu < L2CAP_ECRED_MIN_MTU || mps < L2CAP_ECRED_MIN_MPS) { |
---|
| 6024 | + result = L2CAP_CR_LE_UNACCEPT_PARAMS; |
---|
| 6025 | + goto response; |
---|
| 6026 | + } |
---|
| 6027 | + |
---|
| 6028 | + psm = req->psm; |
---|
| 6029 | + |
---|
| 6030 | + /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A |
---|
| 6031 | + * page 1059: |
---|
| 6032 | + * |
---|
| 6033 | + * Valid range: 0x0001-0x00ff |
---|
| 6034 | + * |
---|
| 6035 | + * Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges |
---|
| 6036 | + */ |
---|
| 6037 | + if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) { |
---|
| 6038 | + result = L2CAP_CR_LE_BAD_PSM; |
---|
| 6039 | + goto response; |
---|
| 6040 | + } |
---|
| 6041 | + |
---|
| 6042 | + BT_DBG("psm 0x%2.2x mtu %u mps %u", __le16_to_cpu(psm), mtu, mps); |
---|
| 6043 | + |
---|
| 6044 | + memset(&pdu, 0, sizeof(pdu)); |
---|
| 6045 | + |
---|
| 6046 | + /* Check if we have socket listening on psm */ |
---|
| 6047 | + pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src, |
---|
| 6048 | + &conn->hcon->dst, LE_LINK); |
---|
| 6049 | + if (!pchan) { |
---|
| 6050 | + result = L2CAP_CR_LE_BAD_PSM; |
---|
| 6051 | + goto response; |
---|
| 6052 | + } |
---|
| 6053 | + |
---|
| 6054 | + mutex_lock(&conn->chan_lock); |
---|
| 6055 | + l2cap_chan_lock(pchan); |
---|
| 6056 | + |
---|
| 6057 | + if (!smp_sufficient_security(conn->hcon, pchan->sec_level, |
---|
| 6058 | + SMP_ALLOW_STK)) { |
---|
| 6059 | + result = L2CAP_CR_LE_AUTHENTICATION; |
---|
| 6060 | + goto unlock; |
---|
| 6061 | + } |
---|
| 6062 | + |
---|
| 6063 | + result = L2CAP_CR_LE_SUCCESS; |
---|
| 6064 | + |
---|
| 6065 | + for (i = 0; i < num_scid; i++) { |
---|
| 6066 | + u16 scid = __le16_to_cpu(req->scid[i]); |
---|
| 6067 | + |
---|
| 6068 | + BT_DBG("scid[%d] 0x%4.4x", i, scid); |
---|
| 6069 | + |
---|
| 6070 | + pdu.dcid[i] = 0x0000; |
---|
| 6071 | + len += sizeof(*pdu.dcid); |
---|
| 6072 | + |
---|
| 6073 | + /* Check for valid dynamic CID range */ |
---|
| 6074 | + if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) { |
---|
| 6075 | + result = L2CAP_CR_LE_INVALID_SCID; |
---|
| 6076 | + continue; |
---|
| 6077 | + } |
---|
| 6078 | + |
---|
| 6079 | + /* Check if we already have channel with that dcid */ |
---|
| 6080 | + if (__l2cap_get_chan_by_dcid(conn, scid)) { |
---|
| 6081 | + result = L2CAP_CR_LE_SCID_IN_USE; |
---|
| 6082 | + continue; |
---|
| 6083 | + } |
---|
| 6084 | + |
---|
| 6085 | + chan = pchan->ops->new_connection(pchan); |
---|
| 6086 | + if (!chan) { |
---|
| 6087 | + result = L2CAP_CR_LE_NO_MEM; |
---|
| 6088 | + continue; |
---|
| 6089 | + } |
---|
| 6090 | + |
---|
| 6091 | + bacpy(&chan->src, &conn->hcon->src); |
---|
| 6092 | + bacpy(&chan->dst, &conn->hcon->dst); |
---|
| 6093 | + chan->src_type = bdaddr_src_type(conn->hcon); |
---|
| 6094 | + chan->dst_type = bdaddr_dst_type(conn->hcon); |
---|
| 6095 | + chan->psm = psm; |
---|
| 6096 | + chan->dcid = scid; |
---|
| 6097 | + chan->omtu = mtu; |
---|
| 6098 | + chan->remote_mps = mps; |
---|
| 6099 | + |
---|
| 6100 | + __l2cap_chan_add(conn, chan); |
---|
| 6101 | + |
---|
| 6102 | + l2cap_ecred_init(chan, __le16_to_cpu(req->credits)); |
---|
| 6103 | + |
---|
| 6104 | + /* Init response */ |
---|
| 6105 | + if (!pdu.rsp.credits) { |
---|
| 6106 | + pdu.rsp.mtu = cpu_to_le16(chan->imtu); |
---|
| 6107 | + pdu.rsp.mps = cpu_to_le16(chan->mps); |
---|
| 6108 | + pdu.rsp.credits = cpu_to_le16(chan->rx_credits); |
---|
| 6109 | + } |
---|
| 6110 | + |
---|
| 6111 | + pdu.dcid[i] = cpu_to_le16(chan->scid); |
---|
| 6112 | + |
---|
| 6113 | + __set_chan_timer(chan, chan->ops->get_sndtimeo(chan)); |
---|
| 6114 | + |
---|
| 6115 | + chan->ident = cmd->ident; |
---|
| 6116 | + chan->mode = L2CAP_MODE_EXT_FLOWCTL; |
---|
| 6117 | + |
---|
| 6118 | + if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { |
---|
| 6119 | + l2cap_state_change(chan, BT_CONNECT2); |
---|
| 6120 | + defer = true; |
---|
| 6121 | + chan->ops->defer(chan); |
---|
| 6122 | + } else { |
---|
| 6123 | + l2cap_chan_ready(chan); |
---|
| 6124 | + } |
---|
| 6125 | + } |
---|
| 6126 | + |
---|
| 6127 | +unlock: |
---|
| 6128 | + l2cap_chan_unlock(pchan); |
---|
| 6129 | + mutex_unlock(&conn->chan_lock); |
---|
| 6130 | + l2cap_chan_put(pchan); |
---|
| 6131 | + |
---|
| 6132 | +response: |
---|
| 6133 | + pdu.rsp.result = cpu_to_le16(result); |
---|
| 6134 | + |
---|
| 6135 | + if (defer) |
---|
| 6136 | + return 0; |
---|
| 6137 | + |
---|
| 6138 | + l2cap_send_cmd(conn, cmd->ident, L2CAP_ECRED_CONN_RSP, |
---|
| 6139 | + sizeof(pdu.rsp) + len, &pdu); |
---|
| 6140 | + |
---|
| 6141 | + return 0; |
---|
| 6142 | +} |
---|
| 6143 | + |
---|
| 6144 | +static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn, |
---|
| 6145 | + struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
---|
| 6146 | + u8 *data) |
---|
| 6147 | +{ |
---|
| 6148 | + struct l2cap_ecred_conn_rsp *rsp = (void *) data; |
---|
| 6149 | + struct hci_conn *hcon = conn->hcon; |
---|
| 6150 | + u16 mtu, mps, credits, result; |
---|
| 6151 | + struct l2cap_chan *chan, *tmp; |
---|
| 6152 | + int err = 0, sec_level; |
---|
| 6153 | + int i = 0; |
---|
| 6154 | + |
---|
| 6155 | + if (cmd_len < sizeof(*rsp)) |
---|
| 6156 | + return -EPROTO; |
---|
| 6157 | + |
---|
| 6158 | + mtu = __le16_to_cpu(rsp->mtu); |
---|
| 6159 | + mps = __le16_to_cpu(rsp->mps); |
---|
| 6160 | + credits = __le16_to_cpu(rsp->credits); |
---|
| 6161 | + result = __le16_to_cpu(rsp->result); |
---|
| 6162 | + |
---|
| 6163 | + BT_DBG("mtu %u mps %u credits %u result 0x%4.4x", mtu, mps, credits, |
---|
| 6164 | + result); |
---|
| 6165 | + |
---|
| 6166 | + mutex_lock(&conn->chan_lock); |
---|
| 6167 | + |
---|
| 6168 | + cmd_len -= sizeof(*rsp); |
---|
| 6169 | + |
---|
| 6170 | + list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) { |
---|
| 6171 | + u16 dcid; |
---|
| 6172 | + |
---|
| 6173 | + if (chan->ident != cmd->ident || |
---|
| 6174 | + chan->mode != L2CAP_MODE_EXT_FLOWCTL || |
---|
| 6175 | + chan->state == BT_CONNECTED) |
---|
| 6176 | + continue; |
---|
| 6177 | + |
---|
| 6178 | + l2cap_chan_lock(chan); |
---|
| 6179 | + |
---|
| 6180 | + /* Check that there is a dcid for each pending channel */ |
---|
| 6181 | + if (cmd_len < sizeof(dcid)) { |
---|
| 6182 | + l2cap_chan_del(chan, ECONNREFUSED); |
---|
| 6183 | + l2cap_chan_unlock(chan); |
---|
| 6184 | + continue; |
---|
| 6185 | + } |
---|
| 6186 | + |
---|
| 6187 | + dcid = __le16_to_cpu(rsp->dcid[i++]); |
---|
| 6188 | + cmd_len -= sizeof(u16); |
---|
| 6189 | + |
---|
| 6190 | + BT_DBG("dcid[%d] 0x%4.4x", i, dcid); |
---|
| 6191 | + |
---|
| 6192 | + /* Check if dcid is already in use */ |
---|
| 6193 | + if (dcid && __l2cap_get_chan_by_dcid(conn, dcid)) { |
---|
| 6194 | + /* If a device receives a |
---|
| 6195 | + * L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an |
---|
| 6196 | + * already-assigned Destination CID, then both the |
---|
| 6197 | + * original channel and the new channel shall be |
---|
| 6198 | + * immediately discarded and not used. |
---|
| 6199 | + */ |
---|
| 6200 | + l2cap_chan_del(chan, ECONNREFUSED); |
---|
| 6201 | + l2cap_chan_unlock(chan); |
---|
| 6202 | + chan = __l2cap_get_chan_by_dcid(conn, dcid); |
---|
| 6203 | + l2cap_chan_lock(chan); |
---|
| 6204 | + l2cap_chan_del(chan, ECONNRESET); |
---|
| 6205 | + l2cap_chan_unlock(chan); |
---|
| 6206 | + continue; |
---|
| 6207 | + } |
---|
| 6208 | + |
---|
| 6209 | + switch (result) { |
---|
| 6210 | + case L2CAP_CR_LE_AUTHENTICATION: |
---|
| 6211 | + case L2CAP_CR_LE_ENCRYPTION: |
---|
| 6212 | + /* If we already have MITM protection we can't do |
---|
| 6213 | + * anything. |
---|
| 6214 | + */ |
---|
| 6215 | + if (hcon->sec_level > BT_SECURITY_MEDIUM) { |
---|
| 6216 | + l2cap_chan_del(chan, ECONNREFUSED); |
---|
| 6217 | + break; |
---|
| 6218 | + } |
---|
| 6219 | + |
---|
| 6220 | + sec_level = hcon->sec_level + 1; |
---|
| 6221 | + if (chan->sec_level < sec_level) |
---|
| 6222 | + chan->sec_level = sec_level; |
---|
| 6223 | + |
---|
| 6224 | + /* We'll need to send a new Connect Request */ |
---|
| 6225 | + clear_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags); |
---|
| 6226 | + |
---|
| 6227 | + smp_conn_security(hcon, chan->sec_level); |
---|
| 6228 | + break; |
---|
| 6229 | + |
---|
| 6230 | + case L2CAP_CR_LE_BAD_PSM: |
---|
| 6231 | + l2cap_chan_del(chan, ECONNREFUSED); |
---|
| 6232 | + break; |
---|
| 6233 | + |
---|
| 6234 | + default: |
---|
| 6235 | + /* If dcid was not set it means channels was refused */ |
---|
| 6236 | + if (!dcid) { |
---|
| 6237 | + l2cap_chan_del(chan, ECONNREFUSED); |
---|
| 6238 | + break; |
---|
| 6239 | + } |
---|
| 6240 | + |
---|
| 6241 | + chan->ident = 0; |
---|
| 6242 | + chan->dcid = dcid; |
---|
| 6243 | + chan->omtu = mtu; |
---|
| 6244 | + chan->remote_mps = mps; |
---|
| 6245 | + chan->tx_credits = credits; |
---|
| 6246 | + l2cap_chan_ready(chan); |
---|
| 6247 | + break; |
---|
| 6248 | + } |
---|
| 6249 | + |
---|
| 6250 | + l2cap_chan_unlock(chan); |
---|
| 6251 | + } |
---|
| 6252 | + |
---|
| 6253 | + mutex_unlock(&conn->chan_lock); |
---|
| 6254 | + |
---|
| 6255 | + return err; |
---|
| 6256 | +} |
---|
| 6257 | + |
---|
| 6258 | +static inline int l2cap_ecred_reconf_req(struct l2cap_conn *conn, |
---|
| 6259 | + struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
---|
| 6260 | + u8 *data) |
---|
| 6261 | +{ |
---|
| 6262 | + struct l2cap_ecred_reconf_req *req = (void *) data; |
---|
| 6263 | + struct l2cap_ecred_reconf_rsp rsp; |
---|
| 6264 | + u16 mtu, mps, result; |
---|
| 6265 | + struct l2cap_chan *chan; |
---|
| 6266 | + int i, num_scid; |
---|
| 6267 | + |
---|
| 6268 | + if (!enable_ecred) |
---|
| 6269 | + return -EINVAL; |
---|
| 6270 | + |
---|
| 6271 | + if (cmd_len < sizeof(*req) || cmd_len - sizeof(*req) % sizeof(u16)) { |
---|
| 6272 | + result = L2CAP_CR_LE_INVALID_PARAMS; |
---|
| 6273 | + goto respond; |
---|
| 6274 | + } |
---|
| 6275 | + |
---|
| 6276 | + mtu = __le16_to_cpu(req->mtu); |
---|
| 6277 | + mps = __le16_to_cpu(req->mps); |
---|
| 6278 | + |
---|
| 6279 | + BT_DBG("mtu %u mps %u", mtu, mps); |
---|
| 6280 | + |
---|
| 6281 | + if (mtu < L2CAP_ECRED_MIN_MTU) { |
---|
| 6282 | + result = L2CAP_RECONF_INVALID_MTU; |
---|
| 6283 | + goto respond; |
---|
| 6284 | + } |
---|
| 6285 | + |
---|
| 6286 | + if (mps < L2CAP_ECRED_MIN_MPS) { |
---|
| 6287 | + result = L2CAP_RECONF_INVALID_MPS; |
---|
| 6288 | + goto respond; |
---|
| 6289 | + } |
---|
| 6290 | + |
---|
| 6291 | + cmd_len -= sizeof(*req); |
---|
| 6292 | + num_scid = cmd_len / sizeof(u16); |
---|
| 6293 | + result = L2CAP_RECONF_SUCCESS; |
---|
| 6294 | + |
---|
| 6295 | + for (i = 0; i < num_scid; i++) { |
---|
| 6296 | + u16 scid; |
---|
| 6297 | + |
---|
| 6298 | + scid = __le16_to_cpu(req->scid[i]); |
---|
| 6299 | + if (!scid) |
---|
| 6300 | + return -EPROTO; |
---|
| 6301 | + |
---|
| 6302 | + chan = __l2cap_get_chan_by_dcid(conn, scid); |
---|
| 6303 | + if (!chan) |
---|
| 6304 | + continue; |
---|
| 6305 | + |
---|
| 6306 | + /* If the MTU value is decreased for any of the included |
---|
| 6307 | + * channels, then the receiver shall disconnect all |
---|
| 6308 | + * included channels. |
---|
| 6309 | + */ |
---|
| 6310 | + if (chan->omtu > mtu) { |
---|
| 6311 | + BT_ERR("chan %p decreased MTU %u -> %u", chan, |
---|
| 6312 | + chan->omtu, mtu); |
---|
| 6313 | + result = L2CAP_RECONF_INVALID_MTU; |
---|
| 6314 | + } |
---|
| 6315 | + |
---|
| 6316 | + chan->omtu = mtu; |
---|
| 6317 | + chan->remote_mps = mps; |
---|
| 6318 | + } |
---|
| 6319 | + |
---|
| 6320 | +respond: |
---|
| 6321 | + rsp.result = cpu_to_le16(result); |
---|
| 6322 | + |
---|
| 6323 | + l2cap_send_cmd(conn, cmd->ident, L2CAP_ECRED_RECONF_RSP, sizeof(rsp), |
---|
| 6324 | + &rsp); |
---|
| 6325 | + |
---|
| 6326 | + return 0; |
---|
| 6327 | +} |
---|
| 6328 | + |
---|
| 6329 | +static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn, |
---|
| 6330 | + struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
---|
| 6331 | + u8 *data) |
---|
| 6332 | +{ |
---|
| 6333 | + struct l2cap_chan *chan, *tmp; |
---|
| 6334 | + struct l2cap_ecred_conn_rsp *rsp = (void *) data; |
---|
| 6335 | + u16 result; |
---|
| 6336 | + |
---|
| 6337 | + if (cmd_len < sizeof(*rsp)) |
---|
| 6338 | + return -EPROTO; |
---|
| 6339 | + |
---|
| 6340 | + result = __le16_to_cpu(rsp->result); |
---|
| 6341 | + |
---|
| 6342 | + BT_DBG("result 0x%4.4x", rsp->result); |
---|
| 6343 | + |
---|
| 6344 | + if (!result) |
---|
| 6345 | + return 0; |
---|
| 6346 | + |
---|
| 6347 | + list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) { |
---|
| 6348 | + if (chan->ident != cmd->ident) |
---|
| 6349 | + continue; |
---|
| 6350 | + |
---|
| 6351 | + l2cap_chan_del(chan, ECONNRESET); |
---|
| 6352 | + } |
---|
5655 | 6353 | |
---|
5656 | 6354 | return 0; |
---|
5657 | 6355 | } |
---|
.. | .. |
---|
5672 | 6370 | if (!chan) |
---|
5673 | 6371 | goto done; |
---|
5674 | 6372 | |
---|
| 6373 | + chan = l2cap_chan_hold_unless_zero(chan); |
---|
| 6374 | + if (!chan) |
---|
| 6375 | + goto done; |
---|
| 6376 | + |
---|
5675 | 6377 | l2cap_chan_lock(chan); |
---|
5676 | 6378 | l2cap_chan_del(chan, ECONNREFUSED); |
---|
5677 | 6379 | l2cap_chan_unlock(chan); |
---|
| 6380 | + l2cap_chan_put(chan); |
---|
5678 | 6381 | |
---|
5679 | 6382 | done: |
---|
5680 | 6383 | mutex_unlock(&conn->chan_lock); |
---|
.. | .. |
---|
5709 | 6412 | |
---|
5710 | 6413 | case L2CAP_LE_CREDITS: |
---|
5711 | 6414 | err = l2cap_le_credits(conn, cmd, cmd_len, data); |
---|
| 6415 | + break; |
---|
| 6416 | + |
---|
| 6417 | + case L2CAP_ECRED_CONN_REQ: |
---|
| 6418 | + err = l2cap_ecred_conn_req(conn, cmd, cmd_len, data); |
---|
| 6419 | + break; |
---|
| 6420 | + |
---|
| 6421 | + case L2CAP_ECRED_CONN_RSP: |
---|
| 6422 | + err = l2cap_ecred_conn_rsp(conn, cmd, cmd_len, data); |
---|
| 6423 | + break; |
---|
| 6424 | + |
---|
| 6425 | + case L2CAP_ECRED_RECONF_REQ: |
---|
| 6426 | + err = l2cap_ecred_reconf_req(conn, cmd, cmd_len, data); |
---|
| 6427 | + break; |
---|
| 6428 | + |
---|
| 6429 | + case L2CAP_ECRED_RECONF_RSP: |
---|
| 6430 | + err = l2cap_ecred_reconf_rsp(conn, cmd, cmd_len, data); |
---|
5712 | 6431 | break; |
---|
5713 | 6432 | |
---|
5714 | 6433 | case L2CAP_DISCONN_REQ: |
---|
.. | .. |
---|
5773 | 6492 | struct sk_buff *skb) |
---|
5774 | 6493 | { |
---|
5775 | 6494 | struct hci_conn *hcon = conn->hcon; |
---|
5776 | | - u8 *data = skb->data; |
---|
5777 | | - int len = skb->len; |
---|
5778 | | - struct l2cap_cmd_hdr cmd; |
---|
| 6495 | + struct l2cap_cmd_hdr *cmd; |
---|
5779 | 6496 | int err; |
---|
5780 | 6497 | |
---|
5781 | 6498 | l2cap_raw_recv(conn, skb); |
---|
.. | .. |
---|
5783 | 6500 | if (hcon->type != ACL_LINK) |
---|
5784 | 6501 | goto drop; |
---|
5785 | 6502 | |
---|
5786 | | - while (len >= L2CAP_CMD_HDR_SIZE) { |
---|
5787 | | - u16 cmd_len; |
---|
5788 | | - memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE); |
---|
5789 | | - data += L2CAP_CMD_HDR_SIZE; |
---|
5790 | | - len -= L2CAP_CMD_HDR_SIZE; |
---|
| 6503 | + while (skb->len >= L2CAP_CMD_HDR_SIZE) { |
---|
| 6504 | + u16 len; |
---|
5791 | 6505 | |
---|
5792 | | - cmd_len = le16_to_cpu(cmd.len); |
---|
| 6506 | + cmd = (void *) skb->data; |
---|
| 6507 | + skb_pull(skb, L2CAP_CMD_HDR_SIZE); |
---|
5793 | 6508 | |
---|
5794 | | - BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, |
---|
5795 | | - cmd.ident); |
---|
| 6509 | + len = le16_to_cpu(cmd->len); |
---|
5796 | 6510 | |
---|
5797 | | - if (cmd_len > len || !cmd.ident) { |
---|
| 6511 | + BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, |
---|
| 6512 | + cmd->ident); |
---|
| 6513 | + |
---|
| 6514 | + if (len > skb->len || !cmd->ident) { |
---|
5798 | 6515 | BT_DBG("corrupted command"); |
---|
5799 | 6516 | break; |
---|
5800 | 6517 | } |
---|
5801 | 6518 | |
---|
5802 | | - err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data); |
---|
| 6519 | + err = l2cap_bredr_sig_cmd(conn, cmd, len, skb->data); |
---|
5803 | 6520 | if (err) { |
---|
5804 | 6521 | struct l2cap_cmd_rej_unk rej; |
---|
5805 | 6522 | |
---|
5806 | 6523 | BT_ERR("Wrong link type (%d)", err); |
---|
5807 | 6524 | |
---|
5808 | 6525 | rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); |
---|
5809 | | - l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, |
---|
| 6526 | + l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, |
---|
5810 | 6527 | sizeof(rej), &rej); |
---|
5811 | 6528 | } |
---|
5812 | 6529 | |
---|
5813 | | - data += cmd_len; |
---|
5814 | | - len -= cmd_len; |
---|
| 6530 | + skb_pull(skb, len); |
---|
5815 | 6531 | } |
---|
5816 | 6532 | |
---|
5817 | 6533 | drop: |
---|
.. | .. |
---|
6213 | 6929 | struct l2cap_ctrl *control, |
---|
6214 | 6930 | struct sk_buff *skb, u8 event) |
---|
6215 | 6931 | { |
---|
| 6932 | + struct l2cap_ctrl local_control; |
---|
6216 | 6933 | int err = 0; |
---|
6217 | 6934 | bool skb_in_use = false; |
---|
6218 | 6935 | |
---|
.. | .. |
---|
6237 | 6954 | chan->buffer_seq = chan->expected_tx_seq; |
---|
6238 | 6955 | skb_in_use = true; |
---|
6239 | 6956 | |
---|
| 6957 | + /* l2cap_reassemble_sdu may free skb, hence invalidate |
---|
| 6958 | + * control, so make a copy in advance to use it after |
---|
| 6959 | + * l2cap_reassemble_sdu returns and to avoid the race |
---|
| 6960 | + * condition, for example: |
---|
| 6961 | + * |
---|
| 6962 | + * The current thread calls: |
---|
| 6963 | + * l2cap_reassemble_sdu |
---|
| 6964 | + * chan->ops->recv == l2cap_sock_recv_cb |
---|
| 6965 | + * __sock_queue_rcv_skb |
---|
| 6966 | + * Another thread calls: |
---|
| 6967 | + * bt_sock_recvmsg |
---|
| 6968 | + * skb_recv_datagram |
---|
| 6969 | + * skb_free_datagram |
---|
| 6970 | + * Then the current thread tries to access control, but |
---|
| 6971 | + * it was freed by skb_free_datagram. |
---|
| 6972 | + */ |
---|
| 6973 | + local_control = *control; |
---|
6240 | 6974 | err = l2cap_reassemble_sdu(chan, skb, control); |
---|
6241 | 6975 | if (err) |
---|
6242 | 6976 | break; |
---|
6243 | 6977 | |
---|
6244 | | - if (control->final) { |
---|
| 6978 | + if (local_control.final) { |
---|
6245 | 6979 | if (!test_and_clear_bit(CONN_REJ_ACT, |
---|
6246 | 6980 | &chan->conn_state)) { |
---|
6247 | | - control->final = 0; |
---|
6248 | | - l2cap_retransmit_all(chan, control); |
---|
| 6981 | + local_control.final = 0; |
---|
| 6982 | + l2cap_retransmit_all(chan, &local_control); |
---|
6249 | 6983 | l2cap_ertm_send(chan); |
---|
6250 | 6984 | } |
---|
6251 | 6985 | } |
---|
.. | .. |
---|
6625 | 7359 | static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, |
---|
6626 | 7360 | struct sk_buff *skb) |
---|
6627 | 7361 | { |
---|
| 7362 | + /* l2cap_reassemble_sdu may free skb, hence invalidate control, so store |
---|
| 7363 | + * the txseq field in advance to use it after l2cap_reassemble_sdu |
---|
| 7364 | + * returns and to avoid the race condition, for example: |
---|
| 7365 | + * |
---|
| 7366 | + * The current thread calls: |
---|
| 7367 | + * l2cap_reassemble_sdu |
---|
| 7368 | + * chan->ops->recv == l2cap_sock_recv_cb |
---|
| 7369 | + * __sock_queue_rcv_skb |
---|
| 7370 | + * Another thread calls: |
---|
| 7371 | + * bt_sock_recvmsg |
---|
| 7372 | + * skb_recv_datagram |
---|
| 7373 | + * skb_free_datagram |
---|
| 7374 | + * Then the current thread tries to access control, but it was freed by |
---|
| 7375 | + * skb_free_datagram. |
---|
| 7376 | + */ |
---|
| 7377 | + u16 txseq = control->txseq; |
---|
| 7378 | + |
---|
6628 | 7379 | BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb, |
---|
6629 | 7380 | chan->rx_state); |
---|
6630 | 7381 | |
---|
6631 | | - if (l2cap_classify_txseq(chan, control->txseq) == |
---|
6632 | | - L2CAP_TXSEQ_EXPECTED) { |
---|
| 7382 | + if (l2cap_classify_txseq(chan, txseq) == L2CAP_TXSEQ_EXPECTED) { |
---|
6633 | 7383 | l2cap_pass_to_tx(chan, control); |
---|
6634 | 7384 | |
---|
6635 | 7385 | BT_DBG("buffer_seq %d->%d", chan->buffer_seq, |
---|
.. | .. |
---|
6652 | 7402 | } |
---|
6653 | 7403 | } |
---|
6654 | 7404 | |
---|
6655 | | - chan->last_acked_seq = control->txseq; |
---|
6656 | | - chan->expected_tx_seq = __next_seq(chan, control->txseq); |
---|
| 7405 | + chan->last_acked_seq = txseq; |
---|
| 7406 | + chan->expected_tx_seq = __next_seq(chan, txseq); |
---|
6657 | 7407 | |
---|
6658 | 7408 | return 0; |
---|
6659 | 7409 | } |
---|
.. | .. |
---|
6757 | 7507 | struct l2cap_le_credits pkt; |
---|
6758 | 7508 | u16 return_credits; |
---|
6759 | 7509 | |
---|
6760 | | - /* We return more credits to the sender only after the amount of |
---|
6761 | | - * credits falls below half of the initial amount. |
---|
6762 | | - */ |
---|
6763 | | - if (chan->rx_credits >= (le_max_credits + 1) / 2) |
---|
| 7510 | + return_credits = (chan->imtu / chan->mps) + 1; |
---|
| 7511 | + |
---|
| 7512 | + if (chan->rx_credits >= return_credits) |
---|
6764 | 7513 | return; |
---|
6765 | 7514 | |
---|
6766 | | - return_credits = le_max_credits - chan->rx_credits; |
---|
| 7515 | + return_credits -= chan->rx_credits; |
---|
6767 | 7516 | |
---|
6768 | 7517 | BT_DBG("chan %p returning %u credits to sender", chan, return_credits); |
---|
6769 | 7518 | |
---|
.. | .. |
---|
6777 | 7526 | l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt); |
---|
6778 | 7527 | } |
---|
6779 | 7528 | |
---|
6780 | | -static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) |
---|
| 7529 | +static int l2cap_ecred_recv(struct l2cap_chan *chan, struct sk_buff *skb) |
---|
| 7530 | +{ |
---|
| 7531 | + int err; |
---|
| 7532 | + |
---|
| 7533 | + BT_DBG("SDU reassemble complete: chan %p skb->len %u", chan, skb->len); |
---|
| 7534 | + |
---|
| 7535 | + /* Wait recv to confirm reception before updating the credits */ |
---|
| 7536 | + err = chan->ops->recv(chan, skb); |
---|
| 7537 | + |
---|
| 7538 | + /* Update credits whenever an SDU is received */ |
---|
| 7539 | + l2cap_chan_le_send_credits(chan); |
---|
| 7540 | + |
---|
| 7541 | + return err; |
---|
| 7542 | +} |
---|
| 7543 | + |
---|
| 7544 | +static int l2cap_ecred_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) |
---|
6781 | 7545 | { |
---|
6782 | 7546 | int err; |
---|
6783 | 7547 | |
---|
.. | .. |
---|
6795 | 7559 | chan->rx_credits--; |
---|
6796 | 7560 | BT_DBG("rx_credits %u -> %u", chan->rx_credits + 1, chan->rx_credits); |
---|
6797 | 7561 | |
---|
6798 | | - l2cap_chan_le_send_credits(chan); |
---|
| 7562 | + /* Update if remote had run out of credits, this should only happens |
---|
| 7563 | + * if the remote is not using the entire MPS. |
---|
| 7564 | + */ |
---|
| 7565 | + if (!chan->rx_credits) |
---|
| 7566 | + l2cap_chan_le_send_credits(chan); |
---|
6799 | 7567 | |
---|
6800 | 7568 | err = 0; |
---|
6801 | 7569 | |
---|
.. | .. |
---|
6821 | 7589 | } |
---|
6822 | 7590 | |
---|
6823 | 7591 | if (skb->len == sdu_len) |
---|
6824 | | - return chan->ops->recv(chan, skb); |
---|
| 7592 | + return l2cap_ecred_recv(chan, skb); |
---|
6825 | 7593 | |
---|
6826 | 7594 | chan->sdu = skb; |
---|
6827 | 7595 | chan->sdu_len = sdu_len; |
---|
.. | .. |
---|
6853 | 7621 | skb = NULL; |
---|
6854 | 7622 | |
---|
6855 | 7623 | if (chan->sdu->len == chan->sdu_len) { |
---|
6856 | | - err = chan->ops->recv(chan, chan->sdu); |
---|
| 7624 | + err = l2cap_ecred_recv(chan, chan->sdu); |
---|
6857 | 7625 | if (!err) { |
---|
6858 | 7626 | chan->sdu = NULL; |
---|
6859 | 7627 | chan->sdu_last_frag = NULL; |
---|
.. | .. |
---|
6891 | 7659 | return; |
---|
6892 | 7660 | } |
---|
6893 | 7661 | |
---|
| 7662 | + l2cap_chan_hold(chan); |
---|
6894 | 7663 | l2cap_chan_lock(chan); |
---|
6895 | 7664 | } else { |
---|
6896 | 7665 | BT_DBG("unknown cid 0x%4.4x", cid); |
---|
.. | .. |
---|
6903 | 7672 | BT_DBG("chan %p, len %d", chan, skb->len); |
---|
6904 | 7673 | |
---|
6905 | 7674 | /* If we receive data on a fixed channel before the info req/rsp |
---|
6906 | | - * procdure is done simply assume that the channel is supported |
---|
| 7675 | + * procedure is done simply assume that the channel is supported |
---|
6907 | 7676 | * and mark it as ready. |
---|
6908 | 7677 | */ |
---|
6909 | 7678 | if (chan->chan_type == L2CAP_CHAN_FIXED) |
---|
.. | .. |
---|
6914 | 7683 | |
---|
6915 | 7684 | switch (chan->mode) { |
---|
6916 | 7685 | case L2CAP_MODE_LE_FLOWCTL: |
---|
6917 | | - if (l2cap_le_data_rcv(chan, skb) < 0) |
---|
| 7686 | + case L2CAP_MODE_EXT_FLOWCTL: |
---|
| 7687 | + if (l2cap_ecred_data_rcv(chan, skb) < 0) |
---|
6918 | 7688 | goto drop; |
---|
6919 | 7689 | |
---|
6920 | 7690 | goto done; |
---|
.. | .. |
---|
6949 | 7719 | |
---|
6950 | 7720 | done: |
---|
6951 | 7721 | l2cap_chan_unlock(chan); |
---|
| 7722 | + l2cap_chan_put(chan); |
---|
6952 | 7723 | } |
---|
6953 | 7724 | |
---|
6954 | 7725 | static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, |
---|
.. | .. |
---|
7086 | 7857 | conn->mtu = hcon->hdev->le_mtu; |
---|
7087 | 7858 | break; |
---|
7088 | 7859 | } |
---|
7089 | | - /* fall through */ |
---|
| 7860 | + fallthrough; |
---|
7090 | 7861 | default: |
---|
7091 | 7862 | conn->mtu = hcon->hdev->acl_mtu; |
---|
7092 | 7863 | break; |
---|
.. | .. |
---|
7133 | 7904 | return ((psm & 0x0101) == 0x0001); |
---|
7134 | 7905 | } |
---|
7135 | 7906 | |
---|
| 7907 | +struct l2cap_chan_data { |
---|
| 7908 | + struct l2cap_chan *chan; |
---|
| 7909 | + struct pid *pid; |
---|
| 7910 | + int count; |
---|
| 7911 | +}; |
---|
| 7912 | + |
---|
| 7913 | +static void l2cap_chan_by_pid(struct l2cap_chan *chan, void *data) |
---|
| 7914 | +{ |
---|
| 7915 | + struct l2cap_chan_data *d = data; |
---|
| 7916 | + struct pid *pid; |
---|
| 7917 | + |
---|
| 7918 | + if (chan == d->chan) |
---|
| 7919 | + return; |
---|
| 7920 | + |
---|
| 7921 | + if (!test_bit(FLAG_DEFER_SETUP, &chan->flags)) |
---|
| 7922 | + return; |
---|
| 7923 | + |
---|
| 7924 | + pid = chan->ops->get_peer_pid(chan); |
---|
| 7925 | + |
---|
| 7926 | + /* Only count deferred channels with the same PID/PSM */ |
---|
| 7927 | + if (d->pid != pid || chan->psm != d->chan->psm || chan->ident || |
---|
| 7928 | + chan->mode != L2CAP_MODE_EXT_FLOWCTL || chan->state != BT_CONNECT) |
---|
| 7929 | + return; |
---|
| 7930 | + |
---|
| 7931 | + d->count++; |
---|
| 7932 | +} |
---|
| 7933 | + |
---|
7136 | 7934 | int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, |
---|
7137 | 7935 | bdaddr_t *dst, u8 dst_type) |
---|
7138 | 7936 | { |
---|
.. | .. |
---|
7141 | 7939 | struct hci_dev *hdev; |
---|
7142 | 7940 | int err; |
---|
7143 | 7941 | |
---|
7144 | | - BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst, |
---|
7145 | | - dst_type, __le16_to_cpu(psm)); |
---|
| 7942 | + BT_DBG("%pMR -> %pMR (type %u) psm 0x%4.4x mode 0x%2.2x", &chan->src, |
---|
| 7943 | + dst, dst_type, __le16_to_cpu(psm), chan->mode); |
---|
7146 | 7944 | |
---|
7147 | 7945 | hdev = hci_get_route(dst, &chan->src, chan->src_type); |
---|
7148 | 7946 | if (!hdev) |
---|
.. | .. |
---|
7170 | 7968 | case L2CAP_MODE_BASIC: |
---|
7171 | 7969 | break; |
---|
7172 | 7970 | case L2CAP_MODE_LE_FLOWCTL: |
---|
7173 | | - l2cap_le_flowctl_init(chan); |
---|
| 7971 | + break; |
---|
| 7972 | + case L2CAP_MODE_EXT_FLOWCTL: |
---|
| 7973 | + if (!enable_ecred) { |
---|
| 7974 | + err = -EOPNOTSUPP; |
---|
| 7975 | + goto done; |
---|
| 7976 | + } |
---|
7174 | 7977 | break; |
---|
7175 | 7978 | case L2CAP_MODE_ERTM: |
---|
7176 | 7979 | case L2CAP_MODE_STREAMING: |
---|
7177 | 7980 | if (!disable_ertm) |
---|
7178 | 7981 | break; |
---|
7179 | | - /* fall through */ |
---|
| 7982 | + fallthrough; |
---|
7180 | 7983 | default: |
---|
7181 | 7984 | err = -EOPNOTSUPP; |
---|
7182 | 7985 | goto done; |
---|
.. | .. |
---|
7228 | 8031 | else |
---|
7229 | 8032 | hcon = hci_connect_le_scan(hdev, dst, dst_type, |
---|
7230 | 8033 | chan->sec_level, |
---|
7231 | | - HCI_LE_CONN_TIMEOUT); |
---|
| 8034 | + HCI_LE_CONN_TIMEOUT, |
---|
| 8035 | + CONN_REASON_L2CAP_CHAN); |
---|
7232 | 8036 | |
---|
7233 | 8037 | } else { |
---|
7234 | 8038 | u8 auth_type = l2cap_get_auth_type(chan); |
---|
7235 | | - hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type); |
---|
| 8039 | + hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type, |
---|
| 8040 | + CONN_REASON_L2CAP_CHAN); |
---|
7236 | 8041 | } |
---|
7237 | 8042 | |
---|
7238 | 8043 | if (IS_ERR(hcon)) { |
---|
.. | .. |
---|
7245 | 8050 | hci_conn_drop(hcon); |
---|
7246 | 8051 | err = -ENOMEM; |
---|
7247 | 8052 | goto done; |
---|
| 8053 | + } |
---|
| 8054 | + |
---|
| 8055 | + if (chan->mode == L2CAP_MODE_EXT_FLOWCTL) { |
---|
| 8056 | + struct l2cap_chan_data data; |
---|
| 8057 | + |
---|
| 8058 | + data.chan = chan; |
---|
| 8059 | + data.pid = chan->ops->get_peer_pid(chan); |
---|
| 8060 | + data.count = 1; |
---|
| 8061 | + |
---|
| 8062 | + l2cap_chan_list(conn, l2cap_chan_by_pid, &data); |
---|
| 8063 | + |
---|
| 8064 | + /* Check if there isn't too many channels being connected */ |
---|
| 8065 | + if (data.count > L2CAP_ECRED_CONN_SCID_MAX) { |
---|
| 8066 | + hci_conn_drop(hcon); |
---|
| 8067 | + err = -EPROTO; |
---|
| 8068 | + goto done; |
---|
| 8069 | + } |
---|
7248 | 8070 | } |
---|
7249 | 8071 | |
---|
7250 | 8072 | mutex_lock(&conn->chan_lock); |
---|
.. | .. |
---|
7295 | 8117 | return err; |
---|
7296 | 8118 | } |
---|
7297 | 8119 | EXPORT_SYMBOL_GPL(l2cap_chan_connect); |
---|
| 8120 | + |
---|
| 8121 | +static void l2cap_ecred_reconfigure(struct l2cap_chan *chan) |
---|
| 8122 | +{ |
---|
| 8123 | + struct l2cap_conn *conn = chan->conn; |
---|
| 8124 | + struct { |
---|
| 8125 | + struct l2cap_ecred_reconf_req req; |
---|
| 8126 | + __le16 scid; |
---|
| 8127 | + } pdu; |
---|
| 8128 | + |
---|
| 8129 | + pdu.req.mtu = cpu_to_le16(chan->imtu); |
---|
| 8130 | + pdu.req.mps = cpu_to_le16(chan->mps); |
---|
| 8131 | + pdu.scid = cpu_to_le16(chan->scid); |
---|
| 8132 | + |
---|
| 8133 | + chan->ident = l2cap_get_ident(conn); |
---|
| 8134 | + |
---|
| 8135 | + l2cap_send_cmd(conn, chan->ident, L2CAP_ECRED_RECONF_REQ, |
---|
| 8136 | + sizeof(pdu), &pdu); |
---|
| 8137 | +} |
---|
| 8138 | + |
---|
| 8139 | +int l2cap_chan_reconfigure(struct l2cap_chan *chan, __u16 mtu) |
---|
| 8140 | +{ |
---|
| 8141 | + if (chan->imtu > mtu) |
---|
| 8142 | + return -EINVAL; |
---|
| 8143 | + |
---|
| 8144 | + BT_DBG("chan %p mtu 0x%4.4x", chan, mtu); |
---|
| 8145 | + |
---|
| 8146 | + chan->imtu = mtu; |
---|
| 8147 | + |
---|
| 8148 | + l2cap_ecred_reconfigure(chan); |
---|
| 8149 | + |
---|
| 8150 | + return 0; |
---|
| 8151 | +} |
---|
7298 | 8152 | |
---|
7299 | 8153 | /* ---- L2CAP interface with lower layer (HCI) ---- */ |
---|
7300 | 8154 | |
---|
.. | .. |
---|
7353 | 8207 | if (src_type != c->src_type) |
---|
7354 | 8208 | continue; |
---|
7355 | 8209 | |
---|
7356 | | - l2cap_chan_hold(c); |
---|
| 8210 | + c = l2cap_chan_hold_unless_zero(c); |
---|
7357 | 8211 | read_unlock(&chan_list_lock); |
---|
7358 | 8212 | return c; |
---|
7359 | 8213 | } |
---|
.. | .. |
---|
7507 | 8361 | else |
---|
7508 | 8362 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
---|
7509 | 8363 | } else if (chan->state == BT_CONNECT2 && |
---|
7510 | | - chan->mode != L2CAP_MODE_LE_FLOWCTL) { |
---|
| 8364 | + !(chan->mode == L2CAP_MODE_EXT_FLOWCTL || |
---|
| 8365 | + chan->mode == L2CAP_MODE_LE_FLOWCTL)) { |
---|
7511 | 8366 | struct l2cap_conn_rsp rsp; |
---|
7512 | 8367 | __u16 res, stat; |
---|
7513 | 8368 | |
---|
.. | .. |
---|
7683 | 8538 | return 0; |
---|
7684 | 8539 | } |
---|
7685 | 8540 | |
---|
7686 | | -static int l2cap_debugfs_open(struct inode *inode, struct file *file) |
---|
7687 | | -{ |
---|
7688 | | - return single_open(file, l2cap_debugfs_show, inode->i_private); |
---|
7689 | | -} |
---|
7690 | | - |
---|
7691 | | -static const struct file_operations l2cap_debugfs_fops = { |
---|
7692 | | - .open = l2cap_debugfs_open, |
---|
7693 | | - .read = seq_read, |
---|
7694 | | - .llseek = seq_lseek, |
---|
7695 | | - .release = single_release, |
---|
7696 | | -}; |
---|
| 8541 | +DEFINE_SHOW_ATTRIBUTE(l2cap_debugfs); |
---|
7697 | 8542 | |
---|
7698 | 8543 | static struct dentry *l2cap_debugfs; |
---|
7699 | 8544 | |
---|
.. | .. |
---|
7713 | 8558 | l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs, |
---|
7714 | 8559 | NULL, &l2cap_debugfs_fops); |
---|
7715 | 8560 | |
---|
7716 | | - debugfs_create_u16("l2cap_le_max_credits", 0644, bt_debugfs, |
---|
7717 | | - &le_max_credits); |
---|
7718 | | - debugfs_create_u16("l2cap_le_default_mps", 0644, bt_debugfs, |
---|
7719 | | - &le_default_mps); |
---|
7720 | | - |
---|
7721 | 8561 | return 0; |
---|
7722 | 8562 | } |
---|
7723 | 8563 | |
---|
.. | .. |
---|
7730 | 8570 | |
---|
7731 | 8571 | module_param(disable_ertm, bool, 0644); |
---|
7732 | 8572 | MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode"); |
---|
| 8573 | + |
---|
| 8574 | +module_param(enable_ecred, bool, 0644); |
---|
| 8575 | +MODULE_PARM_DESC(enable_ecred, "Enable enhanced credit flow control mode"); |
---|