21 #include <netlink-private/genl.h>
22 #include <netlink/netlink.h>
23 #include <netlink/genl/genl.h>
24 #include <netlink/genl/family.h>
25 #include <netlink/utils.h>
28 #define FAMILY_ATTR_ID 0x01
29 #define FAMILY_ATTR_NAME 0x02
30 #define FAMILY_ATTR_VERSION 0x04
31 #define FAMILY_ATTR_HDRSIZE 0x08
32 #define FAMILY_ATTR_MAXATTR 0x10
33 #define FAMILY_ATTR_OPS 0x20
35 struct nl_object_ops genl_family_ops;
37 static void family_constructor(
struct nl_object *c)
39 struct genl_family *family = (
struct genl_family *) c;
41 nl_init_list_head(&family->gf_ops);
42 nl_init_list_head(&family->gf_mc_grps);
45 static void family_free_data(
struct nl_object *c)
47 struct genl_family *family = (
struct genl_family *) c;
48 struct genl_family_op *ops, *tmp;
49 struct genl_family_grp *grp, *t_grp;
54 nl_list_for_each_entry_safe(ops, tmp, &family->gf_ops, o_list) {
55 nl_list_del(&ops->o_list);
59 nl_list_for_each_entry_safe(grp, t_grp, &family->gf_mc_grps, list) {
60 nl_list_del(&grp->list);
66 static int family_clone(
struct nl_object *_dst,
struct nl_object *_src)
68 struct genl_family *dst = nl_object_priv(_dst);
69 struct genl_family *src = nl_object_priv(_src);
70 struct genl_family_op *ops;
71 struct genl_family_grp *grp;
74 nl_list_for_each_entry(ops, &src->gf_ops, o_list) {
75 err = genl_family_add_op(dst, ops->o_id, ops->o_flags);
80 nl_list_for_each_entry(grp, &src->gf_mc_grps, list) {
81 err = genl_family_add_grp(dst, grp->id, grp->name);
90 static void family_dump_line(
struct nl_object *obj,
struct nl_dump_params *p)
92 struct genl_family *family = (
struct genl_family *) obj;
94 nl_dump(p,
"0x%04x %s version %u\n",
95 family->gf_id, family->gf_name, family->gf_version);
98 static const struct trans_tbl ops_flags[] = {
99 __ADD(GENL_ADMIN_PERM, admin_perm)
100 __ADD(GENL_CMD_CAP_DO, has_doit)
101 __ADD(GENL_CMD_CAP_DUMP, has_dump)
102 __ADD(GENL_CMD_CAP_HASPOL, has_policy)
105 static
char *ops_flags2str(
int flags,
char *buf,
size_t len)
107 return __flags2str(flags, buf, len, ops_flags, ARRAY_SIZE(ops_flags));
110 static void family_dump_details(
struct nl_object *obj,
struct nl_dump_params *p)
112 struct genl_family_grp *grp;
113 struct genl_family *family = (
struct genl_family *) obj;
115 family_dump_line(obj, p);
116 nl_dump_line(p,
" hdrsize %u maxattr %u\n",
117 family->gf_hdrsize, family->gf_maxattr);
119 if (family->ce_mask & FAMILY_ATTR_OPS) {
120 struct genl_family_op *op;
123 nl_list_for_each_entry(op, &family->gf_ops, o_list) {
124 ops_flags2str(op->o_flags, buf,
sizeof(buf));
126 genl_op2name(family->gf_id, op->o_id, buf,
sizeof(buf));
128 nl_dump_line(p,
" op %s (0x%02x)", buf, op->o_id);
132 ops_flags2str(op->o_flags, buf,
139 nl_list_for_each_entry(grp, &family->gf_mc_grps, list) {
140 nl_dump_line(p,
" grp %s (0x%02x)\n", grp->name, grp->id);
145 static void family_dump_stats(
struct nl_object *obj,
struct nl_dump_params *p)
147 family_dump_details(obj, p);
150 static int family_compare(
struct nl_object *_a,
struct nl_object *_b,
151 uint32_t attrs,
int flags)
153 struct genl_family *a = (
struct genl_family *) _a;
154 struct genl_family *b = (
struct genl_family *) _b;
157 #define FAM_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, FAMILY_ATTR_##ATTR, a, b, EXPR)
159 diff |= FAM_DIFF(ID, a->gf_id != b->gf_id);
160 diff |= FAM_DIFF(VERSION, a->gf_version != b->gf_version);
161 diff |= FAM_DIFF(HDRSIZE, a->gf_hdrsize != b->gf_hdrsize);
162 diff |= FAM_DIFF(MAXATTR, a->gf_maxattr != b->gf_maxattr);
163 diff |= FAM_DIFF(NAME, strcmp(a->gf_name, b->gf_name));
215 if (family->ce_mask & FAMILY_ATTR_ID)
216 return family->gf_id;
218 return GENL_ID_GENERATE;
229 family->ce_mask |= FAMILY_ATTR_ID;
247 if (family->ce_mask & FAMILY_ATTR_NAME)
248 return family->gf_name;
260 strncpy(family->gf_name, name, GENL_NAMSIZ-1);
261 family->ce_mask |= FAMILY_ATTR_NAME;
277 if (family->ce_mask & FAMILY_ATTR_VERSION)
278 return family->gf_version;
290 family->gf_version = version;
291 family->ce_mask |= FAMILY_ATTR_VERSION;
309 if (family->ce_mask & FAMILY_ATTR_HDRSIZE)
310 return family->gf_hdrsize;
315 void genl_family_set_hdrsize(
struct genl_family *family, uint32_t hdrsize)
317 family->gf_hdrsize = hdrsize;
318 family->ce_mask |= FAMILY_ATTR_HDRSIZE;
328 uint32_t genl_family_get_maxattr(
struct genl_family *family)
330 if (family->ce_mask & FAMILY_ATTR_MAXATTR)
331 return family->gf_maxattr;
333 return family->gf_maxattr;
336 void genl_family_set_maxattr(
struct genl_family *family, uint32_t maxattr)
338 family->gf_maxattr = maxattr;
339 family->ce_mask |= FAMILY_ATTR_MAXATTR;
349 int genl_family_add_op(
struct genl_family *family,
int id,
int flags)
351 struct genl_family_op *op;
353 op = calloc(1,
sizeof(*op));
360 nl_list_add_tail(&op->o_list, &family->gf_ops);
361 family->ce_mask |= FAMILY_ATTR_OPS;
366 int genl_family_add_grp(
struct genl_family *family, uint32_t
id,
369 struct genl_family_grp *grp;
371 grp = calloc(1,
sizeof(*grp));
376 strncpy(grp->name, name, GENL_NAMSIZ - 1);
378 nl_list_add_tail(&grp->list, &family->gf_mc_grps);
386 struct nl_object_ops genl_family_ops = {
387 .oo_name =
"genl/family",
388 .oo_size =
sizeof(
struct genl_family),
389 .oo_constructor = family_constructor,
390 .oo_free_data = family_free_data,
391 .oo_clone = family_clone,
397 .oo_compare = family_compare,
398 .oo_id_attrs = FAMILY_ATTR_ID,