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