aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/name_table.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/name_table.c')
-rw-r--r--net/tipc/name_table.c88
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 */
756static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, 756static 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 */
792static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, 795static 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 */
822static void nametbl_header(struct print_buf *buf, u32 depth) 829static 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 */
843static void nametbl_list(struct print_buf *buf, u32 depth_info, 852static 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
892struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) 904struct 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