]> granicus.if.org Git - libnl/commitdiff
cache: provide safe variant of nl_cache_mngt_require() and use it
authorThomas Graf <tgraf@suug.ch>
Fri, 16 Nov 2012 00:11:55 +0000 (01:11 +0100)
committerThomas Graf <tgraf@suug.ch>
Fri, 16 Nov 2012 00:11:55 +0000 (01:11 +0100)
This makes runtime removal of cache operations possible if non-safe
API is not in use by application. The non-safe API will be removed
in the next major version.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
14 files changed:
include/netlink-local.h
include/netlink/cache.h
lib/cache.c
lib/cache_mngt.c
lib/netfilter/log_msg_obj.c
lib/netfilter/queue_msg_obj.c
lib/route/addr.c
lib/route/link.c
lib/route/neigh.c
lib/route/neightbl.c
lib/route/nexthop.c
lib/route/route_obj.c
lib/route/tc.c
src/nl-addr-list.c

index 2bfae3efdade90796c917a569c9abdd28861ae34..b891d8cb368cad9be81d6596db73290f5e665e84 100644 (file)
@@ -117,14 +117,6 @@ extern int __str2flags(const char *, const struct trans_tbl *, size_t);
 
 extern void dump_from_ops(struct nl_object *, struct nl_dump_params *);
 
