diff --git a/src/libs/compat/freebsd_network/device_hooks.c b/src/libs/compat/freebsd_network/device_hooks.c index 4ab25af2f0..37165fda42 100644 --- a/src/libs/compat/freebsd_network/device_hooks.c +++ b/src/libs/compat/freebsd_network/device_hooks.c @@ -237,15 +237,21 @@ compat_control(void *cookie, uint32 op, void *arg, size_t length) if (length < 4) return B_BAD_VALUE; + const int MTUs[] = { + ETHERMTU_JUMBO, + PAGESIZE - (ETHER_HDR_LEN + ETHER_CRC_LEN), + 2290, /* IEEE80211_MTU_MAX */ + 0 + }; + // This is (usually) only invoked during initialization to get the - // maximum frame size. Thus we try to set the largest possible one, - // as there is no way to determine what the driver might support. - struct ifreq ifr; - ifr.ifr_mtu = ETHERMTU_JUMBO; - if (compat_control(cookie, SIOCSIFMTU, &ifr, sizeof(ifr)) != 0) { - // Try again with 4K at least. - ifr.ifr_mtu = 4096 - (ETHER_HDR_LEN + ETHER_CRC_LEN); - compat_control(cookie, SIOCSIFMTU, &ifr, sizeof(ifr)); + // maximum frame size. Thus we try a few common possible values, + // as there is no way to determine what is supported (or required). + for (int i = 0; MTUs[i] != 0; i++) { + struct ifreq ifr; + ifr.ifr_mtu = MTUs[i]; + if (compat_control(cookie, SIOCSIFMTU, &ifr, sizeof(ifr)) == 0) + break; } frameSize = ifp->if_mtu + (ETHER_HDR_LEN + ETHER_CRC_LEN);