Skip to content

Commit

Permalink
genetlink: introduce pre_doit/post_doit hooks
Browse files Browse the repository at this point in the history
Each family may have some amount of boilerplate
locking code that applies to most, or even all,
commands.

This allows a family to handle such things in
a more generic way, by allowing it to
 a) include private flags in each operation
 b) specify a pre_doit hook that is called,
    before an operation's doit() callback and
    may return an error directly,
 c) specify a post_doit hook that can undo
    locking or similar things done by pre_doit,
    and finally
 d) include two private pointers in each info
    struct passed between all these operations
    including doit(). (It's two because I'll
    need two in nl80211 -- can be extended.)

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Oct 5, 2010
1 parent 2ee4e27 commit ff4c92d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
18 changes: 18 additions & 0 deletions include/net/genetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ struct genl_multicast_group {
u32 id;
};

struct genl_ops;
struct genl_info;

/**
* struct genl_family - generic netlink family
* @id: protocol family idenfitier
Expand All @@ -29,6 +32,10 @@ struct genl_multicast_group {
* @maxattr: maximum number of attributes supported
* @netnsok: set to true if the family can handle network
* namespaces and should be presented in all of them
* @pre_doit: called before an operation's doit callback, it may
* do additional, common, filtering and return an error
* @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
Expand All @@ -41,6 +48,12 @@ struct genl_family {
unsigned int version;
unsigned int maxattr;
bool netnsok;
int (*pre_doit)(struct genl_ops *ops,
struct sk_buff *skb,
struct genl_info *info);
void (*post_doit)(struct genl_ops *ops,
struct sk_buff *skb,
struct genl_info *info);
struct nlattr ** attrbuf; /* private */
struct list_head ops_list; /* private */
struct list_head family_list; /* private */
Expand All @@ -55,6 +68,8 @@ struct genl_family {
* @genlhdr: generic netlink message header
* @userhdr: user specific header
* @attrs: netlink attributes
* @_net: network namespace
* @user_ptr: user pointers
*/
struct genl_info {
u32 snd_seq;
Expand All @@ -66,6 +81,7 @@ struct genl_info {
#ifdef CONFIG_NET_NS
struct net * _net;
#endif
void * user_ptr[2];
};

static inline struct net *genl_info_net(struct genl_info *info)
Expand All @@ -81,6 +97,7 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net)
/**
* struct genl_ops - generic netlink operations
* @cmd: command identifier
* @internal_flags: flags used by the family
* @flags: flags
* @policy: attribute validation policy
* @doit: standard command callback
Expand All @@ -90,6 +107,7 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net)
*/
struct genl_ops {
u8 cmd;
u8 internal_flags;
unsigned int flags;
const struct nla_policy *policy;
int (*doit)(struct sk_buff *skb,
Expand Down
14 changes: 13 additions & 1 deletion net/netlink/genetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,8 +547,20 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
info.attrs = family->attrbuf;
genl_info_net_set(&info, net);
memset(&info.user_ptr, 0, sizeof(info.user_ptr));

return ops->doit(skb, &info);
if (family->pre_doit) {
err = family->pre_doit(ops, skb, &info);
if (err)
return err;
}

err = ops->doit(skb, &info);

if (family->post_doit)
family->post_doit(ops, skb, &info);

return err;
}

static void genl_rcv(struct sk_buff *skb)
Expand Down

0 comments on commit ff4c92d

Please sign in to comment.