From daefa7695928f90138d4d87c4f88a645c1a5f29b Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Thu, 21 Apr 2011 14:48:54 +0200 Subject: 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. --- lib/route/tc.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file 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; @@ -300,6 +304,33 @@ void rtnl_tc_set_link(struct rtnl_tc *tc, struct rtnl_link *link) tc->ce_mask |= TCA_ATTR_LINK | TCA_ATTR_IFINDEX; } +/** + * 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 @@ -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) { -- cgit v1.2.1