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);
93 static int genl_msg_parser(
struct nl_cache_ops *ops,
struct sockaddr_nl *who,
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 = -NLE_MSGTYPE_NOSUPPORT;
115 if (cmd->c_msg_parser == NULL)
116 err = -NLE_OPNOTSUPP;
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);
177 err = -NLE_PROTO_MISMATCH;
186 if (ops->co_genl == NULL) {
191 ops->co_genl->o_cache_ops = ops;
192 ops->co_genl->o_name = ops->co_msgtypes[0].
mt_name;
193 ops->co_genl->o_family = ops->co_msgtypes[0].
mt_id;
198 nl_list_add_tail(&ops->co_genl->o_list, &genl_ops_list);
212 nl_list_del(&ops->co_genl->o_list);
222 static int __genl_ops_resolve(
struct nl_cache *ctrl,
struct genl_ops *ops)
224 struct genl_family *family;
227 if (family != NULL) {
228 ops->o_id = genl_family_get_id(family);
229 genl_family_put(family);
234 return -NLE_OBJ_NOTFOUND;
237 int genl_ops_resolve(
struct nl_sock *sk,
struct genl_ops *ops)
239 struct nl_cache *ctrl;
242 if ((err = genl_ctrl_alloc_cache(sk, &ctrl)) < 0)
245 err = __genl_ops_resolve(ctrl, ops);
252 int genl_mngt_resolve(
struct nl_sock *sk)
254 struct nl_cache *ctrl;
258 if ((err = genl_ctrl_alloc_cache(sk, &ctrl)) < 0)
261 nl_list_for_each_entry(ops, &genl_ops_list, o_list) {
262 err = __genl_ops_resolve(ctrl, ops);