-static inline struct nl_cache *dp_cache(struct nl_object *obj)
-{
-       if (obj->ce_cache == NULL)
-               return nl_cache_mngt_require(obj->ce_ops->oo_name);
-
-       return obj->ce_cache;
-}
-
 static inline int nl_cb_call(struct nl_cb *cb, int type, struct nl_msg *msg)
 {
        return cb->cb_set[type](msg, cb->cb_args[type]);
index f193c76c5cae659c8efb03961758e44644e604a1..ac03842ed059cd582ff6d6689b84574f341dd490 100644 (file)
@@ -52,6 +52,7 @@ extern struct nl_cache *      nl_cache_clone(struct nl_cache *);
 extern void                    nl_cache_clear(struct nl_cache *);
 extern void                    nl_cache_get(struct nl_cache *);
 extern void                    nl_cache_free(struct nl_cache *);
+extern void                    nl_cache_put(struct nl_cache *cache);
 
 /* Cache modification */
 extern int                     nl_cache_add(struct nl_cache *,
@@ -118,6 +119,7 @@ extern int                  nl_cache_mngt_unregister(struct nl_cache_ops *);
 extern void                    nl_cache_mngt_provide(struct nl_cache *);
 extern void                    nl_cache_mngt_unprovide(struct nl_cache *);
 extern struct nl_cache *       nl_cache_mngt_require(const char *);
+extern struct nl_cache *       nl_cache_mngt_require_safe(const char *);
 extern struct nl_cache *       __nl_cache_mngt_require(const char *);
 
 struct nl_cache_mngr;
index aa17ad8ad4fc559c61c528b25ffa689fca584ecf..415e4714723f9bea55e548b017a8091499c93458 100644 (file)
@@ -410,6 +410,11 @@ void nl_cache_free(struct nl_cache *cache)
                __nl_cache_free(cache);
 }
 
+void nl_cache_put(struct nl_cache *cache)
+{
+       return nl_cache_free(cache);
+}
+
 /** @} */
 
 /**
index 914ab9b067b43c929d7cc1a6e6c23056a1eb93b8..fbb702f68d8f851d2a38a56ff3582cdb3da6e77c 100644 (file)
@@ -390,14 +390,15 @@ struct nl_cache *__nl_cache_mngt_require(const char *name)
 }
 
 /**
- * Demand the use of a global cache
- * @arg name           name of the required object type
+ * Return cache previously provided via nl_cache_mngt_provide()
+ * @arg name           Name of cache to lookup
  *
- * Trys to find a cache of the specified type for global
- * use.
+ * @attention This function is not safe, it does not increment the reference
+ *            counter. Please use nl_cache_mngt_require_safe().
+ *
+ * @see nl_cache_mngt_require_safe()
  *
- * @return A cache provided by another subsystem of the
- *         specified type marked to be available.
+ * @return Pointer to cache or NULL if none registered
  */
 struct nl_cache *nl_cache_mngt_require(const char *name)
 {
@@ -412,6 +413,25 @@ struct nl_cache *nl_cache_mngt_require(const char *name)
        return cache;
 }
 
+/**
+ * Return cache previously provided via nl_cache_mngt_provide()
+ * @arg name           Name of cache to lookup
+ *
+ * @note The reference counter of the returned cache is incremented
+ *       and must be decremented after use with nl_cache_put().
+ *
+ * @return Pointer to cache or NULL if none registered
+ */
+struct nl_cache *nl_cache_mngt_require_safe(const char *name)
+{
+       struct nl_cache *cache;
+
+       if ((cache = nl_cache_mngt_require(name)))
+               nl_cache_get(cache);
+       
+       return cache;
+}
+
 /** @} */
 
 /** @} */
index d2cde4e0575d4cf90f5ce34e1a014a3b5ed06521..d2ad0ff3852e4e0447965230b339e25780a0f426 100644 (file)
@@ -76,7 +76,7 @@ static void log_msg_dump(struct nl_object *a, struct nl_dump_params *p)
        struct nl_cache *link_cache;
        char buf[64];
 
-       link_cache = nl_cache_mngt_require("route/link");
+       link_cache = nl_cache_mngt_require_safe("route/link");
 
        nl_new_line(p);
 
@@ -167,6 +167,9 @@ static void log_msg_dump(struct nl_object *a, struct nl_dump_params *p)
                nl_dump(p, "SEQGLOBAL=%d ", msg->log_msg_seq_global);
 
        nl_dump(p, "\n");
+
+       if (link_cache)
+               nl_cache_put(link_cache);
 }
 
 /**
index 33305ed8ac65f470c2cc92c36db1f1ea0bbdda3a..bfaafc54810ae098dcca612946292db17718cd50 100644 (file)
@@ -66,7 +66,7 @@ static void nfnl_queue_msg_dump(struct nl_object *a, struct nl_dump_params *p)
        struct nl_cache *link_cache;
        char buf[64];
 
-       link_cache = nl_cache_mngt_require("route/link");
+       link_cache = nl_cache_mngt_require_safe("route/link");
 
        nl_new_line(p);
 
@@ -152,6 +152,9 @@ static void nfnl_queue_msg_dump(struct nl_object *a, struct nl_dump_params *p)
                                         buf, sizeof(buf)));
 
        nl_dump(p, "\n");
+
+       if (link_cache)
+               nl_cache_put(link_cache);
 }
 
 /**
index 7e29529517ca5832062b8d7e6b678a3df1f28caa..c5e14bbf789ab7f5e516e9437c5533bfde6c52e4 100644 (file)
@@ -332,7 +332,7 @@ static void addr_dump_line(struct nl_object *obj, struct nl_dump_params *p)
        struct nl_cache *link_cache;
        char buf[128];
 
-       link_cache = nl_cache_mngt_require("route/link");
+       link_cache = nl_cache_mngt_require_safe("route/link");
 
        if (addr->ce_mask & ADDR_ATTR_LOCAL)
                nl_dump_line(p, "%s",
@@ -361,6 +361,9 @@ static void addr_dump_line(struct nl_object *obj, struct nl_dump_params *p)
                nl_dump(p, " <%s>", buf);
 
        nl_dump(p, "\n");
+
+       if (link_cache)
+               nl_cache_put(link_cache);
 }
 
 static void addr_dump_details(struct nl_object *obj, struct nl_dump_params *p)
index b378f30be37c1d61611f158694184dc36bb1ab3d..1cecd54013aed4443bdbfc87fbc18331059bdc6c 100644 (file)
@@ -581,7 +581,7 @@ static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
 static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)
 {
        char buf[128];
-       struct nl_cache *cache = dp_cache(obj);
+       struct nl_cache *cache = obj->ce_cache;
        struct rtnl_link *link = (struct rtnl_link *) obj;
 
        nl_dump_line(p, "%s %s ", link->l_name,
index 4b5893a052488421963f0d15f166b946133dc408..4a85a851cf6fb6f61f4426e1edbc34a4844cb359 100644 (file)
@@ -401,7 +401,7 @@ int rtnl_neigh_parse(struct nlmsghdr *n, struct rtnl_neigh **result)
         * Get the bridge index for AF_BRIDGE family entries
         */
        if (neigh->n_family == AF_BRIDGE) {
-               struct nl_cache *lcache = nl_cache_mngt_require("route/link");
+               struct nl_cache *lcache = nl_cache_mngt_require_safe("route/link");
                if (lcache ) {
                        struct rtnl_link *link = rtnl_link_get(lcache,
                                                        neigh->n_ifindex);
@@ -410,6 +410,8 @@ int rtnl_neigh_parse(struct nlmsghdr *n, struct rtnl_neigh **result)
                                rtnl_link_put(link);
                                neigh->ce_mask |= NEIGH_ATTR_MASTER;
                        }
+
+                       nl_cache_put(lcache);
                }
        }
 
