[PATCH 2/5] lib/route: SRIOV Clone Support

Jef Oliver jef.oliver at intel.com
Tue Nov 1 13:01:37 PDT 2016


This patch adds support for cloning SRIOV VF specific data in the
link object.

Signed-off-by: Jef Oliver <jef.oliver at intel.com>
---
 include/netlink-private/route/link/sriov.h |  1 +
 lib/route/link.c                           |  4 +++
 lib/route/link/sriov.c                     | 57 ++++++++++++++++++++++++++++++
 libnl-route-3.sym                          |  1 +
 4 files changed, 63 insertions(+)

diff --git a/include/netlink-private/route/link/sriov.h b/include/netlink-private/route/link/sriov.h
index 49e601b..ac823fa 100644
--- a/include/netlink-private/route/link/sriov.h
+++ b/include/netlink-private/route/link/sriov.h
@@ -20,6 +20,7 @@
 extern "C" {
 #endif
 
+extern int rtnl_link_sriov_clone(struct rtnl_link *, struct rtnl_link *);
 extern void rtnl_link_sriov_free_data(struct rtnl_link *);
 extern int rtnl_link_sriov_parse_vflist(struct rtnl_link *, struct nlattr **);
 
diff --git a/lib/route/link.c b/lib/route/link.c
index ba871af..5610ee0 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -315,6 +315,10 @@ static int link_clone(struct nl_object *_dst, struct nl_object *_src)
 		if (!(dst->l_phys_port_id = nl_data_clone(src->l_phys_port_id)))
 			return -NLE_NOMEM;
 
+	if (src->ce_mask & LINK_ATTR_VF_LIST)
+		if ((err = rtnl_link_sriov_clone(dst, src)) < 0)
+			return err;
+
 	return 0;
 }
 
diff --git a/lib/route/link/sriov.c b/lib/route/link/sriov.c
index 528de83..1acd69e 100644
--- a/lib/route/link/sriov.c
+++ b/lib/route/link/sriov.c
@@ -79,6 +79,63 @@ static struct nla_policy sriov_stats_policy[IFLA_VF_STATS_MAX+1] = {
 
 /** @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 (!(err = 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)
+				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;
+
+			dst_vlans = calloc(1, sizeof(dst_vlans));
+			if (!dst_vlans)
+				return -NLE_NOMEM;
+			memcpy(dst_vlans, src_vlans, sizeof(nl_vf_vlans_t));
+
+			dst_vlan_info = calloc(dst_vlans->size + 1,
+					       sizeof(dst_vlan_info));
+			if (!dst_vlan_info)
+				return -NLE_NOMEM;
+			memcpy(dst_vlan_info, src_vlan_info,
+			       dst_vlans->size * sizeof(dst_vlan_info));
+
+			dst_vlans->vlans = 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;
+}
+
 /* Free stored SRIOV VF data */
 void rtnl_link_sriov_free_data(struct rtnl_link *link) {
 	int err = 0;
diff --git a/libnl-route-3.sym b/libnl-route-3.sym
index 819b82b..b455ea5 100644
--- a/libnl-route-3.sym
+++ b/libnl-route-3.sym
@@ -967,6 +967,7 @@ global:
 	rtnl_link_has_vf_list;
 	rtnl_link_set_vf_list;
 	rtnl_link_unset_vf_list;
+	rtnl_link_sriov_clone;
 	rtnl_link_sriov_free_data;
 	rtnl_link_sriov_parse_vflist;
 	rtnl_link_vf_alloc;
-- 
2.10.1




More information about the libnl mailing list