libnl  3.2.29
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  vf_vlan_info[len] = nla_data(nla_list);
572  list_len++;
573  }
574 
575  err = rtnl_link_vf_vlan_info(list_len, vf_vlan_info,
576  &vf_vlans);
577  if (err < 0)
578  return err;
579 
580  vf_data->vf_vlans = vf_vlans;
581  vf_data->ce_mask |= SRIOV_ATTR_VLAN;
582  } else if (t[IFLA_VF_VLAN]) {
583  vf_vlan = nla_data(t[IFLA_VF_VLAN]);
584 
585  if (vf_vlan->vlan) {
586  err = rtnl_link_vf_vlan_alloc(&vf_vlans, 1);
587  if (err < 0)
588  return err;
589 
590  vf_vlans->vlans[0].vf_vlan = vf_vlan->vlan;
591  vf_vlans->vlans[0].vf_vlan_qos = vf_vlan->qos;
592  vf_vlans->vlans[0].vf_vlan_proto = ETH_P_8021Q;
593 
594  vf_data->vf_vlans = vf_vlans;
595  vf_data->ce_mask |= SRIOV_ATTR_VLAN;
596  }
597  }
598 
599  if (t[IFLA_VF_TX_RATE]) {
600  vf_tx_rate = nla_data(t[IFLA_VF_TX_RATE]);
601 
602  if (vf_tx_rate->rate) {
603  vf_data->vf_rate = vf_tx_rate->rate;
604  vf_data->ce_mask |= SRIOV_ATTR_TX_RATE;
605  }
606  }
607 
608  if (t[IFLA_VF_SPOOFCHK]) {
609  vf_spoofchk = nla_data(t[IFLA_VF_SPOOFCHK]);
610 
611  if (vf_spoofchk->setting != -1) {
612  vf_data->vf_spoofchk = vf_spoofchk->setting ? 1 : 0;
613  vf_data->ce_mask |= SRIOV_ATTR_SPOOFCHK;
614  }
615  }
616 
617  if (t[IFLA_VF_LINK_STATE]) {
618  vf_linkstate = nla_data(t[IFLA_VF_LINK_STATE]);
619 
620  vf_data->vf_linkstate = vf_linkstate->link_state;
621  vf_data->ce_mask |= SRIOV_ATTR_LINK_STATE;
622  }
623 
624  if (t[IFLA_VF_RATE]) {
625  vf_rate = nla_data(t[IFLA_VF_RATE]);
626 
627  if (vf_rate->max_tx_rate) {
628  vf_data->vf_max_tx_rate = vf_rate->max_tx_rate;
629  vf_data->ce_mask |= SRIOV_ATTR_RATE_MAX;
630  }
631  if (vf_rate->min_tx_rate) {
632  vf_data->vf_min_tx_rate = vf_rate->min_tx_rate;
633  vf_data->ce_mask |= SRIOV_ATTR_RATE_MIN;
634  }
635  }
636 
637  if (t[IFLA_VF_RSS_QUERY_EN]) {
638  vf_rss_query = nla_data(t[IFLA_VF_RSS_QUERY_EN]);
639 
640  if (vf_rss_query->setting != -1) {
641  vf_data->vf_rss_query_en = vf_rss_query->setting ? 1 : 0;
642  vf_data->ce_mask |= SRIOV_ATTR_RSS_QUERY_EN;
643  }
644  }
645 
646  if (t[IFLA_VF_STATS]) {
647  err = nla_parse_nested(stb, IFLA_VF_STATS_MAX,
648  t[IFLA_VF_STATS],
649  sriov_stats_policy);
650  if (err < 0)
651  return err;
652 
653  SET_VF_STAT(link, cur, stb,
655  IFLA_VF_STATS_RX_PACKETS);
656  SET_VF_STAT(link, cur, stb,
658  IFLA_VF_STATS_TX_PACKETS);
659  SET_VF_STAT(link, cur, stb,
661  IFLA_VF_STATS_RX_BYTES);
662  SET_VF_STAT(link, cur, stb,
664  IFLA_VF_STATS_TX_BYTES);
665  SET_VF_STAT(link, cur, stb,
667  IFLA_VF_STATS_BROADCAST);
668  SET_VF_STAT(link, cur, stb,
670  IFLA_VF_STATS_MULTICAST);
671 
672  vf_data->ce_mask |= IFLA_VF_STATS;
673  }
674 
675  if (t[IFLA_VF_TRUST]) {
676  vf_trust = nla_data(t[IFLA_VF_TRUST]);
677 
678  if (vf_trust->setting != -1) {
679  vf_data->vf_trust = vf_trust->setting ? 1 : 0;
680  vf_data->ce_mask |= SRIOV_ATTR_TRUST;
681  }
682  }
683 
684  nl_list_add_head(&vf_data->vf_list, &vf_head->vf_list);
685  vf_head = vf_data;
686  }
687 
688  return 0;
689 }
690 
691 /**
692  * @name SR-IOV Sub-Object
693  * @{
694  */
695 
696 /**
697  * Add a SRIOV VF object to a link object
698  * @param link Link object to add to
699  * @param vf_data SRIOV VF object to add
700  *
701  * @return 0 if SRIOV VF object added successfully
702  * @return -NLE_OBJ_NOTFOUND if \p link or \p vf_data not provided
703  * @return -NLE_NOMEM if out of memory
704  */
705 int rtnl_link_vf_add(struct rtnl_link *link, struct rtnl_link_vf *vf_data) {
706  struct rtnl_link_vf *vf_head = NULL;
707 
708  if (!link||!vf_data)
709  return -NLE_OBJ_NOTFOUND;
710 
711  if (!link->l_vf_list) {
712  link->l_vf_list = rtnl_link_vf_alloc();
713  if (!link->l_vf_list)
714  return -NLE_NOMEM;
715  }
716 
717  vf_head = vf_data;
718  vf_head->ce_refcnt++;
719 
720  vf_head = link->l_vf_list;
721  nl_list_add_head(&vf_data->vf_list, &vf_head->vf_list);
722  link->l_vf_list = vf_head;
723 
724  rtnl_link_set_vf_list(link);
725 
726  return 0;
727 }
728 
729 /**
730  * Allocate a new SRIOV VF object
731  *
732  * @return NULL if out of memory
733  * @return New VF Object
734  *
735  * @see rtnl_link_vf_put()
736  *
737  * The SRIOV VF object must be returned to the link object with
738  * rtnl_link_vf_put() when operations are done to prevent memory leaks.
739  */
741  struct rtnl_link_vf *vf;
742 
743  if (!(vf = calloc(1, sizeof(*vf))))
744  return NULL;
745 
746  NL_INIT_LIST_HEAD(&vf->vf_list);
747  vf->ce_refcnt = 1;
748 
749  NL_DBG(4, "Allocated new SRIOV VF object %p\n", vf);
750 
751  return vf;
752 }
753 
754 /**
755  * Free SRIOV VF object.
756  * @arg vf_data SRIOV VF data object
757  */
758 void rtnl_link_vf_free(struct rtnl_link_vf *vf_data) {
759  if (!vf_data)
760  return;
761 
762  if (vf_data->ce_refcnt > 0)
763  NL_DBG(1, "Warning: Freeing SRIOV VF object in use...\n");
764 
765  if (vf_data->ce_mask & SRIOV_ATTR_ADDR)
766  nl_addr_put(vf_data->vf_lladdr);
767  if (vf_data->ce_mask & SRIOV_ATTR_VLAN)
768  rtnl_link_vf_vlan_put(vf_data->vf_vlans);
769 
770  NL_DBG(4, "Freed SRIOV VF object %p\n", vf_data);
771  free(vf_data);
772 
773  return;
774 }
775 
776 /**
777  * Lookup SRIOV VF in link object by VF index.
778  *
779  * @return NULL if VF not found
780  * @return VF Object
781  *
782  * @see rtnl_link_vf_put()
783  *
784  * The SRIOV VF object must be returned to the link object with
785  * rtnl_link_vf_put() when operations are done to prevent memory leaks.
786  */
787 struct rtnl_link_vf *rtnl_link_vf_get(struct rtnl_link *link, uint32_t vf_num) {
788  struct rtnl_link_vf *list, *vf, *next, *ret = NULL;
789 
790  list = link->l_vf_list;
791  nl_list_for_each_entry_safe(vf, next, &list->vf_list, vf_list) {
792  if (vf->vf_index == vf_num) {
793  ret = vf;
794  break;
795  }
796  }
797 
798  if (ret) {
799  ret->ce_refcnt++;
800  NL_DBG(4, "New reference to SRIOV VF object %p, total %i\n",
801  ret, ret->ce_refcnt);
802  }
803 
804  return ret;
805 }
806 
807 /**
808  * Return SRIOV VF object to the owning link object.
809  * @arg vf_data SRIOV VF data object
810  *
811  * @see rtnl_link_vf_alloc()
812  * @see rtnl_link_vf_get()
813  */
814 void rtnl_link_vf_put(struct rtnl_link_vf *vf_data) {
815  if (!vf_data)
816  return;
817 
818  vf_data->ce_refcnt--;
819  NL_DBG(4, "Returned SRIOV VF object reference %p, %i remaining\n",
820  vf_data, vf_data->ce_refcnt);
821 
822  if (vf_data->ce_refcnt < 0)
823  BUG();
824 
825  if (vf_data->ce_refcnt <= 0)
826  rtnl_link_vf_free(vf_data);
827 
828  return;
829 }
830 
831 /**
832  * Get link layer address of SRIOV Virtual Function
833  * @arg vf_data SRIOV VF object
834  * @arg addr Pointer to store Link Layer address
835  *
836  * @see rtnl_link_get_num_vf()
837  * @see rtnl_link_vf_set_addr()
838  *
839  * @copydoc pointer_lifetime_warning
840  * @return 0 if addr is present and addr is set to pointer containing address
841  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
842  * @return -NLE_NOATTR if the link layer address is not set
843  */
844 int rtnl_link_vf_get_addr(struct rtnl_link_vf *vf_data, struct nl_addr **addr)
845 {
846  if (!vf_data)
847  return -NLE_OBJ_NOTFOUND;
848 
849  if (vf_data->ce_mask & SRIOV_ATTR_ADDR)
850  *addr = vf_data->vf_lladdr;
851  else
852  return -NLE_NOATTR;
853 
854  return 0;
855 }
856 
857 /**
858  * Set link layer address of SRIOV Virtual Function object
859  * @param vf_data SRIOV VF object
860  * @param addr New link layer address
861  *
862  * This function increments the reference counter of the address object
863  * and overwrites any existing link layer address previously assigned.
864  *
865  * @see rtnl_link_vf_get_addr()
866  */
867 void rtnl_link_vf_set_addr(struct rtnl_link_vf *vf_data, struct nl_addr *addr) {
868  if (vf_data->vf_lladdr)
869  nl_addr_put(vf_data->vf_lladdr);
870 
871  nl_addr_get(addr);
872  vf_data->vf_lladdr = addr;
873  vf_data->ce_mask |= SRIOV_ATTR_ADDR;
874 
875  return;
876 }
877 
878 /**
879  * Set the Infiniband node GUID for the SRIOV Virtual Function object
880  * @param vf_data SRIOV VF object
881  * @param guid node GUID
882  */
884  uint64_t guid) {
885  vf_data->vf_guid_node = guid;
886  vf_data->ce_mask |= SRIOV_ATTR_IB_NODE_GUID;
887 
888  return;
889 }
890 
891 /**
892  * Set the Infiniband port GUID for the SRIOV Virtual Function object
893  * @param vf_data SRIOV VF object
894  * @param guid port GUID
895  */
897  uint64_t guid) {
898  vf_data->vf_guid_port = guid;
899  vf_data->ce_mask |= SRIOV_ATTR_IB_PORT_GUID;
900 
901  return;
902 }
903 
904 /**
905  * Get index of SRIOV Virtual Function
906  * @arg vf_data SRIOV VF object
907  * @arg vf_index Pointer to store VF index
908  *
909  * @see rtnl_link_get_num_vf()
910  *
911  * @return 0 if index is present and vf_index is set
912  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
913  * @return -NLE_NOATTR if the VF index is not set
914  */
915 int rtnl_link_vf_get_index(struct rtnl_link_vf *vf_data, uint32_t *vf_index)
916 {
917  if (!vf_data)
918  return -NLE_OBJ_NOTFOUND;
919 
920  if (vf_data->ce_mask & SRIOV_ATTR_INDEX)
921  *vf_index = vf_data->vf_index;
922  else
923  return -NLE_NOATTR;
924 
925  return 0;
926 }
927 
928 /**
929  * Set index of SRIOV Virtual Function object
930  * @param vf_data SRIOV VF object
931  * @param vf_index Index value
932  *
933  * @see rtnl_link_vf_get_index()
934  */
935 void rtnl_link_vf_set_index(struct rtnl_link_vf *vf_data, uint32_t vf_index)
936 {
937  vf_data->vf_index = vf_index;
938  vf_data->ce_mask |= SRIOV_ATTR_INDEX;
939 
940  return;
941 }
942 
943 /**
944  * Get link state of SRIOV Virtual Function
945  * @arg vf_data SRIOV VF object
946  * @arg vf_linkstate Pointer to store VF link state
947  *
948  * @see rtnl_link_get_num_vf()
949  * @see rtnl_link_set_linkstate()
950  *
951  * @return 0 if link state is present and vf_linkstate is set
952  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
953  * @return -NLE_NOATTR if the VF link state is not set
954  */
956  uint32_t *vf_linkstate)
957 {
958  if (!vf_data)
959  return -NLE_OBJ_NOTFOUND;
960 
961  if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE)
962  *vf_linkstate = vf_data->vf_linkstate;
963  else
964  return -NLE_NOATTR;
965 
966  return 0;
967 }
968 
969 /**
970  * Set link state of SRIOV Virtual Function object
971  * @param vf_data SRIOV VF object
972  * @param vf_linkstate Link state value
973  *
974  * @see rtnl_link_get_linkstate()
975  *
976  * Not all hardware supports setting link state. If the feature is unsupported,
977  * the link change request will fail with -NLE_OPNOTSUPP
978  */
980  uint32_t vf_linkstate) {
981  vf_data->vf_linkstate = vf_linkstate;
982  vf_data->ce_mask |= SRIOV_ATTR_LINK_STATE;
983 
984  return;
985 }
986 
987 /**
988  * Get TX Rate Limit of SRIOV Virtual Function
989  * @arg vf_data SRIOV VF object
990  * @arg vf_rate Pointer to store VF rate limiting data
991  *
992  * @see rtnl_link_get_num_vf()
993  * @see rtnl_link_set_rate()
994  *
995  * When the older rate API has been implemented, the rate member of the struct
996  * will be set, and the api member will be set to RTNL_LINK_VF_API_OLD.
997  * When the newer rate API has been implemented, the max_tx_rate
998  * and/or the minx_tx_rate will be set, and the api member will be set to
999  * RTNL_LINK_VF_API_NEW.
1000  *
1001  * Old rate API supports only a maximum TX rate.
1002  * ip link set dev vf 0 rate
1003  * New rate API supports minumum and maximum TX rates.
1004  * ip link set dev vf 0 min_tx_rate
1005  * ip link set dev vf 0 max_tx_rate
1006  *
1007  * @return 0 if rate is present and vf_rate is set
1008  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1009  * @return -NLE_NOATTR if the VF rate is not set
1010  */
1012  struct nl_vf_rate *vf_rate)
1013 {
1014  int set = 0;
1015 
1016  if (!vf_data)
1017  return -NLE_OBJ_NOTFOUND;
1018 
1019  vf_rate->api = RTNL_LINK_VF_RATE_API_UNSPEC;
1020  vf_rate->rate = 0;
1021  vf_rate->max_tx_rate = 0;
1022  vf_rate->min_tx_rate = 0;
1023 
1024  if (vf_data->ce_mask & SRIOV_ATTR_RATE_MAX) {
1025  if (vf_data->vf_max_tx_rate) {
1026  vf_rate->api = RTNL_LINK_VF_RATE_API_NEW;
1027  vf_rate->max_tx_rate = vf_data->vf_max_tx_rate;
1028  set = 1;
1029  }
1030  }
1031  if (vf_data->ce_mask & SRIOV_ATTR_RATE_MIN) {
1032  if (vf_data->vf_min_tx_rate) {
1033  vf_rate->api = RTNL_LINK_VF_RATE_API_NEW;
1034  vf_rate->min_tx_rate = vf_data->vf_min_tx_rate;
1035  set = 1;
1036  }
1037  }
1038  if ((!set) && (vf_data->ce_mask & SRIOV_ATTR_TX_RATE)) {
1039  if (vf_data->vf_rate) {
1040  vf_rate->api = RTNL_LINK_VF_RATE_API_OLD;
1041  vf_rate->rate = vf_data->vf_rate;
1042  set = 1;
1043  }
1044  }
1045 
1046  if (!set)
1047  return -NLE_NOATTR;
1048 
1049  return 0;
1050 }
1051 
1052 /**
1053  * Set TX Rate Limit of SRIOV Virtual Function object
1054  * @param vf_data SRIOV VF object
1055  * @param vf_rate Rate limiting structure
1056  *
1057  * @see rtnl_link_vf_get_rate()
1058  *
1059  * When setting the rate, the API level must be specificed.
1060  * Valid API levels:
1061  * RTNL_LINK_VF_RATE_API_NEW
1062  * RTNL_LINK_VF_RATE_API_OLD
1063  *
1064  * When using the new API, if either the min_tx_rate or
1065  * max_tx_rate has been set, and the other is being changed,
1066  * you must specify the currently set values to preserve
1067  * them. If this is not done, that setting will be disabled.
1068  *
1069  * Old rate API supports only a maximum TX rate.
1070  * ip link set dev vf 0 rate
1071  * New rate API supports minumum and maximum TX rates.
1072  * ip link set dev vf 0 min_tx_rate
1073  * ip link set dev vf 0 max_tx_rate
1074  *
1075  * Not all hardware supports min_tx_rate.
1076  */
1078  struct nl_vf_rate *vf_rate) {
1079  if (vf_rate->api == RTNL_LINK_VF_RATE_API_OLD) {
1080  vf_data->vf_rate = vf_rate->rate;
1081  vf_data->ce_mask |= SRIOV_ATTR_TX_RATE;
1082  } else if (vf_rate->api == RTNL_LINK_VF_RATE_API_NEW) {
1083  vf_data->vf_max_tx_rate = vf_rate->max_tx_rate;
1084  vf_data->ce_mask |= SRIOV_ATTR_RATE_MAX;
1085 
1086  vf_data->vf_min_tx_rate = vf_rate->min_tx_rate;
1087  vf_data->ce_mask |= SRIOV_ATTR_RATE_MIN;
1088  }
1089 
1090  return;
1091 }
1092 
1093 /**
1094  * Get RSS Query EN value of SRIOV Virtual Function
1095  * @arg vf_data SRIOV VF object
1096  * @arg vf_rss_query_en Pointer to store VF RSS Query value
1097  *
1098  * @see rtnl_link_get_num_vf()
1099  * @see rtnl_link_vf_set_rss_query_en()
1100  *
1101  * @return 0 if rss_query_en is present and vf_rss_query_en is set
1102  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1103  * @return -NLE_NOATTR if the VF RSS Query EN value is not set
1104  */
1106  uint32_t *vf_rss_query_en)
1107 {
1108  if (!vf_data)
1109  return -NLE_OBJ_NOTFOUND;
1110 
1111  if (vf_data->ce_mask & SRIOV_ATTR_RSS_QUERY_EN)
1112  *vf_rss_query_en = vf_data->vf_rss_query_en;
1113  else
1114  return -NLE_NOATTR;
1115 
1116  return 0;
1117 }
1118 
1119 /**
1120  * Set RSS configuration querying of SRIOV Virtual Function Object
1121  * @arg vf_data SRIOV VF object
1122  * @arg vf_rss_query_en RSS Query value
1123  *
1124  * @see rtnl_link_vf_get_rss_query_en()
1125  */
1127  uint32_t vf_rss_query_en) {
1128  vf_data->vf_rss_query_en = vf_rss_query_en;
1129  vf_data->ce_mask |= SRIOV_ATTR_RSS_QUERY_EN;
1130 
1131  return;
1132 }
1133 
1134 /**
1135  * Get spoof checking value of SRIOV Virtual Function
1136  * @arg vf_data SRIOV VF object
1137  * @arg vf_spoofchk Pointer to store VF spoofchk value
1138  *
1139  * @see rtnl_link_get_num_vf()
1140  * @see rtnl_link_set_spoofchk()
1141  *
1142  * @return 0 if spoofchk is present and vf_spoofchk is set
1143  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1144  * @return -NLE_NOATTR if the VF spoofcheck is not set
1145  */
1147  uint32_t *vf_spoofchk)
1148 {
1149  if (!vf_data)
1150  return -NLE_OBJ_NOTFOUND;
1151 
1152  if (vf_data->ce_mask & SRIOV_ATTR_SPOOFCHK)
1153  *vf_spoofchk = vf_data->vf_spoofchk;
1154  else
1155  return -NLE_NOATTR;
1156 
1157  return 0;
1158 }
1159 
1160 /**
1161  * Set spoof checking value of SRIOV Virtual Function Object
1162  * @param vf_data
1163  * @param vf_spoofchk
1164  *
1165  * @see rtnl_link_vf_get_spoofchk()
1166  */
1168  uint32_t vf_spoofchk) {
1169  vf_data->vf_spoofchk = vf_spoofchk;
1170  vf_data->ce_mask |= SRIOV_ATTR_SPOOFCHK;
1171 
1172  return;
1173 }
1174 
1175 /**
1176  * Get value of stat counter for SRIOV Virtual Function
1177  * @arg vf_data SRIOV VF object
1178  * @arg stat Identifier of statistical counter
1179  * @arg vf_stat Pointer to store VF stat value in
1180  *
1181  * @see rtnl_link_get_num_vf()
1182  *
1183  * @return 0 if stat is present and vf_stat is set
1184  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1185  * @return -NLE_NOATTR if the VF stat is not set
1186  */
1188  rtnl_link_vf_stats_t stat, uint64_t *vf_stat)
1189 {
1190  if (!vf_data)
1191  return -NLE_OBJ_NOTFOUND;
1192 
1193  if (vf_data->ce_mask & SRIOV_ATTR_STATS)
1194  *vf_stat = vf_data->vf_stats[stat];
1195  else
1196  return -NLE_NOATTR;
1197 
1198  return 0;
1199 }
1200 
1201 /**
1202  * Get trust setting of SRIOV Virtual Function
1203  * @arg vf_data SRIOV VF object
1204  * @arg vf_trust Pointer to store VF trust value
1205  *
1206  * @see rtnl_link_get_num_vf()
1207  * @see rtnl_link_set_trust()
1208  *
1209  * @return 0 if trust is present and vf_trust is set
1210  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1211  * @return -NLE_NOATTR if the VF trust setting is not set
1212  */
1213 int rtnl_link_vf_get_trust(struct rtnl_link_vf *vf_data, uint32_t *vf_trust)
1214 {
1215  if (!vf_data)
1216  return -NLE_OBJ_NOTFOUND;
1217 
1218  if (vf_data->ce_mask & SRIOV_ATTR_TRUST)
1219  *vf_trust = vf_data->vf_trust;
1220  else
1221  return -NLE_NOATTR;
1222 
1223  return 0;
1224 }
1225 
1226 /**
1227  * Set user trust setting on SRIOV Virtual Function Object
1228  * @param vf_data
1229  * @param vf_trust
1230  *
1231  * @see rtnl_link_vf_get_trust()
1232  */
1233 void rtnl_link_vf_set_trust(struct rtnl_link_vf *vf_data, uint32_t vf_trust) {
1234  vf_data->vf_trust = vf_trust;
1235  vf_data->ce_mask |= SRIOV_ATTR_TRUST;
1236 
1237  return;
1238 }
1239 
1240 /**
1241  * Get an array of VLANS on SRIOV Virtual Function
1242  * @arg vf_data SRIOV VF object
1243  * @arg vf_vlans Pointer to nl_vf_vlans_t struct to store vlan info.
1244  *
1245  * @see rtnl_link_get_num_vf()
1246  *
1247  * The SRIOV VF VLANs object must be returned to the SRIOV VF object with
1248  * rtnl_link_vf_vlans_put() when operations are done to prevent memory leaks.
1249  *
1250  * @copydoc pointer_lifetime_warning
1251  * @return 0 if VLAN info is present and vf_vlans is set
1252  * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
1253  * @return -NLE_NOATTR if the VF vlans is not set
1254  */
1256  nl_vf_vlans_t **vf_vlans) {
1257  nl_vf_vlans_t *vf;
1258 
1259  if (!vf_data)
1260  return -NLE_OBJ_NOTFOUND;
1261 
1262  if (vf_data->ce_mask & SRIOV_ATTR_VLAN) {
1263  vf = vf_data->vf_vlans;
1264  vf->ce_refcnt++;
1265  *vf_vlans = vf;
1266  } else
1267  return -NLE_NOATTR;
1268 
1269  return 0;
1270 }
1271 
1272 /**
1273  * Add a SRIOV VF VLANs object to the SRIOV Virtual Function Object
1274  * @param vf_data SRIOV VF object
1275  * @param vf_vlans SRIOV VF VLANs object
1276  *
1277  * @see rtnl_link_vf_get_vlans()
1278  * @see rtnl_link_vf_vlan_alloc()
1279  *
1280  * This function assigns ownership of the SRIOV VF object \p vf_vlans
1281  * to the SRIOV Virtual Function object \p vf_data. Do not use
1282  * rtnl_link_vf_vlan_put() on \p vf_vlans after this.
1283  */
1285  nl_vf_vlans_t *vf_vlans) {
1286  if (!vf_data||!vf_vlans)
1287  return;
1288 
1289  vf_data->vf_vlans = vf_vlans;
1290  vf_data->vf_vlans->ce_refcnt++;
1291  vf_data->ce_mask |= SRIOV_ATTR_VLAN;
1292 
1293  return;
1294 }
1295 
1296 /**
1297  * Allocate a SRIOV VF VLAN object
1298  * @param vf_vlans Pointer to store VLAN object at
1299  * @param vlan_count Number of VLANs that will be stored in VLAN object
1300  *
1301  * The SRIOV VF VLANs object must be returned to the sRIOV VF object with
1302  * rtnl_link_vf_vlan_put() when operations are done to prevent memory leaks.
1303  *
1304  * @return 0 if VLAN object is created and vf_vlans is set.
1305  * @return -NLE_NOMEM if object could not be allocated.
1306  * @return -NLE_INVAL if vlan_count is more than supported by SRIOV VF
1307  */
1308 int rtnl_link_vf_vlan_alloc(nl_vf_vlans_t **vf_vlans, int vlan_count) {
1309  nl_vf_vlans_t *vlans;
1310  nl_vf_vlan_info_t *vlan_info;
1311 
1312  if (vlan_count > MAX_VLAN_LIST_LEN)
1313  return -NLE_INVAL;
1314 
1315  vlans = calloc(1, sizeof(*vlans));
1316  if (!vf_vlans)
1317  return -NLE_NOMEM;
1318 
1319  vlan_info = calloc(vlan_count+1, sizeof(*vlan_info));
1320  if (!vlan_info) {
1321  free(vlans);
1322  return -NLE_NOMEM;
1323  }
1324 
1325  NL_DBG(4, "Allocated new SRIOV VF VLANs object %p\n", vlans);
1326 
1327  vlans->ce_refcnt = 1;
1328  vlans->size = vlan_count;
1329  vlans->vlans = vlan_info;
1330  *vf_vlans = vlans;
1331 
1332  return 0;
1333 }
1334 
1335 /**
1336  * Free an allocated SRIOV VF VLANs object
1337  * @param vf_vlans SRIOV VF VLANs object
1338  */
1340  if (!vf_vlans)
1341  return;
1342 
1343  if (vf_vlans->ce_refcnt > 0)
1344  NL_DBG(1, "Warning: Freeing SRIOV VF VLANs object in use...\n");
1345 
1346  NL_DBG(4, "Freed SRIOV VF object %p\n", vf_vlans);
1347  free(vf_vlans->vlans);
1348  free(vf_vlans);
1349 
1350  return;
1351 }
1352 
1353 /**
1354  * Return SRIOV VF VLANs object to the owning SRIOV VF object.
1355  * @param vf_vlans SRIOV VF VLANs object
1356  */
1358  if (!vf_vlans)
1359  return;
1360 
1361  vf_vlans->ce_refcnt--;
1362  NL_DBG(4, "Returned SRIOV VF VLANs object reference %p, %i remaining\n",
1363  vf_vlans, vf_vlans->ce_refcnt);
1364 
1365  if (vf_vlans->ce_refcnt < 0)
1366  BUG();
1367 
1368  if (vf_vlans->ce_refcnt <= 0)
1369  rtnl_link_vf_vlan_free(vf_vlans);
1370 
1371  return;
1372 }
1373 
1374 /** @} */
1375 
1376 /**
1377  * @name Utilities
1378  * @{
1379  */
1380 
1381 static const struct trans_tbl vf_link_states[] = {
1382  __ADD(IFLA_VF_LINK_STATE_AUTO, autodetect),
1383  __ADD(IFLA_VF_LINK_STATE_ENABLE, up),
1384  __ADD(IFLA_VF_LINK_STATE_DISABLE, down),
1385 };
1386 
1387 char *rtnl_link_vf_linkstate2str(uint32_t ls, char *buf, size_t len)
1388 {
1389  return __type2str(ls, buf, len, vf_link_states,
1390  ARRAY_SIZE(vf_link_states));
1391 }
1392 
1393 int rtnl_link_vf_str2linkstate(const char *name)
1394 {
1395  return __str2type(name, vf_link_states, ARRAY_SIZE(vf_link_states));
1396 }
1397 
1398 static const struct trans_tbl vf_vlan_proto[] = {
1399  __ADD(ETH_P_8021Q, 8021Q),
1400  __ADD(ETH_P_8021AD, 8021AD),
1401 };
1402 
1403 char *rtnl_link_vf_vlanproto2str(uint16_t proto, char *buf, size_t len)
1404 {
1405  return __type2str(proto, buf, len, vf_vlan_proto,
1406  ARRAY_SIZE(vf_vlan_proto));
1407 }
1408 
1409 int rtnl_link_vf_str2vlanproto(const char *name)
1410 {
1411  return __str2type(name, vf_vlan_proto, ARRAY_SIZE(vf_vlan_proto));
1412 }
1413 
1414 /* Return a guid from a format checked string.
1415  * Format string must be xx:xx:xx:xx:xx:xx:xx:xx where XX can be an
1416  * arbitrary hex digit
1417  *
1418  * Function modified from original at iproute2/lib/utils.c:get_guid()
1419  * Original by Eli Cohen <eli@mellanox.com>.
1420  * iproute2 git commit d91fb3f4c7e4dba806541bdc90b1fb60a3581541
1421  */
1422 int rtnl_link_vf_str2guid(uint64_t *guid, const char *guid_s) {
1423  unsigned long int tmp;
1424  char *endptr;
1425  int i;
1426 
1427  if (strlen(guid_s) != RTNL_VF_GUID_STR_LEN)
1428  return -1;
1429 
1430  for (i = 0; i < 7; i++) {
1431  if (guid_s[2 + i * 3] != ':')
1432  return -1;
1433  }
1434 
1435  *guid = 0;
1436  for (i = 0; i < 8; i++) {
1437  tmp = strtoul(guid_s + i * 3, &endptr, 16);
1438  if (endptr != guid_s + i * 3 + 2)
1439  return -1;
1440 
1441  if (tmp > 255)
1442  return -1;
1443 
1444  *guid |= tmp << (56 - 8 * i);
1445  }
1446 
1447  return 0;
1448 }
1449 
1450 /** @} */
1451 
1452 /** @} */
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:1213
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:1187
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:67
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:740
void rtnl_link_vf_put(struct rtnl_link_vf *vf_data)
Return SRIOV VF object to the owning link object.
Definition: sriov.c:814
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:935
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:1167
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:979
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:1255
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:1357
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition: attr.c:917
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:844
double nl_cancel_down_bytes(unsigned long long l, char **unit)
Cancel down a byte counter.
Definition: utils.c:163
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
Definition: attr.h:162
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:992
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:915
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:1126
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:787
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:867
uint16_t minlen
Minimal length of payload required.
Definition: attr.h:72
64 bit integer
Definition: attr.h:42
#define nla_for_each_nested(pos, nla, rem)
Iterate over a stream of nested attributes.
Definition: attr.h:327
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:896
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:705
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:1105
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:1011
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:883
Nested attributes.
Definition: attr.h:46
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:69
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:1308
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:1077
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:1146
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:938
void rtnl_link_vf_free(struct rtnl_link_vf *vf_data)
Free SRIOV VF object.
Definition: sriov.c:758
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:1284
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:1233
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:1339
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition: attr.c:895
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:955
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
Definition: addr.c:963