summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCong Wang <xiyou.wangcong@gmail.com>2014-04-29 17:38:30 (GMT)
committerThomas Haller <thaller@redhat.com>2014-04-30 09:08:15 (GMT)
commit0ba7e663ce3f6bd624c0b8f4dc27a33cfcb0f5d1 (patch)
tree7fecb3bbe188d274d8b281f60fdb60880bc8db15
parentf55ef93d1eb9d792af2a3b79c055ee21bf14e9ea (diff)
downloadlibnl-0ba7e663ce3f6bd624c0b8f4dc27a33cfcb0f5d1.zip
libnl-0ba7e663ce3f6bd624c0b8f4dc27a33cfcb0f5d1.tar.gz
libnl-0ba7e663ce3f6bd624c0b8f4dc27a33cfcb0f5d1.tar.bz2
veth: grab a reference for rtnl_link_veth_get_peer()
So that users could keep a refcount for the peer. The capability trick is from Thomas Haller. Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r--include/netlink/utils.h7
-rw-r--r--lib/route/link/veth.c5
-rw-r--r--lib/utils.c2
-rw-r--r--tests/test-create-veth.c1
4 files changed, 12 insertions, 3 deletions
diff --git a/include/netlink/utils.h b/include/netlink/utils.h
index 2094bb4..4c2aa19 100644
--- a/include/netlink/utils.h
+++ b/include/netlink/utils.h
@@ -90,6 +90,13 @@ enum {
NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE = 1,
#define NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE
+ /**
+ * rtnl_link_veth_get_peer() now returns a reference that is owned by the
+ * caller and must be released by the caller with rtnl_link_put().
+ */
+ NL_CAPABILITY_ROUTE_LINK_VETH_GET_PEER_OWN_REFERENCE = 2,
+#define NL_CAPABILITY_ROUTE_LINK_VETH_GET_PEER_OWN_REFERENCE NL_CAPABILITY_ROUTE_LINK_VETH_GET_PEER_OWN_REFERENCE
+
__NL_CAPABILITY_MAX
#define NL_CAPABILITY_MAX (__NL_CAPABILITY_MAX - 1)
};
diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
index 19c84f8..e7e4a26 100644
--- a/lib/route/link/veth.c
+++ b/lib/route/link/veth.c
@@ -167,7 +167,7 @@ static int veth_alloc(struct rtnl_link *link)
static void veth_free(struct rtnl_link *link)
{
- struct rtnl_link *peer = rtnl_link_veth_get_peer(link);
+ struct rtnl_link *peer = link->l_info;
if (peer) {
link->l_info = NULL;
/* avoid calling this recursively */
@@ -232,6 +232,7 @@ struct rtnl_link *rtnl_link_veth_alloc(void)
struct rtnl_link *rtnl_link_veth_get_peer(struct rtnl_link *link)
{
IS_VETH_LINK_ASSERT(link);
+ nl_object_get(OBJ_CAST(link->l_info));
return link->l_info;
}
@@ -278,7 +279,7 @@ int rtnl_link_veth_add(struct nl_sock *sock, const char *name,
if (!(link = rtnl_link_veth_alloc()))
return -NLE_NOMEM;
- peer = rtnl_link_veth_get_peer(link);
+ peer = link->l_info;
if (name && peer_name) {
rtnl_link_set_name(link, name);
diff --git a/lib/utils.c b/lib/utils.c
index 49ff120..ac36493 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -1145,7 +1145,7 @@ int nl_has_capability (int capability)
_NL_SETV((i), 3, (v3)) | _NL_SETV((i), 7, (v7)) )
_NL_SET(0,
NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE,
- 0,
+ NL_CAPABILITY_ROUTE_LINK_VETH_GET_PEER_OWN_REFERENCE,
0,
0,
0,
diff --git a/tests/test-create-veth.c b/tests/test-create-veth.c
index c0d9145..db5ab8b 100644
--- a/tests/test-create-veth.c
+++ b/tests/test-create-veth.c
@@ -33,6 +33,7 @@ int main(int argc, char *argv[])
return err;
}
printf("peer is %s\n", rtnl_link_get_name(peer));
+ rtnl_link_put(peer);
rtnl_link_put(link);
#endif
nl_close(sk);