aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink/genetlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlink/genetlink.c')
-rw-r--r--net/netlink/genetlink.c225
1 files changed, 163 insertions, 62 deletions
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index eed4c6a8afc0..d07ecda0a92d 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -18,8 +18,6 @@
18#include <net/sock.h> 18#include <net/sock.h>
19#include <net/genetlink.h> 19#include <net/genetlink.h>
20 20
21struct sock *genl_sock = NULL;
22
23static DEFINE_MUTEX(genl_mutex); /* serialization of message processing */ 21static DEFINE_MUTEX(genl_mutex); /* serialization of message processing */
24 22
25static inline void genl_lock(void) 23static inline void genl_lock(void)
@@ -99,25 +97,17 @@ static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
99*/ 97*/
100static inline u16 genl_generate_id(void) 98static inline u16 genl_generate_id(void)
101{ 99{
102 static u16 id_gen_idx; 100 static u16 id_gen_idx = GENL_MIN_ID;
103 int overflowed = 0; 101 int i;
104 102
105 do { 103 for (i = 0; i <= GENL_MAX_ID - GENL_MIN_ID; i++) {
106 if (id_gen_idx == 0) 104 if (!genl_family_find_byid(id_gen_idx))
105 return id_gen_idx;
106 if (++id_gen_idx > GENL_MAX_ID)
107 id_gen_idx = GENL_MIN_ID; 107 id_gen_idx = GENL_MIN_ID;
108 }
108 109
109 if (++id_gen_idx > GENL_MAX_ID) { 110 return 0;
110 if (!overflowed) {
111 overflowed = 1;
112 id_gen_idx = 0;
113 continue;
114 } else
115 return 0;
116 }
117
118 } while (genl_family_find_byid(id_gen_idx));
119
120 return id_gen_idx;
121} 111}
122 112
123static struct genl_multicast_group notify_grp; 113static struct genl_multicast_group notify_grp;
@@ -138,7 +128,7 @@ int genl_register_mc_group(struct genl_family *family,
138{ 128{
139 int id; 129 int id;
140 unsigned long *new_groups; 130 unsigned long *new_groups;
141 int err; 131 int err = 0;
142 132
143 BUG_ON(grp->name[0] == '\0'); 133 BUG_ON(grp->name[0] == '\0');
144 134
@@ -175,10 +165,34 @@ int genl_register_mc_group(struct genl_family *family,
175 mc_groups_longs++; 165 mc_groups_longs++;
176 } 166 }
177 167
178 err = netlink_change_ngroups(genl_sock, 168 if (family->netnsok) {
179 mc_groups_longs * BITS_PER_LONG); 169 struct net *net;
180 if (err) 170
181 goto out; 171 netlink_table_grab();
172 rcu_read_lock();
173 for_each_net_rcu(net) {
174 err = __netlink_change_ngroups(net->genl_sock,
175 mc_groups_longs * BITS_PER_LONG);
176 if (err) {
177 /*
178 * No need to roll back, can only fail if
179 * memory allocation fails and then the
180 * number of _possible_ groups has been
181 * increased on some sockets which is ok.
182 */
183 rcu_read_unlock();
184 netlink_table_ungrab();
185 goto out;
186 }
187 }
188 rcu_read_unlock();
189 netlink_table_ungrab();
190 } else {
191 err = netlink_change_ngroups(init_net.genl_sock,
192 mc_groups_longs * BITS_PER_LONG);
193 if (err)
194 goto out;
195 }
182 196
183 grp->id = id; 197 grp->id = id;
184 set_bit(id, mc_groups); 198 set_bit(id, mc_groups);
@@ -195,8 +209,16 @@ EXPORT_SYMBOL(genl_register_mc_group);
195static void __genl_unregister_mc_group(struct genl_family *family, 209static void __genl_unregister_mc_group(struct genl_family *family,
196 struct genl_multicast_group *grp) 210 struct genl_multicast_group *grp)
197{ 211{
212 struct net *net;
198 BUG_ON(grp->family != family); 213 BUG_ON(grp->family != family);
199 netlink_clear_multicast_users(genl_sock, grp->id); 214
215 netlink_table_grab();
216 rcu_read_lock();
217 for_each_net_rcu(net)
218 __netlink_clear_multicast_users(net->genl_sock, grp->id);
219 rcu_read_unlock();
220 netlink_table_ungrab();
221
200 clear_bit(grp->id, mc_groups); 222 clear_bit(grp->id, mc_groups);
201 list_del(&grp->list); 223 list_del(&grp->list);
202 genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, grp); 224 genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, grp);
@@ -344,11 +366,6 @@ int genl_register_family(struct genl_family *family)
344 goto errout_locked; 366 goto errout_locked;
345 } 367 }
346 368
347 if (genl_family_find_byid(family->id)) {
348 err = -EEXIST;
349 goto errout_locked;
350 }
351
352 if (family->id == GENL_ID_GENERATE) { 369 if (family->id == GENL_ID_GENERATE) {
353 u16 newid = genl_generate_id(); 370 u16 newid = genl_generate_id();
354 371
@@ -358,6 +375,9 @@ int genl_register_family(struct genl_family *family)
358 } 375 }
359 376
360 family->id = newid; 377 family->id = newid;
378 } else if (genl_family_find_byid(family->id)) {
379 err = -EEXIST;
380 goto errout_locked;
361 } 381 }
362 382
363 if (family->maxattr) { 383 if (family->maxattr) {
@@ -467,6 +487,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
467{ 487{
468 struct genl_ops *ops; 488 struct genl_ops *ops;
469 struct genl_family *family; 489 struct genl_family *family;
490 struct net *net = sock_net(skb->sk);
470 struct genl_info info; 491 struct genl_info info;
471 struct genlmsghdr *hdr = nlmsg_data(nlh); 492 struct genlmsghdr *hdr = nlmsg_data(nlh);
472 int hdrlen, err; 493 int hdrlen, err;
@@ -475,6 +496,10 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
475 if (family == NULL) 496 if (family == NULL)
476 return -ENOENT; 497 return -ENOENT;
477 498
499 /* this family doesn't exist in this netns */
500 if (!family->netnsok && !net_eq(net, &init_net))
501 return -ENOENT;
502
478 hdrlen = GENL_HDRLEN + family->hdrsize; 503 hdrlen = GENL_HDRLEN + family->hdrsize;
479 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) 504 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
480 return -EINVAL; 505 return -EINVAL;
@@ -492,7 +517,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
492 return -EOPNOTSUPP; 517 return -EOPNOTSUPP;
493 518
494 genl_unlock(); 519 genl_unlock();
495 err = netlink_dump_start(genl_sock, skb, nlh, 520 err = netlink_dump_start(net->genl_sock, skb, nlh,
496 ops->dumpit, ops->done); 521 ops->dumpit, ops->done);
497 genl_lock(); 522 genl_lock();
498 return err; 523 return err;
@@ -514,6 +539,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
514 info.genlhdr = nlmsg_data(nlh); 539 info.genlhdr = nlmsg_data(nlh);
515 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; 540 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
516 info.attrs = family->attrbuf; 541 info.attrs = family->attrbuf;
542 genl_info_net_set(&info, net);
517 543
518 return ops->doit(skb, &info); 544 return ops->doit(skb, &info);
519} 545}
@@ -534,6 +560,7 @@ static struct genl_family genl_ctrl = {
534 .name = "nlctrl", 560 .name = "nlctrl",
535 .version = 0x2, 561 .version = 0x2,
536 .maxattr = CTRL_ATTR_MAX, 562 .maxattr = CTRL_ATTR_MAX,
563 .netnsok = true,
537}; 564};
538 565
539static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq, 566static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
@@ -650,6 +677,7 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
650 677
651 int i, n = 0; 678 int i, n = 0;
652 struct genl_family *rt; 679 struct genl_family *rt;
680 struct net *net = sock_net(skb->sk);
653 int chains_to_skip = cb->args[0]; 681 int chains_to_skip = cb->args[0];
654 int fams_to_skip = cb->args[1]; 682 int fams_to_skip = cb->args[1];
655 683
@@ -658,6 +686,8 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
658 continue; 686 continue;
659 n = 0; 687 n = 0;
660 list_for_each_entry(rt, genl_family_chain(i), family_list) { 688 list_for_each_entry(rt, genl_family_chain(i), family_list) {
689 if (!rt->netnsok && !net_eq(net, &init_net))
690 continue;
661 if (++n < fams_to_skip) 691 if (++n < fams_to_skip)
662 continue; 692 continue;
663 if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).pid, 693 if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).pid,
@@ -729,6 +759,7 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
729 if (info->attrs[CTRL_ATTR_FAMILY_ID]) { 759 if (info->attrs[CTRL_ATTR_FAMILY_ID]) {
730 u16 id = nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID]); 760 u16 id = nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID]);
731 res = genl_family_find_byid(id); 761 res = genl_family_find_byid(id);
762 err = -ENOENT;
732 } 763 }
733 764
734 if (info->attrs[CTRL_ATTR_FAMILY_NAME]) { 765 if (info->attrs[CTRL_ATTR_FAMILY_NAME]) {
@@ -736,49 +767,61 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
736 767
737 name = nla_data(info->attrs[CTRL_ATTR_FAMILY_NAME]); 768 name = nla_data(info->attrs[CTRL_ATTR_FAMILY_NAME]);
738 res = genl_family_find_byname(name); 769 res = genl_family_find_byname(name);
770 err = -ENOENT;
739 } 771 }
740 772
741 if (res == NULL) { 773 if (res == NULL)
742 err = -ENOENT; 774 return err;
743 goto errout; 775
776 if (!res->netnsok && !net_eq(genl_info_net(info), &init_net)) {
777 /* family doesn't exist here */
778 return -ENOENT;
744 } 779 }
745 780
746 msg = ctrl_build_family_msg(res, info->snd_pid, info->snd_seq, 781 msg = ctrl_build_family_msg(res, info->snd_pid, info->snd_seq,
747 CTRL_CMD_NEWFAMILY); 782 CTRL_CMD_NEWFAMILY);
748 if (IS_ERR(msg)) { 783 if (IS_ERR(msg))
749 err = PTR_ERR(msg); 784 return PTR_ERR(msg);
750 goto errout;
751 }
752 785
753 err = genlmsg_reply(msg, info); 786 return genlmsg_reply(msg, info);
754errout:
755 return err;
756} 787}
757 788
758static int genl_ctrl_event(int event, void *data) 789static int genl_ctrl_event(int event, void *data)
759{ 790{
760 struct sk_buff *msg; 791 struct sk_buff *msg;
792 struct genl_family *family;
793 struct genl_multicast_group *grp;
761 794
762 if (genl_sock == NULL) 795 /* genl is still initialising */
796 if (!init_net.genl_sock)
763 return 0; 797 return 0;
764 798
765 switch (event) { 799 switch (event) {
766 case CTRL_CMD_NEWFAMILY: 800 case CTRL_CMD_NEWFAMILY:
767 case CTRL_CMD_DELFAMILY: 801 case CTRL_CMD_DELFAMILY:
768 msg = ctrl_build_family_msg(data, 0, 0, event); 802 family = data;
769 if (IS_ERR(msg)) 803 msg = ctrl_build_family_msg(family, 0, 0, event);
770 return PTR_ERR(msg);
771
772 genlmsg_multicast(msg, 0, GENL_ID_CTRL, GFP_KERNEL);
773 break; 804 break;
774 case CTRL_CMD_NEWMCAST_GRP: 805 case CTRL_CMD_NEWMCAST_GRP:
775 case CTRL_CMD_DELMCAST_GRP: 806 case CTRL_CMD_DELMCAST_GRP:
807 grp = data;
808 family = grp->family;
776 msg = ctrl_build_mcgrp_msg(data, 0, 0, event); 809 msg = ctrl_build_mcgrp_msg(data, 0, 0, event);
777 if (IS_ERR(msg))
778 return PTR_ERR(msg);
779
780 genlmsg_multicast(msg, 0, GENL_ID_CTRL, GFP_KERNEL);
781 break; 810 break;
811 default:
812 return -EINVAL;
813 }
814
815 if (IS_ERR(msg))
816 return PTR_ERR(msg);
817
818 if (!family->netnsok) {
819 genlmsg_multicast_netns(&init_net, msg, 0,
820 GENL_ID_CTRL, GFP_KERNEL);
821 } else {
822 rcu_read_lock();
823 genlmsg_multicast_allns(msg, 0, GENL_ID_CTRL, GFP_ATOMIC);
824 rcu_read_unlock();
782 } 825 }
783 826
784 return 0; 827 return 0;
@@ -795,6 +838,33 @@ static struct genl_multicast_group notify_grp = {
795 .name = "notify", 838 .name = "notify",
796}; 839};
797 840
841static int __net_init genl_pernet_init(struct net *net)
842{
843 /* we'll bump the group number right afterwards */
844 net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC, 0,
845 genl_rcv, &genl_mutex,
846 THIS_MODULE);
847
848 if (!net->genl_sock && net_eq(net, &init_net))
849 panic("GENL: Cannot initialize generic netlink\n");
850
851 if (!net->genl_sock)
852 return -ENOMEM;
853
854 return 0;
855}
856
857static void __net_exit genl_pernet_exit(struct net *net)
858{
859 netlink_kernel_release(net->genl_sock);
860 net->genl_sock = NULL;
861}
862
863static struct pernet_operations genl_pernet_ops = {
864 .init = genl_pernet_init,
865 .exit = genl_pernet_exit,
866};
867
798static int __init genl_init(void) 868static int __init genl_init(void)
799{ 869{
800 int i, err; 870 int i, err;
@@ -804,36 +874,67 @@ static int __init genl_init(void)
804 874
805 err = genl_register_family(&genl_ctrl); 875 err = genl_register_family(&genl_ctrl);
806 if (err < 0) 876 if (err < 0)
807 goto errout; 877 goto problem;
808 878
809 err = genl_register_ops(&genl_ctrl, &genl_ctrl_ops); 879 err = genl_register_ops(&genl_ctrl, &genl_ctrl_ops);
810 if (err < 0) 880 if (err < 0)
811 goto errout_register; 881 goto problem;
812 882
813 netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV); 883 netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
814 884
815 /* we'll bump the group number right afterwards */ 885 err = register_pernet_subsys(&genl_pernet_ops);
816 genl_sock = netlink_kernel_create(&init_net, NETLINK_GENERIC, 0, 886 if (err)
817 genl_rcv, &genl_mutex, THIS_MODULE); 887 goto problem;
818 if (genl_sock == NULL)
819 panic("GENL: Cannot initialize generic netlink\n");
820 888
821 err = genl_register_mc_group(&genl_ctrl, &notify_grp); 889 err = genl_register_mc_group(&genl_ctrl, &notify_grp);
822 if (err < 0) 890 if (err < 0)
823 goto errout_register; 891 goto problem;
824 892
825 return 0; 893 return 0;
826 894
827errout_register: 895problem:
828 genl_unregister_family(&genl_ctrl);
829errout:
830 panic("GENL: Cannot register controller: %d\n", err); 896 panic("GENL: Cannot register controller: %d\n", err);
831} 897}
832 898
833subsys_initcall(genl_init); 899subsys_initcall(genl_init);
834 900
835EXPORT_SYMBOL(genl_sock);
836EXPORT_SYMBOL(genl_register_ops); 901EXPORT_SYMBOL(genl_register_ops);
837EXPORT_SYMBOL(genl_unregister_ops); 902EXPORT_SYMBOL(genl_unregister_ops);
838EXPORT_SYMBOL(genl_register_family); 903EXPORT_SYMBOL(genl_register_family);
839EXPORT_SYMBOL(genl_unregister_family); 904EXPORT_SYMBOL(genl_unregister_family);
905
906static int genlmsg_mcast(struct sk_buff *skb, u32 pid, unsigned long group,
907 gfp_t flags)
908{
909 struct sk_buff *tmp;
910 struct net *net, *prev = NULL;
911 int err;
912
913 for_each_net_rcu(net) {
914 if (prev) {
915 tmp = skb_clone(skb, flags);
916 if (!tmp) {
917 err = -ENOMEM;
918 goto error;
919 }
920 err = nlmsg_multicast(prev->genl_sock, tmp,
921 pid, group, flags);
922 if (err)
923 goto error;
924 }
925
926 prev = net;
927 }
928
929 return nlmsg_multicast(prev->genl_sock, skb, pid, group, flags);
930 error:
931 kfree_skb(skb);
932 return err;
933}
934
935int genlmsg_multicast_allns(struct sk_buff *skb, u32 pid, unsigned int group,
936 gfp_t flags)
937{
938 return genlmsg_mcast(skb, pid, group, flags);
939}
940EXPORT_SYMBOL(genlmsg_multicast_allns);