Skip to content

gnrc/netif: 6lo: use 16 bit for max_frag_size#13979

Merged
miri64 merged 2 commits intoRIOT-OS:masterfrom
benpicco:net/gnrc/netif/6lo-frag_size
May 6, 2020
Merged

gnrc/netif: 6lo: use 16 bit for max_frag_size#13979
miri64 merged 2 commits intoRIOT-OS:masterfrom
benpicco:net/gnrc/netif/6lo-frag_size

Conversation

@benpicco
Copy link
Contributor

@benpicco benpicco commented Apr 29, 2020

Contribution description

Using 8 bit for max_frag_size limits that value to 255.
802.15.4g (at86rf215, cc26x2_cc13x2_rf) specifies a PDU of 2047 bytes which exceeds that limit.

Using a 16 bit value here allows to use the full L2 PDU.

Before:

12:02:16,300 # ping6 fe80::2068:3123:59f5:d238%8 -s 400
12:02:16,302 # sending 244 bytes
12:02:16,387 # sending 218 bytes
12:02:16,624 # 408 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=0 ttl=64 rssi=-49 dBm time=316.307 ms
12:02:17,302 # sending 244 bytes
12:02:17,387 # sending 218 bytes
12:02:17,624 # 408 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=1 ttl=64 rssi=-49 dBm time=316.307 ms
12:02:18,302 # sending 244 bytes
12:02:18,387 # sending 218 bytes
12:02:18,624 # 408 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=2 ttl=64 rssi=-50 dBm time=316.306 ms
12:02:18,625 #
12:02:18,629 # --- fe80::2068:3123:59f5:d238 PING statistics ---

With this patch:

12:09:44,276 #  ping6 fe80::2068:3123:59f5:d238%8 -s 400
12:09:44,278 # sending 432 bytes
12:09:44,574 # 408 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=0 ttl=64 rssi=-52 dBm time=289.888 ms
12:09:45,279 # sending 432 bytes
12:09:45,574 # 408 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=1 ttl=64 rssi=-52 dBm time=289.885 ms
12:09:46,069 # sending 43 bytes
12:09:46,279 # sending 432 bytes
12:09:46,499 # sending 43 bytes
12:09:46,574 # 408 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=2 ttl=64 rssi=-47 dBm time=289.886 ms
12:09:46,574 #
12:09:46,578 # --- fe80::2068:3123:59f5:d238 PING statistics ---

Testing procedure

Apply this patch to print the size of the TX frames:

--- a/drivers/at86rf215/at86rf215_netdev.c
+++ b/drivers/at86rf215/at86rf215_netdev.c
@@ -146,6 +146,8 @@ static int _send(netdev_t *netdev, const iolist_t *iolist)
         }
     }
 
