/* SPDX-License-Identifier: LGPL-2.1-only */
/*
 * Copyright (c) 2016 Intel Corp. All rights reserved.
 * Copyright (c) 2016 Jef Oliver <jef.oliver@intel.com>
 */

/**
 * @ingroup link
 * @defgroup sriov SRIOV
 * SR-IOV VF link module
 *
 * @details
 * SR-IOV (Single Root Input/Output Virtualization) is a network interface
 * that allows for the isolation of the PCI Express resources. In a virtual
 * environment, SR-IOV allows multiple virtual machines can share a single
 * PCI Express hardware interface. This is done via VFs (Virtual Functions),
 * virtual hardware devices with their own PCI address.
 *
 * @{
 */

#include "nl-default.h"

#include <linux/if_ether.h>
#include <linux/if_link.h>

#include <netlink/netlink.h>
#include <netlink/route/link.h>
#include <netlink/route/link/sriov.h>

#include "nl-route.h"
#include "link-sriov.h"
#include "link-api.h"

/** @cond SKIP */
struct rtnl_link_vf {
	struct nl_list_head vf_list;
	int ce_refcnt;
	uint32_t ce_mask;
	uint32_t vf_index;
	uint64_t vf_guid_node;
	uint64_t vf_guid_port;
	uint32_t vf_linkstate;
	struct nl_addr *vf_lladdr;
	uint32_t vf_max_tx_rate;
	uint32_t vf_min_tx_rate;
	uint32_t vf_rate;
	uint32_t vf_rss_query_en;
	uint32_t vf_spoofchk;
	uint64_t vf_stats[RTNL_LINK_VF_STATS_MAX + 1];
	uint32_t vf_trust;
	struct nl_vf_vlans *vf_vlans;
};

#define SRIOVON "on"
#define SRIOVOFF "off"

#define SET_VF_STAT(link, vf_num, stb, stat, attr) \
	vf_data->vf_stats[stat] = nla_get_u64(stb[attr])

/* SRIOV-VF Attributes */
#define SRIOV_ATTR_INDEX 		(1 <<  0)
#define SRIOV_ATTR_ADDR 		(1 <<  1)
#define SRIOV_ATTR_VLAN 		(1 <<  2)
#define SRIOV_ATTR_TX_RATE 		(1 <<  3)
#define SRIOV_ATTR_SPOOFCHK 		(1 <<  4)
#define SRIOV_ATTR_RATE_MAX 		(1 <<  5)
#define SRIOV_ATTR_RATE_MIN 		(1 <<  6)
#define SRIOV_ATTR_LINK_STATE 		(1 <<  7)
#define SRIOV_ATTR_RSS_QUERY_EN 	(1 <<  8)
#define SRIOV_ATTR_STATS 		(1 <<  9)
#define SRIOV_ATTR_TRUST 		(1 << 10)
#define SRIOV_ATTR_IB_NODE_GUID 	(1 << 11)
#define SRIOV_ATTR_IB_PORT_GUID 	(1 << 12)

static struct nla_policy sriov_info_policy[IFLA_VF_MAX+1] = {
	[IFLA_VF_MAC]		= { .minlen = sizeof(struct ifla_vf_mac) },
	[IFLA_VF_VLAN]		= { .minlen = sizeof(struct ifla_vf_vlan) },
	[IFLA_VF_VLAN_LIST]     = { .type = NLA_NESTED },
	[IFLA_VF_TX_RATE]	= { .minlen = sizeof(struct ifla_vf_tx_rate) },
	[IFLA_VF_SPOOFCHK]	= { .minlen = sizeof(struct ifla_vf_spoofchk) },
	[IFLA_VF_RATE]		= { .minlen = sizeof(struct ifla_vf_rate) },
	[IFLA_VF_LINK_STATE]	= { .minlen = sizeof(struct ifla_vf_link_state) },
	[IFLA_VF_RSS_QUERY_EN]	= { .minlen = sizeof(struct ifla_vf_rss_query_en) },
	[IFLA_VF_STATS]		= { .type = NLA_NESTED },
	[IFLA_VF_TRUST]		= { .minlen = sizeof(struct ifla_vf_trust) },
	[IFLA_VF_IB_NODE_GUID]	= { .minlen = sizeof(struct ifla_vf_guid) },
	[IFLA_VF_IB_PORT_GUID]	= { .minlen = sizeof(struct ifla_vf_guid) },
};

static struct nla_policy sriov_stats_policy[IFLA_VF_STATS_MAX+1] = {
	[IFLA_VF_STATS_RX_PACKETS]	= { .type = NLA_U64 },
	[IFLA_VF_STATS_TX_PACKETS]	= { .type = NLA_U64 },
	[IFLA_VF_STATS_RX_BYTES]	= { .type = NLA_U64 },
	[IFLA_VF_STATS_TX_BYTES]	= { .type = NLA_U64 },
	[IFLA_VF_STATS_BROADCAST]	= { .type = NLA_U64 },
	[IFLA_VF_STATS_MULTICAST]	= { .type = NLA_U64 },
};

/** @endcond */

/* Clone SRIOV VF list in link object */
int rtnl_link_sriov_clone(struct rtnl_link *dst, struct rtnl_link *src) {
	int err = 0;
	struct nl_addr *vf_addr;
	struct rtnl_link_vf *s_list, *d_vf, *s_vf, *next, *dest_h = NULL;
	nl_vf_vlans_t *src_vlans = NULL, *dst_vlans = NULL;
	nl_vf_vlan_info_t *src_vlan_info = NULL, *dst_vlan_info = NULL;

	if (!rtnl_link_has_vf_list(src))
		return 0;

	dst->l_vf_list = rtnl_link_vf_alloc();
	if (!dst->l_vf_list)
		return -NLE_NOMEM;
	dest_h = dst->l_vf_list;
	s_list = src->l_vf_list;

	nl_list_for_each_entry_safe(s_vf, next, &s_list->vf_list, vf_list) {
		if (!(d_vf = rtnl_link_vf_alloc()))
			return -NLE_NOMEM;

		memcpy(d_vf, s_vf, sizeof(*s_vf));

		if (s_vf->ce_mask & SRIOV_ATTR_ADDR) {
			vf_addr = nl_addr_clone(s_vf->vf_lladdr);
			if (!vf_addr) {
				rtnl_link_vf_put(d_vf);
				return -NLE_NOMEM;
			}
			d_vf->vf_lladdr = vf_addr;
		}

		if (s_vf->ce_mask & SRIOV_ATTR_VLAN) {
			src_vlans = s_vf->vf_vlans;
			src_vlan_info = src_vlans->vlans;

			err = rtnl_link_vf_vlan_alloc(&dst_vlans,
						      src_vlans->size);
			if (err < 0) {
				rtnl_link_vf_put(d_vf);
				return err;
			}
			dst_vlan_info = dst_vlans->vlans;
			memcpy(dst_vlans, src_vlans, sizeof(nl_vf_vlans_t));
			memcpy(dst_vlan_info, src_vlan_info,
			       dst_vlans->size * sizeof(*dst_vlan_info));
			d_vf->vf_vlans = dst_vlans;
		}

		nl_list_add_head(&d_vf->vf_list, &dest_h->vf_list);
		dest_h = d_vf;
	}

	return 0;
}

