aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-11-19 16:39:42 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-19 16:39:42 -0500
commit091e0662ee2c37867ad918ce7b6ddd17f0e090e2 (patch)
treee5a066d8f83d8822d448421019a4503f361295f9
parentdbde497966804e63a38fdedc1e3815e77097efc2 (diff)
parent2a94fe48f32ccf7321450a2cc07f2b724a444e5b (diff)
Merge branch 'genetlink_mcast'
Johannes Berg says: ==================== genetlink: clean up multicast group APIs The generic netlink multicast group registration doesn't have to be dynamic, and can thus be simplified just like I did with the ops. This removes some complexity in registration code. Additionally, two users of generic netlink already use multicast groups in a wrong way, add workarounds for those two to keep the userspace API working, but at the same time make them not clash with other users of multicast groups as might happen now. While making it all a bit easier, also prevent such abuse by adding checks to the APIs so each family can only use the groups it owns. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/acpi/event.c25
-rw-r--r--drivers/net/team/team.c27
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c3
-rw-r--r--drivers/scsi/pmcraid.c3
-rw-r--r--drivers/thermal/thermal_core.c25
-rw-r--r--fs/dlm/netlink.c10
-rw-r--r--fs/quota/netlink.c16
-rw-r--r--include/linux/genl_magic_func.h53
-rw-r--r--include/net/genetlink.h84
-rw-r--r--include/uapi/linux/genetlink.h1
-rw-r--r--kernel/taskstats.c3
-rw-r--r--net/core/drop_monitor.c13
-rw-r--r--net/hsr/hsr_netlink.c20
-rw-r--r--net/ieee802154/ieee802154.h6
-rw-r--r--net/ieee802154/netlink.c29
-rw-r--r--net/ieee802154/nl-mac.c22
-rw-r--r--net/ipv4/tcp_metrics.c3
-rw-r--r--net/irda/irnetlink.c3
-rw-r--r--net/l2tp/l2tp_netlink.c7
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c2
-rw-r--r--net/netlabel/netlabel_cipso_v4.c2
-rw-r--r--net/netlabel/netlabel_mgmt.c2
-rw-r--r--net/netlabel/netlabel_unlabeled.c2
-rw-r--r--net/netlink/genetlink.c340
-rw-r--r--net/nfc/netlink.c39
-rw-r--r--net/openvswitch/datapath.c49
-rw-r--r--net/openvswitch/datapath.h1
-rw-r--r--net/openvswitch/dp_notify.c11
-rw-r--r--net/tipc/netlink.c11
-rw-r--r--net/wimax/op-msg.c2
-rw-r--r--net/wimax/stack.c20
-rw-r--r--net/wimax/wimax-internal.h1
-rw-r--r--net/wireless/nl80211.c196
33 files changed, 518 insertions, 513 deletions
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index 8247fcdde079..aeb5aa6ce068 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -78,15 +78,17 @@ enum {
78#define ACPI_GENL_VERSION 0x01 78#define ACPI_GENL_VERSION 0x01
79#define ACPI_GENL_MCAST_GROUP_NAME "acpi_mc_group" 79#define ACPI_GENL_MCAST_GROUP_NAME "acpi_mc_group"
80 80
81static const struct genl_multicast_group acpi_event_mcgrps[] = {
82 { .name = ACPI_GENL_MCAST_GROUP_NAME, },
83};
84
81static struct genl_family acpi_event_genl_family = { 85static struct genl_family acpi_event_genl_family = {
82 .id = GENL_ID_GENERATE, 86 .id = GENL_ID_GENERATE,
83 .name = ACPI_GENL_FAMILY_NAME, 87 .name = ACPI_GENL_FAMILY_NAME,
84 .version = ACPI_GENL_VERSION, 88 .version = ACPI_GENL_VERSION,
85 .maxattr = ACPI_GENL_ATTR_MAX, 89 .maxattr = ACPI_GENL_ATTR_MAX,
86}; 90 .mcgrps = acpi_event_mcgrps,
87 91 .n_mcgrps = ARRAY_SIZE(acpi_event_mcgrps),
88static struct genl_multicast_group acpi_event_mcgrp = {
89 .name = ACPI_GENL_MCAST_GROUP_NAME,
90}; 92};
91 93
92int acpi_bus_generate_netlink_event(const char *device_class, 94int acpi_bus_generate_netlink_event(const char *device_class,
@@ -146,7 +148,7 @@ int acpi_bus_generate_netlink_event(const char *device_class,
146 return result; 148 return result;
147 } 149 }
148 150
149 genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC); 151 genlmsg_multicast(&acpi_event_genl_family, skb, 0, 0, GFP_ATOMIC);
150 return 0; 152 return 0;
151} 153}
152 154
@@ -154,18 +156,7 @@ EXPORT_SYMBOL(acpi_bus_generate_netlink_event);
154 156
155static int acpi_event_genetlink_init(void) 157static int acpi_event_genetlink_init(void)
156{ 158{
157 int result; 159 return genl_register_family(&acpi_event_genl_family);
158
159 result = genl_register_family(&acpi_event_genl_family);
160 if (result)
161 return result;
162
163 result = genl_register_mc_group(&acpi_event_genl_family,
164 &acpi_event_mcgrp);
165 if (result)
166 genl_unregister_family(&acpi_event_genl_family);
167
168 return result;
169} 160}
170 161
171#else 162#else
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 6390254beb7d..0715de50b3dc 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2670,15 +2670,15 @@ static const struct genl_ops team_nl_ops[] = {
2670 }, 2670 },
2671}; 2671};
2672 2672
2673static struct genl_multicast_group team_change_event_mcgrp = { 2673static const struct genl_multicast_group team_nl_mcgrps[] = {
2674 .name = TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME, 2674 { .name = TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME, },
2675}; 2675};
2676 2676
2677static int team_nl_send_multicast(struct sk_buff *skb, 2677static int team_nl_send_multicast(struct sk_buff *skb,
2678 struct team *team, u32 portid) 2678 struct team *team, u32 portid)
2679{ 2679{
2680 return genlmsg_multicast_netns(dev_net(team->dev), skb, 0, 2680 return genlmsg_multicast_netns(&team_nl_family, dev_net(team->dev),
2681 team_change_event_mcgrp.id, GFP_KERNEL); 2681 skb, 0, 0, GFP_KERNEL);
2682} 2682}
2683 2683
2684static int team_nl_send_event_options_get(struct team *team, 2684static int team_nl_send_event_options_get(struct team *team,
@@ -2697,23 +2697,8 @@ static int team_nl_send_event_port_get(struct team *team,
2697 2697
2698static int team_nl_init(void) 2698static int team_nl_init(void)
2699{ 2699{
2700 int err; 2700 return genl_register_family_with_ops_groups(&team_nl_family, team_nl_ops,
2701 2701 team_nl_mcgrps);
2702 err = genl_register_family_with_ops(&team_nl_family, team_nl_ops,
2703 ARRAY_SIZE(team_nl_ops));
2704 if (err)
2705 return err;
2706
2707 err = genl_register_mc_group(&team_nl_family, &team_change_event_mcgrp);
2708 if (err)
2709 goto err_change_event_grp_reg;
2710
2711 return 0;
2712
2713err_change_event_grp_reg:
2714 genl_unregister_family(&team_nl_family);
2715
2716 return err;
2717} 2702}
2718 2703
2719static void team_nl_fini(void) 2704static void team_nl_fini(void)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index cfc3fda79a2d..9df7bc91a26f 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2148,8 +2148,7 @@ static int hwsim_init_netlink(void)
2148 2148
2149 printk(KERN_INFO "mac80211_hwsim: initializing netlink\n"); 2149 printk(KERN_INFO "mac80211_hwsim: initializing netlink\n");
2150 2150
2151 rc = genl_register_family_with_ops(&hwsim_genl_family, 2151 rc = genl_register_family_with_ops(&hwsim_genl_family, hwsim_ops);
2152 hwsim_ops, ARRAY_SIZE(hwsim_ops));
2153 if (rc) 2152 if (rc)
2154 goto failure; 2153 goto failure;
2155 2154
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 1eb7b0280a45..2775441111ff 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -1512,7 +1512,8 @@ static int pmcraid_notify_aen(
1512 } 1512 }
1513 1513
1514 result = 1514 result =
1515 genlmsg_multicast(skb, 0, pmcraid_event_family.id, GFP_ATOMIC); 1515 genlmsg_multicast(&pmcraid_event_family, skb, 0,
1516 pmcraid_event_family.id, GFP_ATOMIC);
1516 1517
1517 /* If there are no listeners, genlmsg_multicast may return non-zero 1518 /* If there are no listeners, genlmsg_multicast may return non-zero
1518 * value. 1519 * value.
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 4962a6aaf295..19edd6124ca3 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -1606,15 +1606,17 @@ exit:
1606EXPORT_SYMBOL_GPL(thermal_zone_get_zone_by_name); 1606EXPORT_SYMBOL_GPL(thermal_zone_get_zone_by_name);
1607 1607
1608#ifdef CONFIG_NET 1608#ifdef CONFIG_NET
1609static const struct genl_multicast_group thermal_event_mcgrps[] = {
1610 { .name = THERMAL_GENL_MCAST_GROUP_NAME, },
1611};
1612
1609static struct genl_family thermal_event_genl_family = { 1613static struct genl_family thermal_event_genl_family = {
1610 .id = GENL_ID_GENERATE, 1614 .id = GENL_ID_GENERATE,
1611 .name = THERMAL_GENL_FAMILY_NAME, 1615 .name = THERMAL_GENL_FAMILY_NAME,
1612 .version = THERMAL_GENL_VERSION, 1616 .version = THERMAL_GENL_VERSION,
1613 .maxattr = THERMAL_GENL_ATTR_MAX, 1617 .maxattr = THERMAL_GENL_ATTR_MAX,
1614}; 1618 .mcgrps = thermal_event_mcgrps,
1615 1619 .n_mcgrps = ARRAY_SIZE(thermal_event_mcgrps),
1616static struct genl_multicast_group thermal_event_mcgrp = {
1617 .name = THERMAL_GENL_MCAST_GROUP_NAME,
1618}; 1620};
1619 1621
1620int thermal_generate_netlink_event(struct thermal_zone_device *tz, 1622int thermal_generate_netlink_event(struct thermal_zone_device *tz,
@@ -1675,7 +1677,8 @@ int thermal_generate_netlink_event(struct thermal_zone_device *tz,
1675 return result; 1677 return result;
1676 } 1678 }
1677 1679
1678 result = genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC); 1680 result = genlmsg_multicast(&thermal_event_genl_family, skb, 0,
1681 0, GFP_ATOMIC);
1679 if (result) 1682 if (result)
1680 dev_err(&tz->device, "Failed to send netlink event:%d", result); 1683 dev_err(&tz->device, "Failed to send netlink event:%d", result);
1681 1684
@@ -1685,17 +1688,7 @@ EXPORT_SYMBOL_GPL(thermal_generate_netlink_event);
1685 1688
1686static int genetlink_init(void) 1689static int genetlink_init(void)
1687{ 1690{
1688 int result; 1691 return genl_register_family(&thermal_event_genl_family);
1689
1690 result = genl_register_family(&thermal_event_genl_family);
1691 if (result)
1692 return result;
1693
1694 result = genl_register_mc_group(&thermal_event_genl_family,
1695 &thermal_event_mcgrp);
1696 if (result)
1697 genl_unregister_family(&thermal_event_genl_family);
1698 return result;
1699} 1692}
1700 1693
1701static void genetlink_exit(void) 1694static void genetlink_exit(void)
diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c
index 60a327863b11..e7cfbaf8d0e2 100644
--- a/fs/dlm/netlink.c
+++ b/fs/dlm/netlink.c
@@ -74,14 +74,16 @@ static int user_cmd(struct sk_buff *skb, struct genl_info *info)
74 return 0; 74 return 0;
75} 75}
76 76
77static struct genl_ops dlm_nl_ops = { 77static struct genl_ops dlm_nl_ops[] = {
78 .cmd = DLM_CMD_HELLO, 78 {
79 .doit = user_cmd, 79 .cmd = DLM_CMD_HELLO,
80 .doit = user_cmd,
81 },
80}; 82};
81 83
82int __init dlm_netlink_init(void) 84int __init dlm_netlink_init(void)
83{ 85{
84 return genl_register_family_with_ops(&family, &dlm_nl_ops, 1); 86 return genl_register_family_with_ops(&family, dlm_nl_ops);
85} 87}
86 88
87void dlm_netlink_exit(void) 89void dlm_netlink_exit(void)
diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c
index 16e8abb7709b..72d29177998e 100644
--- a/fs/quota/netlink.c
+++ b/fs/quota/netlink.c
@@ -9,13 +9,25 @@
9#include <net/netlink.h> 9#include <net/netlink.h>
10#include <net/genetlink.h> 10#include <net/genetlink.h>
11 11
12static const struct genl_multicast_group quota_mcgrps[] = {
13 { .name = "events", },
14};
15
12/* Netlink family structure for quota */ 16/* Netlink family structure for quota */
13static struct genl_family quota_genl_family = { 17static struct genl_family quota_genl_family = {
14 .id = GENL_ID_GENERATE, 18 /*
19 * Needed due to multicast group ID abuse - old code assumed
20 * the family ID was also a valid multicast group ID (which
21 * isn't true) and userspace might thus rely on it. Assign a
22 * static ID for this group to make dealing with that easier.
23 */
24 .id = GENL_ID_VFS_DQUOT,
15 .hdrsize = 0, 25 .hdrsize = 0,
16 .name = "VFS_DQUOT", 26 .name = "VFS_DQUOT",
17 .version = 1, 27 .version = 1,
18 .maxattr = QUOTA_NL_A_MAX, 28 .maxattr = QUOTA_NL_A_MAX,
29 .mcgrps = quota_mcgrps,
30 .n_mcgrps = ARRAY_SIZE(quota_mcgrps),
19}; 31};
20 32
21/** 33/**
@@ -78,7 +90,7 @@ void quota_send_warning(struct kqid qid, dev_t dev,
78 goto attr_err_out; 90 goto attr_err_out;
79 genlmsg_end(skb, msg_head); 91 genlmsg_end(skb, msg_head);
80 92
81 genlmsg_multicast(skb, 0, quota_genl_family.id, GFP_NOFS); 93 genlmsg_multicast(&quota_genl_family, skb, 0, 0, GFP_NOFS);
82 return; 94 return;
83attr_err_out: 95attr_err_out:
84 printk(KERN_ERR "VFS: Not enough space to compose quota message!\n"); 96 printk(KERN_ERR "VFS: Not enough space to compose quota message!\n");
diff --git a/include/linux/genl_magic_func.h b/include/linux/genl_magic_func.h
index 023bc346b877..c0894dd8827b 100644
--- a/include/linux/genl_magic_func.h
+++ b/include/linux/genl_magic_func.h
@@ -273,49 +273,40 @@ static struct genl_family ZZZ_genl_family __read_mostly = {
273 * Magic: define multicast groups 273 * Magic: define multicast groups
274 * Magic: define multicast group registration helper 274 * Magic: define multicast group registration helper
275 */ 275 */
276#define ZZZ_genl_mcgrps CONCAT_(GENL_MAGIC_FAMILY, _genl_mcgrps)
277static const struct genl_multicast_group ZZZ_genl_mcgrps[] = {
278#undef GENL_mc_group
279#define GENL_mc_group(group) { .name = #group, },
280#include GENL_MAGIC_INCLUDE_FILE
281};
282
283enum CONCAT_(GENL_MAGIC_FAMILY, group_ids) {
284#undef GENL_mc_group
285#define GENL_mc_group(group) CONCAT_(GENL_MAGIC_FAMILY, _group_ ## group),
286#include GENL_MAGIC_INCLUDE_FILE
287};
288
276#undef GENL_mc_group 289#undef GENL_mc_group
277#define GENL_mc_group(group) \ 290#define GENL_mc_group(group) \
278static struct genl_multicast_group \
279CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group) __read_mostly = { \
280 .name = #group, \
281}; \
282static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)( \ 291static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)( \
283 struct sk_buff *skb, gfp_t flags) \ 292 struct sk_buff *skb, gfp_t flags) \
284{ \ 293{ \
285 unsigned int group_id = \ 294 unsigned int group_id = \
286 CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group).id; \ 295 CONCAT_(GENL_MAGIC_FAMILY, _group_ ## group); \
287 if (!group_id) \ 296 return genlmsg_multicast(&ZZZ_genl_family, skb, 0, \
288 return -EINVAL; \ 297 group_id, flags); \
289 return genlmsg_multicast(skb, 0, group_id, flags); \
290} 298}
291 299
292#include GENL_MAGIC_INCLUDE_FILE 300#include GENL_MAGIC_INCLUDE_FILE
293 301
294int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void)
295{
296 int err = genl_register_family_with_ops(&ZZZ_genl_family,
297 ZZZ_genl_ops, ARRAY_SIZE(ZZZ_genl_ops));
298 if (err)
299 return err;
300#undef GENL_mc_group
301#define GENL_mc_group(group) \
302 err = genl_register_mc_group(&ZZZ_genl_family, \
303 &CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group)); \
304 if (err) \
305 goto fail; \
306 else \
307 pr_info("%s: mcg %s: %u\n", #group, \
308 __stringify(GENL_MAGIC_FAMILY), \
309 CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group).id);
310
311#include GENL_MAGIC_INCLUDE_FILE
312
313#undef GENL_mc_group 302#undef GENL_mc_group
314#define GENL_mc_group(group) 303#define GENL_mc_group(group)
315 return 0; 304
316fail: 305int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void)
317 genl_unregister_family(&ZZZ_genl_family); 306{
318 return err; 307 return genl_register_family_with_ops_groups(&ZZZ_genl_family, \
308 ZZZ_genl_ops, \
309 ZZZ_genl_mcgrps);
319} 310}
320 311
321void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void) 312void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void)
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index e96385d46b48..ace4abf118d7 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -10,16 +10,9 @@
10/** 10/**
11 * struct genl_multicast_group - generic netlink multicast group 11 * struct genl_multicast_group - generic netlink multicast group
12 * @name: name of the multicast group, names are per-family 12 * @name: name of the multicast group, names are per-family
13 * @id: multicast group ID, assigned by the core, to use with
14 * genlmsg_multicast().
15 * @list: list entry for linking
16 * @family: pointer to family, need not be set before registering
17 */ 13 */
18struct genl_multicast_group { 14struct genl_multicast_group {
19 struct genl_family *family; /* private */
20 struct list_head list; /* private */
21 char name[GENL_NAMSIZ]; 15 char name[GENL_NAMSIZ];
22 u32 id;
23}; 16};
24 17
25struct genl_ops; 18struct genl_ops;
@@ -40,7 +33,9 @@ struct genl_info;
40 * undo operations done by pre_doit, for example release locks 33 * undo operations done by pre_doit, for example release locks
41 * @attrbuf: buffer to store parsed attributes 34 * @attrbuf: buffer to store parsed attributes
42 * @family_list: family list 35 * @family_list: family list
43 * @mcast_groups: multicast groups list 36 * @mcgrps: multicast groups used by this family (private)
37 * @n_mcgrps: number of multicast groups (private)
38 * @mcgrp_offset: starting number of multicast group IDs in this family
44 * @ops: the operations supported by this family (private) 39 * @ops: the operations supported by this family (private)
45 * @n_ops: number of operations supported by this family (private) 40 * @n_ops: number of operations supported by this family (private)
46 */ 41 */
@@ -60,9 +55,11 @@ struct genl_family {
60 struct genl_info *info); 55 struct genl_info *info);
61 struct nlattr ** attrbuf; /* private */ 56 struct nlattr ** attrbuf; /* private */
62 const struct genl_ops * ops; /* private */ 57 const struct genl_ops * ops; /* private */
58 const struct genl_multicast_group *mcgrps; /* private */
63 unsigned int n_ops; /* private */ 59 unsigned int n_ops; /* private */
60 unsigned int n_mcgrps; /* private */
61 unsigned int mcgrp_offset; /* private */
64 struct list_head family_list; /* private */ 62 struct list_head family_list; /* private */
65 struct list_head mcast_groups; /* private */
66 struct module *module; 63 struct module *module;
67}; 64};
68 65
@@ -152,21 +149,32 @@ static inline int genl_register_family(struct genl_family *family)
152 * 149 *
153 * Return 0 on success or a negative error code. 150 * Return 0 on success or a negative error code.
154 */ 151 */
155static inline int genl_register_family_with_ops(struct genl_family *family, 152static inline int
156 const struct genl_ops *ops, size_t n_ops) 153_genl_register_family_with_ops_grps(struct genl_family *family,
154 const struct genl_ops *ops, size_t n_ops,
155 const struct genl_multicast_group *mcgrps,
156 size_t n_mcgrps)
157{ 157{
158 family->module = THIS_MODULE; 158 family->module = THIS_MODULE;
159 family->ops = ops; 159 family->ops = ops;
160 family->n_ops = n_ops; 160 family->n_ops = n_ops;
161 family->mcgrps = mcgrps;
162 family->n_mcgrps = n_mcgrps;
161 return __genl_register_family(family); 163 return __genl_register_family(family);
162} 164}
163 165
166#define genl_register_family_with_ops(family, ops) \
167 _genl_register_family_with_ops_grps((family), \
168 (ops), ARRAY_SIZE(ops), \
169 NULL, 0)
170#define genl_register_family_with_ops_groups(family, ops, grps) \
171 _genl_register_family_with_ops_grps((family), \
172 (ops), ARRAY_SIZE(ops), \
173 (grps), ARRAY_SIZE(grps))
174
164int genl_unregister_family(struct genl_family *family); 175int genl_unregister_family(struct genl_family *family);
165int genl_register_mc_group(struct genl_family *family, 176void genl_notify(struct genl_family *family,
166 struct genl_multicast_group *grp); 177 struct sk_buff *skb, struct net *net, u32 portid,
167void genl_unregister_mc_group(struct genl_family *family,
168 struct genl_multicast_group *grp);
169void genl_notify(struct sk_buff *skb, struct net *net, u32 portid,
170 u32 group, struct nlmsghdr *nlh, gfp_t flags); 178 u32 group, struct nlmsghdr *nlh, gfp_t flags);
171 179
172void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, 180void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
@@ -246,41 +254,54 @@ static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
246 254
247/** 255/**
248 * genlmsg_multicast_netns - multicast a netlink message to a specific netns 256 * genlmsg_multicast_netns - multicast a netlink message to a specific netns
257 * @family: the generic netlink family
249 * @net: the net namespace 258 * @net: the net namespace
250 * @skb: netlink message as socket buffer 259 * @skb: netlink message as socket buffer
251 * @portid: own netlink portid to avoid sending to yourself 260 * @portid: own netlink portid to avoid sending to yourself
252 * @group: multicast group id 261 * @group: offset of multicast group in groups array
253 * @flags: allocation flags 262 * @flags: allocation flags
254 */ 263 */
255static inline int genlmsg_multicast_netns(struct net *net, struct sk_buff *skb, 264static inline int genlmsg_multicast_netns(struct genl_family *family,
265 struct net *net, struct sk_buff *skb,
256 u32 portid, unsigned int group, gfp_t flags) 266 u32 portid, unsigned int group, gfp_t flags)
257{ 267{
268 if (group >= family->n_mcgrps)
269 return -EINVAL;
270 group = family->mcgrp_offset + group;
258 return nlmsg_multicast(net->genl_sock, skb, portid, group, flags); 271 return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
259} 272}
260 273
261/** 274/**
262 * genlmsg_multicast - multicast a netlink message to the default netns 275 * genlmsg_multicast - multicast a netlink message to the default netns
276 * @family: the generic netlink family
263 * @skb: netlink message as socket buffer 277 * @skb: netlink message as socket buffer
264 * @portid: own netlink portid to avoid sending to yourself 278 * @portid: own netlink portid to avoid sending to yourself
265 * @group: multicast group id 279 * @group: offset of multicast group in groups array
266 * @flags: allocation flags 280 * @flags: allocation flags
267 */ 281 */
268static inline int genlmsg_multicast(struct sk_buff *skb, u32 portid, 282static inline int genlmsg_multicast(struct genl_family *family,
283 struct sk_buff *skb, u32 portid,
269 unsigned int group, gfp_t flags) 284 unsigned int group, gfp_t flags)
270{ 285{
271 return genlmsg_multicast_netns(&init_net, skb, portid, group, flags); 286 if (group >= family->n_mcgrps)
287 return -EINVAL;
288 group = family->mcgrp_offset + group;
289 return genlmsg_multicast_netns(family, &init_net, skb,
290 portid, group, flags);
272} 291}
273 292
274/** 293/**
275 * genlmsg_multicast_allns - multicast a netlink message to all net namespaces 294 * genlmsg_multicast_allns - multicast a netlink message to all net namespaces
295 * @family: the generic netlink family
276 * @skb: netlink message as socket buffer 296 * @skb: netlink message as socket buffer
277 * @portid: own netlink portid to avoid sending to yourself 297 * @portid: own netlink portid to avoid sending to yourself
278 * @group: multicast group id 298 * @group: offset of multicast group in groups array
279 * @flags: allocation flags 299 * @flags: allocation flags
280 * 300 *
281 * This function must hold the RTNL or rcu_read_lock(). 301 * This function must hold the RTNL or rcu_read_lock().
282 */ 302 */
283int genlmsg_multicast_allns(struct sk_buff *skb, u32 portid, 303int genlmsg_multicast_allns(struct genl_family *family,
304 struct sk_buff *skb, u32 portid,
284 unsigned int group, gfp_t flags); 305 unsigned int group, gfp_t flags);
285 306
286/** 307/**
@@ -351,5 +372,22 @@ static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
351 return nlmsg_new(genlmsg_total_size(payload), flags); 372 return nlmsg_new(genlmsg_total_size(payload), flags);
352} 373}
353 374
375/**
376 * genl_set_err - report error to genetlink broadcast listeners
377 * @family: the generic netlink family
378 * @net: the network namespace to report the error to
379 * @portid: the PORTID of a process that we want to skip (if any)
380 * @group: the broadcast group that will notice the error
381 * (this is the offset of the multicast group in the groups array)
382 * @code: error code, must be negative (as usual in kernelspace)
383 *
384 * This function returns the number of broadcast listeners that have set the
385 * NETLINK_RECV_NO_ENOBUFS socket option.
386 */
387static inline int genl_set_err(struct genl_family *family, struct net *net,
388 u32 portid, u32 group, int code)
389{
390 return netlink_set_err(net->genl_sock, portid, group, code);
391}
354 392
355#endif /* __NET_GENERIC_NETLINK_H */ 393#endif /* __NET_GENERIC_NETLINK_H */
diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h
index c880a417d8a9..1af72d8228e0 100644
--- a/include/uapi/linux/genetlink.h
+++ b/include/uapi/linux/genetlink.h
@@ -27,6 +27,7 @@ struct genlmsghdr {
27 */ 27 */
28#define GENL_ID_GENERATE 0 28#define GENL_ID_GENERATE 0
29#define GENL_ID_CTRL NLMSG_MIN_TYPE 29#define GENL_ID_CTRL NLMSG_MIN_TYPE
30#define GENL_ID_VFS_DQUOT (NLMSG_MIN_TYPE + 1)
30 31
31/************************************************************************** 32/**************************************************************************
32 * Controller 33 * Controller
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 76595cd9d211..13d2f7cd65db 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -703,8 +703,7 @@ static int __init taskstats_init(void)
703{ 703{
704 int rc; 704 int rc;
705 705
706 rc = genl_register_family_with_ops(&family, taskstats_ops, 706 rc = genl_register_family_with_ops(&family, taskstats_ops);
707 ARRAY_SIZE(taskstats_ops));
708 if (rc) 707 if (rc)
709 return rc; 708 return rc;
710 709
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index f9fe2f22d20b..95897183226e 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -106,6 +106,10 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data)
106 return skb; 106 return skb;
107} 107}
108 108
109static struct genl_multicast_group dropmon_mcgrps[] = {
110 { .name = "events", },
111};
112
109static void send_dm_alert(struct work_struct *work) 113static void send_dm_alert(struct work_struct *work)
110{ 114{
111 struct sk_buff *skb; 115 struct sk_buff *skb;
@@ -116,7 +120,8 @@ static void send_dm_alert(struct work_struct *work)
116 skb = reset_per_cpu_data(data); 120 skb = reset_per_cpu_data(data);
117 121
118 if (skb) 122 if (skb)
119 genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL); 123 genlmsg_multicast(&net_drop_monitor_family, skb, 0,
124 0, GFP_KERNEL);
120} 125}
121 126
122/* 127/*
@@ -364,13 +369,13 @@ static int __init init_net_drop_monitor(void)
364 return -ENOSPC; 369 return -ENOSPC;
365 } 370 }
366 371
367 rc = genl_register_family_with_ops(&net_drop_monitor_family, 372 rc = genl_register_family_with_ops_groups(&net_drop_monitor_family,
368 dropmon_ops, 373 dropmon_ops, dropmon_mcgrps);
369 ARRAY_SIZE(dropmon_ops));
370 if (rc) { 374 if (rc) {
371 pr_err("Could not create drop monitor netlink family\n"); 375 pr_err("Could not create drop monitor netlink family\n");
372 return rc; 376 return rc;
373 } 377 }
378 WARN_ON(net_drop_monitor_family.mcgrp_offset != NET_DM_GRP_ALERT);
374 379
375 rc = register_netdevice_notifier(&dropmon_net_notifier); 380 rc = register_netdevice_notifier(&dropmon_net_notifier);
376 if (rc < 0) { 381 if (rc < 0) {
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 3b9205d2afc4..5325af85eea6 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -90,8 +90,8 @@ static struct genl_family hsr_genl_family = {
90 .maxattr = HSR_A_MAX, 90 .maxattr = HSR_A_MAX,
91}; 91};
92 92
93static struct genl_multicast_group hsr_network_genl_mcgrp = { 93static const struct genl_multicast_group hsr_mcgrps[] = {
94 .name = "hsr-network", 94 { .name = "hsr-network", },
95}; 95};
96 96
97 97
@@ -129,7 +129,7 @@ void hsr_nl_ringerror(struct hsr_priv *hsr_priv, unsigned char addr[ETH_ALEN],
129 goto nla_put_failure; 129 goto nla_put_failure;
130 130
131 genlmsg_end(skb, msg_head); 131 genlmsg_end(skb, msg_head);
132 genlmsg_multicast(skb, 0, hsr_network_genl_mcgrp.id, GFP_ATOMIC); 132 genlmsg_multicast(&hsr_genl_family, skb, 0, 0, GFP_ATOMIC);
133 133
134 return; 134 return;
135 135
@@ -163,7 +163,7 @@ void hsr_nl_nodedown(struct hsr_priv *hsr_priv, unsigned char addr[ETH_ALEN])
163 goto nla_put_failure; 163 goto nla_put_failure;
164 164
165 genlmsg_end(skb, msg_head); 165 genlmsg_end(skb, msg_head);
166 genlmsg_multicast(skb, 0, hsr_network_genl_mcgrp.id, GFP_ATOMIC); 166 genlmsg_multicast(&hsr_genl_family, skb, 0, 0, GFP_ATOMIC);
167 167
168 return; 168 return;
169 169
@@ -414,19 +414,13 @@ int __init hsr_netlink_init(void)
414 if (rc) 414 if (rc)
415 goto fail_rtnl_link_register; 415 goto fail_rtnl_link_register;
416 416
417 rc = genl_register_family_with_ops(&hsr_genl_family, hsr_ops, 417 rc = genl_register_family_with_ops_groups(&hsr_genl_family, hsr_ops,
418 ARRAY_SIZE(hsr_ops)); 418 hsr_mcgrps);
419 if (rc) 419 if (rc)
420 goto fail_genl_register_family; 420 goto fail_genl_register_family;
421 421
422 rc = genl_register_mc_group(&hsr_genl_family, &hsr_network_genl_mcgrp);
423 if (rc)
424 goto fail_genl_register_mc_group;
425
426 return 0; 422 return 0;
427 423
428fail_genl_register_mc_group:
429 genl_unregister_family(&hsr_genl_family);
430fail_genl_register_family: 424fail_genl_register_family:
431 rtnl_link_unregister(&hsr_link_ops); 425 rtnl_link_unregister(&hsr_link_ops);
432fail_rtnl_link_register: 426fail_rtnl_link_register:
@@ -436,9 +430,7 @@ fail_rtnl_link_register:
436 430
437void __exit hsr_netlink_exit(void) 431void __exit hsr_netlink_exit(void)
438{ 432{
439 genl_unregister_mc_group(&hsr_genl_family, &hsr_network_genl_mcgrp);
440 genl_unregister_family(&hsr_genl_family); 433 genl_unregister_family(&hsr_genl_family);
441
442 rtnl_link_unregister(&hsr_link_ops); 434 rtnl_link_unregister(&hsr_link_ops);
443} 435}
444 436
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
index 14d5dab4436f..cee4425b9956 100644
--- a/net/ieee802154/ieee802154.h
+++ b/net/ieee802154/ieee802154.h
@@ -54,8 +54,10 @@ int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb);
54int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info); 54int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info);
55int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info); 55int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info);
56 56
57extern struct genl_multicast_group ieee802154_coord_mcgrp; 57enum ieee802154_mcgrp_ids {
58extern struct genl_multicast_group ieee802154_beacon_mcgrp; 58 IEEE802154_COORD_MCGRP,
59 IEEE802154_BEACON_MCGRP,
60};
59 61
60int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info); 62int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info);
61int ieee802154_associate_resp(struct sk_buff *skb, struct genl_info *info); 63int ieee802154_associate_resp(struct sk_buff *skb, struct genl_info *info);
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 3ffcdbb56aab..43f1b2bf469f 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -70,7 +70,7 @@ int ieee802154_nl_mcast(struct sk_buff *msg, unsigned int group)
70 if (genlmsg_end(msg, hdr) < 0) 70 if (genlmsg_end(msg, hdr) < 0)
71 goto out; 71 goto out;
72 72
73 return genlmsg_multicast(msg, 0, group, GFP_ATOMIC); 73 return genlmsg_multicast(&nl802154_family, msg, 0, group, GFP_ATOMIC);
74out: 74out:
75 nlmsg_free(msg); 75 nlmsg_free(msg);
76 return -ENOBUFS; 76 return -ENOBUFS;
@@ -125,26 +125,17 @@ static const struct genl_ops ieee8021154_ops[] = {
125 ieee802154_dump_iface), 125 ieee802154_dump_iface),
126}; 126};
127 127
128static const struct genl_multicast_group ieee802154_mcgrps[] = {
129 [IEEE802154_COORD_MCGRP] = { .name = IEEE802154_MCAST_COORD_NAME, },
130 [IEEE802154_BEACON_MCGRP] = { .name = IEEE802154_MCAST_BEACON_NAME, },
131};
132
133
128int __init ieee802154_nl_init(void) 134int __init ieee802154_nl_init(void)
129{ 135{
130 int rc; 136 return genl_register_family_with_ops_groups(&nl802154_family,
131 137 ieee8021154_ops,
132 rc = genl_register_family_with_ops(&nl802154_family, ieee8021154_ops, 138 ieee802154_mcgrps);
133 ARRAY_SIZE(ieee8021154_ops));
134 if (rc)
135 return rc;
136
137 rc = genl_register_mc_group(&nl802154_family, &ieee802154_coord_mcgrp);
138 if (rc)
139 goto fail;
140
141 rc = genl_register_mc_group(&nl802154_family, &ieee802154_beacon_mcgrp);
142 if (rc)
143 goto fail;
144 return 0;
145fail:
146 genl_unregister_family(&nl802154_family);
147 return rc;
148} 139}
149 140
150void __exit ieee802154_nl_exit(void) 141void __exit ieee802154_nl_exit(void)
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index 28d493032132..ba5c1e002f37 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -39,14 +39,6 @@
39 39
40#include "ieee802154.h" 40#include "ieee802154.h"
41 41
42struct genl_multicast_group ieee802154_coord_mcgrp = {
43 .name = IEEE802154_MCAST_COORD_NAME,
44};
45
46struct genl_multicast_group ieee802154_beacon_mcgrp = {
47 .name = IEEE802154_MCAST_BEACON_NAME,
48};
49
50int ieee802154_nl_assoc_indic(struct net_device *dev, 42int ieee802154_nl_assoc_indic(struct net_device *dev,
51 struct ieee802154_addr *addr, u8 cap) 43 struct ieee802154_addr *addr, u8 cap)
52{ 44{
@@ -72,7 +64,7 @@ int ieee802154_nl_assoc_indic(struct net_device *dev,
72 nla_put_u8(msg, IEEE802154_ATTR_CAPABILITY, cap)) 64 nla_put_u8(msg, IEEE802154_ATTR_CAPABILITY, cap))
73 goto nla_put_failure; 65 goto nla_put_failure;
74 66
75 return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); 67 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP);
76 68
77nla_put_failure: 69nla_put_failure:
78 nlmsg_free(msg); 70 nlmsg_free(msg);
@@ -98,7 +90,7 @@ int ieee802154_nl_assoc_confirm(struct net_device *dev, u16 short_addr,
98 nla_put_u16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr) || 90 nla_put_u16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr) ||
99 nla_put_u8(msg, IEEE802154_ATTR_STATUS, status)) 91 nla_put_u8(msg, IEEE802154_ATTR_STATUS, status))
100 goto nla_put_failure; 92 goto nla_put_failure;
101 return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); 93 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP);
102 94
103nla_put_failure: 95nla_put_failure:
104 nlmsg_free(msg); 96 nlmsg_free(msg);
@@ -133,7 +125,7 @@ int ieee802154_nl_disassoc_indic(struct net_device *dev,
133 } 125 }
134 if (nla_put_u8(msg, IEEE802154_ATTR_REASON, reason)) 126 if (nla_put_u8(msg, IEEE802154_ATTR_REASON, reason))
135 goto nla_put_failure; 127 goto nla_put_failure;
136 return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); 128 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP);
137 129
138nla_put_failure: 130nla_put_failure:
139 nlmsg_free(msg); 131 nlmsg_free(msg);
@@ -157,7 +149,7 @@ int ieee802154_nl_disassoc_confirm(struct net_device *dev, u8 status)
157 dev->dev_addr) || 149 dev->dev_addr) ||
158 nla_put_u8(msg, IEEE802154_ATTR_STATUS, status)) 150 nla_put_u8(msg, IEEE802154_ATTR_STATUS, status))
159 goto nla_put_failure; 151 goto nla_put_failure;
160 return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); 152 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP);
161 153
162nla_put_failure: 154nla_put_failure:
163 nlmsg_free(msg); 155 nlmsg_free(msg);
@@ -183,7 +175,7 @@ int ieee802154_nl_beacon_indic(struct net_device *dev,
183 nla_put_u16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr) || 175 nla_put_u16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr) ||
184 nla_put_u16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid)) 176 nla_put_u16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid))
185 goto nla_put_failure; 177 goto nla_put_failure;
186 return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); 178 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP);
187 179
188nla_put_failure: 180nla_put_failure:
189 nlmsg_free(msg); 181 nlmsg_free(msg);
@@ -214,7 +206,7 @@ int ieee802154_nl_scan_confirm(struct net_device *dev,
214 (edl && 206 (edl &&
215 nla_put(msg, IEEE802154_ATTR_ED_LIST, 27, edl))) 207 nla_put(msg, IEEE802154_ATTR_ED_LIST, 27, edl)))
216 goto nla_put_failure; 208 goto nla_put_failure;
217 return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); 209 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP);
218 210
219nla_put_failure: 211nla_put_failure:
220 nlmsg_free(msg); 212 nlmsg_free(msg);
@@ -238,7 +230,7 @@ int ieee802154_nl_start_confirm(struct net_device *dev, u8 status)
238 dev->dev_addr) || 230 dev->dev_addr) ||
239 nla_put_u8(msg, IEEE802154_ATTR_STATUS, status)) 231 nla_put_u8(msg, IEEE802154_ATTR_STATUS, status))
240 goto nla_put_failure; 232 goto nla_put_failure;
241 return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); 233 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP);
242 234
243nla_put_failure: 235nla_put_failure:
244 nlmsg_free(msg); 236 nlmsg_free(msg);
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 8c121b523eee..06493736fbc8 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -1082,8 +1082,7 @@ void __init tcp_metrics_init(void)
1082 if (ret < 0) 1082 if (ret < 0)
1083 goto cleanup; 1083 goto cleanup;
1084 ret = genl_register_family_with_ops(&tcp_metrics_nl_family, 1084 ret = genl_register_family_with_ops(&tcp_metrics_nl_family,
1085 tcp_metrics_nl_ops, 1085 tcp_metrics_nl_ops);
1086 ARRAY_SIZE(tcp_metrics_nl_ops));
1087 if (ret < 0) 1086 if (ret < 0)
1088 goto cleanup_subsys; 1087 goto cleanup_subsys;
1089 return; 1088 return;
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c
index bf5d7d476dae..a37b81fe0479 100644
--- a/net/irda/irnetlink.c
+++ b/net/irda/irnetlink.c
@@ -149,8 +149,7 @@ static const struct genl_ops irda_nl_ops[] = {
149 149
150int irda_nl_register(void) 150int irda_nl_register(void)
151{ 151{
152 return genl_register_family_with_ops(&irda_nl_family, 152 return genl_register_family_with_ops(&irda_nl_family, irda_nl_ops);
153 irda_nl_ops, ARRAY_SIZE(irda_nl_ops));
154} 153}
155 154
156void irda_nl_unregister(void) 155void irda_nl_unregister(void)
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index 57db66e24f1f..4cfd722e9153 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -887,13 +887,8 @@ EXPORT_SYMBOL_GPL(l2tp_nl_unregister_ops);
887 887
888static int l2tp_nl_init(void) 888static int l2tp_nl_init(void)
889{ 889{
890 int err;
891
892 pr_info("L2TP netlink interface\n"); 890 pr_info("L2TP netlink interface\n");
893 err = genl_register_family_with_ops(&l2tp_nl_family, l2tp_nl_ops, 891 return genl_register_family_with_ops(&l2tp_nl_family, l2tp_nl_ops);
894 ARRAY_SIZE(l2tp_nl_ops));
895
896 return err;
897} 892}
898 893
899static void l2tp_nl_cleanup(void) 894static void l2tp_nl_cleanup(void)
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index fc8a04ed8854..393498704691 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -3666,7 +3666,7 @@ static const struct genl_ops ip_vs_genl_ops[] __read_mostly = {
3666static int __init ip_vs_genl_register(void) 3666static int __init ip_vs_genl_register(void)
3667{ 3667{
3668 return genl_register_family_with_ops(&ip_vs_genl_family, 3668 return genl_register_family_with_ops(&ip_vs_genl_family,
3669 ip_vs_genl_ops, ARRAY_SIZE(ip_vs_genl_ops)); 3669 ip_vs_genl_ops);
3670} 3670}
3671 3671
3672static void ip_vs_genl_unregister(void) 3672static void ip_vs_genl_unregister(void)
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index 706691739b99..69345cebe3a3 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -783,5 +783,5 @@ static const struct genl_ops netlbl_cipsov4_ops[] = {
783int __init netlbl_cipsov4_genl_init(void) 783int __init netlbl_cipsov4_genl_init(void)
784{ 784{
785 return genl_register_family_with_ops(&netlbl_cipsov4_gnl_family, 785 return genl_register_family_with_ops(&netlbl_cipsov4_gnl_family,
786 netlbl_cipsov4_ops, ARRAY_SIZE(netlbl_cipsov4_ops)); 786 netlbl_cipsov4_ops);
787} 787}
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index 7de6f660b80a..8ef83ee97c6a 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -779,5 +779,5 @@ static const struct genl_ops netlbl_mgmt_genl_ops[] = {
779int __init netlbl_mgmt_genl_init(void) 779int __init netlbl_mgmt_genl_init(void)
780{ 780{
781 return genl_register_family_with_ops(&netlbl_mgmt_gnl_family, 781 return genl_register_family_with_ops(&netlbl_mgmt_gnl_family,
782 netlbl_mgmt_genl_ops, ARRAY_SIZE(netlbl_mgmt_genl_ops)); 782 netlbl_mgmt_genl_ops);
783} 783}
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 76ee9252daa7..43817d73ccf9 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1397,7 +1397,7 @@ static const struct genl_ops netlbl_unlabel_genl_ops[] = {
1397int __init netlbl_unlabel_genl_init(void) 1397int __init netlbl_unlabel_genl_init(void)
1398{ 1398{
1399 return genl_register_family_with_ops(&netlbl_unlabel_gnl_family, 1399 return genl_register_family_with_ops(&netlbl_unlabel_gnl_family,
1400 netlbl_unlabel_genl_ops, ARRAY_SIZE(netlbl_unlabel_genl_ops)); 1400 netlbl_unlabel_genl_ops);
1401} 1401}
1402 1402
1403/* 1403/*
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index f54215d7b8f3..7dbc4f732c75 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -65,12 +65,24 @@ static struct list_head family_ht[GENL_FAM_TAB_SIZE];
65 * To avoid an allocation at boot of just one unsigned long, 65 * To avoid an allocation at boot of just one unsigned long,
66 * declare it global instead. 66 * declare it global instead.
67 * Bit 0 is marked as already used since group 0 is invalid. 67 * Bit 0 is marked as already used since group 0 is invalid.
68 * Bit 1 is marked as already used since the drop-monitor code
69 * abuses the API and thinks it can statically use group 1.
70 * That group will typically conflict with other groups that
71 * any proper users use.
72 * Bit 16 is marked as used since it's used for generic netlink
73 * and the code no longer marks pre-reserved IDs as used.
74 * Bit 17 is marked as already used since the VFS quota code
75 * also abused this API and relied on family == group ID, we
76 * cater to that by giving it a static family and group ID.
68 */ 77 */
69static unsigned long mc_group_start = 0x1; 78static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) |
79 BIT(GENL_ID_VFS_DQUOT);
70static unsigned long *mc_groups = &mc_group_start; 80static unsigned long *mc_groups = &mc_group_start;
71static unsigned long mc_groups_longs = 1; 81static unsigned long mc_groups_longs = 1;
72 82
73static int genl_ctrl_event(int event, void *data); 83static int genl_ctrl_event(int event, struct genl_family *family,
84 const struct genl_multicast_group *grp,
85 int grp_id);
74 86
75static inline unsigned int genl_family_hash(unsigned int id) 87static inline unsigned int genl_family_hash(unsigned int id)
76{ 88{
@@ -126,7 +138,8 @@ static u16 genl_generate_id(void)
126 int i; 138 int i;
127 139
128 for (i = 0; i <= GENL_MAX_ID - GENL_MIN_ID; i++) { 140 for (i = 0; i <= GENL_MAX_ID - GENL_MIN_ID; i++) {
129 if (!genl_family_find_byid(id_gen_idx)) 141 if (id_gen_idx != GENL_ID_VFS_DQUOT &&
142 !genl_family_find_byid(id_gen_idx))
130 return id_gen_idx; 143 return id_gen_idx;
131 if (++id_gen_idx > GENL_MAX_ID) 144 if (++id_gen_idx > GENL_MAX_ID)
132 id_gen_idx = GENL_MIN_ID; 145 id_gen_idx = GENL_MIN_ID;
@@ -135,62 +148,110 @@ static u16 genl_generate_id(void)
135 return 0; 148 return 0;
136} 149}
137 150
138static struct genl_multicast_group notify_grp; 151static int genl_allocate_reserve_groups(int n_groups, int *first_id)
139
140/**
141 * genl_register_mc_group - register a multicast group
142 *
143 * Registers the specified multicast group and notifies userspace
144 * about the new group.
145 *
146 * Returns 0 on success or a negative error code.
147 *
148 * @family: The generic netlink family the group shall be registered for.
149 * @grp: The group to register, must have a name.
150 */
151int genl_register_mc_group(struct genl_family *family,
152 struct genl_multicast_group *grp)
153{ 152{
154 int id;
155 unsigned long *new_groups; 153 unsigned long *new_groups;
156 int err = 0; 154 int start = 0;
155 int i;
156 int id;
157 bool fits;
158
159 do {
160 if (start == 0)
161 id = find_first_zero_bit(mc_groups,
162 mc_groups_longs *
163 BITS_PER_LONG);
164 else
165 id = find_next_zero_bit(mc_groups,
166 mc_groups_longs * BITS_PER_LONG,
167 start);
168
169 fits = true;
170 for (i = id;
171 i < min_t(int, id + n_groups,
172 mc_groups_longs * BITS_PER_LONG);
173 i++) {
174 if (test_bit(i, mc_groups)) {
175 start = i;
176 fits = false;
177 break;
178 }
179 }
157 180
158 BUG_ON(grp->name[0] == '\0'); 181 if (id >= mc_groups_longs * BITS_PER_LONG) {
159 BUG_ON(memchr(grp->name, '\0', GENL_NAMSIZ) == NULL); 182 unsigned long new_longs = mc_groups_longs +
183 BITS_TO_LONGS(n_groups);
184 size_t nlen = new_longs * sizeof(unsigned long);
185
186 if (mc_groups == &mc_group_start) {
187 new_groups = kzalloc(nlen, GFP_KERNEL);
188 if (!new_groups)
189 return -ENOMEM;
190 mc_groups = new_groups;
191 *mc_groups = mc_group_start;
192 } else {
193 new_groups = krealloc(mc_groups, nlen,
194 GFP_KERNEL);
195 if (!new_groups)
196 return -ENOMEM;
197 mc_groups = new_groups;
198 for (i = 0; i < BITS_TO_LONGS(n_groups); i++)
199 mc_groups[mc_groups_longs + i] = 0;
200 }
201 mc_groups_longs = new_longs;
202 }
203 } while (!fits);
160 204
161 genl_lock_all(); 205 for (i = id; i < id + n_groups; i++)
206 set_bit(i, mc_groups);
207 *first_id = id;
208 return 0;
209}
162 210
163 /* special-case our own group */ 211static struct genl_family genl_ctrl;
164 if (grp == &notify_grp)
165 id = GENL_ID_CTRL;
166 else
167 id = find_first_zero_bit(mc_groups,
168 mc_groups_longs * BITS_PER_LONG);
169 212
213static int genl_validate_assign_mc_groups(struct genl_family *family)
214{
215 int first_id;
216 int n_groups = family->n_mcgrps;
217 int err, i;
218 bool groups_allocated = false;
170 219
171 if (id >= mc_groups_longs * BITS_PER_LONG) { 220 if (!n_groups)
172 size_t nlen = (mc_groups_longs + 1) * sizeof(unsigned long); 221 return 0;
173 222
174 if (mc_groups == &mc_group_start) { 223 for (i = 0; i < n_groups; i++) {
175 new_groups = kzalloc(nlen, GFP_KERNEL); 224 const struct genl_multicast_group *grp = &family->mcgrps[i];
176 if (!new_groups) { 225
177 err = -ENOMEM; 226 if (WARN_ON(grp->name[0] == '\0'))
178 goto out; 227 return -EINVAL;
179 } 228 if (WARN_ON(memchr(grp->name, '\0', GENL_NAMSIZ) == NULL))
180 mc_groups = new_groups; 229 return -EINVAL;
181 *mc_groups = mc_group_start;
182 } else {
183 new_groups = krealloc(mc_groups, nlen, GFP_KERNEL);
184 if (!new_groups) {
185 err = -ENOMEM;
186 goto out;
187 }
188 mc_groups = new_groups;
189 mc_groups[mc_groups_longs] = 0;
190 }
191 mc_groups_longs++;
192 } 230 }
193 231
232 /* special-case our own group and hacks */
233 if (family == &genl_ctrl) {
234 first_id = GENL_ID_CTRL;
235 BUG_ON(n_groups != 1);
236 } else if (strcmp(family->name, "NET_DM") == 0) {
237 first_id = 1;
238 BUG_ON(n_groups != 1);
239 } else if (strcmp(family->name, "VFS_DQUOT") == 0) {
240 first_id = GENL_ID_VFS_DQUOT;
241 BUG_ON(n_groups != 1);
242 } else {
243 groups_allocated = true;
244 err = genl_allocate_reserve_groups(n_groups, &first_id);
245 if (err)
246 return err;
247 }
248
249 family->mcgrp_offset = first_id;
250
251 /* if still initializing, can't and don't need to to realloc bitmaps */
252 if (!init_net.genl_sock)
253 return 0;
254
194 if (family->netnsok) { 255 if (family->netnsok) {
195 struct net *net; 256 struct net *net;
196 257
@@ -206,9 +267,7 @@ int genl_register_mc_group(struct genl_family *family,
206 * number of _possible_ groups has been 267 * number of _possible_ groups has been
207 * increased on some sockets which is ok. 268 * increased on some sockets which is ok.
208 */ 269 */
209 rcu_read_unlock(); 270 break;
210 netlink_table_ungrab();
211 goto out;
212 } 271 }
213 } 272 }
214 rcu_read_unlock(); 273 rcu_read_unlock();
@@ -216,71 +275,39 @@ int genl_register_mc_group(struct genl_family *family,
216 } else { 275 } else {
217 err = netlink_change_ngroups(init_net.genl_sock, 276 err = netlink_change_ngroups(init_net.genl_sock,
218 mc_groups_longs * BITS_PER_LONG); 277 mc_groups_longs * BITS_PER_LONG);
219 if (err)
220 goto out;
221 } 278 }
222 279
223 grp->id = id; 280 if (groups_allocated && err) {
224 set_bit(id, mc_groups); 281 for (i = 0; i < family->n_mcgrps; i++)
225 list_add_tail(&grp->list, &family->mcast_groups); 282 clear_bit(family->mcgrp_offset + i, mc_groups);
226 grp->family = family; 283 }
227 284
228 genl_ctrl_event(CTRL_CMD_NEWMCAST_GRP, grp);
229 out:
230 genl_unlock_all();
231 return err; 285 return err;
232} 286}
233EXPORT_SYMBOL(genl_register_mc_group);
234 287
235static void __genl_unregister_mc_group(struct genl_family *family, 288static void genl_unregister_mc_groups(struct genl_family *family)
236 struct genl_multicast_group *grp)
237{ 289{
238 struct net *net; 290 struct net *net;
239 BUG_ON(grp->family != family); 291 int i;
240 292
241 netlink_table_grab(); 293 netlink_table_grab();
242 rcu_read_lock(); 294 rcu_read_lock();
243 for_each_net_rcu(net) 295 for_each_net_rcu(net) {
244 __netlink_clear_multicast_users(net->genl_sock, grp->id); 296 for (i = 0; i < family->n_mcgrps; i++)
297 __netlink_clear_multicast_users(
298 net->genl_sock, family->mcgrp_offset + i);
299 }
245 rcu_read_unlock(); 300 rcu_read_unlock();
246 netlink_table_ungrab(); 301 netlink_table_ungrab();
247 302
248 clear_bit(grp->id, mc_groups); 303 for (i = 0; i < family->n_mcgrps; i++) {
249 list_del(&grp->list); 304 int grp_id = family->mcgrp_offset + i;
250 genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, grp);
251 grp->id = 0;
252 grp->family = NULL;
253}
254
255/**
256 * genl_unregister_mc_group - unregister a multicast group
257 *
258 * Unregisters the specified multicast group and notifies userspace
259 * about it. All current listeners on the group are removed.
260 *
261 * Note: It is not necessary to unregister all multicast groups before
262 * unregistering the family, unregistering the family will cause
263 * all assigned multicast groups to be unregistered automatically.
264 *
265 * @family: Generic netlink family the group belongs to.
266 * @grp: The group to unregister, must have been registered successfully
267 * previously.
268 */
269void genl_unregister_mc_group(struct genl_family *family,
270 struct genl_multicast_group *grp)
271{
272 genl_lock_all();
273 __genl_unregister_mc_group(family, grp);
274 genl_unlock_all();
275}
276EXPORT_SYMBOL(genl_unregister_mc_group);
277
278static void genl_unregister_mc_groups(struct genl_family *family)
279{
280 struct genl_multicast_group *grp, *tmp;
281 305
282 list_for_each_entry_safe(grp, tmp, &family->mcast_groups, list) 306 if (grp_id != 1)
283 __genl_unregister_mc_group(family, grp); 307 clear_bit(grp_id, mc_groups);
308 genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, family,
309 &family->mcgrps[i], grp_id);
310 }
284} 311}
285 312
286static int genl_validate_ops(struct genl_family *family) 313static int genl_validate_ops(struct genl_family *family)
@@ -326,7 +353,7 @@ static int genl_validate_ops(struct genl_family *family)
326 */ 353 */
327int __genl_register_family(struct genl_family *family) 354int __genl_register_family(struct genl_family *family)
328{ 355{
329 int err = -EINVAL; 356 int err = -EINVAL, i;
330 357
331 if (family->id && family->id < GENL_MIN_ID) 358 if (family->id && family->id < GENL_MIN_ID)
332 goto errout; 359 goto errout;
@@ -338,8 +365,6 @@ int __genl_register_family(struct genl_family *family)
338 if (err) 365 if (err)
339 return err; 366 return err;
340 367
341 INIT_LIST_HEAD(&family->mcast_groups);
342
343 genl_lock_all(); 368 genl_lock_all();
344 369
345 if (genl_family_find_byname(family->name)) { 370 if (genl_family_find_byname(family->name)) {
@@ -371,10 +396,18 @@ int __genl_register_family(struct genl_family *family)
371 } else 396 } else
372 family->attrbuf = NULL; 397 family->attrbuf = NULL;
373 398
399 err = genl_validate_assign_mc_groups(family);
400 if (err)
401 goto errout_locked;
402
374 list_add_tail(&family->family_list, genl_family_chain(family->id)); 403 list_add_tail(&family->family_list, genl_family_chain(family->id));
375 genl_unlock_all(); 404 genl_unlock_all();
376 405
377 genl_ctrl_event(CTRL_CMD_NEWFAMILY, family); 406 /* send all events */
407 genl_ctrl_event(CTRL_CMD_NEWFAMILY, family, NULL, 0);
408 for (i = 0; i < family->n_mcgrps; i++)
409 genl_ctrl_event(CTRL_CMD_NEWMCAST_GRP, family,
410 &family->mcgrps[i], family->mcgrp_offset + i);
378 411
379 return 0; 412 return 0;
380 413
@@ -410,7 +443,7 @@ int genl_unregister_family(struct genl_family *family)
410 genl_unlock_all(); 443 genl_unlock_all();
411 444
412 kfree(family->attrbuf); 445 kfree(family->attrbuf);
413 genl_ctrl_event(CTRL_CMD_DELFAMILY, family); 446 genl_ctrl_event(CTRL_CMD_DELFAMILY, family, NULL, 0);
414 return 0; 447 return 0;
415 } 448 }
416 449
@@ -670,23 +703,26 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq,
670 nla_nest_end(skb, nla_ops); 703 nla_nest_end(skb, nla_ops);
671 } 704 }
672 705
673 if (!list_empty(&family->mcast_groups)) { 706 if (family->n_mcgrps) {
674 struct genl_multicast_group *grp;
675 struct nlattr *nla_grps; 707 struct nlattr *nla_grps;
676 int idx = 1; 708 int i;
677 709
678 nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS); 710 nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS);
679 if (nla_grps == NULL) 711 if (nla_grps == NULL)
680 goto nla_put_failure; 712 goto nla_put_failure;
681 713
682 list_for_each_entry(grp, &family->mcast_groups, list) { 714 for (i = 0; i < family->n_mcgrps; i++) {
683 struct nlattr *nest; 715 struct nlattr *nest;
716 const struct genl_multicast_group *grp;
717
718 grp = &family->mcgrps[i];
684 719
685 nest = nla_nest_start(skb, idx++); 720 nest = nla_nest_start(skb, i + 1);
686 if (nest == NULL) 721 if (nest == NULL)
687 goto nla_put_failure; 722 goto nla_put_failure;
688 723
689 if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id) || 724 if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID,
725 family->mcgrp_offset + i) ||
690 nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME, 726 nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME,
691 grp->name)) 727 grp->name))
692 goto nla_put_failure; 728 goto nla_put_failure;
@@ -703,9 +739,10 @@ nla_put_failure:
703 return -EMSGSIZE; 739 return -EMSGSIZE;
704} 740}
705 741
706static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 portid, 742static int ctrl_fill_mcgrp_info(struct genl_family *family,
707 u32 seq, u32 flags, struct sk_buff *skb, 743 const struct genl_multicast_group *grp,
708 u8 cmd) 744 int grp_id, u32 portid, u32 seq, u32 flags,
745 struct sk_buff *skb, u8 cmd)
709{ 746{
710 void *hdr; 747 void *hdr;
711 struct nlattr *nla_grps; 748 struct nlattr *nla_grps;
@@ -715,8 +752,8 @@ static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 portid,
715 if (hdr == NULL) 752 if (hdr == NULL)
716 return -1; 753 return -1;
717 754
718 if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, grp->family->name) || 755 if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, family->name) ||
719 nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, grp->family->id)) 756 nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, family->id))
720 goto nla_put_failure; 757 goto nla_put_failure;
721 758
722 nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS); 759 nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS);
@@ -727,7 +764,7 @@ static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 portid,
727 if (nest == NULL) 764 if (nest == NULL)
728 goto nla_put_failure; 765 goto nla_put_failure;
729 766
730 if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id) || 767 if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp_id) ||
731 nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME, 768 nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME,
732 grp->name)) 769 grp->name))
733 goto nla_put_failure; 770 goto nla_put_failure;
@@ -793,8 +830,10 @@ static struct sk_buff *ctrl_build_family_msg(struct genl_family *family,
793 return skb; 830 return skb;
794} 831}
795 832
796static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp, 833static struct sk_buff *
797 u32 portid, int seq, u8 cmd) 834ctrl_build_mcgrp_msg(struct genl_family *family,
835 const struct genl_multicast_group *grp,
836 int grp_id, u32 portid, int seq, u8 cmd)
798{ 837{
799 struct sk_buff *skb; 838 struct sk_buff *skb;
800 int err; 839 int err;
@@ -803,7 +842,8 @@ static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp,
803 if (skb == NULL) 842 if (skb == NULL)
804 return ERR_PTR(-ENOBUFS); 843 return ERR_PTR(-ENOBUFS);
805 844
806 err = ctrl_fill_mcgrp_info(grp, portid, seq, 0, skb, cmd); 845 err = ctrl_fill_mcgrp_info(family, grp, grp_id, portid,
846 seq, 0, skb, cmd);
807 if (err < 0) { 847 if (err < 0) {
808 nlmsg_free(skb); 848 nlmsg_free(skb);
809 return ERR_PTR(err); 849 return ERR_PTR(err);
@@ -865,11 +905,11 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
865 return genlmsg_reply(msg, info); 905 return genlmsg_reply(msg, info);
866} 906}
867 907
868static int genl_ctrl_event(int event, void *data) 908static int genl_ctrl_event(int event, struct genl_family *family,
909 const struct genl_multicast_group *grp,
910 int grp_id)
869{ 911{
870 struct sk_buff *msg; 912 struct sk_buff *msg;
871 struct genl_family *family;
872 struct genl_multicast_group *grp;
873 913
874 /* genl is still initialising */ 914 /* genl is still initialising */
875 if (!init_net.genl_sock) 915 if (!init_net.genl_sock)
@@ -878,14 +918,13 @@ static int genl_ctrl_event(int event, void *data)
878 switch (event) { 918 switch (event) {
879 case CTRL_CMD_NEWFAMILY: 919 case CTRL_CMD_NEWFAMILY:
880 case CTRL_CMD_DELFAMILY: 920 case CTRL_CMD_DELFAMILY:
881 family = data; 921 WARN_ON(grp);
882 msg = ctrl_build_family_msg(family, 0, 0, event); 922 msg = ctrl_build_family_msg(family, 0, 0, event);
883 break; 923 break;
884 case CTRL_CMD_NEWMCAST_GRP: 924 case CTRL_CMD_NEWMCAST_GRP:
885 case CTRL_CMD_DELMCAST_GRP: 925 case CTRL_CMD_DELMCAST_GRP:
886 grp = data; 926 BUG_ON(!grp);
887 family = grp->family; 927 msg = ctrl_build_mcgrp_msg(family, grp, grp_id, 0, 0, event);
888 msg = ctrl_build_mcgrp_msg(data, 0, 0, event);
889 break; 928 break;
890 default: 929 default:
891 return -EINVAL; 930 return -EINVAL;
@@ -895,26 +934,29 @@ static int genl_ctrl_event(int event, void *data)
895 return PTR_ERR(msg); 934 return PTR_ERR(msg);
896 935
897 if (!family->netnsok) { 936 if (!family->netnsok) {
898 genlmsg_multicast_netns(&init_net, msg, 0, 937 genlmsg_multicast_netns(&genl_ctrl, &init_net, msg, 0,
899 GENL_ID_CTRL, GFP_KERNEL); 938 0, GFP_KERNEL);
900 } else { 939 } else {
901 rcu_read_lock(); 940 rcu_read_lock();
902 genlmsg_multicast_allns(msg, 0, GENL_ID_CTRL, GFP_ATOMIC); 941 genlmsg_multicast_allns(&genl_ctrl, msg, 0,
942 0, GFP_ATOMIC);
903 rcu_read_unlock(); 943 rcu_read_unlock();
904 } 944 }
905 945
906 return 0; 946 return 0;
907} 947}
908 948
909static struct genl_ops genl_ctrl_ops = { 949static struct genl_ops genl_ctrl_ops[] = {
910 .cmd = CTRL_CMD_GETFAMILY, 950 {
911 .doit = ctrl_getfamily, 951 .cmd = CTRL_CMD_GETFAMILY,
912 .dumpit = ctrl_dumpfamily, 952 .doit = ctrl_getfamily,
913 .policy = ctrl_policy, 953 .dumpit = ctrl_dumpfamily,
954 .policy = ctrl_policy,
955 },
914}; 956};
915 957
916static struct genl_multicast_group notify_grp = { 958static struct genl_multicast_group genl_ctrl_groups[] = {
917 .name = "notify", 959 { .name = "notify", },
918}; 960};
919 961
920static int __net_init genl_pernet_init(struct net *net) 962static int __net_init genl_pernet_init(struct net *net)
@@ -954,7 +996,8 @@ static int __init genl_init(void)
954 for (i = 0; i < GENL_FAM_TAB_SIZE; i++) 996 for (i = 0; i < GENL_FAM_TAB_SIZE; i++)
955 INIT_LIST_HEAD(&family_ht[i]); 997 INIT_LIST_HEAD(&family_ht[i]);
956 998
957 err = genl_register_family_with_ops(&genl_ctrl, &genl_ctrl_ops, 1); 999 err = genl_register_family_with_ops_groups(&genl_ctrl, genl_ctrl_ops,
1000 genl_ctrl_groups);
958 if (err < 0) 1001 if (err < 0)
959 goto problem; 1002 goto problem;
960 1003
@@ -962,10 +1005,6 @@ static int __init genl_init(void)
962 if (err) 1005 if (err)
963 goto problem; 1006 goto problem;
964 1007
965 err = genl_register_mc_group(&genl_ctrl, &notify_grp);
966 if (err < 0)
967 goto problem;
968
969 return 0; 1008 return 0;
970 1009
971problem: 1010problem:
@@ -1003,14 +1042,18 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
1003 return err; 1042 return err;
1004} 1043}
1005 1044
1006int genlmsg_multicast_allns(struct sk_buff *skb, u32 portid, unsigned int group, 1045int genlmsg_multicast_allns(struct genl_family *family, struct sk_buff *skb,
1007 gfp_t flags) 1046 u32 portid, unsigned int group, gfp_t flags)
1008{ 1047{
1048 if (group >= family->n_mcgrps)
1049 return -EINVAL;
1050 group = family->mcgrp_offset + group;
1009 return genlmsg_mcast(skb, portid, group, flags); 1051 return genlmsg_mcast(skb, portid, group, flags);
1010} 1052}
1011EXPORT_SYMBOL(genlmsg_multicast_allns); 1053EXPORT_SYMBOL(genlmsg_multicast_allns);
1012 1054
1013void genl_notify(struct sk_buff *skb, struct net *net, u32 portid, u32 group, 1055void genl_notify(struct genl_family *family,
1056 struct sk_buff *skb, struct net *net, u32 portid, u32 group,
1014 struct nlmsghdr *nlh, gfp_t flags) 1057 struct nlmsghdr *nlh, gfp_t flags)
1015{ 1058{
1016 struct sock *sk = net->genl_sock; 1059 struct sock *sk = net->genl_sock;
@@ -1019,6 +1062,9 @@ void genl_notify(struct sk_buff *skb, struct net *net, u32 portid, u32 group,
1019 if (nlh) 1062 if (nlh)
1020 report = nlmsg_report(nlh); 1063 report = nlmsg_report(nlh);
1021 1064
1065 if (group >= family->n_mcgrps)
1066 return;
1067 group = family->mcgrp_offset + group;
1022 nlmsg_notify(sk, skb, portid, group, report, flags); 1068 nlmsg_notify(sk, skb, portid, group, report, flags);
1023} 1069}
1024EXPORT_SYMBOL(genl_notify); 1070EXPORT_SYMBOL(genl_notify);
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index f5585611c098..a9b2342d5253 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -30,8 +30,8 @@
30#include "nfc.h" 30#include "nfc.h"
31#include "llcp.h" 31#include "llcp.h"
32 32
33static struct genl_multicast_group nfc_genl_event_mcgrp = { 33static const struct genl_multicast_group nfc_genl_mcgrps[] = {
34 .name = NFC_GENL_MCAST_EVENT_NAME, 34 { .name = NFC_GENL_MCAST_EVENT_NAME, },
35}; 35};
36 36
37static struct genl_family nfc_genl_family = { 37static struct genl_family nfc_genl_family = {
@@ -194,7 +194,7 @@ int nfc_genl_targets_found(struct nfc_dev *dev)
194 194
195 genlmsg_end(msg, hdr); 195 genlmsg_end(msg, hdr);
196 196
197 return genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC); 197 return genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
198 198
199nla_put_failure: 199nla_put_failure:
200 genlmsg_cancel(msg, hdr); 200 genlmsg_cancel(msg, hdr);
@@ -223,7 +223,7 @@ int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx)
223 223
224 genlmsg_end(msg, hdr); 224 genlmsg_end(msg, hdr);
225 225
226 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); 226 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
227 227
228 return 0; 228 return 0;
229 229
@@ -255,7 +255,7 @@ int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol)
255 255
256 genlmsg_end(msg, hdr); 256 genlmsg_end(msg, hdr);
257 257
258 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); 258 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
259 259
260 return 0; 260 return 0;
261 261
@@ -285,7 +285,7 @@ int nfc_genl_tm_deactivated(struct nfc_dev *dev)
285 285
286 genlmsg_end(msg, hdr); 286 genlmsg_end(msg, hdr);
287 287
288 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); 288 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
289 289
290 return 0; 290 return 0;
291 291
@@ -318,7 +318,7 @@ int nfc_genl_device_added(struct nfc_dev *dev)
318 318
319 genlmsg_end(msg, hdr); 319 genlmsg_end(msg, hdr);
320 320
321 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); 321 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
322 322
323 return 0; 323 return 0;
324 324
@@ -348,7 +348,7 @@ int nfc_genl_device_removed(struct nfc_dev *dev)
348 348
349 genlmsg_end(msg, hdr); 349 genlmsg_end(msg, hdr);
350 350
351 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); 351 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
352 352
353 return 0; 353 return 0;
354 354
@@ -414,7 +414,7 @@ int nfc_genl_llc_send_sdres(struct nfc_dev *dev, struct hlist_head *sdres_list)
414 414
415 genlmsg_end(msg, hdr); 415 genlmsg_end(msg, hdr);
416 416
417 return genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC); 417 return genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
418 418
419nla_put_failure: 419nla_put_failure:
420 genlmsg_cancel(msg, hdr); 420 genlmsg_cancel(msg, hdr);
@@ -448,7 +448,7 @@ int nfc_genl_se_added(struct nfc_dev *dev, u32 se_idx, u16 type)
448 448
449 genlmsg_end(msg, hdr); 449 genlmsg_end(msg, hdr);
450 450
451 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); 451 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
452 452
453 return 0; 453 return 0;
454 454
@@ -479,7 +479,7 @@ int nfc_genl_se_removed(struct nfc_dev *dev, u32 se_idx)
479 479
480 genlmsg_end(msg, hdr); 480 genlmsg_end(msg, hdr);
481 481
482 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); 482 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
483 483
484 return 0; 484 return 0;
485 485
@@ -600,7 +600,7 @@ int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
600 600
601 dev->dep_link_up = true; 601 dev->dep_link_up = true;
602 602
603 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC); 603 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
604 604
605 return 0; 605 return 0;
606 606
@@ -632,7 +632,7 @@ int nfc_genl_dep_link_down_event(struct nfc_dev *dev)
632 632
633 genlmsg_end(msg, hdr); 633 genlmsg_end(msg, hdr);
634 634
635 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC); 635 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
636 636
637 return 0; 637 return 0;
638 638
@@ -1137,7 +1137,7 @@ int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name,
1137 1137
1138 genlmsg_end(msg, hdr); 1138 genlmsg_end(msg, hdr);
1139 1139
1140 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); 1140 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
1141 1141
1142 return 0; 1142 return 0;
1143 1143
@@ -1308,7 +1308,7 @@ static void se_io_cb(void *context, u8 *apdu, size_t apdu_len, int err)
1308 1308
1309 genlmsg_end(msg, hdr); 1309 genlmsg_end(msg, hdr);
1310 1310
1311 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); 1311 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
1312 1312
1313 kfree(ctx); 1313 kfree(ctx);
1314 1314
@@ -1536,16 +1536,15 @@ int __init nfc_genl_init(void)
1536{ 1536{
1537 int rc; 1537 int rc;
1538 1538
1539 rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops, 1539 rc = genl_register_family_with_ops_groups(&nfc_genl_family,
1540 ARRAY_SIZE(nfc_genl_ops)); 1540 nfc_genl_ops,
1541 nfc_genl_mcgrps);
1541 if (rc) 1542 if (rc)
1542 return rc; 1543 return rc;
1543 1544
1544 rc = genl_register_mc_group(&nfc_genl_family, &nfc_genl_event_mcgrp);
1545
1546 netlink_register_notifier(&nl_notifier); 1545 netlink_register_notifier(&nl_notifier);
1547 1546
1548 return rc; 1547 return 0;
1549} 1548}
1550 1549
1551/** 1550/**
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 91e1c927a465..1de4d281e3f1 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -61,11 +61,11 @@
61 61
62int ovs_net_id __read_mostly; 62int ovs_net_id __read_mostly;
63 63
64static void ovs_notify(struct sk_buff *skb, struct genl_info *info, 64static void ovs_notify(struct genl_family *family,
65 struct genl_multicast_group *grp) 65 struct sk_buff *skb, struct genl_info *info)
66{ 66{
67 genl_notify(skb, genl_info_net(info), info->snd_portid, 67 genl_notify(family, skb, genl_info_net(info), info->snd_portid,
68 grp->id, info->nlhdr, GFP_KERNEL); 68 0, info->nlhdr, GFP_KERNEL);
69} 69}
70 70
71/** 71/**
@@ -877,10 +877,10 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
877 ovs_unlock(); 877 ovs_unlock();
878 878
879 if (!IS_ERR(reply)) 879 if (!IS_ERR(reply))
880 ovs_notify(reply, info, &ovs_dp_flow_multicast_group); 880 ovs_notify(&dp_flow_genl_family, reply, info);
881 else 881 else
882 netlink_set_err(sock_net(skb->sk)->genl_sock, 0, 882 genl_set_err(&dp_flow_genl_family, sock_net(skb->sk), 0,
883 ovs_dp_flow_multicast_group.id, PTR_ERR(reply)); 883 0, PTR_ERR(reply));
884 return 0; 884 return 0;
885 885
886err_flow_free: 886err_flow_free:
@@ -990,7 +990,7 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
990 ovs_flow_free(flow, true); 990 ovs_flow_free(flow, true);
991 ovs_unlock(); 991 ovs_unlock();
992 992
993 ovs_notify(reply, info, &ovs_dp_flow_multicast_group); 993 ovs_notify(&dp_flow_genl_family, reply, info);
994 return 0; 994 return 0;
995unlock: 995unlock:
996 ovs_unlock(); 996 ovs_unlock();
@@ -1237,7 +1237,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
1237 1237
1238 ovs_unlock(); 1238 ovs_unlock();
1239 1239
1240 ovs_notify(reply, info, &ovs_dp_datapath_multicast_group); 1240 ovs_notify(&dp_datapath_genl_family, reply, info);
1241 return 0; 1241 return 0;
1242 1242
1243err_destroy_local_port: 1243err_destroy_local_port:
@@ -1302,7 +1302,7 @@ static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info)
1302 __dp_destroy(dp); 1302 __dp_destroy(dp);
1303 ovs_unlock(); 1303 ovs_unlock();
1304 1304
1305 ovs_notify(reply, info, &ovs_dp_datapath_multicast_group); 1305 ovs_notify(&dp_datapath_genl_family, reply, info);
1306 1306
1307 return 0; 1307 return 0;
1308unlock: 1308unlock:
@@ -1326,14 +1326,14 @@ static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info)
1326 info->snd_seq, OVS_DP_CMD_NEW); 1326 info->snd_seq, OVS_DP_CMD_NEW);
1327 if (IS_ERR(reply)) { 1327 if (IS_ERR(reply)) {
1328 err = PTR_ERR(reply); 1328 err = PTR_ERR(reply);
1329 netlink_set_err(sock_net(skb->sk)->genl_sock, 0, 1329 genl_set_err(&dp_datapath_genl_family, sock_net(skb->sk), 0,
1330 ovs_dp_datapath_multicast_group.id, err); 1330 0, err);
1331 err = 0; 1331 err = 0;
1332 goto unlock; 1332 goto unlock;
1333 } 1333 }
1334 1334
1335 ovs_unlock(); 1335 ovs_unlock();
1336 ovs_notify(reply, info, &ovs_dp_datapath_multicast_group); 1336 ovs_notify(&dp_datapath_genl_family, reply, info);
1337 1337
1338 return 0; 1338 return 0;
1339unlock: 1339unlock:
@@ -1425,7 +1425,7 @@ static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = {
1425 [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED }, 1425 [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED },
1426}; 1426};
1427 1427
1428static struct genl_family dp_vport_genl_family = { 1428struct genl_family dp_vport_genl_family = {
1429 .id = GENL_ID_GENERATE, 1429 .id = GENL_ID_GENERATE,
1430 .hdrsize = sizeof(struct ovs_header), 1430 .hdrsize = sizeof(struct ovs_header),
1431 .name = OVS_VPORT_FAMILY, 1431 .name = OVS_VPORT_FAMILY,
@@ -1595,7 +1595,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
1595 goto exit_unlock; 1595 goto exit_unlock;
1596 } 1596 }
1597 1597
1598 ovs_notify(reply, info, &ovs_dp_vport_multicast_group); 1598 ovs_notify(&dp_vport_genl_family, reply, info);
1599 1599
1600exit_unlock: 1600exit_unlock:
1601 ovs_unlock(); 1601 ovs_unlock();
@@ -1642,7 +1642,7 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
1642 BUG_ON(err < 0); 1642 BUG_ON(err < 0);
1643 1643
1644 ovs_unlock(); 1644 ovs_unlock();
1645 ovs_notify(reply, info, &ovs_dp_vport_multicast_group); 1645 ovs_notify(&dp_vport_genl_family, reply, info);
1646 return 0; 1646 return 0;
1647 1647
1648exit_free: 1648exit_free:
@@ -1679,7 +1679,7 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
1679 err = 0; 1679 err = 0;
1680 ovs_dp_detach_port(vport); 1680 ovs_dp_detach_port(vport);
1681 1681
1682 ovs_notify(reply, info, &ovs_dp_vport_multicast_group); 1682 ovs_notify(&dp_vport_genl_family, reply, info);
1683 1683
1684exit_unlock: 1684exit_unlock:
1685 ovs_unlock(); 1685 ovs_unlock();
@@ -1781,7 +1781,7 @@ struct genl_family_and_ops {
1781 struct genl_family *family; 1781 struct genl_family *family;
1782 const struct genl_ops *ops; 1782 const struct genl_ops *ops;
1783 int n_ops; 1783 int n_ops;
1784 struct genl_multicast_group *group; 1784 const struct genl_multicast_group *group;
1785}; 1785};
1786 1786
1787static const struct genl_family_and_ops dp_genl_families[] = { 1787static const struct genl_family_and_ops dp_genl_families[] = {
@@ -1817,17 +1817,14 @@ static int dp_register_genl(void)
1817 for (i = 0; i < ARRAY_SIZE(dp_genl_families); i++) { 1817 for (i = 0; i < ARRAY_SIZE(dp_genl_families); i++) {
1818 const struct genl_family_and_ops *f = &dp_genl_families[i]; 1818 const struct genl_family_and_ops *f = &dp_genl_families[i];
1819 1819
1820 err = genl_register_family_with_ops(f->family, f->ops, 1820 f->family->ops = f->ops;
1821 f->n_ops); 1821 f->family->n_ops = f->n_ops;
1822 f->family->mcgrps = f->group;
1823 f->family->n_mcgrps = f->group ? 1 : 0;
1824 err = genl_register_family(f->family);
1822 if (err) 1825 if (err)
1823 goto error; 1826 goto error;
1824 n_registered++; 1827 n_registered++;
1825
1826 if (f->group) {
1827 err = genl_register_mc_group(f->family, f->group);
1828 if (err)
1829 goto error;
1830 }
1831 } 1828 }
1832 1829
1833 return 0; 1830 return 0;
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h
index d3d14a58aa91..4067ea41be28 100644
--- a/net/openvswitch/datapath.h
+++ b/net/openvswitch/datapath.h
@@ -177,6 +177,7 @@ static inline struct vport *ovs_vport_ovsl(const struct datapath *dp, int port_n
177} 177}
178 178
179extern struct notifier_block ovs_dp_device_notifier; 179extern struct notifier_block ovs_dp_device_notifier;
180extern struct genl_family dp_vport_genl_family;
180extern struct genl_multicast_group ovs_dp_vport_multicast_group; 181extern struct genl_multicast_group ovs_dp_vport_multicast_group;
181 182
182void ovs_dp_process_received_packet(struct vport *, struct sk_buff *); 183void ovs_dp_process_received_packet(struct vport *, struct sk_buff *);
diff --git a/net/openvswitch/dp_notify.c b/net/openvswitch/dp_notify.c
index 5c2dab276109..2c631fe76be1 100644
--- a/net/openvswitch/dp_notify.c
+++ b/net/openvswitch/dp_notify.c
@@ -34,15 +34,14 @@ static void dp_detach_port_notify(struct vport *vport)
34 OVS_VPORT_CMD_DEL); 34 OVS_VPORT_CMD_DEL);
35 ovs_dp_detach_port(vport); 35 ovs_dp_detach_port(vport);
36 if (IS_ERR(notify)) { 36 if (IS_ERR(notify)) {
37 netlink_set_err(ovs_dp_get_net(dp)->genl_sock, 0, 37 genl_set_err(&dp_vport_genl_family, ovs_dp_get_net(dp), 0,
38 ovs_dp_vport_multicast_group.id, 38 0, PTR_ERR(notify));
39 PTR_ERR(notify));
40 return; 39 return;
41 } 40 }
42 41
43 genlmsg_multicast_netns(ovs_dp_get_net(dp), notify, 0, 42 genlmsg_multicast_netns(&dp_vport_genl_family,
44 ovs_dp_vport_multicast_group.id, 43 ovs_dp_get_net(dp), notify, 0,
45 GFP_KERNEL); 44 0, GFP_KERNEL);
46} 45}
47 46
48void ovs_dp_notify_wq(struct work_struct *work) 47void ovs_dp_notify_wq(struct work_struct *work)
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 8bcd4985d0fb..9f72a6376362 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -76,9 +76,11 @@ static struct genl_family tipc_genl_family = {
76 .maxattr = 0, 76 .maxattr = 0,
77}; 77};
78 78
79static struct genl_ops tipc_genl_ops = { 79static struct genl_ops tipc_genl_ops[] = {
80 .cmd = TIPC_GENL_CMD, 80 {
81 .doit = handle_cmd, 81 .cmd = TIPC_GENL_CMD,
82 .doit = handle_cmd,
83 },
82}; 84};
83 85
84static int tipc_genl_family_registered; 86static int tipc_genl_family_registered;
@@ -87,8 +89,7 @@ int tipc_netlink_start(void)
87{ 89{
88 int res; 90 int res;
89 91
90 res = genl_register_family_with_ops(&tipc_genl_family, 92 res = genl_register_family_with_ops(&tipc_genl_family, tipc_genl_ops);
91 &tipc_genl_ops, 1);
92 if (res) { 93 if (res) {
93 pr_err("Failed to register netlink interface\n"); 94 pr_err("Failed to register netlink interface\n");
94 return res; 95 return res;
diff --git a/net/wimax/op-msg.c b/net/wimax/op-msg.c
index ff19cbeaf607..c278b3356f75 100644
--- a/net/wimax/op-msg.c
+++ b/net/wimax/op-msg.c
@@ -279,7 +279,7 @@ int wimax_msg_send(struct wimax_dev *wimax_dev, struct sk_buff *skb)
279 279
280 d_printf(1, dev, "CTX: wimax msg, %zu bytes\n", size); 280 d_printf(1, dev, "CTX: wimax msg, %zu bytes\n", size);
281 d_dump(2, dev, msg, size); 281 d_dump(2, dev, msg, size);
282 genlmsg_multicast(skb, 0, wimax_gnl_mcg.id, GFP_KERNEL); 282 genlmsg_multicast(&wimax_gnl_family, skb, 0, 0, GFP_KERNEL);
283 d_printf(1, dev, "CTX: genl multicast done\n"); 283 d_printf(1, dev, "CTX: genl multicast done\n");
284 return 0; 284 return 0;
285} 285}
diff --git a/net/wimax/stack.c b/net/wimax/stack.c
index 47170c9495f1..ef2191b969a7 100644
--- a/net/wimax/stack.c
+++ b/net/wimax/stack.c
@@ -116,8 +116,9 @@ struct sk_buff *wimax_gnl_re_state_change_alloc(
116 dev_err(dev, "RE_STCH: can't create message\n"); 116 dev_err(dev, "RE_STCH: can't create message\n");
117 goto error_new; 117 goto error_new;
118 } 118 }
119 data = genlmsg_put(report_skb, 0, wimax_gnl_mcg.id, &wimax_gnl_family, 119 /* FIXME: sending a group ID as the seq is wrong */
120 0, WIMAX_GNL_RE_STATE_CHANGE); 120 data = genlmsg_put(report_skb, 0, wimax_gnl_family.mcgrp_offset,
121 &wimax_gnl_family, 0, WIMAX_GNL_RE_STATE_CHANGE);
121 if (data == NULL) { 122 if (data == NULL) {
122 dev_err(dev, "RE_STCH: can't put data into message\n"); 123 dev_err(dev, "RE_STCH: can't put data into message\n");
123 goto error_put; 124 goto error_put;
@@ -177,7 +178,7 @@ int wimax_gnl_re_state_change_send(
177 goto out; 178 goto out;
178 } 179 }
179 genlmsg_end(report_skb, header); 180 genlmsg_end(report_skb, header);
180 genlmsg_multicast(report_skb, 0, wimax_gnl_mcg.id, GFP_KERNEL); 181 genlmsg_multicast(&wimax_gnl_family, report_skb, 0, 0, GFP_KERNEL);
181out: 182out:
182 d_fnend(3, dev, "(wimax_dev %p report_skb %p) = %d\n", 183 d_fnend(3, dev, "(wimax_dev %p report_skb %p) = %d\n",
183 wimax_dev, report_skb, result); 184 wimax_dev, report_skb, result);
@@ -579,8 +580,8 @@ struct genl_family wimax_gnl_family = {
579 .maxattr = WIMAX_GNL_ATTR_MAX, 580 .maxattr = WIMAX_GNL_ATTR_MAX,
580}; 581};
581 582
582struct genl_multicast_group wimax_gnl_mcg = { 583static const struct genl_multicast_group wimax_gnl_mcgrps[] = {
583 .name = "msg", 584 { .name = "msg", },
584}; 585};
585 586
586 587
@@ -597,21 +598,18 @@ int __init wimax_subsys_init(void)
597 598
598 snprintf(wimax_gnl_family.name, sizeof(wimax_gnl_family.name), 599 snprintf(wimax_gnl_family.name, sizeof(wimax_gnl_family.name),
599 "WiMAX"); 600 "WiMAX");
600 result = genl_register_family_with_ops(&wimax_gnl_family, wimax_gnl_ops, 601 result = genl_register_family_with_ops_groups(&wimax_gnl_family,
601 ARRAY_SIZE(wimax_gnl_ops)); 602 wimax_gnl_ops,
603 wimax_gnl_mcgrps);
602 if (unlikely(result < 0)) { 604 if (unlikely(result < 0)) {
603 printk(KERN_ERR "cannot register generic netlink family: %d\n", 605 printk(KERN_ERR "cannot register generic netlink family: %d\n",
604 result); 606 result);
605 goto error_register_family; 607 goto error_register_family;
606 } 608 }
607 609
608 result = genl_register_mc_group(&wimax_gnl_family, &wimax_gnl_mcg);
609 if (result < 0)
610 goto error_mc_group;
611 d_fnend(4, NULL, "() = 0\n"); 610 d_fnend(4, NULL, "() = 0\n");
612 return 0; 611 return 0;
613 612
614error_mc_group:
615 genl_unregister_family(&wimax_gnl_family); 613 genl_unregister_family(&wimax_gnl_family);
616error_register_family: 614error_register_family:
617 d_fnend(4, NULL, "() = %d\n", result); 615 d_fnend(4, NULL, "() = %d\n", result);
diff --git a/net/wimax/wimax-internal.h b/net/wimax/wimax-internal.h
index 8567d3079a83..b445b82020a8 100644
--- a/net/wimax/wimax-internal.h
+++ b/net/wimax/wimax-internal.h
@@ -86,7 +86,6 @@ void wimax_rfkill_rm(struct wimax_dev *);
86 86
87/* generic netlink */ 87/* generic netlink */
88extern struct genl_family wimax_gnl_family; 88extern struct genl_family wimax_gnl_family;
89extern struct genl_multicast_group wimax_gnl_mcg;
90 89
91/* ops */ 90/* ops */
92int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info); 91int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 58c43c8e149f..a1eb21073176 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -47,6 +47,25 @@ static struct genl_family nl80211_fam = {
47 .post_doit = nl80211_post_doit, 47 .post_doit = nl80211_post_doit,
48}; 48};
49 49
50/* multicast groups */
51enum nl80211_multicast_groups {
52 NL80211_MCGRP_CONFIG,
53 NL80211_MCGRP_SCAN,
54 NL80211_MCGRP_REGULATORY,
55 NL80211_MCGRP_MLME,
56 NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
57};
58
59static const struct genl_multicast_group nl80211_mcgrps[] = {
60 [NL80211_MCGRP_CONFIG] = { .name = "config", },
61 [NL80211_MCGRP_SCAN] = { .name = "scan", },
62 [NL80211_MCGRP_REGULATORY] = { .name = "regulatory", },
63 [NL80211_MCGRP_MLME] = { .name = "mlme", },
64#ifdef CONFIG_NL80211_TESTMODE
65 [NL80211_MCGRP_TESTMODE] = { .name = "testmode", }
66#endif
67};
68
50/* returns ERR_PTR values */ 69/* returns ERR_PTR values */
51static struct wireless_dev * 70static struct wireless_dev *
52__cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs) 71__cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
@@ -6656,10 +6675,6 @@ static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
6656 6675
6657 6676
6658#ifdef CONFIG_NL80211_TESTMODE 6677#ifdef CONFIG_NL80211_TESTMODE
6659static struct genl_multicast_group nl80211_testmode_mcgrp = {
6660 .name = "testmode",
6661};
6662
6663static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) 6678static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
6664{ 6679{
6665 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6680 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6868,8 +6883,8 @@ void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
6868 6883
6869 nla_nest_end(skb, data); 6884 nla_nest_end(skb, data);
6870 genlmsg_end(skb, hdr); 6885 genlmsg_end(skb, hdr);
6871 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), skb, 0, 6886 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), skb, 0,
6872 nl80211_testmode_mcgrp.id, gfp); 6887 NL80211_MCGRP_TESTMODE, gfp);
6873} 6888}
6874EXPORT_SYMBOL(cfg80211_testmode_event); 6889EXPORT_SYMBOL(cfg80211_testmode_event);
6875#endif 6890#endif
@@ -9566,21 +9581,6 @@ static const struct genl_ops nl80211_ops[] = {
9566 }, 9581 },
9567}; 9582};
9568 9583
9569static struct genl_multicast_group nl80211_mlme_mcgrp = {
9570 .name = "mlme",
9571};
9572
9573/* multicast groups */
9574static struct genl_multicast_group nl80211_config_mcgrp = {
9575 .name = "config",
9576};
9577static struct genl_multicast_group nl80211_scan_mcgrp = {
9578 .name = "scan",
9579};
9580static struct genl_multicast_group nl80211_regulatory_mcgrp = {
9581 .name = "regulatory",
9582};
9583
9584/* notification functions */ 9584/* notification functions */
9585 9585
9586void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) 9586void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
@@ -9597,8 +9597,8 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
9597 return; 9597 return;
9598 } 9598 }
9599 9599
9600 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 9600 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
9601 nl80211_config_mcgrp.id, GFP_KERNEL); 9601 NL80211_MCGRP_CONFIG, GFP_KERNEL);
9602} 9602}
9603 9603
9604static int nl80211_add_scan_req(struct sk_buff *msg, 9604static int nl80211_add_scan_req(struct sk_buff *msg,
@@ -9707,8 +9707,8 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
9707 return; 9707 return;
9708 } 9708 }
9709 9709
9710 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 9710 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
9711 nl80211_scan_mcgrp.id, GFP_KERNEL); 9711 NL80211_MCGRP_SCAN, GFP_KERNEL);
9712} 9712}
9713 9713
9714void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, 9714void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
@@ -9726,8 +9726,8 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
9726 return; 9726 return;
9727 } 9727 }
9728 9728
9729 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 9729 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
9730 nl80211_scan_mcgrp.id, GFP_KERNEL); 9730 NL80211_MCGRP_SCAN, GFP_KERNEL);
9731} 9731}
9732 9732
9733void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, 9733void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
@@ -9745,8 +9745,8 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
9745 return; 9745 return;
9746 } 9746 }
9747 9747
9748 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 9748 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
9749 nl80211_scan_mcgrp.id, GFP_KERNEL); 9749 NL80211_MCGRP_SCAN, GFP_KERNEL);
9750} 9750}
9751 9751
9752void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, 9752void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
@@ -9764,8 +9764,8 @@ void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
9764 return; 9764 return;
9765 } 9765 }
9766 9766
9767 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 9767 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
9768 nl80211_scan_mcgrp.id, GFP_KERNEL); 9768 NL80211_MCGRP_SCAN, GFP_KERNEL);
9769} 9769}
9770 9770
9771void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, 9771void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
@@ -9782,8 +9782,8 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
9782 return; 9782 return;
9783 } 9783 }
9784 9784
9785 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 9785 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
9786 nl80211_scan_mcgrp.id, GFP_KERNEL); 9786 NL80211_MCGRP_SCAN, GFP_KERNEL);
9787} 9787}
9788 9788
9789/* 9789/*
@@ -9837,8 +9837,8 @@ void nl80211_send_reg_change_event(struct regulatory_request *request)
9837 genlmsg_end(msg, hdr); 9837 genlmsg_end(msg, hdr);
9838 9838
9839 rcu_read_lock(); 9839 rcu_read_lock();
9840 genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, 9840 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
9841 GFP_ATOMIC); 9841 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
9842 rcu_read_unlock(); 9842 rcu_read_unlock();
9843 9843
9844 return; 9844 return;
@@ -9873,8 +9873,8 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
9873 9873
9874 genlmsg_end(msg, hdr); 9874 genlmsg_end(msg, hdr);
9875 9875
9876 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 9876 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
9877 nl80211_mlme_mcgrp.id, gfp); 9877 NL80211_MCGRP_MLME, gfp);
9878 return; 9878 return;
9879 9879
9880 nla_put_failure: 9880 nla_put_failure:
@@ -9961,8 +9961,8 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
9961 9961
9962 genlmsg_end(msg, hdr); 9962 genlmsg_end(msg, hdr);
9963 9963
9964 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 9964 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
9965 nl80211_mlme_mcgrp.id, gfp); 9965 NL80211_MCGRP_MLME, gfp);
9966 return; 9966 return;
9967 9967
9968 nla_put_failure: 9968 nla_put_failure:
@@ -10017,8 +10017,8 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
10017 10017
10018 genlmsg_end(msg, hdr); 10018 genlmsg_end(msg, hdr);
10019 10019
10020 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10020 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10021 nl80211_mlme_mcgrp.id, gfp); 10021 NL80211_MCGRP_MLME, gfp);
10022 return; 10022 return;
10023 10023
10024 nla_put_failure: 10024 nla_put_failure:
@@ -10056,8 +10056,8 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
10056 10056
10057 genlmsg_end(msg, hdr); 10057 genlmsg_end(msg, hdr);
10058 10058
10059 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10059 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10060 nl80211_mlme_mcgrp.id, gfp); 10060 NL80211_MCGRP_MLME, gfp);
10061 return; 10061 return;
10062 10062
10063 nla_put_failure: 10063 nla_put_failure:
@@ -10094,8 +10094,8 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
10094 10094
10095 genlmsg_end(msg, hdr); 10095 genlmsg_end(msg, hdr);
10096 10096
10097 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10097 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10098 nl80211_mlme_mcgrp.id, GFP_KERNEL); 10098 NL80211_MCGRP_MLME, GFP_KERNEL);
10099 return; 10099 return;
10100 10100
10101 nla_put_failure: 10101 nla_put_failure:
@@ -10128,8 +10128,8 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
10128 10128
10129 genlmsg_end(msg, hdr); 10129 genlmsg_end(msg, hdr);
10130 10130
10131 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10131 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10132 nl80211_mlme_mcgrp.id, gfp); 10132 NL80211_MCGRP_MLME, gfp);
10133 return; 10133 return;
10134 10134
10135 nla_put_failure: 10135 nla_put_failure:
@@ -10169,8 +10169,8 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
10169 10169
10170 genlmsg_end(msg, hdr); 10170 genlmsg_end(msg, hdr);
10171 10171
10172 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10172 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10173 nl80211_mlme_mcgrp.id, gfp); 10173 NL80211_MCGRP_MLME, gfp);
10174 return; 10174 return;
10175 10175
10176 nla_put_failure: 10176 nla_put_failure:
@@ -10208,8 +10208,8 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
10208 10208
10209 genlmsg_end(msg, hdr); 10209 genlmsg_end(msg, hdr);
10210 10210
10211 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10211 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10212 nl80211_mlme_mcgrp.id, gfp); 10212 NL80211_MCGRP_MLME, gfp);
10213 return; 10213 return;
10214 10214
10215 nla_put_failure: 10215 nla_put_failure:
@@ -10261,8 +10261,8 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
10261 genlmsg_end(msg, hdr); 10261 genlmsg_end(msg, hdr);
10262 10262
10263 rcu_read_lock(); 10263 rcu_read_lock();
10264 genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, 10264 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
10265 GFP_ATOMIC); 10265 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
10266 rcu_read_unlock(); 10266 rcu_read_unlock();
10267 10267
10268 return; 10268 return;
@@ -10307,8 +10307,8 @@ static void nl80211_send_remain_on_chan_event(
10307 10307
10308 genlmsg_end(msg, hdr); 10308 genlmsg_end(msg, hdr);
10309 10309
10310 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10310 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10311 nl80211_mlme_mcgrp.id, gfp); 10311 NL80211_MCGRP_MLME, gfp);
10312 return; 10312 return;
10313 10313
10314 nla_put_failure: 10314 nla_put_failure:
@@ -10362,8 +10362,8 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
10362 return; 10362 return;
10363 } 10363 }
10364 10364
10365 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10365 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10366 nl80211_mlme_mcgrp.id, gfp); 10366 NL80211_MCGRP_MLME, gfp);
10367} 10367}
10368EXPORT_SYMBOL(cfg80211_new_sta); 10368EXPORT_SYMBOL(cfg80211_new_sta);
10369 10369
@@ -10392,8 +10392,8 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp)
10392 10392
10393 genlmsg_end(msg, hdr); 10393 genlmsg_end(msg, hdr);
10394 10394
10395 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10395 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10396 nl80211_mlme_mcgrp.id, gfp); 10396 NL80211_MCGRP_MLME, gfp);
10397 return; 10397 return;
10398 10398
10399 nla_put_failure: 10399 nla_put_failure:
@@ -10428,8 +10428,8 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
10428 10428
10429 genlmsg_end(msg, hdr); 10429 genlmsg_end(msg, hdr);
10430 10430
10431 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10431 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10432 nl80211_mlme_mcgrp.id, gfp); 10432 NL80211_MCGRP_MLME, gfp);
10433 return; 10433 return;
10434 10434
10435 nla_put_failure: 10435 nla_put_failure:
@@ -10590,8 +10590,8 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
10590 10590
10591 genlmsg_end(msg, hdr); 10591 genlmsg_end(msg, hdr);
10592 10592
10593 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10593 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10594 nl80211_mlme_mcgrp.id, gfp); 10594 NL80211_MCGRP_MLME, gfp);
10595 return; 10595 return;
10596 10596
10597 nla_put_failure: 10597 nla_put_failure:
@@ -10639,8 +10639,8 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
10639 10639
10640 genlmsg_end(msg, hdr); 10640 genlmsg_end(msg, hdr);
10641 10641
10642 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10642 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10643 nl80211_mlme_mcgrp.id, gfp); 10643 NL80211_MCGRP_MLME, gfp);
10644 return; 10644 return;
10645 10645
10646 nla_put_failure: 10646 nla_put_failure:
@@ -10684,8 +10684,8 @@ static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
10684 10684
10685 genlmsg_end(msg, hdr); 10685 genlmsg_end(msg, hdr);
10686 10686
10687 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10687 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10688 nl80211_mlme_mcgrp.id, gfp); 10688 NL80211_MCGRP_MLME, gfp);
10689 return; 10689 return;
10690 10690
10691 nla_put_failure: 10691 nla_put_failure:
@@ -10742,8 +10742,8 @@ nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
10742 10742
10743 genlmsg_end(msg, hdr); 10743 genlmsg_end(msg, hdr);
10744 10744
10745 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10745 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10746 nl80211_mlme_mcgrp.id, gfp); 10746 NL80211_MCGRP_MLME, gfp);
10747 return; 10747 return;
10748 10748
10749 nla_put_failure: 10749 nla_put_failure:
@@ -10789,8 +10789,8 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
10789 10789
10790 genlmsg_end(msg, hdr); 10790 genlmsg_end(msg, hdr);
10791 10791
10792 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10792 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10793 nl80211_mlme_mcgrp.id, gfp); 10793 NL80211_MCGRP_MLME, gfp);
10794 return; 10794 return;
10795 10795
10796 nla_put_failure: 10796 nla_put_failure:
@@ -10866,8 +10866,8 @@ void cfg80211_cqm_txe_notify(struct net_device *dev,
10866 10866
10867 genlmsg_end(msg, hdr); 10867 genlmsg_end(msg, hdr);
10868 10868
10869 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10869 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10870 nl80211_mlme_mcgrp.id, gfp); 10870 NL80211_MCGRP_MLME, gfp);
10871 return; 10871 return;
10872 10872
10873 nla_put_failure: 10873 nla_put_failure:
@@ -10915,8 +10915,8 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
10915 10915
10916 genlmsg_end(msg, hdr); 10916 genlmsg_end(msg, hdr);
10917 10917
10918 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10918 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10919 nl80211_mlme_mcgrp.id, gfp); 10919 NL80211_MCGRP_MLME, gfp);
10920 return; 10920 return;
10921 10921
10922 nla_put_failure: 10922 nla_put_failure:
@@ -10962,8 +10962,8 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev,
10962 10962
10963 genlmsg_end(msg, hdr); 10963 genlmsg_end(msg, hdr);
10964 10964
10965 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10965 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
10966 nl80211_mlme_mcgrp.id, gfp); 10966 NL80211_MCGRP_MLME, gfp);
10967 return; 10967 return;
10968 10968
10969 nla_put_failure: 10969 nla_put_failure:
@@ -11002,8 +11002,8 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
11002 11002
11003 genlmsg_end(msg, hdr); 11003 genlmsg_end(msg, hdr);
11004 11004
11005 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 11005 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
11006 nl80211_mlme_mcgrp.id, gfp); 11006 NL80211_MCGRP_MLME, gfp);
11007 return; 11007 return;
11008 11008
11009 nla_put_failure: 11009 nla_put_failure:
@@ -11154,8 +11154,8 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
11154 11154
11155 genlmsg_end(msg, hdr); 11155 genlmsg_end(msg, hdr);
11156 11156
11157 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 11157 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
11158 nl80211_mlme_mcgrp.id, gfp); 11158 NL80211_MCGRP_MLME, gfp);
11159 return; 11159 return;
11160 11160
11161 free_msg: 11161 free_msg:
@@ -11196,8 +11196,8 @@ void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
11196 11196
11197 genlmsg_end(msg, hdr); 11197 genlmsg_end(msg, hdr);
11198 11198
11199 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 11199 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
11200 nl80211_mlme_mcgrp.id, gfp); 11200 NL80211_MCGRP_MLME, gfp);
11201 return; 11201 return;
11202 11202
11203 nla_put_failure: 11203 nla_put_failure:
@@ -11279,8 +11279,8 @@ void cfg80211_ft_event(struct net_device *netdev,
11279 11279
11280 genlmsg_end(msg, hdr); 11280 genlmsg_end(msg, hdr);
11281 11281
11282 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 11282 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
11283 nl80211_mlme_mcgrp.id, GFP_KERNEL); 11283 NL80211_MCGRP_MLME, GFP_KERNEL);
11284} 11284}
11285EXPORT_SYMBOL(cfg80211_ft_event); 11285EXPORT_SYMBOL(cfg80211_ft_event);
11286 11286
@@ -11329,33 +11329,11 @@ int nl80211_init(void)
11329{ 11329{
11330 int err; 11330 int err;
11331 11331
11332 err = genl_register_family_with_ops(&nl80211_fam, 11332 err = genl_register_family_with_ops_groups(&nl80211_fam, nl80211_ops,
11333 nl80211_ops, ARRAY_SIZE(nl80211_ops)); 11333 nl80211_mcgrps);
11334 if (err) 11334 if (err)
11335 return err; 11335 return err;
11336 11336
11337 err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
11338 if (err)
11339 goto err_out;
11340
11341 err = genl_register_mc_group(&nl80211_fam, &nl80211_scan_mcgrp);
11342 if (err)
11343 goto err_out;
11344
11345 err = genl_register_mc_group(&nl80211_fam, &nl80211_regulatory_mcgrp);
11346 if (err)
11347 goto err_out;
11348
11349 err = genl_register_mc_group(&nl80211_fam, &nl80211_mlme_mcgrp);
11350 if (err)
11351 goto err_out;
11352
11353#ifdef CONFIG_NL80211_TESTMODE
11354 err = genl_register_mc_group(&nl80211_fam, &nl80211_testmode_mcgrp);
11355 if (err)
11356 goto err_out;
11357#endif
11358
11359 err = netlink_register_notifier(&nl80211_netlink_notifier); 11337 err = netlink_register_notifier(&nl80211_netlink_notifier);
11360 if (err) 11338 if (err)
11361 goto err_out; 11339 goto err_out;