libnl 1.1.4
object-api.h
1/*
2 * netlink/object-api.c Object API
3 *
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
7 * of the License.
8 *
9 * Copyright (c) 2003-2007 Thomas Graf <tgraf@suug.ch>
10 */
11
12#ifndef NETLINK_OBJECT_API_H_
13#define NETLINK_OBJECT_API_H_
14
15#include <netlink/netlink.h>
16#include <netlink/utils.h>
17
18#ifdef __cplusplus
19extern "C" {
20#endif
21
22/**
23 * @ingroup object
24 * @defgroup object_api Object API
25 * @brief
26 *
27 * @par 1) Object Definition
28 * @code
29 * // Define your object starting with the common object header
30 * struct my_obj {
31 * NLHDR_COMMON
32 * int my_data;
33 * };
34 *
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),
39 * };
40 *
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);
44 *
45 * // And release it again...
46 * nl_object_put(obj);
47 * @endcode
48 *
49 * @par 2) Allocating additional data
50 * @code
51 * // You may require to allocate additional data and store it inside
52 * // object, f.e. assuming there is a field `ptr'.
53 * struct my_obj {
54 * NLHDR_COMMON
55 * void * ptr;
56 * };
57 *
58 * // And at some point you may assign allocated data to this field:
59 * my_obj->ptr = calloc(1, ...);
60 *
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)
64 * {
65 * struct my_obj *my_obj = nl_object_priv(obj);
66 *
67 * free(my_obj->ptr);
68 * }
69 *
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)
74 * {
75 * struct my_obj *my_src = nl_object_priv(src);
76 * struct my_obj *my_dst = nl_object_priv(dst);
77 *
78 * if (src->ptr) {
79 * dst->ptr = calloc(1, ...);
80 * memcpy(dst->ptr, src->ptr, ...);
81 * }
82 * }
83 *
84 * struct nl_object_ops my_ops = {
85 * ...
86 * .oo_free_data = my_obj_free_data,
87 * .oo_clone = my_obj_clone,
88 * };
89 * @endcode
90 *
91 * @par 3) Object Dumping
92 * @code
93 * static int my_obj_dump_detailed(struct nl_object *obj,
94 * struct nl_dump_params *params)
95 * {
96 * struct my_obj *my_obj = nl_object_priv(obj);
97 * int line = 1; // We will print at least one line for sure
98 *
99 * // It is absolutely essential to use nl_dump() when printing
100 * // any text to make sure the dumping parameters are respected.
101 * nl_dump(params, "Obj Integer: %d\n", my_obj->my_int);
102 *
103 * // Before we can dump the next line, make sure to prefix
104 * // this line correctly.
105 * nl_new_line(params, line++);
106 *
107 * // You may also split a line into multiple nl_dump() calls.
108 * nl_dump(params, "String: %s ", my_obj->my_string);
109 * nl_dump(params, "String-2: %s\n", my_obj->another_string);
110 *
111 * // Return the number of lines dumped
112 * return line;
113 * }
114 *
115 * struct nl_object_ops my_ops = {
116 * ...
117 * .oo_dump[NL_DUMP_FULL] = my_obj_dump_detailed,
118 * };
119 * @endcode
120 *
121 * @par 4) Object Attributes
122 * @code
123 * // The concept of object attributes is optional but can ease the typical
124 * // case of objects that have optional attributes, e.g. a route may have a
125 * // nexthop assigned but it is not required to.
126 *
127 * // The first step to define your object specific bitmask listing all
128 * // attributes
129 * #define MY_ATTR_FOO (1<<0)
130 * #define MY_ATTR_BAR (1<<1)
131 *
132 * // When assigning an optional attribute to the object, make sure
133 * // to mark its availability.
134 * my_obj->foo = 123123;
135 * my_obj->ce_mask |= MY_ATTR_FOO;
136 *
137 * // At any time you may use this mask to check for the availability
138 * // of the attribute, e.g. while dumping
139 * if (my_obj->ce_mask & MY_ATTR_FOO)
140 * nl_dump(params, "foo %d ", my_obj->foo);
141 *
142 * // One of the big advantages of this concept is that it allows for
143 * // standardized comparisons which make it trivial for caches to
144 * // identify unique objects by use of unified comparison functions.
145 * // In order for it to work, your object implementation must provide
146 * // a comparison function and define a list of attributes which
147 * // combined together make an object unique.
148 *
149 * static int my_obj_compare(struct nl_object *_a, struct nl_object *_b,
150 * uint32_t attrs, int flags)
151 * {
152 * struct my_obj *a = nl_object_priv(_a):
153 * struct my_obj *b = nl_object_priv(_b):
154 * int diff = 0;
155 *
156 * // We help ourselves in defining our own DIFF macro which will
157 * // call ATTR_DIFF() on both objects which will make sure to only
158 * // compare the attributes if required.
159 * #define MY_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, MY_ATTR_##ATTR, a, b, EXPR)
160 *
161 * // Call our own diff macro for each attribute to build a bitmask
162 * // representing the attributes which mismatch.
163 * diff |= MY_DIFF(FOO, a->foo != b->foo)
164 * diff |= MY_DIFF(BAR, strcmp(a->bar, b->bar))
165 *
166 * return diff;
167 * }
168 *
169 * // In order to identify identical objects with differing attributes
170 * // you must specify the attributes required to uniquely identify
171 * // your object. Make sure to not include too many attributes, this
172 * // list is used when caches look for an old version of an object.
173 * struct nl_object_ops my_ops = {
174 * ...
175 * .oo_id_attrs = MY_ATTR_FOO,
176 * .oo_compare = my_obj_compare,
177 * };
178 * @endcode
179 * @{
180 */
181
182/**
183 * Common Object Header
184 *
185 * This macro must be included as first member in every object
186 * definition to allow objects to be cached.
187 */
188#define NLHDR_COMMON \
189 int ce_refcnt; \
190 struct nl_object_ops * ce_ops; \
191 struct nl_cache * ce_cache; \
192 struct nl_list_head ce_list; \
193 int ce_msgtype; \
194 int ce_flags; \
195 uint32_t ce_mask;
196
197/**
198 * Return true if attribute is available in both objects
199 * @arg A an object
200 * @arg B another object
201 * @arg ATTR attribute bit
202 *
203 * @return True if the attribute is available, otherwise false is returned.
204 */
205#define AVAILABLE(A, B, ATTR) (((A)->ce_mask & (B)->ce_mask) & (ATTR))
206
207/**
208 * Return true if attributes mismatch
209 * @arg A an object
210 * @arg B another object
211 * @arg ATTR attribute bit
212 * @arg EXPR Comparison expression
213 *
214 * This function will check if the attribute in question is available
215 * in both objects, if not this will count as a mismatch.
216 *
217 * If available the function will execute the expression which must
218 * return true if the attributes mismatch.
219 *
220 * @return True if the attribute mismatch, or false if they match.
221 */
222#define ATTR_MISMATCH(A, B, ATTR, EXPR) (!AVAILABLE(A, B, ATTR) || (EXPR))
223
224/**
225 * Return attribute bit if attribute does not match
226 * @arg LIST list of attributes to be compared
227 * @arg ATTR attribute bit
228 * @arg A an object
229 * @arg B another object
230 * @arg EXPR Comparison expression
231 *
232 * This function will check if the attribute in question is available
233 * in both objects, if not this will count as a mismatch.
234 *
235 * If available the function will execute the expression which must
236 * return true if the attributes mismatch.
237 *
238 * In case the attributes mismatch, the attribute is returned, otherwise
239 * 0 is returned.
240 *
241 * @code
242 * diff |= ATTR_DIFF(attrs, MY_ATTR_FOO, a, b, a->foo != b->foo);
243 * @endcode
244 */
245#define ATTR_DIFF(LIST, ATTR, A, B, EXPR) \
246({ int diff = 0; \
247 if (((LIST) & (ATTR)) && ATTR_MISMATCH(A, B, ATTR, EXPR)) \
248 diff = ATTR; \
249 diff; })
250
251/**
252 * Object Operations
253 */
255{
256 /**
257 * Unique name of object type
258 *
259 * Must be in the form family/name, e.g. "route/addr"
260 */
261 char * oo_name;
262
263 /** Size of object including its header */
264 size_t oo_size;
265
266 /* List of attributes needed to uniquely identify the object */
267 uint32_t oo_id_attrs;
268
269 /**
270 * Constructor function
271 *
272 * Will be called when a new object of this type is allocated.
273 * Can be used to initialize members such as lists etc.
274 */
275 void (*oo_constructor)(struct nl_object *);
276
277 /**
278 * Destructor function
279 *
280 * Will be called when an object is freed. Must free all
281 * resources which may have been allocated as part of this
282 * object.
283 */
284 void (*oo_free_data)(struct nl_object *);
285
286 /**
287 * Cloning function
288 *
289 * Will be called when an object needs to be cloned. Please
290 * note that the generic object code will make an exact
291 * copy of the object first, therefore you only need to take
292 * care of members which require reference counting etc.
293 *
294 * May return a negative error code to abort cloning.
295 */
296 int (*oo_clone)(struct nl_object *, struct nl_object *);
297
298 /**
299 * Dumping functions
300 *
301 * Will be called when an object is dumped. The implementations
302 * have to use nl_dump(), nl_dump_line(), and nl_new_line() to
303 * dump objects.
304 *
305 * The functions must return the number of lines printed.
306 */
307 int (*oo_dump[NL_DUMP_MAX+1])(struct nl_object *,
308 struct nl_dump_params *);
309
310 /**
311 * Comparison function
312 *
313 * Will be called when two objects of the same type are
314 * compared. It takes the two objects in question, an object
315 * specific bitmask defining which attributes should be
316 * compared and flags to control the behaviour.
317 *
318 * The function must return a bitmask with the relevant bit
319 * set for each attribute that mismatches.
320 */
321 int (*oo_compare)(struct nl_object *, struct nl_object *,
322 uint32_t, int);
323
324
325 char *(*oo_attrs2str)(int, char *, size_t);
326};
327
328/** @} */
329
330#ifdef __cplusplus
331}
332#endif
333
334#endif
Dumping parameters.
Definition: types.h:37
Object Operations.
Definition: object-api.h:255
int(* oo_dump[NL_DUMP_MAX+1])(struct nl_object *, struct nl_dump_params *)
Dumping functions.
Definition: object-api.h:307
size_t oo_size
Size of object including its header.
Definition: object-api.h:264
void(* oo_constructor)(struct nl_object *)
Constructor function.
Definition: object-api.h:275
int(* oo_clone)(struct nl_object *, struct nl_object *)
Cloning function.
Definition: object-api.h:296
char * oo_name
Unique name of object type.
Definition: object-api.h:261
void(* oo_free_data)(struct nl_object *)
Destructor function.
Definition: object-api.h:284
int(* oo_compare)(struct nl_object *, struct nl_object *, uint32_t, int)
Comparison function.
Definition: object-api.h:321