/* Dump VLAN details for each SRIOV VF */
static void dump_sriov_vlans(nl_vf_vlans_t *vlans,
			     struct nl_dump_params *p) {
	char buf[64];
	int cur = 0;
	nl_vf_vlan_info_t *vlan_data;
	uint16_t prot;

	vlan_data = vlans->vlans;
	nl_dump(p, "\t      VLANS:\n");
	while (cur < vlans->size) {
		nl_dump(p, "\t      vlan %u", vlan_data[cur].vf_vlan);
		if (vlan_data[cur].vf_vlan_qos)
			nl_dump(p, " qos %u", vlan_data[cur].vf_vlan_qos);
		if (vlan_data[cur].vf_vlan_proto) {
			prot = vlan_data[cur].vf_vlan_proto;
			nl_dump(p, " proto %s",
				rtnl_link_vf_vlanproto2str(prot, buf,
							   sizeof(buf)));
		}
		nl_dump(p, "\n");
		cur++;
	}

	return;
}

/* Dump details for each SRIOV VF */
static void dump_vf_details(struct rtnl_link_vf *vf_data,
			    struct nl_dump_params *p) {
	char buf[64];
	int err = 0;
	struct nl_vf_rate vf_rate;
	uint32_t v = 0;

	nl_dump(p, "\tvf %u: ", vf_data->vf_index);
	if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE) {
		v = vf_data->vf_linkstate;
		nl_dump(p, "state %s ",
			rtnl_link_vf_linkstate2str(v, buf, sizeof(buf)));
	}
	if (vf_data->ce_mask & SRIOV_ATTR_ADDR) {
		nl_dump(p, "addr %s ",
			nl_addr2str(vf_data->vf_lladdr, buf, sizeof(buf)));
	}
	nl_dump(p, "\n");

	v = vf_data->vf_spoofchk;
	nl_dump(p, "\t      spoofchk %s ", v ? SRIOVON : SRIOVOFF);
	v = vf_data->vf_trust;
	nl_dump(p, "trust %s ", v ? SRIOVON : SRIOVOFF);
	v = vf_data->vf_rss_query_en;
	nl_dump(p, "rss_query %s\n", v ? SRIOVON : SRIOVOFF);

	err = rtnl_link_vf_get_rate(vf_data, &vf_rate);
	if (!err) {
		if (vf_rate.api == RTNL_LINK_VF_RATE_API_OLD)
			nl_dump(p, "\t      rate_api old rate %u\n",
				vf_rate.rate);
		else if (vf_rate.api == RTNL_LINK_VF_RATE_API_NEW)
			nl_dump(p, "\t      rate_api new min_rate %u "
					"max_rate %u\n", vf_rate.min_tx_rate,
				vf_rate.max_tx_rate);
	}
	if (vf_data->ce_mask & SRIOV_ATTR_VLAN)
		dump_sriov_vlans(vf_data->vf_vlans, p);

	return;
}

/* Loop through SRIOV VF list dump details */
void rtnl_link_sriov_dump_details(struct rtnl_link *link,
				  struct nl_dump_params *p) {
	struct rtnl_link_vf *vf_data, *list, *next;

	if (!rtnl_link_has_vf_list(link))
		BUG();

	nl_dump(p, "    SRIOV VF List\n");
	list = link->l_vf_list;
	nl_list_for_each_entry_safe(vf_data, next, &list->vf_list, vf_list) {
		if (vf_data->ce_mask & SRIOV_ATTR_INDEX)
			dump_vf_details(vf_data, p);
	}

	return;
}

/* Dump stats for each SRIOV VF */
static void dump_vf_stats(struct rtnl_link_vf *vf_data,
			  struct nl_dump_params *p) {
	char *unit;
	float res;

	nl_dump(p, "    VF %u Stats:\n", vf_data->vf_index);
	nl_dump_line(p, "\tRX:    %-14s %-10s   %-10s %-10s\n",
		     "bytes", "packets", "multicast", "broadcast");

	res = nl_cancel_down_bytes(vf_data->vf_stats[RTNL_LINK_VF_STATS_RX_BYTES],
				   &unit);

	nl_dump_line(p,
		"\t%10.2f %3s   %10" PRIu64 "   %10" PRIu64 " %10" PRIu64 "\n",
		res, unit,
		vf_data->vf_stats[RTNL_LINK_VF_STATS_RX_PACKETS],
		vf_data->vf_stats[RTNL_LINK_VF_STATS_MULTICAST],
		vf_data->vf_stats[RTNL_LINK_VF_STATS_BROADCAST]);

	nl_dump_line(p, "\tTX:    %-14s %-10s\n", "bytes", "packets");

	res = nl_cancel_down_bytes(vf_data->vf_stats[RTNL_LINK_VF_STATS_TX_BYTES],
				   &unit);

	nl_dump_line(p, "\t%10.2f %3s   %10" PRIu64 "\n", res, unit,
		vf_data->vf_stats[RTNL_LINK_VF_STATS_TX_PACKETS]);

	return;
}

/* Loop through SRIOV VF list dump stats */
void rtnl_link_sriov_dump_stats(struct rtnl_link *link,
				struct nl_dump_params *p) {
	struct rtnl_link_vf *vf_data, *list, *next;

	list = link->l_vf_list;
	nl_list_for_each_entry_safe(vf_data, next, &list->vf_list, vf_list) {
		if (vf_data->ce_mask & SRIOV_ATTR_INDEX)
			dump_vf_stats(vf_data, p);
	}
	nl_dump(p, "\n");

	return;
}

/* Free stored SRIOV VF data */
void rtnl_link_sriov_free_data(struct rtnl_link *link) {
	struct rtnl_link_vf *list, *vf, *next;

	if (!rtnl_link_has_vf_list(link))
		return;

	list = link->l_vf_list;
	nl_list_for_each_entry_safe(vf, next, &list->vf_list, vf_list) {
		nl_list_del(&vf->vf_list);
		rtnl_link_vf_put(vf);
	}

	rtnl_link_vf_put(link->l_vf_list);

	return;
}

/* Fill VLAN info array */
static int rtnl_link_vf_vlan_info(int len, struct ifla_vf_vlan_info **vi,
				  nl_vf_vlans_t **nvi) {
	int cur = 0, err;
	nl_vf_vlans_t *vlans;

	if (len <= 0)
		return 0;

	if ((err = rtnl_link_vf_vlan_alloc(&vlans, len)) < 0)
		return err;

	cur = 0;
	while (cur < len) {
		vlans->vlans[cur].vf_vlan = vi[cur]->vlan ? vi[cur]->vlan : 0;
		vlans->vlans[cur].vf_vlan_qos = vi[cur]->qos ? vi[cur]->qos : 0;
		if (vi[cur]->vlan_proto) {
			vlans->vlans[cur].vf_vlan_proto = ntohs(vi[cur]->vlan_proto);
		} else {
			vlans->vlans[cur].vf_vlan_proto = ETH_P_8021Q;
		}
		cur++;
	}

	*nvi = vlans;
	return 0;
}

