Skip to content

Conversation

@jukkar
Copy link
Member

@jukkar jukkar commented Nov 6, 2024

This implements IPv4 and IPv6 Path MTU Discovery support.
See https://www.rfc-editor.org/rfc/rfc1191 for IPv4 and
https://www.rfc-editor.org/rfc/rfc8201 for IPv6

General PMTU information can be found here https://en.wikipedia.org/wiki/Path_MTU_Discovery

Original issue here #2302

@jukkar
Copy link
Member Author

jukkar commented Nov 7, 2024

Note to self, the fragmentation code in both IPv4 and IPv6 needs some additional checks for PMTU. Need to fix that after 4.0 is released.

rlubos
rlubos previously approved these changes Nov 12, 2024
Copy link
Contributor

@rlubos rlubos left a comment

Choose a reason for hiding this comment

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

Looks good, impressive work!

@jukkar
Copy link
Member Author

jukkar commented Nov 12, 2024

Marking this as WIP/DNM as I need to implement these features:

  • IPv4/IPv6 fragmentation code needs some tweaks for PMTU support
  • There are socket options for setting/getting PMTU values from application. I will implement these in this PR.

@jukkar jukkar added the DNM This PR should not be merged (Do Not Merge) label Nov 12, 2024
@jukkar jukkar changed the title Add network PMTU support [WIP] Add network PMTU support Nov 12, 2024
@jukkar jukkar force-pushed the devel/pmtu-support branch from 7e222e7 to 7a09be7 Compare November 13, 2024 09:14
@jukkar jukkar removed the DNM This PR should not be merged (Do Not Merge) label Nov 13, 2024
@jukkar jukkar changed the title [WIP] Add network PMTU support Add network PMTU support Nov 13, 2024
@zephyrbot zephyrbot added the area: Sockets Networking sockets label Nov 13, 2024
@jukkar
Copy link
Member Author

jukkar commented Nov 13, 2024

  • Changed the IPv4/6 fragmentation code to take PMTU into account
  • Add IPV6_MTU and IP_MTU socket option support + tests for those

There is still IP_MTU_DISCOVER and IPV6_MTU_DISCOVER options that could be implemented, but that can be done in the future.

This adds generic code that can be used by both IPv4 and IPv6
Path MTU Discovery mechanism. The actual PMTU support for each
protocol family is in subsequent commits.

Signed-off-by: Jukka Rissanen <[email protected]>
Add initial tests for generic part of PMTU discovery code.

Signed-off-by: Jukka Rissanen <[email protected]>
Add information about PMTU related packets received/sent/dropped
for IPv6.

Signed-off-by: Jukka Rissanen <[email protected]>
Print more cases when the packet is dropped, and also print
the upper layer verdict for the packet.

Signed-off-by: Jukka Rissanen <[email protected]>
Catch "Packet Too Big" ICMPv6 messages and update PMTU for
a given destination IPv6 address.
Use that PMTU when sending data to the destination.

Signed-off-by: Jukka Rissanen <[email protected]>
Allow tests to check whether a IPv6 TCP connection MTU is changed.

Signed-off-by: Jukka Rissanen <[email protected]>
Show information whether PMTU is enabled or not.
Show pmtu destination cache content with "net pmtu"
command. The "net pmtu flush" can be used to clear the
cache.

Signed-off-by: Jukka Rissanen <[email protected]>
Add information about PMTU related packets received/sent/dropped
for IPv4.

Signed-off-by: Jukka Rissanen <[email protected]>
Catch "Destination Unreachable" ICMPv4 messages and update PMTU for
a given destination IPv4 address.
Use that PMTU when sending data to the destination.

Signed-off-by: Jukka Rissanen <[email protected]>
Allow tests to check whether a IPv4 TCP connection MTU is changed.

Signed-off-by: Jukka Rissanen <[email protected]>
Send a network management event for a changed path MTU value.
Both IPv4 and IPv6 have their own events as we cannot mix these
because how the network event numbering space is implemented.

