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