libnl  3.2.20
Object API

Data Structures

struct  nl_object
struct  nl_object_ops
 Object Operations. More...

Macros

#define NLHDR_COMMON
 Common Object Header.
#define AVAILABLE(A, B, ATTR)   (((A)->ce_mask & (B)->ce_mask) & (ATTR))
 Return true if attribute is available in both objects.
#define AVAILABLE_MISMATCH(A, B, ATTR)   (((A)->ce_mask ^ (B)->ce_mask) & (ATTR))
 Return true if attribute is available in only one of both objects.
#define ATTR_MISMATCH(A, B, ATTR, EXPR)
 Return true if attributes mismatch.
#define ATTR_DIFF(LIST, ATTR, A, B, EXPR)
 Return attribute bit if attribute does not match.

Detailed Description

1) Object Definition
// Define your object starting with the common object header
struct my_obj {
int my_data;
};
// Fill out the object operations structure
struct nl_object_ops my_ops = {
.oo_name = "my_obj",
.oo_size = sizeof(struct my_obj),
};
// At this point the object can be allocated, you may want to provide a
// separate _alloc() function to ease allocting objects of this kind.
struct nl_object *obj = nl_object_alloc(&my_ops);
// And release it again...
2) Allocating additional data
// You may require to allocate additional data and store it inside
// object, f.e. assuming there is a field `ptr'.
struct my_obj {
void * ptr;
};
// And at some point you may assign allocated data to this field:
my_obj->ptr = calloc(1, ...);
// In order to not introduce any memory leaks you have to release
// this data again when the last reference is given back.
static void my_obj_free_data(struct nl_object *obj)
{
struct my_obj *my_obj = nl_object_priv(obj);
free(my_obj->ptr);
}
// Also when the object is cloned, you must ensure for your pointer
// stay valid even if one of the clones is freed by either making
// a clone as well or increase the reference count.
static int my_obj_clone(struct nl_object *src, struct nl_object *dst)
{
struct my_obj *my_src = nl_object_priv(src);
struct my_obj *my_dst = nl_object_priv(dst);
if (src->ptr) {
dst->ptr = calloc(1, ...);
memcpy(dst->ptr, src->ptr, ...);
}
}
struct nl_object_ops my_ops = {
...
.oo_free_data = my_obj_free_data,
.oo_clone = my_obj_clone,
};
3) Object Dumping
static int my_obj_dump_detailed(struct nl_object *obj,
struct nl_dump_params *params)
{
struct my_obj *my_obj = nl_object_priv(obj);
// It is absolutely essential to use nl_dump() when printing
// any text to make sure the dumping parameters are respected.
nl_dump(params, "Obj Integer: %d\n", my_obj->my_int);
// Before we can dump the next line, make sure to prefix
// this line correctly.
nl_new_line(params);
// You may also split a line into multiple nl_dump() calls.
nl_dump(params, "String: %s ", my_obj->my_string);
nl_dump(params, "String-2: %s\n", my_obj->another_string);
}
struct nl_object_ops my_ops = {
...
.oo_dump[NL_DUMP_FULL] = my_obj_dump_detailed,
};
4) Object Attributes
// The concept of object attributes is optional but can ease the typical
// case of objects that have optional attributes, e.g. a route may have a
// nexthop assigned but it is not required to.
// The first step to define your object specific bitmask listing all
// attributes
#define MY_ATTR_FOO (1<<0)
#define MY_ATTR_BAR (1<<1)
// When assigning an optional attribute to the object, make sure
// to mark its availability.
my_obj->foo = 123123;
my_obj->ce_mask |= MY_ATTR_FOO;
// At any time you may use this mask to check for the availability
// of the attribute, e.g. while dumping
if (my_obj->ce_mask & MY_ATTR_FOO)
nl_dump(params, "foo %d ", my_obj->foo);
// One of the big advantages of this concept is that it allows for
// standardized comparisons which make it trivial for caches to
// identify unique objects by use of unified comparison functions.
// In order for it to work, your object implementation must provide
// a comparison function and define a list of attributes which
// combined together make an object unique.
static int my_obj_compare(struct nl_object *_a, struct nl_object *_b,
uint32_t attrs, int flags)
{
struct my_obj *a = nl_object_priv(_a):
struct my_obj *b = nl_object_priv(_b):
int diff = 0;
// We help ourselves in defining our own DIFF macro which will
// call ATTR_DIFF() on both objects which will make sure to only
// compare the attributes if required.
#define MY_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, MY_ATTR_##ATTR, a, b, EXPR)
// Call our own diff macro for each attribute to build a bitmask
// representing the attributes which mismatch.
diff |= MY_DIFF(FOO, a->foo != b->foo)
diff |= MY_DIFF(BAR, strcmp(a->bar, b->bar))
return diff;
}
// In order to identify identical objects with differing attributes
// you must specify the attributes required to uniquely identify
// your object. Make sure to not include too many attributes, this
// list is used when caches look for an old version of an object.
struct nl_object_ops my_ops = {
...
.oo_id_attrs = MY_ATTR_FOO,
.oo_compare = my_obj_compare,
};

