summaryrefslogtreecommitdiffstats
path: root/lib/route
diff options
context:
space:
mode:
authorCong Wang <xiyou.wangcong@gmail.com>2014-04-02 01:03:32 (GMT)
committerThomas Haller <thaller@redhat.com>2014-04-09 07:10:19 (GMT)
commit3700bf56fabce08ca40b71dfed0885e556e23423 (patch)
treed42102a30241972d88ec8864d38f9e7a3987e1ae /lib/route
parent6c8f67b87a6a9a9f8f2579cfebbed9b3844cd4fc (diff)
downloadlibnl-3700bf56fabce08ca40b71dfed0885e556e23423.zip
libnl-3700bf56fabce08ca40b71dfed0885e556e23423.tar.gz
libnl-3700bf56fabce08ca40b71dfed0885e556e23423.tar.bz2
veth: use nl_object_clone() to deep copy rtnl_link object
Currently we use memcpy() to copy the peer rtnl_link for veth device, this is wrong, we should do deep copy by calling nl_object_clone() recursively. We should be careful and need to make sure we only call it once. Acked-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: Thomas Haller <thaller@redhat.com>
Diffstat (limited to 'lib/route')
-rw-r--r--lib/route/link/veth.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
index 2ce3cff..b2cfa54 100644
--- a/lib/route/link/veth.c
+++ b/lib/route/link/veth.c
@@ -98,19 +98,19 @@ static void veth_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
static int veth_clone(struct rtnl_link *dst, struct rtnl_link *src)
{
- struct rtnl_link *dst_peer , *src_peer = src->l_info;
- int err;
-
- dst_peer = dst->l_info = rtnl_link_alloc();
- if (!dst_peer || !src_peer)
- return -NLE_NOMEM;
- if ((err = rtnl_link_set_type(dst, "veth")) < 0) {
- rtnl_link_put(dst_peer);
- return err;
+ struct rtnl_link *dst_peer = NULL, *src_peer = src->l_info;
+
+ /* we are calling nl_object_clone() recursively, this should
+ * happen only once */
+ if (src_peer) {
+ src_peer->l_info = NULL;
+ dst_peer = (struct rtnl_link *)nl_object_clone(OBJ_CAST(src_peer));
+ if (!dst_peer)
+ return -NLE_NOMEM;
+ src_peer->l_info = src;
+ dst_peer->l_info = dst;
}
-
- memcpy(dst_peer, src_peer, sizeof(struct rtnl_link));
-
+ dst->l_info = dst_peer;
return 0;
}