@@ -436,7 +438,7 @@ static void neigh_dump_line(struct nl_object *a, struct nl_dump_params *p)
        struct nl_cache *link_cache;
        char state[128], flags[64];
 
-       link_cache = nl_cache_mngt_require("route/link");
+       link_cache = nl_cache_mngt_require_safe("route/link");
 
        if (n->n_family != AF_BRIDGE)
                nl_dump_line(p, "%s ", nl_addr2str(n->n_dst, dst, sizeof(dst)));
@@ -462,6 +464,9 @@ static void neigh_dump_line(struct nl_object *a, struct nl_dump_params *p)
        if (state[0] || flags[0])
                nl_dump(p, ">");
        nl_dump(p, "\n");
+
+       if (link_cache)
+               nl_cache_put(link_cache);
 }
 
 static void neigh_dump_details(struct nl_object *a, struct nl_dump_params *p)
index 1efa5cb61605146e93cb642cb8d48340b0ce7898..509617b97b9bb9ed65623d193ee1faaea015a811 100644 (file)
@@ -237,7 +237,7 @@ static void neightbl_dump_line(struct nl_object *arg, struct nl_dump_params *p)
        if (ntbl->nt_parms.ntp_mask & NEIGHTBLPARM_ATTR_IFINDEX) {
                struct nl_cache *link_cache;
                
-               link_cache = nl_cache_mngt_require("route/link");
+               link_cache = nl_cache_mngt_require_safe("route/link");
 
                if (link_cache) {
                        char buf[32];
@@ -245,6 +245,7 @@ static void neightbl_dump_line(struct nl_object *arg, struct nl_dump_params *p)
                                rtnl_link_i2name(link_cache,
                                                 ntbl->nt_parms.ntp_ifindex,
                                                 buf, sizeof(buf)));
+                       nl_cache_put(link_cache);
                } else
                        nl_dump(p, "<%u> ", ntbl->nt_parms.ntp_ifindex);
        } else