/* Fill the IFLA_VF_VLAN attribute */
static void sriov_fill_vf_vlan(struct nl_msg *msg, nl_vf_vlan_info_t *vinfo,
			       uint32_t index) {
	struct ifla_vf_vlan vlan;

	vlan.vf = index;
	vlan.vlan = vinfo[0].vf_vlan;
	vlan.qos = vinfo[0].vf_vlan_qos;
	NLA_PUT(msg, IFLA_VF_VLAN, sizeof(vlan), &vlan);

nla_put_failure:
	return;
}

/* Fill the IFLA_VF_VLAN_LIST attribute */
static int sriov_fill_vf_vlan_list(struct nl_msg *msg, nl_vf_vlans_t *vlans,
				   uint32_t index) {
	int cur = 0;
	nl_vf_vlan_info_t *vlan_info = vlans->vlans;
	struct ifla_vf_vlan_info vlan;
	struct nlattr *list;

	if (!(list = nla_nest_start(msg, IFLA_VF_VLAN_LIST)))
		return -NLE_MSGSIZE;

	vlan.vf = index;
	while (cur < vlans->size) {
		vlan.vlan = vlan_info[cur].vf_vlan;
		vlan.qos = vlan_info[cur].vf_vlan_qos;
		vlan.vlan_proto = vlan_info[cur].vf_vlan_proto;

		NLA_PUT(msg, IFLA_VF_VLAN_INFO, sizeof(vlan), &vlan);

		cur++;
	}

nla_put_failure:
	nla_nest_end(msg, list);

	return 0;
}

/* Fill individual IFLA_VF_INFO attributes */
static int sriov_fill_vfinfo(struct nl_msg *msg,
			     struct rtnl_link_vf *vf_data) {
	int err = 0, new_rate = 0;
	nl_vf_vlans_t *vlan_list;
	nl_vf_vlan_info_t *vlan_info;
	struct ifla_vf_guid vf_node_guid;
	struct ifla_vf_guid vf_port_guid;
	struct ifla_vf_link_state vf_link_state;
	struct ifla_vf_mac vf_mac;
	struct ifla_vf_rate new_vf_rate;
	struct ifla_vf_rss_query_en vf_rss_query_en;
	struct ifla_vf_spoofchk vf_spoofchk;
	struct ifla_vf_trust vf_trust;
	struct ifla_vf_tx_rate vf_rate;
	struct nlattr *list;
	uint16_t proto;

	if (!(vf_data->ce_mask & SRIOV_ATTR_INDEX))
		return -NLE_MISSING_ATTR;

	if (!(list = nla_nest_start(msg, IFLA_VF_INFO)))
		return -NLE_MSGSIZE;

	/* IFLA_VF_MAC */
	if (vf_data->ce_mask & SRIOV_ATTR_ADDR) {
		vf_mac.vf = vf_data->vf_index;
		memset(vf_mac.mac, 0, sizeof(vf_mac.mac));
		memcpy(vf_mac.mac, nl_addr_get_binary_addr(vf_data->vf_lladdr),
		       nl_addr_get_len(vf_data->vf_lladdr));
		NLA_PUT(msg, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac);
	}

	/* IFLA_VF_VLAN IFLA_VF_VLAN_LIST */
	if (vf_data->ce_mask & SRIOV_ATTR_VLAN) {
		vlan_list = vf_data->vf_vlans;
		vlan_info = vlan_list->vlans;
		proto = vlan_info[0].vf_vlan_proto;
		if (!proto)
			proto = ETH_P_8021Q;

		if ((vlan_list->size == 1) && (proto == ETH_P_8021Q))
			sriov_fill_vf_vlan(msg, vlan_info, vf_data->vf_index);
		else
			err = sriov_fill_vf_vlan_list(msg, vlan_list,
						      vf_data->vf_index);
	}

	/* IFLA_VF_TX_RATE */
	if (vf_data->ce_mask & SRIOV_ATTR_TX_RATE) {
		vf_rate.vf = vf_data->vf_index;
		vf_rate.rate = vf_data->vf_rate;

		NLA_PUT(msg, IFLA_VF_TX_RATE, sizeof(vf_rate), &vf_rate);
	}

	/* IFLA_VF_RATE */
	new_vf_rate.min_tx_rate = 0;
	new_vf_rate.max_tx_rate = 0;
	new_vf_rate.vf = vf_data->vf_index;
	if (vf_data->ce_mask & SRIOV_ATTR_RATE_MIN) {
		new_vf_rate.min_tx_rate = vf_data->vf_min_tx_rate;
		new_rate = 1;
	}
	if (vf_data->ce_mask & SRIOV_ATTR_RATE_MAX) {
		new_vf_rate.max_tx_rate = vf_data->vf_max_tx_rate;
		new_rate = 1;
	}
	if (new_rate)
		NLA_PUT(msg, IFLA_VF_RATE, sizeof(new_vf_rate), &new_vf_rate);

	/* IFLA_VF_SPOOFCHK */
	if (vf_data->ce_mask & SRIOV_ATTR_SPOOFCHK) {
		vf_spoofchk.vf = vf_data->vf_index;
		vf_spoofchk.setting = vf_data->vf_spoofchk;

		NLA_PUT(msg, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
			&vf_spoofchk);
	}

	/* IFLA_VF_LINK_STATE */
	if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE) {
		vf_link_state.vf = vf_data->vf_index;
		vf_link_state.link_state = vf_data->vf_linkstate;

		NLA_PUT(msg, IFLA_VF_LINK_STATE, sizeof(vf_link_state),
			&vf_link_state);
	}

	/* IFLA_VF_RSS_QUERY_EN */
	if (vf_data->ce_mask & SRIOV_ATTR_RSS_QUERY_EN) {
		vf_rss_query_en.vf = vf_data->vf_index;
		vf_rss_query_en.setting = vf_data->vf_rss_query_en;

		NLA_PUT(msg, IFLA_VF_RSS_QUERY_EN, sizeof(vf_rss_query_en),
			&vf_rss_query_en);
	}

	/* IFLA_VF_TRUST */
	if (vf_data->ce_mask & SRIOV_ATTR_TRUST) {
		vf_trust.vf = vf_data->vf_index;
		vf_trust.setting = vf_data->vf_trust;

		NLA_PUT(msg, IFLA_VF_TRUST, sizeof(vf_trust), &vf_trust);
	}

	/* IFLA_VF_IB_NODE_GUID */
	if (vf_data->ce_mask & SRIOV_ATTR_IB_NODE_GUID) {
		vf_node_guid.vf = vf_data->vf_index;
		vf_node_guid.guid = vf_data->vf_guid_node;

		NLA_PUT(msg, IFLA_VF_IB_NODE_GUID, sizeof(vf_node_guid),
			&vf_node_guid);
	}

	/* IFLA_VF_IB_PORT_GUID */
	if (vf_data->ce_mask & SRIOV_ATTR_IB_PORT_GUID) {
		vf_port_guid.vf = vf_data->vf_index;
		vf_port_guid.guid = vf_data->vf_guid_port;

		NLA_PUT(msg, IFLA_VF_IB_PORT_GUID, sizeof(vf_port_guid),
			&vf_port_guid);
	}

