Re: [PATCH] Bluetooth: L2CAP: Fix L2CAP MTU negotiation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Luiz,

pe, 2025-07-11 kello 10:57 -0400, Luiz Augusto von Dentz kirjoitti:
> Hi Pauli,
> 
> On Fri, Jul 11, 2025 at 9:53 AM Pauli Virtanen <pav@xxxxxx> wrote:
> > 
> > Hi,
> > 
> > to, 2025-06-12 kello 09:50 +0200, Frédéric Danis kirjoitti:
> > > OBEX download from iPhone is currently slow due to small packet size
> > > used to transfer data which doesn't follow the MTU negotiated during
> > > L2CAP connection, i.e. 672 bytes instead of 32767:
> > 
> > There are some reports that appear to indicate this commit causes
> > regressions for A2DP:
> > 
> > https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/issues/149#note_285698
> > 
> > https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4793#note_3001287
> 
> Might be a good idea to create a github issue for it, doesn't seem
> like the above issues had collected any btmon traces yet, perhaps the
> MTU is not updated or left to 0? Anyway we may want to add a test in
> l2cap-tester to try to reproduce the same scenario.

The first link had btmon traces, and here's another:

https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4793#note_2999272

> 
> > 
> > > 
> > >   < ACL Data TX: Handle 11 flags 0x00 dlen 12
> > >       L2CAP: Connection Request (0x02) ident 18 len 4
> > >         PSM: 4103 (0x1007)
> > >         Source CID: 72
> > >   > ACL Data RX: Handle 11 flags 0x02 dlen 16
> > >       L2CAP: Connection Response (0x03) ident 18 len 8
> > >         Destination CID: 14608
> > >         Source CID: 72
> > >         Result: Connection successful (0x0000)
> > >         Status: No further information available (0x0000)
> > >   < ACL Data TX: Handle 11 flags 0x00 dlen 27
> > >       L2CAP: Configure Request (0x04) ident 20 len 19
> > >         Destination CID: 14608
> > >         Flags: 0x0000
> > >         Option: Maximum Transmission Unit (0x01) [mandatory]
> > >           MTU: 32767
> > >         Option: Retransmission and Flow Control (0x04) [mandatory]
> > >           Mode: Enhanced Retransmission (0x03)
> > >           TX window size: 63
> > >           Max transmit: 3
> > >           Retransmission timeout: 2000
> > >           Monitor timeout: 12000
> > >           Maximum PDU size: 1009
> > >   > ACL Data RX: Handle 11 flags 0x02 dlen 26
> > >       L2CAP: Configure Request (0x04) ident 72 len 18
> > >         Destination CID: 72
> > >         Flags: 0x0000
> > >         Option: Retransmission and Flow Control (0x04) [mandatory]
> > >           Mode: Enhanced Retransmission (0x03)
> > >           TX window size: 32
> > >           Max transmit: 255
> > >           Retransmission timeout: 0
> > >           Monitor timeout: 0
> > >           Maximum PDU size: 65527
> > >         Option: Frame Check Sequence (0x05) [mandatory]
> > >           FCS: 16-bit FCS (0x01)
> > >   < ACL Data TX: Handle 11 flags 0x00 dlen 29
> > >       L2CAP: Configure Response (0x05) ident 72 len 21
> > >         Source CID: 14608
> > >         Flags: 0x0000
> > >         Result: Success (0x0000)
> > >         Option: Maximum Transmission Unit (0x01) [mandatory]
> > >           MTU: 672
> > >         Option: Retransmission and Flow Control (0x04) [mandatory]
> > >           Mode: Enhanced Retransmission (0x03)
> > >           TX window size: 32
> > >           Max transmit: 255
> > >           Retransmission timeout: 2000
> > >           Monitor timeout: 12000
> > >           Maximum PDU size: 1009
> > >   > ACL Data RX: Handle 11 flags 0x02 dlen 32
> > >       L2CAP: Configure Response (0x05) ident 20 len 24
> > >         Source CID: 72
> > >         Flags: 0x0000
> > >         Result: Success (0x0000)
> > >         Option: Maximum Transmission Unit (0x01) [mandatory]
> > >           MTU: 32767
> > >         Option: Retransmission and Flow Control (0x04) [mandatory]
> > >           Mode: Enhanced Retransmission (0x03)
> > >           TX window size: 63
> > >           Max transmit: 3
> > >           Retransmission timeout: 2000
> > >           Monitor timeout: 12000
> > >           Maximum PDU size: 1009
> > >         Option: Frame Check Sequence (0x05) [mandatory]
> > >           FCS: 16-bit FCS (0x01)
> > >   ...
> > >   > ACL Data RX: Handle 11 flags 0x02 dlen 680
> > >       Channel: 72 len 676 ctrl 0x0202 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8}
> > >       I-frame: Unsegmented TxSeq 1 ReqSeq 2
> > >   < ACL Data TX: Handle 11 flags 0x00 dlen 13
> > >       Channel: 14608 len 9 ctrl 0x0204 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8}
> > >       I-frame: Unsegmented TxSeq 2 ReqSeq 2
> > >   > ACL Data RX: Handle 11 flags 0x02 dlen 680
> > >       Channel: 72 len 676 ctrl 0x0304 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8}
> > >       I-frame: Unsegmented TxSeq 2 ReqSeq 3
> > > 
> > > The MTUs are negotiated for each direction. In this traces 32767 for
> > > iPhone->localhost and no MTU for localhost->iPhone, which based on
> > > '4.4 L2CAP_CONFIGURATION_REQ' (Core specification v5.4, Vol. 3, Part
> > > A):
> > > 
> > >   The only parameters that should be included in the
> > >   L2CAP_CONFIGURATION_REQ packet are those that require different
> > >   values than the default or previously agreed values.
> > >   ...
> > >   Any missing configuration parameters are assumed to have their
> > >   most recently explicitly or implicitly accepted values.
> > > 
> > > and '5.1 Maximum transmission unit (MTU)':
> > > 
> > >   If the remote device sends a positive L2CAP_CONFIGURATION_RSP
> > >   packet it should include the actual MTU to be used on this channel
> > >   for traffic flowing into the local device.
> > >   ...
> > >   The default value is 672 octets.
> > > 
> > > is set by BlueZ to 672 bytes.
> > > 
> > > It seems that the iPhone used the lowest negotiated value to transfer
> > > data to the localhost instead of the negotiated one for the incoming
> > > direction.
> > > 
> > > This could be fixed by using the MTU negotiated for the other
> > > direction, if exists, in the L2CAP_CONFIGURATION_RSP.
> > > This allows to use segmented packets as in the following traces:
> > > 
> > >   < ACL Data TX: Handle 11 flags 0x00 dlen 12
> > >         L2CAP: Connection Request (0x02) ident 22 len 4
> > >           PSM: 4103 (0x1007)
> > >           Source CID: 72
> > >   < ACL Data TX: Handle 11 flags 0x00 dlen 27
> > >         L2CAP: Configure Request (0x04) ident 24 len 19
> > >           Destination CID: 2832
> > >           Flags: 0x0000
> > >           Option: Maximum Transmission Unit (0x01) [mandatory]
> > >             MTU: 32767
> > >           Option: Retransmission and Flow Control (0x04) [mandatory]
> > >             Mode: Enhanced Retransmission (0x03)
> > >             TX window size: 63
> > >             Max transmit: 3
> > >             Retransmission timeout: 2000
> > >             Monitor timeout: 12000
> > >             Maximum PDU size: 1009
> > >   > ACL Data RX: Handle 11 flags 0x02 dlen 26
> > >         L2CAP: Configure Request (0x04) ident 15 len 18
> > >           Destination CID: 72
> > >           Flags: 0x0000
> > >           Option: Retransmission and Flow Control (0x04) [mandatory]
> > >             Mode: Enhanced Retransmission (0x03)
> > >             TX window size: 32
> > >             Max transmit: 255
> > >             Retransmission timeout: 0
> > >             Monitor timeout: 0
> > >             Maximum PDU size: 65527
> > >           Option: Frame Check Sequence (0x05) [mandatory]
> > >             FCS: 16-bit FCS (0x01)
> > >   < ACL Data TX: Handle 11 flags 0x00 dlen 29
> > >         L2CAP: Configure Response (0x05) ident 15 len 21
> > >           Source CID: 2832
> > >           Flags: 0x0000
> > >           Result: Success (0x0000)
> > >           Option: Maximum Transmission Unit (0x01) [mandatory]
> > >             MTU: 32767
> > >           Option: Retransmission and Flow Control (0x04) [mandatory]
> > >             Mode: Enhanced Retransmission (0x03)
> > >             TX window size: 32
> > >             Max transmit: 255
> > >             Retransmission timeout: 2000
> > >             Monitor timeout: 12000
> > >             Maximum PDU size: 1009
> > >   > ACL Data RX: Handle 11 flags 0x02 dlen 32
> > >         L2CAP: Configure Response (0x05) ident 24 len 24
> > >           Source CID: 72
> > >           Flags: 0x0000
> > >           Result: Success (0x0000)
> > >           Option: Maximum Transmission Unit (0x01) [mandatory]
> > >             MTU: 32767
> > >           Option: Retransmission and Flow Control (0x04) [mandatory]
> > >             Mode: Enhanced Retransmission (0x03)
> > >             TX window size: 63
> > >             Max transmit: 3
> > >             Retransmission timeout: 2000
> > >             Monitor timeout: 12000
> > >             Maximum PDU size: 1009
> > >           Option: Frame Check Sequence (0x05) [mandatory]
> > >             FCS: 16-bit FCS (0x01)
> > >   ...
> > >   > ACL Data RX: Handle 11 flags 0x02 dlen 1009
> > >         Channel: 72 len 1005 ctrl 0x4202 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8}
> > >         I-frame: Start (len 21884) TxSeq 1 ReqSeq 2
> > >   > ACL Data RX: Handle 11 flags 0x02 dlen 1009
> > >         Channel: 72 len 1005 ctrl 0xc204 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8}
> > >         I-frame: Continuation TxSeq 2 ReqSeq 2
> > > 
> > > This has been tested with kernel 5.4 and BlueZ 5.77.
> > > 
> > > Signed-off-by: Frédéric Danis <frederic.danis@xxxxxxxxxxxxx>
> > > ---
> > >  net/bluetooth/l2cap_core.c | 9 ++++++++-
> > >  1 file changed, 8 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> > > index a5bde5db58ef..40daa38276f3 100644
> > > --- a/net/bluetooth/l2cap_core.c
> > > +++ b/net/bluetooth/l2cap_core.c
> > > @@ -3415,7 +3415,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data
> > >       struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
> > >       struct l2cap_conf_efs efs;
> > >       u8 remote_efs = 0;
> > > -     u16 mtu = L2CAP_DEFAULT_MTU;
> > > +     u16 mtu = 0;
> > >       u16 result = L2CAP_CONF_SUCCESS;
> > >       u16 size;
> > > 
> > > @@ -3520,6 +3520,13 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data
> > >               /* Configure output options and let the other side know
> > >                * which ones we don't like. */
> > > 
> > > +             /* If MTU is not provided in configure request, use the most recently
> > > +              * explicitly or implicitly accepted value for the other direction,
> > > +              * or the default value.
> > > +              */
> > > +             if (mtu == 0)
> > > +                     mtu = chan->imtu ? chan->imtu : L2CAP_DEFAULT_MTU;
> > > +
> > >               if (mtu < L2CAP_DEFAULT_MIN_MTU)
> > >                       result = L2CAP_CONF_UNACCEPT;
> > >               else {
> > 
> > --
> > Pauli Virtanen
> 
> 





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux