#include "networkd-manager.h"
#include "networkd-queue.h"
#include "networkd-setlink.h"
+#include "networkd-sriov.h"
#include "nlmon.h"
#include "path-lookup.h"
#include "siphash24.h"
return 0;
}
-static bool link_is_ready_to_create_stacked_netdev(Link *link) {
+static bool link_is_ready_to_create_stacked_netdev_one(Link *link, bool allow_unmanaged) {
assert(link);
- if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
+ if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED, LINK_STATE_UNMANAGED))
return false;
+ if (!link->network)
+ return allow_unmanaged;
+
if (link->set_link_messages > 0)
return false;
return true;
}
+static bool link_is_ready_to_create_stacked_netdev(Link *link) {
+ return check_ready_for_all_sr_iov_ports(link, /* allow_unmanaged = */ false,
+ link_is_ready_to_create_stacked_netdev_one);
+}
+
static int netdev_is_ready_to_create(NetDev *netdev, Link *link) {
assert(netdev);
return false;
}
-bool link_is_ready_to_configure(Link *link, bool allow_unmanaged) {
+static bool link_is_ready_to_configure_one(Link *link, bool allow_unmanaged) {
assert(link);
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED, LINK_STATE_UNMANAGED))
return true;
}
+bool link_is_ready_to_configure(Link *link, bool allow_unmanaged) {
+ return check_ready_for_all_sr_iov_ports(link, allow_unmanaged, link_is_ready_to_configure_one);
+}
+
void link_ntp_settings_clear(Link *link) {
link->ntp = strv_free(link->ntp);
}
#include "networkd-manager.h"
#include "networkd-queue.h"
#include "networkd-setlink.h"
+#include "networkd-sriov.h"
#include "networkd-wiphy.h"
static int get_link_default_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return request_call_netlink_async(link->manager->rtnl, m, req);
}
-static bool link_is_ready_to_activate(Link *link, bool up) {
+static bool link_is_ready_to_activate_one(Link *link, bool allow_unmanaged) {
assert(link);
- if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
+ if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED, LINK_STATE_UNMANAGED))
return false;
+ if (!link->network)
+ return allow_unmanaged;
+
if (link->set_link_messages > 0)
return false;
+ return true;
+}
+
+ static bool link_is_ready_to_activate(Link *link, bool up) {
+ assert(link);
+
+ if (!check_ready_for_all_sr_iov_ports(link, /* allow_unmanaged = */ false,
+ link_is_ready_to_activate_one))
+ return false;
+
if (up && link_rfkilled(link) > 0)
return false;
virt_link->sr_iov_phys_port_ifindex = 0;
}
}
+
+bool check_ready_for_all_sr_iov_ports(
+ Link *link,
+ bool allow_unmanaged, /* for the main target */
+ bool (check_one)(Link *link, bool allow_unmanaged)) {
+
+ Link *phys_link;
+ void *v;
+
+ assert(link);
+ assert(link->manager);
+ assert(check_one);
+
+ /* Some drivers make VF ports become down when their PF port becomes down, and may fail to configure
+ * VF ports. Also, when a VF port becomes up/down, its PF port and other VF ports may become down.
+ * See issue #23315. */
+
+ /* First, check the main target. */
+ if (!check_one(link, allow_unmanaged))
+ return false;
+
+ /* If this is a VF port, then also check the PF port. */
+ if (link->sr_iov_phys_port_ifindex > 0) {
+ if (link_get_by_index(link->manager, link->sr_iov_phys_port_ifindex, &phys_link) < 0 ||
+ !check_one(phys_link, /* allow_unmanaged = */ true))
+ return false;
+ } else
+ phys_link = link;
+
+ /* Also check all VF ports. */
+ SET_FOREACH(v, phys_link->sr_iov_virt_port_ifindices) {
+ int ifindex = PTR_TO_INT(v);
+ Link *virt_link;
+
+ if (ifindex == link->ifindex)
+ continue; /* The main target link is a VF port, and its state is already checked. */
+
+ if (link_get_by_index(link->manager, ifindex, &virt_link) < 0)
+ return false;
+
+ if (!check_one(virt_link, /* allow_unmanaged = */ true))
+ return false;
+ }
+
+ return true;
+}
int link_set_sr_iov_ifindices(Link *link);
void link_clear_sr_iov_ifindices(Link *link);
+
+bool check_ready_for_all_sr_iov_ports(
+ Link *link,
+ bool allow_unmanaged, /* for the main target */
+ bool (check_one)(Link *link, bool allow_unmanaged));