[PATCH v3] veth: grab a reference for rtnl_link_veth_get_peer()

Cong Wang xiyou.wangcong at gmail.com
Tue Apr 29 10:38:30 PDT 2014


So that users could keep a refcount for the peer.
The capability trick is from Thomas Haller.

Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
---
 include/netlink/utils.h  | 7 +++++++
 lib/route/link/veth.c    | 5 +++--
 lib/utils.c              | 2 +-
 tests/test-create-veth.c | 1 +
 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);
-- 
1.8.3.1




More information about the libnl mailing list