1 /* SPDX-License-Identifier: LGPL-2.1-or-later
2 * Copyright © 2020 VMware, Inc. */
3
4 #include "networkd-link.h"
5 #include "networkd-manager.h"
6 #include "networkd-queue.h"
7 #include "networkd-sriov.h"
8
sr_iov_handler(sd_netlink * rtnl,sd_netlink_message * m,Request * req,Link * link,SRIOV * sr_iov)9 static int sr_iov_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, SRIOV *sr_iov) {
10 int r;
11
12 assert(m);
13 assert(link);
14
15 r = sd_netlink_message_get_errno(m);
16 if (r < 0 && r != -EEXIST) {
17 log_link_message_error_errno(link, m, r, "Could not set up SR-IOV");
18 link_enter_failed(link);
19 return 1;
20 }
21
22 if (link->sr_iov_messages == 0) {
23 log_link_debug(link, "SR-IOV configured");
24 link->sr_iov_configured = true;
25 link_check_ready(link);
26 }
27
28 return 1;
29 }
30
sr_iov_configure(SRIOV * sr_iov,Link * link,Request * req)31 static int sr_iov_configure(SRIOV *sr_iov, Link *link, Request *req) {
32 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
33 int r;
34
35 assert(sr_iov);
36 assert(link);
37 assert(link->manager);
38 assert(link->manager->rtnl);
39 assert(link->ifindex > 0);
40 assert(req);
41
42 log_link_debug(link, "Setting SR-IOV virtual function %"PRIu32".", sr_iov->vf);
43
44 r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_SETLINK, link->ifindex);
45 if (r < 0)
46 return r;
47
48 r = sr_iov_set_netlink_message(sr_iov, m);
49 if (r < 0)
50 return r;
51
52 return request_call_netlink_async(link->manager->rtnl, m, req);
53 }
54
sr_iov_process_request(Request * req,Link * link,SRIOV * sr_iov)55 static int sr_iov_process_request(Request *req, Link *link, SRIOV *sr_iov) {
56 int r;
57
58 assert(req);
59 assert(link);
60 assert(sr_iov);
61
62 if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
63 return 0;
64
65 r = sr_iov_configure(sr_iov, link, req);
66 if (r < 0)
67 return log_link_warning_errno(link, r,
68 "Failed to configure SR-IOV virtual function %"PRIu32": %m",
69 sr_iov->vf);
70
71 return 1;
72 }
73
link_request_sr_iov_vfs(Link * link)74 int link_request_sr_iov_vfs(Link *link) {
75 SRIOV *sr_iov;
76 int r;
77
78 assert(link);
79 assert(link->network);
80
81 link->sr_iov_configured = false;
82
83 ORDERED_HASHMAP_FOREACH(sr_iov, link->network->sr_iov_by_section) {
84 r = link_queue_request_safe(link, REQUEST_TYPE_SRIOV,
85 sr_iov, NULL,
86 sr_iov_hash_func,
87 sr_iov_compare_func,
88 sr_iov_process_request,
89 &link->sr_iov_messages,
90 sr_iov_handler,
91 NULL);
92 if (r < 0)
93 return log_link_warning_errno(link, r,
94 "Failed to request SR-IOV virtual function %"PRIu32": %m",
95 sr_iov->vf);
96 }
97
98 if (link->sr_iov_messages == 0) {
99 link->sr_iov_configured = true;
100 link_check_ready(link);
101 } else
102 log_link_debug(link, "Configuring SR-IOV");
103
104 return 0;
105 }
106