Add packaging directory
[platform/upstream/libnl3.git] / include / netlink-private / object-api.h
1 /*
2  * netlink-private/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-2013 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 #include <netlink/object.h>
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22
23 /**
24  * @ingroup object
25  * @defgroup object_api Object API
26  * @brief
27  *
28  * @par 1) Object Definition
29  * @code
30  * // Define your object starting with the common object header
31  * struct my_obj {
32  *      NLHDR_COMMON
33  *      int             my_data;
34  * };
35  *
36  * // Fill out the object operations structure
37  * struct nl_object_ops my_ops = {
38  *      .oo_name        = "my_obj",
39  *      .oo_size        = sizeof(struct my_obj),
40  * };
41  *
42  * // At this point the object can be allocated, you may want to provide a
43  * // separate _alloc() function to ease allocting objects of this kind.
44  * struct nl_object *obj = nl_object_alloc(&my_ops);
45  *
46  * // And release it again...
47  * nl_object_put(obj);
48  * @endcode
49  *
50  * @par 2) Allocating additional data
51  * @code
52  * // You may require to allocate additional data and store it inside
53  * // object, f.e. assuming there is a field `ptr'.
54  * struct my_obj {
55  *      NLHDR_COMMON
56  *      void *          ptr;
57  * };
58  *
59  * // And at some point you may assign allocated data to this field:
60  * my_obj->ptr = calloc(1, ...);
61  *
62  * // In order to not introduce any memory leaks you have to release
63  * // this data again when the last reference is given back.
64  * static void my_obj_free_data(struct nl_object *obj)
65  * {
66  *      struct my_obj *my_obj = nl_object_priv(obj);
67  *
68  *      free(my_obj->ptr);
69  * }
70  *
71  * // Also when the object is cloned, you must ensure for your pointer
72  * // stay valid even if one of the clones is freed by either making
73  * // a clone as well or increase the reference count.
74  * static int my_obj_clone(struct nl_object *src, struct nl_object *dst)
75  * {
76  *      struct my_obj *my_src = nl_object_priv(src);
77  *      struct my_obj *my_dst = nl_object_priv(dst);
78  *
79  *      if (src->ptr) {
80  *              dst->ptr = calloc(1, ...);
81  *              memcpy(dst->ptr, src->ptr, ...);
82  *      }
83  * }
84  *
85  * struct nl_object_ops my_ops = {
86  *      ...
87  *      .oo_free_data   = my_obj_free_data,
88  *      .oo_clone       = my_obj_clone,
89  * };
90  * @endcode
91  *
92  * @par 3) Object Dumping
93  * @code
94  * static int my_obj_dump_detailed(struct nl_object *obj,
95  *                                 struct nl_dump_params *params)
96  * {
97  *      struct my_obj *my_obj = nl_object_priv(obj);
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);
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  *
112  * struct nl_object_ops my_ops = {
113  *      ...
114  *      .oo_dump[NL_DUMP_FULL]  = my_obj_dump_detailed,
115  * };
116  * @endcode
117  *
118  * @par 4) Object Attributes
119  * @code
120  * // The concept of object attributes is optional but can ease the typical
121  * // case of objects that have optional attributes, e.g. a route may have a
122  * // nexthop assigned but it is not required to.
123  *
124  * // The first step to define your object specific bitmask listing all
125  * // attributes
126  * #define MY_ATTR_FOO          (1<<0)
127  * #define MY_ATTR_BAR          (1<<1)
128  *
129  * // When assigning an optional attribute to the object, make sure
130  * // to mark its availability.
131  * my_obj->foo = 123123;
132  * my_obj->ce_mask |= MY_ATTR_FOO;
133  *
134  * // At any time you may use this mask to check for the availability
135  * // of the attribute, e.g. while dumping
136  * if (my_obj->ce_mask & MY_ATTR_FOO)
137  *      nl_dump(params, "foo %d ", my_obj->foo);
138  *
139  * // One of the big advantages of this concept is that it allows for
140  * // standardized comparisons which make it trivial for caches to
141  * // identify unique objects by use of unified comparison functions.
142  * // In order for it to work, your object implementation must provide
143  * // a comparison function and define a list of attributes which
144  * // combined together make an object unique.
145  *
146  * static int my_obj_compare(struct nl_object *_a, struct nl_object *_b,
147  *                           uint32_t attrs, int flags)
148  * {
149  *      struct my_obj *a = nl_object_priv(_a):
150  *      struct my_obj *b = nl_object_priv(_b):
151  *      int diff = 0;
152  *
153  *      // We help ourselves in defining our own DIFF macro which will
154  *      // call ATTR_DIFF() on both objects which will make sure to only
155  *      // compare the attributes if required.
156  *      #define MY_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, MY_ATTR_##ATTR, a, b, EXPR)
157  *
158  *      // Call our own diff macro for each attribute to build a bitmask
159  *      // representing the attributes which mismatch.
160  *      diff |= MY_DIFF(FOO, a->foo != b->foo)
161  *      diff |= MY_DIFF(BAR, strcmp(a->bar, b->bar))
162  *
163  *      return diff;
164  * }
165  *
166  * // In order to identify identical objects with differing attributes
167  * // you must specify the attributes required to uniquely identify
168  * // your object. Make sure to not include too many attributes, this
169  * // list is used when caches look for an old version of an object.
170  * struct nl_object_ops my_ops = {
171  *      ...
172  *      .oo_id_attrs            = MY_ATTR_FOO,
173  *      .oo_compare             = my_obj_compare,
174  * };
175  * @endcode
176  * @{
177  */
178
179 /**
180  * Common Object Header
181  *
182  * This macro must be included as first member in every object
183  * definition to allow objects to be cached.
184  */
185 #define NLHDR_COMMON                            \
186         int                     ce_refcnt;      \
187         struct nl_object_ops *  ce_ops;         \
188         struct nl_cache *       ce_cache;       \
189         struct nl_list_head     ce_list;        \
190         int                     ce_msgtype;     \
191         int                     ce_flags;       \
192         uint32_t                ce_mask;
193
194 struct nl_object
195 {
196         NLHDR_COMMON
197 };
198
199
200 /**
201  * Return true if attribute is available in both objects
202  * @arg A               an object
203  * @arg B               another object
204  * @arg ATTR            attribute bit
205  *
206  * @return True if the attribute is available, otherwise false is returned.
207  */
208 #define AVAILABLE(A, B, ATTR)           (((A)->ce_mask & (B)->ce_mask) & (ATTR))
209
210 /**
211  * Return true if attribute is available in only one of both objects
212  * @arg A               an object
213  * @arg B               another object
214  * @arg ATTR            attribute bit
215  *
216  * @return True if the attribute is available in only one of both objects,
217  * otherwise false is returned.
218  */
219 #define AVAILABLE_MISMATCH(A, B, ATTR)  (((A)->ce_mask ^ (B)->ce_mask) & (ATTR))
220
221 /**
222  * Return true if attributes mismatch
223  * @arg A               an object
224  * @arg B               another object
225  * @arg ATTR            attribute bit
226  * @arg EXPR            Comparison expression
227  *
228  * This function will check if the attribute in question is available
229  * in both objects, if not this will count as a mismatch.
230  *
231  * If available the function will execute the expression which must
232  * return true if the attributes mismatch.
233  *
234  * @return True if the attribute mismatch, or false if they match.
235  */
236 #define ATTR_MISMATCH(A, B, ATTR, EXPR) (AVAILABLE_MISMATCH(A, B, ATTR) || \
237                                          (AVAILABLE(A, B, ATTR) && (EXPR)))
238
239 /**
240  * Return attribute bit if attribute does not match
241  * @arg LIST            list of attributes to be compared
242  * @arg ATTR            attribute bit
243  * @arg A               an object
244  * @arg B               another object
245  * @arg EXPR            Comparison expression
246  *
247  * This function will check if the attribute in question is available
248  * in both objects, if not this will count as a mismatch.
249  *
250  * If available the function will execute the expression which must
251  * return true if the attributes mismatch.
252  *
253  * In case the attributes mismatch, the attribute is returned, otherwise
254  * 0 is returned.
255  *
256  * @code
257  * diff |= ATTR_DIFF(attrs, MY_ATTR_FOO, a, b, a->foo != b->foo);
258  * @endcode
259  */
260 #define ATTR_DIFF(LIST, ATTR, A, B, EXPR) \
261 ({      int diff = 0; \
262         if (((LIST) & (ATTR)) && ATTR_MISMATCH(A, B, ATTR, EXPR)) \
263                 diff = ATTR; \
264         diff; })
265
266 /**
267  * Object Operations
268  */
269 struct nl_object_ops
270 {
271         /**
272          * Unique name of object type
273          *
274          * Must be in the form family/name, e.g. "route/addr"
275          */
276         char *          oo_name;
277
278         /** Size of object including its header */
279         size_t          oo_size;
280
281         /* List of attributes needed to uniquely identify the object */
282         uint32_t        oo_id_attrs;
283
284         /**
285          * Constructor function
286          *
287          * Will be called when a new object of this type is allocated.
288          * Can be used to initialize members such as lists etc.
289          */
290         void  (*oo_constructor)(struct nl_object *);
291
292         /**
293          * Destructor function
294          *
295          * Will be called when an object is freed. Must free all
296          * resources which may have been allocated as part of this
297          * object.
298          */
299         void  (*oo_free_data)(struct nl_object *);
300
301         /**
302          * Cloning function
303          *
304          * Will be called when an object needs to be cloned. Please
305          * note that the generic object code will make an exact
306          * copy of the object first, therefore you only need to take
307          * care of members which require reference counting etc.
308          *
309          * May return a negative error code to abort cloning.
310          */
311         int  (*oo_clone)(struct nl_object *, struct nl_object *);
312
313         /**
314          * Dumping functions
315          *
316          * Will be called when an object is dumped. The implementations
317          * have to use nl_dump(), nl_dump_line(), and nl_new_line() to
318          * dump objects.
319          *
320          * The functions must return the number of lines printed.
321          */
322         void (*oo_dump[NL_DUMP_MAX+1])(struct nl_object *,
323                                        struct nl_dump_params *);
324
325         /**
326          * Comparison function
327          *
328          * Will be called when two objects of the same type are
329          * compared. It takes the two objects in question, an object
330          * specific bitmask defining which attributes should be
331          * compared and flags to control the behaviour.
332          *
333          * The function must return a bitmask with the relevant bit
334          * set for each attribute that mismatches.
335          */
336         int   (*oo_compare)(struct nl_object *, struct nl_object *,
337                             uint32_t, int);
338
339
340         /**
341          * update function
342          *
343          * Will be called when the object given by first argument
344          * needs to be updated with the contents of the second object
345          *
346          * The function must return 0 for success and error for failure
347          * to update. In case of failure its assumed that the original
348          * object is not touched
349          */
350         int   (*oo_update)(struct nl_object *, struct nl_object *);
351
352         /**
353          * Hash Key generator function
354          *
355          * When called returns a hash key for the object being
356          * referenced. This key will be used by higher level hash functions
357          * to build association lists. Each object type gets to specify
358          * it's own key formulation
359          */
360         void   (*oo_keygen)(struct nl_object *, uint32_t *, uint32_t);
361
362         char *(*oo_attrs2str)(int, char *, size_t);
363
364         /**
365          * Get key attributes by family function
366          */
367         uint32_t   (*oo_id_attrs_get)(struct nl_object *);
368 };
369
370 /** @} */
371
372 #ifdef __cplusplus
373 }
374 #endif
375
376 #endif