21 #include <netlink-private/genl.h>
22 #include <netlink/netlink.h>
23 #include <netlink/genl/genl.h>
24 #include <netlink/genl/mngt.h>
25 #include <netlink/genl/family.h>
26 #include <netlink/genl/ctrl.h>
27 #include <netlink/utils.h>
31 static NL_LIST_HEAD(genl_ops_list);
38 for (i = 0; i < ops->
o_ncmds; i++) {
40 if (cmd->
c_id == cmd_id)
47 static int cmd_msg_parser(
struct sockaddr_nl *who,
struct nlmsghdr *nlh,
48 struct genl_ops *ops,
struct nl_cache_ops *cache_ops,
void *arg)
51 struct genlmsghdr *ghdr;
56 if (!(cmd = lookup_cmd(ops, ghdr->cmd))) {
57 err = -NLE_MSGTYPE_NOSUPPORT;
85 static int genl_msg_parser(
struct nl_cache_ops *ops,
struct sockaddr_nl *who,
86 struct nlmsghdr *nlh,
struct nl_parser_param *pp)
88 if (ops->co_genl == NULL)
91 return cmd_msg_parser(who, nlh, ops->co_genl, ops, pp);
94 static struct genl_ops *lookup_family(
int family)
98 nl_list_for_each_entry(ops, &genl_ops_list,
o_list) {
99 if (ops->
o_id == family)
106 static struct genl_ops *lookup_family_by_name(
const char *name)
110 nl_list_for_each_entry(ops, &genl_ops_list,
o_list) {
111 if (!strcmp(ops->
o_name, name))
118 char *genl_op2name(
int family,
int op,
char *buf,
size_t len)
123 if ((ops = lookup_family(family))) {
124 for (i = 0; i < ops->
o_ncmds; i++) {
128 if (cmd->
c_id == op) {
129 strncpy(buf, cmd->
c_name, len - 1);
135 strncpy(buf,
"unknown", len - 1);
172 if (ops->
o_id && lookup_family(ops->
o_id))
175 if (lookup_family_by_name(ops->
o_name))
178 nl_list_add_tail(&ops->
o_list, &genl_ops_list);
196 nl_list_del(&ops->
o_list);
216 if (!(ops = lookup_family(nlh->nlmsg_type)))
217 return -NLE_MSGTYPE_NOSUPPORT;
219 return cmd_msg_parser(nlmsg_get_src(msg), nlh, ops, NULL, arg);
245 if (ops->co_protocol != NETLINK_GENERIC) {
246 err = -NLE_PROTO_MISMATCH;
250 if (ops->co_hdrsize < GENL_HDRSIZE(0)) {
255 if (ops->co_genl == NULL) {
260 ops->co_genl->o_cache_ops = ops;
261 ops->co_genl->o_hdrsize = ops->co_hdrsize - GENL_HDRLEN;
262 ops->co_genl->o_name = ops->co_msgtypes[0].mt_name;
263 ops->co_genl->o_id = ops->co_msgtypes[0].mt_id;
264 ops->co_msg_parser = genl_msg_parser;
291 static int __genl_ops_resolve(
struct nl_cache *ctrl,
struct genl_ops *ops)
293 struct genl_family *family;
296 if (family != NULL) {
307 return -NLE_OBJ_NOTFOUND;
310 int genl_resolve_id(
struct genl_ops *ops)
316 if (ops->
o_id != GENL_ID_GENERATE)
353 struct nl_cache *ctrl;
359 err = __genl_ops_resolve(ctrl, ops);
381 struct nl_cache *ctrl;
388 nl_list_for_each_entry(ops, &genl_ops_list,
o_list) {
389 err = __genl_ops_resolve(ctrl, ops);