nla_put_failure:
	nla_nest_end(msg, list);

	return err;
}

/* Fill the IFLA_VFINFO_LIST attribute */
int rtnl_link_sriov_fill_vflist(struct nl_msg *msg, struct rtnl_link *link) {
	int err = 0;
	struct nlattr *data;
	struct rtnl_link_vf *list, *vf, *next;

	if (!(err = rtnl_link_has_vf_list(link)))
		return 0;

	if (!(data = nla_nest_start(msg, IFLA_VFINFO_LIST)))
		return -NLE_MSGSIZE;

	list = link->l_vf_list;
	nl_list_for_each_entry_safe(vf, next, &list->vf_list, vf_list) {
		if (vf->ce_mask & SRIOV_ATTR_INDEX) {
			if ((err = sriov_fill_vfinfo(msg, vf)) < 0)
				goto nla_nest_list_failure;
		}
	}

nla_nest_list_failure:
	nla_nest_end(msg, data);

	return err;
}

/* Parse IFLA_VFINFO_LIST and IFLA_VF_INFO attributes */
int rtnl_link_sriov_parse_vflist(struct rtnl_link *link, struct nlattr **tb) {
	int err, len, list_len, list_rem;
	struct ifla_vf_mac *vf_lladdr;
	struct ifla_vf_vlan *vf_vlan;
	struct ifla_vf_vlan_info *vf_vlan_info[MAX_VLAN_LIST_LEN];
	struct ifla_vf_tx_rate *vf_tx_rate;
	struct ifla_vf_spoofchk *vf_spoofchk;
	struct ifla_vf_link_state *vf_linkstate;
	struct ifla_vf_rate *vf_rate;
	struct ifla_vf_rss_query_en *vf_rss_query;
	struct ifla_vf_trust *vf_trust;
	struct nlattr *nla, *nla_list, *t[IFLA_VF_MAX+1],
		*stb[RTNL_LINK_VF_STATS_MAX+1];
	nl_vf_vlans_t *vf_vlans = NULL;
	struct rtnl_link_vf *vf_data, *vf_head = NULL;

	len = nla_len(tb[IFLA_VFINFO_LIST]);
	link->l_vf_list = rtnl_link_vf_alloc();
	if (!link->l_vf_list)
		return -NLE_NOMEM;
	vf_head = link->l_vf_list;

	for (nla = nla_data(tb[IFLA_VFINFO_LIST]); nla_ok(nla, len);
	     nla = nla_next(nla, &len)) {
		err = nla_parse(t, IFLA_VF_MAX, nla_data(nla), nla_len(nla),
				sriov_info_policy);
		if (err < 0)
			return err;

		vf_data = rtnl_link_vf_alloc();
		if (!vf_data)
			return -NLE_NOMEM;

		if (t[IFLA_VF_MAC]) {
			vf_lladdr = nla_data(t[IFLA_VF_MAC]);

			vf_data->vf_index = vf_lladdr->vf;
			vf_data->ce_mask |= SRIOV_ATTR_INDEX;

			vf_data->vf_lladdr = nl_addr_build(AF_LLC,
							   vf_lladdr->mac, 6);
			if (vf_data->vf_lladdr == NULL) {
				rtnl_link_vf_put(vf_data);
				return -NLE_NOMEM;
			}
			nl_addr_set_family(vf_data->vf_lladdr, AF_LLC);
			vf_data->ce_mask |= SRIOV_ATTR_ADDR;
		}

		if (t[IFLA_VF_VLAN_LIST]) {
			list_len = 0;
			nla_for_each_nested(nla_list, t[IFLA_VF_VLAN_LIST],
					    list_rem) {
				if (list_len >= MAX_VLAN_LIST_LEN)
					break;
				vf_vlan_info[list_len] = nla_data(nla_list);
				list_len++;
			}

			err = rtnl_link_vf_vlan_info(list_len, vf_vlan_info,
						     &vf_vlans);
			if (err < 0) {
				rtnl_link_vf_put(vf_data);
				return err;
			}

			vf_data->vf_vlans = vf_vlans;
			vf_data->ce_mask |= SRIOV_ATTR_VLAN;
		} else if (t[IFLA_VF_VLAN]) {
			vf_vlan = nla_data(t[IFLA_VF_VLAN]);

			if (vf_vlan->vlan) {
				err = rtnl_link_vf_vlan_alloc(&vf_vlans, 1);
				if (err < 0) {
					rtnl_link_vf_put(vf_data);
					return err;
				}

				vf_vlans->vlans[0].vf_vlan = vf_vlan->vlan;
				vf_vlans->vlans[0].vf_vlan_qos = vf_vlan->qos;
				vf_vlans->vlans[0].vf_vlan_proto = ETH_P_8021Q;

				vf_data->vf_vlans = vf_vlans;
				vf_data->ce_mask |= SRIOV_ATTR_VLAN;
			}
		}

		if (t[IFLA_VF_TX_RATE]) {
			vf_tx_rate = nla_data(t[IFLA_VF_TX_RATE]);

			if (vf_tx_rate->rate) {
				vf_data->vf_rate = vf_tx_rate->rate;
				vf_data->ce_mask |= SRIOV_ATTR_TX_RATE;
			}
		}

		if (t[IFLA_VF_SPOOFCHK]) {
			vf_spoofchk = nla_data(t[IFLA_VF_SPOOFCHK]);

			if (vf_spoofchk->setting != -1) {
				vf_data->vf_spoofchk = vf_spoofchk->setting ? 1 : 0;
				vf_data->ce_mask |= SRIOV_ATTR_SPOOFCHK;
			}
		}

		if (t[IFLA_VF_LINK_STATE]) {
			vf_linkstate = nla_data(t[IFLA_VF_LINK_STATE]);

			vf_data->vf_linkstate = vf_linkstate->link_state;
			vf_data->ce_mask |= SRIOV_ATTR_LINK_STATE;
		}

		if (t[IFLA_VF_RATE]) {
			vf_rate = nla_data(t[IFLA_VF_RATE]);

			if (vf_rate->max_tx_rate) {
				vf_data->vf_max_tx_rate = vf_rate->max_tx_rate;
				vf_data->ce_mask |= SRIOV_ATTR_RATE_MAX;
			}
			if (vf_rate->min_tx_rate) {
				vf_data->vf_min_tx_rate = vf_rate->min_tx_rate;
				vf_data->ce_mask |= SRIOV_ATTR_RATE_MIN;
			}
		}

		if (t[IFLA_VF_RSS_QUERY_EN]) {
			vf_rss_query = nla_data(t[IFLA_VF_RSS_QUERY_EN]);

			if (vf_rss_query->setting != -1) {
				vf_data->vf_rss_query_en = vf_rss_query->setting ? 1 : 0;
				vf_data->ce_mask |= SRIOV_ATTR_RSS_QUERY_EN;
			}
		}

		if (t[IFLA_VF_STATS]) {
			err = nla_parse_nested(stb, RTNL_LINK_VF_STATS_MAX,
					       t[IFLA_VF_STATS],
					       sriov_stats_policy);
			if (err < 0) {
				rtnl_link_vf_put(vf_data);
				return err;
			}

			SET_VF_STAT(link, cur, stb,
				    RTNL_LINK_VF_STATS_RX_PACKETS,
				    IFLA_VF_STATS_RX_PACKETS);
			SET_VF_STAT(link, cur, stb,
				    RTNL_LINK_VF_STATS_TX_PACKETS,
				    IFLA_VF_STATS_TX_PACKETS);
			SET_VF_STAT(link, cur, stb,
				    RTNL_LINK_VF_STATS_RX_BYTES,
				    IFLA_VF_STATS_RX_BYTES);
			SET_VF_STAT(link, cur, stb,
				    RTNL_LINK_VF_STATS_TX_BYTES,
				    IFLA_VF_STATS_TX_BYTES);
			SET_VF_STAT(link, cur, stb,
				    RTNL_LINK_VF_STATS_BROADCAST,
				    IFLA_VF_STATS_BROADCAST);
			SET_VF_STAT(link, cur, stb,
				    RTNL_LINK_VF_STATS_MULTICAST,
				    IFLA_VF_STATS_MULTICAST);

			vf_data->ce_mask |= SRIOV_ATTR_STATS;
		}

		if (t[IFLA_VF_TRUST]) {
			vf_trust = nla_data(t[IFLA_VF_TRUST]);

			if (vf_trust->setting != -1) {
				vf_data->vf_trust = vf_trust->setting ? 1 : 0;
				vf_data->ce_mask |= SRIOV_ATTR_TRUST;
			}
		}

		nl_list_add_head(&vf_data->vf_list, &vf_head->vf_list);
		vf_head = vf_data;
	}

	return 0;
}

