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; |
