diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /net/netlink/genetlink.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'net/netlink/genetlink.c')
-rw-r--r-- | net/netlink/genetlink.c | 153 |
1 files changed, 40 insertions, 113 deletions
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index f2aabb6f410..482fa571b4e 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -33,14 +33,6 @@ void genl_unlock(void) | |||
33 | } | 33 | } |
34 | EXPORT_SYMBOL(genl_unlock); | 34 | EXPORT_SYMBOL(genl_unlock); |
35 | 35 | ||
36 | #ifdef CONFIG_LOCKDEP | ||
37 | int lockdep_genl_is_held(void) | ||
38 | { | ||
39 | return lockdep_is_held(&genl_mutex); | ||
40 | } | ||
41 | EXPORT_SYMBOL(lockdep_genl_is_held); | ||
42 | #endif | ||
43 | |||
44 | #define GENL_FAM_TAB_SIZE 16 | 36 | #define GENL_FAM_TAB_SIZE 16 |
45 | #define GENL_FAM_TAB_MASK (GENL_FAM_TAB_SIZE - 1) | 37 | #define GENL_FAM_TAB_MASK (GENL_FAM_TAB_SIZE - 1) |
46 | 38 | ||
@@ -106,7 +98,7 @@ static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family) | |||
106 | /* Of course we are going to have problems once we hit | 98 | /* Of course we are going to have problems once we hit |
107 | * 2^16 alive types, but that can only happen by year 2K | 99 | * 2^16 alive types, but that can only happen by year 2K |
108 | */ | 100 | */ |
109 | static u16 genl_generate_id(void) | 101 | static inline u16 genl_generate_id(void) |
110 | { | 102 | { |
111 | static u16 id_gen_idx = GENL_MIN_ID; | 103 | static u16 id_gen_idx = GENL_MIN_ID; |
112 | int i; | 104 | int i; |
@@ -498,37 +490,6 @@ int genl_unregister_family(struct genl_family *family) | |||
498 | } | 490 | } |
499 | EXPORT_SYMBOL(genl_unregister_family); | 491 | EXPORT_SYMBOL(genl_unregister_family); |
500 | 492 | ||
501 | /** | ||
502 | * genlmsg_put - Add generic netlink header to netlink message | ||
503 | * @skb: socket buffer holding the message | ||
504 | * @portid: netlink portid the message is addressed to | ||
505 | * @seq: sequence number (usually the one of the sender) | ||
506 | * @family: generic netlink family | ||
507 | * @flags: netlink message flags | ||
508 | * @cmd: generic netlink command | ||
509 | * | ||
510 | * Returns pointer to user specific header | ||
511 | */ | ||
512 | void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, | ||
513 | struct genl_family *family, int flags, u8 cmd) | ||
514 | { | ||
515 | struct nlmsghdr *nlh; | ||
516 | struct genlmsghdr *hdr; | ||
517 | |||
518 | nlh = nlmsg_put(skb, portid, seq, family->id, GENL_HDRLEN + | ||
519 | family->hdrsize, flags); | ||
520 | if (nlh == NULL) | ||
521 | return NULL; | ||
522 | |||
523 | hdr = nlmsg_data(nlh); | ||
524 | hdr->cmd = cmd; | ||
525 | hdr->version = family->version; | ||
526 | hdr->reserved = 0; | ||
527 | |||
528 | return (char *) hdr + GENL_HDRLEN; | ||
529 | } | ||
530 | EXPORT_SYMBOL(genlmsg_put); | ||
531 | |||
532 | static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 493 | static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
533 | { | 494 | { |
534 | struct genl_ops *ops; | 495 | struct genl_ops *ops; |
@@ -555,7 +516,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
555 | return -EOPNOTSUPP; | 516 | return -EOPNOTSUPP; |
556 | 517 | ||
557 | if ((ops->flags & GENL_ADMIN_PERM) && | 518 | if ((ops->flags & GENL_ADMIN_PERM) && |
558 | !capable(CAP_NET_ADMIN)) | 519 | security_netlink_recv(skb, CAP_NET_ADMIN)) |
559 | return -EPERM; | 520 | return -EPERM; |
560 | 521 | ||
561 | if (nlh->nlmsg_flags & NLM_F_DUMP) { | 522 | if (nlh->nlmsg_flags & NLM_F_DUMP) { |
@@ -563,13 +524,8 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
563 | return -EOPNOTSUPP; | 524 | return -EOPNOTSUPP; |
564 | 525 | ||
565 | genl_unlock(); | 526 | genl_unlock(); |
566 | { | 527 | err = netlink_dump_start(net->genl_sock, skb, nlh, |
567 | struct netlink_dump_control c = { | 528 | ops->dumpit, ops->done, 0); |
568 | .dump = ops->dumpit, | ||
569 | .done = ops->done, | ||
570 | }; | ||
571 | err = netlink_dump_start(net->genl_sock, skb, nlh, &c); | ||
572 | } | ||
573 | genl_lock(); | 529 | genl_lock(); |
574 | return err; | 530 | return err; |
575 | } | 531 | } |
@@ -585,7 +541,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
585 | } | 541 | } |
586 | 542 | ||
587 | info.snd_seq = nlh->nlmsg_seq; | 543 | info.snd_seq = nlh->nlmsg_seq; |
588 | info.snd_portid = NETLINK_CB(skb).portid; | 544 | info.snd_pid = NETLINK_CB(skb).pid; |
589 | info.nlhdr = nlh; | 545 | info.nlhdr = nlh; |
590 | info.genlhdr = nlmsg_data(nlh); | 546 | info.genlhdr = nlmsg_data(nlh); |
591 | info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; | 547 | info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; |
@@ -626,21 +582,20 @@ static struct genl_family genl_ctrl = { | |||
626 | .netnsok = true, | 582 | .netnsok = true, |
627 | }; | 583 | }; |
628 | 584 | ||
629 | static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq, | 585 | static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq, |
630 | u32 flags, struct sk_buff *skb, u8 cmd) | 586 | u32 flags, struct sk_buff *skb, u8 cmd) |
631 | { | 587 | { |
632 | void *hdr; | 588 | void *hdr; |
633 | 589 | ||
634 | hdr = genlmsg_put(skb, portid, seq, &genl_ctrl, flags, cmd); | 590 | hdr = genlmsg_put(skb, pid, seq, &genl_ctrl, flags, cmd); |
635 | if (hdr == NULL) | 591 | if (hdr == NULL) |
636 | return -1; | 592 | return -1; |
637 | 593 | ||
638 | if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, family->name) || | 594 | NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, family->name); |
639 | nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, family->id) || | 595 | NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, family->id); |
640 | nla_put_u32(skb, CTRL_ATTR_VERSION, family->version) || | 596 | NLA_PUT_U32(skb, CTRL_ATTR_VERSION, family->version); |
641 | nla_put_u32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize) || | 597 | NLA_PUT_U32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize); |
642 | nla_put_u32(skb, CTRL_ATTR_MAXATTR, family->maxattr)) | 598 | NLA_PUT_U32(skb, CTRL_ATTR_MAXATTR, family->maxattr); |
643 | goto nla_put_failure; | ||
644 | 599 | ||
645 | if (!list_empty(&family->ops_list)) { | 600 | if (!list_empty(&family->ops_list)) { |
646 | struct nlattr *nla_ops; | 601 | struct nlattr *nla_ops; |
@@ -658,9 +613,8 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq, | |||
658 | if (nest == NULL) | 613 | if (nest == NULL) |
659 | goto nla_put_failure; | 614 | goto nla_put_failure; |
660 | 615 | ||
661 | if (nla_put_u32(skb, CTRL_ATTR_OP_ID, ops->cmd) || | 616 | NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd); |
662 | nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, ops->flags)) | 617 | NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags); |
663 | goto nla_put_failure; | ||
664 | 618 | ||
665 | nla_nest_end(skb, nest); | 619 | nla_nest_end(skb, nest); |
666 | } | 620 | } |
@@ -684,10 +638,9 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq, | |||
684 | if (nest == NULL) | 638 | if (nest == NULL) |
685 | goto nla_put_failure; | 639 | goto nla_put_failure; |
686 | 640 | ||
687 | if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id) || | 641 | NLA_PUT_U32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id); |
688 | nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME, | 642 | NLA_PUT_STRING(skb, CTRL_ATTR_MCAST_GRP_NAME, |
689 | grp->name)) | 643 | grp->name); |
690 | goto nla_put_failure; | ||
691 | 644 | ||
692 | nla_nest_end(skb, nest); | 645 | nla_nest_end(skb, nest); |
693 | } | 646 | } |
@@ -701,7 +654,7 @@ nla_put_failure: | |||
701 | return -EMSGSIZE; | 654 | return -EMSGSIZE; |
702 | } | 655 | } |
703 | 656 | ||
704 | static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 portid, | 657 | static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 pid, |
705 | u32 seq, u32 flags, struct sk_buff *skb, | 658 | u32 seq, u32 flags, struct sk_buff *skb, |
706 | u8 cmd) | 659 | u8 cmd) |
707 | { | 660 | { |
@@ -709,13 +662,12 @@ static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 portid, | |||
709 | struct nlattr *nla_grps; | 662 | struct nlattr *nla_grps; |
710 | struct nlattr *nest; | 663 | struct nlattr *nest; |
711 | 664 | ||
712 | hdr = genlmsg_put(skb, portid, seq, &genl_ctrl, flags, cmd); | 665 | hdr = genlmsg_put(skb, pid, seq, &genl_ctrl, flags, cmd); |
713 | if (hdr == NULL) | 666 | if (hdr == NULL) |
714 | return -1; | 667 | return -1; |
715 | 668 | ||
716 | if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, grp->family->name) || | 669 | NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, grp->family->name); |
717 | nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, grp->family->id)) | 670 | NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, grp->family->id); |
718 | goto nla_put_failure; | ||
719 | 671 | ||
720 | nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS); | 672 | nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS); |
721 | if (nla_grps == NULL) | 673 | if (nla_grps == NULL) |
@@ -725,10 +677,9 @@ static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 portid, | |||
725 | if (nest == NULL) | 677 | if (nest == NULL) |
726 | goto nla_put_failure; | 678 | goto nla_put_failure; |
727 | 679 | ||
728 | if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id) || | 680 | NLA_PUT_U32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id); |
729 | nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME, | 681 | NLA_PUT_STRING(skb, CTRL_ATTR_MCAST_GRP_NAME, |
730 | grp->name)) | 682 | grp->name); |
731 | goto nla_put_failure; | ||
732 | 683 | ||
733 | nla_nest_end(skb, nest); | 684 | nla_nest_end(skb, nest); |
734 | nla_nest_end(skb, nla_grps); | 685 | nla_nest_end(skb, nla_grps); |
@@ -756,7 +707,7 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb) | |||
756 | continue; | 707 | continue; |
757 | if (++n < fams_to_skip) | 708 | if (++n < fams_to_skip) |
758 | continue; | 709 | continue; |
759 | if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).portid, | 710 | if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).pid, |
760 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 711 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
761 | skb, CTRL_CMD_NEWFAMILY) < 0) | 712 | skb, CTRL_CMD_NEWFAMILY) < 0) |
762 | goto errout; | 713 | goto errout; |
@@ -773,7 +724,7 @@ errout: | |||
773 | } | 724 | } |
774 | 725 | ||
775 | static struct sk_buff *ctrl_build_family_msg(struct genl_family *family, | 726 | static struct sk_buff *ctrl_build_family_msg(struct genl_family *family, |
776 | u32 portid, int seq, u8 cmd) | 727 | u32 pid, int seq, u8 cmd) |
777 | { | 728 | { |
778 | struct sk_buff *skb; | 729 | struct sk_buff *skb; |
779 | int err; | 730 | int err; |
@@ -782,7 +733,7 @@ static struct sk_buff *ctrl_build_family_msg(struct genl_family *family, | |||
782 | if (skb == NULL) | 733 | if (skb == NULL) |
783 | return ERR_PTR(-ENOBUFS); | 734 | return ERR_PTR(-ENOBUFS); |
784 | 735 | ||
785 | err = ctrl_fill_info(family, portid, seq, 0, skb, cmd); | 736 | err = ctrl_fill_info(family, pid, seq, 0, skb, cmd); |
786 | if (err < 0) { | 737 | if (err < 0) { |
787 | nlmsg_free(skb); | 738 | nlmsg_free(skb); |
788 | return ERR_PTR(err); | 739 | return ERR_PTR(err); |
@@ -792,7 +743,7 @@ static struct sk_buff *ctrl_build_family_msg(struct genl_family *family, | |||
792 | } | 743 | } |
793 | 744 | ||
794 | static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp, | 745 | static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp, |
795 | u32 portid, int seq, u8 cmd) | 746 | u32 pid, int seq, u8 cmd) |
796 | { | 747 | { |
797 | struct sk_buff *skb; | 748 | struct sk_buff *skb; |
798 | int err; | 749 | int err; |
@@ -801,7 +752,7 @@ static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp, | |||
801 | if (skb == NULL) | 752 | if (skb == NULL) |
802 | return ERR_PTR(-ENOBUFS); | 753 | return ERR_PTR(-ENOBUFS); |
803 | 754 | ||
804 | err = ctrl_fill_mcgrp_info(grp, portid, seq, 0, skb, cmd); | 755 | err = ctrl_fill_mcgrp_info(grp, pid, seq, 0, skb, cmd); |
805 | if (err < 0) { | 756 | if (err < 0) { |
806 | nlmsg_free(skb); | 757 | nlmsg_free(skb); |
807 | return ERR_PTR(err); | 758 | return ERR_PTR(err); |
@@ -833,15 +784,6 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info) | |||
833 | 784 | ||
834 | name = nla_data(info->attrs[CTRL_ATTR_FAMILY_NAME]); | 785 | name = nla_data(info->attrs[CTRL_ATTR_FAMILY_NAME]); |
835 | res = genl_family_find_byname(name); | 786 | res = genl_family_find_byname(name); |
836 | #ifdef CONFIG_MODULES | ||
837 | if (res == NULL) { | ||
838 | genl_unlock(); | ||
839 | request_module("net-pf-%d-proto-%d-family-%s", | ||
840 | PF_NETLINK, NETLINK_GENERIC, name); | ||
841 | genl_lock(); | ||
842 | res = genl_family_find_byname(name); | ||
843 | } | ||
844 | #endif | ||
845 | err = -ENOENT; | 787 | err = -ENOENT; |
846 | } | 788 | } |
847 | 789 | ||
@@ -853,7 +795,7 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info) | |||
853 | return -ENOENT; | 795 | return -ENOENT; |
854 | } | 796 | } |
855 | 797 | ||
856 | msg = ctrl_build_family_msg(res, info->snd_portid, info->snd_seq, | 798 | msg = ctrl_build_family_msg(res, info->snd_pid, info->snd_seq, |
857 | CTRL_CMD_NEWFAMILY); | 799 | CTRL_CMD_NEWFAMILY); |
858 | if (IS_ERR(msg)) | 800 | if (IS_ERR(msg)) |
859 | return PTR_ERR(msg); | 801 | return PTR_ERR(msg); |
@@ -915,14 +857,10 @@ static struct genl_multicast_group notify_grp = { | |||
915 | 857 | ||
916 | static int __net_init genl_pernet_init(struct net *net) | 858 | static int __net_init genl_pernet_init(struct net *net) |
917 | { | 859 | { |
918 | struct netlink_kernel_cfg cfg = { | ||
919 | .input = genl_rcv, | ||
920 | .cb_mutex = &genl_mutex, | ||
921 | .flags = NL_CFG_F_NONROOT_RECV, | ||
922 | }; | ||
923 | |||
924 | /* we'll bump the group number right afterwards */ | 860 | /* we'll bump the group number right afterwards */ |
925 | net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC, &cfg); | 861 | net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC, 0, |
862 | genl_rcv, &genl_mutex, | ||
863 | THIS_MODULE); | ||
926 | 864 | ||
927 | if (!net->genl_sock && net_eq(net, &init_net)) | 865 | if (!net->genl_sock && net_eq(net, &init_net)) |
928 | panic("GENL: Cannot initialize generic netlink\n"); | 866 | panic("GENL: Cannot initialize generic netlink\n"); |
@@ -955,6 +893,8 @@ static int __init genl_init(void) | |||
955 | if (err < 0) | 893 | if (err < 0) |
956 | goto problem; | 894 | goto problem; |
957 | 895 | ||
896 | netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV); | ||
897 | |||
958 | err = register_pernet_subsys(&genl_pernet_ops); | 898 | err = register_pernet_subsys(&genl_pernet_ops); |
959 | if (err) | 899 | if (err) |
960 | goto problem; | 900 | goto problem; |
@@ -971,7 +911,7 @@ problem: | |||
971 | 911 | ||
972 | subsys_initcall(genl_init); | 912 | subsys_initcall(genl_init); |
973 | 913 | ||
974 | static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group, | 914 | static int genlmsg_mcast(struct sk_buff *skb, u32 pid, unsigned long group, |
975 | gfp_t flags) | 915 | gfp_t flags) |
976 | { | 916 | { |
977 | struct sk_buff *tmp; | 917 | struct sk_buff *tmp; |
@@ -986,7 +926,7 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group, | |||
986 | goto error; | 926 | goto error; |
987 | } | 927 | } |
988 | err = nlmsg_multicast(prev->genl_sock, tmp, | 928 | err = nlmsg_multicast(prev->genl_sock, tmp, |
989 | portid, group, flags); | 929 | pid, group, flags); |
990 | if (err) | 930 | if (err) |
991 | goto error; | 931 | goto error; |
992 | } | 932 | } |
@@ -994,28 +934,15 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group, | |||
994 | prev = net; | 934 | prev = net; |
995 | } | 935 | } |
996 | 936 | ||
997 | return nlmsg_multicast(prev->genl_sock, skb, portid, group, flags); | 937 | return nlmsg_multicast(prev->genl_sock, skb, pid, group, flags); |
998 | error: | 938 | error: |
999 | kfree_skb(skb); | 939 | kfree_skb(skb); |
1000 | return err; | 940 | return err; |
1001 | } | 941 | } |
1002 | 942 | ||
1003 | int genlmsg_multicast_allns(struct sk_buff *skb, u32 portid, unsigned int group, | 943 | int genlmsg_multicast_allns(struct sk_buff *skb, u32 pid, unsigned int group, |
1004 | gfp_t flags) | 944 | gfp_t flags) |
1005 | { | 945 | { |
1006 | return genlmsg_mcast(skb, portid, group, flags); | 946 | return genlmsg_mcast(skb, pid, group, flags); |
1007 | } | 947 | } |
1008 | EXPORT_SYMBOL(genlmsg_multicast_allns); | 948 | EXPORT_SYMBOL(genlmsg_multicast_allns); |
1009 | |||
1010 | void genl_notify(struct sk_buff *skb, struct net *net, u32 portid, u32 group, | ||
1011 | struct nlmsghdr *nlh, gfp_t flags) | ||
1012 | { | ||
1013 | struct sock *sk = net->genl_sock; | ||
1014 | int report = 0; | ||
1015 | |||
1016 | if (nlh) | ||
1017 | report = nlmsg_report(nlh); | ||
1018 | |||
1019 | nlmsg_notify(sk, skb, portid, group, report, flags); | ||
1020 | } | ||
1021 | EXPORT_SYMBOL(genl_notify); | ||