/**
 * @name SR-IOV Sub-Object
 * @{
 */

/**
 * Add a SRIOV VF object to a link object
 * @param link  	Link object to add to
 * @param vf_data 	SRIOV VF object to add
 *
 * @return 0 if SRIOV VF object added successfully
 * @return -NLE_OBJ_NOTFOUND if \p link or \p vf_data not provided
 * @return -NLE_NOMEM if out of memory
 */
int rtnl_link_vf_add(struct rtnl_link *link, struct rtnl_link_vf *vf_data) {
	struct rtnl_link_vf *vf_head = NULL;

	if (!link||!vf_data)
		return -NLE_OBJ_NOTFOUND;

	if (!link->l_vf_list) {
		link->l_vf_list = rtnl_link_vf_alloc();
		if (!link->l_vf_list)
			return -NLE_NOMEM;
	}

	vf_head = vf_data;
	vf_head->ce_refcnt++;

	vf_head = link->l_vf_list;
	nl_list_add_head(&vf_data->vf_list, &vf_head->vf_list);
	link->l_vf_list = vf_head;

	rtnl_link_set_vf_list(link);

	return 0;
}

/**
 * Allocate a new SRIOV VF object
 *
 * @return NULL if out of memory
 * @return New VF Object
 *
 * @see rtnl_link_vf_put()
 *
 * The SRIOV VF object must be returned to the link object with
 * rtnl_link_vf_put() when operations are done to prevent memory leaks.
 */
struct rtnl_link_vf *rtnl_link_vf_alloc(void) {
	struct rtnl_link_vf *vf;

	if (!(vf = calloc(1, sizeof(*vf))))
		return NULL;

	NL_INIT_LIST_HEAD(&vf->vf_list);
	vf->ce_refcnt = 1;

	NL_DBG(4, "Allocated new SRIOV VF object %p\n", vf);

	return vf;
}

/**
 * Free SRIOV VF object.
 * @arg vf_data 	SRIOV VF data object
 */
void rtnl_link_vf_free(struct rtnl_link_vf *vf_data) {
	if (!vf_data)
		return;

	if (vf_data->ce_refcnt > 0)
		NL_DBG(1, "Warning: Freeing SRIOV VF object in use...\n");

	if (vf_data->ce_mask & SRIOV_ATTR_ADDR)
		nl_addr_put(vf_data->vf_lladdr);
	if (vf_data->ce_mask & SRIOV_ATTR_VLAN)
		rtnl_link_vf_vlan_put(vf_data->vf_vlans);

	NL_DBG(4, "Freed SRIOV VF object %p\n", vf_data);
	free(vf_data);

	return;
}

/**
 * Lookup SRIOV VF in link object by VF index.
 *
 * @return NULL if VF not found
 * @return VF Object
 *
 * @see rtnl_link_vf_put()
 *
 * The SRIOV VF object must be returned to the link object with
 * rtnl_link_vf_put() when operations are done to prevent memory leaks.
 */
struct rtnl_link_vf *rtnl_link_vf_get(struct rtnl_link *link, uint32_t vf_num) {
	struct rtnl_link_vf *list, *vf, *next, *ret = NULL;

	list = link->l_vf_list;
	nl_list_for_each_entry_safe(vf, next, &list->vf_list, vf_list) {
		if (vf->vf_index == vf_num) {
			ret = vf;
			break;
		}
	}

	if (ret) {
		ret->ce_refcnt++;
		NL_DBG(4, "New reference to SRIOV VF object %p, total %i\n",
		       ret, ret->ce_refcnt);
	}

	return ret;
}

/**
 * Return SRIOV VF object to the owning link object.
 * @arg vf_data 	SRIOV VF data object
 *
 * @see rtnl_link_vf_alloc()
 * @see rtnl_link_vf_get()
 */
void rtnl_link_vf_put(struct rtnl_link_vf *vf_data) {
	if (!vf_data)
		return;

	vf_data->ce_refcnt--;
	NL_DBG(4, "Returned SRIOV VF object reference %p, %i remaining\n",
	       vf_data, vf_data->ce_refcnt);

	if (vf_data->ce_refcnt < 0)
		BUG();

	if (vf_data->ce_refcnt <= 0)
		rtnl_link_vf_free(vf_data);

	return;
}

/**
 * Get link layer address of SRIOV Virtual Function
 * @arg vf_data 	SRIOV VF object
 * @arg addr 		Pointer to store Link Layer address
 *
 * @see rtnl_link_get_num_vf()
 * @see rtnl_link_vf_set_addr()
 *
 * @copydoc pointer_lifetime_warning
 * @return 0 if addr is present and addr is set to pointer containing address
 * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
 * @return -NLE_NOATTR if the link layer address is not set
 */
