aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-12-23 14:54:40 -0500
committerDavid S. Miller <davem@davemloft.net>2014-12-27 02:20:23 -0500
commitc380d9a7afff0e4c2e5f3c1c2dc7d2f4214dd962 (patch)
treeadc927b4f3fb05268c6ca808aee5d0109351fec1 /net
parent7d68536bed72b09de03b07479dd707c5831b3b94 (diff)
genetlink: pass multicast bind/unbind to families
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>
Diffstat (limited to 'net')
-rw-r--r--net/netlink/genetlink.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 76393f2f4b22..05bf40bbd189 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -983,11 +983,70 @@ static struct genl_multicast_group genl_ctrl_groups[] = {
983 { .name = "notify", }, 983 { .name = "notify", },
984}; 984};
985 985
986static int genl_bind(int group)
987{
988 int i, err;
989 bool found = false;
990
991 down_read(&cb_lock);
992 for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
993 struct genl_family *f;
994
995 list_for_each_entry(f, genl_family_chain(i), family_list) {
996 if (group >= f->mcgrp_offset &&
997 group < f->mcgrp_offset + f->n_mcgrps) {
998 int fam_grp = group - f->mcgrp_offset;
999
1000 if (f->mcast_bind)
1001 err = f->mcast_bind(fam_grp);
1002 else
1003 err = 0;
1004 found = true;
1005 break;
1006 }
1007 }
1008 }
1009 up_read(&cb_lock);
1010
1011 if (WARN_ON(!found))
1012 err = 0;
1013
1014 return err;
1015}
1016
1017static void genl_unbind(int group)
1018{
1019 int i;
1020 bool found = false;
1021
1022 down_read(&cb_lock);
1023 for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
1024 struct genl_family *f;
1025
1026 list_for_each_entry(f, genl_family_chain(i), family_list) {
1027 if (group >= f->mcgrp_offset &&
1028 group < f->mcgrp_offset + f->n_mcgrps) {
1029 int fam_grp = group - f->mcgrp_offset;
1030
1031 if (f->mcast_unbind)
1032 f->mcast_unbind(fam_grp);
1033 found = true;
1034 break;
1035 }
1036 }
1037 }
1038 up_read(&cb_lock);
1039
1040 WARN_ON(!found);
1041}
1042
986static int __net_init genl_pernet_init(struct net *net) 1043static int __net_init genl_pernet_init(struct net *net)
987{ 1044{
988 struct netlink_kernel_cfg cfg = { 1045 struct netlink_kernel_cfg cfg = {
989 .input = genl_rcv, 1046 .input = genl_rcv,
990 .flags = NL_CFG_F_NONROOT_RECV, 1047 .flags = NL_CFG_F_NONROOT_RECV,
1048 .bind = genl_bind,
1049 .unbind = genl_unbind,
991 }; 1050 };
992 1051
993 /* we'll bump the group number right afterwards */ 1052 /* we'll bump the group number right afterwards */