+    printf("sending %d bytes\n", len);
+
     /* send data out directly if pre-loading id disabled */
     if (!(dev->flags & AT86RF215_OPT_PRELOADING)) {
         at86rf215_tx_exec(dev);

Enable a 802.15.4g PHY mode

ifconfig 8 set phy mr-o-qpsk

12:10:47,350 # Iface  8  HWaddr: 01:55  Channel: 26  NID: 0x23  PHY: MR-O-QPSK 
12:10:47,354 #            chip rate: 2000  rate mode: 0 
12:10:47,358 #           Long HWaddr: 1A:F9:8F:5F:30:5D:05:8C 
12:10:47,364 #            TX-Power: 0dBm  State: IDLE  max. Retrans.: 3  CSMA Retries: 4 
12:10:47,371 #           AUTOACK  ACK_REQ  CSMA  L2-PDU:2022 MTU:1280  HL:64  RTR  
12:10:47,373 #           6LO  IPHC  
12:10:47,376 #           Source address length: 8
12:10:47,378 #           Link type: wireless
12:10:47,384 #           inet6 addr: fe80::18f9:8f5f:305d:58c  scope: link  VAL
12:10:47,387 #           inet6 group: ff02::2
12:10:47,389 #           inet6 group: ff02::1
12:10:47,393 #           inet6 group: ff02::1:ff5d:58c
12:10:47,394 #           
12:10:47,397 #           Statistics for Layer 2
12:10:47,400 #             RX packets 7  bytes 1429
12:10:47,405 #             TX packets 9 (Multicast: 6)  bytes 1554
12:10:47,408 #             TX succeeded 9 errors 0
12:10:47,413 #           Statistics for IPv6
12:10:47,413 #             RX packets 4  bytes 1408
12:10:47,418 #             TX packets 9 (Multicast: 6)  bytes 1728
12:10:47,421 #             TX succeeded 9 errors 0

Unfortunately the MTU is still smaller than the L2-PDU so packets are still limited to 1280 bytes.

Issues/PRs references

#13912

@benpicco benpicco added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Area: network Area: Networking Impact: minor The PR is small in size and might only require a quick look of a knowledgeable reviewer labels Apr 29, 2020
@benpicco benpicco requested a review from miri64 April 29, 2020 10:22
@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Apr 29, 2020
@benpicco
Copy link
Contributor Author

benpicco commented Apr 29, 2020

The change required to make use of the full PDU is equally simple, so I piggybacked it here too.

2020-04-29 13:00:37,210 # Iface  8  HWaddr: 01:55  Channel: 26  NID: 0x23  PHY: MR-O-QPSK 
2020-04-29 13:00:37,214 #            chip rate: 2000  rate mode: 0 
2020-04-29 13:00:37,218 #           Long HWaddr: 1A:F9:8F:5F:30:5D:05:8C 
2020-04-29 13:00:37,225 #            TX-Power: 0dBm  State: IDLE  max. Retrans.: 3  CSMA Retries: 4 
2020-04-29 13:00:37,231 #           AUTOACK  ACK_REQ  CSMA  L2-PDU:2022 MTU:2022  HL:64  RTR  
2020-04-29 13:00:37,233 #           6LO  IPHC  
2020-04-29 13:00:37,236 #           Source address length: 8
2020-04-29 13:00:37,239 #           Link type: wireless
2020-04-29 13:00:37,244 #           inet6 addr: fe80::18f9:8f5f:305d:58c  scope: link  VAL
2020-04-29 13:00:37,247 #           inet6 group: ff02::2
2020-04-29 13:00:37,250 #           inet6 group: ff02::1
2020-04-29 13:00:37,253 #           inet6 group: ff02::1:ff5d:58c
2020-04-29 13:00:37,254 #           
2020-04-29 13:00:37,257 #           Statistics for Layer 2
2020-04-29 13:00:37,260 #             RX packets 0  bytes 0
2020-04-29 13:00:37,265 #             TX packets 2 (Multicast: 2)  bytes 86
2020-04-29 13:00:37,268 #             TX succeeded 2 errors 0
2020-04-29 13:00:37,270 #           Statistics for IPv6
2020-04-29 13:00:37,273 #             RX packets 0  bytes 0
2020-04-29 13:00:37,278 #             TX packets 2 (Multicast: 2)  bytes 128
2020-04-29 13:00:37,281 #             TX succeeded 2 errors 0

2020-04-29 13:02:38,118 #  ping6 fe80::2068:3123:59f5:d238%8 -s 1700
2020-04-29 13:02:38,123 # sending 1732 bytes
2020-04-29 13:02:39,108 # 1708 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=0 ttl=64 rssi=-51 dBm time=981.766 ms
2020-04-29 13:02:39,123 # sending 1732 bytes
2020-04-29 13:02:40,108 # 1708 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=1 ttl=64 rssi=-52 dBm time=981.751 ms
2020-04-29 13:02:40,123 # sending 1732 bytes
2020-04-29 13:02:41,108 # 1708 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=2 ttl=64 rssi=-50 dBm time=981.751 ms
2020-04-29 13:02:41,108 # 
2020-04-29 13:02:41,112 # --- fe80::2068:3123:59f5:d238 PING statistics ---
2020-04-29 13:02:41,117 # 3 packets transmitted, 3 packets received, 0% packet loss
2020-04-29 13:02:41,122 # round-trip min/avg/max = 981.751/981.756/981.766 ms

I had problems sending larger packets though, but that seems more like a driver / timing issue with RTTs > 1s getting unreliable.

edit: who would have thought, but sending pings faster than the RTT does indeed lead to packet loss.

2020-04-29 15:34:38,834 # ping6 fe80::2068:3123:59f5:d238%8 -s 1900 -i 2000
2020-04-29 15:34:38,840 # sending 1932 bytes
2020-04-29 15:34:39,934 # 1908 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=0 ttl=64 rssi=-53 dBm time=1091.011 ms
2020-04-29 15:34:40,841 # sending 1932 bytes
2020-04-29 15:34:41,934 # 1908 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=1 ttl=64 rssi=-53 dBm time=1090.984 ms
2020-04-29 15:34:42,841 # sending 1932 bytes
2020-04-29 15:34:43,934 # 1908 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=2 ttl=64 rssi=-53 dBm time=1091.012 ms
2020-04-29 15:34:43,934 # 
2020-04-29 15:34:43,938 # --- fe80::2068:3123:59f5:d238 PING statistics ---
2020-04-29 15:34:43,943 # 3 packets transmitted, 3 packets received, 0% packet loss

Works with 2s between pings.

Using 8 bit for `max_frag_size` limits that value to 255.
802.15.4g specifies a PDU of 2047 bytes which exceeds that limit.

Using a 16 bit value here allows to use the full L2 PDU.

Before:

    12:02:16,300 # ping6 fe80::2068:3123:59f5:d238%8 -s 400
    12:02:16,302 # sending 244 bytes
    12:02:16,387 # sending 218 bytes
    12:02:16,624 # 408 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=0 ttl=64 rssi=-49 dBm time=316.307 ms
    12:02:17,302 # sending 244 bytes
    12:02:17,387 # sending 218 bytes
    12:02:17,624 # 408 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=1 ttl=64 rssi=-49 dBm time=316.307 ms
    12:02:18,302 # sending 244 bytes
    12:02:18,387 # sending 218 bytes
    12:02:18,624 # 408 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=2 ttl=64 rssi=-50 dBm time=316.306 ms
    12:02:18,625 #
    12:02:18,629 # --- fe80::2068:3123:59f5:d238 PING statistics ---

With this patch:

    12:09:44,276 #  ping6 fe80::2068:3123:59f5:d238%8 -s 400
    12:09:44,278 # sending 432 bytes
    12:09:44,574 # 408 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=0 ttl=64 rssi=-52 dBm time=289.888 ms
    12:09:45,279 # sending 432 bytes
    12:09:45,574 # 408 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=1 ttl=64 rssi=-52 dBm time=289.885 ms
    12:09:46,069 # sending 43 bytes
    12:09:46,279 # sending 432 bytes
    12:09:46,499 # sending 43 bytes
    12:09:46,574 # 408 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=2 ttl=64 rssi=-47 dBm time=289.886 ms
    12:09:46,574 #
    12:09:46,578 # --- fe80::2068:3123:59f5:d238 PING statistics ---
If the L2-PDU is greater than IPV6_MIN_MTU, use that as the MTU instead.
@benpicco benpicco force-pushed the net/gnrc/netif/6lo-frag_size branch from 01102d5 to 18651eb Compare April 29, 2020 10:49
@benpicco
Copy link
Contributor Author

benpicco commented Apr 29, 2020

If I use a higher date rate (rate_mode 4) I can send larger packets which hints at a driver issue, but only to a point. There seems to be another hard limit at 2006 bytes:

2020-04-29 13:07:58,545 #  ping6 fe80::2068:3123:59f5:d238%8 -s 1974
2020-04-29 13:07:58,551 # sending 2006 bytes
2020-04-29 13:07:58,625 # 1982 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=0 ttl=64 rssi=-55 dBm time=72.146 ms
2020-04-29 13:07:59,551 # sending 2006 bytes
2020-04-29 13:07:59,626 # 1982 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=1 ttl=64 rssi=-55 dBm time=72.116 ms
2020-04-29 13:08:00,551 # sending 2006 bytes
2020-04-29 13:08:00,625 # 1982 bytes from fe80::2068:3123:59f5:d238%8: icmp_seq=2 ttl=64 rssi=-55 dBm time=72.119 ms
2020-04-29 13:08:00,626 # 
2020-04-29 13:08:00,630 # --- fe80::2068:3123:59f5:d238 PING statistics ---
2020-04-29 13:08:00,635 # 3 packets transmitted, 3 packets received, 0% packet loss
2020-04-29 13:08:00,639 # round-trip min/avg/max = 72.116/72.127/72.146 ms
> 2020-04-29 13:08:27,775 #  sending 43 bytes
2020-04-29 13:08:27,993 # sending 43 bytes
ping6 fe80::2068:3123:59f5:d238%8 -s 1975
2020-04-29 13:08:58,536 # ping6 fe80::2068:3123:59f5:d238%8 -s 1975
2020-04-29 13:09:01,537 # 
2020-04-29 13:09:01,541 # --- fe80::2068:3123:59f5:d238 PING statistics ---
2020-04-29 13:09:01,546 # 3 packets transmitted, 0 packets received, 100% packet loss

Here, the data doesn't even each the driver.

2020-04-29 15:46:25,853 # ipv6: send unicast
2020-04-29 15:46:25,858 # ipv6: set payload length to 1984 (network byteorder c007)
2020-04-29 15:46:25,861 # ipv6: set next header to 58
2020-04-29 15:46:25,865 # ipv6: set packet source to fe80::18f9:8f5f:305d:58c
2020-04-29 15:46:25,870 # ipv6: write protect up to payload to calculate checksum
2020-04-29 15:46:25,874 # ipv6: calculate checksum for upper header.
2020-04-29 15:46:25,877 # ipv6: add interface header to packet
2020-04-29 15:46:25,880 # ipv6: send unicast over interface 8
2020-04-29 15:46:25,883 # ipv6: packet too big, 2024 > 2022

I'm a bit puzzled where those 40 bytes of headers are coming from here.

@benpicco
Copy link
Contributor Author

For legacy O-QPSK the largest non-fragmented payload is 99 bytes, only 3 bytes less than the L2-PDU. Which results in a 123 byte frame (only 4 bytes shy of the max frame size of 127 bytes)

2020-04-29 15:55:16,916 # ipv6: send unicast
2020-04-29 15:55:16,921 # ipv6: set payload length to 99 (network byteorder 6300)
2020-04-29 15:55:16,923 # ipv6: set next header to 58
2020-04-29 15:55:16,928 # ipv6: set packet source to fe80::18f9:8f5f:305d:58c
2020-04-29 15:55:16,933 # ipv6: write protect up to payload to calculate checksum
2020-04-29 15:55:16,936 # ipv6: calculate checksum for upper header.
2020-04-29 15:55:16,940 # ipv6: add interface header to packet
2020-04-29 15:55:16,943 # ipv6: send unicast over interface 8
2020-04-29 15:55:16,953 # ipv6: Sending (src = fe80::18f9:8f5f:305d:58c, dst = fe80::2068:3123:59f5:d238, next header = 58, length = 99)
2020-04-29 15:55:16,955 # ipv6: send to 6LoWPAN instead
2020-04-29 15:55:16,959 # 6lo: GNRC_NETDEV_MSG_TYPE_SND received
2020-04-29 15:55:16,963 # 6lo: iface->sixlo.max_frag_size = 102 for interface 8
2020-04-29 15:55:16,966 # 6lo: Dispatch for sending
2020-04-29 15:55:16,967 # sending 123 bytes

assert(res == sizeof(tmp));
#ifdef MODULE_GNRC_SIXLOWPAN
netif->ipv6.mtu = IPV6_MIN_MTU;
netif->ipv6.mtu = MAX(IPV6_MIN_MTU, tmp);
Copy link
Member

@miri64 miri64 Apr 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a good idea, as this will lead to fragmentation in the wider internet. Better cap it at 1500.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or better: we should implement Path MTU discovery ;-P

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll see what I can do for Path MTU discovery, but that should be unrelated.
Btw.: SLIP already does MTU:65535 HL:64 RTR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. My bad. This comment was more loud thinking and inner alarm bells ringing ;-).

@benpicco
Copy link
Contributor Author

benpicco commented May 5, 2020

btw I think this is still useful even without Path MTU discovery 😉

@miri64
Copy link
Member

miri64 commented May 5, 2020

Yes, of course. Just hadn't time to review the past few days. :-)

Copy link
Member

@miri64 miri64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no way of testing this, as I don't have the hardware. However, the test looks sane and does not increase the RAM usage of the gnrc_netif module.

@miri64 miri64 merged commit 18bd56d into RIOT-OS:master May 6, 2020
@benpicco benpicco deleted the net/gnrc/netif/6lo-frag_size branch May 6, 2020 10:44
@miri64 miri64 added this to the Release 2020.07 milestone Jun 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: network Area: Networking CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Impact: minor The PR is small in size and might only require a quick look of a knowledgeable reviewer Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants