summaryrefslogtreecommitdiff
path: root/include/net/genetlink.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/genetlink.h')
-rw-r--r--include/net/genetlink.h139
1 files changed, 41 insertions, 98 deletions
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 1b177ed..8e0b6c8 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -10,9 +10,16 @@
/**
* struct genl_multicast_group - generic netlink multicast group
* @name: name of the multicast group, names are per-family
+ * @id: multicast group ID, assigned by the core, to use with
+ * genlmsg_multicast().
+ * @list: list entry for linking
+ * @family: pointer to family, need not be set before registering
*/
struct genl_multicast_group {
+ struct genl_family *family; /* private */
+ struct list_head list; /* private */
char name[GENL_NAMSIZ];
+ u32 id;
};
struct genl_ops;
@@ -32,12 +39,9 @@ struct genl_info;
* @post_doit: called after an operation's doit callback, it may
* undo operations done by pre_doit, for example release locks
* @attrbuf: buffer to store parsed attributes
+ * @ops_list: list of all assigned operations
* @family_list: family list
- * @mcgrps: multicast groups used by this family (private)
- * @n_mcgrps: number of multicast groups (private)
- * @mcgrp_offset: starting number of multicast group IDs in this family
- * @ops: the operations supported by this family (private)
- * @n_ops: number of operations supported by this family (private)
+ * @mcast_groups: multicast groups list
*/
struct genl_family {
unsigned int id;
@@ -47,19 +51,16 @@ struct genl_family {
unsigned int maxattr;
bool netnsok;
bool parallel_ops;
- int (*pre_doit)(const struct genl_ops *ops,
+ int (*pre_doit)(struct genl_ops *ops,
struct sk_buff *skb,
struct genl_info *info);
- void (*post_doit)(const struct genl_ops *ops,
+ void (*post_doit)(struct genl_ops *ops,
struct sk_buff *skb,
struct genl_info *info);
struct nlattr ** attrbuf; /* private */
- const struct genl_ops * ops; /* private */
- const struct genl_multicast_group *mcgrps; /* private */
- unsigned int n_ops; /* private */
- unsigned int n_mcgrps; /* private */
- unsigned int mcgrp_offset; /* private */
+ struct list_head ops_list; /* private */
struct list_head family_list; /* private */
+ struct list_head mcast_groups; /* private */
struct module *module;
};
@@ -109,18 +110,19 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net)
* @ops_list: operations list
*/
struct genl_ops {
+ u8 cmd;
+ u8 internal_flags;
+ unsigned int flags;
const struct nla_policy *policy;
int (*doit)(struct sk_buff *skb,
struct genl_info *info);
int (*dumpit)(struct sk_buff *skb,
struct netlink_callback *cb);
int (*done)(struct netlink_callback *cb);
- u8 cmd;
- u8 internal_flags;
- u8 flags;
+ struct list_head ops_list;
};
-int __genl_register_family(struct genl_family *family);
+extern int __genl_register_family(struct genl_family *family);
static inline int genl_register_family(struct genl_family *family)
{
@@ -128,57 +130,28 @@ static inline int genl_register_family(struct genl_family *family)
return __genl_register_family(family);
}
-/**
- * genl_register_family_with_ops - register a generic netlink family with ops
- * @family: generic netlink family
- * @ops: operations to be registered
- * @n_ops: number of elements to register
- *
- * Registers the specified family and operations from the specified table.
- * Only one family may be registered with the same family name or identifier.
- *
- * The family id may equal GENL_ID_GENERATE causing an unique id to
- * be automatically generated and assigned.
- *
- * Either a doit or dumpit callback must be specified for every registered
- * operation or the function will fail. Only one operation structure per
- * command identifier may be registered.
- *
- * See include/net/genetlink.h for more documenation on the operations
- * structure.
- *
- * Return 0 on success or a negative error code.
- */
-static inline int
-_genl_register_family_with_ops_grps(struct genl_family *family,
- const struct genl_ops *ops, size_t n_ops,
- const struct genl_multicast_group *mcgrps,
- size_t n_mcgrps)
+extern int __genl_register_family_with_ops(struct genl_family *family,
+ struct genl_ops *ops, size_t n_ops);
+
+static inline int genl_register_family_with_ops(struct genl_family *family,
+ struct genl_ops *ops, size_t n_ops)
{
family->module = THIS_MODULE;
- family->ops = ops;
- family->n_ops = n_ops;
- family->mcgrps = mcgrps;
- family->n_mcgrps = n_mcgrps;
- return __genl_register_family(family);
+ return __genl_register_family_with_ops(family, ops, n_ops);
}
-#define genl_register_family_with_ops(family, ops) \
- _genl_register_family_with_ops_grps((family), \
- (ops), ARRAY_SIZE(ops), \
- NULL, 0)
-#define genl_register_family_with_ops_groups(family, ops, grps) \
- _genl_register_family_with_ops_grps((family), \
- (ops), ARRAY_SIZE(ops), \
- (grps), ARRAY_SIZE(grps))
-
-int genl_unregister_family(struct genl_family *family);
-void genl_notify(struct genl_family *family,
- struct sk_buff *skb, struct net *net, u32 portid,
- u32 group, struct nlmsghdr *nlh, gfp_t flags);
+extern int genl_unregister_family(struct genl_family *family);
+extern int genl_register_ops(struct genl_family *, struct genl_ops *ops);
+extern int genl_unregister_ops(struct genl_family *, struct genl_ops *ops);
+extern int genl_register_mc_group(struct genl_family *family,
+ struct genl_multicast_group *grp);
+extern void genl_unregister_mc_group(struct genl_family *family,
+ struct genl_multicast_group *grp);
+extern void genl_notify(struct sk_buff *skb, struct net *net, u32 portid,
+ u32 group, struct nlmsghdr *nlh, gfp_t flags);
void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
- struct genl_family *family, int flags, u8 cmd);
+ struct genl_family *family, int flags, u8 cmd);
/**
* genlmsg_nlhdr - Obtain netlink header from user specified header
@@ -254,51 +227,41 @@ static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
/**
* genlmsg_multicast_netns - multicast a netlink message to a specific netns
- * @family: the generic netlink family
* @net: the net namespace
* @skb: netlink message as socket buffer
* @portid: own netlink portid to avoid sending to yourself
- * @group: offset of multicast group in groups array
+ * @group: multicast group id
* @flags: allocation flags
*/
-static inline int genlmsg_multicast_netns(struct genl_family *family,
- struct net *net, struct sk_buff *skb,
+static inline int genlmsg_multicast_netns(struct net *net, struct sk_buff *skb,
u32 portid, unsigned int group, gfp_t flags)
{
- if (WARN_ON_ONCE(group >= family->n_mcgrps))
- return -EINVAL;
- group = family->mcgrp_offset + group;
return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
}
/**
* genlmsg_multicast - multicast a netlink message to the default netns
- * @family: the generic netlink family
* @skb: netlink message as socket buffer
* @portid: own netlink portid to avoid sending to yourself
- * @group: offset of multicast group in groups array
+ * @group: multicast group id
* @flags: allocation flags
*/
-static inline int genlmsg_multicast(struct genl_family *family,
- struct sk_buff *skb, u32 portid,
+static inline int genlmsg_multicast(struct sk_buff *skb, u32 portid,
unsigned int group, gfp_t flags)
{
- return genlmsg_multicast_netns(family, &init_net, skb,
- portid, group, flags);
+ return genlmsg_multicast_netns(&init_net, skb, portid, group, flags);
}
/**
* genlmsg_multicast_allns - multicast a netlink message to all net namespaces
- * @family: the generic netlink family
* @skb: netlink message as socket buffer
* @portid: own netlink portid to avoid sending to yourself
- * @group: offset of multicast group in groups array
+ * @group: multicast group id
* @flags: allocation flags
*
* This function must hold the RTNL or rcu_read_lock().
*/
-int genlmsg_multicast_allns(struct genl_family *family,
- struct sk_buff *skb, u32 portid,
+int genlmsg_multicast_allns(struct sk_buff *skb, u32 portid,
unsigned int group, gfp_t flags);
/**
@@ -369,25 +332,5 @@ static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
return nlmsg_new(genlmsg_total_size(payload), flags);
}
-/**
- * genl_set_err - report error to genetlink broadcast listeners
- * @family: the generic netlink family
- * @net: the network namespace to report the error to
- * @portid: the PORTID of a process that we want to skip (if any)
- * @group: the broadcast group that will notice the error
- * (this is the offset of the multicast group in the groups array)
- * @code: error code, must be negative (as usual in kernelspace)
- *
- * This function returns the number of broadcast listeners that have set the
- * NETLINK_RECV_NO_ENOBUFS socket option.
- */
-static inline int genl_set_err(struct genl_family *family, struct net *net,
- u32 portid, u32 group, int code)
-{
- if (WARN_ON_ONCE(group >= family->n_mcgrps))
- return -EINVAL;
- group = family->mcgrp_offset + group;
- return netlink_set_err(net->genl_sock, portid, group, code);
-}
#endif /* __NET_GENERIC_NETLINK_H */