index 189bccd15e830bbcc158c807deaaecc9117534fd..9990c51271b55bd845f3629319785b0065dce23b 100644 (file)
@@ -109,7 +109,7 @@ static void nh_dump_line(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
        struct nl_cache *link_cache;
        char buf[128];
 
-       link_cache = nl_cache_mngt_require("route/link");
+       link_cache = nl_cache_mngt_require_safe("route/link");
 
        nl_dump(dp, "via");
 
@@ -128,6 +128,9 @@ static void nh_dump_line(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
        }
 
        nl_dump(dp, " ");
+
+       if (link_cache)
+               nl_cache_put(link_cache);
 }
 
 static void nh_dump_details(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
@@ -135,7 +138,7 @@ static void nh_dump_details(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
        struct nl_cache *link_cache;
        char buf[128];
 
-       link_cache = nl_cache_mngt_require("route/link");
+       link_cache = nl_cache_mngt_require_safe("route/link");
 
        nl_dump(dp, "nexthop");
 
@@ -164,6 +167,9 @@ static void nh_dump_details(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
        if (nh->ce_mask & NH_ATTR_FLAGS)
                nl_dump(dp, " <%s>", rtnl_route_nh_flags2str(nh->rtnh_flags,
                                                        buf, sizeof(buf)));
+
+       if (link_cache)
+               nl_cache_put(link_cache);
 }
 
 void rtnl_route_nh_dump(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
index 0ee9ca02aa2afc5632ef485d1f6c20a20153eb84..cc29746b81ba3bfc0a800b619f98e309b3909b02 100644 (file)
@@ -210,7 +210,7 @@ static void route_dump_details(struct nl_object *a, struct nl_dump_params *p)
        char buf[128];
        int i;
 
-       link_cache = nl_cache_mngt_require("route/link");
+       link_cache = nl_cache_mngt_require_safe("route/link");
 
        route_dump_line(a, p);
        nl_dump_line(p, "    ");
@@ -271,6 +271,9 @@ static void route_dump_details(struct nl_object *a, struct nl_dump_params *p)
                                        r->rt_metrics[i]);
                nl_dump(p, "]\n");
        }
+
+       if (link_cache)
+               nl_cache_put(link_cache);
 }
 
 static void route_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
index 6c72c158f40f65327f20123de3370134e39f266d..5a0b7839f26c21b45db3a74f895b3c6f57fcbaba 100644 (file)
@@ -822,7 +822,7 @@ void rtnl_tc_dump_line(struct nl_object *obj, struct nl_dump_params *p)
 
        nl_dump(p, "%s ", tc->tc_kind);
 
-       if ((link_cache = nl_cache_mngt_require("route/link"))) {
+       if ((link_cache = nl_cache_mngt_require_safe("route/link"))) {
                nl_dump(p, "dev %s ",
                        rtnl_link_i2name(link_cache, tc->tc_ifindex,
                                         buf, sizeof(buf)));
@@ -837,6 +837,9 @@ void rtnl_tc_dump_line(struct nl_object *obj, struct nl_dump_params *p)
 
        tc_dump(tc, NL_DUMP_LINE, p);
        nl_dump(p, "\n");
+
+       if (link_cache)
+               nl_cache_put(link_cache);
 }
 
 void rtnl_tc_dump_details(struct nl_object *obj, struct nl_dump_params *p)
index 5044d5ce80f5497c435fd8e9f96abbba39ac2760..20995a841e3b4ec0ee41c32bee36466552dd5f73 100644 (file)
@@ -65,7 +65,7 @@ static void env_dump(struct nl_object *obj, void *arg)
                     nl_addr2str(rtnl_addr_get_local(addr), buf, sizeof(buf)));
 
        nl_dump_line(p, "%s_IFINDEX=%u\n", pfx, rtnl_addr_get_ifindex(addr));
-       link_cache = nl_cache_mngt_require("route/link");
+       link_cache = nl_cache_mngt_require_safe("route/link");
        if (link_cache)
                nl_dump_line(p, "%s_IFNAME=%s\n", pfx,
                             rtnl_link_i2name(link_cache,
@@ -94,6 +94,9 @@ static void env_dump(struct nl_object *obj, void *arg)
        nl_dump_line(p, "%s_CACHEINFO_VALID=%u\n", pfx,
                     rtnl_addr_get_valid_lifetime(addr));
 
+       if (link_cache)
+               nl_cache_put(link_cache);
+
 #if 0
        if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
                struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;