network: use request queue to set MTU
This commit is contained in:
@@ -115,6 +115,8 @@ sources = files('''
|
||||
networkd-route.h
|
||||
networkd-routing-policy-rule.c
|
||||
networkd-routing-policy-rule.h
|
||||
networkd-setlink.c
|
||||
networkd-setlink.h
|
||||
networkd-speed-meter.c
|
||||
networkd-speed-meter.h
|
||||
networkd-sriov.c
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "networkd-nexthop.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "networkd-route.h"
|
||||
#include "networkd-setlink.h"
|
||||
#include "networkd-state-file.h"
|
||||
#include "string-table.h"
|
||||
#include "strv.h"
|
||||
@@ -685,7 +686,7 @@ static int dhcp_reset_mtu(Link *link) {
|
||||
if (link->original_mtu == mtu)
|
||||
return 0;
|
||||
|
||||
r = link_set_mtu(link, link->original_mtu);
|
||||
r = link_request_to_set_mtu(link, link->original_mtu);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP error: could not reset MTU: %m");
|
||||
|
||||
@@ -1129,7 +1130,7 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
|
||||
|
||||
r = sd_dhcp_lease_get_mtu(lease, &mtu);
|
||||
if (r >= 0) {
|
||||
r = link_set_mtu(link, mtu);
|
||||
r = link_request_to_set_mtu(link, mtu);
|
||||
if (r < 0)
|
||||
log_link_error_errno(link, r, "Failed to set MTU to %" PRIu16 ": %m", mtu);
|
||||
}
|
||||
|
||||
+19
-113
@@ -45,6 +45,7 @@
|
||||
#include "networkd-queue.h"
|
||||
#include "networkd-radv.h"
|
||||
#include "networkd-routing-policy-rule.h"
|
||||
#include "networkd-setlink.h"
|
||||
#include "networkd-sriov.h"
|
||||
#include "networkd-state-file.h"
|
||||
#include "networkd-sysctl.h"
|
||||
@@ -151,6 +152,9 @@ bool link_is_ready_to_configure(Link *link, bool allow_unmanaged) {
|
||||
if (!link_has_carrier(link) && !link->network->configure_without_carrier)
|
||||
return false;
|
||||
|
||||
if (link->set_link_messages > 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -970,118 +974,6 @@ static int link_set_nomaster(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->ifname);
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 0;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set MTU, ignoring");
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_link_debug(link, "Setting MTU done.");
|
||||
|
||||
/* The kernel resets ipv6 mtu after changing device mtu;
|
||||
* we must set this here, after we've set device mtu */
|
||||
r = link_set_ipv6_mtu(link);
|
||||
if (r < 0)
|
||||
log_link_warning_errno(link, r, "Cannot set IPv6 MTU, ignoring: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_set_mtu(Link *link, uint32_t mtu) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(link->manager->rtnl);
|
||||
|
||||
if (mtu == 0)
|
||||
return 0;
|
||||
|
||||
if (link->mtu == mtu)
|
||||
return 0;
|
||||
|
||||
log_link_debug(link, "Setting MTU: %" PRIu32, mtu);
|
||||
|
||||
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
|
||||
|
||||
/* IPv6 protocol requires a minimum MTU of IPV6_MTU_MIN(1280) bytes
|
||||
* on the interface. Bump up MTU bytes to IPV6_MTU_MIN. */
|
||||
if (link_ipv6_enabled(link) && mtu < IPV6_MIN_MTU) {
|
||||
|
||||
log_link_warning(link, "Bumping MTU to " STRINGIFY(IPV6_MIN_MTU) ", as "
|
||||
"IPv6 is requested and requires a minimum MTU of " STRINGIFY(IPV6_MIN_MTU) " bytes");
|
||||
|
||||
mtu = IPV6_MIN_MTU;
|
||||
}
|
||||
|
||||
r = sd_netlink_message_append_u32(req, IFLA_MTU, mtu);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append MTU: %m");
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, req, set_mtu_handler,
|
||||
link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||
|
||||
link_ref(link);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool link_reduces_vlan_mtu(Link *link) {
|
||||
/* See netif_reduces_vlan_mtu() in kernel. */
|
||||
return streq_ptr(link->kind, "macsec");
|
||||
}
|
||||
|
||||
static uint32_t link_get_requested_mtu_by_stacked_netdevs(Link *link) {
|
||||
uint32_t mtu = 0;
|
||||
NetDev *dev;
|
||||
|
||||
HASHMAP_FOREACH(dev, link->network->stacked_netdevs)
|
||||
if (dev->kind == NETDEV_KIND_VLAN && dev->mtu > 0)
|
||||
/* See vlan_dev_change_mtu() in kernel. */
|
||||
mtu = MAX(mtu, link_reduces_vlan_mtu(link) ? dev->mtu + 4 : dev->mtu);
|
||||
|
||||
else if (dev->kind == NETDEV_KIND_MACVLAN && dev->mtu > mtu)
|
||||
/* See macvlan_change_mtu() in kernel. */
|
||||
mtu = dev->mtu;
|
||||
|
||||
return mtu;
|
||||
}
|
||||
|
||||
static int link_configure_mtu(Link *link) {
|
||||
uint32_t mtu;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
if (link->network->mtu > 0)
|
||||
return link_set_mtu(link, link->network->mtu);
|
||||
|
||||
mtu = link_get_requested_mtu_by_stacked_netdevs(link);
|
||||
if (link->mtu >= mtu)
|
||||
return 0;
|
||||
|
||||
log_link_notice(link, "Bumping MTU bytes from %"PRIu32" to %"PRIu32" because of stacked device. "
|
||||
"If it is not desired, then please explicitly specify MTUBytes= setting.",
|
||||
link->mtu, mtu);
|
||||
|
||||
return link_set_mtu(link, mtu);
|
||||
}
|
||||
|
||||
static int set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
@@ -1892,14 +1784,28 @@ static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int link_enter_join_netdev(Link *link) {
|
||||
int link_enter_join_netdev(Link *link) {
|
||||
NetDev *netdev;
|
||||
Request req;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
assert(link->state == LINK_STATE_INITIALIZED);
|
||||
|
||||
req = (Request) {
|
||||
.link = link,
|
||||
.type = REQUEST_TYPE_SET_LINK,
|
||||
.set_link_operation = SET_LINK_MTU,
|
||||
};
|
||||
|
||||
if (ordered_set_contains(link->manager->request_queue, &req)) {
|
||||
link->entering_to_join_netdev = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
link->entering_to_join_netdev = false;
|
||||
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
|
||||
link->enslaving = 0;
|
||||
|
||||
@@ -95,6 +95,7 @@ typedef struct Link {
|
||||
unsigned tc_messages;
|
||||
unsigned sr_iov_messages;
|
||||
unsigned enslaving;
|
||||
unsigned set_link_messages;
|
||||
|
||||
Set *addresses;
|
||||
Set *addresses_foreign;
|
||||
@@ -136,6 +137,7 @@ typedef struct Link {
|
||||
bool sr_iov_configured:1;
|
||||
bool can_configured:1;
|
||||
bool activated:1;
|
||||
bool entering_to_join_netdev:1;
|
||||
|
||||
sd_dhcp_server *dhcp_server;
|
||||
|
||||
@@ -218,6 +220,7 @@ int link_up(Link *link);
|
||||
int link_down(Link *link, link_netlink_message_handler_t callback);
|
||||
int link_activate(Link *link);
|
||||
|
||||
int link_enter_join_netdev(Link *link);
|
||||
void link_enter_failed(Link *link);
|
||||
|
||||
void link_set_state(Link *link, LinkState state);
|
||||
@@ -232,8 +235,6 @@ bool link_ipv6_enabled(Link *link);
|
||||
bool link_ipv6ll_enabled(Link *link);
|
||||
int link_ipv6ll_gained(Link *link, const struct in6_addr *address);
|
||||
|
||||
int link_set_mtu(Link *link, uint32_t mtu);
|
||||
|
||||
bool link_ipv4ll_enabled(Link *link);
|
||||
|
||||
int link_stop_engines(Link *link, bool may_keep_dhcp);
|
||||
|
||||
@@ -44,6 +44,8 @@ static void request_free_object(RequestType type, void *object) {
|
||||
case REQUEST_TYPE_ROUTING_POLICY_RULE:
|
||||
routing_policy_rule_free(object);
|
||||
break;
|
||||
case REQUEST_TYPE_SET_LINK:
|
||||
break;
|
||||
default:
|
||||
assert_not_reached("invalid request type.");
|
||||
}
|
||||
@@ -113,6 +115,9 @@ static void request_hash_func(const Request *req, struct siphash *state) {
|
||||
case REQUEST_TYPE_ROUTING_POLICY_RULE:
|
||||
routing_policy_rule_hash_func(req->rule, state);
|
||||
break;
|
||||
case REQUEST_TYPE_SET_LINK:
|
||||
siphash24_compress(&req->set_link_operation, sizeof(req->set_link_operation), state);
|
||||
break;
|
||||
default:
|
||||
assert_not_reached("invalid request type.");
|
||||
}
|
||||
@@ -153,6 +158,8 @@ static int request_compare_func(const struct Request *a, const struct Request *b
|
||||
return route_compare_func(a->route, b->route);
|
||||
case REQUEST_TYPE_ROUTING_POLICY_RULE:
|
||||
return routing_policy_rule_compare_func(a->rule, b->rule);
|
||||
case REQUEST_TYPE_SET_LINK:
|
||||
return CMP(a->set_link_operation, b->set_link_operation);
|
||||
default:
|
||||
assert_not_reached("invalid request type.");
|
||||
}
|
||||
@@ -175,15 +182,14 @@ int link_queue_request(
|
||||
Request **ret) {
|
||||
|
||||
_cleanup_(request_freep) Request *req = NULL;
|
||||
Request *existing;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(type >= 0 && type < _REQUEST_TYPE_MAX);
|
||||
if (type != REQUEST_TYPE_DHCP_SERVER) {
|
||||
assert(object);
|
||||
assert(netlink_handler);
|
||||
}
|
||||
assert(IN_SET(type, REQUEST_TYPE_DHCP_SERVER, REQUEST_TYPE_SET_LINK) || object);
|
||||
assert(type == REQUEST_TYPE_DHCP_SERVER || netlink_handler);
|
||||
|
||||
req = new(Request, 1);
|
||||
if (!req) {
|
||||
@@ -201,19 +207,20 @@ int link_queue_request(
|
||||
.netlink_handler = netlink_handler,
|
||||
};
|
||||
|
||||
r = ordered_set_ensure_put(&link->manager->request_queue, &request_hash_ops, req);
|
||||
if (r < 0) {
|
||||
/* To prevent from removing duplicated request. */
|
||||
existing = ordered_set_get(link->manager->request_queue, req);
|
||||
if (existing) {
|
||||
/* To prevent from removing the existing request. */
|
||||
req->link = link_unref(req->link);
|
||||
|
||||
if (r == -EEXIST) {
|
||||
if (ret)
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
return r;
|
||||
if (ret)
|
||||
*ret = existing;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = ordered_set_ensure_put(&link->manager->request_queue, &request_hash_ops, req);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (req->message_counter)
|
||||
(*req->message_counter)++;
|
||||
|
||||
@@ -266,6 +273,9 @@ int manager_process_requests(sd_event_source *s, void *userdata) {
|
||||
case REQUEST_TYPE_ROUTING_POLICY_RULE:
|
||||
r = request_process_routing_policy_rule(req);
|
||||
break;
|
||||
case REQUEST_TYPE_SET_LINK:
|
||||
r = request_process_set_link(req);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "sd-event.h"
|
||||
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-setlink.h"
|
||||
|
||||
typedef struct Address Address;
|
||||
typedef struct AddressLabel AddressLabel;
|
||||
@@ -30,10 +31,13 @@ typedef enum RequestType {
|
||||
REQUEST_TYPE_NEXTHOP,
|
||||
REQUEST_TYPE_ROUTE,
|
||||
REQUEST_TYPE_ROUTING_POLICY_RULE,
|
||||
REQUEST_TYPE_SET_LINK,
|
||||
_REQUEST_TYPE_MAX,
|
||||
_REQUEST_TYPE_INVALID = -EINVAL,
|
||||
} RequestType;
|
||||
|
||||
assert_cc(sizeof(SetLinkOperation) <= sizeof(void*));
|
||||
|
||||
typedef struct Request {
|
||||
Link *link;
|
||||
RequestType type;
|
||||
@@ -48,6 +52,7 @@ typedef struct Request {
|
||||
NextHop *nexthop;
|
||||
Route *route;
|
||||
RoutingPolicyRule *rule;
|
||||
SetLinkOperation set_link_operation;
|
||||
void *object;
|
||||
};
|
||||
void *userdata;
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "missing_network.h"
|
||||
#include "netlink-util.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "string-table.h"
|
||||
|
||||
static const char *const set_link_operation_table[_SET_LINK_OPERATION_MAX] = {
|
||||
[SET_LINK_MTU] = "MTU",
|
||||
};
|
||||
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(set_link_operation, SetLinkOperation);
|
||||
|
||||
static int set_link_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, SetLinkOperation op, bool ignore) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->set_link_messages > 0);
|
||||
assert(op >= 0 && op < _SET_LINK_OPERATION_MAX);
|
||||
|
||||
link->set_link_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 0;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0) {
|
||||
const char *error_msg;
|
||||
|
||||
error_msg = strjoina("Failed to set ", set_link_operation_to_string(op), ignore ? ", ignoring" : "");
|
||||
log_link_message_warning_errno(link, m, r, error_msg);
|
||||
|
||||
if (!ignore)
|
||||
link_enter_failed(link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_link_debug(link, "%s set.", set_link_operation_to_string(op));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int link_set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
r = set_link_handler_internal(rtnl, m, link, SET_LINK_MTU, true);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
/* The kernel resets ipv6 mtu after changing device mtu;
|
||||
* we must set this here, after we've set device mtu */
|
||||
r = link_set_ipv6_mtu(link);
|
||||
if (r < 0)
|
||||
log_link_warning_errno(link, r, "Failed to set IPv6 MTU, ignoring: %m");
|
||||
|
||||
if (link->entering_to_join_netdev) {
|
||||
r = link_enter_join_netdev(link);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_configure(
|
||||
Link *link,
|
||||
SetLinkOperation op,
|
||||
void *userdata,
|
||||
link_netlink_message_handler_t callback) {
|
||||
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(link->manager->rtnl);
|
||||
assert(link->network);
|
||||
assert(op >= 0 && op < _SET_LINK_OPERATION_MAX);
|
||||
assert(callback);
|
||||
|
||||
log_link_debug(link, "Setting %s", set_link_operation_to_string(op));
|
||||
|
||||
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
|
||||
if (r < 0)
|
||||
return log_link_debug_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
|
||||
|
||||
switch (op) {
|
||||
case SET_LINK_MTU:
|
||||
r = sd_netlink_message_append_u32(req, IFLA_MTU, PTR_TO_UINT32(userdata));
|
||||
if (r < 0)
|
||||
return log_link_debug_errno(link, r, "Could not append IFLA_MTU attribute: %m");
|
||||
break;
|
||||
default:
|
||||
assert_not_reached("Invalid set link operation");
|
||||
}
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, req, callback,
|
||||
link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
return log_link_debug_errno(link, r, "Could not send RTM_SETLINK message: %m");
|
||||
|
||||
link_ref(link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool link_is_ready_to_call_set_link(Request *req) {
|
||||
Link *link;
|
||||
|
||||
assert(req);
|
||||
|
||||
link = req->link;
|
||||
|
||||
if (!IN_SET(link->state, LINK_STATE_INITIALIZED, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int request_process_set_link(Request *req) {
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->type == REQUEST_TYPE_SET_LINK);
|
||||
assert(req->set_link_operation >= 0 && req->set_link_operation < _SET_LINK_OPERATION_MAX);
|
||||
assert(req->netlink_handler);
|
||||
|
||||
if (!link_is_ready_to_call_set_link(req))
|
||||
return 0;
|
||||
|
||||
r = link_configure(req->link, req->set_link_operation, req->userdata, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(req->link, r, "Failed to set %s: %m",
|
||||
set_link_operation_to_string(req->set_link_operation));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int link_request_set_link(
|
||||
Link *link,
|
||||
SetLinkOperation op,
|
||||
link_netlink_message_handler_t netlink_handler,
|
||||
Request **ret) {
|
||||
|
||||
Request *req;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(op >= 0 && op < _SET_LINK_OPERATION_MAX);
|
||||
assert(netlink_handler);
|
||||
|
||||
r = link_queue_request(link, REQUEST_TYPE_SET_LINK, INT_TO_PTR(op), false,
|
||||
&link->set_link_messages, netlink_handler, &req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request to set %s: %m",
|
||||
set_link_operation_to_string(op));
|
||||
|
||||
log_link_debug(link, "Requested to set %s", set_link_operation_to_string(op));
|
||||
|
||||
if (ret)
|
||||
*ret = req;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_request_to_set_mtu(Link *link, uint32_t mtu) {
|
||||
Request *req = NULL; /* avoid false maybe-uninitialized warning */
|
||||
int r;
|
||||
|
||||
assert(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 (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;
|
||||
}
|
||||
|
||||
if (link->mtu == mtu)
|
||||
return 0;
|
||||
|
||||
r = link_request_set_link(link, SET_LINK_MTU, link_set_mtu_handler, &req);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
req->userdata = UINT32_TO_PTR(mtu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool link_reduces_vlan_mtu(Link *link) {
|
||||
/* See netif_reduces_vlan_mtu() in kernel. */
|
||||
return streq_ptr(link->kind, "macsec");
|
||||
}
|
||||
|
||||
static uint32_t link_get_requested_mtu_by_stacked_netdevs(Link *link) {
|
||||
uint32_t mtu = 0;
|
||||
NetDev *dev;
|
||||
|
||||
HASHMAP_FOREACH(dev, link->network->stacked_netdevs)
|
||||
if (dev->kind == NETDEV_KIND_VLAN && dev->mtu > 0)
|
||||
/* See vlan_dev_change_mtu() in kernel. */
|
||||
mtu = MAX(mtu, link_reduces_vlan_mtu(link) ? dev->mtu + 4 : dev->mtu);
|
||||
|
||||
else if (dev->kind == NETDEV_KIND_MACVLAN && dev->mtu > mtu)
|
||||
/* See macvlan_change_mtu() in kernel. */
|
||||
mtu = dev->mtu;
|
||||
|
||||
return mtu;
|
||||
}
|
||||
|
||||
int link_configure_mtu(Link *link) {
|
||||
uint32_t mtu;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
if (link->network->mtu > 0)
|
||||
return link_request_to_set_mtu(link, link->network->mtu);
|
||||
|
||||
mtu = link_get_requested_mtu_by_stacked_netdevs(link);
|
||||
if (link->mtu >= mtu)
|
||||
return 0;
|
||||
|
||||
log_link_notice(link, "Bumping MTU bytes from %"PRIu32" to %"PRIu32" because of stacked device. "
|
||||
"If it is not desired, then please explicitly specify MTUBytes= setting.",
|
||||
link->mtu, mtu);
|
||||
|
||||
return link_request_to_set_mtu(link, mtu);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
typedef struct Link Link;
|
||||
typedef struct Request Request;
|
||||
|
||||
typedef enum SetLinkOperation {
|
||||
SET_LINK_MTU, /* Setting MTU. */
|
||||
_SET_LINK_OPERATION_MAX,
|
||||
_SET_LINK_OPERATION_INVALID = -EINVAL,
|
||||
} SetLinkOperation;
|
||||
|
||||
int link_request_to_set_mtu(Link *link, uint32_t mtu);
|
||||
|
||||
int link_configure_mtu(Link *link);
|
||||
|
||||
int request_process_set_link(Request *req);
|
||||
Reference in New Issue
Block a user