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.c190
1 files changed, 4 insertions, 186 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 18a3d44238bc..105ba7adf06f 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -36,11 +36,13 @@
36 36
37#include <net/sock.h> 37#include <net/sock.h>
38#include "core.h" 38#include "core.h"
39#include "config.h" 39#include "netlink.h"
40#include "name_table.h" 40#include "name_table.h"
41#include "name_distr.h" 41#include "name_distr.h"
42#include "subscr.h" 42#include "subscr.h"
43#include "bcast.h" 43#include "bcast.h"
44#include "addr.h"
45#include <net/genetlink.h>
44 46
45#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */ 47#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */
46 48
@@ -773,190 +775,6 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s)
773 spin_unlock_bh(&tn->nametbl_lock); 775 spin_unlock_bh(&tn->nametbl_lock);
774} 776}
775 777
776/**
777 * subseq_list - print specified sub-sequence contents into the given buffer
778 */
779static int subseq_list(struct sub_seq *sseq, char *buf, int len, u32 depth,
780 u32 index)
781{
782 char portIdStr[27];
783 const char *scope_str[] = {"", " zone", " cluster", " node"};
784 struct publication *publ;
785 struct name_info *info;
786 int ret;
787
788 ret = tipc_snprintf(buf, len, "%-10u %-10u ", sseq->lower, sseq->upper);
789
790 if (depth == 2) {
791 ret += tipc_snprintf(buf - ret, len + ret, "\n");
792 return ret;
793 }
794
795 info = sseq->info;
796
797 list_for_each_entry(publ, &info->zone_list, zone_list) {
798 sprintf(portIdStr, "<%u.%u.%u:%u>",
799 tipc_zone(publ->node), tipc_cluster(publ->node),
800 tipc_node(publ->node), publ->ref);
801 ret += tipc_snprintf(buf + ret, len - ret, "%-26s ", portIdStr);
802 if (depth > 3) {
803 ret += tipc_snprintf(buf + ret, len - ret, "%-10u %s",
804 publ->key, scope_str[publ->scope]);
805 }
806 if (!list_is_last(&publ->zone_list, &info->zone_list))
807 ret += tipc_snprintf(buf + ret, len - ret,
808 "\n%33s", " ");
809 }
810
811 ret += tipc_snprintf(buf + ret, len - ret, "\n");
812 return ret;
813}
814
815/**
816 * nameseq_list - print specified name sequence contents into the given buffer
817 */
818static int nameseq_list(struct name_seq *seq, char *buf, int len, u32 depth,
819 u32 type, u32 lowbound, u32 upbound, u32 index)
820{
821 struct sub_seq *sseq;
822 char typearea[11];
823 int ret = 0;
824
825 if (seq->first_free == 0)
826 return 0;
827
828 sprintf(typearea, "%-10u", seq->type);
829
830 if (depth == 1) {
831 ret += tipc_snprintf(buf, len, "%s\n", typearea);
832 return ret;
833 }
834
835 for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) {
836 if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) {
837 ret += tipc_snprintf(buf + ret, len - ret, "%s ",
838 typearea);
839 spin_lock_bh(&seq->lock);
840 ret += subseq_list(sseq, buf + ret, len - ret,
841 depth, index);
842 spin_unlock_bh(&seq->lock);
843 sprintf(typearea, "%10s", " ");
844 }
845 }
846 return ret;
847}
848
849/**
850 * nametbl_header - print name table header into the given buffer
851 */
852static int nametbl_header(char *buf, int len, u32 depth)
853{
854 const char *header[] = {
855 "Type ",
856 "Lower Upper ",
857 "Port Identity ",
858 "Publication Scope"
859 };
860
861 int i;
862 int ret = 0;
863
864 if (depth > 4)
865 depth = 4;
866 for (i = 0; i < depth; i++)
867 ret += tipc_snprintf(buf + ret, len - ret, header[i]);
868 ret += tipc_snprintf(buf + ret, len - ret, "\n");
869 return ret;
870}
871
872/**
873 * nametbl_list - print specified name table contents into the given buffer
874 */
875static int nametbl_list(struct net *net, char *buf, int len, u32 depth_info,
876 u32 type, u32 lowbound, u32 upbound)
877{
878 struct tipc_net *tn = net_generic(net, tipc_net_id);
879 struct hlist_head *seq_head;
880 struct name_seq *seq;
881 int all_types;
882 int ret = 0;
883 u32 depth;
884 u32 i;
885
886 all_types = (depth_info & TIPC_NTQ_ALLTYPES);
887 depth = (depth_info & ~TIPC_NTQ_ALLTYPES);
888
889 if (depth == 0)
890 return 0;
891
892 if (all_types) {
893 /* display all entries in name table to specified depth */
894 ret += nametbl_header(buf, len, depth);
895 lowbound = 0;
896 upbound = ~0;
897 for (i = 0; i < TIPC_NAMETBL_SIZE; i++) {
898 seq_head = &tn->nametbl->seq_hlist[i];
899 hlist_for_each_entry_rcu(seq, seq_head, ns_list) {
900 ret += nameseq_list(seq, buf + ret, len - ret,
901 depth, seq->type,
902 lowbound, upbound, i);
903 }
904 }
905 } else {
906 /* display only the sequence that matches the specified type */
907 if (upbound < lowbound) {
908 ret += tipc_snprintf(buf + ret, len - ret,
909 "invalid name sequence specified\n");
910 return ret;
911 }
912 ret += nametbl_header(buf + ret, len - ret, depth);
913 i = hash(type);
914 seq_head = &tn->nametbl->seq_hlist[i];
915 hlist_for_each_entry_rcu(seq, seq_head, ns_list) {
916 if (seq->type == type) {
917 ret += nameseq_list(seq, buf + ret, len - ret,
918 depth, type,
919 lowbound, upbound, i);
920 break;
921 }
922 }
923 }
924 return ret;
925}
926
927struct sk_buff *tipc_nametbl_get(struct net *net, const void *req_tlv_area,
928 int req_tlv_space)
929{
930 struct sk_buff *buf;
931 struct tipc_name_table_query *argv;
932 struct tlv_desc *rep_tlv;
933 char *pb;
934 int pb_len;
935 int str_len;
936
937 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY))
938 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
939
940 buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN));
941 if (!buf)
942 return NULL;
943
944 rep_tlv = (struct tlv_desc *)buf->data;
945 pb = TLV_DATA(rep_tlv);
946 pb_len = ULTRA_STRING_MAX_LEN;
947 argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area);
948 rcu_read_lock();
949 str_len = nametbl_list(net, pb, pb_len, ntohl(argv->depth),
950 ntohl(argv->type),
951 ntohl(argv->lowbound), ntohl(argv->upbound));
952 rcu_read_unlock();
953 str_len += 1; /* for "\0" */
954 skb_put(buf, TLV_SPACE(str_len));
955 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
956
957 return buf;
958}
959
960int tipc_nametbl_init(struct net *net) 778int tipc_nametbl_init(struct net *net)
961{ 779{
962 struct tipc_net *tn = net_generic(net, tipc_net_id); 780 struct tipc_net *tn = net_generic(net, tipc_net_id);
@@ -1055,7 +873,7 @@ static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg,
1055 *last_publ = p->key; 873 *last_publ = p->key;
1056 874
1057 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, 875 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq,
1058 &tipc_genl_v2_family, NLM_F_MULTI, 876 &tipc_genl_family, NLM_F_MULTI,
1059 TIPC_NL_NAME_TABLE_GET); 877 TIPC_NL_NAME_TABLE_GET);
1060 if (!hdr) 878 if (!hdr)
1061 return -EMSGSIZE; 879 return -EMSGSIZE;