diff --git a/include/netlink/object-api.h b/include/netlink/object-api.h index cfd5699..ec2192b 100644 --- a/include/netlink/object-api.h +++ b/include/netlink/object-api.h @@ -336,6 +336,18 @@ struct nl_object_ops uint32_t, int); + /** + * update function + * + * Will be called when the object given by first argument + * needs to be updated with the contents of the second object + * + * The function must return 0 for success and error for failure + * to update. In case of failure its assumed that the original + * object is not touched + */ + int (*oo_update)(struct nl_object *, struct nl_object *); + char *(*oo_attrs2str)(int, char *, size_t); /** diff --git a/include/netlink/object.h b/include/netlink/object.h index bbda5f5..788ae48 100644 --- a/include/netlink/object.h +++ b/include/netlink/object.h @@ -31,6 +31,8 @@ extern int nl_object_alloc_name(const char *, struct nl_object **); extern void nl_object_free(struct nl_object *); extern struct nl_object * nl_object_clone(struct nl_object *obj); +extern int nl_object_update(struct nl_object *dst, + struct nl_object *src); extern void nl_object_get(struct nl_object *); extern void nl_object_put(struct nl_object *); extern int nl_object_shared(struct nl_object *); diff --git a/lib/cache.c b/lib/cache.c index 45a1a27..f73fedf 100644 --- a/lib/cache.c +++ b/lib/cache.c @@ -642,6 +642,17 @@ static int cache_include(struct nl_cache *cache, struct nl_object *obj, case NL_ACT_DEL: old = nl_cache_search(cache, obj); if (old) { + /* + * Some objects types might support merging the new + * object with the old existing cache object. + * Handle them first. + */ + if (nl_object_update(old, obj) == 0) { + cb(cache, old, NL_ACT_CHANGE, data); + nl_object_put(obj); + return 0; + } + nl_cache_remove(old); if (type->mt_act == NL_ACT_DEL) { if (cb) diff --git a/lib/object.c b/lib/object.c index 585189e..d58f9a7 100644 --- a/lib/object.c +++ b/lib/object.c @@ -138,6 +138,23 @@ struct nl_object *nl_object_clone(struct nl_object *obj) return new; } +/** + * Merge a cacheable object + * @arg dst object to be merged into + * @arg src new object to be merged into dst + * + * @return 0 or a negative error code. + */ +int nl_object_update(struct nl_object *dst, struct nl_object *src) +{ + struct nl_object_ops *ops = obj_ops(dst); + + if (ops->oo_update) + return ops->oo_update(dst, src); + + return -NLE_OPNOTSUPP; +} + /** * Free a cacheable object * @arg obj object to free