int rtnl_link_vf_get_addr(struct rtnl_link_vf *vf_data, struct nl_addr **addr)
{
	if (!vf_data)
		return -NLE_OBJ_NOTFOUND;

	if (vf_data->ce_mask & SRIOV_ATTR_ADDR)
		*addr = vf_data->vf_lladdr;
	else
		return -NLE_NOATTR;

	return 0;
}

/**
 * Set link layer address of SRIOV Virtual Function object
 * @param vf_data 	SRIOV VF object
 * @param addr 		New link layer address
 *
 * This function increments the reference counter of the address object
 * and overwrites any existing link layer address previously assigned.
 *
 * @see rtnl_link_vf_get_addr()
 */
void rtnl_link_vf_set_addr(struct rtnl_link_vf *vf_data, struct nl_addr *addr) {
	if (vf_data->vf_lladdr)
		nl_addr_put(vf_data->vf_lladdr);

	nl_addr_get(addr);
	vf_data->vf_lladdr = addr;
	vf_data->ce_mask |= SRIOV_ATTR_ADDR;

	return;
}

/**
 * Set the Infiniband node GUID for the SRIOV Virtual Function object
 * @param vf_data 	SRIOV VF object
 * @param guid  	node GUID
 */
void rtnl_link_vf_set_ib_node_guid(struct rtnl_link_vf *vf_data,
				   uint64_t guid) {
	vf_data->vf_guid_node = guid;
	vf_data->ce_mask |= SRIOV_ATTR_IB_NODE_GUID;

	return;
}

/**
 * Set the Infiniband port GUID for the SRIOV Virtual Function object
 * @param vf_data 	SRIOV VF object
 * @param guid  	port GUID
 */
void rtnl_link_vf_set_ib_port_guid(struct rtnl_link_vf *vf_data,
				   uint64_t guid) {
	vf_data->vf_guid_port = guid;
	vf_data->ce_mask |= SRIOV_ATTR_IB_PORT_GUID;

	return;
}

/**
 * Get index of SRIOV Virtual Function
 * @arg vf_data 	SRIOV VF object
 * @arg vf_index 	Pointer to store VF index
 *
 * @see rtnl_link_get_num_vf()
 *
 * @return 0 if index is present and vf_index is set
 * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
 * @return -NLE_NOATTR if the VF index is not set
 */
int rtnl_link_vf_get_index(struct rtnl_link_vf *vf_data, uint32_t *vf_index)
{
	if (!vf_data)
		return -NLE_OBJ_NOTFOUND;

	if (vf_data->ce_mask & SRIOV_ATTR_INDEX)
		*vf_index = vf_data->vf_index;
	else
		return -NLE_NOATTR;

	return 0;
}

/**
 * Set index of SRIOV Virtual Function object
 * @param vf_data 	SRIOV VF object
 * @param vf_index 	Index value
 *
 * @see rtnl_link_vf_get_index()
 */
void rtnl_link_vf_set_index(struct rtnl_link_vf *vf_data, uint32_t vf_index)
{
	vf_data->vf_index = vf_index;
	vf_data->ce_mask |= SRIOV_ATTR_INDEX;

	return;
}

/**
 * Get link state of SRIOV Virtual Function
 * @arg vf_data  	SRIOV VF object
 * @arg vf_linkstate 	Pointer to store VF link state
 *
 * @see rtnl_link_get_num_vf()
 * @see rtnl_link_set_linkstate()
 *
 * @return 0 if link state is present and vf_linkstate is set
 * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
 * @return -NLE_NOATTR if the VF link state is not set
 */
int rtnl_link_vf_get_linkstate(struct rtnl_link_vf *vf_data,
			       uint32_t *vf_linkstate)
{
	if (!vf_data)
		return -NLE_OBJ_NOTFOUND;

	if (vf_data->ce_mask & SRIOV_ATTR_LINK_STATE)
		*vf_linkstate = vf_data->vf_linkstate;
	else
		return -NLE_NOATTR;

	return 0;
}

/**
 * Set link state of SRIOV Virtual Function object
 * @param vf_data 	SRIOV VF object
 * @param vf_linkstate Link state value
 *
 * @see rtnl_link_get_linkstate()
 *
 * Not all hardware supports setting link state. If the feature is unsupported,
 * the link change request will fail with -NLE_OPNOTSUPP
 */
void rtnl_link_vf_set_linkstate(struct rtnl_link_vf *vf_data,
				uint32_t vf_linkstate) {
	vf_data->vf_linkstate = vf_linkstate;
	vf_data->ce_mask |= SRIOV_ATTR_LINK_STATE;

	return;
}

/**
 * Get TX Rate Limit of SRIOV Virtual Function
 * @arg vf_data 	SRIOV VF object
 * @arg vf_rate 	Pointer to store VF rate limiting data
 *
 * @see rtnl_link_get_num_vf()
 * @see rtnl_link_set_rate()
 *
 * When the older rate API has been implemented, the rate member of the struct
 * will be set, and the api member will be set to RTNL_LINK_VF_API_OLD.
 * When the newer rate API has been implemented, the max_tx_rate
 * and/or the minx_tx_rate will be set, and the api member will be set to
 * RTNL_LINK_VF_API_NEW.
 *
 * Old rate API supports only a maximum TX rate.
 *   ip link set dev vf 0 rate
 * New rate API supports minumum and maximum TX rates.
 *   ip link set dev vf 0 min_tx_rate
 *   ip link set dev vf 0 max_tx_rate
 *
 * @return 0 if rate is present and vf_rate is set
 * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
 * @return -NLE_NOATTR if the VF rate is not set
 */
int rtnl_link_vf_get_rate(struct rtnl_link_vf *vf_data,
			  struct nl_vf_rate *vf_rate)
{
	int set = 0;

	if (!vf_data)
		return -NLE_OBJ_NOTFOUND;

	vf_rate->api = RTNL_LINK_VF_RATE_API_UNSPEC;
	vf_rate->rate = 0;
	vf_rate->max_tx_rate = 0;
	vf_rate->min_tx_rate = 0;

	if (vf_data->ce_mask & SRIOV_ATTR_RATE_MAX) {
		if (vf_data->vf_max_tx_rate) {
			vf_rate->api = RTNL_LINK_VF_RATE_API_NEW;
			vf_rate->max_tx_rate = vf_data->vf_max_tx_rate;
			set = 1;
		}
	}
	if (vf_data->ce_mask & SRIOV_ATTR_RATE_MIN) {
		if (vf_data->vf_min_tx_rate) {
			vf_rate->api = RTNL_LINK_VF_RATE_API_NEW;
			vf_rate->min_tx_rate = vf_data->vf_min_tx_rate;
			set = 1;
		}
	}
	if ((!set) && (vf_data->ce_mask & SRIOV_ATTR_TX_RATE)) {
		if (vf_data->vf_rate) {
			vf_rate->api = RTNL_LINK_VF_RATE_API_OLD;
			vf_rate->rate = vf_data->vf_rate;
			set = 1;
		}
	}

	if (!set)
		return -NLE_NOATTR;

	return 0;
}

