diff options
author | Thomas Graf <tgraf@suug.ch> | 2011-04-21 14:48:54 +0200 |
---|---|---|
committer | Thomas Graf <tgraf@suug.ch> | 2011-04-21 14:48:54 +0200 |
commit | daefa7695928f90138d4d87c4f88a645c1a5f29b (patch) | |
tree | f699a943f92507060791c04fe9402faa92b8206b | |
parent | 83f14112e22d3d28dab4c88763136f2321718664 (diff) | |
download | libnl-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.
-rw-r--r-- | lib/route/tc.c | 39 |
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) { |