15#include <netlink-private/genl.h>
16#include <netlink/netlink.h>
17#include <netlink/genl/genl.h>
18#include <netlink/genl/family.h>
19#include <netlink/utils.h>
21#include "netlink-private/utils.h"
24#define FAMILY_ATTR_ID 0x01
25#define FAMILY_ATTR_NAME 0x02
26#define FAMILY_ATTR_VERSION 0x04
27#define FAMILY_ATTR_HDRSIZE 0x08
28#define FAMILY_ATTR_MAXATTR 0x10
29#define FAMILY_ATTR_OPS 0x20
31struct nl_object_ops genl_family_ops;
33static void family_constructor(
struct nl_object *c)
35 struct genl_family *family = (
struct genl_family *) c;
37 nl_init_list_head(&family->gf_ops);
38 nl_init_list_head(&family->gf_mc_grps);
41static void family_free_data(
struct nl_object *c)
43 struct genl_family *family = (
struct genl_family *) c;
44 struct genl_family_op *ops, *tmp;
45 struct genl_family_grp *grp, *t_grp;
50 nl_list_for_each_entry_safe(ops, tmp, &family->gf_ops, o_list) {
51 nl_list_del(&ops->o_list);
55 nl_list_for_each_entry_safe(grp, t_grp, &family->gf_mc_grps, list) {
56 nl_list_del(&grp->list);
62static int family_clone(
struct nl_object *_dst,
struct nl_object *_src)
64 struct genl_family *dst = nl_object_priv(_dst);
65 struct genl_family *src = nl_object_priv(_src);
66 struct genl_family_op *ops;
67 struct genl_family_grp *grp;
70 nl_init_list_head(&dst->gf_ops);
71 nl_init_list_head(&dst->gf_mc_grps);
73 nl_list_for_each_entry(ops, &src->gf_ops, o_list) {
74 err = genl_family_add_op(dst, ops->o_id, ops->o_flags);
79 nl_list_for_each_entry(grp, &src->gf_mc_grps, list) {
80 err = genl_family_add_grp(dst, grp->id, grp->name);
89static void family_dump_line(
struct nl_object *obj,
struct nl_dump_params *p)
91 struct genl_family *family = (
struct genl_family *) obj;
93 nl_dump(p,
"0x%04x %s version %u\n",
94 family->gf_id, family->gf_name, family->gf_version);
97static const struct trans_tbl ops_flags[] = {
98 __ADD(GENL_ADMIN_PERM, admin_perm),
99 __ADD(GENL_CMD_CAP_DO, has_doit),
100 __ADD(GENL_CMD_CAP_DUMP, has_dump),
101 __ADD(GENL_CMD_CAP_HASPOL, has_policy),
104static char *ops_flags2str(
int flags,
char *buf,
size_t len)
106 return __flags2str(flags, buf, len, ops_flags, ARRAY_SIZE(ops_flags));
109static void family_dump_details(
struct nl_object *obj,
struct nl_dump_params *p)
111 struct genl_family_grp *grp;
112 struct genl_family *family = (
struct genl_family *) obj;
114 family_dump_line(obj, p);
115 nl_dump_line(p,
" hdrsize %u maxattr %u\n",
116 family->gf_hdrsize, family->gf_maxattr);
118 if (family->ce_mask & FAMILY_ATTR_OPS) {
119 struct genl_family_op *op;
122 nl_list_for_each_entry(op, &family->gf_ops, o_list) {
123 ops_flags2str(op->o_flags, buf,
sizeof(buf));
125 genl_op2name(family->gf_id, op->o_id, buf,
sizeof(buf));
127 nl_dump_line(p,
" op %s (0x%02x)", buf, op->o_id);
131 ops_flags2str(op->o_flags, buf,
138 nl_list_for_each_entry(grp, &family->gf_mc_grps, list) {
139 nl_dump_line(p,
" grp %s (0x%02x)\n", grp->name, grp->id);
144static void family_dump_stats(
struct nl_object *obj,
struct nl_dump_params *p)
146 family_dump_details(obj, p);
149static uint64_t family_compare(
struct nl_object *_a,
struct nl_object *_b,
150 uint64_t attrs,
int flags)
152 struct genl_family *a = (
struct genl_family *) _a;
153 struct genl_family *b = (
struct genl_family *) _b;
156#define FAM_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, FAMILY_ATTR_##ATTR, a, b, EXPR)
158 diff |= FAM_DIFF(ID, a->gf_id != b->gf_id);
159 diff |= FAM_DIFF(VERSION, a->gf_version != b->gf_version);
160 diff |= FAM_DIFF(HDRSIZE, a->gf_hdrsize != b->gf_hdrsize);
161 diff |= FAM_DIFF(MAXATTR, a->gf_maxattr != b->gf_maxattr);
162 diff |= FAM_DIFF(NAME, strcmp(a->gf_name, b->gf_name));
214 if (family->ce_mask & FAMILY_ATTR_ID)
215 return family->gf_id;
228 family->ce_mask |= FAMILY_ATTR_ID;
246 if (family->ce_mask & FAMILY_ATTR_NAME)
247 return family->gf_name;
259 _nl_strncpy_trunc(family->gf_name, name, GENL_NAMSIZ);
260 family->ce_mask |= FAMILY_ATTR_NAME;
276 if (family->ce_mask & FAMILY_ATTR_VERSION)
277 return family->gf_version;
289 family->gf_version = version;
290 family->ce_mask |= FAMILY_ATTR_VERSION;
308 if (family->ce_mask & FAMILY_ATTR_HDRSIZE)
309 return family->gf_hdrsize;
314void genl_family_set_hdrsize(
struct genl_family *family, uint32_t hdrsize)
316 family->gf_hdrsize = hdrsize;
317 family->ce_mask |= FAMILY_ATTR_HDRSIZE;
327uint32_t genl_family_get_maxattr(
struct genl_family *family)
329 if (family->ce_mask & FAMILY_ATTR_MAXATTR)
330 return family->gf_maxattr;
335void genl_family_set_maxattr(
struct genl_family *family, uint32_t maxattr)
337 family->gf_maxattr = maxattr;
338 family->ce_mask |= FAMILY_ATTR_MAXATTR;
348int genl_family_add_op(
struct genl_family *family,
int id,
int flags)
350 struct genl_family_op *op;
352 op = calloc(1,
sizeof(*op));
359 nl_list_add_tail(&op->o_list, &family->gf_ops);
360 family->ce_mask |= FAMILY_ATTR_OPS;
365int genl_family_add_grp(
struct genl_family *family, uint32_t
id,
368 struct genl_family_grp *grp;
371 || strlen (name) >= GENL_NAMSIZ)
374 grp = calloc(1,
sizeof(*grp));
379 _nl_strncpy_assert(grp->name, name, GENL_NAMSIZ);
381 nl_list_add_tail(&grp->list, &family->gf_mc_grps);
389struct nl_object_ops genl_family_ops = {
390 .oo_name =
"genl/family",
391 .oo_size =
sizeof(
struct genl_family),
392 .oo_constructor = family_constructor,
393 .oo_free_data = family_free_data,
394 .oo_clone = family_clone,
400 .oo_compare = family_compare,
401 .oo_id_attrs = FAMILY_ATTR_ID,
void genl_family_set_name(struct genl_family *family, const char *name)
Set human readable name.
void genl_family_set_version(struct genl_family *family, uint8_t version)
Set interface version.
struct genl_family * genl_family_alloc(void)
Allocate new Generic Netlink family object.
void genl_family_put(struct genl_family *family)
Release reference on Generic Netlink family object.
uint8_t genl_family_get_version(struct genl_family *family)
Return interface version.
char * genl_family_get_name(struct genl_family *family)
Return human readable name.
unsigned int genl_family_get_id(struct genl_family *family)
Return numeric identifier.
uint32_t genl_family_get_hdrsize(struct genl_family *family)
Return user header size expected by kernel component.
void genl_family_set_id(struct genl_family *family, unsigned int id)
Set the numeric identifier.
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
@ NL_DUMP_STATS
Dump all attributes including statistics.
@ NL_DUMP_LINE
Dump object briefly on one line.
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.