/**
 * Set TX Rate Limit of SRIOV Virtual Function object
 * @param vf_data 	SRIOV VF object
 * @param vf_rate 	Rate limiting structure
 *
 * @see rtnl_link_vf_get_rate()
 *
 * When setting the rate, the API level must be specificed.
 * Valid API levels:
 *   RTNL_LINK_VF_RATE_API_NEW
 *   RTNL_LINK_VF_RATE_API_OLD
 *
 * When using the new API, if either the min_tx_rate or
 * max_tx_rate has been set, and the other is being changed,
 * you must specify the currently set values to preserve
 * them. If this is not done, that setting will be disabled.
 *
 * Old rate API supports only a maximum TX rate.
 *   ip link set dev vf 0 rate
 * New rate API supports minumum and maximum TX rates.
 *   ip link set dev vf 0 min_tx_rate
 *   ip link set dev vf 0 max_tx_rate
 *
 * Not all hardware supports min_tx_rate.
 */
void rtnl_link_vf_set_rate(struct rtnl_link_vf *vf_data,
			   struct nl_vf_rate *vf_rate) {
	if (vf_rate->api == RTNL_LINK_VF_RATE_API_OLD) {
		vf_data->vf_rate = vf_rate->rate;
		vf_data->ce_mask |= SRIOV_ATTR_TX_RATE;
	} else if (vf_rate->api == RTNL_LINK_VF_RATE_API_NEW) {
		vf_data->vf_max_tx_rate = vf_rate->max_tx_rate;
		vf_data->ce_mask |= SRIOV_ATTR_RATE_MAX;

		vf_data->vf_min_tx_rate = vf_rate->min_tx_rate;
		vf_data->ce_mask |= SRIOV_ATTR_RATE_MIN;
	}

	return;
}

/**
 * Get RSS Query EN value of SRIOV Virtual Function
 * @arg vf_data 	SRIOV VF object
 * @arg vf_rss_query_en	Pointer to store VF RSS Query value
 *
 * @see rtnl_link_get_num_vf()
 * @see rtnl_link_vf_set_rss_query_en()
 *
 * @return 0 if rss_query_en is present and vf_rss_query_en is set
 * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
 * @return -NLE_NOATTR if the VF RSS Query EN value is not set
 */
int rtnl_link_vf_get_rss_query_en(struct rtnl_link_vf *vf_data,
				  uint32_t *vf_rss_query_en)
{
	if (!vf_data)
		return -NLE_OBJ_NOTFOUND;

	if (vf_data->ce_mask & SRIOV_ATTR_RSS_QUERY_EN)
		*vf_rss_query_en = vf_data->vf_rss_query_en;
	else
		return -NLE_NOATTR;

	return 0;
}

/**
 * Set RSS configuration querying of SRIOV Virtual Function Object
 * @arg vf_data 	SRIOV VF object
 * @arg vf_rss_query_en	RSS Query value
 *
 * @see rtnl_link_vf_get_rss_query_en()
 */
void rtnl_link_vf_set_rss_query_en(struct rtnl_link_vf *vf_data,
				  uint32_t vf_rss_query_en) {
	vf_data->vf_rss_query_en = vf_rss_query_en;
	vf_data->ce_mask |= SRIOV_ATTR_RSS_QUERY_EN;

	return;
}

/**
 * Get spoof checking value of SRIOV Virtual Function
 * @arg vf_data 	SRIOV VF object
 * @arg vf_spoofchk 	Pointer to store VF spoofchk value
 *
 * @see rtnl_link_get_num_vf()
 * @see rtnl_link_set_spoofchk()
 *
 * @return 0 if spoofchk is present and vf_spoofchk is set
 * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
 * @return -NLE_NOATTR if the VF spoofcheck is not set
 */
int rtnl_link_vf_get_spoofchk(struct rtnl_link_vf *vf_data,
			      uint32_t *vf_spoofchk)
{
	if (!vf_data)
		return -NLE_OBJ_NOTFOUND;

	if (vf_data->ce_mask & SRIOV_ATTR_SPOOFCHK)
		*vf_spoofchk = vf_data->vf_spoofchk;
	else
		return -NLE_NOATTR;

	return 0;
}

/**
 * Set spoof checking value of SRIOV Virtual Function Object
 * @param vf_data
 * @param vf_spoofchk
 *
 * @see rtnl_link_vf_get_spoofchk()
 */
void rtnl_link_vf_set_spoofchk(struct rtnl_link_vf *vf_data,
			       uint32_t vf_spoofchk) {
	vf_data->vf_spoofchk = vf_spoofchk;
	vf_data->ce_mask |= SRIOV_ATTR_SPOOFCHK;

	return;
}

/**
 * Get value of stat counter for SRIOV Virtual Function
 * @arg vf_data 	SRIOV VF object
 * @arg stat 		Identifier of statistical counter
 * @arg vf_stat 	Pointer to store VF stat value in
 *
 * @see rtnl_link_get_num_vf()
 *
 * @return 0 if stat is present and vf_stat is set
 * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
 * @return -NLE_NOATTR if the VF stat is not set
 */
int rtnl_link_vf_get_stat(struct rtnl_link_vf *vf_data,
			  rtnl_link_vf_stats_t stat, uint64_t *vf_stat)
{
	if (!vf_data)
		return -NLE_OBJ_NOTFOUND;

	if (vf_data->ce_mask & SRIOV_ATTR_STATS)
		*vf_stat = vf_data->vf_stats[stat];
	else
		return -NLE_NOATTR;

	return 0;
}

/**
 * Get trust setting of SRIOV Virtual Function
 * @arg vf_data 	SRIOV VF object
 * @arg vf_trust 	Pointer to store VF trust value
 *
 * @see rtnl_link_get_num_vf()
 * @see rtnl_link_set_trust()
 *
 * @return 0 if trust is present and vf_trust is set
 * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
 * @return -NLE_NOATTR if the VF trust setting is not set
 */
int rtnl_link_vf_get_trust(struct rtnl_link_vf *vf_data, uint32_t *vf_trust)
{
	if (!vf_data)
		return -NLE_OBJ_NOTFOUND;

	if (vf_data->ce_mask & SRIOV_ATTR_TRUST)
		*vf_trust = vf_data->vf_trust;
	else
		return -NLE_NOATTR;

	return 0;
}

/**
 * Set user trust setting on SRIOV Virtual Function Object
 * @param vf_data
 * @param vf_trust
 *
 * @see rtnl_link_vf_get_trust()
 */
void rtnl_link_vf_set_trust(struct rtnl_link_vf *vf_data, uint32_t vf_trust) {
	vf_data->vf_trust = vf_trust;
	vf_data->ce_mask |= SRIOV_ATTR_TRUST;

	return;
}