Signed-off-by: Jukka Rissanen <[email protected]>
Verify that the PMTU changed events are generated and we can
catch them.

Signed-off-by: Jukka Rissanen <[email protected]>
Print the changed PMTU value and IP address in the event monitor.

Signed-off-by: Jukka Rissanen <[email protected]>
Set the commands to monitor correctly. Before this change some
events were missed.

Signed-off-by: Jukka Rissanen <[email protected]>
Add IP_MTU IPv4 socket option and implement getsockopt()
call for the option. The IP_MTU option does not support
setsockopt() call.

Signed-off-by: Jukka Rissanen <[email protected]>
Make sure we can use IP_MTU socket option from application.

Signed-off-by: Jukka Rissanen <[email protected]>
Add IPV6_MTU IPv6 socket option and implement getsockopt() and
setsockopt() calls for the option.

Signed-off-by: Jukka Rissanen <[email protected]>
Make sure we can use IPV6_MTU socket option from application.

Signed-off-by: Jukka Rissanen <[email protected]>
If PMTU is enabled, then use the MTU value from it instead of always
using network interface MTU.

Signed-off-by: Jukka Rissanen <[email protected]>
Enable PMTU so that we test it with IPv4 fragmentation code.

Signed-off-by: Jukka Rissanen <[email protected]>
Shorten the timeouts so that the tests are run in 6 second instead
of 15 seconds.

Use only native_sim for the tests so that the tests are run without
any extra delays.

Signed-off-by: Jukka Rissanen <[email protected]>
If PMTU is enabled, then use the MTU value from it instead of always
using network interface MTU.

Signed-off-by: Jukka Rissanen <[email protected]>
@jukkar jukkar force-pushed the devel/pmtu-support branch from 7a09be7 to c2190bf Compare November 14, 2024 11:55
@jukkar
Copy link
Member Author

jukkar commented Nov 14, 2024

  • Rebased latest main
  • Fixed the IPv6 fragment data count which must be a multiple of 8 bytes. The issue was not seen earlier because we always sent max. 1280 bytes in one fragment. But now the real MTU is used instead which need to check this.

Copy link
Contributor

Choose a reason for hiding this comment

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

nit; Typo in the commit message: tests: net: ipvr6_fragment: -> tests: net: ipv6_fragment:

Enable PMTU so that we test it with IPv6 fragmentation code.

Signed-off-by: Jukka Rissanen <[email protected]>
After we take the true MTU into account, we need to send proper
number of bytes (multiple of 8) in one IPv6 fragment.

Signed-off-by: Jukka Rissanen <[email protected]>
@jukkar jukkar force-pushed the devel/pmtu-support branch from c2190bf to 32e3339 Compare November 15, 2024 08:15
@jukkar
Copy link
Member Author

jukkar commented Nov 18, 2024

@pdgendt if you have time, please take a look.

#define NET_IPV6_PMTU_ENTRIES 0
#endif

#define NET_PMTU_MAX_ENTRIES (NET_IPV4_PMTU_ENTRIES + NET_IPV6_PMTU_ENTRIES)
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor hidden detail, the number of cache entries each get a maximum option setting, however AFAICS the entries are shared between IPv4 and IPv6?

So if both are set to 3, you could have 6 IPv4 and 0 IPv6 entries? Or am I missing something?

Copy link
Member Author

Choose a reason for hiding this comment

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

The cache is shared between IPv4 and IPv6 entries in order to utilize the cache better. If the cache is "full", the oldest entry is re-used be it IPv4 or IPv6. We could certainly separate the IPv4 and IPv6 entries to individual caches, but I think it would just use more memory without extra benefits.

@nashif nashif merged commit 247941f into zephyrproject-rtos:main Nov 18, 2024
24 checks passed
@jukkar jukkar deleted the devel/pmtu-support branch November 18, 2024 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants