1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker * Copyright (c) 2016 Intel Corp. All rights reserved.
4*4dc78e53SAndroid Build Coastguard Worker * Copyright (c) 2016 Jef Oliver <[email protected]>
5*4dc78e53SAndroid Build Coastguard Worker */
6*4dc78e53SAndroid Build Coastguard Worker
7*4dc78e53SAndroid Build Coastguard Worker /**
8*4dc78e53SAndroid Build Coastguard Worker * @ingroup link
9*4dc78e53SAndroid Build Coastguard Worker * @defgroup sriov SRIOV
10*4dc78e53SAndroid Build Coastguard Worker * SR-IOV VF link module
11*4dc78e53SAndroid Build Coastguard Worker *
12*4dc78e53SAndroid Build Coastguard Worker * @details
13*4dc78e53SAndroid Build Coastguard Worker * SR-IOV (Single Root Input/Output Virtualization) is a network interface
14*4dc78e53SAndroid Build Coastguard Worker * that allows for the isolation of the PCI Express resources. In a virtual
15*4dc78e53SAndroid Build Coastguard Worker * environment, SR-IOV allows multiple virtual machines can share a single
16*4dc78e53SAndroid Build Coastguard Worker * PCI Express hardware interface. This is done via VFs (Virtual Functions),
17*4dc78e53SAndroid Build Coastguard Worker * virtual hardware devices with their own PCI address.
18*4dc78e53SAndroid Build Coastguard Worker *
19*4dc78e53SAndroid Build Coastguard Worker * @{
20*4dc78e53SAndroid Build Coastguard Worker */
21*4dc78e53SAndroid Build Coastguard Worker
22*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
23*4dc78e53SAndroid Build Coastguard Worker
24*4dc78e53SAndroid Build Coastguard Worker #include <linux/if_ether.h>
25*4dc78e53SAndroid Build Coastguard Worker #include <linux/if_link.h>
26*4dc78e53SAndroid Build Coastguard Worker
27*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
28*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/link.h>
29*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/link/sriov.h>
30*4dc78e53SAndroid Build Coastguard Worker
31*4dc78e53SAndroid Build Coastguard Worker #include "nl-route.h"
32*4dc78e53SAndroid Build Coastguard Worker #include "link-sriov.h"
33*4dc78e53SAndroid Build Coastguard Worker #include "link-api.h"
34*4dc78e53SAndroid Build Coastguard Worker
35*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
36*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf {
37*4dc78e53SAndroid Build Coastguard Worker struct nl_list_head vf_list;
38*4dc78e53SAndroid Build Coastguard Worker int ce_refcnt;
39*4dc78e53SAndroid Build Coastguard Worker uint32_t ce_mask;
40*4dc78e53SAndroid Build Coastguard Worker uint32_t vf_index;
41*4dc78e53SAndroid Build Coastguard Worker uint64_t vf_guid_node;
42*4dc78e53SAndroid Build Coastguard Worker uint64_t vf_guid_port;
43*4dc78e53SAndroid Build Coastguard Worker uint32_t vf_linkstate;
44*4dc78e53SAndroid Build Coastguard Worker struct nl_addr *vf_lladdr;
45*4dc78e53SAndroid Build Coastguard Worker uint32_t vf_max_tx_rate;
46*4dc78e53SAndroid Build Coastguard Worker uint32_t vf_min_tx_rate;
47*4dc78e53SAndroid Build Coastguard Worker uint32_t vf_rate;
48*4dc78e53SAndroid Build Coastguard Worker uint32_t vf_rss_query_en;
49*4dc78e53SAndroid Build Coastguard Worker uint32_t vf_spoofchk;
50*4dc78e53SAndroid Build Coastguard Worker uint64_t vf_stats[RTNL_LINK_VF_STATS_MAX + 1];
51*4dc78e53SAndroid Build Coastguard Worker uint32_t vf_trust;
52*4dc78e53SAndroid Build Coastguard Worker struct nl_vf_vlans *vf_vlans;
53*4dc78e53SAndroid Build Coastguard Worker };
54*4dc78e53SAndroid Build Coastguard Worker
55*4dc78e53SAndroid Build Coastguard Worker #define SRIOVON "on"
56*4dc78e53SAndroid Build Coastguard Worker #define SRIOVOFF "off"
57*4dc78e53SAndroid Build Coastguard Worker
58*4dc78e53SAndroid Build Coastguard Worker #define SET_VF_STAT(link, vf_num, stb, stat, attr) \
59*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_stats[stat] = nla_get_u64(stb[attr])
60*4dc78e53SAndroid Build Coastguard Worker
61*4dc78e53SAndroid Build Coastguard Worker /* SRIOV-VF Attributes */
62*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_INDEX (1 << 0)
63*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_ADDR (1 << 1)
64*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_VLAN (1 << 2)
65*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_TX_RATE (1 << 3)
66*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_SPOOFCHK (1 << 4)
67*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_RATE_MAX (1 << 5)
68*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_RATE_MIN (1 << 6)
69*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_LINK_STATE (1 << 7)
70*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_RSS_QUERY_EN (1 << 8)
71*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_STATS (1 << 9)
72*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_TRUST (1 << 10)
73*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_IB_NODE_GUID (1 << 11)
74*4dc78e53SAndroid Build Coastguard Worker #define SRIOV_ATTR_IB_PORT_GUID (1 << 12)
75*4dc78e53SAndroid Build Coastguard Worker
76*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy sriov_info_policy[IFLA_VF_MAX+1] = {
77*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_MAC] = { .minlen = sizeof(struct ifla_vf_mac) },
78*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_VLAN] = { .minlen = sizeof(struct ifla_vf_vlan) },
79*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_VLAN_LIST] = { .type = NLA_NESTED },
80*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_TX_RATE] = { .minlen = sizeof(struct ifla_vf_tx_rate) },
81*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_SPOOFCHK] = { .minlen = sizeof(struct ifla_vf_spoofchk) },
82*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_RATE] = { .minlen = sizeof(struct ifla_vf_rate) },
83*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_LINK_STATE] = { .minlen = sizeof(struct ifla_vf_link_state) },
84*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_RSS_QUERY_EN] = { .minlen = sizeof(struct ifla_vf_rss_query_en) },
85*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_STATS] = { .type = NLA_NESTED },
86*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_TRUST] = { .minlen = sizeof(struct ifla_vf_trust) },
87*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_IB_NODE_GUID] = { .minlen = sizeof(struct ifla_vf_guid) },
88*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_IB_PORT_GUID] = { .minlen = sizeof(struct ifla_vf_guid) },
89*4dc78e53SAndroid Build Coastguard Worker };
90*4dc78e53SAndroid Build Coastguard Worker
91*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy sriov_stats_policy[IFLA_VF_STATS_MAX+1] = {
92*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_STATS_RX_PACKETS] = { .type = NLA_U64 },
93*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_STATS_TX_PACKETS] = { .type = NLA_U64 },
94*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_STATS_RX_BYTES] = { .type = NLA_U64 },
95*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_STATS_TX_BYTES] = { .type = NLA_U64 },
96*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_STATS_BROADCAST] = { .type = NLA_U64 },
97*4dc78e53SAndroid Build Coastguard Worker [IFLA_VF_STATS_MULTICAST] = { .type = NLA_U64 },
98*4dc78e53SAndroid Build Coastguard Worker };
99*4dc78e53SAndroid Build Coastguard Worker
100*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
101*4dc78e53SAndroid Build Coastguard Worker
102*4dc78e53SAndroid Build Coastguard Worker /* Clone SRIOV VF list in link object */
rtnl_link_sriov_clone(struct rtnl_link * dst,struct rtnl_link * src)103*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_sriov_clone(struct rtnl_link *dst, struct rtnl_link *src) {
104*4dc78e53SAndroid Build Coastguard Worker int err = 0;
105*4dc78e53SAndroid Build Coastguard Worker struct nl_addr *vf_addr;
106*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *s_list, *d_vf, *s_vf, *next, *dest_h = NULL;
107*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlans_t *src_vlans = NULL, *dst_vlans = NULL;
108*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlan_info_t *src_vlan_info = NULL, *dst_vlan_info = NULL;
109*4dc78e53SAndroid Build Coastguard Worker
110*4dc78e53SAndroid Build Coastguard Worker if (!rtnl_link_has_vf_list(src))
111*4dc78e53SAndroid Build Coastguard Worker return 0;
112*4dc78e53SAndroid Build Coastguard Worker
113*4dc78e53SAndroid Build Coastguard Worker dst->l_vf_list = rtnl_link_vf_alloc();
114*4dc78e53SAndroid Build Coastguard Worker if (!dst->l_vf_list)
115*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
116*4dc78e53SAndroid Build Coastguard Worker dest_h = dst->l_vf_list;
117*4dc78e53SAndroid Build Coastguard Worker s_list = src->l_vf_list;
118*4dc78e53SAndroid Build Coastguard Worker
119*4dc78e53SAndroid Build Coastguard Worker nl_list_for_each_entry_safe(s_vf, next, &s_list->vf_list, vf_list) {
120*4dc78e53SAndroid Build Coastguard Worker if (!(d_vf = rtnl_link_vf_alloc()))
121*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
122*4dc78e53SAndroid Build Coastguard Worker
123*4dc78e53SAndroid Build Coastguard Worker memcpy(d_vf, s_vf, sizeof(*s_vf));
124*4dc78e53SAndroid Build Coastguard Worker
125*4dc78e53SAndroid Build Coastguard Worker if (s_vf->ce_mask & SRIOV_ATTR_ADDR) {
126*4dc78e53SAndroid Build Coastguard Worker vf_addr = nl_addr_clone(s_vf->vf_lladdr);
127*4dc78e53SAndroid Build Coastguard Worker if (!vf_addr) {
128*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_put(d_vf);
129*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
130*4dc78e53SAndroid Build Coastguard Worker }
131*4dc78e53SAndroid Build Coastguard Worker d_vf->vf_lladdr = vf_addr;
132*4dc78e53SAndroid Build Coastguard Worker }
133*4dc78e53SAndroid Build Coastguard Worker
134*4dc78e53SAndroid Build Coastguard Worker if (s_vf->ce_mask & SRIOV_ATTR_VLAN) {
135*4dc78e53SAndroid Build Coastguard Worker src_vlans = s_vf->vf_vlans;
136*4dc78e53SAndroid Build Coastguard Worker src_vlan_info = src_vlans->vlans;
137*4dc78e53SAndroid Build Coastguard Worker
138*4dc78e53SAndroid Build Coastguard Worker err = rtnl_link_vf_vlan_alloc(&dst_vlans,
139*4dc78e53SAndroid Build Coastguard Worker src_vlans->size);
140*4dc78e53SAndroid Build Coastguard Worker if (err < 0) {
141*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_put(d_vf);
142*4dc78e53SAndroid Build Coastguard Worker return err;
143*4dc78e53SAndroid Build Coastguard Worker }
144*4dc78e53SAndroid Build Coastguard Worker dst_vlan_info = dst_vlans->vlans;
145*4dc78e53SAndroid Build Coastguard Worker memcpy(dst_vlans, src_vlans, sizeof(nl_vf_vlans_t));
146*4dc78e53SAndroid Build Coastguard Worker memcpy(dst_vlan_info, src_vlan_info,
147*4dc78e53SAndroid Build Coastguard Worker dst_vlans->size * sizeof(*dst_vlan_info));
148*4dc78e53SAndroid Build Coastguard Worker d_vf->vf_vlans = dst_vlans;
149*4dc78e53SAndroid Build Coastguard Worker }
150*4dc78e53SAndroid Build Coastguard Worker
151*4dc78e53SAndroid Build Coastguard Worker nl_list_add_head(&d_vf->vf_list, &dest_h->vf_list);
152*4dc78e53SAndroid Build Coastguard Worker dest_h = d_vf;
153*4dc78e53SAndroid Build Coastguard Worker }
154*4dc78e53SAndroid Build Coastguard Worker
155*4dc78e53SAndroid Build Coastguard Worker return 0;
156*4dc78e53SAndroid Build Coastguard Worker }
157*4dc78e53SAndroid Build Coastguard Worker
158*4dc78e53SAndroid Build Coastguard Worker /* Dump VLAN details for each SRIOV VF */
dump_sriov_vlans(nl_vf_vlans_t * vlans,struct nl_dump_params * p)159*4dc78e53SAndroid Build Coastguard Worker static void dump_sriov_vlans(nl_vf_vlans_t *vlans,
160*4dc78e53SAndroid Build Coastguard Worker struct nl_dump_params *p) {
161*4dc78e53SAndroid Build Coastguard Worker char buf[64];
162*4dc78e53SAndroid Build Coastguard Worker int cur = 0;
163*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlan_info_t *vlan_data;
164*4dc78e53SAndroid Build Coastguard Worker uint16_t prot;
165*4dc78e53SAndroid Build Coastguard Worker
166*4dc78e53SAndroid Build Coastguard Worker vlan_data = vlans->vlans;
167*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "\t VLANS:\n");
168*4dc78e53SAndroid Build Coastguard Worker while (cur < vlans->size) {
169*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "\t vlan %u", vlan_data[cur].vf_vlan);
170*4dc78e53SAndroid Build Coastguard Worker if (vlan_data[cur].vf_vlan_qos)
171*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " qos %u", vlan_data[cur].vf_vlan_qos);
172*4dc78e53SAndroid Build Coastguard Worker if (vlan_data[cur].vf_vlan_proto) {
173*4dc78e53SAndroid Build Coastguard Worker prot = vlan_data[cur].vf_vlan_proto;
174*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " proto %s",
175*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_vlanproto2str(prot, buf,
176*4dc78e53SAndroid Build Coastguard Worker sizeof(buf)));
177*4dc78e53SAndroid Build Coastguard Worker }
178*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "\n");
179*4dc78e53SAndroid Build Coastguard Worker cur++;
180*4dc78e53SAndroid Build Coastguard Worker }
181*4dc78e53SAndroid Build Coastguard Worker
182*4dc78e53SAndroid Build Coastguard Worker return;
183*4dc78e53SAndroid Build Coastguard Worker }
184*4dc78e53SAndroid Build Coastguard Worker
185*4dc78e53SAndroid Build Coastguard Worker /* Dump details for each SRIOV VF */
dump_vf_details(struct rtnl_link_vf * vf_data,struct nl_dump_params * p)186*4dc78e53SAndroid Build Coastguard Worker static void dump_vf_details(struct rtnl_link_vf *vf_data,
187*4dc78e53SAndroid Build Coastguard Worker struct nl_dump_params *p) {
188*4dc78e53SAndroid Build Coastguard Worker char buf[64];
189*4dc78e53SAndroid Build Coastguard Worker int err = 0;
190*4dc78e53SAndroid Build Coastguard Worker struct nl_vf_rate vf_rate;
191*4dc78e53SAndroid Build Coastguard Worker uint32_t v = 0;
192*4dc78e53SAndroid Build Coastguard Worker
193*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "\tvf %u: ", vf_data->vf_index);
194*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE) {
195*4dc78e53SAndroid Build Coastguard Worker v = vf_data->vf_linkstate;
196*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "state %s ",
197*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_linkstate2str(v, buf, sizeof(buf)));
198*4dc78e53SAndroid Build Coastguard Worker }
199*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_ADDR) {
200*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "addr %s ",
201*4dc78e53SAndroid Build Coastguard Worker nl_addr2str(vf_data->vf_lladdr, buf, sizeof(buf)));
202*4dc78e53SAndroid Build Coastguard Worker }
203*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "\n");
204*4dc78e53SAndroid Build Coastguard Worker
205*4dc78e53SAndroid Build Coastguard Worker v = vf_data->vf_spoofchk;
206*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "\t spoofchk %s ", v ? SRIOVON : SRIOVOFF);
207*4dc78e53SAndroid Build Coastguard Worker v = vf_data->vf_trust;
208*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "trust %s ", v ? SRIOVON : SRIOVOFF);
209*4dc78e53SAndroid Build Coastguard Worker v = vf_data->vf_rss_query_en;
210*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "rss_query %s\n", v ? SRIOVON : SRIOVOFF);
211*4dc78e53SAndroid Build Coastguard Worker
212*4dc78e53SAndroid Build Coastguard Worker err = rtnl_link_vf_get_rate(vf_data, &vf_rate);
213*4dc78e53SAndroid Build Coastguard Worker if (!err) {
214*4dc78e53SAndroid Build Coastguard Worker if (vf_rate.api == RTNL_LINK_VF_RATE_API_OLD)
215*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "\t rate_api old rate %u\n",
216*4dc78e53SAndroid Build Coastguard Worker vf_rate.rate);
217*4dc78e53SAndroid Build Coastguard Worker else if (vf_rate.api == RTNL_LINK_VF_RATE_API_NEW)
218*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "\t rate_api new min_rate %u "
219*4dc78e53SAndroid Build Coastguard Worker "max_rate %u\n", vf_rate.min_tx_rate,
220*4dc78e53SAndroid Build Coastguard Worker vf_rate.max_tx_rate);
221*4dc78e53SAndroid Build Coastguard Worker }
222*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_VLAN)
223*4dc78e53SAndroid Build Coastguard Worker dump_sriov_vlans(vf_data->vf_vlans, p);
224*4dc78e53SAndroid Build Coastguard Worker
225*4dc78e53SAndroid Build Coastguard Worker return;
226*4dc78e53SAndroid Build Coastguard Worker }
227*4dc78e53SAndroid Build Coastguard Worker
228*4dc78e53SAndroid Build Coastguard Worker /* Loop through SRIOV VF list dump details */
rtnl_link_sriov_dump_details(struct rtnl_link * link,struct nl_dump_params * p)229*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_sriov_dump_details(struct rtnl_link *link,
230*4dc78e53SAndroid Build Coastguard Worker struct nl_dump_params *p) {
231*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *vf_data, *list, *next;
232*4dc78e53SAndroid Build Coastguard Worker
233*4dc78e53SAndroid Build Coastguard Worker if (!rtnl_link_has_vf_list(link))
234*4dc78e53SAndroid Build Coastguard Worker BUG();
235*4dc78e53SAndroid Build Coastguard Worker
236*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " SRIOV VF List\n");
237*4dc78e53SAndroid Build Coastguard Worker list = link->l_vf_list;
238*4dc78e53SAndroid Build Coastguard Worker nl_list_for_each_entry_safe(vf_data, next, &list->vf_list, vf_list) {
239*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_INDEX)
240*4dc78e53SAndroid Build Coastguard Worker dump_vf_details(vf_data, p);
241*4dc78e53SAndroid Build Coastguard Worker }
242*4dc78e53SAndroid Build Coastguard Worker
243*4dc78e53SAndroid Build Coastguard Worker return;
244*4dc78e53SAndroid Build Coastguard Worker }
245*4dc78e53SAndroid Build Coastguard Worker
246*4dc78e53SAndroid Build Coastguard Worker /* Dump stats for each SRIOV VF */
dump_vf_stats(struct rtnl_link_vf * vf_data,struct nl_dump_params * p)247*4dc78e53SAndroid Build Coastguard Worker static void dump_vf_stats(struct rtnl_link_vf *vf_data,
248*4dc78e53SAndroid Build Coastguard Worker struct nl_dump_params *p) {
249*4dc78e53SAndroid Build Coastguard Worker char *unit;
250*4dc78e53SAndroid Build Coastguard Worker float res;
251*4dc78e53SAndroid Build Coastguard Worker
252*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " VF %u Stats:\n", vf_data->vf_index);
253*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, "\tRX: %-14s %-10s %-10s %-10s\n",
254*4dc78e53SAndroid Build Coastguard Worker "bytes", "packets", "multicast", "broadcast");
255*4dc78e53SAndroid Build Coastguard Worker
256*4dc78e53SAndroid Build Coastguard Worker res = nl_cancel_down_bytes(vf_data->vf_stats[RTNL_LINK_VF_STATS_RX_BYTES],
257*4dc78e53SAndroid Build Coastguard Worker &unit);
258*4dc78e53SAndroid Build Coastguard Worker
259*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p,
260*4dc78e53SAndroid Build Coastguard Worker "\t%10.2f %3s %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "\n",
261*4dc78e53SAndroid Build Coastguard Worker res, unit,
262*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_stats[RTNL_LINK_VF_STATS_RX_PACKETS],
263*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_stats[RTNL_LINK_VF_STATS_MULTICAST],
264*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_stats[RTNL_LINK_VF_STATS_BROADCAST]);
265*4dc78e53SAndroid Build Coastguard Worker
266*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, "\tTX: %-14s %-10s\n", "bytes", "packets");
267*4dc78e53SAndroid Build Coastguard Worker
268*4dc78e53SAndroid Build Coastguard Worker res = nl_cancel_down_bytes(vf_data->vf_stats[RTNL_LINK_VF_STATS_TX_BYTES],
269*4dc78e53SAndroid Build Coastguard Worker &unit);
270*4dc78e53SAndroid Build Coastguard Worker
271*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, "\t%10.2f %3s %10" PRIu64 "\n", res, unit,
272*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_stats[RTNL_LINK_VF_STATS_TX_PACKETS]);
273*4dc78e53SAndroid Build Coastguard Worker
274*4dc78e53SAndroid Build Coastguard Worker return;
275*4dc78e53SAndroid Build Coastguard Worker }
276*4dc78e53SAndroid Build Coastguard Worker
277*4dc78e53SAndroid Build Coastguard Worker /* Loop through SRIOV VF list dump stats */
rtnl_link_sriov_dump_stats(struct rtnl_link * link,struct nl_dump_params * p)278*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_sriov_dump_stats(struct rtnl_link *link,
279*4dc78e53SAndroid Build Coastguard Worker struct nl_dump_params *p) {
280*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *vf_data, *list, *next;
281*4dc78e53SAndroid Build Coastguard Worker
282*4dc78e53SAndroid Build Coastguard Worker list = link->l_vf_list;
283*4dc78e53SAndroid Build Coastguard Worker nl_list_for_each_entry_safe(vf_data, next, &list->vf_list, vf_list) {
284*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_INDEX)
285*4dc78e53SAndroid Build Coastguard Worker dump_vf_stats(vf_data, p);
286*4dc78e53SAndroid Build Coastguard Worker }
287*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "\n");
288*4dc78e53SAndroid Build Coastguard Worker
289*4dc78e53SAndroid Build Coastguard Worker return;
290*4dc78e53SAndroid Build Coastguard Worker }
291*4dc78e53SAndroid Build Coastguard Worker
292*4dc78e53SAndroid Build Coastguard Worker /* Free stored SRIOV VF data */
rtnl_link_sriov_free_data(struct rtnl_link * link)293*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_sriov_free_data(struct rtnl_link *link) {
294*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *list, *vf, *next;
295*4dc78e53SAndroid Build Coastguard Worker
296*4dc78e53SAndroid Build Coastguard Worker if (!rtnl_link_has_vf_list(link))
297*4dc78e53SAndroid Build Coastguard Worker return;
298*4dc78e53SAndroid Build Coastguard Worker
299*4dc78e53SAndroid Build Coastguard Worker list = link->l_vf_list;
300*4dc78e53SAndroid Build Coastguard Worker nl_list_for_each_entry_safe(vf, next, &list->vf_list, vf_list) {
301*4dc78e53SAndroid Build Coastguard Worker nl_list_del(&vf->vf_list);
302*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_put(vf);
303*4dc78e53SAndroid Build Coastguard Worker }
304*4dc78e53SAndroid Build Coastguard Worker
305*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_put(link->l_vf_list);
306*4dc78e53SAndroid Build Coastguard Worker
307*4dc78e53SAndroid Build Coastguard Worker return;
308*4dc78e53SAndroid Build Coastguard Worker }
309*4dc78e53SAndroid Build Coastguard Worker
310*4dc78e53SAndroid Build Coastguard Worker /* Fill VLAN info array */
rtnl_link_vf_vlan_info(int len,struct ifla_vf_vlan_info ** vi,nl_vf_vlans_t ** nvi)311*4dc78e53SAndroid Build Coastguard Worker static int rtnl_link_vf_vlan_info(int len, struct ifla_vf_vlan_info **vi,
312*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlans_t **nvi) {
313*4dc78e53SAndroid Build Coastguard Worker int cur = 0, err;
314*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlans_t *vlans;
315*4dc78e53SAndroid Build Coastguard Worker
316*4dc78e53SAndroid Build Coastguard Worker if (len <= 0)
317*4dc78e53SAndroid Build Coastguard Worker return 0;
318*4dc78e53SAndroid Build Coastguard Worker
319*4dc78e53SAndroid Build Coastguard Worker if ((err = rtnl_link_vf_vlan_alloc(&vlans, len)) < 0)
320*4dc78e53SAndroid Build Coastguard Worker return err;
321*4dc78e53SAndroid Build Coastguard Worker
322*4dc78e53SAndroid Build Coastguard Worker cur = 0;
323*4dc78e53SAndroid Build Coastguard Worker while (cur < len) {
324*4dc78e53SAndroid Build Coastguard Worker vlans->vlans[cur].vf_vlan = vi[cur]->vlan ? vi[cur]->vlan : 0;
325*4dc78e53SAndroid Build Coastguard Worker vlans->vlans[cur].vf_vlan_qos = vi[cur]->qos ? vi[cur]->qos : 0;
326*4dc78e53SAndroid Build Coastguard Worker if (vi[cur]->vlan_proto) {
327*4dc78e53SAndroid Build Coastguard Worker vlans->vlans[cur].vf_vlan_proto = ntohs(vi[cur]->vlan_proto);
328*4dc78e53SAndroid Build Coastguard Worker } else {
329*4dc78e53SAndroid Build Coastguard Worker vlans->vlans[cur].vf_vlan_proto = ETH_P_8021Q;
330*4dc78e53SAndroid Build Coastguard Worker }
331*4dc78e53SAndroid Build Coastguard Worker cur++;
332*4dc78e53SAndroid Build Coastguard Worker }
333*4dc78e53SAndroid Build Coastguard Worker
334*4dc78e53SAndroid Build Coastguard Worker *nvi = vlans;
335*4dc78e53SAndroid Build Coastguard Worker return 0;
336*4dc78e53SAndroid Build Coastguard Worker }
337*4dc78e53SAndroid Build Coastguard Worker
338*4dc78e53SAndroid Build Coastguard Worker /* Fill the IFLA_VF_VLAN attribute */
sriov_fill_vf_vlan(struct nl_msg * msg,nl_vf_vlan_info_t * vinfo,uint32_t index)339*4dc78e53SAndroid Build Coastguard Worker static void sriov_fill_vf_vlan(struct nl_msg *msg, nl_vf_vlan_info_t *vinfo,
340*4dc78e53SAndroid Build Coastguard Worker uint32_t index) {
341*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_vlan vlan;
342*4dc78e53SAndroid Build Coastguard Worker
343*4dc78e53SAndroid Build Coastguard Worker vlan.vf = index;
344*4dc78e53SAndroid Build Coastguard Worker vlan.vlan = vinfo[0].vf_vlan;
345*4dc78e53SAndroid Build Coastguard Worker vlan.qos = vinfo[0].vf_vlan_qos;
346*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, IFLA_VF_VLAN, sizeof(vlan), &vlan);
347*4dc78e53SAndroid Build Coastguard Worker
348*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
349*4dc78e53SAndroid Build Coastguard Worker return;
350*4dc78e53SAndroid Build Coastguard Worker }
351*4dc78e53SAndroid Build Coastguard Worker
352*4dc78e53SAndroid Build Coastguard Worker /* Fill the IFLA_VF_VLAN_LIST attribute */
sriov_fill_vf_vlan_list(struct nl_msg * msg,nl_vf_vlans_t * vlans,uint32_t index)353*4dc78e53SAndroid Build Coastguard Worker static int sriov_fill_vf_vlan_list(struct nl_msg *msg, nl_vf_vlans_t *vlans,
354*4dc78e53SAndroid Build Coastguard Worker uint32_t index) {
355*4dc78e53SAndroid Build Coastguard Worker int cur = 0;
356*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlan_info_t *vlan_info = vlans->vlans;
357*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_vlan_info vlan;
358*4dc78e53SAndroid Build Coastguard Worker struct nlattr *list;
359*4dc78e53SAndroid Build Coastguard Worker
360*4dc78e53SAndroid Build Coastguard Worker if (!(list = nla_nest_start(msg, IFLA_VF_VLAN_LIST)))
361*4dc78e53SAndroid Build Coastguard Worker return -NLE_MSGSIZE;
362*4dc78e53SAndroid Build Coastguard Worker
363*4dc78e53SAndroid Build Coastguard Worker vlan.vf = index;
364*4dc78e53SAndroid Build Coastguard Worker while (cur < vlans->size) {
365*4dc78e53SAndroid Build Coastguard Worker vlan.vlan = vlan_info[cur].vf_vlan;
366*4dc78e53SAndroid Build Coastguard Worker vlan.qos = vlan_info[cur].vf_vlan_qos;
367*4dc78e53SAndroid Build Coastguard Worker vlan.vlan_proto = vlan_info[cur].vf_vlan_proto;
368*4dc78e53SAndroid Build Coastguard Worker
369*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, IFLA_VF_VLAN_INFO, sizeof(vlan), &vlan);
370*4dc78e53SAndroid Build Coastguard Worker
371*4dc78e53SAndroid Build Coastguard Worker cur++;
372*4dc78e53SAndroid Build Coastguard Worker }
373*4dc78e53SAndroid Build Coastguard Worker
374*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
375*4dc78e53SAndroid Build Coastguard Worker nla_nest_end(msg, list);
376*4dc78e53SAndroid Build Coastguard Worker
377*4dc78e53SAndroid Build Coastguard Worker return 0;
378*4dc78e53SAndroid Build Coastguard Worker }
379*4dc78e53SAndroid Build Coastguard Worker
380*4dc78e53SAndroid Build Coastguard Worker /* Fill individual IFLA_VF_INFO attributes */
sriov_fill_vfinfo(struct nl_msg * msg,struct rtnl_link_vf * vf_data)381*4dc78e53SAndroid Build Coastguard Worker static int sriov_fill_vfinfo(struct nl_msg *msg,
382*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *vf_data) {
383*4dc78e53SAndroid Build Coastguard Worker int err = 0, new_rate = 0;
384*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlans_t *vlan_list;
385*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlan_info_t *vlan_info;
386*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_guid vf_node_guid;
387*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_guid vf_port_guid;
388*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_link_state vf_link_state;
389*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_mac vf_mac;
390*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_rate new_vf_rate;
391*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_rss_query_en vf_rss_query_en;
392*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_spoofchk vf_spoofchk;
393*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_trust vf_trust;
394*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_tx_rate vf_rate;
395*4dc78e53SAndroid Build Coastguard Worker struct nlattr *list;
396*4dc78e53SAndroid Build Coastguard Worker uint16_t proto;
397*4dc78e53SAndroid Build Coastguard Worker
398*4dc78e53SAndroid Build Coastguard Worker if (!(vf_data->ce_mask & SRIOV_ATTR_INDEX))
399*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
400*4dc78e53SAndroid Build Coastguard Worker
401*4dc78e53SAndroid Build Coastguard Worker if (!(list = nla_nest_start(msg, IFLA_VF_INFO)))
402*4dc78e53SAndroid Build Coastguard Worker return -NLE_MSGSIZE;
403*4dc78e53SAndroid Build Coastguard Worker
404*4dc78e53SAndroid Build Coastguard Worker /* IFLA_VF_MAC */
405*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_ADDR) {
406*4dc78e53SAndroid Build Coastguard Worker vf_mac.vf = vf_data->vf_index;
407*4dc78e53SAndroid Build Coastguard Worker memset(vf_mac.mac, 0, sizeof(vf_mac.mac));
408*4dc78e53SAndroid Build Coastguard Worker memcpy(vf_mac.mac, nl_addr_get_binary_addr(vf_data->vf_lladdr),
409*4dc78e53SAndroid Build Coastguard Worker nl_addr_get_len(vf_data->vf_lladdr));
410*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac);
411*4dc78e53SAndroid Build Coastguard Worker }
412*4dc78e53SAndroid Build Coastguard Worker
413*4dc78e53SAndroid Build Coastguard Worker /* IFLA_VF_VLAN IFLA_VF_VLAN_LIST */
414*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_VLAN) {
415*4dc78e53SAndroid Build Coastguard Worker vlan_list = vf_data->vf_vlans;
416*4dc78e53SAndroid Build Coastguard Worker vlan_info = vlan_list->vlans;
417*4dc78e53SAndroid Build Coastguard Worker proto = vlan_info[0].vf_vlan_proto;
418*4dc78e53SAndroid Build Coastguard Worker if (!proto)
419*4dc78e53SAndroid Build Coastguard Worker proto = ETH_P_8021Q;
420*4dc78e53SAndroid Build Coastguard Worker
421*4dc78e53SAndroid Build Coastguard Worker if ((vlan_list->size == 1) && (proto == ETH_P_8021Q))
422*4dc78e53SAndroid Build Coastguard Worker sriov_fill_vf_vlan(msg, vlan_info, vf_data->vf_index);
423*4dc78e53SAndroid Build Coastguard Worker else
424*4dc78e53SAndroid Build Coastguard Worker err = sriov_fill_vf_vlan_list(msg, vlan_list,
425*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_index);
426*4dc78e53SAndroid Build Coastguard Worker }
427*4dc78e53SAndroid Build Coastguard Worker
428*4dc78e53SAndroid Build Coastguard Worker /* IFLA_VF_TX_RATE */
429*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_TX_RATE) {
430*4dc78e53SAndroid Build Coastguard Worker vf_rate.vf = vf_data->vf_index;
431*4dc78e53SAndroid Build Coastguard Worker vf_rate.rate = vf_data->vf_rate;
432*4dc78e53SAndroid Build Coastguard Worker
433*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, IFLA_VF_TX_RATE, sizeof(vf_rate), &vf_rate);
434*4dc78e53SAndroid Build Coastguard Worker }
435*4dc78e53SAndroid Build Coastguard Worker
436*4dc78e53SAndroid Build Coastguard Worker /* IFLA_VF_RATE */
437*4dc78e53SAndroid Build Coastguard Worker new_vf_rate.min_tx_rate = 0;
438*4dc78e53SAndroid Build Coastguard Worker new_vf_rate.max_tx_rate = 0;
439*4dc78e53SAndroid Build Coastguard Worker new_vf_rate.vf = vf_data->vf_index;
440*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_RATE_MIN) {
441*4dc78e53SAndroid Build Coastguard Worker new_vf_rate.min_tx_rate = vf_data->vf_min_tx_rate;
442*4dc78e53SAndroid Build Coastguard Worker new_rate = 1;
443*4dc78e53SAndroid Build Coastguard Worker }
444*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_RATE_MAX) {
445*4dc78e53SAndroid Build Coastguard Worker new_vf_rate.max_tx_rate = vf_data->vf_max_tx_rate;
446*4dc78e53SAndroid Build Coastguard Worker new_rate = 1;
447*4dc78e53SAndroid Build Coastguard Worker }
448*4dc78e53SAndroid Build Coastguard Worker if (new_rate)
449*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, IFLA_VF_RATE, sizeof(new_vf_rate), &new_vf_rate);
450*4dc78e53SAndroid Build Coastguard Worker
451*4dc78e53SAndroid Build Coastguard Worker /* IFLA_VF_SPOOFCHK */
452*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_SPOOFCHK) {
453*4dc78e53SAndroid Build Coastguard Worker vf_spoofchk.vf = vf_data->vf_index;
454*4dc78e53SAndroid Build Coastguard Worker vf_spoofchk.setting = vf_data->vf_spoofchk;
455*4dc78e53SAndroid Build Coastguard Worker
456*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
457*4dc78e53SAndroid Build Coastguard Worker &vf_spoofchk);
458*4dc78e53SAndroid Build Coastguard Worker }
459*4dc78e53SAndroid Build Coastguard Worker
460*4dc78e53SAndroid Build Coastguard Worker /* IFLA_VF_LINK_STATE */
461*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE) {
462*4dc78e53SAndroid Build Coastguard Worker vf_link_state.vf = vf_data->vf_index;
463*4dc78e53SAndroid Build Coastguard Worker vf_link_state.link_state = vf_data->vf_linkstate;
464*4dc78e53SAndroid Build Coastguard Worker
465*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, IFLA_VF_LINK_STATE, sizeof(vf_link_state),
466*4dc78e53SAndroid Build Coastguard Worker &vf_link_state);
467*4dc78e53SAndroid Build Coastguard Worker }
468*4dc78e53SAndroid Build Coastguard Worker
469*4dc78e53SAndroid Build Coastguard Worker /* IFLA_VF_RSS_QUERY_EN */
470*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_RSS_QUERY_EN) {
471*4dc78e53SAndroid Build Coastguard Worker vf_rss_query_en.vf = vf_data->vf_index;
472*4dc78e53SAndroid Build Coastguard Worker vf_rss_query_en.setting = vf_data->vf_rss_query_en;
473*4dc78e53SAndroid Build Coastguard Worker
474*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, IFLA_VF_RSS_QUERY_EN, sizeof(vf_rss_query_en),
475*4dc78e53SAndroid Build Coastguard Worker &vf_rss_query_en);
476*4dc78e53SAndroid Build Coastguard Worker }
477*4dc78e53SAndroid Build Coastguard Worker
478*4dc78e53SAndroid Build Coastguard Worker /* IFLA_VF_TRUST */
479*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_TRUST) {
480*4dc78e53SAndroid Build Coastguard Worker vf_trust.vf = vf_data->vf_index;
481*4dc78e53SAndroid Build Coastguard Worker vf_trust.setting = vf_data->vf_trust;
482*4dc78e53SAndroid Build Coastguard Worker
483*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, IFLA_VF_TRUST, sizeof(vf_trust), &vf_trust);
484*4dc78e53SAndroid Build Coastguard Worker }
485*4dc78e53SAndroid Build Coastguard Worker
486*4dc78e53SAndroid Build Coastguard Worker /* IFLA_VF_IB_NODE_GUID */
487*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_IB_NODE_GUID) {
488*4dc78e53SAndroid Build Coastguard Worker vf_node_guid.vf = vf_data->vf_index;
489*4dc78e53SAndroid Build Coastguard Worker vf_node_guid.guid = vf_data->vf_guid_node;
490*4dc78e53SAndroid Build Coastguard Worker
491*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, IFLA_VF_IB_NODE_GUID, sizeof(vf_node_guid),
492*4dc78e53SAndroid Build Coastguard Worker &vf_node_guid);
493*4dc78e53SAndroid Build Coastguard Worker }
494*4dc78e53SAndroid Build Coastguard Worker
495*4dc78e53SAndroid Build Coastguard Worker /* IFLA_VF_IB_PORT_GUID */
496*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_IB_PORT_GUID) {
497*4dc78e53SAndroid Build Coastguard Worker vf_port_guid.vf = vf_data->vf_index;
498*4dc78e53SAndroid Build Coastguard Worker vf_port_guid.guid = vf_data->vf_guid_port;
499*4dc78e53SAndroid Build Coastguard Worker
500*4dc78e53SAndroid Build Coastguard Worker NLA_PUT(msg, IFLA_VF_IB_PORT_GUID, sizeof(vf_port_guid),
501*4dc78e53SAndroid Build Coastguard Worker &vf_port_guid);
502*4dc78e53SAndroid Build Coastguard Worker }
503*4dc78e53SAndroid Build Coastguard Worker
504*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
505*4dc78e53SAndroid Build Coastguard Worker nla_nest_end(msg, list);
506*4dc78e53SAndroid Build Coastguard Worker
507*4dc78e53SAndroid Build Coastguard Worker return err;
508*4dc78e53SAndroid Build Coastguard Worker }
509*4dc78e53SAndroid Build Coastguard Worker
510*4dc78e53SAndroid Build Coastguard Worker /* Fill the IFLA_VFINFO_LIST attribute */
rtnl_link_sriov_fill_vflist(struct nl_msg * msg,struct rtnl_link * link)511*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_sriov_fill_vflist(struct nl_msg *msg, struct rtnl_link *link) {
512*4dc78e53SAndroid Build Coastguard Worker int err = 0;
513*4dc78e53SAndroid Build Coastguard Worker struct nlattr *data;
514*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *list, *vf, *next;
515*4dc78e53SAndroid Build Coastguard Worker
516*4dc78e53SAndroid Build Coastguard Worker if (!(err = rtnl_link_has_vf_list(link)))
517*4dc78e53SAndroid Build Coastguard Worker return 0;
518*4dc78e53SAndroid Build Coastguard Worker
519*4dc78e53SAndroid Build Coastguard Worker if (!(data = nla_nest_start(msg, IFLA_VFINFO_LIST)))
520*4dc78e53SAndroid Build Coastguard Worker return -NLE_MSGSIZE;
521*4dc78e53SAndroid Build Coastguard Worker
522*4dc78e53SAndroid Build Coastguard Worker list = link->l_vf_list;
523*4dc78e53SAndroid Build Coastguard Worker nl_list_for_each_entry_safe(vf, next, &list->vf_list, vf_list) {
524*4dc78e53SAndroid Build Coastguard Worker if (vf->ce_mask & SRIOV_ATTR_INDEX) {
525*4dc78e53SAndroid Build Coastguard Worker if ((err = sriov_fill_vfinfo(msg, vf)) < 0)
526*4dc78e53SAndroid Build Coastguard Worker goto nla_nest_list_failure;
527*4dc78e53SAndroid Build Coastguard Worker }
528*4dc78e53SAndroid Build Coastguard Worker }
529*4dc78e53SAndroid Build Coastguard Worker
530*4dc78e53SAndroid Build Coastguard Worker nla_nest_list_failure:
531*4dc78e53SAndroid Build Coastguard Worker nla_nest_end(msg, data);
532*4dc78e53SAndroid Build Coastguard Worker
533*4dc78e53SAndroid Build Coastguard Worker return err;
534*4dc78e53SAndroid Build Coastguard Worker }
535*4dc78e53SAndroid Build Coastguard Worker
536*4dc78e53SAndroid Build Coastguard Worker /* Parse IFLA_VFINFO_LIST and IFLA_VF_INFO attributes */
rtnl_link_sriov_parse_vflist(struct rtnl_link * link,struct nlattr ** tb)537*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_sriov_parse_vflist(struct rtnl_link *link, struct nlattr **tb) {
538*4dc78e53SAndroid Build Coastguard Worker int err, len, list_len, list_rem;
539*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_mac *vf_lladdr;
540*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_vlan *vf_vlan;
541*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_vlan_info *vf_vlan_info[MAX_VLAN_LIST_LEN];
542*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_tx_rate *vf_tx_rate;
543*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_spoofchk *vf_spoofchk;
544*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_link_state *vf_linkstate;
545*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_rate *vf_rate;
546*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_rss_query_en *vf_rss_query;
547*4dc78e53SAndroid Build Coastguard Worker struct ifla_vf_trust *vf_trust;
548*4dc78e53SAndroid Build Coastguard Worker struct nlattr *nla, *nla_list, *t[IFLA_VF_MAX+1],
549*4dc78e53SAndroid Build Coastguard Worker *stb[RTNL_LINK_VF_STATS_MAX+1];
550*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlans_t *vf_vlans = NULL;
551*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *vf_data, *vf_head = NULL;
552*4dc78e53SAndroid Build Coastguard Worker
553*4dc78e53SAndroid Build Coastguard Worker len = nla_len(tb[IFLA_VFINFO_LIST]);
554*4dc78e53SAndroid Build Coastguard Worker link->l_vf_list = rtnl_link_vf_alloc();
555*4dc78e53SAndroid Build Coastguard Worker if (!link->l_vf_list)
556*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
557*4dc78e53SAndroid Build Coastguard Worker vf_head = link->l_vf_list;
558*4dc78e53SAndroid Build Coastguard Worker
559*4dc78e53SAndroid Build Coastguard Worker for (nla = nla_data(tb[IFLA_VFINFO_LIST]); nla_ok(nla, len);
560*4dc78e53SAndroid Build Coastguard Worker nla = nla_next(nla, &len)) {
561*4dc78e53SAndroid Build Coastguard Worker err = nla_parse(t, IFLA_VF_MAX, nla_data(nla), nla_len(nla),
562*4dc78e53SAndroid Build Coastguard Worker sriov_info_policy);
563*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
564*4dc78e53SAndroid Build Coastguard Worker return err;
565*4dc78e53SAndroid Build Coastguard Worker
566*4dc78e53SAndroid Build Coastguard Worker vf_data = rtnl_link_vf_alloc();
567*4dc78e53SAndroid Build Coastguard Worker if (!vf_data)
568*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
569*4dc78e53SAndroid Build Coastguard Worker
570*4dc78e53SAndroid Build Coastguard Worker if (t[IFLA_VF_MAC]) {
571*4dc78e53SAndroid Build Coastguard Worker vf_lladdr = nla_data(t[IFLA_VF_MAC]);
572*4dc78e53SAndroid Build Coastguard Worker
573*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_index = vf_lladdr->vf;
574*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_INDEX;
575*4dc78e53SAndroid Build Coastguard Worker
576*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_lladdr = nl_addr_build(AF_LLC,
577*4dc78e53SAndroid Build Coastguard Worker vf_lladdr->mac, 6);
578*4dc78e53SAndroid Build Coastguard Worker if (vf_data->vf_lladdr == NULL) {
579*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_put(vf_data);
580*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
581*4dc78e53SAndroid Build Coastguard Worker }
582*4dc78e53SAndroid Build Coastguard Worker nl_addr_set_family(vf_data->vf_lladdr, AF_LLC);
583*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_ADDR;
584*4dc78e53SAndroid Build Coastguard Worker }
585*4dc78e53SAndroid Build Coastguard Worker
586*4dc78e53SAndroid Build Coastguard Worker if (t[IFLA_VF_VLAN_LIST]) {
587*4dc78e53SAndroid Build Coastguard Worker list_len = 0;
588*4dc78e53SAndroid Build Coastguard Worker nla_for_each_nested(nla_list, t[IFLA_VF_VLAN_LIST],
589*4dc78e53SAndroid Build Coastguard Worker list_rem) {
590*4dc78e53SAndroid Build Coastguard Worker if (list_len >= MAX_VLAN_LIST_LEN)
591*4dc78e53SAndroid Build Coastguard Worker break;
592*4dc78e53SAndroid Build Coastguard Worker vf_vlan_info[list_len] = nla_data(nla_list);
593*4dc78e53SAndroid Build Coastguard Worker list_len++;
594*4dc78e53SAndroid Build Coastguard Worker }
595*4dc78e53SAndroid Build Coastguard Worker
596*4dc78e53SAndroid Build Coastguard Worker err = rtnl_link_vf_vlan_info(list_len, vf_vlan_info,
597*4dc78e53SAndroid Build Coastguard Worker &vf_vlans);
598*4dc78e53SAndroid Build Coastguard Worker if (err < 0) {
599*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_put(vf_data);
600*4dc78e53SAndroid Build Coastguard Worker return err;
601*4dc78e53SAndroid Build Coastguard Worker }
602*4dc78e53SAndroid Build Coastguard Worker
603*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_vlans = vf_vlans;
604*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_VLAN;
605*4dc78e53SAndroid Build Coastguard Worker } else if (t[IFLA_VF_VLAN]) {
606*4dc78e53SAndroid Build Coastguard Worker vf_vlan = nla_data(t[IFLA_VF_VLAN]);
607*4dc78e53SAndroid Build Coastguard Worker
608*4dc78e53SAndroid Build Coastguard Worker if (vf_vlan->vlan) {
609*4dc78e53SAndroid Build Coastguard Worker err = rtnl_link_vf_vlan_alloc(&vf_vlans, 1);
610*4dc78e53SAndroid Build Coastguard Worker if (err < 0) {
611*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_put(vf_data);
612*4dc78e53SAndroid Build Coastguard Worker return err;
613*4dc78e53SAndroid Build Coastguard Worker }
614*4dc78e53SAndroid Build Coastguard Worker
615*4dc78e53SAndroid Build Coastguard Worker vf_vlans->vlans[0].vf_vlan = vf_vlan->vlan;
616*4dc78e53SAndroid Build Coastguard Worker vf_vlans->vlans[0].vf_vlan_qos = vf_vlan->qos;
617*4dc78e53SAndroid Build Coastguard Worker vf_vlans->vlans[0].vf_vlan_proto = ETH_P_8021Q;
618*4dc78e53SAndroid Build Coastguard Worker
619*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_vlans = vf_vlans;
620*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_VLAN;
621*4dc78e53SAndroid Build Coastguard Worker }
622*4dc78e53SAndroid Build Coastguard Worker }
623*4dc78e53SAndroid Build Coastguard Worker
624*4dc78e53SAndroid Build Coastguard Worker if (t[IFLA_VF_TX_RATE]) {
625*4dc78e53SAndroid Build Coastguard Worker vf_tx_rate = nla_data(t[IFLA_VF_TX_RATE]);
626*4dc78e53SAndroid Build Coastguard Worker
627*4dc78e53SAndroid Build Coastguard Worker if (vf_tx_rate->rate) {
628*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_rate = vf_tx_rate->rate;
629*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_TX_RATE;
630*4dc78e53SAndroid Build Coastguard Worker }
631*4dc78e53SAndroid Build Coastguard Worker }
632*4dc78e53SAndroid Build Coastguard Worker
633*4dc78e53SAndroid Build Coastguard Worker if (t[IFLA_VF_SPOOFCHK]) {
634*4dc78e53SAndroid Build Coastguard Worker vf_spoofchk = nla_data(t[IFLA_VF_SPOOFCHK]);
635*4dc78e53SAndroid Build Coastguard Worker
636*4dc78e53SAndroid Build Coastguard Worker if (vf_spoofchk->setting != ((uint32_t)-1)) {
637*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_spoofchk = vf_spoofchk->setting ? 1 : 0;
638*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_SPOOFCHK;
639*4dc78e53SAndroid Build Coastguard Worker }
640*4dc78e53SAndroid Build Coastguard Worker }
641*4dc78e53SAndroid Build Coastguard Worker
642*4dc78e53SAndroid Build Coastguard Worker if (t[IFLA_VF_LINK_STATE]) {
643*4dc78e53SAndroid Build Coastguard Worker vf_linkstate = nla_data(t[IFLA_VF_LINK_STATE]);
644*4dc78e53SAndroid Build Coastguard Worker
645*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_linkstate = vf_linkstate->link_state;
646*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_LINK_STATE;
647*4dc78e53SAndroid Build Coastguard Worker }
648*4dc78e53SAndroid Build Coastguard Worker
649*4dc78e53SAndroid Build Coastguard Worker if (t[IFLA_VF_RATE]) {
650*4dc78e53SAndroid Build Coastguard Worker vf_rate = nla_data(t[IFLA_VF_RATE]);
651*4dc78e53SAndroid Build Coastguard Worker
652*4dc78e53SAndroid Build Coastguard Worker if (vf_rate->max_tx_rate) {
653*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_max_tx_rate = vf_rate->max_tx_rate;
654*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_RATE_MAX;
655*4dc78e53SAndroid Build Coastguard Worker }
656*4dc78e53SAndroid Build Coastguard Worker if (vf_rate->min_tx_rate) {
657*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_min_tx_rate = vf_rate->min_tx_rate;
658*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_RATE_MIN;
659*4dc78e53SAndroid Build Coastguard Worker }
660*4dc78e53SAndroid Build Coastguard Worker }
661*4dc78e53SAndroid Build Coastguard Worker
662*4dc78e53SAndroid Build Coastguard Worker if (t[IFLA_VF_RSS_QUERY_EN]) {
663*4dc78e53SAndroid Build Coastguard Worker vf_rss_query = nla_data(t[IFLA_VF_RSS_QUERY_EN]);
664*4dc78e53SAndroid Build Coastguard Worker
665*4dc78e53SAndroid Build Coastguard Worker if (vf_rss_query->setting != ((uint32_t)-1)) {
666*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_rss_query_en = vf_rss_query->setting ? 1 : 0;
667*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_RSS_QUERY_EN;
668*4dc78e53SAndroid Build Coastguard Worker }
669*4dc78e53SAndroid Build Coastguard Worker }
670*4dc78e53SAndroid Build Coastguard Worker
671*4dc78e53SAndroid Build Coastguard Worker if (t[IFLA_VF_STATS]) {
672*4dc78e53SAndroid Build Coastguard Worker err = nla_parse_nested(stb, RTNL_LINK_VF_STATS_MAX,
673*4dc78e53SAndroid Build Coastguard Worker t[IFLA_VF_STATS],
674*4dc78e53SAndroid Build Coastguard Worker sriov_stats_policy);
675*4dc78e53SAndroid Build Coastguard Worker if (err < 0) {
676*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_put(vf_data);
677*4dc78e53SAndroid Build Coastguard Worker return err;
678*4dc78e53SAndroid Build Coastguard Worker }
679*4dc78e53SAndroid Build Coastguard Worker
680*4dc78e53SAndroid Build Coastguard Worker SET_VF_STAT(link, cur, stb,
681*4dc78e53SAndroid Build Coastguard Worker RTNL_LINK_VF_STATS_RX_PACKETS,
682*4dc78e53SAndroid Build Coastguard Worker IFLA_VF_STATS_RX_PACKETS);
683*4dc78e53SAndroid Build Coastguard Worker SET_VF_STAT(link, cur, stb,
684*4dc78e53SAndroid Build Coastguard Worker RTNL_LINK_VF_STATS_TX_PACKETS,
685*4dc78e53SAndroid Build Coastguard Worker IFLA_VF_STATS_TX_PACKETS);
686*4dc78e53SAndroid Build Coastguard Worker SET_VF_STAT(link, cur, stb,
687*4dc78e53SAndroid Build Coastguard Worker RTNL_LINK_VF_STATS_RX_BYTES,
688*4dc78e53SAndroid Build Coastguard Worker IFLA_VF_STATS_RX_BYTES);
689*4dc78e53SAndroid Build Coastguard Worker SET_VF_STAT(link, cur, stb,
690*4dc78e53SAndroid Build Coastguard Worker RTNL_LINK_VF_STATS_TX_BYTES,
691*4dc78e53SAndroid Build Coastguard Worker IFLA_VF_STATS_TX_BYTES);
692*4dc78e53SAndroid Build Coastguard Worker SET_VF_STAT(link, cur, stb,
693*4dc78e53SAndroid Build Coastguard Worker RTNL_LINK_VF_STATS_BROADCAST,
694*4dc78e53SAndroid Build Coastguard Worker IFLA_VF_STATS_BROADCAST);
695*4dc78e53SAndroid Build Coastguard Worker SET_VF_STAT(link, cur, stb,
696*4dc78e53SAndroid Build Coastguard Worker RTNL_LINK_VF_STATS_MULTICAST,
697*4dc78e53SAndroid Build Coastguard Worker IFLA_VF_STATS_MULTICAST);
698*4dc78e53SAndroid Build Coastguard Worker
699*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_STATS;
700*4dc78e53SAndroid Build Coastguard Worker }
701*4dc78e53SAndroid Build Coastguard Worker
702*4dc78e53SAndroid Build Coastguard Worker if (t[IFLA_VF_TRUST]) {
703*4dc78e53SAndroid Build Coastguard Worker vf_trust = nla_data(t[IFLA_VF_TRUST]);
704*4dc78e53SAndroid Build Coastguard Worker
705*4dc78e53SAndroid Build Coastguard Worker if (vf_trust->setting != ((uint32_t)-1)) {
706*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_trust = vf_trust->setting ? 1 : 0;
707*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_TRUST;
708*4dc78e53SAndroid Build Coastguard Worker }
709*4dc78e53SAndroid Build Coastguard Worker }
710*4dc78e53SAndroid Build Coastguard Worker
711*4dc78e53SAndroid Build Coastguard Worker nl_list_add_head(&vf_data->vf_list, &vf_head->vf_list);
712*4dc78e53SAndroid Build Coastguard Worker vf_head = vf_data;
713*4dc78e53SAndroid Build Coastguard Worker }
714*4dc78e53SAndroid Build Coastguard Worker
715*4dc78e53SAndroid Build Coastguard Worker return 0;
716*4dc78e53SAndroid Build Coastguard Worker }
717*4dc78e53SAndroid Build Coastguard Worker
718*4dc78e53SAndroid Build Coastguard Worker /**
719*4dc78e53SAndroid Build Coastguard Worker * @name SR-IOV Sub-Object
720*4dc78e53SAndroid Build Coastguard Worker * @{
721*4dc78e53SAndroid Build Coastguard Worker */
722*4dc78e53SAndroid Build Coastguard Worker
723*4dc78e53SAndroid Build Coastguard Worker /**
724*4dc78e53SAndroid Build Coastguard Worker * Add a SRIOV VF object to a link object
725*4dc78e53SAndroid Build Coastguard Worker * @param link Link object to add to
726*4dc78e53SAndroid Build Coastguard Worker * @param vf_data SRIOV VF object to add
727*4dc78e53SAndroid Build Coastguard Worker *
728*4dc78e53SAndroid Build Coastguard Worker * @return 0 if SRIOV VF object added successfully
729*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_OBJ_NOTFOUND if \p link or \p vf_data not provided
730*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_NOMEM if out of memory
731*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_add(struct rtnl_link * link,struct rtnl_link_vf * vf_data)732*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_add(struct rtnl_link *link, struct rtnl_link_vf *vf_data) {
733*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *vf_head = NULL;
734*4dc78e53SAndroid Build Coastguard Worker
735*4dc78e53SAndroid Build Coastguard Worker if (!link||!vf_data)
736*4dc78e53SAndroid Build Coastguard Worker return -NLE_OBJ_NOTFOUND;
737*4dc78e53SAndroid Build Coastguard Worker
738*4dc78e53SAndroid Build Coastguard Worker if (!link->l_vf_list) {
739*4dc78e53SAndroid Build Coastguard Worker link->l_vf_list = rtnl_link_vf_alloc();
740*4dc78e53SAndroid Build Coastguard Worker if (!link->l_vf_list)
741*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
742*4dc78e53SAndroid Build Coastguard Worker }
743*4dc78e53SAndroid Build Coastguard Worker
744*4dc78e53SAndroid Build Coastguard Worker vf_head = vf_data;
745*4dc78e53SAndroid Build Coastguard Worker vf_head->ce_refcnt++;
746*4dc78e53SAndroid Build Coastguard Worker
747*4dc78e53SAndroid Build Coastguard Worker vf_head = link->l_vf_list;
748*4dc78e53SAndroid Build Coastguard Worker nl_list_add_head(&vf_data->vf_list, &vf_head->vf_list);
749*4dc78e53SAndroid Build Coastguard Worker link->l_vf_list = vf_head;
750*4dc78e53SAndroid Build Coastguard Worker
751*4dc78e53SAndroid Build Coastguard Worker rtnl_link_set_vf_list(link);
752*4dc78e53SAndroid Build Coastguard Worker
753*4dc78e53SAndroid Build Coastguard Worker return 0;
754*4dc78e53SAndroid Build Coastguard Worker }
755*4dc78e53SAndroid Build Coastguard Worker
756*4dc78e53SAndroid Build Coastguard Worker /**
757*4dc78e53SAndroid Build Coastguard Worker * Allocate a new SRIOV VF object
758*4dc78e53SAndroid Build Coastguard Worker *
759*4dc78e53SAndroid Build Coastguard Worker * @return NULL if out of memory
760*4dc78e53SAndroid Build Coastguard Worker * @return New VF Object
761*4dc78e53SAndroid Build Coastguard Worker *
762*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_put()
763*4dc78e53SAndroid Build Coastguard Worker *
764*4dc78e53SAndroid Build Coastguard Worker * The SRIOV VF object must be returned to the link object with
765*4dc78e53SAndroid Build Coastguard Worker * rtnl_link_vf_put() when operations are done to prevent memory leaks.
766*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_alloc(void)767*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *rtnl_link_vf_alloc(void) {
768*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *vf;
769*4dc78e53SAndroid Build Coastguard Worker
770*4dc78e53SAndroid Build Coastguard Worker if (!(vf = calloc(1, sizeof(*vf))))
771*4dc78e53SAndroid Build Coastguard Worker return NULL;
772*4dc78e53SAndroid Build Coastguard Worker
773*4dc78e53SAndroid Build Coastguard Worker NL_INIT_LIST_HEAD(&vf->vf_list);
774*4dc78e53SAndroid Build Coastguard Worker vf->ce_refcnt = 1;
775*4dc78e53SAndroid Build Coastguard Worker
776*4dc78e53SAndroid Build Coastguard Worker NL_DBG(4, "Allocated new SRIOV VF object %p\n", vf);
777*4dc78e53SAndroid Build Coastguard Worker
778*4dc78e53SAndroid Build Coastguard Worker return vf;
779*4dc78e53SAndroid Build Coastguard Worker }
780*4dc78e53SAndroid Build Coastguard Worker
781*4dc78e53SAndroid Build Coastguard Worker /**
782*4dc78e53SAndroid Build Coastguard Worker * Free SRIOV VF object.
783*4dc78e53SAndroid Build Coastguard Worker * @arg vf_data SRIOV VF data object
784*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_free(struct rtnl_link_vf * vf_data)785*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_free(struct rtnl_link_vf *vf_data) {
786*4dc78e53SAndroid Build Coastguard Worker if (!vf_data)
787*4dc78e53SAndroid Build Coastguard Worker return;
788*4dc78e53SAndroid Build Coastguard Worker
789*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_refcnt > 0)
790*4dc78e53SAndroid Build Coastguard Worker NL_DBG(1, "Warning: Freeing SRIOV VF object in use...\n");
791*4dc78e53SAndroid Build Coastguard Worker
792*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_ADDR)
793*4dc78e53SAndroid Build Coastguard Worker nl_addr_put(vf_data->vf_lladdr);
794*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_VLAN)
795*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_vlan_put(vf_data->vf_vlans);
796*4dc78e53SAndroid Build Coastguard Worker
797*4dc78e53SAndroid Build Coastguard Worker NL_DBG(4, "Freed SRIOV VF object %p\n", vf_data);
798*4dc78e53SAndroid Build Coastguard Worker free(vf_data);
799*4dc78e53SAndroid Build Coastguard Worker
800*4dc78e53SAndroid Build Coastguard Worker return;
801*4dc78e53SAndroid Build Coastguard Worker }
802*4dc78e53SAndroid Build Coastguard Worker
803*4dc78e53SAndroid Build Coastguard Worker /**
804*4dc78e53SAndroid Build Coastguard Worker * Lookup SRIOV VF in link object by VF index.
805*4dc78e53SAndroid Build Coastguard Worker *
806*4dc78e53SAndroid Build Coastguard Worker * @return NULL if VF not found
807*4dc78e53SAndroid Build Coastguard Worker * @return VF Object
808*4dc78e53SAndroid Build Coastguard Worker *
809*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_put()
810*4dc78e53SAndroid Build Coastguard Worker *
811*4dc78e53SAndroid Build Coastguard Worker * The SRIOV VF object must be returned to the link object with
812*4dc78e53SAndroid Build Coastguard Worker * rtnl_link_vf_put() when operations are done to prevent memory leaks.
813*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_get(struct rtnl_link * link,uint32_t vf_num)814*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *rtnl_link_vf_get(struct rtnl_link *link, uint32_t vf_num) {
815*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_vf *list, *vf, *next, *ret = NULL;
816*4dc78e53SAndroid Build Coastguard Worker
817*4dc78e53SAndroid Build Coastguard Worker list = link->l_vf_list;
818*4dc78e53SAndroid Build Coastguard Worker nl_list_for_each_entry_safe(vf, next, &list->vf_list, vf_list) {
819*4dc78e53SAndroid Build Coastguard Worker if (vf->vf_index == vf_num) {
820*4dc78e53SAndroid Build Coastguard Worker ret = vf;
821*4dc78e53SAndroid Build Coastguard Worker break;
822*4dc78e53SAndroid Build Coastguard Worker }
823*4dc78e53SAndroid Build Coastguard Worker }
824*4dc78e53SAndroid Build Coastguard Worker
825*4dc78e53SAndroid Build Coastguard Worker if (ret) {
826*4dc78e53SAndroid Build Coastguard Worker ret->ce_refcnt++;
827*4dc78e53SAndroid Build Coastguard Worker NL_DBG(4, "New reference to SRIOV VF object %p, total %i\n",
828*4dc78e53SAndroid Build Coastguard Worker ret, ret->ce_refcnt);
829*4dc78e53SAndroid Build Coastguard Worker }
830*4dc78e53SAndroid Build Coastguard Worker
831*4dc78e53SAndroid Build Coastguard Worker return ret;
832*4dc78e53SAndroid Build Coastguard Worker }
833*4dc78e53SAndroid Build Coastguard Worker
834*4dc78e53SAndroid Build Coastguard Worker /**
835*4dc78e53SAndroid Build Coastguard Worker * Return SRIOV VF object to the owning link object.
836*4dc78e53SAndroid Build Coastguard Worker * @arg vf_data SRIOV VF data object
837*4dc78e53SAndroid Build Coastguard Worker *
838*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_alloc()
839*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_get()
840*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_put(struct rtnl_link_vf * vf_data)841*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_put(struct rtnl_link_vf *vf_data) {
842*4dc78e53SAndroid Build Coastguard Worker if (!vf_data)
843*4dc78e53SAndroid Build Coastguard Worker return;
844*4dc78e53SAndroid Build Coastguard Worker
845*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_refcnt--;
846*4dc78e53SAndroid Build Coastguard Worker NL_DBG(4, "Returned SRIOV VF object reference %p, %i remaining\n",
847*4dc78e53SAndroid Build Coastguard Worker vf_data, vf_data->ce_refcnt);
848*4dc78e53SAndroid Build Coastguard Worker
849*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_refcnt < 0)
850*4dc78e53SAndroid Build Coastguard Worker BUG();
851*4dc78e53SAndroid Build Coastguard Worker
852*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_refcnt <= 0)
853*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_free(vf_data);
854*4dc78e53SAndroid Build Coastguard Worker
855*4dc78e53SAndroid Build Coastguard Worker return;
856*4dc78e53SAndroid Build Coastguard Worker }
857*4dc78e53SAndroid Build Coastguard Worker
858*4dc78e53SAndroid Build Coastguard Worker /**
859*4dc78e53SAndroid Build Coastguard Worker * Get link layer address of SRIOV Virtual Function
860*4dc78e53SAndroid Build Coastguard Worker * @arg vf_data SRIOV VF object
861*4dc78e53SAndroid Build Coastguard Worker * @arg addr Pointer to store Link Layer address
862*4dc78e53SAndroid Build Coastguard Worker *
863*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_num_vf()
864*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_set_addr()
865*4dc78e53SAndroid Build Coastguard Worker *
866*4dc78e53SAndroid Build Coastguard Worker * @copydoc pointer_lifetime_warning
867*4dc78e53SAndroid Build Coastguard Worker * @return 0 if addr is present and addr is set to pointer containing address
868*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
869*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_NOATTR if the link layer address is not set
870*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_get_addr(struct rtnl_link_vf * vf_data,struct nl_addr ** addr)871*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_addr(struct rtnl_link_vf *vf_data, struct nl_addr **addr)
872*4dc78e53SAndroid Build Coastguard Worker {
873*4dc78e53SAndroid Build Coastguard Worker if (!vf_data)
874*4dc78e53SAndroid Build Coastguard Worker return -NLE_OBJ_NOTFOUND;
875*4dc78e53SAndroid Build Coastguard Worker
876*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_ADDR)
877*4dc78e53SAndroid Build Coastguard Worker *addr = vf_data->vf_lladdr;
878*4dc78e53SAndroid Build Coastguard Worker else
879*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOATTR;
880*4dc78e53SAndroid Build Coastguard Worker
881*4dc78e53SAndroid Build Coastguard Worker return 0;
882*4dc78e53SAndroid Build Coastguard Worker }
883*4dc78e53SAndroid Build Coastguard Worker
884*4dc78e53SAndroid Build Coastguard Worker /**
885*4dc78e53SAndroid Build Coastguard Worker * Set link layer address of SRIOV Virtual Function object
886*4dc78e53SAndroid Build Coastguard Worker * @param vf_data SRIOV VF object
887*4dc78e53SAndroid Build Coastguard Worker * @param addr New link layer address
888*4dc78e53SAndroid Build Coastguard Worker *
889*4dc78e53SAndroid Build Coastguard Worker * This function increments the reference counter of the address object
890*4dc78e53SAndroid Build Coastguard Worker * and overwrites any existing link layer address previously assigned.
891*4dc78e53SAndroid Build Coastguard Worker *
892*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_get_addr()
893*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_set_addr(struct rtnl_link_vf * vf_data,struct nl_addr * addr)894*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_addr(struct rtnl_link_vf *vf_data, struct nl_addr *addr) {
895*4dc78e53SAndroid Build Coastguard Worker if (vf_data->vf_lladdr)
896*4dc78e53SAndroid Build Coastguard Worker nl_addr_put(vf_data->vf_lladdr);
897*4dc78e53SAndroid Build Coastguard Worker
898*4dc78e53SAndroid Build Coastguard Worker nl_addr_get(addr);
899*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_lladdr = addr;
900*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_ADDR;
901*4dc78e53SAndroid Build Coastguard Worker
902*4dc78e53SAndroid Build Coastguard Worker return;
903*4dc78e53SAndroid Build Coastguard Worker }
904*4dc78e53SAndroid Build Coastguard Worker
905*4dc78e53SAndroid Build Coastguard Worker /**
906*4dc78e53SAndroid Build Coastguard Worker * Set the Infiniband node GUID for the SRIOV Virtual Function object
907*4dc78e53SAndroid Build Coastguard Worker * @param vf_data SRIOV VF object
908*4dc78e53SAndroid Build Coastguard Worker * @param guid node GUID
909*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_set_ib_node_guid(struct rtnl_link_vf * vf_data,uint64_t guid)910*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_ib_node_guid(struct rtnl_link_vf *vf_data,
911*4dc78e53SAndroid Build Coastguard Worker uint64_t guid) {
912*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_guid_node = guid;
913*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_IB_NODE_GUID;
914*4dc78e53SAndroid Build Coastguard Worker
915*4dc78e53SAndroid Build Coastguard Worker return;
916*4dc78e53SAndroid Build Coastguard Worker }
917*4dc78e53SAndroid Build Coastguard Worker
918*4dc78e53SAndroid Build Coastguard Worker /**
919*4dc78e53SAndroid Build Coastguard Worker * Set the Infiniband port GUID for the SRIOV Virtual Function object
920*4dc78e53SAndroid Build Coastguard Worker * @param vf_data SRIOV VF object
921*4dc78e53SAndroid Build Coastguard Worker * @param guid port GUID
922*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_set_ib_port_guid(struct rtnl_link_vf * vf_data,uint64_t guid)923*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_ib_port_guid(struct rtnl_link_vf *vf_data,
924*4dc78e53SAndroid Build Coastguard Worker uint64_t guid) {
925*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_guid_port = guid;
926*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_IB_PORT_GUID;
927*4dc78e53SAndroid Build Coastguard Worker
928*4dc78e53SAndroid Build Coastguard Worker return;
929*4dc78e53SAndroid Build Coastguard Worker }
930*4dc78e53SAndroid Build Coastguard Worker
931*4dc78e53SAndroid Build Coastguard Worker /**
932*4dc78e53SAndroid Build Coastguard Worker * Get index of SRIOV Virtual Function
933*4dc78e53SAndroid Build Coastguard Worker * @arg vf_data SRIOV VF object
934*4dc78e53SAndroid Build Coastguard Worker * @arg vf_index Pointer to store VF index
935*4dc78e53SAndroid Build Coastguard Worker *
936*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_num_vf()
937*4dc78e53SAndroid Build Coastguard Worker *
938*4dc78e53SAndroid Build Coastguard Worker * @return 0 if index is present and vf_index is set
939*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
940*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_NOATTR if the VF index is not set
941*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_get_index(struct rtnl_link_vf * vf_data,uint32_t * vf_index)942*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_index(struct rtnl_link_vf *vf_data, uint32_t *vf_index)
943*4dc78e53SAndroid Build Coastguard Worker {
944*4dc78e53SAndroid Build Coastguard Worker if (!vf_data)
945*4dc78e53SAndroid Build Coastguard Worker return -NLE_OBJ_NOTFOUND;
946*4dc78e53SAndroid Build Coastguard Worker
947*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_INDEX)
948*4dc78e53SAndroid Build Coastguard Worker *vf_index = vf_data->vf_index;
949*4dc78e53SAndroid Build Coastguard Worker else
950*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOATTR;
951*4dc78e53SAndroid Build Coastguard Worker
952*4dc78e53SAndroid Build Coastguard Worker return 0;
953*4dc78e53SAndroid Build Coastguard Worker }
954*4dc78e53SAndroid Build Coastguard Worker
955*4dc78e53SAndroid Build Coastguard Worker /**
956*4dc78e53SAndroid Build Coastguard Worker * Set index of SRIOV Virtual Function object
957*4dc78e53SAndroid Build Coastguard Worker * @param vf_data SRIOV VF object
958*4dc78e53SAndroid Build Coastguard Worker * @param vf_index Index value
959*4dc78e53SAndroid Build Coastguard Worker *
960*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_get_index()
961*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_set_index(struct rtnl_link_vf * vf_data,uint32_t vf_index)962*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_index(struct rtnl_link_vf *vf_data, uint32_t vf_index)
963*4dc78e53SAndroid Build Coastguard Worker {
964*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_index = vf_index;
965*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_INDEX;
966*4dc78e53SAndroid Build Coastguard Worker
967*4dc78e53SAndroid Build Coastguard Worker return;
968*4dc78e53SAndroid Build Coastguard Worker }
969*4dc78e53SAndroid Build Coastguard Worker
970*4dc78e53SAndroid Build Coastguard Worker /**
971*4dc78e53SAndroid Build Coastguard Worker * Get link state of SRIOV Virtual Function
972*4dc78e53SAndroid Build Coastguard Worker * @arg vf_data SRIOV VF object
973*4dc78e53SAndroid Build Coastguard Worker * @arg vf_linkstate Pointer to store VF link state
974*4dc78e53SAndroid Build Coastguard Worker *
975*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_num_vf()
976*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_linkstate()
977*4dc78e53SAndroid Build Coastguard Worker *
978*4dc78e53SAndroid Build Coastguard Worker * @return 0 if link state is present and vf_linkstate is set
979*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
980*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_NOATTR if the VF link state is not set
981*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_get_linkstate(struct rtnl_link_vf * vf_data,uint32_t * vf_linkstate)982*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_linkstate(struct rtnl_link_vf *vf_data,
983*4dc78e53SAndroid Build Coastguard Worker uint32_t *vf_linkstate)
984*4dc78e53SAndroid Build Coastguard Worker {
985*4dc78e53SAndroid Build Coastguard Worker if (!vf_data)
986*4dc78e53SAndroid Build Coastguard Worker return -NLE_OBJ_NOTFOUND;
987*4dc78e53SAndroid Build Coastguard Worker
988*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE)
989*4dc78e53SAndroid Build Coastguard Worker *vf_linkstate = vf_data->vf_linkstate;
990*4dc78e53SAndroid Build Coastguard Worker else
991*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOATTR;
992*4dc78e53SAndroid Build Coastguard Worker
993*4dc78e53SAndroid Build Coastguard Worker return 0;
994*4dc78e53SAndroid Build Coastguard Worker }
995*4dc78e53SAndroid Build Coastguard Worker
996*4dc78e53SAndroid Build Coastguard Worker /**
997*4dc78e53SAndroid Build Coastguard Worker * Set link state of SRIOV Virtual Function object
998*4dc78e53SAndroid Build Coastguard Worker * @param vf_data SRIOV VF object
999*4dc78e53SAndroid Build Coastguard Worker * @param vf_linkstate Link state value
1000*4dc78e53SAndroid Build Coastguard Worker *
1001*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_linkstate()
1002*4dc78e53SAndroid Build Coastguard Worker *
1003*4dc78e53SAndroid Build Coastguard Worker * Not all hardware supports setting link state. If the feature is unsupported,
1004*4dc78e53SAndroid Build Coastguard Worker * the link change request will fail with -NLE_OPNOTSUPP
1005*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_set_linkstate(struct rtnl_link_vf * vf_data,uint32_t vf_linkstate)1006*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_linkstate(struct rtnl_link_vf *vf_data,
1007*4dc78e53SAndroid Build Coastguard Worker uint32_t vf_linkstate) {
1008*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_linkstate = vf_linkstate;
1009*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_LINK_STATE;
1010*4dc78e53SAndroid Build Coastguard Worker
1011*4dc78e53SAndroid Build Coastguard Worker return;
1012*4dc78e53SAndroid Build Coastguard Worker }
1013*4dc78e53SAndroid Build Coastguard Worker
1014*4dc78e53SAndroid Build Coastguard Worker /**
1015*4dc78e53SAndroid Build Coastguard Worker * Get TX Rate Limit of SRIOV Virtual Function
1016*4dc78e53SAndroid Build Coastguard Worker * @arg vf_data SRIOV VF object
1017*4dc78e53SAndroid Build Coastguard Worker * @arg vf_rate Pointer to store VF rate limiting data
1018*4dc78e53SAndroid Build Coastguard Worker *
1019*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_num_vf()
1020*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_rate()
1021*4dc78e53SAndroid Build Coastguard Worker *
1022*4dc78e53SAndroid Build Coastguard Worker * When the older rate API has been implemented, the rate member of the struct
1023*4dc78e53SAndroid Build Coastguard Worker * will be set, and the api member will be set to RTNL_LINK_VF_API_OLD.
1024*4dc78e53SAndroid Build Coastguard Worker * When the newer rate API has been implemented, the max_tx_rate
1025*4dc78e53SAndroid Build Coastguard Worker * and/or the minx_tx_rate will be set, and the api member will be set to
1026*4dc78e53SAndroid Build Coastguard Worker * RTNL_LINK_VF_API_NEW.
1027*4dc78e53SAndroid Build Coastguard Worker *
1028*4dc78e53SAndroid Build Coastguard Worker * Old rate API supports only a maximum TX rate.
1029*4dc78e53SAndroid Build Coastguard Worker * ip link set dev vf 0 rate
1030*4dc78e53SAndroid Build Coastguard Worker * New rate API supports minumum and maximum TX rates.
1031*4dc78e53SAndroid Build Coastguard Worker * ip link set dev vf 0 min_tx_rate
1032*4dc78e53SAndroid Build Coastguard Worker * ip link set dev vf 0 max_tx_rate
1033*4dc78e53SAndroid Build Coastguard Worker *
1034*4dc78e53SAndroid Build Coastguard Worker * @return 0 if rate is present and vf_rate is set
1035*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1036*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_NOATTR if the VF rate is not set
1037*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_get_rate(struct rtnl_link_vf * vf_data,struct nl_vf_rate * vf_rate)1038*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_rate(struct rtnl_link_vf *vf_data,
1039*4dc78e53SAndroid Build Coastguard Worker struct nl_vf_rate *vf_rate)
1040*4dc78e53SAndroid Build Coastguard Worker {
1041*4dc78e53SAndroid Build Coastguard Worker int set = 0;
1042*4dc78e53SAndroid Build Coastguard Worker
1043*4dc78e53SAndroid Build Coastguard Worker if (!vf_data)
1044*4dc78e53SAndroid Build Coastguard Worker return -NLE_OBJ_NOTFOUND;
1045*4dc78e53SAndroid Build Coastguard Worker
1046*4dc78e53SAndroid Build Coastguard Worker vf_rate->api = RTNL_LINK_VF_RATE_API_UNSPEC;
1047*4dc78e53SAndroid Build Coastguard Worker vf_rate->rate = 0;
1048*4dc78e53SAndroid Build Coastguard Worker vf_rate->max_tx_rate = 0;
1049*4dc78e53SAndroid Build Coastguard Worker vf_rate->min_tx_rate = 0;
1050*4dc78e53SAndroid Build Coastguard Worker
1051*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_RATE_MAX) {
1052*4dc78e53SAndroid Build Coastguard Worker if (vf_data->vf_max_tx_rate) {
1053*4dc78e53SAndroid Build Coastguard Worker vf_rate->api = RTNL_LINK_VF_RATE_API_NEW;
1054*4dc78e53SAndroid Build Coastguard Worker vf_rate->max_tx_rate = vf_data->vf_max_tx_rate;
1055*4dc78e53SAndroid Build Coastguard Worker set = 1;
1056*4dc78e53SAndroid Build Coastguard Worker }
1057*4dc78e53SAndroid Build Coastguard Worker }
1058*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_RATE_MIN) {
1059*4dc78e53SAndroid Build Coastguard Worker if (vf_data->vf_min_tx_rate) {
1060*4dc78e53SAndroid Build Coastguard Worker vf_rate->api = RTNL_LINK_VF_RATE_API_NEW;
1061*4dc78e53SAndroid Build Coastguard Worker vf_rate->min_tx_rate = vf_data->vf_min_tx_rate;
1062*4dc78e53SAndroid Build Coastguard Worker set = 1;
1063*4dc78e53SAndroid Build Coastguard Worker }
1064*4dc78e53SAndroid Build Coastguard Worker }
1065*4dc78e53SAndroid Build Coastguard Worker if ((!set) && (vf_data->ce_mask & SRIOV_ATTR_TX_RATE)) {
1066*4dc78e53SAndroid Build Coastguard Worker if (vf_data->vf_rate) {
1067*4dc78e53SAndroid Build Coastguard Worker vf_rate->api = RTNL_LINK_VF_RATE_API_OLD;
1068*4dc78e53SAndroid Build Coastguard Worker vf_rate->rate = vf_data->vf_rate;
1069*4dc78e53SAndroid Build Coastguard Worker set = 1;
1070*4dc78e53SAndroid Build Coastguard Worker }
1071*4dc78e53SAndroid Build Coastguard Worker }
1072*4dc78e53SAndroid Build Coastguard Worker
1073*4dc78e53SAndroid Build Coastguard Worker if (!set)
1074*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOATTR;
1075*4dc78e53SAndroid Build Coastguard Worker
1076*4dc78e53SAndroid Build Coastguard Worker return 0;
1077*4dc78e53SAndroid Build Coastguard Worker }
1078*4dc78e53SAndroid Build Coastguard Worker
1079*4dc78e53SAndroid Build Coastguard Worker /**
1080*4dc78e53SAndroid Build Coastguard Worker * Set TX Rate Limit of SRIOV Virtual Function object
1081*4dc78e53SAndroid Build Coastguard Worker * @param vf_data SRIOV VF object
1082*4dc78e53SAndroid Build Coastguard Worker * @param vf_rate Rate limiting structure
1083*4dc78e53SAndroid Build Coastguard Worker *
1084*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_get_rate()
1085*4dc78e53SAndroid Build Coastguard Worker *
1086*4dc78e53SAndroid Build Coastguard Worker * When setting the rate, the API level must be specificed.
1087*4dc78e53SAndroid Build Coastguard Worker * Valid API levels:
1088*4dc78e53SAndroid Build Coastguard Worker * RTNL_LINK_VF_RATE_API_NEW
1089*4dc78e53SAndroid Build Coastguard Worker * RTNL_LINK_VF_RATE_API_OLD
1090*4dc78e53SAndroid Build Coastguard Worker *
1091*4dc78e53SAndroid Build Coastguard Worker * When using the new API, if either the min_tx_rate or
1092*4dc78e53SAndroid Build Coastguard Worker * max_tx_rate has been set, and the other is being changed,
1093*4dc78e53SAndroid Build Coastguard Worker * you must specify the currently set values to preserve
1094*4dc78e53SAndroid Build Coastguard Worker * them. If this is not done, that setting will be disabled.
1095*4dc78e53SAndroid Build Coastguard Worker *
1096*4dc78e53SAndroid Build Coastguard Worker * Old rate API supports only a maximum TX rate.
1097*4dc78e53SAndroid Build Coastguard Worker * ip link set dev vf 0 rate
1098*4dc78e53SAndroid Build Coastguard Worker * New rate API supports minumum and maximum TX rates.
1099*4dc78e53SAndroid Build Coastguard Worker * ip link set dev vf 0 min_tx_rate
1100*4dc78e53SAndroid Build Coastguard Worker * ip link set dev vf 0 max_tx_rate
1101*4dc78e53SAndroid Build Coastguard Worker *
1102*4dc78e53SAndroid Build Coastguard Worker * Not all hardware supports min_tx_rate.
1103*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_set_rate(struct rtnl_link_vf * vf_data,struct nl_vf_rate * vf_rate)1104*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_rate(struct rtnl_link_vf *vf_data,
1105*4dc78e53SAndroid Build Coastguard Worker struct nl_vf_rate *vf_rate) {
1106*4dc78e53SAndroid Build Coastguard Worker if (vf_rate->api == RTNL_LINK_VF_RATE_API_OLD) {
1107*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_rate = vf_rate->rate;
1108*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_TX_RATE;
1109*4dc78e53SAndroid Build Coastguard Worker } else if (vf_rate->api == RTNL_LINK_VF_RATE_API_NEW) {
1110*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_max_tx_rate = vf_rate->max_tx_rate;
1111*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_RATE_MAX;
1112*4dc78e53SAndroid Build Coastguard Worker
1113*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_min_tx_rate = vf_rate->min_tx_rate;
1114*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_RATE_MIN;
1115*4dc78e53SAndroid Build Coastguard Worker }
1116*4dc78e53SAndroid Build Coastguard Worker
1117*4dc78e53SAndroid Build Coastguard Worker return;
1118*4dc78e53SAndroid Build Coastguard Worker }
1119*4dc78e53SAndroid Build Coastguard Worker
1120*4dc78e53SAndroid Build Coastguard Worker /**
1121*4dc78e53SAndroid Build Coastguard Worker * Get RSS Query EN value of SRIOV Virtual Function
1122*4dc78e53SAndroid Build Coastguard Worker * @arg vf_data SRIOV VF object
1123*4dc78e53SAndroid Build Coastguard Worker * @arg vf_rss_query_en Pointer to store VF RSS Query value
1124*4dc78e53SAndroid Build Coastguard Worker *
1125*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_num_vf()
1126*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_set_rss_query_en()
1127*4dc78e53SAndroid Build Coastguard Worker *
1128*4dc78e53SAndroid Build Coastguard Worker * @return 0 if rss_query_en is present and vf_rss_query_en is set
1129*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1130*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_NOATTR if the VF RSS Query EN value is not set
1131*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_get_rss_query_en(struct rtnl_link_vf * vf_data,uint32_t * vf_rss_query_en)1132*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_rss_query_en(struct rtnl_link_vf *vf_data,
1133*4dc78e53SAndroid Build Coastguard Worker uint32_t *vf_rss_query_en)
1134*4dc78e53SAndroid Build Coastguard Worker {
1135*4dc78e53SAndroid Build Coastguard Worker if (!vf_data)
1136*4dc78e53SAndroid Build Coastguard Worker return -NLE_OBJ_NOTFOUND;
1137*4dc78e53SAndroid Build Coastguard Worker
1138*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_RSS_QUERY_EN)
1139*4dc78e53SAndroid Build Coastguard Worker *vf_rss_query_en = vf_data->vf_rss_query_en;
1140*4dc78e53SAndroid Build Coastguard Worker else
1141*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOATTR;
1142*4dc78e53SAndroid Build Coastguard Worker
1143*4dc78e53SAndroid Build Coastguard Worker return 0;
1144*4dc78e53SAndroid Build Coastguard Worker }
1145*4dc78e53SAndroid Build Coastguard Worker
1146*4dc78e53SAndroid Build Coastguard Worker /**
1147*4dc78e53SAndroid Build Coastguard Worker * Set RSS configuration querying of SRIOV Virtual Function Object
1148*4dc78e53SAndroid Build Coastguard Worker * @arg vf_data SRIOV VF object
1149*4dc78e53SAndroid Build Coastguard Worker * @arg vf_rss_query_en RSS Query value
1150*4dc78e53SAndroid Build Coastguard Worker *
1151*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_get_rss_query_en()
1152*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_set_rss_query_en(struct rtnl_link_vf * vf_data,uint32_t vf_rss_query_en)1153*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_rss_query_en(struct rtnl_link_vf *vf_data,
1154*4dc78e53SAndroid Build Coastguard Worker uint32_t vf_rss_query_en) {
1155*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_rss_query_en = vf_rss_query_en;
1156*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_RSS_QUERY_EN;
1157*4dc78e53SAndroid Build Coastguard Worker
1158*4dc78e53SAndroid Build Coastguard Worker return;
1159*4dc78e53SAndroid Build Coastguard Worker }
1160*4dc78e53SAndroid Build Coastguard Worker
1161*4dc78e53SAndroid Build Coastguard Worker /**
1162*4dc78e53SAndroid Build Coastguard Worker * Get spoof checking value of SRIOV Virtual Function
1163*4dc78e53SAndroid Build Coastguard Worker * @arg vf_data SRIOV VF object
1164*4dc78e53SAndroid Build Coastguard Worker * @arg vf_spoofchk Pointer to store VF spoofchk value
1165*4dc78e53SAndroid Build Coastguard Worker *
1166*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_num_vf()
1167*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_spoofchk()
1168*4dc78e53SAndroid Build Coastguard Worker *
1169*4dc78e53SAndroid Build Coastguard Worker * @return 0 if spoofchk is present and vf_spoofchk is set
1170*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1171*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_NOATTR if the VF spoofcheck is not set
1172*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_get_spoofchk(struct rtnl_link_vf * vf_data,uint32_t * vf_spoofchk)1173*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_spoofchk(struct rtnl_link_vf *vf_data,
1174*4dc78e53SAndroid Build Coastguard Worker uint32_t *vf_spoofchk)
1175*4dc78e53SAndroid Build Coastguard Worker {
1176*4dc78e53SAndroid Build Coastguard Worker if (!vf_data)
1177*4dc78e53SAndroid Build Coastguard Worker return -NLE_OBJ_NOTFOUND;
1178*4dc78e53SAndroid Build Coastguard Worker
1179*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_SPOOFCHK)
1180*4dc78e53SAndroid Build Coastguard Worker *vf_spoofchk = vf_data->vf_spoofchk;
1181*4dc78e53SAndroid Build Coastguard Worker else
1182*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOATTR;
1183*4dc78e53SAndroid Build Coastguard Worker
1184*4dc78e53SAndroid Build Coastguard Worker return 0;
1185*4dc78e53SAndroid Build Coastguard Worker }
1186*4dc78e53SAndroid Build Coastguard Worker
1187*4dc78e53SAndroid Build Coastguard Worker /**
1188*4dc78e53SAndroid Build Coastguard Worker * Set spoof checking value of SRIOV Virtual Function Object
1189*4dc78e53SAndroid Build Coastguard Worker * @param vf_data
1190*4dc78e53SAndroid Build Coastguard Worker * @param vf_spoofchk
1191*4dc78e53SAndroid Build Coastguard Worker *
1192*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_get_spoofchk()
1193*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_set_spoofchk(struct rtnl_link_vf * vf_data,uint32_t vf_spoofchk)1194*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_spoofchk(struct rtnl_link_vf *vf_data,
1195*4dc78e53SAndroid Build Coastguard Worker uint32_t vf_spoofchk) {
1196*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_spoofchk = vf_spoofchk;
1197*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_SPOOFCHK;
1198*4dc78e53SAndroid Build Coastguard Worker
1199*4dc78e53SAndroid Build Coastguard Worker return;
1200*4dc78e53SAndroid Build Coastguard Worker }
1201*4dc78e53SAndroid Build Coastguard Worker
1202*4dc78e53SAndroid Build Coastguard Worker /**
1203*4dc78e53SAndroid Build Coastguard Worker * Get value of stat counter for SRIOV Virtual Function
1204*4dc78e53SAndroid Build Coastguard Worker * @arg vf_data SRIOV VF object
1205*4dc78e53SAndroid Build Coastguard Worker * @arg stat Identifier of statistical counter
1206*4dc78e53SAndroid Build Coastguard Worker * @arg vf_stat Pointer to store VF stat value in
1207*4dc78e53SAndroid Build Coastguard Worker *
1208*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_num_vf()
1209*4dc78e53SAndroid Build Coastguard Worker *
1210*4dc78e53SAndroid Build Coastguard Worker * @return 0 if stat is present and vf_stat is set
1211*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1212*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_NOATTR if the VF stat is not set
1213*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_get_stat(struct rtnl_link_vf * vf_data,rtnl_link_vf_stats_t stat,uint64_t * vf_stat)1214*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_stat(struct rtnl_link_vf *vf_data,
1215*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_stats_t stat, uint64_t *vf_stat)
1216*4dc78e53SAndroid Build Coastguard Worker {
1217*4dc78e53SAndroid Build Coastguard Worker if (!vf_data)
1218*4dc78e53SAndroid Build Coastguard Worker return -NLE_OBJ_NOTFOUND;
1219*4dc78e53SAndroid Build Coastguard Worker
1220*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_STATS)
1221*4dc78e53SAndroid Build Coastguard Worker *vf_stat = vf_data->vf_stats[stat];
1222*4dc78e53SAndroid Build Coastguard Worker else
1223*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOATTR;
1224*4dc78e53SAndroid Build Coastguard Worker
1225*4dc78e53SAndroid Build Coastguard Worker return 0;
1226*4dc78e53SAndroid Build Coastguard Worker }
1227*4dc78e53SAndroid Build Coastguard Worker
1228*4dc78e53SAndroid Build Coastguard Worker /**
1229*4dc78e53SAndroid Build Coastguard Worker * Get trust setting of SRIOV Virtual Function
1230*4dc78e53SAndroid Build Coastguard Worker * @arg vf_data SRIOV VF object
1231*4dc78e53SAndroid Build Coastguard Worker * @arg vf_trust Pointer to store VF trust value
1232*4dc78e53SAndroid Build Coastguard Worker *
1233*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_num_vf()
1234*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_trust()
1235*4dc78e53SAndroid Build Coastguard Worker *
1236*4dc78e53SAndroid Build Coastguard Worker * @return 0 if trust is present and vf_trust is set
1237*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1238*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_NOATTR if the VF trust setting is not set
1239*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_get_trust(struct rtnl_link_vf * vf_data,uint32_t * vf_trust)1240*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_trust(struct rtnl_link_vf *vf_data, uint32_t *vf_trust)
1241*4dc78e53SAndroid Build Coastguard Worker {
1242*4dc78e53SAndroid Build Coastguard Worker if (!vf_data)
1243*4dc78e53SAndroid Build Coastguard Worker return -NLE_OBJ_NOTFOUND;
1244*4dc78e53SAndroid Build Coastguard Worker
1245*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_TRUST)
1246*4dc78e53SAndroid Build Coastguard Worker *vf_trust = vf_data->vf_trust;
1247*4dc78e53SAndroid Build Coastguard Worker else
1248*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOATTR;
1249*4dc78e53SAndroid Build Coastguard Worker
1250*4dc78e53SAndroid Build Coastguard Worker return 0;
1251*4dc78e53SAndroid Build Coastguard Worker }
1252*4dc78e53SAndroid Build Coastguard Worker
1253*4dc78e53SAndroid Build Coastguard Worker /**
1254*4dc78e53SAndroid Build Coastguard Worker * Set user trust setting on SRIOV Virtual Function Object
1255*4dc78e53SAndroid Build Coastguard Worker * @param vf_data
1256*4dc78e53SAndroid Build Coastguard Worker * @param vf_trust
1257*4dc78e53SAndroid Build Coastguard Worker *
1258*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_get_trust()
1259*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_set_trust(struct rtnl_link_vf * vf_data,uint32_t vf_trust)1260*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_trust(struct rtnl_link_vf *vf_data, uint32_t vf_trust) {
1261*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_trust = vf_trust;
1262*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_TRUST;
1263*4dc78e53SAndroid Build Coastguard Worker
1264*4dc78e53SAndroid Build Coastguard Worker return;
1265*4dc78e53SAndroid Build Coastguard Worker }
1266*4dc78e53SAndroid Build Coastguard Worker
1267*4dc78e53SAndroid Build Coastguard Worker /**
1268*4dc78e53SAndroid Build Coastguard Worker * Get an array of VLANS on SRIOV Virtual Function
1269*4dc78e53SAndroid Build Coastguard Worker * @arg vf_data SRIOV VF object
1270*4dc78e53SAndroid Build Coastguard Worker * @arg vf_vlans Pointer to nl_vf_vlans_t struct to store vlan info.
1271*4dc78e53SAndroid Build Coastguard Worker *
1272*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_num_vf()
1273*4dc78e53SAndroid Build Coastguard Worker *
1274*4dc78e53SAndroid Build Coastguard Worker * The SRIOV VF VLANs object must be returned to the SRIOV VF object with
1275*4dc78e53SAndroid Build Coastguard Worker * rtnl_link_vf_vlans_put() when operations are done to prevent memory leaks.
1276*4dc78e53SAndroid Build Coastguard Worker *
1277*4dc78e53SAndroid Build Coastguard Worker * @copydoc pointer_lifetime_warning
1278*4dc78e53SAndroid Build Coastguard Worker * @return 0 if VLAN info is present and vf_vlans is set
1279*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1280*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_NOATTR if the VF vlans is not set
1281*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_get_vlans(struct rtnl_link_vf * vf_data,nl_vf_vlans_t ** vf_vlans)1282*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_get_vlans(struct rtnl_link_vf *vf_data,
1283*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlans_t **vf_vlans) {
1284*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlans_t *vf;
1285*4dc78e53SAndroid Build Coastguard Worker
1286*4dc78e53SAndroid Build Coastguard Worker if (!vf_data)
1287*4dc78e53SAndroid Build Coastguard Worker return -NLE_OBJ_NOTFOUND;
1288*4dc78e53SAndroid Build Coastguard Worker
1289*4dc78e53SAndroid Build Coastguard Worker if (vf_data->ce_mask & SRIOV_ATTR_VLAN) {
1290*4dc78e53SAndroid Build Coastguard Worker vf = vf_data->vf_vlans;
1291*4dc78e53SAndroid Build Coastguard Worker vf->ce_refcnt++;
1292*4dc78e53SAndroid Build Coastguard Worker *vf_vlans = vf;
1293*4dc78e53SAndroid Build Coastguard Worker } else
1294*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOATTR;
1295*4dc78e53SAndroid Build Coastguard Worker
1296*4dc78e53SAndroid Build Coastguard Worker return 0;
1297*4dc78e53SAndroid Build Coastguard Worker }
1298*4dc78e53SAndroid Build Coastguard Worker
1299*4dc78e53SAndroid Build Coastguard Worker /**
1300*4dc78e53SAndroid Build Coastguard Worker * Add a SRIOV VF VLANs object to the SRIOV Virtual Function Object
1301*4dc78e53SAndroid Build Coastguard Worker * @param vf_data SRIOV VF object
1302*4dc78e53SAndroid Build Coastguard Worker * @param vf_vlans SRIOV VF VLANs object
1303*4dc78e53SAndroid Build Coastguard Worker *
1304*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_get_vlans()
1305*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_vf_vlan_alloc()
1306*4dc78e53SAndroid Build Coastguard Worker *
1307*4dc78e53SAndroid Build Coastguard Worker * This function assigns ownership of the SRIOV VF object \p vf_vlans
1308*4dc78e53SAndroid Build Coastguard Worker * to the SRIOV Virtual Function object \p vf_data. Do not use
1309*4dc78e53SAndroid Build Coastguard Worker * rtnl_link_vf_vlan_put() on \p vf_vlans after this.
1310*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_set_vlans(struct rtnl_link_vf * vf_data,nl_vf_vlans_t * vf_vlans)1311*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_set_vlans(struct rtnl_link_vf *vf_data,
1312*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlans_t *vf_vlans) {
1313*4dc78e53SAndroid Build Coastguard Worker if (!vf_data||!vf_vlans)
1314*4dc78e53SAndroid Build Coastguard Worker return;
1315*4dc78e53SAndroid Build Coastguard Worker
1316*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_vlans = vf_vlans;
1317*4dc78e53SAndroid Build Coastguard Worker vf_data->vf_vlans->ce_refcnt++;
1318*4dc78e53SAndroid Build Coastguard Worker vf_data->ce_mask |= SRIOV_ATTR_VLAN;
1319*4dc78e53SAndroid Build Coastguard Worker
1320*4dc78e53SAndroid Build Coastguard Worker return;
1321*4dc78e53SAndroid Build Coastguard Worker }
1322*4dc78e53SAndroid Build Coastguard Worker
1323*4dc78e53SAndroid Build Coastguard Worker /**
1324*4dc78e53SAndroid Build Coastguard Worker * Allocate a SRIOV VF VLAN object
1325*4dc78e53SAndroid Build Coastguard Worker * @param vf_vlans Pointer to store VLAN object at
1326*4dc78e53SAndroid Build Coastguard Worker * @param vlan_count Number of VLANs that will be stored in VLAN object
1327*4dc78e53SAndroid Build Coastguard Worker *
1328*4dc78e53SAndroid Build Coastguard Worker * The SRIOV VF VLANs object must be returned to the sRIOV VF object with
1329*4dc78e53SAndroid Build Coastguard Worker * rtnl_link_vf_vlan_put() when operations are done to prevent memory leaks.
1330*4dc78e53SAndroid Build Coastguard Worker *
1331*4dc78e53SAndroid Build Coastguard Worker * @return 0 if VLAN object is created and vf_vlans is set.
1332*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_NOMEM if object could not be allocated.
1333*4dc78e53SAndroid Build Coastguard Worker * @return -NLE_INVAL if vlan_count is more than supported by SRIOV VF
1334*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_vlan_alloc(nl_vf_vlans_t ** vf_vlans,int vlan_count)1335*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_vlan_alloc(nl_vf_vlans_t **vf_vlans, int vlan_count) {
1336*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlans_t *vlans;
1337*4dc78e53SAndroid Build Coastguard Worker nl_vf_vlan_info_t *vlan_info;
1338*4dc78e53SAndroid Build Coastguard Worker
1339*4dc78e53SAndroid Build Coastguard Worker if (vlan_count > MAX_VLAN_LIST_LEN)
1340*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
1341*4dc78e53SAndroid Build Coastguard Worker
1342*4dc78e53SAndroid Build Coastguard Worker vlans = calloc(1, sizeof(*vlans));
1343*4dc78e53SAndroid Build Coastguard Worker if (!vlans)
1344*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
1345*4dc78e53SAndroid Build Coastguard Worker
1346*4dc78e53SAndroid Build Coastguard Worker vlan_info = calloc(vlan_count+1, sizeof(*vlan_info));
1347*4dc78e53SAndroid Build Coastguard Worker if (!vlan_info) {
1348*4dc78e53SAndroid Build Coastguard Worker free(vlans);
1349*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
1350*4dc78e53SAndroid Build Coastguard Worker }
1351*4dc78e53SAndroid Build Coastguard Worker
1352*4dc78e53SAndroid Build Coastguard Worker NL_DBG(4, "Allocated new SRIOV VF VLANs object %p\n", vlans);
1353*4dc78e53SAndroid Build Coastguard Worker
1354*4dc78e53SAndroid Build Coastguard Worker vlans->ce_refcnt = 1;
1355*4dc78e53SAndroid Build Coastguard Worker vlans->size = vlan_count;
1356*4dc78e53SAndroid Build Coastguard Worker vlans->vlans = vlan_info;
1357*4dc78e53SAndroid Build Coastguard Worker *vf_vlans = vlans;
1358*4dc78e53SAndroid Build Coastguard Worker
1359*4dc78e53SAndroid Build Coastguard Worker return 0;
1360*4dc78e53SAndroid Build Coastguard Worker }
1361*4dc78e53SAndroid Build Coastguard Worker
1362*4dc78e53SAndroid Build Coastguard Worker /**
1363*4dc78e53SAndroid Build Coastguard Worker * Free an allocated SRIOV VF VLANs object
1364*4dc78e53SAndroid Build Coastguard Worker * @param vf_vlans SRIOV VF VLANs object
1365*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_vlan_free(nl_vf_vlans_t * vf_vlans)1366*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_vlan_free(nl_vf_vlans_t *vf_vlans) {
1367*4dc78e53SAndroid Build Coastguard Worker if (!vf_vlans)
1368*4dc78e53SAndroid Build Coastguard Worker return;
1369*4dc78e53SAndroid Build Coastguard Worker
1370*4dc78e53SAndroid Build Coastguard Worker if (vf_vlans->ce_refcnt > 0)
1371*4dc78e53SAndroid Build Coastguard Worker NL_DBG(1, "Warning: Freeing SRIOV VF VLANs object in use...\n");
1372*4dc78e53SAndroid Build Coastguard Worker
1373*4dc78e53SAndroid Build Coastguard Worker NL_DBG(4, "Freed SRIOV VF object %p\n", vf_vlans);
1374*4dc78e53SAndroid Build Coastguard Worker free(vf_vlans->vlans);
1375*4dc78e53SAndroid Build Coastguard Worker free(vf_vlans);
1376*4dc78e53SAndroid Build Coastguard Worker
1377*4dc78e53SAndroid Build Coastguard Worker return;
1378*4dc78e53SAndroid Build Coastguard Worker }
1379*4dc78e53SAndroid Build Coastguard Worker
1380*4dc78e53SAndroid Build Coastguard Worker /**
1381*4dc78e53SAndroid Build Coastguard Worker * Return SRIOV VF VLANs object to the owning SRIOV VF object.
1382*4dc78e53SAndroid Build Coastguard Worker * @param vf_vlans SRIOV VF VLANs object
1383*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_vlan_put(nl_vf_vlans_t * vf_vlans)1384*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_vf_vlan_put(nl_vf_vlans_t *vf_vlans) {
1385*4dc78e53SAndroid Build Coastguard Worker if (!vf_vlans)
1386*4dc78e53SAndroid Build Coastguard Worker return;
1387*4dc78e53SAndroid Build Coastguard Worker
1388*4dc78e53SAndroid Build Coastguard Worker vf_vlans->ce_refcnt--;
1389*4dc78e53SAndroid Build Coastguard Worker NL_DBG(4, "Returned SRIOV VF VLANs object reference %p, %i remaining\n",
1390*4dc78e53SAndroid Build Coastguard Worker vf_vlans, vf_vlans->ce_refcnt);
1391*4dc78e53SAndroid Build Coastguard Worker
1392*4dc78e53SAndroid Build Coastguard Worker if (vf_vlans->ce_refcnt < 0)
1393*4dc78e53SAndroid Build Coastguard Worker BUG();
1394*4dc78e53SAndroid Build Coastguard Worker
1395*4dc78e53SAndroid Build Coastguard Worker if (vf_vlans->ce_refcnt <= 0)
1396*4dc78e53SAndroid Build Coastguard Worker rtnl_link_vf_vlan_free(vf_vlans);
1397*4dc78e53SAndroid Build Coastguard Worker
1398*4dc78e53SAndroid Build Coastguard Worker return;
1399*4dc78e53SAndroid Build Coastguard Worker }
1400*4dc78e53SAndroid Build Coastguard Worker
1401*4dc78e53SAndroid Build Coastguard Worker /** @} */
1402*4dc78e53SAndroid Build Coastguard Worker
1403*4dc78e53SAndroid Build Coastguard Worker /**
1404*4dc78e53SAndroid Build Coastguard Worker * @name Utilities
1405*4dc78e53SAndroid Build Coastguard Worker * @{
1406*4dc78e53SAndroid Build Coastguard Worker */
1407*4dc78e53SAndroid Build Coastguard Worker
1408*4dc78e53SAndroid Build Coastguard Worker static const struct trans_tbl vf_link_states[] = {
1409*4dc78e53SAndroid Build Coastguard Worker __ADD(IFLA_VF_LINK_STATE_AUTO, autodetect),
1410*4dc78e53SAndroid Build Coastguard Worker __ADD(IFLA_VF_LINK_STATE_ENABLE, up),
1411*4dc78e53SAndroid Build Coastguard Worker __ADD(IFLA_VF_LINK_STATE_DISABLE, down),
1412*4dc78e53SAndroid Build Coastguard Worker };
1413*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_vf_linkstate2str(uint32_t ls,char * buf,size_t len)1414*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_vf_linkstate2str(uint32_t ls, char *buf, size_t len)
1415*4dc78e53SAndroid Build Coastguard Worker {
1416*4dc78e53SAndroid Build Coastguard Worker return __type2str(ls, buf, len, vf_link_states,
1417*4dc78e53SAndroid Build Coastguard Worker ARRAY_SIZE(vf_link_states));
1418*4dc78e53SAndroid Build Coastguard Worker }
1419*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_vf_str2linkstate(const char * name)1420*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_str2linkstate(const char *name)
1421*4dc78e53SAndroid Build Coastguard Worker {
1422*4dc78e53SAndroid Build Coastguard Worker return __str2type(name, vf_link_states, ARRAY_SIZE(vf_link_states));
1423*4dc78e53SAndroid Build Coastguard Worker }
1424*4dc78e53SAndroid Build Coastguard Worker
1425*4dc78e53SAndroid Build Coastguard Worker static const struct trans_tbl vf_vlan_proto[] = {
1426*4dc78e53SAndroid Build Coastguard Worker __ADD(ETH_P_8021Q, 8021Q),
1427*4dc78e53SAndroid Build Coastguard Worker __ADD(ETH_P_8021AD, 8021AD),
1428*4dc78e53SAndroid Build Coastguard Worker };
1429*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_vf_vlanproto2str(uint16_t proto,char * buf,size_t len)1430*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_vf_vlanproto2str(uint16_t proto, char *buf, size_t len)
1431*4dc78e53SAndroid Build Coastguard Worker {
1432*4dc78e53SAndroid Build Coastguard Worker return __type2str(proto, buf, len, vf_vlan_proto,
1433*4dc78e53SAndroid Build Coastguard Worker ARRAY_SIZE(vf_vlan_proto));
1434*4dc78e53SAndroid Build Coastguard Worker }
1435*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_vf_str2vlanproto(const char * name)1436*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_str2vlanproto(const char *name)
1437*4dc78e53SAndroid Build Coastguard Worker {
1438*4dc78e53SAndroid Build Coastguard Worker return __str2type(name, vf_vlan_proto, ARRAY_SIZE(vf_vlan_proto));
1439*4dc78e53SAndroid Build Coastguard Worker }
1440*4dc78e53SAndroid Build Coastguard Worker
1441*4dc78e53SAndroid Build Coastguard Worker /* Return a guid from a format checked string.
1442*4dc78e53SAndroid Build Coastguard Worker * Format string must be xx:xx:xx:xx:xx:xx:xx:xx where XX can be an
1443*4dc78e53SAndroid Build Coastguard Worker * arbitrary hex digit
1444*4dc78e53SAndroid Build Coastguard Worker *
1445*4dc78e53SAndroid Build Coastguard Worker * Function modified from original at iproute2/lib/utils.c:get_guid()
1446*4dc78e53SAndroid Build Coastguard Worker * Original by Eli Cohen <[email protected]>.
1447*4dc78e53SAndroid Build Coastguard Worker * iproute2 git commit d91fb3f4c7e4dba806541bdc90b1fb60a3581541
1448*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_vf_str2guid(uint64_t * guid,const char * guid_s)1449*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_vf_str2guid(uint64_t *guid, const char *guid_s) {
1450*4dc78e53SAndroid Build Coastguard Worker unsigned long int tmp;
1451*4dc78e53SAndroid Build Coastguard Worker char *endptr;
1452*4dc78e53SAndroid Build Coastguard Worker int i;
1453*4dc78e53SAndroid Build Coastguard Worker
1454*4dc78e53SAndroid Build Coastguard Worker if (strlen(guid_s) != RTNL_VF_GUID_STR_LEN)
1455*4dc78e53SAndroid Build Coastguard Worker return -1;
1456*4dc78e53SAndroid Build Coastguard Worker
1457*4dc78e53SAndroid Build Coastguard Worker for (i = 0; i < 7; i++) {
1458*4dc78e53SAndroid Build Coastguard Worker if (guid_s[2 + i * 3] != ':')
1459*4dc78e53SAndroid Build Coastguard Worker return -1;
1460*4dc78e53SAndroid Build Coastguard Worker }
1461*4dc78e53SAndroid Build Coastguard Worker
1462*4dc78e53SAndroid Build Coastguard Worker *guid = 0;
1463*4dc78e53SAndroid Build Coastguard Worker for (i = 0; i < 8; i++) {
1464*4dc78e53SAndroid Build Coastguard Worker tmp = strtoul(guid_s + i * 3, &endptr, 16);
1465*4dc78e53SAndroid Build Coastguard Worker if (endptr != guid_s + i * 3 + 2)
1466*4dc78e53SAndroid Build Coastguard Worker return -1;
1467*4dc78e53SAndroid Build Coastguard Worker
1468*4dc78e53SAndroid Build Coastguard Worker if (tmp > 255)
1469*4dc78e53SAndroid Build Coastguard Worker return -1;
1470*4dc78e53SAndroid Build Coastguard Worker
1471*4dc78e53SAndroid Build Coastguard Worker *guid |= tmp << (56 - 8 * i);
1472*4dc78e53SAndroid Build Coastguard Worker }
1473*4dc78e53SAndroid Build Coastguard Worker
1474*4dc78e53SAndroid Build Coastguard Worker return 0;
1475*4dc78e53SAndroid Build Coastguard Worker }
1476*4dc78e53SAndroid Build Coastguard Worker
1477*4dc78e53SAndroid Build Coastguard Worker /** @} */
1478*4dc78e53SAndroid Build Coastguard Worker
1479*4dc78e53SAndroid Build Coastguard Worker /** @} */
1480