diff options
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 | ||
81 | static const struct genl_multicast_group acpi_event_mcgrps[] = { | ||
82 | { .name = ACPI_GENL_MCAST_GROUP_NAME, }, | ||
83 | }; | ||
84 | |||
81 | static struct genl_family acpi_event_genl_family = { | 85 | static 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), | |
88 | static struct genl_multicast_group acpi_event_mcgrp = { | ||
89 | .name = ACPI_GENL_MCAST_GROUP_NAME, | ||
90 | }; | 92 | }; |
91 | 93 | ||
92 | int acpi_bus_generate_netlink_event(const char *device_class, | 94 | int 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 | ||
155 | static int acpi_event_genetlink_init(void) | 157 | static 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 | ||
2673 | static struct genl_multicast_group team_change_event_mcgrp = { | 2673 | static 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 | ||
2677 | static int team_nl_send_multicast(struct sk_buff *skb, | 2677 | static 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 | ||
2684 | static int team_nl_send_event_options_get(struct team *team, | 2684 | static 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 | ||
2698 | static int team_nl_init(void) | 2698 | static 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 | |||
2713 | err_change_event_grp_reg: | ||
2714 | genl_unregister_family(&team_nl_family); | ||
2715 | |||
2716 | return err; | ||
2717 | } | 2702 | } |
2718 | 2703 | ||
2719 | static void team_nl_fini(void) | 2704 | static 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: | |||
1606 | EXPORT_SYMBOL_GPL(thermal_zone_get_zone_by_name); | 1606 | EXPORT_SYMBOL_GPL(thermal_zone_get_zone_by_name); |
1607 | 1607 | ||
1608 | #ifdef CONFIG_NET | 1608 | #ifdef CONFIG_NET |
1609 | static const struct genl_multicast_group thermal_event_mcgrps[] = { | ||
1610 | { .name = THERMAL_GENL_MCAST_GROUP_NAME, }, | ||
1611 | }; | ||
1612 | |||
1609 | static struct genl_family thermal_event_genl_family = { | 1613 | static 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), | |
1616 | static struct genl_multicast_group thermal_event_mcgrp = { | ||
1617 | .name = THERMAL_GENL_MCAST_GROUP_NAME, | ||
1618 | }; | 1620 | }; |
1619 | 1621 | ||
1620 | int thermal_generate_netlink_event(struct thermal_zone_device *tz, | 1622 | int 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 | ||
1686 | static int genetlink_init(void) | 1689 | static 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 | ||
1701 | static void genetlink_exit(void) | 1694 | static 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 | ||
77 | static struct genl_ops dlm_nl_ops = { | 77 | static 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 | ||
82 | int __init dlm_netlink_init(void) | 84 | int __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 | ||
87 | void dlm_netlink_exit(void) | 89 | void 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 | ||
12 | static const struct genl_multicast_group quota_mcgrps[] = { | ||
13 | { .name = "events", }, | ||
14 | }; | ||
15 | |||
12 | /* Netlink family structure for quota */ | 16 | /* Netlink family structure for quota */ |
13 | static struct genl_family quota_genl_family = { | 17 | static 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("a_genl_family, skb, 0, 0, GFP_NOFS); |
82 | return; | 94 | return; |
83 | attr_err_out: | 95 | attr_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) | ||
277 | static 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 | |||
283 | enum 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) \ |
278 | static struct genl_multicast_group \ | ||
279 | CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group) __read_mostly = { \ | ||
280 | .name = #group, \ | ||
281 | }; \ | ||
282 | static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)( \ | 291 | static 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 | ||
294 | int 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 | |
316 | fail: | 305 | int 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 | ||
321 | void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void) | 312 | void 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 | */ |
18 | struct genl_multicast_group { | 14 | struct 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 | ||
25 | struct genl_ops; | 18 | struct 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 | */ |
155 | static inline int genl_register_family_with_ops(struct genl_family *family, | 152 | static 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 | |||
164 | int genl_unregister_family(struct genl_family *family); | 175 | int genl_unregister_family(struct genl_family *family); |
165 | int genl_register_mc_group(struct genl_family *family, | 176 | void genl_notify(struct genl_family *family, |
166 | struct genl_multicast_group *grp); | 177 | struct sk_buff *skb, struct net *net, u32 portid, |
167 | void genl_unregister_mc_group(struct genl_family *family, | ||
168 | struct genl_multicast_group *grp); | ||
169 | void 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 | ||
172 | void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, | 180 | void *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 | */ |
255 | static inline int genlmsg_multicast_netns(struct net *net, struct sk_buff *skb, | 264 | static 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 | */ |
268 | static inline int genlmsg_multicast(struct sk_buff *skb, u32 portid, | 282 | static 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 | */ |
283 | int genlmsg_multicast_allns(struct sk_buff *skb, u32 portid, | 303 | int 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 | */ | ||
387 | static 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 | ||
109 | static struct genl_multicast_group dropmon_mcgrps[] = { | ||
110 | { .name = "events", }, | ||
111 | }; | ||
112 | |||
109 | static void send_dm_alert(struct work_struct *work) | 113 | static 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 | ||
93 | static struct genl_multicast_group hsr_network_genl_mcgrp = { | 93 | static 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 | ||
428 | fail_genl_register_mc_group: | ||
429 | genl_unregister_family(&hsr_genl_family); | ||
430 | fail_genl_register_family: | 424 | fail_genl_register_family: |
431 | rtnl_link_unregister(&hsr_link_ops); | 425 | rtnl_link_unregister(&hsr_link_ops); |
432 | fail_rtnl_link_register: | 426 | fail_rtnl_link_register: |
@@ -436,9 +430,7 @@ fail_rtnl_link_register: | |||
436 | 430 | ||
437 | void __exit hsr_netlink_exit(void) | 431 | void __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); | |||
54 | int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info); | 54 | int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info); |
55 | int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info); | 55 | int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info); |
56 | 56 | ||
57 | extern struct genl_multicast_group ieee802154_coord_mcgrp; | 57 | enum ieee802154_mcgrp_ids { |
58 | extern struct genl_multicast_group ieee802154_beacon_mcgrp; | 58 | IEEE802154_COORD_MCGRP, |
59 | IEEE802154_BEACON_MCGRP, | ||
60 | }; | ||
59 | 61 | ||
60 | int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info); | 62 | int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info); |
61 | int ieee802154_associate_resp(struct sk_buff *skb, struct genl_info *info); | 63 | int 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); |
74 | out: | 74 | out: |
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 | ||
128 | static 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 | |||
128 | int __init ieee802154_nl_init(void) | 134 | int __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; | ||
145 | fail: | ||
146 | genl_unregister_family(&nl802154_family); | ||
147 | return rc; | ||
148 | } | 139 | } |
149 | 140 | ||
150 | void __exit ieee802154_nl_exit(void) | 141 | void __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 | ||
42 | struct genl_multicast_group ieee802154_coord_mcgrp = { | ||
43 | .name = IEEE802154_MCAST_COORD_NAME, | ||
44 | }; | ||
45 | |||
46 | struct genl_multicast_group ieee802154_beacon_mcgrp = { | ||
47 | .name = IEEE802154_MCAST_BEACON_NAME, | ||
48 | }; | ||
49 | |||
50 | int ieee802154_nl_assoc_indic(struct net_device *dev, | 42 | int 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 | ||
77 | nla_put_failure: | 69 | nla_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 | ||
103 | nla_put_failure: | 95 | nla_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 | ||
138 | nla_put_failure: | 130 | nla_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 | ||
162 | nla_put_failure: | 154 | nla_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 | ||
188 | nla_put_failure: | 180 | nla_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 | ||
219 | nla_put_failure: | 211 | nla_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 | ||
243 | nla_put_failure: | 235 | nla_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 | ||
150 | int irda_nl_register(void) | 150 | int 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 | ||
156 | void irda_nl_unregister(void) | 155 | void 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 | ||
888 | static int l2tp_nl_init(void) | 888 | static 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 | ||
899 | static void l2tp_nl_cleanup(void) | 894 | static 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 = { | |||
3666 | static int __init ip_vs_genl_register(void) | 3666 | static 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 | ||
3672 | static void ip_vs_genl_unregister(void) | 3672 | static 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[] = { | |||
783 | int __init netlbl_cipsov4_genl_init(void) | 783 | int __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[] = { | |||
779 | int __init netlbl_mgmt_genl_init(void) | 779 | int __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[] = { | |||
1397 | int __init netlbl_unlabel_genl_init(void) | 1397 | int __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 | */ |
69 | static unsigned long mc_group_start = 0x1; | 78 | static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) | |
79 | BIT(GENL_ID_VFS_DQUOT); | ||
70 | static unsigned long *mc_groups = &mc_group_start; | 80 | static unsigned long *mc_groups = &mc_group_start; |
71 | static unsigned long mc_groups_longs = 1; | 81 | static unsigned long mc_groups_longs = 1; |
72 | 82 | ||
73 | static int genl_ctrl_event(int event, void *data); | 83 | static int genl_ctrl_event(int event, struct genl_family *family, |
84 | const struct genl_multicast_group *grp, | ||
85 | int grp_id); | ||
74 | 86 | ||
75 | static inline unsigned int genl_family_hash(unsigned int id) | 87 | static 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 | ||
138 | static struct genl_multicast_group notify_grp; | 151 | static 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 | */ | ||
151 | int 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 */ | 211 | static struct genl_family genl_ctrl; |
164 | if (grp == ¬ify_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 | ||
213 | static 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 | } |
233 | EXPORT_SYMBOL(genl_register_mc_group); | ||
234 | 287 | ||
235 | static void __genl_unregister_mc_group(struct genl_family *family, | 288 | static 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 | */ | ||
269 | void 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 | } | ||
276 | EXPORT_SYMBOL(genl_unregister_mc_group); | ||
277 | |||
278 | static 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 | ||
286 | static int genl_validate_ops(struct genl_family *family) | 313 | static int genl_validate_ops(struct genl_family *family) |
@@ -326,7 +353,7 @@ static int genl_validate_ops(struct genl_family *family) | |||
326 | */ | 353 | */ |
327 | int __genl_register_family(struct genl_family *family) | 354 | int __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 | ||
706 | static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 portid, | 742 | static 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 | ||
796 | static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp, | 833 | static struct sk_buff * |
797 | u32 portid, int seq, u8 cmd) | 834 | ctrl_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 | ||
868 | static int genl_ctrl_event(int event, void *data) | 908 | static 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 | ||
909 | static struct genl_ops genl_ctrl_ops = { | 949 | static 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 | ||
916 | static struct genl_multicast_group notify_grp = { | 958 | static struct genl_multicast_group genl_ctrl_groups[] = { |
917 | .name = "notify", | 959 | { .name = "notify", }, |
918 | }; | 960 | }; |
919 | 961 | ||
920 | static int __net_init genl_pernet_init(struct net *net) | 962 | static 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, ¬ify_grp); | ||
966 | if (err < 0) | ||
967 | goto problem; | ||
968 | |||
969 | return 0; | 1008 | return 0; |
970 | 1009 | ||
971 | problem: | 1010 | problem: |
@@ -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 | ||
1006 | int genlmsg_multicast_allns(struct sk_buff *skb, u32 portid, unsigned int group, | 1045 | int 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 | } |
1011 | EXPORT_SYMBOL(genlmsg_multicast_allns); | 1053 | EXPORT_SYMBOL(genlmsg_multicast_allns); |
1012 | 1054 | ||
1013 | void genl_notify(struct sk_buff *skb, struct net *net, u32 portid, u32 group, | 1055 | void 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 | } |
1024 | EXPORT_SYMBOL(genl_notify); | 1070 | EXPORT_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 | ||
33 | static struct genl_multicast_group nfc_genl_event_mcgrp = { | 33 | static 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 | ||
37 | static struct genl_family nfc_genl_family = { | 37 | static 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 | ||
199 | nla_put_failure: | 199 | nla_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 | ||
419 | nla_put_failure: | 419 | nla_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 | ||
62 | int ovs_net_id __read_mostly; | 62 | int ovs_net_id __read_mostly; |
63 | 63 | ||
64 | static void ovs_notify(struct sk_buff *skb, struct genl_info *info, | 64 | static 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 | ||
886 | err_flow_free: | 886 | err_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; |
995 | unlock: | 995 | unlock: |
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 | ||
1243 | err_destroy_local_port: | 1243 | err_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; |
1308 | unlock: | 1308 | unlock: |
@@ -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; |
1339 | unlock: | 1339 | unlock: |
@@ -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 | ||
1428 | static struct genl_family dp_vport_genl_family = { | 1428 | struct 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 | ||
1600 | exit_unlock: | 1600 | exit_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 | ||
1648 | exit_free: | 1648 | exit_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 | ||
1684 | exit_unlock: | 1684 | exit_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 | ||
1787 | static const struct genl_family_and_ops dp_genl_families[] = { | 1787 | static 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 | ||
179 | extern struct notifier_block ovs_dp_device_notifier; | 179 | extern struct notifier_block ovs_dp_device_notifier; |
180 | extern struct genl_family dp_vport_genl_family; | ||
180 | extern struct genl_multicast_group ovs_dp_vport_multicast_group; | 181 | extern struct genl_multicast_group ovs_dp_vport_multicast_group; |
181 | 182 | ||
182 | void ovs_dp_process_received_packet(struct vport *, struct sk_buff *); | 183 | void 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 | ||
48 | void ovs_dp_notify_wq(struct work_struct *work) | 47 | void 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 | ||
79 | static struct genl_ops tipc_genl_ops = { | 79 | static 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 | ||
84 | static int tipc_genl_family_registered; | 86 | static 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); |
181 | out: | 182 | out: |
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 | ||
582 | struct genl_multicast_group wimax_gnl_mcg = { | 583 | static 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 | ||
614 | error_mc_group: | ||
615 | genl_unregister_family(&wimax_gnl_family); | 613 | genl_unregister_family(&wimax_gnl_family); |
616 | error_register_family: | 614 | error_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 */ |
88 | extern struct genl_family wimax_gnl_family; | 88 | extern struct genl_family wimax_gnl_family; |
89 | extern struct genl_multicast_group wimax_gnl_mcg; | ||
90 | 89 | ||
91 | /* ops */ | 90 | /* ops */ |
92 | int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info); | 91 | int 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 */ | ||
51 | enum 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 | |||
59 | static 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 */ |
51 | static struct wireless_dev * | 70 | static 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 |
6659 | static struct genl_multicast_group nl80211_testmode_mcgrp = { | ||
6660 | .name = "testmode", | ||
6661 | }; | ||
6662 | |||
6663 | static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) | 6678 | static 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 | } |
6874 | EXPORT_SYMBOL(cfg80211_testmode_event); | 6889 | EXPORT_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 | ||
9569 | static struct genl_multicast_group nl80211_mlme_mcgrp = { | ||
9570 | .name = "mlme", | ||
9571 | }; | ||
9572 | |||
9573 | /* multicast groups */ | ||
9574 | static struct genl_multicast_group nl80211_config_mcgrp = { | ||
9575 | .name = "config", | ||
9576 | }; | ||
9577 | static struct genl_multicast_group nl80211_scan_mcgrp = { | ||
9578 | .name = "scan", | ||
9579 | }; | ||
9580 | static struct genl_multicast_group nl80211_regulatory_mcgrp = { | ||
9581 | .name = "regulatory", | ||
9582 | }; | ||
9583 | |||
9584 | /* notification functions */ | 9584 | /* notification functions */ |
9585 | 9585 | ||
9586 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) | 9586 | void 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 | ||
9604 | static int nl80211_add_scan_req(struct sk_buff *msg, | 9604 | static 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 | ||
9714 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, | 9714 | void 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 | ||
9733 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, | 9733 | void 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 | ||
9752 | void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, | 9752 | void 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 | ||
9771 | void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, | 9771 | void 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 | } |
10368 | EXPORT_SYMBOL(cfg80211_new_sta); | 10368 | EXPORT_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 | } |
11285 | EXPORT_SYMBOL(cfg80211_ft_event); | 11285 | EXPORT_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; |