Revert "genetlink: remove genl_bind"

This reverts commit 0845447d9c which is
commit 1e82a62fec613844da9e558f3493540a5b7a7b67 upstream.

It breaks the API and isn't something we should really have to worry
about in android devices.

Cc: Sean Tranchetti <stranche@codeaurora.org>
Change-Id: I4ec83063705a9f0fe449ff46803f6594b69efd08
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Signed-off-by: Will McVicker <willmcvicker@google.com>
This commit is contained in:
Greg Kroah-Hartman 2020-07-22 17:50:56 +02:00 committed by Will McVicker
parent 6b8d7ece3b
commit e80ce97d57
2 changed files with 57 additions and 0 deletions

View file

@ -34,6 +34,12 @@ struct genl_info;
* 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
* @mcast_bind: a socket bound to the given multicast group (which
* is given as the offset into the groups array)
* @mcast_unbind: a socket was unbound from the given multicast group.
* Note that unbind() will not be called symmetrically if the
* generic netlink family is removed while there are still open
* sockets.
* @attrbuf: buffer to store parsed attributes (private)
* @mcgrps: multicast groups used by this family
* @n_mcgrps: number of multicast groups
@ -56,6 +62,8 @@ struct genl_family {
void (*post_doit)(const struct genl_ops *ops,
struct sk_buff *skb,
struct genl_info *info);
int (*mcast_bind)(struct net *net, int group);
void (*mcast_unbind)(struct net *net, int group);
struct nlattr ** attrbuf; /* private */
const struct genl_ops * ops;
const struct genl_multicast_group *mcgrps;

View file

@ -961,11 +961,60 @@ static struct genl_family genl_ctrl __ro_after_init = {
.netnsok = true,
};
static int genl_bind(struct net *net, int group)
{
struct genl_family *f;
int err = 0;
unsigned int id;
down_read(&cb_lock);
idr_for_each_entry(&genl_fam_idr, f, id) {
if (group >= f->mcgrp_offset &&
group < f->mcgrp_offset + f->n_mcgrps) {
int fam_grp = group - f->mcgrp_offset;
if (!f->netnsok && net != &init_net)
err = -ENOENT;
else if (f->mcast_bind)
err = f->mcast_bind(net, fam_grp);
else
err = 0;
break;
}
}
up_read(&cb_lock);
return err;
}
static void genl_unbind(struct net *net, int group)
{
struct genl_family *f;
unsigned int id;
down_read(&cb_lock);
idr_for_each_entry(&genl_fam_idr, f, id) {
if (group >= f->mcgrp_offset &&
group < f->mcgrp_offset + f->n_mcgrps) {
int fam_grp = group - f->mcgrp_offset;
if (f->mcast_unbind)
f->mcast_unbind(net, fam_grp);
break;
}
}
up_read(&cb_lock);
}
static int __net_init genl_pernet_init(struct net *net)
{
struct netlink_kernel_cfg cfg = {
.input = genl_rcv,
.flags = NL_CFG_F_NONROOT_RECV,
.bind = genl_bind,
.unbind = genl_unbind,
};
/* we'll bump the group number right afterwards */