libnl  1.1
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 
34 struct nl_object_ops genl_family_ops;
35 /** @endcond */
36 
37 static 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 
44 static 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 
58 static 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 
74 static 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 
84 static 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 
91 static 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 
96 static 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 
129 static int family_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
130 {
131  return family_dump_full(obj, p);
132 }
133 
134 static 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 
160 struct genl_family *genl_family_alloc(void)
161 {
162  return (struct genl_family *) nl_object_alloc(&genl_family_ops);
163 }
164 
165 void 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 
177 unsigned 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 
185 void 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 
191 char *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 
199 void 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 
205 uint8_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 
213 void 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 
219 uint32_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 
227 void 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 
233 uint32_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 
241 void 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 
247 int 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 */
267 struct 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 /** @} */
Dump object in a brief one-liner.
Definition: types.h:22
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
Dump all attribtes in XML format.
Definition: types.h:25
Object Operations.
Definition: object-api.h:254
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
Definition: object.c:173
Dumping parameters.
Definition: types.h:36
char * oo_name
Unique name of object type.
Definition: object-api.h:261
Dump all attributes but no statistics.
Definition: types.h:23
Dump all attributes including statistics.
Definition: types.h:24
Dump all attribtues as env variables.
Definition: types.h:26