diff options
Diffstat (limited to 'net/tipc/name_table.c')
-rw-r--r-- | net/tipc/name_table.c | 88 |
1 files changed, 51 insertions, 37 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index c8b0b5c3c56e..360c478b0b53 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
@@ -753,19 +753,20 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s) | |||
753 | /** | 753 | /** |
754 | * subseq_list - print specified sub-sequence contents into the given buffer | 754 | * subseq_list - print specified sub-sequence contents into the given buffer |
755 | */ | 755 | */ |
756 | static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, | 756 | static int subseq_list(struct sub_seq *sseq, char *buf, int len, u32 depth, |
757 | u32 index) | 757 | u32 index) |
758 | { | 758 | { |
759 | char portIdStr[27]; | 759 | char portIdStr[27]; |
760 | const char *scope_str[] = {"", " zone", " cluster", " node"}; | 760 | const char *scope_str[] = {"", " zone", " cluster", " node"}; |
761 | struct publication *publ; | 761 | struct publication *publ; |
762 | struct name_info *info; | 762 | struct name_info *info; |
763 | int ret; | ||
763 | 764 | ||
764 | tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); | 765 | ret = tipc_snprintf(buf, len, "%-10u %-10u ", sseq->lower, sseq->upper); |
765 | 766 | ||
766 | if (depth == 2) { | 767 | if (depth == 2) { |
767 | tipc_printf(buf, "\n"); | 768 | ret += tipc_snprintf(buf - ret, len + ret, "\n"); |
768 | return; | 769 | return ret; |
769 | } | 770 | } |
770 | 771 | ||
771 | info = sseq->info; | 772 | info = sseq->info; |
@@ -774,52 +775,58 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, | |||
774 | sprintf(portIdStr, "<%u.%u.%u:%u>", | 775 | sprintf(portIdStr, "<%u.%u.%u:%u>", |
775 | tipc_zone(publ->node), tipc_cluster(publ->node), | 776 | tipc_zone(publ->node), tipc_cluster(publ->node), |
776 | tipc_node(publ->node), publ->ref); | 777 | tipc_node(publ->node), publ->ref); |
777 | tipc_printf(buf, "%-26s ", portIdStr); | 778 | ret += tipc_snprintf(buf + ret, len - ret, "%-26s ", portIdStr); |
778 | if (depth > 3) { | 779 | if (depth > 3) { |
779 | tipc_printf(buf, "%-10u %s", publ->key, | 780 | ret += tipc_snprintf(buf + ret, len - ret, "%-10u %s", |
780 | scope_str[publ->scope]); | 781 | publ->key, scope_str[publ->scope]); |
781 | } | 782 | } |
782 | if (!list_is_last(&publ->zone_list, &info->zone_list)) | 783 | if (!list_is_last(&publ->zone_list, &info->zone_list)) |
783 | tipc_printf(buf, "\n%33s", " "); | 784 | ret += tipc_snprintf(buf + ret, len - ret, |
785 | "\n%33s", " "); | ||
784 | }; | 786 | }; |
785 | 787 | ||
786 | tipc_printf(buf, "\n"); | 788 | ret += tipc_snprintf(buf + ret, len - ret, "\n"); |
789 | return ret; | ||
787 | } | 790 | } |
788 | 791 | ||
789 | /** | 792 | /** |
790 | * nameseq_list - print specified name sequence contents into the given buffer | 793 | * nameseq_list - print specified name sequence contents into the given buffer |
791 | */ | 794 | */ |
792 | static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, | 795 | static int nameseq_list(struct name_seq *seq, char *buf, int len, u32 depth, |
793 | u32 type, u32 lowbound, u32 upbound, u32 index) | 796 | u32 type, u32 lowbound, u32 upbound, u32 index) |
794 | { | 797 | { |
795 | struct sub_seq *sseq; | 798 | struct sub_seq *sseq; |
796 | char typearea[11]; | 799 | char typearea[11]; |
800 | int ret = 0; | ||
797 | 801 | ||
798 | if (seq->first_free == 0) | 802 | if (seq->first_free == 0) |
799 | return; | 803 | return 0; |
800 | 804 | ||
801 | sprintf(typearea, "%-10u", seq->type); | 805 | sprintf(typearea, "%-10u", seq->type); |
802 | 806 | ||
803 | if (depth == 1) { | 807 | if (depth == 1) { |
804 | tipc_printf(buf, "%s\n", typearea); | 808 | ret += tipc_snprintf(buf, len, "%s\n", typearea); |
805 | return; | 809 | return ret; |
806 | } | 810 | } |
807 | 811 | ||
808 | for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { | 812 | for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { |
809 | if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { | 813 | if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { |
810 | tipc_printf(buf, "%s ", typearea); | 814 | ret += tipc_snprintf(buf + ret, len - ret, "%s ", |
815 | typearea); | ||
811 | spin_lock_bh(&seq->lock); | 816 | spin_lock_bh(&seq->lock); |
812 | subseq_list(sseq, buf, depth, index); | 817 | ret += subseq_list(sseq, buf + ret, len - ret, |
818 | depth, index); | ||
813 | spin_unlock_bh(&seq->lock); | 819 | spin_unlock_bh(&seq->lock); |
814 | sprintf(typearea, "%10s", " "); | 820 | sprintf(typearea, "%10s", " "); |
815 | } | 821 | } |
816 | } | 822 | } |
823 | return ret; | ||
817 | } | 824 | } |
818 | 825 | ||
819 | /** | 826 | /** |
820 | * nametbl_header - print name table header into the given buffer | 827 | * nametbl_header - print name table header into the given buffer |
821 | */ | 828 | */ |
822 | static void nametbl_header(struct print_buf *buf, u32 depth) | 829 | static int nametbl_header(char *buf, int len, u32 depth) |
823 | { | 830 | { |
824 | const char *header[] = { | 831 | const char *header[] = { |
825 | "Type ", | 832 | "Type ", |
@@ -829,24 +836,27 @@ static void nametbl_header(struct print_buf *buf, u32 depth) | |||
829 | }; | 836 | }; |
830 | 837 | ||
831 | int i; | 838 | int i; |
839 | int ret = 0; | ||
832 | 840 | ||
833 | if (depth > 4) | 841 | if (depth > 4) |
834 | depth = 4; | 842 | depth = 4; |
835 | for (i = 0; i < depth; i++) | 843 | for (i = 0; i < depth; i++) |
836 | tipc_printf(buf, header[i]); | 844 | ret += tipc_snprintf(buf + ret, len - ret, header[i]); |
837 | tipc_printf(buf, "\n"); | 845 | ret += tipc_snprintf(buf + ret, len - ret, "\n"); |
846 | return ret; | ||
838 | } | 847 | } |
839 | 848 | ||
840 | /** | 849 | /** |
841 | * nametbl_list - print specified name table contents into the given buffer | 850 | * nametbl_list - print specified name table contents into the given buffer |
842 | */ | 851 | */ |
843 | static void nametbl_list(struct print_buf *buf, u32 depth_info, | 852 | static int nametbl_list(char *buf, int len, u32 depth_info, |
844 | u32 type, u32 lowbound, u32 upbound) | 853 | u32 type, u32 lowbound, u32 upbound) |
845 | { | 854 | { |
846 | struct hlist_head *seq_head; | 855 | struct hlist_head *seq_head; |
847 | struct hlist_node *seq_node; | 856 | struct hlist_node *seq_node; |
848 | struct name_seq *seq; | 857 | struct name_seq *seq; |
849 | int all_types; | 858 | int all_types; |
859 | int ret = 0; | ||
850 | u32 depth; | 860 | u32 depth; |
851 | u32 i; | 861 | u32 i; |
852 | 862 | ||
@@ -854,65 +864,69 @@ static void nametbl_list(struct print_buf *buf, u32 depth_info, | |||
854 | depth = (depth_info & ~TIPC_NTQ_ALLTYPES); | 864 | depth = (depth_info & ~TIPC_NTQ_ALLTYPES); |
855 | 865 | ||
856 | if (depth == 0) | 866 | if (depth == 0) |
857 | return; | 867 | return 0; |
858 | 868 | ||
859 | if (all_types) { | 869 | if (all_types) { |
860 | /* display all entries in name table to specified depth */ | 870 | /* display all entries in name table to specified depth */ |
861 | nametbl_header(buf, depth); | 871 | ret += nametbl_header(buf, len, depth); |
862 | lowbound = 0; | 872 | lowbound = 0; |
863 | upbound = ~0; | 873 | upbound = ~0; |
864 | for (i = 0; i < tipc_nametbl_size; i++) { | 874 | for (i = 0; i < tipc_nametbl_size; i++) { |
865 | seq_head = &table.types[i]; | 875 | seq_head = &table.types[i]; |
866 | hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { | 876 | hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { |
867 | nameseq_list(seq, buf, depth, seq->type, | 877 | ret += nameseq_list(seq, buf + ret, len - ret, |
868 | lowbound, upbound, i); | 878 | depth, seq->type, |
879 | lowbound, upbound, i); | ||
869 | } | 880 | } |
870 | } | 881 | } |
871 | } else { | 882 | } else { |
872 | /* display only the sequence that matches the specified type */ | 883 | /* display only the sequence that matches the specified type */ |
873 | if (upbound < lowbound) { | 884 | if (upbound < lowbound) { |
874 | tipc_printf(buf, "invalid name sequence specified\n"); | 885 | ret += tipc_snprintf(buf + ret, len - ret, |
875 | return; | 886 | "invalid name sequence specified\n"); |
887 | return ret; | ||
876 | } | 888 | } |
877 | nametbl_header(buf, depth); | 889 | ret += nametbl_header(buf + ret, len - ret, depth); |
878 | i = hash(type); | 890 | i = hash(type); |
879 | seq_head = &table.types[i]; | 891 | seq_head = &table.types[i]; |
880 | hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { | 892 | hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { |
881 | if (seq->type == type) { | 893 | if (seq->type == type) { |
882 | nameseq_list(seq, buf, depth, type, | 894 | ret += nameseq_list(seq, buf + ret, len - ret, |
883 | lowbound, upbound, i); | 895 | depth, type, |
896 | lowbound, upbound, i); | ||
884 | break; | 897 | break; |
885 | } | 898 | } |
886 | } | 899 | } |
887 | } | 900 | } |
901 | return ret; | ||
888 | } | 902 | } |
889 | 903 | ||
890 | #define MAX_NAME_TBL_QUERY 32768 | ||
891 | |||
892 | struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) | 904 | struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) |
893 | { | 905 | { |
894 | struct sk_buff *buf; | 906 | struct sk_buff *buf; |
895 | struct tipc_name_table_query *argv; | 907 | struct tipc_name_table_query *argv; |
896 | struct tlv_desc *rep_tlv; | 908 | struct tlv_desc *rep_tlv; |
897 | struct print_buf b; | 909 | char *pb; |
910 | int pb_len; | ||
898 | int str_len; | 911 | int str_len; |
899 | 912 | ||
900 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY)) | 913 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY)) |
901 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | 914 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); |
902 | 915 | ||
903 | buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_NAME_TBL_QUERY)); | 916 | buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); |
904 | if (!buf) | 917 | if (!buf) |
905 | return NULL; | 918 | return NULL; |
906 | 919 | ||
907 | rep_tlv = (struct tlv_desc *)buf->data; | 920 | rep_tlv = (struct tlv_desc *)buf->data; |
908 | tipc_printbuf_init(&b, TLV_DATA(rep_tlv), MAX_NAME_TBL_QUERY); | 921 | pb = TLV_DATA(rep_tlv); |
922 | pb_len = ULTRA_STRING_MAX_LEN; | ||
909 | argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area); | 923 | argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area); |
910 | read_lock_bh(&tipc_nametbl_lock); | 924 | read_lock_bh(&tipc_nametbl_lock); |
911 | nametbl_list(&b, ntohl(argv->depth), ntohl(argv->type), | 925 | str_len = nametbl_list(pb, pb_len, ntohl(argv->depth), |
912 | ntohl(argv->lowbound), ntohl(argv->upbound)); | 926 | ntohl(argv->type), |
927 | ntohl(argv->lowbound), ntohl(argv->upbound)); | ||
913 | read_unlock_bh(&tipc_nametbl_lock); | 928 | read_unlock_bh(&tipc_nametbl_lock); |
914 | str_len = tipc_printbuf_validate(&b); | 929 | str_len += 1; /* for "\0" */ |
915 | |||
916 | skb_put(buf, TLV_SPACE(str_len)); | 930 | skb_put(buf, TLV_SPACE(str_len)); |
917 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | 931 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); |
918 | 932 | ||