genetlink: Add per family bind/unbind callbacks
[linux-2.6-block.git] / net / netlink / genetlink.c
index 8c7af02f845400473becca42527ee0fbd7a29883..50ec599a5cff57a9f138c8b6fbd966e63a64e275 100644 (file)
@@ -1836,6 +1836,9 @@ static int genl_bind(struct net *net, int group)
                    !ns_capable(net->user_ns, CAP_SYS_ADMIN))
                        ret = -EPERM;
 
+               if (family->bind)
+                       family->bind(i);
+
                break;
        }
 
@@ -1843,12 +1846,39 @@ static int genl_bind(struct net *net, int group)
        return ret;
 }
 
+static void genl_unbind(struct net *net, int group)
+{
+       const struct genl_family *family;
+       unsigned int id;
+
+       down_read(&cb_lock);
+
+       idr_for_each_entry(&genl_fam_idr, family, id) {
+               int i;
+
+               if (family->n_mcgrps == 0)
+                       continue;
+
+               i = group - family->mcgrp_offset;
+               if (i < 0 || i >= family->n_mcgrps)
+                       continue;
+
+               if (family->unbind)
+                       family->unbind(i);
+
+               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,
                .release        = genl_release,
        };