83 #include <netlink-generic.h>
84 #include <netlink/netlink.h>
85 #include <netlink/genl/genl.h>
86 #include <netlink/genl/mngt.h>
87 #include <netlink/genl/family.h>
88 #include <netlink/genl/ctrl.h>
89 #include <netlink/utils.h>
91 static NL_LIST_HEAD(genl_ops_list);
97 struct genlmsghdr *ghdr;
102 if (ops->co_genl == NULL)
105 for (i = 0; i < ops->co_genl->o_ncmds; i++) {
106 cmd = &ops->co_genl->o_cmds[i];
107 if (cmd->
c_id == ghdr->cmd)
111 err = nl_errno(ENOENT);
115 if (cmd->c_msg_parser == NULL)
116 err = nl_error(EOPNOTSUPP,
"No message parser found.");
119 struct genl_info info = {
132 err = cmd->c_msg_parser(ops, cmd, &info, pp);
139 char *genl_op2name(
int family,
int op,
char *buf,
size_t len)
144 nl_list_for_each_entry(ops, &genl_ops_list, o_list) {
145 if (ops->o_family == family) {
146 for (i = 0; i < ops->o_ncmds; i++) {
148 cmd = &ops->o_cmds[i];
150 if (cmd->
c_id == op) {
151 strncpy(buf, cmd->
c_name, len - 1);
158 strncpy(buf,
"unknown", len - 1);
176 if (ops->co_protocol != NETLINK_GENERIC) {
177 err = nl_error(EINVAL,
"cache operations not for protocol " \
178 "NETLINK_GENERIC (protocol=%s)",
183 if (ops->co_hdrsize < GENL_HDRSIZE(0)) {
184 err = nl_error(EINVAL,
"co_hdrsize too short, probably " \
185 "not including genlmsghdr, minsize=%d",
190 if (ops->co_genl == NULL) {
191 err = nl_error(EINVAL,
"co_genl is NULL, must provide " \
192 "valid genl operations");
196 ops->co_genl->o_cache_ops = ops;
197 ops->co_genl->o_name = ops->co_msgtypes[0].
mt_name;
198 ops->co_genl->o_family = ops->co_msgtypes[0].
mt_id;
203 nl_list_add_tail(&ops->co_genl->o_list, &genl_ops_list);
217 nl_list_del(&ops->co_genl->o_list);
227 static int __genl_ops_resolve(
struct nl_cache *ctrl,
struct genl_ops *ops)
229 struct genl_family *family;
232 if (family != NULL) {
233 ops->o_id = genl_family_get_id(family);
234 genl_family_put(family);
239 return nl_error(ENOENT,
"Unable to find generic netlink family \"%s\"",
243 int genl_ops_resolve(
struct nl_handle *handle,
struct genl_ops *ops)
245 struct nl_cache *ctrl;
248 ctrl = genl_ctrl_alloc_cache(handle);
250 err = nl_get_errno();
254 err = __genl_ops_resolve(ctrl, ops);
261 int genl_mngt_resolve(
struct nl_handle *handle)
263 struct nl_cache *ctrl;
267 ctrl = genl_ctrl_alloc_cache(handle);
269 err = nl_get_errno();
273 nl_list_for_each_entry(ops, &genl_ops_list, o_list) {
274 err = __genl_ops_resolve(ctrl, ops);
struct nla_policy * c_attr_policy
Attribute validation policy (optional)
char * mt_name
Name of operation for human-readable printing.
void * nlmsg_data(const struct nlmsghdr *nlh)
head of message payload
int genl_register(struct nl_cache_ops *ops)
Register generic netlink operations.
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
char * c_name
Name/description of command.
int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, struct nla_policy *policy)
parse attributes of a netlink message
void nl_cache_free(struct nl_cache *cache)
Free a cache.
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
struct genl_family * genl_ctrl_search_by_name(struct nl_cache *cache, const char *name)
Look up generic netlink family by family name in the provided cache.
int c_id
Unique command identifier.
void genl_unregister(struct nl_cache_ops *ops)
Unregister generic netlink operations.
Generic Netlink Operations.
void * genlmsg_data(const struct genlmsghdr *gnlh)
Get head of message payload.
int mt_id
Netlink message type.
int c_maxattr
Maximum attribute identifier, must be provided if a message parser is available.
int(* co_msg_parser)(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *)
Called whenever a message was received that needs to be parsed.