network/setlink: adjust requested MTU when it is ready to set
This should not change any effective behavior. Just for safety, and making the logic consistent with others, e.g. setting master ifindex.
This commit is contained in:
@@ -453,6 +453,43 @@ static bool netdev_is_ready(NetDev *netdev) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t link_adjust_mtu(Link *link, uint32_t mtu) {
|
||||
const char *origin;
|
||||
uint32_t min_mtu;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return mtu;
|
||||
}
|
||||
|
||||
static int link_is_ready_to_set_link(Link *link, Request *req) {
|
||||
int r;
|
||||
|
||||
@@ -570,13 +607,24 @@ static int link_is_ready_to_set_link(Link *link, Request *req) {
|
||||
}))
|
||||
return false;
|
||||
|
||||
/* Changing FD mode may affect MTU. */
|
||||
/* Changing FD mode may affect MTU.
|
||||
* See https://docs.kernel.org/networking/can.html#can-fd-flexible-data-rate-driver-support
|
||||
* MTU = 16 (CAN_MTU) => Classical CAN device
|
||||
* MTU = 72 (CANFD_MTU) => CAN FD capable device */
|
||||
if (ordered_set_contains(link->manager->request_queue,
|
||||
&(const Request) {
|
||||
.link = link,
|
||||
.type = REQUEST_TYPE_SET_LINK_CAN,
|
||||
}))
|
||||
return false;
|
||||
|
||||
/* Now, it is ready to set MTU, but before setting, adjust requested MTU. */
|
||||
uint32_t mtu = link_adjust_mtu(link, PTR_TO_UINT32(req->userdata));
|
||||
if (mtu == link->mtu)
|
||||
return -EALREADY; /* Not necessary to set the same value. */
|
||||
|
||||
req->userdata = UINT32_TO_PTR(mtu);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@@ -865,51 +913,12 @@ int link_request_to_set_master(Link *link) {
|
||||
}
|
||||
|
||||
int link_request_to_set_mtu(Link *link, uint32_t mtu) {
|
||||
const char *origin;
|
||||
uint32_t min_mtu, max_mtu;
|
||||
Request *req;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
max_mtu = link->max_mtu;
|
||||
if (link->iftype == ARPHRD_CAN)
|
||||
/* The maximum MTU may be changed when FD mode is changed.
|
||||
* See https://docs.kernel.org/networking/can.html#can-fd-flexible-data-rate-driver-support
|
||||
* MTU = 16 (CAN_MTU) => Classical CAN device
|
||||
* MTU = 72 (CANFD_MTU) => CAN FD capable device
|
||||
* So, even if the current maximum is 16, we should not reduce the requested value now. */
|
||||
max_mtu = MAX(max_mtu, 72u);
|
||||
|
||||
if (mtu > max_mtu) {
|
||||
log_link_warning(link, "Reducing the requested MTU %"PRIu32" to the interface's maximum MTU %"PRIu32".",
|
||||
mtu, max_mtu);
|
||||
mtu = max_mtu;
|
||||
}
|
||||
|
||||
if (link->mtu == mtu)
|
||||
if (mtu == 0)
|
||||
return 0;
|
||||
|
||||
r = link_request_set_link(link, REQUEST_TYPE_SET_LINK_MTU,
|
||||
|
||||
Reference in New Issue
Block a user