diff options
Diffstat (limited to 'net/tipc/netlink_compat.c')
-rw-r--r-- | net/tipc/netlink_compat.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 02461233b6d8..40c24ea31231 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include "config.h" | 35 | #include "config.h" |
36 | #include "bearer.h" | 36 | #include "bearer.h" |
37 | #include "link.h" | 37 | #include "link.h" |
38 | #include "name_table.h" | ||
38 | #include <net/genetlink.h> | 39 | #include <net/genetlink.h> |
39 | #include <linux/tipc_config.h> | 40 | #include <linux/tipc_config.h> |
40 | 41 | ||
@@ -58,6 +59,7 @@ struct tipc_nl_compat_msg { | |||
58 | }; | 59 | }; |
59 | 60 | ||
60 | struct tipc_nl_compat_cmd_dump { | 61 | struct tipc_nl_compat_cmd_dump { |
62 | int (*header)(struct tipc_nl_compat_msg *); | ||
61 | int (*dumpit)(struct sk_buff *, struct netlink_callback *); | 63 | int (*dumpit)(struct sk_buff *, struct netlink_callback *); |
62 | int (*format)(struct tipc_nl_compat_msg *msg, struct nlattr **attrs); | 64 | int (*format)(struct tipc_nl_compat_msg *msg, struct nlattr **attrs); |
63 | }; | 65 | }; |
@@ -246,6 +248,9 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, | |||
246 | if (msg->rep_type) | 248 | if (msg->rep_type) |
247 | tipc_tlv_init(msg->rep, msg->rep_type); | 249 | tipc_tlv_init(msg->rep, msg->rep_type); |
248 | 250 | ||
251 | if (cmd->header) | ||
252 | (*cmd->header)(msg); | ||
253 | |||
249 | arg = nlmsg_new(0, GFP_KERNEL); | 254 | arg = nlmsg_new(0, GFP_KERNEL); |
250 | if (!arg) { | 255 | if (!arg) { |
251 | kfree_skb(msg->rep); | 256 | kfree_skb(msg->rep); |
@@ -626,6 +631,93 @@ static int tipc_nl_compat_link_reset_stats(struct sk_buff *skb, | |||
626 | return 0; | 631 | return 0; |
627 | } | 632 | } |
628 | 633 | ||
634 | static int tipc_nl_compat_name_table_dump_header(struct tipc_nl_compat_msg *msg) | ||
635 | { | ||
636 | int i; | ||
637 | u32 depth; | ||
638 | struct tipc_name_table_query *ntq; | ||
639 | static const char * const header[] = { | ||
640 | "Type ", | ||
641 | "Lower Upper ", | ||
642 | "Port Identity ", | ||
643 | "Publication Scope" | ||
644 | }; | ||
645 | |||
646 | ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req); | ||
647 | |||
648 | depth = ntohl(ntq->depth); | ||
649 | |||
650 | if (depth > 4) | ||
651 | depth = 4; | ||
652 | for (i = 0; i < depth; i++) | ||
653 | tipc_tlv_sprintf(msg->rep, header[i]); | ||
654 | tipc_tlv_sprintf(msg->rep, "\n"); | ||
655 | |||
656 | return 0; | ||
657 | } | ||
658 | |||
659 | static int tipc_nl_compat_name_table_dump(struct tipc_nl_compat_msg *msg, | ||
660 | struct nlattr **attrs) | ||
661 | { | ||
662 | char port_str[27]; | ||
663 | struct tipc_name_table_query *ntq; | ||
664 | struct nlattr *nt[TIPC_NLA_NAME_TABLE_MAX + 1]; | ||
665 | struct nlattr *publ[TIPC_NLA_PUBL_MAX + 1]; | ||
666 | u32 node, depth, type, lowbound, upbound; | ||
667 | static const char * const scope_str[] = {"", " zone", " cluster", | ||
668 | " node"}; | ||
669 | |||
670 | nla_parse_nested(nt, TIPC_NLA_NAME_TABLE_MAX, | ||
671 | attrs[TIPC_NLA_NAME_TABLE], NULL); | ||
672 | |||
673 | nla_parse_nested(publ, TIPC_NLA_PUBL_MAX, nt[TIPC_NLA_NAME_TABLE_PUBL], | ||
674 | NULL); | ||
675 | |||
676 | ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req); | ||
677 | |||
678 | depth = ntohl(ntq->depth); | ||
679 | type = ntohl(ntq->type); | ||
680 | lowbound = ntohl(ntq->lowbound); | ||
681 | upbound = ntohl(ntq->upbound); | ||
682 | |||
683 | if (!(depth & TIPC_NTQ_ALLTYPES) && | ||
684 | (type != nla_get_u32(publ[TIPC_NLA_PUBL_TYPE]))) | ||
685 | return 0; | ||
686 | if (lowbound && (lowbound > nla_get_u32(publ[TIPC_NLA_PUBL_UPPER]))) | ||
687 | return 0; | ||
688 | if (upbound && (upbound < nla_get_u32(publ[TIPC_NLA_PUBL_LOWER]))) | ||
689 | return 0; | ||
690 | |||
691 | tipc_tlv_sprintf(msg->rep, "%-10u ", | ||
692 | nla_get_u32(publ[TIPC_NLA_PUBL_TYPE])); | ||
693 | |||
694 | if (depth == 1) | ||
695 | goto out; | ||
696 | |||
697 | tipc_tlv_sprintf(msg->rep, "%-10u %-10u ", | ||
698 | nla_get_u32(publ[TIPC_NLA_PUBL_LOWER]), | ||
699 | nla_get_u32(publ[TIPC_NLA_PUBL_UPPER])); | ||
700 | |||
701 | if (depth == 2) | ||
702 | goto out; | ||
703 | |||
704 | node = nla_get_u32(publ[TIPC_NLA_PUBL_NODE]); | ||
705 | sprintf(port_str, "<%u.%u.%u:%u>", tipc_zone(node), tipc_cluster(node), | ||
706 | tipc_node(node), nla_get_u32(publ[TIPC_NLA_PUBL_REF])); | ||
707 | tipc_tlv_sprintf(msg->rep, "%-26s ", port_str); | ||
708 | |||
709 | if (depth == 3) | ||
710 | goto out; | ||
711 | |||
712 | tipc_tlv_sprintf(msg->rep, "%-10u %s", | ||
713 | nla_get_u32(publ[TIPC_NLA_PUBL_REF]), | ||
714 | scope_str[nla_get_u32(publ[TIPC_NLA_PUBL_SCOPE])]); | ||
715 | out: | ||
716 | tipc_tlv_sprintf(msg->rep, "\n"); | ||
717 | |||
718 | return 0; | ||
719 | } | ||
720 | |||
629 | static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) | 721 | static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) |
630 | { | 722 | { |
631 | struct tipc_nl_compat_cmd_dump dump; | 723 | struct tipc_nl_compat_cmd_dump dump; |
@@ -675,6 +767,14 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) | |||
675 | doit.doit = tipc_nl_link_reset_stats; | 767 | doit.doit = tipc_nl_link_reset_stats; |
676 | doit.transcode = tipc_nl_compat_link_reset_stats; | 768 | doit.transcode = tipc_nl_compat_link_reset_stats; |
677 | return tipc_nl_compat_doit(&doit, msg); | 769 | return tipc_nl_compat_doit(&doit, msg); |
770 | case TIPC_CMD_SHOW_NAME_TABLE: | ||
771 | msg->req_type = TIPC_TLV_NAME_TBL_QUERY; | ||
772 | msg->rep_size = ULTRA_STRING_MAX_LEN; | ||
773 | msg->rep_type = TIPC_TLV_ULTRA_STRING; | ||
774 | dump.header = tipc_nl_compat_name_table_dump_header; | ||
775 | dump.dumpit = tipc_nl_name_table_dump; | ||
776 | dump.format = tipc_nl_compat_name_table_dump; | ||
777 | return tipc_nl_compat_dumpit(&dump, msg); | ||
678 | } | 778 | } |
679 | 779 | ||
680 | return -EOPNOTSUPP; | 780 | return -EOPNOTSUPP; |
@@ -780,6 +880,7 @@ static int tipc_nl_compat_tmp_wrap(struct sk_buff *skb, struct genl_info *info) | |||
780 | case TIPC_CMD_SET_LINK_PRI: | 880 | case TIPC_CMD_SET_LINK_PRI: |
781 | case TIPC_CMD_SET_LINK_WINDOW: | 881 | case TIPC_CMD_SET_LINK_WINDOW: |
782 | case TIPC_CMD_RESET_LINK_STATS: | 882 | case TIPC_CMD_RESET_LINK_STATS: |
883 | case TIPC_CMD_SHOW_NAME_TABLE: | ||
783 | return tipc_nl_compat_recv(skb, info); | 884 | return tipc_nl_compat_recv(skb, info); |
784 | } | 885 | } |
785 | 886 | ||