/**
 * Get an array of VLANS on SRIOV Virtual Function
 * @arg vf_data 	SRIOV VF object
 * @arg vf_vlans 	Pointer to nl_vf_vlans_t struct to store vlan info.
 *
 * @see rtnl_link_get_num_vf()
 *
 * The SRIOV VF VLANs object must be returned to the SRIOV VF object with
 * rtnl_link_vf_vlans_put() when operations are done to prevent memory leaks.
 *
 * @copydoc pointer_lifetime_warning
 * @return 0 if VLAN info is present and vf_vlans is set
 * @return -NLE_OBJ_NOTFOUND if information for VF info is not found
 * @return -NLE_NOATTR if the VF vlans is not set
 */
int rtnl_link_vf_get_vlans(struct rtnl_link_vf *vf_data,
			   nl_vf_vlans_t **vf_vlans) {
	nl_vf_vlans_t *vf;

	if (!vf_data)
		return -NLE_OBJ_NOTFOUND;

	if (vf_data->ce_mask & SRIOV_ATTR_VLAN) {
		vf = vf_data->vf_vlans;
		vf->ce_refcnt++;
		*vf_vlans = vf;
	} else
		return -NLE_NOATTR;

	return 0;
}

/**
 * Add a SRIOV VF VLANs object to the SRIOV Virtual Function Object
 * @param vf_data 	SRIOV VF object
 * @param vf_vlans 	SRIOV VF VLANs object
 *
 * @see rtnl_link_vf_get_vlans()
 * @see rtnl_link_vf_vlan_alloc()
 *
 * This function assigns ownership of the SRIOV VF object \p vf_vlans
 * to the SRIOV Virtual Function object \p vf_data. Do not use
 * rtnl_link_vf_vlan_put() on \p vf_vlans after this.
 */
void rtnl_link_vf_set_vlans(struct rtnl_link_vf *vf_data,
			    nl_vf_vlans_t *vf_vlans) {
	if (!vf_data||!vf_vlans)
		return;

	vf_data->vf_vlans = vf_vlans;
	vf_data->vf_vlans->ce_refcnt++;
	vf_data->ce_mask |= SRIOV_ATTR_VLAN;

	return;
}

/**
 * Allocate a SRIOV VF VLAN object
 * @param vf_vlans 	Pointer to store VLAN object at
 * @param vlan_count 	Number of VLANs that will be stored in VLAN object
 *
 * The SRIOV VF VLANs object must be returned to the sRIOV VF object with
 * rtnl_link_vf_vlan_put() when operations are done to prevent memory leaks.
 *
 * @return 0 if VLAN object is created and vf_vlans is set.
 * @return -NLE_NOMEM if object could not be allocated.
 * @return -NLE_INVAL if vlan_count is more than supported by SRIOV VF
 */
int rtnl_link_vf_vlan_alloc(nl_vf_vlans_t **vf_vlans, int vlan_count) {
	nl_vf_vlans_t *vlans;
	nl_vf_vlan_info_t *vlan_info;

	if (vlan_count > MAX_VLAN_LIST_LEN)
		return -NLE_INVAL;

	vlans = calloc(1, sizeof(*vlans));
	if (!vlans)
		return -NLE_NOMEM;

	vlan_info = calloc(vlan_count+1, sizeof(*vlan_info));
	if (!vlan_info) {
		free(vlans);
		return -NLE_NOMEM;
	}

	NL_DBG(4, "Allocated new SRIOV VF VLANs object %p\n", vlans);

	vlans->ce_refcnt = 1;
	vlans->size = vlan_count;
	vlans->vlans = vlan_info;
	*vf_vlans = vlans;

	return 0;
}

/**
 * Free an allocated SRIOV VF VLANs object
 * @param vf_vlans 	SRIOV VF VLANs object
 */
void rtnl_link_vf_vlan_free(nl_vf_vlans_t *vf_vlans) {
	if (!vf_vlans)
		return;

	if (vf_vlans->ce_refcnt > 0)
		NL_DBG(1, "Warning: Freeing SRIOV VF VLANs object in use...\n");

	NL_DBG(4, "Freed SRIOV VF object %p\n", vf_vlans);
	free(vf_vlans->vlans);
	free(vf_vlans);

	return;
}

/**
 * Return SRIOV VF VLANs object to the owning SRIOV VF object.
 * @param vf_vlans 	SRIOV VF VLANs object
 */
void rtnl_link_vf_vlan_put(nl_vf_vlans_t *vf_vlans) {
	if (!vf_vlans)
		return;

	vf_vlans->ce_refcnt--;
	NL_DBG(4, "Returned SRIOV VF VLANs object reference %p, %i remaining\n",
	       vf_vlans, vf_vlans->ce_refcnt);

	if (vf_vlans->ce_refcnt < 0)
		BUG();

	if (vf_vlans->ce_refcnt <= 0)
		rtnl_link_vf_vlan_free(vf_vlans);

	return;
}

/** @} */

/**
 * @name Utilities
 * @{
 */

static const struct trans_tbl vf_link_states[] = {
	__ADD(IFLA_VF_LINK_STATE_AUTO, autodetect),
	__ADD(IFLA_VF_LINK_STATE_ENABLE, up),
	__ADD(IFLA_VF_LINK_STATE_DISABLE, down),
};

char *rtnl_link_vf_linkstate2str(uint32_t ls, char *buf, size_t len)
{
	return __type2str(ls, buf, len, vf_link_states,
			  ARRAY_SIZE(vf_link_states));
}

int rtnl_link_vf_str2linkstate(const char *name)
{
	return __str2type(name, vf_link_states, ARRAY_SIZE(vf_link_states));
}

static const struct trans_tbl vf_vlan_proto[] = {
	__ADD(ETH_P_8021Q, 8021Q),
	__ADD(ETH_P_8021AD, 8021AD),
};

char *rtnl_link_vf_vlanproto2str(uint16_t proto, char *buf, size_t len)
{
	return __type2str(proto, buf, len, vf_vlan_proto,
			  ARRAY_SIZE(vf_vlan_proto));
}

int rtnl_link_vf_str2vlanproto(const char *name)
{
	return __str2type(name, vf_vlan_proto, ARRAY_SIZE(vf_vlan_proto));
}

/* Return a guid from a format checked string.
 * Format string must be xx:xx:xx:xx:xx:xx:xx:xx where XX can be an
 * arbitrary hex digit
 *
 * Function modified from original at iproute2/lib/utils.c:get_guid()
 * Original by Eli Cohen <eli@mellanox.com>.
 * iproute2 git commit d91fb3f4c7e4dba806541bdc90b1fb60a3581541
 */
int rtnl_link_vf_str2guid(uint64_t *guid, const char *guid_s) {
	unsigned long int tmp;
	char *endptr;
	int i;

	if (strlen(guid_s) != RTNL_VF_GUID_STR_LEN)
		return -1;

	for (i = 0; i < 7; i++) {
		if (guid_s[2 + i * 3] != ':')
			return -1;
	}

	*guid = 0;
	for (i = 0; i < 8; i++) {
		tmp = strtoul(guid_s + i * 3, &endptr, 16);
		if (endptr != guid_s + i * 3 + 2)
			return -1;

		if (tmp > 255)
			return -1;

		*guid |= tmp << (56 - 8 * i);
	}

	return 0;
}

/** @} */

/** @} */
