Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tipc: convert legacy nl link stat to nl compat

Add functionality for safely appending string data to a TLV without
keeping write count in the caller.

Convert TIPC_CMD_SHOW_LINK_STATS to compat dumpit.

Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Richard Alpe and committed by
David S. Miller
f2b3b2d4 9ab15465

+215 -192
+10
include/uapi/linux/tipc_config.h
··· 277 277 return ntohs(tlv->tlv_len); 278 278 } 279 279 280 + static inline void TLV_SET_LEN(struct tlv_desc *tlv, __u16 len) 281 + { 282 + tlv->tlv_len = htons(len); 283 + } 284 + 280 285 static inline int TLV_CHECK_TYPE(struct tlv_desc *tlv, __u16 type) 281 286 { 282 287 return (ntohs(tlv->tlv_type) == type); 288 + } 289 + 290 + static inline void TLV_SET_TYPE(struct tlv_desc *tlv, __u16 type) 291 + { 292 + tlv->tlv_type = htons(type); 283 293 } 284 294 285 295 static inline int TLV_SET(void *tlv, __u16 type, void *data, __u16 len)
-43
net/tipc/bcast.c
··· 860 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 863 int tipc_bclink_reset_stats(struct net *net) 907 864 { 908 865 struct tipc_net *tn = net_generic(net, tipc_net_id);
-1
net/tipc/bcast.h
··· 127 127 u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr); 128 128 void tipc_bclink_update_link_state(struct tipc_node *node, 129 129 u32 last_sent); 130 - int tipc_bclink_stats(struct net *net, char *stats_buf, const u32 buf_size); 131 130 int tipc_bclink_reset_stats(struct net *net); 132 131 int tipc_bclink_set_queue_limits(struct net *net, u32 limit); 133 132 void tipc_bcbearer_sort(struct net *net, struct tipc_node_map *nm_ptr,
-4
net/tipc/config.c
··· 213 213 rep_tlv_buf = tipc_node_get_links(net, req_tlv_area, 214 214 req_tlv_space); 215 215 break; 216 - case TIPC_CMD_SHOW_LINK_STATS: 217 - rep_tlv_buf = tipc_link_cmd_show_stats(net, req_tlv_area, 218 - req_tlv_space); 219 - break; 220 216 case TIPC_CMD_RESET_LINK_STATS: 221 217 rep_tlv_buf = tipc_link_cmd_reset_stats(net, req_tlv_area, 222 218 req_tlv_space);
-141
net/tipc/link.c
··· 2146 2146 return tipc_cfg_reply_none(); 2147 2147 } 2148 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 2149 static void link_print(struct tipc_link *l_ptr, const char *str) 2291 2150 { 2292 2151 struct tipc_net *tn = net_generic(l_ptr->owner->net, tipc_net_id);
-3
net/tipc/link.h
··· 217 217 void tipc_link_purge_queues(struct tipc_link *l_ptr); 218 218 struct sk_buff *tipc_link_cmd_config(struct net *net, const void *req_tlv_area, 219 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 220 struct sk_buff *tipc_link_cmd_reset_stats(struct net *net, 224 221 const void *req_tlv_area, 225 222 int req_tlv_space);