Macro Definition Documentation

#define NLHDR_COMMON
Value:
int ce_refcnt; \
struct nl_object_ops * ce_ops; \
struct nl_cache * ce_cache; \
struct nl_list_head ce_list; \
int ce_msgtype; \
int ce_flags; \
uint32_t ce_mask;

Common Object Header.

This macro must be included as first member in every object definition to allow objects to be cached.

Definition at line 184 of file object-api.h.

#define AVAILABLE (   A,
  B,
  ATTR 
)    (((A)->ce_mask & (B)->ce_mask) & (ATTR))

Return true if attribute is available in both objects.

Parameters:
Aan object
Banother object
ATTRattribute bit
Returns:
True if the attribute is available, otherwise false is returned.

Definition at line 207 of file object-api.h.

#define AVAILABLE_MISMATCH (   A,
  B,
  ATTR 
)    (((A)->ce_mask ^ (B)->ce_mask) & (ATTR))

Return true if attribute is available in only one of both objects.

Parameters:
Aan object
Banother object
ATTRattribute bit
Returns:
True if the attribute is available in only one of both objects, otherwise false is returned.

Definition at line 218 of file object-api.h.

#define ATTR_MISMATCH (   A,
  B,
  ATTR,
  EXPR 
)
Value:
(AVAILABLE_MISMATCH(A, B, ATTR) || \
(AVAILABLE(A, B, ATTR) && (EXPR)))

Return true if attributes mismatch.

Parameters:
Aan object
Banother object
ATTRattribute bit
EXPRComparison expression

This function will check if the attribute in question is available in both objects, if not this will count as a mismatch.

If available the function will execute the expression which must return true if the attributes mismatch.

Returns:
True if the attribute mismatch, or false if they match.

Definition at line 235 of file object-api.h.

#define ATTR_DIFF (   LIST,
  ATTR,
  A,
  B,
  EXPR 
)
Value:
({ int diff = 0; \
if (((LIST) & (ATTR)) && ATTR_MISMATCH(A, B, ATTR, EXPR)) \
diff = ATTR; \
diff; })

Return attribute bit if attribute does not match.

Parameters:
LISTlist of attributes to be compared
ATTRattribute bit
Aan object
Banother object
EXPRComparison expression

This function will check if the attribute in question is available in both objects, if not this will count as a mismatch.

If available the function will execute the expression which must return true if the attributes mismatch.

In case the attributes mismatch, the attribute is returned, otherwise 0 is returned.

diff |= ATTR_DIFF(attrs, MY_ATTR_FOO, a, b, a->foo != b->foo);

Definition at line 259 of file object-api.h.