diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/netlink/genetlink.c | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 6efb0e9036b5..e9ef640200b4 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -77,7 +77,8 @@ static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_VFS_DQUOT); | |||
77 | static unsigned long *mc_groups = &mc_group_start; | 77 | static unsigned long *mc_groups = &mc_group_start; |
78 | static unsigned long mc_groups_longs = 1; | 78 | static unsigned long mc_groups_longs = 1; |
79 | 79 | ||
80 | static int genl_ctrl_event(int event, void *data); | 80 | static int genl_ctrl_event(int event, struct genl_family *family, |
81 | struct genl_multicast_group *grp); | ||
81 | 82 | ||
82 | static inline unsigned int genl_family_hash(unsigned int id) | 83 | static inline unsigned int genl_family_hash(unsigned int id) |
83 | { | 84 | { |
@@ -235,9 +236,8 @@ int genl_register_mc_group(struct genl_family *family, | |||
235 | grp->id = id; | 236 | grp->id = id; |
236 | set_bit(id, mc_groups); | 237 | set_bit(id, mc_groups); |
237 | list_add_tail(&grp->list, &family->mcast_groups); | 238 | list_add_tail(&grp->list, &family->mcast_groups); |
238 | grp->family = family; | ||
239 | 239 | ||
240 | genl_ctrl_event(CTRL_CMD_NEWMCAST_GRP, grp); | 240 | genl_ctrl_event(CTRL_CMD_NEWMCAST_GRP, family, grp); |
241 | out: | 241 | out: |
242 | genl_unlock_all(); | 242 | genl_unlock_all(); |
243 | return err; | 243 | return err; |
@@ -248,7 +248,6 @@ static void __genl_unregister_mc_group(struct genl_family *family, | |||
248 | struct genl_multicast_group *grp) | 248 | struct genl_multicast_group *grp) |
249 | { | 249 | { |
250 | struct net *net; | 250 | struct net *net; |
251 | BUG_ON(grp->family != family); | ||
252 | 251 | ||
253 | netlink_table_grab(); | 252 | netlink_table_grab(); |
254 | rcu_read_lock(); | 253 | rcu_read_lock(); |
@@ -260,9 +259,8 @@ static void __genl_unregister_mc_group(struct genl_family *family, | |||
260 | if (grp->id != 1) | 259 | if (grp->id != 1) |
261 | clear_bit(grp->id, mc_groups); | 260 | clear_bit(grp->id, mc_groups); |
262 | list_del(&grp->list); | 261 | list_del(&grp->list); |
263 | genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, grp); | 262 | genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, family, grp); |
264 | grp->id = 0; | 263 | grp->id = 0; |
265 | grp->family = NULL; | ||
266 | } | 264 | } |
267 | 265 | ||
268 | static void genl_unregister_mc_groups(struct genl_family *family) | 266 | static void genl_unregister_mc_groups(struct genl_family *family) |
@@ -364,7 +362,7 @@ int __genl_register_family(struct genl_family *family) | |||
364 | list_add_tail(&family->family_list, genl_family_chain(family->id)); | 362 | list_add_tail(&family->family_list, genl_family_chain(family->id)); |
365 | genl_unlock_all(); | 363 | genl_unlock_all(); |
366 | 364 | ||
367 | genl_ctrl_event(CTRL_CMD_NEWFAMILY, family); | 365 | genl_ctrl_event(CTRL_CMD_NEWFAMILY, family, NULL); |
368 | 366 | ||
369 | return 0; | 367 | return 0; |
370 | 368 | ||
@@ -400,7 +398,7 @@ int genl_unregister_family(struct genl_family *family) | |||
400 | genl_unlock_all(); | 398 | genl_unlock_all(); |
401 | 399 | ||
402 | kfree(family->attrbuf); | 400 | kfree(family->attrbuf); |
403 | genl_ctrl_event(CTRL_CMD_DELFAMILY, family); | 401 | genl_ctrl_event(CTRL_CMD_DELFAMILY, family, NULL); |
404 | return 0; | 402 | return 0; |
405 | } | 403 | } |
406 | 404 | ||
@@ -693,7 +691,8 @@ nla_put_failure: | |||
693 | return -EMSGSIZE; | 691 | return -EMSGSIZE; |
694 | } | 692 | } |
695 | 693 | ||
696 | static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 portid, | 694 | static int ctrl_fill_mcgrp_info(struct genl_family *family, |
695 | struct genl_multicast_group *grp, u32 portid, | ||
697 | u32 seq, u32 flags, struct sk_buff *skb, | 696 | u32 seq, u32 flags, struct sk_buff *skb, |
698 | u8 cmd) | 697 | u8 cmd) |
699 | { | 698 | { |
@@ -705,8 +704,8 @@ static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 portid, | |||
705 | if (hdr == NULL) | 704 | if (hdr == NULL) |
706 | return -1; | 705 | return -1; |
707 | 706 | ||
708 | if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, grp->family->name) || | 707 | if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, family->name) || |
709 | nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, grp->family->id)) | 708 | nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, family->id)) |
710 | goto nla_put_failure; | 709 | goto nla_put_failure; |
711 | 710 | ||
712 | nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS); | 711 | nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS); |
@@ -783,7 +782,8 @@ static struct sk_buff *ctrl_build_family_msg(struct genl_family *family, | |||
783 | return skb; | 782 | return skb; |
784 | } | 783 | } |
785 | 784 | ||
786 | static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp, | 785 | static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_family *family, |
786 | struct genl_multicast_group *grp, | ||
787 | u32 portid, int seq, u8 cmd) | 787 | u32 portid, int seq, u8 cmd) |
788 | { | 788 | { |
789 | struct sk_buff *skb; | 789 | struct sk_buff *skb; |
@@ -793,7 +793,7 @@ static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp, | |||
793 | if (skb == NULL) | 793 | if (skb == NULL) |
794 | return ERR_PTR(-ENOBUFS); | 794 | return ERR_PTR(-ENOBUFS); |
795 | 795 | ||
796 | err = ctrl_fill_mcgrp_info(grp, portid, seq, 0, skb, cmd); | 796 | err = ctrl_fill_mcgrp_info(family, grp, portid, seq, 0, skb, cmd); |
797 | if (err < 0) { | 797 | if (err < 0) { |
798 | nlmsg_free(skb); | 798 | nlmsg_free(skb); |
799 | return ERR_PTR(err); | 799 | return ERR_PTR(err); |
@@ -855,11 +855,10 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info) | |||
855 | return genlmsg_reply(msg, info); | 855 | return genlmsg_reply(msg, info); |
856 | } | 856 | } |
857 | 857 | ||
858 | static int genl_ctrl_event(int event, void *data) | 858 | static int genl_ctrl_event(int event, struct genl_family *family, |
859 | struct genl_multicast_group *grp) | ||
859 | { | 860 | { |
860 | struct sk_buff *msg; | 861 | struct sk_buff *msg; |
861 | struct genl_family *family; | ||
862 | struct genl_multicast_group *grp; | ||
863 | 862 | ||
864 | /* genl is still initialising */ | 863 | /* genl is still initialising */ |
865 | if (!init_net.genl_sock) | 864 | if (!init_net.genl_sock) |
@@ -868,14 +867,13 @@ static int genl_ctrl_event(int event, void *data) | |||
868 | switch (event) { | 867 | switch (event) { |
869 | case CTRL_CMD_NEWFAMILY: | 868 | case CTRL_CMD_NEWFAMILY: |
870 | case CTRL_CMD_DELFAMILY: | 869 | case CTRL_CMD_DELFAMILY: |
871 | family = data; | 870 | WARN_ON(grp); |
872 | msg = ctrl_build_family_msg(family, 0, 0, event); | 871 | msg = ctrl_build_family_msg(family, 0, 0, event); |
873 | break; | 872 | break; |
874 | case CTRL_CMD_NEWMCAST_GRP: | 873 | case CTRL_CMD_NEWMCAST_GRP: |
875 | case CTRL_CMD_DELMCAST_GRP: | 874 | case CTRL_CMD_DELMCAST_GRP: |
876 | grp = data; | 875 | BUG_ON(!grp); |
877 | family = grp->family; | 876 | msg = ctrl_build_mcgrp_msg(family, grp, 0, 0, event); |
878 | msg = ctrl_build_mcgrp_msg(data, 0, 0, event); | ||
879 | break; | 877 | break; |
880 | default: | 878 | default: |
881 | return -EINVAL; | 879 | return -EINVAL; |