aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-11-19 09:19:39 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-19 16:39:06 -0500
commit2a94fe48f32ccf7321450a2cc07f2b724a444e5b (patch)
treee5a066d8f83d8822d448421019a4503f361295f9
parent68eb55031da7c967d954e5f9415cd05f4abdb692 (diff)
genetlink: make multicast groups const, prevent abuse
Register generic netlink multicast groups as an array with the family and give them contiguous group IDs. Then instead of passing the global group ID to the various functions that send messages, pass the ID relative to the family - for most families that's just 0 because the only have one group. This avoids the list_head and ID in each group, adding a new field for the mcast group ID offset to the family. At the same time, this allows us to prevent abusing groups again like the quota and dropmon code did, since we can now check that a family only uses a group it owns. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/acpi/event.c26
-rw-r--r--drivers/net/team/team.c25
-rw-r--r--drivers/thermal/thermal_core.c24
-rw-r--r--fs/quota/netlink.c15
-rw-r--r--include/linux/genl_magic_func.h49
-rw-r--r--include/net/genetlink.h48
-rw-r--r--net/core/drop_monitor.c18
-rw-r--r--net/hsr/hsr_netlink.c19
-rw-r--r--net/ieee802154/ieee802154.h6
-rw-r--r--net/ieee802154/netlink.c26
-rw-r--r--net/ieee802154/nl-mac.c22
-rw-r--r--net/netlink/genetlink.c278
-rw-r--r--net/nfc/netlink.c51
-rw-r--r--net/openvswitch/datapath.c43
-rw-r--r--net/openvswitch/dp_notify.c6
-rw-r--r--net/wimax/op-msg.c3
-rw-r--r--net/wimax/stack.c21
-rw-r--r--net/wimax/wimax-internal.h1
-rw-r--r--net/wireless/nl80211.c129
19 files changed, 377 insertions, 433 deletions
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index 68a8755202ec..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,8 +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(&acpi_event_genl_family, 151 genlmsg_multicast(&acpi_event_genl_family, skb, 0, 0, GFP_ATOMIC);
150 skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC);
151 return 0; 152 return 0;
152} 153}
153 154
@@ -155,18 +156,7 @@ EXPORT_SYMBOL(acpi_bus_generate_netlink_event);
155 156
156static int acpi_event_genetlink_init(void) 157static int acpi_event_genetlink_init(void)
157{ 158{
158 int result; 159 return genl_register_family(&acpi_event_genl_family);
159
160 result = genl_register_family(&acpi_event_genl_family);
161 if (result)
162 return result;
163
164 result = genl_register_mc_group(&acpi_event_genl_family,
165 &acpi_event_mcgrp);
166 if (result)
167 genl_unregister_family(&acpi_event_genl_family);
168
169 return result;
170} 160}
171 161
172#else 162#else
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 2721e29935a6..0715de50b3dc 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2670,16 +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(&team_nl_family, dev_net(team->dev), 2680 return genlmsg_multicast_netns(&team_nl_family, dev_net(team->dev),
2681 skb, 0, team_change_event_mcgrp.id, 2681 skb, 0, 0, GFP_KERNEL);
2682 GFP_KERNEL);
2683} 2682}
2684 2683
2685static int team_nl_send_event_options_get(struct team *team, 2684static int team_nl_send_event_options_get(struct team *team,
@@ -2698,22 +2697,8 @@ static int team_nl_send_event_port_get(struct team *team,
2698 2697
2699static int team_nl_init(void) 2698static int team_nl_init(void)
2700{ 2699{
2701 int err; 2700 return genl_register_family_with_ops_groups(&team_nl_family, team_nl_ops,
2702 2701 team_nl_mcgrps);
2703 err = genl_register_family_with_ops(&team_nl_family, 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/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 2570a944fffc..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,
@@ -1676,7 +1678,7 @@ int thermal_generate_netlink_event(struct thermal_zone_device *tz,
1676 } 1678 }
1677 1679
1678 result = genlmsg_multicast(&thermal_event_genl_family, skb, 0, 1680 result = genlmsg_multicast(&thermal_event_genl_family, skb, 0,
1679 thermal_event_mcgrp.id, GFP_ATOMIC); 1681 0, GFP_ATOMIC);
1680 if (result) 1682 if (result)
1681 dev_err(&tz->device, "Failed to send netlink event:%d", result); 1683 dev_err(&tz->device, "Failed to send netlink event:%d", result);
1682 1684
@@ -1686,17 +1688,7 @@ EXPORT_SYMBOL_GPL(thermal_generate_netlink_event);
1686 1688
1687static int genetlink_init(void) 1689static int genetlink_init(void)
1688{ 1690{
1689 int result; 1691 return genl_register_family(&thermal_event_genl_family);
1690
1691 result = genl_register_family(&thermal_event_genl_family);
1692 if (result)
1693 return result;
1694
1695 result = genl_register_mc_group(&thermal_event_genl_family,
1696 &thermal_event_mcgrp);
1697 if (result)
1698 genl_unregister_family(&thermal_event_genl_family);
1699 return result;
1700} 1692}
1701 1693
1702static void genetlink_exit(void) 1694static void genetlink_exit(void)
diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c
index a5b5eddf6603..72d29177998e 100644
--- a/fs/quota/netlink.c
+++ b/fs/quota/netlink.c
@@ -9,6 +9,10 @@
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 /* 18 /*
@@ -22,10 +26,8 @@ static struct genl_family quota_genl_family = {
22 .name = "VFS_DQUOT", 26 .name = "VFS_DQUOT",
23 .version = 1, 27 .version = 1,
24 .maxattr = QUOTA_NL_A_MAX, 28 .maxattr = QUOTA_NL_A_MAX,
25}; 29 .mcgrps = quota_mcgrps,
26 30 .n_mcgrps = ARRAY_SIZE(quota_mcgrps),
27static struct genl_multicast_group quota_mcgrp = {
28 .name = "events",
29}; 31};
30 32
31/** 33/**
@@ -88,7 +90,7 @@ void quota_send_warning(struct kqid qid, dev_t dev,
88 goto attr_err_out; 90 goto attr_err_out;
89 genlmsg_end(skb, msg_head); 91 genlmsg_end(skb, msg_head);
90 92
91 genlmsg_multicast(&quota_genl_family, skb, 0, quota_mcgrp.id, GFP_NOFS); 93 genlmsg_multicast(&quota_genl_family, skb, 0, 0, GFP_NOFS);
92 return; 94 return;
93attr_err_out: 95attr_err_out:
94 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");
@@ -102,9 +104,6 @@ static int __init quota_init(void)
102 if (genl_register_family(&quota_genl_family) != 0) 104 if (genl_register_family(&quota_genl_family) != 0)
103 printk(KERN_ERR 105 printk(KERN_ERR
104 "VFS: Failed to create quota netlink interface.\n"); 106 "VFS: Failed to create quota netlink interface.\n");
105 if (genl_register_mc_group(&quota_genl_family, &quota_mcgrp))
106 printk(KERN_ERR
107 "VFS: Failed to register quota mcast group.\n");
108 return 0; 107 return 0;
109}; 108};
110 109
diff --git a/include/linux/genl_magic_func.h b/include/linux/genl_magic_func.h
index 5b9b8ae6748b..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) \
288 return -EINVAL; \
289 return genlmsg_multicast(&ZZZ_genl_family, skb, 0, \ 296 return genlmsg_multicast(&ZZZ_genl_family, skb, 0, \
290 group_id, flags); \ 297 group_id, flags); \
291} 298}
292 299
293#include GENL_MAGIC_INCLUDE_FILE 300#include GENL_MAGIC_INCLUDE_FILE
294 301
295int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void)
296{
297 int err = genl_register_family_with_ops(&ZZZ_genl_family, 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 60aef0df386b..ace4abf118d7 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -10,14 +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 */ 13 */
17struct genl_multicast_group { 14struct genl_multicast_group {
18 struct list_head list; /* private */
19 char name[GENL_NAMSIZ]; 15 char name[GENL_NAMSIZ];
20 u32 id;
21}; 16};
22 17
23struct genl_ops; 18struct genl_ops;
@@ -38,7 +33,9 @@ struct genl_info;
38 * undo operations done by pre_doit, for example release locks 33 * undo operations done by pre_doit, for example release locks
39 * @attrbuf: buffer to store parsed attributes 34 * @attrbuf: buffer to store parsed attributes
40 * @family_list: family list 35 * @family_list: family list
41 * @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
42 * @ops: the operations supported by this family (private) 39 * @ops: the operations supported by this family (private)
43 * @n_ops: number of operations supported by this family (private) 40 * @n_ops: number of operations supported by this family (private)
44 */ 41 */
@@ -58,9 +55,11 @@ struct genl_family {
58 struct genl_info *info); 55 struct genl_info *info);
59 struct nlattr ** attrbuf; /* private */ 56 struct nlattr ** attrbuf; /* private */
60 const struct genl_ops * ops; /* private */ 57 const struct genl_ops * ops; /* private */
58 const struct genl_multicast_group *mcgrps; /* private */
61 unsigned int n_ops; /* private */ 59 unsigned int n_ops; /* private */
60 unsigned int n_mcgrps; /* private */
61 unsigned int mcgrp_offset; /* private */
62 struct list_head family_list; /* private */ 62 struct list_head family_list; /* private */
63 struct list_head mcast_groups; /* private */
64 struct module *module; 63 struct module *module;
65}; 64};
66 65
@@ -150,22 +149,30 @@ static inline int genl_register_family(struct genl_family *family)
150 * 149 *
151 * Return 0 on success or a negative error code. 150 * Return 0 on success or a negative error code.
152 */ 151 */
153static inline int _genl_register_family_with_ops(struct genl_family *family, 152static inline int
154 const struct genl_ops *ops, 153_genl_register_family_with_ops_grps(struct genl_family *family,
155 size_t n_ops) 154 const struct genl_ops *ops, size_t n_ops,
155 const struct genl_multicast_group *mcgrps,
156 size_t n_mcgrps)
156{ 157{
157 family->module = THIS_MODULE; 158 family->module = THIS_MODULE;
158 family->ops = ops; 159 family->ops = ops;
159 family->n_ops = n_ops; 160 family->n_ops = n_ops;
161 family->mcgrps = mcgrps;
162 family->n_mcgrps = n_mcgrps;
160 return __genl_register_family(family); 163 return __genl_register_family(family);
161} 164}
162 165
163#define genl_register_family_with_ops(family, ops) \ 166#define genl_register_family_with_ops(family, ops) \
164 _genl_register_family_with_ops((family), (ops), ARRAY_SIZE(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))
165 174
166int genl_unregister_family(struct genl_family *family); 175int genl_unregister_family(struct genl_family *family);
167int genl_register_mc_group(struct genl_family *family,
168 struct genl_multicast_group *grp);
169void genl_notify(struct genl_family *family, 176void genl_notify(struct genl_family *family,
170 struct sk_buff *skb, struct net *net, u32 portid, 177 struct sk_buff *skb, struct net *net, u32 portid,
171 u32 group, struct nlmsghdr *nlh, gfp_t flags); 178 u32 group, struct nlmsghdr *nlh, gfp_t flags);
@@ -251,13 +258,16 @@ static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
251 * @net: the net namespace 258 * @net: the net namespace
252 * @skb: netlink message as socket buffer 259 * @skb: netlink message as socket buffer
253 * @portid: own netlink portid to avoid sending to yourself 260 * @portid: own netlink portid to avoid sending to yourself
254 * @group: multicast group id 261 * @group: offset of multicast group in groups array
255 * @flags: allocation flags 262 * @flags: allocation flags
256 */ 263 */
257static inline int genlmsg_multicast_netns(struct genl_family *family, 264static inline int genlmsg_multicast_netns(struct genl_family *family,
258 struct net *net, struct sk_buff *skb, 265 struct net *net, struct sk_buff *skb,
259 u32 portid, unsigned int group, gfp_t flags) 266 u32 portid, unsigned int group, gfp_t flags)
260{ 267{
268 if (group >= family->n_mcgrps)
269 return -EINVAL;
270 group = family->mcgrp_offset + group;
261 return nlmsg_multicast(net->genl_sock, skb, portid, group, flags); 271 return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
262} 272}
263 273
@@ -266,13 +276,16 @@ static inline int genlmsg_multicast_netns(struct genl_family *family,
266 * @family: the generic netlink family 276 * @family: the generic netlink family
267 * @skb: netlink message as socket buffer 277 * @skb: netlink message as socket buffer
268 * @portid: own netlink portid to avoid sending to yourself 278 * @portid: own netlink portid to avoid sending to yourself
269 * @group: multicast group id 279 * @group: offset of multicast group in groups array
270 * @flags: allocation flags 280 * @flags: allocation flags
271 */ 281 */
272static inline int genlmsg_multicast(struct genl_family *family, 282static inline int genlmsg_multicast(struct genl_family *family,
273 struct sk_buff *skb, u32 portid, 283 struct sk_buff *skb, u32 portid,
274 unsigned int group, gfp_t flags) 284 unsigned int group, gfp_t flags)
275{ 285{
286 if (group >= family->n_mcgrps)
287 return -EINVAL;
288 group = family->mcgrp_offset + group;
276 return genlmsg_multicast_netns(family, &init_net, skb, 289 return genlmsg_multicast_netns(family, &init_net, skb,
277 portid, group, flags); 290 portid, group, flags);
278} 291}
@@ -282,7 +295,7 @@ static inline int genlmsg_multicast(struct genl_family *family,
282 * @family: the generic netlink family 295 * @family: the generic netlink family
283 * @skb: netlink message as socket buffer 296 * @skb: netlink message as socket buffer
284 * @portid: own netlink portid to avoid sending to yourself 297 * @portid: own netlink portid to avoid sending to yourself
285 * @group: multicast group id 298 * @group: offset of multicast group in groups array
286 * @flags: allocation flags 299 * @flags: allocation flags
287 * 300 *
288 * This function must hold the RTNL or rcu_read_lock(). 301 * This function must hold the RTNL or rcu_read_lock().
@@ -365,6 +378,7 @@ static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
365 * @net: the network namespace to report the error to 378 * @net: the network namespace to report the error to
366 * @portid: the PORTID of a process that we want to skip (if any) 379 * @portid: the PORTID of a process that we want to skip (if any)
367 * @group: the broadcast group that will notice the error 380 * @group: the broadcast group that will notice the error
381 * (this is the offset of the multicast group in the groups array)
368 * @code: error code, must be negative (as usual in kernelspace) 382 * @code: error code, must be negative (as usual in kernelspace)
369 * 383 *
370 * This function returns the number of broadcast listeners that have set the 384 * This function returns the number of broadcast listeners that have set the
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 1eab1dc48821..95897183226e 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -106,8 +106,8 @@ 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 dm_mcgrp = { 109static struct genl_multicast_group dropmon_mcgrps[] = {
110 .name = "events", 110 { .name = "events", },
111}; 111};
112 112
113static void send_dm_alert(struct work_struct *work) 113static void send_dm_alert(struct work_struct *work)
@@ -121,7 +121,7 @@ static void send_dm_alert(struct work_struct *work)
121 121
122 if (skb) 122 if (skb)
123 genlmsg_multicast(&net_drop_monitor_family, skb, 0, 123 genlmsg_multicast(&net_drop_monitor_family, skb, 0,
124 dm_mcgrp.id, GFP_KERNEL); 124 0, GFP_KERNEL);
125} 125}
126 126
127/* 127/*
@@ -369,19 +369,13 @@ static int __init init_net_drop_monitor(void)
369 return -ENOSPC; 369 return -ENOSPC;
370 } 370 }
371 371
372 rc = genl_register_family_with_ops(&net_drop_monitor_family, 372 rc = genl_register_family_with_ops_groups(&net_drop_monitor_family,
373 dropmon_ops); 373 dropmon_ops, dropmon_mcgrps);
374 if (rc) { 374 if (rc) {
375 pr_err("Could not create drop monitor netlink family\n"); 375 pr_err("Could not create drop monitor netlink family\n");
376 return rc; 376 return rc;
377 } 377 }
378 378 WARN_ON(net_drop_monitor_family.mcgrp_offset != NET_DM_GRP_ALERT);
379 rc = genl_register_mc_group(&net_drop_monitor_family, &dm_mcgrp);
380 if (rc) {
381 pr_err("Failed to register drop monitor mcast group\n");
382 goto out_unreg;
383 }
384 WARN_ON(dm_mcgrp.id != NET_DM_GRP_ALERT);
385 379
386 rc = register_netdevice_notifier(&dropmon_net_notifier); 380 rc = register_netdevice_notifier(&dropmon_net_notifier);
387 if (rc < 0) { 381 if (rc < 0) {
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 0009416c08c2..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,8 +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(&hsr_genl_family, skb, 0, 132 genlmsg_multicast(&hsr_genl_family, skb, 0, 0, GFP_ATOMIC);
133 hsr_network_genl_mcgrp.id, GFP_ATOMIC);
134 133
135 return; 134 return;
136 135
@@ -164,8 +163,7 @@ void hsr_nl_nodedown(struct hsr_priv *hsr_priv, unsigned char addr[ETH_ALEN])
164 goto nla_put_failure; 163 goto nla_put_failure;
165 164
166 genlmsg_end(skb, msg_head); 165 genlmsg_end(skb, msg_head);
167 genlmsg_multicast(&hsr_genl_family, skb, 0, 166 genlmsg_multicast(&hsr_genl_family, skb, 0, 0, GFP_ATOMIC);
168 hsr_network_genl_mcgrp.id, GFP_ATOMIC);
169 167
170 return; 168 return;
171 169
@@ -416,18 +414,13 @@ int __init hsr_netlink_init(void)
416 if (rc) 414 if (rc)
417 goto fail_rtnl_link_register; 415 goto fail_rtnl_link_register;
418 416
419 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 hsr_mcgrps);
420 if (rc) 419 if (rc)
421 goto fail_genl_register_family; 420 goto fail_genl_register_family;
422 421
423 rc = genl_register_mc_group(&hsr_genl_family, &hsr_network_genl_mcgrp);
424 if (rc)
425 goto fail_genl_register_mc_group;
426
427 return 0; 422 return 0;
428 423
429fail_genl_register_mc_group:
430 genl_unregister_family(&hsr_genl_family);
431fail_genl_register_family: 424fail_genl_register_family:
432 rtnl_link_unregister(&hsr_link_ops); 425 rtnl_link_unregister(&hsr_link_ops);
433fail_rtnl_link_register: 426fail_rtnl_link_register:
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 5172f467a383..43f1b2bf469f 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -125,25 +125,17 @@ static const struct genl_ops ieee8021154_ops[] = {
125 ieee802154_dump_iface), 125 ieee802154_dump_iface),
126}; 126};
127 127
128int __init ieee802154_nl_init(void) 128static const struct genl_multicast_group ieee802154_mcgrps[] = {
129{ 129 [IEEE802154_COORD_MCGRP] = { .name = IEEE802154_MCAST_COORD_NAME, },
130 int rc; 130 [IEEE802154_BEACON_MCGRP] = { .name = IEEE802154_MCAST_BEACON_NAME, },
131 131};
132 rc = genl_register_family_with_ops(&nl802154_family, ieee8021154_ops);
133 if (rc)
134 return rc;
135 132
136 rc = genl_register_mc_group(&nl802154_family, &ieee802154_coord_mcgrp);
137 if (rc)
138 goto fail;
139 133
140 rc = genl_register_mc_group(&nl802154_family, &ieee802154_beacon_mcgrp); 134int __init ieee802154_nl_init(void)
141 if (rc) 135{
142 goto fail; 136 return genl_register_family_with_ops_groups(&nl802154_family,
143 return 0; 137 ieee8021154_ops,
144fail: 138 ieee802154_mcgrps);
145 genl_unregister_family(&nl802154_family);
146 return rc;
147} 139}
148 140
149void __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/netlink/genetlink.c b/net/netlink/genetlink.c
index 36e3a86cacf6..7dbc4f732c75 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -69,16 +69,20 @@ static struct list_head family_ht[GENL_FAM_TAB_SIZE];
69 * abuses the API and thinks it can statically use group 1. 69 * abuses the API and thinks it can statically use group 1.
70 * That group will typically conflict with other groups that 70 * That group will typically conflict with other groups that
71 * any proper users use. 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.
72 * Bit 17 is marked as already used since the VFS quota code 74 * Bit 17 is marked as already used since the VFS quota code
73 * also abused this API and relied on family == group ID, we 75 * also abused this API and relied on family == group ID, we
74 * cater to that by giving it a static family and group ID. 76 * cater to that by giving it a static family and group ID.
75 */ 77 */
76static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_VFS_DQUOT); 78static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) |
79 BIT(GENL_ID_VFS_DQUOT);
77static unsigned long *mc_groups = &mc_group_start; 80static unsigned long *mc_groups = &mc_group_start;
78static unsigned long mc_groups_longs = 1; 81static unsigned long mc_groups_longs = 1;
79 82
80static int genl_ctrl_event(int event, struct genl_family *family, 83static int genl_ctrl_event(int event, struct genl_family *family,
81 struct genl_multicast_group *grp); 84 const struct genl_multicast_group *grp,
85 int grp_id);
82 86
83static inline unsigned int genl_family_hash(unsigned int id) 87static inline unsigned int genl_family_hash(unsigned int id)
84{ 88{
@@ -144,66 +148,110 @@ static u16 genl_generate_id(void)
144 return 0; 148 return 0;
145} 149}
146 150
147static struct genl_multicast_group notify_grp; 151static int genl_allocate_reserve_groups(int n_groups, int *first_id)
148
149/**
150 * genl_register_mc_group - register a multicast group
151 *
152 * Registers the specified multicast group and notifies userspace
153 * about the new group.
154 *
155 * Returns 0 on success or a negative error code.
156 *
157 * @family: The generic netlink family the group shall be registered for.
158 * @grp: The group to register, must have a name.
159 */
160int genl_register_mc_group(struct genl_family *family,
161 struct genl_multicast_group *grp)
162{ 152{
163 int id;
164 unsigned long *new_groups; 153 unsigned long *new_groups;
165 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 }
166 180
167 BUG_ON(grp->name[0] == '\0'); 181 if (id >= mc_groups_longs * BITS_PER_LONG) {
168 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);
169 204
170 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}
210
211static struct genl_family genl_ctrl;
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;
219
220 if (!n_groups)
221 return 0;
222
223 for (i = 0; i < n_groups; i++) {
224 const struct genl_multicast_group *grp = &family->mcgrps[i];
225
226 if (WARN_ON(grp->name[0] == '\0'))
227 return -EINVAL;
228 if (WARN_ON(memchr(grp->name, '\0', GENL_NAMSIZ) == NULL))
229 return -EINVAL;
230 }
171 231
172 /* special-case our own group and hacks */ 232 /* special-case our own group and hacks */
173 if (grp == &notify_grp) 233 if (family == &genl_ctrl) {
174 id = GENL_ID_CTRL; 234 first_id = GENL_ID_CTRL;
175 else if (strcmp(family->name, "NET_DM") == 0) 235 BUG_ON(n_groups != 1);
176 id = 1; 236 } else if (strcmp(family->name, "NET_DM") == 0) {
177 else if (strcmp(family->name, "VFS_DQUOT") == 0) 237 first_id = 1;
178 id = GENL_ID_VFS_DQUOT; 238 BUG_ON(n_groups != 1);
179 else 239 } else if (strcmp(family->name, "VFS_DQUOT") == 0) {
180 id = find_first_zero_bit(mc_groups, 240 first_id = GENL_ID_VFS_DQUOT;
181 mc_groups_longs * BITS_PER_LONG); 241 BUG_ON(n_groups != 1);
182 242 } else {
183 243 groups_allocated = true;
184 if (id >= mc_groups_longs * BITS_PER_LONG) { 244 err = genl_allocate_reserve_groups(n_groups, &first_id);
185 size_t nlen = (mc_groups_longs + 1) * sizeof(unsigned long); 245 if (err)
186 246 return err;
187 if (mc_groups == &mc_group_start) {
188 new_groups = kzalloc(nlen, GFP_KERNEL);
189 if (!new_groups) {
190 err = -ENOMEM;
191 goto out;
192 }
193 mc_groups = new_groups;
194 *mc_groups = mc_group_start;
195 } else {
196 new_groups = krealloc(mc_groups, nlen, GFP_KERNEL);
197 if (!new_groups) {
198 err = -ENOMEM;
199 goto out;
200 }
201 mc_groups = new_groups;
202 mc_groups[mc_groups_longs] = 0;
203 }
204 mc_groups_longs++;
205 } 247 }
206 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
207 if (family->netnsok) { 255 if (family->netnsok) {
208 struct net *net; 256 struct net *net;
209 257
@@ -219,9 +267,7 @@ int genl_register_mc_group(struct genl_family *family,
219 * number of _possible_ groups has been 267 * number of _possible_ groups has been
220 * increased on some sockets which is ok. 268 * increased on some sockets which is ok.
221 */ 269 */
222 rcu_read_unlock(); 270 break;
223 netlink_table_ungrab();
224 goto out;
225 } 271 }
226 } 272 }
227 rcu_read_unlock(); 273 rcu_read_unlock();
@@ -229,46 +275,39 @@ int genl_register_mc_group(struct genl_family *family,
229 } else { 275 } else {
230 err = netlink_change_ngroups(init_net.genl_sock, 276 err = netlink_change_ngroups(init_net.genl_sock,
231 mc_groups_longs * BITS_PER_LONG); 277 mc_groups_longs * BITS_PER_LONG);
232 if (err)
233 goto out;
234 } 278 }
235 279
236 grp->id = id; 280 if (groups_allocated && err) {
237 set_bit(id, mc_groups); 281 for (i = 0; i < family->n_mcgrps; i++)
238 list_add_tail(&grp->list, &family->mcast_groups); 282 clear_bit(family->mcgrp_offset + i, mc_groups);
283 }
239 284
240 genl_ctrl_event(CTRL_CMD_NEWMCAST_GRP, family, grp);
241 out:
242 genl_unlock_all();
243 return err; 285 return err;
244} 286}
245EXPORT_SYMBOL(genl_register_mc_group);
246 287
247static void __genl_unregister_mc_group(struct genl_family *family, 288static void genl_unregister_mc_groups(struct genl_family *family)
248 struct genl_multicast_group *grp)
249{ 289{
250 struct net *net; 290 struct net *net;
291 int i;
251 292
252 netlink_table_grab(); 293 netlink_table_grab();
253 rcu_read_lock(); 294 rcu_read_lock();
254 for_each_net_rcu(net) 295 for_each_net_rcu(net) {
255 __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 }
256 rcu_read_unlock(); 300 rcu_read_unlock();
257 netlink_table_ungrab(); 301 netlink_table_ungrab();
258 302
259 if (grp->id != 1) 303 for (i = 0; i < family->n_mcgrps; i++) {
260 clear_bit(grp->id, mc_groups); 304 int grp_id = family->mcgrp_offset + i;
261 list_del(&grp->list);
262 genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, family, grp);
263 grp->id = 0;
264}
265
266static void genl_unregister_mc_groups(struct genl_family *family)
267{
268 struct genl_multicast_group *grp, *tmp;
269 305
270 list_for_each_entry_safe(grp, tmp, &family->mcast_groups, list) 306 if (grp_id != 1)
271 __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 }
272} 311}
273 312
274static int genl_validate_ops(struct genl_family *family) 313static int genl_validate_ops(struct genl_family *family)
@@ -314,7 +353,7 @@ static int genl_validate_ops(struct genl_family *family)
314 */ 353 */
315int __genl_register_family(struct genl_family *family) 354int __genl_register_family(struct genl_family *family)
316{ 355{
317 int err = -EINVAL; 356 int err = -EINVAL, i;
318 357
319 if (family->id && family->id < GENL_MIN_ID) 358 if (family->id && family->id < GENL_MIN_ID)
320 goto errout; 359 goto errout;
@@ -326,8 +365,6 @@ int __genl_register_family(struct genl_family *family)
326 if (err) 365 if (err)
327 return err; 366 return err;
328 367
329 INIT_LIST_HEAD(&family->mcast_groups);
330
331 genl_lock_all(); 368 genl_lock_all();
332 369
333 if (genl_family_find_byname(family->name)) { 370 if (genl_family_find_byname(family->name)) {
@@ -359,10 +396,18 @@ int __genl_register_family(struct genl_family *family)
359 } else 396 } else
360 family->attrbuf = NULL; 397 family->attrbuf = NULL;
361 398
399 err = genl_validate_assign_mc_groups(family);
400 if (err)
401 goto errout_locked;
402
362 list_add_tail(&family->family_list, genl_family_chain(family->id)); 403 list_add_tail(&family->family_list, genl_family_chain(family->id));
363 genl_unlock_all(); 404 genl_unlock_all();
364 405
365 genl_ctrl_event(CTRL_CMD_NEWFAMILY, family, NULL); 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);
366 411
367 return 0; 412 return 0;
368 413
@@ -398,7 +443,7 @@ int genl_unregister_family(struct genl_family *family)
398 genl_unlock_all(); 443 genl_unlock_all();
399 444
400 kfree(family->attrbuf); 445 kfree(family->attrbuf);
401 genl_ctrl_event(CTRL_CMD_DELFAMILY, family, NULL); 446 genl_ctrl_event(CTRL_CMD_DELFAMILY, family, NULL, 0);
402 return 0; 447 return 0;
403 } 448 }
404 449
@@ -658,23 +703,26 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq,
658 nla_nest_end(skb, nla_ops); 703 nla_nest_end(skb, nla_ops);
659 } 704 }
660 705
661 if (!list_empty(&family->mcast_groups)) { 706 if (family->n_mcgrps) {
662 struct genl_multicast_group *grp;
663 struct nlattr *nla_grps; 707 struct nlattr *nla_grps;
664 int idx = 1; 708 int i;
665 709
666 nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS); 710 nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS);
667 if (nla_grps == NULL) 711 if (nla_grps == NULL)
668 goto nla_put_failure; 712 goto nla_put_failure;
669 713
670 list_for_each_entry(grp, &family->mcast_groups, list) { 714 for (i = 0; i < family->n_mcgrps; i++) {
671 struct nlattr *nest; 715 struct nlattr *nest;
716 const struct genl_multicast_group *grp;
672 717
673 nest = nla_nest_start(skb, idx++); 718 grp = &family->mcgrps[i];
719
720 nest = nla_nest_start(skb, i + 1);
674 if (nest == NULL) 721 if (nest == NULL)
675 goto nla_put_failure; 722 goto nla_put_failure;
676 723
677 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) ||
678 nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME, 726 nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME,
679 grp->name)) 727 grp->name))
680 goto nla_put_failure; 728 goto nla_put_failure;
@@ -692,9 +740,9 @@ nla_put_failure:
692} 740}
693 741
694static int ctrl_fill_mcgrp_info(struct genl_family *family, 742static int ctrl_fill_mcgrp_info(struct genl_family *family,
695 struct genl_multicast_group *grp, u32 portid, 743 const struct genl_multicast_group *grp,
696 u32 seq, u32 flags, struct sk_buff *skb, 744 int grp_id, u32 portid, u32 seq, u32 flags,
697 u8 cmd) 745 struct sk_buff *skb, u8 cmd)
698{ 746{
699 void *hdr; 747 void *hdr;
700 struct nlattr *nla_grps; 748 struct nlattr *nla_grps;
@@ -716,7 +764,7 @@ static int ctrl_fill_mcgrp_info(struct genl_family *family,
716 if (nest == NULL) 764 if (nest == NULL)
717 goto nla_put_failure; 765 goto nla_put_failure;
718 766
719 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) ||
720 nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME, 768 nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME,
721 grp->name)) 769 grp->name))
722 goto nla_put_failure; 770 goto nla_put_failure;
@@ -782,9 +830,10 @@ static struct sk_buff *ctrl_build_family_msg(struct genl_family *family,
782 return skb; 830 return skb;
783} 831}
784 832
785static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_family *family, 833static struct sk_buff *
786 struct genl_multicast_group *grp, 834ctrl_build_mcgrp_msg(struct genl_family *family,
787 u32 portid, int seq, u8 cmd) 835 const struct genl_multicast_group *grp,
836 int grp_id, u32 portid, int seq, u8 cmd)
788{ 837{
789 struct sk_buff *skb; 838 struct sk_buff *skb;
790 int err; 839 int err;
@@ -793,7 +842,8 @@ static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_family *family,
793 if (skb == NULL) 842 if (skb == NULL)
794 return ERR_PTR(-ENOBUFS); 843 return ERR_PTR(-ENOBUFS);
795 844
796 err = ctrl_fill_mcgrp_info(family, grp, portid, seq, 0, skb, cmd); 845 err = ctrl_fill_mcgrp_info(family, grp, grp_id, portid,
846 seq, 0, skb, cmd);
797 if (err < 0) { 847 if (err < 0) {
798 nlmsg_free(skb); 848 nlmsg_free(skb);
799 return ERR_PTR(err); 849 return ERR_PTR(err);
@@ -856,7 +906,8 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
856} 906}
857 907
858static int genl_ctrl_event(int event, struct genl_family *family, 908static int genl_ctrl_event(int event, struct genl_family *family,
859 struct genl_multicast_group *grp) 909 const struct genl_multicast_group *grp,
910 int grp_id)
860{ 911{
861 struct sk_buff *msg; 912 struct sk_buff *msg;
862 913
@@ -873,7 +924,7 @@ static int genl_ctrl_event(int event, struct genl_family *family,
873 case CTRL_CMD_NEWMCAST_GRP: 924 case CTRL_CMD_NEWMCAST_GRP:
874 case CTRL_CMD_DELMCAST_GRP: 925 case CTRL_CMD_DELMCAST_GRP:
875 BUG_ON(!grp); 926 BUG_ON(!grp);
876 msg = ctrl_build_mcgrp_msg(family, grp, 0, 0, event); 927 msg = ctrl_build_mcgrp_msg(family, grp, grp_id, 0, 0, event);
877 break; 928 break;
878 default: 929 default:
879 return -EINVAL; 930 return -EINVAL;
@@ -884,11 +935,11 @@ static int genl_ctrl_event(int event, struct genl_family *family,
884 935
885 if (!family->netnsok) { 936 if (!family->netnsok) {
886 genlmsg_multicast_netns(&genl_ctrl, &init_net, msg, 0, 937 genlmsg_multicast_netns(&genl_ctrl, &init_net, msg, 0,
887 GENL_ID_CTRL, GFP_KERNEL); 938 0, GFP_KERNEL);
888 } else { 939 } else {
889 rcu_read_lock(); 940 rcu_read_lock();
890 genlmsg_multicast_allns(&genl_ctrl, msg, 0, 941 genlmsg_multicast_allns(&genl_ctrl, msg, 0,
891 GENL_ID_CTRL, GFP_ATOMIC); 942 0, GFP_ATOMIC);
892 rcu_read_unlock(); 943 rcu_read_unlock();
893 } 944 }
894 945
@@ -904,8 +955,8 @@ static struct genl_ops genl_ctrl_ops[] = {
904 }, 955 },
905}; 956};
906 957
907static struct genl_multicast_group notify_grp = { 958static struct genl_multicast_group genl_ctrl_groups[] = {
908 .name = "notify", 959 { .name = "notify", },
909}; 960};
910 961
911static int __net_init genl_pernet_init(struct net *net) 962static int __net_init genl_pernet_init(struct net *net)
@@ -945,7 +996,8 @@ static int __init genl_init(void)
945 for (i = 0; i < GENL_FAM_TAB_SIZE; i++) 996 for (i = 0; i < GENL_FAM_TAB_SIZE; i++)
946 INIT_LIST_HEAD(&family_ht[i]); 997 INIT_LIST_HEAD(&family_ht[i]);
947 998
948 err = genl_register_family_with_ops(&genl_ctrl, genl_ctrl_ops); 999 err = genl_register_family_with_ops_groups(&genl_ctrl, genl_ctrl_ops,
1000 genl_ctrl_groups);
949 if (err < 0) 1001 if (err < 0)
950 goto problem; 1002 goto problem;
951 1003
@@ -953,10 +1005,6 @@ static int __init genl_init(void)
953 if (err) 1005 if (err)
954 goto problem; 1006 goto problem;
955 1007
956 err = genl_register_mc_group(&genl_ctrl, &notify_grp);
957 if (err < 0)
958 goto problem;
959
960 return 0; 1008 return 0;
961 1009
962problem: 1010problem:
@@ -997,6 +1045,9 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
997int genlmsg_multicast_allns(struct genl_family *family, struct sk_buff *skb, 1045int genlmsg_multicast_allns(struct genl_family *family, struct sk_buff *skb,
998 u32 portid, unsigned int group, gfp_t flags) 1046 u32 portid, unsigned int group, gfp_t flags)
999{ 1047{
1048 if (group >= family->n_mcgrps)
1049 return -EINVAL;
1050 group = family->mcgrp_offset + group;
1000 return genlmsg_mcast(skb, portid, group, flags); 1051 return genlmsg_mcast(skb, portid, group, flags);
1001} 1052}
1002EXPORT_SYMBOL(genlmsg_multicast_allns); 1053EXPORT_SYMBOL(genlmsg_multicast_allns);
@@ -1011,6 +1062,9 @@ void genl_notify(struct genl_family *family,
1011 if (nlh) 1062 if (nlh)
1012 report = nlmsg_report(nlh); 1063 report = nlmsg_report(nlh);
1013 1064
1065 if (group >= family->n_mcgrps)
1066 return;
1067 group = family->mcgrp_offset + group;
1014 nlmsg_notify(sk, skb, portid, group, report, flags); 1068 nlmsg_notify(sk, skb, portid, group, report, flags);
1015} 1069}
1016EXPORT_SYMBOL(genl_notify); 1070EXPORT_SYMBOL(genl_notify);
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index 3092df313fb1..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,8 +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(&nfc_genl_family, msg, 0, 197 return genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
198 nfc_genl_event_mcgrp.id, GFP_ATOMIC);
199 198
200nla_put_failure: 199nla_put_failure:
201 genlmsg_cancel(msg, hdr); 200 genlmsg_cancel(msg, hdr);
@@ -224,8 +223,7 @@ int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx)
224 223
225 genlmsg_end(msg, hdr); 224 genlmsg_end(msg, hdr);
226 225
227 genlmsg_multicast(&nfc_genl_family, msg, 0, 226 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
228 nfc_genl_event_mcgrp.id, GFP_KERNEL);
229 227
230 return 0; 228 return 0;
231 229
@@ -257,8 +255,7 @@ int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol)
257 255
258 genlmsg_end(msg, hdr); 256 genlmsg_end(msg, hdr);
259 257
260 genlmsg_multicast(&nfc_genl_family, msg, 0, 258 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
261 nfc_genl_event_mcgrp.id, GFP_KERNEL);
262 259
263 return 0; 260 return 0;
264 261
@@ -288,8 +285,7 @@ int nfc_genl_tm_deactivated(struct nfc_dev *dev)
288 285
289 genlmsg_end(msg, hdr); 286 genlmsg_end(msg, hdr);
290 287
291 genlmsg_multicast(&nfc_genl_family, msg, 0, 288 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
292 nfc_genl_event_mcgrp.id, GFP_KERNEL);
293 289
294 return 0; 290 return 0;
295 291
@@ -322,8 +318,7 @@ int nfc_genl_device_added(struct nfc_dev *dev)
322 318
323 genlmsg_end(msg, hdr); 319 genlmsg_end(msg, hdr);
324 320
325 genlmsg_multicast(&nfc_genl_family, msg, 0, 321 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
326 nfc_genl_event_mcgrp.id, GFP_KERNEL);
327 322
328 return 0; 323 return 0;
329 324
@@ -353,8 +348,7 @@ int nfc_genl_device_removed(struct nfc_dev *dev)
353 348
354 genlmsg_end(msg, hdr); 349 genlmsg_end(msg, hdr);
355 350
356 genlmsg_multicast(&nfc_genl_family, msg, 0, 351 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
357 nfc_genl_event_mcgrp.id, GFP_KERNEL);
358 352
359 return 0; 353 return 0;
360 354
@@ -420,8 +414,7 @@ int nfc_genl_llc_send_sdres(struct nfc_dev *dev, struct hlist_head *sdres_list)
420 414
421 genlmsg_end(msg, hdr); 415 genlmsg_end(msg, hdr);
422 416
423 return genlmsg_multicast(&nfc_genl_family, msg, 0, 417 return genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
424 nfc_genl_event_mcgrp.id, GFP_ATOMIC);
425 418
426nla_put_failure: 419nla_put_failure:
427 genlmsg_cancel(msg, hdr); 420 genlmsg_cancel(msg, hdr);
@@ -455,8 +448,7 @@ int nfc_genl_se_added(struct nfc_dev *dev, u32 se_idx, u16 type)
455 448
456 genlmsg_end(msg, hdr); 449 genlmsg_end(msg, hdr);
457 450
458 genlmsg_multicast(&nfc_genl_family, msg, 0, 451 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
459 nfc_genl_event_mcgrp.id, GFP_KERNEL);
460 452
461 return 0; 453 return 0;
462 454
@@ -487,8 +479,7 @@ int nfc_genl_se_removed(struct nfc_dev *dev, u32 se_idx)
487 479
488 genlmsg_end(msg, hdr); 480 genlmsg_end(msg, hdr);
489 481
490 genlmsg_multicast(&nfc_genl_family, msg, 0, 482 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
491 nfc_genl_event_mcgrp.id, GFP_KERNEL);
492 483
493 return 0; 484 return 0;
494 485
@@ -609,8 +600,7 @@ int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
609 600
610 dev->dep_link_up = true; 601 dev->dep_link_up = true;
611 602
612 genlmsg_multicast(&nfc_genl_family, msg, 0, 603 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
613 nfc_genl_event_mcgrp.id, GFP_ATOMIC);
614 604
615 return 0; 605 return 0;
616 606
@@ -642,8 +632,7 @@ int nfc_genl_dep_link_down_event(struct nfc_dev *dev)
642 632
643 genlmsg_end(msg, hdr); 633 genlmsg_end(msg, hdr);
644 634
645 genlmsg_multicast(&nfc_genl_family, msg, 0, 635 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
646 nfc_genl_event_mcgrp.id, GFP_ATOMIC);
647 636
648 return 0; 637 return 0;
649 638
@@ -1148,8 +1137,7 @@ int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name,
1148 1137
1149 genlmsg_end(msg, hdr); 1138 genlmsg_end(msg, hdr);
1150 1139
1151 genlmsg_multicast(&nfc_genl_family, msg, 0, 1140 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
1152 nfc_genl_event_mcgrp.id, GFP_KERNEL);
1153 1141
1154 return 0; 1142 return 0;
1155 1143
@@ -1320,8 +1308,7 @@ static void se_io_cb(void *context, u8 *apdu, size_t apdu_len, int err)
1320 1308
1321 genlmsg_end(msg, hdr); 1309 genlmsg_end(msg, hdr);
1322 1310
1323 genlmsg_multicast(&nfc_genl_family, msg, 0, 1311 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
1324 nfc_genl_event_mcgrp.id, GFP_KERNEL);
1325 1312
1326 kfree(ctx); 1313 kfree(ctx);
1327 1314
@@ -1549,15 +1536,15 @@ int __init nfc_genl_init(void)
1549{ 1536{
1550 int rc; 1537 int rc;
1551 1538
1552 rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops); 1539 rc = genl_register_family_with_ops_groups(&nfc_genl_family,
1540 nfc_genl_ops,
1541 nfc_genl_mcgrps);
1553 if (rc) 1542 if (rc)
1554 return rc; 1543 return rc;
1555 1544
1556 rc = genl_register_mc_group(&nfc_genl_family, &nfc_genl_event_mcgrp);
1557
1558 netlink_register_notifier(&nl_notifier); 1545 netlink_register_notifier(&nl_notifier);
1559 1546
1560 return rc; 1547 return 0;
1561} 1548}
1562 1549
1563/** 1550/**
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 5c19846b1d2a..1de4d281e3f1 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -62,11 +62,10 @@
62int ovs_net_id __read_mostly; 62int ovs_net_id __read_mostly;
63 63
64static void ovs_notify(struct genl_family *family, 64static void ovs_notify(struct genl_family *family,
65 struct sk_buff *skb, struct genl_info *info, 65 struct sk_buff *skb, struct genl_info *info)
66 struct genl_multicast_group *grp)
67{ 66{
68 genl_notify(family, skb, genl_info_net(info), info->snd_portid, 67 genl_notify(family, skb, genl_info_net(info), info->snd_portid,
69 grp->id, info->nlhdr, GFP_KERNEL); 68 0, info->nlhdr, GFP_KERNEL);
70} 69}
71 70
72/** 71/**
@@ -878,11 +877,10 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
878 ovs_unlock(); 877 ovs_unlock();
879 878
880 if (!IS_ERR(reply)) 879 if (!IS_ERR(reply))
881 ovs_notify(&dp_flow_genl_family, reply, info, 880 ovs_notify(&dp_flow_genl_family, reply, info);
882 &ovs_dp_flow_multicast_group);
883 else 881 else
884 genl_set_err(&dp_flow_genl_family, sock_net(skb->sk), 0, 882 genl_set_err(&dp_flow_genl_family, sock_net(skb->sk), 0,
885 ovs_dp_flow_multicast_group.id, PTR_ERR(reply)); 883 0, PTR_ERR(reply));
886 return 0; 884 return 0;
887 885
888err_flow_free: 886err_flow_free:
@@ -992,8 +990,7 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
992 ovs_flow_free(flow, true); 990 ovs_flow_free(flow, true);
993 ovs_unlock(); 991 ovs_unlock();
994 992
995 ovs_notify(&dp_flow_genl_family, reply, info, 993 ovs_notify(&dp_flow_genl_family, reply, info);
996 &ovs_dp_flow_multicast_group);
997 return 0; 994 return 0;
998unlock: 995unlock:
999 ovs_unlock(); 996 ovs_unlock();
@@ -1240,8 +1237,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
1240 1237
1241 ovs_unlock(); 1238 ovs_unlock();
1242 1239
1243 ovs_notify(&dp_datapath_genl_family, reply, info, 1240 ovs_notify(&dp_datapath_genl_family, reply, info);
1244 &ovs_dp_datapath_multicast_group);
1245 return 0; 1241 return 0;
1246 1242
1247err_destroy_local_port: 1243err_destroy_local_port:
@@ -1306,8 +1302,7 @@ static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info)
1306 __dp_destroy(dp); 1302 __dp_destroy(dp);
1307 ovs_unlock(); 1303 ovs_unlock();
1308 1304
1309 ovs_notify(&dp_datapath_genl_family, reply, info, 1305 ovs_notify(&dp_datapath_genl_family, reply, info);
1310 &ovs_dp_datapath_multicast_group);
1311 1306
1312 return 0; 1307 return 0;
1313unlock: 1308unlock:
@@ -1332,14 +1327,13 @@ static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info)
1332 if (IS_ERR(reply)) { 1327 if (IS_ERR(reply)) {
1333 err = PTR_ERR(reply); 1328 err = PTR_ERR(reply);
1334 genl_set_err(&dp_datapath_genl_family, sock_net(skb->sk), 0, 1329 genl_set_err(&dp_datapath_genl_family, sock_net(skb->sk), 0,
1335 ovs_dp_datapath_multicast_group.id, err); 1330 0, err);
1336 err = 0; 1331 err = 0;
1337 goto unlock; 1332 goto unlock;
1338 } 1333 }
1339 1334
1340 ovs_unlock(); 1335 ovs_unlock();
1341 ovs_notify(&dp_datapath_genl_family, reply, info, 1336 ovs_notify(&dp_datapath_genl_family, reply, info);
1342 &ovs_dp_datapath_multicast_group);
1343 1337
1344 return 0; 1338 return 0;
1345unlock: 1339unlock:
@@ -1601,8 +1595,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
1601 goto exit_unlock; 1595 goto exit_unlock;
1602 } 1596 }
1603 1597
1604 ovs_notify(&dp_vport_genl_family, reply, info, 1598 ovs_notify(&dp_vport_genl_family, reply, info);
1605 &ovs_dp_vport_multicast_group);
1606 1599
1607exit_unlock: 1600exit_unlock:
1608 ovs_unlock(); 1601 ovs_unlock();
@@ -1649,8 +1642,7 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
1649 BUG_ON(err < 0); 1642 BUG_ON(err < 0);
1650 1643
1651 ovs_unlock(); 1644 ovs_unlock();
1652 ovs_notify(&dp_vport_genl_family, reply, info, 1645 ovs_notify(&dp_vport_genl_family, reply, info);
1653 &ovs_dp_vport_multicast_group);
1654 return 0; 1646 return 0;
1655 1647
1656exit_free: 1648exit_free:
@@ -1687,8 +1679,7 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
1687 err = 0; 1679 err = 0;
1688 ovs_dp_detach_port(vport); 1680 ovs_dp_detach_port(vport);
1689 1681
1690 ovs_notify(&dp_vport_genl_family, reply, info, 1682 ovs_notify(&dp_vport_genl_family, reply, info);
1691 &ovs_dp_vport_multicast_group);
1692 1683
1693exit_unlock: 1684exit_unlock:
1694 ovs_unlock(); 1685 ovs_unlock();
@@ -1790,7 +1781,7 @@ struct genl_family_and_ops {
1790 struct genl_family *family; 1781 struct genl_family *family;
1791 const struct genl_ops *ops; 1782 const struct genl_ops *ops;
1792 int n_ops; 1783 int n_ops;
1793 struct genl_multicast_group *group; 1784 const struct genl_multicast_group *group;
1794}; 1785};
1795 1786
1796static const struct genl_family_and_ops dp_genl_families[] = { 1787static const struct genl_family_and_ops dp_genl_families[] = {
@@ -1828,16 +1819,12 @@ static int dp_register_genl(void)
1828 1819
1829 f->family->ops = f->ops; 1820 f->family->ops = f->ops;
1830 f->family->n_ops = 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;
1831 err = genl_register_family(f->family); 1824 err = genl_register_family(f->family);
1832 if (err) 1825 if (err)
1833 goto error; 1826 goto error;
1834 n_registered++; 1827 n_registered++;
1835
1836 if (f->group) {
1837 err = genl_register_mc_group(f->family, f->group);
1838 if (err)
1839 goto error;
1840 }
1841 } 1828 }
1842 1829
1843 return 0; 1830 return 0;
diff --git a/net/openvswitch/dp_notify.c b/net/openvswitch/dp_notify.c
index f4b66c84ea0b..2c631fe76be1 100644
--- a/net/openvswitch/dp_notify.c
+++ b/net/openvswitch/dp_notify.c
@@ -35,15 +35,13 @@ static void dp_detach_port_notify(struct vport *vport)
35 ovs_dp_detach_port(vport); 35 ovs_dp_detach_port(vport);
36 if (IS_ERR(notify)) { 36 if (IS_ERR(notify)) {
37 genl_set_err(&dp_vport_genl_family, ovs_dp_get_net(dp), 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(&dp_vport_genl_family, 42 genlmsg_multicast_netns(&dp_vport_genl_family,
44 ovs_dp_get_net(dp), notify, 0, 43 ovs_dp_get_net(dp), notify, 0,
45 ovs_dp_vport_multicast_group.id, 44 0, GFP_KERNEL);
46 GFP_KERNEL);
47} 45}
48 46
49void ovs_dp_notify_wq(struct work_struct *work) 47void ovs_dp_notify_wq(struct work_struct *work)
diff --git a/net/wimax/op-msg.c b/net/wimax/op-msg.c
index f37dd3c5576d..c278b3356f75 100644
--- a/net/wimax/op-msg.c
+++ b/net/wimax/op-msg.c
@@ -279,8 +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(&wimax_gnl_family, skb, 0, 282 genlmsg_multicast(&wimax_gnl_family, skb, 0, 0, GFP_KERNEL);
283 wimax_gnl_mcg.id, GFP_KERNEL);
284 d_printf(1, dev, "CTX: genl multicast done\n"); 283 d_printf(1, dev, "CTX: genl multicast done\n");
285 return 0; 284 return 0;
286} 285}
diff --git a/net/wimax/stack.c b/net/wimax/stack.c
index 18888748e699..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,8 +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(&wimax_gnl_family, report_skb, 0, 181 genlmsg_multicast(&wimax_gnl_family, report_skb, 0, 0, GFP_KERNEL);
181 wimax_gnl_mcg.id, GFP_KERNEL);
182out: 182out:
183 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",
184 wimax_dev, report_skb, result); 184 wimax_dev, report_skb, result);
@@ -580,8 +580,8 @@ struct genl_family wimax_gnl_family = {
580 .maxattr = WIMAX_GNL_ATTR_MAX, 580 .maxattr = WIMAX_GNL_ATTR_MAX,
581}; 581};
582 582
583struct genl_multicast_group wimax_gnl_mcg = { 583static const struct genl_multicast_group wimax_gnl_mcgrps[] = {
584 .name = "msg", 584 { .name = "msg", },
585}; 585};
586 586
587 587
@@ -598,21 +598,18 @@ int __init wimax_subsys_init(void)
598 598
599 snprintf(wimax_gnl_family.name, sizeof(wimax_gnl_family.name), 599 snprintf(wimax_gnl_family.name, sizeof(wimax_gnl_family.name),
600 "WiMAX"); 600 "WiMAX");
601 result = genl_register_family_with_ops(&wimax_gnl_family, 601 result = genl_register_family_with_ops_groups(&wimax_gnl_family,
602 wimax_gnl_ops); 602 wimax_gnl_ops,
603 wimax_gnl_mcgrps);
603 if (unlikely(result < 0)) { 604 if (unlikely(result < 0)) {
604 printk(KERN_ERR "cannot register generic netlink family: %d\n", 605 printk(KERN_ERR "cannot register generic netlink family: %d\n",
605 result); 606 result);
606 goto error_register_family; 607 goto error_register_family;
607 } 608 }
608 609
609 result = genl_register_mc_group(&wimax_gnl_family, &wimax_gnl_mcg);
610 if (result < 0)
611 goto error_mc_group;
612 d_fnend(4, NULL, "() = 0\n"); 610 d_fnend(4, NULL, "() = 0\n");
613 return 0; 611 return 0;
614 612
615error_mc_group:
616 genl_unregister_family(&wimax_gnl_family); 613 genl_unregister_family(&wimax_gnl_family);
617error_register_family: 614error_register_family:
618 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 f20edfd2e1f0..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];
@@ -6869,7 +6884,7 @@ void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
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(&nl80211_fam, 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)
@@ -9598,7 +9598,7 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
9598 } 9598 }
9599 9599
9600 genlmsg_multicast_netns(&nl80211_fam, 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,
@@ -9708,7 +9708,7 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
9708 } 9708 }
9709 9709
9710 genlmsg_multicast_netns(&nl80211_fam, 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,
@@ -9727,7 +9727,7 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
9727 } 9727 }
9728 9728
9729 genlmsg_multicast_netns(&nl80211_fam, 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,
@@ -9746,7 +9746,7 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
9746 } 9746 }
9747 9747
9748 genlmsg_multicast_netns(&nl80211_fam, 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,
@@ -9765,7 +9765,7 @@ void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
9765 } 9765 }
9766 9766
9767 genlmsg_multicast_netns(&nl80211_fam, 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,
@@ -9783,7 +9783,7 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
9783 } 9783 }
9784 9784
9785 genlmsg_multicast_netns(&nl80211_fam, 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/*
@@ -9838,7 +9838,7 @@ void nl80211_send_reg_change_event(struct regulatory_request *request)
9838 9838
9839 rcu_read_lock(); 9839 rcu_read_lock();
9840 genlmsg_multicast_allns(&nl80211_fam, msg, 0, 9840 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
9841 nl80211_regulatory_mcgrp.id, GFP_ATOMIC); 9841 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
9842 rcu_read_unlock(); 9842 rcu_read_unlock();
9843 9843
9844 return; 9844 return;
@@ -9874,7 +9874,7 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
9874 genlmsg_end(msg, hdr); 9874 genlmsg_end(msg, hdr);
9875 9875
9876 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -9962,7 +9962,7 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
9962 genlmsg_end(msg, hdr); 9962 genlmsg_end(msg, hdr);
9963 9963
9964 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10018,7 +10018,7 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
10018 genlmsg_end(msg, hdr); 10018 genlmsg_end(msg, hdr);
10019 10019
10020 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10057,7 +10057,7 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
10057 genlmsg_end(msg, hdr); 10057 genlmsg_end(msg, hdr);
10058 10058
10059 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10095,7 +10095,7 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
10095 genlmsg_end(msg, hdr); 10095 genlmsg_end(msg, hdr);
10096 10096
10097 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10129,7 +10129,7 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
10129 genlmsg_end(msg, hdr); 10129 genlmsg_end(msg, hdr);
10130 10130
10131 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10170,7 +10170,7 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
10170 genlmsg_end(msg, hdr); 10170 genlmsg_end(msg, hdr);
10171 10171
10172 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10209,7 +10209,7 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
10209 genlmsg_end(msg, hdr); 10209 genlmsg_end(msg, hdr);
10210 10210
10211 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10262,7 +10262,7 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
10262 10262
10263 rcu_read_lock(); 10263 rcu_read_lock();
10264 genlmsg_multicast_allns(&nl80211_fam, msg, 0, 10264 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
10265 nl80211_regulatory_mcgrp.id, GFP_ATOMIC); 10265 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
10266 rcu_read_unlock(); 10266 rcu_read_unlock();
10267 10267
10268 return; 10268 return;
@@ -10308,7 +10308,7 @@ static void nl80211_send_remain_on_chan_event(
10308 genlmsg_end(msg, hdr); 10308 genlmsg_end(msg, hdr);
10309 10309
10310 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10363,7 +10363,7 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
10363 } 10363 }
10364 10364
10365 genlmsg_multicast_netns(&nl80211_fam, 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
@@ -10393,7 +10393,7 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp)
10393 genlmsg_end(msg, hdr); 10393 genlmsg_end(msg, hdr);
10394 10394
10395 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10429,7 +10429,7 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
10429 genlmsg_end(msg, hdr); 10429 genlmsg_end(msg, hdr);
10430 10430
10431 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10591,7 +10591,7 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
10591 genlmsg_end(msg, hdr); 10591 genlmsg_end(msg, hdr);
10592 10592
10593 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10640,7 +10640,7 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
10640 genlmsg_end(msg, hdr); 10640 genlmsg_end(msg, hdr);
10641 10641
10642 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10685,7 +10685,7 @@ static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
10685 genlmsg_end(msg, hdr); 10685 genlmsg_end(msg, hdr);
10686 10686
10687 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10743,7 +10743,7 @@ nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
10743 genlmsg_end(msg, hdr); 10743 genlmsg_end(msg, hdr);
10744 10744
10745 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10790,7 +10790,7 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
10790 genlmsg_end(msg, hdr); 10790 genlmsg_end(msg, hdr);
10791 10791
10792 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10867,7 +10867,7 @@ void cfg80211_cqm_txe_notify(struct net_device *dev,
10867 genlmsg_end(msg, hdr); 10867 genlmsg_end(msg, hdr);
10868 10868
10869 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10916,7 +10916,7 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
10916 genlmsg_end(msg, hdr); 10916 genlmsg_end(msg, hdr);
10917 10917
10918 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -10963,7 +10963,7 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev,
10963 genlmsg_end(msg, hdr); 10963 genlmsg_end(msg, hdr);
10964 10964
10965 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -11003,7 +11003,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
11003 genlmsg_end(msg, hdr); 11003 genlmsg_end(msg, hdr);
11004 11004
11005 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -11155,7 +11155,7 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
11155 genlmsg_end(msg, hdr); 11155 genlmsg_end(msg, hdr);
11156 11156
11157 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -11197,7 +11197,7 @@ void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
11197 genlmsg_end(msg, hdr); 11197 genlmsg_end(msg, hdr);
11198 11198
11199 genlmsg_multicast_netns(&nl80211_fam, 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:
@@ -11280,7 +11280,7 @@ void cfg80211_ft_event(struct net_device *netdev,
11280 genlmsg_end(msg, hdr); 11280 genlmsg_end(msg, hdr);
11281 11281
11282 genlmsg_multicast_netns(&nl80211_fam, 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,32 +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, nl80211_ops); 11332 err = genl_register_family_with_ops_groups(&nl80211_fam, nl80211_ops,
11333 nl80211_mcgrps);
11333 if (err) 11334 if (err)
11334 return err; 11335 return err;
11335 11336
11336 err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
11337 if (err)
11338 goto err_out;
11339
11340 err = genl_register_mc_group(&nl80211_fam, &nl80211_scan_mcgrp);
11341 if (err)
11342 goto err_out;
11343
11344 err = genl_register_mc_group(&nl80211_fam, &nl80211_regulatory_mcgrp);
11345 if (err)
11346 goto err_out;
11347
11348 err = genl_register_mc_group(&nl80211_fam, &nl80211_mlme_mcgrp);
11349 if (err)
11350 goto err_out;
11351
11352#ifdef CONFIG_NL80211_TESTMODE
11353 err = genl_register_mc_group(&nl80211_fam, &nl80211_testmode_mcgrp);
11354 if (err)
11355 goto err_out;
11356#endif
11357
11358 err = netlink_register_notifier(&nl80211_netlink_notifier); 11337 err = netlink_register_notifier(&nl80211_netlink_notifier);
11359 if (err) 11338 if (err)
11360 goto err_out; 11339 goto err_out;