libnl  3.6.0
ctrl.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
4  */
5 
6 /**
7  * @ingroup genl
8  * @defgroup genl_ctrl Controller (Resolver)
9  *
10  * Resolves Generic Netlink family names to numeric identifiers.
11  *
12  * The controller is a component in the kernel that resolves Generic Netlink
13  * family names to their numeric identifiers. This module provides functions
14  * to query the controller to access the resolving functionality.
15  * @{
16  */
17 
18 #include <netlink-private/genl.h>
19 #include <netlink/netlink.h>
20 #include <netlink/genl/genl.h>
21 #include <netlink/genl/family.h>
22 #include <netlink/genl/mngt.h>
23 #include <netlink/genl/ctrl.h>
24 #include <netlink/utils.h>
25 
26 /** @cond SKIP */
27 #define CTRL_VERSION 0x0001
28 
29 static struct nl_cache_ops genl_ctrl_ops;
30 
31 static int ctrl_request_update(struct nl_cache *c, struct nl_sock *h)
32 {
33  return genl_send_simple(h, GENL_ID_CTRL, CTRL_CMD_GETFAMILY,
34  CTRL_VERSION, NLM_F_DUMP);
35 }
36 
37 static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = {
38  [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 },
39  [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_STRING,
40  .maxlen = GENL_NAMSIZ },
41  [CTRL_ATTR_VERSION] = { .type = NLA_U32 },
42  [CTRL_ATTR_HDRSIZE] = { .type = NLA_U32 },
43  [CTRL_ATTR_MAXATTR] = { .type = NLA_U32 },
44  [CTRL_ATTR_OPS] = { .type = NLA_NESTED },
45  [CTRL_ATTR_MCAST_GROUPS] = { .type = NLA_NESTED },
46 };
47 
48 static struct nla_policy family_op_policy[CTRL_ATTR_OP_MAX+1] = {
49  [CTRL_ATTR_OP_ID] = { .type = NLA_U32 },
50  [CTRL_ATTR_OP_FLAGS] = { .type = NLA_U32 },
51 };
52 
53 static struct nla_policy family_grp_policy[CTRL_ATTR_MCAST_GRP_MAX+1] = {
54  [CTRL_ATTR_MCAST_GRP_NAME] = { .type = NLA_STRING },
55  [CTRL_ATTR_MCAST_GRP_ID] = { .type = NLA_U32 },
56 };
57 
58 static int parse_mcast_grps(struct genl_family *family, struct nlattr *grp_attr)
59 {
60  struct nlattr *nla;
61  int remaining, err;
62 
63  if (!grp_attr)
64  BUG();
65 
66  nla_for_each_nested(nla, grp_attr, remaining) {
67  struct nlattr *tb[CTRL_ATTR_MCAST_GRP_MAX+1];
68  int id;
69  const char * name;
70 
71  err = nla_parse_nested(tb, CTRL_ATTR_MCAST_GRP_MAX, nla,
72  family_grp_policy);
73  if (err < 0)
74  goto errout;
75 
76  if (tb[CTRL_ATTR_MCAST_GRP_ID] == NULL) {
77  err = -NLE_MISSING_ATTR;
78  goto errout;
79  }
80  id = nla_get_u32(tb[CTRL_ATTR_MCAST_GRP_ID]);
81 
82  if (tb[CTRL_ATTR_MCAST_GRP_NAME] == NULL) {
83  err = -NLE_MISSING_ATTR;
84  goto errout;
85  }
86  name = nla_get_string(tb[CTRL_ATTR_MCAST_GRP_NAME]);
87 
88  err = genl_family_add_grp(family, id, name);
89  if (err < 0)
90  goto errout;
91  }
92 
93  err = 0;
94 
95 errout:
96  return err;
97 }
98 
99 static int ctrl_msg_parser(struct nl_cache_ops *ops, struct genl_cmd *cmd,
100  struct genl_info *info, void *arg)
101 {
102  struct genl_family *family;
103  struct nl_parser_param *pp = arg;
104  int err;
105 
106  family = genl_family_alloc();
107  if (family == NULL) {
108  err = -NLE_NOMEM;
109  goto errout;
110  }
111 
112  if (info->attrs[CTRL_ATTR_FAMILY_NAME] == NULL) {
113  err = -NLE_MISSING_ATTR;
114  goto errout;
115  }
116 
117  if (info->attrs[CTRL_ATTR_FAMILY_ID] == NULL) {
118  err = -NLE_MISSING_ATTR;
119  goto errout;
120  }
121 
122  family->ce_msgtype = info->nlh->nlmsg_type;
123  genl_family_set_id(family,
124  nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID]));
125  genl_family_set_name(family,
126  nla_get_string(info->attrs[CTRL_ATTR_FAMILY_NAME]));
127 
128  if (info->attrs[CTRL_ATTR_VERSION]) {
129  uint32_t version = nla_get_u32(info->attrs[CTRL_ATTR_VERSION]);
130  genl_family_set_version(family, version);
131  }
132 
133  if (info->attrs[CTRL_ATTR_HDRSIZE]) {
134  uint32_t hdrsize = nla_get_u32(info->attrs[CTRL_ATTR_HDRSIZE]);
135  genl_family_set_hdrsize(family, hdrsize);
136  }
137 
138  if (info->attrs[CTRL_ATTR_MAXATTR]) {
139  uint32_t maxattr = nla_get_u32(info->attrs[CTRL_ATTR_MAXATTR]);
140  genl_family_set_maxattr(family, maxattr);
141  }
142 
143  if (info->attrs[CTRL_ATTR_OPS]) {
144  struct nlattr *nla, *nla_ops;
145  int remaining;
146 
147  nla_ops = info->attrs[CTRL_ATTR_OPS];
148  nla_for_each_nested(nla, nla_ops, remaining) {
149  struct nlattr *tb[CTRL_ATTR_OP_MAX+1];
150  int flags = 0, id;
151 
152  err = nla_parse_nested(tb, CTRL_ATTR_OP_MAX, nla,
153  family_op_policy);
154  if (err < 0)
155  goto errout;
156 
157  if (tb[CTRL_ATTR_OP_ID] == NULL) {
158  err = -NLE_MISSING_ATTR;
159  goto errout;
160  }
161 
162  id = nla_get_u32(tb[CTRL_ATTR_OP_ID]);
163 
164  if (tb[CTRL_ATTR_OP_FLAGS])
165  flags = nla_get_u32(tb[CTRL_ATTR_OP_FLAGS]);
166 
167  err = genl_family_add_op(family, id, flags);
168  if (err < 0)
169  goto errout;
170 
171  }
172  }
173 
174  if (info->attrs[CTRL_ATTR_MCAST_GROUPS]) {
175  err = parse_mcast_grps(family, info->attrs[CTRL_ATTR_MCAST_GROUPS]);
176  if (err < 0)
177  goto errout;
178  }
179 
180  err = pp->pp_cb((struct nl_object *) family, pp);
181 errout:
182  genl_family_put(family);
183  return err;
184 }
185 
186 /**
187  * process responses from from the query sent by genl_ctrl_probe_by_name
188  * @arg nl_msg Returned message.
189  * @arg name genl_family structure to fill out.
190  *
191  * Process returned messages, filling out the missing informatino in the
192  * genl_family structure
193  *
194  * @return Indicator to keep processing frames or not
195  *
196  */
197 static int probe_response(struct nl_msg *msg, void *arg)
198 {
199  struct nlattr *tb[CTRL_ATTR_MAX+1];
200  struct nlmsghdr *nlh = nlmsg_hdr(msg);
201  struct genl_family *ret = (struct genl_family *)arg;
202 
203  if (genlmsg_parse(nlh, 0, tb, CTRL_ATTR_MAX, ctrl_policy))
204  return NL_SKIP;
205 
206  if (tb[CTRL_ATTR_FAMILY_ID])
207  genl_family_set_id(ret, nla_get_u16(tb[CTRL_ATTR_FAMILY_ID]));
208 
209  if (tb[CTRL_ATTR_MCAST_GROUPS])
210  if (parse_mcast_grps(ret, tb[CTRL_ATTR_MCAST_GROUPS]) < 0)
211  return NL_SKIP;
212 
213  return NL_STOP;
214 }
215 
216 /**
217  * Look up generic netlink family by family name querying the kernel directly
218  * @arg sk Socket.
219  * @arg name Family name.
220  *
221  * Directly query's the kernel for a given family name. The caller will own a
222  * reference on the returned object which needsd to be given back after usage
223  * using genl_family_put.
224  *
225  * Note: This API call differs from genl_ctrl_search_by_name in that it querys
226  * the kernel directly, alowing for module autoload to take place to resolve the
227  * family request. Using an nl_cache prevents that operation
228  *
229  * @return Generic netlink family object or NULL if no match was found.
230  */
231 static struct genl_family *genl_ctrl_probe_by_name(struct nl_sock *sk,
232  const char *name)
233 {
234  struct nl_msg *msg;
235  struct genl_family *ret;
236  struct nl_cb *cb, *orig;
237  int rc;
238 
239  ret = genl_family_alloc();
240  if (!ret)
241  goto out;
242 
243  genl_family_set_name(ret, name);
244 
245  msg = nlmsg_alloc();
246  if (!msg)
247  goto out_fam_free;
248 
249  if (!(orig = nl_socket_get_cb(sk)))
250  goto out_msg_free;
251 
252  cb = nl_cb_clone(orig);
253  nl_cb_put(orig);
254  if (!cb)
255  goto out_msg_free;
256 
257  if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, GENL_ID_CTRL,
258  0, 0, CTRL_CMD_GETFAMILY, 1)) {
259  BUG();
260  goto out_cb_free;
261  }
262 
263  if (nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, name) < 0)
264  goto out_cb_free;
265 
266  rc = nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, probe_response,
267  (void *) ret);
268  if (rc < 0)
269  goto out_cb_free;
270 
271  rc = nl_send_auto_complete(sk, msg);
272  if (rc < 0)
273  goto out_cb_free;
274 
275  rc = nl_recvmsgs(sk, cb);
276  if (rc < 0)
277  goto out_cb_free;
278 
279  /* If search was successful, request may be ACKed after data */
280  rc = wait_for_ack(sk);
281  if (rc < 0)
282  goto out_cb_free;
283 
284  if (genl_family_get_id(ret) != 0) {
285  nlmsg_free(msg);
286  nl_cb_put(cb);
287  return ret;
288  }
289 
290 out_cb_free:
291  nl_cb_put(cb);
292 out_msg_free:
293  nlmsg_free(msg);
294 out_fam_free:
295  genl_family_put(ret);
296  ret = NULL;
297 out:
298  return ret;
299 }
300 
301 
302 /** @endcond */
303 
304 /**
305  * @name Controller Cache
306  *
307  * The controller cache allows to keep a local copy of the list of all
308  * kernel side registered Generic Netlink families to quickly resolve
309  * multiple Generic Netlink family names without requiring to communicate
310  * with the kernel for each resolving iteration.
311  *
312  * @{
313  */
314 
315 /**
316  * Allocate a new controller cache
317  * @arg sk Generic Netlink socket
318  * @arg result Pointer to store resulting cache
319  *
320  * Allocates a new cache mirroring the state of the controller and stores it
321  * in \c *result. The allocated cache will contain a list of all currently
322  * registered kernel side Generic Netlink families. The cache is meant to be
323  * used to resolve family names locally.
324  *
325  * @return 0 on success or a negative error code.
326  */
327 int genl_ctrl_alloc_cache(struct nl_sock *sk, struct nl_cache **result)
328 {
329  return nl_cache_alloc_and_fill(&genl_ctrl_ops, sk, result);
330 }
331 
332 /**
333  * Search controller cache for a numeric address match
334  * @arg cache Controller cache
335  * @arg id Numeric family identifier.
336  *
337  * Searches a previously allocated controller cache and looks for an entry
338  * that matches the specified numeric family identifier \c id. If a match
339  * is found successfully, the reference count of the matching object is
340  * increased by one before the objet is returned.
341  *
342  * @see genl_ctrl_alloc_cache()
343  * @see genl_ctrl_search_by_name()
344  * @see genl_family_put()
345  *
346  * @return Generic Netlink family object or NULL if no match was found.
347  */
348 struct genl_family *genl_ctrl_search(struct nl_cache *cache, int id)
349 {
350  struct genl_family *fam;
351 
352  if (cache->c_ops != &genl_ctrl_ops)
353  BUG();
354 
355  nl_list_for_each_entry(fam, &cache->c_items, ce_list) {
356  if (fam->gf_id == id) {
357  nl_object_get((struct nl_object *) fam);
358  return fam;
359  }
360  }
361 
362  return NULL;
363 }
364 
365 /**
366  * Search controller cache for a family name match
367  * @arg cache Controller cache
368  * @arg name Name of Generic Netlink family
369  *
370  * Searches a previously allocated controller cache and looks for an entry
371  * that matches the specified family \c name. If a match is found successfully,
372  * the reference count of the matching object is increased by one before the
373  * objet is returned.
374  *
375  * @see genl_ctrl_alloc_cache()
376  * @see genl_ctrl_search()
377  * @see genl_family_put()
378  *
379  * @return Generic Netlink family object or NULL if no match was found.
380  */
381 struct genl_family *genl_ctrl_search_by_name(struct nl_cache *cache,
382  const char *name)
383 {
384  struct genl_family *fam;
385 
386  if (cache->c_ops != &genl_ctrl_ops)
387  BUG();
388 
389  nl_list_for_each_entry(fam, &cache->c_items, ce_list) {
390  if (!strcmp(name, fam->gf_name)) {
391  nl_object_get((struct nl_object *) fam);
392  return fam;
393  }
394  }
395 
396  return NULL;
397 }
398 
399 /** @} */
400 
401 /**
402  * @name Direct Resolvers
403  *
404  * These functions communicate directly with the kernel and do not require
405  * a cache to be kept up to date.
406  *
407  * @{
408  */
409 
410 /**
411  * Resolve Generic Netlink family name to numeric identifier
412  * @arg sk Generic Netlink socket.
413  * @arg name Name of Generic Netlink family
414  *
415  * Resolves the Generic Netlink family name to the corresponding numeric
416  * family identifier. This function queries the kernel directly, use
417  * genl_ctrl_search_by_name() if you need to resolve multiple names.
418  *
419  * @see genl_ctrl_search_by_name()
420  *
421  * @return The numeric family identifier or a negative error code.
422  */
423 int genl_ctrl_resolve(struct nl_sock *sk, const char *name)
424 {
425  struct genl_family *family;
426  int err;
427 
428  family = genl_ctrl_probe_by_name(sk, name);
429  if (family == NULL) {
430  err = -NLE_OBJ_NOTFOUND;
431  goto errout;
432  }
433 
434  err = genl_family_get_id(family);
435  genl_family_put(family);
436 errout:
437  return err;
438 }
439 
440 static int genl_ctrl_grp_by_name(const struct genl_family *family,
441  const char *grp_name)
442 {
443  struct genl_family_grp *grp;
444 
445  nl_list_for_each_entry(grp, &family->gf_mc_grps, list) {
446  if (!strcmp(grp->name, grp_name)) {
447  return grp->id;
448  }
449  }
450 
451  return -NLE_OBJ_NOTFOUND;
452 }
453 
454 /**
455  * Resolve Generic Netlink family group name
456  * @arg sk Generic Netlink socket
457  * @arg family_name Name of Generic Netlink family
458  * @arg grp_name Name of group to resolve
459  *
460  * Looks up the family object and resolves the group name to the numeric
461  * group identifier.
462  *
463  * @return Numeric group identifier or a negative error code.
464  */
465 int genl_ctrl_resolve_grp(struct nl_sock *sk, const char *family_name,
466  const char *grp_name)
467 {
468 
469  struct genl_family *family;
470  int err;
471 
472  family = genl_ctrl_probe_by_name(sk, family_name);
473  if (family == NULL) {
474  err = -NLE_OBJ_NOTFOUND;
475  goto errout;
476  }
477 
478  err = genl_ctrl_grp_by_name(family, grp_name);
479  genl_family_put(family);
480 errout:
481  return err;
482 }
483 
484 /** @} */
485 
486 /** @cond SKIP */
487 static struct genl_cmd genl_cmds[] = {
488  {
489  .c_id = CTRL_CMD_NEWFAMILY,
490  .c_name = "NEWFAMILY" ,
491  .c_maxattr = CTRL_ATTR_MAX,
492  .c_attr_policy = ctrl_policy,
493  .c_msg_parser = ctrl_msg_parser,
494  },
495  {
496  .c_id = CTRL_CMD_DELFAMILY,
497  .c_name = "DELFAMILY" ,
498  },
499  {
500  .c_id = CTRL_CMD_GETFAMILY,
501  .c_name = "GETFAMILY" ,
502  },
503  {
504  .c_id = CTRL_CMD_NEWOPS,
505  .c_name = "NEWOPS" ,
506  },
507  {
508  .c_id = CTRL_CMD_DELOPS,
509  .c_name = "DELOPS" ,
510  },
511 };
512 
513 static struct genl_ops genl_ops = {
514  .o_cmds = genl_cmds,
515  .o_ncmds = ARRAY_SIZE(genl_cmds),
516 };
517 
518 extern struct nl_object_ops genl_family_ops;
519 
520 static struct nl_cache_ops genl_ctrl_ops = {
521  .co_name = "genl/family",
522  .co_hdrsize = GENL_HDRSIZE(0),
523  .co_msgtypes = GENL_FAMILY(GENL_ID_CTRL, "nlctrl"),
524  .co_genl = &genl_ops,
525  .co_protocol = NETLINK_GENERIC,
526  .co_request_update = ctrl_request_update,
527  .co_obj_ops = &genl_family_ops,
528 };
529 
530 static void __init ctrl_init(void)
531 {
532  genl_register(&genl_ctrl_ops);
533 }
534 
535 static void __exit ctrl_exit(void)
536 {
537  genl_unregister(&genl_ctrl_ops);
538 }
539 /** @endcond */
540 
541 /** @} */
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:699
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition: attr.c:649
int nla_put_string(struct nl_msg *msg, int attrtype, const char *str)
Add string attribute to netlink message.
Definition: attr.c:779
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
Definition: attr.c:1013
#define nla_for_each_nested(pos, nla, rem)
Iterate over a stream of nested attributes.
Definition: attr.h:324
char * nla_get_string(const struct nlattr *nla)
Return payload of string attribute.
Definition: attr.c:790
@ NLA_STRING
NUL terminated character string.
Definition: attr.h:39
@ NLA_U16
16 bit integer
Definition: attr.h:36
@ NLA_NESTED
Nested attributes.
Definition: attr.h:42
@ NLA_U32
32 bit integer
Definition: attr.h:37
int nl_cache_alloc_and_fill(struct nl_cache_ops *ops, struct nl_sock *sock, struct nl_cache **result)
Allocate new cache and fill it.
Definition: cache.c:228
int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, void *arg)
Set up a callback.
Definition: handlers.c:287
struct nl_cb * nl_cb_clone(struct nl_cb *orig)
Clone an existing callback handle.
Definition: handlers.c:224
@ NL_STOP
Stop parsing altogether and discard remaining messages.
Definition: handlers.h:62
@ NL_SKIP
Skip this message.
Definition: handlers.h:60
@ NL_CB_VALID
Message is valid.
Definition: handlers.h:89
@ NL_CB_CUSTOM
Customized handler specified by the user.
Definition: handlers.h:77
struct genl_family * genl_ctrl_search(struct nl_cache *cache, int id)
Search controller cache for a numeric address match.
Definition: ctrl.c:348
int genl_ctrl_resolve(struct nl_sock *sk, const char *name)
Resolve Generic Netlink family name to numeric identifier.
Definition: ctrl.c:423
int genl_ctrl_alloc_cache(struct nl_sock *sk, struct nl_cache **result)
Allocate a new controller cache.
Definition: ctrl.c:327
struct genl_family * genl_ctrl_search_by_name(struct nl_cache *cache, const char *name)
Search controller cache for a family name match.
Definition: ctrl.c:381
int genl_ctrl_resolve_grp(struct nl_sock *sk, const char *family_name, const char *grp_name)
Resolve Generic Netlink family group name.
Definition: ctrl.c:465
void genl_family_set_name(struct genl_family *family, const char *name)
Set human readable name.
Definition: family.c:257
void genl_family_set_version(struct genl_family *family, uint8_t version)
Set interface version.
Definition: family.c:287
void genl_family_put(struct genl_family *family)
Release reference on Generic Netlink family object.
Definition: family.c:194
unsigned int genl_family_get_id(struct genl_family *family)
Return numeric identifier.
Definition: family.c:212
void genl_family_set_id(struct genl_family *family, unsigned int id)
Set the numeric identifier.
Definition: family.c:225
struct genl_family * genl_family_alloc(void)
Allocate new Generic Netlink family object.
Definition: family.c:180
int genl_register(struct nl_cache_ops *ops)
Register Generic Netlink family backed cache.
Definition: mngt.c:241
void genl_unregister(struct nl_cache_ops *ops)
Unregister cache based Generic Netlink family.
Definition: mngt.c:278
int genl_send_simple(struct nl_sock *sk, int family, int cmd, int version, int flags)
Send a Generic Netlink message consisting only of a header.
Definition: genl.c:79
int genlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, const struct nla_policy *policy)
Parse Generic Netlink message including attributes.
Definition: genl.c:186
void * genlmsg_put(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, int hdrlen, int flags, uint8_t cmd, uint8_t version)
Add Generic Netlink headers to Netlink message.
Definition: genl.c:343
#define NL_AUTO_PORT
Will cause the netlink port to be set to the port assigned to the netlink icoket ust before sending t...
Definition: msg.h:29
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
Definition: msg.c:558
struct nl_msg * nlmsg_alloc(void)
Allocate a new netlink message with the default maximum payload size.
Definition: msg.c:294
struct nlmsghdr * nlmsg_hdr(struct nl_msg *n)
Return actual netlink message.
Definition: msg.c:536
#define NL_AUTO_SEQ
May be used to refer to a sequence number which should be automatically set just before sending the m...
Definition: msg.h:40
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
Definition: object.c:203
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
Definition: nl.c:1241
int nl_recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
Receive a set of messages from a netlink socket.
Definition: nl.c:1071
Definition of a Generic Netlink command.
Definition: mngt.h:82
int c_id
Numeric command identifier (required)
Definition: mngt.h:84
Informative structure passed on to message parser callbacks.
Definition: mngt.h:32
struct nlmsghdr * nlh
Pointer to Netlink message header.
Definition: mngt.h:37
struct nlattr ** attrs
Pointer to array of parsed attributes.
Definition: mngt.h:46
Definition of a Generic Netlink family.
Definition: mngt.h:127
struct genl_cmd * o_cmds
Optional array defining the available Generic Netlink commands.
Definition: mngt.h:144
Attribute validation policy.
Definition: attr.h:63
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:65