libnl 1.1.4
family.c
1/*
2 * lib/genl/family.c Generic Netlink Family
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-2006 Thomas Graf <tgraf@suug.ch>
10 */
11
12/**
13 * @ingroup genl
14 * @defgroup genl_family Generic Netlink Family
15 * @brief
16 *
17 * @{
18 */
19
20#include <netlink-generic.h>
21#include <netlink/netlink.h>
22#include <netlink/genl/genl.h>
23#include <netlink/genl/family.h>
24#include <netlink/utils.h>
25
26/** @cond SKIP */
27#define FAMILY_ATTR_ID 0x01
28#define FAMILY_ATTR_NAME 0x02
29#define FAMILY_ATTR_VERSION 0x04
30#define FAMILY_ATTR_HDRSIZE 0x08
31#define FAMILY_ATTR_MAXATTR 0x10
32#define FAMILY_ATTR_OPS 0x20
33
34struct nl_object_ops genl_family_ops;
35/** @endcond */
36
37static void family_constructor(struct nl_object *c)
38{
39 struct genl_family *family = (struct genl_family *) c;
40
41 nl_init_list_head(&family->gf_ops);
42}
43
44static void family_free_data(struct nl_object *c)
45{
46 struct genl_family *family = (struct genl_family *) c;
47 struct genl_family_op *ops, *tmp;
48
49 if (family == NULL)
50 return;
51
52 nl_list_for_each_entry_safe(ops, tmp, &family->gf_ops, o_list) {
53 nl_list_del(&ops->o_list);
54 free(ops);
55 }
56}
57
58static int family_clone(struct nl_object *_dst, struct nl_object *_src)
59{
60 struct genl_family *dst = nl_object_priv(_dst);
61 struct genl_family *src = nl_object_priv(_src);
62 struct genl_family_op *ops;
63 int err;
64
65 nl_list_for_each_entry(ops, &src->gf_ops, o_list) {
66 err = genl_family_add_op(dst, ops->o_id, ops->o_flags);
67 if (err < 0)
68 return err;
69 }
70
71 return 0;
72}
73
74static int family_dump_brief(struct nl_object *obj, struct nl_dump_params *p)
75{
76 struct genl_family *family = (struct genl_family *) obj;
77
78 dp_dump(p, "0x%04x %s version %u\n",
79 family->gf_id, family->gf_name, family->gf_version);
80
81 return 1;
82}
83
84static struct trans_tbl ops_flags[] = {
85 __ADD(GENL_ADMIN_PERM, admin-perm)
86 __ADD(GENL_CMD_CAP_DO, has-doit)
87 __ADD(GENL_CMD_CAP_DUMP, has-dump)
88 __ADD(GENL_CMD_CAP_HASPOL, has-policy)
89};
90
91static char *ops_flags2str(int flags, char *buf, size_t len)
92{
93 return __flags2str(flags, buf, len, ops_flags, ARRAY_SIZE(ops_flags));
94}
95
96static int family_dump_full(struct nl_object *obj, struct nl_dump_params *p)
97{
98 struct genl_family *family = (struct genl_family *) obj;
99 int line;
100
101 line = family_dump_brief(obj, p);
102 dp_dump_line(p, line++, " hdrsize %u maxattr %u\n",
103 family->gf_hdrsize, family->gf_maxattr);
104
105 if (family->ce_mask & FAMILY_ATTR_OPS) {
106 struct genl_family_op *op;
107 char buf[64];
108
109 nl_list_for_each_entry(op, &family->gf_ops, o_list) {
110 ops_flags2str(op->o_flags, buf, sizeof(buf));
111
112 genl_op2name(family->gf_id, op->o_id, buf, sizeof(buf));
113
114 dp_dump_line(p, line++, " op %s (0x%02x)",
115 buf, op->o_id);
116
117 if (op->o_flags)
118 dp_dump(p, " <%s>",
119 ops_flags2str(op->o_flags, buf,
120 sizeof(buf)));
121
122 dp_dump(p, "\n");
123 }
124 }
125
126 return line;
127}
128
129static int family_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
130{
131 return family_dump_full(obj, p);
132}
133
134static int family_compare(struct nl_object *_a, struct nl_object *_b,
135 uint32_t attrs, int flags)
136{
137 struct genl_family *a = (struct genl_family *) _a;
138 struct genl_family *b = (struct genl_family *) _b;
139 int diff = 0;
140
141#define FAM_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, FAMILY_ATTR_##ATTR, a, b, EXPR)
142
143 diff |= FAM_DIFF(ID, a->gf_id != b->gf_id);
144 diff |= FAM_DIFF(VERSION, a->gf_version != b->gf_version);
145 diff |= FAM_DIFF(HDRSIZE, a->gf_hdrsize != b->gf_hdrsize);
146 diff |= FAM_DIFF(MAXATTR, a->gf_maxattr != b->gf_maxattr);
147 diff |= FAM_DIFF(NAME, strcmp(a->gf_name, b->gf_name));
148
149#undef FAM_DIFF
150
151 return diff;
152}
153
154
155/**
156 * @name Family Object
157 * @{
158 */
159
160struct genl_family *genl_family_alloc(void)
161{
162 return (struct genl_family *) nl_object_alloc(&genl_family_ops);
163}
164
165void genl_family_put(struct genl_family *family)
166{
167 nl_object_put((struct nl_object *) family);
168}
169
170/** @} */
171
172/**
173 * @name Attributes
174 * @{
175 */
176
177unsigned int genl_family_get_id(struct genl_family *family)
178{
179 if (family->ce_mask & FAMILY_ATTR_ID)
180 return family->gf_id;
181 else
182 return GENL_ID_GENERATE;
183}
184
185void genl_family_set_id(struct genl_family *family, unsigned int id)
186{
187 family->gf_id = id;
188 family->ce_mask |= FAMILY_ATTR_ID;
189}
190
191char *genl_family_get_name(struct genl_family *family)
192{
193 if (family->ce_mask & FAMILY_ATTR_NAME)
194 return family->gf_name;
195 else
196 return NULL;
197}
198
199void genl_family_set_name(struct genl_family *family, const char *name)
200{
201 strncpy(family->gf_name, name, GENL_NAMSIZ-1);
202 family->ce_mask |= FAMILY_ATTR_NAME;
203}
204
205uint8_t genl_family_get_version(struct genl_family *family)
206{
207 if (family->ce_mask & FAMILY_ATTR_VERSION)
208 return family->gf_version;
209 else
210 return 0;
211}
212
213void genl_family_set_version(struct genl_family *family, uint8_t version)
214{
215 family->gf_version = version;
216 family->ce_mask |= FAMILY_ATTR_VERSION;
217}
218
219uint32_t genl_family_get_hdrsize(struct genl_family *family)
220{
221 if (family->ce_mask & FAMILY_ATTR_HDRSIZE)
222 return family->gf_hdrsize;
223 else
224 return 0;
225}
226
227void genl_family_set_hdrsize(struct genl_family *family, uint32_t hdrsize)
228{
229 family->gf_hdrsize = hdrsize;
230 family->ce_mask |= FAMILY_ATTR_HDRSIZE;
231}
232
233uint32_t genl_family_get_maxattr(struct genl_family *family)
234{
235 if (family->ce_mask & FAMILY_ATTR_MAXATTR)
236 return family->gf_maxattr;
237 else
238 return family->gf_maxattr;
239}
240
241void genl_family_set_maxattr(struct genl_family *family, uint32_t maxattr)
242{
243 family->gf_maxattr = maxattr;
244 family->ce_mask |= FAMILY_ATTR_MAXATTR;
245}
246
247int genl_family_add_op(struct genl_family *family, int id, int flags)
248{
249 struct genl_family_op *op;
250
251 op = calloc(1, sizeof(*op));
252 if (op == NULL)
253 return nl_errno(ENOMEM);
254
255 op->o_id = id;
256 op->o_flags = flags;
257
258 nl_list_add_tail(&op->o_list, &family->gf_ops);
259 family->ce_mask |= FAMILY_ATTR_OPS;
260
261 return 0;
262}
263
264/** @} */
265
266/** @cond SKIP */
267struct nl_object_ops genl_family_ops = {
268 .oo_name = "genl/family",
269 .oo_size = sizeof(struct genl_family),
270 .oo_constructor = family_constructor,
271 .oo_free_data = family_free_data,
272 .oo_clone = family_clone,
273 .oo_dump[NL_DUMP_BRIEF] = family_dump_brief,
274 .oo_dump[NL_DUMP_FULL] = family_dump_full,
275 .oo_dump[NL_DUMP_STATS] = family_dump_stats,
276#if 0
277 .oo_dump[NL_DUMP_XML] = addr_dump_xml,
278 .oo_dump[NL_DUMP_ENV] = addr_dump_env,
279#endif
280 .oo_compare = family_compare,
281 .oo_id_attrs = FAMILY_ATTR_ID,
282};
283/** @endcond */
284
285/** @} */
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
Definition: object.c:178
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
Definition: object.c:42
@ NL_DUMP_FULL
Dump all attributes but no statistics.
Definition: types.h:23
@ NL_DUMP_BRIEF
Dump object in a brief one-liner.
Definition: types.h:22
@ NL_DUMP_ENV
Dump all attribtues as env variables.
Definition: types.h:26
@ NL_DUMP_STATS
Dump all attributes including statistics.
Definition: types.h:24
@ NL_DUMP_XML
Dump all attribtes in XML format.
Definition: types.h:25
Dumping parameters.
Definition: types.h:37
Object Operations.
Definition: object-api.h:255
char * oo_name
Unique name of object type.
Definition: object-api.h:261