2 * netlink/object-api.c Object API
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation version 2.1
9 * Copyright (c) 2003-2007 Thomas Graf <tgraf@suug.ch>
12 #ifndef NETLINK_OBJECT_API_H_
13 #define NETLINK_OBJECT_API_H_
15 #include <netlink/netlink.h>
16 #include <netlink/utils.h>
24 * @defgroup object_api Object API
27 * @par 1) Object Definition
29 * // Define your object starting with the common object header
35 * // Fill out the object operations structure
36 * struct nl_object_ops my_ops = {
37 * .oo_name = "my_obj",
38 * .oo_size = sizeof(struct my_obj),
41 * // At this point the object can be allocated, you may want to provide a
42 * // separate _alloc() function to ease allocting objects of this kind.
43 * struct nl_object *obj = nl_object_alloc(&my_ops);
45 * // And release it again...
49 * @par 2) Allocating additional data
51 * // You may require to allocate additional data and store it inside
52 * // object, f.e. assuming there is a field `ptr'.
58 * // And at some point you may assign allocated data to this field:
59 * my_obj->ptr = calloc(1, ...);
61 * // In order to not introduce any memory leaks you have to release
62 * // this data again when the last reference is given back.
63 * static void my_obj_free_data(struct nl_object *obj)
65 * struct my_obj *my_obj = nl_object_priv(obj);
70 * // Also when the object is cloned, you must ensure for your pointer
71 * // stay valid even if one of the clones is freed by either making
72 * // a clone as well or increase the reference count.
73 * static int my_obj_clone(struct nl_object *src, struct nl_object *dst)
75 * struct my_obj *my_src = nl_object_priv(src);
76 * struct my_obj *my_dst = nl_object_priv(dst);
79 * dst->ptr = calloc(1, ...);
80 * memcpy(dst->ptr, src->ptr, ...);
84 * struct nl_object_ops my_ops = {
86 * .oo_free_data = my_obj_free_data,
87 * .oo_clone = my_obj_clone,
91 * @par 3) Object Dumping
93 * static int my_obj_dump_detailed(struct nl_object *obj,
94 * struct nl_dump_params *params)
96 * struct my_obj *my_obj = nl_object_priv(obj);
98 * // It is absolutely essential to use nl_dump() when printing
99 * // any text to make sure the dumping parameters are respected.
100 * nl_dump(params, "Obj Integer: %d\n", my_obj->my_int);
102 * // Before we can dump the next line, make sure to prefix
103 * // this line correctly.
104 * nl_new_line(params);
106 * // You may also split a line into multiple nl_dump() calls.
107 * nl_dump(params, "String: %s ", my_obj->my_string);
108 * nl_dump(params, "String-2: %s\n", my_obj->another_string);
111 * struct nl_object_ops my_ops = {
113 * .oo_dump[NL_DUMP_FULL] = my_obj_dump_detailed,
117 * @par 4) Object Attributes
119 * // The concept of object attributes is optional but can ease the typical
120 * // case of objects that have optional attributes, e.g. a route may have a
121 * // nexthop assigned but it is not required to.
123 * // The first step to define your object specific bitmask listing all
125 * #define MY_ATTR_FOO (1<<0)
126 * #define MY_ATTR_BAR (1<<1)
128 * // When assigning an optional attribute to the object, make sure
129 * // to mark its availability.
130 * my_obj->foo = 123123;
131 * my_obj->ce_mask |= MY_ATTR_FOO;
133 * // At any time you may use this mask to check for the availability
134 * // of the attribute, e.g. while dumping
135 * if (my_obj->ce_mask & MY_ATTR_FOO)
136 * nl_dump(params, "foo %d ", my_obj->foo);
138 * // One of the big advantages of this concept is that it allows for
139 * // standardized comparisons which make it trivial for caches to
140 * // identify unique objects by use of unified comparison functions.
141 * // In order for it to work, your object implementation must provide
142 * // a comparison function and define a list of attributes which
143 * // combined together make an object unique.
145 * static int my_obj_compare(struct nl_object *_a, struct nl_object *_b,
146 * uint32_t attrs, int flags)
148 * struct my_obj *a = nl_object_priv(_a):
149 * struct my_obj *b = nl_object_priv(_b):
152 * // We help ourselves in defining our own DIFF macro which will
153 * // call ATTR_DIFF() on both objects which will make sure to only
154 * // compare the attributes if required.
155 * #define MY_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, MY_ATTR_##ATTR, a, b, EXPR)
157 * // Call our own diff macro for each attribute to build a bitmask
158 * // representing the attributes which mismatch.
159 * diff |= MY_DIFF(FOO, a->foo != b->foo)
160 * diff |= MY_DIFF(BAR, strcmp(a->bar, b->bar))
165 * // In order to identify identical objects with differing attributes
166 * // you must specify the attributes required to uniquely identify
167 * // your object. Make sure to not include too many attributes, this
168 * // list is used when caches look for an old version of an object.
169 * struct nl_object_ops my_ops = {
171 * .oo_id_attrs = MY_ATTR_FOO,
172 * .oo_compare = my_obj_compare,
179 * Common Object Header
181 * This macro must be included as first member in every object
182 * definition to allow objects to be cached.
184 #define NLHDR_COMMON \
186 struct nl_object_ops * ce_ops; \
187 struct nl_cache * ce_cache; \
188 struct nl_list_head ce_list; \
194 * Return true if attribute is available in both objects
196 * @arg B another object
197 * @arg ATTR attribute bit
199 * @return True if the attribute is available, otherwise false is returned.
201 #define AVAILABLE(A, B, ATTR) (((A)->ce_mask & (B)->ce_mask) & (ATTR))
204 * Return true if attributes mismatch
206 * @arg B another object
207 * @arg ATTR attribute bit
208 * @arg EXPR Comparison expression
210 * This function will check if the attribute in question is available
211 * in both objects, if not this will count as a mismatch.
213 * If available the function will execute the expression which must
214 * return true if the attributes mismatch.
216 * @return True if the attribute mismatch, or false if they match.
218 #define ATTR_MISMATCH(A, B, ATTR, EXPR) (!AVAILABLE(A, B, ATTR) || (EXPR))
221 * Return attribute bit if attribute does not match
222 * @arg LIST list of attributes to be compared
223 * @arg ATTR attribute bit
225 * @arg B another object
226 * @arg EXPR Comparison expression
228 * This function will check if the attribute in question is available
229 * in both objects, if not this will count as a mismatch.
231 * If available the function will execute the expression which must
232 * return true if the attributes mismatch.
234 * In case the attributes mismatch, the attribute is returned, otherwise
238 * diff |= ATTR_DIFF(attrs, MY_ATTR_FOO, a, b, a->foo != b->foo);
241 #define ATTR_DIFF(LIST, ATTR, A, B, EXPR) \
243 if (((LIST) & (ATTR)) && ATTR_MISMATCH(A, B, ATTR, EXPR)) \
254 * Unique name of object type
256 * Must be in the form family/name, e.g. "route/addr"
260 /** Size of object including its header */
263 /* List of attributes needed to uniquely identify the object */
264 uint32_t oo_id_attrs
;
267 * Constructor function
269 * Will be called when a new object of this type is allocated.
270 * Can be used to initialize members such as lists etc.
272 void (*oo_constructor
)(struct nl_object
*);
275 * Destructor function
277 * Will be called when an object is freed. Must free all
278 * resources which may have been allocated as part of this
281 void (*oo_free_data
)(struct nl_object
*);
286 * Will be called when an object needs to be cloned. Please
287 * note that the generic object code will make an exact
288 * copy of the object first, therefore you only need to take
289 * care of members which require reference counting etc.
291 * May return a negative error code to abort cloning.
293 int (*oo_clone
)(struct nl_object
*, struct nl_object
*);
298 * Will be called when an object is dumped. The implementations
299 * have to use nl_dump(), nl_dump_line(), and nl_new_line() to
302 * The functions must return the number of lines printed.
304 void (*oo_dump
[NL_DUMP_MAX
+1])(struct nl_object
*,
305 struct nl_dump_params
*);
308 * Comparison function
310 * Will be called when two objects of the same type are
311 * compared. It takes the two objects in question, an object
312 * specific bitmask defining which attributes should be
313 * compared and flags to control the behaviour.
315 * The function must return a bitmask with the relevant bit
316 * set for each attribute that mismatches.
318 int (*oo_compare
)(struct nl_object
*, struct nl_object
*,
322 char *(*oo_attrs2str
)(int, char *, size_t);
This page took 0.056434 seconds and 5 git commands to generate.