Development discussion of WireGuard
 help / color / mirror / Atom feed
* wg-quick set_mtu_up - largest or smallest MTU?
@ 2023-11-03 13:12 M P Robert
  2023-11-19 14:41 ` Daniel Gröber
  0 siblings, 1 reply; 2+ messages in thread
From: M P Robert @ 2023-11-03 13:12 UTC (permalink / raw)
  To: wireguard

[-- Attachment #1: Type: text/plain, Size: 1005 bytes --]


I was looking at the auto MTU detection in wg-quick.

It appears that wg-quick is taking the LARGEST of all endpoint MTUs

https://github.com/WireGuard/wireguard-tools/blob/13f4ac4cb74b5a833fa7f825ba785b1e5774e84f/src/wg-quick/linux.bash#L134

In a scenario where you have different peers on different network devices or routes with different MTUs, I would think you would want to take the SMALLEST mtu from all peers in order to avoid having fragmentation talking to the peers on networks with smaller MTUs.

Or perhaps fragmentation for some peers is faster than selecting a smaller packet size for all peers?  Or I am missing something (more likely).  Happy to be educated on this point.

I don't have git-send-email setup at this point, but just in case this is a valid issue, I've attached a sample fix for set_mtu_up that will take the smallest of the discovered peer MTUs rather than the largest.  I'm not a bash guy, so just take it for illustration purposes.

Thanks!

-Matt



[-- Attachment #2: wg-quick.set_mtu_up.sh --]
[-- Type: application/octet-stream, Size: 912 bytes --]

set_mtu_up() {
	local mtu=0 mtufound=0 endpoint output
	if [[ -n $MTU ]]; then
		cmd ip link set mtu "$MTU" up dev "$INTERFACE"
		return
	fi
	while read -r _ endpoint; do
		[[ $endpoint =~ ^\[?([a-z0-9:.]+)\]?:[0-9]+$ ]] || continue
		output="$(ip route get "${BASH_REMATCH[1]}" || true)"
		[[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ( $mtufound -eq 0 || ${BASH_REMATCH[1]} -lt $mtu ) ]] && mtu="${BASH_REMATCH[1]}" && mtufound=1
	done < <(wg show "$INTERFACE" endpoints)
	if [[ $mtufound -eq 0 ]]; then
		read -r output < <(ip route show default || true) || true
		[[ $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ]] && mtu="${BASH_REMATCH[1]}" && mtufound=1
	fi
	[[ $mtufound -eq 1 ]] || mtu=1500
	cmd ip link set mtu $(( mtu - 80 )) up dev "$INTERFACE"
}

[-- Attachment #3: Type: text/plain, Size: 2 bytes --]




^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: wg-quick set_mtu_up - largest or smallest MTU?
  2023-11-03 13:12 wg-quick set_mtu_up - largest or smallest MTU? M P Robert
@ 2023-11-19 14:41 ` Daniel Gröber
  0 siblings, 0 replies; 2+ messages in thread
From: Daniel Gröber @ 2023-11-19 14:41 UTC (permalink / raw)
  To: M P Robert; +Cc: wireguard

Hi Matt,

On Fri, Nov 03, 2023 at 01:12:22PM +0000, M P Robert wrote:
> I was looking at the auto MTU detection in wg-quick.
> 
> It appears that wg-quick is taking the LARGEST of all endpoint MTUs
> 
> https://github.com/WireGuard/wireguard-tools/blob/13f4ac4cb74b5a833fa7f825ba785b1e5774e84f/src/wg-quick/linux.bash#L134

My reading of the code is that we iterate over all peers' endpoints do a
route lookup to get the destination specific MTU and fall back to default
route's MTU if that didn't return anything. In both cases we use the "mtu"
route attribute or failing that the actual interface MTU.

Incidentally the docs don't mention the details of the MTU selection
behaviour. wg-quick(1) has this:

       •      MTU — if not specified, the MTU is automatically determined from
              the endpoint addresses or the system  default  route,  which  is
              usually  a  sane  choice. However, to manually specify an MTU to
              override this automatic discovery, this value may  be  specified
              explicitly.

> In a scenario where you have different peers on different network devices
> or routes with different MTUs, I would think you would want to take the
> SMALLEST mtu from all peers in order to avoid having fragmentation
> talking to the peers on networks with smaller MTUs.

I agree using the smallest MTU would probably be best for most users.

> Or perhaps fragmentation for some peers is faster than selecting a
> smaller packet size for all peers?  Or I am missing something (more
> likely).  Happy to be educated on this point.

In principle hosts that have (some) interfaces using jumbo frames may want
to make use of the largest MTU for efficiency, in this case one may be
willing to take the fragmentation hit on interfaces with smaller MTU.

In this case it'd still be possible to override the automatic MTU selection
by configuring MTU= statically so this isn't a blocker.

> I don't have git-send-email setup at this point, but just in case this is
> a valid issue, I've attached a sample fix for set_mtu_up that will take
> the smallest of the discovered peer MTUs rather than the largest.  I'm
> not a bash guy, so just take it for illustration purposes.

Looks like Thomas already whipped up a patch. You could test it and report
back :)

--Daniel

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-11-19 14:42 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-03 13:12 wg-quick set_mtu_up - largest or smallest MTU? M P Robert
2023-11-19 14:41 ` Daniel Gröber

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).