mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
network: read the minimum and maximum MTU of the interface, and adjust requested MTU based on these values
This commit is contained in:
@@ -2012,7 +2012,7 @@ static int link_update_hardware_address(Link *link, sd_netlink_message *message)
|
||||
}
|
||||
|
||||
static int link_update_mtu(Link *link, sd_netlink_message *message) {
|
||||
uint32_t mtu;
|
||||
uint32_t mtu, min_mtu = 0, max_mtu = UINT32_MAX;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@@ -2024,16 +2024,34 @@ static int link_update_mtu(Link *link, sd_netlink_message *message) {
|
||||
if (r < 0)
|
||||
return log_link_debug_errno(link, r, "rtnl: failed to read MTU in RTM_NEWLINK message: %m");
|
||||
|
||||
if (mtu == 0 || link->mtu == mtu)
|
||||
r = sd_netlink_message_read_u32(message, IFLA_MIN_MTU, &min_mtu);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
return log_link_debug_errno(link, r, "rtnl: failed to read minimum MTU in RTM_NEWLINK message: %m");
|
||||
|
||||
r = sd_netlink_message_read_u32(message, IFLA_MAX_MTU, &max_mtu);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
return log_link_debug_errno(link, r, "rtnl: failed to read maximum MTU in RTM_NEWLINK message: %m");
|
||||
|
||||
if (mtu == 0)
|
||||
return 0;
|
||||
|
||||
if (max_mtu == 0)
|
||||
max_mtu = UINT32_MAX;
|
||||
|
||||
link->min_mtu = min_mtu;
|
||||
link->max_mtu = max_mtu;
|
||||
|
||||
if (link->original_mtu == 0) {
|
||||
link->original_mtu = mtu;
|
||||
log_link_debug(link, "Saved original MTU: %" PRIu32, link->original_mtu);
|
||||
log_link_debug(link, "Saved original MTU %" PRIu32" (min: %"PRIu32", max: %"PRIu32")",
|
||||
link->original_mtu, link->min_mtu, link->max_mtu);
|
||||
}
|
||||
|
||||
if (link->mtu != 0)
|
||||
log_link_debug(link, "MTU is changed: %"PRIu32" → %"PRIu32, link->mtu, mtu);
|
||||
if (link->mtu == mtu)
|
||||
return 0;
|
||||
|
||||
log_link_debug(link, "MTU is changed: %"PRIu32" → %"PRIu32" (min: %"PRIu32", max: %"PRIu32")",
|
||||
link->mtu, mtu, link->min_mtu, link->max_mtu);
|
||||
|
||||
link->mtu = mtu;
|
||||
|
||||
|
||||
@@ -58,6 +58,9 @@ typedef struct Link {
|
||||
struct ether_addr permanent_mac;
|
||||
struct in6_addr ipv6ll_address;
|
||||
uint32_t mtu;
|
||||
uint32_t min_mtu;
|
||||
uint32_t max_mtu;
|
||||
uint32_t original_mtu;
|
||||
sd_device *sd_device;
|
||||
char *driver;
|
||||
|
||||
@@ -114,7 +117,6 @@ typedef struct Link {
|
||||
Address *dhcp_address, *dhcp_address_old;
|
||||
Set *dhcp_routes, *dhcp_routes_old;
|
||||
char *lease_file;
|
||||
uint32_t original_mtu;
|
||||
unsigned dhcp4_messages;
|
||||
sd_ipv4acd *dhcp_acd;
|
||||
bool dhcp4_route_failed:1;
|
||||
|
||||
@@ -677,16 +677,38 @@ int link_request_to_set_master(Link *link) {
|
||||
|
||||
int link_request_to_set_mtu(Link *link, uint32_t mtu) {
|
||||
Request *req = NULL; /* avoid false maybe-uninitialized warning */
|
||||
const char *origin;
|
||||
uint32_t min_mtu;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
/* IPv6 protocol requires a minimum MTU of IPV6_MTU_MIN(1280) bytes on the interface. Bump up
|
||||
* MTU bytes to IPV6_MTU_MIN. */
|
||||
if (mtu < IPV6_MIN_MTU && link_ipv6_enabled(link)) {
|
||||
log_link_warning(link, "Bumping MTU to " STRINGIFY(IPV6_MIN_MTU) ", as IPv6 is enabled "
|
||||
"and requires a minimum MTU of " STRINGIFY(IPV6_MIN_MTU) " bytes");
|
||||
mtu = IPV6_MIN_MTU;
|
||||
min_mtu = link->min_mtu;
|
||||
origin = "the minimum MTU of the interface";
|
||||
if (link_ipv6_enabled(link)) {
|
||||
/* IPv6 protocol requires a minimum MTU of IPV6_MTU_MIN(1280) bytes on the interface. Bump up
|
||||
* MTU bytes to IPV6_MTU_MIN. */
|
||||
if (min_mtu < IPV6_MIN_MTU) {
|
||||
min_mtu = IPV6_MIN_MTU;
|
||||
origin = "the minimum IPv6 MTU";
|
||||
}
|
||||
if (min_mtu < link->network->ipv6_mtu) {
|
||||
min_mtu = link->network->ipv6_mtu;
|
||||
origin = "the requested IPv6 MTU in IPv6MTUBytes=";
|
||||
}
|
||||
}
|
||||
|
||||
if (mtu < min_mtu) {
|
||||
log_link_warning(link, "Bumping the requested MTU %"PRIu32" to %s (%"PRIu32")",
|
||||
mtu, origin, min_mtu);
|
||||
mtu = min_mtu;
|
||||
}
|
||||
|
||||
if (mtu > link->max_mtu) {
|
||||
log_link_warning(link, "Reducing the requested MTU %"PRIu32" to the interface's maximum MTU %"PRIu32".",
|
||||
mtu, link->max_mtu);
|
||||
mtu = link->max_mtu;
|
||||
}
|
||||
|
||||
if (link->mtu == mtu)
|
||||
|
||||
Reference in New Issue
Block a user