xref: /aosp_15_r20/external/libnl/lib/genl/family.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker  * Copyright (c) 2003-2012 Thomas Graf <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker  */
5*4dc78e53SAndroid Build Coastguard Worker 
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker  * @ingroup genl_ctrl
8*4dc78e53SAndroid Build Coastguard Worker  * @defgroup genl_family Generic Netlink Family Object
9*4dc78e53SAndroid Build Coastguard Worker  *
10*4dc78e53SAndroid Build Coastguard Worker  * Object representing a kernel side registered Generic Netlink family
11*4dc78e53SAndroid Build Coastguard Worker  *
12*4dc78e53SAndroid Build Coastguard Worker  * @{
13*4dc78e53SAndroid Build Coastguard Worker  */
14*4dc78e53SAndroid Build Coastguard Worker 
15*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
16*4dc78e53SAndroid Build Coastguard Worker 
17*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
18*4dc78e53SAndroid Build Coastguard Worker #include <netlink/genl/genl.h>
19*4dc78e53SAndroid Build Coastguard Worker #include <netlink/genl/family.h>
20*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
21*4dc78e53SAndroid Build Coastguard Worker 
22*4dc78e53SAndroid Build Coastguard Worker #include "nl-genl.h"
23*4dc78e53SAndroid Build Coastguard Worker #include "nl-priv-dynamic-core/object-api.h"
24*4dc78e53SAndroid Build Coastguard Worker #include "nl-priv-dynamic-core/nl-core.h"
25*4dc78e53SAndroid Build Coastguard Worker 
26*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
27*4dc78e53SAndroid Build Coastguard Worker struct genl_family_op
28*4dc78e53SAndroid Build Coastguard Worker {
29*4dc78e53SAndroid Build Coastguard Worker 	uint32_t		o_id;
30*4dc78e53SAndroid Build Coastguard Worker 	uint32_t		o_flags;
31*4dc78e53SAndroid Build Coastguard Worker 
32*4dc78e53SAndroid Build Coastguard Worker 	struct nl_list_head	o_list;
33*4dc78e53SAndroid Build Coastguard Worker };
34*4dc78e53SAndroid Build Coastguard Worker 
35*4dc78e53SAndroid Build Coastguard Worker #define FAMILY_ATTR_ID		0x01
36*4dc78e53SAndroid Build Coastguard Worker #define FAMILY_ATTR_NAME	0x02
37*4dc78e53SAndroid Build Coastguard Worker #define FAMILY_ATTR_VERSION	0x04
38*4dc78e53SAndroid Build Coastguard Worker #define FAMILY_ATTR_HDRSIZE	0x08
39*4dc78e53SAndroid Build Coastguard Worker #define FAMILY_ATTR_MAXATTR	0x10
40*4dc78e53SAndroid Build Coastguard Worker #define FAMILY_ATTR_OPS		0x20
41*4dc78e53SAndroid Build Coastguard Worker 
42*4dc78e53SAndroid Build Coastguard Worker struct nl_object_ops genl_family_ops;
43*4dc78e53SAndroid Build Coastguard Worker 
family_constructor(struct nl_object * c)44*4dc78e53SAndroid Build Coastguard Worker static void family_constructor(struct nl_object *c)
45*4dc78e53SAndroid Build Coastguard Worker {
46*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family *family = (struct genl_family *) c;
47*4dc78e53SAndroid Build Coastguard Worker 
48*4dc78e53SAndroid Build Coastguard Worker 	nl_init_list_head(&family->gf_ops);
49*4dc78e53SAndroid Build Coastguard Worker 	nl_init_list_head(&family->gf_mc_grps);
50*4dc78e53SAndroid Build Coastguard Worker }
51*4dc78e53SAndroid Build Coastguard Worker 
family_free_data(struct nl_object * c)52*4dc78e53SAndroid Build Coastguard Worker static void family_free_data(struct nl_object *c)
53*4dc78e53SAndroid Build Coastguard Worker {
54*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family *family = (struct genl_family *) c;
55*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family_op *ops, *tmp;
56*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family_grp *grp, *t_grp;
57*4dc78e53SAndroid Build Coastguard Worker 
58*4dc78e53SAndroid Build Coastguard Worker 	if (family == NULL)
59*4dc78e53SAndroid Build Coastguard Worker 		return;
60*4dc78e53SAndroid Build Coastguard Worker 
61*4dc78e53SAndroid Build Coastguard Worker 	nl_list_for_each_entry_safe(ops, tmp, &family->gf_ops, o_list) {
62*4dc78e53SAndroid Build Coastguard Worker 		nl_list_del(&ops->o_list);
63*4dc78e53SAndroid Build Coastguard Worker 		free(ops);
64*4dc78e53SAndroid Build Coastguard Worker 	}
65*4dc78e53SAndroid Build Coastguard Worker 
66*4dc78e53SAndroid Build Coastguard Worker 	nl_list_for_each_entry_safe(grp, t_grp, &family->gf_mc_grps, list) {
67*4dc78e53SAndroid Build Coastguard Worker 		nl_list_del(&grp->list);
68*4dc78e53SAndroid Build Coastguard Worker 		free(grp);
69*4dc78e53SAndroid Build Coastguard Worker 	}
70*4dc78e53SAndroid Build Coastguard Worker 
71*4dc78e53SAndroid Build Coastguard Worker }
72*4dc78e53SAndroid Build Coastguard Worker 
family_clone(struct nl_object * _dst,struct nl_object * _src)73*4dc78e53SAndroid Build Coastguard Worker static int family_clone(struct nl_object *_dst, struct nl_object *_src)
74*4dc78e53SAndroid Build Coastguard Worker {
75*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family *dst = nl_object_priv(_dst);
76*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family *src = nl_object_priv(_src);
77*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family_op *ops;
78*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family_grp *grp;
79*4dc78e53SAndroid Build Coastguard Worker 	int err;
80*4dc78e53SAndroid Build Coastguard Worker 
81*4dc78e53SAndroid Build Coastguard Worker 	nl_init_list_head(&dst->gf_ops);
82*4dc78e53SAndroid Build Coastguard Worker 	nl_init_list_head(&dst->gf_mc_grps);
83*4dc78e53SAndroid Build Coastguard Worker 
84*4dc78e53SAndroid Build Coastguard Worker 	nl_list_for_each_entry(ops, &src->gf_ops, o_list) {
85*4dc78e53SAndroid Build Coastguard Worker 		err = genl_family_add_op(dst, ops->o_id, ops->o_flags);
86*4dc78e53SAndroid Build Coastguard Worker 		if (err < 0)
87*4dc78e53SAndroid Build Coastguard Worker 			return err;
88*4dc78e53SAndroid Build Coastguard Worker 	}
89*4dc78e53SAndroid Build Coastguard Worker 
90*4dc78e53SAndroid Build Coastguard Worker 	nl_list_for_each_entry(grp, &src->gf_mc_grps, list) {
91*4dc78e53SAndroid Build Coastguard Worker 		err = genl_family_add_grp(dst, grp->id, grp->name);
92*4dc78e53SAndroid Build Coastguard Worker 		if (err < 0)
93*4dc78e53SAndroid Build Coastguard Worker 			return err;
94*4dc78e53SAndroid Build Coastguard Worker 	}
95*4dc78e53SAndroid Build Coastguard Worker 
96*4dc78e53SAndroid Build Coastguard Worker 
97*4dc78e53SAndroid Build Coastguard Worker 	return 0;
98*4dc78e53SAndroid Build Coastguard Worker }
99*4dc78e53SAndroid Build Coastguard Worker 
family_dump_line(struct nl_object * obj,struct nl_dump_params * p)100*4dc78e53SAndroid Build Coastguard Worker static void family_dump_line(struct nl_object *obj, struct nl_dump_params *p)
101*4dc78e53SAndroid Build Coastguard Worker {
102*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family *family = (struct genl_family *) obj;
103*4dc78e53SAndroid Build Coastguard Worker 
104*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "0x%04x %s version %u\n",
105*4dc78e53SAndroid Build Coastguard Worker 		family->gf_id, family->gf_name, family->gf_version);
106*4dc78e53SAndroid Build Coastguard Worker }
107*4dc78e53SAndroid Build Coastguard Worker 
108*4dc78e53SAndroid Build Coastguard Worker static const struct trans_tbl ops_flags[] = {
109*4dc78e53SAndroid Build Coastguard Worker 	__ADD(GENL_ADMIN_PERM, admin_perm),
110*4dc78e53SAndroid Build Coastguard Worker 	__ADD(GENL_CMD_CAP_DO, has_doit),
111*4dc78e53SAndroid Build Coastguard Worker 	__ADD(GENL_CMD_CAP_DUMP, has_dump),
112*4dc78e53SAndroid Build Coastguard Worker 	__ADD(GENL_CMD_CAP_HASPOL, has_policy),
113*4dc78e53SAndroid Build Coastguard Worker };
114*4dc78e53SAndroid Build Coastguard Worker 
ops_flags2str(int flags,char * buf,size_t len)115*4dc78e53SAndroid Build Coastguard Worker static char *ops_flags2str(int flags, char *buf, size_t len)
116*4dc78e53SAndroid Build Coastguard Worker {
117*4dc78e53SAndroid Build Coastguard Worker 	return __flags2str(flags, buf, len, ops_flags, ARRAY_SIZE(ops_flags));
118*4dc78e53SAndroid Build Coastguard Worker }
119*4dc78e53SAndroid Build Coastguard Worker 
family_dump_details(struct nl_object * obj,struct nl_dump_params * p)120*4dc78e53SAndroid Build Coastguard Worker static void family_dump_details(struct nl_object *obj, struct nl_dump_params *p)
121*4dc78e53SAndroid Build Coastguard Worker {
122*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family_grp *grp;
123*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family *family = (struct genl_family *) obj;
124*4dc78e53SAndroid Build Coastguard Worker 
125*4dc78e53SAndroid Build Coastguard Worker 	family_dump_line(obj, p);
126*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p, "    hdrsize %u maxattr %u\n",
127*4dc78e53SAndroid Build Coastguard Worker 		     family->gf_hdrsize, family->gf_maxattr);
128*4dc78e53SAndroid Build Coastguard Worker 
129*4dc78e53SAndroid Build Coastguard Worker 	if (family->ce_mask & FAMILY_ATTR_OPS) {
130*4dc78e53SAndroid Build Coastguard Worker 		struct genl_family_op *op;
131*4dc78e53SAndroid Build Coastguard Worker 		char buf[64];
132*4dc78e53SAndroid Build Coastguard Worker 
133*4dc78e53SAndroid Build Coastguard Worker 		nl_list_for_each_entry(op, &family->gf_ops, o_list) {
134*4dc78e53SAndroid Build Coastguard Worker 			ops_flags2str(op->o_flags, buf, sizeof(buf));
135*4dc78e53SAndroid Build Coastguard Worker 
136*4dc78e53SAndroid Build Coastguard Worker 			genl_op2name(family->gf_id, op->o_id, buf, sizeof(buf));
137*4dc78e53SAndroid Build Coastguard Worker 
138*4dc78e53SAndroid Build Coastguard Worker 			nl_dump_line(p, "      op %s (0x%02x)", buf, op->o_id);
139*4dc78e53SAndroid Build Coastguard Worker 
140*4dc78e53SAndroid Build Coastguard Worker 			if (op->o_flags)
141*4dc78e53SAndroid Build Coastguard Worker 				nl_dump(p, " <%s>",
142*4dc78e53SAndroid Build Coastguard Worker 					ops_flags2str(op->o_flags, buf,
143*4dc78e53SAndroid Build Coastguard Worker 						      sizeof(buf)));
144*4dc78e53SAndroid Build Coastguard Worker 
145*4dc78e53SAndroid Build Coastguard Worker 			nl_dump(p, "\n");
146*4dc78e53SAndroid Build Coastguard Worker 		}
147*4dc78e53SAndroid Build Coastguard Worker 	}
148*4dc78e53SAndroid Build Coastguard Worker 
149*4dc78e53SAndroid Build Coastguard Worker 	nl_list_for_each_entry(grp, &family->gf_mc_grps, list) {
150*4dc78e53SAndroid Build Coastguard Worker 		nl_dump_line(p, "      grp %s (0x%02x)\n", grp->name, grp->id);
151*4dc78e53SAndroid Build Coastguard Worker 	}
152*4dc78e53SAndroid Build Coastguard Worker 
153*4dc78e53SAndroid Build Coastguard Worker }
154*4dc78e53SAndroid Build Coastguard Worker 
family_dump_stats(struct nl_object * obj,struct nl_dump_params * p)155*4dc78e53SAndroid Build Coastguard Worker static void family_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
156*4dc78e53SAndroid Build Coastguard Worker {
157*4dc78e53SAndroid Build Coastguard Worker 	family_dump_details(obj, p);
158*4dc78e53SAndroid Build Coastguard Worker }
159*4dc78e53SAndroid Build Coastguard Worker 
family_compare(struct nl_object * _a,struct nl_object * _b,uint64_t attrs,int flags)160*4dc78e53SAndroid Build Coastguard Worker static uint64_t family_compare(struct nl_object *_a, struct nl_object *_b,
161*4dc78e53SAndroid Build Coastguard Worker 			  uint64_t attrs, int flags)
162*4dc78e53SAndroid Build Coastguard Worker {
163*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family *a = (struct genl_family *) _a;
164*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family *b = (struct genl_family *) _b;
165*4dc78e53SAndroid Build Coastguard Worker 	uint64_t diff = 0;
166*4dc78e53SAndroid Build Coastguard Worker 
167*4dc78e53SAndroid Build Coastguard Worker #define _DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ATTR, a, b, EXPR)
168*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(FAMILY_ATTR_ID, a->gf_id != b->gf_id);
169*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(FAMILY_ATTR_VERSION, a->gf_version != b->gf_version);
170*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(FAMILY_ATTR_HDRSIZE, a->gf_hdrsize != b->gf_hdrsize);
171*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(FAMILY_ATTR_MAXATTR, a->gf_maxattr != b->gf_maxattr);
172*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(FAMILY_ATTR_NAME, strcmp(a->gf_name, b->gf_name));
173*4dc78e53SAndroid Build Coastguard Worker #undef _DIFF
174*4dc78e53SAndroid Build Coastguard Worker 
175*4dc78e53SAndroid Build Coastguard Worker 	return diff;
176*4dc78e53SAndroid Build Coastguard Worker }
177*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
178*4dc78e53SAndroid Build Coastguard Worker 
179*4dc78e53SAndroid Build Coastguard Worker /**
180*4dc78e53SAndroid Build Coastguard Worker  * @name Object Allocation
181*4dc78e53SAndroid Build Coastguard Worker  * @{
182*4dc78e53SAndroid Build Coastguard Worker  */
183*4dc78e53SAndroid Build Coastguard Worker 
184*4dc78e53SAndroid Build Coastguard Worker /**
185*4dc78e53SAndroid Build Coastguard Worker  * Allocate new Generic Netlink family object
186*4dc78e53SAndroid Build Coastguard Worker  *
187*4dc78e53SAndroid Build Coastguard Worker  * @return Newly allocated Generic Netlink family object or NULL.
188*4dc78e53SAndroid Build Coastguard Worker  */
genl_family_alloc(void)189*4dc78e53SAndroid Build Coastguard Worker struct genl_family *genl_family_alloc(void)
190*4dc78e53SAndroid Build Coastguard Worker {
191*4dc78e53SAndroid Build Coastguard Worker 	return (struct genl_family *) nl_object_alloc(&genl_family_ops);
192*4dc78e53SAndroid Build Coastguard Worker }
193*4dc78e53SAndroid Build Coastguard Worker 
194*4dc78e53SAndroid Build Coastguard Worker /**
195*4dc78e53SAndroid Build Coastguard Worker  * Release reference on Generic Netlink family object
196*4dc78e53SAndroid Build Coastguard Worker  * @arg family		Generic Netlink family object
197*4dc78e53SAndroid Build Coastguard Worker  *
198*4dc78e53SAndroid Build Coastguard Worker  * Reduces the reference counter of a Generic Netlink family object by one.
199*4dc78e53SAndroid Build Coastguard Worker  * The object is freed after the last user has returned its reference.
200*4dc78e53SAndroid Build Coastguard Worker  *
201*4dc78e53SAndroid Build Coastguard Worker  * @see nl_object_put()
202*4dc78e53SAndroid Build Coastguard Worker  */
genl_family_put(struct genl_family * family)203*4dc78e53SAndroid Build Coastguard Worker void genl_family_put(struct genl_family *family)
204*4dc78e53SAndroid Build Coastguard Worker {
205*4dc78e53SAndroid Build Coastguard Worker 	nl_object_put((struct nl_object *) family);
206*4dc78e53SAndroid Build Coastguard Worker }
207*4dc78e53SAndroid Build Coastguard Worker 
208*4dc78e53SAndroid Build Coastguard Worker /** @} */
209*4dc78e53SAndroid Build Coastguard Worker 
210*4dc78e53SAndroid Build Coastguard Worker /**
211*4dc78e53SAndroid Build Coastguard Worker  * @name Numeric Identifier
212*4dc78e53SAndroid Build Coastguard Worker  * @{
213*4dc78e53SAndroid Build Coastguard Worker  */
214*4dc78e53SAndroid Build Coastguard Worker 
215*4dc78e53SAndroid Build Coastguard Worker /**
216*4dc78e53SAndroid Build Coastguard Worker  * Return numeric identifier
217*4dc78e53SAndroid Build Coastguard Worker  * @arg family		Generic Netlink family object
218*4dc78e53SAndroid Build Coastguard Worker  *
219*4dc78e53SAndroid Build Coastguard Worker  * @return Numeric identifier or 0 if not available.
220*4dc78e53SAndroid Build Coastguard Worker  */
genl_family_get_id(struct genl_family * family)221*4dc78e53SAndroid Build Coastguard Worker unsigned int genl_family_get_id(struct genl_family *family)
222*4dc78e53SAndroid Build Coastguard Worker {
223*4dc78e53SAndroid Build Coastguard Worker 	if (family->ce_mask & FAMILY_ATTR_ID)
224*4dc78e53SAndroid Build Coastguard Worker 		return family->gf_id;
225*4dc78e53SAndroid Build Coastguard Worker 	else
226*4dc78e53SAndroid Build Coastguard Worker 		return 0;
227*4dc78e53SAndroid Build Coastguard Worker }
228*4dc78e53SAndroid Build Coastguard Worker 
229*4dc78e53SAndroid Build Coastguard Worker /**
230*4dc78e53SAndroid Build Coastguard Worker  * Set the numeric identifier
231*4dc78e53SAndroid Build Coastguard Worker  * @arg family		Generic Netlink family object
232*4dc78e53SAndroid Build Coastguard Worker  * @arg id		New numeric identifier
233*4dc78e53SAndroid Build Coastguard Worker  */
genl_family_set_id(struct genl_family * family,unsigned int id)234*4dc78e53SAndroid Build Coastguard Worker void genl_family_set_id(struct genl_family *family, unsigned int id)
235*4dc78e53SAndroid Build Coastguard Worker {
236*4dc78e53SAndroid Build Coastguard Worker 	family->gf_id = id;
237*4dc78e53SAndroid Build Coastguard Worker 	family->ce_mask |= FAMILY_ATTR_ID;
238*4dc78e53SAndroid Build Coastguard Worker }
239*4dc78e53SAndroid Build Coastguard Worker 
240*4dc78e53SAndroid Build Coastguard Worker /** @} */
241*4dc78e53SAndroid Build Coastguard Worker 
242*4dc78e53SAndroid Build Coastguard Worker /**
243*4dc78e53SAndroid Build Coastguard Worker  * @name Human Readable Name
244*4dc78e53SAndroid Build Coastguard Worker  * @{
245*4dc78e53SAndroid Build Coastguard Worker  */
246*4dc78e53SAndroid Build Coastguard Worker 
247*4dc78e53SAndroid Build Coastguard Worker /**
248*4dc78e53SAndroid Build Coastguard Worker  * Return human readable name
249*4dc78e53SAndroid Build Coastguard Worker  * @arg family		Generic Netlink family object
250*4dc78e53SAndroid Build Coastguard Worker  *
251*4dc78e53SAndroid Build Coastguard Worker  * @return Name of family or NULL if not available
252*4dc78e53SAndroid Build Coastguard Worker  */
genl_family_get_name(struct genl_family * family)253*4dc78e53SAndroid Build Coastguard Worker char *genl_family_get_name(struct genl_family *family)
254*4dc78e53SAndroid Build Coastguard Worker {
255*4dc78e53SAndroid Build Coastguard Worker 	if (family->ce_mask & FAMILY_ATTR_NAME)
256*4dc78e53SAndroid Build Coastguard Worker 		return family->gf_name;
257*4dc78e53SAndroid Build Coastguard Worker 	else
258*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
259*4dc78e53SAndroid Build Coastguard Worker }
260*4dc78e53SAndroid Build Coastguard Worker 
261*4dc78e53SAndroid Build Coastguard Worker /**
262*4dc78e53SAndroid Build Coastguard Worker  * Set human readable name
263*4dc78e53SAndroid Build Coastguard Worker  * @arg family		Generic Netlink family object
264*4dc78e53SAndroid Build Coastguard Worker  * @arg name		New human readable name
265*4dc78e53SAndroid Build Coastguard Worker  */
genl_family_set_name(struct genl_family * family,const char * name)266*4dc78e53SAndroid Build Coastguard Worker void genl_family_set_name(struct genl_family *family, const char *name)
267*4dc78e53SAndroid Build Coastguard Worker {
268*4dc78e53SAndroid Build Coastguard Worker 	_nl_strncpy_trunc(family->gf_name, name, GENL_NAMSIZ);
269*4dc78e53SAndroid Build Coastguard Worker 	family->ce_mask |= FAMILY_ATTR_NAME;
270*4dc78e53SAndroid Build Coastguard Worker }
271*4dc78e53SAndroid Build Coastguard Worker 
272*4dc78e53SAndroid Build Coastguard Worker /**
273*4dc78e53SAndroid Build Coastguard Worker  * @name Interface Version
274*4dc78e53SAndroid Build Coastguard Worker  * @{
275*4dc78e53SAndroid Build Coastguard Worker  */
276*4dc78e53SAndroid Build Coastguard Worker 
277*4dc78e53SAndroid Build Coastguard Worker /**
278*4dc78e53SAndroid Build Coastguard Worker  * Return interface version
279*4dc78e53SAndroid Build Coastguard Worker  * @arg family		Generic Netlink family object
280*4dc78e53SAndroid Build Coastguard Worker  *
281*4dc78e53SAndroid Build Coastguard Worker  * @return Interface version or 0 if not available.
282*4dc78e53SAndroid Build Coastguard Worker  */
genl_family_get_version(struct genl_family * family)283*4dc78e53SAndroid Build Coastguard Worker uint8_t genl_family_get_version(struct genl_family *family)
284*4dc78e53SAndroid Build Coastguard Worker {
285*4dc78e53SAndroid Build Coastguard Worker 	if (family->ce_mask & FAMILY_ATTR_VERSION)
286*4dc78e53SAndroid Build Coastguard Worker 		return family->gf_version;
287*4dc78e53SAndroid Build Coastguard Worker 	else
288*4dc78e53SAndroid Build Coastguard Worker 		return 0;
289*4dc78e53SAndroid Build Coastguard Worker }
290*4dc78e53SAndroid Build Coastguard Worker 
291*4dc78e53SAndroid Build Coastguard Worker /**
292*4dc78e53SAndroid Build Coastguard Worker  * Set interface version
293*4dc78e53SAndroid Build Coastguard Worker  * @arg family		Generic Netlink family object
294*4dc78e53SAndroid Build Coastguard Worker  * @arg version		New interface version
295*4dc78e53SAndroid Build Coastguard Worker  */
genl_family_set_version(struct genl_family * family,uint8_t version)296*4dc78e53SAndroid Build Coastguard Worker void genl_family_set_version(struct genl_family *family, uint8_t version)
297*4dc78e53SAndroid Build Coastguard Worker {
298*4dc78e53SAndroid Build Coastguard Worker 	family->gf_version = version;
299*4dc78e53SAndroid Build Coastguard Worker 	family->ce_mask |= FAMILY_ATTR_VERSION;
300*4dc78e53SAndroid Build Coastguard Worker }
301*4dc78e53SAndroid Build Coastguard Worker 
302*4dc78e53SAndroid Build Coastguard Worker /** @} */
303*4dc78e53SAndroid Build Coastguard Worker 
304*4dc78e53SAndroid Build Coastguard Worker /**
305*4dc78e53SAndroid Build Coastguard Worker  * @name Header Size
306*4dc78e53SAndroid Build Coastguard Worker  * @{
307*4dc78e53SAndroid Build Coastguard Worker  */
308*4dc78e53SAndroid Build Coastguard Worker 
309*4dc78e53SAndroid Build Coastguard Worker /**
310*4dc78e53SAndroid Build Coastguard Worker  * Return user header size expected by kernel component
311*4dc78e53SAndroid Build Coastguard Worker  * @arg family		Generic Netlink family object
312*4dc78e53SAndroid Build Coastguard Worker  *
313*4dc78e53SAndroid Build Coastguard Worker  * @return Expected header length or 0 if not available.
314*4dc78e53SAndroid Build Coastguard Worker  */
genl_family_get_hdrsize(struct genl_family * family)315*4dc78e53SAndroid Build Coastguard Worker uint32_t genl_family_get_hdrsize(struct genl_family *family)
316*4dc78e53SAndroid Build Coastguard Worker {
317*4dc78e53SAndroid Build Coastguard Worker 	if (family->ce_mask & FAMILY_ATTR_HDRSIZE)
318*4dc78e53SAndroid Build Coastguard Worker 		return family->gf_hdrsize;
319*4dc78e53SAndroid Build Coastguard Worker 	else
320*4dc78e53SAndroid Build Coastguard Worker 		return 0;
321*4dc78e53SAndroid Build Coastguard Worker }
322*4dc78e53SAndroid Build Coastguard Worker 
genl_family_set_hdrsize(struct genl_family * family,uint32_t hdrsize)323*4dc78e53SAndroid Build Coastguard Worker void genl_family_set_hdrsize(struct genl_family *family, uint32_t hdrsize)
324*4dc78e53SAndroid Build Coastguard Worker {
325*4dc78e53SAndroid Build Coastguard Worker 	family->gf_hdrsize = hdrsize;
326*4dc78e53SAndroid Build Coastguard Worker 	family->ce_mask |= FAMILY_ATTR_HDRSIZE;
327*4dc78e53SAndroid Build Coastguard Worker }
328*4dc78e53SAndroid Build Coastguard Worker 
329*4dc78e53SAndroid Build Coastguard Worker /** @} */
330*4dc78e53SAndroid Build Coastguard Worker 
331*4dc78e53SAndroid Build Coastguard Worker /**
332*4dc78e53SAndroid Build Coastguard Worker  * @name Maximum Expected Attribute
333*4dc78e53SAndroid Build Coastguard Worker  * @{
334*4dc78e53SAndroid Build Coastguard Worker  */
335*4dc78e53SAndroid Build Coastguard Worker 
genl_family_get_maxattr(struct genl_family * family)336*4dc78e53SAndroid Build Coastguard Worker uint32_t genl_family_get_maxattr(struct genl_family *family)
337*4dc78e53SAndroid Build Coastguard Worker {
338*4dc78e53SAndroid Build Coastguard Worker 	if (family->ce_mask & FAMILY_ATTR_MAXATTR)
339*4dc78e53SAndroid Build Coastguard Worker 		return family->gf_maxattr;
340*4dc78e53SAndroid Build Coastguard Worker 	else
341*4dc78e53SAndroid Build Coastguard Worker 		return 0;
342*4dc78e53SAndroid Build Coastguard Worker }
343*4dc78e53SAndroid Build Coastguard Worker 
genl_family_set_maxattr(struct genl_family * family,uint32_t maxattr)344*4dc78e53SAndroid Build Coastguard Worker void genl_family_set_maxattr(struct genl_family *family, uint32_t maxattr)
345*4dc78e53SAndroid Build Coastguard Worker {
346*4dc78e53SAndroid Build Coastguard Worker 	family->gf_maxattr = maxattr;
347*4dc78e53SAndroid Build Coastguard Worker 	family->ce_mask |= FAMILY_ATTR_MAXATTR;
348*4dc78e53SAndroid Build Coastguard Worker }
349*4dc78e53SAndroid Build Coastguard Worker 
350*4dc78e53SAndroid Build Coastguard Worker /** @} */
351*4dc78e53SAndroid Build Coastguard Worker 
352*4dc78e53SAndroid Build Coastguard Worker /**
353*4dc78e53SAndroid Build Coastguard Worker  * @name Operations
354*4dc78e53SAndroid Build Coastguard Worker  * @{
355*4dc78e53SAndroid Build Coastguard Worker  */
356*4dc78e53SAndroid Build Coastguard Worker 
genl_family_add_op(struct genl_family * family,int id,int flags)357*4dc78e53SAndroid Build Coastguard Worker int genl_family_add_op(struct genl_family *family, int id, int flags)
358*4dc78e53SAndroid Build Coastguard Worker {
359*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family_op *op;
360*4dc78e53SAndroid Build Coastguard Worker 
361*4dc78e53SAndroid Build Coastguard Worker 	op = calloc(1, sizeof(*op));
362*4dc78e53SAndroid Build Coastguard Worker 	if (op == NULL)
363*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
364*4dc78e53SAndroid Build Coastguard Worker 
365*4dc78e53SAndroid Build Coastguard Worker 	op->o_id = id;
366*4dc78e53SAndroid Build Coastguard Worker 	op->o_flags = flags;
367*4dc78e53SAndroid Build Coastguard Worker 
368*4dc78e53SAndroid Build Coastguard Worker 	nl_list_add_tail(&op->o_list, &family->gf_ops);
369*4dc78e53SAndroid Build Coastguard Worker 	family->ce_mask |= FAMILY_ATTR_OPS;
370*4dc78e53SAndroid Build Coastguard Worker 
371*4dc78e53SAndroid Build Coastguard Worker 	return 0;
372*4dc78e53SAndroid Build Coastguard Worker }
373*4dc78e53SAndroid Build Coastguard Worker 
genl_family_add_grp(struct genl_family * family,uint32_t id,const char * name)374*4dc78e53SAndroid Build Coastguard Worker int genl_family_add_grp(struct genl_family *family, uint32_t id,
375*4dc78e53SAndroid Build Coastguard Worker                         const char *name)
376*4dc78e53SAndroid Build Coastguard Worker {
377*4dc78e53SAndroid Build Coastguard Worker 	struct genl_family_grp *grp;
378*4dc78e53SAndroid Build Coastguard Worker 
379*4dc78e53SAndroid Build Coastguard Worker 	if (   !name
380*4dc78e53SAndroid Build Coastguard Worker 	    || strlen (name) >= GENL_NAMSIZ)
381*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
382*4dc78e53SAndroid Build Coastguard Worker 
383*4dc78e53SAndroid Build Coastguard Worker 	grp = calloc(1, sizeof(*grp));
384*4dc78e53SAndroid Build Coastguard Worker 	if (grp == NULL)
385*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
386*4dc78e53SAndroid Build Coastguard Worker 
387*4dc78e53SAndroid Build Coastguard Worker 	grp->id = id;
388*4dc78e53SAndroid Build Coastguard Worker 	_nl_strncpy_assert(grp->name, name, GENL_NAMSIZ);
389*4dc78e53SAndroid Build Coastguard Worker 
390*4dc78e53SAndroid Build Coastguard Worker 	nl_list_add_tail(&grp->list, &family->gf_mc_grps);
391*4dc78e53SAndroid Build Coastguard Worker 
392*4dc78e53SAndroid Build Coastguard Worker 	return 0;
393*4dc78e53SAndroid Build Coastguard Worker }
394*4dc78e53SAndroid Build Coastguard Worker 
395*4dc78e53SAndroid Build Coastguard Worker /** @} */
396*4dc78e53SAndroid Build Coastguard Worker 
397*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
398*4dc78e53SAndroid Build Coastguard Worker struct nl_object_ops genl_family_ops = {
399*4dc78e53SAndroid Build Coastguard Worker 	.oo_name		= "genl/family",
400*4dc78e53SAndroid Build Coastguard Worker 	.oo_size		= sizeof(struct genl_family),
401*4dc78e53SAndroid Build Coastguard Worker 	.oo_constructor		= family_constructor,
402*4dc78e53SAndroid Build Coastguard Worker 	.oo_free_data		= family_free_data,
403*4dc78e53SAndroid Build Coastguard Worker 	.oo_clone		= family_clone,
404*4dc78e53SAndroid Build Coastguard Worker 	.oo_dump = {
405*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_LINE]	= family_dump_line,
406*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_DETAILS]	= family_dump_details,
407*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_STATS]	= family_dump_stats,
408*4dc78e53SAndroid Build Coastguard Worker 	},
409*4dc78e53SAndroid Build Coastguard Worker 	.oo_compare		= family_compare,
410*4dc78e53SAndroid Build Coastguard Worker 	.oo_id_attrs		= FAMILY_ATTR_ID,
411*4dc78e53SAndroid Build Coastguard Worker };
412*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
413*4dc78e53SAndroid Build Coastguard Worker 
414*4dc78e53SAndroid Build Coastguard Worker /** @} */
415