]> git.ipfire.org Git - thirdparty/libnl.git/commitdiff
Provide rtnl_tc_get_link() and fix link refcnt
authorThomas Graf <tgraf@suug.ch>
Thu, 21 Apr 2011 12:48:54 +0000 (14:48 +0200)
committerThomas Graf <tgraf@suug.ch>
Thu, 21 Apr 2011 12:48:54 +0000 (14:48 +0200)
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

index 0aa44f753a7984b5b4354eb4525330e73a41b9c4..03920aa696a28141aa2ea25254a869a05e69e7bc 100644 (file)
@@ -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) {