diff options
author | Cong Wang <xiyou.wangcong@gmail.com> | 2014-04-02 01:03:32 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-04-09 07:10:19 (GMT) |
commit | 3700bf56fabce08ca40b71dfed0885e556e23423 (patch) | |
tree | d42102a30241972d88ec8864d38f9e7a3987e1ae /lib/route | |
parent | 6c8f67b87a6a9a9f8f2579cfebbed9b3844cd4fc (diff) | |
download | libnl-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.c | 24 |
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; } |