Skip to content

Commit

Permalink
genetlink: pass multicast bind/unbind to families
Browse files Browse the repository at this point in the history
In order to make the newly fixed multicast bind/unbind
functionality in generic netlink, pass them down to the
appropriate family.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
jmberg-intel authored and davem330 committed Dec 27, 2014
1 parent 7d68536 commit c380d9a
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
5 changes: 5 additions & 0 deletions include/net/genetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ 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
* @attrbuf: buffer to store parsed attributes
* @family_list: family list
* @mcgrps: multicast groups used by this family (private)
Expand All @@ -53,6 +56,8 @@ struct genl_family {
void (*post_doit)(const struct genl_ops *ops,
struct sk_buff *skb,
struct genl_info *info);
int (*mcast_bind)(int group);
void (*mcast_unbind)(int group);
struct nlattr ** attrbuf; /* private */
const struct genl_ops * ops; /* private */
const struct genl_multicast_group *mcgrps; /* private */
Expand Down
59 changes: 59 additions & 0 deletions net/netlink/genetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -983,11 +983,70 @@ static struct genl_multicast_group genl_ctrl_groups[] = {
{ .name = "notify", },
};

static int genl_bind(int group)
{
int i, err;
bool found = false;

down_read(&cb_lock);
for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
struct genl_family *f;

list_for_each_entry(f, genl_family_chain(i), family_list) {
if (group >= f->mcgrp_offset &&
group < f->mcgrp_offset + f->n_mcgrps) {
int fam_grp = group - f->mcgrp_offset;

if (f->mcast_bind)
err = f->mcast_bind(fam_grp);
else
err = 0;
found = true;
break;
}
}
}
up_read(&cb_lock);

if (WARN_ON(!found))
err = 0;

return err;
}

static void genl_unbind(int group)
{
int i;
bool found = false;

down_read(&cb_lock);
for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
struct genl_family *f;

list_for_each_entry(f, genl_family_chain(i), family_list) {
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(fam_grp);
found = true;
break;
}
}
}
up_read(&cb_lock);

WARN_ON(!found);
}

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 */
Expand Down

0 comments on commit c380d9a

Please sign in to comment.