[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