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

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

 



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


> 
>   < 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