diff options
Diffstat (limited to 'include/net/genetlink.h')
-rw-r--r-- | include/net/genetlink.h | 139 |
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 */ |