diff options
author | Tom Herbert <tom@herbertland.com> | 2015-12-16 02:41:37 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-12-05 13:20:46 +0300 |
commit | 142afbc6b2f33832f332ce5b561aa817edfff0b4 (patch) | |
tree | e1aafbe5f172b7a44fd38a084083d9bf54910228 /net/netlink | |
parent | b42518053ffd221d79cff2df8c0257db88a71334 (diff) | |
download | linux-142afbc6b2f33832f332ce5b561aa817edfff0b4.tar.xz |
netlink: add a start callback for starting a netlink dump
commit fc9e50f5a5a4e1fa9ba2756f745a13e693cf6a06 upstream.
The start callback allows the caller to set up a context for the
dump callbacks. Presumably, the context can then be destroyed in
the done callback.
Signed-off-by: Tom Herbert <tom@herbertland.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Cc: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/netlink')
-rw-r--r-- | net/netlink/af_netlink.c | 4 | ||||
-rw-r--r-- | net/netlink/genetlink.c | 16 |
2 files changed, 20 insertions, 0 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index d22e8d210fce..1dfd8d17a574 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -2043,6 +2043,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, cb = &nlk->cb; memset(cb, 0, sizeof(*cb)); + cb->start = control->start; cb->dump = control->dump; cb->done = control->done; cb->nlh = nlh; @@ -2056,6 +2057,9 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, mutex_unlock(nlk->cb_mutex); + if (cb->start) + cb->start(cb); + ret = netlink_dump(sk); sock_put(sk); diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 76393f2f4b22..2983147f8ef2 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -507,6 +507,20 @@ void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, } EXPORT_SYMBOL(genlmsg_put); +static int genl_lock_start(struct netlink_callback *cb) +{ + /* our ops are always const - netlink API doesn't propagate that */ + const struct genl_ops *ops = cb->data; + int rc = 0; + + if (ops->start) { + genl_lock(); + rc = ops->start(cb); + genl_unlock(); + } + return rc; +} + static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb) { /* our ops are always const - netlink API doesn't propagate that */ @@ -571,6 +585,7 @@ static int genl_family_rcv_msg(struct genl_family *family, .module = family->module, /* we have const, but the netlink API doesn't */ .data = (void *)ops, + .start = genl_lock_start, .dump = genl_lock_dumpit, .done = genl_lock_done, }; @@ -582,6 +597,7 @@ static int genl_family_rcv_msg(struct genl_family *family, } else { struct netlink_dump_control c = { .module = family->module, + .start = ops->start, .dump = ops->dumpit, .done = ops->done, }; |