| /* SPDX-License-Identifier: LGPL-2.1-or-later |
| * Copyright © 2020 VMware, Inc. */ |
| |
| #include "networkd-link.h" |
| #include "networkd-manager.h" |
| #include "networkd-queue.h" |
| #include "networkd-sriov.h" |
| |
| static int sr_iov_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, SRIOV *sr_iov) { |
| int r; |
| |
| assert(m); |
| assert(link); |
| |
| r = sd_netlink_message_get_errno(m); |
| if (r < 0 && r != -EEXIST) { |
| log_link_message_error_errno(link, m, r, "Could not set up SR-IOV"); |
| link_enter_failed(link); |
| return 1; |
| } |
| |
| if (link->sr_iov_messages == 0) { |
| log_link_debug(link, "SR-IOV configured"); |
| link->sr_iov_configured = true; |
| link_check_ready(link); |
| } |
| |
| return 1; |
| } |
| |
| static int sr_iov_configure(SRIOV *sr_iov, Link *link, Request *req) { |
| _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; |
| int r; |
| |
| assert(sr_iov); |
| assert(link); |
| assert(link->manager); |
| assert(link->manager->rtnl); |
| assert(link->ifindex > 0); |
| assert(req); |
| |
| log_link_debug(link, "Setting SR-IOV virtual function %"PRIu32".", sr_iov->vf); |
| |
| r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_SETLINK, link->ifindex); |
| if (r < 0) |
| return r; |
| |
| r = sr_iov_set_netlink_message(sr_iov, m); |
| if (r < 0) |
| return r; |
| |
| return request_call_netlink_async(link->manager->rtnl, m, req); |
| } |
| |
| static int sr_iov_process_request(Request *req, Link *link, SRIOV *sr_iov) { |
| int r; |
| |
| assert(req); |
| assert(link); |
| assert(sr_iov); |
| |
| if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) |
| return 0; |
| |
| r = sr_iov_configure(sr_iov, link, req); |
| if (r < 0) |
| return log_link_warning_errno(link, r, |
| "Failed to configure SR-IOV virtual function %"PRIu32": %m", |
| sr_iov->vf); |
| |
| return 1; |
| } |
| |
| int link_request_sr_iov_vfs(Link *link) { |
| SRIOV *sr_iov; |
| int r; |
| |
| assert(link); |
| assert(link->network); |
| |
| link->sr_iov_configured = false; |
| |
| ORDERED_HASHMAP_FOREACH(sr_iov, link->network->sr_iov_by_section) { |
| r = link_queue_request_safe(link, REQUEST_TYPE_SRIOV, |
| sr_iov, NULL, |
| sr_iov_hash_func, |
| sr_iov_compare_func, |
| sr_iov_process_request, |
| &link->sr_iov_messages, |
| sr_iov_handler, |
| NULL); |
| if (r < 0) |
| return log_link_warning_errno(link, r, |
| "Failed to request SR-IOV virtual function %"PRIu32": %m", |
| sr_iov->vf); |
| } |
| |
| if (link->sr_iov_messages == 0) { |
| link->sr_iov_configured = true; |
| link_check_ready(link); |
| } else |
| log_link_debug(link, "Configuring SR-IOV"); |
| |
| return 0; |
| } |