diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/Makefile | 6 | ||||
-rw-r--r-- | net/tipc/bcast.c | 45 | ||||
-rw-r--r-- | net/tipc/bcast.h | 1 | ||||
-rw-r--r-- | net/tipc/bearer.c | 86 | ||||
-rw-r--r-- | net/tipc/bearer.h | 5 | ||||
-rw-r--r-- | net/tipc/config.c | 332 | ||||
-rw-r--r-- | net/tipc/config.h | 67 | ||||
-rw-r--r-- | net/tipc/core.c | 10 | ||||
-rw-r--r-- | net/tipc/core.h | 3 | ||||
-rw-r--r-- | net/tipc/link.c | 325 | ||||
-rw-r--r-- | net/tipc/link.h | 8 | ||||
-rw-r--r-- | net/tipc/log.c | 55 | ||||
-rw-r--r-- | net/tipc/name_table.c | 190 | ||||
-rw-r--r-- | net/tipc/name_table.h | 2 | ||||
-rw-r--r-- | net/tipc/net.c | 6 | ||||
-rw-r--r-- | net/tipc/netlink.c | 67 | ||||
-rw-r--r-- | net/tipc/netlink.h | 4 | ||||
-rw-r--r-- | net/tipc/netlink_compat.c | 1084 | ||||
-rw-r--r-- | net/tipc/node.c | 131 | ||||
-rw-r--r-- | net/tipc/node.h | 4 | ||||
-rw-r--r-- | net/tipc/socket.c | 90 | ||||
-rw-r--r-- | net/tipc/socket.h | 1 |
22 files changed, 1127 insertions, 1395 deletions
diff --git a/net/tipc/Makefile b/net/tipc/Makefile index 333e4592772c..599b1a540d2b 100644 --- a/net/tipc/Makefile +++ b/net/tipc/Makefile | |||
@@ -4,11 +4,11 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_TIPC) := tipc.o | 5 | obj-$(CONFIG_TIPC) := tipc.o |
6 | 6 | ||
7 | tipc-y += addr.o bcast.o bearer.o config.o \ | 7 | tipc-y += addr.o bcast.o bearer.o \ |
8 | core.o link.o discover.o msg.o \ | 8 | core.o link.o discover.o msg.o \ |
9 | name_distr.o subscr.o name_table.o net.o \ | 9 | name_distr.o subscr.o name_table.o net.o \ |
10 | netlink.o node.o socket.o log.o eth_media.o \ | 10 | netlink.o netlink_compat.o node.o socket.o eth_media.o \ |
11 | server.o | 11 | server.o socket.o |
12 | 12 | ||
13 | tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o | 13 | tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o |
14 | tipc-$(CONFIG_SYSCTL) += sysctl.o | 14 | tipc-$(CONFIG_SYSCTL) += sysctl.o |
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 81b1fef1f5e0..3e41704832de 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -810,7 +810,7 @@ int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg) | |||
810 | 810 | ||
811 | tipc_bclink_lock(net); | 811 | tipc_bclink_lock(net); |
812 | 812 | ||
813 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, | 813 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, |
814 | NLM_F_MULTI, TIPC_NL_LINK_GET); | 814 | NLM_F_MULTI, TIPC_NL_LINK_GET); |
815 | if (!hdr) | 815 | if (!hdr) |
816 | return -EMSGSIZE; | 816 | return -EMSGSIZE; |
@@ -860,49 +860,6 @@ msg_full: | |||
860 | return -EMSGSIZE; | 860 | return -EMSGSIZE; |
861 | } | 861 | } |
862 | 862 | ||
863 | int tipc_bclink_stats(struct net *net, char *buf, const u32 buf_size) | ||
864 | { | ||
865 | int ret; | ||
866 | struct tipc_stats *s; | ||
867 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
868 | struct tipc_link *bcl = tn->bcl; | ||
869 | |||
870 | if (!bcl) | ||
871 | return 0; | ||
872 | |||
873 | tipc_bclink_lock(net); | ||
874 | |||
875 | s = &bcl->stats; | ||
876 | |||
877 | ret = tipc_snprintf(buf, buf_size, "Link <%s>\n" | ||
878 | " Window:%u packets\n", | ||
879 | bcl->name, bcl->queue_limit[0]); | ||
880 | ret += tipc_snprintf(buf + ret, buf_size - ret, | ||
881 | " RX packets:%u fragments:%u/%u bundles:%u/%u\n", | ||
882 | s->recv_info, s->recv_fragments, | ||
883 | s->recv_fragmented, s->recv_bundles, | ||
884 | s->recv_bundled); | ||
885 | ret += tipc_snprintf(buf + ret, buf_size - ret, | ||
886 | " TX packets:%u fragments:%u/%u bundles:%u/%u\n", | ||
887 | s->sent_info, s->sent_fragments, | ||
888 | s->sent_fragmented, s->sent_bundles, | ||
889 | s->sent_bundled); | ||
890 | ret += tipc_snprintf(buf + ret, buf_size - ret, | ||
891 | " RX naks:%u defs:%u dups:%u\n", | ||
892 | s->recv_nacks, s->deferred_recv, s->duplicates); | ||
893 | ret += tipc_snprintf(buf + ret, buf_size - ret, | ||
894 | " TX naks:%u acks:%u dups:%u\n", | ||
895 | s->sent_nacks, s->sent_acks, s->retransmitted); | ||
896 | ret += tipc_snprintf(buf + ret, buf_size - ret, | ||
897 | " Congestion link:%u Send queue max:%u avg:%u\n", | ||
898 | s->link_congs, s->max_queue_sz, | ||
899 | s->queue_sz_counts ? | ||
900 | (s->accu_queue_sz / s->queue_sz_counts) : 0); | ||
901 | |||
902 | tipc_bclink_unlock(net); | ||
903 | return ret; | ||
904 | } | ||
905 | |||
906 | int tipc_bclink_reset_stats(struct net *net) | 863 | int tipc_bclink_reset_stats(struct net *net) |
907 | { | 864 | { |
908 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 865 | struct tipc_net *tn = net_generic(net, tipc_net_id); |
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h index a910c0b9f249..43f397fbac55 100644 --- a/net/tipc/bcast.h +++ b/net/tipc/bcast.h | |||
@@ -127,7 +127,6 @@ u32 tipc_bclink_get_last_sent(struct net *net); | |||
127 | u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr); | 127 | u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr); |
128 | void tipc_bclink_update_link_state(struct tipc_node *node, | 128 | void tipc_bclink_update_link_state(struct tipc_node *node, |
129 | u32 last_sent); | 129 | u32 last_sent); |
130 | int tipc_bclink_stats(struct net *net, char *stats_buf, const u32 buf_size); | ||
131 | int tipc_bclink_reset_stats(struct net *net); | 130 | int tipc_bclink_reset_stats(struct net *net); |
132 | int tipc_bclink_set_queue_limits(struct net *net, u32 limit); | 131 | int tipc_bclink_set_queue_limits(struct net *net, u32 limit); |
133 | void tipc_bcbearer_sort(struct net *net, struct tipc_node_map *nm_ptr, | 132 | void tipc_bcbearer_sort(struct net *net, struct tipc_node_map *nm_ptr, |
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 33dc3486d16c..48852c2dcc03 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -36,7 +36,6 @@ | |||
36 | 36 | ||
37 | #include <net/sock.h> | 37 | #include <net/sock.h> |
38 | #include "core.h" | 38 | #include "core.h" |
39 | #include "config.h" | ||
40 | #include "bearer.h" | 39 | #include "bearer.h" |
41 | #include "link.h" | 40 | #include "link.h" |
42 | #include "discover.h" | 41 | #include "discover.h" |
@@ -112,38 +111,18 @@ void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a) | |||
112 | m_ptr = media_find_id(a->media_id); | 111 | m_ptr = media_find_id(a->media_id); |
113 | 112 | ||
114 | if (m_ptr && !m_ptr->addr2str(a, addr_str, sizeof(addr_str))) | 113 | if (m_ptr && !m_ptr->addr2str(a, addr_str, sizeof(addr_str))) |
115 | ret = tipc_snprintf(buf, len, "%s(%s)", m_ptr->name, addr_str); | 114 | ret = scnprintf(buf, len, "%s(%s)", m_ptr->name, addr_str); |
116 | else { | 115 | else { |
117 | u32 i; | 116 | u32 i; |
118 | 117 | ||
119 | ret = tipc_snprintf(buf, len, "UNKNOWN(%u)", a->media_id); | 118 | ret = scnprintf(buf, len, "UNKNOWN(%u)", a->media_id); |
120 | for (i = 0; i < sizeof(a->value); i++) | 119 | for (i = 0; i < sizeof(a->value); i++) |
121 | ret += tipc_snprintf(buf - ret, len + ret, | 120 | ret += scnprintf(buf - ret, len + ret, |
122 | "-%02x", a->value[i]); | 121 | "-%02x", a->value[i]); |
123 | } | 122 | } |
124 | } | 123 | } |
125 | 124 | ||
126 | /** | 125 | /** |
127 | * tipc_media_get_names - record names of registered media in buffer | ||
128 | */ | ||
129 | struct sk_buff *tipc_media_get_names(void) | ||
130 | { | ||
131 | struct sk_buff *buf; | ||
132 | int i; | ||
133 | |||
134 | buf = tipc_cfg_reply_alloc(MAX_MEDIA * TLV_SPACE(TIPC_MAX_MEDIA_NAME)); | ||
135 | if (!buf) | ||
136 | return NULL; | ||
137 | |||
138 | for (i = 0; media_info_array[i] != NULL; i++) { | ||
139 | tipc_cfg_append_tlv(buf, TIPC_TLV_MEDIA_NAME, | ||
140 | media_info_array[i]->name, | ||
141 | strlen(media_info_array[i]->name) + 1); | ||
142 | } | ||
143 | return buf; | ||
144 | } | ||
145 | |||
146 | /** | ||
147 | * bearer_name_validate - validate & (optionally) deconstruct bearer name | 126 | * bearer_name_validate - validate & (optionally) deconstruct bearer name |
148 | * @name: ptr to bearer name string | 127 | * @name: ptr to bearer name string |
149 | * @name_parts: ptr to area for bearer name components (or NULL if not needed) | 128 | * @name_parts: ptr to area for bearer name components (or NULL if not needed) |
@@ -205,35 +184,6 @@ struct tipc_bearer *tipc_bearer_find(struct net *net, const char *name) | |||
205 | return NULL; | 184 | return NULL; |
206 | } | 185 | } |
207 | 186 | ||
208 | /** | ||
209 | * tipc_bearer_get_names - record names of bearers in buffer | ||
210 | */ | ||
211 | struct sk_buff *tipc_bearer_get_names(struct net *net) | ||
212 | { | ||
213 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
214 | struct sk_buff *buf; | ||
215 | struct tipc_bearer *b; | ||
216 | int i, j; | ||
217 | |||
218 | buf = tipc_cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME)); | ||
219 | if (!buf) | ||
220 | return NULL; | ||
221 | |||
222 | for (i = 0; media_info_array[i] != NULL; i++) { | ||
223 | for (j = 0; j < MAX_BEARERS; j++) { | ||
224 | b = rtnl_dereference(tn->bearer_list[j]); | ||
225 | if (!b) | ||
226 | continue; | ||
227 | if (b->media == media_info_array[i]) { | ||
228 | tipc_cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME, | ||
229 | b->name, | ||
230 | strlen(b->name) + 1); | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | return buf; | ||
235 | } | ||
236 | |||
237 | void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest) | 187 | void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest) |
238 | { | 188 | { |
239 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 189 | struct tipc_net *tn = net_generic(net, tipc_net_id); |
@@ -265,8 +215,8 @@ void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest) | |||
265 | /** | 215 | /** |
266 | * tipc_enable_bearer - enable bearer with the given name | 216 | * tipc_enable_bearer - enable bearer with the given name |
267 | */ | 217 | */ |
268 | int tipc_enable_bearer(struct net *net, const char *name, u32 disc_domain, | 218 | static int tipc_enable_bearer(struct net *net, const char *name, |
269 | u32 priority) | 219 | u32 disc_domain, u32 priority) |
270 | { | 220 | { |
271 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 221 | struct tipc_net *tn = net_generic(net, tipc_net_id); |
272 | struct tipc_bearer *b_ptr; | 222 | struct tipc_bearer *b_ptr; |
@@ -422,22 +372,6 @@ static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr, | |||
422 | kfree_rcu(b_ptr, rcu); | 372 | kfree_rcu(b_ptr, rcu); |
423 | } | 373 | } |
424 | 374 | ||
425 | int tipc_disable_bearer(struct net *net, const char *name) | ||
426 | { | ||
427 | struct tipc_bearer *b_ptr; | ||
428 | int res; | ||
429 | |||
430 | b_ptr = tipc_bearer_find(net, name); | ||
431 | if (b_ptr == NULL) { | ||
432 | pr_warn("Attempt to disable unknown bearer <%s>\n", name); | ||
433 | res = -EINVAL; | ||
434 | } else { | ||
435 | bearer_disable(net, b_ptr, false); | ||
436 | res = 0; | ||
437 | } | ||
438 | return res; | ||
439 | } | ||
440 | |||
441 | int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b) | 375 | int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b) |
442 | { | 376 | { |
443 | struct net_device *dev; | 377 | struct net_device *dev; |
@@ -658,7 +592,7 @@ static int __tipc_nl_add_bearer(struct tipc_nl_msg *msg, | |||
658 | struct nlattr *attrs; | 592 | struct nlattr *attrs; |
659 | struct nlattr *prop; | 593 | struct nlattr *prop; |
660 | 594 | ||
661 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, | 595 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, |
662 | NLM_F_MULTI, TIPC_NL_BEARER_GET); | 596 | NLM_F_MULTI, TIPC_NL_BEARER_GET); |
663 | if (!hdr) | 597 | if (!hdr) |
664 | return -EMSGSIZE; | 598 | return -EMSGSIZE; |
@@ -785,7 +719,7 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) | |||
785 | char *name; | 719 | char *name; |
786 | struct tipc_bearer *bearer; | 720 | struct tipc_bearer *bearer; |
787 | struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; | 721 | struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; |
788 | struct net *net = genl_info_net(info); | 722 | struct net *net = sock_net(skb->sk); |
789 | 723 | ||
790 | if (!info->attrs[TIPC_NLA_BEARER]) | 724 | if (!info->attrs[TIPC_NLA_BEARER]) |
791 | return -EINVAL; | 725 | return -EINVAL; |
@@ -816,11 +750,11 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) | |||
816 | 750 | ||
817 | int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) | 751 | int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) |
818 | { | 752 | { |
819 | struct net *net = genl_info_net(info); | ||
820 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
821 | int err; | 753 | int err; |
822 | char *bearer; | 754 | char *bearer; |
823 | struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; | 755 | struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; |
756 | struct net *net = sock_net(skb->sk); | ||
757 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
824 | u32 domain; | 758 | u32 domain; |
825 | u32 prio; | 759 | u32 prio; |
826 | 760 | ||
@@ -924,7 +858,7 @@ static int __tipc_nl_add_media(struct tipc_nl_msg *msg, | |||
924 | struct nlattr *attrs; | 858 | struct nlattr *attrs; |
925 | struct nlattr *prop; | 859 | struct nlattr *prop; |
926 | 860 | ||
927 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, | 861 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, |
928 | NLM_F_MULTI, TIPC_NL_MEDIA_GET); | 862 | NLM_F_MULTI, TIPC_NL_MEDIA_GET); |
929 | if (!hdr) | 863 | if (!hdr) |
930 | return -EMSGSIZE; | 864 | return -EMSGSIZE; |
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index c035e3e24764..6b17795ff8bc 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h | |||
@@ -173,9 +173,6 @@ struct tipc_bearer_names { | |||
173 | */ | 173 | */ |
174 | 174 | ||
175 | void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr); | 175 | void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr); |
176 | int tipc_enable_bearer(struct net *net, const char *bearer_name, | ||
177 | u32 disc_domain, u32 priority); | ||
178 | int tipc_disable_bearer(struct net *net, const char *name); | ||
179 | 176 | ||
180 | /* | 177 | /* |
181 | * Routines made available to TIPC by supported media types | 178 | * Routines made available to TIPC by supported media types |
@@ -199,13 +196,11 @@ int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info); | |||
199 | int tipc_media_set_priority(const char *name, u32 new_value); | 196 | int tipc_media_set_priority(const char *name, u32 new_value); |
200 | int tipc_media_set_window(const char *name, u32 new_value); | 197 | int tipc_media_set_window(const char *name, u32 new_value); |
201 | void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); | 198 | void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); |
202 | struct sk_buff *tipc_media_get_names(void); | ||
203 | int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b); | 199 | int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b); |
204 | void tipc_disable_l2_media(struct tipc_bearer *b); | 200 | void tipc_disable_l2_media(struct tipc_bearer *b); |
205 | int tipc_l2_send_msg(struct net *net, struct sk_buff *buf, | 201 | int tipc_l2_send_msg(struct net *net, struct sk_buff *buf, |
206 | struct tipc_bearer *b, struct tipc_media_addr *dest); | 202 | struct tipc_bearer *b, struct tipc_media_addr *dest); |
207 | 203 | ||
208 | struct sk_buff *tipc_bearer_get_names(struct net *net); | ||
209 | void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest); | 204 | void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest); |
210 | void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest); | 205 | void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest); |
211 | struct tipc_bearer *tipc_bearer_find(struct net *net, const char *name); | 206 | struct tipc_bearer *tipc_bearer_find(struct net *net, const char *name); |
diff --git a/net/tipc/config.c b/net/tipc/config.c deleted file mode 100644 index 6873360cda53..000000000000 --- a/net/tipc/config.c +++ /dev/null | |||
@@ -1,332 +0,0 @@ | |||
1 | /* | ||
2 | * net/tipc/config.c: TIPC configuration management code | ||
3 | * | ||
4 | * Copyright (c) 2002-2006, Ericsson AB | ||
5 | * Copyright (c) 2004-2007, 2010-2013, Wind River Systems | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer in the | ||
15 | * documentation and/or other materials provided with the distribution. | ||
16 | * 3. Neither the names of the copyright holders nor the names of its | ||
17 | * contributors may be used to endorse or promote products derived from | ||
18 | * this software without specific prior written permission. | ||
19 | * | ||
20 | * Alternatively, this software may be distributed under the terms of the | ||
21 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
22 | * Software Foundation. | ||
23 | * | ||
24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
28 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
29 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
30 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
31 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
32 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
33 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
34 | * POSSIBILITY OF SUCH DAMAGE. | ||
35 | */ | ||
36 | |||
37 | #include "core.h" | ||
38 | #include "socket.h" | ||
39 | #include "name_table.h" | ||
40 | #include "config.h" | ||
41 | #include "server.h" | ||
42 | |||
43 | #define REPLY_TRUNCATED "<truncated>\n" | ||
44 | |||
45 | static const void *req_tlv_area; /* request message TLV area */ | ||
46 | static int req_tlv_space; /* request message TLV area size */ | ||
47 | static int rep_headroom; /* reply message headroom to use */ | ||
48 | |||
49 | struct sk_buff *tipc_cfg_reply_alloc(int payload_size) | ||
50 | { | ||
51 | struct sk_buff *buf; | ||
52 | |||
53 | buf = alloc_skb(rep_headroom + payload_size, GFP_ATOMIC); | ||
54 | if (buf) | ||
55 | skb_reserve(buf, rep_headroom); | ||
56 | return buf; | ||
57 | } | ||
58 | |||
59 | int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, | ||
60 | void *tlv_data, int tlv_data_size) | ||
61 | { | ||
62 | struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf); | ||
63 | int new_tlv_space = TLV_SPACE(tlv_data_size); | ||
64 | |||
65 | if (skb_tailroom(buf) < new_tlv_space) | ||
66 | return 0; | ||
67 | skb_put(buf, new_tlv_space); | ||
68 | tlv->tlv_type = htons(tlv_type); | ||
69 | tlv->tlv_len = htons(TLV_LENGTH(tlv_data_size)); | ||
70 | if (tlv_data_size && tlv_data) | ||
71 | memcpy(TLV_DATA(tlv), tlv_data, tlv_data_size); | ||
72 | return 1; | ||
73 | } | ||
74 | |||
75 | static struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value) | ||
76 | { | ||
77 | struct sk_buff *buf; | ||
78 | __be32 value_net; | ||
79 | |||
80 | buf = tipc_cfg_reply_alloc(TLV_SPACE(sizeof(value))); | ||
81 | if (buf) { | ||
82 | value_net = htonl(value); | ||
83 | tipc_cfg_append_tlv(buf, tlv_type, &value_net, | ||
84 | sizeof(value_net)); | ||
85 | } | ||
86 | return buf; | ||
87 | } | ||
88 | |||
89 | static struct sk_buff *tipc_cfg_reply_unsigned(u32 value) | ||
90 | { | ||
91 | return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value); | ||
92 | } | ||
93 | |||
94 | struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string) | ||
95 | { | ||
96 | struct sk_buff *buf; | ||
97 | int string_len = strlen(string) + 1; | ||
98 | |||
99 | buf = tipc_cfg_reply_alloc(TLV_SPACE(string_len)); | ||
100 | if (buf) | ||
101 | tipc_cfg_append_tlv(buf, tlv_type, string, string_len); | ||
102 | return buf; | ||
103 | } | ||
104 | |||
105 | static struct sk_buff *tipc_show_stats(void) | ||
106 | { | ||
107 | struct sk_buff *buf; | ||
108 | struct tlv_desc *rep_tlv; | ||
109 | char *pb; | ||
110 | int pb_len; | ||
111 | int str_len; | ||
112 | u32 value; | ||
113 | |||
114 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) | ||
115 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | ||
116 | |||
117 | value = ntohl(*(u32 *)TLV_DATA(req_tlv_area)); | ||
118 | if (value != 0) | ||
119 | return tipc_cfg_reply_error_string("unsupported argument"); | ||
120 | |||
121 | buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); | ||
122 | if (buf == NULL) | ||
123 | return NULL; | ||
124 | |||
125 | rep_tlv = (struct tlv_desc *)buf->data; | ||
126 | pb = TLV_DATA(rep_tlv); | ||
127 | pb_len = ULTRA_STRING_MAX_LEN; | ||
128 | |||
129 | str_len = tipc_snprintf(pb, pb_len, "TIPC version " TIPC_MOD_VER "\n"); | ||
130 | str_len += 1; /* for "\0" */ | ||
131 | skb_put(buf, TLV_SPACE(str_len)); | ||
132 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | ||
133 | |||
134 | return buf; | ||
135 | } | ||
136 | |||
137 | static struct sk_buff *cfg_enable_bearer(struct net *net) | ||
138 | { | ||
139 | struct tipc_bearer_config *args; | ||
140 | |||
141 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_CONFIG)) | ||
142 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | ||
143 | |||
144 | args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area); | ||
145 | if (tipc_enable_bearer(net, args->name, | ||
146 | ntohl(args->disc_domain), | ||
147 | ntohl(args->priority))) | ||
148 | return tipc_cfg_reply_error_string("unable to enable bearer"); | ||
149 | |||
150 | return tipc_cfg_reply_none(); | ||
151 | } | ||
152 | |||
153 | static struct sk_buff *cfg_disable_bearer(struct net *net) | ||
154 | { | ||
155 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_NAME)) | ||
156 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | ||
157 | |||
158 | if (tipc_disable_bearer(net, (char *)TLV_DATA(req_tlv_area))) | ||
159 | return tipc_cfg_reply_error_string("unable to disable bearer"); | ||
160 | |||
161 | return tipc_cfg_reply_none(); | ||
162 | } | ||
163 | |||
164 | static struct sk_buff *cfg_set_own_addr(struct net *net) | ||
165 | { | ||
166 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
167 | u32 addr; | ||
168 | |||
169 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) | ||
170 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | ||
171 | |||
172 | addr = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); | ||
173 | if (addr == tn->own_addr) | ||
174 | return tipc_cfg_reply_none(); | ||
175 | if (!tipc_addr_node_valid(addr)) | ||
176 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE | ||
177 | " (node address)"); | ||
178 | if (tn->own_addr) | ||
179 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | ||
180 | " (cannot change node address once assigned)"); | ||
181 | if (!tipc_net_start(net, addr)) | ||
182 | return tipc_cfg_reply_none(); | ||
183 | |||
184 | return tipc_cfg_reply_error_string("cannot change to network mode"); | ||
185 | } | ||
186 | |||
187 | static struct sk_buff *cfg_set_netid(struct net *net) | ||
188 | { | ||
189 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
190 | u32 value; | ||
191 | |||
192 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) | ||
193 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | ||
194 | value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); | ||
195 | if (value == tn->net_id) | ||
196 | return tipc_cfg_reply_none(); | ||
197 | if (value < 1 || value > 9999) | ||
198 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE | ||
199 | " (network id must be 1-9999)"); | ||
200 | if (tn->own_addr) | ||
201 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | ||
202 | " (cannot change network id once TIPC has joined a network)"); | ||
203 | tn->net_id = value; | ||
204 | return tipc_cfg_reply_none(); | ||
205 | } | ||
206 | |||
207 | struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, | ||
208 | const void *request_area, int request_space, | ||
209 | int reply_headroom) | ||
210 | { | ||
211 | struct sk_buff *rep_tlv_buf; | ||
212 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
213 | |||
214 | rtnl_lock(); | ||
215 | |||
216 | /* Save request and reply details in a well-known location */ | ||
217 | req_tlv_area = request_area; | ||
218 | req_tlv_space = request_space; | ||
219 | rep_headroom = reply_headroom; | ||
220 | |||
221 | /* Check command authorization */ | ||
222 | if (likely(in_own_node(net, orig_node))) { | ||
223 | /* command is permitted */ | ||
224 | } else { | ||
225 | rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | ||
226 | " (cannot be done remotely)"); | ||
227 | goto exit; | ||
228 | } | ||
229 | |||
230 | /* Call appropriate processing routine */ | ||
231 | switch (cmd) { | ||
232 | case TIPC_CMD_NOOP: | ||
233 | rep_tlv_buf = tipc_cfg_reply_none(); | ||
234 | break; | ||
235 | case TIPC_CMD_GET_NODES: | ||
236 | rep_tlv_buf = tipc_node_get_nodes(net, req_tlv_area, | ||
237 | req_tlv_space); | ||
238 | break; | ||
239 | case TIPC_CMD_GET_LINKS: | ||
240 | rep_tlv_buf = tipc_node_get_links(net, req_tlv_area, | ||
241 | req_tlv_space); | ||
242 | break; | ||
243 | case TIPC_CMD_SHOW_LINK_STATS: | ||
244 | rep_tlv_buf = tipc_link_cmd_show_stats(net, req_tlv_area, | ||
245 | req_tlv_space); | ||
246 | break; | ||
247 | case TIPC_CMD_RESET_LINK_STATS: | ||
248 | rep_tlv_buf = tipc_link_cmd_reset_stats(net, req_tlv_area, | ||
249 | req_tlv_space); | ||
250 | break; | ||
251 | case TIPC_CMD_SHOW_NAME_TABLE: | ||
252 | rep_tlv_buf = tipc_nametbl_get(net, req_tlv_area, | ||
253 | req_tlv_space); | ||
254 | break; | ||
255 | case TIPC_CMD_GET_BEARER_NAMES: | ||
256 | rep_tlv_buf = tipc_bearer_get_names(net); | ||
257 | break; | ||
258 | case TIPC_CMD_GET_MEDIA_NAMES: | ||
259 | rep_tlv_buf = tipc_media_get_names(); | ||
260 | break; | ||
261 | case TIPC_CMD_SHOW_PORTS: | ||
262 | rep_tlv_buf = tipc_sk_socks_show(net); | ||
263 | break; | ||
264 | case TIPC_CMD_SHOW_STATS: | ||
265 | rep_tlv_buf = tipc_show_stats(); | ||
266 | break; | ||
267 | case TIPC_CMD_SET_LINK_TOL: | ||
268 | case TIPC_CMD_SET_LINK_PRI: | ||
269 | case TIPC_CMD_SET_LINK_WINDOW: | ||
270 | rep_tlv_buf = tipc_link_cmd_config(net, req_tlv_area, | ||
271 | req_tlv_space, cmd); | ||
272 | break; | ||
273 | case TIPC_CMD_ENABLE_BEARER: | ||
274 | rep_tlv_buf = cfg_enable_bearer(net); | ||
275 | break; | ||
276 | case TIPC_CMD_DISABLE_BEARER: | ||
277 | rep_tlv_buf = cfg_disable_bearer(net); | ||
278 | break; | ||
279 | case TIPC_CMD_SET_NODE_ADDR: | ||
280 | rep_tlv_buf = cfg_set_own_addr(net); | ||
281 | break; | ||
282 | case TIPC_CMD_SET_NETID: | ||
283 | rep_tlv_buf = cfg_set_netid(net); | ||
284 | break; | ||
285 | case TIPC_CMD_GET_NETID: | ||
286 | rep_tlv_buf = tipc_cfg_reply_unsigned(tn->net_id); | ||
287 | break; | ||
288 | case TIPC_CMD_NOT_NET_ADMIN: | ||
289 | rep_tlv_buf = | ||
290 | tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); | ||
291 | break; | ||
292 | case TIPC_CMD_SET_MAX_ZONES: | ||
293 | case TIPC_CMD_GET_MAX_ZONES: | ||
294 | case TIPC_CMD_SET_MAX_SLAVES: | ||
295 | case TIPC_CMD_GET_MAX_SLAVES: | ||
296 | case TIPC_CMD_SET_MAX_CLUSTERS: | ||
297 | case TIPC_CMD_GET_MAX_CLUSTERS: | ||
298 | case TIPC_CMD_SET_MAX_NODES: | ||
299 | case TIPC_CMD_GET_MAX_NODES: | ||
300 | case TIPC_CMD_SET_MAX_SUBSCR: | ||
301 | case TIPC_CMD_GET_MAX_SUBSCR: | ||
302 | case TIPC_CMD_SET_MAX_PUBL: | ||
303 | case TIPC_CMD_GET_MAX_PUBL: | ||
304 | case TIPC_CMD_SET_LOG_SIZE: | ||
305 | case TIPC_CMD_SET_REMOTE_MNG: | ||
306 | case TIPC_CMD_GET_REMOTE_MNG: | ||
307 | case TIPC_CMD_DUMP_LOG: | ||
308 | case TIPC_CMD_SET_MAX_PORTS: | ||
309 | case TIPC_CMD_GET_MAX_PORTS: | ||
310 | rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | ||
311 | " (obsolete command)"); | ||
312 | break; | ||
313 | default: | ||
314 | rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | ||
315 | " (unknown command)"); | ||
316 | break; | ||
317 | } | ||
318 | |||
319 | WARN_ON(rep_tlv_buf->len > TLV_SPACE(ULTRA_STRING_MAX_LEN)); | ||
320 | |||
321 | /* Append an error message if we cannot return all requested data */ | ||
322 | if (rep_tlv_buf->len == TLV_SPACE(ULTRA_STRING_MAX_LEN)) { | ||
323 | if (*(rep_tlv_buf->data + ULTRA_STRING_MAX_LEN) != '\0') | ||
324 | sprintf(rep_tlv_buf->data + rep_tlv_buf->len - | ||
325 | sizeof(REPLY_TRUNCATED) - 1, REPLY_TRUNCATED); | ||
326 | } | ||
327 | |||
328 | /* Return reply buffer */ | ||
329 | exit: | ||
330 | rtnl_unlock(); | ||
331 | return rep_tlv_buf; | ||
332 | } | ||
diff --git a/net/tipc/config.h b/net/tipc/config.h deleted file mode 100644 index 9e9b575fc429..000000000000 --- a/net/tipc/config.h +++ /dev/null | |||
@@ -1,67 +0,0 @@ | |||
1 | /* | ||
2 | * net/tipc/config.h: Include file for TIPC configuration service code | ||
3 | * | ||
4 | * Copyright (c) 2003-2006, Ericsson AB | ||
5 | * Copyright (c) 2005, Wind River Systems | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer in the | ||
15 | * documentation and/or other materials provided with the distribution. | ||
16 | * 3. Neither the names of the copyright holders nor the names of its | ||
17 | * contributors may be used to endorse or promote products derived from | ||
18 | * this software without specific prior written permission. | ||
19 | * | ||
20 | * Alternatively, this software may be distributed under the terms of the | ||
21 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
22 | * Software Foundation. | ||
23 | * | ||
24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
28 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
29 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
30 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
31 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
32 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
33 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
34 | * POSSIBILITY OF SUCH DAMAGE. | ||
35 | */ | ||
36 | |||
37 | #ifndef _TIPC_CONFIG_H | ||
38 | #define _TIPC_CONFIG_H | ||
39 | |||
40 | #include "link.h" | ||
41 | |||
42 | #define ULTRA_STRING_MAX_LEN 32768 | ||
43 | |||
44 | struct sk_buff *tipc_cfg_reply_alloc(int payload_size); | ||
45 | int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, | ||
46 | void *tlv_data, int tlv_data_size); | ||
47 | struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string); | ||
48 | |||
49 | static inline struct sk_buff *tipc_cfg_reply_none(void) | ||
50 | { | ||
51 | return tipc_cfg_reply_alloc(0); | ||
52 | } | ||
53 | |||
54 | static inline struct sk_buff *tipc_cfg_reply_error_string(char *string) | ||
55 | { | ||
56 | return tipc_cfg_reply_string_type(TIPC_TLV_ERROR_STRING, string); | ||
57 | } | ||
58 | |||
59 | static inline struct sk_buff *tipc_cfg_reply_ultra_string(char *string) | ||
60 | { | ||
61 | return tipc_cfg_reply_string_type(TIPC_TLV_ULTRA_STRING, string); | ||
62 | } | ||
63 | |||
64 | struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd, | ||
65 | const void *req_tlv_area, int req_tlv_space, | ||
66 | int headroom); | ||
67 | #endif | ||
diff --git a/net/tipc/core.c b/net/tipc/core.c index 674bd2698528..935205e6bcfe 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
@@ -39,7 +39,8 @@ | |||
39 | #include "core.h" | 39 | #include "core.h" |
40 | #include "name_table.h" | 40 | #include "name_table.h" |
41 | #include "subscr.h" | 41 | #include "subscr.h" |
42 | #include "config.h" | 42 | #include "bearer.h" |
43 | #include "net.h" | ||
43 | #include "socket.h" | 44 | #include "socket.h" |
44 | 45 | ||
45 | #include <linux/module.h> | 46 | #include <linux/module.h> |
@@ -111,6 +112,10 @@ static int __init tipc_init(void) | |||
111 | if (err) | 112 | if (err) |
112 | goto out_netlink; | 113 | goto out_netlink; |
113 | 114 | ||
115 | err = tipc_netlink_compat_start(); | ||
116 | if (err) | ||
117 | goto out_netlink_compat; | ||
118 | |||
114 | err = tipc_socket_init(); | 119 | err = tipc_socket_init(); |
115 | if (err) | 120 | if (err) |
116 | goto out_socket; | 121 | goto out_socket; |
@@ -136,6 +141,8 @@ out_pernet: | |||
136 | out_sysctl: | 141 | out_sysctl: |
137 | tipc_socket_stop(); | 142 | tipc_socket_stop(); |
138 | out_socket: | 143 | out_socket: |
144 | tipc_netlink_compat_stop(); | ||
145 | out_netlink_compat: | ||
139 | tipc_netlink_stop(); | 146 | tipc_netlink_stop(); |
140 | out_netlink: | 147 | out_netlink: |
141 | pr_err("Unable to start in single node mode\n"); | 148 | pr_err("Unable to start in single node mode\n"); |
@@ -146,6 +153,7 @@ static void __exit tipc_exit(void) | |||
146 | { | 153 | { |
147 | tipc_bearer_cleanup(); | 154 | tipc_bearer_cleanup(); |
148 | tipc_netlink_stop(); | 155 | tipc_netlink_stop(); |
156 | tipc_netlink_compat_stop(); | ||
149 | tipc_socket_stop(); | 157 | tipc_socket_stop(); |
150 | tipc_unregister_sysctl(); | 158 | tipc_unregister_sysctl(); |
151 | unregister_pernet_subsys(&tipc_net_ops); | 159 | unregister_pernet_subsys(&tipc_net_ops); |
diff --git a/net/tipc/core.h b/net/tipc/core.h index 817b2e9d4227..3dc68c7a966d 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h | |||
@@ -70,8 +70,6 @@ | |||
70 | 70 | ||
71 | #define TIPC_MOD_VER "2.0.0" | 71 | #define TIPC_MOD_VER "2.0.0" |
72 | 72 | ||
73 | int tipc_snprintf(char *buf, int len, const char *fmt, ...); | ||
74 | |||
75 | extern int tipc_net_id __read_mostly; | 73 | extern int tipc_net_id __read_mostly; |
76 | extern int sysctl_tipc_rmem[3] __read_mostly; | 74 | extern int sysctl_tipc_rmem[3] __read_mostly; |
77 | extern int sysctl_tipc_named_timeout __read_mostly; | 75 | extern int sysctl_tipc_named_timeout __read_mostly; |
@@ -115,5 +113,4 @@ void tipc_unregister_sysctl(void); | |||
115 | #define tipc_register_sysctl() 0 | 113 | #define tipc_register_sysctl() 0 |
116 | #define tipc_unregister_sysctl() | 114 | #define tipc_unregister_sysctl() |
117 | #endif | 115 | #endif |
118 | |||
119 | #endif | 116 | #endif |
diff --git a/net/tipc/link.c b/net/tipc/link.c index 942491234099..a4cf364316de 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include "socket.h" | 40 | #include "socket.h" |
41 | #include "name_distr.h" | 41 | #include "name_distr.h" |
42 | #include "discover.h" | 42 | #include "discover.h" |
43 | #include "config.h" | ||
44 | #include "netlink.h" | 43 | #include "netlink.h" |
45 | 44 | ||
46 | #include <linux/pkt_sched.h> | 45 | #include <linux/pkt_sched.h> |
@@ -1959,150 +1958,6 @@ static struct tipc_node *tipc_link_find_owner(struct net *net, | |||
1959 | } | 1958 | } |
1960 | 1959 | ||
1961 | /** | 1960 | /** |
1962 | * link_value_is_valid -- validate proposed link tolerance/priority/window | ||
1963 | * | ||
1964 | * @cmd: value type (TIPC_CMD_SET_LINK_*) | ||
1965 | * @new_value: the new value | ||
1966 | * | ||
1967 | * Returns 1 if value is within range, 0 if not. | ||
1968 | */ | ||
1969 | static int link_value_is_valid(u16 cmd, u32 new_value) | ||
1970 | { | ||
1971 | switch (cmd) { | ||
1972 | case TIPC_CMD_SET_LINK_TOL: | ||
1973 | return (new_value >= TIPC_MIN_LINK_TOL) && | ||
1974 | (new_value <= TIPC_MAX_LINK_TOL); | ||
1975 | case TIPC_CMD_SET_LINK_PRI: | ||
1976 | return (new_value <= TIPC_MAX_LINK_PRI); | ||
1977 | case TIPC_CMD_SET_LINK_WINDOW: | ||
1978 | return (new_value >= TIPC_MIN_LINK_WIN) && | ||
1979 | (new_value <= TIPC_MAX_LINK_WIN); | ||
1980 | } | ||
1981 | return 0; | ||
1982 | } | ||
1983 | |||
1984 | /** | ||
1985 | * link_cmd_set_value - change priority/tolerance/window for link/bearer/media | ||
1986 | * @net: the applicable net namespace | ||
1987 | * @name: ptr to link, bearer, or media name | ||
1988 | * @new_value: new value of link, bearer, or media setting | ||
1989 | * @cmd: which link, bearer, or media attribute to set (TIPC_CMD_SET_LINK_*) | ||
1990 | * | ||
1991 | * Caller must hold RTNL lock to ensure link/bearer/media is not deleted. | ||
1992 | * | ||
1993 | * Returns 0 if value updated and negative value on error. | ||
1994 | */ | ||
1995 | static int link_cmd_set_value(struct net *net, const char *name, u32 new_value, | ||
1996 | u16 cmd) | ||
1997 | { | ||
1998 | struct tipc_node *node; | ||
1999 | struct tipc_link *l_ptr; | ||
2000 | struct tipc_bearer *b_ptr; | ||
2001 | struct tipc_media *m_ptr; | ||
2002 | int bearer_id; | ||
2003 | int res = 0; | ||
2004 | |||
2005 | node = tipc_link_find_owner(net, name, &bearer_id); | ||
2006 | if (node) { | ||
2007 | tipc_node_lock(node); | ||
2008 | l_ptr = node->links[bearer_id]; | ||
2009 | |||
2010 | if (l_ptr) { | ||
2011 | switch (cmd) { | ||
2012 | case TIPC_CMD_SET_LINK_TOL: | ||
2013 | link_set_supervision_props(l_ptr, new_value); | ||
2014 | tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, | ||
2015 | new_value, 0, 0); | ||
2016 | break; | ||
2017 | case TIPC_CMD_SET_LINK_PRI: | ||
2018 | l_ptr->priority = new_value; | ||
2019 | tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, | ||
2020 | 0, new_value, 0); | ||
2021 | break; | ||
2022 | case TIPC_CMD_SET_LINK_WINDOW: | ||
2023 | tipc_link_set_queue_limits(l_ptr, new_value); | ||
2024 | break; | ||
2025 | default: | ||
2026 | res = -EINVAL; | ||
2027 | break; | ||
2028 | } | ||
2029 | } | ||
2030 | tipc_node_unlock(node); | ||
2031 | return res; | ||
2032 | } | ||
2033 | |||
2034 | b_ptr = tipc_bearer_find(net, name); | ||
2035 | if (b_ptr) { | ||
2036 | switch (cmd) { | ||
2037 | case TIPC_CMD_SET_LINK_TOL: | ||
2038 | b_ptr->tolerance = new_value; | ||
2039 | break; | ||
2040 | case TIPC_CMD_SET_LINK_PRI: | ||
2041 | b_ptr->priority = new_value; | ||
2042 | break; | ||
2043 | case TIPC_CMD_SET_LINK_WINDOW: | ||
2044 | b_ptr->window = new_value; | ||
2045 | break; | ||
2046 | default: | ||
2047 | res = -EINVAL; | ||
2048 | break; | ||
2049 | } | ||
2050 | return res; | ||
2051 | } | ||
2052 | |||
2053 | m_ptr = tipc_media_find(name); | ||
2054 | if (!m_ptr) | ||
2055 | return -ENODEV; | ||
2056 | switch (cmd) { | ||
2057 | case TIPC_CMD_SET_LINK_TOL: | ||
2058 | m_ptr->tolerance = new_value; | ||
2059 | break; | ||
2060 | case TIPC_CMD_SET_LINK_PRI: | ||
2061 | m_ptr->priority = new_value; | ||
2062 | break; | ||
2063 | case TIPC_CMD_SET_LINK_WINDOW: | ||
2064 | m_ptr->window = new_value; | ||
2065 | break; | ||
2066 | default: | ||
2067 | res = -EINVAL; | ||
2068 | break; | ||
2069 | } | ||
2070 | return res; | ||
2071 | } | ||
2072 | |||
2073 | struct sk_buff *tipc_link_cmd_config(struct net *net, const void *req_tlv_area, | ||
2074 | int req_tlv_space, u16 cmd) | ||
2075 | { | ||
2076 | struct tipc_link_config *args; | ||
2077 | u32 new_value; | ||
2078 | int res; | ||
2079 | |||
2080 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_CONFIG)) | ||
2081 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | ||
2082 | |||
2083 | args = (struct tipc_link_config *)TLV_DATA(req_tlv_area); | ||
2084 | new_value = ntohl(args->value); | ||
2085 | |||
2086 | if (!link_value_is_valid(cmd, new_value)) | ||
2087 | return tipc_cfg_reply_error_string( | ||
2088 | "cannot change, value invalid"); | ||
2089 | |||
2090 | if (!strcmp(args->name, tipc_bclink_name)) { | ||
2091 | if ((cmd == TIPC_CMD_SET_LINK_WINDOW) && | ||
2092 | (tipc_bclink_set_queue_limits(net, new_value) == 0)) | ||
2093 | return tipc_cfg_reply_none(); | ||
2094 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | ||
2095 | " (cannot change setting on broadcast link)"); | ||
2096 | } | ||
2097 | |||
2098 | res = link_cmd_set_value(net, args->name, new_value, cmd); | ||
2099 | if (res) | ||
2100 | return tipc_cfg_reply_error_string("cannot change link setting"); | ||
2101 | |||
2102 | return tipc_cfg_reply_none(); | ||
2103 | } | ||
2104 | |||
2105 | /** | ||
2106 | * link_reset_statistics - reset link statistics | 1961 | * link_reset_statistics - reset link statistics |
2107 | * @l_ptr: pointer to link | 1962 | * @l_ptr: pointer to link |
2108 | */ | 1963 | */ |
@@ -2113,180 +1968,6 @@ static void link_reset_statistics(struct tipc_link *l_ptr) | |||
2113 | l_ptr->stats.recv_info = l_ptr->next_in_no; | 1968 | l_ptr->stats.recv_info = l_ptr->next_in_no; |
2114 | } | 1969 | } |
2115 | 1970 | ||
2116 | struct sk_buff *tipc_link_cmd_reset_stats(struct net *net, | ||
2117 | const void *req_tlv_area, | ||
2118 | int req_tlv_space) | ||
2119 | { | ||
2120 | char *link_name; | ||
2121 | struct tipc_link *l_ptr; | ||
2122 | struct tipc_node *node; | ||
2123 | unsigned int bearer_id; | ||
2124 | |||
2125 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME)) | ||
2126 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | ||
2127 | |||
2128 | link_name = (char *)TLV_DATA(req_tlv_area); | ||
2129 | if (!strcmp(link_name, tipc_bclink_name)) { | ||
2130 | if (tipc_bclink_reset_stats(net)) | ||
2131 | return tipc_cfg_reply_error_string("link not found"); | ||
2132 | return tipc_cfg_reply_none(); | ||
2133 | } | ||
2134 | node = tipc_link_find_owner(net, link_name, &bearer_id); | ||
2135 | if (!node) | ||
2136 | return tipc_cfg_reply_error_string("link not found"); | ||
2137 | |||
2138 | tipc_node_lock(node); | ||
2139 | l_ptr = node->links[bearer_id]; | ||
2140 | if (!l_ptr) { | ||
2141 | tipc_node_unlock(node); | ||
2142 | return tipc_cfg_reply_error_string("link not found"); | ||
2143 | } | ||
2144 | link_reset_statistics(l_ptr); | ||
2145 | tipc_node_unlock(node); | ||
2146 | return tipc_cfg_reply_none(); | ||
2147 | } | ||
2148 | |||
2149 | /** | ||
2150 | * percent - convert count to a percentage of total (rounding up or down) | ||
2151 | */ | ||
2152 | static u32 percent(u32 count, u32 total) | ||
2153 | { | ||
2154 | return (count * 100 + (total / 2)) / total; | ||
2155 | } | ||
2156 | |||
2157 | /** | ||
2158 | * tipc_link_stats - print link statistics | ||
2159 | * @net: the applicable net namespace | ||
2160 | * @name: link name | ||
2161 | * @buf: print buffer area | ||
2162 | * @buf_size: size of print buffer area | ||
2163 | * | ||
2164 | * Returns length of print buffer data string (or 0 if error) | ||
2165 | */ | ||
2166 | static int tipc_link_stats(struct net *net, const char *name, char *buf, | ||
2167 | const u32 buf_size) | ||
2168 | { | ||
2169 | struct tipc_link *l; | ||
2170 | struct tipc_stats *s; | ||
2171 | struct tipc_node *node; | ||
2172 | char *status; | ||
2173 | u32 profile_total = 0; | ||
2174 | unsigned int bearer_id; | ||
2175 | int ret; | ||
2176 | |||
2177 | if (!strcmp(name, tipc_bclink_name)) | ||
2178 | return tipc_bclink_stats(net, buf, buf_size); | ||
2179 | |||
2180 | node = tipc_link_find_owner(net, name, &bearer_id); | ||
2181 | if (!node) | ||
2182 | return 0; | ||
2183 | |||
2184 | tipc_node_lock(node); | ||
2185 | |||
2186 | l = node->links[bearer_id]; | ||
2187 | if (!l) { | ||
2188 | tipc_node_unlock(node); | ||
2189 | return 0; | ||
2190 | } | ||
2191 | |||
2192 | s = &l->stats; | ||
2193 | |||
2194 | if (tipc_link_is_active(l)) | ||
2195 | status = "ACTIVE"; | ||
2196 | else if (tipc_link_is_up(l)) | ||
2197 | status = "STANDBY"; | ||
2198 | else | ||
2199 | status = "DEFUNCT"; | ||
2200 | |||
2201 | ret = tipc_snprintf(buf, buf_size, "Link <%s>\n" | ||
2202 | " %s MTU:%u Priority:%u Tolerance:%u ms" | ||
2203 | " Window:%u packets\n", | ||
2204 | l->name, status, l->max_pkt, l->priority, | ||
2205 | l->tolerance, l->queue_limit[0]); | ||
2206 | |||
2207 | ret += tipc_snprintf(buf + ret, buf_size - ret, | ||
2208 | " RX packets:%u fragments:%u/%u bundles:%u/%u\n", | ||
2209 | l->next_in_no - s->recv_info, s->recv_fragments, | ||
2210 | s->recv_fragmented, s->recv_bundles, | ||
2211 | s->recv_bundled); | ||
2212 | |||
2213 | ret += tipc_snprintf(buf + ret, buf_size - ret, | ||
2214 | " TX packets:%u fragments:%u/%u bundles:%u/%u\n", | ||
2215 | l->next_out_no - s->sent_info, s->sent_fragments, | ||
2216 | s->sent_fragmented, s->sent_bundles, | ||
2217 | s->sent_bundled); | ||
2218 | |||
2219 | profile_total = s->msg_length_counts; | ||
2220 | if (!profile_total) | ||
2221 | profile_total = 1; | ||
2222 | |||
2223 | ret += tipc_snprintf(buf + ret, buf_size - ret, | ||
2224 | " TX profile sample:%u packets average:%u octets\n" | ||
2225 | " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% " | ||
2226 | "-16384:%u%% -32768:%u%% -66000:%u%%\n", | ||
2227 | s->msg_length_counts, | ||
2228 | s->msg_lengths_total / profile_total, | ||
2229 | percent(s->msg_length_profile[0], profile_total), | ||
2230 | percent(s->msg_length_profile[1], profile_total), | ||
2231 | percent(s->msg_length_profile[2], profile_total), | ||
2232 | percent(s->msg_length_profile[3], profile_total), | ||
2233 | percent(s->msg_length_profile[4], profile_total), | ||
2234 | percent(s->msg_length_profile[5], profile_total), | ||
2235 | percent(s->msg_length_profile[6], profile_total)); | ||
2236 | |||
2237 | ret += tipc_snprintf(buf + ret, buf_size - ret, | ||
2238 | " RX states:%u probes:%u naks:%u defs:%u" | ||
2239 | " dups:%u\n", s->recv_states, s->recv_probes, | ||
2240 | s->recv_nacks, s->deferred_recv, s->duplicates); | ||
2241 | |||
2242 | ret += tipc_snprintf(buf + ret, buf_size - ret, | ||
2243 | " TX states:%u probes:%u naks:%u acks:%u" | ||
2244 | " dups:%u\n", s->sent_states, s->sent_probes, | ||
2245 | s->sent_nacks, s->sent_acks, s->retransmitted); | ||
2246 | |||
2247 | ret += tipc_snprintf(buf + ret, buf_size - ret, | ||
2248 | " Congestion link:%u Send queue" | ||
2249 | " max:%u avg:%u\n", s->link_congs, | ||
2250 | s->max_queue_sz, s->queue_sz_counts ? | ||
2251 | (s->accu_queue_sz / s->queue_sz_counts) : 0); | ||
2252 | |||
2253 | tipc_node_unlock(node); | ||
2254 | return ret; | ||
2255 | } | ||
2256 | |||
2257 | struct sk_buff *tipc_link_cmd_show_stats(struct net *net, | ||
2258 | const void *req_tlv_area, | ||
2259 | int req_tlv_space) | ||
2260 | { | ||
2261 | struct sk_buff *buf; | ||
2262 | struct tlv_desc *rep_tlv; | ||
2263 | int str_len; | ||
2264 | int pb_len; | ||
2265 | char *pb; | ||
2266 | |||
2267 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME)) | ||
2268 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | ||
2269 | |||
2270 | buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); | ||
2271 | if (!buf) | ||
2272 | return NULL; | ||
2273 | |||
2274 | rep_tlv = (struct tlv_desc *)buf->data; | ||
2275 | pb = TLV_DATA(rep_tlv); | ||
2276 | pb_len = ULTRA_STRING_MAX_LEN; | ||
2277 | str_len = tipc_link_stats(net, (char *)TLV_DATA(req_tlv_area), | ||
2278 | pb, pb_len); | ||
2279 | if (!str_len) { | ||
2280 | kfree_skb(buf); | ||
2281 | return tipc_cfg_reply_error_string("link not found"); | ||
2282 | } | ||
2283 | str_len += 1; /* for "\0" */ | ||
2284 | skb_put(buf, TLV_SPACE(str_len)); | ||
2285 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | ||
2286 | |||
2287 | return buf; | ||
2288 | } | ||
2289 | |||
2290 | static void link_print(struct tipc_link *l_ptr, const char *str) | 1971 | static void link_print(struct tipc_link *l_ptr, const char *str) |
2291 | { | 1972 | { |
2292 | struct tipc_net *tn = net_generic(l_ptr->owner->net, tipc_net_id); | 1973 | struct tipc_net *tn = net_generic(l_ptr->owner->net, tipc_net_id); |
@@ -2357,7 +2038,7 @@ int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info) | |||
2357 | struct tipc_link *link; | 2038 | struct tipc_link *link; |
2358 | struct tipc_node *node; | 2039 | struct tipc_node *node; |
2359 | struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1]; | 2040 | struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1]; |
2360 | struct net *net = genl_info_net(info); | 2041 | struct net *net = sock_net(skb->sk); |
2361 | 2042 | ||
2362 | if (!info->attrs[TIPC_NLA_LINK]) | 2043 | if (!info->attrs[TIPC_NLA_LINK]) |
2363 | return -EINVAL; | 2044 | return -EINVAL; |
@@ -2498,7 +2179,7 @@ static int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg, | |||
2498 | struct nlattr *prop; | 2179 | struct nlattr *prop; |
2499 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 2180 | struct tipc_net *tn = net_generic(net, tipc_net_id); |
2500 | 2181 | ||
2501 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, | 2182 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, |
2502 | NLM_F_MULTI, TIPC_NL_LINK_GET); | 2183 | NLM_F_MULTI, TIPC_NL_LINK_GET); |
2503 | if (!hdr) | 2184 | if (!hdr) |
2504 | return -EMSGSIZE; | 2185 | return -EMSGSIZE; |
@@ -2709,7 +2390,7 @@ int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info) | |||
2709 | struct tipc_link *link; | 2390 | struct tipc_link *link; |
2710 | struct tipc_node *node; | 2391 | struct tipc_node *node; |
2711 | struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1]; | 2392 | struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1]; |
2712 | struct net *net = genl_info_net(info); | 2393 | struct net *net = sock_net(skb->sk); |
2713 | 2394 | ||
2714 | if (!info->attrs[TIPC_NLA_LINK]) | 2395 | if (!info->attrs[TIPC_NLA_LINK]) |
2715 | return -EINVAL; | 2396 | return -EINVAL; |
diff --git a/net/tipc/link.h b/net/tipc/link.h index 34d3f55c4cea..7aeb52092bf3 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h | |||
@@ -215,14 +215,6 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr); | |||
215 | int tipc_link_is_up(struct tipc_link *l_ptr); | 215 | int tipc_link_is_up(struct tipc_link *l_ptr); |
216 | int tipc_link_is_active(struct tipc_link *l_ptr); | 216 | int tipc_link_is_active(struct tipc_link *l_ptr); |
217 | void tipc_link_purge_queues(struct tipc_link *l_ptr); | 217 | void tipc_link_purge_queues(struct tipc_link *l_ptr); |
218 | struct sk_buff *tipc_link_cmd_config(struct net *net, const void *req_tlv_area, | ||
219 | int req_tlv_space, u16 cmd); | ||
220 | struct sk_buff *tipc_link_cmd_show_stats(struct net *net, | ||
221 | const void *req_tlv_area, | ||
222 | int req_tlv_space); | ||
223 | struct sk_buff *tipc_link_cmd_reset_stats(struct net *net, | ||
224 | const void *req_tlv_area, | ||
225 | int req_tlv_space); | ||
226 | void tipc_link_reset_all(struct tipc_node *node); | 218 | void tipc_link_reset_all(struct tipc_node *node); |
227 | void tipc_link_reset(struct tipc_link *l_ptr); | 219 | void tipc_link_reset(struct tipc_link *l_ptr); |
228 | void tipc_link_reset_list(struct net *net, unsigned int bearer_id); | 220 | void tipc_link_reset_list(struct net *net, unsigned int bearer_id); |
diff --git a/net/tipc/log.c b/net/tipc/log.c deleted file mode 100644 index abef644f27d8..000000000000 --- a/net/tipc/log.c +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | /* | ||
2 | * net/tipc/log.c: TIPC print buffer routines for debugging | ||
3 | * | ||
4 | * Copyright (c) 1996-2006, Ericsson AB | ||
5 | * Copyright (c) 2005-2007, Wind River Systems | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer in the | ||
15 | * documentation and/or other materials provided with the distribution. | ||
16 | * 3. Neither the names of the copyright holders nor the names of its | ||
17 | * contributors may be used to endorse or promote products derived from | ||
18 | * this software without specific prior written permission. | ||
19 | * | ||
20 | * Alternatively, this software may be distributed under the terms of the | ||
21 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
22 | * Software Foundation. | ||
23 | * | ||
24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
28 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
29 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
30 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
31 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
32 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
33 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
34 | * POSSIBILITY OF SUCH DAMAGE. | ||
35 | */ | ||
36 | |||
37 | #include "core.h" | ||
38 | #include "config.h" | ||
39 | |||
40 | /** | ||
41 | * tipc_snprintf - append formatted output to print buffer | ||
42 | * @buf: pointer to print buffer | ||
43 | * @len: buffer length | ||
44 | * @fmt: formatted info to be printed | ||
45 | */ | ||
46 | int tipc_snprintf(char *buf, int len, const char *fmt, ...) | ||
47 | { | ||
48 | int i; | ||
49 | va_list args; | ||
50 | |||
51 | va_start(args, fmt); | ||
52 | i = vscnprintf(buf, len, fmt, args); | ||
53 | va_end(args); | ||
54 | return i; | ||
55 | } | ||
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 | */ | ||
779 | static 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 | */ | ||
818 | static 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 | */ | ||
852 | static 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 | */ | ||
875 | static 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 | |||
927 | struct 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 | |||
960 | int tipc_nametbl_init(struct net *net) | 778 | int 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; |
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h index 0304ddc6b101..1524a73830f7 100644 --- a/net/tipc/name_table.h +++ b/net/tipc/name_table.h | |||
@@ -97,8 +97,6 @@ struct name_table { | |||
97 | 97 | ||
98 | int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb); | 98 | int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb); |
99 | 99 | ||
100 | struct sk_buff *tipc_nametbl_get(struct net *net, const void *req_tlv_area, | ||
101 | int req_tlv_space); | ||
102 | u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node); | 100 | u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node); |
103 | int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, | 101 | int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, |
104 | u32 limit, struct tipc_plist *dports); | 102 | u32 limit, struct tipc_plist *dports); |
diff --git a/net/tipc/net.c b/net/tipc/net.c index 263267e0e7fe..a54f3cbe2246 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c | |||
@@ -40,8 +40,6 @@ | |||
40 | #include "subscr.h" | 40 | #include "subscr.h" |
41 | #include "socket.h" | 41 | #include "socket.h" |
42 | #include "node.h" | 42 | #include "node.h" |
43 | #include "config.h" | ||
44 | #include "bcast.h" | ||
45 | 43 | ||
46 | static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { | 44 | static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { |
47 | [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC }, | 45 | [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC }, |
@@ -156,7 +154,7 @@ static int __tipc_nl_add_net(struct net *net, struct tipc_nl_msg *msg) | |||
156 | void *hdr; | 154 | void *hdr; |
157 | struct nlattr *attrs; | 155 | struct nlattr *attrs; |
158 | 156 | ||
159 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, | 157 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, |
160 | NLM_F_MULTI, TIPC_NL_NET_GET); | 158 | NLM_F_MULTI, TIPC_NL_NET_GET); |
161 | if (!hdr) | 159 | if (!hdr) |
162 | return -EMSGSIZE; | 160 | return -EMSGSIZE; |
@@ -208,7 +206,7 @@ out: | |||
208 | 206 | ||
209 | int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) | 207 | int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) |
210 | { | 208 | { |
211 | struct net *net = genl_info_net(info); | 209 | struct net *net = sock_net(skb->sk); |
212 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 210 | struct tipc_net *tn = net_generic(net, tipc_net_id); |
213 | struct nlattr *attrs[TIPC_NLA_NET_MAX + 1]; | 211 | struct nlattr *attrs[TIPC_NLA_NET_MAX + 1]; |
214 | int err; | 212 | int err; |
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index fe0f5134ce15..7f6475efc984 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c | |||
@@ -35,7 +35,6 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include "core.h" | 37 | #include "core.h" |
38 | #include "config.h" | ||
39 | #include "socket.h" | 38 | #include "socket.h" |
40 | #include "name_table.h" | 39 | #include "name_table.h" |
41 | #include "bearer.h" | 40 | #include "bearer.h" |
@@ -44,39 +43,6 @@ | |||
44 | #include "net.h" | 43 | #include "net.h" |
45 | #include <net/genetlink.h> | 44 | #include <net/genetlink.h> |
46 | 45 | ||
47 | static int handle_cmd(struct sk_buff *skb, struct genl_info *info) | ||
48 | { | ||
49 | struct net *net = genl_info_net(info); | ||
50 | struct sk_buff *rep_buf; | ||
51 | struct nlmsghdr *rep_nlh; | ||
52 | struct nlmsghdr *req_nlh = info->nlhdr; | ||
53 | struct tipc_genlmsghdr *req_userhdr = info->userhdr; | ||
54 | int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); | ||
55 | u16 cmd; | ||
56 | |||
57 | if ((req_userhdr->cmd & 0xC000) && | ||
58 | (!netlink_net_capable(skb, CAP_NET_ADMIN))) | ||
59 | cmd = TIPC_CMD_NOT_NET_ADMIN; | ||
60 | else | ||
61 | cmd = req_userhdr->cmd; | ||
62 | |||
63 | rep_buf = tipc_cfg_do_cmd(net, req_userhdr->dest, cmd, | ||
64 | nlmsg_data(req_nlh) + GENL_HDRLEN + | ||
65 | TIPC_GENL_HDRLEN, | ||
66 | nlmsg_attrlen(req_nlh, GENL_HDRLEN + | ||
67 | TIPC_GENL_HDRLEN), hdr_space); | ||
68 | |||
69 | if (rep_buf) { | ||
70 | skb_push(rep_buf, hdr_space); | ||
71 | rep_nlh = nlmsg_hdr(rep_buf); | ||
72 | memcpy(rep_nlh, req_nlh, hdr_space); | ||
73 | rep_nlh->nlmsg_len = rep_buf->len; | ||
74 | genlmsg_unicast(net, rep_buf, NETLINK_CB(skb).portid); | ||
75 | } | ||
76 | |||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { | 46 | static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { |
81 | [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, }, | 47 | [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, }, |
82 | [TIPC_NLA_BEARER] = { .type = NLA_NESTED, }, | 48 | [TIPC_NLA_BEARER] = { .type = NLA_NESTED, }, |
@@ -89,28 +55,10 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { | |||
89 | [TIPC_NLA_NAME_TABLE] = { .type = NLA_NESTED, } | 55 | [TIPC_NLA_NAME_TABLE] = { .type = NLA_NESTED, } |
90 | }; | 56 | }; |
91 | 57 | ||
92 | /* Legacy ASCII API */ | ||
93 | static struct genl_family tipc_genl_family = { | ||
94 | .id = GENL_ID_GENERATE, | ||
95 | .name = TIPC_GENL_NAME, | ||
96 | .version = TIPC_GENL_VERSION, | ||
97 | .hdrsize = TIPC_GENL_HDRLEN, | ||
98 | .maxattr = 0, | ||
99 | .netnsok = true, | ||
100 | }; | ||
101 | |||
102 | /* Legacy ASCII API */ | ||
103 | static struct genl_ops tipc_genl_ops[] = { | ||
104 | { | ||
105 | .cmd = TIPC_GENL_CMD, | ||
106 | .doit = handle_cmd, | ||
107 | }, | ||
108 | }; | ||
109 | |||
110 | /* Users of the legacy API (tipc-config) can't handle that we add operations, | 58 | /* Users of the legacy API (tipc-config) can't handle that we add operations, |
111 | * so we have a separate genl handling for the new API. | 59 | * so we have a separate genl handling for the new API. |
112 | */ | 60 | */ |
113 | struct genl_family tipc_genl_v2_family = { | 61 | struct genl_family tipc_genl_family = { |
114 | .id = GENL_ID_GENERATE, | 62 | .id = GENL_ID_GENERATE, |
115 | .name = TIPC_GENL_V2_NAME, | 63 | .name = TIPC_GENL_V2_NAME, |
116 | .version = TIPC_GENL_V2_VERSION, | 64 | .version = TIPC_GENL_V2_VERSION, |
@@ -202,9 +150,9 @@ static const struct genl_ops tipc_genl_v2_ops[] = { | |||
202 | 150 | ||
203 | int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr) | 151 | int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr) |
204 | { | 152 | { |
205 | u32 maxattr = tipc_genl_v2_family.maxattr; | 153 | u32 maxattr = tipc_genl_family.maxattr; |
206 | 154 | ||
207 | *attr = tipc_genl_v2_family.attrbuf; | 155 | *attr = tipc_genl_family.attrbuf; |
208 | if (!*attr) | 156 | if (!*attr) |
209 | return -EOPNOTSUPP; | 157 | return -EOPNOTSUPP; |
210 | 158 | ||
@@ -215,13 +163,7 @@ int tipc_netlink_start(void) | |||
215 | { | 163 | { |
216 | int res; | 164 | int res; |
217 | 165 | ||
218 | res = genl_register_family_with_ops(&tipc_genl_family, tipc_genl_ops); | 166 | res = genl_register_family_with_ops(&tipc_genl_family, |
219 | if (res) { | ||
220 | pr_err("Failed to register legacy interface\n"); | ||
221 | return res; | ||
222 | } | ||
223 | |||
224 | res = genl_register_family_with_ops(&tipc_genl_v2_family, | ||
225 | tipc_genl_v2_ops); | 167 | tipc_genl_v2_ops); |
226 | if (res) { | 168 | if (res) { |
227 | pr_err("Failed to register netlink interface\n"); | 169 | pr_err("Failed to register netlink interface\n"); |
@@ -233,5 +175,4 @@ int tipc_netlink_start(void) | |||
233 | void tipc_netlink_stop(void) | 175 | void tipc_netlink_stop(void) |
234 | { | 176 | { |
235 | genl_unregister_family(&tipc_genl_family); | 177 | genl_unregister_family(&tipc_genl_family); |
236 | genl_unregister_family(&tipc_genl_v2_family); | ||
237 | } | 178 | } |
diff --git a/net/tipc/netlink.h b/net/tipc/netlink.h index ae2f2d923a15..08a1db67b927 100644 --- a/net/tipc/netlink.h +++ b/net/tipc/netlink.h | |||
@@ -36,7 +36,7 @@ | |||
36 | #ifndef _TIPC_NETLINK_H | 36 | #ifndef _TIPC_NETLINK_H |
37 | #define _TIPC_NETLINK_H | 37 | #define _TIPC_NETLINK_H |
38 | 38 | ||
39 | extern struct genl_family tipc_genl_v2_family; | 39 | extern struct genl_family tipc_genl_family; |
40 | int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***buf); | 40 | int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***buf); |
41 | 41 | ||
42 | struct tipc_nl_msg { | 42 | struct tipc_nl_msg { |
@@ -46,6 +46,8 @@ struct tipc_nl_msg { | |||
46 | }; | 46 | }; |
47 | 47 | ||
48 | int tipc_netlink_start(void); | 48 | int tipc_netlink_start(void); |
49 | int tipc_netlink_compat_start(void); | ||
49 | void tipc_netlink_stop(void); | 50 | void tipc_netlink_stop(void); |
51 | void tipc_netlink_compat_stop(void); | ||
50 | 52 | ||
51 | #endif | 53 | #endif |
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c new file mode 100644 index 000000000000..ce9121e8e990 --- /dev/null +++ b/net/tipc/netlink_compat.c | |||
@@ -0,0 +1,1084 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014, Ericsson AB | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * 2. Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * 3. Neither the names of the copyright holders nor the names of its | ||
14 | * contributors may be used to endorse or promote products derived from | ||
15 | * this software without specific prior written permission. | ||
16 | * | ||
17 | * Alternatively, this software may be distributed under the terms of the | ||
18 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
19 | * Software Foundation. | ||
20 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
25 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
31 | * POSSIBILITY OF SUCH DAMAGE. | ||
32 | */ | ||
33 | |||
34 | #include "core.h" | ||
35 | #include "bearer.h" | ||
36 | #include "link.h" | ||
37 | #include "name_table.h" | ||
38 | #include "socket.h" | ||
39 | #include "node.h" | ||
40 | #include "net.h" | ||
41 | #include <net/genetlink.h> | ||
42 | #include <linux/tipc_config.h> | ||
43 | |||
44 | /* The legacy API had an artificial message length limit called | ||
45 | * ULTRA_STRING_MAX_LEN. | ||
46 | */ | ||
47 | #define ULTRA_STRING_MAX_LEN 32768 | ||
48 | |||
49 | #define TIPC_SKB_MAX TLV_SPACE(ULTRA_STRING_MAX_LEN) | ||
50 | |||
51 | #define REPLY_TRUNCATED "<truncated>\n" | ||
52 | |||
53 | struct tipc_nl_compat_msg { | ||
54 | u16 cmd; | ||
55 | int rep_type; | ||
56 | int rep_size; | ||
57 | int req_type; | ||
58 | struct sk_buff *rep; | ||
59 | struct tlv_desc *req; | ||
60 | struct sock *dst_sk; | ||
61 | }; | ||
62 | |||
63 | struct tipc_nl_compat_cmd_dump { | ||
64 | int (*header)(struct tipc_nl_compat_msg *); | ||
65 | int (*dumpit)(struct sk_buff *, struct netlink_callback *); | ||
66 | int (*format)(struct tipc_nl_compat_msg *msg, struct nlattr **attrs); | ||
67 | }; | ||
68 | |||
69 | struct tipc_nl_compat_cmd_doit { | ||
70 | int (*doit)(struct sk_buff *skb, struct genl_info *info); | ||
71 | int (*transcode)(struct sk_buff *skb, struct tipc_nl_compat_msg *msg); | ||
72 | }; | ||
73 | |||
74 | static int tipc_skb_tailroom(struct sk_buff *skb) | ||
75 | { | ||
76 | int tailroom; | ||
77 | int limit; | ||
78 | |||
79 | tailroom = skb_tailroom(skb); | ||
80 | limit = TIPC_SKB_MAX - skb->len; | ||
81 | |||
82 | if (tailroom < limit) | ||
83 | return tailroom; | ||
84 | |||
85 | return limit; | ||
86 | } | ||
87 | |||
88 | static int tipc_add_tlv(struct sk_buff *skb, u16 type, void *data, u16 len) | ||
89 | { | ||
90 | struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(skb); | ||
91 | |||
92 | if (tipc_skb_tailroom(skb) < TLV_SPACE(len)) | ||
93 | return -EMSGSIZE; | ||
94 | |||
95 | skb_put(skb, TLV_SPACE(len)); | ||
96 | tlv->tlv_type = htons(type); | ||
97 | tlv->tlv_len = htons(TLV_LENGTH(len)); | ||
98 | if (len && data) | ||
99 | memcpy(TLV_DATA(tlv), data, len); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static void tipc_tlv_init(struct sk_buff *skb, u16 type) | ||
105 | { | ||
106 | struct tlv_desc *tlv = (struct tlv_desc *)skb->data; | ||
107 | |||
108 | TLV_SET_LEN(tlv, 0); | ||
109 | TLV_SET_TYPE(tlv, type); | ||
110 | skb_put(skb, sizeof(struct tlv_desc)); | ||
111 | } | ||
112 | |||
113 | static int tipc_tlv_sprintf(struct sk_buff *skb, const char *fmt, ...) | ||
114 | { | ||
115 | int n; | ||
116 | u16 len; | ||
117 | u32 rem; | ||
118 | char *buf; | ||
119 | struct tlv_desc *tlv; | ||
120 | va_list args; | ||
121 | |||
122 | rem = tipc_skb_tailroom(skb); | ||
123 | |||
124 | tlv = (struct tlv_desc *)skb->data; | ||
125 | len = TLV_GET_LEN(tlv); | ||
126 | buf = TLV_DATA(tlv) + len; | ||
127 | |||
128 | va_start(args, fmt); | ||
129 | n = vscnprintf(buf, rem, fmt, args); | ||
130 | va_end(args); | ||
131 | |||
132 | TLV_SET_LEN(tlv, n + len); | ||
133 | skb_put(skb, n); | ||
134 | |||
135 | return n; | ||
136 | } | ||
137 | |||
138 | static struct sk_buff *tipc_tlv_alloc(int size) | ||
139 | { | ||
140 | int hdr_len; | ||
141 | struct sk_buff *buf; | ||
142 | |||
143 | size = TLV_SPACE(size); | ||
144 | hdr_len = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); | ||
145 | |||
146 | buf = alloc_skb(hdr_len + size, GFP_KERNEL); | ||
147 | if (!buf) | ||
148 | return NULL; | ||
149 | |||
150 | skb_reserve(buf, hdr_len); | ||
151 | |||
152 | return buf; | ||
153 | } | ||
154 | |||
155 | static struct sk_buff *tipc_get_err_tlv(char *str) | ||
156 | { | ||
157 | int str_len = strlen(str) + 1; | ||
158 | struct sk_buff *buf; | ||
159 | |||
160 | buf = tipc_tlv_alloc(TLV_SPACE(str_len)); | ||
161 | if (buf) | ||
162 | tipc_add_tlv(buf, TIPC_TLV_ERROR_STRING, str, str_len); | ||
163 | |||
164 | return buf; | ||
165 | } | ||
166 | |||
167 | static int __tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, | ||
168 | struct tipc_nl_compat_msg *msg, | ||
169 | struct sk_buff *arg) | ||
170 | { | ||
171 | int len = 0; | ||
172 | int err; | ||
173 | struct sk_buff *buf; | ||
174 | struct nlmsghdr *nlmsg; | ||
175 | struct netlink_callback cb; | ||
176 | |||
177 | memset(&cb, 0, sizeof(cb)); | ||
178 | cb.nlh = (struct nlmsghdr *)arg->data; | ||
179 | cb.skb = arg; | ||
180 | |||
181 | buf = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | ||
182 | if (!buf) | ||
183 | return -ENOMEM; | ||
184 | |||
185 | buf->sk = msg->dst_sk; | ||
186 | |||
187 | do { | ||
188 | int rem; | ||
189 | |||
190 | len = (*cmd->dumpit)(buf, &cb); | ||
191 | |||
192 | nlmsg_for_each_msg(nlmsg, nlmsg_hdr(buf), len, rem) { | ||
193 | struct nlattr **attrs; | ||
194 | |||
195 | err = tipc_nlmsg_parse(nlmsg, &attrs); | ||
196 | if (err) | ||
197 | goto err_out; | ||
198 | |||
199 | err = (*cmd->format)(msg, attrs); | ||
200 | if (err) | ||
201 | goto err_out; | ||
202 | |||
203 | if (tipc_skb_tailroom(msg->rep) <= 1) { | ||
204 | err = -EMSGSIZE; | ||
205 | goto err_out; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | skb_reset_tail_pointer(buf); | ||
210 | buf->len = 0; | ||
211 | |||
212 | } while (len); | ||
213 | |||
214 | err = 0; | ||
215 | |||
216 | err_out: | ||
217 | kfree_skb(buf); | ||
218 | |||
219 | if (err == -EMSGSIZE) { | ||
220 | /* The legacy API only considered messages filling | ||
221 | * "ULTRA_STRING_MAX_LEN" to be truncated. | ||
222 | */ | ||
223 | if ((TIPC_SKB_MAX - msg->rep->len) <= 1) { | ||
224 | char *tail = skb_tail_pointer(msg->rep); | ||
225 | |||
226 | if (*tail != '\0') | ||
227 | sprintf(tail - sizeof(REPLY_TRUNCATED) - 1, | ||
228 | REPLY_TRUNCATED); | ||
229 | } | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | return err; | ||
235 | } | ||
236 | |||
237 | static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, | ||
238 | struct tipc_nl_compat_msg *msg) | ||
239 | { | ||
240 | int err; | ||
241 | struct sk_buff *arg; | ||
242 | |||
243 | if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type)) | ||
244 | return -EINVAL; | ||
245 | |||
246 | msg->rep = tipc_tlv_alloc(msg->rep_size); | ||
247 | if (!msg->rep) | ||
248 | return -ENOMEM; | ||
249 | |||
250 | if (msg->rep_type) | ||
251 | tipc_tlv_init(msg->rep, msg->rep_type); | ||
252 | |||
253 | if (cmd->header) | ||
254 | (*cmd->header)(msg); | ||
255 | |||
256 | arg = nlmsg_new(0, GFP_KERNEL); | ||
257 | if (!arg) { | ||
258 | kfree_skb(msg->rep); | ||
259 | return -ENOMEM; | ||
260 | } | ||
261 | |||
262 | err = __tipc_nl_compat_dumpit(cmd, msg, arg); | ||
263 | if (err) | ||
264 | kfree_skb(msg->rep); | ||
265 | |||
266 | kfree_skb(arg); | ||
267 | |||
268 | return err; | ||
269 | } | ||
270 | |||
271 | static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd, | ||
272 | struct tipc_nl_compat_msg *msg) | ||
273 | { | ||
274 | int err; | ||
275 | struct sk_buff *doit_buf; | ||
276 | struct sk_buff *trans_buf; | ||
277 | struct nlattr **attrbuf; | ||
278 | struct genl_info info; | ||
279 | |||
280 | trans_buf = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | ||
281 | if (!trans_buf) | ||
282 | return -ENOMEM; | ||
283 | |||
284 | err = (*cmd->transcode)(trans_buf, msg); | ||
285 | if (err) | ||
286 | goto trans_out; | ||
287 | |||
288 | attrbuf = kmalloc((tipc_genl_family.maxattr + 1) * | ||
289 | sizeof(struct nlattr *), GFP_KERNEL); | ||
290 | if (!attrbuf) { | ||
291 | err = -ENOMEM; | ||
292 | goto trans_out; | ||
293 | } | ||
294 | |||
295 | err = nla_parse(attrbuf, tipc_genl_family.maxattr, | ||
296 | (const struct nlattr *)trans_buf->data, | ||
297 | trans_buf->len, NULL); | ||
298 | if (err) | ||
299 | goto parse_out; | ||
300 | |||
301 | doit_buf = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | ||
302 | if (!doit_buf) { | ||
303 | err = -ENOMEM; | ||
304 | goto parse_out; | ||
305 | } | ||
306 | |||
307 | doit_buf->sk = msg->dst_sk; | ||
308 | |||
309 | memset(&info, 0, sizeof(info)); | ||
310 | info.attrs = attrbuf; | ||
311 | |||
312 | err = (*cmd->doit)(doit_buf, &info); | ||
313 | |||
314 | kfree_skb(doit_buf); | ||
315 | parse_out: | ||
316 | kfree(attrbuf); | ||
317 | trans_out: | ||
318 | kfree_skb(trans_buf); | ||
319 | |||
320 | return err; | ||
321 | } | ||
322 | |||
323 | static int tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd, | ||
324 | struct tipc_nl_compat_msg *msg) | ||
325 | { | ||
326 | int err; | ||
327 | |||
328 | if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type)) | ||
329 | return -EINVAL; | ||
330 | |||
331 | err = __tipc_nl_compat_doit(cmd, msg); | ||
332 | if (err) | ||
333 | return err; | ||
334 | |||
335 | /* The legacy API considered an empty message a success message */ | ||
336 | msg->rep = tipc_tlv_alloc(0); | ||
337 | if (!msg->rep) | ||
338 | return -ENOMEM; | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static int tipc_nl_compat_bearer_dump(struct tipc_nl_compat_msg *msg, | ||
344 | struct nlattr **attrs) | ||
345 | { | ||
346 | struct nlattr *bearer[TIPC_NLA_BEARER_MAX + 1]; | ||
347 | |||
348 | nla_parse_nested(bearer, TIPC_NLA_BEARER_MAX, attrs[TIPC_NLA_BEARER], | ||
349 | NULL); | ||
350 | |||
351 | return tipc_add_tlv(msg->rep, TIPC_TLV_BEARER_NAME, | ||
352 | nla_data(bearer[TIPC_NLA_BEARER_NAME]), | ||
353 | nla_len(bearer[TIPC_NLA_BEARER_NAME])); | ||
354 | } | ||
355 | |||
356 | static int tipc_nl_compat_bearer_enable(struct sk_buff *skb, | ||
357 | struct tipc_nl_compat_msg *msg) | ||
358 | { | ||
359 | struct nlattr *prop; | ||
360 | struct nlattr *bearer; | ||
361 | struct tipc_bearer_config *b; | ||
362 | |||
363 | b = (struct tipc_bearer_config *)TLV_DATA(msg->req); | ||
364 | |||
365 | bearer = nla_nest_start(skb, TIPC_NLA_BEARER); | ||
366 | if (!bearer) | ||
367 | return -EMSGSIZE; | ||
368 | |||
369 | if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, b->name)) | ||
370 | return -EMSGSIZE; | ||
371 | |||
372 | if (nla_put_u32(skb, TIPC_NLA_BEARER_DOMAIN, ntohl(b->disc_domain))) | ||
373 | return -EMSGSIZE; | ||
374 | |||
375 | if (ntohl(b->priority) <= TIPC_MAX_LINK_PRI) { | ||
376 | prop = nla_nest_start(skb, TIPC_NLA_BEARER_PROP); | ||
377 | if (!prop) | ||
378 | return -EMSGSIZE; | ||
379 | if (nla_put_u32(skb, TIPC_NLA_PROP_PRIO, ntohl(b->priority))) | ||
380 | return -EMSGSIZE; | ||
381 | nla_nest_end(skb, prop); | ||
382 | } | ||
383 | nla_nest_end(skb, bearer); | ||
384 | |||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static int tipc_nl_compat_bearer_disable(struct sk_buff *skb, | ||
389 | struct tipc_nl_compat_msg *msg) | ||
390 | { | ||
391 | char *name; | ||
392 | struct nlattr *bearer; | ||
393 | |||
394 | name = (char *)TLV_DATA(msg->req); | ||
395 | |||
396 | bearer = nla_nest_start(skb, TIPC_NLA_BEARER); | ||
397 | if (!bearer) | ||
398 | return -EMSGSIZE; | ||
399 | |||
400 | if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, name)) | ||
401 | return -EMSGSIZE; | ||
402 | |||
403 | nla_nest_end(skb, bearer); | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static inline u32 perc(u32 count, u32 total) | ||
409 | { | ||
410 | return (count * 100 + (total / 2)) / total; | ||
411 | } | ||
412 | |||
413 | static void __fill_bc_link_stat(struct tipc_nl_compat_msg *msg, | ||
414 | struct nlattr *prop[], struct nlattr *stats[]) | ||
415 | { | ||
416 | tipc_tlv_sprintf(msg->rep, " Window:%u packets\n", | ||
417 | nla_get_u32(prop[TIPC_NLA_PROP_WIN])); | ||
418 | |||
419 | tipc_tlv_sprintf(msg->rep, | ||
420 | " RX packets:%u fragments:%u/%u bundles:%u/%u\n", | ||
421 | nla_get_u32(stats[TIPC_NLA_STATS_RX_INFO]), | ||
422 | nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]), | ||
423 | nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]), | ||
424 | nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]), | ||
425 | nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); | ||
426 | |||
427 | tipc_tlv_sprintf(msg->rep, | ||
428 | " TX packets:%u fragments:%u/%u bundles:%u/%u\n", | ||
429 | nla_get_u32(stats[TIPC_NLA_STATS_TX_INFO]), | ||
430 | nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]), | ||
431 | nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]), | ||
432 | nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]), | ||
433 | nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); | ||
434 | |||
435 | tipc_tlv_sprintf(msg->rep, " RX naks:%u defs:%u dups:%u\n", | ||
436 | nla_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]), | ||
437 | nla_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]), | ||
438 | nla_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); | ||
439 | |||
440 | tipc_tlv_sprintf(msg->rep, " TX naks:%u acks:%u dups:%u\n", | ||
441 | nla_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]), | ||
442 | nla_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]), | ||
443 | nla_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); | ||
444 | |||
445 | tipc_tlv_sprintf(msg->rep, | ||
446 | " Congestion link:%u Send queue max:%u avg:%u", | ||
447 | nla_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]), | ||
448 | nla_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]), | ||
449 | nla_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); | ||
450 | } | ||
451 | |||
452 | static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg, | ||
453 | struct nlattr **attrs) | ||
454 | { | ||
455 | char *name; | ||
456 | struct nlattr *link[TIPC_NLA_LINK_MAX + 1]; | ||
457 | struct nlattr *prop[TIPC_NLA_PROP_MAX + 1]; | ||
458 | struct nlattr *stats[TIPC_NLA_STATS_MAX + 1]; | ||
459 | |||
460 | nla_parse_nested(link, TIPC_NLA_LINK_MAX, attrs[TIPC_NLA_LINK], NULL); | ||
461 | |||
462 | nla_parse_nested(prop, TIPC_NLA_PROP_MAX, link[TIPC_NLA_LINK_PROP], | ||
463 | NULL); | ||
464 | |||
465 | nla_parse_nested(stats, TIPC_NLA_STATS_MAX, link[TIPC_NLA_LINK_STATS], | ||
466 | NULL); | ||
467 | |||
468 | name = (char *)TLV_DATA(msg->req); | ||
469 | if (strcmp(name, nla_data(link[TIPC_NLA_LINK_NAME])) != 0) | ||
470 | return 0; | ||
471 | |||
472 | tipc_tlv_sprintf(msg->rep, "\nLink <%s>\n", | ||
473 | nla_data(link[TIPC_NLA_LINK_NAME])); | ||
474 | |||
475 | if (link[TIPC_NLA_LINK_BROADCAST]) { | ||
476 | __fill_bc_link_stat(msg, prop, stats); | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | if (link[TIPC_NLA_LINK_ACTIVE]) | ||
481 | tipc_tlv_sprintf(msg->rep, " ACTIVE"); | ||
482 | else if (link[TIPC_NLA_LINK_UP]) | ||
483 | tipc_tlv_sprintf(msg->rep, " STANDBY"); | ||
484 | else | ||
485 | tipc_tlv_sprintf(msg->rep, " DEFUNCT"); | ||
486 | |||
487 | tipc_tlv_sprintf(msg->rep, " MTU:%u Priority:%u", | ||
488 | nla_get_u32(link[TIPC_NLA_LINK_MTU]), | ||
489 | nla_get_u32(prop[TIPC_NLA_PROP_PRIO])); | ||
490 | |||
491 | tipc_tlv_sprintf(msg->rep, " Tolerance:%u ms Window:%u packets\n", | ||
492 | nla_get_u32(prop[TIPC_NLA_PROP_TOL]), | ||
493 | nla_get_u32(prop[TIPC_NLA_PROP_WIN])); | ||
494 | |||
495 | tipc_tlv_sprintf(msg->rep, | ||
496 | " RX packets:%u fragments:%u/%u bundles:%u/%u\n", | ||
497 | nla_get_u32(link[TIPC_NLA_LINK_RX]) - | ||
498 | nla_get_u32(stats[TIPC_NLA_STATS_RX_INFO]), | ||
499 | nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]), | ||
500 | nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]), | ||
501 | nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]), | ||
502 | nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); | ||
503 | |||
504 | tipc_tlv_sprintf(msg->rep, | ||
505 | " TX packets:%u fragments:%u/%u bundles:%u/%u\n", | ||
506 | nla_get_u32(link[TIPC_NLA_LINK_TX]) - | ||
507 | nla_get_u32(stats[TIPC_NLA_STATS_TX_INFO]), | ||
508 | nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]), | ||
509 | nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]), | ||
510 | nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]), | ||
511 | nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); | ||
512 | |||
513 | tipc_tlv_sprintf(msg->rep, | ||
514 | " TX profile sample:%u packets average:%u octets\n", | ||
515 | nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_CNT]), | ||
516 | nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_TOT]) / | ||
517 | nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])); | ||
518 | |||
519 | tipc_tlv_sprintf(msg->rep, | ||
520 | " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% ", | ||
521 | perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P0]), | ||
522 | nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), | ||
523 | perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P1]), | ||
524 | nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), | ||
525 | perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P2]), | ||
526 | nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), | ||
527 | perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P3]), | ||
528 | nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT]))); | ||
529 | |||
530 | tipc_tlv_sprintf(msg->rep, "-16384:%u%% -32768:%u%% -66000:%u%%\n", | ||
531 | perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P4]), | ||
532 | nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), | ||
533 | perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P5]), | ||
534 | nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), | ||
535 | perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P6]), | ||
536 | nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT]))); | ||
537 | |||
538 | tipc_tlv_sprintf(msg->rep, | ||
539 | " RX states:%u probes:%u naks:%u defs:%u dups:%u\n", | ||
540 | nla_get_u32(stats[TIPC_NLA_STATS_RX_STATES]), | ||
541 | nla_get_u32(stats[TIPC_NLA_STATS_RX_PROBES]), | ||
542 | nla_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]), | ||
543 | nla_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]), | ||
544 | nla_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); | ||
545 | |||
546 | tipc_tlv_sprintf(msg->rep, | ||
547 | " TX states:%u probes:%u naks:%u acks:%u dups:%u\n", | ||
548 | nla_get_u32(stats[TIPC_NLA_STATS_TX_STATES]), | ||
549 | nla_get_u32(stats[TIPC_NLA_STATS_TX_PROBES]), | ||
550 | nla_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]), | ||
551 | nla_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]), | ||
552 | nla_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); | ||
553 | |||
554 | tipc_tlv_sprintf(msg->rep, | ||
555 | " Congestion link:%u Send queue max:%u avg:%u", | ||
556 | nla_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]), | ||
557 | nla_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]), | ||
558 | nla_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); | ||
559 | |||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | static int tipc_nl_compat_link_dump(struct tipc_nl_compat_msg *msg, | ||
564 | struct nlattr **attrs) | ||
565 | { | ||
566 | struct nlattr *link[TIPC_NLA_LINK_MAX + 1]; | ||
567 | struct tipc_link_info link_info; | ||
568 | |||
569 | nla_parse_nested(link, TIPC_NLA_LINK_MAX, attrs[TIPC_NLA_LINK], NULL); | ||
570 | |||
571 | link_info.dest = nla_get_flag(link[TIPC_NLA_LINK_DEST]); | ||
572 | link_info.up = htonl(nla_get_flag(link[TIPC_NLA_LINK_UP])); | ||
573 | strcpy(link_info.str, nla_data(link[TIPC_NLA_LINK_NAME])); | ||
574 | |||
575 | return tipc_add_tlv(msg->rep, TIPC_TLV_LINK_INFO, | ||
576 | &link_info, sizeof(link_info)); | ||
577 | } | ||
578 | |||
579 | static int tipc_nl_compat_link_set(struct sk_buff *skb, | ||
580 | struct tipc_nl_compat_msg *msg) | ||
581 | { | ||
582 | struct nlattr *link; | ||
583 | struct nlattr *prop; | ||
584 | struct tipc_link_config *lc; | ||
585 | |||
586 | lc = (struct tipc_link_config *)TLV_DATA(msg->req); | ||
587 | |||
588 | link = nla_nest_start(skb, TIPC_NLA_LINK); | ||
589 | if (!link) | ||
590 | return -EMSGSIZE; | ||
591 | |||
592 | if (nla_put_string(skb, TIPC_NLA_LINK_NAME, lc->name)) | ||
593 | return -EMSGSIZE; | ||
594 | |||
595 | prop = nla_nest_start(skb, TIPC_NLA_LINK_PROP); | ||
596 | if (!prop) | ||
597 | return -EMSGSIZE; | ||
598 | |||
599 | if (msg->cmd == TIPC_CMD_SET_LINK_PRI) { | ||
600 | if (nla_put_u32(skb, TIPC_NLA_PROP_PRIO, ntohl(lc->value))) | ||
601 | return -EMSGSIZE; | ||
602 | } else if (msg->cmd == TIPC_CMD_SET_LINK_TOL) { | ||
603 | if (nla_put_u32(skb, TIPC_NLA_PROP_TOL, ntohl(lc->value))) | ||
604 | return -EMSGSIZE; | ||
605 | } else if (msg->cmd == TIPC_CMD_SET_LINK_WINDOW) { | ||
606 | if (nla_put_u32(skb, TIPC_NLA_PROP_WIN, ntohl(lc->value))) | ||
607 | return -EMSGSIZE; | ||
608 | } | ||
609 | |||
610 | nla_nest_end(skb, prop); | ||
611 | nla_nest_end(skb, link); | ||
612 | |||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | static int tipc_nl_compat_link_reset_stats(struct sk_buff *skb, | ||
617 | struct tipc_nl_compat_msg *msg) | ||
618 | { | ||
619 | char *name; | ||
620 | struct nlattr *link; | ||
621 | |||
622 | name = (char *)TLV_DATA(msg->req); | ||
623 | |||
624 | link = nla_nest_start(skb, TIPC_NLA_LINK); | ||
625 | if (!link) | ||
626 | return -EMSGSIZE; | ||
627 | |||
628 | if (nla_put_string(skb, TIPC_NLA_LINK_NAME, name)) | ||
629 | return -EMSGSIZE; | ||
630 | |||
631 | nla_nest_end(skb, link); | ||
632 | |||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | static int tipc_nl_compat_name_table_dump_header(struct tipc_nl_compat_msg *msg) | ||
637 | { | ||
638 | int i; | ||
639 | u32 depth; | ||
640 | struct tipc_name_table_query *ntq; | ||
641 | static const char * const header[] = { | ||
642 | "Type ", | ||
643 | "Lower Upper ", | ||
644 | "Port Identity ", | ||
645 | "Publication Scope" | ||
646 | }; | ||
647 | |||
648 | ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req); | ||
649 | |||
650 | depth = ntohl(ntq->depth); | ||
651 | |||
652 | if (depth > 4) | ||
653 | depth = 4; | ||
654 | for (i = 0; i < depth; i++) | ||
655 | tipc_tlv_sprintf(msg->rep, header[i]); | ||
656 | tipc_tlv_sprintf(msg->rep, "\n"); | ||
657 | |||
658 | return 0; | ||
659 | } | ||
660 | |||
661 | static int tipc_nl_compat_name_table_dump(struct tipc_nl_compat_msg *msg, | ||
662 | struct nlattr **attrs) | ||
663 | { | ||
664 | char port_str[27]; | ||
665 | struct tipc_name_table_query *ntq; | ||
666 | struct nlattr *nt[TIPC_NLA_NAME_TABLE_MAX + 1]; | ||
667 | struct nlattr *publ[TIPC_NLA_PUBL_MAX + 1]; | ||
668 | u32 node, depth, type, lowbound, upbound; | ||
669 | static const char * const scope_str[] = {"", " zone", " cluster", | ||
670 | " node"}; | ||
671 | |||
672 | nla_parse_nested(nt, TIPC_NLA_NAME_TABLE_MAX, | ||
673 | attrs[TIPC_NLA_NAME_TABLE], NULL); | ||
674 | |||
675 | nla_parse_nested(publ, TIPC_NLA_PUBL_MAX, nt[TIPC_NLA_NAME_TABLE_PUBL], | ||
676 | NULL); | ||
677 | |||
678 | ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req); | ||
679 | |||
680 | depth = ntohl(ntq->depth); | ||
681 | type = ntohl(ntq->type); | ||
682 | lowbound = ntohl(ntq->lowbound); | ||
683 | upbound = ntohl(ntq->upbound); | ||
684 | |||
685 | if (!(depth & TIPC_NTQ_ALLTYPES) && | ||
686 | (type != nla_get_u32(publ[TIPC_NLA_PUBL_TYPE]))) | ||
687 | return 0; | ||
688 | if (lowbound && (lowbound > nla_get_u32(publ[TIPC_NLA_PUBL_UPPER]))) | ||
689 | return 0; | ||
690 | if (upbound && (upbound < nla_get_u32(publ[TIPC_NLA_PUBL_LOWER]))) | ||
691 | return 0; | ||
692 | |||
693 | tipc_tlv_sprintf(msg->rep, "%-10u ", | ||
694 | nla_get_u32(publ[TIPC_NLA_PUBL_TYPE])); | ||
695 | |||
696 | if (depth == 1) | ||
697 | goto out; | ||
698 | |||
699 | tipc_tlv_sprintf(msg->rep, "%-10u %-10u ", | ||
700 | nla_get_u32(publ[TIPC_NLA_PUBL_LOWER]), | ||
701 | nla_get_u32(publ[TIPC_NLA_PUBL_UPPER])); | ||
702 | |||
703 | if (depth == 2) | ||
704 | goto out; | ||
705 | |||
706 | node = nla_get_u32(publ[TIPC_NLA_PUBL_NODE]); | ||
707 | sprintf(port_str, "<%u.%u.%u:%u>", tipc_zone(node), tipc_cluster(node), | ||
708 | tipc_node(node), nla_get_u32(publ[TIPC_NLA_PUBL_REF])); | ||
709 | tipc_tlv_sprintf(msg->rep, "%-26s ", port_str); | ||
710 | |||
711 | if (depth == 3) | ||
712 | goto out; | ||
713 | |||
714 | tipc_tlv_sprintf(msg->rep, "%-10u %s", | ||
715 | nla_get_u32(publ[TIPC_NLA_PUBL_REF]), | ||
716 | scope_str[nla_get_u32(publ[TIPC_NLA_PUBL_SCOPE])]); | ||
717 | out: | ||
718 | tipc_tlv_sprintf(msg->rep, "\n"); | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | static int __tipc_nl_compat_publ_dump(struct tipc_nl_compat_msg *msg, | ||
724 | struct nlattr **attrs) | ||
725 | { | ||
726 | u32 type, lower, upper; | ||
727 | struct nlattr *publ[TIPC_NLA_PUBL_MAX + 1]; | ||
728 | |||
729 | nla_parse_nested(publ, TIPC_NLA_PUBL_MAX, attrs[TIPC_NLA_PUBL], NULL); | ||
730 | |||
731 | type = nla_get_u32(publ[TIPC_NLA_PUBL_TYPE]); | ||
732 | lower = nla_get_u32(publ[TIPC_NLA_PUBL_LOWER]); | ||
733 | upper = nla_get_u32(publ[TIPC_NLA_PUBL_UPPER]); | ||
734 | |||
735 | if (lower == upper) | ||
736 | tipc_tlv_sprintf(msg->rep, " {%u,%u}", type, lower); | ||
737 | else | ||
738 | tipc_tlv_sprintf(msg->rep, " {%u,%u,%u}", type, lower, upper); | ||
739 | |||
740 | return 0; | ||
741 | } | ||
742 | |||
743 | static int tipc_nl_compat_publ_dump(struct tipc_nl_compat_msg *msg, u32 sock) | ||
744 | { | ||
745 | int err; | ||
746 | void *hdr; | ||
747 | struct nlattr *nest; | ||
748 | struct sk_buff *args; | ||
749 | struct tipc_nl_compat_cmd_dump dump; | ||
750 | |||
751 | args = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | ||
752 | if (!args) | ||
753 | return -ENOMEM; | ||
754 | |||
755 | hdr = genlmsg_put(args, 0, 0, &tipc_genl_family, NLM_F_MULTI, | ||
756 | TIPC_NL_PUBL_GET); | ||
757 | |||
758 | nest = nla_nest_start(args, TIPC_NLA_SOCK); | ||
759 | if (!nest) { | ||
760 | kfree_skb(args); | ||
761 | return -EMSGSIZE; | ||
762 | } | ||
763 | |||
764 | if (nla_put_u32(args, TIPC_NLA_SOCK_REF, sock)) { | ||
765 | kfree_skb(args); | ||
766 | return -EMSGSIZE; | ||
767 | } | ||
768 | |||
769 | nla_nest_end(args, nest); | ||
770 | genlmsg_end(args, hdr); | ||
771 | |||
772 | dump.dumpit = tipc_nl_publ_dump; | ||
773 | dump.format = __tipc_nl_compat_publ_dump; | ||
774 | |||
775 | err = __tipc_nl_compat_dumpit(&dump, msg, args); | ||
776 | |||
777 | kfree_skb(args); | ||
778 | |||
779 | return err; | ||
780 | } | ||
781 | |||
782 | static int tipc_nl_compat_sk_dump(struct tipc_nl_compat_msg *msg, | ||
783 | struct nlattr **attrs) | ||
784 | { | ||
785 | int err; | ||
786 | u32 sock_ref; | ||
787 | struct nlattr *sock[TIPC_NLA_SOCK_MAX + 1]; | ||
788 | |||
789 | nla_parse_nested(sock, TIPC_NLA_SOCK_MAX, attrs[TIPC_NLA_SOCK], NULL); | ||
790 | |||
791 | sock_ref = nla_get_u32(sock[TIPC_NLA_SOCK_REF]); | ||
792 | tipc_tlv_sprintf(msg->rep, "%u:", sock_ref); | ||
793 | |||
794 | if (sock[TIPC_NLA_SOCK_CON]) { | ||
795 | u32 node; | ||
796 | struct nlattr *con[TIPC_NLA_CON_MAX + 1]; | ||
797 | |||
798 | nla_parse_nested(con, TIPC_NLA_CON_MAX, sock[TIPC_NLA_SOCK_CON], | ||
799 | NULL); | ||
800 | |||
801 | node = nla_get_u32(con[TIPC_NLA_CON_NODE]); | ||
802 | tipc_tlv_sprintf(msg->rep, " connected to <%u.%u.%u:%u>", | ||
803 | tipc_zone(node), | ||
804 | tipc_cluster(node), | ||
805 | tipc_node(node), | ||
806 | nla_get_u32(con[TIPC_NLA_CON_SOCK])); | ||
807 | |||
808 | if (con[TIPC_NLA_CON_FLAG]) | ||
809 | tipc_tlv_sprintf(msg->rep, " via {%u,%u}\n", | ||
810 | nla_get_u32(con[TIPC_NLA_CON_TYPE]), | ||
811 | nla_get_u32(con[TIPC_NLA_CON_INST])); | ||
812 | else | ||
813 | tipc_tlv_sprintf(msg->rep, "\n"); | ||
814 | } else if (sock[TIPC_NLA_SOCK_HAS_PUBL]) { | ||
815 | tipc_tlv_sprintf(msg->rep, " bound to"); | ||
816 | |||
817 | err = tipc_nl_compat_publ_dump(msg, sock_ref); | ||
818 | if (err) | ||
819 | return err; | ||
820 | } | ||
821 | tipc_tlv_sprintf(msg->rep, "\n"); | ||
822 | |||
823 | return 0; | ||
824 | } | ||
825 | |||
826 | static int tipc_nl_compat_media_dump(struct tipc_nl_compat_msg *msg, | ||
827 | struct nlattr **attrs) | ||
828 | { | ||
829 | struct nlattr *media[TIPC_NLA_MEDIA_MAX + 1]; | ||
830 | |||
831 | nla_parse_nested(media, TIPC_NLA_MEDIA_MAX, attrs[TIPC_NLA_MEDIA], | ||
832 | NULL); | ||
833 | |||
834 | return tipc_add_tlv(msg->rep, TIPC_TLV_MEDIA_NAME, | ||
835 | nla_data(media[TIPC_NLA_MEDIA_NAME]), | ||
836 | nla_len(media[TIPC_NLA_MEDIA_NAME])); | ||
837 | } | ||
838 | |||
839 | static int tipc_nl_compat_node_dump(struct tipc_nl_compat_msg *msg, | ||
840 | struct nlattr **attrs) | ||
841 | { | ||
842 | struct tipc_node_info node_info; | ||
843 | struct nlattr *node[TIPC_NLA_NODE_MAX + 1]; | ||
844 | |||
845 | nla_parse_nested(node, TIPC_NLA_NODE_MAX, attrs[TIPC_NLA_NODE], NULL); | ||
846 | |||
847 | node_info.addr = htonl(nla_get_u32(node[TIPC_NLA_NODE_ADDR])); | ||
848 | node_info.up = htonl(nla_get_flag(node[TIPC_NLA_NODE_UP])); | ||
849 | |||
850 | return tipc_add_tlv(msg->rep, TIPC_TLV_NODE_INFO, &node_info, | ||
851 | sizeof(node_info)); | ||
852 | } | ||
853 | |||
854 | static int tipc_nl_compat_net_set(struct sk_buff *skb, | ||
855 | struct tipc_nl_compat_msg *msg) | ||
856 | { | ||
857 | u32 val; | ||
858 | struct nlattr *net; | ||
859 | |||
860 | val = ntohl(*(__be32 *)TLV_DATA(msg->req)); | ||
861 | |||
862 | net = nla_nest_start(skb, TIPC_NLA_NET); | ||
863 | if (!net) | ||
864 | return -EMSGSIZE; | ||
865 | |||
866 | if (msg->cmd == TIPC_CMD_SET_NODE_ADDR) { | ||
867 | if (nla_put_u32(skb, TIPC_NLA_NET_ADDR, val)) | ||
868 | return -EMSGSIZE; | ||
869 | } else if (msg->cmd == TIPC_CMD_SET_NETID) { | ||
870 | if (nla_put_u32(skb, TIPC_NLA_NET_ID, val)) | ||
871 | return -EMSGSIZE; | ||
872 | } | ||
873 | nla_nest_end(skb, net); | ||
874 | |||
875 | return 0; | ||
876 | } | ||
877 | |||
878 | static int tipc_nl_compat_net_dump(struct tipc_nl_compat_msg *msg, | ||
879 | struct nlattr **attrs) | ||
880 | { | ||
881 | __be32 id; | ||
882 | struct nlattr *net[TIPC_NLA_NET_MAX + 1]; | ||
883 | |||
884 | nla_parse_nested(net, TIPC_NLA_NET_MAX, attrs[TIPC_NLA_NET], NULL); | ||
885 | id = htonl(nla_get_u32(net[TIPC_NLA_NET_ID])); | ||
886 | |||
887 | return tipc_add_tlv(msg->rep, TIPC_TLV_UNSIGNED, &id, sizeof(id)); | ||
888 | } | ||
889 | |||
890 | static int tipc_cmd_show_stats_compat(struct tipc_nl_compat_msg *msg) | ||
891 | { | ||
892 | msg->rep = tipc_tlv_alloc(ULTRA_STRING_MAX_LEN); | ||
893 | if (!msg->rep) | ||
894 | return -ENOMEM; | ||
895 | |||
896 | tipc_tlv_init(msg->rep, TIPC_TLV_ULTRA_STRING); | ||
897 | tipc_tlv_sprintf(msg->rep, "TIPC version " TIPC_MOD_VER "\n"); | ||
898 | |||
899 | return 0; | ||
900 | } | ||
901 | |||
902 | static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg) | ||
903 | { | ||
904 | struct tipc_nl_compat_cmd_dump dump; | ||
905 | struct tipc_nl_compat_cmd_doit doit; | ||
906 | |||
907 | memset(&dump, 0, sizeof(dump)); | ||
908 | memset(&doit, 0, sizeof(doit)); | ||
909 | |||
910 | switch (msg->cmd) { | ||
911 | case TIPC_CMD_NOOP: | ||
912 | msg->rep = tipc_tlv_alloc(0); | ||
913 | if (!msg->rep) | ||
914 | return -ENOMEM; | ||
915 | return 0; | ||
916 | case TIPC_CMD_GET_BEARER_NAMES: | ||
917 | msg->rep_size = MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME); | ||
918 | dump.dumpit = tipc_nl_bearer_dump; | ||
919 | dump.format = tipc_nl_compat_bearer_dump; | ||
920 | return tipc_nl_compat_dumpit(&dump, msg); | ||
921 | case TIPC_CMD_ENABLE_BEARER: | ||
922 | msg->req_type = TIPC_TLV_BEARER_CONFIG; | ||
923 | doit.doit = tipc_nl_bearer_enable; | ||
924 | doit.transcode = tipc_nl_compat_bearer_enable; | ||
925 | return tipc_nl_compat_doit(&doit, msg); | ||
926 | case TIPC_CMD_DISABLE_BEARER: | ||
927 | msg->req_type = TIPC_TLV_BEARER_NAME; | ||
928 | doit.doit = tipc_nl_bearer_disable; | ||
929 | doit.transcode = tipc_nl_compat_bearer_disable; | ||
930 | return tipc_nl_compat_doit(&doit, msg); | ||
931 | case TIPC_CMD_SHOW_LINK_STATS: | ||
932 | msg->req_type = TIPC_TLV_LINK_NAME; | ||
933 | msg->rep_size = ULTRA_STRING_MAX_LEN; | ||
934 | msg->rep_type = TIPC_TLV_ULTRA_STRING; | ||
935 | dump.dumpit = tipc_nl_link_dump; | ||
936 | dump.format = tipc_nl_compat_link_stat_dump; | ||
937 | return tipc_nl_compat_dumpit(&dump, msg); | ||
938 | case TIPC_CMD_GET_LINKS: | ||
939 | msg->req_type = TIPC_TLV_NET_ADDR; | ||
940 | msg->rep_size = ULTRA_STRING_MAX_LEN; | ||
941 | dump.dumpit = tipc_nl_link_dump; | ||
942 | dump.format = tipc_nl_compat_link_dump; | ||
943 | return tipc_nl_compat_dumpit(&dump, msg); | ||
944 | case TIPC_CMD_SET_LINK_TOL: | ||
945 | case TIPC_CMD_SET_LINK_PRI: | ||
946 | case TIPC_CMD_SET_LINK_WINDOW: | ||
947 | msg->req_type = TIPC_TLV_LINK_CONFIG; | ||
948 | doit.doit = tipc_nl_link_set; | ||
949 | doit.transcode = tipc_nl_compat_link_set; | ||
950 | return tipc_nl_compat_doit(&doit, msg); | ||
951 | case TIPC_CMD_RESET_LINK_STATS: | ||
952 | msg->req_type = TIPC_TLV_LINK_NAME; | ||
953 | doit.doit = tipc_nl_link_reset_stats; | ||
954 | doit.transcode = tipc_nl_compat_link_reset_stats; | ||
955 | return tipc_nl_compat_doit(&doit, msg); | ||
956 | case TIPC_CMD_SHOW_NAME_TABLE: | ||
957 | msg->req_type = TIPC_TLV_NAME_TBL_QUERY; | ||
958 | msg->rep_size = ULTRA_STRING_MAX_LEN; | ||
959 | msg->rep_type = TIPC_TLV_ULTRA_STRING; | ||
960 | dump.header = tipc_nl_compat_name_table_dump_header; | ||
961 | dump.dumpit = tipc_nl_name_table_dump; | ||
962 | dump.format = tipc_nl_compat_name_table_dump; | ||
963 | return tipc_nl_compat_dumpit(&dump, msg); | ||
964 | case TIPC_CMD_SHOW_PORTS: | ||
965 | msg->rep_size = ULTRA_STRING_MAX_LEN; | ||
966 | msg->rep_type = TIPC_TLV_ULTRA_STRING; | ||
967 | dump.dumpit = tipc_nl_sk_dump; | ||
968 | dump.format = tipc_nl_compat_sk_dump; | ||
969 | return tipc_nl_compat_dumpit(&dump, msg); | ||
970 | case TIPC_CMD_GET_MEDIA_NAMES: | ||
971 | msg->rep_size = MAX_MEDIA * TLV_SPACE(TIPC_MAX_MEDIA_NAME); | ||
972 | dump.dumpit = tipc_nl_media_dump; | ||
973 | dump.format = tipc_nl_compat_media_dump; | ||
974 | return tipc_nl_compat_dumpit(&dump, msg); | ||
975 | case TIPC_CMD_GET_NODES: | ||
976 | msg->rep_size = ULTRA_STRING_MAX_LEN; | ||
977 | dump.dumpit = tipc_nl_node_dump; | ||
978 | dump.format = tipc_nl_compat_node_dump; | ||
979 | return tipc_nl_compat_dumpit(&dump, msg); | ||
980 | case TIPC_CMD_SET_NODE_ADDR: | ||
981 | msg->req_type = TIPC_TLV_NET_ADDR; | ||
982 | doit.doit = tipc_nl_net_set; | ||
983 | doit.transcode = tipc_nl_compat_net_set; | ||
984 | return tipc_nl_compat_doit(&doit, msg); | ||
985 | case TIPC_CMD_SET_NETID: | ||
986 | msg->req_type = TIPC_TLV_UNSIGNED; | ||
987 | doit.doit = tipc_nl_net_set; | ||
988 | doit.transcode = tipc_nl_compat_net_set; | ||
989 | return tipc_nl_compat_doit(&doit, msg); | ||
990 | case TIPC_CMD_GET_NETID: | ||
991 | msg->rep_size = sizeof(u32); | ||
992 | dump.dumpit = tipc_nl_net_dump; | ||
993 | dump.format = tipc_nl_compat_net_dump; | ||
994 | return tipc_nl_compat_dumpit(&dump, msg); | ||
995 | case TIPC_CMD_SHOW_STATS: | ||
996 | return tipc_cmd_show_stats_compat(msg); | ||
997 | } | ||
998 | |||
999 | return -EOPNOTSUPP; | ||
1000 | } | ||
1001 | |||
1002 | static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info) | ||
1003 | { | ||
1004 | int err; | ||
1005 | int len; | ||
1006 | struct tipc_nl_compat_msg msg; | ||
1007 | struct nlmsghdr *req_nlh; | ||
1008 | struct nlmsghdr *rep_nlh; | ||
1009 | struct tipc_genlmsghdr *req_userhdr = info->userhdr; | ||
1010 | struct net *net = genl_info_net(info); | ||
1011 | |||
1012 | memset(&msg, 0, sizeof(msg)); | ||
1013 | |||
1014 | req_nlh = (struct nlmsghdr *)skb->data; | ||
1015 | msg.req = nlmsg_data(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN; | ||
1016 | msg.cmd = req_userhdr->cmd; | ||
1017 | msg.dst_sk = info->dst_sk; | ||
1018 | |||
1019 | if ((msg.cmd & 0xC000) && (!netlink_net_capable(skb, CAP_NET_ADMIN))) { | ||
1020 | msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_NET_ADMIN); | ||
1021 | err = -EACCES; | ||
1022 | goto send; | ||
1023 | } | ||
1024 | |||
1025 | len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN); | ||
1026 | if (TLV_GET_LEN(msg.req) && !TLV_OK(msg.req, len)) { | ||
1027 | msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED); | ||
1028 | err = -EOPNOTSUPP; | ||
1029 | goto send; | ||
1030 | } | ||
1031 | |||
1032 | err = tipc_nl_compat_handle(&msg); | ||
1033 | if (err == -EOPNOTSUPP) | ||
1034 | msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED); | ||
1035 | else if (err == -EINVAL) | ||
1036 | msg.rep = tipc_get_err_tlv(TIPC_CFG_TLV_ERROR); | ||
1037 | send: | ||
1038 | if (!msg.rep) | ||
1039 | return err; | ||
1040 | |||
1041 | len = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); | ||
1042 | skb_push(msg.rep, len); | ||
1043 | rep_nlh = nlmsg_hdr(msg.rep); | ||
1044 | memcpy(rep_nlh, info->nlhdr, len); | ||
1045 | rep_nlh->nlmsg_len = msg.rep->len; | ||
1046 | genlmsg_unicast(net, msg.rep, NETLINK_CB(skb).portid); | ||
1047 | |||
1048 | return err; | ||
1049 | } | ||
1050 | |||
1051 | static struct genl_family tipc_genl_compat_family = { | ||
1052 | .id = GENL_ID_GENERATE, | ||
1053 | .name = TIPC_GENL_NAME, | ||
1054 | .version = TIPC_GENL_VERSION, | ||
1055 | .hdrsize = TIPC_GENL_HDRLEN, | ||
1056 | .maxattr = 0, | ||
1057 | .netnsok = true, | ||
1058 | }; | ||
1059 | |||
1060 | static struct genl_ops tipc_genl_compat_ops[] = { | ||
1061 | { | ||
1062 | .cmd = TIPC_GENL_CMD, | ||
1063 | .doit = tipc_nl_compat_recv, | ||
1064 | }, | ||
1065 | }; | ||
1066 | |||
1067 | int tipc_netlink_compat_start(void) | ||
1068 | { | ||
1069 | int res; | ||
1070 | |||
1071 | res = genl_register_family_with_ops(&tipc_genl_compat_family, | ||
1072 | tipc_genl_compat_ops); | ||
1073 | if (res) { | ||
1074 | pr_err("Failed to register legacy compat interface\n"); | ||
1075 | return res; | ||
1076 | } | ||
1077 | |||
1078 | return 0; | ||
1079 | } | ||
1080 | |||
1081 | void tipc_netlink_compat_stop(void) | ||
1082 | { | ||
1083 | genl_unregister_family(&tipc_genl_compat_family); | ||
1084 | } | ||
diff --git a/net/tipc/node.c b/net/tipc/node.c index 52308498f208..86152de8248d 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -35,7 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include "core.h" | 37 | #include "core.h" |
38 | #include "config.h" | 38 | #include "link.h" |
39 | #include "node.h" | 39 | #include "node.h" |
40 | #include "name_distr.h" | 40 | #include "name_distr.h" |
41 | #include "socket.h" | 41 | #include "socket.h" |
@@ -120,7 +120,6 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr) | |||
120 | list_add_tail_rcu(&n_ptr->list, &temp_node->list); | 120 | list_add_tail_rcu(&n_ptr->list, &temp_node->list); |
121 | n_ptr->action_flags = TIPC_WAIT_PEER_LINKS_DOWN; | 121 | n_ptr->action_flags = TIPC_WAIT_PEER_LINKS_DOWN; |
122 | n_ptr->signature = INVALID_NODE_SIG; | 122 | n_ptr->signature = INVALID_NODE_SIG; |
123 | tn->num_nodes++; | ||
124 | exit: | 123 | exit: |
125 | spin_unlock_bh(&tn->node_list_lock); | 124 | spin_unlock_bh(&tn->node_list_lock); |
126 | return n_ptr; | 125 | return n_ptr; |
@@ -131,8 +130,6 @@ static void tipc_node_delete(struct tipc_net *tn, struct tipc_node *n_ptr) | |||
131 | list_del_rcu(&n_ptr->list); | 130 | list_del_rcu(&n_ptr->list); |
132 | hlist_del_rcu(&n_ptr->hash); | 131 | hlist_del_rcu(&n_ptr->hash); |
133 | kfree_rcu(n_ptr, rcu); | 132 | kfree_rcu(n_ptr, rcu); |
134 | |||
135 | tn->num_nodes--; | ||
136 | } | 133 | } |
137 | 134 | ||
138 | void tipc_node_stop(struct net *net) | 135 | void tipc_node_stop(struct net *net) |
@@ -319,27 +316,18 @@ int tipc_node_is_up(struct tipc_node *n_ptr) | |||
319 | 316 | ||
320 | void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) | 317 | void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) |
321 | { | 318 | { |
322 | struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id); | ||
323 | |||
324 | n_ptr->links[l_ptr->bearer_id] = l_ptr; | 319 | n_ptr->links[l_ptr->bearer_id] = l_ptr; |
325 | spin_lock_bh(&tn->node_list_lock); | ||
326 | tn->num_links++; | ||
327 | spin_unlock_bh(&tn->node_list_lock); | ||
328 | n_ptr->link_cnt++; | 320 | n_ptr->link_cnt++; |
329 | } | 321 | } |
330 | 322 | ||
331 | void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) | 323 | void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) |
332 | { | 324 | { |
333 | struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id); | ||
334 | int i; | 325 | int i; |
335 | 326 | ||
336 | for (i = 0; i < MAX_BEARERS; i++) { | 327 | for (i = 0; i < MAX_BEARERS; i++) { |
337 | if (l_ptr != n_ptr->links[i]) | 328 | if (l_ptr != n_ptr->links[i]) |
338 | continue; | 329 | continue; |
339 | n_ptr->links[i] = NULL; | 330 | n_ptr->links[i] = NULL; |
340 | spin_lock_bh(&tn->node_list_lock); | ||
341 | tn->num_links--; | ||
342 | spin_unlock_bh(&tn->node_list_lock); | ||
343 | n_ptr->link_cnt--; | 331 | n_ptr->link_cnt--; |
344 | } | 332 | } |
345 | } | 333 | } |
@@ -416,121 +404,6 @@ static void node_lost_contact(struct tipc_node *n_ptr) | |||
416 | } | 404 | } |
417 | } | 405 | } |
418 | 406 | ||
419 | struct sk_buff *tipc_node_get_nodes(struct net *net, const void *req_tlv_area, | ||
420 | int req_tlv_space) | ||
421 | { | ||
422 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
423 | u32 domain; | ||
424 | struct sk_buff *buf; | ||
425 | struct tipc_node *n_ptr; | ||
426 | struct tipc_node_info node_info; | ||
427 | u32 payload_size; | ||
428 | |||
429 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) | ||
430 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | ||
431 | |||
432 | domain = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); | ||
433 | if (!tipc_addr_domain_valid(domain)) | ||
434 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE | ||
435 | " (network address)"); | ||
436 | |||
437 | spin_lock_bh(&tn->node_list_lock); | ||
438 | if (!tn->num_nodes) { | ||
439 | spin_unlock_bh(&tn->node_list_lock); | ||
440 | return tipc_cfg_reply_none(); | ||
441 | } | ||
442 | |||
443 | /* For now, get space for all other nodes */ | ||
444 | payload_size = TLV_SPACE(sizeof(node_info)) * tn->num_nodes; | ||
445 | if (payload_size > 32768u) { | ||
446 | spin_unlock_bh(&tn->node_list_lock); | ||
447 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | ||
448 | " (too many nodes)"); | ||
449 | } | ||
450 | spin_unlock_bh(&tn->node_list_lock); | ||
451 | |||
452 | buf = tipc_cfg_reply_alloc(payload_size); | ||
453 | if (!buf) | ||
454 | return NULL; | ||
455 | |||
456 | /* Add TLVs for all nodes in scope */ | ||
457 | rcu_read_lock(); | ||
458 | list_for_each_entry_rcu(n_ptr, &tn->node_list, list) { | ||
459 | if (!tipc_in_scope(domain, n_ptr->addr)) | ||
460 | continue; | ||
461 | node_info.addr = htonl(n_ptr->addr); | ||
462 | node_info.up = htonl(tipc_node_is_up(n_ptr)); | ||
463 | tipc_cfg_append_tlv(buf, TIPC_TLV_NODE_INFO, | ||
464 | &node_info, sizeof(node_info)); | ||
465 | } | ||
466 | rcu_read_unlock(); | ||
467 | return buf; | ||
468 | } | ||
469 | |||
470 | struct sk_buff *tipc_node_get_links(struct net *net, const void *req_tlv_area, | ||
471 | int req_tlv_space) | ||
472 | { | ||
473 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
474 | u32 domain; | ||
475 | struct sk_buff *buf; | ||
476 | struct tipc_node *n_ptr; | ||
477 | struct tipc_link_info link_info; | ||
478 | u32 payload_size; | ||
479 | |||
480 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) | ||
481 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | ||
482 | |||
483 | domain = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); | ||
484 | if (!tipc_addr_domain_valid(domain)) | ||
485 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE | ||
486 | " (network address)"); | ||
487 | |||
488 | if (!tn->own_addr) | ||
489 | return tipc_cfg_reply_none(); | ||
490 | |||
491 | spin_lock_bh(&tn->node_list_lock); | ||
492 | /* Get space for all unicast links + broadcast link */ | ||
493 | payload_size = TLV_SPACE((sizeof(link_info)) * (tn->num_links + 1)); | ||
494 | if (payload_size > 32768u) { | ||
495 | spin_unlock_bh(&tn->node_list_lock); | ||
496 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | ||
497 | " (too many links)"); | ||
498 | } | ||
499 | spin_unlock_bh(&tn->node_list_lock); | ||
500 | |||
501 | buf = tipc_cfg_reply_alloc(payload_size); | ||
502 | if (!buf) | ||
503 | return NULL; | ||
504 | |||
505 | /* Add TLV for broadcast link */ | ||
506 | link_info.dest = htonl(tipc_cluster_mask(tn->own_addr)); | ||
507 | link_info.up = htonl(1); | ||
508 | strlcpy(link_info.str, tipc_bclink_name, TIPC_MAX_LINK_NAME); | ||
509 | tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info)); | ||
510 | |||
511 | /* Add TLVs for any other links in scope */ | ||
512 | rcu_read_lock(); | ||
513 | list_for_each_entry_rcu(n_ptr, &tn->node_list, list) { | ||
514 | u32 i; | ||
515 | |||
516 | if (!tipc_in_scope(domain, n_ptr->addr)) | ||
517 | continue; | ||
518 | tipc_node_lock(n_ptr); | ||
519 | for (i = 0; i < MAX_BEARERS; i++) { | ||
520 | if (!n_ptr->links[i]) | ||
521 | continue; | ||
522 | link_info.dest = htonl(n_ptr->addr); | ||
523 | link_info.up = htonl(tipc_link_is_up(n_ptr->links[i])); | ||
524 | strcpy(link_info.str, n_ptr->links[i]->name); | ||
525 | tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, | ||
526 | &link_info, sizeof(link_info)); | ||
527 | } | ||
528 | tipc_node_unlock(n_ptr); | ||
529 | } | ||
530 | rcu_read_unlock(); | ||
531 | return buf; | ||
532 | } | ||
533 | |||
534 | /** | 407 | /** |
535 | * tipc_node_get_linkname - get the name of a link | 408 | * tipc_node_get_linkname - get the name of a link |
536 | * | 409 | * |
@@ -623,7 +496,7 @@ static int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node) | |||
623 | void *hdr; | 496 | void *hdr; |
624 | struct nlattr *attrs; | 497 | struct nlattr *attrs; |
625 | 498 | ||
626 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, | 499 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, |
627 | NLM_F_MULTI, TIPC_NL_NODE_GET); | 500 | NLM_F_MULTI, TIPC_NL_NODE_GET); |
628 | if (!hdr) | 501 | if (!hdr) |
629 | return -EMSGSIZE; | 502 | return -EMSGSIZE; |
diff --git a/net/tipc/node.h b/net/tipc/node.h index 20ec13f9bede..3d18c66b7f78 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h | |||
@@ -142,10 +142,6 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr); | |||
142 | void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr); | 142 | void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr); |
143 | int tipc_node_active_links(struct tipc_node *n_ptr); | 143 | int tipc_node_active_links(struct tipc_node *n_ptr); |
144 | int tipc_node_is_up(struct tipc_node *n_ptr); | 144 | int tipc_node_is_up(struct tipc_node *n_ptr); |
145 | struct sk_buff *tipc_node_get_links(struct net *net, const void *req_tlv_area, | ||
146 | int req_tlv_space); | ||
147 | struct sk_buff *tipc_node_get_nodes(struct net *net, const void *req_tlv_area, | ||
148 | int req_tlv_space); | ||
149 | int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node, | 145 | int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node, |
150 | char *linkname, size_t len); | 146 | char *linkname, size_t len); |
151 | void tipc_node_unlock(struct tipc_node *node); | 147 | void tipc_node_unlock(struct tipc_node *node); |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 4a98d15a1323..f73e975af80b 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include "name_table.h" | 40 | #include "name_table.h" |
41 | #include "node.h" | 41 | #include "node.h" |
42 | #include "link.h" | 42 | #include "link.h" |
43 | #include "config.h" | ||
44 | #include "name_distr.h" | 43 | #include "name_distr.h" |
45 | #include "socket.h" | 44 | #include "socket.h" |
46 | 45 | ||
@@ -2281,91 +2280,6 @@ static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, | |||
2281 | return rc; | 2280 | return rc; |
2282 | } | 2281 | } |
2283 | 2282 | ||
2284 | static int tipc_sk_show(struct tipc_sock *tsk, char *buf, | ||
2285 | int len, int full_id) | ||
2286 | { | ||
2287 | struct net *net = sock_net(&tsk->sk); | ||
2288 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
2289 | struct publication *publ; | ||
2290 | int ret; | ||
2291 | |||
2292 | if (full_id) | ||
2293 | ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:", | ||
2294 | tipc_zone(tn->own_addr), | ||
2295 | tipc_cluster(tn->own_addr), | ||
2296 | tipc_node(tn->own_addr), tsk->portid); | ||
2297 | else | ||
2298 | ret = tipc_snprintf(buf, len, "%-10u:", tsk->portid); | ||
2299 | |||
2300 | if (tsk->connected) { | ||
2301 | u32 dport = tsk_peer_port(tsk); | ||
2302 | u32 destnode = tsk_peer_node(tsk); | ||
2303 | |||
2304 | ret += tipc_snprintf(buf + ret, len - ret, | ||
2305 | " connected to <%u.%u.%u:%u>", | ||
2306 | tipc_zone(destnode), | ||
2307 | tipc_cluster(destnode), | ||
2308 | tipc_node(destnode), dport); | ||
2309 | if (tsk->conn_type != 0) | ||
2310 | ret += tipc_snprintf(buf + ret, len - ret, | ||
2311 | " via {%u,%u}", tsk->conn_type, | ||
2312 | tsk->conn_instance); | ||
2313 | } else if (tsk->published) { | ||
2314 | ret += tipc_snprintf(buf + ret, len - ret, " bound to"); | ||
2315 | list_for_each_entry(publ, &tsk->publications, pport_list) { | ||
2316 | if (publ->lower == publ->upper) | ||
2317 | ret += tipc_snprintf(buf + ret, len - ret, | ||
2318 | " {%u,%u}", publ->type, | ||
2319 | publ->lower); | ||
2320 | else | ||
2321 | ret += tipc_snprintf(buf + ret, len - ret, | ||
2322 | " {%u,%u,%u}", publ->type, | ||
2323 | publ->lower, publ->upper); | ||
2324 | } | ||
2325 | } | ||
2326 | ret += tipc_snprintf(buf + ret, len - ret, "\n"); | ||
2327 | return ret; | ||
2328 | } | ||
2329 | |||
2330 | struct sk_buff *tipc_sk_socks_show(struct net *net) | ||
2331 | { | ||
2332 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
2333 | const struct bucket_table *tbl; | ||
2334 | struct rhash_head *pos; | ||
2335 | struct sk_buff *buf; | ||
2336 | struct tlv_desc *rep_tlv; | ||
2337 | char *pb; | ||
2338 | int pb_len; | ||
2339 | struct tipc_sock *tsk; | ||
2340 | int str_len = 0; | ||
2341 | int i; | ||
2342 | |||
2343 | buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); | ||
2344 | if (!buf) | ||
2345 | return NULL; | ||
2346 | rep_tlv = (struct tlv_desc *)buf->data; | ||
2347 | pb = TLV_DATA(rep_tlv); | ||
2348 | pb_len = ULTRA_STRING_MAX_LEN; | ||
2349 | |||
2350 | rcu_read_lock(); | ||
2351 | tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht); | ||
2352 | for (i = 0; i < tbl->size; i++) { | ||
2353 | rht_for_each_entry_rcu(tsk, pos, tbl, i, node) { | ||
2354 | spin_lock_bh(&tsk->sk.sk_lock.slock); | ||
2355 | str_len += tipc_sk_show(tsk, pb + str_len, | ||
2356 | pb_len - str_len, 0); | ||
2357 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | ||
2358 | } | ||
2359 | } | ||
2360 | rcu_read_unlock(); | ||
2361 | |||
2362 | str_len += 1; /* for "\0" */ | ||
2363 | skb_put(buf, TLV_SPACE(str_len)); | ||
2364 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | ||
2365 | |||
2366 | return buf; | ||
2367 | } | ||
2368 | |||
2369 | /* tipc_sk_reinit: set non-zero address in all existing sockets | 2283 | /* tipc_sk_reinit: set non-zero address in all existing sockets |
2370 | * when we go from standalone to network mode. | 2284 | * when we go from standalone to network mode. |
2371 | */ | 2285 | */ |
@@ -2783,7 +2697,7 @@ static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb, | |||
2783 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 2697 | struct tipc_net *tn = net_generic(net, tipc_net_id); |
2784 | 2698 | ||
2785 | hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, | 2699 | hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, |
2786 | &tipc_genl_v2_family, NLM_F_MULTI, TIPC_NL_SOCK_GET); | 2700 | &tipc_genl_family, NLM_F_MULTI, TIPC_NL_SOCK_GET); |
2787 | if (!hdr) | 2701 | if (!hdr) |
2788 | goto msg_cancel; | 2702 | goto msg_cancel; |
2789 | 2703 | ||
@@ -2864,7 +2778,7 @@ static int __tipc_nl_add_sk_publ(struct sk_buff *skb, | |||
2864 | struct nlattr *attrs; | 2778 | struct nlattr *attrs; |
2865 | 2779 | ||
2866 | hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, | 2780 | hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, |
2867 | &tipc_genl_v2_family, NLM_F_MULTI, TIPC_NL_PUBL_GET); | 2781 | &tipc_genl_family, NLM_F_MULTI, TIPC_NL_PUBL_GET); |
2868 | if (!hdr) | 2782 | if (!hdr) |
2869 | goto msg_cancel; | 2783 | goto msg_cancel; |
2870 | 2784 | ||
diff --git a/net/tipc/socket.h b/net/tipc/socket.h index 8be0da7df8fc..238f1b7bd9bd 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h | |||
@@ -49,7 +49,6 @@ void tipc_sock_release_local(struct socket *sock); | |||
49 | int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, | 49 | int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, |
50 | int flags); | 50 | int flags); |
51 | int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq); | 51 | int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq); |
52 | struct sk_buff *tipc_sk_socks_show(struct net *net); | ||
53 | void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, | 52 | void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, |
54 | struct sk_buff_head *inputq); | 53 | struct sk_buff_head *inputq); |
55 | void tipc_sk_reinit(struct net *net); | 54 | void tipc_sk_reinit(struct net *net); |