summaryrefslogtreecommitdiff
path: root/lib/route/tc.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2011-04-21 14:48:54 +0200
committerThomas Graf <tgraf@suug.ch>2011-04-21 14:48:54 +0200
commitdaefa7695928f90138d4d87c4f88a645c1a5f29b (patch)
treef699a943f92507060791c04fe9402faa92b8206b /lib/route/tc.c
parent83f14112e22d3d28dab4c88763136f2321718664 (diff)
downloadlibnl-daefa7695928f90138d4d87c4f88a645c1a5f29b.tar.gz
Provide rtnl_tc_get_link() and fix link refcnt
Adds rtnl_tc_get_link() returning the link associated with a tc object. Don't clone link associated with tc object when cloning the tc object, refer to same link instead and bump refcnt. Fix refcnt leak when assigning link in msg parser.
Diffstat (limited to 'lib/route/tc.c')
-rw-r--r--lib/route/tc.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/lib/route/tc.c b/lib/route/tc.c
index 0aa44f7..03920aa 100644
--- a/lib/route/tc.c
+++ b/lib/route/tc.c
@@ -179,8 +179,12 @@ compat_xstats:
if ((link_cache = nl_cache_mngt_require("route/link"))) {
struct rtnl_link *link;
- if ((link = rtnl_link_get(link_cache, tc->tc_ifindex)))
+ if ((link = rtnl_link_get(link_cache, tc->tc_ifindex))) {
rtnl_tc_set_link(tc, link);
+
+ /* rtnl_tc_set_link incs refcnt */
+ rtnl_link_put(link);
+ }
}
return 0;
@@ -301,6 +305,33 @@ void rtnl_tc_set_link(struct rtnl_tc *tc, struct rtnl_link *link)
}
/**
+ * Get link of traffic control object
+ * @arg tc traffic control object
+ * @arg link link object
+ *
+ * Returns the link of a traffic control object. The link is only
+ * returned if it has been set before via rtnl_tc_set_link() or
+ * if a link cache was available while parsing the tc object. This
+ * function may still return NULL even if an ifindex is assigned to
+ * the tc object. It will _not_ look up the link by itself.
+ *
+ * @note The returned link will have its reference counter incremented.
+ * It is in the responsibility of the caller to return the
+ * reference.
+ *
+ * @return link object or NULL if not set.
+ */
+struct rtnl_link *rtnl_tc_get_link(struct rtnl_tc *tc)
+{
+ if (tc->tc_link) {
+ nl_object_get(OBJ_CAST(tc->tc_link));
+ return tc->tc_link;
+ }
+
+ return NULL;
+}
+
+/**
* Set the Maximum Transmission Unit (MTU) of traffic control object
* @arg tc traffic control object
* @arg mtu largest packet size expected
@@ -720,10 +751,8 @@ int rtnl_tc_clone(struct nl_object *dstobj, struct nl_object *srcobj)
struct rtnl_tc_ops *ops;
if (src->tc_link) {
- dst->tc_link = (struct rtnl_link *)
- nl_object_clone(OBJ_CAST(src->tc_link));
- if (!dst->tc_link)
- return -NLE_NOMEM;
+ nl_object_get(OBJ_CAST(src->tc_link));
+ dst->tc_link = src->tc_link;
}
if (src->tc_opts) {