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;
}))
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;
}
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,